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