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