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