Home | History | Annotate | Download | only in l2cap
      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 *******************************************************************************/
     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 *******************************************************************************/
     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 *******************************************************************************/
    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 *******************************************************************************/
    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 *******************************************************************************/
    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 *******************************************************************************/
    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 *******************************************************************************/
    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 *******************************************************************************/
    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 *******************************************************************************/
    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 *******************************************************************************/
    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 *******************************************************************************/
    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 *******************************************************************************/
    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 *******************************************************************************/
    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 *******************************************************************************/
    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 *******************************************************************************/
    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 *******************************************************************************/
    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 *******************************************************************************/
    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 *******************************************************************************/
    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 *******************************************************************************/
    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 *******************************************************************************/
    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 *******************************************************************************/
    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 *******************************************************************************/
    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 *******************************************************************************/
    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 *******************************************************************************/
    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