Home | History | Annotate | Download | only in nfc
      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 functions that interface with the NFC NCI transport.
     22  *  On the receive side, it routes events to the appropriate handler
     23  *  (callback). On the transmit side, it manages the command transmission.
     24  *
     25  ******************************************************************************/
     26 #include <string.h>
     27 #include "bt_types.h"
     28 #include "gki.h"
     29 #include "nfc_target.h"
     30 
     31 #include "ce_int.h"
     32 #include "nci_hmsgs.h"
     33 #include "nfc_api.h"
     34 #include "nfc_hal_api.h"
     35 #include "nfc_int.h"
     36 #include "rw_int.h"
     37 
     38 #if (NFC_RW_ONLY == FALSE)
     39 #include "ce_api.h"
     40 #include "ce_int.h"
     41 #include "llcp_int.h"
     42 
     43 /* NFC mandates support for at least one logical connection;
     44  * Update max_conn to the NFCC capability on InitRsp */
     45 #define NFC_SET_MAX_CONN_DEFAULT() \
     46   { nfc_cb.max_conn = 1; }
     47 
     48 #else /* NFC_RW_ONLY */
     49 #define ce_init()
     50 #define llcp_init()
     51 
     52 #define NFC_SET_MAX_CONN_DEFAULT()
     53 
     54 #endif /* NFC_RW_ONLY */
     55 /****************************************************************************
     56 ** Declarations
     57 ****************************************************************************/
     58 tNFC_CB nfc_cb;
     59 
     60 #if (NFC_RW_ONLY == FALSE)
     61 #define NFC_NUM_INTERFACE_MAP 2
     62 #else
     63 #define NFC_NUM_INTERFACE_MAP 1
     64 #endif
     65 
     66 static const tNCI_DISCOVER_MAPS nfc_interface_mapping[NFC_NUM_INTERFACE_MAP] = {
     67     /* Protocols that use Frame Interface do not need to be included in the
     68        interface mapping */
     69     {NCI_PROTOCOL_ISO_DEP, NCI_INTERFACE_MODE_POLL_N_LISTEN,
     70      NCI_INTERFACE_ISO_DEP}
     71 #if (NFC_RW_ONLY == FALSE)
     72     ,
     73     /* this can not be set here due to 2079xB0 NFCC issues */
     74     {NCI_PROTOCOL_NFC_DEP, NCI_INTERFACE_MODE_POLL_N_LISTEN,
     75      NCI_INTERFACE_NFC_DEP}
     76 #endif
     77 };
     78 
     79 #if (BT_TRACE_VERBOSE == TRUE)
     80 /*******************************************************************************
     81 **
     82 ** Function         nfc_state_name
     83 **
     84 ** Description      This function returns the state name.
     85 **
     86 ** NOTE             conditionally compiled to save memory.
     87 **
     88 ** Returns          pointer to the name
     89 **
     90 *******************************************************************************/
     91 static char* nfc_state_name(uint8_t state) {
     92   switch (state) {
     93     case NFC_STATE_NONE:
     94       return ("NONE");
     95     case NFC_STATE_W4_HAL_OPEN:
     96       return ("W4_HAL_OPEN");
     97     case NFC_STATE_CORE_INIT:
     98       return ("CORE_INIT");
     99     case NFC_STATE_W4_POST_INIT_CPLT:
    100       return ("W4_POST_INIT_CPLT");
    101     case NFC_STATE_IDLE:
    102       return ("IDLE");
    103     case NFC_STATE_OPEN:
    104       return ("OPEN");
    105     case NFC_STATE_CLOSING:
    106       return ("CLOSING");
    107     case NFC_STATE_W4_HAL_CLOSE:
    108       return ("W4_HAL_CLOSE");
    109     case NFC_STATE_NFCC_POWER_OFF_SLEEP:
    110       return ("NFCC_POWER_OFF_SLEEP");
    111     default:
    112       return ("???? UNKNOWN STATE");
    113   }
    114 }
    115 
    116 /*******************************************************************************
    117 **
    118 ** Function         nfc_hal_event_name
    119 **
    120 ** Description      This function returns the HAL event name.
    121 **
    122 ** NOTE             conditionally compiled to save memory.
    123 **
    124 ** Returns          pointer to the name
    125 **
    126 *******************************************************************************/
    127 static char* nfc_hal_event_name(uint8_t event) {
    128   switch (event) {
    129     case HAL_NFC_OPEN_CPLT_EVT:
    130       return ("HAL_NFC_OPEN_CPLT_EVT");
    131 
    132     case HAL_NFC_CLOSE_CPLT_EVT:
    133       return ("HAL_NFC_CLOSE_CPLT_EVT");
    134 
    135     case HAL_NFC_POST_INIT_CPLT_EVT:
    136       return ("HAL_NFC_POST_INIT_CPLT_EVT");
    137 
    138     case HAL_NFC_PRE_DISCOVER_CPLT_EVT:
    139       return ("HAL_NFC_PRE_DISCOVER_CPLT_EVT");
    140 
    141     case HAL_NFC_REQUEST_CONTROL_EVT:
    142       return ("HAL_NFC_REQUEST_CONTROL_EVT");
    143 
    144     case HAL_NFC_RELEASE_CONTROL_EVT:
    145       return ("HAL_NFC_RELEASE_CONTROL_EVT");
    146 
    147     case HAL_NFC_ERROR_EVT:
    148       return ("HAL_NFC_ERROR_EVT");
    149 
    150     default:
    151       return ("???? UNKNOWN EVENT");
    152   }
    153 }
    154 #endif /* BT_TRACE_VERBOSE == TRUE */
    155 
    156 /*******************************************************************************
    157 **
    158 ** Function         nfc_main_notify_enable_status
    159 **
    160 ** Description      Notify status of Enable/PowerOffSleep/PowerCycle
    161 **
    162 *******************************************************************************/
    163 static void nfc_main_notify_enable_status(tNFC_STATUS nfc_status) {
    164   tNFC_RESPONSE evt_data;
    165 
    166   evt_data.status = nfc_status;
    167 
    168   if (nfc_cb.p_resp_cback) {
    169     /* if getting out of PowerOffSleep mode or restarting NFCC */
    170     if (nfc_cb.flags & (NFC_FL_RESTARTING | NFC_FL_POWER_CYCLE_NFCC)) {
    171       nfc_cb.flags &= ~(NFC_FL_RESTARTING | NFC_FL_POWER_CYCLE_NFCC);
    172       if (nfc_status != NFC_STATUS_OK) {
    173         nfc_cb.flags |= NFC_FL_POWER_OFF_SLEEP;
    174       }
    175       (*nfc_cb.p_resp_cback)(NFC_NFCC_RESTART_REVT, &evt_data);
    176     } else {
    177       (*nfc_cb.p_resp_cback)(NFC_ENABLE_REVT, &evt_data);
    178     }
    179   }
    180 }
    181 
    182 /*******************************************************************************
    183 **
    184 ** Function         nfc_enabled
    185 **
    186 ** Description      NFCC enabled, proceed with stack start up.
    187 **
    188 ** Returns          void
    189 **
    190 *******************************************************************************/
    191 void nfc_enabled(tNFC_STATUS nfc_status, NFC_HDR* p_init_rsp_msg) {
    192   tNFC_RESPONSE evt_data;
    193   tNFC_CONN_CB* p_cb = &nfc_cb.conn_cb[NFC_RF_CONN_ID];
    194   uint8_t* p;
    195   uint8_t num_interfaces = 0, xx;
    196   int yy = 0;
    197 
    198   memset(&evt_data, 0, sizeof(tNFC_RESPONSE));
    199 
    200   if (nfc_status == NCI_STATUS_OK) {
    201     nfc_set_state(NFC_STATE_IDLE);
    202 
    203     p = (uint8_t*)(p_init_rsp_msg + 1) + p_init_rsp_msg->offset +
    204         NCI_MSG_HDR_SIZE + 1;
    205     /* we currently only support NCI of the same version.
    206     * We may need to change this, when we support multiple version of NFCC */
    207     evt_data.enable.nci_version = NCI_VERSION;
    208     STREAM_TO_UINT32(evt_data.enable.nci_features, p);
    209     STREAM_TO_UINT8(num_interfaces, p);
    210 
    211     evt_data.enable.nci_interfaces = 0;
    212     for (xx = 0; xx < num_interfaces; xx++) {
    213       if ((*p) <= NCI_INTERFACE_MAX)
    214         evt_data.enable.nci_interfaces |= (1 << (*p));
    215       else if (((*p) >= NCI_INTERFACE_FIRST_VS) &&
    216                (yy < NFC_NFCC_MAX_NUM_VS_INTERFACE)) {
    217         /* save the VS RF interface in control block, if there's still room */
    218         nfc_cb.vs_interface[yy++] = *p;
    219       }
    220       p++;
    221     }
    222     nfc_cb.nci_interfaces = evt_data.enable.nci_interfaces;
    223     memcpy(evt_data.enable.vs_interface, nfc_cb.vs_interface,
    224            NFC_NFCC_MAX_NUM_VS_INTERFACE);
    225     evt_data.enable.max_conn = *p++;
    226     STREAM_TO_UINT16(evt_data.enable.max_ce_table, p);
    227 #if (NFC_RW_ONLY == FALSE)
    228     nfc_cb.max_ce_table = evt_data.enable.max_ce_table;
    229     nfc_cb.nci_features = evt_data.enable.nci_features;
    230     nfc_cb.max_conn = evt_data.enable.max_conn;
    231 #endif
    232     nfc_cb.nci_ctrl_size = *p++; /* Max Control Packet Payload Length */
    233     p_cb->init_credits = p_cb->num_buff = 0;
    234     STREAM_TO_UINT16(evt_data.enable.max_param_size, p);
    235     nfc_set_conn_id(p_cb, NFC_RF_CONN_ID);
    236     evt_data.enable.manufacture_id = *p++;
    237     STREAM_TO_ARRAY(evt_data.enable.nfcc_info, p, NFC_NFCC_INFO_LEN);
    238     NFC_DiscoveryMap(nfc_cb.num_disc_maps,
    239                      (tNCI_DISCOVER_MAPS*)nfc_cb.p_disc_maps, NULL);
    240   }
    241   /* else not successful. the buffers will be freed in nfc_free_conn_cb () */
    242   else {
    243     if (nfc_cb.flags & NFC_FL_RESTARTING) {
    244       nfc_set_state(NFC_STATE_NFCC_POWER_OFF_SLEEP);
    245     } else {
    246       nfc_free_conn_cb(p_cb);
    247 
    248       /* if NFCC didn't respond to CORE_RESET or CORE_INIT */
    249       if (nfc_cb.nfc_state == NFC_STATE_CORE_INIT) {
    250         /* report status after closing HAL */
    251         nfc_cb.p_hal->close();
    252         return;
    253       } else
    254         nfc_set_state(NFC_STATE_NONE);
    255     }
    256   }
    257 
    258   nfc_main_notify_enable_status(nfc_status);
    259 }
    260 
    261 /*******************************************************************************
    262 **
    263 ** Function         nfc_set_state
    264 **
    265 ** Description      Set the state of NFC stack
    266 **
    267 ** Returns          void
    268 **
    269 *******************************************************************************/
    270 void nfc_set_state(tNFC_STATE nfc_state) {
    271 #if (BT_TRACE_VERBOSE == TRUE)
    272   NFC_TRACE_DEBUG4("nfc_set_state %d (%s)->%d (%s)", nfc_cb.nfc_state,
    273                    nfc_state_name(nfc_cb.nfc_state), nfc_state,
    274                    nfc_state_name(nfc_state));
    275 #else
    276   NFC_TRACE_DEBUG2("nfc_set_state %d->%d", nfc_cb.nfc_state, nfc_state);
    277 #endif
    278   nfc_cb.nfc_state = nfc_state;
    279 }
    280 
    281 /*******************************************************************************
    282 **
    283 ** Function         nfc_gen_cleanup
    284 **
    285 ** Description      Clean up for both going into low power mode and disabling
    286 **                  NFC
    287 **
    288 *******************************************************************************/
    289 void nfc_gen_cleanup(void) {
    290   nfc_cb.flags &= ~NFC_FL_DEACTIVATING;
    291 
    292   /* the HAL pre-discover is still active - clear the pending flag/free the
    293    * buffer */
    294   if (nfc_cb.flags & NFC_FL_DISCOVER_PENDING) {
    295     nfc_cb.flags &= ~NFC_FL_DISCOVER_PENDING;
    296     GKI_freebuf(nfc_cb.p_disc_pending);
    297     nfc_cb.p_disc_pending = NULL;
    298   }
    299 
    300   nfc_cb.flags &= ~(NFC_FL_CONTROL_REQUESTED | NFC_FL_CONTROL_GRANTED |
    301                     NFC_FL_HAL_REQUESTED);
    302 
    303   nfc_stop_timer(&nfc_cb.deactivate_timer);
    304 
    305   /* Reset the connection control blocks */
    306   nfc_reset_all_conn_cbs();
    307 
    308   if (nfc_cb.p_nci_init_rsp) {
    309     GKI_freebuf(nfc_cb.p_nci_init_rsp);
    310     nfc_cb.p_nci_init_rsp = NULL;
    311   }
    312 
    313   /* clear any pending CMD/RSP */
    314   nfc_main_flush_cmd_queue();
    315 }
    316 
    317 /*******************************************************************************
    318 **
    319 ** Function         nfc_main_handle_hal_evt
    320 **
    321 ** Description      Handle BT_EVT_TO_NFC_MSGS
    322 **
    323 *******************************************************************************/
    324 void nfc_main_handle_hal_evt(tNFC_HAL_EVT_MSG* p_msg) {
    325   uint8_t* ps;
    326 
    327   NFC_TRACE_DEBUG1("nfc_main_handle_hal_evt(): HAL event=0x%x", p_msg->hal_evt);
    328 
    329   switch (p_msg->hal_evt) {
    330     case HAL_NFC_OPEN_CPLT_EVT: /* only for failure case */
    331       nfc_enabled(NFC_STATUS_FAILED, NULL);
    332       break;
    333 
    334     case HAL_NFC_CLOSE_CPLT_EVT:
    335       if (nfc_cb.p_resp_cback) {
    336         if (nfc_cb.nfc_state == NFC_STATE_W4_HAL_CLOSE) {
    337           if (nfc_cb.flags & NFC_FL_POWER_OFF_SLEEP) {
    338             nfc_cb.flags &= ~NFC_FL_POWER_OFF_SLEEP;
    339             nfc_set_state(NFC_STATE_NFCC_POWER_OFF_SLEEP);
    340             (*nfc_cb.p_resp_cback)(NFC_NFCC_POWER_OFF_REVT, NULL);
    341           } else {
    342             nfc_set_state(NFC_STATE_NONE);
    343             (*nfc_cb.p_resp_cback)(NFC_DISABLE_REVT, NULL);
    344             nfc_cb.p_resp_cback = NULL;
    345           }
    346         } else {
    347           /* found error during initialization */
    348           nfc_set_state(NFC_STATE_NONE);
    349           nfc_main_notify_enable_status(NFC_STATUS_FAILED);
    350         }
    351       }
    352       break;
    353 
    354     case HAL_NFC_POST_INIT_CPLT_EVT:
    355       if (nfc_cb.p_nci_init_rsp) {
    356         /*
    357         ** if NFC_Disable() is called before receiving
    358         ** HAL_NFC_POST_INIT_CPLT_EVT, then wait for HAL_NFC_CLOSE_CPLT_EVT.
    359         */
    360         if (nfc_cb.nfc_state == NFC_STATE_W4_POST_INIT_CPLT) {
    361           if (p_msg->status == HAL_NFC_STATUS_OK) {
    362             nfc_enabled(NCI_STATUS_OK, nfc_cb.p_nci_init_rsp);
    363           } else /* if post initailization failed */
    364           {
    365             nfc_enabled(NCI_STATUS_FAILED, NULL);
    366           }
    367         }
    368 
    369         GKI_freebuf(nfc_cb.p_nci_init_rsp);
    370         nfc_cb.p_nci_init_rsp = NULL;
    371       }
    372       break;
    373 
    374     case HAL_NFC_PRE_DISCOVER_CPLT_EVT:
    375       /* restore the command window, no matter if the discover command is still
    376        * pending */
    377       nfc_cb.nci_cmd_window = NCI_MAX_CMD_WINDOW;
    378       nfc_cb.flags &= ~NFC_FL_CONTROL_GRANTED;
    379       if (nfc_cb.flags & NFC_FL_DISCOVER_PENDING) {
    380         /* issue the discovery command now, if it is still pending */
    381         nfc_cb.flags &= ~NFC_FL_DISCOVER_PENDING;
    382         ps = (uint8_t*)nfc_cb.p_disc_pending;
    383         nci_snd_discover_cmd(*ps, (tNFC_DISCOVER_PARAMS*)(ps + 1));
    384         GKI_freebuf(nfc_cb.p_disc_pending);
    385         nfc_cb.p_disc_pending = NULL;
    386       } else {
    387         /* check if there's other pending commands */
    388         nfc_ncif_check_cmd_queue(NULL);
    389       }
    390 
    391       if (p_msg->status == HAL_NFC_STATUS_ERR_CMD_TIMEOUT)
    392         nfc_ncif_event_status(NFC_NFCC_TIMEOUT_REVT, NFC_STATUS_HW_TIMEOUT);
    393       break;
    394 
    395     case HAL_NFC_REQUEST_CONTROL_EVT:
    396       nfc_cb.flags |= NFC_FL_CONTROL_REQUESTED;
    397       nfc_cb.flags |= NFC_FL_HAL_REQUESTED;
    398       nfc_ncif_check_cmd_queue(NULL);
    399       break;
    400 
    401     case HAL_NFC_RELEASE_CONTROL_EVT:
    402       if (nfc_cb.flags & NFC_FL_CONTROL_GRANTED) {
    403         nfc_cb.flags &= ~NFC_FL_CONTROL_GRANTED;
    404         nfc_cb.nci_cmd_window = NCI_MAX_CMD_WINDOW;
    405         nfc_ncif_check_cmd_queue(NULL);
    406 
    407         if (p_msg->status == HAL_NFC_STATUS_ERR_CMD_TIMEOUT)
    408           nfc_ncif_event_status(NFC_NFCC_TIMEOUT_REVT, NFC_STATUS_HW_TIMEOUT);
    409       }
    410       break;
    411 
    412     case HAL_NFC_ERROR_EVT:
    413       switch (p_msg->status) {
    414         case HAL_NFC_STATUS_ERR_TRANSPORT:
    415           /* Notify app of transport error */
    416           if (nfc_cb.p_resp_cback) {
    417             (*nfc_cb.p_resp_cback)(NFC_NFCC_TRANSPORT_ERR_REVT, NULL);
    418 
    419             /* if enabling NFC, notify upper layer of failure after closing HAL
    420              */
    421             if (nfc_cb.nfc_state < NFC_STATE_IDLE) {
    422               nfc_enabled(NFC_STATUS_FAILED, NULL);
    423             }
    424           }
    425           break;
    426 
    427         case HAL_NFC_STATUS_ERR_CMD_TIMEOUT:
    428           nfc_ncif_event_status(NFC_NFCC_TIMEOUT_REVT, NFC_STATUS_HW_TIMEOUT);
    429 
    430           /* if enabling NFC, notify upper layer of failure after closing HAL */
    431           if (nfc_cb.nfc_state < NFC_STATE_IDLE) {
    432             nfc_enabled(NFC_STATUS_FAILED, NULL);
    433             return;
    434           }
    435           break;
    436 
    437         default:
    438           break;
    439       }
    440       break;
    441 
    442     default:
    443       NFC_TRACE_ERROR1("nfc_main_handle_hal_evt (): unhandled event (0x%x).",
    444                        p_msg->hal_evt);
    445       break;
    446   }
    447 }
    448 
    449 /*******************************************************************************
    450 **
    451 ** Function         nfc_main_flush_cmd_queue
    452 **
    453 ** Description      This function is called when setting power off sleep state.
    454 **
    455 ** Returns          void
    456 **
    457 *******************************************************************************/
    458 void nfc_main_flush_cmd_queue(void) {
    459   NFC_HDR* p_msg;
    460 
    461   NFC_TRACE_DEBUG0("nfc_main_flush_cmd_queue ()");
    462 
    463   /* initialize command window */
    464   nfc_cb.nci_cmd_window = NCI_MAX_CMD_WINDOW;
    465 
    466   /* Stop command-pending timer */
    467   nfc_stop_timer(&nfc_cb.nci_wait_rsp_timer);
    468 
    469   /* dequeue and free buffer */
    470   while ((p_msg = (NFC_HDR*)GKI_dequeue(&nfc_cb.nci_cmd_xmit_q)) != NULL) {
    471     GKI_freebuf(p_msg);
    472   }
    473 }
    474 
    475 /*******************************************************************************
    476 **
    477 ** Function         nfc_main_post_hal_evt
    478 **
    479 ** Description      This function posts HAL event to NFC_TASK
    480 **
    481 ** Returns          void
    482 **
    483 *******************************************************************************/
    484 void nfc_main_post_hal_evt(uint8_t hal_evt, tHAL_NFC_STATUS status) {
    485   tNFC_HAL_EVT_MSG* p_msg;
    486 
    487   p_msg = (tNFC_HAL_EVT_MSG*)GKI_getbuf(sizeof(tNFC_HAL_EVT_MSG));
    488   if (p_msg != NULL) {
    489     /* Initialize NFC_HDR */
    490     p_msg->hdr.len = 0;
    491     p_msg->hdr.event = BT_EVT_TO_NFC_MSGS;
    492     p_msg->hdr.offset = 0;
    493     p_msg->hdr.layer_specific = 0;
    494     p_msg->hal_evt = hal_evt;
    495     p_msg->status = status;
    496     GKI_send_msg(NFC_TASK, NFC_MBOX_ID, p_msg);
    497   } else {
    498     NFC_TRACE_ERROR0("nfc_main_post_hal_evt (): No buffer");
    499   }
    500 }
    501 
    502 /*******************************************************************************
    503 **
    504 ** Function         nfc_main_hal_cback
    505 **
    506 ** Description      HAL event handler
    507 **
    508 ** Returns          void
    509 **
    510 *******************************************************************************/
    511 static void nfc_main_hal_cback(uint8_t event, tHAL_NFC_STATUS status) {
    512 #if (BT_TRACE_VERBOSE == TRUE)
    513   NFC_TRACE_DEBUG3("nfc_main_hal_cback event: %s(0x%x), status=%d",
    514                    nfc_hal_event_name(event), event, status);
    515 #else
    516   NFC_TRACE_DEBUG2("nfc_main_hal_cback event: 0x%x, status=%d", event, status);
    517 #endif
    518 
    519   switch (event) {
    520     case HAL_NFC_OPEN_CPLT_EVT:
    521       /*
    522       ** if NFC_Disable() is called before receiving HAL_NFC_OPEN_CPLT_EVT,
    523       ** then wait for HAL_NFC_CLOSE_CPLT_EVT.
    524       */
    525       if (nfc_cb.nfc_state == NFC_STATE_W4_HAL_OPEN) {
    526         if (status == HAL_NFC_STATUS_OK) {
    527           /* Notify NFC_TASK that NCI tranport is initialized */
    528           GKI_send_event(NFC_TASK, NFC_TASK_EVT_TRANSPORT_READY);
    529         } else {
    530           nfc_main_post_hal_evt(event, status);
    531         }
    532       }
    533       break;
    534 
    535     case HAL_NFC_CLOSE_CPLT_EVT:
    536     case HAL_NFC_POST_INIT_CPLT_EVT:
    537     case HAL_NFC_PRE_DISCOVER_CPLT_EVT:
    538     case HAL_NFC_REQUEST_CONTROL_EVT:
    539     case HAL_NFC_RELEASE_CONTROL_EVT:
    540     case HAL_NFC_ERROR_EVT:
    541       nfc_main_post_hal_evt(event, status);
    542       break;
    543 
    544     default:
    545       NFC_TRACE_DEBUG1("nfc_main_hal_cback unhandled event %x", event);
    546       break;
    547   }
    548 }
    549 
    550 /*******************************************************************************
    551 **
    552 ** Function         nfc_main_hal_data_cback
    553 **
    554 ** Description      HAL data event handler
    555 **
    556 ** Returns          void
    557 **
    558 *******************************************************************************/
    559 static void nfc_main_hal_data_cback(uint16_t data_len, uint8_t* p_data) {
    560   NFC_HDR* p_msg;
    561 
    562   /* ignore all data while shutting down NFCC */
    563   if (nfc_cb.nfc_state == NFC_STATE_W4_HAL_CLOSE) {
    564     return;
    565   }
    566 
    567   if (p_data) {
    568     p_msg = (NFC_HDR*)GKI_getpoolbuf(NFC_NCI_POOL_ID);
    569     if (p_msg != NULL) {
    570       /* Initialize NFC_HDR */
    571       p_msg->len = data_len;
    572       p_msg->event = BT_EVT_TO_NFC_NCI;
    573       p_msg->offset = NFC_RECEIVE_MSGS_OFFSET;
    574 
    575       /* no need to check length, it always less than pool size */
    576       memcpy((uint8_t*)(p_msg + 1) + p_msg->offset, p_data, p_msg->len);
    577 
    578       GKI_send_msg(NFC_TASK, NFC_MBOX_ID, p_msg);
    579     } else {
    580       NFC_TRACE_ERROR0("nfc_main_hal_data_cback (): No buffer");
    581     }
    582   }
    583 }
    584 
    585 /*******************************************************************************
    586 **
    587 ** Function         NFC_Enable
    588 **
    589 ** Description      This function enables NFC. Prior to calling NFC_Enable:
    590 **                  - the NFCC must be powered up, and ready to receive
    591 **                    commands.
    592 **                  - GKI must be enabled
    593 **                  - NFC_TASK must be started
    594 **                  - NCIT_TASK must be started (if using dedicated NCI
    595 **                    transport)
    596 **
    597 **                  This function opens the NCI transport (if applicable),
    598 **                  resets the NFC controller, and initializes the NFC
    599 **                  subsystems.
    600 **
    601 **                  When the NFC startup procedure is completed, an
    602 **                  NFC_ENABLE_REVT is returned to the application using the
    603 **                  tNFC_RESPONSE_CBACK.
    604 **
    605 ** Returns          tNFC_STATUS
    606 **
    607 *******************************************************************************/
    608 tNFC_STATUS NFC_Enable(tNFC_RESPONSE_CBACK* p_cback) {
    609   NFC_TRACE_API0("NFC_Enable ()");
    610 
    611   /* Validate callback */
    612   if (!p_cback) {
    613     return (NFC_STATUS_INVALID_PARAM);
    614   }
    615   nfc_cb.p_resp_cback = p_cback;
    616 
    617   /* Open HAL transport. */
    618   nfc_set_state(NFC_STATE_W4_HAL_OPEN);
    619   nfc_cb.p_hal->open(nfc_main_hal_cback, nfc_main_hal_data_cback);
    620 
    621   return (NFC_STATUS_OK);
    622 }
    623 
    624 /*******************************************************************************
    625 **
    626 ** Function         NFC_Disable
    627 **
    628 ** Description      This function performs clean up routines for shutting down
    629 **                  NFC and closes the NCI transport (if using dedicated NCI
    630 **                  transport).
    631 **
    632 **                  When the NFC shutdown procedure is completed, an
    633 **                  NFC_DISABLED_REVT is returned to the application using the
    634 **                  tNFC_RESPONSE_CBACK.
    635 **
    636 ** Returns          nothing
    637 **
    638 *******************************************************************************/
    639 void NFC_Disable(void) {
    640   NFC_TRACE_API1("NFC_Disable (): nfc_state = %d", nfc_cb.nfc_state);
    641 
    642   if ((nfc_cb.nfc_state == NFC_STATE_NONE) ||
    643       (nfc_cb.nfc_state == NFC_STATE_NFCC_POWER_OFF_SLEEP)) {
    644     nfc_set_state(NFC_STATE_NONE);
    645     if (nfc_cb.p_resp_cback) {
    646       (*nfc_cb.p_resp_cback)(NFC_DISABLE_REVT, NULL);
    647       nfc_cb.p_resp_cback = NULL;
    648     }
    649     return;
    650   }
    651 
    652   /* Close transport and clean up */
    653   nfc_task_shutdown_nfcc();
    654 }
    655 
    656 /*******************************************************************************
    657 **
    658 ** Function         NFC_Init
    659 **
    660 ** Description      This function initializes control block for NFC
    661 **
    662 ** Returns          nothing
    663 **
    664 *******************************************************************************/
    665 void NFC_Init(tHAL_NFC_ENTRY* p_hal_entry_tbl) {
    666   int xx;
    667 
    668   /* Clear nfc control block */
    669   memset(&nfc_cb, 0, sizeof(tNFC_CB));
    670 
    671   /* Reset the nfc control block */
    672   for (xx = 0; xx < NCI_MAX_CONN_CBS; xx++) {
    673     nfc_cb.conn_cb[xx].conn_id = NFC_ILLEGAL_CONN_ID;
    674   }
    675 
    676   /* NCI init */
    677   nfc_cb.p_hal = p_hal_entry_tbl;
    678   nfc_cb.nfc_state = NFC_STATE_NONE;
    679   nfc_cb.nci_cmd_window = NCI_MAX_CMD_WINDOW;
    680   nfc_cb.nci_wait_rsp_tout = NFC_CMD_CMPL_TIMEOUT;
    681   nfc_cb.p_disc_maps = nfc_interface_mapping;
    682   nfc_cb.num_disc_maps = NFC_NUM_INTERFACE_MAP;
    683   nfc_cb.trace_level = NFC_INITIAL_TRACE_LEVEL;
    684   nfc_cb.nci_ctrl_size = NCI_CTRL_INIT_SIZE;
    685   nfc_cb.reassembly = true;
    686 
    687   rw_init();
    688   ce_init();
    689   llcp_init();
    690   NFC_SET_MAX_CONN_DEFAULT();
    691 }
    692 
    693 /*******************************************************************************
    694 **
    695 ** Function         NFC_GetLmrtSize
    696 **
    697 ** Description      Called by application wto query the Listen Mode Routing
    698 **                  Table size supported by NFCC
    699 **
    700 ** Returns          Listen Mode Routing Table size
    701 **
    702 *******************************************************************************/
    703 uint16_t NFC_GetLmrtSize(void) {
    704   uint16_t size = 0;
    705 #if (NFC_RW_ONLY == FALSE)
    706   size = nfc_cb.max_ce_table;
    707 #endif
    708   return size;
    709 }
    710 
    711 /*******************************************************************************
    712 **
    713 ** Function         NFC_SetConfig
    714 **
    715 ** Description      This function is called to send the configuration parameter
    716 **                  TLV to NFCC. The response from NFCC is reported by
    717 **                  tNFC_RESPONSE_CBACK as NFC_SET_CONFIG_REVT.
    718 **
    719 ** Parameters       tlv_size - the length of p_param_tlvs.
    720 **                  p_param_tlvs - the parameter ID/Len/Value list
    721 **
    722 ** Returns          tNFC_STATUS
    723 **
    724 *******************************************************************************/
    725 tNFC_STATUS NFC_SetConfig(uint8_t tlv_size, uint8_t* p_param_tlvs) {
    726   return nci_snd_core_set_config(p_param_tlvs, tlv_size);
    727 }
    728 
    729 /*******************************************************************************
    730 **
    731 ** Function         NFC_GetConfig
    732 **
    733 ** Description      This function is called to retrieve the parameter TLV from
    734 **                  NFCC. The response from NFCC is reported by
    735 **                  tNFC_RESPONSE_CBACK as NFC_GET_CONFIG_REVT.
    736 **
    737 ** Parameters       num_ids - the number of parameter IDs
    738 **                  p_param_ids - the parameter ID list.
    739 **
    740 ** Returns          tNFC_STATUS
    741 **
    742 *******************************************************************************/
    743 tNFC_STATUS NFC_GetConfig(uint8_t num_ids, uint8_t* p_param_ids) {
    744   return nci_snd_core_get_config(p_param_ids, num_ids);
    745 }
    746 
    747 /*******************************************************************************
    748 **
    749 ** Function         NFC_DiscoveryMap
    750 **
    751 ** Description      This function is called to set the discovery interface
    752 **                  mapping. The response from NFCC is reported by
    753 **                  tNFC_DISCOVER_CBACK as NFC_MAP_DEVT.
    754 **
    755 ** Parameters       num - the number of items in p_params.
    756 **                  p_maps - the discovery interface mappings
    757 **                  p_cback - the discovery callback function
    758 **
    759 ** Returns          tNFC_STATUS
    760 **
    761 *******************************************************************************/
    762 tNFC_STATUS NFC_DiscoveryMap(uint8_t num, tNFC_DISCOVER_MAPS* p_maps,
    763                              tNFC_DISCOVER_CBACK* p_cback) {
    764   uint8_t num_disc_maps = num;
    765   uint8_t xx, yy, num_intf, intf_mask;
    766   tNFC_DISCOVER_MAPS
    767       max_maps[NFC_NFCC_MAX_NUM_VS_INTERFACE + NCI_INTERFACE_MAX];
    768   bool is_supported;
    769 
    770   nfc_cb.p_discv_cback = p_cback;
    771   num_intf = 0;
    772   NFC_TRACE_DEBUG1("nci_interfaces supported by NFCC: 0x%x",
    773                    nfc_cb.nci_interfaces);
    774 
    775   for (xx = 0; xx < NFC_NFCC_MAX_NUM_VS_INTERFACE + NCI_INTERFACE_MAX; xx++) {
    776     memset(&max_maps[xx], 0x00, sizeof(tNFC_DISCOVER_MAPS));
    777   }
    778 
    779   for (xx = 0; xx < num_disc_maps; xx++) {
    780     is_supported = false;
    781     if (p_maps[xx].intf_type > NCI_INTERFACE_MAX) {
    782       for (yy = 0; yy < NFC_NFCC_MAX_NUM_VS_INTERFACE; yy++) {
    783         if (nfc_cb.vs_interface[yy] == p_maps[xx].intf_type)
    784           is_supported = true;
    785       }
    786       NFC_TRACE_DEBUG3("[%d]: vs intf_type:0x%x is_supported:%d", xx,
    787                        p_maps[xx].intf_type, is_supported);
    788     } else {
    789       intf_mask = (1 << (p_maps[xx].intf_type));
    790       if (intf_mask & nfc_cb.nci_interfaces) {
    791         is_supported = true;
    792       }
    793       NFC_TRACE_DEBUG4("[%d]: intf_type:%d intf_mask: 0x%x is_supported:%d", xx,
    794                        p_maps[xx].intf_type, intf_mask, is_supported);
    795     }
    796     if (is_supported)
    797       memcpy(&max_maps[num_intf++], &p_maps[xx], sizeof(tNFC_DISCOVER_MAPS));
    798     else {
    799       NFC_TRACE_WARNING1(
    800           "NFC_DiscoveryMap interface=0x%x is not supported by NFCC",
    801           p_maps[xx].intf_type);
    802     }
    803   }
    804 
    805   return nci_snd_discover_map_cmd(num_intf, (tNCI_DISCOVER_MAPS*)max_maps);
    806 }
    807 
    808 /*******************************************************************************
    809 **
    810 ** Function         NFC_DiscoveryStart
    811 **
    812 ** Description      This function is called to start Polling and/or Listening.
    813 **                  The response from NFCC is reported by tNFC_DISCOVER_CBACK as
    814 **                  NFC_START_DEVT. The notification from NFCC is reported by
    815 **                  tNFC_DISCOVER_CBACK as NFC_RESULT_DEVT.
    816 **
    817 ** Parameters       num_params - the number of items in p_params.
    818 **                  p_params - the discovery parameters
    819 **                  p_cback - the discovery callback function
    820 **
    821 ** Returns          tNFC_STATUS
    822 **
    823 *******************************************************************************/
    824 tNFC_STATUS NFC_DiscoveryStart(uint8_t num_params,
    825                                tNFC_DISCOVER_PARAMS* p_params,
    826                                tNFC_DISCOVER_CBACK* p_cback) {
    827   uint8_t* p;
    828   int params_size;
    829   tNFC_STATUS status = NFC_STATUS_NO_BUFFERS;
    830 
    831   NFC_TRACE_API0("NFC_DiscoveryStart");
    832   if (nfc_cb.p_disc_pending) {
    833     NFC_TRACE_ERROR0("There's pending NFC_DiscoveryStart");
    834     status = NFC_STATUS_BUSY;
    835   } else {
    836     nfc_cb.p_discv_cback = p_cback;
    837     nfc_cb.flags |= NFC_FL_DISCOVER_PENDING;
    838     nfc_cb.flags |= NFC_FL_CONTROL_REQUESTED;
    839     params_size = sizeof(tNFC_DISCOVER_PARAMS) * num_params;
    840     nfc_cb.p_disc_pending =
    841         GKI_getbuf((uint16_t)(NFC_HDR_SIZE + 1 + params_size));
    842     if (nfc_cb.p_disc_pending) {
    843       p = (uint8_t*)nfc_cb.p_disc_pending;
    844       *p++ = num_params;
    845       memcpy(p, p_params, params_size);
    846       status = NFC_STATUS_CMD_STARTED;
    847       nfc_ncif_check_cmd_queue(NULL);
    848     }
    849   }
    850 
    851   NFC_TRACE_API1("NFC_DiscoveryStart status: 0x%x", status);
    852   return status;
    853 }
    854 
    855 /*******************************************************************************
    856 **
    857 ** Function         NFC_DiscoverySelect
    858 **
    859 ** Description      If tNFC_DISCOVER_CBACK reports status=NFC_MULTIPLE_PROT,
    860 **                  the application needs to use this function to select the
    861 **                  the logical endpoint to continue. The response from NFCC is
    862 **                  reported by tNFC_DISCOVER_CBACK as NFC_SELECT_DEVT.
    863 **
    864 ** Parameters       rf_disc_id - The ID identifies the remote device.
    865 **                  protocol - the logical endpoint on the remote devide
    866 **                  rf_interface - the RF interface to communicate with NFCC
    867 **
    868 ** Returns          tNFC_STATUS
    869 **
    870 *******************************************************************************/
    871 tNFC_STATUS NFC_DiscoverySelect(uint8_t rf_disc_id, uint8_t protocol,
    872                                 uint8_t rf_interface) {
    873   return nci_snd_discover_select_cmd(rf_disc_id, protocol, rf_interface);
    874 }
    875 
    876 /*******************************************************************************
    877 **
    878 ** Function         NFC_ConnCreate
    879 **
    880 ** Description      This function is called to create a logical connection with
    881 **                  NFCC for data exchange.
    882 **
    883 ** Parameters       dest_type - the destination type
    884 **                  id   - the NFCEE ID or RF Discovery ID .
    885 **                  protocol   - the protocol.
    886 **                  p_cback - the connection callback function
    887 **
    888 ** Returns          tNFC_STATUS
    889 **
    890 *******************************************************************************/
    891 tNFC_STATUS NFC_ConnCreate(uint8_t dest_type, uint8_t id, uint8_t protocol,
    892                            tNFC_CONN_CBACK* p_cback) {
    893   tNFC_STATUS status = NFC_STATUS_FAILED;
    894   tNFC_CONN_CB* p_cb;
    895   uint8_t num_tlv = 0, tlv_size = 0;
    896   uint8_t param_tlvs[4], *pp;
    897 
    898   p_cb = nfc_alloc_conn_cb(p_cback);
    899   if (p_cb) {
    900     p_cb->id = id;
    901     pp = param_tlvs;
    902     if (dest_type == NCI_DEST_TYPE_NFCEE) {
    903       num_tlv = 1;
    904       UINT8_TO_STREAM(pp, NCI_CON_CREATE_TAG_NFCEE_VAL);
    905       UINT8_TO_STREAM(pp, 2);
    906       UINT8_TO_STREAM(pp, id);
    907       UINT8_TO_STREAM(pp, protocol);
    908       tlv_size = 4;
    909     } else if (dest_type == NCI_DEST_TYPE_REMOTE) {
    910       num_tlv = 1;
    911       UINT8_TO_STREAM(pp, NCI_CON_CREATE_TAG_RF_DISC_ID);
    912       UINT8_TO_STREAM(pp, 1);
    913       UINT8_TO_STREAM(pp, id);
    914       tlv_size = 3;
    915     } else if (dest_type == NCI_DEST_TYPE_NFCC) {
    916       p_cb->id = NFC_TEST_ID;
    917     }
    918     /* Add handling of NCI_DEST_TYPE_REMOTE when more RF interface definitions
    919      * are added */
    920     p_cb->act_protocol = protocol;
    921     p_cb->p_cback = p_cback;
    922     status = nci_snd_core_conn_create(dest_type, num_tlv, tlv_size, param_tlvs);
    923     if (status == NFC_STATUS_FAILED) nfc_free_conn_cb(p_cb);
    924   }
    925   return status;
    926 }
    927 
    928 /*******************************************************************************
    929 **
    930 ** Function         NFC_ConnClose
    931 **
    932 ** Description      This function is called to close a logical connection with
    933 **                  NFCC.
    934 **
    935 ** Parameters       conn_id - the connection id.
    936 **
    937 ** Returns          tNFC_STATUS
    938 **
    939 *******************************************************************************/
    940 tNFC_STATUS NFC_ConnClose(uint8_t conn_id) {
    941   tNFC_CONN_CB* p_cb = nfc_find_conn_cb_by_conn_id(conn_id);
    942   tNFC_STATUS status = NFC_STATUS_FAILED;
    943 
    944   if (p_cb) {
    945     status = nci_snd_core_conn_close(conn_id);
    946   }
    947   return status;
    948 }
    949 
    950 /*******************************************************************************
    951 **
    952 ** Function         NFC_SetStaticRfCback
    953 **
    954 ** Description      This function is called to update the data callback function
    955 **                  to receive the data for the given connection id.
    956 **
    957 ** Parameters       p_cback - the connection callback function
    958 **
    959 ** Returns          Nothing
    960 **
    961 *******************************************************************************/
    962 void NFC_SetStaticRfCback(tNFC_CONN_CBACK* p_cback) {
    963   tNFC_CONN_CB* p_cb = &nfc_cb.conn_cb[NFC_RF_CONN_ID];
    964 
    965   p_cb->p_cback = p_cback;
    966   /* just in case DH has received NCI data before the data callback is set
    967    * check if there's any data event to report on this connection id */
    968   nfc_data_event(p_cb);
    969 }
    970 
    971 /*******************************************************************************
    972 **
    973 ** Function         NFC_SetReassemblyFlag
    974 **
    975 ** Description      This function is called to set if nfc will reassemble
    976 **                  nci packet as much as its buffer can hold or it should not
    977 **                  reassemble but forward the fragmented nci packet to layer
    978 **                  above. If nci data pkt is fragmented, nfc may send multiple
    979 **                  NFC_DATA_CEVT with status NFC_STATUS_CONTINUE before sending
    980 **                  NFC_DATA_CEVT with status NFC_STATUS_OK based on reassembly
    981 **                  configuration and reassembly buffer size
    982 **
    983 ** Parameters       reassembly - flag to indicate if nfc may reassemble or not
    984 **
    985 ** Returns          Nothing
    986 **
    987 *******************************************************************************/
    988 void NFC_SetReassemblyFlag(bool reassembly) { nfc_cb.reassembly = reassembly; }
    989 
    990 /*******************************************************************************
    991 **
    992 ** Function         NFC_SendData
    993 **
    994 ** Description      This function is called to send the given data packet
    995 **                  to the connection identified by the given connection id.
    996 **
    997 ** Parameters       conn_id - the connection id.
    998 **                  p_data - the data packet.
    999 **                  p_data->offset must be >= NCI_MSG_OFFSET_SIZE +
   1000 **                  NCI_DATA_HDR_SIZE
   1001 **                  The data payload starts at
   1002 **                  ((uint8_t *) (p_data + 1) + p_data->offset)
   1003 **
   1004 ** Returns          tNFC_STATUS
   1005 **
   1006 *******************************************************************************/
   1007 tNFC_STATUS NFC_SendData(uint8_t conn_id, NFC_HDR* p_data) {
   1008   tNFC_STATUS status = NFC_STATUS_FAILED;
   1009   tNFC_CONN_CB* p_cb = nfc_find_conn_cb_by_conn_id(conn_id);
   1010 
   1011   if (p_cb && p_data &&
   1012       p_data->offset >= NCI_MSG_OFFSET_SIZE + NCI_DATA_HDR_SIZE) {
   1013     status = nfc_ncif_send_data(p_cb, p_data);
   1014   }
   1015 
   1016   if (status != NFC_STATUS_OK) GKI_freebuf(p_data);
   1017 
   1018   return status;
   1019 }
   1020 
   1021 /*******************************************************************************
   1022 **
   1023 ** Function         NFC_FlushData
   1024 **
   1025 ** Description      This function is called to discard the tx data queue of
   1026 **                  the given connection id.
   1027 **
   1028 ** Parameters       conn_id - the connection id.
   1029 **
   1030 ** Returns          tNFC_STATUS
   1031 **
   1032 *******************************************************************************/
   1033 tNFC_STATUS NFC_FlushData(uint8_t conn_id) {
   1034   tNFC_STATUS status = NFC_STATUS_FAILED;
   1035   tNFC_CONN_CB* p_cb = nfc_find_conn_cb_by_conn_id(conn_id);
   1036   void* p_buf;
   1037 
   1038   if (p_cb) {
   1039     status = NFC_STATUS_OK;
   1040     while ((p_buf = GKI_dequeue(&p_cb->tx_q)) != NULL) GKI_freebuf(p_buf);
   1041   }
   1042 
   1043   return status;
   1044 }
   1045 
   1046 /*******************************************************************************
   1047 **
   1048 ** Function         NFC_Deactivate
   1049 **
   1050 ** Description      This function is called to stop the discovery process or
   1051 **                  put the listen device in sleep mode or terminate the NFC
   1052 **                  link.
   1053 **
   1054 **                  The response from NFCC is reported by tNFC_DISCOVER_CBACK
   1055 **                  as NFC_DEACTIVATE_DEVT.
   1056 **
   1057 ** Parameters       deactivate_type - NFC_DEACTIVATE_TYPE_IDLE, to IDLE mode.
   1058 **                                    NFC_DEACTIVATE_TYPE_SLEEP to SLEEP mode.
   1059 **                                    NFC_DEACTIVATE_TYPE_SLEEP_AF to SLEEP_AF
   1060 **                                    mode.
   1061 **
   1062 ** Returns          tNFC_STATUS
   1063 **
   1064 *******************************************************************************/
   1065 tNFC_STATUS NFC_Deactivate(tNFC_DEACT_TYPE deactivate_type) {
   1066   tNFC_CONN_CB* p_cb = &nfc_cb.conn_cb[NFC_RF_CONN_ID];
   1067   tNFC_STATUS status = NFC_STATUS_OK;
   1068 
   1069 #if (BT_TRACE_VERBOSE == TRUE)
   1070   NFC_TRACE_API3("NFC_Deactivate %d (%s) deactivate_type:%d", nfc_cb.nfc_state,
   1071                  nfc_state_name(nfc_cb.nfc_state), deactivate_type);
   1072 #else
   1073   NFC_TRACE_API2("NFC_Deactivate %d deactivate_type:%d", nfc_cb.nfc_state,
   1074                  deactivate_type);
   1075 #endif
   1076 
   1077   if (nfc_cb.flags & NFC_FL_DISCOVER_PENDING) {
   1078     /* the HAL pre-discover is still active - clear the pending flag */
   1079     nfc_cb.flags &= ~NFC_FL_DISCOVER_PENDING;
   1080     if (!(nfc_cb.flags & NFC_FL_HAL_REQUESTED)) {
   1081       /* if HAL did not request for control, clear this bit now */
   1082       nfc_cb.flags &= ~NFC_FL_CONTROL_REQUESTED;
   1083     }
   1084     GKI_freebuf(nfc_cb.p_disc_pending);
   1085     nfc_cb.p_disc_pending = NULL;
   1086     return NFC_STATUS_OK;
   1087   }
   1088 
   1089   if (nfc_cb.nfc_state == NFC_STATE_OPEN) {
   1090     nfc_set_state(NFC_STATE_CLOSING);
   1091     NFC_TRACE_DEBUG3("act_protocol %d credits:%d/%d", p_cb->act_protocol,
   1092                      p_cb->init_credits, p_cb->num_buff);
   1093     if ((p_cb->act_protocol == NCI_PROTOCOL_NFC_DEP) &&
   1094         (p_cb->init_credits != p_cb->num_buff)) {
   1095       nfc_cb.flags |= NFC_FL_DEACTIVATING;
   1096       nfc_cb.deactivate_timer.param = (uintptr_t)deactivate_type;
   1097       nfc_start_timer(&nfc_cb.deactivate_timer,
   1098                       (uint16_t)(NFC_TTYPE_WAIT_2_DEACTIVATE),
   1099                       NFC_DEACTIVATE_TIMEOUT);
   1100       return status;
   1101     }
   1102   }
   1103 
   1104   status = nci_snd_deactivate_cmd(deactivate_type);
   1105   return status;
   1106 }
   1107 
   1108 /*******************************************************************************
   1109 **
   1110 ** Function         NFC_UpdateRFCommParams
   1111 **
   1112 ** Description      This function is called to update RF Communication
   1113 **                  parameters once the Frame RF Interface has been activated.
   1114 **
   1115 **                  The response from NFCC is reported by tNFC_RESPONSE_CBACK
   1116 **                  as NFC_RF_COMM_PARAMS_UPDATE_REVT.
   1117 **
   1118 ** Returns          tNFC_STATUS
   1119 **
   1120 *******************************************************************************/
   1121 tNFC_STATUS NFC_UpdateRFCommParams(tNFC_RF_COMM_PARAMS* p_params) {
   1122   uint8_t tlvs[12];
   1123   uint8_t* p = tlvs;
   1124   uint8_t data_exch_config;
   1125 
   1126   /* RF Technology and Mode */
   1127   if (p_params->include_rf_tech_mode) {
   1128     UINT8_TO_STREAM(p, NCI_RF_PARAM_ID_TECH_N_MODE);
   1129     UINT8_TO_STREAM(p, 1);
   1130     UINT8_TO_STREAM(p, p_params->rf_tech_n_mode);
   1131   }
   1132 
   1133   /* Transmit Bit Rate */
   1134   if (p_params->include_tx_bit_rate) {
   1135     UINT8_TO_STREAM(p, NCI_RF_PARAM_ID_TX_BIT_RATE);
   1136     UINT8_TO_STREAM(p, 1);
   1137     UINT8_TO_STREAM(p, p_params->tx_bit_rate);
   1138   }
   1139 
   1140   /* Receive Bit Rate */
   1141   if (p_params->include_tx_bit_rate) {
   1142     UINT8_TO_STREAM(p, NCI_RF_PARAM_ID_RX_BIT_RATE);
   1143     UINT8_TO_STREAM(p, 1);
   1144     UINT8_TO_STREAM(p, p_params->rx_bit_rate);
   1145   }
   1146 
   1147   /* NFC-B Data Exchange Configuration */
   1148   if (p_params->include_nfc_b_config) {
   1149     UINT8_TO_STREAM(p, NCI_RF_PARAM_ID_B_DATA_EX_PARAM);
   1150     UINT8_TO_STREAM(p, 1);
   1151 
   1152     data_exch_config = (p_params->min_tr0 & 0x03) << 6; /* b7b6 : Mininum TR0 */
   1153     data_exch_config |= (p_params->min_tr1 & 0x03)
   1154                         << 4; /* b5b4 : Mininum TR1 */
   1155     data_exch_config |= (p_params->suppression_eos & 0x01)
   1156                         << 3; /* b3 :   Suppression of EoS */
   1157     data_exch_config |= (p_params->suppression_sos & 0x01)
   1158                         << 2; /* b2 :   Suppression of SoS */
   1159     data_exch_config |= (p_params->min_tr2 & 0x03); /* b1b0 : Mininum TR2 */
   1160 
   1161     UINT8_TO_STREAM(p, data_exch_config);
   1162   }
   1163 
   1164   return nci_snd_parameter_update_cmd(tlvs, (uint8_t)(p - tlvs));
   1165 }
   1166 
   1167 /*******************************************************************************
   1168 **
   1169 ** Function         NFC_SetPowerOffSleep
   1170 **
   1171 ** Description      This function closes/opens transport and turns off/on NFCC.
   1172 **
   1173 ** Returns          tNFC_STATUS
   1174 **
   1175 *******************************************************************************/
   1176 tNFC_STATUS NFC_SetPowerOffSleep(bool enable) {
   1177   NFC_TRACE_API1("NFC_SetPowerOffSleep () enable = %d", enable);
   1178 
   1179   if ((enable == false) &&
   1180       (nfc_cb.nfc_state == NFC_STATE_NFCC_POWER_OFF_SLEEP)) {
   1181     nfc_cb.flags |= NFC_FL_RESTARTING;
   1182 
   1183     /* open transport */
   1184     nfc_set_state(NFC_STATE_W4_HAL_OPEN);
   1185     nfc_cb.p_hal->open(nfc_main_hal_cback, nfc_main_hal_data_cback);
   1186 
   1187     return NFC_STATUS_OK;
   1188   } else if ((enable == true) && (nfc_cb.nfc_state == NFC_STATE_IDLE)) {
   1189     /* close transport to turn off NFCC and clean up */
   1190     nfc_cb.flags |= NFC_FL_POWER_OFF_SLEEP;
   1191     nfc_task_shutdown_nfcc();
   1192 
   1193     return NFC_STATUS_OK;
   1194   }
   1195 
   1196   NFC_TRACE_ERROR1("NFC_SetPowerOffSleep () invalid state = %d",
   1197                    nfc_cb.nfc_state);
   1198   return NFC_STATUS_FAILED;
   1199 }
   1200 
   1201 /*******************************************************************************
   1202 **
   1203 ** Function         NFC_PowerCycleNFCC
   1204 **
   1205 ** Description      This function turns off and then on NFCC.
   1206 **
   1207 ** Returns          tNFC_STATUS
   1208 **
   1209 *******************************************************************************/
   1210 tNFC_STATUS NFC_PowerCycleNFCC(void) {
   1211   NFC_TRACE_API0("NFC_PowerCycleNFCC ()");
   1212 
   1213   if (nfc_cb.nfc_state == NFC_STATE_IDLE) {
   1214     /* power cycle NFCC */
   1215     nfc_cb.flags |= NFC_FL_POWER_CYCLE_NFCC;
   1216     nfc_task_shutdown_nfcc();
   1217 
   1218     return NFC_STATUS_OK;
   1219   }
   1220 
   1221   NFC_TRACE_ERROR1("NFC_PowerCycleNFCC () invalid state = %d",
   1222                    nfc_cb.nfc_state);
   1223   return NFC_STATUS_FAILED;
   1224 }
   1225 
   1226 /*******************************************************************************
   1227 **
   1228 ** Function         NFC_SetTraceLevel
   1229 **
   1230 ** Description      This function sets the trace level for NFC.  If called with
   1231 **                  a value of 0xFF, it simply returns the current trace level.
   1232 **
   1233 ** Returns          The new or current trace level
   1234 **
   1235 *******************************************************************************/
   1236 uint8_t NFC_SetTraceLevel(uint8_t new_level) {
   1237   NFC_TRACE_API1("NFC_SetTraceLevel () new_level = %d", new_level);
   1238 
   1239   if (new_level != 0xFF) nfc_cb.trace_level = new_level;
   1240 
   1241   return (nfc_cb.trace_level);
   1242 }
   1243 
   1244 #if (BT_TRACE_VERBOSE == TRUE)
   1245 /*******************************************************************************
   1246 **
   1247 ** Function         NFC_GetStatusName
   1248 **
   1249 ** Description      This function returns the status name.
   1250 **
   1251 ** NOTE             conditionally compiled to save memory.
   1252 **
   1253 ** Returns          pointer to the name
   1254 **
   1255 *******************************************************************************/
   1256 char* NFC_GetStatusName(tNFC_STATUS status) {
   1257   switch (status) {
   1258     case NFC_STATUS_OK:
   1259       return "OK";
   1260     case NFC_STATUS_REJECTED:
   1261       return "REJECTED";
   1262     case NFC_STATUS_MSG_CORRUPTED:
   1263       return "CORRUPTED";
   1264     case NFC_STATUS_BUFFER_FULL:
   1265       return "BUFFER_FULL";
   1266     case NFC_STATUS_FAILED:
   1267       return "FAILED";
   1268     case NFC_STATUS_NOT_INITIALIZED:
   1269       return "NOT_INITIALIZED";
   1270     case NFC_STATUS_SYNTAX_ERROR:
   1271       return "SYNTAX_ERROR";
   1272     case NFC_STATUS_SEMANTIC_ERROR:
   1273       return "SEMANTIC_ERROR";
   1274     case NFC_STATUS_UNKNOWN_GID:
   1275       return "UNKNOWN_GID";
   1276     case NFC_STATUS_UNKNOWN_OID:
   1277       return "UNKNOWN_OID";
   1278     case NFC_STATUS_INVALID_PARAM:
   1279       return "INVALID_PARAM";
   1280     case NFC_STATUS_MSG_SIZE_TOO_BIG:
   1281       return "MSG_SIZE_TOO_BIG";
   1282     case NFC_STATUS_ALREADY_STARTED:
   1283       return "ALREADY_STARTED";
   1284     case NFC_STATUS_ACTIVATION_FAILED:
   1285       return "ACTIVATION_FAILED";
   1286     case NFC_STATUS_TEAR_DOWN:
   1287       return "TEAR_DOWN";
   1288     case NFC_STATUS_RF_TRANSMISSION_ERR:
   1289       return "RF_TRANSMISSION_ERR";
   1290     case NFC_STATUS_RF_PROTOCOL_ERR:
   1291       return "RF_PROTOCOL_ERR";
   1292     case NFC_STATUS_TIMEOUT:
   1293       return "TIMEOUT";
   1294     case NFC_STATUS_EE_INTF_ACTIVE_FAIL:
   1295       return "EE_INTF_ACTIVE_FAIL";
   1296     case NFC_STATUS_EE_TRANSMISSION_ERR:
   1297       return "EE_TRANSMISSION_ERR";
   1298     case NFC_STATUS_EE_PROTOCOL_ERR:
   1299       return "EE_PROTOCOL_ERR";
   1300     case NFC_STATUS_EE_TIMEOUT:
   1301       return "EE_TIMEOUT";
   1302     case NFC_STATUS_CMD_STARTED:
   1303       return "CMD_STARTED";
   1304     case NFC_STATUS_HW_TIMEOUT:
   1305       return "HW_TIMEOUT";
   1306     case NFC_STATUS_CONTINUE:
   1307       return "CONTINUE";
   1308     case NFC_STATUS_REFUSED:
   1309       return "REFUSED";
   1310     case NFC_STATUS_BAD_RESP:
   1311       return "BAD_RESP";
   1312     case NFC_STATUS_CMD_NOT_CMPLTD:
   1313       return "CMD_NOT_CMPLTD";
   1314     case NFC_STATUS_NO_BUFFERS:
   1315       return "NO_BUFFERS";
   1316     case NFC_STATUS_WRONG_PROTOCOL:
   1317       return "WRONG_PROTOCOL";
   1318     case NFC_STATUS_BUSY:
   1319       return "BUSY";
   1320     case NFC_STATUS_LINK_LOSS:
   1321       return "LINK_LOSS";
   1322     case NFC_STATUS_BAD_LENGTH:
   1323       return "BAD_LENGTH";
   1324     case NFC_STATUS_BAD_HANDLE:
   1325       return "BAD_HANDLE";
   1326     case NFC_STATUS_CONGESTED:
   1327       return "CONGESTED";
   1328     default:
   1329       return "UNKNOWN";
   1330   }
   1331 }
   1332 #endif
   1333