1 /******************************************************************************
3 * Copyright (C) 1999-2012 Broadcom Corporation
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:
9 * http://www.apache.org/licenses/LICENSE-2.0
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.
17 ******************************************************************************/
19 /******************************************************************************
21 * This file contains L2CAP utility functions
23 ******************************************************************************/
42 /*******************************************************************************
44 ** Function l2cu_allocate_lcb
46 ** Description Look for an unused LCB
48 ** Returns LCB address or NULL if none found
50 *******************************************************************************/
51 tL2C_LCB *l2cu_allocate_lcb (BD_ADDR p_bd_addr, BOOLEAN is_bonding, tBT_TRANSPORT transport)
54 tL2C_LCB *p_lcb = &l2cb.lcb_pool[0];
56 for (xx = 0; xx < MAX_L2CAP_LINKS; xx++, p_lcb++)
60 memset (p_lcb, 0, sizeof (tL2C_LCB));
62 memcpy (p_lcb->remote_bd_addr, p_bd_addr, BD_ADDR_LEN);
65 p_lcb->link_state = LST_DISCONNECTED;
66 p_lcb->handle = HCI_INVALID_HANDLE;
67 p_lcb->link_flush_tout = 0xFFFF;
68 p_lcb->timer_entry.param = (TIMER_PARAM_TYPE)p_lcb;
69 p_lcb->info_timer_entry.param = (TIMER_PARAM_TYPE)p_lcb;
70 p_lcb->idle_timeout = l2cb.idle_timeout;
71 p_lcb->id = 1; /* spec does not allow '0' */
72 p_lcb->is_bonding = is_bonding;
73 #if (BLE_INCLUDED == TRUE)
74 p_lcb->transport = transport;
76 if (transport == BT_TRANSPORT_LE)
78 l2cb.num_ble_links_active++;
79 l2c_ble_link_adjust_allocation();
84 l2cb.num_links_active++;
85 l2c_link_adjust_allocation();
91 /* If here, no free LCB found */
95 /*******************************************************************************
97 ** Function l2cu_update_lcb_4_bonding
99 ** Description Mark the lcb for bonding. Used when bonding takes place on
100 ** an existing ACL connection. (Pre-Lisbon devices)
104 *******************************************************************************/
105 void l2cu_update_lcb_4_bonding (BD_ADDR p_bd_addr, BOOLEAN is_bonding)
107 tL2C_LCB *p_lcb = l2cu_find_lcb_by_bd_addr (p_bd_addr, BT_TRANSPORT_BR_EDR);
111 L2CAP_TRACE_DEBUG ("l2cu_update_lcb_4_bonding BDA: %08x%04x is_bonding: %d",
112 (p_bd_addr[0]<<24)+(p_bd_addr[1]<<16)+(p_bd_addr[2]<<8)+p_bd_addr[3],
113 (p_bd_addr[4]<<8)+p_bd_addr[5], is_bonding);
114 p_lcb->is_bonding = is_bonding;
118 /*******************************************************************************
120 ** Function l2cu_release_lcb
122 ** Description Release an LCB. All timers will be stopped, channels
123 ** dropped, buffers returned etc.
127 *******************************************************************************/
128 void l2cu_release_lcb (tL2C_LCB *p_lcb)
132 p_lcb->in_use = FALSE;
133 p_lcb->is_bonding = FALSE;
135 #if (BLE_INCLUDED == TRUE)
136 btu_stop_timer(&p_lcb->conn_param_enb);
139 btu_stop_timer (&p_lcb->timer_entry);
140 btu_stop_timer (&p_lcb->info_timer_entry);
142 /* Release any unfinished L2CAP packet on this link */
143 if (p_lcb->p_hcit_rcv_acl)
145 GKI_freebuf(p_lcb->p_hcit_rcv_acl);
146 p_lcb->p_hcit_rcv_acl = NULL;
149 #if BTM_SCO_INCLUDED == TRUE
150 #if (BLE_INCLUDED == TRUE)
151 if (p_lcb->transport == BT_TRANSPORT_BR_EDR)
153 /* Release all SCO links */
154 btm_remove_sco_links(p_lcb->remote_bd_addr);
157 if (p_lcb->sent_not_acked > 0)
159 #if (BLE_INCLUDED == TRUE)
160 if (p_lcb->transport == BT_TRANSPORT_LE)
162 l2cb.controller_le_xmit_window += p_lcb->sent_not_acked;
163 if (l2cb.controller_le_xmit_window > l2cb.num_lm_ble_bufs)
165 l2cb.controller_le_xmit_window = l2cb.num_lm_ble_bufs;
171 l2cb.controller_xmit_window += p_lcb->sent_not_acked;
172 if (l2cb.controller_xmit_window > l2cb.num_lm_acl_bufs)
174 l2cb.controller_xmit_window = l2cb.num_lm_acl_bufs;
179 #if (BLE_INCLUDED == TRUE)
180 l2cb.is_ble_connecting = FALSE;
183 #if (L2CAP_NUM_FIXED_CHNLS > 0)
187 for (xx = 0; xx < L2CAP_NUM_FIXED_CHNLS; xx++)
189 if (p_lcb->p_fixed_ccbs[xx])
191 l2cu_release_ccb (p_lcb->p_fixed_ccbs[xx]);
192 p_lcb->p_fixed_ccbs[xx] = NULL;
193 (*l2cb.fixed_reg[xx].pL2CA_FixedConn_Cb)(p_lcb->remote_bd_addr, FALSE, p_lcb->disc_reason, p_lcb->transport);
195 else if ( (p_lcb->peer_chnl_mask[0] & (1 << (xx + L2CAP_FIRST_FIXED_CHNL)))
196 && (l2cb.fixed_reg[xx].pL2CA_FixedConn_Cb != NULL) )
197 (*l2cb.fixed_reg[xx].pL2CA_FixedConn_Cb)(p_lcb->remote_bd_addr, FALSE, p_lcb->disc_reason, p_lcb->transport);
202 /* Ensure no CCBs left on this LCB */
203 for (p_ccb = p_lcb->ccb_queue.p_first_ccb; p_ccb; p_ccb = p_lcb->ccb_queue.p_first_ccb)
205 l2cu_release_ccb (p_ccb);
208 /* Tell BTM Acl management the link was removed */
209 if ((p_lcb->link_state == LST_CONNECTED) || (p_lcb->link_state == LST_DISCONNECTING))
210 #if (BLE_INCLUDED == TRUE)
211 btm_acl_removed (p_lcb->remote_bd_addr, p_lcb->transport);
213 btm_acl_removed (p_lcb->remote_bd_addr, BT_TRANSPORT_BR_EDR);
215 /* Release any held buffers */
216 while (p_lcb->link_xmit_data_q.p_first)
217 GKI_freebuf (GKI_dequeue (&p_lcb->link_xmit_data_q));
219 #if (L2CAP_UCD_INCLUDED == TRUE)
220 /* clean up any security pending UCD */
221 l2c_ucd_delete_sec_pending_q(p_lcb);
224 #if BLE_INCLUDED == TRUE
225 /* Re-adjust flow control windows make sure it does not go negative */
226 if (p_lcb->transport == BT_TRANSPORT_LE)
228 if (l2cb.num_ble_links_active >= 1)
229 l2cb.num_ble_links_active--;
231 l2c_ble_link_adjust_allocation();
236 if (l2cb.num_links_active >= 1)
237 l2cb.num_links_active--;
239 l2c_link_adjust_allocation();
242 /* Check for ping outstanding */
243 if (p_lcb->p_echo_rsp_cb)
245 tL2CA_ECHO_RSP_CB *p_cb = p_lcb->p_echo_rsp_cb;
247 /* Zero out the callback in case app immediately calls us again */
248 p_lcb->p_echo_rsp_cb = NULL;
250 (*p_cb) (L2CAP_PING_RESULT_NO_LINK);
255 /*******************************************************************************
257 ** Function l2cu_find_lcb_by_bd_addr
259 ** Description Look through all active LCBs for a match based on the
260 ** remote BD address.
262 ** Returns pointer to matched LCB, or NULL if no match
264 *******************************************************************************/
265 tL2C_LCB *l2cu_find_lcb_by_bd_addr (BD_ADDR p_bd_addr, tBT_TRANSPORT transport)
268 tL2C_LCB *p_lcb = &l2cb.lcb_pool[0];
270 for (xx = 0; xx < MAX_L2CAP_LINKS; xx++, p_lcb++)
272 if ((p_lcb->in_use) &&
273 #if BLE_INCLUDED == TRUE
274 p_lcb->transport == transport &&
276 (!memcmp (p_lcb->remote_bd_addr, p_bd_addr, BD_ADDR_LEN)))
282 /* If here, no match found */
286 /*******************************************************************************
288 ** Function l2cu_get_conn_role
290 ** Description Determine the desired role (master or slave) of a link.
291 ** If already got a slave link, this one must be a master. If
292 ** already got at least 1 link where we are the master, make this
295 ** Returns HCI_ROLE_MASTER or HCI_ROLE_SLAVE
297 *******************************************************************************/
298 UINT8 l2cu_get_conn_role (tL2C_LCB *p_this_lcb)
301 for (i = 0; i < BTM_ROLE_DEVICE_NUM; i++) {
302 if ((btm_cb.previous_connected_role[i] != BTM_ROLE_UNDEFINED) &&
303 (!bdcmp(p_this_lcb->remote_bd_addr, btm_cb.previous_connected_remote_addr[i]))) {
304 L2CAP_TRACE_WARNING ("l2cu_get_conn_role %d",
305 btm_cb.previous_connected_role[i]);
306 return btm_cb.previous_connected_role[i];
309 return l2cb.desire_role;
312 /*******************************************************************************
314 ** Function l2c_is_cmd_rejected
316 ** Description Checks if cmd_code is command or response
317 ** If a command it will be rejected per spec.
318 ** This function is used when a illegal packet length is detected
320 ** Returns BOOLEAN - TRUE if cmd_code is a command and it is rejected,
321 ** FALSE if response code. (command not rejected)
323 *******************************************************************************/
324 BOOLEAN l2c_is_cmd_rejected (UINT8 cmd_code, UINT8 id, tL2C_LCB *p_lcb)
328 case L2CAP_CMD_CONN_REQ:
329 case L2CAP_CMD_CONFIG_REQ:
330 case L2CAP_CMD_DISC_REQ:
331 case L2CAP_CMD_ECHO_REQ:
332 case L2CAP_CMD_INFO_REQ:
333 case L2CAP_CMD_AMP_CONN_REQ:
334 case L2CAP_CMD_AMP_MOVE_REQ:
335 case L2CAP_CMD_BLE_UPDATE_REQ:
336 l2cu_send_peer_cmd_reject (p_lcb, L2CAP_CMD_REJ_MTU_EXCEEDED, id, L2CAP_DEFAULT_MTU, 0);
337 L2CAP_TRACE_WARNING ("Dumping first Command (%d)", cmd_code);
340 default: /* Otherwise a response */
345 /*******************************************************************************
347 ** Function l2cu_build_header
349 ** Description Builds the L2CAP command packet header
351 ** Returns Pointer to allocated packet or NULL if no resources
353 *******************************************************************************/
354 BT_HDR *l2cu_build_header (tL2C_LCB *p_lcb, UINT16 len, UINT8 cmd, UINT8 id)
356 BT_HDR *p_buf = (BT_HDR *)GKI_getpoolbuf (L2CAP_CMD_POOL_ID);
361 L2CAP_TRACE_ERROR ("l2cu_build_header - no buffer");
365 p_buf->offset = L2CAP_SEND_CMD_OFFSET;
366 p_buf->len = len + HCI_DATA_PREAMBLE_SIZE + L2CAP_PKT_OVERHEAD + L2CAP_CMD_OVERHEAD;
367 p = (UINT8 *)(p_buf + 1) + L2CAP_SEND_CMD_OFFSET;
369 /* Put in HCI header - handle + pkt boundary */
370 #if (BLE_INCLUDED == TRUE)
371 if (p_lcb->transport == BT_TRANSPORT_LE)
373 UINT16_TO_STREAM (p, (p_lcb->handle | (L2CAP_PKT_START_NON_FLUSHABLE << L2CAP_PKT_TYPE_SHIFT)));
378 #if (L2CAP_NON_FLUSHABLE_PB_INCLUDED == TRUE)
379 UINT16_TO_STREAM (p, p_lcb->handle | l2cb.non_flushable_pbf);
381 UINT16_TO_STREAM (p, (p_lcb->handle | (L2CAP_PKT_START << L2CAP_PKT_TYPE_SHIFT)));
385 UINT16_TO_STREAM (p, len + L2CAP_PKT_OVERHEAD + L2CAP_CMD_OVERHEAD);
386 UINT16_TO_STREAM (p, len + L2CAP_CMD_OVERHEAD);
388 #if (BLE_INCLUDED == TRUE)
389 if (p_lcb->transport == BT_TRANSPORT_LE)
391 UINT16_TO_STREAM (p, L2CAP_BLE_SIGNALLING_CID);
396 UINT16_TO_STREAM (p, L2CAP_SIGNALLING_CID);
399 /* Put in L2CAP command header */
400 UINT8_TO_STREAM (p, cmd);
401 UINT8_TO_STREAM (p, id);
402 UINT16_TO_STREAM (p, len);
407 /*******************************************************************************
409 ** Function l2cu_adj_id
411 ** Description Checks for valid ID based on specified mask
412 ** and adjusts the id if invalid.
416 *******************************************************************************/
417 void l2cu_adj_id (tL2C_LCB *p_lcb, UINT8 adj_mask)
419 if ((adj_mask & L2CAP_ADJ_ZERO_ID) && !p_lcb->id)
425 /*******************************************************************************
427 ** Function l2cu_send_peer_cmd_reject
429 ** Description Build and send an L2CAP "command reject" message
434 *******************************************************************************/
435 void l2cu_send_peer_cmd_reject (tL2C_LCB *p_lcb, UINT16 reason, UINT8 rem_id,
436 UINT16 p1, UINT16 p2)
442 /* Put in L2CAP packet header */
443 if (reason == L2CAP_CMD_REJ_MTU_EXCEEDED)
445 else if (reason == L2CAP_CMD_REJ_INVALID_CID)
450 if ((p_buf = l2cu_build_header (p_lcb, (UINT16) (L2CAP_CMD_REJECT_LEN + param_len), L2CAP_CMD_REJECT, rem_id)) == NULL )
452 L2CAP_TRACE_WARNING ("L2CAP - no buffer cmd_rej");
456 p = (UINT8 *)(p_buf + 1) + L2CAP_SEND_CMD_OFFSET + HCI_DATA_PREAMBLE_SIZE +
457 L2CAP_PKT_OVERHEAD + L2CAP_CMD_OVERHEAD;
459 UINT16_TO_STREAM (p, reason);
462 UINT16_TO_STREAM (p, p1);
465 UINT16_TO_STREAM (p, p2);
467 l2c_link_check_send_pkts (p_lcb, NULL, p_buf);
471 /*******************************************************************************
473 ** Function l2cu_send_peer_connect_req
475 ** Description Build and send an L2CAP "connection request" message
480 *******************************************************************************/
481 void l2cu_send_peer_connect_req (tL2C_CCB *p_ccb)
486 /* Create an identifier for this packet */
488 l2cu_adj_id(p_ccb->p_lcb, L2CAP_ADJ_ID);
490 p_ccb->local_id = p_ccb->p_lcb->id;
492 if ((p_buf = l2cu_build_header (p_ccb->p_lcb, L2CAP_CONN_REQ_LEN, L2CAP_CMD_CONN_REQ,
493 p_ccb->local_id)) == NULL)
495 L2CAP_TRACE_WARNING ("L2CAP - no buffer for conn_req");
499 p = (UINT8 *)(p_buf + 1) + L2CAP_SEND_CMD_OFFSET+HCI_DATA_PREAMBLE_SIZE +
500 L2CAP_PKT_OVERHEAD + L2CAP_CMD_OVERHEAD;
502 UINT16_TO_STREAM (p, p_ccb->p_rcb->real_psm);
503 UINT16_TO_STREAM (p, p_ccb->local_cid);
505 l2c_link_check_send_pkts (p_ccb->p_lcb, NULL, p_buf);
509 /*******************************************************************************
511 ** Function l2cu_send_peer_connect_rsp
513 ** Description Build and send an L2CAP "connection response" message
518 *******************************************************************************/
519 void l2cu_send_peer_connect_rsp (tL2C_CCB *p_ccb, UINT16 result, UINT16 status)
524 if (result == L2CAP_CONN_PENDING)
526 /* if we already sent pending response */
527 if (p_ccb->flags & CCB_FLAG_SENT_PENDING)
530 p_ccb->flags |= CCB_FLAG_SENT_PENDING;
533 if ((p_buf=l2cu_build_header(p_ccb->p_lcb, L2CAP_CONN_RSP_LEN, L2CAP_CMD_CONN_RSP, p_ccb->remote_id)) == NULL)
535 L2CAP_TRACE_WARNING ("L2CAP - no buffer for conn_rsp");
539 p = (UINT8 *)(p_buf + 1) + L2CAP_SEND_CMD_OFFSET+HCI_DATA_PREAMBLE_SIZE +
540 L2CAP_PKT_OVERHEAD + L2CAP_CMD_OVERHEAD;
542 UINT16_TO_STREAM (p, p_ccb->local_cid);
543 UINT16_TO_STREAM (p, p_ccb->remote_cid);
544 UINT16_TO_STREAM (p, result);
545 UINT16_TO_STREAM (p, status);
547 l2c_link_check_send_pkts (p_ccb->p_lcb, NULL, p_buf);
551 /*******************************************************************************
553 ** Function l2cu_reject_connection
555 ** Description Build and send an L2CAP "connection response neg" message
556 ** to the peer. This function is called when there is no peer
557 ** CCB (non-existant PSM or no resources).
561 *******************************************************************************/
562 void l2cu_reject_connection (tL2C_LCB *p_lcb, UINT16 remote_cid, UINT8 rem_id, UINT16 result)
567 if ((p_buf = l2cu_build_header(p_lcb, L2CAP_CONN_RSP_LEN, L2CAP_CMD_CONN_RSP, rem_id)) == NULL )
569 L2CAP_TRACE_WARNING ("L2CAP - no buffer for conn_req");
573 p = (UINT8 *)(p_buf + 1) + L2CAP_SEND_CMD_OFFSET+HCI_DATA_PREAMBLE_SIZE + L2CAP_PKT_OVERHEAD + L2CAP_CMD_OVERHEAD;
575 UINT16_TO_STREAM (p, 0); /* Local CID of 0 */
576 UINT16_TO_STREAM (p, remote_cid);
577 UINT16_TO_STREAM (p, result);
578 UINT16_TO_STREAM (p, 0); /* Status of 0 */
580 l2c_link_check_send_pkts (p_lcb, NULL, p_buf);
583 /*******************************************************************************
585 ** Function l2cu_send_peer_config_req
587 ** Description Build and send an L2CAP "configuration request" message
592 *******************************************************************************/
593 void l2cu_send_peer_config_req (tL2C_CCB *p_ccb, tL2CAP_CFG_INFO *p_cfg)
599 /* Create an identifier for this packet */
601 l2cu_adj_id(p_ccb->p_lcb, L2CAP_ADJ_ID);
603 p_ccb->local_id = p_ccb->p_lcb->id;
605 if (p_cfg->mtu_present)
606 cfg_len += L2CAP_CFG_MTU_OPTION_LEN + L2CAP_CFG_OPTION_OVERHEAD;
607 if (p_cfg->flush_to_present)
608 cfg_len += L2CAP_CFG_FLUSH_OPTION_LEN + L2CAP_CFG_OPTION_OVERHEAD;
609 if (p_cfg->qos_present)
610 cfg_len += L2CAP_CFG_QOS_OPTION_LEN + L2CAP_CFG_OPTION_OVERHEAD;
611 if (p_cfg->fcr_present)
612 cfg_len += L2CAP_CFG_FCR_OPTION_LEN + L2CAP_CFG_OPTION_OVERHEAD;
613 if (p_cfg->fcs_present)
614 cfg_len += L2CAP_CFG_FCS_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;
618 if ((p_buf = l2cu_build_header (p_ccb->p_lcb, (UINT16) (L2CAP_CONFIG_REQ_LEN + cfg_len),
619 L2CAP_CMD_CONFIG_REQ, p_ccb->local_id)) == NULL )
621 L2CAP_TRACE_WARNING ("L2CAP - no buffer for conn_req");
625 p = (UINT8 *)(p_buf + 1) + L2CAP_SEND_CMD_OFFSET + HCI_DATA_PREAMBLE_SIZE +
626 L2CAP_PKT_OVERHEAD + L2CAP_CMD_OVERHEAD;
628 UINT16_TO_STREAM (p, p_ccb->remote_cid);
629 UINT16_TO_STREAM (p, p_cfg->flags); /* Flags (continuation) */
631 /* Now, put the options */
632 if (p_cfg->mtu_present)
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);
638 if (p_cfg->flush_to_present)
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);
644 if (p_cfg->qos_present)
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);
656 if (p_cfg->fcr_present)
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_cfg->fcr.rtrans_tout);
664 UINT16_TO_STREAM (p, p_cfg->fcr.mon_tout);
665 UINT16_TO_STREAM (p, p_cfg->fcr.mps);
668 if (p_cfg->fcs_present)
670 UINT8_TO_STREAM (p, L2CAP_CFG_TYPE_FCS);
671 UINT8_TO_STREAM (p, L2CAP_CFG_FCS_OPTION_LEN);
672 UINT8_TO_STREAM (p, p_cfg->fcs);
675 if (p_cfg->ext_flow_spec_present)
677 UINT8_TO_STREAM (p, L2CAP_CFG_TYPE_EXT_FLOW);
678 UINT8_TO_STREAM (p, L2CAP_CFG_EXT_FLOW_OPTION_LEN);
679 UINT8_TO_STREAM (p, p_cfg->ext_flow_spec.id);
680 UINT8_TO_STREAM (p, p_cfg->ext_flow_spec.stype);
681 UINT16_TO_STREAM (p, p_cfg->ext_flow_spec.max_sdu_size);
682 UINT32_TO_STREAM (p, p_cfg->ext_flow_spec.sdu_inter_time);
683 UINT32_TO_STREAM (p, p_cfg->ext_flow_spec.access_latency);
684 UINT32_TO_STREAM (p, p_cfg->ext_flow_spec.flush_timeout);
687 l2c_link_check_send_pkts (p_ccb->p_lcb, NULL, p_buf);
690 /*******************************************************************************
692 ** Function l2cu_send_peer_config_rsp
694 ** Description Build and send an L2CAP "configuration response" message
699 *******************************************************************************/
700 void l2cu_send_peer_config_rsp (tL2C_CCB *p_ccb, tL2CAP_CFG_INFO *p_cfg)
706 /* Create an identifier for this packet */
707 if (p_cfg->mtu_present)
708 cfg_len += L2CAP_CFG_MTU_OPTION_LEN + L2CAP_CFG_OPTION_OVERHEAD;
709 if (p_cfg->flush_to_present)
710 cfg_len += L2CAP_CFG_FLUSH_OPTION_LEN + L2CAP_CFG_OPTION_OVERHEAD;
711 if (p_cfg->qos_present)
712 cfg_len += L2CAP_CFG_QOS_OPTION_LEN + L2CAP_CFG_OPTION_OVERHEAD;
713 if (p_cfg->fcr_present)
714 cfg_len += L2CAP_CFG_FCR_OPTION_LEN + L2CAP_CFG_OPTION_OVERHEAD;
715 if (p_cfg->ext_flow_spec_present)
716 cfg_len += L2CAP_CFG_EXT_FLOW_OPTION_LEN + L2CAP_CFG_OPTION_OVERHEAD;
718 if ((p_buf = l2cu_build_header (p_ccb->p_lcb, (UINT16)(L2CAP_CONFIG_RSP_LEN + cfg_len),
719 L2CAP_CMD_CONFIG_RSP, p_ccb->remote_id)) == NULL )
721 L2CAP_TRACE_WARNING ("L2CAP - no buffer for conn_req");
725 p = (UINT8 *)(p_buf + 1) + L2CAP_SEND_CMD_OFFSET+HCI_DATA_PREAMBLE_SIZE + L2CAP_PKT_OVERHEAD + L2CAP_CMD_OVERHEAD;
727 UINT16_TO_STREAM (p, p_ccb->remote_cid);
728 UINT16_TO_STREAM (p, p_cfg->flags); /* Flags (continuation) Must match request */
729 UINT16_TO_STREAM (p, p_cfg->result);
731 /* Now, put the options */
732 if (p_cfg->mtu_present)
734 UINT8_TO_STREAM (p, L2CAP_CFG_TYPE_MTU);
735 UINT8_TO_STREAM (p, L2CAP_CFG_MTU_OPTION_LEN);
736 UINT16_TO_STREAM (p, p_cfg->mtu);
738 if (p_cfg->flush_to_present)
740 UINT8_TO_STREAM (p, L2CAP_CFG_TYPE_FLUSH_TOUT);
741 UINT8_TO_STREAM (p, L2CAP_CFG_FLUSH_OPTION_LEN);
742 UINT16_TO_STREAM (p, p_cfg->flush_to);
744 if (p_cfg->qos_present)
746 UINT8_TO_STREAM (p, L2CAP_CFG_TYPE_QOS);
747 UINT8_TO_STREAM (p, L2CAP_CFG_QOS_OPTION_LEN);
748 UINT8_TO_STREAM (p, p_cfg->qos.qos_flags);
749 UINT8_TO_STREAM (p, p_cfg->qos.service_type);
750 UINT32_TO_STREAM (p, p_cfg->qos.token_rate);
751 UINT32_TO_STREAM (p, p_cfg->qos.token_bucket_size);
752 UINT32_TO_STREAM (p, p_cfg->qos.peak_bandwidth);
753 UINT32_TO_STREAM (p, p_cfg->qos.latency);
754 UINT32_TO_STREAM (p, p_cfg->qos.delay_variation);
756 if (p_cfg->fcr_present)
758 UINT8_TO_STREAM (p, L2CAP_CFG_TYPE_FCR);
759 UINT8_TO_STREAM (p, L2CAP_CFG_FCR_OPTION_LEN);
760 UINT8_TO_STREAM (p, p_cfg->fcr.mode);
761 UINT8_TO_STREAM (p, p_cfg->fcr.tx_win_sz);
762 UINT8_TO_STREAM (p, p_cfg->fcr.max_transmit);
763 UINT16_TO_STREAM (p, p_ccb->our_cfg.fcr.rtrans_tout);
764 UINT16_TO_STREAM (p, p_ccb->our_cfg.fcr.mon_tout);
765 UINT16_TO_STREAM (p, p_cfg->fcr.mps);
768 if (p_cfg->ext_flow_spec_present)
770 UINT8_TO_STREAM (p, L2CAP_CFG_TYPE_EXT_FLOW);
771 UINT8_TO_STREAM (p, L2CAP_CFG_EXT_FLOW_OPTION_LEN);
772 UINT8_TO_STREAM (p, p_cfg->ext_flow_spec.id);
773 UINT8_TO_STREAM (p, p_cfg->ext_flow_spec.stype);
774 UINT16_TO_STREAM (p, p_cfg->ext_flow_spec.max_sdu_size);
775 UINT32_TO_STREAM (p, p_cfg->ext_flow_spec.sdu_inter_time);
776 UINT32_TO_STREAM (p, p_cfg->ext_flow_spec.access_latency);
777 UINT32_TO_STREAM (p, p_cfg->ext_flow_spec.flush_timeout);
780 l2c_link_check_send_pkts (p_ccb->p_lcb, NULL, p_buf);
783 /*******************************************************************************
785 ** Function l2cu_send_peer_config_rej
787 ** Description Build and send an L2CAP "configuration reject" message
792 *******************************************************************************/
793 void l2cu_send_peer_config_rej (tL2C_CCB *p_ccb, UINT8 *p_data, UINT16 data_len, UINT16 rej_len)
796 UINT16 len, cfg_len, buf_space, len1;
797 UINT8 *p, *p_hci_len, *p_data_end;
800 L2CAP_TRACE_DEBUG("l2cu_send_peer_config_rej: data_len=%d, rej_len=%d", data_len, rej_len);
803 len = BT_HDR_SIZE + HCI_DATA_PREAMBLE_SIZE + L2CAP_PKT_OVERHEAD + L2CAP_CMD_OVERHEAD + L2CAP_CONFIG_RSP_LEN;
807 L2CAP_TRACE_ERROR ("L2CAP - cfg_rej pkt size exceeds buffer design max limit.");
811 p_buf = (BT_HDR *)GKI_getbuf (len + rej_len);
815 L2CAP_TRACE_ERROR ("L2CAP - no buffer for cfg_rej");
819 p_buf->offset = L2CAP_SEND_CMD_OFFSET;
820 p = (UINT8 *)(p_buf + 1) + L2CAP_SEND_CMD_OFFSET;
822 /* Put in HCI header - handle + pkt boundary */
823 #if (L2CAP_NON_FLUSHABLE_PB_INCLUDED == TRUE)
824 if (HCI_NON_FLUSHABLE_PB_SUPPORTED(BTM_ReadLocalFeatures ()))
826 UINT16_TO_STREAM (p, (p_ccb->p_lcb->handle | (L2CAP_PKT_START_NON_FLUSHABLE << L2CAP_PKT_TYPE_SHIFT)));
831 UINT16_TO_STREAM (p, (p_ccb->p_lcb->handle | (L2CAP_PKT_START << L2CAP_PKT_TYPE_SHIFT)));
834 /* Remember the HCI header length position, and save space for it */
838 /* Put in L2CAP packet header */
839 UINT16_TO_STREAM (p, L2CAP_CMD_OVERHEAD + L2CAP_CONFIG_RSP_LEN + rej_len);
840 UINT16_TO_STREAM (p, L2CAP_SIGNALLING_CID);
842 /* Put in L2CAP command header */
843 UINT8_TO_STREAM (p, L2CAP_CMD_CONFIG_RSP);
844 UINT8_TO_STREAM (p, p_ccb->remote_id);
846 UINT16_TO_STREAM (p, L2CAP_CONFIG_RSP_LEN + rej_len);
848 UINT16_TO_STREAM (p, p_ccb->remote_cid);
849 UINT16_TO_STREAM (p, 0); /* Flags = 0 (no continuation) */
850 UINT16_TO_STREAM (p, L2CAP_CFG_UNKNOWN_OPTIONS);
854 /* Now, put the rejected options */
855 p_data_end = p_data + data_len;
856 while (p_data < p_data_end)
859 cfg_len = *(p_data + 1);
861 switch (cfg_code & 0x7F)
863 /* skip known options */
864 case L2CAP_CFG_TYPE_MTU:
865 case L2CAP_CFG_TYPE_FLUSH_TOUT:
866 case L2CAP_CFG_TYPE_QOS:
867 p_data += cfg_len + L2CAP_CFG_OPTION_OVERHEAD;
870 /* unknown options; copy into rsp if not hints */
872 /* sanity check option length */
873 if ((cfg_len + L2CAP_CFG_OPTION_OVERHEAD) <= data_len)
875 if ((cfg_code & 0x80) == 0)
877 if (buf_space >= (cfg_len + L2CAP_CFG_OPTION_OVERHEAD))
879 memcpy(p, p_data, cfg_len + L2CAP_CFG_OPTION_OVERHEAD);
880 p += cfg_len + L2CAP_CFG_OPTION_OVERHEAD;
881 buf_space -= (cfg_len + L2CAP_CFG_OPTION_OVERHEAD);
885 L2CAP_TRACE_WARNING("L2CAP - cfg_rej exceeds allocated buffer");
886 p_data = p_data_end; /* force loop exit */
890 p_data += cfg_len + L2CAP_CFG_OPTION_OVERHEAD;
892 /* bad length; force loop exit */
901 len = (UINT16) (p - p_hci_len - 2);
902 UINT16_TO_STREAM (p_hci_len, len);
904 p_buf->len = len + 4;
906 L2CAP_TRACE_DEBUG ("L2CAP - cfg_rej pkt hci_len=%d, l2cap_len=%d",
907 len, (L2CAP_CMD_OVERHEAD+L2CAP_CONFIG_RSP_LEN+rej_len));
909 l2c_link_check_send_pkts (p_ccb->p_lcb, NULL, p_buf);
912 /*******************************************************************************
914 ** Function l2cu_send_peer_disc_req
916 ** Description Build and send an L2CAP "disconnect request" message
921 *******************************************************************************/
922 void l2cu_send_peer_disc_req (tL2C_CCB *p_ccb)
924 BT_HDR *p_buf, *p_buf2;
927 /* Create an identifier for this packet */
929 l2cu_adj_id(p_ccb->p_lcb, L2CAP_ADJ_ID);
931 p_ccb->local_id = p_ccb->p_lcb->id;
933 if ((p_buf = l2cu_build_header(p_ccb->p_lcb, L2CAP_DISC_REQ_LEN, L2CAP_CMD_DISC_REQ, p_ccb->local_id)) == NULL)
935 L2CAP_TRACE_WARNING ("L2CAP - no buffer for disc_req");
939 p = (UINT8 *)(p_buf + 1) + L2CAP_SEND_CMD_OFFSET + HCI_DATA_PREAMBLE_SIZE + L2CAP_PKT_OVERHEAD + L2CAP_CMD_OVERHEAD;
941 UINT16_TO_STREAM (p, p_ccb->remote_cid);
942 UINT16_TO_STREAM (p, p_ccb->local_cid);
944 /* Move all queued data packets to the LCB. In FCR mode, assume the higher
945 layer checks that all buffers are sent before disconnecting.
947 if (p_ccb->peer_cfg.fcr.mode == L2CAP_FCR_BASIC_MODE)
949 while (p_ccb->xmit_hold_q.p_first)
951 p_buf2 = (BT_HDR *)GKI_dequeue (&p_ccb->xmit_hold_q);
952 l2cu_set_acl_hci_header (p_buf2, p_ccb);
953 l2c_link_check_send_pkts (p_ccb->p_lcb, p_ccb, p_buf2);
957 l2c_link_check_send_pkts (p_ccb->p_lcb, NULL, p_buf);
961 /*******************************************************************************
963 ** Function l2cu_send_peer_disc_rsp
965 ** Description Build and send an L2CAP "disconnect response" message
968 ** This function is passed the parameters for the disconnect
969 ** response instead of the CCB address, as it may be called
970 ** to send a disconnect response when there is no CCB.
974 *******************************************************************************/
975 void l2cu_send_peer_disc_rsp (tL2C_LCB *p_lcb, UINT8 remote_id, UINT16 local_cid,
981 if ((p_buf=l2cu_build_header(p_lcb, L2CAP_DISC_RSP_LEN, L2CAP_CMD_DISC_RSP, remote_id)) == NULL)
983 L2CAP_TRACE_WARNING ("L2CAP - no buffer for disc_rsp");
987 p = (UINT8 *)(p_buf + 1) + L2CAP_SEND_CMD_OFFSET + HCI_DATA_PREAMBLE_SIZE + L2CAP_PKT_OVERHEAD + L2CAP_CMD_OVERHEAD;
989 UINT16_TO_STREAM (p, local_cid);
990 UINT16_TO_STREAM (p, remote_cid);
992 l2c_link_check_send_pkts (p_lcb, NULL, p_buf);
996 /*******************************************************************************
998 ** Function l2cu_send_peer_echo_req
1000 ** Description Build and send an L2CAP "echo request" message
1001 ** to the peer. Note that we do not currently allow
1002 ** data in the echo request.
1006 *******************************************************************************/
1007 void l2cu_send_peer_echo_req (tL2C_LCB *p_lcb, UINT8 *p_data, UINT16 data_len)
1013 l2cu_adj_id(p_lcb, L2CAP_ADJ_ZERO_ID); /* check for wrap to '0' */
1015 if ((p_buf = l2cu_build_header(p_lcb, (UINT16) (L2CAP_ECHO_REQ_LEN + data_len), L2CAP_CMD_ECHO_REQ, p_lcb->id)) == NULL)
1017 L2CAP_TRACE_WARNING ("L2CAP - no buffer for echo_req");
1021 p = (UINT8 *)(p_buf + 1) + L2CAP_SEND_CMD_OFFSET + HCI_DATA_PREAMBLE_SIZE + L2CAP_PKT_OVERHEAD + L2CAP_CMD_OVERHEAD;
1025 ARRAY_TO_STREAM (p, p_data, data_len);
1028 l2c_link_check_send_pkts (p_lcb, NULL, p_buf);
1032 /*******************************************************************************
1034 ** Function l2cu_send_peer_echo_rsp
1036 ** Description Build and send an L2CAP "echo response" message
1041 *******************************************************************************/
1042 void l2cu_send_peer_echo_rsp (tL2C_LCB *p_lcb, UINT8 id, UINT8 *p_data, UINT16 data_len)
1047 /* Filter out duplicate IDs or if available buffers are low (intruder checking) */
1048 if (!id || id == p_lcb->cur_echo_id)
1050 /* Dump this request since it is illegal */
1051 L2CAP_TRACE_WARNING ("L2CAP ignoring duplicate echo request (%d)", id);
1055 p_lcb->cur_echo_id = id;
1056 /* Don't respond if we more than 10% of our buffers are used */
1057 if (GKI_poolutilization (L2CAP_CMD_POOL_ID) > 10)
1059 L2CAP_TRACE_WARNING ("L2CAP gki pool used up to more than 10%%, ignore echo response");
1063 /* Don't return data if it does not fit in ACL and L2CAP MTU */
1064 maxlen = (GKI_get_pool_bufsize(L2CAP_CMD_POOL_ID) > btu_cb.hcit_acl_pkt_size) ?
1065 btu_cb.hcit_acl_data_size : (UINT16)GKI_get_pool_bufsize(L2CAP_CMD_POOL_ID);
1066 maxlen -= (UINT16)(BT_HDR_SIZE + HCI_DATA_PREAMBLE_SIZE + L2CAP_PKT_OVERHEAD +
1067 L2CAP_CMD_OVERHEAD + L2CAP_ECHO_RSP_LEN);
1069 if (data_len > maxlen)
1072 if ((p_buf = l2cu_build_header (p_lcb, (UINT16)(L2CAP_ECHO_RSP_LEN + data_len), L2CAP_CMD_ECHO_RSP, id)) == NULL)
1074 L2CAP_TRACE_WARNING ("L2CAP - no buffer for echo_rsp");
1078 p = (UINT8 *)(p_buf + 1) + L2CAP_SEND_CMD_OFFSET + HCI_DATA_PREAMBLE_SIZE +
1079 L2CAP_PKT_OVERHEAD + L2CAP_CMD_OVERHEAD;
1083 ARRAY_TO_STREAM (p, p_data, data_len);
1086 l2c_link_check_send_pkts (p_lcb, NULL, p_buf);
1089 /*******************************************************************************
1091 ** Function l2cu_send_peer_info_req
1093 ** Description Build and send an L2CAP "info request" message
1097 *******************************************************************************/
1098 void l2cu_send_peer_info_req (tL2C_LCB *p_lcb, UINT16 info_type)
1103 /* check for wrap and/or BRCM ID */
1105 l2cu_adj_id(p_lcb, L2CAP_ADJ_ID);
1107 if ((p_buf = l2cu_build_header(p_lcb, 2, L2CAP_CMD_INFO_REQ, p_lcb->id)) == NULL)
1109 L2CAP_TRACE_WARNING ("L2CAP - no buffer for info_req");
1113 L2CAP_TRACE_EVENT ("l2cu_send_peer_info_req: type 0x%04x", info_type);
1115 p = (UINT8 *)(p_buf + 1) + L2CAP_SEND_CMD_OFFSET+HCI_DATA_PREAMBLE_SIZE +
1116 L2CAP_PKT_OVERHEAD + L2CAP_CMD_OVERHEAD;
1118 UINT16_TO_STREAM (p, info_type);
1120 p_lcb->w4_info_rsp = TRUE;
1121 btu_start_timer (&p_lcb->info_timer_entry, BTU_TTYPE_L2CAP_INFO, L2CAP_WAIT_INFO_RSP_TOUT);
1123 l2c_link_check_send_pkts (p_lcb, NULL, p_buf);
1127 /*******************************************************************************
1129 ** Function l2cu_send_peer_info_rsp
1131 ** Description Build and send an L2CAP "info response" message
1136 *******************************************************************************/
1137 void l2cu_send_peer_info_rsp (tL2C_LCB *p_lcb, UINT8 remote_id, UINT16 info_type)
1141 UINT16 len = L2CAP_INFO_RSP_LEN;
1143 #if (L2CAP_CONFORMANCE_TESTING == TRUE)
1144 if ((info_type == L2CAP_EXTENDED_FEATURES_INFO_TYPE)
1145 && (l2cb.test_info_resp & (L2CAP_EXTFEA_ENH_RETRANS | L2CAP_EXTFEA_STREAM_MODE |
1146 L2CAP_EXTFEA_NO_CRC | L2CAP_EXTFEA_EXT_FLOW_SPEC |
1147 L2CAP_EXTFEA_FIXED_CHNLS | L2CAP_EXTFEA_EXT_WINDOW |
1148 L2CAP_EXTFEA_UCD_RECEPTION )) )
1150 if ((info_type == L2CAP_EXTENDED_FEATURES_INFO_TYPE)
1151 && (L2CAP_EXTFEA_SUPPORTED_MASK & (L2CAP_EXTFEA_ENH_RETRANS | L2CAP_EXTFEA_STREAM_MODE |
1152 L2CAP_EXTFEA_NO_CRC |L2CAP_EXTFEA_FIXED_CHNLS |
1153 L2CAP_EXTFEA_UCD_RECEPTION )) )
1156 len += L2CAP_EXTENDED_FEATURES_ARRAY_SIZE;
1158 else if (info_type == L2CAP_FIXED_CHANNELS_INFO_TYPE)
1160 len += L2CAP_FIXED_CHNL_ARRAY_SIZE;
1162 else if (info_type == L2CAP_CONNLESS_MTU_INFO_TYPE)
1164 len += L2CAP_CONNLESS_MTU_INFO_SIZE;
1167 if ((p_buf = l2cu_build_header(p_lcb, len, L2CAP_CMD_INFO_RSP, remote_id)) == NULL)
1169 L2CAP_TRACE_WARNING ("L2CAP - no buffer for info_rsp");
1173 p = (UINT8 *)(p_buf + 1) + L2CAP_SEND_CMD_OFFSET + HCI_DATA_PREAMBLE_SIZE +
1174 L2CAP_PKT_OVERHEAD + L2CAP_CMD_OVERHEAD;
1176 UINT16_TO_STREAM (p, info_type);
1178 #if (L2CAP_CONFORMANCE_TESTING == TRUE)
1179 if ((info_type == L2CAP_EXTENDED_FEATURES_INFO_TYPE)
1180 && (l2cb.test_info_resp & ( L2CAP_EXTFEA_ENH_RETRANS | L2CAP_EXTFEA_STREAM_MODE
1181 | L2CAP_EXTFEA_UCD_RECEPTION )) )
1183 if ((info_type == L2CAP_EXTENDED_FEATURES_INFO_TYPE)
1184 && (L2CAP_EXTFEA_SUPPORTED_MASK & ( L2CAP_EXTFEA_ENH_RETRANS | L2CAP_EXTFEA_STREAM_MODE
1185 | L2CAP_EXTFEA_UCD_RECEPTION )) )
1188 UINT16_TO_STREAM (p, L2CAP_INFO_RESP_RESULT_SUCCESS);
1189 #if (BLE_INCLUDED == TRUE)
1190 if (p_lcb->transport == BT_TRANSPORT_LE)
1192 /* optional data are not added for now */
1193 UINT32_TO_STREAM (p, L2CAP_BLE_EXTFEA_MASK);
1198 #if L2CAP_CONFORMANCE_TESTING == TRUE
1199 UINT32_TO_STREAM (p, l2cb.test_info_resp);
1201 #if (L2CAP_NUM_FIXED_CHNLS > 0)
1202 UINT32_TO_STREAM (p, L2CAP_EXTFEA_SUPPORTED_MASK | L2CAP_EXTFEA_FIXED_CHNLS);
1204 UINT32_TO_STREAM (p, L2CAP_EXTFEA_SUPPORTED_MASK);
1209 else if (info_type == L2CAP_FIXED_CHANNELS_INFO_TYPE)
1211 UINT16_TO_STREAM (p, L2CAP_INFO_RESP_RESULT_SUCCESS);
1212 memset (p, 0, L2CAP_FIXED_CHNL_ARRAY_SIZE);
1214 p[0] = L2CAP_FIXED_CHNL_SIG_BIT;
1216 if ( L2CAP_EXTFEA_SUPPORTED_MASK & L2CAP_EXTFEA_UCD_RECEPTION )
1217 p[0] |= L2CAP_FIXED_CHNL_CNCTLESS_BIT;
1219 #if (L2CAP_NUM_FIXED_CHNLS > 0)
1223 for (xx = 0; xx < L2CAP_NUM_FIXED_CHNLS; xx++)
1224 if (l2cb.fixed_reg[xx].pL2CA_FixedConn_Cb != NULL)
1225 p[0] |= 1 << (xx + L2CAP_FIRST_FIXED_CHNL);
1229 else if (info_type == L2CAP_CONNLESS_MTU_INFO_TYPE)
1231 UINT16_TO_STREAM (p, L2CAP_INFO_RESP_RESULT_SUCCESS);
1232 UINT16_TO_STREAM (p, L2CAP_UCD_MTU);
1236 UINT16_TO_STREAM (p, L2CAP_INFO_RESP_RESULT_NOT_SUPPORTED); /* 'not supported' */
1239 l2c_link_check_send_pkts (p_lcb, NULL, p_buf);
1242 /******************************************************************************
1244 ** Function l2cu_enqueue_ccb
1246 ** Description queue CCB by priority. The first CCB is highest priority and
1247 ** is served at first. The CCB is queued to an LLCB or an LCB.
1251 *******************************************************************************/
1252 void l2cu_enqueue_ccb (tL2C_CCB *p_ccb)
1255 tL2C_CCB_Q *p_q = NULL;
1257 /* Find out which queue the channel is on
1259 if (p_ccb->p_lcb != NULL)
1260 p_q = &p_ccb->p_lcb->ccb_queue;
1262 if ( (!p_ccb->in_use) || (p_q == NULL) )
1264 L2CAP_TRACE_ERROR ("l2cu_enqueue_ccb CID: 0x%04x ERROR in_use: %u p_lcb: 0x%08x",
1265 p_ccb->local_cid, p_ccb->in_use, p_ccb->p_lcb);
1269 L2CAP_TRACE_DEBUG ("l2cu_enqueue_ccb CID: 0x%04x priority: %d",
1270 p_ccb->local_cid, p_ccb->ccb_priority);
1272 /* If the queue is empty, we go at the front */
1273 if (!p_q->p_first_ccb)
1275 p_q->p_first_ccb = p_q->p_last_ccb = p_ccb;
1276 p_ccb->p_next_ccb = p_ccb->p_prev_ccb = NULL;
1280 p_ccb1 = p_q->p_first_ccb;
1282 while (p_ccb1 != NULL)
1284 /* Insert new ccb at the end of the same priority. Lower number, higher priority */
1285 if (p_ccb->ccb_priority < p_ccb1->ccb_priority)
1287 /* Are we at the head of the queue ? */
1288 if (p_ccb1 == p_q->p_first_ccb)
1289 p_q->p_first_ccb = p_ccb;
1291 p_ccb1->p_prev_ccb->p_next_ccb = p_ccb;
1293 p_ccb->p_next_ccb = p_ccb1;
1294 p_ccb->p_prev_ccb = p_ccb1->p_prev_ccb;
1295 p_ccb1->p_prev_ccb = p_ccb;
1299 p_ccb1 = p_ccb1->p_next_ccb;
1302 /* If we are lower then anyone in the list, we go at the end */
1305 /* add new ccb at the end of the list */
1306 p_q->p_last_ccb->p_next_ccb = p_ccb;
1308 p_ccb->p_next_ccb = NULL;
1309 p_ccb->p_prev_ccb = p_q->p_last_ccb;
1310 p_q->p_last_ccb = p_ccb;
1314 #if (L2CAP_ROUND_ROBIN_CHANNEL_SERVICE == TRUE)
1315 /* Adding CCB into round robin service table of its LCB */
1316 if (p_ccb->p_lcb != NULL)
1318 /* if this is the first channel in this priority group */
1319 if (p_ccb->p_lcb->rr_serv[p_ccb->ccb_priority].num_ccb == 0 )
1321 /* Set the first channel to this CCB */
1322 p_ccb->p_lcb->rr_serv[p_ccb->ccb_priority].p_first_ccb = p_ccb;
1323 /* Set the next serving channel in this group to this CCB */
1324 p_ccb->p_lcb->rr_serv[p_ccb->ccb_priority].p_serve_ccb = p_ccb;
1325 /* Initialize quota of this priority group based on its priority */
1326 p_ccb->p_lcb->rr_serv[p_ccb->ccb_priority].quota = L2CAP_GET_PRIORITY_QUOTA(p_ccb->ccb_priority);
1328 /* increase number of channels in this group */
1329 p_ccb->p_lcb->rr_serv[p_ccb->ccb_priority].num_ccb++;
1335 /******************************************************************************
1337 ** Function l2cu_dequeue_ccb
1339 ** Description dequeue CCB from a queue
1343 *******************************************************************************/
1344 void l2cu_dequeue_ccb (tL2C_CCB *p_ccb)
1346 tL2C_CCB_Q *p_q = NULL;
1348 L2CAP_TRACE_DEBUG ("l2cu_dequeue_ccb CID: 0x%04x", p_ccb->local_cid);
1350 /* Find out which queue the channel is on
1352 if (p_ccb->p_lcb != NULL)
1353 p_q = &p_ccb->p_lcb->ccb_queue;
1355 if ( (!p_ccb->in_use) || (p_q == NULL) || (p_q->p_first_ccb == NULL) )
1357 L2CAP_TRACE_ERROR ("l2cu_dequeue_ccb CID: 0x%04x ERROR in_use: %u p_lcb: 0x%08x p_q: 0x%08x p_q->p_first_ccb: 0x%08x",
1358 p_ccb->local_cid, p_ccb->in_use, p_ccb->p_lcb, p_q, p_q ? p_q->p_first_ccb : 0);
1362 #if (L2CAP_ROUND_ROBIN_CHANNEL_SERVICE == TRUE)
1363 /* Removing CCB from round robin service table of its LCB */
1364 if (p_ccb->p_lcb != NULL)
1366 /* decrease number of channels in this priority group */
1367 p_ccb->p_lcb->rr_serv[p_ccb->ccb_priority].num_ccb--;
1369 /* if it was the last channel in the priority group */
1370 if (p_ccb->p_lcb->rr_serv[p_ccb->ccb_priority].num_ccb == 0 )
1372 p_ccb->p_lcb->rr_serv[p_ccb->ccb_priority].p_first_ccb = NULL;
1373 p_ccb->p_lcb->rr_serv[p_ccb->ccb_priority].p_serve_ccb = NULL;
1377 /* if it is the first channel of this group */
1378 if ( p_ccb->p_lcb->rr_serv[p_ccb->ccb_priority].p_first_ccb == p_ccb )
1380 p_ccb->p_lcb->rr_serv[p_ccb->ccb_priority].p_first_ccb = p_ccb->p_next_ccb;
1382 /* if it is the next serving channel of this group */
1383 if ( p_ccb->p_lcb->rr_serv[p_ccb->ccb_priority].p_serve_ccb == p_ccb )
1385 /* simply, start serving from the first channel */
1386 p_ccb->p_lcb->rr_serv[p_ccb->ccb_priority].p_serve_ccb
1387 = p_ccb->p_lcb->rr_serv[p_ccb->ccb_priority].p_first_ccb;
1393 if (p_ccb == p_q->p_first_ccb)
1395 /* We are removing the first in a queue */
1396 p_q->p_first_ccb = p_ccb->p_next_ccb;
1398 if (p_q->p_first_ccb)
1399 p_q->p_first_ccb->p_prev_ccb = NULL;
1401 p_q->p_last_ccb = NULL;
1403 else if (p_ccb == p_q->p_last_ccb)
1405 /* We are removing the last in a queue */
1406 p_q->p_last_ccb = p_ccb->p_prev_ccb;
1407 p_q->p_last_ccb->p_next_ccb = NULL;
1411 /* In the middle of a chain. */
1412 p_ccb->p_prev_ccb->p_next_ccb = p_ccb->p_next_ccb;
1413 p_ccb->p_next_ccb->p_prev_ccb = p_ccb->p_prev_ccb;
1416 p_ccb->p_next_ccb = p_ccb->p_prev_ccb = NULL;
1419 /******************************************************************************
1421 ** Function l2cu_change_pri_ccb
1427 *******************************************************************************/
1428 void l2cu_change_pri_ccb (tL2C_CCB *p_ccb, tL2CAP_CHNL_PRIORITY priority)
1430 if (p_ccb->ccb_priority != priority)
1432 /* If CCB is not the only guy on the queue */
1433 if ( (p_ccb->p_next_ccb != NULL) || (p_ccb->p_prev_ccb != NULL) )
1435 L2CAP_TRACE_DEBUG ("Update CCB list in logical link");
1437 /* Remove CCB from queue and re-queue it at new priority */
1438 l2cu_dequeue_ccb (p_ccb);
1440 p_ccb->ccb_priority = priority;
1441 l2cu_enqueue_ccb (p_ccb);
1443 #if (L2CAP_ROUND_ROBIN_CHANNEL_SERVICE == TRUE)
1446 /* If CCB is the only guy on the queue, no need to re-enqueue */
1447 /* update only round robin service data */
1448 p_ccb->p_lcb->rr_serv[p_ccb->ccb_priority].num_ccb = 0;
1449 p_ccb->p_lcb->rr_serv[p_ccb->ccb_priority].p_first_ccb = NULL;
1450 p_ccb->p_lcb->rr_serv[p_ccb->ccb_priority].p_serve_ccb = NULL;
1452 p_ccb->ccb_priority = priority;
1454 p_ccb->p_lcb->rr_serv[p_ccb->ccb_priority].p_first_ccb = p_ccb;
1455 p_ccb->p_lcb->rr_serv[p_ccb->ccb_priority].p_serve_ccb = p_ccb;
1456 p_ccb->p_lcb->rr_serv[p_ccb->ccb_priority].quota = L2CAP_GET_PRIORITY_QUOTA(p_ccb->ccb_priority);
1457 p_ccb->p_lcb->rr_serv[p_ccb->ccb_priority].num_ccb = 1;
1463 /*******************************************************************************
1465 ** Function l2cu_allocate_ccb
1467 ** Description This function allocates a Channel Control Block and
1468 ** attaches it to a link control block. The local CID
1469 ** is also assigned.
1471 ** Returns pointer to CCB, or NULL if none
1473 *******************************************************************************/
1474 tL2C_CCB *l2cu_allocate_ccb (tL2C_LCB *p_lcb, UINT16 cid)
1479 L2CAP_TRACE_DEBUG ("l2cu_allocate_ccb: cid 0x%04x", cid);
1481 if (!l2cb.p_free_ccb_first)
1484 /* If a CID was passed in, use that, else take the first free one */
1487 p_ccb = l2cb.p_free_ccb_first;
1488 l2cb.p_free_ccb_first = p_ccb->p_next_ccb;
1494 p_ccb = &l2cb.ccb_pool[cid - L2CAP_BASE_APPL_CID];
1496 if (p_ccb == l2cb.p_free_ccb_first)
1497 l2cb.p_free_ccb_first = p_ccb->p_next_ccb;
1500 for (p_prev = l2cb.p_free_ccb_first; p_prev != NULL; p_prev = p_prev->p_next_ccb)
1502 if (p_prev->p_next_ccb == p_ccb)
1504 p_prev->p_next_ccb = p_ccb->p_next_ccb;
1506 if (p_ccb == l2cb.p_free_ccb_last)
1507 l2cb.p_free_ccb_last = p_prev;
1514 L2CAP_TRACE_ERROR ("l2cu_allocate_ccb: could not find CCB for CID 0x%04x in the free list", cid);
1520 p_ccb->p_next_ccb = p_ccb->p_prev_ccb = NULL;
1522 p_ccb->in_use = TRUE;
1524 /* Get a CID for the connection */
1525 p_ccb->local_cid = L2CAP_BASE_APPL_CID + (UINT16)(p_ccb - l2cb.ccb_pool);
1527 p_ccb->p_lcb = p_lcb;
1528 p_ccb->p_rcb = NULL;
1530 /* Set priority then insert ccb into LCB queue (if we have an LCB) */
1531 p_ccb->ccb_priority = L2CAP_CHNL_PRIORITY_LOW;
1534 l2cu_enqueue_ccb (p_ccb);
1536 /* clear what peer wants to configure */
1537 p_ccb->peer_cfg_bits = 0;
1539 /* Put in default values for configuration */
1540 memset (&p_ccb->our_cfg, 0, sizeof(tL2CAP_CFG_INFO));
1541 memset (&p_ccb->peer_cfg, 0, sizeof(tL2CAP_CFG_INFO));
1543 /* Put in default values for local/peer configurations */
1544 p_ccb->our_cfg.flush_to = p_ccb->peer_cfg.flush_to = L2CAP_DEFAULT_FLUSH_TO;
1545 p_ccb->our_cfg.mtu = p_ccb->peer_cfg.mtu = L2CAP_DEFAULT_MTU;
1546 p_ccb->our_cfg.qos.service_type = p_ccb->peer_cfg.qos.service_type = L2CAP_DEFAULT_SERV_TYPE;
1547 p_ccb->our_cfg.qos.token_rate = p_ccb->peer_cfg.qos.token_rate = L2CAP_DEFAULT_TOKEN_RATE;
1548 p_ccb->our_cfg.qos.token_bucket_size = p_ccb->peer_cfg.qos.token_bucket_size = L2CAP_DEFAULT_BUCKET_SIZE;
1549 p_ccb->our_cfg.qos.peak_bandwidth = p_ccb->peer_cfg.qos.peak_bandwidth = L2CAP_DEFAULT_PEAK_BANDWIDTH;
1550 p_ccb->our_cfg.qos.latency = p_ccb->peer_cfg.qos.latency = L2CAP_DEFAULT_LATENCY;
1551 p_ccb->our_cfg.qos.delay_variation = p_ccb->peer_cfg.qos.delay_variation = L2CAP_DEFAULT_DELAY;
1553 p_ccb->bypass_fcs = 0;
1554 memset (&p_ccb->ertm_info, 0, sizeof(tL2CAP_ERTM_INFO));
1555 p_ccb->peer_cfg_already_rejected = FALSE;
1556 p_ccb->fcr_cfg_tries = L2CAP_MAX_FCR_CFG_TRIES;
1557 p_ccb->fcrb.ack_timer.param = (TIMER_PARAM_TYPE)p_ccb;
1559 /* if timer is running, remove it from timer list */
1560 if (p_ccb->fcrb.ack_timer.in_use)
1561 btu_stop_quick_timer (&p_ccb->fcrb.ack_timer);
1563 p_ccb->fcrb.mon_retrans_timer.param = (TIMER_PARAM_TYPE)p_ccb;
1566 /* CSP408639 Fix: When L2CAP send amp move channel request or receive
1567 * L2CEVT_AMP_MOVE_REQ do following sequence. Send channel move
1568 * request -> Stop retrans/monitor timer -> Change channel state to CST_AMP_MOVING. */
1569 if (p_ccb->fcrb.mon_retrans_timer.in_use)
1570 btu_stop_quick_timer (&p_ccb->fcrb.mon_retrans_timer);
1573 l2c_fcr_stop_timer (p_ccb);
1575 p_ccb->ertm_info.preferred_mode = L2CAP_FCR_BASIC_MODE; /* Default mode for channel is basic mode */
1576 p_ccb->ertm_info.allowed_modes = L2CAP_FCR_CHAN_OPT_BASIC; /* Default mode for channel is basic mode */
1577 p_ccb->ertm_info.fcr_rx_pool_id = L2CAP_FCR_RX_POOL_ID;
1578 p_ccb->ertm_info.fcr_tx_pool_id = L2CAP_FCR_TX_POOL_ID;
1579 p_ccb->ertm_info.user_rx_pool_id = HCI_ACL_POOL_ID;
1580 p_ccb->ertm_info.user_tx_pool_id = HCI_ACL_POOL_ID;
1581 p_ccb->max_rx_mtu = L2CAP_MTU_SIZE;
1582 p_ccb->tx_mps = GKI_get_pool_bufsize(HCI_ACL_POOL_ID) - 32;
1584 GKI_init_q (&p_ccb->xmit_hold_q);
1586 p_ccb->cong_sent = FALSE;
1587 p_ccb->buff_quota = 2; /* This gets set after config */
1589 /* If CCB was reserved Config_Done can already have some value */
1591 p_ccb->config_done = 0;
1594 L2CAP_TRACE_DEBUG ("l2cu_allocate_ccb: cid 0x%04x config_done:0x%x", cid, p_ccb->config_done);
1597 p_ccb->chnl_state = CST_CLOSED;
1599 p_ccb->tx_data_rate = L2CAP_CHNL_DATA_RATE_LOW;
1600 p_ccb->rx_data_rate = L2CAP_CHNL_DATA_RATE_LOW;
1602 #if (L2CAP_NON_FLUSHABLE_PB_INCLUDED == TRUE)
1603 p_ccb->is_flushable = FALSE;
1606 p_ccb->timer_entry.param = (TIMER_PARAM_TYPE)p_ccb;
1607 p_ccb->timer_entry.in_use = 0;
1609 l2c_link_adjust_chnl_allocation ();
1614 /*******************************************************************************
1616 ** Function l2cu_start_post_bond_timer
1618 ** Description This function starts the ACL Link inactivity timer after
1619 ** dedicated bonding
1620 ** This timer can be longer than the normal link inactivity
1621 ** timer for some platforms.
1623 ** Returns BOOLEAN - TRUE if idle timer started or disconnect initiated
1624 ** FALSE if there's one or more pending CCB's exist
1626 *******************************************************************************/
1627 BOOLEAN l2cu_start_post_bond_timer (UINT16 handle)
1630 tL2C_LCB *p_lcb = l2cu_find_lcb_by_handle(handle);
1635 p_lcb->is_bonding = FALSE;
1637 /* Only start timer if no control blocks allocated */
1638 if (p_lcb->ccb_queue.p_first_ccb != NULL)
1641 /* If no channels on the connection, start idle timeout */
1642 if ( (p_lcb->link_state == LST_CONNECTED) || (p_lcb->link_state == LST_CONNECTING) || (p_lcb->link_state == LST_DISCONNECTING) )
1644 if (p_lcb->idle_timeout == 0)
1646 if (btsnd_hcic_disconnect (p_lcb->handle, HCI_ERR_PEER_USER))
1648 p_lcb->link_state = LST_DISCONNECTING;
1649 timeout = L2CAP_LINK_DISCONNECT_TOUT;
1652 timeout = BT_1SEC_TIMEOUT;
1656 timeout = L2CAP_BONDING_TIMEOUT;
1659 if (timeout != 0xFFFF)
1660 btu_start_timer (&p_lcb->timer_entry, BTU_TTYPE_L2CAP_LINK, timeout);
1668 /*******************************************************************************
1670 ** Function l2cu_release_ccb
1672 ** Description This function releases a Channel Control Block. The timer
1673 ** is stopped, any attached buffers freed, and the CCB is removed
1674 ** from the link control block.
1678 *******************************************************************************/
1679 void l2cu_release_ccb (tL2C_CCB *p_ccb)
1681 tL2C_LCB *p_lcb = p_ccb->p_lcb;
1682 tL2C_RCB *p_rcb = p_ccb->p_rcb;
1684 L2CAP_TRACE_DEBUG ("l2cu_release_ccb: cid 0x%04x in_use: %u", p_ccb->local_cid, p_ccb->in_use);
1686 /* If already released, could be race condition */
1690 if (p_rcb && (p_rcb->psm != p_rcb->real_psm))
1692 btm_sec_clr_service_by_psm(p_rcb->psm);
1695 btm_sec_clr_temp_auth_service (p_lcb->remote_bd_addr);
1697 /* Stop the timer */
1698 btu_stop_timer (&p_ccb->timer_entry);
1700 while (p_ccb->xmit_hold_q.p_first)
1701 GKI_freebuf (GKI_dequeue (&p_ccb->xmit_hold_q));
1703 l2c_fcr_cleanup (p_ccb);
1705 /* Channel may not be assigned to any LCB if it was just pre-reserved */
1707 ( (p_ccb->local_cid >= L2CAP_BASE_APPL_CID)
1708 #if (L2CAP_UCD_INCLUDED == TRUE)
1709 ||(p_ccb->local_cid == L2CAP_CONNECTIONLESS_CID)
1714 l2cu_dequeue_ccb (p_ccb);
1716 /* Delink the CCB from the LCB */
1717 p_ccb->p_lcb = NULL;
1720 /* Put the CCB back on the free pool */
1721 if (!l2cb.p_free_ccb_first)
1723 l2cb.p_free_ccb_first = p_ccb;
1724 l2cb.p_free_ccb_last = p_ccb;
1725 p_ccb->p_next_ccb = NULL;
1726 p_ccb->p_prev_ccb = NULL;
1730 p_ccb->p_next_ccb = NULL;
1731 p_ccb->p_prev_ccb = l2cb.p_free_ccb_last;
1732 l2cb.p_free_ccb_last->p_next_ccb = p_ccb;
1733 l2cb.p_free_ccb_last = p_ccb;
1736 /* Flag as not in use */
1737 p_ccb->in_use = FALSE;
1739 /* If no channels on the connection, start idle timeout */
1740 if ((p_lcb) && p_lcb->in_use && (p_lcb->link_state == LST_CONNECTED))
1742 if (!p_lcb->ccb_queue.p_first_ccb)
1744 l2cu_no_dynamic_ccbs (p_lcb);
1748 /* Link is still active, adjust channel quotas. */
1749 l2c_link_adjust_chnl_allocation ();
1754 /*******************************************************************************
1756 ** Function l2cu_find_ccb_by_remote_cid
1758 ** Description Look through all active CCBs on a link for a match based
1759 ** on the remote CID.
1761 ** Returns pointer to matched CCB, or NULL if no match
1763 *******************************************************************************/
1764 tL2C_CCB *l2cu_find_ccb_by_remote_cid (tL2C_LCB *p_lcb, UINT16 remote_cid)
1768 /* If LCB is NULL, look through all active links */
1775 for (p_ccb = p_lcb->ccb_queue.p_first_ccb; p_ccb; p_ccb = p_ccb->p_next_ccb)
1776 if ((p_ccb->in_use) && (p_ccb->remote_cid == remote_cid))
1780 /* If here, no match found */
1784 /*******************************************************************************
1786 ** Function l2cu_allocate_rcb
1788 ** Description Look through the Registration Control Blocks for a free
1791 ** Returns Pointer to the RCB or NULL if not found
1793 *******************************************************************************/
1794 tL2C_RCB *l2cu_allocate_rcb (UINT16 psm)
1796 tL2C_RCB *p_rcb = &l2cb.rcb_pool[0];
1799 for (xx = 0; xx < MAX_L2CAP_CLIENTS; xx++, p_rcb++)
1803 p_rcb->in_use = TRUE;
1805 #if (L2CAP_UCD_INCLUDED == TRUE)
1806 p_rcb->ucd.state = L2C_UCD_STATE_UNUSED;
1812 /* If here, no free RCB found */
1817 /*******************************************************************************
1819 ** Function l2cu_release_rcb
1821 ** Description Mark an RCB as no longet in use
1825 *******************************************************************************/
1826 void l2cu_release_rcb (tL2C_RCB *p_rcb)
1828 p_rcb->in_use = FALSE;
1833 /*******************************************************************************
1835 ** Function l2cu_disconnect_chnl
1837 ** Description Disconnect a channel. Typically, this is due to either
1838 ** receiving a bad configuration, bad packet or max_retries expiring.
1840 *******************************************************************************/
1841 void l2cu_disconnect_chnl (tL2C_CCB *p_ccb)
1843 UINT16 local_cid = p_ccb->local_cid;
1845 if (local_cid >= L2CAP_BASE_APPL_CID)
1847 tL2CA_DISCONNECT_IND_CB *p_disc_cb = p_ccb->p_rcb->api.pL2CA_DisconnectInd_Cb;
1849 L2CAP_TRACE_WARNING ("L2CAP - disconnect_chnl CID: 0x%04x", local_cid);
1851 l2cu_send_peer_disc_req (p_ccb);
1853 l2cu_release_ccb (p_ccb);
1855 (*p_disc_cb)(local_cid, FALSE);
1859 /* failure on the AMP channel, probably need to disconnect ACL */
1860 L2CAP_TRACE_ERROR ("L2CAP - disconnect_chnl CID: 0x%04x Ignored", local_cid);
1865 /*******************************************************************************
1867 ** Function l2cu_find_rcb_by_psm
1869 ** Description Look through the Registration Control Blocks to see if
1870 ** anyone registered to handle the PSM in question
1872 ** Returns Pointer to the RCB or NULL if not found
1874 *******************************************************************************/
1875 tL2C_RCB *l2cu_find_rcb_by_psm (UINT16 psm)
1877 tL2C_RCB *p_rcb = &l2cb.rcb_pool[0];
1880 for (xx = 0; xx < MAX_L2CAP_CLIENTS; xx++, p_rcb++)
1882 if ((p_rcb->in_use) && (p_rcb->psm == psm))
1886 /* If here, no match found */
1891 /*******************************************************************************
1893 ** Function l2cu_process_peer_cfg_req
1895 ** Description This function is called when the peer sends us a "config request"
1896 ** message. It extracts the configuration of interest and saves
1899 ** Note: Negotiation of the FCR channel type is handled internally,
1900 ** all others are passed to the upper layer.
1902 ** Returns UINT8 - L2CAP_PEER_CFG_OK if passed to upper layer,
1903 ** L2CAP_PEER_CFG_UNACCEPTABLE if automatically responded to
1904 ** because parameters are unnacceptable from a specification
1906 ** L2CAP_PEER_CFG_DISCONNECT if no compatible channel modes
1907 ** between the two devices, and shall be closed.
1909 *******************************************************************************/
1910 UINT8 l2cu_process_peer_cfg_req (tL2C_CCB *p_ccb, tL2CAP_CFG_INFO *p_cfg)
1912 BOOLEAN mtu_ok = TRUE;
1913 BOOLEAN qos_type_ok = TRUE;
1914 BOOLEAN flush_to_ok = TRUE;
1915 BOOLEAN fcr_ok = TRUE;
1918 /* Ignore FCR parameters for basic mode */
1919 if (!p_cfg->fcr_present)
1920 p_cfg->fcr.mode = L2CAP_FCR_BASIC_MODE;
1922 /* Save the MTU that our peer can receive */
1923 if (p_cfg->mtu_present)
1925 /* Make sure MTU is at least the minimum */
1926 if (p_cfg->mtu >= L2CAP_MIN_MTU)
1928 /* In basic mode, limit the MTU to our buffer size */
1929 if ( (p_cfg->fcr_present == FALSE) && (p_cfg->mtu > L2CAP_MTU_SIZE) )
1930 p_cfg->mtu = L2CAP_MTU_SIZE;
1932 /* Save the accepted value in case of renegotiation */
1933 p_ccb->peer_cfg.mtu = p_cfg->mtu;
1934 p_ccb->peer_cfg.mtu_present = TRUE;
1935 p_ccb->peer_cfg_bits |= L2CAP_CH_CFG_MASK_MTU;
1937 else /* Illegal MTU value */
1939 p_cfg->mtu = L2CAP_MIN_MTU;
1943 /* Reload mtu from a previously accepted config request */
1944 else if (p_ccb->peer_cfg.mtu_present)
1946 p_cfg->mtu_present = TRUE;
1947 p_cfg->mtu = p_ccb->peer_cfg.mtu;
1950 /* Verify that the flush timeout is a valid value (0 is illegal) */
1951 if (p_cfg->flush_to_present)
1953 if (!p_cfg->flush_to)
1955 p_cfg->flush_to = 0xFFFF; /* Infinite retransmissions (spec default) */
1956 flush_to_ok = FALSE;
1958 else /* Save the accepted value in case of renegotiation */
1960 p_ccb->peer_cfg.flush_to_present = TRUE;
1961 p_ccb->peer_cfg.flush_to = p_cfg->flush_to;
1962 p_ccb->peer_cfg_bits |= L2CAP_CH_CFG_MASK_FLUSH_TO;
1965 /* Reload flush_to from a previously accepted config request */
1966 else if (p_ccb->peer_cfg.flush_to_present)
1968 p_cfg->flush_to_present = TRUE;
1969 p_cfg->flush_to = p_ccb->peer_cfg.flush_to;
1972 /* Save the QOS settings the the peer is using */
1973 if (p_cfg->qos_present)
1975 /* Make sure service type is not a reserved value; otherwise let upper
1976 layer decide if acceptable
1978 if (p_cfg->qos.service_type <= GUARANTEED)
1980 p_ccb->peer_cfg.qos = p_cfg->qos;
1981 p_ccb->peer_cfg.qos_present = TRUE;
1982 p_ccb->peer_cfg_bits |= L2CAP_CH_CFG_MASK_QOS;
1984 else /* Illegal service type value */
1986 p_cfg->qos.service_type = BEST_EFFORT;
1987 qos_type_ok = FALSE;
1990 /* Reload QOS from a previously accepted config request */
1991 else if (p_ccb->peer_cfg.qos_present)
1993 p_cfg->qos_present = TRUE;
1994 p_cfg->qos = p_ccb->peer_cfg.qos;
1997 if ((fcr_status = l2c_fcr_process_peer_cfg_req (p_ccb, p_cfg)) == L2CAP_PEER_CFG_DISCONNECT)
1999 /* Notify caller to disconnect the channel (incompatible modes) */
2000 p_cfg->result = L2CAP_CFG_FAILED_NO_REASON;
2001 p_cfg->mtu_present = p_cfg->qos_present = p_cfg->flush_to_present = 0;
2003 return (L2CAP_PEER_CFG_DISCONNECT);
2006 fcr_ok = (fcr_status == L2CAP_PEER_CFG_OK);
2008 /* Return any unacceptable parameters */
2009 if (mtu_ok && flush_to_ok && qos_type_ok && fcr_ok)
2011 l2cu_adjust_out_mps (p_ccb);
2012 return (L2CAP_PEER_CFG_OK);
2016 p_cfg->result = L2CAP_CFG_UNACCEPTABLE_PARAMS;
2019 p_cfg->mtu_present = FALSE;
2021 p_cfg->flush_to_present = FALSE;
2023 p_cfg->qos_present = FALSE;
2025 p_cfg->fcr_present = FALSE;
2027 return (L2CAP_PEER_CFG_UNACCEPTABLE);
2032 /*******************************************************************************
2034 ** Function l2cu_process_peer_cfg_rsp
2036 ** Description This function is called when the peer sends us a "config response"
2037 ** message. It extracts the configuration of interest and saves
2042 *******************************************************************************/
2043 void l2cu_process_peer_cfg_rsp (tL2C_CCB *p_ccb, tL2CAP_CFG_INFO *p_cfg)
2045 /* If we wanted QoS and the peer sends us a positive response with QoS, use his values */
2046 if ( (p_cfg->qos_present) && (p_ccb->our_cfg.qos_present) )
2047 p_ccb->our_cfg.qos = p_cfg->qos;
2049 if (p_cfg->fcr_present)
2051 /* Save the retransmission and monitor timeout values */
2052 if (p_cfg->fcr.mode == L2CAP_FCR_ERTM_MODE)
2054 p_ccb->peer_cfg.fcr.rtrans_tout = p_cfg->fcr.rtrans_tout;
2055 p_ccb->peer_cfg.fcr.mon_tout = p_cfg->fcr.mon_tout;
2058 /* Calculate the max number of packets for which we can delay sending an ack */
2059 if (p_cfg->fcr.tx_win_sz < p_ccb->our_cfg.fcr.tx_win_sz)
2060 p_ccb->fcrb.max_held_acks = p_cfg->fcr.tx_win_sz / 3;
2062 p_ccb->fcrb.max_held_acks = p_ccb->our_cfg.fcr.tx_win_sz / 3;
2064 L2CAP_TRACE_DEBUG ("l2cu_process_peer_cfg_rsp(): peer tx_win_sz: %d, our tx_win_sz: %d, max_held_acks: %d",
2065 p_cfg->fcr.tx_win_sz, p_ccb->our_cfg.fcr.tx_win_sz, p_ccb->fcrb.max_held_acks);
2069 /*******************************************************************************
2071 ** Function l2cu_process_our_cfg_req
2073 ** Description This function is called when we send a "config request"
2074 ** message. It extracts the configuration of interest and saves
2079 *******************************************************************************/
2080 void l2cu_process_our_cfg_req (tL2C_CCB *p_ccb, tL2CAP_CFG_INFO *p_cfg)
2083 UINT16 hci_flush_to;
2085 /* Save the QOS settings we are using for transmit */
2086 if (p_cfg->qos_present)
2088 p_ccb->our_cfg.qos_present = TRUE;
2089 p_ccb->our_cfg.qos = p_cfg->qos;
2092 if (p_cfg->fcr_present)
2094 /* Override FCR options if attempting streaming or basic */
2095 if (p_cfg->fcr.mode == L2CAP_FCR_BASIC_MODE)
2096 memset(&p_cfg->fcr, 0, sizeof(tL2CAP_FCR_OPTS));
2099 /* On BR/EDR, timer values are zero in config request */
2100 /* On class 2 AMP, timer value in config request shall be non-0 processing time */
2101 /* timer value in config response shall be greater than received processing time */
2102 p_cfg->fcr.mon_tout = p_cfg->fcr.rtrans_tout = 0;
2104 if (p_cfg->fcr.mode == L2CAP_FCR_STREAM_MODE)
2105 p_cfg->fcr.max_transmit = p_cfg->fcr.tx_win_sz = 0;
2108 /* Set the threshold to send acks (may be updated in the cfg response) */
2109 p_ccb->fcrb.max_held_acks = p_cfg->fcr.tx_win_sz / 3;
2111 /* Include FCS option only if peer can handle it */
2112 if (p_ccb->p_lcb->peer_ext_fea & L2CAP_EXTFEA_NO_CRC)
2114 /* FCS check can be bypassed if peer also desires to bypass */
2115 if (p_cfg->fcs_present && p_cfg->fcs == L2CAP_CFG_FCS_BYPASS)
2116 p_ccb->bypass_fcs |= L2CAP_CFG_FCS_OUR;
2119 p_cfg->fcs_present = FALSE;
2123 p_cfg->fcr.mode = L2CAP_FCR_BASIC_MODE;
2126 p_ccb->our_cfg.fcr.mode = p_cfg->fcr.mode;
2127 p_ccb->our_cfg.fcr_present = p_cfg->fcr_present;
2129 /* Check the flush timeout. If it is lower than the current one used */
2130 /* then we need to adjust the flush timeout sent to the controller */
2131 if (p_cfg->flush_to_present)
2133 if ((p_cfg->flush_to == 0)||(p_cfg->flush_to == L2CAP_NO_AUTOMATIC_FLUSH))
2135 /* don't send invalid flush timeout */
2136 /* SPEC: The sender of the Request shall specify its flush timeout value */
2137 /* if it differs from the default value of 0xFFFF */
2138 p_cfg->flush_to_present = FALSE;
2142 p_ccb->our_cfg.flush_to = p_cfg->flush_to;
2143 p_lcb = p_ccb->p_lcb;
2145 if (p_cfg->flush_to < p_lcb->link_flush_tout)
2147 p_lcb->link_flush_tout = p_cfg->flush_to;
2149 /* If the timeout is within range of HCI, set the flush timeout */
2150 if (p_cfg->flush_to <= ((HCI_MAX_AUTO_FLUSH_TOUT * 5) / 8))
2152 /* Convert flush timeout to 0.625 ms units, with round */
2153 hci_flush_to = ((p_cfg->flush_to * 8) + 3) / 5;
2154 btsnd_hcic_write_auto_flush_tout (p_lcb->handle, hci_flush_to);
2162 /*******************************************************************************
2164 ** Function l2cu_process_our_cfg_rsp
2166 ** Description This function is called when we send the peer a "config response"
2167 ** message. It extracts the configuration of interest and saves
2172 *******************************************************************************/
2173 void l2cu_process_our_cfg_rsp (tL2C_CCB *p_ccb, tL2CAP_CFG_INFO *p_cfg)
2175 /* If peer wants QoS, we are allowed to change the values in a positive response */
2176 if ( (p_cfg->qos_present) && (p_ccb->peer_cfg.qos_present) )
2177 p_ccb->peer_cfg.qos = p_cfg->qos;
2179 p_cfg->qos_present = FALSE;
2181 l2c_fcr_adj_our_rsp_options (p_ccb, p_cfg);
2185 /*******************************************************************************
2187 ** Function l2cu_device_reset
2189 ** Description This function is called when reset of the device is
2190 ** completed. For all active connection simulate HCI_DISC
2194 *******************************************************************************/
2195 void l2cu_device_reset (void)
2198 tL2C_LCB *p_lcb = &l2cb.lcb_pool[0];
2200 for (xx = 0; xx < MAX_L2CAP_LINKS; xx++, p_lcb++)
2202 if ((p_lcb->in_use) && (p_lcb->handle != HCI_INVALID_HANDLE))
2204 l2c_link_hci_disc_comp (p_lcb->handle, (UINT8) -1);
2207 #if (BLE_INCLUDED == TRUE)
2208 l2cb.is_ble_connecting = FALSE;
2212 #if (TCS_WUG_MEMBER_INCLUDED == TRUE && TCS_INCLUDED == TRUE)
2213 extern UINT16 tcs_wug_get_clk_offset( BD_ADDR addr ) ;
2216 /*******************************************************************************
2218 ** Function l2cu_create_conn
2220 ** Description This function initiates an acl connection via HCI
2222 ** Returns TRUE if successful, FALSE if gki get buffer fails.
2224 *******************************************************************************/
2225 BOOLEAN l2cu_create_conn (tL2C_LCB *p_lcb, tBT_TRANSPORT transport)
2228 tL2C_LCB *p_lcb_cur = &l2cb.lcb_pool[0];
2229 #if BTM_SCO_INCLUDED == TRUE
2230 BOOLEAN is_sco_active;
2233 #if (BLE_INCLUDED == TRUE)
2234 tBT_DEVICE_TYPE dev_type;
2235 tBLE_ADDR_TYPE addr_type;
2238 BTM_ReadDevInfo(p_lcb->remote_bd_addr, &dev_type, &addr_type);
2240 if (transport == BT_TRANSPORT_LE)
2242 if (!HCI_LE_HOST_SUPPORTED(btm_cb.devcb.local_lmp_features[HCI_EXT_FEATURES_PAGE_1]))
2245 p_lcb->ble_addr_type = addr_type;
2246 p_lcb->transport = BT_TRANSPORT_LE;
2248 return (l2cble_create_conn(p_lcb));
2252 /* If there is a connection where we perform as a slave, try to switch roles
2253 for this connection */
2254 for (xx = 0, p_lcb_cur = &l2cb.lcb_pool[0]; xx < MAX_L2CAP_LINKS; xx++, p_lcb_cur++)
2256 if (p_lcb_cur == p_lcb)
2259 if ((p_lcb_cur->in_use) && (p_lcb_cur->link_role == HCI_ROLE_SLAVE))
2262 #if BTM_SCO_INCLUDED == TRUE
2263 /* The LMP_switch_req shall be sent only if the ACL logical transport
2264 is in active mode, when encryption is disabled, and all synchronous
2265 logical transports on the same physical link are disabled." */
2267 /* Check if there is any SCO Active on this BD Address */
2268 is_sco_active = btm_is_sco_active_by_bdaddr(p_lcb_cur->remote_bd_addr);
2270 L2CAP_TRACE_API ("l2cu_create_conn - btm_is_sco_active_by_bdaddr() is_sco_active = %s", \
2271 (is_sco_active == TRUE) ? "TRUE":"FALSE");
2273 if (is_sco_active == TRUE)
2274 continue; /* No Master Slave switch not allowed when SCO Active */
2276 /*4_1_TODO check if btm_cb.devcb.local_features to be used instead */
2277 if (HCI_SWITCH_SUPPORTED(BTM_ReadLocalFeatures()))
2279 /* mark this lcb waiting for switch to be completed and
2280 start switch on the other one */
2281 p_lcb->link_state = LST_CONNECTING_WAIT_SWITCH;
2282 p_lcb->link_role = HCI_ROLE_MASTER;
2284 if (BTM_SwitchRole (p_lcb_cur->remote_bd_addr, HCI_ROLE_MASTER, NULL) == BTM_CMD_STARTED)
2286 btu_start_timer (&p_lcb->timer_entry, BTU_TTYPE_L2CAP_LINK, L2CAP_LINK_ROLE_SWITCH_TOUT);
2293 p_lcb->link_state = LST_CONNECTING;
2295 return (l2cu_create_conn_after_switch (p_lcb));
2298 /*******************************************************************************
2300 ** Function l2cu_get_num_hi_priority
2302 ** Description Gets the number of high priority channels.
2306 *******************************************************************************/
2307 UINT8 l2cu_get_num_hi_priority (void)
2311 tL2C_LCB *p_lcb = &l2cb.lcb_pool[0];
2313 for (xx = 0; xx < MAX_L2CAP_LINKS; xx++, p_lcb++)
2315 if ((p_lcb->in_use) && (p_lcb->acl_priority == L2CAP_PRIORITY_HIGH))
2324 /*******************************************************************************
2326 ** Function l2cu_create_conn_after_switch
2328 ** Description This function initiates an acl connection via HCI
2329 ** If switch required to create connection it is already done.
2331 ** Returns TRUE if successful, FALSE if gki get buffer fails.
2333 *******************************************************************************/
2335 BOOLEAN l2cu_create_conn_after_switch (tL2C_LCB *p_lcb)
2337 UINT8 allow_switch = HCI_CR_CONN_ALLOW_SWITCH;
2338 tBTM_INQ_INFO *p_inq_info;
2339 UINT8 page_scan_rep_mode;
2340 UINT8 page_scan_mode;
2341 UINT16 clock_offset;
2343 UINT16 num_acl = BTM_GetNumAclLinks();
2344 tBTM_SEC_DEV_REC *p_dev_rec = btm_find_dev (p_lcb->remote_bd_addr);
2345 UINT8 no_hi_prio_chs = l2cu_get_num_hi_priority();
2347 p_features = BTM_ReadLocalFeatures();
2349 L2CAP_TRACE_DEBUG ("l2cu_create_conn_after_switch :%d num_acl:%d no_hi: %d is_bonding:%d",
2350 l2cb.disallow_switch, num_acl, no_hi_prio_chs, p_lcb->is_bonding);
2351 /* FW team says that we can participant in 4 piconets
2352 * typically 3 piconet + 1 for scanning.
2353 * We can enhance the code to count the number of piconets later. */
2354 if ( ((!l2cb.disallow_switch && (num_acl < 3)) || (p_lcb->is_bonding && (no_hi_prio_chs==0)))
2355 && HCI_SWITCH_SUPPORTED(p_features))
2356 allow_switch = HCI_CR_CONN_ALLOW_SWITCH;
2358 allow_switch = HCI_CR_CONN_NOT_ALLOW_SWITCH;
2360 p_lcb->link_state = LST_CONNECTING;
2363 #if (TCS_WUG_MEMBER_INCLUDED == TRUE && TCS_INCLUDED == TRUE)
2364 if ( (clock_offset = tcs_wug_get_clk_offset( p_lcb->remote_bd_addr )) != 0 )
2366 page_scan_rep_mode = HCI_PAGE_SCAN_REP_MODE_R0;
2367 page_scan_mode = HCI_MANDATARY_PAGE_SCAN_MODE;
2373 /* Check with the BT manager if details about remote device are known */
2374 if ((p_inq_info = BTM_InqDbRead(p_lcb->remote_bd_addr)) != NULL)
2376 page_scan_rep_mode = p_inq_info->results.page_scan_rep_mode;
2377 page_scan_mode = p_inq_info->results.page_scan_mode;
2378 clock_offset = (UINT16)(p_inq_info->results.clock_offset);
2382 /* No info known. Use default settings */
2383 page_scan_rep_mode = HCI_PAGE_SCAN_REP_MODE_R1;
2384 page_scan_mode = HCI_MANDATARY_PAGE_SCAN_MODE;
2386 clock_offset = (p_dev_rec) ? p_dev_rec->clock_offset : 0;
2388 #if (TCS_WUG_MEMBER_INCLUDED == TRUE && TCS_INCLUDED == TRUE)
2392 if (!btsnd_hcic_create_conn (p_lcb->remote_bd_addr,
2393 ( HCI_PKT_TYPES_MASK_DM1 | HCI_PKT_TYPES_MASK_DH1
2394 | HCI_PKT_TYPES_MASK_DM3 | HCI_PKT_TYPES_MASK_DH3
2395 | HCI_PKT_TYPES_MASK_DM5 | HCI_PKT_TYPES_MASK_DH5 ),
2402 L2CAP_TRACE_ERROR ("L2CAP - no buffer for l2cu_create_conn");
2403 l2cu_release_lcb (p_lcb);
2407 #if (defined(BTM_BUSY_LEVEL_CHANGE_INCLUDED) && BTM_BUSY_LEVEL_CHANGE_INCLUDED == TRUE)
2408 btm_acl_update_busy_level (BTM_BLI_PAGE_EVT);
2411 btu_start_timer (&p_lcb->timer_entry, BTU_TTYPE_L2CAP_LINK,
2412 L2CAP_LINK_CONNECT_TOUT);
2418 /*******************************************************************************
2420 ** Function l2cu_find_lcb_by_state
2422 ** Description Look through all active LCBs for a match based on the
2425 ** Returns pointer to first matched LCB, or NULL if no match
2427 *******************************************************************************/
2428 tL2C_LCB *l2cu_find_lcb_by_state (tL2C_LINK_STATE state)
2431 tL2C_LCB *p_lcb = &l2cb.lcb_pool[0];
2433 for (i = 0; i < MAX_L2CAP_LINKS; i++, p_lcb++)
2435 if ((p_lcb->in_use) && (p_lcb->link_state == state))
2441 /* If here, no match found */
2446 /*******************************************************************************
2448 ** Function l2cu_lcb_disconnecting
2450 ** Description On each active lcb, check if the lcb is in disconnecting
2451 ** state, or if there are no ccb's on the lcb (implying
2452 idle timeout is running), or if last ccb on the link
2453 is in disconnecting state.
2455 ** Returns TRUE if any of above conditions met, FALSE otherwise
2457 *******************************************************************************/
2458 BOOLEAN l2cu_lcb_disconnecting (void)
2463 BOOLEAN status = FALSE;
2465 p_lcb = &l2cb.lcb_pool[0];
2467 for (i = 0; i < MAX_L2CAP_LINKS; i++, p_lcb++)
2471 /* no ccbs on lcb, or lcb is in disconnecting state */
2472 if ((!p_lcb->ccb_queue.p_first_ccb) || (p_lcb->link_state == LST_DISCONNECTING))
2477 /* only one ccb left on lcb */
2478 else if (p_lcb->ccb_queue.p_first_ccb == p_lcb->ccb_queue.p_last_ccb)
2480 p_ccb = p_lcb->ccb_queue.p_first_ccb;
2482 if ((p_ccb->in_use) &&
2483 ((p_ccb->chnl_state == CST_W4_L2CAP_DISCONNECT_RSP) ||
2484 (p_ccb->chnl_state == CST_W4_L2CA_DISCONNECT_RSP)))
2496 /*******************************************************************************
2498 ** Function l2cu_set_acl_priority
2500 ** Description Sets the transmission priority for a channel.
2501 ** (For initial implementation only two values are valid.
2502 ** L2CAP_PRIORITY_NORMAL and L2CAP_PRIORITY_HIGH).
2504 ** Returns TRUE if a valid channel, else FALSE
2506 *******************************************************************************/
2508 BOOLEAN l2cu_set_acl_priority (BD_ADDR bd_addr, UINT8 priority, BOOLEAN reset_after_rs)
2512 UINT8 command[HCI_BRCM_ACL_PRIORITY_PARAM_SIZE];
2515 APPL_TRACE_EVENT("SET ACL PRIORITY %d", priority);
2517 /* Find the link control block for the acl channel */
2518 if ((p_lcb = l2cu_find_lcb_by_bd_addr(bd_addr, BT_TRANSPORT_BR_EDR)) == NULL)
2520 L2CAP_TRACE_WARNING ("L2CAP - no LCB for L2CA_SetAclPriority");
2524 if (BTM_IS_BRCM_CONTROLLER())
2526 /* Called from above L2CAP through API; send VSC if changed */
2527 if ((!reset_after_rs && (priority != p_lcb->acl_priority)) ||
2528 /* Called because of a master/slave role switch; if high resend VSC */
2529 ( reset_after_rs && p_lcb->acl_priority == L2CAP_PRIORITY_HIGH))
2533 vs_param = (priority == L2CAP_PRIORITY_HIGH) ? HCI_BRCM_ACL_PRIORITY_HIGH : HCI_BRCM_ACL_PRIORITY_LOW;
2535 UINT16_TO_STREAM (pp, p_lcb->handle);
2536 UINT8_TO_STREAM (pp, vs_param);
2538 BTM_VendorSpecificCommand (HCI_BRCM_SET_ACL_PRIORITY, HCI_BRCM_ACL_PRIORITY_PARAM_SIZE, command, NULL);
2540 /* Adjust lmp buffer allocation for this channel if priority changed */
2541 if (p_lcb->acl_priority != priority)
2543 p_lcb->acl_priority = priority;
2544 l2c_link_adjust_allocation();
2551 #if (L2CAP_NON_FLUSHABLE_PB_INCLUDED == TRUE)
2552 /******************************************************************************
2554 ** Function l2cu_set_non_flushable_pbf
2556 ** Description set L2CAP_PKT_START_NON_FLUSHABLE if controller supoorts
2560 *******************************************************************************/
2561 void l2cu_set_non_flushable_pbf (BOOLEAN is_supported)
2564 l2cb.non_flushable_pbf = (L2CAP_PKT_START_NON_FLUSHABLE << L2CAP_PKT_TYPE_SHIFT);
2566 l2cb.non_flushable_pbf = (L2CAP_PKT_START << L2CAP_PKT_TYPE_SHIFT);
2570 /*******************************************************************************
2572 ** Function l2cu_resubmit_pending_sec_req
2574 ** Description This function is called when required security procedures
2575 ** are completed and any pending requests can be re-submitted.
2579 *******************************************************************************/
2580 void l2cu_resubmit_pending_sec_req (BD_ADDR p_bda)
2584 tL2C_CCB *p_next_ccb;
2587 L2CAP_TRACE_DEBUG ("l2cu_resubmit_pending_sec_req p_bda: 0x%08x", p_bda);
2589 /* If we are called with a BDA, only resubmit for that BDA */
2592 p_lcb = l2cu_find_lcb_by_bd_addr (p_bda, BT_TRANSPORT_BR_EDR);
2594 /* If we don't have one, this is an error */
2597 /* For all channels, send the event through their FSMs */
2598 for (p_ccb = p_lcb->ccb_queue.p_first_ccb; p_ccb; p_ccb = p_next_ccb)
2600 p_next_ccb = p_ccb->p_next_ccb;
2601 l2c_csm_execute (p_ccb, L2CEVT_SEC_RE_SEND_CMD, NULL);
2606 L2CAP_TRACE_WARNING ("l2cu_resubmit_pending_sec_req - unknown BD_ADDR");
2611 /* No BDA pasesed in, so check all links */
2612 for (xx = 0, p_lcb = &l2cb.lcb_pool[0]; xx < MAX_L2CAP_LINKS; xx++, p_lcb++)
2616 /* For all channels, send the event through their FSMs */
2617 for (p_ccb = p_lcb->ccb_queue.p_first_ccb; p_ccb; p_ccb = p_next_ccb)
2619 p_next_ccb = p_ccb->p_next_ccb;
2620 l2c_csm_execute (p_ccb, L2CEVT_SEC_RE_SEND_CMD, NULL);
2627 #if L2CAP_CONFORMANCE_TESTING == TRUE
2628 /*******************************************************************************
2630 ** Function l2cu_set_info_rsp_mask
2632 ** Description This function allows the script wrapper to change the
2633 ** info resp mask for conformance testing.
2635 ** Returns pointer to CCB, or NULL if none
2637 *******************************************************************************/
2638 void l2cu_set_info_rsp_mask (UINT32 mask)
2640 l2cb.test_info_resp = mask;
2642 #endif /* L2CAP_CONFORMANCE_TESTING */
2644 /*******************************************************************************
2646 ** Function l2cu_adjust_out_mps
2648 ** Description Sets our MPS based on current controller capabilities
2652 *******************************************************************************/
2653 void l2cu_adjust_out_mps (tL2C_CCB *p_ccb)
2657 /* on the tx side MTU is selected based on packet size of the controller */
2658 packet_size = btm_get_max_packet_size (p_ccb->p_lcb->remote_bd_addr);
2660 if (packet_size <= (L2CAP_PKT_OVERHEAD + L2CAP_FCR_OVERHEAD + L2CAP_SDU_LEN_OVERHEAD + L2CAP_FCS_LEN))
2662 /* something is very wrong */
2663 L2CAP_TRACE_ERROR ("l2cu_adjust_out_mps bad packet size: %u will use MPS: %u", packet_size, p_ccb->peer_cfg.fcr.mps);
2664 p_ccb->tx_mps = p_ccb->peer_cfg.fcr.mps;
2668 packet_size -= (L2CAP_PKT_OVERHEAD + L2CAP_FCR_OVERHEAD + L2CAP_SDU_LEN_OVERHEAD + L2CAP_FCS_LEN);
2670 /* We try to negotiate MTU that each packet can be split into whole
2671 number of max packets. For example if link is 1.2 max packet size is 339 bytes.
2672 At first calculate how many whole packets it is. MAX L2CAP is 1691 + 4 overhead.
2673 1695, that will be 5 Dh5 packets. Now maximum L2CAP packet is
2674 5 * 339 = 1695. Minus 4 bytes L2CAP header 1691.
2676 For EDR 2.0 packet size is 1027. So we better send RFCOMM packet as 1 3DH5 packet
2677 1 * 1027 = 1027. Minus 4 bytes L2CAP header 1023. */
2678 if (p_ccb->peer_cfg.fcr.mps >= packet_size)
2679 p_ccb->tx_mps = p_ccb->peer_cfg.fcr.mps / packet_size * packet_size;
2681 p_ccb->tx_mps = p_ccb->peer_cfg.fcr.mps;
2683 L2CAP_TRACE_DEBUG ("l2cu_adjust_out_mps use %d Based on peer_cfg.fcr.mps: %u packet_size: %u",
2684 p_ccb->tx_mps, p_ccb->peer_cfg.fcr.mps, packet_size);
2689 /*******************************************************************************
2691 ** Function l2cu_initialize_fixed_ccb
2693 ** Description Initialize a fixed channel's CCB
2695 ** Returns TRUE or FALSE
2697 *******************************************************************************/
2698 BOOLEAN l2cu_initialize_fixed_ccb (tL2C_LCB *p_lcb, UINT16 fixed_cid, tL2CAP_FCR_OPTS *p_fcr)
2700 #if (L2CAP_NUM_FIXED_CHNLS > 0)
2703 /* If we already have a CCB, then simply return */
2704 if (p_lcb->p_fixed_ccbs[fixed_cid - L2CAP_FIRST_FIXED_CHNL] != NULL)
2707 if ((p_ccb = l2cu_allocate_ccb (NULL, 0)) == NULL)
2710 btu_stop_timer(&p_lcb->timer_entry);
2712 /* Set CID for the connection */
2713 p_ccb->local_cid = fixed_cid;
2714 p_ccb->remote_cid = fixed_cid;
2716 GKI_init_q (&p_ccb->xmit_hold_q);
2718 p_ccb->is_flushable = FALSE;
2720 p_ccb->timer_entry.param = (TIMER_PARAM_TYPE)p_ccb;
2725 /* Set the FCR parameters. For now, we will use default pools */
2726 p_ccb->our_cfg.fcr = p_ccb->peer_cfg.fcr = *p_fcr;
2728 p_ccb->ertm_info.fcr_rx_pool_id = HCI_ACL_POOL_ID;
2729 p_ccb->ertm_info.fcr_tx_pool_id = HCI_ACL_POOL_ID;
2730 p_ccb->ertm_info.user_rx_pool_id = HCI_ACL_POOL_ID;
2731 p_ccb->ertm_info.user_tx_pool_id = HCI_ACL_POOL_ID;
2733 p_ccb->fcrb.max_held_acks = p_fcr->tx_win_sz / 3;
2736 /* Link ccb to lcb and lcb to ccb */
2737 p_lcb->p_fixed_ccbs[fixed_cid - L2CAP_FIRST_FIXED_CHNL] = p_ccb;
2738 p_ccb->p_lcb = p_lcb;
2740 /* There is no configuration, so if the link is up, the channel is up */
2741 if (p_lcb->link_state == LST_CONNECTED)
2742 p_ccb->chnl_state = CST_OPEN;
2744 /* Set the default idle timeout value to use */
2745 p_ccb->fixed_chnl_idle_tout = l2cb.fixed_reg[fixed_cid - L2CAP_FIRST_FIXED_CHNL].default_idle_tout;
2750 /*******************************************************************************
2752 ** Function l2cu_no_dynamic_ccbs
2754 ** Description Handles the case when there are no more dynamic CCBs. If there
2755 ** are any fixed CCBs, start the longest of the fixed CCB timeouts,
2756 ** otherwise start the default link idle timeout or disconnect.
2760 *******************************************************************************/
2761 void l2cu_no_dynamic_ccbs (tL2C_LCB *p_lcb)
2764 UINT16 timeout = p_lcb->idle_timeout;
2766 #if (L2CAP_NUM_FIXED_CHNLS > 0)
2769 for (xx = 0; xx < L2CAP_NUM_FIXED_CHNLS; xx++)
2771 if ( (p_lcb->p_fixed_ccbs[xx] != NULL) && (p_lcb->p_fixed_ccbs[xx]->fixed_chnl_idle_tout > timeout) )
2772 timeout = p_lcb->p_fixed_ccbs[xx]->fixed_chnl_idle_tout;
2776 /* If the link is pairing, do not mess with the timeouts */
2777 if (p_lcb->is_bonding)
2782 L2CAP_TRACE_DEBUG ("l2cu_no_dynamic_ccbs() IDLE timer 0, disconnecting link");
2784 rc = btm_sec_disconnect (p_lcb->handle, HCI_ERR_PEER_USER);
2785 if (rc == BTM_CMD_STARTED)
2787 l2cu_process_fixed_disc_cback(p_lcb);
2788 p_lcb->link_state = LST_DISCONNECTING;
2789 timeout = L2CAP_LINK_DISCONNECT_TOUT;
2791 else if (rc == BTM_SUCCESS)
2793 l2cu_process_fixed_disc_cback(p_lcb);
2794 /* BTM SEC will make sure that link is release (probably after pairing is done) */
2795 p_lcb->link_state = LST_DISCONNECTING;
2798 else if ( (p_lcb->is_bonding)
2799 && (btsnd_hcic_disconnect (p_lcb->handle, HCI_ERR_PEER_USER)) )
2801 l2cu_process_fixed_disc_cback(p_lcb);
2802 p_lcb->link_state = LST_DISCONNECTING;
2803 timeout = L2CAP_LINK_DISCONNECT_TOUT;
2807 /* probably no buffer to send disconnect */
2808 timeout = BT_1SEC_TIMEOUT;
2812 if (timeout != 0xFFFF)
2814 L2CAP_TRACE_DEBUG ("l2cu_no_dynamic_ccbs() starting IDLE timeout: %d", timeout);
2815 btu_start_timer (&p_lcb->timer_entry, BTU_TTYPE_L2CAP_LINK, timeout);
2819 btu_stop_timer(&p_lcb->timer_entry);
2823 #if (L2CAP_NUM_FIXED_CHNLS > 0)
2824 /*******************************************************************************
2826 ** Function l2cu_process_fixed_chnl_resp
2828 ** Description handle a fixed channel response (or lack thereof)
2829 ** if the link failed, or a fixed channel response was
2830 ** not received, the bitfield is all zeros.
2832 *******************************************************************************/
2833 void l2cu_process_fixed_chnl_resp (tL2C_LCB *p_lcb)
2836 #if (BLE_INCLUDED == TRUE)
2837 /* always exclude LE fixed channel on BR/EDR fix channel capability */
2838 if (p_lcb->transport == BT_TRANSPORT_BR_EDR)
2839 p_lcb->peer_chnl_mask[0] &= ~(L2CAP_FIXED_CHNL_ATT_BIT| \
2840 L2CAP_FIXED_CHNL_BLE_SIG_BIT| \
2841 L2CAP_FIXED_CHNL_SMP_BIT);
2844 /* Tell all registered fixed channels about the connection */
2845 for (xx = 0; xx < L2CAP_NUM_FIXED_CHNLS; xx++)
2847 #if BLE_INCLUDED == TRUE
2848 /* skip sending LE fix channel callbacks on BR/EDR links */
2849 if (p_lcb->transport == BT_TRANSPORT_BR_EDR &&
2850 xx + L2CAP_FIRST_FIXED_CHNL >= L2CAP_ATT_CID &&
2851 xx + L2CAP_FIRST_FIXED_CHNL <= L2CAP_SMP_CID)
2854 if (l2cb.fixed_reg[xx].pL2CA_FixedConn_Cb != NULL)
2856 if (p_lcb->peer_chnl_mask[0] & (1 << (xx + L2CAP_FIRST_FIXED_CHNL)))
2858 if (p_lcb->p_fixed_ccbs[xx])
2859 p_lcb->p_fixed_ccbs[xx]->chnl_state = CST_OPEN;
2860 #if BLE_INCLUDED == TRUE
2861 (*l2cb.fixed_reg[xx].pL2CA_FixedConn_Cb)(p_lcb->remote_bd_addr, TRUE, 0, p_lcb->transport);
2863 (*l2cb.fixed_reg[xx].pL2CA_FixedConn_Cb)(p_lcb->remote_bd_addr, TRUE, 0, BT_TRANSPORT_BR_EDR);
2868 #if BLE_INCLUDED == TRUE
2869 (*l2cb.fixed_reg[xx].pL2CA_FixedConn_Cb)(p_lcb->remote_bd_addr, FALSE, p_lcb->disc_reason, p_lcb->transport);
2871 (*l2cb.fixed_reg[xx].pL2CA_FixedConn_Cb)(p_lcb->remote_bd_addr, FALSE, p_lcb->disc_reason, BT_TRANSPORT_BR_EDR);
2874 if (p_lcb->p_fixed_ccbs[xx])
2876 l2cu_release_ccb (p_lcb->p_fixed_ccbs[xx]);
2877 p_lcb->p_fixed_ccbs[xx] = NULL;
2886 /*******************************************************************************
2888 ** Function l2cu_process_fixed_disc_cback
2890 ** Description send l2cap fixed channel disconnection callback to application
2895 *******************************************************************************/
2896 void l2cu_process_fixed_disc_cback (tL2C_LCB *p_lcb)
2898 #if (L2CAP_NUM_FIXED_CHNLS > 0)
2901 for (xx = 0; xx < L2CAP_NUM_FIXED_CHNLS; xx++)
2903 if (p_lcb->p_fixed_ccbs[xx])
2905 if (p_lcb->p_fixed_ccbs[xx] != p_lcb->p_pending_ccb)
2907 l2cu_release_ccb (p_lcb->p_fixed_ccbs[xx]);
2908 p_lcb->p_fixed_ccbs[xx] = NULL;
2909 #if BLE_INCLUDED == TRUE
2910 (*l2cb.fixed_reg[xx].pL2CA_FixedConn_Cb)(p_lcb->remote_bd_addr, FALSE, p_lcb->disc_reason, p_lcb->transport);
2912 (*l2cb.fixed_reg[xx].pL2CA_FixedConn_Cb)(p_lcb->remote_bd_addr, FALSE, p_lcb->disc_reason, BT_TRANSPORT_BR_EDR);
2916 else if ( (p_lcb->peer_chnl_mask[0] & (1 << (xx + L2CAP_FIRST_FIXED_CHNL)))
2917 && (l2cb.fixed_reg[xx].pL2CA_FixedConn_Cb != NULL) )
2918 #if BLE_INCLUDED == TRUE
2919 (*l2cb.fixed_reg[xx].pL2CA_FixedConn_Cb)(p_lcb->remote_bd_addr, FALSE, p_lcb->disc_reason, p_lcb->transport);
2921 (*l2cb.fixed_reg[xx].pL2CA_FixedConn_Cb)(p_lcb->remote_bd_addr, FALSE, p_lcb->disc_reason, BT_TRANSPORT_BR_EDR);
2927 #if (BLE_INCLUDED == TRUE)
2928 /*******************************************************************************
2930 ** Function l2cu_send_peer_ble_par_req
2932 ** Description Build and send a BLE parameter update request message
2937 *******************************************************************************/
2938 void l2cu_send_peer_ble_par_req (tL2C_LCB *p_lcb, UINT16 min_int, UINT16 max_int, UINT16 latency, UINT16 timeout)
2943 /* Create an identifier for this packet */
2945 l2cu_adj_id (p_lcb, L2CAP_ADJ_ID);
2947 if ((p_buf = l2cu_build_header (p_lcb, L2CAP_CMD_BLE_UPD_REQ_LEN, L2CAP_CMD_BLE_UPDATE_REQ, p_lcb->id)) == NULL )
2949 L2CAP_TRACE_WARNING ("l2cu_send_peer_ble_par_req - no buffer");
2953 p = (UINT8 *)(p_buf + 1) + L2CAP_SEND_CMD_OFFSET + HCI_DATA_PREAMBLE_SIZE +
2954 L2CAP_PKT_OVERHEAD + L2CAP_CMD_OVERHEAD;
2956 UINT16_TO_STREAM (p, min_int);
2957 UINT16_TO_STREAM (p, max_int);
2958 UINT16_TO_STREAM (p, latency);
2959 UINT16_TO_STREAM (p, timeout);
2961 l2c_link_check_send_pkts (p_lcb, NULL, p_buf);
2964 /*******************************************************************************
2966 ** Function l2cu_send_peer_ble_par_rsp
2968 ** Description Build and send a BLE parameter update response message
2973 *******************************************************************************/
2974 void l2cu_send_peer_ble_par_rsp (tL2C_LCB *p_lcb, UINT16 reason, UINT8 rem_id)
2979 if ((p_buf = l2cu_build_header (p_lcb, L2CAP_CMD_BLE_UPD_RSP_LEN, L2CAP_CMD_BLE_UPDATE_RSP, rem_id)) == NULL )
2981 L2CAP_TRACE_WARNING ("l2cu_send_peer_ble_par_rsp - no buffer");
2985 p = (UINT8 *)(p_buf + 1) + L2CAP_SEND_CMD_OFFSET + HCI_DATA_PREAMBLE_SIZE +
2986 L2CAP_PKT_OVERHEAD + L2CAP_CMD_OVERHEAD;
2988 UINT16_TO_STREAM (p, reason);
2990 l2c_link_check_send_pkts (p_lcb, NULL, p_buf);
2993 #endif /* BLE_INCLUDED == TRUE */
2996 /*******************************************************************************
2997 ** Functions used by both Full and Light Stack
2998 ********************************************************************************/
3000 /*******************************************************************************
3002 ** Function l2cu_find_lcb_by_handle
3004 ** Description Look through all active LCBs for a match based on the
3007 ** Returns pointer to matched LCB, or NULL if no match
3009 *******************************************************************************/
3010 tL2C_LCB *l2cu_find_lcb_by_handle (UINT16 handle)
3013 tL2C_LCB *p_lcb = &l2cb.lcb_pool[0];
3015 for (xx = 0; xx < MAX_L2CAP_LINKS; xx++, p_lcb++)
3017 if ((p_lcb->in_use) && (p_lcb->handle == handle))
3023 /* If here, no match found */
3027 /*******************************************************************************
3029 ** Function l2cu_find_ccb_by_cid
3031 ** Description Look through all active CCBs on a link for a match based
3032 ** on the local CID. If passed the link pointer is NULL, all
3033 ** active links are searched.
3035 ** Returns pointer to matched CCB, or NULL if no match
3037 *******************************************************************************/
3038 tL2C_CCB *l2cu_find_ccb_by_cid (tL2C_LCB *p_lcb, UINT16 local_cid)
3040 tL2C_CCB *p_ccb = NULL;
3041 #if (L2CAP_UCD_INCLUDED == TRUE)
3045 if (local_cid >= L2CAP_BASE_APPL_CID)
3047 /* find the associated CCB by "index" */
3048 local_cid -= L2CAP_BASE_APPL_CID;
3050 if (local_cid >= MAX_L2CAP_CHANNELS)
3053 p_ccb = l2cb.ccb_pool + local_cid;
3055 /* make sure the CCB is in use */
3060 /* make sure it's for the same LCB */
3061 else if (p_lcb && p_lcb != p_ccb->p_lcb)
3066 #if (L2CAP_UCD_INCLUDED == TRUE)
3069 /* searching fixed channel */
3070 p_ccb = l2cb.ccb_pool;
3071 for ( xx = 0; xx < MAX_L2CAP_CHANNELS; xx++ )
3073 if ((p_ccb->local_cid == local_cid)
3075 &&(p_lcb == p_ccb->p_lcb))
3080 if ( xx >= MAX_L2CAP_CHANNELS )
3088 #if (L2CAP_ROUND_ROBIN_CHANNEL_SERVICE == TRUE)
3090 /******************************************************************************
3092 ** Function l2cu_get_next_channel_in_rr
3094 ** Description get the next channel to send on a link. It also adjusts the
3095 ** CCB queue to do a basic priority and round-robin scheduling.
3097 ** Returns pointer to CCB or NULL
3099 *******************************************************************************/
3100 static tL2C_CCB *l2cu_get_next_channel_in_rr(tL2C_LCB *p_lcb)
3102 tL2C_CCB *p_serve_ccb = NULL;
3107 /* scan all of priority until finding a channel to serve */
3108 for ( i = 0; (i < L2CAP_NUM_CHNL_PRIORITY)&&(!p_serve_ccb); i++ )
3110 /* scan all channel within serving priority group until finding a channel to serve */
3111 for ( j = 0; (j < p_lcb->rr_serv[p_lcb->rr_pri].num_ccb)&&(!p_serve_ccb); j++)
3113 /* scaning from next serving channel */
3114 p_ccb = p_lcb->rr_serv[p_lcb->rr_pri].p_serve_ccb;
3118 L2CAP_TRACE_ERROR("p_serve_ccb is NULL, rr_pri=%d", p_lcb->rr_pri);
3122 L2CAP_TRACE_DEBUG("RR scan pri=%d, lcid=0x%04x, q_cout=%d",
3123 p_ccb->ccb_priority, p_ccb->local_cid, p_ccb->xmit_hold_q.count );
3125 /* store the next serving channel */
3126 /* this channel is the last channel of its priority group */
3127 if (( p_ccb->p_next_ccb == NULL )
3128 ||( p_ccb->p_next_ccb->ccb_priority != p_ccb->ccb_priority ))
3130 /* next serving channel is set to the first channel in the group */
3131 p_lcb->rr_serv[p_lcb->rr_pri].p_serve_ccb = p_lcb->rr_serv[p_lcb->rr_pri].p_first_ccb;
3135 /* next serving channel is set to the next channel in the group */
3136 p_lcb->rr_serv[p_lcb->rr_pri].p_serve_ccb = p_ccb->p_next_ccb;
3139 if (p_ccb->chnl_state != CST_OPEN)
3142 /* eL2CAP option in use */
3143 if (p_ccb->peer_cfg.fcr.mode != L2CAP_FCR_BASIC_MODE)
3145 if (p_ccb->fcrb.wait_ack || p_ccb->fcrb.remote_busy)
3148 if ( p_ccb->fcrb.retrans_q.count == 0 )
3150 if ( p_ccb->xmit_hold_q.count == 0 )
3153 /* If using the common pool, should be at least 10% free. */
3154 if ( (p_ccb->ertm_info.fcr_tx_pool_id == HCI_ACL_POOL_ID) && (GKI_poolutilization (HCI_ACL_POOL_ID) > 90) )
3157 /* If in eRTM mode, check for window closure */
3158 if ( (p_ccb->peer_cfg.fcr.mode == L2CAP_FCR_ERTM_MODE) && (l2c_fcr_is_flow_controlled (p_ccb)) )
3164 if (p_ccb->xmit_hold_q.count == 0)
3168 /* found a channel to serve */
3169 p_serve_ccb = p_ccb;
3170 /* decrease quota of its priority group */
3171 p_lcb->rr_serv[p_lcb->rr_pri].quota--;
3174 /* if there is no more quota of the priority group or no channel to have data to send */
3175 if ((p_lcb->rr_serv[p_lcb->rr_pri].quota == 0)||(!p_serve_ccb))
3177 /* serve next priority group */
3178 p_lcb->rr_pri = (p_lcb->rr_pri + 1) % L2CAP_NUM_CHNL_PRIORITY;
3179 /* initialize its quota */
3180 p_lcb->rr_serv[p_lcb->rr_pri].quota = L2CAP_GET_PRIORITY_QUOTA(p_lcb->rr_pri);
3186 L2CAP_TRACE_DEBUG("RR service pri=%d, quota=%d, lcid=0x%04x",
3187 p_serve_ccb->ccb_priority,
3188 p_lcb->rr_serv[p_serve_ccb->ccb_priority].quota,
3189 p_serve_ccb->local_cid );
3195 #else /* (L2CAP_ROUND_ROBIN_CHANNEL_SERVICE == TRUE) */
3197 /******************************************************************************
3199 ** Function l2cu_get_next_channel
3201 ** Description get the next channel to send on a link bassed on priority
3204 ** Returns pointer to CCB or NULL
3206 *******************************************************************************/
3207 static tL2C_CCB *l2cu_get_next_channel(tL2C_LCB *p_lcb)
3211 /* Get the first CCB with data to send.
3213 for (p_ccb = p_lcb->ccb_queue.p_first_ccb; p_ccb; p_ccb = p_ccb->p_next_ccb)
3215 if (p_ccb->chnl_state != CST_OPEN)
3218 if (p_ccb->fcrb.wait_ack || p_ccb->fcrb.remote_busy)
3221 if (p_ccb->fcrb.retrans_q.count != 0)
3224 if (p_ccb->xmit_hold_q.count == 0)
3227 /* If using the common pool, should be at least 10% free. */
3228 if ( (p_ccb->ertm_info.fcr_tx_pool_id == HCI_ACL_POOL_ID) && (GKI_poolutilization (HCI_ACL_POOL_ID) > 90) )
3231 /* If in eRTM mode, check for window closure */
3232 if ( (p_ccb->peer_cfg.fcr.mode == L2CAP_FCR_ERTM_MODE) && (l2c_fcr_is_flow_controlled (p_ccb)) )
3235 /* If here, we found someone */
3241 #endif /* (L2CAP_ROUND_ROBIN_CHANNEL_SERVICE == TRUE) */
3243 /******************************************************************************
3245 ** Function l2cu_get_next_buffer_to_send
3247 ** Description get the next buffer to send on a link. It also adjusts the
3248 ** CCB queue to do a basic priority and round-robin scheduling.
3250 ** Returns pointer to buffer or NULL
3252 *******************************************************************************/
3253 BT_HDR *l2cu_get_next_buffer_to_send (tL2C_LCB *p_lcb)
3258 /* Highest priority are fixed channels */
3259 #if (L2CAP_NUM_FIXED_CHNLS > 0)
3262 for (xx = 0; xx < L2CAP_NUM_FIXED_CHNLS; xx++)
3264 if ((p_ccb = p_lcb->p_fixed_ccbs[xx]) == NULL)
3267 /* eL2CAP option in use */
3268 if (p_ccb->peer_cfg.fcr.mode != L2CAP_FCR_BASIC_MODE)
3270 if (p_ccb->fcrb.wait_ack || p_ccb->fcrb.remote_busy)
3273 /* No more checks needed if sending from the reatransmit queue */
3274 if (p_ccb->fcrb.retrans_q.count == 0)
3276 if (p_ccb->xmit_hold_q.count == 0)
3279 /* If using the common pool, should be at least 10% free. */
3280 if ( (p_ccb->ertm_info.fcr_tx_pool_id == HCI_ACL_POOL_ID) && (GKI_poolutilization (HCI_ACL_POOL_ID) > 90) )
3283 /* If in eRTM mode, check for window closure */
3284 if ( (p_ccb->peer_cfg.fcr.mode == L2CAP_FCR_ERTM_MODE) && (l2c_fcr_is_flow_controlled (p_ccb)) )
3288 if ((p_buf = l2c_fcr_get_next_xmit_sdu_seg(p_ccb, 0)) != NULL)
3290 l2cu_check_channel_congestion (p_ccb);
3291 l2cu_set_acl_hci_header (p_buf, p_ccb);
3297 if (p_ccb->xmit_hold_q.count != 0)
3299 p_buf = (BT_HDR *)GKI_dequeue (&p_ccb->xmit_hold_q);
3302 L2CAP_TRACE_ERROR("l2cu_get_buffer_to_send: No data to be sent");
3305 l2cu_check_channel_congestion (p_ccb);
3306 l2cu_set_acl_hci_header (p_buf, p_ccb);
3313 #if (L2CAP_ROUND_ROBIN_CHANNEL_SERVICE == TRUE)
3314 /* get next serving channel in round-robin */
3315 p_ccb = l2cu_get_next_channel_in_rr( p_lcb );
3317 p_ccb = l2cu_get_next_channel( p_lcb );
3320 /* Return if no buffer */
3324 if (p_ccb->peer_cfg.fcr.mode != L2CAP_FCR_BASIC_MODE)
3326 if ((p_buf = l2c_fcr_get_next_xmit_sdu_seg(p_ccb, 0)) == NULL)
3331 p_buf = (BT_HDR *)GKI_dequeue (&p_ccb->xmit_hold_q);
3334 L2CAP_TRACE_ERROR("l2cu_get_buffer_to_send() #2: No data to be sent");
3339 if ( p_ccb->p_rcb && p_ccb->p_rcb->api.pL2CA_TxComplete_Cb && (p_ccb->peer_cfg.fcr.mode != L2CAP_FCR_ERTM_MODE) )
3340 (*p_ccb->p_rcb->api.pL2CA_TxComplete_Cb)(p_ccb->local_cid, 1);
3343 l2cu_check_channel_congestion (p_ccb);
3345 l2cu_set_acl_hci_header (p_buf, p_ccb);
3350 /******************************************************************************
3352 ** Function l2cu_set_acl_hci_header
3354 ** Description Set HCI handle for ACL packet
3358 *******************************************************************************/
3359 void l2cu_set_acl_hci_header (BT_HDR *p_buf, tL2C_CCB *p_ccb)
3363 /* Set the pointer to the beginning of the data minus 4 bytes for the packet header */
3364 p = (UINT8 *)(p_buf + 1) + p_buf->offset - HCI_DATA_PREAMBLE_SIZE;
3366 #if (BLE_INCLUDED == TRUE)
3367 if (p_ccb->p_lcb->transport == BT_TRANSPORT_LE)
3369 UINT16_TO_STREAM (p, p_ccb->p_lcb->handle | (L2CAP_PKT_START_NON_FLUSHABLE << L2CAP_PKT_TYPE_SHIFT));
3371 /* The HCI transport will segment the buffers. */
3372 if (p_buf->len > btu_cb.hcit_ble_acl_data_size)
3374 UINT16_TO_STREAM (p, btu_cb.hcit_ble_acl_data_size);
3378 UINT16_TO_STREAM (p, p_buf->len);
3380 } /* (BLE_INCLUDED == TRUE) */
3384 #if (L2CAP_NON_FLUSHABLE_PB_INCLUDED == TRUE)
3385 if ( (((p_buf->layer_specific & L2CAP_FLUSHABLE_MASK) == L2CAP_FLUSHABLE_CH_BASED) && (p_ccb->is_flushable))
3386 || ((p_buf->layer_specific & L2CAP_FLUSHABLE_MASK) == L2CAP_FLUSHABLE_PKT) )
3388 UINT16_TO_STREAM (p, p_ccb->p_lcb->handle | (L2CAP_PKT_START << L2CAP_PKT_TYPE_SHIFT));
3392 UINT16_TO_STREAM (p, p_ccb->p_lcb->handle | l2cb.non_flushable_pbf);
3395 UINT16_TO_STREAM (p, p_ccb->p_lcb->handle | (L2CAP_PKT_START << L2CAP_PKT_TYPE_SHIFT));
3398 /* The HCI transport will segment the buffers. */
3399 if (p_buf->len > btu_cb.hcit_acl_data_size)
3401 UINT16_TO_STREAM (p, btu_cb.hcit_acl_data_size);
3405 UINT16_TO_STREAM (p, p_buf->len);
3408 p_buf->offset -= HCI_DATA_PREAMBLE_SIZE;
3409 p_buf->len += HCI_DATA_PREAMBLE_SIZE;
3412 /******************************************************************************
3414 ** Function l2cu_check_channel_congestion
3416 ** Description check if any change in congestion status
3420 *******************************************************************************/
3421 void l2cu_check_channel_congestion (tL2C_CCB *p_ccb)
3423 UINT16 q_count = p_ccb->xmit_hold_q.count;
3425 #if (L2CAP_UCD_INCLUDED == TRUE)
3426 if ( p_ccb->local_cid == L2CAP_CONNECTIONLESS_CID )
3428 q_count += p_ccb->p_lcb->ucd_out_sec_pending_q.count;
3432 /* If the CCB queue limit is subject to a quota, check for congestion */
3434 /* if this channel has outgoing traffic */
3435 if (p_ccb->buff_quota != 0)
3437 /* If this channel was congested */
3438 if ( p_ccb->cong_sent )
3440 /* If the channel is not congested now, tell the app */
3441 if (q_count <= (p_ccb->buff_quota / 2))
3443 p_ccb->cong_sent = FALSE;
3444 if (p_ccb->p_rcb && p_ccb->p_rcb->api.pL2CA_CongestionStatus_Cb)
3446 L2CAP_TRACE_DEBUG ("L2CAP - Calling CongestionStatus_Cb (FALSE), CID: 0x%04x xmit_hold_q.count: %u buff_quota: %u",
3447 p_ccb->local_cid, q_count, p_ccb->buff_quota);
3449 /* Prevent recursive calling */
3450 l2cb.is_cong_cback_context = TRUE;
3451 (*p_ccb->p_rcb->api.pL2CA_CongestionStatus_Cb)(p_ccb->local_cid, FALSE);
3452 l2cb.is_cong_cback_context = FALSE;
3454 #if (L2CAP_UCD_INCLUDED == TRUE)
3455 else if ( p_ccb->p_rcb && p_ccb->local_cid == L2CAP_CONNECTIONLESS_CID )
3457 if ( p_ccb->p_rcb->ucd.cb_info.pL2CA_UCD_Congestion_Status_Cb )
3459 L2CAP_TRACE_DEBUG ("L2CAP - Calling UCD CongestionStatus_Cb (FALSE), SecPendingQ:%u,XmitQ:%u,Quota:%u",
3460 p_ccb->p_lcb->ucd_out_sec_pending_q.count,
3461 p_ccb->xmit_hold_q.count, p_ccb->buff_quota);
3462 p_ccb->p_rcb->ucd.cb_info.pL2CA_UCD_Congestion_Status_Cb( p_ccb->p_lcb->remote_bd_addr, FALSE );
3466 #if (L2CAP_NUM_FIXED_CHNLS > 0)
3470 for (xx = 0; xx < L2CAP_NUM_FIXED_CHNLS; xx ++)
3472 if (p_ccb->p_lcb->p_fixed_ccbs[xx] == p_ccb)
3474 if (l2cb.fixed_reg[xx].pL2CA_FixedCong_Cb != NULL)
3475 (* l2cb.fixed_reg[xx].pL2CA_FixedCong_Cb)(p_ccb->p_lcb->remote_bd_addr, FALSE);
3485 /* If this channel was not congested but it is congested now, tell the app */
3486 if (q_count > p_ccb->buff_quota)
3488 p_ccb->cong_sent = TRUE;
3489 if (p_ccb->p_rcb && p_ccb->p_rcb->api.pL2CA_CongestionStatus_Cb)
3491 L2CAP_TRACE_DEBUG ("L2CAP - Calling CongestionStatus_Cb (TRUE),CID:0x%04x,XmitQ:%u,Quota:%u",
3492 p_ccb->local_cid, q_count, p_ccb->buff_quota);
3494 (*p_ccb->p_rcb->api.pL2CA_CongestionStatus_Cb)(p_ccb->local_cid, TRUE);
3496 #if (L2CAP_UCD_INCLUDED == TRUE)
3497 else if ( p_ccb->p_rcb && p_ccb->local_cid == L2CAP_CONNECTIONLESS_CID )
3499 if ( p_ccb->p_rcb->ucd.cb_info.pL2CA_UCD_Congestion_Status_Cb )
3501 L2CAP_TRACE_DEBUG ("L2CAP - Calling UCD CongestionStatus_Cb (TRUE), SecPendingQ:%u,XmitQ:%u,Quota:%u",
3502 p_ccb->p_lcb->ucd_out_sec_pending_q.count,
3503 p_ccb->xmit_hold_q.count, p_ccb->buff_quota);
3504 p_ccb->p_rcb->ucd.cb_info.pL2CA_UCD_Congestion_Status_Cb( p_ccb->p_lcb->remote_bd_addr, TRUE );
3508 #if (L2CAP_NUM_FIXED_CHNLS > 0)
3512 for (xx = 0; xx < L2CAP_NUM_FIXED_CHNLS; xx ++)
3514 if (p_ccb->p_lcb->p_fixed_ccbs[xx] == p_ccb)
3516 if (l2cb.fixed_reg[xx].pL2CA_FixedCong_Cb != NULL)
3517 (* l2cb.fixed_reg[xx].pL2CA_FixedCong_Cb)(p_ccb->p_lcb->remote_bd_addr, TRUE);