1 /****************************************************************************** 2 * 3 * Copyright 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 L2CAP utility functions 22 * 23 ******************************************************************************/ 24 #define LOG_TAG "l2c_utils" 25 26 #include <stdio.h> 27 #include <string.h> 28 29 #include "bt_common.h" 30 #include "bt_types.h" 31 #include "btm_api.h" 32 #include "device/include/controller.h" 33 #include "hci/include/btsnoop.h" 34 #include "hcidefs.h" 35 #include "l2c_int.h" 36 #include "l2cdefs.h" 37 #include "main/shim/l2c_api.h" 38 #include "main/shim/shim.h" 39 #include "osi/include/allocator.h" 40 #include "osi/include/log.h" 41 #include "stack/btm/btm_sec.h" 42 #include "stack/include/acl_api.h" 43 #include "stack/include/hci_error_code.h" 44 45 tL2C_CCB* l2cu_get_next_channel_in_rr(tL2C_LCB* p_lcb); // TODO Move 46 47 /******************************************************************************* 48 * 49 * Function l2cu_allocate_lcb 50 * 51 * Description Look for an unused LCB 52 * 53 * Returns LCB address or NULL if none found 54 * 55 ******************************************************************************/ 56 tL2C_LCB* l2cu_allocate_lcb(const RawAddress& p_bd_addr, bool is_bonding, 57 tBT_TRANSPORT transport) { 58 int xx; 59 tL2C_LCB* p_lcb = &l2cb.lcb_pool[0]; 60 61 for (xx = 0; xx < MAX_L2CAP_LINKS; xx++, p_lcb++) { 62 if (!p_lcb->in_use) { 63 alarm_free(p_lcb->l2c_lcb_timer); 64 alarm_free(p_lcb->info_resp_timer); 65 memset(p_lcb, 0, sizeof(tL2C_LCB)); 66 67 p_lcb->remote_bd_addr = p_bd_addr; 68 69 p_lcb->in_use = true; 70 p_lcb->link_state = LST_DISCONNECTED; 71 p_lcb->InvalidateHandle(); 72 p_lcb->l2c_lcb_timer = alarm_new("l2c_lcb.l2c_lcb_timer"); 73 p_lcb->info_resp_timer = alarm_new("l2c_lcb.info_resp_timer"); 74 p_lcb->idle_timeout = l2cb.idle_timeout; 75 p_lcb->signal_id = 1; /* spec does not allow '0' */ 76 if (is_bonding) { 77 p_lcb->SetBonding(); 78 } else { 79 p_lcb->ResetBonding(); 80 } 81 p_lcb->transport = transport; 82 p_lcb->tx_data_len = 83 controller_get_interface()->get_ble_default_data_packet_length(); 84 p_lcb->le_sec_pending_q = fixed_queue_new(SIZE_MAX); 85 86 if (transport == BT_TRANSPORT_LE) { 87 l2cb.num_ble_links_active++; 88 l2c_ble_link_adjust_allocation(); 89 } else { 90 l2cb.num_used_lcbs++; 91 l2c_link_adjust_allocation(); 92 } 93 p_lcb->link_xmit_data_q = list_new(NULL); 94 return (p_lcb); 95 } 96 } 97 98 /* If here, no free LCB found */ 99 return (NULL); 100 } 101 102 void l2cu_set_lcb_handle(struct t_l2c_linkcb& p_lcb, uint16_t handle) { 103 if (p_lcb.Handle() != HCI_INVALID_HANDLE) { 104 LOG_WARN("Should not replace active handle:%hu with new handle:%hu", 105 p_lcb.Handle(), handle); 106 } 107 p_lcb.SetHandle(handle); 108 } 109 110 /******************************************************************************* 111 * 112 * Function l2cu_update_lcb_4_bonding 113 * 114 * Description Mark the lcb for bonding. Used when bonding takes place on 115 * an existing ACL connection. (Pre-Lisbon devices) 116 * 117 * Returns Nothing 118 * 119 ******************************************************************************/ 120 void l2cu_update_lcb_4_bonding(const RawAddress& p_bd_addr, bool is_bonding) { 121 if (bluetooth::shim::is_gd_l2cap_enabled()) { 122 bluetooth::shim::L2CA_SetBondingState(p_bd_addr, is_bonding); 123 return; 124 } 125 126 tL2C_LCB* p_lcb = l2cu_find_lcb_by_bd_addr(p_bd_addr, BT_TRANSPORT_BR_EDR); 127 128 if (p_lcb) { 129 VLOG(1) << __func__ << " BDA: " << p_bd_addr 130 << " is_bonding: " << is_bonding; 131 if (is_bonding) { 132 p_lcb->SetBonding(); 133 } else { 134 p_lcb->ResetBonding(); 135 } 136 } 137 } 138 139 /******************************************************************************* 140 * 141 * Function l2cu_release_lcb 142 * 143 * Description Release an LCB. All timers will be stopped and freed, 144 * channels dropped, buffers returned etc. 145 * 146 * Returns void 147 * 148 ******************************************************************************/ 149 void l2cu_release_lcb(tL2C_LCB* p_lcb) { 150 tL2C_CCB* p_ccb; 151 152 p_lcb->in_use = false; 153 p_lcb->ResetBonding(); 154 155 /* Stop and free timers */ 156 alarm_free(p_lcb->l2c_lcb_timer); 157 p_lcb->l2c_lcb_timer = NULL; 158 alarm_free(p_lcb->info_resp_timer); 159 p_lcb->info_resp_timer = NULL; 160 161 if (p_lcb->transport == BT_TRANSPORT_BR_EDR) /* Release all SCO links */ 162 BTM_RemoveSco(p_lcb->remote_bd_addr); 163 164 if (p_lcb->sent_not_acked > 0) { 165 if (p_lcb->transport == BT_TRANSPORT_LE) { 166 l2cb.controller_le_xmit_window += p_lcb->sent_not_acked; 167 if (l2cb.controller_le_xmit_window > l2cb.num_lm_ble_bufs) { 168 l2cb.controller_le_xmit_window = l2cb.num_lm_ble_bufs; 169 } 170 } else { 171 l2cb.controller_xmit_window += p_lcb->sent_not_acked; 172 if (l2cb.controller_xmit_window > l2cb.num_lm_acl_bufs) { 173 l2cb.controller_xmit_window = l2cb.num_lm_acl_bufs; 174 } 175 } 176 } 177 178 l2cu_process_fixed_disc_cback(p_lcb); 179 180 /* Ensure no CCBs left on this LCB */ 181 for (p_ccb = p_lcb->ccb_queue.p_first_ccb; p_ccb; 182 p_ccb = p_lcb->ccb_queue.p_first_ccb) { 183 l2cu_release_ccb(p_ccb); 184 } 185 186 /* Tell BTM Acl management the link was removed */ 187 if ((p_lcb->link_state == LST_CONNECTED) || 188 (p_lcb->link_state == LST_DISCONNECTING)) 189 btm_acl_removed(p_lcb->Handle()); 190 191 /* Release any held buffers */ 192 if (p_lcb->link_xmit_data_q) { 193 while (!list_is_empty(p_lcb->link_xmit_data_q)) { 194 BT_HDR* p_buf = static_cast<BT_HDR*>(list_front(p_lcb->link_xmit_data_q)); 195 list_remove(p_lcb->link_xmit_data_q, p_buf); 196 osi_free(p_buf); 197 } 198 list_free(p_lcb->link_xmit_data_q); 199 p_lcb->link_xmit_data_q = NULL; 200 } 201 202 /* Re-adjust flow control windows make sure it does not go negative */ 203 if (p_lcb->transport == BT_TRANSPORT_LE) { 204 if (l2cb.num_ble_links_active >= 1) l2cb.num_ble_links_active--; 205 206 l2c_ble_link_adjust_allocation(); 207 } else { 208 if (l2cb.num_used_lcbs >= 1) l2cb.num_used_lcbs--; 209 210 l2c_link_adjust_allocation(); 211 } 212 213 /* Check and release all the LE COC connections waiting for security */ 214 if (p_lcb->le_sec_pending_q) { 215 while (!fixed_queue_is_empty(p_lcb->le_sec_pending_q)) { 216 tL2CAP_SEC_DATA* p_buf = 217 (tL2CAP_SEC_DATA*)fixed_queue_try_dequeue(p_lcb->le_sec_pending_q); 218 if (p_buf->p_callback) 219 p_buf->p_callback(p_lcb->remote_bd_addr, p_lcb->transport, 220 p_buf->p_ref_data, BTM_DEV_RESET); 221 osi_free(p_buf); 222 } 223 fixed_queue_free(p_lcb->le_sec_pending_q, NULL); 224 p_lcb->le_sec_pending_q = NULL; 225 } 226 } 227 228 /******************************************************************************* 229 * 230 * Function l2cu_find_lcb_by_bd_addr 231 * 232 * Description Look through all active LCBs for a match based on the 233 * remote BD address. 234 * 235 * Returns pointer to matched LCB, or NULL if no match 236 * 237 ******************************************************************************/ 238 tL2C_LCB* l2cu_find_lcb_by_bd_addr(const RawAddress& p_bd_addr, 239 tBT_TRANSPORT transport) { 240 int xx; 241 tL2C_LCB* p_lcb = &l2cb.lcb_pool[0]; 242 243 for (xx = 0; xx < MAX_L2CAP_LINKS; xx++, p_lcb++) { 244 if ((p_lcb->in_use) && p_lcb->transport == transport && 245 (p_lcb->remote_bd_addr == p_bd_addr)) { 246 return (p_lcb); 247 } 248 } 249 250 /* If here, no match found */ 251 return (NULL); 252 } 253 254 /******************************************************************************* 255 * 256 * Function l2c_is_cmd_rejected 257 * 258 * Description Checks if cmd_code is command or response 259 * If a command it will be rejected per spec. 260 * This function is used when a illegal packet length is 261 * detected. 262 * 263 * Returns bool - true if cmd_code is a command and it is rejected, 264 * false if response code. (command not rejected) 265 * 266 ******************************************************************************/ 267 bool l2c_is_cmd_rejected(uint8_t cmd_code, uint8_t signal_id, tL2C_LCB* p_lcb) { 268 switch (cmd_code) { 269 case L2CAP_CMD_CONN_REQ: 270 case L2CAP_CMD_CONFIG_REQ: 271 case L2CAP_CMD_DISC_REQ: 272 case L2CAP_CMD_ECHO_REQ: 273 case L2CAP_CMD_INFO_REQ: 274 case L2CAP_CMD_AMP_CONN_REQ: 275 case L2CAP_CMD_AMP_MOVE_REQ: 276 case L2CAP_CMD_BLE_UPDATE_REQ: 277 l2cu_send_peer_cmd_reject(p_lcb, L2CAP_CMD_REJ_MTU_EXCEEDED, signal_id, 278 L2CAP_DEFAULT_MTU, 0); 279 L2CAP_TRACE_WARNING("Dumping first Command (%d)", cmd_code); 280 return true; 281 282 default: /* Otherwise a response */ 283 return false; 284 } 285 } 286 287 /******************************************************************************* 288 * 289 * Function l2cu_build_header 290 * 291 * Description Builds the L2CAP command packet header 292 * 293 * Returns Pointer to allocated packet or NULL if no resources 294 * 295 ******************************************************************************/ 296 BT_HDR* l2cu_build_header(tL2C_LCB* p_lcb, uint16_t len, uint8_t cmd, 297 uint8_t signal_id) { 298 BT_HDR* p_buf = (BT_HDR*)osi_malloc(L2CAP_CMD_BUF_SIZE); 299 uint8_t* p; 300 301 p_buf->offset = L2CAP_SEND_CMD_OFFSET; 302 p_buf->len = 303 len + HCI_DATA_PREAMBLE_SIZE + L2CAP_PKT_OVERHEAD + L2CAP_CMD_OVERHEAD; 304 p = (uint8_t*)(p_buf + 1) + L2CAP_SEND_CMD_OFFSET; 305 306 /* Put in HCI header - handle + pkt boundary */ 307 if (p_lcb->transport == BT_TRANSPORT_LE) { 308 UINT16_TO_STREAM(p, (p_lcb->Handle() | (L2CAP_PKT_START_NON_FLUSHABLE 309 << L2CAP_PKT_TYPE_SHIFT))); 310 } else { 311 UINT16_TO_STREAM(p, p_lcb->Handle() | l2cb.non_flushable_pbf); 312 } 313 314 UINT16_TO_STREAM(p, len + L2CAP_PKT_OVERHEAD + L2CAP_CMD_OVERHEAD); 315 UINT16_TO_STREAM(p, len + L2CAP_CMD_OVERHEAD); 316 317 if (p_lcb->transport == BT_TRANSPORT_LE) { 318 UINT16_TO_STREAM(p, L2CAP_BLE_SIGNALLING_CID); 319 } else { 320 UINT16_TO_STREAM(p, L2CAP_SIGNALLING_CID); 321 } 322 323 /* Put in L2CAP command header */ 324 UINT8_TO_STREAM(p, cmd); 325 UINT8_TO_STREAM(p, signal_id); 326 UINT16_TO_STREAM(p, len); 327 328 return (p_buf); 329 } 330 331 /******************************************************************************* 332 * 333 * Function l2cu_adj_id 334 * 335 * Description Checks for valid ID based on specified mask 336 * and adjusts the id if invalid. 337 * 338 * Returns void 339 * 340 ******************************************************************************/ 341 void l2cu_adj_id(tL2C_LCB* p_lcb) { 342 if (p_lcb->signal_id == 0) { 343 p_lcb->signal_id++; 344 } 345 } 346 347 /******************************************************************************* 348 * 349 * Function l2cu_send_peer_cmd_reject 350 * 351 * Description Build and send an L2CAP "command reject" message 352 * to the peer. 353 * 354 * Returns void 355 * 356 ******************************************************************************/ 357 void l2cu_send_peer_cmd_reject(tL2C_LCB* p_lcb, uint16_t reason, uint8_t rem_id, 358 uint16_t p1, uint16_t p2) { 359 uint16_t param_len; 360 BT_HDR* p_buf; 361 uint8_t* p; 362 363 /* Put in L2CAP packet header */ 364 if (reason == L2CAP_CMD_REJ_MTU_EXCEEDED) 365 param_len = 2; 366 else if (reason == L2CAP_CMD_REJ_INVALID_CID) 367 param_len = 4; 368 else 369 param_len = 0; 370 371 p_buf = l2cu_build_header(p_lcb, (uint16_t)(L2CAP_CMD_REJECT_LEN + param_len), 372 L2CAP_CMD_REJECT, rem_id); 373 if (p_buf == NULL) { 374 L2CAP_TRACE_WARNING("L2CAP - no buffer cmd_rej"); 375 return; 376 } 377 378 p = (uint8_t*)(p_buf + 1) + L2CAP_SEND_CMD_OFFSET + HCI_DATA_PREAMBLE_SIZE + 379 L2CAP_PKT_OVERHEAD + L2CAP_CMD_OVERHEAD; 380 381 UINT16_TO_STREAM(p, reason); 382 383 if (param_len >= 2) UINT16_TO_STREAM(p, p1); 384 385 if (param_len >= 4) UINT16_TO_STREAM(p, p2); 386 387 l2c_link_check_send_pkts(p_lcb, 0, p_buf); 388 } 389 390 /******************************************************************************* 391 * 392 * Function l2cu_send_peer_connect_req 393 * 394 * Description Build and send an L2CAP "connection request" message 395 * to the peer. 396 * 397 * Returns void 398 * 399 ******************************************************************************/ 400 void l2cu_send_peer_connect_req(tL2C_CCB* p_ccb) { 401 BT_HDR* p_buf; 402 uint8_t* p; 403 404 /* Create an identifier for this packet */ 405 p_ccb->p_lcb->signal_id++; 406 l2cu_adj_id(p_ccb->p_lcb); 407 408 p_ccb->local_id = p_ccb->p_lcb->signal_id; 409 410 p_buf = l2cu_build_header(p_ccb->p_lcb, L2CAP_CONN_REQ_LEN, 411 L2CAP_CMD_CONN_REQ, p_ccb->local_id); 412 if (p_buf == NULL) { 413 L2CAP_TRACE_WARNING("L2CAP - no buffer for conn_req"); 414 return; 415 } 416 417 p = (uint8_t*)(p_buf + 1) + L2CAP_SEND_CMD_OFFSET + HCI_DATA_PREAMBLE_SIZE + 418 L2CAP_PKT_OVERHEAD + L2CAP_CMD_OVERHEAD; 419 420 UINT16_TO_STREAM(p, p_ccb->p_rcb->real_psm); 421 UINT16_TO_STREAM(p, p_ccb->local_cid); 422 423 l2c_link_check_send_pkts(p_ccb->p_lcb, 0, p_buf); 424 } 425 426 /******************************************************************************* 427 * 428 * Function l2cu_send_peer_connect_rsp 429 * 430 * Description Build and send an L2CAP "connection response" message 431 * to the peer. 432 * 433 * Returns void 434 * 435 ******************************************************************************/ 436 void l2cu_send_peer_connect_rsp(tL2C_CCB* p_ccb, uint16_t result, 437 uint16_t status) { 438 if (result == L2CAP_CONN_PENDING) { 439 /* if we already sent pending response */ 440 if (p_ccb->flags & CCB_FLAG_SENT_PENDING) { 441 LOG_DEBUG("Already sent connection pending, not sending again"); 442 return; 443 } else { 444 p_ccb->flags |= CCB_FLAG_SENT_PENDING; 445 } 446 } 447 448 BT_HDR* p_buf = l2cu_build_header(p_ccb->p_lcb, L2CAP_CONN_RSP_LEN, 449 L2CAP_CMD_CONN_RSP, p_ccb->remote_id); 450 if (p_buf == nullptr) { 451 LOG_WARN("no buffer for conn_rsp"); 452 return; 453 } 454 455 uint8_t* p = (uint8_t*)(p_buf + 1) + L2CAP_SEND_CMD_OFFSET + 456 HCI_DATA_PREAMBLE_SIZE + L2CAP_PKT_OVERHEAD + L2CAP_CMD_OVERHEAD; 457 458 UINT16_TO_STREAM(p, p_ccb->local_cid); 459 UINT16_TO_STREAM(p, p_ccb->remote_cid); 460 UINT16_TO_STREAM(p, result); 461 UINT16_TO_STREAM(p, status); 462 463 l2c_link_check_send_pkts(p_ccb->p_lcb, 0, p_buf); 464 } 465 466 /******************************************************************************* 467 * 468 * Function l2cu_reject_connection 469 * 470 * Description Build and send an L2CAP "connection response neg" message 471 * to the peer. This function is called when there is no peer 472 * CCB (non-existant PSM or no resources). 473 * 474 * Returns void 475 * 476 ******************************************************************************/ 477 void l2cu_reject_connection(tL2C_LCB* p_lcb, uint16_t remote_cid, 478 uint8_t rem_id, uint16_t result) { 479 BT_HDR* p_buf; 480 uint8_t* p; 481 482 p_buf = 483 l2cu_build_header(p_lcb, L2CAP_CONN_RSP_LEN, L2CAP_CMD_CONN_RSP, rem_id); 484 if (p_buf == NULL) { 485 L2CAP_TRACE_WARNING("L2CAP - no buffer for conn_req"); 486 return; 487 } 488 489 p = (uint8_t*)(p_buf + 1) + L2CAP_SEND_CMD_OFFSET + HCI_DATA_PREAMBLE_SIZE + 490 L2CAP_PKT_OVERHEAD + L2CAP_CMD_OVERHEAD; 491 492 UINT16_TO_STREAM(p, 0); /* Local CID of 0 */ 493 UINT16_TO_STREAM(p, remote_cid); 494 UINT16_TO_STREAM(p, result); 495 UINT16_TO_STREAM(p, 0); /* Status of 0 */ 496 497 l2c_link_check_send_pkts(p_lcb, 0, p_buf); 498 } 499 500 /******************************************************************************* 501 * 502 * Function l2cu_send_credit_based_reconfig_req 503 * 504 * Description Build and send an L2CAP "recoonfiguration request" message 505 * to the peer. 506 * 507 * Returns void 508 * 509 ******************************************************************************/ 510 void l2cu_send_credit_based_reconfig_req(tL2C_CCB* p_ccb, 511 tL2CAP_LE_CFG_INFO* p_cfg) { 512 BT_HDR* p_buf; 513 uint16_t cmd_len; 514 uint8_t* p; 515 tL2C_LCB* p_lcb = p_ccb->p_lcb; 516 tL2C_CCB* p_ccb_temp; 517 518 cmd_len = L2CAP_CMD_CREDIT_BASED_RECONFIG_REQ_MIN_LEN + 519 sizeof(uint16_t) * p_lcb->pending_ecoc_reconfig_cnt; 520 521 /* Create an identifier for this packet */ 522 p_lcb->signal_id++; 523 l2cu_adj_id(p_lcb); 524 525 p_ccb->local_id = p_lcb->signal_id; 526 527 p_buf = l2cu_build_header(p_lcb, cmd_len, L2CAP_CMD_CREDIT_BASED_RECONFIG_REQ, 528 p_lcb->signal_id); 529 if (p_buf == NULL) { 530 L2CAP_TRACE_WARNING("l2cu_send_reconfig_req - no buffer"); 531 return; 532 } 533 534 p = (uint8_t*)(p_buf + 1) + L2CAP_SEND_CMD_OFFSET + HCI_DATA_PREAMBLE_SIZE + 535 L2CAP_PKT_OVERHEAD + L2CAP_CMD_OVERHEAD; 536 537 L2CAP_TRACE_DEBUG("l2cu_send_reconfig_req number of cids: %d mtu:%d mps:%d", 538 p_lcb->pending_ecoc_reconfig_cnt, p_cfg->mtu, p_cfg->mps); 539 540 UINT16_TO_STREAM(p, p_cfg->mtu); 541 UINT16_TO_STREAM(p, p_cfg->mps); 542 543 for (p_ccb_temp = p_lcb->ccb_queue.p_first_ccb; p_ccb_temp; 544 p_ccb_temp = p_ccb_temp->p_next_ccb) { 545 if ((p_ccb_temp->in_use) && (p_ccb_temp->ecoc) && 546 (p_ccb_temp->reconfig_started)) 547 UINT16_TO_STREAM(p, p_ccb_temp->local_cid); 548 } 549 550 l2c_link_check_send_pkts(p_lcb, 0, p_buf); 551 } 552 553 /******************************************************************************* 554 * 555 * Function l2cu_send_peer_config_req 556 * 557 * Description Build and send an L2CAP "configuration request" message 558 * to the peer. 559 * 560 * Returns void 561 * 562 ******************************************************************************/ 563 void l2cu_send_peer_config_req(tL2C_CCB* p_ccb, tL2CAP_CFG_INFO* p_cfg) { 564 BT_HDR* p_buf; 565 uint16_t cfg_len = 0; 566 uint8_t* p; 567 568 /* Create an identifier for this packet */ 569 p_ccb->p_lcb->signal_id++; 570 l2cu_adj_id(p_ccb->p_lcb); 571 572 p_ccb->local_id = p_ccb->p_lcb->signal_id; 573 574 if (p_cfg->mtu_present) 575 cfg_len += L2CAP_CFG_MTU_OPTION_LEN + L2CAP_CFG_OPTION_OVERHEAD; 576 if (p_cfg->flush_to_present) 577 cfg_len += L2CAP_CFG_FLUSH_OPTION_LEN + L2CAP_CFG_OPTION_OVERHEAD; 578 if (p_cfg->qos_present) 579 cfg_len += L2CAP_CFG_QOS_OPTION_LEN + L2CAP_CFG_OPTION_OVERHEAD; 580 if (p_cfg->fcr_present) 581 cfg_len += L2CAP_CFG_FCR_OPTION_LEN + L2CAP_CFG_OPTION_OVERHEAD; 582 if (p_cfg->fcs_present) 583 cfg_len += L2CAP_CFG_FCS_OPTION_LEN + L2CAP_CFG_OPTION_OVERHEAD; 584 if (p_cfg->ext_flow_spec_present) 585 cfg_len += L2CAP_CFG_EXT_FLOW_OPTION_LEN + L2CAP_CFG_OPTION_OVERHEAD; 586 587 p_buf = l2cu_build_header(p_ccb->p_lcb, 588 (uint16_t)(L2CAP_CONFIG_REQ_LEN + cfg_len), 589 L2CAP_CMD_CONFIG_REQ, p_ccb->local_id); 590 if (p_buf == NULL) { 591 L2CAP_TRACE_WARNING("L2CAP - no buffer for conn_req"); 592 return; 593 } 594 595 p = (uint8_t*)(p_buf + 1) + L2CAP_SEND_CMD_OFFSET + HCI_DATA_PREAMBLE_SIZE + 596 L2CAP_PKT_OVERHEAD + L2CAP_CMD_OVERHEAD; 597 598 UINT16_TO_STREAM(p, p_ccb->remote_cid); 599 UINT16_TO_STREAM(p, p_cfg->flags); /* Flags (continuation) */ 600 601 /* Now, put the options */ 602 if (p_cfg->mtu_present) { 603 UINT8_TO_STREAM(p, L2CAP_CFG_TYPE_MTU); 604 UINT8_TO_STREAM(p, L2CAP_CFG_MTU_OPTION_LEN); 605 UINT16_TO_STREAM(p, p_cfg->mtu); 606 } 607 if (p_cfg->flush_to_present) { 608 UINT8_TO_STREAM(p, L2CAP_CFG_TYPE_FLUSH_TOUT); 609 UINT8_TO_STREAM(p, L2CAP_CFG_FLUSH_OPTION_LEN); 610 UINT16_TO_STREAM(p, p_cfg->flush_to); 611 } 612 if (p_cfg->qos_present) { 613 UINT8_TO_STREAM(p, L2CAP_CFG_TYPE_QOS); 614 UINT8_TO_STREAM(p, L2CAP_CFG_QOS_OPTION_LEN); 615 UINT8_TO_STREAM(p, p_cfg->qos.qos_flags); 616 UINT8_TO_STREAM(p, p_cfg->qos.service_type); 617 UINT32_TO_STREAM(p, p_cfg->qos.token_rate); 618 UINT32_TO_STREAM(p, p_cfg->qos.token_bucket_size); 619 UINT32_TO_STREAM(p, p_cfg->qos.peak_bandwidth); 620 UINT32_TO_STREAM(p, p_cfg->qos.latency); 621 UINT32_TO_STREAM(p, p_cfg->qos.delay_variation); 622 } 623 if (p_cfg->fcr_present) { 624 UINT8_TO_STREAM(p, L2CAP_CFG_TYPE_FCR); 625 UINT8_TO_STREAM(p, L2CAP_CFG_FCR_OPTION_LEN); 626 UINT8_TO_STREAM(p, p_cfg->fcr.mode); 627 UINT8_TO_STREAM(p, p_cfg->fcr.tx_win_sz); 628 UINT8_TO_STREAM(p, p_cfg->fcr.max_transmit); 629 UINT16_TO_STREAM(p, p_cfg->fcr.rtrans_tout); 630 UINT16_TO_STREAM(p, p_cfg->fcr.mon_tout); 631 UINT16_TO_STREAM(p, p_cfg->fcr.mps); 632 } 633 634 if (p_cfg->fcs_present) { 635 UINT8_TO_STREAM(p, L2CAP_CFG_TYPE_FCS); 636 UINT8_TO_STREAM(p, L2CAP_CFG_FCS_OPTION_LEN); 637 UINT8_TO_STREAM(p, p_cfg->fcs); 638 } 639 640 if (p_cfg->ext_flow_spec_present) { 641 UINT8_TO_STREAM(p, L2CAP_CFG_TYPE_EXT_FLOW); 642 UINT8_TO_STREAM(p, L2CAP_CFG_EXT_FLOW_OPTION_LEN); 643 UINT8_TO_STREAM(p, p_cfg->ext_flow_spec.id); 644 UINT8_TO_STREAM(p, p_cfg->ext_flow_spec.stype); 645 UINT16_TO_STREAM(p, p_cfg->ext_flow_spec.max_sdu_size); 646 UINT32_TO_STREAM(p, p_cfg->ext_flow_spec.sdu_inter_time); 647 UINT32_TO_STREAM(p, p_cfg->ext_flow_spec.access_latency); 648 UINT32_TO_STREAM(p, p_cfg->ext_flow_spec.flush_timeout); 649 } 650 651 l2c_link_check_send_pkts(p_ccb->p_lcb, 0, p_buf); 652 } 653 654 /******************************************************************************* 655 * 656 * Function l2cu_send_peer_config_rsp 657 * 658 * Description Build and send an L2CAP "configuration response" message 659 * to the peer. 660 * 661 * Returns void 662 * 663 ******************************************************************************/ 664 void l2cu_send_peer_config_rsp(tL2C_CCB* p_ccb, tL2CAP_CFG_INFO* p_cfg) { 665 BT_HDR* p_buf; 666 uint16_t cfg_len = 0; 667 uint8_t* p; 668 669 /* Create an identifier for this packet */ 670 if (p_cfg->mtu_present) 671 cfg_len += L2CAP_CFG_MTU_OPTION_LEN + L2CAP_CFG_OPTION_OVERHEAD; 672 if (p_cfg->flush_to_present) 673 cfg_len += L2CAP_CFG_FLUSH_OPTION_LEN + L2CAP_CFG_OPTION_OVERHEAD; 674 if (p_cfg->qos_present) 675 cfg_len += L2CAP_CFG_QOS_OPTION_LEN + L2CAP_CFG_OPTION_OVERHEAD; 676 if (p_cfg->fcr_present) 677 cfg_len += L2CAP_CFG_FCR_OPTION_LEN + L2CAP_CFG_OPTION_OVERHEAD; 678 if (p_cfg->ext_flow_spec_present) 679 cfg_len += L2CAP_CFG_EXT_FLOW_OPTION_LEN + L2CAP_CFG_OPTION_OVERHEAD; 680 681 p_buf = l2cu_build_header(p_ccb->p_lcb, 682 (uint16_t)(L2CAP_CONFIG_RSP_LEN + cfg_len), 683 L2CAP_CMD_CONFIG_RSP, p_ccb->remote_id); 684 if (p_buf == NULL) { 685 L2CAP_TRACE_WARNING("L2CAP - no buffer for conn_req"); 686 return; 687 } 688 689 p = (uint8_t*)(p_buf + 1) + L2CAP_SEND_CMD_OFFSET + HCI_DATA_PREAMBLE_SIZE + 690 L2CAP_PKT_OVERHEAD + L2CAP_CMD_OVERHEAD; 691 692 UINT16_TO_STREAM(p, p_ccb->remote_cid); 693 UINT16_TO_STREAM(p, 694 p_cfg->flags); /* Flags (continuation) Must match request */ 695 UINT16_TO_STREAM(p, p_cfg->result); 696 697 /* Now, put the options */ 698 if (p_cfg->mtu_present) { 699 UINT8_TO_STREAM(p, L2CAP_CFG_TYPE_MTU); 700 UINT8_TO_STREAM(p, L2CAP_CFG_MTU_OPTION_LEN); 701 UINT16_TO_STREAM(p, p_cfg->mtu); 702 } 703 if (p_cfg->flush_to_present) { 704 UINT8_TO_STREAM(p, L2CAP_CFG_TYPE_FLUSH_TOUT); 705 UINT8_TO_STREAM(p, L2CAP_CFG_FLUSH_OPTION_LEN); 706 UINT16_TO_STREAM(p, p_cfg->flush_to); 707 } 708 if (p_cfg->qos_present) { 709 UINT8_TO_STREAM(p, L2CAP_CFG_TYPE_QOS); 710 UINT8_TO_STREAM(p, L2CAP_CFG_QOS_OPTION_LEN); 711 UINT8_TO_STREAM(p, p_cfg->qos.qos_flags); 712 UINT8_TO_STREAM(p, p_cfg->qos.service_type); 713 UINT32_TO_STREAM(p, p_cfg->qos.token_rate); 714 UINT32_TO_STREAM(p, p_cfg->qos.token_bucket_size); 715 UINT32_TO_STREAM(p, p_cfg->qos.peak_bandwidth); 716 UINT32_TO_STREAM(p, p_cfg->qos.latency); 717 UINT32_TO_STREAM(p, p_cfg->qos.delay_variation); 718 } 719 if (p_cfg->fcr_present) { 720 UINT8_TO_STREAM(p, L2CAP_CFG_TYPE_FCR); 721 UINT8_TO_STREAM(p, L2CAP_CFG_FCR_OPTION_LEN); 722 UINT8_TO_STREAM(p, p_cfg->fcr.mode); 723 UINT8_TO_STREAM(p, p_cfg->fcr.tx_win_sz); 724 UINT8_TO_STREAM(p, p_cfg->fcr.max_transmit); 725 UINT16_TO_STREAM(p, p_ccb->our_cfg.fcr.rtrans_tout); 726 UINT16_TO_STREAM(p, p_ccb->our_cfg.fcr.mon_tout); 727 UINT16_TO_STREAM(p, p_cfg->fcr.mps); 728 } 729 730 if (p_cfg->ext_flow_spec_present) { 731 UINT8_TO_STREAM(p, L2CAP_CFG_TYPE_EXT_FLOW); 732 UINT8_TO_STREAM(p, L2CAP_CFG_EXT_FLOW_OPTION_LEN); 733 UINT8_TO_STREAM(p, p_cfg->ext_flow_spec.id); 734 UINT8_TO_STREAM(p, p_cfg->ext_flow_spec.stype); 735 UINT16_TO_STREAM(p, p_cfg->ext_flow_spec.max_sdu_size); 736 UINT32_TO_STREAM(p, p_cfg->ext_flow_spec.sdu_inter_time); 737 UINT32_TO_STREAM(p, p_cfg->ext_flow_spec.access_latency); 738 UINT32_TO_STREAM(p, p_cfg->ext_flow_spec.flush_timeout); 739 } 740 741 l2c_link_check_send_pkts(p_ccb->p_lcb, 0, p_buf); 742 } 743 744 /******************************************************************************* 745 * 746 * Function l2cu_send_peer_config_rej 747 * 748 * Description Build and send an L2CAP "configuration reject" message 749 * to the peer. 750 * 751 * Returns void 752 * 753 ******************************************************************************/ 754 void l2cu_send_peer_config_rej(tL2C_CCB* p_ccb, uint8_t* p_data, 755 uint16_t data_len, uint16_t rej_len) { 756 uint16_t len, cfg_len, buf_space, len1; 757 uint8_t *p, *p_hci_len, *p_data_end; 758 uint8_t cfg_code; 759 760 L2CAP_TRACE_DEBUG("l2cu_send_peer_config_rej: data_len=%d, rej_len=%d", 761 data_len, rej_len); 762 763 len = BT_HDR_SIZE + HCI_DATA_PREAMBLE_SIZE + L2CAP_PKT_OVERHEAD + 764 L2CAP_CMD_OVERHEAD + L2CAP_CONFIG_RSP_LEN; 765 len1 = 0xFFFF - len; 766 if (rej_len > len1) { 767 L2CAP_TRACE_ERROR( 768 "L2CAP - cfg_rej pkt size exceeds buffer design max limit."); 769 return; 770 } 771 772 BT_HDR* p_buf = (BT_HDR*)osi_malloc(len + rej_len); 773 p_buf->offset = L2CAP_SEND_CMD_OFFSET; 774 p = (uint8_t*)(p_buf + 1) + L2CAP_SEND_CMD_OFFSET; 775 776 const controller_t* controller = controller_get_interface(); 777 778 /* Put in HCI header - handle + pkt boundary */ 779 if (controller->supports_non_flushable_pb()) { 780 UINT16_TO_STREAM(p, (p_ccb->p_lcb->Handle() | (L2CAP_PKT_START_NON_FLUSHABLE 781 << L2CAP_PKT_TYPE_SHIFT))); 782 } else 783 { 784 UINT16_TO_STREAM(p, (p_ccb->p_lcb->Handle() | 785 (L2CAP_PKT_START << L2CAP_PKT_TYPE_SHIFT))); 786 } 787 788 /* Remember the HCI header length position, and save space for it */ 789 p_hci_len = p; 790 p += 2; 791 792 /* Put in L2CAP packet header */ 793 UINT16_TO_STREAM(p, L2CAP_CMD_OVERHEAD + L2CAP_CONFIG_RSP_LEN + rej_len); 794 UINT16_TO_STREAM(p, L2CAP_SIGNALLING_CID); 795 796 /* Put in L2CAP command header */ 797 UINT8_TO_STREAM(p, L2CAP_CMD_CONFIG_RSP); 798 UINT8_TO_STREAM(p, p_ccb->remote_id); 799 800 UINT16_TO_STREAM(p, L2CAP_CONFIG_RSP_LEN + rej_len); 801 802 UINT16_TO_STREAM(p, p_ccb->remote_cid); 803 UINT16_TO_STREAM(p, 0); /* Flags = 0 (no continuation) */ 804 UINT16_TO_STREAM(p, L2CAP_CFG_UNKNOWN_OPTIONS); 805 806 buf_space = rej_len; 807 808 /* Now, put the rejected options */ 809 p_data_end = p_data + data_len; 810 while (p_data < p_data_end) { 811 cfg_code = *p_data; 812 cfg_len = *(p_data + 1); 813 814 switch (cfg_code & 0x7F) { 815 /* skip known options */ 816 case L2CAP_CFG_TYPE_MTU: 817 case L2CAP_CFG_TYPE_FLUSH_TOUT: 818 case L2CAP_CFG_TYPE_QOS: 819 case L2CAP_CFG_TYPE_FCR: 820 case L2CAP_CFG_TYPE_FCS: 821 case L2CAP_CFG_TYPE_EXT_FLOW: 822 p_data += cfg_len + L2CAP_CFG_OPTION_OVERHEAD; 823 break; 824 825 /* unknown options; copy into rsp if not hints */ 826 default: 827 /* sanity check option length */ 828 if ((cfg_len + L2CAP_CFG_OPTION_OVERHEAD) <= data_len) { 829 if ((cfg_code & 0x80) == 0) { 830 if (buf_space >= (cfg_len + L2CAP_CFG_OPTION_OVERHEAD)) { 831 memcpy(p, p_data, cfg_len + L2CAP_CFG_OPTION_OVERHEAD); 832 p += cfg_len + L2CAP_CFG_OPTION_OVERHEAD; 833 buf_space -= (cfg_len + L2CAP_CFG_OPTION_OVERHEAD); 834 } else { 835 L2CAP_TRACE_WARNING("L2CAP - cfg_rej exceeds allocated buffer"); 836 p_data = p_data_end; /* force loop exit */ 837 break; 838 } 839 } 840 p_data += cfg_len + L2CAP_CFG_OPTION_OVERHEAD; 841 } 842 /* bad length; force loop exit */ 843 else { 844 p_data = p_data_end; 845 } 846 break; 847 } 848 } 849 850 len = (uint16_t)(p - p_hci_len - 2); 851 UINT16_TO_STREAM(p_hci_len, len); 852 853 p_buf->len = len + 4; 854 855 L2CAP_TRACE_DEBUG("L2CAP - cfg_rej pkt hci_len=%d, l2cap_len=%d", len, 856 (L2CAP_CMD_OVERHEAD + L2CAP_CONFIG_RSP_LEN + rej_len)); 857 858 l2c_link_check_send_pkts(p_ccb->p_lcb, 0, p_buf); 859 } 860 861 /******************************************************************************* 862 * 863 * Function l2cu_send_peer_disc_req 864 * 865 * Description Build and send an L2CAP "disconnect request" message 866 * to the peer. 867 * 868 * Returns void 869 * 870 ******************************************************************************/ 871 void l2cu_send_peer_disc_req(tL2C_CCB* p_ccb) { 872 BT_HDR *p_buf, *p_buf2; 873 uint8_t* p; 874 875 if ((!p_ccb) || (p_ccb->p_lcb == NULL)) { 876 L2CAP_TRACE_ERROR("%s L2CAP - ccb or lcb invalid", __func__); 877 return; 878 } 879 880 /* Create an identifier for this packet */ 881 p_ccb->p_lcb->signal_id++; 882 l2cu_adj_id(p_ccb->p_lcb); 883 884 p_ccb->local_id = p_ccb->p_lcb->signal_id; 885 886 p_buf = l2cu_build_header(p_ccb->p_lcb, L2CAP_DISC_REQ_LEN, 887 L2CAP_CMD_DISC_REQ, p_ccb->local_id); 888 if (p_buf == NULL) { 889 L2CAP_TRACE_WARNING("L2CAP - no buffer for disc_req"); 890 return; 891 } 892 893 p = (uint8_t*)(p_buf + 1) + L2CAP_SEND_CMD_OFFSET + HCI_DATA_PREAMBLE_SIZE + 894 L2CAP_PKT_OVERHEAD + L2CAP_CMD_OVERHEAD; 895 896 UINT16_TO_STREAM(p, p_ccb->remote_cid); 897 UINT16_TO_STREAM(p, p_ccb->local_cid); 898 899 /* Move all queued data packets to the LCB. In FCR mode, assume the higher 900 layer checks that all buffers are sent before disconnecting. 901 */ 902 if (p_ccb->peer_cfg.fcr.mode == L2CAP_FCR_BASIC_MODE) { 903 while ((p_buf2 = (BT_HDR*)fixed_queue_try_dequeue(p_ccb->xmit_hold_q)) != 904 NULL) { 905 l2cu_set_acl_hci_header(p_buf2, p_ccb); 906 l2c_link_check_send_pkts(p_ccb->p_lcb, p_ccb->local_cid, p_buf2); 907 } 908 } 909 910 l2c_link_check_send_pkts(p_ccb->p_lcb, 0, p_buf); 911 } 912 913 /******************************************************************************* 914 * 915 * Function l2cu_send_peer_disc_rsp 916 * 917 * Description Build and send an L2CAP "disconnect response" message 918 * to the peer. 919 * 920 * This function is passed the parameters for the disconnect 921 * response instead of the CCB address, as it may be called 922 * to send a disconnect response when there is no CCB. 923 * 924 * Returns void 925 * 926 ******************************************************************************/ 927 void l2cu_send_peer_disc_rsp(tL2C_LCB* p_lcb, uint8_t remote_id, 928 uint16_t local_cid, uint16_t remote_cid) { 929 BT_HDR* p_buf; 930 uint8_t* p; 931 932 p_buf = l2cu_build_header(p_lcb, L2CAP_DISC_RSP_LEN, L2CAP_CMD_DISC_RSP, 933 remote_id); 934 if (p_buf == NULL) { 935 L2CAP_TRACE_WARNING("L2CAP - no buffer for disc_rsp"); 936 return; 937 } 938 939 p = (uint8_t*)(p_buf + 1) + L2CAP_SEND_CMD_OFFSET + HCI_DATA_PREAMBLE_SIZE + 940 L2CAP_PKT_OVERHEAD + L2CAP_CMD_OVERHEAD; 941 942 UINT16_TO_STREAM(p, local_cid); 943 UINT16_TO_STREAM(p, remote_cid); 944 945 l2c_link_check_send_pkts(p_lcb, 0, p_buf); 946 } 947 948 /******************************************************************************* 949 * 950 * Function l2cu_send_peer_echo_rsp 951 * 952 * Description Build and send an L2CAP "echo response" message 953 * to the peer. 954 * 955 * Returns void 956 * 957 ******************************************************************************/ 958 void l2cu_send_peer_echo_rsp(tL2C_LCB* p_lcb, uint8_t signal_id, 959 uint8_t* p_data, uint16_t data_len) { 960 BT_HDR* p_buf; 961 uint8_t* p; 962 uint16_t maxlen; 963 /* Filter out duplicate IDs or if available buffers are low (intruder 964 * checking) */ 965 if (!signal_id || signal_id == p_lcb->cur_echo_id) { 966 /* Dump this request since it is illegal */ 967 L2CAP_TRACE_WARNING("L2CAP ignoring duplicate echo request (%d)", 968 signal_id); 969 return; 970 } else 971 p_lcb->cur_echo_id = signal_id; 972 973 uint16_t acl_data_size = 974 controller_get_interface()->get_acl_data_size_classic(); 975 uint16_t acl_packet_size = 976 controller_get_interface()->get_acl_packet_size_classic(); 977 /* Don't return data if it does not fit in ACL and L2CAP MTU */ 978 maxlen = (L2CAP_CMD_BUF_SIZE > acl_packet_size) 979 ? acl_data_size 980 : (uint16_t)L2CAP_CMD_BUF_SIZE; 981 maxlen -= 982 (uint16_t)(BT_HDR_SIZE + HCI_DATA_PREAMBLE_SIZE + L2CAP_PKT_OVERHEAD + 983 L2CAP_CMD_OVERHEAD + L2CAP_ECHO_RSP_LEN); 984 985 if (data_len > maxlen) data_len = 0; 986 987 p_buf = l2cu_build_header(p_lcb, (uint16_t)(L2CAP_ECHO_RSP_LEN + data_len), 988 L2CAP_CMD_ECHO_RSP, signal_id); 989 if (p_buf == NULL) { 990 L2CAP_TRACE_WARNING("L2CAP - no buffer for echo_rsp"); 991 return; 992 } 993 994 p = (uint8_t*)(p_buf + 1) + L2CAP_SEND_CMD_OFFSET + HCI_DATA_PREAMBLE_SIZE + 995 L2CAP_PKT_OVERHEAD + L2CAP_CMD_OVERHEAD; 996 997 if (data_len) { 998 ARRAY_TO_STREAM(p, p_data, data_len); 999 } 1000 1001 l2c_link_check_send_pkts(p_lcb, 0, p_buf); 1002 } 1003 1004 /******************************************************************************* 1005 * 1006 * Function l2cu_send_peer_info_req 1007 * 1008 * Description Build and send an L2CAP "info request" message 1009 * to the peer. 1010 * Returns void 1011 * 1012 ******************************************************************************/ 1013 void l2cu_send_peer_info_req(tL2C_LCB* p_lcb, uint16_t info_type) { 1014 BT_HDR* p_buf; 1015 uint8_t* p; 1016 1017 /* Create an identifier for this packet */ 1018 p_lcb->signal_id++; 1019 l2cu_adj_id(p_lcb); 1020 1021 p_buf = l2cu_build_header(p_lcb, 2, L2CAP_CMD_INFO_REQ, p_lcb->signal_id); 1022 if (p_buf == NULL) { 1023 L2CAP_TRACE_WARNING("L2CAP - no buffer for info_req"); 1024 return; 1025 } 1026 1027 L2CAP_TRACE_EVENT("l2cu_send_peer_info_req: type 0x%04x", info_type); 1028 1029 p = (uint8_t*)(p_buf + 1) + L2CAP_SEND_CMD_OFFSET + HCI_DATA_PREAMBLE_SIZE + 1030 L2CAP_PKT_OVERHEAD + L2CAP_CMD_OVERHEAD; 1031 1032 UINT16_TO_STREAM(p, info_type); 1033 1034 p_lcb->w4_info_rsp = true; 1035 alarm_set_on_mloop(p_lcb->info_resp_timer, L2CAP_WAIT_INFO_RSP_TIMEOUT_MS, 1036 l2c_info_resp_timer_timeout, p_lcb); 1037 1038 l2c_link_check_send_pkts(p_lcb, 0, p_buf); 1039 } 1040 1041 /******************************************************************************* 1042 * 1043 * Function l2cu_send_peer_info_rsp 1044 * 1045 * Description Build and send an L2CAP "info response" message 1046 * to the peer. 1047 * 1048 * Returns void 1049 * 1050 ******************************************************************************/ 1051 void l2cu_send_peer_info_rsp(tL2C_LCB* p_lcb, uint8_t remote_id, 1052 uint16_t info_type) { 1053 BT_HDR* p_buf; 1054 uint8_t* p; 1055 uint16_t len = L2CAP_INFO_RSP_LEN; 1056 1057 #if (L2CAP_CONFORMANCE_TESTING == TRUE) 1058 if ((info_type == L2CAP_EXTENDED_FEATURES_INFO_TYPE) && 1059 (l2cb.test_info_resp & 1060 (L2CAP_EXTFEA_ENH_RETRANS | L2CAP_EXTFEA_STREAM_MODE | 1061 L2CAP_EXTFEA_NO_CRC | L2CAP_EXTFEA_EXT_FLOW_SPEC | 1062 L2CAP_EXTFEA_FIXED_CHNLS | L2CAP_EXTFEA_EXT_WINDOW | 1063 L2CAP_EXTFEA_UCD_RECEPTION))) 1064 #else 1065 if ((info_type == L2CAP_EXTENDED_FEATURES_INFO_TYPE) && 1066 (L2CAP_EXTFEA_SUPPORTED_MASK & 1067 (L2CAP_EXTFEA_ENH_RETRANS | L2CAP_EXTFEA_STREAM_MODE | 1068 L2CAP_EXTFEA_NO_CRC | L2CAP_EXTFEA_FIXED_CHNLS | 1069 L2CAP_EXTFEA_UCD_RECEPTION)) != 0) 1070 #endif 1071 { 1072 len += L2CAP_EXTENDED_FEATURES_ARRAY_SIZE; 1073 } else if (info_type == L2CAP_FIXED_CHANNELS_INFO_TYPE) { 1074 len += L2CAP_FIXED_CHNL_ARRAY_SIZE; 1075 } else if (info_type == L2CAP_CONNLESS_MTU_INFO_TYPE) { 1076 len += L2CAP_CONNLESS_MTU_INFO_SIZE; 1077 } 1078 1079 p_buf = l2cu_build_header(p_lcb, len, L2CAP_CMD_INFO_RSP, remote_id); 1080 if (p_buf == NULL) { 1081 L2CAP_TRACE_WARNING("L2CAP - no buffer for info_rsp"); 1082 return; 1083 } 1084 1085 p = (uint8_t*)(p_buf + 1) + L2CAP_SEND_CMD_OFFSET + HCI_DATA_PREAMBLE_SIZE + 1086 L2CAP_PKT_OVERHEAD + L2CAP_CMD_OVERHEAD; 1087 1088 UINT16_TO_STREAM(p, info_type); 1089 1090 #if (L2CAP_CONFORMANCE_TESTING == TRUE) 1091 if ((info_type == L2CAP_EXTENDED_FEATURES_INFO_TYPE) && 1092 (l2cb.test_info_resp & 1093 (L2CAP_EXTFEA_ENH_RETRANS | L2CAP_EXTFEA_STREAM_MODE | 1094 L2CAP_EXTFEA_UCD_RECEPTION))) 1095 #else 1096 if ((info_type == L2CAP_EXTENDED_FEATURES_INFO_TYPE) && 1097 (L2CAP_EXTFEA_SUPPORTED_MASK & 1098 (L2CAP_EXTFEA_ENH_RETRANS | L2CAP_EXTFEA_STREAM_MODE | 1099 L2CAP_EXTFEA_UCD_RECEPTION)) != 0) 1100 #endif 1101 { 1102 UINT16_TO_STREAM(p, L2CAP_INFO_RESP_RESULT_SUCCESS); 1103 if (p_lcb->transport == BT_TRANSPORT_LE) { 1104 /* optional data are not added for now */ 1105 UINT32_TO_STREAM(p, L2CAP_BLE_EXTFEA_MASK); 1106 } else { 1107 #if (L2CAP_CONFORMANCE_TESTING == TRUE) 1108 UINT32_TO_STREAM(p, l2cb.test_info_resp); 1109 #else 1110 UINT32_TO_STREAM(p, 1111 L2CAP_EXTFEA_SUPPORTED_MASK | L2CAP_EXTFEA_FIXED_CHNLS); 1112 #endif 1113 } 1114 } else if (info_type == L2CAP_FIXED_CHANNELS_INFO_TYPE) { 1115 UINT16_TO_STREAM(p, L2CAP_INFO_RESP_RESULT_SUCCESS); 1116 memset(p, 0, L2CAP_FIXED_CHNL_ARRAY_SIZE); 1117 1118 p[0] = L2CAP_FIXED_CHNL_SIG_BIT; 1119 1120 if (L2CAP_EXTFEA_SUPPORTED_MASK & L2CAP_EXTFEA_UCD_RECEPTION) 1121 p[0] |= L2CAP_FIXED_CHNL_CNCTLESS_BIT; 1122 1123 { 1124 int xx; 1125 1126 for (xx = 0; xx < L2CAP_NUM_FIXED_CHNLS; xx++) { 1127 /* Skip fixed channels not used on BR/EDR-ACL link */ 1128 if ((xx >= L2CAP_ATT_CID - L2CAP_FIRST_FIXED_CHNL) && 1129 (xx <= L2CAP_SMP_CID - L2CAP_FIRST_FIXED_CHNL)) 1130 continue; 1131 1132 if (l2cb.fixed_reg[xx].pL2CA_FixedConn_Cb != NULL) 1133 p[(xx + L2CAP_FIRST_FIXED_CHNL) / 8] |= 1134 1 << ((xx + L2CAP_FIRST_FIXED_CHNL) % 8); 1135 } 1136 } 1137 } else if (info_type == L2CAP_CONNLESS_MTU_INFO_TYPE) { 1138 UINT16_TO_STREAM(p, L2CAP_INFO_RESP_RESULT_SUCCESS); 1139 UINT16_TO_STREAM(p, L2CAP_MTU_SIZE); 1140 } else { 1141 UINT16_TO_STREAM( 1142 p, L2CAP_INFO_RESP_RESULT_NOT_SUPPORTED); /* 'not supported' */ 1143 } 1144 1145 l2c_link_check_send_pkts(p_lcb, 0, p_buf); 1146 } 1147 1148 /****************************************************************************** 1149 * 1150 * Function l2cu_enqueue_ccb 1151 * 1152 * Description queue CCB by priority. The first CCB is highest priority and 1153 * is served at first. The CCB is queued to an LLCB or an LCB. 1154 * 1155 * Returns None 1156 * 1157 ******************************************************************************/ 1158 void l2cu_enqueue_ccb(tL2C_CCB* p_ccb) { 1159 tL2C_CCB* p_ccb1; 1160 tL2C_CCB_Q* p_q = NULL; 1161 1162 /* Find out which queue the channel is on 1163 */ 1164 if (p_ccb->p_lcb != NULL) p_q = &p_ccb->p_lcb->ccb_queue; 1165 1166 if ((!p_ccb->in_use) || (p_q == NULL)) { 1167 L2CAP_TRACE_ERROR("%s: CID: 0x%04x ERROR in_use: %u p_lcb: %p", __func__, 1168 p_ccb->local_cid, p_ccb->in_use, p_ccb->p_lcb); 1169 return; 1170 } 1171 1172 L2CAP_TRACE_DEBUG("l2cu_enqueue_ccb CID: 0x%04x priority: %d", 1173 p_ccb->local_cid, p_ccb->ccb_priority); 1174 1175 /* If the queue is empty, we go at the front */ 1176 if (!p_q->p_first_ccb) { 1177 p_q->p_first_ccb = p_q->p_last_ccb = p_ccb; 1178 p_ccb->p_next_ccb = p_ccb->p_prev_ccb = NULL; 1179 } else { 1180 p_ccb1 = p_q->p_first_ccb; 1181 1182 while (p_ccb1 != NULL) { 1183 /* Insert new ccb at the end of the same priority. Lower number, higher 1184 * priority */ 1185 if (p_ccb->ccb_priority < p_ccb1->ccb_priority) { 1186 /* Are we at the head of the queue ? */ 1187 if (p_ccb1 == p_q->p_first_ccb) 1188 p_q->p_first_ccb = p_ccb; 1189 else 1190 p_ccb1->p_prev_ccb->p_next_ccb = p_ccb; 1191 1192 p_ccb->p_next_ccb = p_ccb1; 1193 p_ccb->p_prev_ccb = p_ccb1->p_prev_ccb; 1194 p_ccb1->p_prev_ccb = p_ccb; 1195 break; 1196 } 1197 1198 p_ccb1 = p_ccb1->p_next_ccb; 1199 } 1200 1201 /* If we are lower then anyone in the list, we go at the end */ 1202 if (!p_ccb1) { 1203 /* add new ccb at the end of the list */ 1204 p_q->p_last_ccb->p_next_ccb = p_ccb; 1205 1206 p_ccb->p_next_ccb = NULL; 1207 p_ccb->p_prev_ccb = p_q->p_last_ccb; 1208 p_q->p_last_ccb = p_ccb; 1209 } 1210 } 1211 1212 /* Adding CCB into round robin service table of its LCB */ 1213 if (p_ccb->p_lcb != NULL) { 1214 /* if this is the first channel in this priority group */ 1215 if (p_ccb->p_lcb->rr_serv[p_ccb->ccb_priority].num_ccb == 0) { 1216 /* Set the first channel to this CCB */ 1217 p_ccb->p_lcb->rr_serv[p_ccb->ccb_priority].p_first_ccb = p_ccb; 1218 /* Set the next serving channel in this group to this CCB */ 1219 p_ccb->p_lcb->rr_serv[p_ccb->ccb_priority].p_serve_ccb = p_ccb; 1220 /* Initialize quota of this priority group based on its priority */ 1221 p_ccb->p_lcb->rr_serv[p_ccb->ccb_priority].quota = 1222 L2CAP_GET_PRIORITY_QUOTA(p_ccb->ccb_priority); 1223 } 1224 /* increase number of channels in this group */ 1225 p_ccb->p_lcb->rr_serv[p_ccb->ccb_priority].num_ccb++; 1226 } 1227 } 1228 1229 /****************************************************************************** 1230 * 1231 * Function l2cu_dequeue_ccb 1232 * 1233 * Description dequeue CCB from a queue 1234 * 1235 * Returns - 1236 * 1237 ******************************************************************************/ 1238 void l2cu_dequeue_ccb(tL2C_CCB* p_ccb) { 1239 tL2C_CCB_Q* p_q = NULL; 1240 1241 L2CAP_TRACE_DEBUG("l2cu_dequeue_ccb CID: 0x%04x", p_ccb->local_cid); 1242 1243 /* Find out which queue the channel is on 1244 */ 1245 if (p_ccb->p_lcb != NULL) p_q = &p_ccb->p_lcb->ccb_queue; 1246 1247 if ((!p_ccb->in_use) || (p_q == NULL) || (p_q->p_first_ccb == NULL)) { 1248 L2CAP_TRACE_ERROR( 1249 "l2cu_dequeue_ccb CID: 0x%04x ERROR in_use: %u p_lcb: 0x%08x p_q: " 1250 "0x%08x p_q->p_first_ccb: 0x%08x", 1251 p_ccb->local_cid, p_ccb->in_use, p_ccb->p_lcb, p_q, 1252 p_q ? p_q->p_first_ccb : 0); 1253 return; 1254 } 1255 1256 /* Removing CCB from round robin service table of its LCB */ 1257 if (p_ccb->p_lcb != NULL) { 1258 /* decrease number of channels in this priority group */ 1259 p_ccb->p_lcb->rr_serv[p_ccb->ccb_priority].num_ccb--; 1260 1261 /* if it was the last channel in the priority group */ 1262 if (p_ccb->p_lcb->rr_serv[p_ccb->ccb_priority].num_ccb == 0) { 1263 p_ccb->p_lcb->rr_serv[p_ccb->ccb_priority].p_first_ccb = NULL; 1264 p_ccb->p_lcb->rr_serv[p_ccb->ccb_priority].p_serve_ccb = NULL; 1265 } else { 1266 /* if it is the first channel of this group */ 1267 if (p_ccb->p_lcb->rr_serv[p_ccb->ccb_priority].p_first_ccb == p_ccb) { 1268 p_ccb->p_lcb->rr_serv[p_ccb->ccb_priority].p_first_ccb = 1269 p_ccb->p_next_ccb; 1270 } 1271 /* if it is the next serving channel of this group */ 1272 if (p_ccb->p_lcb->rr_serv[p_ccb->ccb_priority].p_serve_ccb == p_ccb) { 1273 /* simply, start serving from the first channel */ 1274 p_ccb->p_lcb->rr_serv[p_ccb->ccb_priority].p_serve_ccb = 1275 p_ccb->p_lcb->rr_serv[p_ccb->ccb_priority].p_first_ccb; 1276 } 1277 } 1278 } 1279 1280 if (p_ccb == p_q->p_first_ccb) { 1281 /* We are removing the first in a queue */ 1282 p_q->p_first_ccb = p_ccb->p_next_ccb; 1283 1284 if (p_q->p_first_ccb) 1285 p_q->p_first_ccb->p_prev_ccb = NULL; 1286 else 1287 p_q->p_last_ccb = NULL; 1288 } else if (p_ccb == p_q->p_last_ccb) { 1289 /* We are removing the last in a queue */ 1290 p_q->p_last_ccb = p_ccb->p_prev_ccb; 1291 p_q->p_last_ccb->p_next_ccb = NULL; 1292 } else { 1293 /* In the middle of a chain. */ 1294 p_ccb->p_prev_ccb->p_next_ccb = p_ccb->p_next_ccb; 1295 p_ccb->p_next_ccb->p_prev_ccb = p_ccb->p_prev_ccb; 1296 } 1297 1298 p_ccb->p_next_ccb = p_ccb->p_prev_ccb = NULL; 1299 } 1300 1301 /****************************************************************************** 1302 * 1303 * Function l2cu_change_pri_ccb 1304 * 1305 * Description 1306 * 1307 * Returns - 1308 * 1309 ******************************************************************************/ 1310 void l2cu_change_pri_ccb(tL2C_CCB* p_ccb, tL2CAP_CHNL_PRIORITY priority) { 1311 if (p_ccb->ccb_priority != priority) { 1312 /* If CCB is not the only guy on the queue */ 1313 if ((p_ccb->p_next_ccb != NULL) || (p_ccb->p_prev_ccb != NULL)) { 1314 L2CAP_TRACE_DEBUG("Update CCB list in logical link"); 1315 1316 /* Remove CCB from queue and re-queue it at new priority */ 1317 l2cu_dequeue_ccb(p_ccb); 1318 1319 p_ccb->ccb_priority = priority; 1320 l2cu_enqueue_ccb(p_ccb); 1321 } 1322 else { 1323 /* If CCB is the only guy on the queue, no need to re-enqueue */ 1324 /* update only round robin service data */ 1325 p_ccb->p_lcb->rr_serv[p_ccb->ccb_priority].num_ccb = 0; 1326 p_ccb->p_lcb->rr_serv[p_ccb->ccb_priority].p_first_ccb = NULL; 1327 p_ccb->p_lcb->rr_serv[p_ccb->ccb_priority].p_serve_ccb = NULL; 1328 1329 p_ccb->ccb_priority = priority; 1330 1331 p_ccb->p_lcb->rr_serv[p_ccb->ccb_priority].p_first_ccb = p_ccb; 1332 p_ccb->p_lcb->rr_serv[p_ccb->ccb_priority].p_serve_ccb = p_ccb; 1333 p_ccb->p_lcb->rr_serv[p_ccb->ccb_priority].quota = 1334 L2CAP_GET_PRIORITY_QUOTA(p_ccb->ccb_priority); 1335 p_ccb->p_lcb->rr_serv[p_ccb->ccb_priority].num_ccb = 1; 1336 } 1337 } 1338 } 1339 1340 /******************************************************************************* 1341 * 1342 * Function l2cu_allocate_ccb 1343 * 1344 * Description This function allocates a Channel Control Block and 1345 * attaches it to a link control block. The local CID 1346 * is also assigned. 1347 * 1348 * Returns pointer to CCB, or NULL if none 1349 * 1350 ******************************************************************************/ 1351 tL2C_CCB* l2cu_allocate_ccb(tL2C_LCB* p_lcb, uint16_t cid) { 1352 LOG_DEBUG("cid 0x%04x", cid); 1353 if (!l2cb.p_free_ccb_first) { 1354 LOG_ERROR("First free ccb is null for cid 0x%04x", cid); 1355 return nullptr; 1356 } 1357 tL2C_CCB* p_ccb; 1358 /* If a CID was passed in, use that, else take the first free one */ 1359 if (cid == 0) { 1360 p_ccb = l2cb.p_free_ccb_first; 1361 l2cb.p_free_ccb_first = p_ccb->p_next_ccb; 1362 } else { 1363 tL2C_CCB* p_prev = nullptr; 1364 1365 p_ccb = &l2cb.ccb_pool[cid - L2CAP_BASE_APPL_CID]; 1366 1367 if (p_ccb == l2cb.p_free_ccb_first) { 1368 l2cb.p_free_ccb_first = p_ccb->p_next_ccb; 1369 } else { 1370 for (p_prev = l2cb.p_free_ccb_first; p_prev != nullptr; 1371 p_prev = p_prev->p_next_ccb) { 1372 if (p_prev->p_next_ccb == p_ccb) { 1373 p_prev->p_next_ccb = p_ccb->p_next_ccb; 1374 1375 if (p_ccb == l2cb.p_free_ccb_last) { 1376 l2cb.p_free_ccb_last = p_prev; 1377 } 1378 1379 break; 1380 } 1381 } 1382 if (p_prev == nullptr) { 1383 LOG_ERROR("Could not find CCB for CID 0x%04x in the free list", cid); 1384 return nullptr; 1385 } 1386 } 1387 } 1388 1389 p_ccb->p_next_ccb = p_ccb->p_prev_ccb = nullptr; 1390 1391 p_ccb->in_use = true; 1392 1393 /* Get a CID for the connection */ 1394 p_ccb->local_cid = L2CAP_BASE_APPL_CID + (uint16_t)(p_ccb - l2cb.ccb_pool); 1395 1396 p_ccb->p_lcb = p_lcb; 1397 p_ccb->p_rcb = nullptr; 1398 1399 /* Set priority then insert ccb into LCB queue (if we have an LCB) */ 1400 p_ccb->ccb_priority = L2CAP_CHNL_PRIORITY_LOW; 1401 1402 if (p_lcb) l2cu_enqueue_ccb(p_ccb); 1403 1404 /* Put in default values for configuration */ 1405 memset(&p_ccb->our_cfg, 0, sizeof(tL2CAP_CFG_INFO)); 1406 memset(&p_ccb->peer_cfg, 0, sizeof(tL2CAP_CFG_INFO)); 1407 1408 /* Put in default values for local/peer configurations */ 1409 p_ccb->our_cfg.flush_to = p_ccb->peer_cfg.flush_to = L2CAP_NO_AUTOMATIC_FLUSH; 1410 p_ccb->our_cfg.mtu = p_ccb->peer_cfg.mtu = L2CAP_DEFAULT_MTU; 1411 p_ccb->our_cfg.qos.service_type = p_ccb->peer_cfg.qos.service_type = 1412 L2CAP_DEFAULT_SERV_TYPE; 1413 p_ccb->our_cfg.qos.token_rate = p_ccb->peer_cfg.qos.token_rate = 1414 L2CAP_DEFAULT_TOKEN_RATE; 1415 p_ccb->our_cfg.qos.token_bucket_size = p_ccb->peer_cfg.qos.token_bucket_size = 1416 L2CAP_DEFAULT_BUCKET_SIZE; 1417 p_ccb->our_cfg.qos.peak_bandwidth = p_ccb->peer_cfg.qos.peak_bandwidth = 1418 L2CAP_DEFAULT_PEAK_BANDWIDTH; 1419 p_ccb->our_cfg.qos.latency = p_ccb->peer_cfg.qos.latency = 1420 L2CAP_DEFAULT_LATENCY; 1421 p_ccb->our_cfg.qos.delay_variation = p_ccb->peer_cfg.qos.delay_variation = 1422 L2CAP_DEFAULT_DELAY; 1423 1424 p_ccb->peer_cfg_already_rejected = false; 1425 p_ccb->fcr_cfg_tries = L2CAP_MAX_FCR_CFG_TRIES; 1426 1427 alarm_free(p_ccb->fcrb.ack_timer); 1428 p_ccb->fcrb.ack_timer = alarm_new("l2c_fcrb.ack_timer"); 1429 1430 /* CSP408639 Fix: When L2CAP send amp move channel request or receive 1431 * L2CEVT_AMP_MOVE_REQ do following sequence. Send channel move 1432 * request -> Stop retrans/monitor timer -> Change channel state to 1433 * CST_AMP_MOVING. */ 1434 alarm_free(p_ccb->fcrb.mon_retrans_timer); 1435 p_ccb->fcrb.mon_retrans_timer = alarm_new("l2c_fcrb.mon_retrans_timer"); 1436 1437 p_ccb->max_rx_mtu = BT_DEFAULT_BUFFER_SIZE - 1438 (L2CAP_MIN_OFFSET + L2CAP_SDU_LEN_OFFSET + L2CAP_FCS_LEN); 1439 p_ccb->tx_mps = BT_DEFAULT_BUFFER_SIZE - 32; 1440 1441 p_ccb->xmit_hold_q = fixed_queue_new(SIZE_MAX); 1442 p_ccb->fcrb.srej_rcv_hold_q = fixed_queue_new(SIZE_MAX); 1443 p_ccb->fcrb.retrans_q = fixed_queue_new(SIZE_MAX); 1444 p_ccb->fcrb.waiting_for_ack_q = fixed_queue_new(SIZE_MAX); 1445 1446 p_ccb->cong_sent = false; 1447 p_ccb->buff_quota = 2; /* This gets set after config */ 1448 1449 /* If CCB was reserved Config_Done can already have some value */ 1450 if (cid == 0) { 1451 p_ccb->config_done = 0; 1452 } else { 1453 LOG_DEBUG("cid 0x%04x config_done:0x%x", cid, p_ccb->config_done); 1454 } 1455 1456 p_ccb->chnl_state = CST_CLOSED; 1457 p_ccb->flags = 0; 1458 p_ccb->tx_data_rate = L2CAP_CHNL_DATA_RATE_LOW; 1459 p_ccb->rx_data_rate = L2CAP_CHNL_DATA_RATE_LOW; 1460 1461 p_ccb->is_flushable = false; 1462 p_ccb->ecoc = false; 1463 1464 alarm_free(p_ccb->l2c_ccb_timer); 1465 p_ccb->l2c_ccb_timer = alarm_new("l2c.l2c_ccb_timer"); 1466 1467 l2c_link_adjust_chnl_allocation(); 1468 1469 return p_ccb; 1470 } 1471 1472 /******************************************************************************* 1473 * 1474 * Function l2cu_start_post_bond_timer 1475 * 1476 * Description This function starts the ACL Link inactivity timer after 1477 * dedicated bonding 1478 * This timer can be longer than the normal link inactivity 1479 * timer for some platforms. 1480 * 1481 * Returns bool - true if idle timer started or disconnect initiated 1482 * false if there's one or more pending CCB's exist 1483 * 1484 ******************************************************************************/ 1485 bool l2cu_start_post_bond_timer(uint16_t handle) { 1486 if (bluetooth::shim::is_gd_l2cap_enabled()) { 1487 return true; 1488 } 1489 1490 tL2C_LCB* p_lcb = l2cu_find_lcb_by_handle(handle); 1491 1492 if (!p_lcb) return (true); 1493 1494 p_lcb->ResetBonding(); 1495 1496 /* Only start timer if no control blocks allocated */ 1497 if (p_lcb->ccb_queue.p_first_ccb != NULL) return (false); 1498 1499 /* If no channels on the connection, start idle timeout */ 1500 if ((p_lcb->link_state == LST_CONNECTED) || 1501 (p_lcb->link_state == LST_CONNECTING) || 1502 (p_lcb->link_state == LST_DISCONNECTING)) { 1503 uint64_t timeout_ms = L2CAP_BONDING_TIMEOUT * 1000; 1504 1505 if (p_lcb->idle_timeout == 0) { 1506 acl_disconnect_from_handle(p_lcb->Handle(), HCI_ERR_PEER_USER); 1507 p_lcb->link_state = LST_DISCONNECTING; 1508 timeout_ms = L2CAP_LINK_DISCONNECT_TIMEOUT_MS; 1509 } 1510 alarm_set_on_mloop(p_lcb->l2c_lcb_timer, timeout_ms, l2c_lcb_timer_timeout, 1511 p_lcb); 1512 return (true); 1513 } 1514 1515 return (false); 1516 } 1517 1518 /******************************************************************************* 1519 * 1520 * Function l2cu_release_ccb 1521 * 1522 * Description This function releases a Channel Control Block. The timer 1523 * is stopped, any attached buffers freed, and the CCB is 1524 * removed from the link control block. 1525 * 1526 * Returns void 1527 * 1528 ******************************************************************************/ 1529 void l2cu_release_ccb(tL2C_CCB* p_ccb) { 1530 tL2C_LCB* p_lcb = p_ccb->p_lcb; 1531 tL2C_RCB* p_rcb = p_ccb->p_rcb; 1532 1533 L2CAP_TRACE_DEBUG("l2cu_release_ccb: cid 0x%04x in_use: %u", 1534 p_ccb->local_cid, p_ccb->in_use); 1535 1536 /* If already released, could be race condition */ 1537 if (!p_ccb->in_use) return; 1538 1539 btsnoop_get_interface()->clear_l2cap_allowlist( 1540 p_lcb->Handle(), p_ccb->local_cid, p_ccb->remote_cid); 1541 1542 if (p_rcb && (p_rcb->psm != p_rcb->real_psm)) { 1543 BTM_SecClrServiceByPsm(p_rcb->psm); 1544 } 1545 1546 /* Free the timer */ 1547 alarm_free(p_ccb->l2c_ccb_timer); 1548 p_ccb->l2c_ccb_timer = NULL; 1549 1550 fixed_queue_free(p_ccb->xmit_hold_q, osi_free); 1551 p_ccb->xmit_hold_q = NULL; 1552 1553 l2c_fcr_cleanup(p_ccb); 1554 1555 /* Channel may not be assigned to any LCB if it was just pre-reserved */ 1556 if ((p_lcb) && ((p_ccb->local_cid >= L2CAP_BASE_APPL_CID))) { 1557 l2cu_dequeue_ccb(p_ccb); 1558 1559 /* Delink the CCB from the LCB */ 1560 p_ccb->p_lcb = NULL; 1561 } 1562 1563 /* Put the CCB back on the free pool */ 1564 if (!l2cb.p_free_ccb_first) { 1565 l2cb.p_free_ccb_first = p_ccb; 1566 l2cb.p_free_ccb_last = p_ccb; 1567 p_ccb->p_next_ccb = NULL; 1568 p_ccb->p_prev_ccb = NULL; 1569 } else { 1570 p_ccb->p_next_ccb = NULL; 1571 p_ccb->p_prev_ccb = l2cb.p_free_ccb_last; 1572 l2cb.p_free_ccb_last->p_next_ccb = p_ccb; 1573 l2cb.p_free_ccb_last = p_ccb; 1574 } 1575 1576 /* Flag as not in use */ 1577 p_ccb->in_use = false; 1578 1579 /* If no channels on the connection, start idle timeout */ 1580 if ((p_lcb) && p_lcb->in_use) { 1581 if (p_lcb->link_state == LST_CONNECTED) { 1582 if (!p_lcb->ccb_queue.p_first_ccb) { 1583 // Closing a security channel on LE device should not start connection 1584 // timeout 1585 if (p_lcb->transport == BT_TRANSPORT_LE && 1586 p_ccb->local_cid == L2CAP_SMP_CID) 1587 return; 1588 1589 l2cu_no_dynamic_ccbs(p_lcb); 1590 } else { 1591 /* Link is still active, adjust channel quotas. */ 1592 l2c_link_adjust_chnl_allocation(); 1593 } 1594 } else if (p_lcb->link_state == LST_CONNECTING) { 1595 if (!p_lcb->ccb_queue.p_first_ccb) { 1596 if (p_lcb->transport == BT_TRANSPORT_LE && 1597 p_ccb->local_cid == L2CAP_ATT_CID) { 1598 L2CAP_TRACE_WARNING("%s - disconnecting the LE link", __func__); 1599 l2cu_no_dynamic_ccbs(p_lcb); 1600 } 1601 } 1602 } 1603 } 1604 } 1605 1606 /******************************************************************************* 1607 * 1608 * Function l2cu_find_ccb_by_remote_cid 1609 * 1610 * Description Look through all active CCBs on a link for a match based 1611 * on the remote CID. 1612 * 1613 * Returns pointer to matched CCB, or NULL if no match 1614 * 1615 ******************************************************************************/ 1616 tL2C_CCB* l2cu_find_ccb_by_remote_cid(tL2C_LCB* p_lcb, uint16_t remote_cid) { 1617 tL2C_CCB* p_ccb; 1618 1619 /* If LCB is NULL, look through all active links */ 1620 if (!p_lcb) { 1621 return NULL; 1622 } else { 1623 for (p_ccb = p_lcb->ccb_queue.p_first_ccb; p_ccb; p_ccb = p_ccb->p_next_ccb) 1624 if ((p_ccb->in_use) && (p_ccb->remote_cid == remote_cid)) return (p_ccb); 1625 } 1626 1627 /* If here, no match found */ 1628 return (NULL); 1629 } 1630 1631 /******************************************************************************* 1632 * 1633 * Function l2cu_allocate_rcb 1634 * 1635 * Description Look through the Registration Control Blocks for a free 1636 * one. 1637 * 1638 * Returns Pointer to the RCB or NULL if not found 1639 * 1640 ******************************************************************************/ 1641 tL2C_RCB* l2cu_allocate_rcb(uint16_t psm) { 1642 tL2C_RCB* p_rcb = &l2cb.rcb_pool[0]; 1643 uint16_t xx; 1644 1645 for (xx = 0; xx < MAX_L2CAP_CLIENTS; xx++, p_rcb++) { 1646 if (!p_rcb->in_use) { 1647 p_rcb->in_use = true; 1648 p_rcb->psm = psm; 1649 return (p_rcb); 1650 } 1651 } 1652 1653 /* If here, no free RCB found */ 1654 return (NULL); 1655 } 1656 1657 /******************************************************************************* 1658 * 1659 * Function l2cu_allocate_ble_rcb 1660 * 1661 * Description Look through the BLE Registration Control Blocks for a free 1662 * one. 1663 * 1664 * Returns Pointer to the BLE RCB or NULL if not found 1665 * 1666 ******************************************************************************/ 1667 tL2C_RCB* l2cu_allocate_ble_rcb(uint16_t psm) { 1668 tL2C_RCB* p_rcb = &l2cb.ble_rcb_pool[0]; 1669 uint16_t xx; 1670 1671 for (xx = 0; xx < BLE_MAX_L2CAP_CLIENTS; xx++, p_rcb++) { 1672 if (!p_rcb->in_use) { 1673 p_rcb->in_use = true; 1674 p_rcb->psm = psm; 1675 return (p_rcb); 1676 } 1677 } 1678 1679 /* If here, no free RCB found */ 1680 return (NULL); 1681 } 1682 1683 /******************************************************************************* 1684 * 1685 * Function l2cu_release_rcb 1686 * 1687 * Description Mark an RCB as no longet in use 1688 * 1689 * Returns void 1690 * 1691 ******************************************************************************/ 1692 void l2cu_release_rcb(tL2C_RCB* p_rcb) { 1693 p_rcb->in_use = false; 1694 p_rcb->psm = 0; 1695 } 1696 1697 /******************************************************************************* 1698 * 1699 * Function l2cu_release_ble_rcb 1700 * 1701 * Description Mark an LE RCB as no longer in use 1702 * 1703 * Returns void 1704 * 1705 ******************************************************************************/ 1706 void l2cu_release_ble_rcb(tL2C_RCB* p_rcb) { 1707 L2CA_FreeLePSM(p_rcb->psm); 1708 p_rcb->in_use = false; 1709 p_rcb->psm = 0; 1710 } 1711 1712 /******************************************************************************* 1713 * 1714 * Function l2cu_disconnect_chnl 1715 * 1716 * Description Disconnect a channel. Typically, this is due to either 1717 * receiving a bad configuration, bad packet or max_retries 1718 * expiring. 1719 * 1720 ******************************************************************************/ 1721 void l2cu_disconnect_chnl(tL2C_CCB* p_ccb) { 1722 uint16_t local_cid = p_ccb->local_cid; 1723 1724 if (local_cid >= L2CAP_BASE_APPL_CID) { 1725 tL2CA_DISCONNECT_IND_CB* p_disc_cb = 1726 p_ccb->p_rcb->api.pL2CA_DisconnectInd_Cb; 1727 1728 L2CAP_TRACE_WARNING("L2CAP - disconnect_chnl CID: 0x%04x", local_cid); 1729 1730 l2cu_send_peer_disc_req(p_ccb); 1731 1732 l2cu_release_ccb(p_ccb); 1733 1734 (*p_disc_cb)(local_cid, false); 1735 } else { 1736 /* failure on the AMP channel, probably need to disconnect ACL */ 1737 L2CAP_TRACE_ERROR("L2CAP - disconnect_chnl CID: 0x%04x Ignored", local_cid); 1738 } 1739 } 1740 1741 /******************************************************************************* 1742 * 1743 * Function l2cu_find_rcb_by_psm 1744 * 1745 * Description Look through the Registration Control Blocks to see if 1746 * anyone registered to handle the PSM in question 1747 * 1748 * Returns Pointer to the RCB or NULL if not found 1749 * 1750 ******************************************************************************/ 1751 tL2C_RCB* l2cu_find_rcb_by_psm(uint16_t psm) { 1752 tL2C_RCB* p_rcb = &l2cb.rcb_pool[0]; 1753 uint16_t xx; 1754 1755 for (xx = 0; xx < MAX_L2CAP_CLIENTS; xx++, p_rcb++) { 1756 if ((p_rcb->in_use) && (p_rcb->psm == psm)) return (p_rcb); 1757 } 1758 1759 /* If here, no match found */ 1760 return (NULL); 1761 } 1762 1763 /******************************************************************************* 1764 * 1765 * Function l2cu_find_ble_rcb_by_psm 1766 * 1767 * Description Look through the BLE Registration Control Blocks to see if 1768 * anyone registered to handle the PSM in question 1769 * 1770 * Returns Pointer to the BLE RCB or NULL if not found 1771 * 1772 ******************************************************************************/ 1773 tL2C_RCB* l2cu_find_ble_rcb_by_psm(uint16_t psm) { 1774 tL2C_RCB* p_rcb = &l2cb.ble_rcb_pool[0]; 1775 uint16_t xx; 1776 1777 for (xx = 0; xx < BLE_MAX_L2CAP_CLIENTS; xx++, p_rcb++) { 1778 if ((p_rcb->in_use) && (p_rcb->psm == psm)) return (p_rcb); 1779 } 1780 1781 /* If here, no match found */ 1782 return (NULL); 1783 } 1784 1785 /******************************************************************************* 1786 * 1787 * Function l2cu_process_peer_cfg_req 1788 * 1789 * Description This function is called when the peer sends us a "config 1790 * request" message. It extracts the configuration of interest 1791 * and saves it in the CCB. 1792 * 1793 * Note: Negotiation of the FCR channel type is handled 1794 * internally, all others are passed to the upper layer. 1795 * 1796 * Returns uint8_t - L2CAP_PEER_CFG_OK if passed to upper layer, 1797 * L2CAP_PEER_CFG_UNACCEPTABLE if automatically 1798 * responded to because parameters are 1799 * unnacceptable from a specification point 1800 * of view. 1801 * L2CAP_PEER_CFG_DISCONNECT if no compatible channel 1802 * modes between the two devices, and shall 1803 * be closed. 1804 * 1805 ******************************************************************************/ 1806 uint8_t l2cu_process_peer_cfg_req(tL2C_CCB* p_ccb, tL2CAP_CFG_INFO* p_cfg) { 1807 bool mtu_ok = true; 1808 bool qos_type_ok = true; 1809 bool flush_to_ok = true; 1810 bool fcr_ok = true; 1811 uint8_t fcr_status; 1812 uint16_t required_remote_mtu = 1813 std::max<uint16_t>(L2CAP_MIN_MTU, p_ccb->p_rcb->required_remote_mtu); 1814 1815 /* Ignore FCR parameters for basic mode */ 1816 if (!p_cfg->fcr_present) p_cfg->fcr.mode = L2CAP_FCR_BASIC_MODE; 1817 1818 if (!p_cfg->mtu_present && required_remote_mtu > L2CAP_DEFAULT_MTU) { 1819 // We reject if we have a MTU requirement higher than default MTU 1820 p_cfg->mtu = required_remote_mtu; 1821 mtu_ok = false; 1822 } else if (p_cfg->mtu_present) { 1823 /* Make sure MTU is at least the minimum */ 1824 if (p_cfg->mtu >= required_remote_mtu) { 1825 /* In basic mode, limit the MTU to our buffer size */ 1826 if ((!p_cfg->fcr_present) && (p_cfg->mtu > L2CAP_MTU_SIZE)) 1827 p_cfg->mtu = L2CAP_MTU_SIZE; 1828 1829 /* Save the accepted value in case of renegotiation */ 1830 p_ccb->peer_cfg.mtu = p_cfg->mtu; 1831 p_ccb->peer_cfg.mtu_present = true; 1832 } else /* Illegal MTU value */ 1833 { 1834 p_cfg->mtu = required_remote_mtu; 1835 mtu_ok = false; 1836 } 1837 } 1838 /* Reload mtu from a previously accepted config request */ 1839 else if (p_ccb->peer_cfg.mtu_present && !(p_ccb->config_done & IB_CFG_DONE)) { 1840 p_cfg->mtu_present = true; 1841 p_cfg->mtu = p_ccb->peer_cfg.mtu; 1842 } 1843 1844 /* Verify that the flush timeout is a valid value (0 is illegal) */ 1845 if (p_cfg->flush_to_present) { 1846 if (!p_cfg->flush_to) { 1847 p_cfg->flush_to = 0xFFFF; /* Infinite retransmissions (spec default) */ 1848 flush_to_ok = false; 1849 } else /* Save the accepted value in case of renegotiation */ 1850 { 1851 p_ccb->peer_cfg.flush_to_present = true; 1852 p_ccb->peer_cfg.flush_to = p_cfg->flush_to; 1853 } 1854 } 1855 /* Reload flush_to from a previously accepted config request */ 1856 else if (p_ccb->peer_cfg.flush_to_present && 1857 !(p_ccb->config_done & IB_CFG_DONE)) { 1858 p_cfg->flush_to_present = true; 1859 p_cfg->flush_to = p_ccb->peer_cfg.flush_to; 1860 } 1861 1862 /* Save the QOS settings the the peer is using */ 1863 if (p_cfg->qos_present) { 1864 /* Make sure service type is not a reserved value; otherwise let upper 1865 layer decide if acceptable 1866 */ 1867 if (p_cfg->qos.service_type <= SVC_TYPE_GUARANTEED) { 1868 p_ccb->peer_cfg.qos = p_cfg->qos; 1869 p_ccb->peer_cfg.qos_present = true; 1870 } else /* Illegal service type value */ 1871 { 1872 p_cfg->qos.service_type = SVC_TYPE_BEST_EFFORT; 1873 qos_type_ok = false; 1874 } 1875 } 1876 /* Reload QOS from a previously accepted config request */ 1877 else if (p_ccb->peer_cfg.qos_present && !(p_ccb->config_done & IB_CFG_DONE)) { 1878 p_cfg->qos_present = true; 1879 p_cfg->qos = p_ccb->peer_cfg.qos; 1880 } 1881 1882 fcr_status = l2c_fcr_process_peer_cfg_req(p_ccb, p_cfg); 1883 if (fcr_status == L2CAP_PEER_CFG_DISCONNECT) { 1884 /* Notify caller to disconnect the channel (incompatible modes) */ 1885 p_cfg->result = L2CAP_CFG_FAILED_NO_REASON; 1886 p_cfg->mtu_present = p_cfg->qos_present = p_cfg->flush_to_present = 0; 1887 1888 return (L2CAP_PEER_CFG_DISCONNECT); 1889 } 1890 1891 fcr_ok = (fcr_status == L2CAP_PEER_CFG_OK); 1892 1893 /* Return any unacceptable parameters */ 1894 if (mtu_ok && flush_to_ok && qos_type_ok && fcr_ok) { 1895 l2cu_adjust_out_mps(p_ccb); 1896 return (L2CAP_PEER_CFG_OK); 1897 } else { 1898 p_cfg->result = L2CAP_CFG_UNACCEPTABLE_PARAMS; 1899 1900 if (mtu_ok) p_cfg->mtu_present = false; 1901 if (flush_to_ok) p_cfg->flush_to_present = false; 1902 if (qos_type_ok) p_cfg->qos_present = false; 1903 if (fcr_ok) p_cfg->fcr_present = false; 1904 1905 return (L2CAP_PEER_CFG_UNACCEPTABLE); 1906 } 1907 } 1908 1909 /******************************************************************************* 1910 * 1911 * Function l2cu_process_peer_cfg_rsp 1912 * 1913 * Description This function is called when the peer sends us a "config 1914 * response" message. It extracts the configuration of interest 1915 * and saves it in the CCB. 1916 * 1917 * Returns void 1918 * 1919 ******************************************************************************/ 1920 void l2cu_process_peer_cfg_rsp(tL2C_CCB* p_ccb, tL2CAP_CFG_INFO* p_cfg) { 1921 /* If we wanted QoS and the peer sends us a positive response with QoS, use 1922 * his values */ 1923 if ((p_cfg->qos_present) && (p_ccb->our_cfg.qos_present)) 1924 p_ccb->our_cfg.qos = p_cfg->qos; 1925 1926 if (p_cfg->fcr_present) { 1927 /* Save the retransmission and monitor timeout values */ 1928 if (p_cfg->fcr.mode == L2CAP_FCR_ERTM_MODE) { 1929 p_ccb->peer_cfg.fcr.rtrans_tout = p_cfg->fcr.rtrans_tout; 1930 p_ccb->peer_cfg.fcr.mon_tout = p_cfg->fcr.mon_tout; 1931 } 1932 1933 /* Calculate the max number of packets for which we can delay sending an ack 1934 */ 1935 if (p_cfg->fcr.tx_win_sz < p_ccb->our_cfg.fcr.tx_win_sz) 1936 p_ccb->fcrb.max_held_acks = p_cfg->fcr.tx_win_sz / 3; 1937 else 1938 p_ccb->fcrb.max_held_acks = p_ccb->our_cfg.fcr.tx_win_sz / 3; 1939 1940 L2CAP_TRACE_DEBUG( 1941 "l2cu_process_peer_cfg_rsp(): peer tx_win_sz: %d, our tx_win_sz: %d, " 1942 "max_held_acks: %d", 1943 p_cfg->fcr.tx_win_sz, p_ccb->our_cfg.fcr.tx_win_sz, 1944 p_ccb->fcrb.max_held_acks); 1945 } 1946 } 1947 1948 /******************************************************************************* 1949 * 1950 * Function l2cu_process_our_cfg_req 1951 * 1952 * Description This function is called when we send a "config request" 1953 * message. It extracts the configuration of interest and saves 1954 * it in the CCB. 1955 * 1956 * Returns void 1957 * 1958 ******************************************************************************/ 1959 void l2cu_process_our_cfg_req(tL2C_CCB* p_ccb, tL2CAP_CFG_INFO* p_cfg) { 1960 /* Save the QOS settings we are using for transmit */ 1961 if (p_cfg->qos_present) { 1962 p_ccb->our_cfg.qos_present = true; 1963 p_ccb->our_cfg.qos = p_cfg->qos; 1964 } 1965 1966 if (p_cfg->fcr_present) { 1967 /* Override FCR options if attempting streaming or basic */ 1968 if (p_cfg->fcr.mode == L2CAP_FCR_BASIC_MODE) 1969 memset(&p_cfg->fcr, 0, sizeof(tL2CAP_FCR_OPTS)); 1970 else { 1971 /* On BR/EDR, timer values are zero in config request */ 1972 /* On class 2 AMP, timer value in config request shall be non-0 processing 1973 * time */ 1974 /* timer value in config response shall be greater than 1975 * received processing time */ 1976 p_cfg->fcr.mon_tout = p_cfg->fcr.rtrans_tout = 0; 1977 } 1978 1979 /* Set the threshold to send acks (may be updated in the cfg response) */ 1980 p_ccb->fcrb.max_held_acks = p_cfg->fcr.tx_win_sz / 3; 1981 1982 /* Include FCS option only if peer can handle it */ 1983 if ((p_ccb->p_lcb->peer_ext_fea & L2CAP_EXTFEA_NO_CRC) == 0) { 1984 p_cfg->fcs_present = false; 1985 } 1986 } else { 1987 p_cfg->fcr.mode = L2CAP_FCR_BASIC_MODE; 1988 } 1989 1990 p_ccb->our_cfg.fcr.mode = p_cfg->fcr.mode; 1991 p_ccb->our_cfg.fcr_present = p_cfg->fcr_present; 1992 } 1993 1994 /******************************************************************************* 1995 * 1996 * Function l2cu_process_our_cfg_rsp 1997 * 1998 * Description This function is called when we send the peer a "config 1999 * response" message. It extracts the configuration of interest 2000 * and saves it in the CCB. 2001 * 2002 * Returns void 2003 * 2004 ******************************************************************************/ 2005 void l2cu_process_our_cfg_rsp(tL2C_CCB* p_ccb, tL2CAP_CFG_INFO* p_cfg) { 2006 /* If peer wants QoS, we are allowed to change the values in a positive 2007 * response */ 2008 if ((p_cfg->qos_present) && (p_ccb->peer_cfg.qos_present)) 2009 p_ccb->peer_cfg.qos = p_cfg->qos; 2010 else 2011 p_cfg->qos_present = false; 2012 2013 l2c_fcr_adj_our_rsp_options(p_ccb, p_cfg); 2014 } 2015 2016 /******************************************************************************* 2017 * 2018 * Function l2cu_device_reset 2019 * 2020 * Description This function is called when reset of the device is 2021 * completed. For all active connection simulate HCI_DISC 2022 * 2023 * Returns void 2024 * 2025 ******************************************************************************/ 2026 void l2cu_device_reset(void) { 2027 if (bluetooth::shim::is_gd_l2cap_enabled()) { 2028 return; 2029 } 2030 2031 int xx; 2032 tL2C_LCB* p_lcb = &l2cb.lcb_pool[0]; 2033 2034 for (xx = 0; xx < MAX_L2CAP_LINKS; xx++, p_lcb++) { 2035 if ((p_lcb->in_use) && (p_lcb->Handle() != HCI_INVALID_HANDLE)) { 2036 l2c_link_hci_disc_comp(p_lcb->Handle(), HCI_ERR_UNDEFINED); 2037 } 2038 } 2039 } 2040 2041 /* This function initiates an acl connection to a LE device. 2042 * Returns true if request started successfully, false otherwise. */ 2043 bool l2cu_create_conn_le(tL2C_LCB* p_lcb) { 2044 if (!controller_get_interface()->supports_ble()) return false; 2045 p_lcb->transport = BT_TRANSPORT_LE; 2046 return (l2cble_create_conn(p_lcb)); 2047 } 2048 2049 /* This function initiates an acl connection to a Classic device via HCI. */ 2050 void l2cu_create_conn_br_edr(tL2C_LCB* p_lcb) { 2051 const bool controller_supports_role_switch = 2052 controller_get_interface()->supports_role_switch(); 2053 2054 /* While creating a new classic connection, check check all the other 2055 * active connections where we are not SCO nor central. 2056 * If our controller supports role switching, try switching 2057 * roles back to CENTRAL on those connections. 2058 */ 2059 tL2C_LCB* p_lcb_cur = &l2cb.lcb_pool[0]; 2060 for (uint8_t xx = 0; xx < MAX_L2CAP_LINKS; xx++, p_lcb_cur++) { 2061 if (p_lcb_cur == p_lcb) continue; 2062 if (!p_lcb_cur->in_use) continue; 2063 if (BTM_IsScoActiveByBdaddr(p_lcb_cur->remote_bd_addr)) { 2064 L2CAP_TRACE_DEBUG( 2065 "%s Central peripheral switch not allowed when SCO active", __func__); 2066 continue; 2067 } 2068 if (p_lcb->IsLinkRoleCentral()) continue; 2069 /* The LMP_switch_req shall be sent only if the ACL logical transport 2070 is in active mode, when encryption is disabled, and all synchronous 2071 logical transports on the same physical link are disabled." */ 2072 2073 /*4_1_TODO check if btm_cb.devcb.local_features to be used instead */ 2074 if (controller_supports_role_switch) { 2075 /* mark this lcb waiting for switch to be completed and 2076 start switch on the other one */ 2077 p_lcb->link_state = LST_CONNECTING_WAIT_SWITCH; 2078 p_lcb->SetLinkRoleAsCentral(); 2079 2080 if (BTM_SwitchRoleToCentral(p_lcb_cur->remote_bd_addr) == 2081 BTM_CMD_STARTED) { 2082 alarm_set_on_mloop(p_lcb->l2c_lcb_timer, 2083 L2CAP_LINK_ROLE_SWITCH_TIMEOUT_MS, 2084 l2c_lcb_timer_timeout, p_lcb); 2085 return; 2086 } 2087 } 2088 } 2089 p_lcb->link_state = LST_CONNECTING; 2090 l2cu_create_conn_after_switch(p_lcb); 2091 } 2092 2093 /******************************************************************************* 2094 * 2095 * Function l2cu_get_num_hi_priority 2096 * 2097 * Description Gets the number of high priority channels. 2098 * 2099 * Returns 2100 * 2101 ******************************************************************************/ 2102 uint8_t l2cu_get_num_hi_priority(void) { 2103 uint8_t no_hi = 0; 2104 int xx; 2105 tL2C_LCB* p_lcb = &l2cb.lcb_pool[0]; 2106 2107 for (xx = 0; xx < MAX_L2CAP_LINKS; xx++, p_lcb++) { 2108 if ((p_lcb->in_use) && (p_lcb->acl_priority == L2CAP_PRIORITY_HIGH)) { 2109 no_hi++; 2110 } 2111 } 2112 return no_hi; 2113 } 2114 2115 /******************************************************************************* 2116 * 2117 * Function l2cu_create_conn_after_switch 2118 * 2119 * Description This continues a connection creation possibly after 2120 * a role switch. 2121 * 2122 ******************************************************************************/ 2123 void l2cu_create_conn_after_switch(tL2C_LCB* p_lcb) { 2124 const bool there_are_high_priority_channels = 2125 (l2cu_get_num_hi_priority() > 0); 2126 2127 acl_create_classic_connection(p_lcb->remote_bd_addr, 2128 there_are_high_priority_channels, 2129 p_lcb->IsBonding()); 2130 2131 alarm_set_on_mloop(p_lcb->l2c_lcb_timer, L2CAP_LINK_CONNECT_TIMEOUT_MS, 2132 l2c_lcb_timer_timeout, p_lcb); 2133 } 2134 2135 /******************************************************************************* 2136 * 2137 * Function l2cu_find_lcb_by_state 2138 * 2139 * Description Look through all active LCBs for a match based on the 2140 * LCB state. 2141 * 2142 * Returns pointer to first matched LCB, or NULL if no match 2143 * 2144 ******************************************************************************/ 2145 tL2C_LCB* l2cu_find_lcb_by_state(tL2C_LINK_STATE state) { 2146 uint16_t i; 2147 tL2C_LCB* p_lcb = &l2cb.lcb_pool[0]; 2148 2149 for (i = 0; i < MAX_L2CAP_LINKS; i++, p_lcb++) { 2150 if ((p_lcb->in_use) && (p_lcb->link_state == state)) { 2151 return (p_lcb); 2152 } 2153 } 2154 2155 /* If here, no match found */ 2156 return (NULL); 2157 } 2158 2159 /******************************************************************************* 2160 * 2161 * Function l2cu_lcb_disconnecting 2162 * 2163 * Description On each active lcb, check if the lcb is in disconnecting 2164 * state, or if there are no ccb's on the lcb (implying 2165 idle timeout is running), or if last ccb on the link 2166 is in disconnecting state. 2167 * 2168 * Returns true if any of above conditions met, false otherwise 2169 * 2170 ******************************************************************************/ 2171 bool l2cu_lcb_disconnecting(void) { 2172 tL2C_LCB* p_lcb; 2173 tL2C_CCB* p_ccb; 2174 uint16_t i; 2175 bool status = false; 2176 2177 p_lcb = &l2cb.lcb_pool[0]; 2178 2179 for (i = 0; i < MAX_L2CAP_LINKS; i++, p_lcb++) { 2180 if (p_lcb->in_use) { 2181 /* no ccbs on lcb, or lcb is in disconnecting state */ 2182 if ((!p_lcb->ccb_queue.p_first_ccb) || 2183 (p_lcb->link_state == LST_DISCONNECTING)) { 2184 status = true; 2185 break; 2186 } 2187 /* only one ccb left on lcb */ 2188 else if (p_lcb->ccb_queue.p_first_ccb == p_lcb->ccb_queue.p_last_ccb) { 2189 p_ccb = p_lcb->ccb_queue.p_first_ccb; 2190 2191 if ((p_ccb->in_use) && 2192 ((p_ccb->chnl_state == CST_W4_L2CAP_DISCONNECT_RSP) || 2193 (p_ccb->chnl_state == CST_W4_L2CA_DISCONNECT_RSP))) { 2194 status = true; 2195 break; 2196 } 2197 } 2198 } 2199 } 2200 return status; 2201 } 2202 2203 /******************************************************************************* 2204 * 2205 * Function l2cu_set_acl_priority 2206 * 2207 * Description Sets the transmission priority for a channel. 2208 * (For initial implementation only two values are valid. 2209 * L2CAP_PRIORITY_NORMAL and L2CAP_PRIORITY_HIGH). 2210 * 2211 * Returns true if a valid channel, else false 2212 * 2213 ******************************************************************************/ 2214 2215 bool l2cu_set_acl_priority(const RawAddress& bd_addr, tL2CAP_PRIORITY priority, 2216 bool reset_after_rs) { 2217 tL2C_LCB* p_lcb; 2218 uint8_t* pp; 2219 uint8_t command[HCI_BRCM_ACL_PRIORITY_PARAM_SIZE]; 2220 uint8_t vs_param; 2221 2222 APPL_TRACE_EVENT("SET ACL PRIORITY %d", priority); 2223 2224 /* Find the link control block for the acl channel */ 2225 p_lcb = l2cu_find_lcb_by_bd_addr(bd_addr, BT_TRANSPORT_BR_EDR); 2226 if (p_lcb == NULL) { 2227 L2CAP_TRACE_WARNING("L2CAP - no LCB for L2CA_SetAclPriority"); 2228 return (false); 2229 } 2230 2231 if (controller_get_interface()->get_bt_version()->manufacturer == 2232 LMP_COMPID_BROADCOM) { 2233 /* Called from above L2CAP through API; send VSC if changed */ 2234 if ((!reset_after_rs && (priority != p_lcb->acl_priority)) || 2235 /* Called because of a central/peripheral role switch; if high resend 2236 VSC */ 2237 (reset_after_rs && p_lcb->acl_priority == L2CAP_PRIORITY_HIGH)) { 2238 pp = command; 2239 2240 vs_param = (priority == L2CAP_PRIORITY_HIGH) ? HCI_BRCM_ACL_PRIORITY_HIGH 2241 : HCI_BRCM_ACL_PRIORITY_LOW; 2242 2243 UINT16_TO_STREAM(pp, p_lcb->Handle()); 2244 UINT8_TO_STREAM(pp, vs_param); 2245 2246 BTM_VendorSpecificCommand(HCI_BRCM_SET_ACL_PRIORITY, 2247 HCI_BRCM_ACL_PRIORITY_PARAM_SIZE, command, 2248 NULL); 2249 } 2250 } 2251 2252 /* Adjust lmp buffer allocation for this channel if priority changed */ 2253 if (p_lcb->acl_priority != priority) { 2254 p_lcb->acl_priority = priority; 2255 l2c_link_adjust_allocation(); 2256 } 2257 return (true); 2258 } 2259 2260 /****************************************************************************** 2261 * 2262 * Function l2cu_set_non_flushable_pbf 2263 * 2264 * Description set L2CAP_PKT_START_NON_FLUSHABLE if controller supoorts 2265 * 2266 * Returns void 2267 * 2268 ******************************************************************************/ 2269 void l2cu_set_non_flushable_pbf(bool is_supported) { 2270 if (bluetooth::shim::is_gd_l2cap_enabled()) { 2271 return; 2272 } 2273 2274 if (is_supported) 2275 l2cb.non_flushable_pbf = 2276 (L2CAP_PKT_START_NON_FLUSHABLE << L2CAP_PKT_TYPE_SHIFT); 2277 else 2278 l2cb.non_flushable_pbf = (L2CAP_PKT_START << L2CAP_PKT_TYPE_SHIFT); 2279 } 2280 2281 /******************************************************************************* 2282 * 2283 * Function l2cu_resubmit_pending_sec_req 2284 * 2285 * Description This function is called when required security procedures 2286 * are completed and any pending requests can be re-submitted. 2287 * 2288 * Returns void 2289 * 2290 ******************************************************************************/ 2291 void l2cu_resubmit_pending_sec_req(const RawAddress* p_bda) { 2292 if (bluetooth::shim::is_gd_l2cap_enabled()) { 2293 // GD L2cap will enforce security when condition changed 2294 return; 2295 } 2296 2297 tL2C_LCB* p_lcb; 2298 tL2C_CCB* p_ccb; 2299 tL2C_CCB* p_next_ccb; 2300 int xx; 2301 2302 L2CAP_TRACE_DEBUG("l2cu_resubmit_pending_sec_req p_bda: 0x%08x", p_bda); 2303 2304 /* If we are called with a BDA, only resubmit for that BDA */ 2305 if (p_bda) { 2306 p_lcb = l2cu_find_lcb_by_bd_addr(*p_bda, BT_TRANSPORT_BR_EDR); 2307 2308 /* If we don't have one, this is an error */ 2309 if (p_lcb) { 2310 /* For all channels, send the event through their FSMs */ 2311 for (p_ccb = p_lcb->ccb_queue.p_first_ccb; p_ccb; p_ccb = p_next_ccb) { 2312 p_next_ccb = p_ccb->p_next_ccb; 2313 l2c_csm_execute(p_ccb, L2CEVT_SEC_RE_SEND_CMD, NULL); 2314 } 2315 } else { 2316 L2CAP_TRACE_WARNING("l2cu_resubmit_pending_sec_req - unknown BD_ADDR"); 2317 } 2318 } else { 2319 /* No BDA pasesed in, so check all links */ 2320 for (xx = 0, p_lcb = &l2cb.lcb_pool[0]; xx < MAX_L2CAP_LINKS; 2321 xx++, p_lcb++) { 2322 if (p_lcb->in_use) { 2323 /* For all channels, send the event through their FSMs */ 2324 for (p_ccb = p_lcb->ccb_queue.p_first_ccb; p_ccb; p_ccb = p_next_ccb) { 2325 p_next_ccb = p_ccb->p_next_ccb; 2326 l2c_csm_execute(p_ccb, L2CEVT_SEC_RE_SEND_CMD, NULL); 2327 } 2328 } 2329 } 2330 } 2331 } 2332 2333 #if (L2CAP_CONFORMANCE_TESTING == TRUE) 2334 /******************************************************************************* 2335 * 2336 * Function l2cu_set_info_rsp_mask 2337 * 2338 * Description This function allows the script wrapper to change the 2339 * info resp mask for conformance testing. 2340 * 2341 * Returns pointer to CCB, or NULL if none 2342 * 2343 ******************************************************************************/ 2344 void l2cu_set_info_rsp_mask(uint32_t mask) { l2cb.test_info_resp = mask; } 2345 #endif /* L2CAP_CONFORMANCE_TESTING */ 2346 2347 /******************************************************************************* 2348 * 2349 * Function l2cu_adjust_out_mps 2350 * 2351 * Description Sets our MPS based on current controller capabilities 2352 * 2353 * Returns void 2354 * 2355 ******************************************************************************/ 2356 void l2cu_adjust_out_mps(tL2C_CCB* p_ccb) { 2357 uint16_t packet_size; 2358 2359 /* on the tx side MTU is selected based on packet size of the controller */ 2360 packet_size = BTM_GetMaxPacketSize(p_ccb->p_lcb->remote_bd_addr); 2361 2362 if (packet_size <= (L2CAP_PKT_OVERHEAD + L2CAP_FCR_OVERHEAD + 2363 L2CAP_SDU_LEN_OVERHEAD + L2CAP_FCS_LEN)) { 2364 /* something is very wrong */ 2365 L2CAP_TRACE_ERROR( 2366 "l2cu_adjust_out_mps bad packet size: %u will use MPS: %u", 2367 packet_size, p_ccb->peer_cfg.fcr.mps); 2368 p_ccb->tx_mps = p_ccb->peer_cfg.fcr.mps; 2369 } else { 2370 packet_size -= (L2CAP_PKT_OVERHEAD + L2CAP_FCR_OVERHEAD + 2371 L2CAP_SDU_LEN_OVERHEAD + L2CAP_FCS_LEN); 2372 2373 /* We try to negotiate MTU that each packet can be split into whole 2374 number of max packets. For example if link is 1.2 max packet size is 339 2375 bytes. 2376 At first calculate how many whole packets it is. MAX L2CAP is 1691 + 4 2377 overhead. 2378 1695, that will be 5 Dh5 packets. Now maximum L2CAP packet is 2379 5 * 339 = 1695. Minus 4 bytes L2CAP header 1691. 2380 2381 For EDR 2.0 packet size is 1027. So we better send RFCOMM packet as 1 3DH5 2382 packet 2383 1 * 1027 = 1027. Minus 4 bytes L2CAP header 1023. */ 2384 if (p_ccb->peer_cfg.fcr.mps >= packet_size) 2385 p_ccb->tx_mps = p_ccb->peer_cfg.fcr.mps / packet_size * packet_size; 2386 else 2387 p_ccb->tx_mps = p_ccb->peer_cfg.fcr.mps; 2388 2389 L2CAP_TRACE_DEBUG( 2390 "l2cu_adjust_out_mps use %d Based on peer_cfg.fcr.mps: %u " 2391 "packet_size: %u", 2392 p_ccb->tx_mps, p_ccb->peer_cfg.fcr.mps, packet_size); 2393 } 2394 } 2395 2396 /******************************************************************************* 2397 * 2398 * Function l2cu_initialize_fixed_ccb 2399 * 2400 * Description Initialize a fixed channel's CCB 2401 * 2402 * Returns true or false 2403 * 2404 ******************************************************************************/ 2405 bool l2cu_initialize_fixed_ccb(tL2C_LCB* p_lcb, uint16_t fixed_cid) { 2406 tL2C_CCB* p_ccb; 2407 2408 /* If we already have a CCB, then simply return */ 2409 p_ccb = p_lcb->p_fixed_ccbs[fixed_cid - L2CAP_FIRST_FIXED_CHNL]; 2410 if ((p_ccb != NULL) && p_ccb->in_use) { 2411 /* 2412 * NOTE: The "in_use" check is needed to ignore leftover entries 2413 * that have been already released by l2cu_release_ccb(). 2414 */ 2415 return (true); 2416 } 2417 2418 p_ccb = l2cu_allocate_ccb(NULL, 0); 2419 if (p_ccb == NULL) return (false); 2420 2421 alarm_cancel(p_lcb->l2c_lcb_timer); 2422 2423 /* Set CID for the connection */ 2424 p_ccb->local_cid = fixed_cid; 2425 p_ccb->remote_cid = fixed_cid; 2426 2427 p_ccb->is_flushable = false; 2428 2429 /* Link ccb to lcb and lcb to ccb */ 2430 p_lcb->p_fixed_ccbs[fixed_cid - L2CAP_FIRST_FIXED_CHNL] = p_ccb; 2431 p_ccb->p_lcb = p_lcb; 2432 2433 /* There is no configuration, so if the link is up, the channel is up */ 2434 if (p_lcb->link_state == LST_CONNECTED) p_ccb->chnl_state = CST_OPEN; 2435 2436 /* Set the default idle timeout value to use */ 2437 p_ccb->fixed_chnl_idle_tout = 2438 l2cb.fixed_reg[fixed_cid - L2CAP_FIRST_FIXED_CHNL].default_idle_tout; 2439 return (true); 2440 } 2441 2442 /******************************************************************************* 2443 * 2444 * Function l2cu_no_dynamic_ccbs 2445 * 2446 * Description Handles the case when there are no more dynamic CCBs. If 2447 * there are any fixed CCBs, start the longest of the fixed CCB 2448 * timeouts, otherwise start the default link idle timeout or 2449 * disconnect. 2450 * 2451 * Returns void 2452 * 2453 ******************************************************************************/ 2454 void l2cu_no_dynamic_ccbs(tL2C_LCB* p_lcb) { 2455 tBTM_STATUS rc; 2456 uint64_t timeout_ms = p_lcb->idle_timeout * 1000; 2457 bool start_timeout = true; 2458 2459 int xx; 2460 2461 for (xx = 0; xx < L2CAP_NUM_FIXED_CHNLS; xx++) { 2462 if ((p_lcb->p_fixed_ccbs[xx] != NULL) && 2463 (p_lcb->p_fixed_ccbs[xx]->fixed_chnl_idle_tout * 1000 > timeout_ms)) { 2464 2465 if (p_lcb->p_fixed_ccbs[xx]->fixed_chnl_idle_tout == L2CAP_NO_IDLE_TIMEOUT) { 2466 L2CAP_TRACE_DEBUG("%s NO IDLE timeout set for fixed cid 0x%04x", __func__, 2467 p_lcb->p_fixed_ccbs[xx]->local_cid); 2468 start_timeout = false; 2469 } 2470 timeout_ms = p_lcb->p_fixed_ccbs[xx]->fixed_chnl_idle_tout * 1000; 2471 } 2472 } 2473 2474 /* If the link is pairing, do not mess with the timeouts */ 2475 if (p_lcb->IsBonding()) return; 2476 2477 if (timeout_ms == 0) { 2478 L2CAP_TRACE_DEBUG( 2479 "l2cu_no_dynamic_ccbs() IDLE timer 0, disconnecting link"); 2480 2481 rc = btm_sec_disconnect(p_lcb->Handle(), HCI_ERR_PEER_USER); 2482 if (rc == BTM_CMD_STARTED) { 2483 l2cu_process_fixed_disc_cback(p_lcb); 2484 p_lcb->link_state = LST_DISCONNECTING; 2485 timeout_ms = L2CAP_LINK_DISCONNECT_TIMEOUT_MS; 2486 } else if (rc == BTM_SUCCESS) { 2487 l2cu_process_fixed_disc_cback(p_lcb); 2488 /* BTM SEC will make sure that link is release (probably after pairing is 2489 * done) */ 2490 p_lcb->link_state = LST_DISCONNECTING; 2491 start_timeout = false; 2492 } else if (p_lcb->IsBonding()) { 2493 acl_disconnect_from_handle(p_lcb->Handle(), HCI_ERR_PEER_USER); 2494 l2cu_process_fixed_disc_cback(p_lcb); 2495 p_lcb->link_state = LST_DISCONNECTING; 2496 timeout_ms = L2CAP_LINK_DISCONNECT_TIMEOUT_MS; 2497 } else { 2498 /* probably no buffer to send disconnect */ 2499 timeout_ms = BT_1SEC_TIMEOUT_MS; 2500 } 2501 } 2502 2503 if (start_timeout) { 2504 L2CAP_TRACE_DEBUG("%s starting IDLE timeout: %d ms", __func__, timeout_ms); 2505 alarm_set_on_mloop(p_lcb->l2c_lcb_timer, timeout_ms, l2c_lcb_timer_timeout, 2506 p_lcb); 2507 } else { 2508 alarm_cancel(p_lcb->l2c_lcb_timer); 2509 } 2510 } 2511 2512 /******************************************************************************* 2513 * 2514 * Function l2cu_process_fixed_chnl_resp 2515 * 2516 * Description handle a fixed channel response (or lack thereof) 2517 * if the link failed, or a fixed channel response was 2518 * not received, the bitfield is all zeros. 2519 * 2520 ******************************************************************************/ 2521 void l2cu_process_fixed_chnl_resp(tL2C_LCB* p_lcb) { 2522 if (p_lcb->transport == BT_TRANSPORT_BR_EDR) { 2523 /* ignore all not assigned BR/EDR channels */ 2524 p_lcb->peer_chnl_mask[0] &= 2525 (L2CAP_FIXED_CHNL_SIG_BIT | L2CAP_FIXED_CHNL_CNCTLESS_BIT | 2526 L2CAP_FIXED_CHNL_SMP_BR_BIT); 2527 } else 2528 p_lcb->peer_chnl_mask[0] = l2cb.l2c_ble_fixed_chnls_mask; 2529 2530 /* Tell all registered fixed channels about the connection */ 2531 for (int xx = 0; xx < L2CAP_NUM_FIXED_CHNLS; xx++) { 2532 uint16_t channel_id = xx + L2CAP_FIRST_FIXED_CHNL; 2533 2534 /* See BT Spec Ver 5.0 | Vol 3, Part A 2.1 table 2.1 and 2.2 */ 2535 2536 /* skip sending LE fix channel callbacks on BR/EDR links */ 2537 if (p_lcb->transport == BT_TRANSPORT_BR_EDR && 2538 channel_id >= L2CAP_ATT_CID && channel_id <= L2CAP_SMP_CID) 2539 continue; 2540 2541 /* skip sending BR fix channel callbacks on LE links */ 2542 if (p_lcb->transport == BT_TRANSPORT_LE && channel_id == L2CAP_SMP_BR_CID) 2543 continue; 2544 2545 if (!l2cb.fixed_reg[xx].pL2CA_FixedConn_Cb) continue; 2546 2547 if (p_lcb->peer_chnl_mask[(channel_id) / 8] & (1 << ((channel_id) % 8))) { 2548 if (p_lcb->p_fixed_ccbs[xx]) 2549 p_lcb->p_fixed_ccbs[xx]->chnl_state = CST_OPEN; 2550 (*l2cb.fixed_reg[xx].pL2CA_FixedConn_Cb)( 2551 channel_id, p_lcb->remote_bd_addr, true, 0, p_lcb->transport); 2552 } else { 2553 (*l2cb.fixed_reg[xx].pL2CA_FixedConn_Cb)( 2554 channel_id, p_lcb->remote_bd_addr, false, p_lcb->DisconnectReason(), 2555 p_lcb->transport); 2556 2557 if (p_lcb->p_fixed_ccbs[xx]) { 2558 l2cu_release_ccb(p_lcb->p_fixed_ccbs[xx]); 2559 p_lcb->p_fixed_ccbs[xx] = NULL; 2560 } 2561 } 2562 } 2563 } 2564 2565 /******************************************************************************* 2566 * 2567 * Function l2cu_process_fixed_disc_cback 2568 * 2569 * Description send l2cap fixed channel disconnection callback to the 2570 * application 2571 * 2572 * Returns void 2573 * 2574 ******************************************************************************/ 2575 void l2cu_process_fixed_disc_cback(tL2C_LCB* p_lcb) { 2576 2577 /* Select peer channels mask to use depending on transport */ 2578 uint8_t peer_channel_mask = p_lcb->peer_chnl_mask[0]; 2579 2580 // For LE, reset the stored peer channel mask 2581 if (p_lcb->transport == BT_TRANSPORT_LE) p_lcb->peer_chnl_mask[0] = 0; 2582 2583 for (int xx = 0; xx < L2CAP_NUM_FIXED_CHNLS; xx++) { 2584 if (p_lcb->p_fixed_ccbs[xx]) { 2585 if (p_lcb->p_fixed_ccbs[xx] != p_lcb->p_pending_ccb) { 2586 tL2C_CCB* p_l2c_chnl_ctrl_block; 2587 p_l2c_chnl_ctrl_block = p_lcb->p_fixed_ccbs[xx]; 2588 p_lcb->p_fixed_ccbs[xx] = NULL; 2589 l2cu_release_ccb(p_l2c_chnl_ctrl_block); 2590 (*l2cb.fixed_reg[xx].pL2CA_FixedConn_Cb)( 2591 xx + L2CAP_FIRST_FIXED_CHNL, p_lcb->remote_bd_addr, false, 2592 p_lcb->DisconnectReason(), p_lcb->transport); 2593 } 2594 } else if ((peer_channel_mask & (1 << (xx + L2CAP_FIRST_FIXED_CHNL))) && 2595 (l2cb.fixed_reg[xx].pL2CA_FixedConn_Cb != NULL)) 2596 (*l2cb.fixed_reg[xx].pL2CA_FixedConn_Cb)( 2597 xx + L2CAP_FIRST_FIXED_CHNL, p_lcb->remote_bd_addr, false, 2598 p_lcb->DisconnectReason(), p_lcb->transport); 2599 } 2600 } 2601 2602 /******************************************************************************* 2603 * 2604 * Function l2cu_send_peer_ble_par_req 2605 * 2606 * Description Build and send a BLE parameter update request message 2607 * to the peer. 2608 * 2609 * Returns void 2610 * 2611 ******************************************************************************/ 2612 void l2cu_send_peer_ble_par_req(tL2C_LCB* p_lcb, uint16_t min_int, 2613 uint16_t max_int, uint16_t latency, 2614 uint16_t timeout) { 2615 BT_HDR* p_buf; 2616 uint8_t* p; 2617 2618 /* Create an identifier for this packet */ 2619 p_lcb->signal_id++; 2620 l2cu_adj_id(p_lcb); 2621 2622 p_buf = l2cu_build_header(p_lcb, L2CAP_CMD_BLE_UPD_REQ_LEN, 2623 L2CAP_CMD_BLE_UPDATE_REQ, p_lcb->signal_id); 2624 if (p_buf == NULL) { 2625 L2CAP_TRACE_WARNING("l2cu_send_peer_ble_par_req - no buffer"); 2626 return; 2627 } 2628 2629 p = (uint8_t*)(p_buf + 1) + L2CAP_SEND_CMD_OFFSET + HCI_DATA_PREAMBLE_SIZE + 2630 L2CAP_PKT_OVERHEAD + L2CAP_CMD_OVERHEAD; 2631 2632 UINT16_TO_STREAM(p, min_int); 2633 UINT16_TO_STREAM(p, max_int); 2634 UINT16_TO_STREAM(p, latency); 2635 UINT16_TO_STREAM(p, timeout); 2636 2637 l2c_link_check_send_pkts(p_lcb, 0, p_buf); 2638 } 2639 2640 /******************************************************************************* 2641 * 2642 * Function l2cu_send_peer_ble_par_rsp 2643 * 2644 * Description Build and send a BLE parameter update response message 2645 * to the peer. 2646 * 2647 * Returns void 2648 * 2649 ******************************************************************************/ 2650 void l2cu_send_peer_ble_par_rsp(tL2C_LCB* p_lcb, uint16_t reason, 2651 uint8_t rem_id) { 2652 BT_HDR* p_buf; 2653 uint8_t* p; 2654 2655 p_buf = l2cu_build_header(p_lcb, L2CAP_CMD_BLE_UPD_RSP_LEN, 2656 L2CAP_CMD_BLE_UPDATE_RSP, rem_id); 2657 if (p_buf == NULL) { 2658 L2CAP_TRACE_WARNING("l2cu_send_peer_ble_par_rsp - no buffer"); 2659 return; 2660 } 2661 2662 p = (uint8_t*)(p_buf + 1) + L2CAP_SEND_CMD_OFFSET + HCI_DATA_PREAMBLE_SIZE + 2663 L2CAP_PKT_OVERHEAD + L2CAP_CMD_OVERHEAD; 2664 2665 UINT16_TO_STREAM(p, reason); 2666 2667 l2c_link_check_send_pkts(p_lcb, 0, p_buf); 2668 } 2669 2670 /******************************************************************************* 2671 * 2672 * Function l2cu_send_peer_ble_credit_based_conn_req 2673 * 2674 * Description Build and send a BLE packet to establish LE connection 2675 * oriented L2CAP channel. 2676 * 2677 * Returns void 2678 * 2679 ******************************************************************************/ 2680 void l2cu_send_peer_ble_credit_based_conn_req(tL2C_CCB* p_ccb) { 2681 BT_HDR* p_buf; 2682 uint8_t* p; 2683 tL2C_LCB* p_lcb = NULL; 2684 uint16_t mtu; 2685 uint16_t mps; 2686 uint16_t initial_credit; 2687 2688 if (!p_ccb) return; 2689 p_lcb = p_ccb->p_lcb; 2690 2691 /* Create an identifier for this packet */ 2692 p_ccb->p_lcb->signal_id++; 2693 l2cu_adj_id(p_ccb->p_lcb); 2694 2695 p_ccb->local_id = p_ccb->p_lcb->signal_id; 2696 2697 p_buf = 2698 l2cu_build_header(p_lcb, L2CAP_CMD_BLE_CREDIT_BASED_CONN_REQ_LEN, 2699 L2CAP_CMD_BLE_CREDIT_BASED_CONN_REQ, p_lcb->signal_id); 2700 if (p_buf == NULL) { 2701 L2CAP_TRACE_WARNING("l2cu_send_peer_ble_credit_based_conn_req - no buffer"); 2702 return; 2703 } 2704 2705 p = (uint8_t*)(p_buf + 1) + L2CAP_SEND_CMD_OFFSET + HCI_DATA_PREAMBLE_SIZE + 2706 L2CAP_PKT_OVERHEAD + L2CAP_CMD_OVERHEAD; 2707 2708 mtu = p_ccb->local_conn_cfg.mtu; 2709 mps = p_ccb->local_conn_cfg.mps; 2710 initial_credit = p_ccb->local_conn_cfg.credits; 2711 2712 L2CAP_TRACE_DEBUG( 2713 "l2cu_send_peer_ble_credit_based_conn_req PSM:0x%04x local_cid:%d\ 2714 mtu:%d mps:%d initial_credit:%d", 2715 p_ccb->p_rcb->real_psm, p_ccb->local_cid, mtu, mps, initial_credit); 2716 2717 UINT16_TO_STREAM(p, p_ccb->p_rcb->real_psm); 2718 UINT16_TO_STREAM(p, p_ccb->local_cid); 2719 UINT16_TO_STREAM(p, mtu); 2720 UINT16_TO_STREAM(p, mps); 2721 UINT16_TO_STREAM(p, initial_credit); 2722 2723 l2c_link_check_send_pkts(p_lcb, 0, p_buf); 2724 } 2725 2726 /******************************************************************************* 2727 * 2728 * Function l2cu_send_peer_credit_based_conn_req 2729 * 2730 * Description Build and send a BLE packet to establish enhanced connection 2731 * oriented L2CAP channel. 2732 * 2733 * Returns void 2734 * 2735 ******************************************************************************/ 2736 void l2cu_send_peer_credit_based_conn_req(tL2C_CCB* p_ccb) { 2737 BT_HDR* p_buf; 2738 uint8_t* p; 2739 tL2C_LCB* p_lcb = NULL; 2740 uint16_t mtu; 2741 uint16_t mps; 2742 uint16_t initial_credit; 2743 2744 if (!p_ccb) return; 2745 2746 p_lcb = p_ccb->p_lcb; 2747 2748 /* Create an identifier for this packet */ 2749 p_ccb->p_lcb->signal_id++; 2750 l2cu_adj_id(p_ccb->p_lcb); 2751 2752 p_ccb->local_id = p_lcb->signal_id; 2753 2754 p_buf = l2cu_build_header(p_lcb, 2755 L2CAP_CMD_CREDIT_BASED_CONN_REQ_MIN_LEN + 2756 2 * p_lcb->pending_ecoc_conn_cnt, 2757 L2CAP_CMD_CREDIT_BASED_CONN_REQ, p_ccb->local_id); 2758 if (p_buf == NULL) { 2759 L2CAP_TRACE_WARNING("%s - no buffer", __func__); 2760 return; 2761 } 2762 2763 p = (uint8_t*)(p_buf + 1) + L2CAP_SEND_CMD_OFFSET + HCI_DATA_PREAMBLE_SIZE + 2764 L2CAP_PKT_OVERHEAD + L2CAP_CMD_OVERHEAD; 2765 2766 mtu = p_ccb->local_conn_cfg.mtu; 2767 mps = p_ccb->local_conn_cfg.mps; 2768 initial_credit = p_ccb->local_conn_cfg.credits; 2769 2770 L2CAP_TRACE_DEBUG( 2771 "%s PSM:0x%04x mtu:%d mps:%d initial_credit:%d, cids_cnt %d", __func__, 2772 p_ccb->p_rcb->real_psm, mtu, mps, initial_credit, 2773 p_lcb->pending_ecoc_conn_cnt); 2774 2775 UINT16_TO_STREAM(p, p_ccb->p_rcb->real_psm); 2776 UINT16_TO_STREAM(p, mtu); 2777 UINT16_TO_STREAM(p, mps); 2778 UINT16_TO_STREAM(p, initial_credit); 2779 2780 for (int i = 0; i < p_lcb->pending_ecoc_conn_cnt; i++) { 2781 uint16_t cid = p_lcb->pending_ecoc_connection_cids[i]; 2782 L2CAP_TRACE_DEBUG("\n\t cid: ", cid); 2783 UINT16_TO_STREAM(p, cid); 2784 } 2785 2786 l2c_link_check_send_pkts(p_lcb, 0, p_buf); 2787 } 2788 2789 /******************************************************************************* 2790 * 2791 * Function l2cu_reject_ble_coc_connection 2792 * 2793 * Description Build and send an L2CAP "Credit based connection res" 2794 * message to the peer. This function is called for non-success 2795 * cases. 2796 * 2797 * Returns void 2798 * 2799 ******************************************************************************/ 2800 void l2cu_reject_ble_coc_connection(tL2C_LCB* p_lcb, uint8_t rem_id, 2801 uint16_t result) { 2802 BT_HDR* p_buf; 2803 uint8_t* p; 2804 2805 p_buf = l2cu_build_header(p_lcb, L2CAP_CMD_BLE_CREDIT_BASED_CONN_RES_LEN, 2806 L2CAP_CMD_BLE_CREDIT_BASED_CONN_RES, rem_id); 2807 if (p_buf == NULL) { 2808 L2CAP_TRACE_WARNING("l2cu_reject_ble_coc_connection - no buffer"); 2809 return; 2810 } 2811 2812 p = (uint8_t*)(p_buf + 1) + L2CAP_SEND_CMD_OFFSET + HCI_DATA_PREAMBLE_SIZE + 2813 L2CAP_PKT_OVERHEAD + L2CAP_CMD_OVERHEAD; 2814 2815 UINT16_TO_STREAM(p, 0); /* Local CID of 0 */ 2816 UINT16_TO_STREAM(p, 0); /* MTU */ 2817 UINT16_TO_STREAM(p, 0); /* MPS */ 2818 UINT16_TO_STREAM(p, 0); /* initial credit */ 2819 UINT16_TO_STREAM(p, result); 2820 2821 l2c_link_check_send_pkts(p_lcb, 0, p_buf); 2822 } 2823 2824 /******************************************************************************* 2825 * 2826 * Function l2cu_reject_credit_based_connection_req 2827 * 2828 * Description Build and send an L2CAP "credit based connection 2829 *res" message to the peer. This function is called for non-success cases. 2830 * 2831 * Returns void 2832 * 2833 ******************************************************************************/ 2834 void l2cu_reject_credit_based_conn_req(tL2C_LCB* p_lcb, uint8_t rem_id, 2835 uint8_t num_of_channels, 2836 uint16_t result) { 2837 BT_HDR* p_buf; 2838 uint8_t* p; 2839 uint8_t rsp_len = L2CAP_CMD_CREDIT_BASED_CONN_RES_MIN_LEN + 2840 sizeof(uint16_t) * num_of_channels; 2841 2842 p_buf = l2cu_build_header(p_lcb, rsp_len, L2CAP_CMD_CREDIT_BASED_CONN_RES, 2843 rem_id); 2844 if (p_buf == NULL) { 2845 L2CAP_TRACE_WARNING("l2cu_reject_credit_based_conn_req - no buffer"); 2846 return; 2847 } 2848 2849 p = (uint8_t*)(p_buf + 1) + L2CAP_SEND_CMD_OFFSET + HCI_DATA_PREAMBLE_SIZE + 2850 L2CAP_PKT_OVERHEAD + L2CAP_CMD_OVERHEAD; 2851 2852 memset(p, 0, rsp_len); 2853 UINT16_TO_STREAM(p, L2CAP_CREDIT_BASED_MIN_MTU); /* dummy MTU to satisy PTS */ 2854 UINT16_TO_STREAM(p, L2CAP_CREDIT_BASED_MIN_MPS); /* dummy MPS to satisy PTS*/ 2855 UINT16_TO_STREAM(p, 1); /* dummy initial credit to satisy PTS */ 2856 UINT16_TO_STREAM(p, result); 2857 2858 l2c_link_check_send_pkts(p_lcb, 0, p_buf); 2859 } 2860 2861 /******************************************************************************* 2862 * 2863 * Function l2cu_send_peer_credit_based_conn_res 2864 * 2865 * Description Build and send an L2CAP "Credit based connection res" 2866 * message to the peer. This function is called in case of 2867 * success. 2868 * 2869 * Returns void 2870 * 2871 ******************************************************************************/ 2872 void l2cu_send_peer_credit_based_conn_res(tL2C_CCB* p_ccb, 2873 std::vector<uint16_t>& accepted_cids, 2874 uint16_t result) { 2875 BT_HDR* p_buf; 2876 uint8_t* p; 2877 2878 L2CAP_TRACE_DEBUG("%s", __func__); 2879 uint8_t rsp_len = L2CAP_CMD_CREDIT_BASED_CONN_RES_MIN_LEN + 2880 p_ccb->p_lcb->pending_ecoc_conn_cnt * sizeof(uint16_t); 2881 2882 p_buf = l2cu_build_header(p_ccb->p_lcb, rsp_len, 2883 L2CAP_CMD_CREDIT_BASED_CONN_RES, p_ccb->remote_id); 2884 if (p_buf == NULL) { 2885 L2CAP_TRACE_WARNING("%s - no buffer", __func__); 2886 return; 2887 } 2888 2889 p = (uint8_t*)(p_buf + 1) + L2CAP_SEND_CMD_OFFSET + HCI_DATA_PREAMBLE_SIZE + 2890 L2CAP_PKT_OVERHEAD + L2CAP_CMD_OVERHEAD; 2891 2892 memset(p, 0, rsp_len); 2893 UINT16_TO_STREAM(p, p_ccb->local_conn_cfg.mtu); /* MTU */ 2894 UINT16_TO_STREAM(p, p_ccb->local_conn_cfg.mps); /* MPS */ 2895 UINT16_TO_STREAM(p, p_ccb->local_conn_cfg.credits); /* initial credit */ 2896 2897 if (result == L2CAP_CONN_OK) { 2898 /* In case of success, we need to check if stack 2899 * did not have previous result stored e.g. when there was no 2900 * resources for allocation all the requrested channels, 2901 * before user indication. 2902 */ 2903 result = p_ccb->p_lcb->pending_l2cap_result; 2904 } 2905 2906 UINT16_TO_STREAM(p, result); 2907 2908 /* We need to keep order from the request. 2909 * if this vector contais 0 it means channel has been rejected by 2910 * the stack. 2911 * If there is valid cid, we need to verify if it is accepted by upper layer. 2912 */ 2913 for (int i = 0; i < p_ccb->p_lcb->pending_ecoc_conn_cnt; i++) { 2914 uint16_t cid = p_ccb->p_lcb->pending_ecoc_connection_cids[i]; 2915 if (cid == 0) { 2916 UINT16_TO_STREAM(p, 0); 2917 continue; 2918 } 2919 auto it = std::find(accepted_cids.begin(), accepted_cids.end(), cid); 2920 if (it != accepted_cids.end()) { 2921 UINT16_TO_STREAM(p, cid); 2922 } else { 2923 UINT16_TO_STREAM(p, 0); 2924 } 2925 } 2926 2927 l2c_link_check_send_pkts(p_ccb->p_lcb, 0, p_buf); 2928 } 2929 2930 /******************************************************************************* 2931 * 2932 * Function l2cu_reject_ble_connection 2933 * 2934 * Description Build and send an L2CAP "Credit based connection res" 2935 * message to the peer. This function is called for non-success 2936 * cases. 2937 * 2938 * Returns void 2939 * 2940 ******************************************************************************/ 2941 void l2cu_reject_ble_connection(tL2C_CCB* p_ccb, uint8_t rem_id, 2942 uint16_t result) { 2943 if (p_ccb->ecoc) 2944 l2cu_reject_credit_based_conn_req( 2945 p_ccb->p_lcb, rem_id, p_ccb->p_lcb->pending_ecoc_reconfig_cnt, result); 2946 else 2947 l2cu_reject_ble_coc_connection(p_ccb->p_lcb, rem_id, result); 2948 } 2949 2950 /******************************************************************************* 2951 * 2952 * Function l2cu_send_ble_reconfig_rsp 2953 * 2954 * Description Build and send an L2CAP "Credit based reconfig res" 2955 * message to the peer. This function is called for non-success 2956 * cases. 2957 * 2958 * Returns void 2959 * 2960 ******************************************************************************/ 2961 2962 void l2cu_send_ble_reconfig_rsp(tL2C_LCB* p_lcb, uint8_t rem_id, 2963 uint16_t result) { 2964 BT_HDR* p_buf; 2965 uint8_t* p; 2966 2967 L2CAP_TRACE_DEBUG("l2cu_send_ble_reconfig_rsp result 0x04%x", result); 2968 2969 p_buf = l2cu_build_header(p_lcb, L2CAP_CMD_CREDIT_BASED_RECONFIG_RES_LEN, 2970 L2CAP_CMD_CREDIT_BASED_RECONFIG_RES, rem_id); 2971 if (p_buf == NULL) { 2972 L2CAP_TRACE_WARNING("l2cu_send_peer_ble_credit_based_conn_res - no buffer"); 2973 return; 2974 } 2975 2976 p = (uint8_t*)(p_buf + 1) + L2CAP_SEND_CMD_OFFSET + HCI_DATA_PREAMBLE_SIZE + 2977 L2CAP_PKT_OVERHEAD + L2CAP_CMD_OVERHEAD; 2978 2979 memset(p, 0, L2CAP_CMD_CREDIT_BASED_RECONFIG_RES_LEN); 2980 UINT16_TO_STREAM(p, result); 2981 2982 l2c_link_check_send_pkts(p_lcb, 0, p_buf); 2983 } 2984 2985 /******************************************************************************* 2986 * 2987 * Function l2cu_send_peer_ble_credit_based_conn_res 2988 * 2989 * Description Build and send an L2CAP "Credit based connection res" 2990 * message to the peer. This function is called in case of 2991 * success. 2992 * 2993 * Returns void 2994 * 2995 ******************************************************************************/ 2996 void l2cu_send_peer_ble_credit_based_conn_res(tL2C_CCB* p_ccb, 2997 uint16_t result) { 2998 BT_HDR* p_buf; 2999 uint8_t* p; 3000 3001 L2CAP_TRACE_DEBUG("l2cu_send_peer_ble_credit_based_conn_res"); 3002 p_buf = 3003 l2cu_build_header(p_ccb->p_lcb, L2CAP_CMD_BLE_CREDIT_BASED_CONN_RES_LEN, 3004 L2CAP_CMD_BLE_CREDIT_BASED_CONN_RES, p_ccb->remote_id); 3005 if (p_buf == NULL) { 3006 L2CAP_TRACE_WARNING("l2cu_send_peer_ble_credit_based_conn_res - no buffer"); 3007 return; 3008 } 3009 3010 p = (uint8_t*)(p_buf + 1) + L2CAP_SEND_CMD_OFFSET + HCI_DATA_PREAMBLE_SIZE + 3011 L2CAP_PKT_OVERHEAD + L2CAP_CMD_OVERHEAD; 3012 3013 UINT16_TO_STREAM(p, p_ccb->local_cid); /* Local CID */ 3014 UINT16_TO_STREAM(p, p_ccb->local_conn_cfg.mtu); /* MTU */ 3015 UINT16_TO_STREAM(p, p_ccb->local_conn_cfg.mps); /* MPS */ 3016 UINT16_TO_STREAM(p, p_ccb->local_conn_cfg.credits); /* initial credit */ 3017 UINT16_TO_STREAM(p, result); 3018 3019 l2c_link_check_send_pkts(p_ccb->p_lcb, 0, p_buf); 3020 } 3021 3022 /******************************************************************************* 3023 * 3024 * Function l2cu_send_peer_ble_flow_control_credit 3025 * 3026 * Description Build and send a BLE packet to give credits to peer device 3027 * for LE connection oriented L2CAP channel. 3028 * 3029 * Returns void 3030 * 3031 ******************************************************************************/ 3032 void l2cu_send_peer_ble_flow_control_credit(tL2C_CCB* p_ccb, 3033 uint16_t credit_value) { 3034 BT_HDR* p_buf; 3035 uint8_t* p; 3036 tL2C_LCB* p_lcb = NULL; 3037 3038 if (!p_ccb) return; 3039 p_lcb = p_ccb->p_lcb; 3040 3041 /* Create an identifier for this packet */ 3042 p_ccb->p_lcb->signal_id++; 3043 l2cu_adj_id(p_ccb->p_lcb); 3044 3045 p_ccb->local_id = p_ccb->p_lcb->signal_id; 3046 3047 p_buf = l2cu_build_header(p_lcb, L2CAP_CMD_BLE_FLOW_CTRL_CREDIT_LEN, 3048 L2CAP_CMD_BLE_FLOW_CTRL_CREDIT, p_lcb->signal_id); 3049 if (p_buf == NULL) { 3050 L2CAP_TRACE_WARNING("l2cu_send_peer_ble_credit_based_conn_req - no buffer"); 3051 return; 3052 } 3053 3054 p = (uint8_t*)(p_buf + 1) + L2CAP_SEND_CMD_OFFSET + HCI_DATA_PREAMBLE_SIZE + 3055 L2CAP_PKT_OVERHEAD + L2CAP_CMD_OVERHEAD; 3056 3057 UINT16_TO_STREAM(p, p_ccb->local_cid); 3058 UINT16_TO_STREAM(p, credit_value); 3059 3060 l2c_link_check_send_pkts(p_lcb, 0, p_buf); 3061 } 3062 3063 /******************************************************************************* 3064 * 3065 * Function l2cu_send_peer_ble_credit_based_conn_req 3066 * 3067 * Description Build and send a BLE packet to disconnect LE connection 3068 * oriented L2CAP channel. 3069 * 3070 * Returns void 3071 * 3072 ******************************************************************************/ 3073 void l2cu_send_peer_ble_credit_based_disconn_req(tL2C_CCB* p_ccb) { 3074 BT_HDR* p_buf; 3075 uint8_t* p; 3076 tL2C_LCB* p_lcb = NULL; 3077 L2CAP_TRACE_DEBUG("%s", __func__); 3078 3079 if (!p_ccb) return; 3080 p_lcb = p_ccb->p_lcb; 3081 3082 /* Create an identifier for this packet */ 3083 p_ccb->p_lcb->signal_id++; 3084 l2cu_adj_id(p_ccb->p_lcb); 3085 3086 p_ccb->local_id = p_ccb->p_lcb->signal_id; 3087 p_buf = l2cu_build_header(p_lcb, L2CAP_DISC_REQ_LEN, L2CAP_CMD_DISC_REQ, 3088 p_lcb->signal_id); 3089 if (p_buf == NULL) { 3090 L2CAP_TRACE_WARNING( 3091 "l2cu_send_peer_ble_credit_based_disconn_req - no buffer"); 3092 return; 3093 } 3094 3095 p = (uint8_t*)(p_buf + 1) + L2CAP_SEND_CMD_OFFSET + HCI_DATA_PREAMBLE_SIZE + 3096 L2CAP_PKT_OVERHEAD + L2CAP_CMD_OVERHEAD; 3097 3098 UINT16_TO_STREAM(p, p_ccb->remote_cid); 3099 UINT16_TO_STREAM(p, p_ccb->local_cid); 3100 3101 l2c_link_check_send_pkts(p_lcb, 0, p_buf); 3102 } 3103 3104 /******************************************************************************* 3105 * Functions used by both Full and Light Stack 3106 ******************************************************************************/ 3107 3108 /******************************************************************************* 3109 * 3110 * Function l2cu_find_lcb_by_handle 3111 * 3112 * Description Look through all active LCBs for a match based on the 3113 * HCI handle. 3114 * 3115 * Returns pointer to matched LCB, or NULL if no match 3116 * 3117 ******************************************************************************/ 3118 tL2C_LCB* l2cu_find_lcb_by_handle(uint16_t handle) { 3119 int xx; 3120 tL2C_LCB* p_lcb = &l2cb.lcb_pool[0]; 3121 3122 for (xx = 0; xx < MAX_L2CAP_LINKS; xx++, p_lcb++) { 3123 if ((p_lcb->in_use) && (p_lcb->Handle() == handle)) { 3124 return (p_lcb); 3125 } 3126 } 3127 3128 /* If here, no match found */ 3129 return (NULL); 3130 } 3131 3132 /******************************************************************************* 3133 * 3134 * Function l2cu_find_ccb_by_cid 3135 * 3136 * Description Look through all active CCBs on a link for a match based 3137 * on the local CID. If passed the link pointer is NULL, all 3138 * active links are searched. 3139 * 3140 * Returns pointer to matched CCB, or NULL if no match 3141 * 3142 ******************************************************************************/ 3143 tL2C_CCB* l2cu_find_ccb_by_cid(tL2C_LCB* p_lcb, uint16_t local_cid) { 3144 tL2C_CCB* p_ccb = NULL; 3145 if (local_cid >= L2CAP_BASE_APPL_CID) { 3146 /* find the associated CCB by "index" */ 3147 local_cid -= L2CAP_BASE_APPL_CID; 3148 3149 if (local_cid >= MAX_L2CAP_CHANNELS) return NULL; 3150 3151 p_ccb = l2cb.ccb_pool + local_cid; 3152 3153 /* make sure the CCB is in use */ 3154 if (!p_ccb->in_use) { 3155 p_ccb = NULL; 3156 } 3157 /* make sure it's for the same LCB */ 3158 else if (p_lcb && p_lcb != p_ccb->p_lcb) { 3159 p_ccb = NULL; 3160 } 3161 } 3162 return (p_ccb); 3163 } 3164 3165 /****************************************************************************** 3166 * 3167 * Function l2cu_set_acl_hci_header 3168 * 3169 * Description Set HCI handle for ACL packet 3170 * 3171 * Returns None 3172 * 3173 ******************************************************************************/ 3174 void l2cu_set_acl_hci_header(BT_HDR* p_buf, tL2C_CCB* p_ccb) { 3175 uint8_t* p; 3176 3177 /* Set the pointer to the beginning of the data minus 4 bytes for the packet 3178 * header */ 3179 p = (uint8_t*)(p_buf + 1) + p_buf->offset - HCI_DATA_PREAMBLE_SIZE; 3180 3181 if (p_ccb->p_lcb->transport == BT_TRANSPORT_LE) { 3182 UINT16_TO_STREAM(p, p_ccb->p_lcb->Handle() | (L2CAP_PKT_START_NON_FLUSHABLE 3183 << L2CAP_PKT_TYPE_SHIFT)); 3184 3185 uint16_t acl_data_size = 3186 controller_get_interface()->get_acl_data_size_ble(); 3187 /* The HCI transport will segment the buffers. */ 3188 if (p_buf->len > acl_data_size) { 3189 UINT16_TO_STREAM(p, acl_data_size); 3190 } else { 3191 UINT16_TO_STREAM(p, p_buf->len); 3192 } 3193 } else { 3194 if (((p_buf->layer_specific & L2CAP_FLUSHABLE_MASK) == 3195 L2CAP_FLUSHABLE_CH_BASED) && 3196 (p_ccb->is_flushable)) { 3197 UINT16_TO_STREAM(p, p_ccb->p_lcb->Handle() | 3198 (L2CAP_PKT_START << L2CAP_PKT_TYPE_SHIFT)); 3199 } else { 3200 UINT16_TO_STREAM(p, p_ccb->p_lcb->Handle() | l2cb.non_flushable_pbf); 3201 } 3202 3203 uint16_t acl_data_size = 3204 controller_get_interface()->get_acl_data_size_classic(); 3205 /* The HCI transport will segment the buffers. */ 3206 if (p_buf->len > acl_data_size) { 3207 UINT16_TO_STREAM(p, acl_data_size); 3208 } else { 3209 UINT16_TO_STREAM(p, p_buf->len); 3210 } 3211 } 3212 p_buf->offset -= HCI_DATA_PREAMBLE_SIZE; 3213 p_buf->len += HCI_DATA_PREAMBLE_SIZE; 3214 } 3215 3216 static void send_congestion_status_to_all_clients(tL2C_CCB* p_ccb, 3217 bool status) { 3218 p_ccb->cong_sent = status; 3219 3220 if (p_ccb->p_rcb && p_ccb->p_rcb->api.pL2CA_CongestionStatus_Cb) { 3221 L2CAP_TRACE_DEBUG( 3222 "L2CAP - Calling CongestionStatus_Cb (%d), CID: 0x%04x " 3223 "xmit_hold_q.count: %u buff_quota: %u", 3224 status, p_ccb->local_cid, fixed_queue_length(p_ccb->xmit_hold_q), 3225 p_ccb->buff_quota); 3226 3227 /* Prevent recursive calling */ 3228 if (status == false) l2cb.is_cong_cback_context = true; 3229 3230 (*p_ccb->p_rcb->api.pL2CA_CongestionStatus_Cb)(p_ccb->local_cid, status); 3231 3232 if (status == false) l2cb.is_cong_cback_context = false; 3233 } 3234 else { 3235 for (uint8_t xx = 0; xx < L2CAP_NUM_FIXED_CHNLS; xx++) { 3236 if (p_ccb->p_lcb->p_fixed_ccbs[xx] == p_ccb) { 3237 if (l2cb.fixed_reg[xx].pL2CA_FixedCong_Cb != NULL) 3238 (*l2cb.fixed_reg[xx].pL2CA_FixedCong_Cb)(p_ccb->p_lcb->remote_bd_addr, 3239 status); 3240 break; 3241 } 3242 } 3243 } 3244 } 3245 3246 /* check if any change in congestion status */ 3247 void l2cu_check_channel_congestion(tL2C_CCB* p_ccb) { 3248 /* If the CCB queue limit is subject to a quota, check for congestion if this 3249 * channel has outgoing traffic */ 3250 if (p_ccb->buff_quota == 0) return; 3251 3252 size_t q_count = fixed_queue_length(p_ccb->xmit_hold_q); 3253 3254 if (p_ccb->cong_sent) { 3255 /* if channel was congested, but is not congested now, tell the app */ 3256 if (q_count <= (p_ccb->buff_quota / 2)) 3257 send_congestion_status_to_all_clients(p_ccb, false); 3258 } else { 3259 /* if channel was not congested, but is congested now, tell the app */ 3260 if (q_count > p_ccb->buff_quota) 3261 send_congestion_status_to_all_clients(p_ccb, true); 3262 } 3263 } 3264 3265 /******************************************************************************* 3266 * 3267 * Function l2cu_is_ccb_active 3268 * 3269 * Description Check if Channel Control Block is in use or released 3270 * 3271 * Returns bool - true if Channel Control Block is in use 3272 * false if p_ccb is null or is released. 3273 * 3274 ******************************************************************************/ 3275 bool l2cu_is_ccb_active(tL2C_CCB* p_ccb) { return (p_ccb && p_ccb->in_use); } 3276