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