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