1 /****************************************************************************** 2 * 3 * Copyright (C) 1999-2012 Broadcom Corporation 4 * 5 * Licensed under the Apache License, Version 2.0 (the "License"); 6 * you may not use this file except in compliance with the License. 7 * You may obtain a copy of the License at: 8 * 9 * http://www.apache.org/licenses/LICENSE-2.0 10 * 11 * Unless required by applicable law or agreed to in writing, software 12 * distributed under the License is distributed on an "AS IS" BASIS, 13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 * See the License for the specific language governing permissions and 15 * limitations under the License. 16 * 17 ******************************************************************************/ 18 19 /****************************************************************************** 20 * 21 * This file contains the L2CAP UCD code 22 * 23 ******************************************************************************/ 24 25 #include <stdlib.h> 26 #include <string.h> 27 #include <stdio.h> 28 29 #include "bt_common.h" 30 #include "bt_types.h" 31 #include "hcidefs.h" 32 #include "hcimsgs.h" 33 #include "l2cdefs.h" 34 #include "l2c_int.h" 35 #include "btu.h" 36 #include "btm_api.h" 37 #include "btm_int.h" 38 39 #if (L2CAP_UCD_INCLUDED == TRUE) 40 41 extern fixed_queue_t *btu_bta_alarm_queue; 42 43 static BOOLEAN l2c_ucd_connect ( BD_ADDR rem_bda ); 44 45 /******************************************************************************* 46 ** 47 ** Function l2c_ucd_discover_cback 48 ** 49 ** Description UCD Discover callback 50 ** 51 ** Returns void 52 ** 53 *******************************************************************************/ 54 static void l2c_ucd_discover_cback (BD_ADDR rem_bda, UINT8 info_type, UINT32 data) 55 { 56 tL2C_RCB *p_rcb = &l2cb.rcb_pool[0]; 57 UINT16 xx; 58 59 L2CAP_TRACE_DEBUG ("L2CAP - l2c_ucd_discover_cback"); 60 61 for (xx = 0; xx < MAX_L2CAP_CLIENTS; xx++, p_rcb++) 62 { 63 if (p_rcb->in_use) 64 { 65 /* if this application is waiting UCD reception info */ 66 if (( info_type == L2CAP_UCD_INFO_TYPE_RECEPTION ) 67 && ( p_rcb->ucd.state & L2C_UCD_STATE_W4_RECEPTION )) 68 { 69 p_rcb->ucd.cb_info.pL2CA_UCD_Discover_Cb (rem_bda, info_type, data); 70 p_rcb->ucd.state &= ~(L2C_UCD_STATE_W4_RECEPTION); 71 } 72 73 /* if this application is waiting UCD MTU info */ 74 if (( info_type == L2CAP_UCD_INFO_TYPE_MTU ) 75 && ( p_rcb->ucd.state & L2C_UCD_STATE_W4_MTU )) 76 { 77 p_rcb->ucd.cb_info.pL2CA_UCD_Discover_Cb (rem_bda, info_type, data); 78 p_rcb->ucd.state &= ~(L2C_UCD_STATE_W4_MTU); 79 } 80 } 81 } 82 } 83 84 /******************************************************************************* 85 ** 86 ** Function l2c_ucd_data_ind_cback 87 ** 88 ** Description UCD Data callback 89 ** 90 ** Returns void 91 ** 92 *******************************************************************************/ 93 static void l2c_ucd_data_ind_cback (BD_ADDR rem_bda, BT_HDR *p_buf) 94 { 95 UINT8 *p; 96 UINT16 psm; 97 tL2C_RCB *p_rcb; 98 99 L2CAP_TRACE_DEBUG ("L2CAP - l2c_ucd_data_ind_cback"); 100 101 p = (UINT8 *)(p_buf + 1) + p_buf->offset; 102 STREAM_TO_UINT16(psm, p) 103 104 p_buf->offset += L2CAP_UCD_OVERHEAD; 105 p_buf->len -= L2CAP_UCD_OVERHEAD; 106 107 if ((p_rcb = l2cu_find_rcb_by_psm (psm)) == NULL) 108 { 109 L2CAP_TRACE_ERROR ("L2CAP - no RCB for l2c_ucd_data_ind_cback, PSM: 0x%04x", psm); 110 osi_free(p_buf); 111 } 112 else 113 { 114 p_rcb->ucd.cb_info.pL2CA_UCD_Data_Cb(rem_bda, p_buf); 115 } 116 } 117 118 /******************************************************************************* 119 ** 120 ** Function l2c_ucd_congestion_status_cback 121 ** 122 ** Description UCD Congestion Status callback 123 ** 124 ** Returns void 125 ** 126 *******************************************************************************/ 127 static void l2c_ucd_congestion_status_cback (BD_ADDR rem_bda, BOOLEAN is_congested) 128 { 129 tL2C_RCB *p_rcb = &l2cb.rcb_pool[0]; 130 UINT16 xx; 131 132 L2CAP_TRACE_DEBUG ("L2CAP - l2c_ucd_congestion_status_cback"); 133 134 for (xx = 0; xx < MAX_L2CAP_CLIENTS; xx++, p_rcb++) 135 { 136 if (( p_rcb->in_use ) 137 &&( p_rcb->ucd.state != L2C_UCD_STATE_UNUSED )) 138 { 139 if ( p_rcb->ucd.cb_info.pL2CA_UCD_Congestion_Status_Cb ) 140 { 141 L2CAP_TRACE_DEBUG ("L2CAP - Calling UCDCongestionStatus_Cb (%d), PSM=0x%04x, BDA: %08x%04x,", 142 is_congested, p_rcb->psm, 143 (rem_bda[0]<<24)+(rem_bda[1]<<16)+(rem_bda[2]<<8)+rem_bda[3], 144 (rem_bda[4]<<8)+rem_bda[5]); 145 146 p_rcb->ucd.cb_info.pL2CA_UCD_Congestion_Status_Cb ( rem_bda, is_congested ); 147 } 148 } 149 } 150 } 151 152 /******************************************************************************* 153 ** 154 ** Function l2c_ucd_disconnect_ind_cback 155 ** 156 ** Description UCD disconnect callback (This prevent to access null pointer) 157 ** 158 ** Returns void 159 ** 160 *******************************************************************************/ 161 static void l2c_ucd_disconnect_ind_cback (UINT16 cid, BOOLEAN result) 162 { 163 /* do nothing */ 164 } 165 166 /******************************************************************************* 167 ** 168 ** Function l2c_ucd_config_ind_cback 169 ** 170 ** Description UCD config callback (This prevent to access null pointer) 171 ** 172 ** Returns void 173 ** 174 *******************************************************************************/ 175 static void l2c_ucd_config_ind_cback (UINT16 cid, tL2CAP_CFG_INFO *p_cfg) 176 { 177 /* do nothing */ 178 } 179 180 /******************************************************************************* 181 ** 182 ** Function l2c_ucd_config_cfm_cback 183 ** 184 ** Description UCD config callback (This prevent to access null pointer) 185 ** 186 ** Returns void 187 ** 188 *******************************************************************************/ 189 static void l2c_ucd_config_cfm_cback (UINT16 cid, tL2CAP_CFG_INFO *p_cfg) 190 { 191 /* do nothing */ 192 } 193 194 /******************************************************************************* 195 ** 196 ** Function L2CA_UcdRegister 197 ** 198 ** Description Register PSM on UCD. 199 ** 200 ** Parameters: tL2CAP_UCD_CB_INFO 201 ** 202 ** Return value: TRUE if successs 203 ** 204 *******************************************************************************/ 205 BOOLEAN L2CA_UcdRegister ( UINT16 psm, tL2CAP_UCD_CB_INFO *p_cb_info ) 206 { 207 tL2C_RCB *p_rcb; 208 209 L2CAP_TRACE_API ("L2CA_UcdRegister() PSM: 0x%04x", psm); 210 211 if ((!p_cb_info->pL2CA_UCD_Discover_Cb) 212 || (!p_cb_info->pL2CA_UCD_Data_Cb)) 213 { 214 L2CAP_TRACE_ERROR ("L2CAP - no callback registering PSM(0x%04x) on UCD", psm); 215 return (FALSE); 216 } 217 218 if ((p_rcb = l2cu_find_rcb_by_psm (psm)) == NULL) 219 { 220 L2CAP_TRACE_ERROR ("L2CAP - no RCB for L2CA_UcdRegister, PSM: 0x%04x", psm); 221 return (FALSE); 222 } 223 224 p_rcb->ucd.state = L2C_UCD_STATE_W4_DATA; 225 p_rcb->ucd.cb_info = *p_cb_info; 226 227 /* check if master rcb is created for UCD */ 228 if ((p_rcb = l2cu_find_rcb_by_psm (L2C_UCD_RCB_ID)) == NULL) 229 { 230 if ((p_rcb = l2cu_allocate_rcb (L2C_UCD_RCB_ID)) == NULL) 231 { 232 L2CAP_TRACE_ERROR ("L2CAP - no RCB available for L2CA_UcdRegister"); 233 return (FALSE); 234 } 235 else 236 { 237 /* these callback functions will forward data to each UCD application */ 238 p_rcb->ucd.cb_info.pL2CA_UCD_Discover_Cb = l2c_ucd_discover_cback; 239 p_rcb->ucd.cb_info.pL2CA_UCD_Data_Cb = l2c_ucd_data_ind_cback; 240 p_rcb->ucd.cb_info.pL2CA_UCD_Congestion_Status_Cb = l2c_ucd_congestion_status_cback; 241 242 memset (&p_rcb->api, 0, sizeof(tL2CAP_APPL_INFO)); 243 p_rcb->api.pL2CA_DisconnectInd_Cb = l2c_ucd_disconnect_ind_cback; 244 245 /* This will make L2CAP check UCD congestion callback */ 246 p_rcb->api.pL2CA_CongestionStatus_Cb = NULL; 247 248 /* do nothing but prevent crash */ 249 p_rcb->api.pL2CA_ConfigInd_Cb = l2c_ucd_config_ind_cback; 250 p_rcb->api.pL2CA_ConfigCfm_Cb = l2c_ucd_config_cfm_cback; 251 } 252 } 253 254 return (TRUE); 255 } 256 257 /******************************************************************************* 258 ** 259 ** Function L2CA_UcdDeregister 260 ** 261 ** Description Deregister PSM on UCD. 262 ** 263 ** Parameters: PSM 264 ** 265 ** Return value: TRUE if successs 266 ** 267 *******************************************************************************/ 268 BOOLEAN L2CA_UcdDeregister ( UINT16 psm ) 269 { 270 tL2C_CCB *p_ccb; 271 tL2C_RCB *p_rcb; 272 UINT16 xx; 273 274 L2CAP_TRACE_API ("L2CA_UcdDeregister() PSM: 0x%04x", psm); 275 276 if ((p_rcb = l2cu_find_rcb_by_psm (psm)) == NULL) 277 { 278 L2CAP_TRACE_ERROR ("L2CAP - no RCB for L2CA_UcdDeregister, PSM: 0x%04x", psm); 279 return (FALSE); 280 } 281 282 p_rcb->ucd.state = L2C_UCD_STATE_UNUSED; 283 284 /* check this was the last UCD registration */ 285 p_rcb = &l2cb.rcb_pool[0]; 286 287 for (xx = 0; xx < MAX_L2CAP_CLIENTS; xx++, p_rcb++) 288 { 289 if ((p_rcb->in_use) && (p_rcb->ucd.state != L2C_UCD_STATE_UNUSED)) 290 return (TRUE); 291 } 292 293 /* delete master rcb for UCD */ 294 if ((p_rcb = l2cu_find_rcb_by_psm (L2C_UCD_RCB_ID)) != NULL) 295 { 296 l2cu_release_rcb (p_rcb); 297 } 298 299 /* delete CCB for UCD */ 300 p_ccb = l2cb.ccb_pool; 301 for ( xx = 0; xx < MAX_L2CAP_CHANNELS; xx++ ) 302 { 303 if (( p_ccb->in_use ) 304 &&( p_ccb->local_cid == L2CAP_CONNECTIONLESS_CID )) 305 { 306 l2cu_release_ccb (p_ccb); 307 } 308 p_ccb++; 309 } 310 311 return (TRUE); 312 } 313 314 /******************************************************************************* 315 ** 316 ** Function L2CA_UcdDiscover 317 ** 318 ** Description Discover UCD of remote device. 319 ** 320 ** Parameters: PSM 321 ** BD_ADDR of remote device 322 ** info_type : L2CAP_UCD_INFO_TYPE_RECEPTION 323 ** L2CAP_UCD_INFO_TYPE_MTU 324 ** 325 ** 326 ** Return value: TRUE if successs 327 ** 328 *******************************************************************************/ 329 BOOLEAN L2CA_UcdDiscover ( UINT16 psm, BD_ADDR rem_bda, UINT8 info_type ) 330 { 331 tL2C_LCB *p_lcb; 332 tL2C_CCB *p_ccb; 333 tL2C_RCB *p_rcb; 334 335 L2CAP_TRACE_API ("L2CA_UcdDiscover() PSM: 0x%04x BDA: %08x%04x, InfoType=0x%02x", psm, 336 (rem_bda[0]<<24)+(rem_bda[1]<<16)+(rem_bda[2]<<8)+rem_bda[3], 337 (rem_bda[4]<<8)+rem_bda[5], info_type); 338 339 /* Fail if the PSM is not registered */ 340 if (((p_rcb = l2cu_find_rcb_by_psm (psm)) == NULL) 341 ||( p_rcb->ucd.state == L2C_UCD_STATE_UNUSED )) 342 { 343 L2CAP_TRACE_WARNING ("L2CAP - no RCB for L2CA_UcdDiscover, PSM: 0x%04x", psm); 344 return (FALSE); 345 } 346 347 /* First, see if we already have a link to the remote */ 348 /* then find the channel control block for UCD. */ 349 if (((p_lcb = l2cu_find_lcb_by_bd_addr (rem_bda, BT_TRANSPORT_BR_EDR)) == NULL) 350 ||((p_ccb = l2cu_find_ccb_by_cid (p_lcb, L2CAP_CONNECTIONLESS_CID)) == NULL)) 351 { 352 if ( l2c_ucd_connect (rem_bda) == FALSE ) 353 { 354 return (FALSE); 355 } 356 } 357 358 /* set waiting flags in rcb */ 359 360 if ( info_type & L2CAP_UCD_INFO_TYPE_RECEPTION ) 361 p_rcb->ucd.state |= L2C_UCD_STATE_W4_RECEPTION; 362 363 if ( info_type & L2CAP_UCD_INFO_TYPE_MTU ) 364 p_rcb->ucd.state |= L2C_UCD_STATE_W4_MTU; 365 366 /* if link is already established */ 367 if ((p_lcb)&&(p_lcb->link_state == LST_CONNECTED)) 368 { 369 if (!p_ccb) 370 { 371 p_ccb = l2cu_find_ccb_by_cid (p_lcb, L2CAP_CONNECTIONLESS_CID); 372 } 373 l2c_ucd_check_pending_info_req(p_ccb); 374 } 375 return (TRUE); 376 } 377 378 /******************************************************************************* 379 ** 380 ** Function L2CA_UcdDataWrite 381 ** 382 ** Description Send UCD to remote device 383 ** 384 ** Parameters: PSM 385 ** BD Address of remote 386 ** Pointer to buffer of type BT_HDR 387 ** flags : L2CAP_FLUSHABLE_CH_BASED 388 ** L2CAP_FLUSHABLE_PKT 389 ** L2CAP_NON_FLUSHABLE_PKT 390 ** 391 ** Return value L2CAP_DW_SUCCESS, if data accepted 392 ** L2CAP_DW_FAILED, if error 393 ** 394 *******************************************************************************/ 395 UINT16 L2CA_UcdDataWrite (UINT16 psm, BD_ADDR rem_bda, BT_HDR *p_buf, UINT16 flags) 396 { 397 tL2C_LCB *p_lcb; 398 tL2C_CCB *p_ccb; 399 tL2C_RCB *p_rcb; 400 UINT8 *p; 401 402 L2CAP_TRACE_API ("L2CA_UcdDataWrite() PSM: 0x%04x BDA: %08x%04x", psm, 403 (rem_bda[0]<<24)+(rem_bda[1]<<16)+(rem_bda[2]<<8)+rem_bda[3], 404 (rem_bda[4]<<8)+rem_bda[5]); 405 406 /* Fail if the PSM is not registered */ 407 if (((p_rcb = l2cu_find_rcb_by_psm (psm)) == NULL) 408 ||( p_rcb->ucd.state == L2C_UCD_STATE_UNUSED )) 409 { 410 L2CAP_TRACE_WARNING ("L2CAP - no RCB for L2CA_UcdDataWrite, PSM: 0x%04x", psm); 411 osi_free(p_buf); 412 return (L2CAP_DW_FAILED); 413 } 414 415 /* First, see if we already have a link to the remote */ 416 /* then find the channel control block for UCD */ 417 if (((p_lcb = l2cu_find_lcb_by_bd_addr (rem_bda, BT_TRANSPORT_BR_EDR)) == NULL) 418 ||((p_ccb = l2cu_find_ccb_by_cid (p_lcb, L2CAP_CONNECTIONLESS_CID)) == NULL)) 419 { 420 if ( l2c_ucd_connect (rem_bda) == FALSE ) 421 { 422 osi_free(p_buf); 423 return (L2CAP_DW_FAILED); 424 } 425 426 /* If we still don't have lcb and ccb after connect attempt, then can't proceed */ 427 if (((p_lcb = l2cu_find_lcb_by_bd_addr (rem_bda, BT_TRANSPORT_BR_EDR)) == NULL) 428 || ((p_ccb = l2cu_find_ccb_by_cid (p_lcb, L2CAP_CONNECTIONLESS_CID)) == NULL)) 429 { 430 osi_free(p_buf); 431 return (L2CAP_DW_FAILED); 432 } 433 } 434 435 /* write PSM */ 436 p_buf->offset -= L2CAP_UCD_OVERHEAD; 437 p_buf->len += L2CAP_UCD_OVERHEAD; 438 p = (UINT8 *)(p_buf + 1) + p_buf->offset; 439 440 UINT16_TO_STREAM (p, psm); 441 442 /* UCD MTU check */ 443 if ((p_lcb->ucd_mtu) && (p_buf->len > p_lcb->ucd_mtu)) 444 { 445 L2CAP_TRACE_WARNING ("L2CAP - Handle: 0x%04x UCD bigger than peer's UCD mtu size cannot be sent", p_lcb->handle); 446 osi_free(p_buf); 447 return (L2CAP_DW_FAILED); 448 } 449 450 /* If already congested, do not accept any more packets */ 451 if (p_ccb->cong_sent) 452 { 453 L2CAP_TRACE_ERROR ("L2CAP - Handle: 0x%04x UCD cannot be sent, already congested count: %u buff_quota: %u", 454 p_lcb->handle, 455 (fixed_queue_length(p_ccb->xmit_hold_q) + 456 fixed_queue_length(p_lcb->ucd_out_sec_pending_q)), 457 p_ccb->buff_quota); 458 459 osi_free(p_buf); 460 return (L2CAP_DW_FAILED); 461 } 462 463 /* channel based, packet based flushable or non-flushable */ 464 p_buf->layer_specific = flags; 465 466 l2c_csm_execute (p_ccb, L2CEVT_L2CA_DATA_WRITE, p_buf); 467 468 if (p_ccb->cong_sent) 469 return (L2CAP_DW_CONGESTED); 470 else 471 return (L2CAP_DW_SUCCESS); 472 } 473 474 /******************************************************************************* 475 ** 476 ** Function L2CA_UcdSetIdleTimeout 477 ** 478 ** Description Set UCD Idle timeout. 479 ** 480 ** Parameters: BD Addr 481 ** Timeout in second 482 ** 483 ** Return value: TRUE if successs 484 ** 485 *******************************************************************************/ 486 BOOLEAN L2CA_UcdSetIdleTimeout ( BD_ADDR rem_bda, UINT16 timeout ) 487 { 488 tL2C_LCB *p_lcb; 489 tL2C_CCB *p_ccb; 490 491 L2CAP_TRACE_API ("L2CA_UcdSetIdleTimeout() Timeout: 0x%04x BDA: %08x%04x", timeout, 492 (rem_bda[0]<<24)+(rem_bda[1]<<16)+(rem_bda[2]<<8)+rem_bda[3], 493 (rem_bda[4]<<8)+rem_bda[5]); 494 495 /* First, see if we already have a link to the remote */ 496 /* then find the channel control block. */ 497 if (((p_lcb = l2cu_find_lcb_by_bd_addr (rem_bda, BT_TRANSPORT_BR_EDR)) == NULL) 498 ||((p_ccb = l2cu_find_ccb_by_cid (p_lcb, L2CAP_CONNECTIONLESS_CID)) == NULL)) 499 { 500 L2CAP_TRACE_WARNING ("L2CAP - no UCD channel"); 501 return (FALSE); 502 } 503 else 504 { 505 p_ccb->fixed_chnl_idle_tout = timeout; 506 return (TRUE); 507 } 508 } 509 510 /******************************************************************************* 511 ** 512 ** Function L2CA_UCDSetTxPriority 513 ** 514 ** Description Sets the transmission priority for a connectionless channel. 515 ** 516 ** Returns TRUE if a valid channel, else FALSE 517 ** 518 *******************************************************************************/ 519 BOOLEAN L2CA_UCDSetTxPriority ( BD_ADDR rem_bda, tL2CAP_CHNL_PRIORITY priority ) 520 { 521 tL2C_LCB *p_lcb; 522 tL2C_CCB *p_ccb; 523 524 L2CAP_TRACE_API ("L2CA_UCDSetTxPriority() priority: 0x%02x BDA: %08x%04x", priority, 525 (rem_bda[0]<<24)+(rem_bda[1]<<16)+(rem_bda[2]<<8)+rem_bda[3], 526 (rem_bda[4]<<8)+rem_bda[5]); 527 528 if ((p_lcb = l2cu_find_lcb_by_bd_addr (rem_bda, BT_TRANSPORT_BR_EDR)) == NULL) 529 { 530 L2CAP_TRACE_WARNING ("L2CAP - no LCB for L2CA_UCDSetTxPriority"); 531 return (FALSE); 532 } 533 534 /* Find the channel control block */ 535 if ((p_ccb = l2cu_find_ccb_by_cid (p_lcb, L2CAP_CONNECTIONLESS_CID)) == NULL) 536 { 537 L2CAP_TRACE_WARNING ("L2CAP - no CCB for L2CA_UCDSetTxPriority"); 538 return (FALSE); 539 } 540 541 /* it will update the order of CCB in LCB by priority and update round robin service variables */ 542 l2cu_change_pri_ccb (p_ccb, priority); 543 544 return (TRUE); 545 } 546 547 /******************************************************************************* 548 ** 549 ** Function l2c_ucd_connect 550 ** 551 ** Description Connect UCD to remote device. 552 ** 553 ** Parameters: BD_ADDR of remote device 554 ** 555 ** Return value: TRUE if successs 556 ** 557 *******************************************************************************/ 558 static BOOLEAN l2c_ucd_connect ( BD_ADDR rem_bda ) 559 { 560 tL2C_LCB *p_lcb; 561 tL2C_CCB *p_ccb; 562 tL2C_RCB *p_rcb; 563 564 L2CAP_TRACE_DEBUG ("l2c_ucd_connect() BDA: %08x%04x", 565 (rem_bda[0]<<24)+(rem_bda[1]<<16)+(rem_bda[2]<<8)+rem_bda[3], 566 (rem_bda[4]<<8)+rem_bda[5]); 567 568 /* Fail if we have not established communications with the controller */ 569 if (!BTM_IsDeviceUp()) 570 { 571 L2CAP_TRACE_WARNING ("l2c_ucd_connect - BTU not ready"); 572 return (FALSE); 573 } 574 575 /* First, see if we already have a link to the remote */ 576 if ((p_lcb = l2cu_find_lcb_by_bd_addr (rem_bda, BT_TRANSPORT_BR_EDR)) == NULL) 577 { 578 /* No link. Get an LCB and start link establishment */ 579 if ( ((p_lcb = l2cu_allocate_lcb (rem_bda, FALSE, BT_TRANSPORT_BR_EDR)) == NULL) 580 || (l2cu_create_conn(p_lcb, BT_TRANSPORT_BR_EDR) == FALSE) ) 581 { 582 L2CAP_TRACE_WARNING ("L2CAP - conn not started l2c_ucd_connect"); 583 return (FALSE); 584 } 585 } 586 else if ( p_lcb->info_rx_bits & (1 << L2CAP_EXTENDED_FEATURES_INFO_TYPE) ) 587 { 588 if (!(p_lcb->peer_ext_fea & L2CAP_EXTFEA_UCD_RECEPTION)) 589 { 590 L2CAP_TRACE_WARNING ("L2CAP - UCD is not supported by peer, l2c_ucd_connect"); 591 return (FALSE); 592 } 593 } 594 595 /* Find the channel control block. */ 596 if ((p_ccb = l2cu_find_ccb_by_cid (p_lcb, L2CAP_CONNECTIONLESS_CID)) == NULL) 597 { 598 /* Allocate a channel control block */ 599 if ((p_ccb = l2cu_allocate_ccb (p_lcb, 0)) == NULL) 600 { 601 L2CAP_TRACE_WARNING ("L2CAP - no CCB for l2c_ucd_connect"); 602 return (FALSE); 603 } 604 else 605 { 606 /* Set CID for the connection */ 607 p_ccb->local_cid = L2CAP_CONNECTIONLESS_CID; 608 p_ccb->remote_cid = L2CAP_CONNECTIONLESS_CID; 609 610 /* Set the default idle timeout value to use */ 611 p_ccb->fixed_chnl_idle_tout = L2CAP_UCD_IDLE_TIMEOUT; 612 613 /* Set the default channel priority value to use */ 614 l2cu_change_pri_ccb (p_ccb, L2CAP_UCD_CH_PRIORITY); 615 616 if ((p_rcb = l2cu_find_rcb_by_psm (L2C_UCD_RCB_ID)) == NULL) 617 { 618 L2CAP_TRACE_WARNING ("L2CAP - no UCD registered, l2c_ucd_connect"); 619 return (FALSE); 620 } 621 /* Save UCD registration info */ 622 p_ccb->p_rcb = p_rcb; 623 624 /* There is no configuration, so if the link is up, the channel is up */ 625 if (p_lcb->link_state == LST_CONNECTED) 626 { 627 p_ccb->chnl_state = CST_OPEN; 628 } 629 } 630 } 631 632 return (TRUE); 633 } 634 635 /******************************************************************************* 636 ** 637 ** Function l2c_ucd_delete_sec_pending_q 638 ** 639 ** Description discard all of UCD packets in security pending queue 640 ** 641 ** Returns None 642 ** 643 *******************************************************************************/ 644 void l2c_ucd_delete_sec_pending_q(tL2C_LCB *p_lcb) 645 { 646 /* clean up any security pending UCD */ 647 while (! fixed_queue_is_empty(p_lcb->ucd_out_sec_pending_q)) 648 osi_free(fixed_queue_try_dequeue(p_lcb->ucd_out_sec_pending_q)); 649 fixed_queue_free(p_lcb->ucd_out_sec_pending_q, NULL); 650 p_lcb->ucd_out_sec_pending_q = NULL; 651 652 while (! fixed_queue_is_empty(p_lcb->ucd_in_sec_pending_q)) 653 osi_free(fixed_queue_try_dequeue(p_lcb->ucd_in_sec_pending_q)); 654 fixed_queue_free(p_lcb->ucd_in_sec_pending_q); 655 p_lcb->ucd_in_sec_pending_q = NULL; 656 } 657 658 /******************************************************************************* 659 ** 660 ** Function l2c_ucd_check_pending_info_req 661 ** 662 ** Description check if any application is waiting for UCD information 663 ** 664 ** Return TRUE if any pending UCD info request 665 ** 666 *******************************************************************************/ 667 BOOLEAN l2c_ucd_check_pending_info_req(tL2C_CCB *p_ccb) 668 { 669 tL2C_RCB *p_rcb = &l2cb.rcb_pool[0]; 670 UINT16 xx; 671 BOOLEAN pending = FALSE; 672 673 if (p_ccb == NULL) 674 { 675 L2CAP_TRACE_ERROR ("L2CAP - NULL p_ccb in l2c_ucd_check_pending_info_req"); 676 return (FALSE); 677 } 678 679 for (xx = 0; xx < MAX_L2CAP_CLIENTS; xx++, p_rcb++) 680 { 681 if (p_rcb->in_use) 682 { 683 /* if application is waiting UCD reception info */ 684 if (p_rcb->ucd.state & L2C_UCD_STATE_W4_RECEPTION) 685 { 686 /* if this information is available */ 687 if ( p_ccb->p_lcb->info_rx_bits & (1 << L2CAP_EXTENDED_FEATURES_INFO_TYPE) ) 688 { 689 if (!(p_ccb->p_lcb->peer_ext_fea & L2CAP_EXTFEA_UCD_RECEPTION)) 690 { 691 L2CAP_TRACE_WARNING ("L2CAP - UCD is not supported by peer, l2c_ucd_check_pending_info_req"); 692 693 l2c_ucd_delete_sec_pending_q(p_ccb->p_lcb); 694 l2cu_release_ccb (p_ccb); 695 } 696 697 p_ccb->p_rcb->ucd.cb_info.pL2CA_UCD_Discover_Cb (p_ccb->p_lcb->remote_bd_addr, 698 L2CAP_UCD_INFO_TYPE_RECEPTION, 699 p_ccb->p_lcb->peer_ext_fea & L2CAP_EXTFEA_UCD_RECEPTION); 700 } 701 else 702 { 703 pending = TRUE; 704 if (p_ccb->p_lcb->w4_info_rsp == FALSE) 705 { 706 l2cu_send_peer_info_req (p_ccb->p_lcb, L2CAP_EXTENDED_FEATURES_INFO_TYPE); 707 } 708 } 709 } 710 711 /* if application is waiting for UCD MTU */ 712 if (p_rcb->ucd.state & L2C_UCD_STATE_W4_MTU) 713 { 714 /* if this information is available */ 715 if ( p_ccb->p_lcb->info_rx_bits & (1 << L2CAP_CONNLESS_MTU_INFO_TYPE)) 716 { 717 p_ccb->p_rcb->ucd.cb_info.pL2CA_UCD_Discover_Cb (p_ccb->p_lcb->remote_bd_addr, 718 L2CAP_UCD_INFO_TYPE_MTU, 719 p_ccb->p_lcb->ucd_mtu); 720 } 721 else 722 { 723 pending = TRUE; 724 if (p_ccb->p_lcb->w4_info_rsp == FALSE) 725 { 726 l2cu_send_peer_info_req (p_ccb->p_lcb, L2CAP_CONNLESS_MTU_INFO_TYPE); 727 } 728 } 729 } 730 } 731 } 732 return (pending); 733 } 734 735 /******************************************************************************* 736 ** 737 ** Function l2c_ucd_enqueue_pending_out_sec_q 738 ** 739 ** Description enqueue outgoing UCD packet into security pending queue 740 ** and check congestion 741 ** 742 ** Return None 743 ** 744 *******************************************************************************/ 745 void l2c_ucd_enqueue_pending_out_sec_q(tL2C_CCB *p_ccb, void *p_data) 746 { 747 fixed_queue_enqueue(p_ccb->p_lcb->ucd_out_sec_pending_q, p_data); 748 l2cu_check_channel_congestion (p_ccb); 749 } 750 751 /******************************************************************************* 752 ** 753 ** Function l2c_ucd_check_pending_out_sec_q 754 ** 755 ** Description check outgoing security 756 ** 757 ** Return TRUE if any UCD packet for security 758 ** 759 *******************************************************************************/ 760 BOOLEAN l2c_ucd_check_pending_out_sec_q(tL2C_CCB *p_ccb) 761 { 762 BT_HDR *p_buf = (BT_HDR*)fixed_queue_try_peek_first(p_ccb->p_lcb->ucd_out_sec_pending_q); 763 764 if (p_buf != NULL) 765 { 766 UINT16 psm; 767 UINT8 *p = (UINT8 *)(p_buf + 1) + p_buf->offset; 768 769 STREAM_TO_UINT16(psm, p) 770 771 p_ccb->chnl_state = CST_ORIG_W4_SEC_COMP; 772 btm_sec_l2cap_access_req (p_ccb->p_lcb->remote_bd_addr, psm, 773 p_ccb->p_lcb->handle, CONNLESS_ORIG, &l2c_link_sec_comp, p_ccb); 774 775 return (TRUE); 776 } 777 return (FALSE); 778 } 779 780 /******************************************************************************* 781 ** 782 ** Function l2c_ucd_send_pending_out_sec_q 783 ** 784 ** Description dequeue UCD packet from security pending queue and 785 ** enqueue it into CCB 786 ** 787 ** Return None 788 ** 789 *******************************************************************************/ 790 void l2c_ucd_send_pending_out_sec_q(tL2C_CCB *p_ccb) 791 { 792 BT_HDR *p_buf = (BT_HDR*)fixed_queue_try_dequeue(p_ccb->p_lcb->ucd_out_sec_pending_q); 793 794 if (p_buf != NULL) 795 { 796 l2c_enqueue_peer_data (p_ccb, (BT_HDR *)p_buf); 797 l2c_link_check_send_pkts (p_ccb->p_lcb, NULL, NULL); 798 } 799 } 800 801 /******************************************************************************* 802 ** 803 ** Function l2c_ucd_discard_pending_out_sec_q 804 ** 805 ** Description dequeue UCD packet from security pending queue and 806 ** discard it. 807 ** 808 ** Return None 809 ** 810 *******************************************************************************/ 811 void l2c_ucd_discard_pending_out_sec_q(tL2C_CCB *p_ccb) 812 { 813 BT_HDR *p_buf = (BT_HDR*)fixed_queue_try_dequeue(p_ccb->p_lcb->ucd_out_sec_pending_q); 814 815 /* we may need to report to application */ 816 osi_free(p_buf); 817 } 818 819 /******************************************************************************* 820 ** 821 ** Function l2c_ucd_check_pending_in_sec_q 822 ** 823 ** Description check incoming security 824 ** 825 ** Return TRUE if any UCD packet for security 826 ** 827 *******************************************************************************/ 828 BOOLEAN l2c_ucd_check_pending_in_sec_q(tL2C_CCB *p_ccb) 829 { 830 BT_HDR *p_buf = (BT_HDR*)fixed_queue_try_dequeue(p_ccb->p_lcb->ucd_in_sec_pending_q); 831 832 if (p_buf != NULL) 833 { 834 UINT16 psm; 835 UINT8 *p = (UINT8 *)(p_buf + 1) + p_buf->offset; 836 STREAM_TO_UINT16(psm, p) 837 838 p_ccb->chnl_state = CST_TERM_W4_SEC_COMP; 839 btm_sec_l2cap_access_req (p_ccb->p_lcb->remote_bd_addr, psm, 840 p_ccb->p_lcb->handle, CONNLESS_TERM, &l2c_link_sec_comp, p_ccb); 841 842 return (TRUE); 843 } 844 return (FALSE); 845 } 846 847 /******************************************************************************* 848 ** 849 ** Function l2c_ucd_send_pending_in_sec_q 850 ** 851 ** Description dequeue UCD packet from security pending queue and 852 ** send it to application 853 ** 854 ** Return None 855 ** 856 *******************************************************************************/ 857 void l2c_ucd_send_pending_in_sec_q(tL2C_CCB *p_ccb) 858 { 859 BT_HDR *p_buf = (BT_HDR*)fixed_queue_try_dequeue(p_ccb->p_lcb->ucd_in_sec_pending_q) 860 861 if (p_buf != NULL) 862 { 863 p_ccb->p_rcb->ucd.cb_info.pL2CA_UCD_Data_Cb(p_ccb->p_lcb->remote_bd_addr, (BT_HDR *)p_buf); 864 } 865 } 866 867 /******************************************************************************* 868 ** 869 ** Function l2c_ucd_discard_pending_in_sec_q 870 ** 871 ** Description dequeue UCD packet from security pending queue and 872 ** discard it. 873 ** 874 ** Return None 875 ** 876 *******************************************************************************/ 877 void l2c_ucd_discard_pending_in_sec_q(tL2C_CCB *p_ccb) 878 { 879 BT_HDR *p_buf = (BT_HDR*)fixed_queue_try_dequeue(p_ccb->p_lcb->ucd_in_sec_pending_q); 880 osi_free(p_buf); 881 } 882 883 /******************************************************************************* 884 ** 885 ** Function l2c_ucd_check_rx_pkts 886 ** 887 ** Description Check if UCD reception is registered. 888 ** Process received UCD packet if application is expecting. 889 ** 890 ** Return TRUE if UCD reception is registered 891 ** 892 *******************************************************************************/ 893 BOOLEAN l2c_ucd_check_rx_pkts(tL2C_LCB *p_lcb, BT_HDR *p_msg) 894 { 895 tL2C_CCB *p_ccb; 896 tL2C_RCB *p_rcb; 897 898 if (((p_ccb = l2cu_find_ccb_by_cid (p_lcb, L2CAP_CONNECTIONLESS_CID)) != NULL) 899 ||((p_rcb = l2cu_find_rcb_by_psm (L2C_UCD_RCB_ID)) != NULL)) 900 { 901 if (p_ccb == NULL) 902 { 903 /* Allocate a channel control block */ 904 if ((p_ccb = l2cu_allocate_ccb (p_lcb, 0)) == NULL) 905 { 906 L2CAP_TRACE_WARNING ("L2CAP - no CCB for UCD reception"); 907 osi_free(p_msg); 908 return TRUE; 909 } 910 else 911 { 912 /* Set CID for the connection */ 913 p_ccb->local_cid = L2CAP_CONNECTIONLESS_CID; 914 p_ccb->remote_cid = L2CAP_CONNECTIONLESS_CID; 915 916 /* Set the default idle timeout value to use */ 917 p_ccb->fixed_chnl_idle_tout = L2CAP_UCD_IDLE_TIMEOUT; 918 919 /* Set the default channel priority value to use */ 920 l2cu_change_pri_ccb (p_ccb, L2CAP_UCD_CH_PRIORITY); 921 922 /* Save registration info */ 923 p_ccb->p_rcb = p_rcb; 924 925 p_ccb->chnl_state = CST_OPEN; 926 } 927 } 928 l2c_csm_execute(p_ccb, L2CEVT_L2CAP_DATA, p_msg); 929 return TRUE; 930 } 931 else 932 return FALSE; 933 } 934 935 /******************************************************************************* 936 ** 937 ** Function l2c_ucd_process_event 938 ** 939 ** Description This is called from main state machine when LCID is connectionless 940 ** Process the event if it is for UCD. 941 ** 942 ** Return TRUE if the event is consumed by UCD 943 ** FALSE if the event needs to be processed by main state machine 944 ** 945 *******************************************************************************/ 946 BOOLEAN l2c_ucd_process_event(tL2C_CCB *p_ccb, UINT16 event, void *p_data) 947 { 948 /* if the event is not processed by this function, this variable will be set to FALSE */ 949 BOOLEAN done = TRUE; 950 951 switch (p_ccb->chnl_state) 952 { 953 case CST_CLOSED: 954 switch (event) 955 { 956 case L2CEVT_LP_CONNECT_CFM: /* Link came up */ 957 /* check if waiting for UCD info */ 958 if (!l2c_ucd_check_pending_info_req (p_ccb)) 959 { 960 /* check if any outgoing UCD packet is waiting security check */ 961 if (!l2c_ucd_check_pending_out_sec_q(p_ccb)) 962 { 963 p_ccb->chnl_state = CST_OPEN; 964 } 965 } 966 break; 967 968 case L2CEVT_L2CAP_DATA: /* Peer data packet rcvd */ 969 fixed_queue_enqueue(p_ccb->p_lcb->ucd_in_sec_pending_q, p_data); 970 break; 971 972 case L2CEVT_L2CA_DATA_WRITE: /* Upper layer data to send */ 973 l2c_ucd_enqueue_pending_out_sec_q(p_ccb, p_data); 974 break; 975 976 case L2CEVT_L2CAP_INFO_RSP: 977 /* check if waiting for UCD info */ 978 if (!l2c_ucd_check_pending_info_req (p_ccb)) 979 { 980 /* check if any outgoing UCD packet is waiting security check */ 981 if (!l2c_ucd_check_pending_out_sec_q(p_ccb)) 982 { 983 p_ccb->chnl_state = CST_OPEN; 984 } 985 } 986 break; 987 988 default: 989 done = FALSE; /* main state machine continues to process event */ 990 break; 991 } 992 break; 993 994 case CST_ORIG_W4_SEC_COMP: 995 switch (event) 996 { 997 case L2CEVT_SEC_RE_SEND_CMD: /* BTM has enough info to proceed */ 998 /* check if any outgoing UCD packet is waiting security check */ 999 if (!l2c_ucd_check_pending_out_sec_q(p_ccb)) 1000 { 1001 p_ccb->chnl_state = CST_OPEN; 1002 } 1003 break; 1004 1005 case L2CEVT_SEC_COMP: /* Security completed success */ 1006 p_ccb->chnl_state = CST_OPEN; 1007 l2c_ucd_send_pending_out_sec_q(p_ccb); 1008 1009 if (! fixed_queue_is_empty(p_ccb->p_lcb->ucd_out_sec_pending_q)) 1010 { 1011 /* start a timer to send next UCD packet in OPEN state */ 1012 /* it will prevent stack overflow */ 1013 alarm_set_on_queue(p_ccb->l2c_ccb_timer, 0, 1014 l2c_ccb_timer_timeout, p_ccb, 1015 btu_general_alarm_queue); 1016 } 1017 else 1018 { 1019 /* start a timer for idle timeout of UCD */ 1020 period_ms_t timeout_ms = p_ccb->fixed_chnl_idle_tout * 1000; 1021 alarm_set_on_queue(p_ccb->l2c_ccb_timer, timeout_ms, 1022 l2c_ccb_timer_timeout, p_ccb, 1023 btu_general_alarm_queue); 1024 } 1025 break; 1026 1027 case L2CEVT_SEC_COMP_NEG: 1028 p_ccb->chnl_state = CST_OPEN; 1029 l2c_ucd_discard_pending_out_sec_q(p_ccb); 1030 1031 /* start a timer for idle timeout of UCD */ 1032 period_ms_t timeout_ms = p_ccb->fixed_chnl_idle_tout * 1000; 1033 alarm_set_on_queue(p_ccb->l2c_ccb_timer, timeout_ms, 1034 l2c_ccb_timer_timeout, p_ccb, 1035 btu_general_alarm_queue); 1036 break; 1037 1038 case L2CEVT_L2CA_DATA_WRITE: /* Upper layer data to send */ 1039 l2c_ucd_enqueue_pending_out_sec_q(p_ccb, p_data); 1040 break; 1041 1042 case L2CEVT_L2CAP_DATA: /* Peer data packet rcvd */ 1043 fixed_queue_enqueue(p_ccb->p_lcb->ucd_in_sec_pending_q, p_data); 1044 break; 1045 1046 case L2CEVT_L2CAP_INFO_RSP: 1047 /* check if waiting for UCD info */ 1048 l2c_ucd_check_pending_info_req (p_ccb); 1049 break; 1050 1051 default: 1052 done = FALSE; /* main state machine continues to process event */ 1053 break; 1054 } 1055 break; 1056 1057 1058 case CST_TERM_W4_SEC_COMP: 1059 switch (event) 1060 { 1061 case L2CEVT_SEC_COMP: 1062 p_ccb->chnl_state = CST_OPEN; 1063 l2c_ucd_send_pending_in_sec_q (p_ccb); 1064 1065 if (! fixed_queue_is_empty(p_ccb->p_lcb->ucd_in_sec_pending_q)) 1066 { 1067 /* start a timer to check next UCD packet in OPEN state */ 1068 /* it will prevent stack overflow */ 1069 alarm_set_on_queue(p_ccb->l2c_ccb_timer, 0, 1070 l2c_ccb_timer_timeout, p_ccb, 1071 btu_general_alarm_queue); 1072 } 1073 else 1074 { 1075 /* start a timer for idle timeout of UCD */ 1076 period_ms_t timeout_ms = p_ccb->fixed_chnl_idle_tout * 1000; 1077 alarm_set_on_queue(p_ccb->l2c_ccb_timer, timeout_ms, 1078 l2c_ccb_timer_timeout, p_ccb, 1079 btu_general_alarm_queue); 1080 } 1081 break; 1082 1083 case L2CEVT_SEC_COMP_NEG: 1084 if (((tL2C_CONN_INFO *)p_data)->status == BTM_DELAY_CHECK) 1085 { 1086 done = FALSE; 1087 break; 1088 } 1089 p_ccb->chnl_state = CST_OPEN; 1090 l2c_ucd_discard_pending_in_sec_q (p_ccb); 1091 1092 /* start a timer for idle timeout of UCD */ 1093 period_ms_t timeout_ms = p_ccb->fixed_chnl_idle_tout * 1000; 1094 alarm_set_on_queue(p_ccb->l2c_ccb_timer, timeout_ms, 1095 l2c_ccb_timer_timeout, p_ccb, 1096 btu_general_alarm_queue); 1097 break; 1098 1099 case L2CEVT_L2CA_DATA_WRITE: /* Upper layer data to send */ 1100 l2c_ucd_enqueue_pending_out_sec_q(p_ccb, p_data); 1101 break; 1102 1103 case L2CEVT_L2CAP_DATA: /* Peer data packet rcvd */ 1104 fixed_queue_enqueue(p_ccb->p_lcb->ucd_in_sec_pending_q, p_data); 1105 break; 1106 1107 case L2CEVT_SEC_RE_SEND_CMD: /* BTM has enough info to proceed */ 1108 /* check if any incoming UCD packet is waiting security check */ 1109 if (!l2c_ucd_check_pending_in_sec_q(p_ccb)) 1110 { 1111 p_ccb->chnl_state = CST_OPEN; 1112 } 1113 break; 1114 1115 case L2CEVT_L2CAP_INFO_RSP: 1116 /* check if waiting for UCD info */ 1117 l2c_ucd_check_pending_info_req (p_ccb); 1118 break; 1119 1120 default: 1121 done = FALSE; /* main state machine continues to process event */ 1122 break; 1123 } 1124 break; 1125 1126 case CST_OPEN: 1127 switch (event) 1128 { 1129 case L2CEVT_L2CAP_DATA: /* Peer data packet rcvd */ 1130 /* stop idle timer of UCD */ 1131 alarm_cancel(p_ccb->l2c_ccb_timer); 1132 1133 fixed_queue_enqueue(p_ccb->p_lcb->ucd_in_sec_pending_q, p_data); 1134 l2c_ucd_check_pending_in_sec_q (p_ccb); 1135 break; 1136 1137 case L2CEVT_L2CA_DATA_WRITE: /* Upper layer data to send */ 1138 /* stop idle timer of UCD */ 1139 alarm_cancel(p_ccb->l2c_ccb_timer); 1140 1141 l2c_ucd_enqueue_pending_out_sec_q(p_ccb, p_data); 1142 1143 /* coverity[check_return] */ /* coverity[unchecked_value] */ 1144 /* success changes state, failure stays in current state */ 1145 l2c_ucd_check_pending_out_sec_q (p_ccb); 1146 break; 1147 1148 case L2CEVT_TIMEOUT: 1149 /* check if any UCD packet is waiting security check */ 1150 if ((!l2c_ucd_check_pending_in_sec_q(p_ccb)) 1151 &&(!l2c_ucd_check_pending_out_sec_q(p_ccb))) 1152 { 1153 l2cu_release_ccb (p_ccb); 1154 } 1155 break; 1156 1157 case L2CEVT_L2CAP_INFO_RSP: 1158 /* check if waiting for UCD info */ 1159 l2c_ucd_check_pending_info_req (p_ccb); 1160 break; 1161 1162 default: 1163 done = FALSE; /* main state machine continues to process event */ 1164 break; 1165 } 1166 break; 1167 1168 default: 1169 done = FALSE; /* main state machine continues to process event */ 1170 break; 1171 } 1172 1173 return done; 1174 } 1175 #endif /* (L2CAP_UCD_INCLUDED == TRUE) */ 1176