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