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