Home | History | Annotate | Download | only in llcp
      1 /******************************************************************************
      2  *
      3  *  Copyright (C) 2010-2014 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 LLCP utilities
     22  *
     23  ******************************************************************************/
     24 
     25 #include <string.h>
     26 #include "bt_types.h"
     27 #include "gki.h"
     28 #include "llcp_defs.h"
     29 #include "llcp_int.h"
     30 #include "nfc_int.h"
     31 #include "nfc_target.h"
     32 #include "trace_api.h"
     33 
     34 /*******************************************************************************
     35 **
     36 ** Function         llcp_util_parse_link_params
     37 **
     38 ** Description      Parse LLCP Link parameters
     39 **
     40 ** Returns          TRUE if success
     41 **
     42 *******************************************************************************/
     43 bool llcp_util_parse_link_params(uint16_t length, uint8_t* p_bytes) {
     44   uint8_t param_type, param_len, *p = p_bytes;
     45 
     46   while (length) {
     47     BE_STREAM_TO_UINT8(param_type, p);
     48     length--;
     49 
     50     switch (param_type) {
     51       case LLCP_VERSION_TYPE:
     52         BE_STREAM_TO_UINT8(param_len, p);
     53         BE_STREAM_TO_UINT8(llcp_cb.lcb.peer_version, p);
     54         LLCP_TRACE_DEBUG1("Peer Version - 0x%02X", llcp_cb.lcb.peer_version);
     55         break;
     56 
     57       case LLCP_MIUX_TYPE:
     58         BE_STREAM_TO_UINT8(param_len, p);
     59         BE_STREAM_TO_UINT16(llcp_cb.lcb.peer_miu, p);
     60         llcp_cb.lcb.peer_miu &= LLCP_MIUX_MASK;
     61         llcp_cb.lcb.peer_miu += LLCP_DEFAULT_MIU;
     62         LLCP_TRACE_DEBUG1("Peer MIU - %d bytes", llcp_cb.lcb.peer_miu);
     63         break;
     64 
     65       case LLCP_WKS_TYPE:
     66         BE_STREAM_TO_UINT8(param_len, p);
     67         BE_STREAM_TO_UINT16(llcp_cb.lcb.peer_wks, p);
     68         LLCP_TRACE_DEBUG1("Peer WKS - 0x%04X", llcp_cb.lcb.peer_wks);
     69         break;
     70 
     71       case LLCP_LTO_TYPE:
     72         BE_STREAM_TO_UINT8(param_len, p);
     73         BE_STREAM_TO_UINT8(llcp_cb.lcb.peer_lto, p);
     74         llcp_cb.lcb.peer_lto *= LLCP_LTO_UNIT; /* 10ms unit */
     75         LLCP_TRACE_DEBUG1("Peer LTO - %d ms", llcp_cb.lcb.peer_lto);
     76         break;
     77 
     78       case LLCP_OPT_TYPE:
     79         BE_STREAM_TO_UINT8(param_len, p);
     80         BE_STREAM_TO_UINT8(llcp_cb.lcb.peer_opt, p);
     81         LLCP_TRACE_DEBUG1("Peer OPT - 0x%02X", llcp_cb.lcb.peer_opt);
     82         break;
     83 
     84       default:
     85         LLCP_TRACE_ERROR1(
     86             "llcp_util_parse_link_params (): Unexpected type 0x%x", param_type);
     87         BE_STREAM_TO_UINT8(param_len, p);
     88         p += param_len;
     89         break;
     90     }
     91 
     92     if (length >= param_len + 1)
     93       length -= param_len + 1;
     94     else {
     95       LLCP_TRACE_ERROR0("llcp_util_parse_link_params (): Bad LTV's");
     96       return false;
     97     }
     98   }
     99   return true;
    100 }
    101 
    102 /*******************************************************************************
    103 **
    104 ** Function         llcp_util_adjust_ll_congestion
    105 **
    106 ** Description      adjust tx/rx congestion thresholds on logical link
    107 **
    108 ** Returns          void
    109 **
    110 *******************************************************************************/
    111 void llcp_util_adjust_ll_congestion(void) {
    112   /* buffer quota is allocated equally for each logical data link */
    113   if (llcp_cb.num_logical_data_link) {
    114     llcp_cb.ll_tx_congest_start =
    115         llcp_cb.max_num_ll_tx_buff / llcp_cb.num_logical_data_link;
    116     llcp_cb.ll_rx_congest_start =
    117         llcp_cb.max_num_ll_rx_buff / llcp_cb.num_logical_data_link;
    118   } else {
    119     llcp_cb.ll_tx_congest_start = llcp_cb.max_num_ll_tx_buff;
    120     llcp_cb.ll_rx_congest_start = llcp_cb.max_num_ll_rx_buff;
    121   }
    122 
    123   /* at least one for each logical data link */
    124   if (llcp_cb.ll_tx_congest_start == 0) {
    125     llcp_cb.ll_tx_congest_start = 1;
    126   }
    127   if (llcp_cb.ll_rx_congest_start == 0) {
    128     llcp_cb.ll_rx_congest_start = 1;
    129   }
    130 
    131   if (llcp_cb.ll_tx_congest_start > 1) {
    132     llcp_cb.ll_tx_congest_end = 1;
    133   } else {
    134     llcp_cb.ll_tx_congest_end = 0;
    135   }
    136 
    137   LLCP_TRACE_DEBUG4(
    138       "num_logical_data_link=%d, ll_tx_congest_start=%d, ll_tx_congest_end=%d, "
    139       "ll_rx_congest_start=%d",
    140       llcp_cb.num_logical_data_link, llcp_cb.ll_tx_congest_start,
    141       llcp_cb.ll_tx_congest_end, llcp_cb.ll_rx_congest_start);
    142 }
    143 
    144 /*******************************************************************************
    145 **
    146 ** Function         llcp_util_adjust_dl_rx_congestion
    147 **
    148 ** Description      adjust rx congestion thresholds on data link
    149 **
    150 ** Returns          void
    151 **
    152 *******************************************************************************/
    153 void llcp_util_adjust_dl_rx_congestion(void) {
    154   uint8_t idx, rx_congest_start;
    155 
    156   if (llcp_cb.num_data_link_connection) {
    157     rx_congest_start = llcp_cb.num_rx_buff / llcp_cb.num_data_link_connection;
    158 
    159     for (idx = 0; idx < LLCP_MAX_DATA_LINK; idx++) {
    160       if (llcp_cb.dlcb[idx].state == LLCP_DLC_STATE_CONNECTED) {
    161         if (rx_congest_start > llcp_cb.dlcb[idx].local_rw) {
    162           /*
    163           ** set rx congestion threshold LLCP_DL_MIN_RX_CONGEST at
    164           ** least so, we don't need to flow off too often.
    165           */
    166           if (llcp_cb.dlcb[idx].local_rw + 1 > LLCP_DL_MIN_RX_CONGEST)
    167             llcp_cb.dlcb[idx].rx_congest_threshold =
    168                 llcp_cb.dlcb[idx].local_rw + 1;
    169           else
    170             llcp_cb.dlcb[idx].rx_congest_threshold = LLCP_DL_MIN_RX_CONGEST;
    171         } else {
    172           llcp_cb.dlcb[idx].rx_congest_threshold = LLCP_DL_MIN_RX_CONGEST;
    173         }
    174 
    175         LLCP_TRACE_DEBUG3("DLC[%d], local_rw=%d, rx_congest_threshold=%d", idx,
    176                           llcp_cb.dlcb[idx].local_rw,
    177                           llcp_cb.dlcb[idx].rx_congest_threshold);
    178       }
    179     }
    180   }
    181 }
    182 
    183 /*******************************************************************************
    184 **
    185 ** Function         llcp_util_check_rx_congested_status
    186 **
    187 ** Description      Update rx congested status
    188 **
    189 ** Returns          void
    190 **
    191 *******************************************************************************/
    192 void llcp_util_check_rx_congested_status(void) {
    193   uint8_t idx;
    194 
    195   if (llcp_cb.overall_rx_congested) {
    196     /* check if rx congestion clear */
    197     if (llcp_cb.total_rx_ui_pdu + llcp_cb.total_rx_i_pdu <=
    198         llcp_cb.overall_rx_congest_end) {
    199       LLCP_TRACE_DEBUG3(
    200           "llcp_util_check_rx_congested_status (): rx link is uncongested, "
    201           "%d+%d <= %d",
    202           llcp_cb.total_rx_ui_pdu, llcp_cb.total_rx_i_pdu,
    203           llcp_cb.overall_rx_congest_end);
    204 
    205       llcp_cb.overall_rx_congested = false;
    206 
    207       for (idx = 0; idx < LLCP_MAX_DATA_LINK; idx++) {
    208         /* set flag to clear local busy status on data link connections */
    209         if ((llcp_cb.dlcb[idx].state == LLCP_DLC_STATE_CONNECTED) &&
    210             (llcp_cb.dlcb[idx].is_rx_congested == false)) {
    211           llcp_cb.dlcb[idx].flags |= LLCP_DATA_LINK_FLAG_PENDING_RR_RNR;
    212         }
    213       }
    214     }
    215   } else {
    216     /* check if rx link is congested */
    217     if (llcp_cb.total_rx_ui_pdu + llcp_cb.total_rx_i_pdu >=
    218         llcp_cb.overall_rx_congest_start) {
    219       LLCP_TRACE_WARNING3(
    220           "llcp_util_check_rx_congested_status (): rx link is congested, %d+%d "
    221           ">= %d",
    222           llcp_cb.total_rx_ui_pdu, llcp_cb.total_rx_i_pdu,
    223           llcp_cb.overall_rx_congest_start);
    224 
    225       llcp_cb.overall_rx_congested = true;
    226 
    227       /* rx link congestion is started, send RNR to remote end point */
    228       for (idx = 0; idx < LLCP_MAX_DATA_LINK; idx++) {
    229         if ((llcp_cb.dlcb[idx].state == LLCP_DLC_STATE_CONNECTED) &&
    230             (llcp_cb.dlcb[idx].is_rx_congested == false)) {
    231           llcp_cb.dlcb[idx].flags |= LLCP_DATA_LINK_FLAG_PENDING_RR_RNR;
    232         }
    233       }
    234     }
    235   }
    236 }
    237 
    238 /*******************************************************************************
    239 **
    240 ** Function         llcp_util_send_ui
    241 **
    242 ** Description      Send UI PDU
    243 **
    244 ** Returns          tLLCP_STATUS
    245 **
    246 *******************************************************************************/
    247 tLLCP_STATUS llcp_util_send_ui(uint8_t ssap, uint8_t dsap,
    248                                tLLCP_APP_CB* p_app_cb, NFC_HDR* p_msg) {
    249   uint8_t* p;
    250   tLLCP_STATUS status = LLCP_STATUS_SUCCESS;
    251 
    252   p_msg->offset -= LLCP_PDU_HEADER_SIZE;
    253   p_msg->len += LLCP_PDU_HEADER_SIZE;
    254 
    255   p = (uint8_t*)(p_msg + 1) + p_msg->offset;
    256   UINT16_TO_BE_STREAM(p, LLCP_GET_PDU_HEADER(dsap, LLCP_PDU_UI_TYPE, ssap));
    257 
    258   GKI_enqueue(&p_app_cb->ui_xmit_q, p_msg);
    259   llcp_cb.total_tx_ui_pdu++;
    260 
    261   llcp_link_check_send_data();
    262 
    263   if ((p_app_cb->is_ui_tx_congested) ||
    264       (p_app_cb->ui_xmit_q.count >= llcp_cb.ll_tx_congest_start) ||
    265       (llcp_cb.overall_tx_congested) ||
    266       (llcp_cb.total_tx_ui_pdu >= llcp_cb.max_num_ll_tx_buff)) {
    267     /* set congested here so overall congestion check routine will not report
    268      * event again, */
    269     /* or notify uncongestion later */
    270     p_app_cb->is_ui_tx_congested = true;
    271 
    272     LLCP_TRACE_WARNING2("Logical link (SAP=0x%X) congested: ui_xmit_q.count=%d",
    273                         ssap, p_app_cb->ui_xmit_q.count);
    274 
    275     status = LLCP_STATUS_CONGESTED;
    276   }
    277 
    278   return status;
    279 }
    280 
    281 /*******************************************************************************
    282 **
    283 ** Function         llcp_util_send_disc
    284 **
    285 ** Description      Send DISC PDU
    286 **
    287 ** Returns          void
    288 **
    289 *******************************************************************************/
    290 void llcp_util_send_disc(uint8_t dsap, uint8_t ssap) {
    291   NFC_HDR* p_msg;
    292   uint8_t* p;
    293 
    294   p_msg = (NFC_HDR*)GKI_getpoolbuf(LLCP_POOL_ID);
    295 
    296   if (p_msg) {
    297     p_msg->len = LLCP_PDU_DISC_SIZE;
    298     p_msg->offset = NCI_MSG_OFFSET_SIZE + NCI_DATA_HDR_SIZE;
    299 
    300     p = (uint8_t*)(p_msg + 1) + p_msg->offset;
    301     UINT16_TO_BE_STREAM(p, LLCP_GET_PDU_HEADER(dsap, LLCP_PDU_DISC_TYPE, ssap));
    302 
    303     GKI_enqueue(&llcp_cb.lcb.sig_xmit_q, p_msg);
    304     llcp_link_check_send_data();
    305   }
    306 }
    307 
    308 /*******************************************************************************
    309 **
    310 ** Function         llcp_util_allocate_data_link
    311 **
    312 ** Description      Allocate tLLCP_DLCB for data link connection
    313 **
    314 ** Returns          tLLCP_DLCB *
    315 **
    316 ******************************************************************************/
    317 tLLCP_DLCB* llcp_util_allocate_data_link(uint8_t reg_sap, uint8_t remote_sap) {
    318   tLLCP_DLCB* p_dlcb = NULL;
    319   int idx;
    320 
    321   LLCP_TRACE_DEBUG2(
    322       "llcp_util_allocate_data_link (): reg_sap = 0x%x, remote_sap = 0x%x",
    323       reg_sap, remote_sap);
    324 
    325   for (idx = 0; idx < LLCP_MAX_DATA_LINK; idx++) {
    326     if (llcp_cb.dlcb[idx].state == LLCP_DLC_STATE_IDLE) {
    327       p_dlcb = &(llcp_cb.dlcb[idx]);
    328 
    329       memset(p_dlcb, 0, sizeof(tLLCP_DLCB));
    330       break;
    331     }
    332   }
    333 
    334   if (!p_dlcb) {
    335     LLCP_TRACE_ERROR0("llcp_util_allocate_data_link (): Out of DLCB");
    336   } else {
    337     p_dlcb->p_app_cb = llcp_util_get_app_cb(reg_sap);
    338     p_dlcb->local_sap = reg_sap;
    339     p_dlcb->remote_sap = remote_sap;
    340     p_dlcb->timer.param = (uintptr_t)p_dlcb;
    341 
    342     /* this is for inactivity timer and congestion control. */
    343     llcp_cb.num_data_link_connection++;
    344 
    345     LLCP_TRACE_DEBUG3(
    346         "llcp_util_allocate_data_link (): local_sap = 0x%x, remote_sap = 0x%x, "
    347         "num_data_link_connection = %d",
    348         p_dlcb->local_sap, p_dlcb->remote_sap,
    349         llcp_cb.num_data_link_connection);
    350   }
    351   return p_dlcb;
    352 }
    353 
    354 /*******************************************************************************
    355 **
    356 ** Function         llcp_util_deallocate_data_link
    357 **
    358 ** Description      Deallocate tLLCP_DLCB
    359 **
    360 ** Returns          void
    361 **
    362 ******************************************************************************/
    363 void llcp_util_deallocate_data_link(tLLCP_DLCB* p_dlcb) {
    364   if (p_dlcb) {
    365     LLCP_TRACE_DEBUG1("llcp_util_deallocate_data_link (): local_sap = 0x%x",
    366                       p_dlcb->local_sap);
    367 
    368     if (p_dlcb->state != LLCP_DLC_STATE_IDLE) {
    369       nfc_stop_quick_timer(&p_dlcb->timer);
    370       llcp_dlc_flush_q(p_dlcb);
    371 
    372       p_dlcb->state = LLCP_DLC_STATE_IDLE;
    373 
    374       if (llcp_cb.num_data_link_connection > 0) {
    375         llcp_cb.num_data_link_connection--;
    376       }
    377 
    378       LLCP_TRACE_DEBUG1(
    379           "llcp_util_deallocate_data_link (): num_data_link_connection = %d",
    380           llcp_cb.num_data_link_connection);
    381     }
    382   }
    383 }
    384 
    385 /*******************************************************************************
    386 **
    387 ** Function         llcp_util_send_connect
    388 **
    389 ** Description      Send CONNECT PDU
    390 **
    391 ** Returns          tLLCP_STATUS
    392 **
    393 ******************************************************************************/
    394 tLLCP_STATUS llcp_util_send_connect(tLLCP_DLCB* p_dlcb,
    395                                     tLLCP_CONNECTION_PARAMS* p_params) {
    396   NFC_HDR* p_msg;
    397   uint8_t* p;
    398   uint16_t miu_len = 0, rw_len = 0, sn_len = 0;
    399 
    400   if (p_params->miu != LLCP_DEFAULT_MIU) {
    401     miu_len = 4; /* TYPE, LEN, 2 bytes MIU */
    402   }
    403   if (p_params->rw != LLCP_DEFAULT_RW) {
    404     rw_len = 3;           /* TYPE, LEN, 1 byte RW */
    405     p_params->rw &= 0x0F; /* only 4 bits  */
    406   }
    407   if ((strlen(p_params->sn)) && (p_dlcb->remote_sap == LLCP_SAP_SDP)) {
    408     sn_len = (uint16_t)(2 + strlen(p_params->sn)); /* TYPE, LEN, SN */
    409   }
    410 
    411   p_msg = (NFC_HDR*)GKI_getpoolbuf(LLCP_POOL_ID);
    412 
    413   if (p_msg) {
    414     p_msg->len = LLCP_PDU_HEADER_SIZE + miu_len + rw_len + sn_len;
    415     p_msg->offset = NCI_MSG_OFFSET_SIZE + NCI_DATA_HDR_SIZE;
    416 
    417     p = (uint8_t*)(p_msg + 1) + p_msg->offset;
    418 
    419     UINT16_TO_BE_STREAM(
    420         p, LLCP_GET_PDU_HEADER(p_dlcb->remote_sap, LLCP_PDU_CONNECT_TYPE,
    421                                p_dlcb->local_sap));
    422 
    423     if (miu_len) {
    424       UINT8_TO_BE_STREAM(p, LLCP_MIUX_TYPE);
    425       UINT8_TO_BE_STREAM(p, LLCP_MIUX_LEN);
    426       UINT16_TO_BE_STREAM(p, p_params->miu - LLCP_DEFAULT_MIU);
    427     }
    428 
    429     if (rw_len) {
    430       UINT8_TO_BE_STREAM(p, LLCP_RW_TYPE);
    431       UINT8_TO_BE_STREAM(p, LLCP_RW_LEN);
    432       UINT8_TO_BE_STREAM(p, p_params->rw);
    433     }
    434 
    435     if (sn_len) {
    436       UINT8_TO_BE_STREAM(p, LLCP_SN_TYPE);
    437       UINT8_TO_BE_STREAM(p, sn_len - 2);
    438       memcpy(p, p_params->sn, sn_len - 2);
    439     }
    440 
    441     GKI_enqueue(&llcp_cb.lcb.sig_xmit_q, p_msg);
    442     llcp_link_check_send_data();
    443 
    444     return LLCP_STATUS_SUCCESS;
    445   }
    446 
    447   return LLCP_STATUS_FAIL;
    448 }
    449 
    450 /*******************************************************************************
    451 **
    452 ** Function         llcp_util_parse_connect
    453 **
    454 ** Description      Parse CONNECT PDU
    455 **
    456 ** Returns          tLLCP_STATUS
    457 **
    458 *******************************************************************************/
    459 tLLCP_STATUS llcp_util_parse_connect(uint8_t* p_bytes, uint16_t length,
    460                                      tLLCP_CONNECTION_PARAMS* p_params) {
    461   uint8_t param_type, param_len, *p = p_bytes;
    462 
    463   p_params->miu = LLCP_DEFAULT_MIU;
    464   p_params->rw = LLCP_DEFAULT_RW;
    465   p_params->sn[0] = 0;
    466   p_params->sn[1] = 0;
    467 
    468   while (length) {
    469     BE_STREAM_TO_UINT8(param_type, p);
    470     length--;
    471 
    472     switch (param_type) {
    473       case LLCP_MIUX_TYPE:
    474         BE_STREAM_TO_UINT8(param_len, p);
    475         BE_STREAM_TO_UINT16(p_params->miu, p);
    476         p_params->miu &= LLCP_MIUX_MASK;
    477         p_params->miu += LLCP_DEFAULT_MIU;
    478 
    479         LLCP_TRACE_DEBUG1("llcp_util_parse_connect (): LLCP_MIUX_TYPE:%d",
    480                           p_params->miu);
    481         break;
    482 
    483       case LLCP_RW_TYPE:
    484         BE_STREAM_TO_UINT8(param_len, p);
    485         BE_STREAM_TO_UINT8(p_params->rw, p);
    486         p_params->rw &= 0x0F;
    487 
    488         LLCP_TRACE_DEBUG1("llcp_util_parse_connect (): LLCP_RW_TYPE:%d",
    489                           p_params->rw);
    490         break;
    491 
    492       case LLCP_SN_TYPE:
    493         BE_STREAM_TO_UINT8(param_len, p);
    494 
    495         if (param_len == 0) {
    496           /* indicate that SN type is included without SN */
    497           p_params->sn[1] = LLCP_SN_TYPE;
    498         } else if (param_len <= LLCP_MAX_SN_LEN) {
    499           memcpy(p_params->sn, p, param_len);
    500           p_params->sn[param_len] = 0;
    501         } else {
    502           memcpy(p_params->sn, p, LLCP_MAX_SN_LEN);
    503           p_params->sn[LLCP_MAX_SN_LEN] = 0;
    504         }
    505         p += param_len;
    506 
    507         LLCP_TRACE_DEBUG1("llcp_util_parse_connect (): LLCP_SN_TYPE:<%s>",
    508                           p_params->sn);
    509         break;
    510 
    511       default:
    512         LLCP_TRACE_ERROR1("llcp_util_parse_connect (): Unexpected type 0x%x",
    513                           param_type);
    514         BE_STREAM_TO_UINT8(param_len, p);
    515         p += param_len;
    516         break;
    517     }
    518 
    519     /* check remaining lengh */
    520     if (length >= param_len + 1) {
    521       length -= param_len + 1;
    522     } else {
    523       LLCP_TRACE_ERROR0("llcp_util_parse_connect (): Bad LTV's");
    524       return LLCP_STATUS_FAIL;
    525     }
    526   }
    527   return LLCP_STATUS_SUCCESS;
    528 }
    529 
    530 /*******************************************************************************
    531 **
    532 ** Function         llcp_util_send_cc
    533 **
    534 ** Description      Send CC PDU
    535 **
    536 ** Returns          tLLCP_STATUS
    537 **
    538 ******************************************************************************/
    539 tLLCP_STATUS llcp_util_send_cc(tLLCP_DLCB* p_dlcb,
    540                                tLLCP_CONNECTION_PARAMS* p_params) {
    541   NFC_HDR* p_msg;
    542   uint8_t* p;
    543   uint16_t miu_len = 0, rw_len = 0;
    544 
    545   if (p_params->miu != LLCP_DEFAULT_MIU) {
    546     miu_len = 4;
    547   }
    548   if (p_params->rw != LLCP_DEFAULT_RW) {
    549     rw_len = 3;
    550     p_params->rw &= 0x0F;
    551   }
    552 
    553   p_msg = (NFC_HDR*)GKI_getpoolbuf(LLCP_POOL_ID);
    554 
    555   if (p_msg) {
    556     p_msg->len = LLCP_PDU_HEADER_SIZE + miu_len + rw_len;
    557     p_msg->offset = NCI_MSG_OFFSET_SIZE + NCI_DATA_HDR_SIZE;
    558 
    559     p = (uint8_t*)(p_msg + 1) + p_msg->offset;
    560 
    561     UINT16_TO_BE_STREAM(
    562         p, LLCP_GET_PDU_HEADER(p_dlcb->remote_sap, LLCP_PDU_CC_TYPE,
    563                                p_dlcb->local_sap));
    564 
    565     if (miu_len) {
    566       UINT8_TO_BE_STREAM(p, LLCP_MIUX_TYPE);
    567       UINT8_TO_BE_STREAM(p, LLCP_MIUX_LEN);
    568       UINT16_TO_BE_STREAM(p, p_params->miu - LLCP_DEFAULT_MIU);
    569     }
    570 
    571     if (rw_len) {
    572       UINT8_TO_BE_STREAM(p, LLCP_RW_TYPE);
    573       UINT8_TO_BE_STREAM(p, LLCP_RW_LEN);
    574       UINT8_TO_BE_STREAM(p, p_params->rw);
    575     }
    576 
    577     GKI_enqueue(&llcp_cb.lcb.sig_xmit_q, p_msg);
    578     llcp_link_check_send_data();
    579 
    580     return LLCP_STATUS_SUCCESS;
    581   }
    582 
    583   return LLCP_STATUS_FAIL;
    584 }
    585 
    586 /*******************************************************************************
    587 **
    588 ** Function         llcp_util_parse_cc
    589 **
    590 ** Description      Parse CC PDU
    591 **
    592 ** Returns          tLLCP_STATUS
    593 **
    594 *******************************************************************************/
    595 tLLCP_STATUS llcp_util_parse_cc(uint8_t* p_bytes, uint16_t length,
    596                                 uint16_t* p_miu, uint8_t* p_rw) {
    597   uint8_t param_type, param_len, *p = p_bytes;
    598 
    599   *p_miu = LLCP_DEFAULT_MIU;
    600   *p_rw = LLCP_DEFAULT_RW;
    601 
    602   while (length) {
    603     BE_STREAM_TO_UINT8(param_type, p);
    604     length--;
    605 
    606     switch (param_type) {
    607       case LLCP_MIUX_TYPE:
    608         BE_STREAM_TO_UINT8(param_len, p);
    609         BE_STREAM_TO_UINT16((*p_miu), p);
    610         (*p_miu) &= LLCP_MIUX_MASK;
    611         (*p_miu) += LLCP_DEFAULT_MIU;
    612 
    613         LLCP_TRACE_DEBUG1("llcp_util_parse_cc (): LLCP_MIUX_TYPE:%d", *p_miu);
    614         break;
    615 
    616       case LLCP_RW_TYPE:
    617         BE_STREAM_TO_UINT8(param_len, p);
    618         BE_STREAM_TO_UINT8((*p_rw), p);
    619         (*p_rw) &= 0x0F;
    620 
    621         LLCP_TRACE_DEBUG1("llcp_util_parse_cc (): LLCP_RW_TYPE:%d", *p_rw);
    622         break;
    623 
    624       default:
    625         LLCP_TRACE_ERROR1("llcp_util_parse_cc (): Unexpected type 0x%x",
    626                           param_type);
    627         BE_STREAM_TO_UINT8(param_len, p);
    628         p += param_len;
    629         break;
    630     }
    631 
    632     if (length >= param_len + 1)
    633       length -= param_len + 1;
    634     else {
    635       LLCP_TRACE_ERROR0("llcp_util_parse_cc (): Bad LTV's");
    636       return LLCP_STATUS_FAIL;
    637     }
    638   }
    639   return LLCP_STATUS_SUCCESS;
    640 }
    641 
    642 /*******************************************************************************
    643 **
    644 ** Function         llcp_util_send_dm
    645 **
    646 ** Description      Send DM PDU
    647 **
    648 ** Returns          void
    649 **
    650 *******************************************************************************/
    651 void llcp_util_send_dm(uint8_t dsap, uint8_t ssap, uint8_t reason) {
    652   NFC_HDR* p_msg;
    653   uint8_t* p;
    654 
    655   p_msg = (NFC_HDR*)GKI_getpoolbuf(LLCP_POOL_ID);
    656 
    657   if (p_msg) {
    658     p_msg->len = LLCP_PDU_DM_SIZE;
    659     p_msg->offset = NCI_MSG_OFFSET_SIZE + NCI_DATA_HDR_SIZE;
    660 
    661     p = (uint8_t*)(p_msg + 1) + p_msg->offset;
    662     UINT16_TO_BE_STREAM(p, LLCP_GET_PDU_HEADER(dsap, LLCP_PDU_DM_TYPE, ssap));
    663     UINT8_TO_BE_STREAM(p, reason);
    664 
    665     GKI_enqueue(&llcp_cb.lcb.sig_xmit_q, p_msg);
    666     llcp_link_check_send_data();
    667   }
    668 }
    669 
    670 /*******************************************************************************
    671 **
    672 ** Function         llcp_util_build_info_pdu
    673 **
    674 ** Description      Add DSAP, PTYPE, SSAP and sequence numbers and update local
    675 **                  ack sequence
    676 **
    677 ** Returns          void
    678 **
    679 *******************************************************************************/
    680 void llcp_util_build_info_pdu(tLLCP_DLCB* p_dlcb, NFC_HDR* p_msg) {
    681   uint8_t* p;
    682   uint8_t rcv_seq;
    683 
    684   p_msg->offset -= LLCP_PDU_HEADER_SIZE + LLCP_SEQUENCE_SIZE;
    685   p_msg->len += LLCP_PDU_HEADER_SIZE + LLCP_SEQUENCE_SIZE;
    686   p = (uint8_t*)(p_msg + 1) + p_msg->offset;
    687 
    688   UINT16_TO_BE_STREAM(p,
    689                       LLCP_GET_PDU_HEADER(p_dlcb->remote_sap, LLCP_PDU_I_TYPE,
    690                                           p_dlcb->local_sap));
    691 
    692   /* if local_busy or rx congested then do not update receive sequence number to
    693    * flow off */
    694   if ((p_dlcb->local_busy) || (p_dlcb->is_rx_congested) ||
    695       (llcp_cb.overall_rx_congested)) {
    696     rcv_seq = p_dlcb->sent_ack_seq;
    697   } else {
    698     p_dlcb->sent_ack_seq = p_dlcb->next_rx_seq;
    699     rcv_seq = p_dlcb->sent_ack_seq;
    700   }
    701   UINT8_TO_BE_STREAM(p, LLCP_GET_SEQUENCE(p_dlcb->next_tx_seq, rcv_seq));
    702 }
    703 
    704 /*******************************************************************************
    705 **
    706 ** Function         llcp_util_send_frmr
    707 **
    708 ** Description      Send FRMR PDU
    709 **
    710 ** Returns          tLLCP_STATUS
    711 **
    712 *******************************************************************************/
    713 tLLCP_STATUS llcp_util_send_frmr(tLLCP_DLCB* p_dlcb, uint8_t flags,
    714                                  uint8_t ptype, uint8_t sequence) {
    715   NFC_HDR* p_msg;
    716   uint8_t* p;
    717 
    718   p_msg = (NFC_HDR*)GKI_getpoolbuf(LLCP_POOL_ID);
    719 
    720   if (p_msg) {
    721     p_msg->len = LLCP_PDU_FRMR_SIZE;
    722     p_msg->offset = NCI_MSG_OFFSET_SIZE + NCI_DATA_HDR_SIZE;
    723 
    724     p = (uint8_t*)(p_msg + 1) + p_msg->offset;
    725 
    726     UINT16_TO_BE_STREAM(
    727         p, LLCP_GET_PDU_HEADER(p_dlcb->remote_sap, LLCP_PDU_FRMR_TYPE,
    728                                p_dlcb->local_sap));
    729     UINT8_TO_BE_STREAM(p, (flags << 4) | ptype);
    730     UINT8_TO_BE_STREAM(p, sequence);
    731     UINT8_TO_BE_STREAM(p, (p_dlcb->next_tx_seq << 4) | p_dlcb->next_rx_seq);
    732     UINT8_TO_BE_STREAM(p, (p_dlcb->rcvd_ack_seq << 4) | p_dlcb->sent_ack_seq);
    733 
    734     GKI_enqueue(&llcp_cb.lcb.sig_xmit_q, p_msg);
    735     llcp_link_check_send_data();
    736 
    737     return LLCP_STATUS_SUCCESS;
    738   } else {
    739     LLCP_TRACE_ERROR0("llcp_util_send_frmr (): Out of resource");
    740     return LLCP_STATUS_FAIL;
    741   }
    742 }
    743 
    744 /*******************************************************************************
    745 **
    746 ** Function         llcp_util_send_rr_rnr
    747 **
    748 ** Description      Send RR or RNR PDU
    749 **
    750 ** Returns          void
    751 **
    752 *******************************************************************************/
    753 void llcp_util_send_rr_rnr(tLLCP_DLCB* p_dlcb) {
    754   NFC_HDR* p_msg;
    755   uint8_t* p;
    756   uint8_t pdu_type;
    757   uint8_t pdu_size;
    758   uint8_t rcv_seq;
    759 
    760   /* if no indication of change in local busy or rx congestion */
    761   if ((p_dlcb->flags & LLCP_DATA_LINK_FLAG_PENDING_RR_RNR) == 0) {
    762     /* if all ack is sent */
    763     if (p_dlcb->sent_ack_seq == p_dlcb->next_rx_seq) {
    764       /* we don't need to send RR/RNR */
    765       return;
    766     } else {
    767       /* if rx flow off because of local busy or congestion */
    768       if ((p_dlcb->local_busy) || (p_dlcb->is_rx_congested) ||
    769           (llcp_cb.overall_rx_congested)) {
    770         /* don't send RR/RNR */
    771         return;
    772       }
    773     }
    774   }
    775 
    776   if ((p_dlcb->local_busy) || (p_dlcb->is_rx_congested) ||
    777       (llcp_cb.overall_rx_congested)) {
    778     LLCP_TRACE_DEBUG3(
    779         "llcp_util_send_rr_rnr (): "
    780         "local_busy=%d,is_rx_congested=%d,overall_rx_congested=%d",
    781         p_dlcb->local_busy, p_dlcb->is_rx_congested,
    782         llcp_cb.overall_rx_congested);
    783 
    784     /* if local_busy or rx congested then do not update receive sequence number
    785      * to flow off */
    786     pdu_type = LLCP_PDU_RNR_TYPE;
    787     pdu_size = LLCP_PDU_RNR_SIZE;
    788     rcv_seq = p_dlcb->sent_ack_seq;
    789   } else {
    790     pdu_type = LLCP_PDU_RR_TYPE;
    791     pdu_size = LLCP_PDU_RR_SIZE;
    792 
    793     p_dlcb->sent_ack_seq = p_dlcb->next_rx_seq;
    794     rcv_seq = p_dlcb->sent_ack_seq;
    795   }
    796 
    797   p_msg = (NFC_HDR*)GKI_getpoolbuf(LLCP_POOL_ID);
    798 
    799   if (p_msg) {
    800     p_dlcb->flags &= ~LLCP_DATA_LINK_FLAG_PENDING_RR_RNR;
    801 
    802     p_msg->len = pdu_size;
    803     p_msg->offset = NCI_MSG_OFFSET_SIZE + NCI_DATA_HDR_SIZE;
    804 
    805     p = (uint8_t*)(p_msg + 1) + p_msg->offset;
    806 
    807     UINT16_TO_BE_STREAM(p, LLCP_GET_PDU_HEADER(p_dlcb->remote_sap, pdu_type,
    808                                                p_dlcb->local_sap));
    809 
    810     UINT8_TO_BE_STREAM(p, rcv_seq);
    811 
    812 #if (BT_TRACE_VERBOSE == TRUE)
    813     LLCP_TRACE_DEBUG5("LLCP TX - N(S,R):(NA,%d) V(S,SA,R,RA):(%d,%d,%d,%d)",
    814                       p_dlcb->next_rx_seq, p_dlcb->next_tx_seq,
    815                       p_dlcb->rcvd_ack_seq, p_dlcb->next_rx_seq,
    816                       p_dlcb->sent_ack_seq);
    817 #endif
    818     GKI_enqueue(&llcp_cb.lcb.sig_xmit_q, p_msg);
    819     llcp_link_check_send_data();
    820   } else {
    821     LLCP_TRACE_ERROR0("llcp_util_send_rr_rnr (): Out of resource");
    822   }
    823 }
    824 
    825 /*******************************************************************************
    826 **
    827 ** Function         llcp_util_get_app_cb
    828 **
    829 ** Description      get pointer of application registered control block by SAP
    830 **
    831 ** Returns          tLLCP_APP_CB *
    832 **
    833 *******************************************************************************/
    834 tLLCP_APP_CB* llcp_util_get_app_cb(uint8_t local_sap) {
    835   tLLCP_APP_CB* p_app_cb = NULL;
    836 
    837   if (local_sap <= LLCP_UPPER_BOUND_WK_SAP) {
    838     if ((local_sap != LLCP_SAP_LM) && (local_sap < LLCP_MAX_WKS)) {
    839       p_app_cb = &llcp_cb.wks_cb[local_sap];
    840     }
    841   } else if (local_sap <= LLCP_UPPER_BOUND_SDP_SAP) {
    842     if (local_sap - LLCP_LOWER_BOUND_SDP_SAP < LLCP_MAX_SERVER) {
    843       p_app_cb = &llcp_cb.server_cb[local_sap - LLCP_LOWER_BOUND_SDP_SAP];
    844     }
    845   } else if (local_sap <= LLCP_UPPER_BOUND_LOCAL_SAP) {
    846     if (local_sap - LLCP_LOWER_BOUND_LOCAL_SAP < LLCP_MAX_CLIENT) {
    847       p_app_cb = &llcp_cb.client_cb[local_sap - LLCP_LOWER_BOUND_LOCAL_SAP];
    848     }
    849   }
    850 
    851   return (p_app_cb);
    852 }
    853