Home | History | Annotate | Download | only in hal
      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  *  Functions for handling NFC HAL NCI Transport events
     22  *
     23  ******************************************************************************/
     24 #include <string.h>
     25 #include "nfc_hal_int.h"
     26 #include "nfc_hal_post_reset.h"
     27 #include "upio.h"
     28 #include "userial.h"
     29 
     30 /****************************************************************************
     31 ** Definitions
     32 ****************************************************************************/
     33 
     34 /* Default NFC HAL NCI port configuration  */
     35 NFC_HAL_TRANS_CFG_QUALIFIER tNFC_HAL_TRANS_CFG nfc_hal_trans_cfg = {
     36     NFC_HAL_SHARED_TRANSPORT_ENABLED, /* bSharedTransport */
     37     USERIAL_BAUD_115200,              /* Baud rate */
     38     USERIAL_FC_HW                     /* Flow control */
     39 };
     40 
     41 /* Control block for NFC HAL NCI transport */
     42 tNFC_HAL_CB nfc_hal_cb;
     43 
     44 extern tNFC_HAL_CFG* p_nfc_hal_cfg;
     45 /****************************************************************************
     46 ** Internal function prototypes
     47 ****************************************************************************/
     48 static void nfc_hal_main_userial_cback(tUSERIAL_PORT port, tUSERIAL_EVT evt,
     49                                        tUSERIAL_EVT_DATA* p_data);
     50 static void nfc_hal_main_handle_terminate(void);
     51 static void nfc_hal_main_timeout_cback(void* p_tle);
     52 
     53 #if (NFC_HAL_DEBUG == TRUE)
     54 const char* const nfc_hal_init_state_str[] = {
     55     "IDLE",           /* Initialization is done                */
     56     "W4_XTAL_SET",    /* Waiting for crystal setting rsp       */
     57     "POST_XTAL_SET",  /* Waiting for reset ntf after xtal set  */
     58     "W4_NFCC_ENABLE", /* Waiting for reset ntf atter REG_PU up */
     59     "W4_BUILD_INFO",  /* Waiting for build info rsp            */
     60     "W4_PATCH_INFO",  /* Waiting for patch info rsp            */
     61     "W4_APP_COMPL",   /* Waiting for complete from application */
     62     "W4_POST_INIT",   /* Waiting for complete of post init     */
     63     "W4_CONTROL",     /* Waiting for control release           */
     64     "W4_PREDISC",     /* Waiting for complete of prediscover   */
     65     "CLOSING"         /* Shutting down                         */
     66 };
     67 #endif
     68 
     69 /*******************************************************************************
     70 **
     71 ** Function         nfc_hal_main_init
     72 **
     73 ** Description      This function initializes control block for NFC HAL
     74 **
     75 ** Returns          nothing
     76 **
     77 *******************************************************************************/
     78 void nfc_hal_main_init(void) {
     79   /* Clear control block */
     80   memset(&nfc_hal_cb, 0, sizeof(tNFC_HAL_CB));
     81 
     82   nfc_hal_cb.ncit_cb.nci_ctrl_size = NFC_HAL_NCI_INIT_CTRL_PAYLOAD_SIZE;
     83   nfc_hal_cb.trace_level = NFC_HAL_INITIAL_TRACE_LEVEL;
     84   nfc_hal_cb.timer.p_cback = nfc_hal_main_timeout_cback;
     85 }
     86 
     87 /*******************************************************************************
     88 **
     89 ** Function         nfc_hal_main_open_transport
     90 **
     91 ** Description      Open transport and prepare for new incoming message;
     92 **
     93 ** Returns          nothing
     94 **
     95 *******************************************************************************/
     96 static void nfc_hal_main_open_transport(void) {
     97   tUSERIAL_OPEN_CFG open_cfg;
     98 
     99   /* Initialize control block */
    100   nfc_hal_cb.ncit_cb.rcv_state =
    101       NFC_HAL_RCV_IDLE_ST; /* to process packet type */
    102 
    103   if (nfc_hal_cb.ncit_cb.p_rcv_msg) {
    104     GKI_freebuf(nfc_hal_cb.ncit_cb.p_rcv_msg);
    105     nfc_hal_cb.ncit_cb.p_rcv_msg = NULL;
    106   }
    107 
    108   /* open transport */
    109   open_cfg.fmt =
    110       (USERIAL_DATABITS_8 | USERIAL_PARITY_NONE | USERIAL_STOPBITS_1);
    111   open_cfg.baud = nfc_hal_trans_cfg.userial_baud;
    112   open_cfg.fc = nfc_hal_trans_cfg.userial_fc;
    113   open_cfg.buf = USERIAL_BUF_BYTE;
    114 
    115   USERIAL_Open(USERIAL_NFC_PORT, &open_cfg, nfc_hal_main_userial_cback);
    116 
    117   {
    118     /* Wait for NFCC to enable - Core reset notification */
    119     NFC_HAL_SET_INIT_STATE(NFC_HAL_INIT_STATE_W4_NFCC_ENABLE);
    120 
    121     /* NFCC Enable timeout */
    122     nfc_hal_main_start_quick_timer(
    123         &nfc_hal_cb.timer, NFC_HAL_TTYPE_NFCC_ENABLE,
    124         ((p_nfc_hal_cfg->nfc_hal_nfcc_enable_timeout) *
    125          QUICK_TIMER_TICKS_PER_SEC) /
    126             1000);
    127   }
    128 }
    129 
    130 /*******************************************************************************
    131 **
    132 ** Function         nfc_hal_main_close
    133 **
    134 ** Description      Check and shutdown NFCC
    135 **
    136 ** Returns          None
    137 **
    138 *******************************************************************************/
    139 void nfc_hal_main_close(void) {
    140   tHAL_NFC_CBACK* p_stack_cback_temp;
    141 
    142   if ((nfc_hal_cb.dev_cb.initializing_state !=
    143        NFC_HAL_INIT_STATE_W4_NFCC_TURN_OFF) &&
    144       (nfc_hal_cb.hal_flags & NFC_HAL_FLAGS_NEED_DISABLE_VSC)) {
    145     nfc_hal_cb.dev_cb.initializing_state = NFC_HAL_INIT_STATE_W4_NFCC_TURN_OFF;
    146     nfc_hal_dm_set_power_level_zero();
    147   } else {
    148     nfc_hal_main_handle_terminate();
    149 
    150     /* Close uart */
    151     USERIAL_Close(USERIAL_NFC_PORT);
    152 
    153     if (nfc_hal_cb.p_stack_cback) {
    154       p_stack_cback_temp = nfc_hal_cb.p_stack_cback;
    155       nfc_hal_cb.p_stack_cback = NULL;
    156       p_stack_cback_temp(HAL_NFC_CLOSE_CPLT_EVT, HAL_NFC_STATUS_OK);
    157     }
    158   }
    159 }
    160 
    161 /*******************************************************************************
    162 **
    163 ** Function         nfa_hal_pre_discover_done_cback
    164 **
    165 ** Description      Pre-discovery CFG is sent.
    166 **
    167 ** Returns          nothing
    168 **
    169 *******************************************************************************/
    170 void nfa_hal_pre_discover_done_cback(tNFC_HAL_NCI_EVT event, uint16_t data_len,
    171                                      uint8_t* p_data) {
    172   NFC_HAL_SET_INIT_STATE(NFC_HAL_INIT_STATE_IDLE);
    173   nfc_hal_main_stop_quick_timer(&nfc_hal_cb.ncit_cb.nci_wait_rsp_timer);
    174   nfc_hal_cb.p_stack_cback(HAL_NFC_PRE_DISCOVER_CPLT_EVT, HAL_NFC_STATUS_OK);
    175 }
    176 
    177 /*******************************************************************************
    178 **
    179 ** Function         nfa_hal_send_pre_discover_cfg
    180 **
    181 ** Description      sending Pre-discovery CFG
    182 **
    183 ** Returns          nothing
    184 **
    185 *******************************************************************************/
    186 void nfa_hal_send_pre_discover_cfg(void) {
    187   if (nfc_hal_dm_set_config(
    188           p_nfc_hal_pre_discover_cfg[0], &p_nfc_hal_pre_discover_cfg[1],
    189           nfa_hal_pre_discover_done_cback) != HAL_NFC_STATUS_OK) {
    190     nfa_hal_pre_discover_done_cback(0, 0, NULL);
    191   }
    192 }
    193 
    194 /*******************************************************************************
    195 **
    196 ** Function         nfc_hal_main_send_error
    197 **
    198 ** Description      send an Error event to NFC stack
    199 **
    200 ** Returns          nothing
    201 **
    202 *******************************************************************************/
    203 void nfc_hal_main_send_error(tHAL_NFC_STATUS status) {
    204   /* Notify stack */
    205   nfc_hal_cb.p_stack_cback(HAL_NFC_ERROR_EVT, status);
    206 }
    207 
    208 /*******************************************************************************
    209 **
    210 ** Function         nfc_hal_main_userial_cback
    211 **
    212 ** Description      USERIAL callback for NCI transport
    213 **
    214 ** Returns          nothing
    215 **
    216 *******************************************************************************/
    217 static void nfc_hal_main_userial_cback(tUSERIAL_PORT port, tUSERIAL_EVT evt,
    218                                        tUSERIAL_EVT_DATA* p_data) {
    219   if (evt == USERIAL_RX_READY_EVT) {
    220     /* Notify transport task of serial port event */
    221     GKI_send_event(NFC_HAL_TASK, NFC_HAL_TASK_EVT_DATA_RDY);
    222   } else if (evt == USERIAL_TX_DONE_EVT) {
    223     /* Serial driver has finshed sending data from USERIAL_Write */
    224     /* Currently, no action is needed for this event */
    225   } else if (evt == USERIAL_ERR_EVT) {
    226     HAL_TRACE_ERROR0(
    227         "nfc_hal_main_userial_cback: USERIAL_ERR_EVT. Notifying NFC_TASK of "
    228         "transport error");
    229     if (nfc_hal_cb.ncit_cb.nci_wait_rsp != NFC_HAL_WAIT_RSP_NONE) {
    230       nfc_hal_main_stop_quick_timer(&nfc_hal_cb.ncit_cb.nci_wait_rsp_timer);
    231       nfc_hal_nci_cmd_timeout_cback(
    232           (void*)&nfc_hal_cb.ncit_cb.nci_wait_rsp_timer);
    233     } else {
    234       nfc_hal_main_send_error(HAL_NFC_STATUS_ERR_TRANSPORT);
    235     }
    236   } else if (evt == USERIAL_WAKEUP_EVT) {
    237     HAL_TRACE_DEBUG1("nfc_hal_main_userial_cback: USERIAL_WAKEUP_EVT: %d",
    238                      p_data->sigs);
    239   } else {
    240     HAL_TRACE_DEBUG1("nfc_hal_main_userial_cback: unhandled userial evt: %i",
    241                      evt);
    242   }
    243 }
    244 
    245 /*******************************************************************************
    246 **
    247 ** Function         nfc_hal_main_exit_op_done
    248 **
    249 ** Description      handle completion of HAL exit operation
    250 **
    251 ** Returns          nothing
    252 **
    253 *******************************************************************************/
    254 void nfc_hal_main_exit_op_done(tNFC_HAL_NCI_EVT event, uint16_t data_len,
    255                                uint8_t* p_data) {
    256   nfc_hal_main_close();
    257 }
    258 
    259 /*******************************************************************************
    260 **
    261 ** Function         nfc_hal_main_pre_init_done
    262 **
    263 ** Description      notify complete of pre-initialization
    264 **
    265 ** Returns          nothing
    266 **
    267 *******************************************************************************/
    268 void nfc_hal_main_pre_init_done(tHAL_NFC_STATUS status) {
    269   HAL_TRACE_DEBUG1("nfc_hal_main_pre_init_done () status = %d", status);
    270 
    271   if (status != HAL_NFC_STATUS_OK) {
    272     nfc_hal_main_handle_terminate();
    273 
    274     /* Close uart */
    275     USERIAL_Close(USERIAL_NFC_PORT);
    276   }
    277 
    278   /* Notify NFC Task the status of initialization */
    279   nfc_hal_cb.p_stack_cback(HAL_NFC_OPEN_CPLT_EVT, status);
    280 }
    281 
    282 /*******************************************************************************
    283 **
    284 ** Function         nfc_hal_main_timeout_cback
    285 **
    286 ** Description      callback function for timeout
    287 **
    288 ** Returns          void
    289 **
    290 *******************************************************************************/
    291 static void nfc_hal_main_timeout_cback(void* p_tle) {
    292   TIMER_LIST_ENT* p_tlent = (TIMER_LIST_ENT*)p_tle;
    293 
    294   HAL_TRACE_DEBUG0("nfc_hal_main_timeout_cback ()");
    295 
    296   switch (p_tlent->event) {
    297     case NFC_HAL_TTYPE_POWER_CYCLE:
    298       nfc_hal_main_open_transport();
    299       break;
    300 
    301     case NFC_HAL_TTYPE_NFCC_ENABLE:
    302       /* NFCC should have enabled now, notify transport openned */
    303       nfc_hal_dm_pre_init_nfcc();
    304       break;
    305 
    306     default:
    307       HAL_TRACE_DEBUG1(
    308           "nfc_hal_main_timeout_cback: unhandled timer event (0x%04x)",
    309           p_tlent->event);
    310       break;
    311   }
    312 }
    313 
    314 /*******************************************************************************
    315 **
    316 ** Function         nfc_hal_main_handle_terminate
    317 **
    318 ** Description      Handle NFI transport shutdown
    319 **
    320 ** Returns          nothing
    321 **
    322 *******************************************************************************/
    323 static void nfc_hal_main_handle_terminate(void) {
    324   NFC_HDR* p_msg;
    325 
    326   /* dequeue and free buffer */
    327   if (nfc_hal_cb.ncit_cb.p_pend_cmd != NULL) {
    328     GKI_freebuf(nfc_hal_cb.ncit_cb.p_pend_cmd);
    329     nfc_hal_cb.ncit_cb.p_pend_cmd = NULL;
    330   }
    331 
    332   /* Free unsent nfc rx buffer */
    333   if (nfc_hal_cb.ncit_cb.p_rcv_msg) {
    334     GKI_freebuf(nfc_hal_cb.ncit_cb.p_rcv_msg);
    335     nfc_hal_cb.ncit_cb.p_rcv_msg = NULL;
    336   }
    337 
    338   /* Free buffer for pending fragmented response/notification */
    339   if (nfc_hal_cb.ncit_cb.p_frag_msg) {
    340     GKI_freebuf(nfc_hal_cb.ncit_cb.p_frag_msg);
    341     nfc_hal_cb.ncit_cb.p_frag_msg = NULL;
    342   }
    343 
    344   /* Free buffers in the tx mbox */
    345   while ((p_msg = (NFC_HDR*)GKI_read_mbox(NFC_HAL_TASK_MBOX)) != NULL) {
    346     GKI_freebuf(p_msg);
    347   }
    348 
    349   /* notify closing transport */
    350   nfc_hal_dm_shutting_down_nfcc();
    351 }
    352 
    353 /*******************************************************************************
    354 **
    355 ** Function         nfc_hal_main_start_quick_timer
    356 **
    357 ** Description      Start a timer for the specified amount of time.
    358 **                  NOTE: The timeout resolution depends on including modules.
    359 **                  QUICK_TIMER_TICKS_PER_SEC should be used to convert from
    360 **                  time to ticks.
    361 **
    362 **
    363 ** Returns          void
    364 **
    365 *******************************************************************************/
    366 void nfc_hal_main_start_quick_timer(TIMER_LIST_ENT* p_tle, uint16_t type,
    367                                     uint32_t timeout) {
    368   NFC_HDR* p_msg;
    369 
    370   /* if timer list is currently empty, start periodic GKI timer */
    371   if (nfc_hal_cb.quick_timer_queue.p_first == NULL) {
    372     /* if timer starts on other than NCIT task (script wrapper) */
    373     if (GKI_get_taskid() != NFC_HAL_TASK) {
    374       /* post event to start timer in NCIT task */
    375       p_msg = (NFC_HDR*)GKI_getbuf(NFC_HDR_SIZE);
    376       if (p_msg != NULL) {
    377         p_msg->event = NFC_HAL_EVT_TO_START_QUICK_TIMER;
    378         GKI_send_msg(NFC_HAL_TASK, NFC_HAL_TASK_MBOX, p_msg);
    379       }
    380     } else {
    381       GKI_start_timer(NFC_HAL_QUICK_TIMER_ID,
    382                       ((GKI_SECS_TO_TICKS(1) / QUICK_TIMER_TICKS_PER_SEC)),
    383                       true);
    384     }
    385   }
    386 
    387   GKI_remove_from_timer_list(&nfc_hal_cb.quick_timer_queue, p_tle);
    388 
    389   p_tle->event = type;
    390   p_tle->ticks = timeout; /* Save the number of ticks for the timer */
    391 
    392   GKI_add_to_timer_list(&nfc_hal_cb.quick_timer_queue, p_tle);
    393 }
    394 
    395 /*******************************************************************************
    396 **
    397 ** Function         nfc_hal_main_stop_quick_timer
    398 **
    399 ** Description      Stop a timer.
    400 **
    401 ** Returns          void
    402 **
    403 *******************************************************************************/
    404 void nfc_hal_main_stop_quick_timer(TIMER_LIST_ENT* p_tle) {
    405   GKI_remove_from_timer_list(&nfc_hal_cb.quick_timer_queue, p_tle);
    406 
    407   /* if timer list is empty stop periodic GKI timer */
    408   if (nfc_hal_cb.quick_timer_queue.p_first == NULL) {
    409     GKI_stop_timer(NFC_HAL_QUICK_TIMER_ID);
    410   }
    411 }
    412 
    413 /*******************************************************************************
    414 **
    415 ** Function         nfc_hal_main_process_quick_timer_evt
    416 **
    417 ** Description      Process quick timer event
    418 **
    419 ** Returns          void
    420 **
    421 *******************************************************************************/
    422 static void nfc_hal_main_process_quick_timer_evt(void) {
    423   TIMER_LIST_ENT* p_tle;
    424 
    425   GKI_update_timer_list(&nfc_hal_cb.quick_timer_queue, 1);
    426 
    427   while ((nfc_hal_cb.quick_timer_queue.p_first) &&
    428          (!nfc_hal_cb.quick_timer_queue.p_first->ticks)) {
    429     p_tle = nfc_hal_cb.quick_timer_queue.p_first;
    430     GKI_remove_from_timer_list(&nfc_hal_cb.quick_timer_queue, p_tle);
    431 
    432     if (p_tle->p_cback) {
    433       (*p_tle->p_cback)(p_tle);
    434     }
    435   }
    436 
    437   /* if timer list is empty stop periodic GKI timer */
    438   if (nfc_hal_cb.quick_timer_queue.p_first == NULL) {
    439     GKI_stop_timer(NFC_HAL_QUICK_TIMER_ID);
    440   }
    441 }
    442 
    443 /*******************************************************************************
    444 **
    445 ** Function         nfc_hal_send_nci_msg_to_nfc_task
    446 **
    447 ** Description      This function is called to send nci message to nfc task
    448 **
    449 ** Returns          void
    450 **
    451 *******************************************************************************/
    452 void nfc_hal_send_nci_msg_to_nfc_task(NFC_HDR* p_msg) {
    453 #ifdef NFC_HAL_SHARED_GKI
    454   /* Using shared NFC/HAL GKI resources - send message buffer directly to
    455    * NFC_TASK for processing */
    456   p_msg->event = BT_EVT_TO_NFC_NCI;
    457   GKI_send_msg(NFC_TASK, NFC_MBOX_ID, p_msg);
    458 #else
    459   /* Send NCI message to the stack */
    460   nfc_hal_cb.p_data_cback(p_msg->len, (uint8_t*)((p_msg + 1) + p_msg->offset));
    461   GKI_freebuf(p_msg);
    462 #endif
    463 }
    464 
    465 /*******************************************************************************
    466 **
    467 ** Function         nfc_hal_send_credit_ntf_for_cid
    468 **
    469 ** Description      This function is called to send credit ntf
    470 **                  for the specified connection id to nfc task
    471 **
    472 ** Returns          void
    473 **
    474 *******************************************************************************/
    475 static void nfc_hal_send_credit_ntf_for_cid(uint8_t cid) {
    476   NFC_HDR* p_msg;
    477   uint8_t *p, *ps;
    478 
    479   /* Start of new message. Allocate a buffer for message */
    480   p_msg = (NFC_HDR*)GKI_getpoolbuf(NFC_HAL_NCI_POOL_ID);
    481   if (p_msg != NULL) {
    482     /* Initialize NFC_HDR */
    483     p_msg->len = NCI_DATA_HDR_SIZE + 0x03;
    484     p_msg->event = 0;
    485     p_msg->offset = 0;
    486     p_msg->layer_specific = 0;
    487 
    488     p = (uint8_t*)(p_msg + 1) + p_msg->offset;
    489     ps = p;
    490     NCI_MSG_BLD_HDR0(p, NCI_MT_NTF, NCI_GID_CORE);
    491     NCI_MSG_BLD_HDR1(p, NCI_MSG_CORE_CONN_CREDITS);
    492     UINT8_TO_STREAM(p, 0x03);
    493 
    494     /* Number of credit entries */
    495     *p++ = 0x01;
    496     /* Connection id of the credit ntf */
    497     *p++ = cid;
    498     /* Number of credits */
    499     *p = 0x01;
    500 #ifdef DISP_NCI
    501     DISP_NCI(ps, (uint16_t)p_msg->len, true);
    502 #endif
    503     nfc_hal_send_nci_msg_to_nfc_task(p_msg);
    504   } else {
    505     HAL_TRACE_ERROR0(
    506         "Unable to allocate buffer for Sending credit ntf to stack");
    507   }
    508 }
    509 
    510 /*******************************************************************************
    511 **
    512 ** Function         nfc_hal_main_send_message
    513 **
    514 ** Description      This function is calledto send an NCI message.
    515 **
    516 ** Returns          void
    517 **
    518 *******************************************************************************/
    519 static void nfc_hal_main_send_message(NFC_HDR* p_msg) {
    520 #if (NFC_HAL_HCI_INCLUDED == TRUE)
    521   uint8_t cid, pbf;
    522   uint16_t data_len;
    523 #endif
    524   uint8_t *ps, *pp;
    525   uint16_t len = p_msg->len;
    526 #ifdef DISP_NCI
    527   uint8_t delta;
    528 #endif
    529 
    530   HAL_TRACE_DEBUG1("nfc_hal_main_send_message() ls:0x%x",
    531                    p_msg->layer_specific);
    532   if ((p_msg->layer_specific == NFC_HAL_WAIT_RSP_CMD) ||
    533       (p_msg->layer_specific == NFC_HAL_WAIT_RSP_VSC)) {
    534     nfc_hal_nci_send_cmd(p_msg);
    535   } else {
    536     /* NFC task has fragmented the data packet to the appropriate size
    537      * and data credit is available; just send it */
    538 
    539     /* add NCI packet type in front of message */
    540     nfc_hal_nci_add_nfc_pkt_type(p_msg);
    541 
    542     /* send this packet to transport */
    543     ps = (uint8_t*)(p_msg + 1) + p_msg->offset;
    544     pp = ps + 1;
    545 #ifdef DISP_NCI
    546     delta = p_msg->len - len;
    547     DISP_NCI(ps + delta, (uint16_t)(p_msg->len - delta), false);
    548 #endif
    549 
    550 #if (NFC_HAL_HCI_INCLUDED == TRUE)
    551     if (nfc_hal_cb.hci_cb.hcp_conn_id) {
    552       NCI_DATA_PRS_HDR(pp, pbf, cid, data_len);
    553       if (cid == nfc_hal_cb.hci_cb.hcp_conn_id) {
    554         if (nfc_hal_hci_handle_hcp_pkt_to_hc(pp)) {
    555           HAL_TRACE_DEBUG0(
    556               "nfc_hal_main_send_message() - Drop rsp to Fake cmd, Fake credit "
    557               "ntf");
    558           GKI_freebuf(p_msg);
    559           nfc_hal_send_credit_ntf_for_cid(cid);
    560           return;
    561         }
    562       }
    563     }
    564 #endif
    565 
    566     /* check low power mode state */
    567     if (nfc_hal_dm_power_mode_execute(NFC_HAL_LP_TX_DATA_EVT)) {
    568       USERIAL_Write(USERIAL_NFC_PORT, ps, p_msg->len);
    569     } else {
    570       HAL_TRACE_ERROR0(
    571           "nfc_hal_main_send_message(): drop data in low power mode");
    572     }
    573     GKI_freebuf(p_msg);
    574   }
    575 }
    576 
    577 /*******************************************************************************
    578 **
    579 ** Function         nfc_hal_main_task
    580 **
    581 ** Description      NFC HAL NCI transport event processing task
    582 **
    583 ** Returns          0
    584 **
    585 *******************************************************************************/
    586 uint32_t nfc_hal_main_task(uint32_t param) {
    587   uint16_t event;
    588   uint8_t byte;
    589   uint8_t num_interfaces;
    590   uint8_t* p;
    591   NFC_HDR* p_msg;
    592   bool free_msg;
    593 
    594   HAL_TRACE_DEBUG0("NFC_HAL_TASK started");
    595 
    596   /* Main loop */
    597   while (true) {
    598     event = GKI_wait(0xFFFF, 0);
    599 
    600     /* Handle NFC_HAL_TASK_EVT_INITIALIZE (for initializing NCI transport) */
    601     if (event & NFC_HAL_TASK_EVT_INITIALIZE) {
    602       HAL_TRACE_DEBUG0(
    603           "NFC_HAL_TASK got NFC_HAL_TASK_EVT_INITIALIZE signal. Opening NFC "
    604           "transport...");
    605 
    606       nfc_hal_main_open_transport();
    607     }
    608 
    609     /* Check for terminate event */
    610     if (event & NFC_HAL_TASK_EVT_TERMINATE) {
    611       HAL_TRACE_DEBUG0("NFC_HAL_TASK got NFC_HAL_TASK_EVT_TERMINATE");
    612 
    613       nfc_hal_main_close();
    614 
    615       continue;
    616     }
    617 
    618     /* Check for power cycle event */
    619     if (event & NFC_HAL_TASK_EVT_POWER_CYCLE) {
    620       HAL_TRACE_DEBUG0("NFC_HAL_TASK got NFC_HAL_TASK_EVT_POWER_CYCLE");
    621       nfc_hal_main_handle_terminate();
    622 
    623       /* Close uart */
    624       USERIAL_Close(USERIAL_NFC_PORT);
    625 
    626       /* power cycle timeout */
    627       nfc_hal_main_start_quick_timer(
    628           &nfc_hal_cb.timer, NFC_HAL_TTYPE_POWER_CYCLE,
    629           (NFC_HAL_POWER_CYCLE_DELAY * QUICK_TIMER_TICKS_PER_SEC) / 1000);
    630       continue;
    631     }
    632 
    633     /* NCI message ready to be sent to NFCC */
    634     if (event & NFC_HAL_TASK_EVT_MBOX) {
    635       while ((p_msg = (NFC_HDR*)GKI_read_mbox(NFC_HAL_TASK_MBOX)) != NULL) {
    636         free_msg = true;
    637         switch (p_msg->event & NFC_EVT_MASK) {
    638           case NFC_HAL_EVT_TO_NFC_NCI:
    639             nfc_hal_main_send_message(p_msg);
    640             /* do not free buffer. NCI VS code may keep it for processing later
    641              */
    642             free_msg = false;
    643             break;
    644 
    645           case NFC_HAL_EVT_POST_CORE_RESET:
    646             NFC_HAL_SET_INIT_STATE(NFC_HAL_INIT_STATE_W4_POST_INIT_DONE);
    647 
    648             /* set NCI Control packet size from CORE_INIT_RSP */
    649             p = (uint8_t*)(p_msg + 1) + p_msg->offset + NCI_MSG_HDR_SIZE;
    650             p += 5;
    651             STREAM_TO_UINT8(num_interfaces, p);
    652             p += (num_interfaces + 3);
    653             nfc_hal_cb.ncit_cb.nci_ctrl_size = *p;
    654 
    655             /* start post initialization */
    656             nfc_hal_cb.dev_cb.next_dm_config = NFC_HAL_DM_CONFIG_LPTD;
    657             nfc_hal_cb.dev_cb.next_startup_vsc = 1;
    658 
    659             nfc_hal_dm_config_nfcc();
    660             break;
    661 
    662           case NFC_HAL_EVT_TO_START_QUICK_TIMER:
    663             GKI_start_timer(
    664                 NFC_HAL_QUICK_TIMER_ID,
    665                 ((GKI_SECS_TO_TICKS(1) / QUICK_TIMER_TICKS_PER_SEC)), true);
    666             break;
    667 
    668           case NFC_HAL_EVT_HCI:
    669             nfc_hal_hci_evt_hdlr((tNFC_HAL_HCI_EVENT_DATA*)p_msg);
    670             break;
    671 
    672           case NFC_HAL_EVT_PRE_DISCOVER:
    673             NFC_HAL_SET_INIT_STATE(NFC_HAL_INIT_STATE_W4_PREDISCOVER_DONE);
    674             nfa_hal_send_pre_discover_cfg();
    675             break;
    676 
    677           case NFC_HAL_EVT_CONTROL_GRANTED:
    678             nfc_hal_dm_send_pend_cmd();
    679             break;
    680 
    681           default:
    682             break;
    683         }
    684 
    685         if (free_msg) GKI_freebuf(p_msg);
    686       }
    687     }
    688 
    689     /* Data waiting to be read from serial port */
    690     if (event & NFC_HAL_TASK_EVT_DATA_RDY) {
    691       while (true) {
    692         /* Read one byte to see if there is anything waiting to be read */
    693         if (USERIAL_Read(USERIAL_NFC_PORT, &byte, 1) == 0) {
    694           break;
    695         }
    696 
    697         if (nfc_hal_nci_receive_msg(byte)) {
    698           /* complete of receiving NCI message */
    699           nfc_hal_nci_assemble_nci_msg();
    700           if (nfc_hal_cb.ncit_cb.p_rcv_msg) {
    701             if (nfc_hal_nci_preproc_rx_nci_msg(nfc_hal_cb.ncit_cb.p_rcv_msg)) {
    702               /* Send NCI message to the stack */
    703               nfc_hal_send_nci_msg_to_nfc_task(nfc_hal_cb.ncit_cb.p_rcv_msg);
    704             } else {
    705               if (nfc_hal_cb.ncit_cb.p_rcv_msg)
    706                 GKI_freebuf(nfc_hal_cb.ncit_cb.p_rcv_msg);
    707             }
    708             nfc_hal_cb.ncit_cb.p_rcv_msg = NULL;
    709           }
    710         }
    711       } /* while (TRUE) */
    712     }
    713 
    714     /* Process quick timer tick */
    715     if (event & NFC_HAL_QUICK_TIMER_EVT_MASK) {
    716       nfc_hal_main_process_quick_timer_evt();
    717     }
    718   }
    719 
    720   HAL_TRACE_DEBUG0("nfc_hal_main_task terminated");
    721 
    722   GKI_exit_task(GKI_get_taskid());
    723   return 0;
    724 }
    725 
    726 /*******************************************************************************
    727 **
    728 ** Function         HAL_NfcSetTraceLevel
    729 **
    730 ** Description      This function sets the trace level for HAL.  If called with
    731 **                  a value of 0xFF, it simply returns the current trace level.
    732 **
    733 ** Returns          The new or current trace level
    734 **
    735 *******************************************************************************/
    736 uint8_t HAL_NfcSetTraceLevel(uint8_t new_level) {
    737   if (new_level != 0xFF) nfc_hal_cb.trace_level = new_level;
    738 
    739   return (nfc_hal_cb.trace_level);
    740 }
    741