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