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