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