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