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