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