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;    /* Default mode for channel is basic mode */
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 (SDP_INCLUDED == TRUE)
1680     if (p_rcb && (p_rcb->psm != p_rcb->real_psm)) {
1681         btm_sec_clr_service_by_psm(p_rcb->psm);
1682     }
1683 #endif  ///SMP_INCLUDED == TRUE
1684     if (p_ccb->should_free_rcb) {
1685         osi_free(p_rcb);
1686         p_ccb->p_rcb = NULL;
1687         p_ccb->should_free_rcb = false;
1688     }
1689     if (p_lcb) {
1690         btm_sec_clr_temp_auth_service (p_lcb->remote_bd_addr);
1691     }
1692 
1693     /* Stop and free the timer */
1694     btu_free_timer (&p_ccb->timer_entry);
1695 
1696     fixed_queue_free(p_ccb->xmit_hold_q, osi_free_func);
1697     p_ccb->xmit_hold_q = NULL;
1698 #if (CLASSIC_BT_INCLUDED == TRUE)
1699     fixed_queue_free(p_ccb->fcrb.srej_rcv_hold_q, osi_free_func);
1700     fixed_queue_free(p_ccb->fcrb.retrans_q, osi_free_func);
1701     fixed_queue_free(p_ccb->fcrb.waiting_for_ack_q, osi_free_func);
1702     p_ccb->fcrb.srej_rcv_hold_q = NULL;
1703     p_ccb->fcrb.retrans_q = NULL;
1704     p_ccb->fcrb.waiting_for_ack_q = NULL;
1705 #endif  ///CLASSIC_BT_INCLUDED == TRUE
1706 
1707 
1708 #if (CLASSIC_BT_INCLUDED == TRUE)
1709     l2c_fcr_cleanup (p_ccb);
1710 #endif  ///CLASSIC_BT_INCLUDED == TRUE
1711     /* Channel may not be assigned to any LCB if it was just pre-reserved */
1712     if ( (p_lcb) &&
1713             ( (p_ccb->local_cid >= L2CAP_BASE_APPL_CID)
1714 #if (L2CAP_UCD_INCLUDED == TRUE)
1715               || (p_ccb->local_cid == L2CAP_CONNECTIONLESS_CID)
1716 #endif
1717             )
1718        ) {
1719         l2cu_dequeue_ccb (p_ccb);
1720 
1721         /* Delink the CCB from the LCB */
1722         p_ccb->p_lcb = NULL;
1723     }
1724 
1725 
1726     /* Flag as not in use */
1727     p_ccb->in_use = FALSE;
1728 
1729     /* If no channels on the connection, start idle timeout */
1730     if ((p_lcb) && p_lcb->in_use && (p_lcb->link_state == LST_CONNECTED)) {
1731         if (!p_lcb->ccb_queue.p_first_ccb) {
1732             l2cu_no_dynamic_ccbs (p_lcb);
1733         } else {
1734             /* Link is still active, adjust channel quotas. */
1735             l2c_link_adjust_chnl_allocation ();
1736         }
1737     }
1738 }
1739 
1740 /*******************************************************************************
1741 **
1742 ** Function         l2cu_find_ccb_by_remote_cid
1743 **
1744 ** Description      Look through all active CCBs on a link for a match based
1745 **                  on the remote CID.
1746 **
1747 ** Returns          pointer to matched CCB, or NULL if no match
1748 **
1749 *******************************************************************************/
l2cu_find_ccb_by_remote_cid(tL2C_LCB * p_lcb,UINT16 remote_cid)1750 tL2C_CCB *l2cu_find_ccb_by_remote_cid (tL2C_LCB *p_lcb, UINT16 remote_cid)
1751 {
1752     tL2C_CCB    *p_ccb;
1753 
1754     /* If LCB is NULL, look through all active links */
1755     if (!p_lcb) {
1756         return NULL;
1757     } else {
1758         for (p_ccb = p_lcb->ccb_queue.p_first_ccb; p_ccb; p_ccb = p_ccb->p_next_ccb)
1759             if ((p_ccb->in_use) && (p_ccb->remote_cid == remote_cid)) {
1760                 return (p_ccb);
1761             }
1762     }
1763 
1764     /* If here, no match found */
1765     return (NULL);
1766 }
1767 
1768 /*******************************************************************************
1769 **
1770 ** Function         l2cu_allocate_rcb
1771 **
1772 ** Description      Look through the Registration Control Blocks for a free
1773 **                  one.
1774 **
1775 ** Returns          Pointer to the RCB or NULL if not found
1776 **
1777 *******************************************************************************/
l2cu_allocate_rcb(UINT16 psm)1778 tL2C_RCB *l2cu_allocate_rcb (UINT16 psm)
1779 {
1780     tL2C_RCB    *p_rcb = &l2cb.rcb_pool[0];
1781     UINT16      xx;
1782 
1783     for (xx = 0; xx < MAX_L2CAP_CLIENTS; xx++, p_rcb++) {
1784         if (!p_rcb->in_use) {
1785             p_rcb->in_use = TRUE;
1786             p_rcb->psm    = psm;
1787 #if (L2CAP_UCD_INCLUDED == TRUE)
1788             p_rcb->ucd.state = L2C_UCD_STATE_UNUSED;
1789 #endif
1790             return (p_rcb);
1791         }
1792     }
1793 
1794     /* If here, no free RCB found */
1795     return (NULL);
1796 }
1797 
1798 #if (BLE_INCLUDED == TRUE)
1799 /*******************************************************************************
1800 **
1801 ** Function         l2cu_allocate_ble_rcb
1802 **
1803 ** Description      Look through the BLE Registration Control Blocks for a free
1804 **                  one.
1805 **
1806 ** Returns          Pointer to the BLE RCB or NULL if not found
1807 **
1808 *******************************************************************************/
l2cu_allocate_ble_rcb(UINT16 psm)1809 tL2C_RCB *l2cu_allocate_ble_rcb (UINT16 psm)
1810 {
1811     tL2C_RCB    *p_rcb = &l2cb.ble_rcb_pool[0];
1812     UINT16      xx;
1813 
1814     for (xx = 0; xx < BLE_MAX_L2CAP_CLIENTS; xx++, p_rcb++)
1815     {
1816         if (!p_rcb->in_use)
1817         {
1818             p_rcb->in_use = TRUE;
1819             p_rcb->psm    = psm;
1820 #if (L2CAP_UCD_INCLUDED == TRUE)
1821             p_rcb->ucd.state = L2C_UCD_STATE_UNUSED;
1822 #endif
1823             return (p_rcb);
1824         }
1825     }
1826 
1827     /* If here, no free RCB found */
1828     return (NULL);
1829 }
1830 #endif  ///BLE_INCLUDED == TRUE
1831 
1832 /*******************************************************************************
1833 **
1834 ** Function         l2cu_release_rcb
1835 **
1836 ** Description      Mark an RCB as no longet in use
1837 **
1838 ** Returns          void
1839 **
1840 *******************************************************************************/
l2cu_release_rcb(tL2C_RCB * p_rcb)1841 void l2cu_release_rcb (tL2C_RCB *p_rcb)
1842 {
1843     p_rcb->in_use = FALSE;
1844     p_rcb->psm    = 0;
1845 }
1846 
1847 
1848 /*******************************************************************************
1849 **
1850 ** Function         l2cu_disconnect_chnl
1851 **
1852 ** Description      Disconnect a channel. Typically, this is due to either
1853 **                  receiving a bad configuration,  bad packet or max_retries expiring.
1854 **
1855 *******************************************************************************/
l2cu_disconnect_chnl(tL2C_CCB * p_ccb)1856 void l2cu_disconnect_chnl (tL2C_CCB *p_ccb)
1857 {
1858     UINT16      local_cid = p_ccb->local_cid;
1859 
1860     if (local_cid >= L2CAP_BASE_APPL_CID) {
1861         tL2CA_DISCONNECT_IND_CB   *p_disc_cb = p_ccb->p_rcb->api.pL2CA_DisconnectInd_Cb;
1862 
1863         L2CAP_TRACE_WARNING ("L2CAP - disconnect_chnl CID: 0x%04x", local_cid);
1864 
1865         l2cu_send_peer_disc_req (p_ccb);
1866 
1867         l2cu_release_ccb (p_ccb);
1868 
1869         (*p_disc_cb)(local_cid, FALSE);
1870     } else {
1871         /* failure on the AMP channel, probably need to disconnect ACL */
1872         L2CAP_TRACE_ERROR ("L2CAP - disconnect_chnl CID: 0x%04x Ignored", local_cid);
1873     }
1874 }
1875 
1876 
1877 /*******************************************************************************
1878 **
1879 ** Function         l2cu_find_rcb_by_psm
1880 **
1881 ** Description      Look through the Registration Control Blocks to see if
1882 **                  anyone registered to handle the PSM in question
1883 **
1884 ** Returns          Pointer to the RCB or NULL if not found
1885 **
1886 *******************************************************************************/
l2cu_find_rcb_by_psm(UINT16 psm)1887 tL2C_RCB *l2cu_find_rcb_by_psm (UINT16 psm)
1888 {
1889     tL2C_RCB    *p_rcb = &l2cb.rcb_pool[0];
1890     UINT16      xx;
1891 
1892     for (xx = 0; xx < MAX_L2CAP_CLIENTS; xx++, p_rcb++) {
1893         if ((p_rcb->in_use) && (p_rcb->psm == psm)) {
1894             return (p_rcb);
1895         }
1896     }
1897 
1898     /* If here, no match found */
1899     return (NULL);
1900 }
1901 
1902 #if (BLE_INCLUDED == TRUE)
1903 /*******************************************************************************
1904 **
1905 ** Function         l2cu_find_ble_rcb_by_psm
1906 **
1907 ** Description      Look through the BLE Registration Control Blocks to see if
1908 **                  anyone registered to handle the PSM in question
1909 **
1910 ** Returns          Pointer to the BLE RCB or NULL if not found
1911 **
1912 *******************************************************************************/
l2cu_find_ble_rcb_by_psm(UINT16 psm)1913 tL2C_RCB *l2cu_find_ble_rcb_by_psm (UINT16 psm)
1914 {
1915     tL2C_RCB    *p_rcb = &l2cb.ble_rcb_pool[0];
1916     UINT16      xx;
1917 
1918     for (xx = 0; xx < BLE_MAX_L2CAP_CLIENTS; xx++, p_rcb++)
1919     {
1920         if ((p_rcb->in_use) && (p_rcb->psm == psm)) {
1921             return (p_rcb);
1922         }
1923     }
1924 
1925     /* If here, no match found */
1926     return (NULL);
1927 }
1928 #endif  ///BLE_INCLUDED == TRUE
1929 
1930 
1931 /*******************************************************************************
1932 **
1933 ** Function         l2cu_process_peer_cfg_req
1934 **
1935 ** Description      This function is called when the peer sends us a "config request"
1936 **                  message. It extracts the configuration of interest and saves
1937 **                  it in the CCB.
1938 **
1939 **                  Note:  Negotiation of the FCR channel type is handled internally,
1940 **                         all others are passed to the upper layer.
1941 **
1942 ** Returns          UINT8 - L2CAP_PEER_CFG_OK if passed to upper layer,
1943 **                          L2CAP_PEER_CFG_UNACCEPTABLE if automatically responded to
1944 **                              because parameters are unnacceptable from a specification
1945 **                              point of view.
1946 **                          L2CAP_PEER_CFG_DISCONNECT if no compatible channel modes
1947 **                              between the two devices, and shall be closed.
1948 **
1949 *******************************************************************************/
l2cu_process_peer_cfg_req(tL2C_CCB * p_ccb,tL2CAP_CFG_INFO * p_cfg)1950 UINT8 l2cu_process_peer_cfg_req (tL2C_CCB *p_ccb, tL2CAP_CFG_INFO *p_cfg)
1951 {
1952     BOOLEAN  mtu_ok      = TRUE;
1953     BOOLEAN  qos_type_ok = TRUE;
1954     BOOLEAN  flush_to_ok = TRUE;
1955     BOOLEAN  fcr_ok      = TRUE;
1956 #if (CLASSIC_BT_INCLUDED == TRUE)
1957     UINT8    fcr_status;
1958 #endif  ///CLASSIC_BT_INCLUDED == TRUE
1959     /* Ignore FCR parameters for basic mode */
1960     if (!p_cfg->fcr_present) {
1961         p_cfg->fcr.mode = L2CAP_FCR_BASIC_MODE;
1962     }
1963 
1964     /* Save the MTU that our peer can receive */
1965     if (p_cfg->mtu_present) {
1966         /* Make sure MTU is at least the minimum */
1967         if (p_cfg->mtu >= L2CAP_MIN_MTU) {
1968             /* In basic mode, limit the MTU to our buffer size */
1969             if ( (p_cfg->fcr_present == FALSE) && (p_cfg->mtu > L2CAP_MTU_SIZE) ) {
1970                 p_cfg->mtu = L2CAP_MTU_SIZE;
1971             }
1972 
1973             /* Save the accepted value in case of renegotiation */
1974             p_ccb->peer_cfg.mtu = p_cfg->mtu;
1975             p_ccb->peer_cfg.mtu_present = TRUE;
1976             p_ccb->peer_cfg_bits |= L2CAP_CH_CFG_MASK_MTU;
1977         } else { /* Illegal MTU value */
1978             p_cfg->mtu = L2CAP_MIN_MTU;
1979             mtu_ok     = FALSE;
1980         }
1981     }
1982     /* Reload mtu from a previously accepted config request */
1983     else if (p_ccb->peer_cfg.mtu_present) {
1984         p_cfg->mtu_present = TRUE;
1985         p_cfg->mtu = p_ccb->peer_cfg.mtu;
1986     }
1987 
1988     /* Verify that the flush timeout is a valid value (0 is illegal) */
1989     if (p_cfg->flush_to_present) {
1990         if (!p_cfg->flush_to) {
1991             p_cfg->flush_to = 0xFFFF;   /* Infinite retransmissions (spec default) */
1992             flush_to_ok     = FALSE;
1993         } else { /* Save the accepted value in case of renegotiation */
1994             p_ccb->peer_cfg.flush_to_present = TRUE;
1995             p_ccb->peer_cfg.flush_to = p_cfg->flush_to;
1996             p_ccb->peer_cfg_bits |= L2CAP_CH_CFG_MASK_FLUSH_TO;
1997         }
1998     }
1999     /* Reload flush_to from a previously accepted config request */
2000     else if (p_ccb->peer_cfg.flush_to_present) {
2001         p_cfg->flush_to_present = TRUE;
2002         p_cfg->flush_to = p_ccb->peer_cfg.flush_to;
2003     }
2004 
2005     /* Save the QOS settings the the peer is using */
2006     if (p_cfg->qos_present) {
2007         /* Make sure service type is not a reserved value; otherwise let upper
2008            layer decide if acceptable
2009         */
2010         if (p_cfg->qos.service_type <= GUARANTEED) {
2011             p_ccb->peer_cfg.qos         = p_cfg->qos;
2012             p_ccb->peer_cfg.qos_present = TRUE;
2013             p_ccb->peer_cfg_bits |= L2CAP_CH_CFG_MASK_QOS;
2014         } else { /* Illegal service type value */
2015             p_cfg->qos.service_type = BEST_EFFORT;
2016             qos_type_ok             = FALSE;
2017         }
2018     }
2019     /* Reload QOS from a previously accepted config request */
2020     else if (p_ccb->peer_cfg.qos_present) {
2021         p_cfg->qos_present = TRUE;
2022         p_cfg->qos         = p_ccb->peer_cfg.qos;
2023     }
2024 #if (CLASSIC_BT_INCLUDED == TRUE)
2025     if ((fcr_status = l2c_fcr_process_peer_cfg_req (p_ccb, p_cfg)) == L2CAP_PEER_CFG_DISCONNECT) {
2026         /* Notify caller to disconnect the channel (incompatible modes) */
2027         p_cfg->result = L2CAP_CFG_FAILED_NO_REASON;
2028         p_cfg->mtu_present = p_cfg->qos_present = p_cfg->flush_to_present = 0;
2029 
2030         return (L2CAP_PEER_CFG_DISCONNECT);
2031     }
2032 
2033     fcr_ok = (fcr_status == L2CAP_PEER_CFG_OK);
2034 #endif  ///CLASSIC_BT_INCLUDED == TRUE
2035 
2036     /* Return any unacceptable parameters */
2037     if (mtu_ok && flush_to_ok && qos_type_ok && fcr_ok) {
2038         l2cu_adjust_out_mps (p_ccb);
2039         return (L2CAP_PEER_CFG_OK);
2040     } else {
2041         p_cfg->result = L2CAP_CFG_UNACCEPTABLE_PARAMS;
2042 
2043         if (mtu_ok) {
2044             p_cfg->mtu_present = FALSE;
2045         }
2046         if (flush_to_ok) {
2047             p_cfg->flush_to_present = FALSE;
2048         }
2049         if (qos_type_ok) {
2050             p_cfg->qos_present = FALSE;
2051         }
2052         if (fcr_ok) {
2053             p_cfg->fcr_present = FALSE;
2054         }
2055 
2056         return (L2CAP_PEER_CFG_UNACCEPTABLE);
2057     }
2058 }
2059 
2060 
2061 /*******************************************************************************
2062 **
2063 ** Function         l2cu_process_peer_cfg_rsp
2064 **
2065 ** Description      This function is called when the peer sends us a "config response"
2066 **                  message. It extracts the configuration of interest and saves
2067 **                  it in the CCB.
2068 **
2069 ** Returns          void
2070 **
2071 *******************************************************************************/
l2cu_process_peer_cfg_rsp(tL2C_CCB * p_ccb,tL2CAP_CFG_INFO * p_cfg)2072 void l2cu_process_peer_cfg_rsp (tL2C_CCB *p_ccb, tL2CAP_CFG_INFO *p_cfg)
2073 {
2074     /* If we wanted QoS and the peer sends us a positive response with QoS, use his values */
2075     if ( (p_cfg->qos_present) && (p_ccb->our_cfg.qos_present) ) {
2076         p_ccb->our_cfg.qos = p_cfg->qos;
2077     }
2078 
2079     if (p_cfg->fcr_present) {
2080         /* Save the retransmission and monitor timeout values */
2081         if (p_cfg->fcr.mode == L2CAP_FCR_ERTM_MODE) {
2082             p_ccb->peer_cfg.fcr.rtrans_tout = p_cfg->fcr.rtrans_tout;
2083             p_ccb->peer_cfg.fcr.mon_tout = p_cfg->fcr.mon_tout;
2084         }
2085 
2086         /* Calculate the max number of packets for which we can delay sending an ack */
2087         if (p_cfg->fcr.tx_win_sz < p_ccb->our_cfg.fcr.tx_win_sz) {
2088             p_ccb->fcrb.max_held_acks = p_cfg->fcr.tx_win_sz / 3;
2089         } else {
2090             p_ccb->fcrb.max_held_acks = p_ccb->our_cfg.fcr.tx_win_sz / 3;
2091         }
2092 
2093         L2CAP_TRACE_DEBUG ("l2cu_process_peer_cfg_rsp(): peer tx_win_sz: %d, our tx_win_sz: %d, max_held_acks: %d",
2094                            p_cfg->fcr.tx_win_sz, p_ccb->our_cfg.fcr.tx_win_sz, p_ccb->fcrb.max_held_acks);
2095     }
2096 }
2097 
2098 /*******************************************************************************
2099 **
2100 ** Function         l2cu_process_our_cfg_req
2101 **
2102 ** Description      This function is called when we send a "config request"
2103 **                  message. It extracts the configuration of interest and saves
2104 **                  it in the CCB.
2105 **
2106 ** Returns          void
2107 **
2108 *******************************************************************************/
l2cu_process_our_cfg_req(tL2C_CCB * p_ccb,tL2CAP_CFG_INFO * p_cfg)2109 void l2cu_process_our_cfg_req (tL2C_CCB *p_ccb, tL2CAP_CFG_INFO *p_cfg)
2110 {
2111     tL2C_LCB    *p_lcb;
2112     UINT16      hci_flush_to;
2113 
2114     /* Save the QOS settings we are using for transmit */
2115     if (p_cfg->qos_present) {
2116         p_ccb->our_cfg.qos_present = TRUE;
2117         p_ccb->our_cfg.qos         = p_cfg->qos;
2118     }
2119 
2120     if (p_cfg->fcr_present) {
2121         /* Override FCR options if attempting streaming or basic */
2122         if (p_cfg->fcr.mode == L2CAP_FCR_BASIC_MODE) {
2123             memset(&p_cfg->fcr, 0, sizeof(tL2CAP_FCR_OPTS));
2124         } else {
2125             /* On BR/EDR, timer values are zero in config request */
2126             /* On class 2 AMP, timer value in config request shall be non-0 processing time */
2127             /*                 timer value in config response shall be greater than received processing time */
2128             p_cfg->fcr.mon_tout = p_cfg->fcr.rtrans_tout = 0;
2129 
2130             if (p_cfg->fcr.mode == L2CAP_FCR_STREAM_MODE) {
2131                 p_cfg->fcr.max_transmit = p_cfg->fcr.tx_win_sz = 0;
2132             }
2133         }
2134 
2135         /* Set the threshold to send acks (may be updated in the cfg response) */
2136         p_ccb->fcrb.max_held_acks = p_cfg->fcr.tx_win_sz / 3;
2137 
2138         /* Include FCS option only if peer can handle it */
2139         if (p_ccb->p_lcb->peer_ext_fea & L2CAP_EXTFEA_NO_CRC) {
2140             /* FCS check can be bypassed if peer also desires to bypass */
2141             if (p_cfg->fcs_present && p_cfg->fcs == L2CAP_CFG_FCS_BYPASS) {
2142                 p_ccb->bypass_fcs |= L2CAP_CFG_FCS_OUR;
2143             }
2144         } else {
2145             p_cfg->fcs_present = FALSE;
2146         }
2147     } else {
2148         p_cfg->fcr.mode = L2CAP_FCR_BASIC_MODE;
2149     }
2150 
2151     p_ccb->our_cfg.fcr.mode    = p_cfg->fcr.mode;
2152     p_ccb->our_cfg.fcr_present = p_cfg->fcr_present;
2153 
2154     /* Check the flush timeout. If it is lower than the current one used */
2155     /* then we need to adjust the flush timeout sent to the controller   */
2156     if (p_cfg->flush_to_present) {
2157         if ((p_cfg->flush_to == 0) || (p_cfg->flush_to == L2CAP_NO_AUTOMATIC_FLUSH)) {
2158             /* don't send invalid flush timeout */
2159             /* SPEC: The sender of the Request shall specify its flush timeout value */
2160             /*       if it differs from the default value of 0xFFFF                  */
2161             p_cfg->flush_to_present = FALSE;
2162         } else {
2163             p_ccb->our_cfg.flush_to = p_cfg->flush_to;
2164             p_lcb = p_ccb->p_lcb;
2165 
2166             if (p_cfg->flush_to < p_lcb->link_flush_tout) {
2167                 p_lcb->link_flush_tout = p_cfg->flush_to;
2168 
2169                 /* If the timeout is within range of HCI, set the flush timeout */
2170                 if (p_cfg->flush_to <= ((HCI_MAX_AUTO_FLUSH_TOUT * 5) / 8)) {
2171                     /* Convert flush timeout to 0.625 ms units, with round */
2172                     hci_flush_to = ((p_cfg->flush_to * 8) + 3) / 5;
2173                     btsnd_hcic_write_auto_flush_tout (p_lcb->handle, hci_flush_to);
2174                 }
2175             }
2176         }
2177     }
2178 }
2179 
2180 
2181 /*******************************************************************************
2182 **
2183 ** Function         l2cu_process_our_cfg_rsp
2184 **
2185 ** Description      This function is called when we send the peer a "config response"
2186 **                  message. It extracts the configuration of interest and saves
2187 **                  it in the CCB.
2188 **
2189 ** Returns          void
2190 **
2191 *******************************************************************************/
2192 #if (CLASSIC_BT_INCLUDED == TRUE)
l2cu_process_our_cfg_rsp(tL2C_CCB * p_ccb,tL2CAP_CFG_INFO * p_cfg)2193 void l2cu_process_our_cfg_rsp (tL2C_CCB *p_ccb, tL2CAP_CFG_INFO *p_cfg)
2194 {
2195     /* If peer wants QoS, we are allowed to change the values in a positive response */
2196     if ( (p_cfg->qos_present) && (p_ccb->peer_cfg.qos_present) ) {
2197         p_ccb->peer_cfg.qos = p_cfg->qos;
2198     } else {
2199         p_cfg->qos_present = FALSE;
2200     }
2201 
2202     l2c_fcr_adj_our_rsp_options (p_ccb, p_cfg);
2203 }
2204 #endif  ///CLASSIC_BT_INCLUDED == TRUE
2205 
2206 
2207 /*******************************************************************************
2208 **
2209 ** Function         l2cu_device_reset
2210 **
2211 ** Description      This function is called when reset of the device is
2212 **                  completed.  For all active connection simulate HCI_DISC
2213 **
2214 ** Returns          void
2215 **
2216 *******************************************************************************/
l2cu_device_reset(void)2217 void l2cu_device_reset (void)
2218 {
2219     list_node_t *p_node = NULL;
2220     tL2C_LCB    *p_lcb  = NULL;
2221     for (p_node = list_begin(l2cb.p_lcb_pool); p_node; p_node = list_next(p_node)) {
2222         p_lcb = list_node(p_node);
2223         if ((p_lcb->in_use) && (p_lcb->handle != HCI_INVALID_HANDLE)) {
2224             l2c_link_hci_disc_comp (p_lcb->handle, (UINT8) - 1);
2225         }
2226     }
2227 #if (BLE_INCLUDED == TRUE)
2228     l2cb.is_ble_connecting = FALSE;
2229 #endif
2230 }
2231 
2232 /*******************************************************************************
2233 **
2234 ** Function         l2cu_create_conn
2235 **
2236 ** Description      This function initiates an acl connection via HCI
2237 **
2238 ** Returns          TRUE if successful, FALSE if gki get buffer fails.
2239 **
2240 *******************************************************************************/
l2cu_create_conn(tL2C_LCB * p_lcb,tBT_TRANSPORT transport)2241 BOOLEAN l2cu_create_conn (tL2C_LCB *p_lcb, tBT_TRANSPORT transport)
2242 {
2243 #if BTM_SCO_INCLUDED == TRUE
2244     BOOLEAN         is_sco_active;
2245 #endif
2246     list_node_t *p_node     = NULL;
2247     tL2C_LCB    *p_lcb_cur  = NULL;
2248 
2249 #if (BLE_INCLUDED == TRUE)
2250     tBT_DEVICE_TYPE     dev_type;
2251     tBLE_ADDR_TYPE      addr_type = p_lcb->open_addr_type;
2252     if(addr_type == BLE_ADDR_UNKNOWN_TYPE) {
2253         BTM_ReadDevInfo(p_lcb->remote_bd_addr, &dev_type, &addr_type);
2254     }
2255 
2256     if (transport == BT_TRANSPORT_LE) {
2257         if (!controller_get_interface()->supports_ble()) {
2258             return FALSE;
2259         }
2260         if(addr_type > BLE_ADDR_TYPE_MAX) {
2261             addr_type = BLE_ADDR_PUBLIC;
2262         }
2263         p_lcb->ble_addr_type = addr_type;
2264         p_lcb->transport = BT_TRANSPORT_LE;
2265 
2266         return (l2cble_create_conn(p_lcb));
2267     }
2268 #endif
2269 
2270     /* If there is a connection where we perform as a slave, try to switch roles
2271        for this connection */
2272     for (p_node = list_begin(l2cb.p_lcb_pool); p_node; p_node = list_next(p_node)) {
2273         p_lcb_cur = list_node(p_node);
2274         if (p_lcb_cur == p_lcb) {
2275             continue;
2276         }
2277 
2278         if ((p_lcb_cur->in_use) && (p_lcb_cur->link_role == HCI_ROLE_SLAVE)) {
2279 
2280 #if BTM_SCO_INCLUDED == TRUE
2281             /* The LMP_switch_req shall be sent only if the ACL logical transport
2282             is in active mode, when encryption is disabled, and all synchronous
2283             logical transports on the same physical link are disabled." */
2284 
2285             /* Check if there is any SCO Active on this BD Address */
2286             is_sco_active = btm_is_sco_active_by_bdaddr(p_lcb_cur->remote_bd_addr);
2287 
2288             L2CAP_TRACE_API ("l2cu_create_conn - btm_is_sco_active_by_bdaddr() is_sco_active = %s", \
2289                              (is_sco_active == TRUE) ? "TRUE" : "FALSE");
2290 
2291             if (is_sco_active == TRUE) {
2292                 continue;    /* No Master Slave switch not allowed when SCO Active */
2293             }
2294 #endif
2295             /*4_1_TODO check  if btm_cb.devcb.local_features to be used instead */
2296             if (HCI_SWITCH_SUPPORTED(BTM_ReadLocalFeatures())) {
2297                 /* mark this lcb waiting for switch to be completed and
2298                    start switch on the other one */
2299                 p_lcb->link_state = LST_CONNECTING_WAIT_SWITCH;
2300                 p_lcb->link_role  = HCI_ROLE_MASTER;
2301 
2302                 if (BTM_SwitchRole (p_lcb_cur->remote_bd_addr, HCI_ROLE_MASTER, NULL) == BTM_CMD_STARTED) {
2303                     btu_start_timer (&p_lcb->timer_entry, BTU_TTYPE_L2CAP_LINK, L2CAP_LINK_ROLE_SWITCH_TOUT);
2304                     return (TRUE);
2305                 }
2306             }
2307         }
2308     }
2309 
2310     p_lcb->link_state = LST_CONNECTING;
2311 
2312     return (l2cu_create_conn_after_switch (p_lcb));
2313 }
2314 
2315 /*******************************************************************************
2316 **
2317 ** Function         l2cu_get_num_hi_priority
2318 **
2319 ** Description      Gets the number of high priority channels.
2320 **
2321 ** Returns
2322 **
2323 *******************************************************************************/
l2cu_get_num_hi_priority(void)2324 UINT8 l2cu_get_num_hi_priority (void)
2325 {
2326     UINT8       no_hi = 0;
2327     list_node_t *p_node = NULL;
2328     tL2C_LCB    *p_lcb = NULL;
2329 
2330     for (p_node = list_begin(l2cb.p_lcb_pool); p_node; p_node = list_next(p_node)) {
2331         p_lcb = list_node(p_node);
2332         if ((p_lcb->in_use) && (p_lcb->acl_priority == L2CAP_PRIORITY_HIGH)) {
2333             no_hi++;
2334         }
2335     }
2336     return no_hi;
2337 }
2338 
2339 
2340 /*******************************************************************************
2341 **
2342 ** Function         l2cu_create_conn_after_switch
2343 **
2344 ** Description      This function initiates an acl connection via HCI
2345 **                  If switch required to create connection it is already done.
2346 **
2347 ** Returns          TRUE if successful, FALSE if osi get buffer fails.
2348 **
2349 *******************************************************************************/
2350 
l2cu_create_conn_after_switch(tL2C_LCB * p_lcb)2351 BOOLEAN l2cu_create_conn_after_switch (tL2C_LCB *p_lcb)
2352 {
2353     UINT8            allow_switch = HCI_CR_CONN_ALLOW_SWITCH;
2354     tBTM_INQ_INFO    *p_inq_info;
2355     UINT8            page_scan_rep_mode;
2356     UINT8            page_scan_mode;
2357     UINT16           clock_offset;
2358     UINT8            *p_features;
2359     UINT16           num_acl = BTM_GetNumAclLinks();
2360     tBTM_SEC_DEV_REC *p_dev_rec = btm_find_dev (p_lcb->remote_bd_addr);
2361     UINT8            no_hi_prio_chs = l2cu_get_num_hi_priority();
2362 
2363     p_features = BTM_ReadLocalFeatures();
2364 
2365     L2CAP_TRACE_DEBUG ("l2cu_create_conn_after_switch :%d num_acl:%d no_hi: %d is_bonding:%d",
2366                        l2cb.disallow_switch, num_acl, no_hi_prio_chs, p_lcb->is_bonding);
2367     /* FW team says that we can participant in 4 piconets
2368      * typically 3 piconet + 1 for scanning.
2369      * We can enhance the code to count the number of piconets later. */
2370     if ( ((!l2cb.disallow_switch && (num_acl < 3)) || (p_lcb->is_bonding && (no_hi_prio_chs == 0)))
2371             && HCI_SWITCH_SUPPORTED(p_features)) {
2372         allow_switch = HCI_CR_CONN_ALLOW_SWITCH;
2373     } else {
2374         allow_switch = HCI_CR_CONN_NOT_ALLOW_SWITCH;
2375     }
2376 
2377     p_lcb->link_state = LST_CONNECTING;
2378 
2379     /* Check with the BT manager if details about remote device are known */
2380     if ((p_inq_info = BTM_InqDbRead(p_lcb->remote_bd_addr)) != NULL) {
2381         page_scan_rep_mode = p_inq_info->results.page_scan_rep_mode;
2382         page_scan_mode = p_inq_info->results.page_scan_mode;
2383         clock_offset = (UINT16)(p_inq_info->results.clock_offset);
2384     } else {
2385         /* No info known. Use default settings */
2386         page_scan_rep_mode = HCI_PAGE_SCAN_REP_MODE_R1;
2387         page_scan_mode = HCI_MANDATARY_PAGE_SCAN_MODE;
2388 
2389         clock_offset = (p_dev_rec) ? p_dev_rec->clock_offset : 0;
2390     }
2391 
2392     if (!btsnd_hcic_create_conn (p_lcb->remote_bd_addr,
2393                                  ( HCI_PKT_TYPES_MASK_DM1 | HCI_PKT_TYPES_MASK_DH1
2394                                    | HCI_PKT_TYPES_MASK_DM3 | HCI_PKT_TYPES_MASK_DH3
2395                                    | HCI_PKT_TYPES_MASK_DM5 | HCI_PKT_TYPES_MASK_DH5 ),
2396                                  page_scan_rep_mode,
2397                                  page_scan_mode,
2398                                  clock_offset,
2399                                  allow_switch))
2400 
2401     {
2402         L2CAP_TRACE_ERROR ("L2CAP - no buffer for l2cu_create_conn");
2403         l2cu_release_lcb (p_lcb);
2404         return (FALSE);
2405     }
2406 
2407     btm_acl_update_busy_level (BTM_BLI_PAGE_EVT);
2408 
2409     btu_start_timer (&p_lcb->timer_entry, BTU_TTYPE_L2CAP_LINK,
2410                      L2CAP_LINK_CONNECT_TOUT);
2411 
2412     return (TRUE);
2413 }
2414 
2415 
2416 /*******************************************************************************
2417 **
2418 ** Function         l2cu_find_lcb_by_state
2419 **
2420 ** Description      Look through all active LCBs for a match based on the
2421 **                  LCB state.
2422 **
2423 ** Returns          pointer to first matched LCB, or NULL if no match
2424 **
2425 *******************************************************************************/
l2cu_find_lcb_by_state(tL2C_LINK_STATE state)2426 tL2C_LCB *l2cu_find_lcb_by_state (tL2C_LINK_STATE state)
2427 {
2428     list_node_t *p_node = NULL;
2429     tL2C_LCB    *p_lcb = NULL;
2430 
2431     for (p_node = list_begin(l2cb.p_lcb_pool); p_node; p_node = list_next(p_node)) {
2432         p_lcb = list_node(p_node);
2433         if ((p_lcb->in_use) && (p_lcb->link_state == state)) {
2434             return (p_lcb);
2435         }
2436     }
2437 
2438     /* If here, no match found */
2439     return (NULL);
2440 }
2441 
2442 
2443 /*******************************************************************************
2444 **
2445 ** Function         l2cu_lcb_disconnecting
2446 **
2447 ** Description      On each active lcb, check if the lcb is in disconnecting
2448 **                  state, or if there are no ccb's on the lcb (implying
2449                     idle timeout is running), or if last ccb on the link
2450                     is in disconnecting state.
2451 **
2452 ** Returns          TRUE if any of above conditions met, FALSE otherwise
2453 **
2454 *******************************************************************************/
l2cu_lcb_disconnecting(void)2455 BOOLEAN l2cu_lcb_disconnecting (void)
2456 {
2457     tL2C_LCB    *p_lcb;
2458     tL2C_CCB    *p_ccb;
2459     BOOLEAN     status = FALSE;
2460     list_node_t *p_node = NULL;
2461 
2462     for (p_node = list_begin(l2cb.p_lcb_pool); p_node; p_node = list_next(p_node)) {
2463         p_lcb = list_node(p_node);
2464         if (p_lcb->in_use) {
2465             /* no ccbs on lcb, or lcb is in disconnecting state */
2466             if ((!p_lcb->ccb_queue.p_first_ccb) || (p_lcb->link_state == LST_DISCONNECTING)) {
2467                 status = TRUE;
2468                 break;
2469             }
2470             /* only one ccb left on lcb */
2471             else if (p_lcb->ccb_queue.p_first_ccb == p_lcb->ccb_queue.p_last_ccb) {
2472                 p_ccb = p_lcb->ccb_queue.p_first_ccb;
2473 
2474                 if ((p_ccb->in_use) &&
2475                         ((p_ccb->chnl_state == CST_W4_L2CAP_DISCONNECT_RSP) ||
2476                          (p_ccb->chnl_state == CST_W4_L2CA_DISCONNECT_RSP))) {
2477                     status = TRUE;
2478                     break;
2479                 }
2480             }
2481         }
2482     }
2483     return status;
2484 }
2485 
2486 
2487 /*******************************************************************************
2488 **
2489 ** Function         l2cu_set_acl_priority
2490 **
2491 ** Description      Sets the transmission priority for a channel.
2492 **                  (For initial implementation only two values are valid.
2493 **                  L2CAP_PRIORITY_NORMAL and L2CAP_PRIORITY_HIGH).
2494 **
2495 ** Returns          TRUE if a valid channel, else FALSE
2496 **
2497 *******************************************************************************/
2498 
l2cu_set_acl_priority(BD_ADDR bd_addr,UINT8 priority,BOOLEAN reset_after_rs)2499 BOOLEAN l2cu_set_acl_priority (BD_ADDR bd_addr, UINT8 priority, BOOLEAN reset_after_rs)
2500 {
2501     tL2C_LCB            *p_lcb;
2502     UINT8               *pp;
2503     UINT8                command[HCI_BRCM_ACL_PRIORITY_PARAM_SIZE];
2504     UINT8                vs_param;
2505 
2506     //APPL_TRACE_EVENT("SET ACL PRIORITY %d", priority);
2507 
2508     /* Find the link control block for the acl channel */
2509     if ((p_lcb = l2cu_find_lcb_by_bd_addr(bd_addr, BT_TRANSPORT_BR_EDR)) == NULL) {
2510         L2CAP_TRACE_WARNING ("L2CAP - no LCB for L2CA_SetAclPriority");
2511         return (FALSE);
2512     }
2513 
2514     if (BTM_IS_BRCM_CONTROLLER()) {
2515         /* Called from above L2CAP through API; send VSC if changed */
2516         if ((!reset_after_rs && (priority != p_lcb->acl_priority)) ||
2517                 /* Called because of a master/slave role switch; if high resend VSC */
2518                 ( reset_after_rs && p_lcb->acl_priority == L2CAP_PRIORITY_HIGH)) {
2519             pp = command;
2520 
2521             vs_param = (priority == L2CAP_PRIORITY_HIGH) ? HCI_BRCM_ACL_PRIORITY_HIGH : HCI_BRCM_ACL_PRIORITY_LOW;
2522 
2523             UINT16_TO_STREAM (pp, p_lcb->handle);
2524             UINT8_TO_STREAM  (pp, vs_param);
2525 
2526             BTM_VendorSpecificCommand (HCI_BRCM_SET_ACL_PRIORITY, HCI_BRCM_ACL_PRIORITY_PARAM_SIZE, command, NULL);
2527 
2528             /* Adjust lmp buffer allocation for this channel if priority changed */
2529             if (p_lcb->acl_priority != priority) {
2530                 p_lcb->acl_priority = priority;
2531                 l2c_link_adjust_allocation();
2532             }
2533         }
2534     }
2535     return (TRUE);
2536 }
2537 
2538 #if (L2CAP_NON_FLUSHABLE_PB_INCLUDED == TRUE)
2539 /******************************************************************************
2540 **
2541 ** Function         l2cu_set_non_flushable_pbf
2542 **
2543 ** Description      set L2CAP_PKT_START_NON_FLUSHABLE if controller supoorts
2544 **
2545 ** Returns          void
2546 **
2547 *******************************************************************************/
l2cu_set_non_flushable_pbf(BOOLEAN is_supported)2548 void l2cu_set_non_flushable_pbf (BOOLEAN is_supported)
2549 {
2550     if (is_supported) {
2551         l2cb.non_flushable_pbf = (L2CAP_PKT_START_NON_FLUSHABLE << L2CAP_PKT_TYPE_SHIFT);
2552     } else {
2553         l2cb.non_flushable_pbf = (L2CAP_PKT_START << L2CAP_PKT_TYPE_SHIFT);
2554     }
2555 }
2556 #endif
2557 
2558 /*******************************************************************************
2559 **
2560 ** Function         l2cu_resubmit_pending_sec_req
2561 **
2562 ** Description      This function is called when required security procedures
2563 **                  are completed and any pending requests can be re-submitted.
2564 **
2565 ** Returns          void
2566 **
2567 *******************************************************************************/
2568 #if (CLASSIC_BT_INCLUDED == TRUE)
l2cu_resubmit_pending_sec_req(BD_ADDR p_bda)2569 void l2cu_resubmit_pending_sec_req (BD_ADDR p_bda)
2570 {
2571     tL2C_LCB        *p_lcb;
2572     tL2C_CCB        *p_ccb;
2573     tL2C_CCB        *p_next_ccb;
2574     L2CAP_TRACE_DEBUG ("l2cu_resubmit_pending_sec_req  p_bda: %p", p_bda);
2575     list_node_t     *p_node = NULL;
2576 
2577     /* If we are called with a BDA, only resubmit for that BDA */
2578     if (p_bda) {
2579         p_lcb = l2cu_find_lcb_by_bd_addr (p_bda, BT_TRANSPORT_BR_EDR);
2580         /* If we don't have one, this is an error */
2581         if (p_lcb) {
2582             /* For all channels, send the event through their FSMs */
2583             for (p_ccb = p_lcb->ccb_queue.p_first_ccb; p_ccb; p_ccb = p_next_ccb) {
2584                 p_next_ccb = p_ccb->p_next_ccb;
2585                 l2c_csm_execute (p_ccb, L2CEVT_SEC_RE_SEND_CMD, NULL);
2586             }
2587         } else {
2588             L2CAP_TRACE_WARNING ("l2cu_resubmit_pending_sec_req - unknown BD_ADDR");
2589         }
2590     } else {
2591         /* No BDA pasesed in, so check all links */
2592     for (p_node = list_begin(l2cb.p_lcb_pool); p_node; p_node = list_next(p_node)) {
2593         p_lcb = list_node(p_node);
2594             if (p_lcb->in_use) {
2595                 /* For all channels, send the event through their FSMs */
2596                 for (p_ccb = p_lcb->ccb_queue.p_first_ccb; p_ccb; p_ccb = p_next_ccb) {
2597                     p_next_ccb = p_ccb->p_next_ccb;
2598                     l2c_csm_execute (p_ccb, L2CEVT_SEC_RE_SEND_CMD, NULL);
2599                 }
2600             }
2601         }
2602     }
2603 }
2604 #endif  ///CLASSIC_BT_INCLUDED == TRUE
2605 
2606 #if L2CAP_CONFORMANCE_TESTING == TRUE
2607 /*******************************************************************************
2608 **
2609 ** Function         l2cu_set_info_rsp_mask
2610 **
2611 ** Description      This function allows the script wrapper to change the
2612 **                  info resp mask for conformance testing.
2613 **
2614 ** Returns          pointer to CCB, or NULL if none
2615 **
2616 *******************************************************************************/
l2cu_set_info_rsp_mask(UINT32 mask)2617 void l2cu_set_info_rsp_mask (UINT32 mask)
2618 {
2619     l2cb.test_info_resp = mask;
2620 }
2621 #endif  /* L2CAP_CONFORMANCE_TESTING */
2622 
2623 /*******************************************************************************
2624 **
2625 ** Function         l2cu_adjust_out_mps
2626 **
2627 ** Description      Sets our MPS based on current controller capabilities
2628 **
2629 ** Returns          void
2630 **
2631 *******************************************************************************/
l2cu_adjust_out_mps(tL2C_CCB * p_ccb)2632 void l2cu_adjust_out_mps (tL2C_CCB *p_ccb)
2633 {
2634     UINT16 packet_size;
2635 
2636     /* on the tx side MTU is selected based on packet size of the controller */
2637     packet_size = btm_get_max_packet_size (p_ccb->p_lcb->remote_bd_addr);
2638 
2639     if (packet_size <= (L2CAP_PKT_OVERHEAD + L2CAP_FCR_OVERHEAD + L2CAP_SDU_LEN_OVERHEAD + L2CAP_FCS_LEN)) {
2640         /* something is very wrong */
2641         L2CAP_TRACE_DEBUG ("l2cu_adjust_out_mps bad packet size: %u  will use MPS: %u", packet_size, p_ccb->peer_cfg.fcr.mps);
2642         p_ccb->tx_mps = p_ccb->peer_cfg.fcr.mps;
2643     } else {
2644         packet_size -= (L2CAP_PKT_OVERHEAD + L2CAP_FCR_OVERHEAD + L2CAP_SDU_LEN_OVERHEAD + L2CAP_FCS_LEN);
2645 
2646         /* We try to negotiate MTU that each packet can be split into whole
2647         number of max packets.  For example if link is 1.2 max packet size is 339 bytes.
2648         At first calculate how many whole packets it is.  MAX L2CAP is 1691 + 4 overhead.
2649         1695, that will be 5 Dh5 packets.  Now maximum L2CAP packet is
2650         5 * 339 = 1695. Minus 4 bytes L2CAP header 1691.
2651 
2652         For EDR 2.0 packet size is 1027.  So we better send RFCOMM packet as 1 3DH5 packet
2653         1 * 1027 = 1027.  Minus 4 bytes L2CAP header 1023.  */
2654         if (p_ccb->peer_cfg.fcr.mps >= packet_size) {
2655             p_ccb->tx_mps = p_ccb->peer_cfg.fcr.mps / packet_size * packet_size;
2656         } else {
2657             p_ccb->tx_mps = p_ccb->peer_cfg.fcr.mps;
2658         }
2659 
2660         L2CAP_TRACE_DEBUG ("l2cu_adjust_out_mps use %d   Based on peer_cfg.fcr.mps: %u  packet_size: %u",
2661                            p_ccb->tx_mps, p_ccb->peer_cfg.fcr.mps, packet_size);
2662     }
2663 }
2664 
2665 
2666 /*******************************************************************************
2667 **
2668 ** Function         l2cu_initialize_fixed_ccb
2669 **
2670 ** Description      Initialize a fixed channel's CCB
2671 **
2672 ** Returns          TRUE or FALSE
2673 **
2674 *******************************************************************************/
l2cu_initialize_fixed_ccb(tL2C_LCB * p_lcb,UINT16 fixed_cid,tL2CAP_FCR_OPTS * p_fcr)2675 BOOLEAN l2cu_initialize_fixed_ccb (tL2C_LCB *p_lcb, UINT16 fixed_cid, tL2CAP_FCR_OPTS *p_fcr)
2676 {
2677 #if (L2CAP_NUM_FIXED_CHNLS > 0)
2678     tL2C_CCB    *p_ccb;
2679     /* If we already have a CCB, then simply return */
2680     if (p_lcb->p_fixed_ccbs[fixed_cid - L2CAP_FIRST_FIXED_CHNL] != NULL) {
2681         return (TRUE);
2682     }
2683 
2684     if ((p_ccb = l2cu_allocate_ccb (NULL, 0)) == NULL) {
2685         return (FALSE);
2686     }
2687 
2688     btu_stop_timer(&p_lcb->timer_entry);
2689 
2690     /* Set CID for the connection */
2691     p_ccb->local_cid  = fixed_cid;
2692     p_ccb->remote_cid = fixed_cid;
2693 
2694     p_ccb->is_flushable = FALSE;
2695 
2696     p_ccb->timer_entry.param  = (TIMER_PARAM_TYPE)p_ccb;
2697 
2698 
2699     if (p_fcr) {
2700         /* Set the FCR parameters. For now, we will use default pools */
2701         p_ccb->our_cfg.fcr = p_ccb->peer_cfg.fcr = *p_fcr;
2702 
2703         p_ccb->ertm_info.fcr_rx_buf_size  = L2CAP_FCR_RX_BUF_SIZE;
2704         p_ccb->ertm_info.fcr_tx_buf_size  = L2CAP_FCR_TX_BUF_SIZE;
2705         p_ccb->ertm_info.user_rx_buf_size = L2CAP_USER_RX_BUF_SIZE;
2706         p_ccb->ertm_info.user_tx_buf_size = L2CAP_USER_TX_BUF_SIZE;
2707 
2708         p_ccb->fcrb.max_held_acks = p_fcr->tx_win_sz / 3;
2709     }
2710 
2711     /* Link ccb to lcb and lcb to ccb */
2712     p_lcb->p_fixed_ccbs[fixed_cid - L2CAP_FIRST_FIXED_CHNL] = p_ccb;
2713     p_ccb->p_lcb = p_lcb;
2714 
2715     /* There is no configuration, so if the link is up, the channel is up */
2716     if (p_lcb->link_state == LST_CONNECTED) {
2717         p_ccb->chnl_state = CST_OPEN;
2718     }
2719 
2720     /* Set the default idle timeout value to use */
2721     p_ccb->fixed_chnl_idle_tout = l2cb.fixed_reg[fixed_cid - L2CAP_FIRST_FIXED_CHNL].default_idle_tout;
2722 #endif
2723     return (TRUE);
2724 }
2725 
2726 /*******************************************************************************
2727 **
2728 ** Function         l2cu_no_dynamic_ccbs
2729 **
2730 ** Description      Handles the case when there are no more dynamic CCBs. If there
2731 **                  are any fixed CCBs, start the longest of the fixed CCB timeouts,
2732 **                  otherwise start the default link idle timeout or disconnect.
2733 **
2734 ** Returns          void
2735 **
2736 *******************************************************************************/
l2cu_no_dynamic_ccbs(tL2C_LCB * p_lcb)2737 void l2cu_no_dynamic_ccbs (tL2C_LCB *p_lcb)
2738 {
2739 #if (SMP_INCLUDED == TRUE)
2740     tBTM_STATUS     rc;
2741 #endif  ///SMP_INCLUDED == TRUE
2742     UINT16          timeout = p_lcb->idle_timeout;
2743 
2744 #if (L2CAP_NUM_FIXED_CHNLS > 0)
2745     int         xx;
2746 
2747     for (xx = 0; xx < L2CAP_NUM_FIXED_CHNLS; xx++) {
2748         if ( (p_lcb->p_fixed_ccbs[xx] != NULL) && (p_lcb->p_fixed_ccbs[xx]->fixed_chnl_idle_tout > timeout) ) {
2749             timeout = p_lcb->p_fixed_ccbs[xx]->fixed_chnl_idle_tout;
2750         }
2751     }
2752 #endif
2753 
2754     /* If the link is pairing, do not mess with the timeouts */
2755     if (p_lcb->is_bonding) {
2756         return;
2757     }
2758 
2759     if (timeout == 0) {
2760         L2CAP_TRACE_DEBUG ("l2cu_no_dynamic_ccbs() IDLE timer 0, disconnecting link");
2761 #if (SMP_INCLUDED == TRUE)
2762         rc = btm_sec_disconnect (p_lcb->handle, HCI_ERR_PEER_USER);
2763         if (rc == BTM_CMD_STARTED) {
2764             l2cu_process_fixed_disc_cback(p_lcb);
2765             p_lcb->link_state = LST_DISCONNECTING;
2766             timeout = L2CAP_LINK_DISCONNECT_TOUT;
2767         } else if (rc == BTM_SUCCESS) {
2768             l2cu_process_fixed_disc_cback(p_lcb);
2769             /* BTM SEC will make sure that link is release (probably after pairing is done) */
2770             p_lcb->link_state = LST_DISCONNECTING;
2771             timeout = 0xFFFF;
2772         } else if ( (p_lcb->is_bonding)
2773                     &&   (btsnd_hcic_disconnect (p_lcb->handle, HCI_ERR_PEER_USER)) ) {
2774             l2cu_process_fixed_disc_cback(p_lcb);
2775             p_lcb->link_state = LST_DISCONNECTING;
2776             timeout = L2CAP_LINK_DISCONNECT_TOUT;
2777         } else {
2778             /* probably no buffer to send disconnect */
2779             timeout = BT_1SEC_TIMEOUT;
2780         }
2781 #else
2782         if (btsnd_hcic_disconnect (p_lcb->handle, HCI_ERR_PEER_USER)) {
2783             l2cu_process_fixed_disc_cback(p_lcb);
2784             p_lcb->link_state = LST_DISCONNECTING;
2785             timeout = L2CAP_LINK_DISCONNECT_TOUT;
2786         } else {
2787             timeout = BT_1SEC_TIMEOUT;
2788         }
2789 #endif  ///SMP_INCLUDED == TRUE
2790 
2791     }
2792 
2793     if (timeout != 0xFFFF) {
2794         L2CAP_TRACE_DEBUG ("l2cu_no_dynamic_ccbs() starting IDLE timeout: %d", timeout);
2795         btu_start_timer (&p_lcb->timer_entry, BTU_TTYPE_L2CAP_LINK, timeout);
2796     } else {
2797         btu_stop_timer(&p_lcb->timer_entry);
2798     }
2799 }
2800 
2801 #if (L2CAP_NUM_FIXED_CHNLS > 0)
2802 /*******************************************************************************
2803 **
2804 ** Function         l2cu_process_fixed_chnl_resp
2805 **
2806 ** Description      handle a fixed channel response (or lack thereof)
2807 **                  if the link failed, or a fixed channel response was
2808 **                  not received, the bitfield is all zeros.
2809 **
2810 *******************************************************************************/
l2cu_process_fixed_chnl_resp(tL2C_LCB * p_lcb)2811 void l2cu_process_fixed_chnl_resp (tL2C_LCB *p_lcb)
2812 {
2813     L2CAP_TRACE_DEBUG("%s",__func__);
2814 #if (BLE_INCLUDED == TRUE)
2815     if (p_lcb->transport == BT_TRANSPORT_BR_EDR) {
2816         /* ignore all not assigned BR/EDR channels */
2817         p_lcb->peer_chnl_mask[0] &= (L2CAP_FIXED_CHNL_SIG_BIT | \
2818                                      L2CAP_FIXED_CHNL_CNCTLESS_BIT | \
2819                                      L2CAP_FIXED_CHNL_SMP_BR_BIT);
2820     } else {
2821         p_lcb->peer_chnl_mask[0] = l2cb.l2c_ble_fixed_chnls_mask;
2822     }
2823 #endif
2824 
2825     /* Tell all registered fixed channels about the connection */
2826     for (int xx = 0; xx < L2CAP_NUM_FIXED_CHNLS; xx++) {
2827 #if BLE_INCLUDED == TRUE
2828         /* skip sending LE fix channel callbacks on BR/EDR links */
2829         if (p_lcb->transport == BT_TRANSPORT_BR_EDR &&
2830                 xx + L2CAP_FIRST_FIXED_CHNL >= L2CAP_ATT_CID &&
2831                 xx + L2CAP_FIRST_FIXED_CHNL <= L2CAP_SMP_CID) {
2832             continue;
2833         }
2834 #endif
2835         if (l2cb.fixed_reg[xx].pL2CA_FixedConn_Cb != NULL) {
2836             if (p_lcb->peer_chnl_mask[(xx + L2CAP_FIRST_FIXED_CHNL) / 8]
2837                     & (1 << ((xx + L2CAP_FIRST_FIXED_CHNL) % 8))) {
2838                 if (p_lcb->p_fixed_ccbs[xx]) {
2839                     p_lcb->p_fixed_ccbs[xx]->chnl_state = CST_OPEN;
2840                 }
2841 #if BLE_INCLUDED == TRUE
2842                 (*l2cb.fixed_reg[xx].pL2CA_FixedConn_Cb)(xx + L2CAP_FIRST_FIXED_CHNL,
2843                         p_lcb->remote_bd_addr, TRUE, 0, p_lcb->transport);
2844 #else
2845                 (*l2cb.fixed_reg[xx].pL2CA_FixedConn_Cb)(xx + L2CAP_FIRST_FIXED_CHNL,
2846                         p_lcb->remote_bd_addr, TRUE, 0, BT_TRANSPORT_BR_EDR);
2847 #endif
2848             } else {
2849 #if BLE_INCLUDED == TRUE
2850                 (*l2cb.fixed_reg[xx].pL2CA_FixedConn_Cb)(xx + L2CAP_FIRST_FIXED_CHNL,
2851                         p_lcb->remote_bd_addr, FALSE, p_lcb->disc_reason, p_lcb->transport);
2852 #else
2853                 (*l2cb.fixed_reg[xx].pL2CA_FixedConn_Cb)(xx + L2CAP_FIRST_FIXED_CHNL,
2854                         p_lcb->remote_bd_addr, FALSE, p_lcb->disc_reason, BT_TRANSPORT_BR_EDR);
2855 #endif
2856 
2857                 if (p_lcb->p_fixed_ccbs[xx]) {
2858                     l2cu_release_ccb (p_lcb->p_fixed_ccbs[xx]);
2859                     p_lcb->p_fixed_ccbs[xx] = NULL;
2860                 }
2861             }
2862         }
2863     }
2864 }
2865 #endif
2866 
2867 
2868 /*******************************************************************************
2869 **
2870 ** Function         l2cu_process_fixed_disc_cback
2871 **
2872 ** Description      send l2cap fixed channel disconnection callback to application
2873 **
2874 **
2875 ** Returns          void
2876 **
2877 *******************************************************************************/
l2cu_process_fixed_disc_cback(tL2C_LCB * p_lcb)2878 void l2cu_process_fixed_disc_cback (tL2C_LCB *p_lcb)
2879 {
2880 #if (L2CAP_NUM_FIXED_CHNLS > 0)
2881 
2882     /* Select peer channels mask to use depending on transport */
2883     UINT8 peer_channel_mask = p_lcb->peer_chnl_mask[0];
2884 
2885     // For LE, reset the stored peer channel mask
2886     if (p_lcb->transport == BT_TRANSPORT_LE) {
2887         p_lcb->peer_chnl_mask[0] = 0;
2888     }
2889 
2890     for (int xx = 0; xx < L2CAP_NUM_FIXED_CHNLS; xx++) {
2891         if (p_lcb->p_fixed_ccbs[xx]) {
2892             if (p_lcb->p_fixed_ccbs[xx] != p_lcb->p_pending_ccb) {
2893                 tL2C_CCB *p_l2c_chnl_ctrl_block;
2894                 p_l2c_chnl_ctrl_block = p_lcb->p_fixed_ccbs[xx];
2895                 p_lcb->p_fixed_ccbs[xx] = NULL;
2896                 l2cu_release_ccb(p_l2c_chnl_ctrl_block);
2897 #if BLE_INCLUDED == TRUE
2898                 (*l2cb.fixed_reg[xx].pL2CA_FixedConn_Cb)(xx + L2CAP_FIRST_FIXED_CHNL,
2899                         p_lcb->remote_bd_addr, FALSE, p_lcb->disc_reason, p_lcb->transport);
2900 #else
2901                 (*l2cb.fixed_reg[xx].pL2CA_FixedConn_Cb)(xx + L2CAP_FIRST_FIXED_CHNL,
2902                         p_lcb->remote_bd_addr, FALSE, p_lcb->disc_reason, BT_TRANSPORT_BR_EDR);
2903 #endif
2904             }
2905         } else if ( (peer_channel_mask & (1 << (xx + L2CAP_FIRST_FIXED_CHNL)))
2906                     && (l2cb.fixed_reg[xx].pL2CA_FixedConn_Cb != NULL) ) {
2907 #if BLE_INCLUDED == TRUE
2908             (*l2cb.fixed_reg[xx].pL2CA_FixedConn_Cb)(xx + L2CAP_FIRST_FIXED_CHNL,
2909                     p_lcb->remote_bd_addr, FALSE, p_lcb->disc_reason, p_lcb->transport);
2910 #else
2911             (*l2cb.fixed_reg[xx].pL2CA_FixedConn_Cb)(xx + L2CAP_FIRST_FIXED_CHNL,
2912                     p_lcb->remote_bd_addr, FALSE, p_lcb->disc_reason, BT_TRANSPORT_BR_EDR);
2913 #endif
2914         }
2915     }
2916 #endif
2917 }
2918 
2919 #if (BLE_INCLUDED == TRUE)
2920 /*******************************************************************************
2921 **
2922 ** Function         l2cu_send_peer_ble_par_req
2923 **
2924 ** Description      Build and send a BLE parameter update request message
2925 **                  to the peer.
2926 **
2927 ** Returns          void
2928 **
2929 *******************************************************************************/
l2cu_send_peer_ble_par_req(tL2C_LCB * p_lcb,UINT16 min_int,UINT16 max_int,UINT16 latency,UINT16 timeout)2930 void l2cu_send_peer_ble_par_req (tL2C_LCB *p_lcb, UINT16 min_int, UINT16 max_int,
2931                                  UINT16 latency, UINT16 timeout)
2932 {
2933     BT_HDR  *p_buf;
2934     UINT8   *p;
2935 
2936     /* Create an identifier for this packet */
2937     p_lcb->id++;
2938     l2cu_adj_id (p_lcb, L2CAP_ADJ_ID);
2939 
2940     if ((p_buf = l2cu_build_header (p_lcb, L2CAP_CMD_BLE_UPD_REQ_LEN,
2941                                     L2CAP_CMD_BLE_UPDATE_REQ, p_lcb->id)) == NULL ) {
2942         L2CAP_TRACE_WARNING ("l2cu_send_peer_ble_par_req - no buffer");
2943         return;
2944     }
2945 
2946     p = (UINT8 *)(p_buf + 1) + L2CAP_SEND_CMD_OFFSET + HCI_DATA_PREAMBLE_SIZE +
2947         L2CAP_PKT_OVERHEAD + L2CAP_CMD_OVERHEAD;
2948 
2949     UINT16_TO_STREAM (p, min_int);
2950     UINT16_TO_STREAM (p, max_int);
2951     UINT16_TO_STREAM (p, latency);
2952     UINT16_TO_STREAM (p, timeout);
2953 
2954     l2c_link_check_send_pkts (p_lcb, NULL, p_buf);
2955 }
2956 
2957 /*******************************************************************************
2958 **
2959 ** Function         l2cu_send_peer_ble_par_rsp
2960 **
2961 ** Description      Build and send a BLE parameter update response message
2962 **                  to the peer.
2963 **
2964 ** Returns          void
2965 **
2966 *******************************************************************************/
l2cu_send_peer_ble_par_rsp(tL2C_LCB * p_lcb,UINT16 reason,UINT8 rem_id)2967 void l2cu_send_peer_ble_par_rsp (tL2C_LCB *p_lcb, UINT16 reason, UINT8 rem_id)
2968 {
2969     BT_HDR  *p_buf;
2970     UINT8   *p;
2971 
2972     if ((p_buf = l2cu_build_header (p_lcb, L2CAP_CMD_BLE_UPD_RSP_LEN,
2973                                     L2CAP_CMD_BLE_UPDATE_RSP, rem_id)) == NULL ) {
2974         L2CAP_TRACE_WARNING ("l2cu_send_peer_ble_par_rsp - no buffer");
2975         return;
2976     }
2977 
2978     p = (UINT8 *)(p_buf + 1) + L2CAP_SEND_CMD_OFFSET + HCI_DATA_PREAMBLE_SIZE +
2979         L2CAP_PKT_OVERHEAD + L2CAP_CMD_OVERHEAD;
2980 
2981     UINT16_TO_STREAM (p, reason);
2982 
2983     l2c_link_check_send_pkts (p_lcb, NULL, p_buf);
2984 }
2985 
2986 /*******************************************************************************
2987 **
2988 ** Function         l2cu_send_peer_ble_credit_based_conn_req
2989 **
2990 ** Description      Build and send a BLE packet to establish LE connection oriented
2991 **                  L2CAP channel.
2992 **
2993 ** Returns          void
2994 **
2995 *******************************************************************************/
l2cu_send_peer_ble_credit_based_conn_req(tL2C_CCB * p_ccb)2996 void l2cu_send_peer_ble_credit_based_conn_req (tL2C_CCB *p_ccb)
2997 {
2998     BT_HDR  *p_buf;
2999     UINT8   *p;
3000     tL2C_LCB *p_lcb = NULL;
3001     UINT16 mtu;
3002     UINT16 mps;
3003     UINT16 initial_credit;
3004 
3005     if (!p_ccb) {
3006         return;
3007     }
3008     p_lcb = p_ccb->p_lcb;
3009 
3010     /* Create an identifier for this packet */
3011     p_ccb->p_lcb->id++;
3012     l2cu_adj_id(p_ccb->p_lcb, L2CAP_ADJ_ID);
3013 
3014     p_ccb->local_id = p_ccb->p_lcb->id;
3015 
3016     if ((p_buf = l2cu_build_header (p_lcb, L2CAP_CMD_BLE_CREDIT_BASED_CONN_REQ_LEN,
3017                     L2CAP_CMD_BLE_CREDIT_BASED_CONN_REQ, p_lcb->id)) == NULL )
3018     {
3019         L2CAP_TRACE_WARNING ("l2cu_send_peer_ble_credit_based_conn_req - no buffer");
3020         return;
3021     }
3022 
3023     p = (UINT8 *)(p_buf + 1) + L2CAP_SEND_CMD_OFFSET + HCI_DATA_PREAMBLE_SIZE +
3024                                L2CAP_PKT_OVERHEAD + L2CAP_CMD_OVERHEAD;
3025 
3026     mtu = p_ccb->local_conn_cfg.mtu;
3027     mps = p_ccb->local_conn_cfg.mps;
3028     initial_credit = p_ccb->local_conn_cfg.credits;
3029 
3030     L2CAP_TRACE_DEBUG ("l2cu_send_peer_ble_credit_based_conn_req PSM:0x%04x local_cid:%d\
3031                 mtu:%d mps:%d initial_credit:%d", p_ccb->p_rcb->real_psm,\
3032                 p_ccb->local_cid, mtu, mps, initial_credit);
3033 
3034     UINT16_TO_STREAM (p, p_ccb->p_rcb->real_psm);
3035     UINT16_TO_STREAM (p, p_ccb->local_cid);
3036     UINT16_TO_STREAM (p, mtu);
3037     UINT16_TO_STREAM (p, mps);
3038     UINT16_TO_STREAM (p, initial_credit);
3039 
3040     l2c_link_check_send_pkts (p_lcb, NULL, p_buf);
3041 }
3042 
3043 /*******************************************************************************
3044 **
3045 ** Function         l2cu_reject_ble_connection
3046 **
3047 ** Description      Build and send an L2CAP "Credit based connection res" message
3048 **                  to the peer. This function is called for non-success cases.
3049 **
3050 ** Returns          void
3051 **
3052 *******************************************************************************/
l2cu_reject_ble_connection(tL2C_LCB * p_lcb,UINT8 rem_id,UINT16 result)3053 void l2cu_reject_ble_connection (tL2C_LCB *p_lcb, UINT8 rem_id, UINT16 result)
3054 {
3055     BT_HDR  *p_buf;
3056     UINT8   *p;
3057 
3058     if ((p_buf = l2cu_build_header(p_lcb, L2CAP_CMD_BLE_CREDIT_BASED_CONN_RES_LEN,
3059                     L2CAP_CMD_BLE_CREDIT_BASED_CONN_RES, rem_id)) == NULL )
3060     {
3061         L2CAP_TRACE_WARNING ("l2cu_reject_ble_connection - no buffer");
3062         return;
3063     }
3064 
3065     p = (UINT8 *)(p_buf + 1) + L2CAP_SEND_CMD_OFFSET + HCI_DATA_PREAMBLE_SIZE +
3066                                L2CAP_PKT_OVERHEAD + L2CAP_CMD_OVERHEAD;
3067 
3068     UINT16_TO_STREAM (p, 0);                    /* Local CID of 0   */
3069     UINT16_TO_STREAM (p, 0);                    /* MTU */
3070     UINT16_TO_STREAM (p, 0);                    /* MPS */
3071     UINT16_TO_STREAM (p, 0);                    /* initial credit */
3072     UINT16_TO_STREAM (p, result);
3073 
3074     l2c_link_check_send_pkts (p_lcb, NULL, p_buf);
3075 }
3076 
3077 /*******************************************************************************
3078 **
3079 ** Function         l2cu_send_peer_ble_credit_based_conn_res
3080 **
3081 ** Description      Build and send an L2CAP "Credit based connection res" message
3082 **                  to the peer. This function is called in case of success.
3083 **
3084 ** Returns          void
3085 **
3086 *******************************************************************************/
l2cu_send_peer_ble_credit_based_conn_res(tL2C_CCB * p_ccb,UINT16 result)3087 void l2cu_send_peer_ble_credit_based_conn_res (tL2C_CCB *p_ccb, UINT16 result)
3088 {
3089     BT_HDR  *p_buf;
3090     UINT8   *p;
3091 
3092     L2CAP_TRACE_DEBUG ("l2cu_send_peer_ble_credit_based_conn_res");
3093     if ((p_buf = l2cu_build_header(p_ccb->p_lcb, L2CAP_CMD_BLE_CREDIT_BASED_CONN_RES_LEN,
3094                     L2CAP_CMD_BLE_CREDIT_BASED_CONN_RES, p_ccb->remote_id)) == NULL )
3095     {
3096         L2CAP_TRACE_WARNING ("l2cu_send_peer_ble_credit_based_conn_res - no buffer");
3097         return;
3098     }
3099 
3100     p = (UINT8 *)(p_buf + 1) + L2CAP_SEND_CMD_OFFSET + HCI_DATA_PREAMBLE_SIZE +
3101                                L2CAP_PKT_OVERHEAD + L2CAP_CMD_OVERHEAD;
3102 
3103     UINT16_TO_STREAM (p, p_ccb->local_cid);                      /* Local CID */
3104     UINT16_TO_STREAM (p, p_ccb->local_conn_cfg.mtu);             /* MTU */
3105     UINT16_TO_STREAM (p, p_ccb->local_conn_cfg.mps);             /* MPS */
3106     UINT16_TO_STREAM (p, p_ccb->local_conn_cfg.credits);         /* initial credit */
3107     UINT16_TO_STREAM (p, result);
3108 
3109     l2c_link_check_send_pkts (p_ccb->p_lcb, NULL, p_buf);
3110 }
3111 
3112 /*******************************************************************************
3113 **
3114 ** Function         l2cu_send_peer_ble_flow_control_credit
3115 **
3116 ** Description      Build and send a BLE packet to give credits to peer device
3117 **                  for LE connection oriented L2CAP channel.
3118 **
3119 ** Returns          void
3120 **
3121 *******************************************************************************/
l2cu_send_peer_ble_flow_control_credit(tL2C_CCB * p_ccb,UINT16 credit_value)3122 void l2cu_send_peer_ble_flow_control_credit(tL2C_CCB *p_ccb, UINT16 credit_value)
3123 {
3124     BT_HDR  *p_buf;
3125     UINT8   *p;
3126     tL2C_LCB *p_lcb = NULL;
3127 
3128     if (!p_ccb) {
3129         return;
3130     }
3131     p_lcb = p_ccb->p_lcb;
3132 
3133     /* Create an identifier for this packet */
3134     p_ccb->p_lcb->id++;
3135     l2cu_adj_id(p_ccb->p_lcb, L2CAP_ADJ_ID);
3136 
3137     p_ccb->local_id = p_ccb->p_lcb->id;
3138 
3139     if ((p_buf = l2cu_build_header (p_lcb, L2CAP_CMD_BLE_FLOW_CTRL_CREDIT_LEN,
3140                     L2CAP_CMD_BLE_FLOW_CTRL_CREDIT, p_lcb->id)) == NULL )
3141     {
3142         L2CAP_TRACE_WARNING ("l2cu_send_peer_ble_credit_based_conn_req - no buffer");
3143         return;
3144     }
3145 
3146     p = (UINT8 *)(p_buf + 1) + L2CAP_SEND_CMD_OFFSET + HCI_DATA_PREAMBLE_SIZE +
3147                                L2CAP_PKT_OVERHEAD + L2CAP_CMD_OVERHEAD;
3148 
3149     UINT16_TO_STREAM (p, p_ccb->local_cid);
3150     UINT16_TO_STREAM (p, credit_value);
3151 
3152     l2c_link_check_send_pkts (p_lcb, NULL, p_buf);
3153 }
3154 
3155 /*******************************************************************************
3156 **
3157 ** Function         l2cu_send_peer_ble_credit_based_conn_req
3158 **
3159 ** Description      Build and send a BLE packet to disconnect LE connection oriented
3160 **                  L2CAP channel.
3161 **
3162 ** Returns          void
3163 **
3164 *******************************************************************************/
l2cu_send_peer_ble_credit_based_disconn_req(tL2C_CCB * p_ccb)3165 void l2cu_send_peer_ble_credit_based_disconn_req(tL2C_CCB *p_ccb)
3166 {
3167     BT_HDR  *p_buf;
3168     UINT8   *p;
3169     tL2C_LCB *p_lcb = NULL;
3170     L2CAP_TRACE_DEBUG ("%s",__func__);
3171 
3172     if (!p_ccb) {
3173         return;
3174     }
3175     p_lcb = p_ccb->p_lcb;
3176 
3177     /* Create an identifier for this packet */
3178     p_ccb->p_lcb->id++;
3179     l2cu_adj_id(p_ccb->p_lcb, L2CAP_ADJ_ID);
3180 
3181     p_ccb->local_id = p_ccb->p_lcb->id;
3182      if ((p_buf = l2cu_build_header (p_lcb, L2CAP_DISC_REQ_LEN,
3183                     L2CAP_CMD_DISC_REQ, p_lcb->id)) == NULL )
3184     {
3185         L2CAP_TRACE_WARNING ("l2cu_send_peer_ble_credit_based_disconn_req - no buffer");
3186         return;
3187     }
3188 
3189     p = (UINT8 *)(p_buf + 1) + L2CAP_SEND_CMD_OFFSET + HCI_DATA_PREAMBLE_SIZE +
3190                                L2CAP_PKT_OVERHEAD + L2CAP_CMD_OVERHEAD;
3191 
3192     UINT16_TO_STREAM (p, p_ccb->remote_cid);
3193     UINT16_TO_STREAM (p,p_ccb->local_cid);
3194 
3195     l2c_link_check_send_pkts (p_lcb, NULL, p_buf);
3196 }
3197 
3198 #endif /* BLE_INCLUDED == TRUE */
3199 
3200 /*******************************************************************************
3201 ** Functions used by both Full and Light Stack
3202 ********************************************************************************/
3203 
3204 /*******************************************************************************
3205 **
3206 ** Function         l2cu_find_lcb_by_handle
3207 **
3208 ** Description      Look through all active LCBs for a match based on the
3209 **                  HCI handle.
3210 **
3211 ** Returns          pointer to matched LCB, or NULL if no match
3212 **
3213 *******************************************************************************/
l2cu_find_lcb_by_handle(UINT16 handle)3214 tL2C_LCB  *l2cu_find_lcb_by_handle (UINT16 handle)
3215 {
3216     list_node_t *p_node = NULL;
3217     tL2C_LCB    *p_lcb  = NULL;
3218     for (p_node = list_begin(l2cb.p_lcb_pool); p_node; p_node = list_next(p_node)) {
3219         p_lcb = list_node(p_node);
3220         if ((p_lcb->in_use) && (p_lcb->handle == handle)) {
3221             return (p_lcb);
3222         }
3223     }
3224 
3225     /* If here, no match found */
3226     return (NULL);
3227 }
3228 
3229 /*******************************************************************************
3230 **
3231 ** Function         l2cu_find_ccb_by_cid
3232 **
3233 ** Description      Look through all active CCBs on a link for a match based
3234 **                  on the local CID. If passed the link pointer is NULL, all
3235 **                  active links are searched.
3236 **
3237 ** Returns          pointer to matched CCB, or NULL if no match
3238 **
3239 *******************************************************************************/
l2cu_find_ccb_in_list(void * p_ccb_node,void * p_local_cid)3240 bool l2cu_find_ccb_in_list(void *p_ccb_node, void *p_local_cid)
3241 {
3242     tL2C_CCB *p_ccb = (tL2C_CCB *)p_ccb_node;
3243     uint8_t local_cid = *((uint8_t *)p_local_cid);
3244 
3245     if (p_ccb->local_cid == local_cid && p_ccb->in_use) {
3246         return FALSE;
3247     }
3248     return TRUE;
3249 }
3250 
l2cu_find_ccb_by_cid(tL2C_LCB * p_lcb,UINT16 local_cid)3251 tL2C_CCB *l2cu_find_ccb_by_cid (tL2C_LCB *p_lcb, UINT16 local_cid)
3252 {
3253     tL2C_CCB    *p_ccb = NULL;
3254 #if (L2CAP_UCD_INCLUDED == FALSE)
3255     if (local_cid < L2CAP_BASE_APPL_CID) {
3256         return NULL;
3257     }
3258 #endif //(L2CAP_UCD_INCLUDED == FALSE)
3259     list_node_t *p_node = NULL;
3260 
3261     p_node = (list_foreach(l2cb.p_ccb_pool, l2cu_find_ccb_in_list, &local_cid));
3262     if (p_node) {
3263 	p_ccb = (tL2C_CCB *)list_node(p_node);
3264 
3265 	if (p_lcb && p_lcb != p_ccb->p_lcb) {
3266 	    p_ccb = NULL;
3267  	}
3268     }
3269 
3270     return (p_ccb);
3271 }
3272 
l2cu_find_free_ccb(void)3273 tL2C_CCB *l2cu_find_free_ccb (void)
3274 {
3275     tL2C_CCB    *p_ccb = NULL;
3276 
3277     list_node_t *p_node = NULL;
3278 
3279     for (p_node = list_begin(l2cb.p_ccb_pool); p_node; p_node = list_next(p_node))
3280     {
3281         p_ccb = list_node(p_node);
3282         if(p_ccb && !p_ccb->in_use ) {
3283             return p_ccb;
3284         }
3285     }
3286 
3287     return (NULL);
3288 }
3289 
3290 #if (L2CAP_ROUND_ROBIN_CHANNEL_SERVICE == TRUE && CLASSIC_BT_INCLUDED == TRUE)
3291 
3292 /******************************************************************************
3293 **
3294 ** Function         l2cu_get_next_channel_in_rr
3295 **
3296 ** Description      get the next channel to send on a link. It also adjusts the
3297 **                  CCB queue to do a basic priority and round-robin scheduling.
3298 **
3299 ** Returns          pointer to CCB or NULL
3300 **
3301 *******************************************************************************/
l2cu_get_next_channel_in_rr(tL2C_LCB * p_lcb)3302 static tL2C_CCB *l2cu_get_next_channel_in_rr(tL2C_LCB *p_lcb)
3303 {
3304     tL2C_CCB    *p_serve_ccb = NULL;
3305     tL2C_CCB    *p_ccb;
3306 
3307     int i, j;
3308 
3309     /* scan all of priority until finding a channel to serve */
3310     for ( i = 0; (i < L2CAP_NUM_CHNL_PRIORITY) && (!p_serve_ccb); i++ ) {
3311         /* scan all channel within serving priority group until finding a channel to serve */
3312         for ( j = 0; (j < p_lcb->rr_serv[p_lcb->rr_pri].num_ccb) && (!p_serve_ccb); j++) {
3313             /* scaning from next serving channel */
3314             p_ccb = p_lcb->rr_serv[p_lcb->rr_pri].p_serve_ccb;
3315 
3316             if (!p_ccb) {
3317                 L2CAP_TRACE_ERROR("p_serve_ccb is NULL, rr_pri=%d", p_lcb->rr_pri);
3318                 return NULL;
3319             }
3320 
3321             L2CAP_TRACE_DEBUG("RR scan pri=%d, lcid=0x%04x, q_cout=%d",
3322                               p_ccb->ccb_priority, p_ccb->local_cid,
3323                               fixed_queue_length(p_ccb->xmit_hold_q));
3324 
3325             /* store the next serving channel */
3326             /* this channel is the last channel of its priority group */
3327             if (( p_ccb->p_next_ccb == NULL )
3328                     || ( p_ccb->p_next_ccb->ccb_priority != p_ccb->ccb_priority )) {
3329                 /* next serving channel is set to the first channel in the group */
3330                 p_lcb->rr_serv[p_lcb->rr_pri].p_serve_ccb = p_lcb->rr_serv[p_lcb->rr_pri].p_first_ccb;
3331             } else {
3332                 /* next serving channel is set to the next channel in the group */
3333                 p_lcb->rr_serv[p_lcb->rr_pri].p_serve_ccb = p_ccb->p_next_ccb;
3334             }
3335 
3336             if (p_ccb->chnl_state != CST_OPEN) {
3337                 continue;
3338             }
3339 
3340             /* eL2CAP option in use */
3341             if (p_ccb->peer_cfg.fcr.mode != L2CAP_FCR_BASIC_MODE) {
3342                 if (p_ccb->fcrb.wait_ack || p_ccb->fcrb.remote_busy) {
3343                     continue;
3344                 }
3345 
3346                 if (fixed_queue_is_empty(p_ccb->fcrb.retrans_q)) {
3347                     if (fixed_queue_is_empty(p_ccb->xmit_hold_q)) {
3348                         continue;
3349                     }
3350 
3351 
3352 #if (CLASSIC_BT_INCLUDED == TRUE)
3353                     /* If in eRTM mode, check for window closure */
3354                     if ( (p_ccb->peer_cfg.fcr.mode == L2CAP_FCR_ERTM_MODE) && (l2c_fcr_is_flow_controlled (p_ccb)) ) {
3355                         continue;
3356                     }
3357 #endif  ///CLASSIC_BT_INCLUDED == TRUE
3358                 }
3359             } else {
3360                 if (fixed_queue_is_empty(p_ccb->xmit_hold_q)) {
3361                     continue;
3362                 }
3363             }
3364 
3365             /* found a channel to serve */
3366             p_serve_ccb = p_ccb;
3367             /* decrease quota of its priority group */
3368             p_lcb->rr_serv[p_lcb->rr_pri].quota--;
3369         }
3370 
3371         /* if there is no more quota of the priority group or no channel to have data to send */
3372         if ((p_lcb->rr_serv[p_lcb->rr_pri].quota == 0) || (!p_serve_ccb)) {
3373             /* serve next priority group */
3374             p_lcb->rr_pri = (p_lcb->rr_pri + 1) % L2CAP_NUM_CHNL_PRIORITY;
3375             /* initialize its quota */
3376             p_lcb->rr_serv[p_lcb->rr_pri].quota = L2CAP_GET_PRIORITY_QUOTA(p_lcb->rr_pri);
3377         }
3378     }
3379 
3380     if (p_serve_ccb) {
3381         L2CAP_TRACE_DEBUG("RR service pri=%d, quota=%d, lcid=0x%04x",
3382                           p_serve_ccb->ccb_priority,
3383                           p_lcb->rr_serv[p_serve_ccb->ccb_priority].quota,
3384                           p_serve_ccb->local_cid );
3385     }
3386 
3387     return p_serve_ccb;
3388 }
3389 
3390 #else /* (L2CAP_ROUND_ROBIN_CHANNEL_SERVICE == TRUE) */
3391 
3392 /******************************************************************************
3393 **
3394 ** Function         l2cu_get_next_channel
3395 **
3396 ** Description      get the next channel to send on a link bassed on priority
3397 **                  scheduling.
3398 **
3399 ** Returns          pointer to CCB or NULL
3400 **
3401 *******************************************************************************/
3402 #if (CLASSIC_BT_INCLUDED == TRUE)
l2cu_get_next_channel(tL2C_LCB * p_lcb)3403 static tL2C_CCB *l2cu_get_next_channel(tL2C_LCB *p_lcb)
3404 {
3405     tL2C_CCB    *p_ccb;
3406 
3407     /* Get the first CCB with data to send.
3408     */
3409     for (p_ccb = p_lcb->ccb_queue.p_first_ccb; p_ccb; p_ccb = p_ccb->p_next_ccb) {
3410         if (p_ccb->chnl_state != CST_OPEN) {
3411             continue;
3412         }
3413 
3414         if (p_ccb->fcrb.wait_ack || p_ccb->fcrb.remote_busy) {
3415             continue;
3416         }
3417 
3418         if (!fixed_queue_is_empty(p_ccb->fcrb.retrans_q))
3419             return p_ccb;
3420         }
3421 
3422         if (fixed_queue_is_empty(p_ccb->xmit_hold_q))
3423             continue;
3424         }
3425 
3426         /* If in eRTM mode, check for window closure */
3427         if ( (p_ccb->peer_cfg.fcr.mode == L2CAP_FCR_ERTM_MODE) && (l2c_fcr_is_flow_controlled (p_ccb)) ) {
3428             continue;
3429         }
3430 
3431         /* If here, we found someone */
3432         return p_ccb;
3433     }
3434 
3435     return NULL;
3436 }
3437 #endif  ///CLASSIC_BT_INCLUDED == TRUE
3438 
3439 #endif /* (L2CAP_ROUND_ROBIN_CHANNEL_SERVICE == TRUE) */
3440 
3441 /******************************************************************************
3442 **
3443 ** Function         l2cu_get_next_buffer_to_send
3444 **
3445 ** Description      get the next buffer to send on a link. It also adjusts the
3446 **                  CCB queue to do a basic priority and round-robin scheduling.
3447 **
3448 ** Returns          pointer to buffer or NULL
3449 **
3450 *******************************************************************************/
3451 BT_HDR *l2cu_get_next_buffer_to_send (tL2C_LCB *p_lcb)
3452 {
3453     tL2C_CCB    *p_ccb;
3454     BT_HDR      *p_buf = NULL;
3455 
3456     /* Highest priority are fixed channels */
3457 #if (L2CAP_NUM_FIXED_CHNLS > 0)
3458     int         xx;
3459 
3460     for (xx = 0; xx < L2CAP_NUM_FIXED_CHNLS; xx++) {
3461         if ((p_ccb = p_lcb->p_fixed_ccbs[xx]) == NULL) {
3462             continue;
3463         }
3464 
3465         /* eL2CAP option in use */
3466         if (p_ccb->peer_cfg.fcr.mode != L2CAP_FCR_BASIC_MODE) {
3467 #if (CLASSIC_BT_INCLUDED == TRUE)
3468             if (p_ccb->fcrb.wait_ack || p_ccb->fcrb.remote_busy) {
3469                 continue;
3470             }
3471 
3472             /* No more checks needed if sending from the reatransmit queue */
3473             if (fixed_queue_is_empty(p_ccb->fcrb.retrans_q))
3474             {
3475                 if (fixed_queue_is_empty(p_ccb->xmit_hold_q)) {
3476                     continue;
3477                 }
3478                 /* If in eRTM mode, check for window closure */
3479                 if ( (p_ccb->peer_cfg.fcr.mode == L2CAP_FCR_ERTM_MODE) && (l2c_fcr_is_flow_controlled (p_ccb)) ) {
3480                     continue;
3481                 }
3482             }
3483             if ((p_buf = l2c_fcr_get_next_xmit_sdu_seg(p_ccb, 0)) != NULL) {
3484                 l2cu_check_channel_congestion (p_ccb);
3485                 l2cu_set_acl_hci_header (p_buf, p_ccb);
3486                 return (p_buf);
3487             }
3488 #else
3489             continue;
3490 #endif  ///CLASSIC_BT_INCLUDED == TRUE
3491 
3492         } else {
3493             if (!fixed_queue_is_empty(p_ccb->xmit_hold_q)) {
3494                 p_buf = (BT_HDR *)fixed_queue_dequeue(p_ccb->xmit_hold_q, 0);
3495                 if (NULL == p_buf) {
3496                     L2CAP_TRACE_ERROR("l2cu_get_buffer_to_send: No data to be sent");
3497                     return (NULL);
3498                 }
3499                 l2cu_check_channel_congestion (p_ccb);
3500                 l2cu_set_acl_hci_header (p_buf, p_ccb);
3501                 /* send tx complete */
3502                 if (l2cb.fixed_reg[xx].pL2CA_FixedTxComplete_Cb) {
3503                     (*l2cb.fixed_reg[xx].pL2CA_FixedTxComplete_Cb)(p_ccb->local_cid, 1);
3504                 }
3505                 return (p_buf);
3506             }
3507         }
3508     }
3509 #endif
3510 #if (CLASSIC_BT_INCLUDED == TRUE)
3511 #if (L2CAP_ROUND_ROBIN_CHANNEL_SERVICE == TRUE)
3512     /* get next serving channel in round-robin */
3513     p_ccb  = l2cu_get_next_channel_in_rr( p_lcb );
3514 #else
3515     p_ccb  = l2cu_get_next_channel( p_lcb );
3516 #endif
3517 
3518     /* Return if no buffer */
3519     if (p_ccb == NULL) {
3520         return (NULL);
3521     }
3522 
3523     if (p_ccb->peer_cfg.fcr.mode != L2CAP_FCR_BASIC_MODE) {
3524 
3525         if ((p_buf = l2c_fcr_get_next_xmit_sdu_seg(p_ccb, 0)) == NULL) {
3526             return (NULL);
3527         }
3528 
3529     } else {
3530         p_buf = (BT_HDR *)fixed_queue_dequeue(p_ccb->xmit_hold_q, 0);
3531         if (NULL == p_buf) {
3532             L2CAP_TRACE_ERROR("l2cu_get_buffer_to_send() #2: No data to be sent");
3533             return (NULL);
3534         }
3535     }
3536 
3537     if ( p_ccb->p_rcb && p_ccb->p_rcb->api.pL2CA_TxComplete_Cb && (p_ccb->peer_cfg.fcr.mode != L2CAP_FCR_ERTM_MODE) ) {
3538         (*p_ccb->p_rcb->api.pL2CA_TxComplete_Cb)(p_ccb->local_cid, 1);
3539     }
3540 
3541 
3542     l2cu_check_channel_congestion (p_ccb);
3543 
3544     l2cu_set_acl_hci_header (p_buf, p_ccb);
3545 #endif  ///CLASSIC_BT_INCLUDED == TRUE
3546 
3547     return (p_buf);
3548 }
3549 
3550 /******************************************************************************
3551 **
3552 ** Function         l2cu_set_acl_hci_header
3553 **
3554 ** Description      Set HCI handle for ACL packet
3555 **
3556 ** Returns          None
3557 **
3558 *******************************************************************************/
3559 void l2cu_set_acl_hci_header (BT_HDR *p_buf, tL2C_CCB *p_ccb)
3560 {
3561     UINT8       *p;
3562 
3563     /* Set the pointer to the beginning of the data minus 4 bytes for the packet header */
3564     p = (UINT8 *)(p_buf + 1) + p_buf->offset - HCI_DATA_PREAMBLE_SIZE;
3565 
3566 #if (BLE_INCLUDED == TRUE)
3567     if (p_ccb->p_lcb->transport == BT_TRANSPORT_LE) {
3568         UINT16_TO_STREAM (p, p_ccb->p_lcb->handle | (L2CAP_PKT_START_NON_FLUSHABLE << L2CAP_PKT_TYPE_SHIFT));
3569 
3570         uint16_t acl_data_size = controller_get_interface()->get_acl_data_size_ble();
3571         /* The HCI transport will segment the buffers. */
3572         if (p_buf->len > acl_data_size) {
3573             UINT16_TO_STREAM (p, acl_data_size);
3574         } else {
3575             UINT16_TO_STREAM (p, p_buf->len);
3576         }
3577     } /* (BLE_INCLUDED == TRUE) */
3578     else
3579 #endif
3580     {
3581 #if (L2CAP_NON_FLUSHABLE_PB_INCLUDED == TRUE)
3582         if ( (((p_buf->layer_specific & L2CAP_FLUSHABLE_MASK) == L2CAP_FLUSHABLE_CH_BASED) && (p_ccb->is_flushable))
3583                 || ((p_buf->layer_specific & L2CAP_FLUSHABLE_MASK) == L2CAP_FLUSHABLE_PKT) ) {
3584             UINT16_TO_STREAM (p, p_ccb->p_lcb->handle | (L2CAP_PKT_START << L2CAP_PKT_TYPE_SHIFT));
3585         } else {
3586             UINT16_TO_STREAM (p, p_ccb->p_lcb->handle | l2cb.non_flushable_pbf);
3587         }
3588 #else
3589         UINT16_TO_STREAM (p, p_ccb->p_lcb->handle | (L2CAP_PKT_START << L2CAP_PKT_TYPE_SHIFT));
3590 #endif
3591 
3592         uint16_t acl_data_size = controller_get_interface()->get_acl_data_size_classic();
3593         /* The HCI transport will segment the buffers. */
3594         if (p_buf->len > acl_data_size) {
3595             UINT16_TO_STREAM (p, acl_data_size);
3596         } else {
3597             UINT16_TO_STREAM (p, p_buf->len);
3598         }
3599     }
3600     p_buf->offset -= HCI_DATA_PREAMBLE_SIZE;
3601     p_buf->len    += HCI_DATA_PREAMBLE_SIZE;
3602 }
3603 
3604 /******************************************************************************
3605 **
3606 ** Function         l2cu_check_channel_congestion
3607 **
3608 ** Description      check if any change in congestion status
3609 **
3610 ** Returns          None
3611 **
3612 *******************************************************************************/
3613 void l2cu_check_channel_congestion (tL2C_CCB *p_ccb)
3614 {
3615     size_t q_count = fixed_queue_length(p_ccb->xmit_hold_q);
3616 
3617 #if (L2CAP_UCD_INCLUDED == TRUE)
3618     if ( p_ccb->local_cid == L2CAP_CONNECTIONLESS_CID ) {
3619         q_count += fixed_queue_length(p_ccb->p_lcb->ucd_out_sec_pending_q);
3620     }
3621 #endif
3622     /* If the CCB queue limit is subject to a quota, check for congestion */
3623     /* if this channel has outgoing traffic */
3624     if (p_ccb->buff_quota != 0) {
3625         /* If this channel was congested */
3626         if ( p_ccb->cong_sent ) {
3627             /* If the channel is not congested now, tell the app */
3628             if (q_count <= (p_ccb->buff_quota / 2)) {
3629                 p_ccb->cong_sent = FALSE;
3630                 if (p_ccb->p_rcb && p_ccb->p_rcb->api.pL2CA_CongestionStatus_Cb) {
3631                     L2CAP_TRACE_DEBUG ("L2CAP - Calling CongestionStatus_Cb (FALSE), CID: 0x%04x  xmit_hold_q.count: %u  buff_quota: %u",
3632                                        p_ccb->local_cid, q_count, p_ccb->buff_quota);
3633 
3634                     /* Prevent recursive calling */
3635                     l2cb.is_cong_cback_context = TRUE;
3636                     (*p_ccb->p_rcb->api.pL2CA_CongestionStatus_Cb)(p_ccb->local_cid, FALSE);
3637                     l2cb.is_cong_cback_context = FALSE;
3638                 }
3639 #if (L2CAP_UCD_INCLUDED == TRUE)
3640                 else if ( p_ccb->p_rcb && p_ccb->local_cid == L2CAP_CONNECTIONLESS_CID ) {
3641                     if ( p_ccb->p_rcb->ucd.cb_info.pL2CA_UCD_Congestion_Status_Cb ) {
3642                         L2CAP_TRACE_DEBUG ("L2CAP - Calling UCD CongestionStatus_Cb (FALSE), SecPendingQ:%u,XmitQ:%u,Quota:%u",
3643                                            fixed_queue_length(p_ccb->p_lcb->ucd_out_sec_pending_q),
3644                                            fixed_queue_length(p_ccb->xmit_hold_q),
3645                                            p_ccb->buff_quota);
3646                         p_ccb->p_rcb->ucd.cb_info.pL2CA_UCD_Congestion_Status_Cb( p_ccb->p_lcb->remote_bd_addr, FALSE );
3647                     }
3648                 }
3649 #endif
3650 #if (L2CAP_NUM_FIXED_CHNLS > 0)
3651                 else {
3652                     UINT8 xx;
3653                     for (xx = 0; xx < L2CAP_NUM_FIXED_CHNLS; xx ++) {
3654                         if (p_ccb->p_lcb->p_fixed_ccbs[xx] == p_ccb) {
3655                             if (l2cb.fixed_reg[xx].pL2CA_FixedCong_Cb != NULL) {
3656                                 (* l2cb.fixed_reg[xx].pL2CA_FixedCong_Cb)(p_ccb->p_lcb->remote_bd_addr, FALSE);
3657                             }
3658                             break;
3659                         }
3660                     }
3661                 }
3662 #endif
3663             }
3664         } else {
3665             tL2C_LCB *p_lcb = p_ccb->p_lcb;
3666             /* If this channel was not congested but it is congested now, tell the app */
3667             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)) {
3668                 p_ccb->cong_sent = TRUE;
3669                 if (p_ccb->p_rcb && p_ccb->p_rcb->api.pL2CA_CongestionStatus_Cb) {
3670                     L2CAP_TRACE_DEBUG ("L2CAP - Calling CongestionStatus_Cb (TRUE),CID:0x%04x,XmitQ:%u,Quota:%u",
3671                                        p_ccb->local_cid, q_count, p_ccb->buff_quota);
3672 
3673                     (*p_ccb->p_rcb->api.pL2CA_CongestionStatus_Cb)(p_ccb->local_cid, TRUE);
3674                 }
3675 #if (L2CAP_UCD_INCLUDED == TRUE)
3676                 else if ( p_ccb->p_rcb && p_ccb->local_cid == L2CAP_CONNECTIONLESS_CID ) {
3677                     if ( p_ccb->p_rcb->ucd.cb_info.pL2CA_UCD_Congestion_Status_Cb ) {
3678                         L2CAP_TRACE_DEBUG ("L2CAP - Calling UCD CongestionStatus_Cb (TRUE), SecPendingQ:%u,XmitQ:%u,Quota:%u",
3679                                           fixed_queue_length(p_ccb->p_lcb->ucd_out_sec_pending_q),
3680                                           fixed_queue_length(p_ccb->xmit_hold_q),
3681                                           p_ccb->buff_quota);
3682                         p_ccb->p_rcb->ucd.cb_info.pL2CA_UCD_Congestion_Status_Cb( p_ccb->p_lcb->remote_bd_addr, TRUE );
3683                     }
3684                 }
3685 #endif
3686 #if (L2CAP_NUM_FIXED_CHNLS > 0)
3687                 else {
3688                     UINT8 xx;
3689                     for (xx = 0; xx < L2CAP_NUM_FIXED_CHNLS; xx ++) {
3690                         if (p_ccb->p_lcb->p_fixed_ccbs[xx] == p_ccb) {
3691                             if (l2cb.fixed_reg[xx].pL2CA_FixedCong_Cb != NULL) {
3692                                 (* l2cb.fixed_reg[xx].pL2CA_FixedCong_Cb)(p_ccb->p_lcb->remote_bd_addr, TRUE);
3693                             }
3694                             break;
3695                         }
3696                     }
3697                 }
3698 #endif
3699             }
3700         }
3701     }
3702 }
3703