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