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