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