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