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