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