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