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