Home | History | Annotate | Download | only in ee
      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 is the main implementation file for the NFA EE.
     22  *
     23  ******************************************************************************/
     24 #include <string.h>
     25 #include "nfa_dm_int.h"
     26 #include "nfa_ee_int.h"
     27 #include "nfa_sys.h"
     28 #include "nfa_sys_int.h"
     29 #include "nfc_api.h"
     30 
     31 extern void nfa_ee_vs_cback(tNFC_VS_EVT event, NFC_HDR* p_data);
     32 /*****************************************************************************
     33 **  Global Variables
     34 *****************************************************************************/
     35 
     36 /* system manager control block definition */
     37 tNFA_EE_CB nfa_ee_cb;
     38 
     39 /*****************************************************************************
     40 **  Constants
     41 *****************************************************************************/
     42 static const tNFA_SYS_REG nfa_ee_sys_reg = {nfa_ee_sys_enable, nfa_ee_evt_hdlr,
     43                                             nfa_ee_sys_disable,
     44                                             nfa_ee_proc_nfcc_power_mode};
     45 
     46 #define NFA_EE_NUM_ACTIONS (NFA_EE_MAX_EVT & 0x00ff)
     47 
     48 const tNFA_EE_SM_ACT nfa_ee_actions[] = {
     49     /* NFA-EE action function/ internal events */
     50     nfa_ee_api_discover,      /* NFA_EE_API_DISCOVER_EVT      */
     51     nfa_ee_api_register,      /* NFA_EE_API_REGISTER_EVT      */
     52     nfa_ee_api_deregister,    /* NFA_EE_API_DEREGISTER_EVT    */
     53     nfa_ee_api_mode_set,      /* NFA_EE_API_MODE_SET_EVT      */
     54     nfa_ee_api_set_tech_cfg,  /* NFA_EE_API_SET_TECH_CFG_EVT  */
     55     nfa_ee_api_set_proto_cfg, /* NFA_EE_API_SET_PROTO_CFG_EVT */
     56     nfa_ee_api_add_aid,       /* NFA_EE_API_ADD_AID_EVT       */
     57     nfa_ee_api_remove_aid,    /* NFA_EE_API_REMOVE_AID_EVT    */
     58     nfa_ee_api_lmrt_size,     /* NFA_EE_API_LMRT_SIZE_EVT     */
     59     nfa_ee_api_update_now,    /* NFA_EE_API_UPDATE_NOW_EVT    */
     60     nfa_ee_api_connect,       /* NFA_EE_API_CONNECT_EVT       */
     61     nfa_ee_api_send_data,     /* NFA_EE_API_SEND_DATA_EVT     */
     62     nfa_ee_api_disconnect,    /* NFA_EE_API_DISCONNECT_EVT    */
     63     nfa_ee_nci_disc_rsp,      /* NFA_EE_NCI_DISC_RSP_EVT      */
     64     nfa_ee_nci_disc_ntf,      /* NFA_EE_NCI_DISC_NTF_EVT      */
     65     nfa_ee_nci_mode_set_rsp,  /* NFA_EE_NCI_MODE_SET_RSP_EVT  */
     66     nfa_ee_nci_conn,          /* NFA_EE_NCI_CONN_EVT          */
     67     nfa_ee_nci_conn,          /* NFA_EE_NCI_DATA_EVT          */
     68     nfa_ee_nci_action_ntf,    /* NFA_EE_NCI_ACTION_NTF_EVT    */
     69     nfa_ee_nci_disc_req_ntf,  /* NFA_EE_NCI_DISC_REQ_NTF_EVT  */
     70     nfa_ee_nci_wait_rsp,      /* NFA_EE_NCI_WAIT_RSP_EVT      */
     71     nfa_ee_rout_timeout,      /* NFA_EE_ROUT_TIMEOUT_EVT      */
     72     nfa_ee_discv_timeout,     /* NFA_EE_DISCV_TIMEOUT_EVT     */
     73     nfa_ee_lmrt_to_nfcc       /* NFA_EE_CFG_TO_NFCC_EVT       */
     74 };
     75 
     76 /*******************************************************************************
     77 **
     78 ** Function         nfa_ee_init
     79 **
     80 ** Description      Initialize NFA EE control block
     81 **                  register to NFA SYS
     82 **
     83 ** Returns          None
     84 **
     85 *******************************************************************************/
     86 void nfa_ee_init(void) {
     87   int xx;
     88 
     89   NFA_TRACE_DEBUG0("nfa_ee_init ()");
     90 
     91   /* initialize control block */
     92   memset(&nfa_ee_cb, 0, sizeof(tNFA_EE_CB));
     93   for (xx = 0; xx < NFA_EE_MAX_EE_SUPPORTED; xx++) {
     94     nfa_ee_cb.ecb[xx].nfcee_id = NFA_EE_INVALID;
     95     nfa_ee_cb.ecb[xx].ee_status = NFC_NFCEE_STATUS_INACTIVE;
     96   }
     97 
     98   nfa_ee_cb.ecb[NFA_EE_CB_4_DH].ee_status = NFC_NFCEE_STATUS_ACTIVE;
     99   nfa_ee_cb.ecb[NFA_EE_CB_4_DH].nfcee_id = NFC_DH_ID;
    100 
    101   /* register message handler on NFA SYS */
    102   nfa_sys_register(NFA_ID_EE, &nfa_ee_sys_reg);
    103 }
    104 
    105 /*******************************************************************************
    106 **
    107 ** Function         nfa_ee_sys_enable
    108 **
    109 ** Description      Enable NFA EE
    110 **
    111 ** Returns          None
    112 **
    113 *******************************************************************************/
    114 void nfa_ee_sys_enable(void) {
    115   if (nfa_ee_max_ee_cfg) {
    116     /* collect NFCEE information */
    117     NFC_NfceeDiscover(true);
    118     nfa_sys_start_timer(&nfa_ee_cb.discv_timer, NFA_EE_DISCV_TIMEOUT_EVT,
    119                         NFA_EE_DISCV_TIMEOUT_VAL);
    120   } else {
    121     nfa_ee_cb.em_state = NFA_EE_EM_STATE_INIT_DONE;
    122     nfa_sys_cback_notify_enable_complete(NFA_ID_EE);
    123   }
    124 }
    125 
    126 /*******************************************************************************
    127 **
    128 ** Function         nfa_ee_restore_one_ecb
    129 **
    130 ** Description      activate the NFCEE and restore the routing when
    131 **                  changing power state from low power mode to full power mode
    132 **
    133 ** Returns          None
    134 **
    135 *******************************************************************************/
    136 void nfa_ee_restore_one_ecb(tNFA_EE_ECB* p_cb) {
    137   uint8_t mask;
    138   tNFC_NFCEE_MODE_SET_REVT rsp;
    139   tNFA_EE_NCI_MODE_SET ee_msg;
    140 
    141   NFA_TRACE_DEBUG4(
    142       "nfa_ee_restore_one_ecb () nfcee_id:0x%x, ecb_flags:0x%x ee_status:0x%x "
    143       "ee_old_status: 0x%x",
    144       p_cb->nfcee_id, p_cb->ecb_flags, p_cb->ee_status, p_cb->ee_old_status);
    145   if ((p_cb->nfcee_id != NFA_EE_INVALID) &&
    146       (p_cb->ee_status & NFA_EE_STATUS_RESTORING) == 0 &&
    147       (p_cb->ee_old_status & NFA_EE_STATUS_RESTORING) != 0) {
    148     p_cb->ee_old_status &= ~NFA_EE_STATUS_RESTORING;
    149     mask = nfa_ee_ecb_to_mask(p_cb);
    150     if (p_cb->ee_status != p_cb->ee_old_status) {
    151       p_cb->ecb_flags |= NFA_EE_ECB_FLAGS_RESTORE;
    152       if (p_cb->ee_old_status == NFC_NFCEE_STATUS_ACTIVE) {
    153         NFC_NfceeModeSet(p_cb->nfcee_id, NFC_MODE_ACTIVATE);
    154 
    155         if (nfa_ee_cb.ee_cfged & mask) {
    156           /* if any routing is configured on this NFCEE. need to mark this NFCEE
    157            * as changed
    158            * to cause the configuration to be sent to NFCC again */
    159           p_cb->ecb_flags |= NFA_EE_ECB_FLAGS_ROUTING;
    160           p_cb->ecb_flags |= NFA_EE_ECB_FLAGS_VS;
    161         }
    162       } else {
    163         NFC_NfceeModeSet(p_cb->nfcee_id, NFC_MODE_DEACTIVATE);
    164       }
    165     } else if (p_cb->ee_status == NFC_NFCEE_STATUS_ACTIVE) {
    166       /* the initial NFCEE status after start up is the same as the current
    167        * status and it's active:
    168        * process the same as the host gets activate rsp */
    169       p_cb->ecb_flags |= NFA_EE_ECB_FLAGS_RESTORE;
    170       if (nfa_ee_cb.ee_cfged & mask) {
    171         /* if any routing is configured on this NFCEE. need to mark this NFCEE
    172          * as changed
    173          * to cause the configuration to be sent to NFCC again */
    174         p_cb->ecb_flags |= NFA_EE_ECB_FLAGS_ROUTING;
    175         p_cb->ecb_flags |= NFA_EE_ECB_FLAGS_VS;
    176       }
    177       rsp.mode = NFA_EE_MD_ACTIVATE;
    178       rsp.nfcee_id = p_cb->nfcee_id;
    179       rsp.status = NFA_STATUS_OK;
    180       ee_msg.p_data = &rsp;
    181       nfa_ee_nci_mode_set_rsp((tNFA_EE_MSG*)&ee_msg);
    182     }
    183   }
    184 }
    185 
    186 /*******************************************************************************
    187 **
    188 ** Function         nfa_ee_proc_nfcc_power_mode
    189 **
    190 ** Description      Restore NFA EE sub-module
    191 **
    192 ** Returns          None
    193 **
    194 *******************************************************************************/
    195 void nfa_ee_proc_nfcc_power_mode(uint8_t nfcc_power_mode) {
    196   uint32_t xx;
    197   tNFA_EE_ECB* p_cb;
    198   bool proc_complete = true;
    199 
    200   NFA_TRACE_DEBUG1("nfa_ee_proc_nfcc_power_mode (): nfcc_power_mode=%d",
    201                    nfcc_power_mode);
    202   /* if NFCC power state is change to full power */
    203   if (nfcc_power_mode == NFA_DM_PWR_MODE_FULL) {
    204     if (nfa_ee_max_ee_cfg) {
    205       p_cb = nfa_ee_cb.ecb;
    206       for (xx = 0; xx < NFA_EE_MAX_EE_SUPPORTED; xx++, p_cb++) {
    207         p_cb->ee_old_status = 0;
    208         if (xx >= nfa_ee_cb.cur_ee) p_cb->nfcee_id = NFA_EE_INVALID;
    209 
    210         if ((p_cb->nfcee_id != NFA_EE_INVALID) &&
    211             (p_cb->ee_interface[0] != NFC_NFCEE_INTERFACE_HCI_ACCESS) &&
    212             (p_cb->ee_status != NFA_EE_STATUS_REMOVED)) {
    213           proc_complete = false;
    214           /* NFA_EE_STATUS_RESTORING bit makes sure the ee_status restore to
    215            * ee_old_status
    216            * NFA_EE_STATUS_RESTORING bit is cleared in ee_status at
    217            * NFCEE_DISCOVER NTF.
    218            * NFA_EE_STATUS_RESTORING bit is cleared in ee_old_status at
    219            * restoring the activate/inactive status after NFCEE_DISCOVER NTF */
    220           p_cb->ee_status |= NFA_EE_STATUS_RESTORING;
    221           p_cb->ee_old_status = p_cb->ee_status;
    222           /* NFA_EE_FLAGS_RESTORE bit makes sure the routing/nci logical
    223            * connection is restore to prior to entering low power mode */
    224           p_cb->ecb_flags |= NFA_EE_ECB_FLAGS_RESTORE;
    225         }
    226       }
    227       nfa_ee_cb.em_state = NFA_EE_EM_STATE_RESTORING;
    228       nfa_ee_cb.num_ee_expecting = 0;
    229       if (nfa_sys_is_register(NFA_ID_HCI)) {
    230         nfa_ee_cb.ee_flags |= NFA_EE_FLAG_WAIT_HCI;
    231         nfa_ee_cb.ee_flags |= NFA_EE_FLAG_NOTIFY_HCI;
    232       }
    233       NFC_NfceeDiscover(true);
    234       nfa_sys_start_timer(&nfa_ee_cb.discv_timer, NFA_EE_DISCV_TIMEOUT_EVT,
    235                           NFA_EE_DISCV_TIMEOUT_VAL);
    236     }
    237   } else {
    238     nfa_sys_stop_timer(&nfa_ee_cb.timer);
    239     nfa_sys_stop_timer(&nfa_ee_cb.discv_timer);
    240     nfa_ee_cb.num_ee_expecting = 0;
    241   }
    242 
    243   if (proc_complete)
    244     nfa_sys_cback_notify_nfcc_power_mode_proc_complete(NFA_ID_EE);
    245 }
    246 
    247 /*******************************************************************************
    248 **
    249 ** Function         nfa_ee_proc_hci_info_cback
    250 **
    251 ** Description      HCI initialization complete from power off sleep mode
    252 **
    253 ** Returns          None
    254 **
    255 *******************************************************************************/
    256 void nfa_ee_proc_hci_info_cback(void) {
    257   uint32_t xx;
    258   tNFA_EE_ECB* p_cb;
    259   tNFA_EE_MSG data;
    260 
    261   NFA_TRACE_DEBUG0("nfa_ee_proc_hci_info_cback ()");
    262   /* if NFCC power state is change to full power */
    263   nfa_ee_cb.ee_flags &= ~NFA_EE_FLAG_WAIT_HCI;
    264 
    265   p_cb = nfa_ee_cb.ecb;
    266   for (xx = 0; xx < NFA_EE_MAX_EE_SUPPORTED; xx++, p_cb++) {
    267     /* NCI spec says: An NFCEE_DISCOVER_NTF that contains a Protocol type of
    268      * "HCI Access"
    269      * SHALL NOT contain any other additional Protocol
    270      * i.e. check only first supported NFCEE interface is HCI access */
    271     /* NFA_HCI module handles restoring configurations for HCI access */
    272     if (p_cb->ee_interface[0] != NFC_NFCEE_INTERFACE_HCI_ACCESS) {
    273       nfa_ee_restore_one_ecb(p_cb);
    274     }
    275   }
    276 
    277   if (nfa_ee_restore_ntf_done()) {
    278     nfa_ee_check_restore_complete();
    279     if (nfa_ee_cb.em_state == NFA_EE_EM_STATE_INIT_DONE) {
    280       if (nfa_ee_cb.discv_timer.in_use) {
    281         nfa_sys_stop_timer(&nfa_ee_cb.discv_timer);
    282         data.hdr.event = NFA_EE_DISCV_TIMEOUT_EVT;
    283         nfa_ee_evt_hdlr((NFC_HDR*)&data);
    284       }
    285     }
    286   }
    287 }
    288 
    289 /*******************************************************************************
    290 **
    291 ** Function         nfa_ee_proc_evt
    292 **
    293 ** Description      Process NFCEE related events from NFC stack
    294 **
    295 **
    296 ** Returns          None
    297 **
    298 *******************************************************************************/
    299 void nfa_ee_proc_evt(tNFC_RESPONSE_EVT event, void* p_data) {
    300   tNFA_EE_INT_EVT int_event = 0;
    301   tNFA_EE_NCI_WAIT_RSP cbk;
    302   NFC_HDR* p_hdr;
    303 
    304   switch (event) {
    305     case NFC_NFCEE_DISCOVER_REVT: /* 4  NFCEE Discover response */
    306       int_event = NFA_EE_NCI_DISC_RSP_EVT;
    307       break;
    308 
    309     case NFC_NFCEE_INFO_REVT: /* 5  NFCEE Discover Notification */
    310       int_event = NFA_EE_NCI_DISC_NTF_EVT;
    311       break;
    312 
    313     case NFC_NFCEE_MODE_SET_REVT: /* 6  NFCEE Mode Set response */
    314       int_event = NFA_EE_NCI_MODE_SET_RSP_EVT;
    315       break;
    316 
    317     case NFC_EE_ACTION_REVT:
    318       int_event = NFA_EE_NCI_ACTION_NTF_EVT;
    319       break;
    320 
    321     case NFC_EE_DISCOVER_REQ_REVT: /* 10 EE Discover Req notification */
    322       int_event = NFA_EE_NCI_DISC_REQ_NTF_EVT;
    323       break;
    324 
    325     case NFC_SET_ROUTING_REVT:
    326       int_event = NFA_EE_NCI_WAIT_RSP_EVT;
    327       cbk.opcode = NCI_MSG_RF_SET_ROUTING;
    328       break;
    329   }
    330 
    331   NFA_TRACE_DEBUG2("nfa_ee_proc_evt: event=0x%02x int_event:0x%x", event,
    332                    int_event);
    333   if (int_event) {
    334     p_hdr = (NFC_HDR*)&cbk;
    335     cbk.hdr.event = int_event;
    336     cbk.p_data = p_data;
    337 
    338     nfa_ee_evt_hdlr(p_hdr);
    339   }
    340 }
    341 
    342 /*******************************************************************************
    343 **
    344 ** Function         nfa_ee_ecb_to_mask
    345 **
    346 ** Description      Given a ecb, return the bit mask to be used in
    347 **                  nfa_ee_cb.ee_cfged
    348 **
    349 ** Returns          the bitmask for the given ecb.
    350 **
    351 *******************************************************************************/
    352 uint8_t nfa_ee_ecb_to_mask(tNFA_EE_ECB* p_cb) {
    353   uint8_t mask;
    354   uint8_t index;
    355 
    356   index = (uint8_t)(p_cb - nfa_ee_cb.ecb);
    357   mask = 1 << index;
    358 
    359   return mask;
    360 }
    361 
    362 /*******************************************************************************
    363 **
    364 ** Function         nfa_ee_find_ecb
    365 **
    366 ** Description      Return the ecb associated with the given nfcee_id
    367 **
    368 ** Returns          tNFA_EE_ECB
    369 **
    370 *******************************************************************************/
    371 tNFA_EE_ECB* nfa_ee_find_ecb(uint8_t nfcee_id) {
    372   uint32_t xx;
    373   tNFA_EE_ECB *p_ret = NULL, *p_cb;
    374   NFA_TRACE_DEBUG0("nfa_ee_find_ecb ()");
    375 
    376   if (nfcee_id == NFC_DH_ID) {
    377     p_ret = &nfa_ee_cb.ecb[NFA_EE_CB_4_DH];
    378   } else {
    379     p_cb = nfa_ee_cb.ecb;
    380     for (xx = 0; xx < NFA_EE_MAX_EE_SUPPORTED; xx++, p_cb++) {
    381       if (nfcee_id == p_cb->nfcee_id) {
    382         p_ret = p_cb;
    383         break;
    384       }
    385     }
    386   }
    387 
    388   return p_ret;
    389 }
    390 
    391 /*******************************************************************************
    392 **
    393 ** Function         nfa_ee_find_ecb_by_conn_id
    394 **
    395 ** Description      Return the ecb associated with the given connection id
    396 **
    397 ** Returns          tNFA_EE_ECB
    398 **
    399 *******************************************************************************/
    400 tNFA_EE_ECB* nfa_ee_find_ecb_by_conn_id(uint8_t conn_id) {
    401   uint32_t xx;
    402   tNFA_EE_ECB *p_ret = NULL, *p_cb;
    403   NFA_TRACE_DEBUG0("nfa_ee_find_ecb_by_conn_id ()");
    404 
    405   p_cb = nfa_ee_cb.ecb;
    406   for (xx = 0; xx < nfa_ee_cb.cur_ee; xx++, p_cb++) {
    407     if (conn_id == p_cb->conn_id) {
    408       p_ret = p_cb;
    409       break;
    410     }
    411   }
    412 
    413   return p_ret;
    414 }
    415 
    416 /*******************************************************************************
    417 **
    418 ** Function         nfa_ee_sys_disable
    419 **
    420 ** Description      Deregister NFA EE from NFA SYS/DM
    421 **
    422 **
    423 ** Returns          None
    424 **
    425 *******************************************************************************/
    426 void nfa_ee_sys_disable(void) {
    427   uint32_t xx;
    428   tNFA_EE_ECB* p_cb;
    429   tNFA_EE_MSG msg;
    430 
    431   NFA_TRACE_DEBUG0("nfa_ee_sys_disable ()");
    432 
    433   nfa_ee_cb.em_state = NFA_EE_EM_STATE_DISABLED;
    434   /* report NFA_EE_DEREGISTER_EVT to all registered to EE */
    435   for (xx = 0; xx < NFA_EE_MAX_CBACKS; xx++) {
    436     if (nfa_ee_cb.p_ee_cback[xx]) {
    437       msg.deregister.index = xx;
    438       nfa_ee_api_deregister(&msg);
    439     }
    440   }
    441 
    442   nfa_ee_cb.num_ee_expecting = 0;
    443   p_cb = nfa_ee_cb.ecb;
    444   for (xx = 0; xx < nfa_ee_cb.cur_ee; xx++, p_cb++) {
    445     if (p_cb->conn_st == NFA_EE_CONN_ST_CONN) {
    446       if (nfa_sys_is_graceful_disable()) {
    447         /* Disconnect NCI connection on graceful shutdown */
    448         msg.disconnect.p_cb = p_cb;
    449         nfa_ee_api_disconnect(&msg);
    450         nfa_ee_cb.num_ee_expecting++;
    451       } else {
    452         /* fake NFA_EE_DISCONNECT_EVT on ungraceful shutdown */
    453         msg.conn.conn_id = p_cb->conn_id;
    454         msg.conn.event = NFC_CONN_CLOSE_CEVT;
    455         nfa_ee_nci_conn(&msg);
    456       }
    457     }
    458   }
    459 
    460   if (nfa_ee_cb.num_ee_expecting) {
    461     nfa_ee_cb.ee_flags |= NFA_EE_FLAG_WAIT_DISCONN;
    462     nfa_ee_cb.em_state = NFA_EE_EM_STATE_DISABLING;
    463   }
    464 
    465   nfa_sys_stop_timer(&nfa_ee_cb.timer);
    466   nfa_sys_stop_timer(&nfa_ee_cb.discv_timer);
    467 
    468   /* If Application initiated NFCEE discovery, fake/report the event */
    469   nfa_ee_report_disc_done(false);
    470 
    471   /* deregister message handler on NFA SYS */
    472   if (nfa_ee_cb.em_state == NFA_EE_EM_STATE_DISABLED)
    473     nfa_sys_deregister(NFA_ID_EE);
    474 }
    475 
    476 /*******************************************************************************
    477 **
    478 ** Function         nfa_ee_check_disable
    479 **
    480 ** Description      Check if it is safe to move to disabled state
    481 **
    482 ** Returns          None
    483 **
    484 *******************************************************************************/
    485 void nfa_ee_check_disable(void) {
    486   if (!(nfa_ee_cb.ee_flags & NFA_EE_FLAG_WAIT_DISCONN)) {
    487     nfa_ee_cb.em_state = NFA_EE_EM_STATE_DISABLED;
    488     nfa_sys_deregister(NFA_ID_EE);
    489   }
    490 }
    491 /*******************************************************************************
    492 **
    493 ** Function         nfa_ee_reg_cback_enable_done
    494 **
    495 ** Description      Allow a module to register to EE to be notified when NFA-EE
    496 **                  finishes enable process
    497 **
    498 ** Returns          None
    499 **
    500 *******************************************************************************/
    501 void nfa_ee_reg_cback_enable_done(tNFA_EE_ENABLE_DONE_CBACK* p_cback) {
    502   nfa_ee_cb.p_enable_cback = p_cback;
    503 }
    504 
    505 #if (BT_TRACE_VERBOSE == TRUE)
    506 /*******************************************************************************
    507 **
    508 ** Function         nfa_ee_sm_st_2_str
    509 **
    510 ** Description      convert nfa-ee state to string
    511 **
    512 *******************************************************************************/
    513 static char* nfa_ee_sm_st_2_str(uint8_t state) {
    514   switch (state) {
    515     case NFA_EE_EM_STATE_INIT:
    516       return "INIT";
    517 
    518     case NFA_EE_EM_STATE_INIT_DONE:
    519       return "INIT_DONE";
    520 
    521     case NFA_EE_EM_STATE_RESTORING:
    522       return "RESTORING";
    523 
    524     case NFA_EE_EM_STATE_DISABLING:
    525       return "DISABLING";
    526 
    527     case NFA_EE_EM_STATE_DISABLED:
    528       return "DISABLED";
    529 
    530     default:
    531       return "Unknown";
    532   }
    533 }
    534 
    535 /*******************************************************************************
    536 **
    537 ** Function         nfa_ee_sm_evt_2_str
    538 **
    539 ** Description      convert nfa-ee evt to string
    540 **
    541 *******************************************************************************/
    542 static char* nfa_ee_sm_evt_2_str(uint16_t event) {
    543   switch (event) {
    544     case NFA_EE_API_DISCOVER_EVT:
    545       return "API_DISCOVER";
    546     case NFA_EE_API_REGISTER_EVT:
    547       return "API_REGISTER";
    548     case NFA_EE_API_DEREGISTER_EVT:
    549       return "API_DEREGISTER";
    550     case NFA_EE_API_MODE_SET_EVT:
    551       return "API_MODE_SET";
    552     case NFA_EE_API_SET_TECH_CFG_EVT:
    553       return "API_SET_TECH_CFG";
    554     case NFA_EE_API_SET_PROTO_CFG_EVT:
    555       return "API_SET_PROTO_CFG";
    556     case NFA_EE_API_ADD_AID_EVT:
    557       return "API_ADD_AID";
    558     case NFA_EE_API_REMOVE_AID_EVT:
    559       return "API_REMOVE_AID";
    560     case NFA_EE_API_LMRT_SIZE_EVT:
    561       return "API_LMRT_SIZE";
    562     case NFA_EE_API_UPDATE_NOW_EVT:
    563       return "API_UPDATE_NOW";
    564     case NFA_EE_API_CONNECT_EVT:
    565       return "API_CONNECT";
    566     case NFA_EE_API_SEND_DATA_EVT:
    567       return "API_SEND_DATA";
    568     case NFA_EE_API_DISCONNECT_EVT:
    569       return "API_DISCONNECT";
    570     case NFA_EE_NCI_DISC_RSP_EVT:
    571       return "NCI_DISC_RSP";
    572     case NFA_EE_NCI_DISC_NTF_EVT:
    573       return "NCI_DISC_NTF";
    574     case NFA_EE_NCI_MODE_SET_RSP_EVT:
    575       return "NCI_MODE_SET";
    576     case NFA_EE_NCI_CONN_EVT:
    577       return "NCI_CONN";
    578     case NFA_EE_NCI_DATA_EVT:
    579       return "NCI_DATA";
    580     case NFA_EE_NCI_ACTION_NTF_EVT:
    581       return "NCI_ACTION";
    582     case NFA_EE_NCI_DISC_REQ_NTF_EVT:
    583       return "NCI_DISC_REQ";
    584     case NFA_EE_NCI_WAIT_RSP_EVT:
    585       return "NCI_WAIT_RSP";
    586     case NFA_EE_ROUT_TIMEOUT_EVT:
    587       return "ROUT_TIMEOUT";
    588     case NFA_EE_DISCV_TIMEOUT_EVT:
    589       return "NFA_EE_DISCV_TIMEOUT_EVT";
    590     case NFA_EE_CFG_TO_NFCC_EVT:
    591       return "CFG_TO_NFCC";
    592     default:
    593       return "Unknown";
    594   }
    595 }
    596 #endif /* BT_TRACE_VERBOSE */
    597 
    598 /*******************************************************************************
    599 **
    600 ** Function         nfa_ee_evt_hdlr
    601 **
    602 ** Description      Processing event for NFA EE
    603 **
    604 **
    605 ** Returns          TRUE if p_msg needs to be deallocated
    606 **
    607 *******************************************************************************/
    608 bool nfa_ee_evt_hdlr(NFC_HDR* p_msg) {
    609   tNFA_EE_MSG* p_evt_data = (tNFA_EE_MSG*)p_msg;
    610   uint16_t event = p_msg->event & 0x00ff;
    611   bool act = false;
    612 
    613 #if (BT_TRACE_VERBOSE == TRUE)
    614   NFA_TRACE_DEBUG4("nfa_ee_evt_hdlr (): Event %s(0x%02x), State: %s(%d)",
    615                    nfa_ee_sm_evt_2_str(p_evt_data->hdr.event),
    616                    p_evt_data->hdr.event,
    617                    nfa_ee_sm_st_2_str(nfa_ee_cb.em_state), nfa_ee_cb.em_state);
    618 #else
    619   NFA_TRACE_DEBUG2("nfa_ee_evt_hdlr (): Event 0x%02x, State: %d",
    620                    p_evt_data->hdr.event, nfa_ee_cb.em_state);
    621 #endif
    622 
    623   switch (nfa_ee_cb.em_state) {
    624     case NFA_EE_EM_STATE_INIT_DONE:
    625     case NFA_EE_EM_STATE_RESTORING:
    626       act = true;
    627       break;
    628     case NFA_EE_EM_STATE_INIT:
    629       if ((p_msg->event == NFA_EE_NCI_DISC_NTF_EVT) ||
    630           (p_msg->event == NFA_EE_NCI_DISC_RSP_EVT))
    631         act = true;
    632       break;
    633     case NFA_EE_EM_STATE_DISABLING:
    634       if (p_msg->event == NFA_EE_NCI_CONN_EVT) act = true;
    635       break;
    636   }
    637   if (act) {
    638     if (event < NFA_EE_NUM_ACTIONS) {
    639       (*nfa_ee_actions[event])(p_evt_data);
    640     }
    641   } else {
    642     /* if the data event is not handled by action function, free the data packet
    643      */
    644     if (p_msg->event == NFA_EE_NCI_DATA_EVT)
    645       GKI_freebuf(p_evt_data->conn.p_data);
    646   }
    647 
    648   return true;
    649 }
    650