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