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