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 the L2CAP UCD code
22  *
23  ******************************************************************************/
24 
25 #include <stdio.h>
26 #include <stdlib.h>
27 #include <string.h>
28 
29 #include "bt_common.h"
30 #include "bt_types.h"
31 #include "btm_api.h"
32 #include "btm_int.h"
33 #include "btu.h"
34 #include "hcidefs.h"
35 #include "hcimsgs.h"
36 #include "l2c_int.h"
37 #include "l2cdefs.h"
38 
39 #if (L2CAP_UCD_INCLUDED == TRUE)
40 
41 extern fixed_queue_t* btu_bta_alarm_queue;
42 
43 static bool l2c_ucd_connect(BD_ADDR rem_bda);
44 
45 /*******************************************************************************
46  *
47  * Function         l2c_ucd_discover_cback
48  *
49  * Description      UCD Discover callback
50  *
51  * Returns          void
52  *
53  ******************************************************************************/
l2c_ucd_discover_cback(BD_ADDR rem_bda,uint8_t info_type,uint32_t data)54 static void l2c_ucd_discover_cback(BD_ADDR rem_bda, uint8_t info_type,
55                                    uint32_t data) {
56   tL2C_RCB* p_rcb = &l2cb.rcb_pool[0];
57   uint16_t xx;
58 
59   L2CAP_TRACE_DEBUG("L2CAP - l2c_ucd_discover_cback");
60 
61   for (xx = 0; xx < MAX_L2CAP_CLIENTS; xx++, p_rcb++) {
62     if (p_rcb->in_use) {
63       /* if this application is waiting UCD reception info */
64       if ((info_type == L2CAP_UCD_INFO_TYPE_RECEPTION) &&
65           (p_rcb->ucd.state & L2C_UCD_STATE_W4_RECEPTION)) {
66         p_rcb->ucd.cb_info.pL2CA_UCD_Discover_Cb(rem_bda, info_type, data);
67         p_rcb->ucd.state &= ~(L2C_UCD_STATE_W4_RECEPTION);
68       }
69 
70       /* if this application is waiting UCD MTU info */
71       if ((info_type == L2CAP_UCD_INFO_TYPE_MTU) &&
72           (p_rcb->ucd.state & L2C_UCD_STATE_W4_MTU)) {
73         p_rcb->ucd.cb_info.pL2CA_UCD_Discover_Cb(rem_bda, info_type, data);
74         p_rcb->ucd.state &= ~(L2C_UCD_STATE_W4_MTU);
75       }
76     }
77   }
78 }
79 
80 /*******************************************************************************
81  *
82  * Function         l2c_ucd_data_ind_cback
83  *
84  * Description      UCD Data callback
85  *
86  * Returns          void
87  *
88  ******************************************************************************/
l2c_ucd_data_ind_cback(BD_ADDR rem_bda,BT_HDR * p_buf)89 static void l2c_ucd_data_ind_cback(BD_ADDR rem_bda, BT_HDR* p_buf) {
90   uint8_t* p;
91   uint16_t psm;
92   tL2C_RCB* p_rcb;
93 
94   L2CAP_TRACE_DEBUG("L2CAP - l2c_ucd_data_ind_cback");
95 
96   p = (uint8_t*)(p_buf + 1) + p_buf->offset;
97   STREAM_TO_UINT16(psm, p)
98 
99   p_buf->offset += L2CAP_UCD_OVERHEAD;
100   p_buf->len -= L2CAP_UCD_OVERHEAD;
101 
102   p_rcb = l2cu_find_rcb_by_psm(psm);
103   if (p_rcb == NULL) {
104     L2CAP_TRACE_ERROR("L2CAP - no RCB for l2c_ucd_data_ind_cback, PSM: 0x%04x",
105                       psm);
106     osi_free(p_buf);
107   } else {
108     p_rcb->ucd.cb_info.pL2CA_UCD_Data_Cb(rem_bda, p_buf);
109   }
110 }
111 
112 /*******************************************************************************
113  *
114  * Function         l2c_ucd_congestion_status_cback
115  *
116  * Description      UCD Congestion Status callback
117  *
118  * Returns          void
119  *
120  ******************************************************************************/
l2c_ucd_congestion_status_cback(BD_ADDR rem_bda,bool is_congested)121 static void l2c_ucd_congestion_status_cback(BD_ADDR rem_bda,
122                                             bool is_congested) {
123   tL2C_RCB* p_rcb = &l2cb.rcb_pool[0];
124   uint16_t xx;
125 
126   L2CAP_TRACE_DEBUG("L2CAP - l2c_ucd_congestion_status_cback");
127 
128   for (xx = 0; xx < MAX_L2CAP_CLIENTS; xx++, p_rcb++) {
129     if ((p_rcb->in_use) && (p_rcb->ucd.state != L2C_UCD_STATE_UNUSED)) {
130       if (p_rcb->ucd.cb_info.pL2CA_UCD_Congestion_Status_Cb) {
131         L2CAP_TRACE_DEBUG(
132             "L2CAP - Calling UCDCongestionStatus_Cb (%d), PSM=0x%04x, BDA: "
133             "%08x%04x,",
134             is_congested, p_rcb->psm, (rem_bda[0] << 24) + (rem_bda[1] << 16) +
135                                           (rem_bda[2] << 8) + rem_bda[3],
136             (rem_bda[4] << 8) + rem_bda[5]);
137 
138         p_rcb->ucd.cb_info.pL2CA_UCD_Congestion_Status_Cb(rem_bda,
139                                                           is_congested);
140       }
141     }
142   }
143 }
144 
145 /*******************************************************************************
146  *
147  * Function         l2c_ucd_disconnect_ind_cback
148  *
149  * Description      UCD disconnect callback (Prevent to access null pointer)
150  *
151  * Returns          void
152  *
153  ******************************************************************************/
l2c_ucd_disconnect_ind_cback(uint16_t cid,bool result)154 static void l2c_ucd_disconnect_ind_cback(uint16_t cid, bool result) {
155   /* do nothing */
156 }
157 
158 /*******************************************************************************
159  *
160  * Function         l2c_ucd_config_ind_cback
161  *
162  * Description      UCD config callback (This prevent to access null pointer)
163  *
164  * Returns          void
165  *
166  ******************************************************************************/
l2c_ucd_config_ind_cback(uint16_t cid,tL2CAP_CFG_INFO * p_cfg)167 static void l2c_ucd_config_ind_cback(uint16_t cid, tL2CAP_CFG_INFO* p_cfg) {
168   /* do nothing */
169 }
170 
171 /*******************************************************************************
172  *
173  * Function         l2c_ucd_config_cfm_cback
174  *
175  * Description      UCD config callback (This prevent to access null pointer)
176  *
177  * Returns          void
178  *
179  ******************************************************************************/
l2c_ucd_config_cfm_cback(uint16_t cid,tL2CAP_CFG_INFO * p_cfg)180 static void l2c_ucd_config_cfm_cback(uint16_t cid, tL2CAP_CFG_INFO* p_cfg) {
181   /* do nothing */
182 }
183 
184 /*******************************************************************************
185  *
186  *  Function        L2CA_UcdRegister
187  *
188  *  Description     Register PSM on UCD.
189  *
190  *  Parameters:     tL2CAP_UCD_CB_INFO
191  *
192  *  Return value:   true if successs
193  *
194  ******************************************************************************/
L2CA_UcdRegister(uint16_t psm,tL2CAP_UCD_CB_INFO * p_cb_info)195 bool L2CA_UcdRegister(uint16_t psm, tL2CAP_UCD_CB_INFO* p_cb_info) {
196   tL2C_RCB* p_rcb;
197 
198   L2CAP_TRACE_API("L2CA_UcdRegister()  PSM: 0x%04x", psm);
199 
200   if ((!p_cb_info->pL2CA_UCD_Discover_Cb) || (!p_cb_info->pL2CA_UCD_Data_Cb)) {
201     L2CAP_TRACE_ERROR("L2CAP - no callback registering PSM(0x%04x) on UCD",
202                       psm);
203     return (false);
204   }
205 
206   p_rcb = l2cu_find_rcb_by_psm(psm);
207   if (p_rcb == NULL) {
208     L2CAP_TRACE_ERROR("L2CAP - no RCB for L2CA_UcdRegister, PSM: 0x%04x", psm);
209     return (false);
210   }
211 
212   p_rcb->ucd.state = L2C_UCD_STATE_W4_DATA;
213   p_rcb->ucd.cb_info = *p_cb_info;
214 
215   /* check if master rcb is created for UCD */
216   p_rcb = l2cu_find_rcb_by_psm(L2C_UCD_RCB_ID);
217   if (p_rcb == NULL) {
218     p_rcb = l2cu_allocate_rcb(L2C_UCD_RCB_ID);
219     if (p_rcb == NULL) {
220       L2CAP_TRACE_ERROR("L2CAP - no RCB available for L2CA_UcdRegister");
221       return (false);
222     } else {
223       /* these callback functions will forward data to each UCD application */
224       p_rcb->ucd.cb_info.pL2CA_UCD_Discover_Cb = l2c_ucd_discover_cback;
225       p_rcb->ucd.cb_info.pL2CA_UCD_Data_Cb = l2c_ucd_data_ind_cback;
226       p_rcb->ucd.cb_info.pL2CA_UCD_Congestion_Status_Cb =
227           l2c_ucd_congestion_status_cback;
228 
229       memset(&p_rcb->api, 0, sizeof(tL2CAP_APPL_INFO));
230       p_rcb->api.pL2CA_DisconnectInd_Cb = l2c_ucd_disconnect_ind_cback;
231 
232       /* This will make L2CAP check UCD congestion callback */
233       p_rcb->api.pL2CA_CongestionStatus_Cb = NULL;
234 
235       /* do nothing but prevent crash */
236       p_rcb->api.pL2CA_ConfigInd_Cb = l2c_ucd_config_ind_cback;
237       p_rcb->api.pL2CA_ConfigCfm_Cb = l2c_ucd_config_cfm_cback;
238     }
239   }
240 
241   return (true);
242 }
243 
244 /*******************************************************************************
245  *
246  *  Function        L2CA_UcdDeregister
247  *
248  *  Description     Deregister PSM on UCD.
249  *
250  *  Parameters:     PSM
251  *
252  *  Return value:   true if successs
253  *
254  ******************************************************************************/
L2CA_UcdDeregister(uint16_t psm)255 bool L2CA_UcdDeregister(uint16_t psm) {
256   tL2C_CCB* p_ccb;
257   tL2C_RCB* p_rcb;
258   uint16_t xx;
259 
260   L2CAP_TRACE_API("L2CA_UcdDeregister()  PSM: 0x%04x", psm);
261 
262   p_rcb = l2cu_find_rcb_by_psm(psm);
263   if (p_rcb == NULL) {
264     L2CAP_TRACE_ERROR("L2CAP - no RCB for L2CA_UcdDeregister, PSM: 0x%04x",
265                       psm);
266     return (false);
267   }
268 
269   p_rcb->ucd.state = L2C_UCD_STATE_UNUSED;
270 
271   /* check this was the last UCD registration */
272   p_rcb = &l2cb.rcb_pool[0];
273 
274   for (xx = 0; xx < MAX_L2CAP_CLIENTS; xx++, p_rcb++) {
275     if ((p_rcb->in_use) && (p_rcb->ucd.state != L2C_UCD_STATE_UNUSED))
276       return (true);
277   }
278 
279   /* delete master rcb for UCD */
280   p_rcb = l2cu_find_rcb_by_psm(L2C_UCD_RCB_ID);
281   if (p_rcb != NULL) {
282     l2cu_release_rcb(p_rcb);
283   }
284 
285   /* delete CCB for UCD */
286   p_ccb = l2cb.ccb_pool;
287   for (xx = 0; xx < MAX_L2CAP_CHANNELS; xx++) {
288     if ((p_ccb->in_use) && (p_ccb->local_cid == L2CAP_CONNECTIONLESS_CID)) {
289       l2cu_release_ccb(p_ccb);
290     }
291     p_ccb++;
292   }
293 
294   return (true);
295 }
296 
297 /*******************************************************************************
298  *
299  *  Function        L2CA_UcdDiscover
300  *
301  *  Description     Discover UCD of remote device.
302  *
303  *  Parameters:     PSM
304  *                  BD_ADDR of remote device
305  *                  info_type : L2CAP_UCD_INFO_TYPE_RECEPTION
306  *                              L2CAP_UCD_INFO_TYPE_MTU
307  *
308  *
309  *  Return value:   true if successs
310  *
311  ******************************************************************************/
L2CA_UcdDiscover(uint16_t psm,BD_ADDR rem_bda,uint8_t info_type)312 bool L2CA_UcdDiscover(uint16_t psm, BD_ADDR rem_bda, uint8_t info_type) {
313   tL2C_LCB* p_lcb;
314   tL2C_CCB* p_ccb;
315   tL2C_RCB* p_rcb;
316 
317   L2CAP_TRACE_API(
318       "L2CA_UcdDiscover()  PSM: 0x%04x  BDA: %08x%04x, InfoType=0x%02x", psm,
319       (rem_bda[0] << 24) + (rem_bda[1] << 16) + (rem_bda[2] << 8) + rem_bda[3],
320       (rem_bda[4] << 8) + rem_bda[5], info_type);
321 
322   /* Fail if the PSM is not registered */
323   if (((p_rcb = l2cu_find_rcb_by_psm(psm)) == NULL) ||
324       (p_rcb->ucd.state == L2C_UCD_STATE_UNUSED)) {
325     L2CAP_TRACE_WARNING("L2CAP - no RCB for L2CA_UcdDiscover, PSM: 0x%04x",
326                         psm);
327     return (false);
328   }
329 
330   /* First, see if we already have a link to the remote */
331   /* then find the channel control block for UCD. */
332   if (((p_lcb = l2cu_find_lcb_by_bd_addr(rem_bda, BT_TRANSPORT_BR_EDR)) ==
333        NULL) ||
334       ((p_ccb = l2cu_find_ccb_by_cid(p_lcb, L2CAP_CONNECTIONLESS_CID)) ==
335        NULL)) {
336     if (l2c_ucd_connect(rem_bda) == false) {
337       return (false);
338     }
339   }
340 
341   /* set waiting flags in rcb */
342 
343   if (info_type & L2CAP_UCD_INFO_TYPE_RECEPTION)
344     p_rcb->ucd.state |= L2C_UCD_STATE_W4_RECEPTION;
345 
346   if (info_type & L2CAP_UCD_INFO_TYPE_MTU)
347     p_rcb->ucd.state |= L2C_UCD_STATE_W4_MTU;
348 
349   /* if link is already established */
350   if ((p_lcb) && (p_lcb->link_state == LST_CONNECTED)) {
351     if (!p_ccb) {
352       p_ccb = l2cu_find_ccb_by_cid(p_lcb, L2CAP_CONNECTIONLESS_CID);
353     }
354     l2c_ucd_check_pending_info_req(p_ccb);
355   }
356   return (true);
357 }
358 
359 /*******************************************************************************
360  *
361  *  Function        L2CA_UcdDataWrite
362  *
363  *  Description     Send UCD to remote device
364  *
365  *  Parameters:     PSM
366  *                  BD Address of remote
367  *                  Pointer to buffer of type BT_HDR
368  *                  flags : L2CAP_FLUSHABLE_CH_BASED
369  *                          L2CAP_FLUSHABLE_PKT
370  *                          L2CAP_NON_FLUSHABLE_PKT
371  *
372  * Return value     L2CAP_DW_SUCCESS, if data accepted
373  *                  L2CAP_DW_FAILED,  if error
374  *
375  ******************************************************************************/
L2CA_UcdDataWrite(uint16_t psm,BD_ADDR rem_bda,BT_HDR * p_buf,uint16_t flags)376 uint16_t L2CA_UcdDataWrite(uint16_t psm, BD_ADDR rem_bda, BT_HDR* p_buf,
377                            uint16_t flags) {
378   tL2C_LCB* p_lcb;
379   tL2C_CCB* p_ccb;
380   tL2C_RCB* p_rcb;
381   uint8_t* p;
382 
383   L2CAP_TRACE_API(
384       "L2CA_UcdDataWrite()  PSM: 0x%04x  BDA: %08x%04x", psm,
385       (rem_bda[0] << 24) + (rem_bda[1] << 16) + (rem_bda[2] << 8) + rem_bda[3],
386       (rem_bda[4] << 8) + rem_bda[5]);
387 
388   /* Fail if the PSM is not registered */
389   if (((p_rcb = l2cu_find_rcb_by_psm(psm)) == NULL) ||
390       (p_rcb->ucd.state == L2C_UCD_STATE_UNUSED)) {
391     L2CAP_TRACE_WARNING("L2CAP - no RCB for L2CA_UcdDataWrite, PSM: 0x%04x",
392                         psm);
393     osi_free(p_buf);
394     return (L2CAP_DW_FAILED);
395   }
396 
397   /* First, see if we already have a link to the remote */
398   /*  then find the channel control block for UCD */
399   if (((p_lcb = l2cu_find_lcb_by_bd_addr(rem_bda, BT_TRANSPORT_BR_EDR)) ==
400        NULL) ||
401       ((p_ccb = l2cu_find_ccb_by_cid(p_lcb, L2CAP_CONNECTIONLESS_CID)) ==
402        NULL)) {
403     if (l2c_ucd_connect(rem_bda) == false) {
404       osi_free(p_buf);
405       return (L2CAP_DW_FAILED);
406     }
407 
408     /* If we still don't have lcb and ccb after connect attempt, then can't
409      * proceed */
410     if (((p_lcb = l2cu_find_lcb_by_bd_addr(rem_bda, BT_TRANSPORT_BR_EDR)) ==
411          NULL) ||
412         ((p_ccb = l2cu_find_ccb_by_cid(p_lcb, L2CAP_CONNECTIONLESS_CID)) ==
413          NULL)) {
414       osi_free(p_buf);
415       return (L2CAP_DW_FAILED);
416     }
417   }
418 
419   /* write PSM */
420   p_buf->offset -= L2CAP_UCD_OVERHEAD;
421   p_buf->len += L2CAP_UCD_OVERHEAD;
422   p = (uint8_t*)(p_buf + 1) + p_buf->offset;
423 
424   UINT16_TO_STREAM(p, psm);
425 
426   /* UCD MTU check */
427   if ((p_lcb->ucd_mtu) && (p_buf->len > p_lcb->ucd_mtu)) {
428     L2CAP_TRACE_WARNING(
429         "L2CAP - Handle: 0x%04x  UCD bigger than peer's UCD mtu size cannot be "
430         "sent",
431         p_lcb->handle);
432     osi_free(p_buf);
433     return (L2CAP_DW_FAILED);
434   }
435 
436   /* If already congested, do not accept any more packets */
437   if (p_ccb->cong_sent) {
438     L2CAP_TRACE_ERROR(
439         "L2CAP - Handle: 0x%04x UCD cannot be sent, already congested count: "
440         "%u  buff_quota: %u",
441         p_lcb->handle, (fixed_queue_length(p_ccb->xmit_hold_q) +
442                         fixed_queue_length(p_lcb->ucd_out_sec_pending_q)),
443         p_ccb->buff_quota);
444 
445     osi_free(p_buf);
446     return (L2CAP_DW_FAILED);
447   }
448 
449   /* channel based, packet based flushable or non-flushable */
450   p_buf->layer_specific = flags;
451 
452   l2c_csm_execute(p_ccb, L2CEVT_L2CA_DATA_WRITE, p_buf);
453 
454   if (p_ccb->cong_sent)
455     return (L2CAP_DW_CONGESTED);
456   else
457     return (L2CAP_DW_SUCCESS);
458 }
459 
460 /*******************************************************************************
461  *
462  *  Function        L2CA_UcdSetIdleTimeout
463  *
464  *  Description     Set UCD Idle timeout.
465  *
466  *  Parameters:     BD Addr
467  *                  Timeout in second
468  *
469  *  Return value:   true if successs
470  *
471  ******************************************************************************/
L2CA_UcdSetIdleTimeout(BD_ADDR rem_bda,uint16_t timeout)472 bool L2CA_UcdSetIdleTimeout(BD_ADDR rem_bda, uint16_t timeout) {
473   tL2C_LCB* p_lcb;
474   tL2C_CCB* p_ccb;
475 
476   L2CAP_TRACE_API(
477       "L2CA_UcdSetIdleTimeout()  Timeout: 0x%04x  BDA: %08x%04x", timeout,
478       (rem_bda[0] << 24) + (rem_bda[1] << 16) + (rem_bda[2] << 8) + rem_bda[3],
479       (rem_bda[4] << 8) + rem_bda[5]);
480 
481   /* First, see if we already have a link to the remote */
482   /* then find the channel control block. */
483   if (((p_lcb = l2cu_find_lcb_by_bd_addr(rem_bda, BT_TRANSPORT_BR_EDR)) ==
484        NULL) ||
485       ((p_ccb = l2cu_find_ccb_by_cid(p_lcb, L2CAP_CONNECTIONLESS_CID)) ==
486        NULL)) {
487     L2CAP_TRACE_WARNING("L2CAP - no UCD channel");
488     return (false);
489   } else {
490     p_ccb->fixed_chnl_idle_tout = timeout;
491     return (true);
492   }
493 }
494 
495 /*******************************************************************************
496  *
497  * Function         L2CA_UCDSetTxPriority
498  *
499  * Description      Sets the transmission priority for a connectionless channel.
500  *
501  * Returns          true if a valid channel, else false
502  *
503  ******************************************************************************/
L2CA_UCDSetTxPriority(BD_ADDR rem_bda,tL2CAP_CHNL_PRIORITY priority)504 bool L2CA_UCDSetTxPriority(BD_ADDR rem_bda, tL2CAP_CHNL_PRIORITY priority) {
505   tL2C_LCB* p_lcb;
506   tL2C_CCB* p_ccb;
507 
508   L2CAP_TRACE_API(
509       "L2CA_UCDSetTxPriority()  priority: 0x%02x  BDA: %08x%04x", priority,
510       (rem_bda[0] << 24) + (rem_bda[1] << 16) + (rem_bda[2] << 8) + rem_bda[3],
511       (rem_bda[4] << 8) + rem_bda[5]);
512 
513   p_lcb = l2cu_find_lcb_by_bd_addr(rem_bda, BT_TRANSPORT_BR_EDR);
514   if (p_lcb == NULL) {
515     L2CAP_TRACE_WARNING("L2CAP - no LCB for L2CA_UCDSetTxPriority");
516     return (false);
517   }
518 
519   /* Find the channel control block */
520   p_ccb = l2cu_find_ccb_by_cid(p_lcb, L2CAP_CONNECTIONLESS_CID);
521   if (p_ccb == NULL) {
522     L2CAP_TRACE_WARNING("L2CAP - no CCB for L2CA_UCDSetTxPriority");
523     return (false);
524   }
525 
526   /* it will update the order of CCB in LCB by priority and update round robin
527    * service variables */
528   l2cu_change_pri_ccb(p_ccb, priority);
529 
530   return (true);
531 }
532 
533 /*******************************************************************************
534  *
535  *  Function        l2c_ucd_connect
536  *
537  *  Description     Connect UCD to remote device.
538  *
539  *  Parameters:     BD_ADDR of remote device
540  *
541  *  Return value:   true if successs
542  *
543  ******************************************************************************/
l2c_ucd_connect(BD_ADDR rem_bda)544 static bool l2c_ucd_connect(BD_ADDR rem_bda) {
545   tL2C_LCB* p_lcb;
546   tL2C_CCB* p_ccb;
547   tL2C_RCB* p_rcb;
548 
549   L2CAP_TRACE_DEBUG(
550       "l2c_ucd_connect()  BDA: %08x%04x",
551       (rem_bda[0] << 24) + (rem_bda[1] << 16) + (rem_bda[2] << 8) + rem_bda[3],
552       (rem_bda[4] << 8) + rem_bda[5]);
553 
554   /* Fail if we have not established communications with the controller */
555   if (!BTM_IsDeviceUp()) {
556     L2CAP_TRACE_WARNING("l2c_ucd_connect - BTU not ready");
557     return (false);
558   }
559 
560   /* First, see if we already have a link to the remote */
561   p_lcb = l2cu_find_lcb_by_bd_addr(rem_bda, BT_TRANSPORT_BR_EDR);
562   if (p_lcb == NULL) {
563     /* No link. Get an LCB and start link establishment */
564     if (((p_lcb = l2cu_allocate_lcb(rem_bda, false, BT_TRANSPORT_BR_EDR)) ==
565          NULL) ||
566         (l2cu_create_conn(p_lcb, BT_TRANSPORT_BR_EDR) == false)) {
567       L2CAP_TRACE_WARNING("L2CAP - conn not started l2c_ucd_connect");
568       return (false);
569     }
570   } else if (p_lcb->info_rx_bits & (1 << L2CAP_EXTENDED_FEATURES_INFO_TYPE)) {
571     if (!(p_lcb->peer_ext_fea & L2CAP_EXTFEA_UCD_RECEPTION)) {
572       L2CAP_TRACE_WARNING(
573           "L2CAP - UCD is not supported by peer, l2c_ucd_connect");
574       return (false);
575     }
576   }
577 
578   /* Find the channel control block. */
579   p_ccb = l2cu_find_ccb_by_cid(p_lcb, L2CAP_CONNECTIONLESS_CID);
580   if (p_ccb == NULL) {
581     /* Allocate a channel control block */
582     p_ccb = l2cu_allocate_ccb(p_lcb, 0);
583     if (p_ccb == NULL) {
584       L2CAP_TRACE_WARNING("L2CAP - no CCB for l2c_ucd_connect");
585       return (false);
586     } else {
587       /* Set CID for the connection */
588       p_ccb->local_cid = L2CAP_CONNECTIONLESS_CID;
589       p_ccb->remote_cid = L2CAP_CONNECTIONLESS_CID;
590 
591       /* Set the default idle timeout value to use */
592       p_ccb->fixed_chnl_idle_tout = L2CAP_UCD_IDLE_TIMEOUT;
593 
594       /* Set the default channel priority value to use */
595       l2cu_change_pri_ccb(p_ccb, L2CAP_UCD_CH_PRIORITY);
596 
597       p_rcb = l2cu_find_rcb_by_psm(L2C_UCD_RCB_ID);
598       if (p_rcb == NULL) {
599         L2CAP_TRACE_WARNING("L2CAP - no UCD registered, l2c_ucd_connect");
600         return (false);
601       }
602       /* Save UCD registration info */
603       p_ccb->p_rcb = p_rcb;
604 
605       /* There is no configuration, so if the link is up, the channel is up */
606       if (p_lcb->link_state == LST_CONNECTED) {
607         p_ccb->chnl_state = CST_OPEN;
608       }
609     }
610   }
611 
612   return (true);
613 }
614 
615 /*******************************************************************************
616  *
617  *  Function        l2c_ucd_delete_sec_pending_q
618  *
619  * Description      discard all of UCD packets in security pending queue
620  *
621  * Returns          None
622  *
623  ******************************************************************************/
l2c_ucd_delete_sec_pending_q(tL2C_LCB * p_lcb)624 void l2c_ucd_delete_sec_pending_q(tL2C_LCB* p_lcb) {
625   /* clean up any security pending UCD */
626   while (!fixed_queue_is_empty(p_lcb->ucd_out_sec_pending_q))
627     osi_free(fixed_queue_try_dequeue(p_lcb->ucd_out_sec_pending_q));
628   fixed_queue_free(p_lcb->ucd_out_sec_pending_q, NULL);
629   p_lcb->ucd_out_sec_pending_q = NULL;
630 
631   while (!fixed_queue_is_empty(p_lcb->ucd_in_sec_pending_q))
632     osi_free(fixed_queue_try_dequeue(p_lcb->ucd_in_sec_pending_q));
633   fixed_queue_free(p_lcb->ucd_in_sec_pending_q);
634   p_lcb->ucd_in_sec_pending_q = NULL;
635 }
636 
637 /*******************************************************************************
638  *
639  *  Function        l2c_ucd_check_pending_info_req
640  *
641  * Description      check if any application is waiting for UCD information
642  *
643  *  Return          true if any pending UCD info request
644  *
645  ******************************************************************************/
l2c_ucd_check_pending_info_req(tL2C_CCB * p_ccb)646 bool l2c_ucd_check_pending_info_req(tL2C_CCB* p_ccb) {
647   tL2C_RCB* p_rcb = &l2cb.rcb_pool[0];
648   uint16_t xx;
649   bool pending = false;
650 
651   if (p_ccb == NULL) {
652     L2CAP_TRACE_ERROR("L2CAP - NULL p_ccb in l2c_ucd_check_pending_info_req");
653     return (false);
654   }
655 
656   for (xx = 0; xx < MAX_L2CAP_CLIENTS; xx++, p_rcb++) {
657     if (p_rcb->in_use) {
658       /* if application is waiting UCD reception info */
659       if (p_rcb->ucd.state & L2C_UCD_STATE_W4_RECEPTION) {
660         /* if this information is available */
661         if (p_ccb->p_lcb->info_rx_bits &
662             (1 << L2CAP_EXTENDED_FEATURES_INFO_TYPE)) {
663           if (!(p_ccb->p_lcb->peer_ext_fea & L2CAP_EXTFEA_UCD_RECEPTION)) {
664             L2CAP_TRACE_WARNING(
665                 "L2CAP - UCD is not supported by peer, "
666                 "l2c_ucd_check_pending_info_req");
667 
668             l2c_ucd_delete_sec_pending_q(p_ccb->p_lcb);
669             l2cu_release_ccb(p_ccb);
670           }
671 
672           p_ccb->p_rcb->ucd.cb_info.pL2CA_UCD_Discover_Cb(
673               p_ccb->p_lcb->remote_bd_addr, L2CAP_UCD_INFO_TYPE_RECEPTION,
674               p_ccb->p_lcb->peer_ext_fea & L2CAP_EXTFEA_UCD_RECEPTION);
675         } else {
676           pending = true;
677           if (p_ccb->p_lcb->w4_info_rsp == false) {
678             l2cu_send_peer_info_req(p_ccb->p_lcb,
679                                     L2CAP_EXTENDED_FEATURES_INFO_TYPE);
680           }
681         }
682       }
683 
684       /* if application is waiting for UCD MTU */
685       if (p_rcb->ucd.state & L2C_UCD_STATE_W4_MTU) {
686         /* if this information is available */
687         if (p_ccb->p_lcb->info_rx_bits & (1 << L2CAP_CONNLESS_MTU_INFO_TYPE)) {
688           p_ccb->p_rcb->ucd.cb_info.pL2CA_UCD_Discover_Cb(
689               p_ccb->p_lcb->remote_bd_addr, L2CAP_UCD_INFO_TYPE_MTU,
690               p_ccb->p_lcb->ucd_mtu);
691         } else {
692           pending = true;
693           if (p_ccb->p_lcb->w4_info_rsp == false) {
694             l2cu_send_peer_info_req(p_ccb->p_lcb, L2CAP_CONNLESS_MTU_INFO_TYPE);
695           }
696         }
697       }
698     }
699   }
700   return (pending);
701 }
702 
703 /*******************************************************************************
704  *
705  *  Function        l2c_ucd_enqueue_pending_out_sec_q
706  *
707  *  Description     enqueue outgoing UCD packet into security pending queue
708  *                  and check congestion
709  *
710  *  Return          None
711  *
712  ******************************************************************************/
l2c_ucd_enqueue_pending_out_sec_q(tL2C_CCB * p_ccb,void * p_data)713 void l2c_ucd_enqueue_pending_out_sec_q(tL2C_CCB* p_ccb, void* p_data) {
714   fixed_queue_enqueue(p_ccb->p_lcb->ucd_out_sec_pending_q, p_data);
715   l2cu_check_channel_congestion(p_ccb);
716 }
717 
718 /*******************************************************************************
719  *
720  *  Function        l2c_ucd_check_pending_out_sec_q
721  *
722  *  Description     check outgoing security
723  *
724  *  Return          true if any UCD packet for security
725  *
726  ******************************************************************************/
l2c_ucd_check_pending_out_sec_q(tL2C_CCB * p_ccb)727 bool l2c_ucd_check_pending_out_sec_q(tL2C_CCB* p_ccb) {
728   BT_HDR* p_buf =
729       (BT_HDR*)fixed_queue_try_peek_first(p_ccb->p_lcb->ucd_out_sec_pending_q);
730 
731   if (p_buf != NULL) {
732     uint16_t psm;
733     uint8_t* p = (uint8_t*)(p_buf + 1) + p_buf->offset;
734 
735     STREAM_TO_UINT16(psm, p)
736 
737     p_ccb->chnl_state = CST_ORIG_W4_SEC_COMP;
738     btm_sec_l2cap_access_req(p_ccb->p_lcb->remote_bd_addr, psm,
739                              p_ccb->p_lcb->handle, CONNLESS_ORIG,
740                              &l2c_link_sec_comp, p_ccb);
741 
742     return (true);
743   }
744   return (false);
745 }
746 
747 /*******************************************************************************
748  *
749  *  Function        l2c_ucd_send_pending_out_sec_q
750  *
751  *  Description     dequeue UCD packet from security pending queue and
752  *                  enqueue it into CCB
753  *
754  *  Return          None
755  *
756  ******************************************************************************/
l2c_ucd_send_pending_out_sec_q(tL2C_CCB * p_ccb)757 void l2c_ucd_send_pending_out_sec_q(tL2C_CCB* p_ccb) {
758   BT_HDR* p_buf =
759       (BT_HDR*)fixed_queue_try_dequeue(p_ccb->p_lcb->ucd_out_sec_pending_q);
760 
761   if (p_buf != NULL) {
762     l2c_enqueue_peer_data(p_ccb, (BT_HDR*)p_buf);
763     l2c_link_check_send_pkts(p_ccb->p_lcb, NULL, NULL);
764   }
765 }
766 
767 /*******************************************************************************
768  *
769  *  Function        l2c_ucd_discard_pending_out_sec_q
770  *
771  *  Description     dequeue UCD packet from security pending queue and
772  *                  discard it.
773  *
774  *  Return          None
775  *
776  ******************************************************************************/
l2c_ucd_discard_pending_out_sec_q(tL2C_CCB * p_ccb)777 void l2c_ucd_discard_pending_out_sec_q(tL2C_CCB* p_ccb) {
778   BT_HDR* p_buf =
779       (BT_HDR*)fixed_queue_try_dequeue(p_ccb->p_lcb->ucd_out_sec_pending_q);
780 
781   /* we may need to report to application */
782   osi_free(p_buf);
783 }
784 
785 /*******************************************************************************
786  *
787  *  Function        l2c_ucd_check_pending_in_sec_q
788  *
789  *  Description     check incoming security
790  *
791  *  Return          true if any UCD packet for security
792  *
793  ******************************************************************************/
l2c_ucd_check_pending_in_sec_q(tL2C_CCB * p_ccb)794 bool l2c_ucd_check_pending_in_sec_q(tL2C_CCB* p_ccb) {
795   BT_HDR* p_buf =
796       (BT_HDR*)fixed_queue_try_dequeue(p_ccb->p_lcb->ucd_in_sec_pending_q);
797 
798   if (p_buf != NULL) {
799     uint16_t psm;
800     uint8_t* p = (uint8_t*)(p_buf + 1) + p_buf->offset;
801     STREAM_TO_UINT16(psm, p)
802 
803     p_ccb->chnl_state = CST_TERM_W4_SEC_COMP;
804     btm_sec_l2cap_access_req(p_ccb->p_lcb->remote_bd_addr, psm,
805                              p_ccb->p_lcb->handle, CONNLESS_TERM,
806                              &l2c_link_sec_comp, p_ccb);
807 
808     return (true);
809   }
810   return (false);
811 }
812 
813 /*******************************************************************************
814  *
815  *  Function        l2c_ucd_send_pending_in_sec_q
816  *
817  *  Description     dequeue UCD packet from security pending queue and
818  *                  send it to application
819  *
820  *  Return          None
821  *
822  ******************************************************************************/
l2c_ucd_send_pending_in_sec_q(tL2C_CCB * p_ccb)823 void l2c_ucd_send_pending_in_sec_q(tL2C_CCB* p_ccb) {
824   BT_HDR* p_buf =
825       (BT_HDR*)fixed_queue_try_dequeue(p_ccb->p_lcb->ucd_in_sec_pending_q)
826 
827           if (p_buf != NULL) {
828     p_ccb->p_rcb->ucd.cb_info.pL2CA_UCD_Data_Cb(p_ccb->p_lcb->remote_bd_addr,
829                                                 (BT_HDR*)p_buf);
830   }
831 }
832 
833 /*******************************************************************************
834  *
835  *  Function        l2c_ucd_discard_pending_in_sec_q
836  *
837  *  Description     dequeue UCD packet from security pending queue and
838  *                  discard it.
839  *
840  *  Return          None
841  *
842  ******************************************************************************/
l2c_ucd_discard_pending_in_sec_q(tL2C_CCB * p_ccb)843 void l2c_ucd_discard_pending_in_sec_q(tL2C_CCB* p_ccb) {
844   BT_HDR* p_buf =
845       (BT_HDR*)fixed_queue_try_dequeue(p_ccb->p_lcb->ucd_in_sec_pending_q);
846   osi_free(p_buf);
847 }
848 
849 /*******************************************************************************
850  *
851  *  Function        l2c_ucd_check_rx_pkts
852  *
853  *  Description     Check if UCD reception is registered.
854  *                  Process received UCD packet if application is expecting.
855  *
856  *  Return          true if UCD reception is registered
857  *
858  ******************************************************************************/
l2c_ucd_check_rx_pkts(tL2C_LCB * p_lcb,BT_HDR * p_msg)859 bool l2c_ucd_check_rx_pkts(tL2C_LCB* p_lcb, BT_HDR* p_msg) {
860   tL2C_CCB* p_ccb;
861   tL2C_RCB* p_rcb;
862 
863   if (((p_ccb = l2cu_find_ccb_by_cid(p_lcb, L2CAP_CONNECTIONLESS_CID)) !=
864        NULL) ||
865       ((p_rcb = l2cu_find_rcb_by_psm(L2C_UCD_RCB_ID)) != NULL)) {
866     if (p_ccb == NULL) {
867       /* Allocate a channel control block */
868       p_ccb = l2cu_allocate_ccb(p_lcb, 0);
869       if (p_ccb == NULL) {
870         L2CAP_TRACE_WARNING("L2CAP - no CCB for UCD reception");
871         osi_free(p_msg);
872         return true;
873       } else {
874         /* Set CID for the connection */
875         p_ccb->local_cid = L2CAP_CONNECTIONLESS_CID;
876         p_ccb->remote_cid = L2CAP_CONNECTIONLESS_CID;
877 
878         /* Set the default idle timeout value to use */
879         p_ccb->fixed_chnl_idle_tout = L2CAP_UCD_IDLE_TIMEOUT;
880 
881         /* Set the default channel priority value to use */
882         l2cu_change_pri_ccb(p_ccb, L2CAP_UCD_CH_PRIORITY);
883 
884         /* Save registration info */
885         p_ccb->p_rcb = p_rcb;
886 
887         p_ccb->chnl_state = CST_OPEN;
888       }
889     }
890     l2c_csm_execute(p_ccb, L2CEVT_L2CAP_DATA, p_msg);
891     return true;
892   } else
893     return false;
894 }
895 
896 /*******************************************************************************
897  *
898  *  Function        l2c_ucd_process_event
899  *
900  *  Description     This is called from main state machine when LCID is
901  *                  connectionless. Process the event if it is for UCD.
902  *
903  *  Return          true if the event is consumed by UCD
904  *                  false if the event needs to be processed by the main state
905  *                        machine
906  *
907  ******************************************************************************/
l2c_ucd_process_event(tL2C_CCB * p_ccb,uint16_t event,void * p_data)908 bool l2c_ucd_process_event(tL2C_CCB* p_ccb, uint16_t event, void* p_data) {
909   /* if the event is not processed by this function, this variable will be set
910    * to false */
911   bool done = true;
912 
913   switch (p_ccb->chnl_state) {
914     case CST_CLOSED:
915       switch (event) {
916         case L2CEVT_LP_CONNECT_CFM: /* Link came up         */
917           /* check if waiting for UCD info */
918           if (!l2c_ucd_check_pending_info_req(p_ccb)) {
919             /* check if any outgoing UCD packet is waiting security check */
920             if (!l2c_ucd_check_pending_out_sec_q(p_ccb)) {
921               p_ccb->chnl_state = CST_OPEN;
922             }
923           }
924           break;
925 
926         case L2CEVT_L2CAP_DATA: /* Peer data packet rcvd    */
927           fixed_queue_enqueue(p_ccb->p_lcb->ucd_in_sec_pending_q, p_data);
928           break;
929 
930         case L2CEVT_L2CA_DATA_WRITE: /* Upper layer data to send */
931           l2c_ucd_enqueue_pending_out_sec_q(p_ccb, p_data);
932           break;
933 
934         case L2CEVT_L2CAP_INFO_RSP:
935           /* check if waiting for UCD info */
936           if (!l2c_ucd_check_pending_info_req(p_ccb)) {
937             /* check if any outgoing UCD packet is waiting security check */
938             if (!l2c_ucd_check_pending_out_sec_q(p_ccb)) {
939               p_ccb->chnl_state = CST_OPEN;
940             }
941           }
942           break;
943 
944         default:
945           done = false; /* main state machine continues to process event */
946           break;
947       }
948       break;
949 
950     case CST_ORIG_W4_SEC_COMP:
951       switch (event) {
952         case L2CEVT_SEC_RE_SEND_CMD: /* BTM has enough info to proceed */
953           /* check if any outgoing UCD packet is waiting security check */
954           if (!l2c_ucd_check_pending_out_sec_q(p_ccb)) {
955             p_ccb->chnl_state = CST_OPEN;
956           }
957           break;
958 
959         case L2CEVT_SEC_COMP: /* Security completed success */
960           p_ccb->chnl_state = CST_OPEN;
961           l2c_ucd_send_pending_out_sec_q(p_ccb);
962 
963           if (!fixed_queue_is_empty(p_ccb->p_lcb->ucd_out_sec_pending_q)) {
964             /* start a timer to send next UCD packet in OPEN state */
965             /* it will prevent stack overflow */
966             alarm_set_on_queue(p_ccb->l2c_ccb_timer, 0, l2c_ccb_timer_timeout,
967                                p_ccb, btu_general_alarm_queue);
968           } else {
969             /* start a timer for idle timeout of UCD */
970             period_ms_t timeout_ms = p_ccb->fixed_chnl_idle_tout * 1000;
971             alarm_set_on_queue(p_ccb->l2c_ccb_timer, timeout_ms,
972                                l2c_ccb_timer_timeout, p_ccb,
973                                btu_general_alarm_queue);
974           }
975           break;
976 
977         case L2CEVT_SEC_COMP_NEG:
978           p_ccb->chnl_state = CST_OPEN;
979           l2c_ucd_discard_pending_out_sec_q(p_ccb);
980 
981           /* start a timer for idle timeout of UCD */
982           period_ms_t timeout_ms = p_ccb->fixed_chnl_idle_tout * 1000;
983           alarm_set_on_queue(p_ccb->l2c_ccb_timer, timeout_ms,
984                              l2c_ccb_timer_timeout, p_ccb,
985                              btu_general_alarm_queue);
986           break;
987 
988         case L2CEVT_L2CA_DATA_WRITE: /* Upper layer data to send */
989           l2c_ucd_enqueue_pending_out_sec_q(p_ccb, p_data);
990           break;
991 
992         case L2CEVT_L2CAP_DATA: /* Peer data packet rcvd    */
993           fixed_queue_enqueue(p_ccb->p_lcb->ucd_in_sec_pending_q, p_data);
994           break;
995 
996         case L2CEVT_L2CAP_INFO_RSP:
997           /* check if waiting for UCD info */
998           l2c_ucd_check_pending_info_req(p_ccb);
999           break;
1000 
1001         default:
1002           done = false; /* main state machine continues to process event */
1003           break;
1004       }
1005       break;
1006 
1007     case CST_TERM_W4_SEC_COMP:
1008       switch (event) {
1009         case L2CEVT_SEC_COMP:
1010           p_ccb->chnl_state = CST_OPEN;
1011           l2c_ucd_send_pending_in_sec_q(p_ccb);
1012 
1013           if (!fixed_queue_is_empty(p_ccb->p_lcb->ucd_in_sec_pending_q)) {
1014             /* start a timer to check next UCD packet in OPEN state */
1015             /* it will prevent stack overflow */
1016             alarm_set_on_queue(p_ccb->l2c_ccb_timer, 0, l2c_ccb_timer_timeout,
1017                                p_ccb, btu_general_alarm_queue);
1018           } else {
1019             /* start a timer for idle timeout of UCD */
1020             period_ms_t timeout_ms = p_ccb->fixed_chnl_idle_tout * 1000;
1021             alarm_set_on_queue(p_ccb->l2c_ccb_timer, timeout_ms,
1022                                l2c_ccb_timer_timeout, p_ccb,
1023                                btu_general_alarm_queue);
1024           }
1025           break;
1026 
1027         case L2CEVT_SEC_COMP_NEG:
1028           if (((tL2C_CONN_INFO*)p_data)->status == BTM_DELAY_CHECK) {
1029             done = false;
1030             break;
1031           }
1032           p_ccb->chnl_state = CST_OPEN;
1033           l2c_ucd_discard_pending_in_sec_q(p_ccb);
1034 
1035           /* start a timer for idle timeout of UCD */
1036           period_ms_t timeout_ms = p_ccb->fixed_chnl_idle_tout * 1000;
1037           alarm_set_on_queue(p_ccb->l2c_ccb_timer, timeout_ms,
1038                              l2c_ccb_timer_timeout, p_ccb,
1039                              btu_general_alarm_queue);
1040           break;
1041 
1042         case L2CEVT_L2CA_DATA_WRITE: /* Upper layer data to send */
1043           l2c_ucd_enqueue_pending_out_sec_q(p_ccb, p_data);
1044           break;
1045 
1046         case L2CEVT_L2CAP_DATA: /* Peer data packet rcvd    */
1047           fixed_queue_enqueue(p_ccb->p_lcb->ucd_in_sec_pending_q, p_data);
1048           break;
1049 
1050         case L2CEVT_SEC_RE_SEND_CMD: /* BTM has enough info to proceed */
1051           /* check if any incoming UCD packet is waiting security check */
1052           if (!l2c_ucd_check_pending_in_sec_q(p_ccb)) {
1053             p_ccb->chnl_state = CST_OPEN;
1054           }
1055           break;
1056 
1057         case L2CEVT_L2CAP_INFO_RSP:
1058           /* check if waiting for UCD info */
1059           l2c_ucd_check_pending_info_req(p_ccb);
1060           break;
1061 
1062         default:
1063           done = false; /* main state machine continues to process event */
1064           break;
1065       }
1066       break;
1067 
1068     case CST_OPEN:
1069       switch (event) {
1070         case L2CEVT_L2CAP_DATA: /* Peer data packet rcvd    */
1071           /* stop idle timer of UCD */
1072           alarm_cancel(p_ccb->l2c_ccb_timer);
1073 
1074           fixed_queue_enqueue(p_ccb->p_lcb->ucd_in_sec_pending_q, p_data);
1075           l2c_ucd_check_pending_in_sec_q(p_ccb);
1076           break;
1077 
1078         case L2CEVT_L2CA_DATA_WRITE: /* Upper layer data to send */
1079           /* stop idle timer of UCD */
1080           alarm_cancel(p_ccb->l2c_ccb_timer);
1081 
1082           l2c_ucd_enqueue_pending_out_sec_q(p_ccb, p_data);
1083 
1084           /* success changes state, failure stays in current state */
1085           l2c_ucd_check_pending_out_sec_q(p_ccb);
1086           break;
1087 
1088         case L2CEVT_TIMEOUT:
1089           /* check if any UCD packet is waiting security check */
1090           if ((!l2c_ucd_check_pending_in_sec_q(p_ccb)) &&
1091               (!l2c_ucd_check_pending_out_sec_q(p_ccb))) {
1092             l2cu_release_ccb(p_ccb);
1093           }
1094           break;
1095 
1096         case L2CEVT_L2CAP_INFO_RSP:
1097           /* check if waiting for UCD info */
1098           l2c_ucd_check_pending_info_req(p_ccb);
1099           break;
1100 
1101         default:
1102           done = false; /* main state machine continues to process event */
1103           break;
1104       }
1105       break;
1106 
1107     default:
1108       done = false; /* main state machine continues to process event */
1109       break;
1110   }
1111 
1112   return done;
1113 }
1114 #endif /* (L2CAP_UCD_INCLUDED == TRUE) */
1115