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