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