• 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 file contains the action functions for NFA-EE
22  *
23  ******************************************************************************/
24 #include <android-base/logging.h>
25 #include <android-base/stringprintf.h>
26 #include <statslog_nfc.h>
27 #include <string.h>
28 
29 #include "include/debug_lmrt.h"
30 #include "metrics.h"
31 #include "nfa_api.h"
32 #include "nfa_dm_int.h"
33 #include "nfa_ee_int.h"
34 #include "nfa_hci_int.h"
35 #include "nfa_nfcee_int.h"
36 #include "nfa_sys_int.h"
37 #include "nfc_config.h"
38 #include "nfc_int.h"
39 
40 using android::base::StringPrintf;
41 
42 /* the de-bounce timer:
43  * The NFA-EE API functions are called to set the routing and VS configuration.
44  * When this timer expires, the configuration is sent to NFCC all at once.
45  * This is the timeout value for the de-bounce timer. */
46 #ifndef NFA_EE_ROUT_TIMEOUT_VAL
47 #define NFA_EE_ROUT_TIMEOUT_VAL 1000
48 #endif
49 
50 #define NFA_EE_ROUT_BUF_SIZE 540
51 #define NFA_EE_ROUT_MAX_TLV_SIZE 0xFD
52 
53 /* the following 2 tables convert the technology mask in API and control block
54  * to the command for NFCC */
55 #define NFA_EE_NUM_TECH 3
56 const uint8_t nfa_ee_tech_mask_list[NFA_EE_NUM_TECH] = {
57     NFA_TECHNOLOGY_MASK_A, NFA_TECHNOLOGY_MASK_B, NFA_TECHNOLOGY_MASK_F};
58 
59 const uint8_t nfa_ee_tech_list[NFA_EE_NUM_TECH] = {
60     NFC_RF_TECHNOLOGY_A, NFC_RF_TECHNOLOGY_B, NFC_RF_TECHNOLOGY_F};
61 extern bool nfa_ee_route_debounce_timer;
62 
63 /* the following 2 tables convert the protocol mask in API and control block to
64  * the command for NFCC */
65 #define NFA_EE_NUM_PROTO 5
66 
67 extern uint8_t mute_tech_route_option;
68 
69 #define NFCEE_TYPE_NDEF 0x04  // indicates that the NFCEE supports NDEF storage
70 #define NFCEE_TAG_INDEX 0
71 
add_route_tech_proto_tlv(uint8_t ** pp,uint8_t tlv_type,uint8_t nfcee_id,uint8_t pwr_cfg,uint8_t tech_proto)72 static void add_route_tech_proto_tlv(uint8_t** pp, uint8_t tlv_type,
73                                      uint8_t nfcee_id, uint8_t pwr_cfg,
74                                      uint8_t tech_proto) {
75   LOG(VERBOSE) << StringPrintf(
76       "%s: nfcee_id=0x%x, pwr_cfg=0x%x, tech_proto=0x%x", __func__, nfcee_id,
77       pwr_cfg, tech_proto);
78   *(*pp)++ = tlv_type;
79   *(*pp)++ = 3;
80   *(*pp)++ = nfcee_id;
81   *(*pp)++ = pwr_cfg;
82   *(*pp)++ = tech_proto;
83 }
84 
add_route_aid_tlv(uint8_t ** pp,uint8_t * pa,uint8_t nfcee_id,uint8_t pwr_cfg,uint8_t tag)85 static void add_route_aid_tlv(uint8_t** pp, uint8_t* pa, uint8_t nfcee_id,
86                               uint8_t pwr_cfg, uint8_t tag) {
87   pa++;                /* EMV tag */
88   uint8_t len = *pa++; /* aid_len */
89   *(*pp)++ = tag;
90   *(*pp)++ = len + 2;
91   *(*pp)++ = nfcee_id;
92   *(*pp)++ = pwr_cfg;
93   /* copy the AID */
94   memcpy(*pp, pa, len);
95   *pp += len;
96 }
97 
add_route_sys_code_tlv(uint8_t ** p_buff,uint8_t * p_sys_code_cfg,uint8_t sys_code_rt_loc,uint8_t sys_code_pwr_cfg)98 static void add_route_sys_code_tlv(uint8_t** p_buff, uint8_t* p_sys_code_cfg,
99                                    uint8_t sys_code_rt_loc,
100                                    uint8_t sys_code_pwr_cfg) {
101   LOG(VERBOSE) << StringPrintf("%s: nfcee_id=0x%x, pwr_cfg=0x%x", __func__,
102                                sys_code_rt_loc, sys_code_pwr_cfg);
103   *(*p_buff)++ = NFC_ROUTE_TAG_SYSCODE | nfa_ee_cb.route_block_control;
104   *(*p_buff)++ = NFA_EE_SYSTEM_CODE_LEN + 2;
105   *(*p_buff)++ = sys_code_rt_loc;
106   *(*p_buff)++ = sys_code_pwr_cfg;
107   /* copy the system code */
108   memcpy(*p_buff, p_sys_code_cfg, NFA_EE_SYSTEM_CODE_LEN);
109   *p_buff += NFA_EE_SYSTEM_CODE_LEN;
110 }
111 
112 const uint8_t nfa_ee_proto_mask_list[NFA_EE_NUM_PROTO] = {
113     NFA_PROTOCOL_MASK_T1T, NFA_PROTOCOL_MASK_T2T, NFA_PROTOCOL_MASK_T3T,
114     NFA_PROTOCOL_MASK_ISO_DEP};
115 
116 const uint8_t nfa_ee_proto_list[NFA_EE_NUM_PROTO] = {
117     NFC_PROTOCOL_T1T, NFC_PROTOCOL_T2T, NFC_PROTOCOL_T3T, NFC_PROTOCOL_ISO_DEP};
118 
119 const uint8_t NFA_REMOVE_ALL_AID[] = {0xFF, 0xFF, 0xFF, 0xFF,
120                                       0xFF, 0xFF, 0xFF, 0xFF};
121 static void nfa_ee_report_discover_req_evt(void);
122 static void nfa_ee_build_discover_req_evt(tNFA_EE_DISCOVER_REQ* p_evt_data);
123 void nfa_ee_check_set_routing(uint16_t new_size, int* p_max_len, uint8_t* p,
124                               int* p_cur_offset);
125 /*******************************************************************************
126 **
127 ** Function         nfa_ee_trace_aid
128 **
129 ** Description      trace AID
130 **
131 ** Returns          void
132 **
133 *******************************************************************************/
nfa_ee_trace_aid(std::string p_str,uint8_t id,uint8_t aid_len,uint8_t * p)134 static void nfa_ee_trace_aid(std::string p_str, uint8_t id, uint8_t aid_len,
135                              uint8_t* p) {
136   int len = aid_len;
137   int xx, yy = 0;
138   const uint8_t MAX_BUFF_SIZE = 100;
139   char buff[MAX_BUFF_SIZE];
140 
141   buff[0] = 0;
142   if (aid_len > NFA_MAX_AID_LEN) {
143     LOG(ERROR) << StringPrintf("%s: aid_len=%d exceeds max(%d)", __func__,
144                                aid_len, NFA_MAX_AID_LEN);
145     len = NFA_MAX_AID_LEN;
146   }
147   for (xx = 0; xx < len; xx++) {
148     yy += snprintf(&buff[yy], MAX_BUFF_SIZE - yy, "%02x ", *p);
149     p++;
150   }
151   LOG(VERBOSE) << StringPrintf("%s: %s id=0x%x len=%d aid=%s", __func__,
152                                p_str.c_str(), id, aid_len, buff);
153 }
154 
155 /*******************************************************************************
156 **
157 ** Function         nfa_ee_update_route_size
158 **
159 ** Description      Update the size required for technology and protocol routing
160 **                  of the given NFCEE ID.
161 **
162 ** Returns          void
163 **
164 *******************************************************************************/
nfa_ee_update_route_size(tNFA_EE_ECB * p_cb)165 static void nfa_ee_update_route_size(tNFA_EE_ECB* p_cb) {
166   int xx;
167   uint8_t power_cfg = 0;
168 
169   p_cb->size_mask_proto = 0;
170   p_cb->size_mask_tech = 0;
171   /* add the Technology based routing */
172   for (xx = 0; xx < NFA_EE_NUM_TECH; xx++) {
173     power_cfg = 0;
174     if (p_cb->tech_switch_on & nfa_ee_tech_mask_list[xx])
175       power_cfg |= NCI_ROUTE_PWR_STATE_ON;
176     if (p_cb->tech_switch_off & nfa_ee_tech_mask_list[xx])
177       power_cfg |= NCI_ROUTE_PWR_STATE_SWITCH_OFF;
178     if (p_cb->tech_battery_off & nfa_ee_tech_mask_list[xx])
179       power_cfg |= NCI_ROUTE_PWR_STATE_BATT_OFF;
180     if ((power_cfg & NCI_ROUTE_PWR_STATE_ON) &&
181         (NFC_GetNCIVersion() >= NCI_VERSION_2_0)) {
182       if (p_cb->tech_screen_lock & nfa_ee_tech_mask_list[xx])
183         power_cfg |= NCI_ROUTE_PWR_STATE_SCREEN_ON_LOCK();
184       if (p_cb->tech_screen_off & nfa_ee_tech_mask_list[xx])
185         power_cfg |= NCI_ROUTE_PWR_STATE_SCREEN_OFF_UNLOCK();
186       if (p_cb->tech_screen_off_lock & nfa_ee_tech_mask_list[xx])
187         power_cfg |= NCI_ROUTE_PWR_STATE_SCREEN_OFF_LOCK();
188     }
189     if (power_cfg) {
190       /* 5 = 1 (tag) + 1 (len) + 1(nfcee_id) + 1(power cfg) + 1 (technology) */
191       p_cb->size_mask_tech += 5;
192     }
193   }
194 
195   /* add the Protocol based routing */
196   for (xx = 0; xx < NFA_EE_NUM_PROTO; xx++) {
197     power_cfg = 0;
198     if (p_cb->proto_switch_on & nfa_ee_proto_mask_list[xx])
199       power_cfg |= NCI_ROUTE_PWR_STATE_ON;
200     if (p_cb->proto_switch_off & nfa_ee_proto_mask_list[xx])
201       power_cfg |= NCI_ROUTE_PWR_STATE_SWITCH_OFF;
202     if (p_cb->proto_battery_off & nfa_ee_proto_mask_list[xx])
203       power_cfg |= NCI_ROUTE_PWR_STATE_BATT_OFF;
204     if ((power_cfg & NCI_ROUTE_PWR_STATE_ON) &&
205         (NFC_GetNCIVersion() >= NCI_VERSION_2_0)) {
206       if (p_cb->proto_screen_lock & nfa_ee_proto_mask_list[xx])
207         power_cfg |= NCI_ROUTE_PWR_STATE_SCREEN_ON_LOCK();
208       if (p_cb->proto_screen_off & nfa_ee_proto_mask_list[xx])
209         power_cfg |= NCI_ROUTE_PWR_STATE_SCREEN_OFF_UNLOCK();
210       if (p_cb->proto_screen_off_lock & nfa_ee_proto_mask_list[xx])
211         power_cfg |= NCI_ROUTE_PWR_STATE_SCREEN_OFF_LOCK();
212     }
213 
214     if (power_cfg) {
215       /* 5 = 1 (tag) + 1 (len) + 1(nfcee_id) + 1(power cfg) + 1 (protocol) */
216       p_cb->size_mask_proto += 5;
217     }
218   }
219   LOG(VERBOSE) << StringPrintf(
220       "%s: nfcee_id=0x%x size_mask_proto=%d "
221       "size_mask_tech=%d",
222       __func__, p_cb->nfcee_id, p_cb->size_mask_proto, p_cb->size_mask_tech);
223 }
224 
225 /*******************************************************************************
226 **
227 ** Function         nfa_ee_update_route_aid_size
228 **
229 ** Description      Update the size required for AID routing
230 **                  of the given NFCEE ID.
231 **
232 ** Returns          void
233 **
234 *******************************************************************************/
nfa_ee_update_route_aid_size(tNFA_EE_ECB * p_cb)235 static void nfa_ee_update_route_aid_size(tNFA_EE_ECB* p_cb) {
236   uint8_t *pa, len;
237   int start_offset;
238   int xx;
239 
240   p_cb->size_aid = 0;
241   if (p_cb->aid_entries) {
242     start_offset = 0;
243     for (xx = 0; xx < p_cb->aid_entries; xx++) {
244       /* add one AID entry */
245       if (p_cb->aid_rt_info[xx] & NFA_EE_AE_ROUTE) {
246         pa = &p_cb->aid_cfg[start_offset];
247         pa++;        /* EMV tag */
248         len = *pa++; /* aid_len */
249         /* 4 = 1 (tag) + 1 (len) + 1(nfcee_id) + 1(power cfg) */
250         p_cb->size_aid += 4;
251         p_cb->size_aid += len;
252       }
253       start_offset += p_cb->aid_len[xx];
254     }
255   }
256   LOG(VERBOSE) << StringPrintf("%s: nfcee_id=0x%x size_aid=%d", __func__,
257                                p_cb->nfcee_id, p_cb->size_aid);
258 }
259 
260 /*******************************************************************************
261 **
262 ** Function         nfa_ee_update_route_sys_code_size
263 **
264 ** Description      Update the size required for system code routing
265 **                  of the given NFCEE ID.
266 **
267 ** Returns          void
268 **
269 *******************************************************************************/
nfa_ee_update_route_sys_code_size(tNFA_EE_ECB * p_cb)270 static void nfa_ee_update_route_sys_code_size(tNFA_EE_ECB* p_cb) {
271   p_cb->size_sys_code = 0;
272   if (p_cb->sys_code_cfg_entries) {
273     for (uint8_t xx = 0; xx < p_cb->sys_code_cfg_entries; xx++) {
274       if (p_cb->sys_code_rt_loc_vs_info[xx] & NFA_EE_AE_ROUTE) {
275         /* 4 = 1 (tag) + 1 (len) + 1(nfcee_id) + 1(power cfg) */
276         p_cb->size_sys_code += 4;
277         p_cb->size_sys_code += NFA_EE_SYSTEM_CODE_LEN;
278       }
279     }
280   }
281   LOG(VERBOSE) << StringPrintf("%s:  nfcee_id=0x%x size_sys_code=%d", __func__,
282                                p_cb->nfcee_id, p_cb->size_sys_code);
283 }
284 
285 /*******************************************************************************
286 **
287 ** Function         nfa_ee_total_lmrt_size
288 **
289 ** Description      the total listen mode routing table size
290 **
291 ** Returns          uint16_t
292 **
293 *******************************************************************************/
nfa_ee_total_lmrt_size(void)294 static uint16_t nfa_ee_total_lmrt_size(void) {
295   int xx;
296   uint16_t lmrt_size = 0;
297   tNFA_EE_ECB* p_cb;
298 
299   p_cb = &nfa_ee_cb.ecb[NFA_EE_CB_4_DH];
300   lmrt_size += p_cb->size_mask_proto;
301   lmrt_size += p_cb->size_mask_tech;
302   lmrt_size += p_cb->size_aid;
303   lmrt_size += p_cb->size_sys_code;
304   if (nfa_ee_cb.cur_ee > 0) p_cb = &nfa_ee_cb.ecb[nfa_ee_cb.cur_ee - 1];
305   for (xx = 0; xx < nfa_ee_cb.cur_ee; xx++, p_cb--) {
306     if ((p_cb->ee_status & ~NFA_EE_STATUS_MEP_MASK) ==
307         NFC_NFCEE_STATUS_ACTIVE) {
308       lmrt_size += p_cb->size_mask_proto;
309       lmrt_size += p_cb->size_mask_tech;
310       lmrt_size += p_cb->size_aid;
311       lmrt_size += p_cb->size_sys_code;
312     }
313   }
314   LOG(VERBOSE) << StringPrintf("%s: size=%d", __func__, lmrt_size);
315   return lmrt_size;
316 }
317 
nfa_ee_add_tech_route_to_ecb(tNFA_EE_ECB * p_cb,uint8_t * pp,uint8_t * p,uint8_t * ps,int * p_cur_offset)318 static void nfa_ee_add_tech_route_to_ecb(tNFA_EE_ECB* p_cb, uint8_t* pp,
319                                          uint8_t* p, uint8_t* ps,
320                                          int* p_cur_offset) {
321   uint8_t num_tlv = *ps;
322 
323   /* add the Technology based routing */
324   for (int xx = 0; xx < NFA_EE_NUM_TECH; xx++) {
325     uint8_t power_cfg = 0;
326     if (p_cb->tech_switch_on & nfa_ee_tech_mask_list[xx])
327       power_cfg |= NCI_ROUTE_PWR_STATE_ON;
328     if (p_cb->tech_switch_off & nfa_ee_tech_mask_list[xx])
329       power_cfg |= NCI_ROUTE_PWR_STATE_SWITCH_OFF;
330     if (p_cb->tech_battery_off & nfa_ee_tech_mask_list[xx])
331       power_cfg |= NCI_ROUTE_PWR_STATE_BATT_OFF;
332     if ((power_cfg & NCI_ROUTE_PWR_STATE_ON) &&
333         (NFC_GetNCIVersion() >= NCI_VERSION_2_0)) {
334       if (p_cb->tech_screen_lock & nfa_ee_tech_mask_list[xx])
335         power_cfg |= NCI_ROUTE_PWR_STATE_SCREEN_ON_LOCK();
336       if (p_cb->tech_screen_off & nfa_ee_tech_mask_list[xx])
337         power_cfg |= NCI_ROUTE_PWR_STATE_SCREEN_OFF_UNLOCK();
338       if (p_cb->tech_screen_off_lock & nfa_ee_tech_mask_list[xx])
339         power_cfg |= NCI_ROUTE_PWR_STATE_SCREEN_OFF_LOCK();
340     }
341     if (power_cfg) {
342       if (mute_tech_route_option) {
343         add_route_tech_proto_tlv(&pp, NFC_ROUTE_TAG_TECH, p_cb->nfcee_id,
344                                  power_cfg, nfa_ee_tech_list[xx]);
345       } else {
346         bool block = 0;
347         uint8_t mask = 0;
348 
349         nfa_dm_get_tech_route_block(&mask, &block);
350 
351         // If block a tech, allow no power states
352         if (block && ((((mask & NFA_TECHNOLOGY_MASK_A) == 0) &&
353                        (nfa_ee_tech_list[xx] == NFC_RF_TECHNOLOGY_A)) ||
354                       (((mask & NFA_TECHNOLOGY_MASK_B) == 0) &&
355                        (nfa_ee_tech_list[xx] == NFC_RF_TECHNOLOGY_B)) ||
356                       (((mask & NFA_TECHNOLOGY_MASK_F) == 0) &&
357                        (nfa_ee_tech_list[xx] == NFC_RF_TECHNOLOGY_F)))) {
358           LOG(VERBOSE) << StringPrintf("%s:  Blocking tech routing for tech=%d",
359                                        __func__, nfa_ee_tech_list[xx]);
360 
361           add_route_tech_proto_tlv(
362               &pp, nfa_ee_cb.route_block_control | NFC_ROUTE_TAG_TECH,
363               0x00 /* DH */, 0x00 /* no power states */, nfa_ee_tech_list[xx]);
364         } else {
365           add_route_tech_proto_tlv(
366               &pp,
367               nfa_dm_get_nfc_secure()
368                   ? nfa_ee_cb.route_block_control | NFC_ROUTE_TAG_TECH
369                   : NFC_ROUTE_TAG_TECH,
370               p_cb->nfcee_id, power_cfg, nfa_ee_tech_list[xx]);
371         }
372       }
373       num_tlv++;
374       if (power_cfg != NCI_ROUTE_PWR_STATE_ON)
375         nfa_ee_cb.ee_cfged |= NFA_EE_CFGED_OFF_ROUTING;
376     }
377   }
378 
379   /* update the num_tlv and current offset */
380   uint8_t entry_size = (uint8_t)(pp - p);
381   *p_cur_offset += entry_size;
382   *ps = num_tlv;
383 }
384 
nfa_ee_add_proto_route_to_ecb(tNFA_EE_ECB * p_cb,uint8_t * pp,uint8_t * p,uint8_t * ps,int * p_cur_offset)385 static void nfa_ee_add_proto_route_to_ecb(tNFA_EE_ECB* p_cb, uint8_t* pp,
386                                           uint8_t* p, uint8_t* ps,
387                                           int* p_cur_offset) {
388   uint8_t num_tlv = *ps;
389 
390   /* add the Protocol based routing */
391   for (int xx = 0; xx < NFA_EE_NUM_PROTO; xx++) {
392     uint8_t power_cfg = 0, proto_tag = 0;
393     if (p_cb->proto_switch_on & nfa_ee_proto_mask_list[xx])
394       power_cfg |= NCI_ROUTE_PWR_STATE_ON;
395     if (p_cb->proto_switch_off & nfa_ee_proto_mask_list[xx])
396       power_cfg |= NCI_ROUTE_PWR_STATE_SWITCH_OFF;
397     if (p_cb->proto_battery_off & nfa_ee_proto_mask_list[xx])
398       power_cfg |= NCI_ROUTE_PWR_STATE_BATT_OFF;
399     if (power_cfg) {
400       /* Applying Route Block for ISO DEP Protocol, so that AIDs
401        * which are not in the routing table can also be blocked */
402       if (nfa_ee_proto_mask_list[xx] == NFA_PROTOCOL_MASK_ISO_DEP) {
403         proto_tag = NFC_ROUTE_TAG_PROTO | nfa_ee_cb.route_block_control;
404 
405         /* Enable screen on lock power state for ISO-DEP protocol to
406            enable HCE screen lock */
407         if ((power_cfg & NCI_ROUTE_PWR_STATE_ON) &&
408             (NFC_GetNCIVersion() >= NCI_VERSION_2_0)) {
409           if (p_cb->proto_screen_lock & nfa_ee_proto_mask_list[xx])
410             power_cfg |= NCI_ROUTE_PWR_STATE_SCREEN_ON_LOCK();
411           if (p_cb->proto_screen_off & nfa_ee_proto_mask_list[xx])
412             power_cfg |= NCI_ROUTE_PWR_STATE_SCREEN_OFF_UNLOCK();
413           if (p_cb->proto_screen_off_lock & nfa_ee_proto_mask_list[xx])
414             power_cfg |= NCI_ROUTE_PWR_STATE_SCREEN_OFF_LOCK();
415         }
416       } else {
417         proto_tag = NFC_ROUTE_TAG_PROTO;
418       }
419       add_route_tech_proto_tlv(&pp, proto_tag, p_cb->nfcee_id, power_cfg,
420                                nfa_ee_proto_list[xx]);
421       num_tlv++;
422       if (power_cfg != NCI_ROUTE_PWR_STATE_ON)
423         nfa_ee_cb.ee_cfged |= NFA_EE_CFGED_OFF_ROUTING;
424     }
425   }
426 
427   /* update the num_tlv and current offset */
428   uint8_t entry_size = (uint8_t)(pp - p);
429   *p_cur_offset += entry_size;
430   *ps = num_tlv;
431 }
432 
433 /*******************************************************************************
434 **
435 ** Function         nfa_ee_add_aid_route_to_ecb
436 **
437 ** Description      Adds AIDs corresponding to ecb into listen mode routing
438 **                  table(LMRT) buffer. Empty AID needs to be pushed as last
439 **                  entry in LMRT. If Empty AID is part of any of the ecb,
440 **                  its index is stored in tNFA_EE_EMPTY_AID_ECB structure.
441 **                  If addEmptyAidRoute is set to true, only empty AID will
442 **                  be added into LMRT buffer
443 **
444 ** Returns          void
445 **
446 *******************************************************************************/
nfa_ee_add_aid_route_to_ecb(tNFA_EE_ECB * p_cb,uint8_t * pp,uint8_t * p,uint8_t * ps,int * p_cur_offset,int * p_max_len,tNFA_EE_EMPTY_AID_ECB & empty_aid_ecb)447 static void nfa_ee_add_aid_route_to_ecb(tNFA_EE_ECB* p_cb, uint8_t* pp,
448                                         uint8_t* p, uint8_t* ps,
449                                         int* p_cur_offset, int* p_max_len,
450                                         tNFA_EE_EMPTY_AID_ECB& empty_aid_ecb) {
451   uint8_t num_tlv = *ps;
452 
453   /* add the AID routing */
454   if (p_cb->aid_entries) {
455     int start_offset = 0;
456     int xx = 0;
457     if (empty_aid_ecb.addEmptyAidRoute) {
458       xx = empty_aid_ecb.index;
459       start_offset = empty_aid_ecb.offset;
460     }
461     for (; xx < p_cb->aid_entries; xx++) {
462       /*
463        * If addEmptyAidRoute is false and aid is empty AID don't add to the
464        * LMRT buffer. Instead update the empty aid ecb and index, which will
465        * be used later to add empty add at the end of the routing table
466        */
467       if (p_cb->aid_len[xx] == NFA_EMPTY_AID_TLV_LEN &&
468           !empty_aid_ecb.addEmptyAidRoute) {
469         empty_aid_ecb.p_cb = p_cb;
470         empty_aid_ecb.index = xx;
471         empty_aid_ecb.offset = start_offset;
472         start_offset += p_cb->aid_len[xx];
473         continue;
474       }
475       /* remember the beginning of this AID routing entry, just in case we
476        * need to put it in next command */
477       uint8_t route_qual = 0;
478       uint8_t* p_start = pp;
479       /* add one AID entry */
480       if (p_cb->aid_rt_info[xx] & NFA_EE_AE_ROUTE) {
481         num_tlv++;
482         uint8_t* pa = &p_cb->aid_cfg[start_offset];
483 
484         if (p_cb->aid_info[xx] & NCI_ROUTE_QUAL_LONG_SELECT) {
485           route_qual |= NCI_ROUTE_QUAL_LONG_SELECT;
486         }
487         if (p_cb->aid_info[xx] & NCI_ROUTE_QUAL_SHORT_SELECT) {
488           route_qual |= NCI_ROUTE_QUAL_SHORT_SELECT;
489         }
490 
491         uint8_t tag =
492             NFC_ROUTE_TAG_AID | nfa_ee_cb.route_block_control | route_qual;
493 
494         add_route_aid_tlv(&pp, pa, p_cb->nfcee_id, p_cb->aid_pwr_cfg[xx], tag);
495       }
496       start_offset += p_cb->aid_len[xx];
497       uint8_t new_size = (uint8_t)(pp - p_start);
498       nfa_ee_check_set_routing(new_size, p_max_len, ps, p_cur_offset);
499       if (*ps == 0) {
500         /* just sent routing command, update local */
501         *ps = 1;
502         num_tlv = *ps;
503         *p_cur_offset = new_size;
504         pp = ps + 1;
505         p = pp;
506         memcpy(p, p_start, new_size);
507         pp += new_size;
508       } else {
509         /* add the new entry */
510         *ps = num_tlv;
511         *p_cur_offset += new_size;
512       }
513 
514       if (empty_aid_ecb.addEmptyAidRoute) {
515         // Break the loop after adding Empty AID
516         break;
517       }
518     }
519     LOG(VERBOSE) << StringPrintf("%s: Added %d AIDs for NFCEE 0x%x", __func__,
520                                  p_cb->aid_entries, p_cb->nfcee_id);
521   } else {
522     LOG(VERBOSE) << StringPrintf("%s: No AID entries available", __func__);
523   }
524 }
525 
nfa_ee_add_sys_code_route_to_ecb(tNFA_EE_ECB * p_cb,uint8_t * pp,uint8_t * p,uint8_t * p_buff,int * p_cur_offset,int * p_max_len)526 static void nfa_ee_add_sys_code_route_to_ecb(tNFA_EE_ECB* p_cb, uint8_t* pp,
527                                              uint8_t* p, uint8_t* p_buff,
528                                              int* p_cur_offset,
529                                              int* p_max_len) {
530   uint8_t num_tlv = *p_buff;
531 
532   /* add the SC routing */
533   if (p_cb->sys_code_cfg_entries) {
534     int start_offset = 0;
535     for (int xx = 0; xx < p_cb->sys_code_cfg_entries; xx++) {
536       /* remember the beginning of this SC routing entry, just in case we
537        * need to put it in next command */
538       uint8_t* p_start = pp;
539       /* add one SC entry */
540       if (p_cb->sys_code_rt_loc_vs_info[xx] & NFA_EE_AE_ROUTE) {
541         if (start_offset >
542             (sizeof(p_cb->sys_code_cfg) - NFA_EE_SYSTEM_CODE_LEN)) {
543           LOG(ERROR) << StringPrintf("%s:  start_offset higher than 2",
544                                      __func__);
545           return;
546         }
547         uint8_t* p_sys_code_cfg = &p_cb->sys_code_cfg[start_offset];
548         if (nfa_ee_is_active(p_cb->sys_code_rt_loc[xx] | NFA_HANDLE_GROUP_EE)) {
549           if (mute_tech_route_option) {
550             add_route_sys_code_tlv(&pp, p_sys_code_cfg,
551                                    p_cb->sys_code_rt_loc[xx],
552                                    p_cb->sys_code_pwr_cfg[xx]);
553           } else {
554             bool block = 0;
555             uint8_t mask = 0;
556 
557             nfa_dm_get_tech_route_block(&mask, &block);
558 
559             // If block a tech, allow no power states
560             if (block && (mask & NFA_TECHNOLOGY_MASK_F) == 0) {
561               LOG(VERBOSE) << StringPrintf(
562                   "%s:  Blocking SC routing as tech F muted", __func__);
563 
564               add_route_sys_code_tlv(&pp, p_sys_code_cfg, 0x00, 0x00);
565             } else {
566               add_route_sys_code_tlv(&pp, p_sys_code_cfg,
567                                      p_cb->sys_code_rt_loc[xx],
568                                      p_cb->sys_code_pwr_cfg[xx]);
569             }
570           }
571 
572           p_cb->ecb_flags |= NFA_EE_ECB_FLAGS_ROUTING;
573           num_tlv++;
574         } else {
575           LOG(VERBOSE) << StringPrintf("%s:  ignoring route loc%x", __func__,
576                                        p_cb->sys_code_rt_loc[xx]);
577         }
578       }
579       start_offset += NFA_EE_SYSTEM_CODE_LEN;
580       uint8_t new_size = (uint8_t)(pp - p_start);
581       nfa_ee_check_set_routing(new_size, p_max_len, p_buff, p_cur_offset);
582       if (*p_buff == 0 && (num_tlv > 0x00)) {
583         /* just sent routing command, update local */
584         *p_buff = 1;
585         num_tlv = *p_buff;
586         *p_cur_offset = new_size;
587         pp = p_buff + 1;
588         p = pp;
589         memcpy(p, p_start, new_size);
590         pp += new_size;
591       } else {
592         /* add the new entry */
593         *p_buff = num_tlv;
594         *p_cur_offset += new_size;
595       }
596     }
597     LOG(VERBOSE) << StringPrintf("%s: num_tlv:- %d", __func__, num_tlv);
598   } else {
599     LOG(VERBOSE) << StringPrintf("%s: No SC entries available", __func__);
600   }
601 }
602 
603 /*******************************************************************************
604 **
605 ** Function         nfa_ee_conn_cback
606 **
607 ** Description      process connection callback event from stack
608 **
609 ** Returns          void
610 **
611 *******************************************************************************/
nfa_ee_conn_cback(uint8_t conn_id,tNFC_CONN_EVT event,tNFC_CONN * p_data)612 static void nfa_ee_conn_cback(uint8_t conn_id, tNFC_CONN_EVT event,
613                               tNFC_CONN* p_data) {
614   tNFA_EE_NCI_CONN cbk;
615 
616   LOG(VERBOSE) << StringPrintf("%s: conn_id=%d, event=0x%02x", __func__,
617                                conn_id, event);
618 
619   cbk.hdr.event = NFA_EE_NCI_CONN_EVT;
620   if (event == NFC_DATA_CEVT) {
621     /* Treat data event specially to avoid potential memory leak */
622     cbk.hdr.event = NFA_EE_NCI_DATA_EVT;
623   }
624   cbk.conn_id = conn_id;
625   cbk.event = event;
626   cbk.p_data = p_data;
627   tNFA_EE_MSG nfa_ee_msg;
628   nfa_ee_msg.conn = cbk;
629 
630   nfa_ee_evt_hdlr(&nfa_ee_msg.hdr);
631 }
632 
633 /*******************************************************************************
634 **
635 ** Function         nfa_ee_find_max_aid_cfg_len
636 **
637 ** Description      Find the max len for aid_cfg
638 **
639 ** Returns          max length
640 **
641 *******************************************************************************/
nfa_ee_find_max_aid_cfg_len(void)642 int nfa_ee_find_max_aid_cfg_len(void) {
643   int max_lmrt_size = NFC_GetLmrtSize();
644   if (max_lmrt_size > NFA_EE_MAX_PROTO_TECH_EXT_ROUTE_LEN) {
645     return max_lmrt_size - NFA_EE_MAX_PROTO_TECH_EXT_ROUTE_LEN;
646   } else {
647     return 0;
648   }
649 }
650 
651 /*******************************************************************************
652 **
653 ** Function         nfa_ee_find_total_aid_len
654 **
655 ** Description      Find the total len in aid_cfg from start_entry to the last
656 **
657 ** Returns          void
658 **
659 *******************************************************************************/
nfa_ee_find_total_aid_len(tNFA_EE_ECB * p_cb,int start_entry)660 int nfa_ee_find_total_aid_len(tNFA_EE_ECB* p_cb, int start_entry) {
661   int len = 0, xx;
662 
663   if (p_cb->aid_entries > start_entry) {
664     for (xx = start_entry; xx < p_cb->aid_entries; xx++) {
665       len += p_cb->aid_len[xx];
666     }
667   }
668   return len;
669 }
670 
671 /*******************************************************************************
672 **
673 ** Function         nfa_ee_find_total_sys_code_len
674 **
675 ** Description      Find the total len in sys_code_cfg from start_entry to the
676 **                  last in the given ecb.
677 **
678 ** Returns          void
679 **
680 *******************************************************************************/
nfa_ee_find_total_sys_code_len(tNFA_EE_ECB * p_cb,int start_entry)681 int nfa_ee_find_total_sys_code_len(tNFA_EE_ECB* p_cb, int start_entry) {
682   int len = 0;
683   if (p_cb->sys_code_cfg_entries > start_entry) {
684     for (int xx = start_entry; xx < p_cb->sys_code_cfg_entries; xx++) {
685       len += NFA_EE_SYSTEM_CODE_LEN;
686     }
687   }
688   return len;
689 }
690 
691 /*******************************************************************************
692 **
693 ** Function         nfa_all_ee_find_total_sys_code_len
694 **
695 ** Description      Find the total len in sys_code_cfg from start_entry to the
696 **                  last for all EE and DH.
697 **
698 ** Returns          total length
699 **
700 *******************************************************************************/
nfa_all_ee_find_total_sys_code_len()701 int nfa_all_ee_find_total_sys_code_len() {
702   int total_len = 0;
703   for (int32_t xx = 0; xx < NFA_EE_NUM_ECBS; xx++) {
704     tNFA_EE_ECB* p_cb = &nfa_ee_cb.ecb[xx];
705     total_len += nfa_ee_find_total_sys_code_len(p_cb, 0);
706   }
707   return total_len;
708 }
709 
710 /*******************************************************************************
711 **
712 ** Function         nfa_ee_find_aid_offset
713 **
714 ** Description      Given the AID, find the associated tNFA_EE_ECB and the
715 **                  offset in aid_cfg[]. *p_entry is the index.
716 **
717 ** Returns          void
718 **
719 *******************************************************************************/
nfa_ee_find_aid_offset(uint8_t aid_len,uint8_t * p_aid,int * p_offset,int * p_entry)720 tNFA_EE_ECB* nfa_ee_find_aid_offset(uint8_t aid_len, uint8_t* p_aid,
721                                     int* p_offset, int* p_entry) {
722   int xx, yy, aid_len_offset, offset;
723   tNFA_EE_ECB *p_ret = nullptr, *p_ecb;
724 
725   p_ecb = &nfa_ee_cb.ecb[NFA_EE_CB_4_DH];
726   aid_len_offset = 1; /* skip the tag */
727   for (yy = 0; yy <= nfa_ee_cb.cur_ee; yy++) {
728     if (p_ecb->aid_entries) {
729       offset = 0;
730       for (xx = 0; xx < p_ecb->aid_entries; xx++) {
731         if ((p_ecb->aid_cfg[offset + aid_len_offset] == aid_len) &&
732             (memcmp(&p_ecb->aid_cfg[offset + aid_len_offset + 1], p_aid,
733                     aid_len) == 0)) {
734           p_ret = p_ecb;
735           if (p_offset) *p_offset = offset;
736           if (p_entry) *p_entry = xx;
737           break;
738         }
739         offset += p_ecb->aid_len[xx];
740       }
741 
742       if (p_ret) {
743         /* found the entry already */
744         break;
745       }
746     }
747     p_ecb = &nfa_ee_cb.ecb[yy];
748   }
749 
750   return p_ret;
751 }
752 
753 /*******************************************************************************
754  **
755  ** Function         nfa_ee_find_sys_code_offset
756  **
757  ** Description      Given the System Code, find the associated tNFA_EE_ECB and
758  *the
759  **                  offset in sys_code_cfg[]. *p_entry is the index.
760  **
761  ** Returns          void
762  **
763  *******************************************************************************/
nfa_ee_find_sys_code_offset(uint16_t sys_code,int * p_offset,int * p_entry)764 tNFA_EE_ECB* nfa_ee_find_sys_code_offset(uint16_t sys_code, int* p_offset,
765                                          int* p_entry) {
766   tNFA_EE_ECB* p_ret = nullptr;
767 
768   for (uint8_t xx = 0; xx < NFA_EE_NUM_ECBS; xx++) {
769     tNFA_EE_ECB* p_ecb = &nfa_ee_cb.ecb[xx];
770     uint8_t mask = nfa_ee_ecb_to_mask(p_ecb);
771     if ((nfa_ee_cb.ee_cfged & mask) == 0 || p_ecb->sys_code_cfg_entries == 0) {
772       continue; /*try next ecb*/
773     }
774     if (p_ecb->sys_code_cfg_entries) {
775       uint8_t offset = 0;
776       for (uint8_t yy = 0; yy < p_ecb->sys_code_cfg_entries; yy++) {
777         if (offset >=
778             (NFA_EE_MAX_SYSTEM_CODE_ENTRIES * NFA_EE_SYSTEM_CODE_LEN)) {
779           LOG(ERROR) << StringPrintf(
780               "%s:  offset higher than max allowed value", __func__);
781           return nullptr;
782         }
783         if ((memcmp(&p_ecb->sys_code_cfg[offset], &sys_code,
784                     NFA_EE_SYSTEM_CODE_LEN) == 0)) {
785           p_ret = p_ecb;
786           if (p_offset) *p_offset = offset;
787           if (p_entry) *p_entry = yy;
788           break;
789         }
790         offset += NFA_EE_SYSTEM_CODE_LEN;
791       }
792 
793       if (p_ret) {
794         /* found the entry already */
795         return p_ret;
796       }
797     }
798   }
799   return p_ret;
800 }
801 
802 /*******************************************************************************
803 **
804 ** Function         nfa_ee_report_event
805 **
806 ** Description      report the given event to the callback
807 **
808 ** Returns          void
809 **
810 *******************************************************************************/
nfa_ee_report_event(tNFA_EE_CBACK * p_cback,tNFA_EE_EVT event,tNFA_EE_CBACK_DATA * p_data)811 void nfa_ee_report_event(tNFA_EE_CBACK* p_cback, tNFA_EE_EVT event,
812                          tNFA_EE_CBACK_DATA* p_data) {
813   int xx;
814 
815   /* use the given callback, if not NULL */
816   if (p_cback) {
817     (*p_cback)(event, p_data);
818     return;
819   }
820   /* if the given is NULL, report to all registered ones */
821   for (xx = 0; xx < NFA_EE_MAX_CBACKS; xx++) {
822     if (nfa_ee_cb.p_ee_cback[xx] != nullptr) {
823       (*nfa_ee_cb.p_ee_cback[xx])(event, p_data);
824     }
825   }
826 }
827 /*******************************************************************************
828 **
829 ** Function         nfa_ee_start_timer
830 **
831 ** Description      start the de-bounce timer
832 **
833 ** Returns          void
834 **
835 *******************************************************************************/
nfa_ee_start_timer(void)836 void nfa_ee_start_timer(void) {
837   if (nfa_ee_route_debounce_timer && nfa_dm_is_active())
838     nfa_sys_start_timer(&nfa_ee_cb.timer, NFA_EE_ROUT_TIMEOUT_EVT,
839                         NFA_EE_ROUT_TIMEOUT_VAL);
840 }
841 
842 /*******************************************************************************
843 **
844 ** Function         nfa_ee_api_discover
845 **
846 ** Description      process discover command from user
847 **
848 ** Returns          void
849 **
850 *******************************************************************************/
nfa_ee_api_discover(tNFA_EE_MSG * p_data)851 void nfa_ee_api_discover(tNFA_EE_MSG* p_data) {
852   tNFA_EE_CBACK* p_cback = p_data->ee_discover.p_cback;
853   tNFA_EE_CBACK_DATA evt_data = {0};
854 
855   LOG(VERBOSE) << StringPrintf("%s: in_use=%d", __func__,
856                                nfa_ee_cb.discv_timer.in_use);
857   if (nfa_ee_cb.discv_timer.in_use) {
858     nfa_sys_stop_timer(&nfa_ee_cb.discv_timer);
859     if (NFA_GetNCIVersion() < NCI_VERSION_2_0) NFC_NfceeDiscover(false);
860   }
861   if (nfa_ee_cb.p_ee_disc_cback == nullptr &&
862       NFC_NfceeDiscover(true) == NFC_STATUS_OK) {
863     nfa_ee_cb.p_ee_disc_cback = p_cback;
864   } else {
865     evt_data.status = NFA_STATUS_FAILED;
866     nfa_ee_report_event(p_cback, NFA_EE_DISCOVER_EVT, &evt_data);
867   }
868 }
869 
870 /*******************************************************************************
871 **
872 ** Function         nfa_ee_api_register
873 **
874 ** Description      process register command from user
875 **
876 ** Returns          void
877 **
878 *******************************************************************************/
nfa_ee_api_register(tNFA_EE_MSG * p_data)879 void nfa_ee_api_register(tNFA_EE_MSG* p_data) {
880   int xx;
881   tNFA_EE_CBACK* p_cback = p_data->ee_register.p_cback;
882   tNFA_EE_CBACK_DATA evt_data = {0};
883   bool found = false;
884 
885   evt_data.ee_register = NFA_STATUS_FAILED;
886   /* loop through all entries to see if there's a matching callback */
887   for (xx = 0; xx < NFA_EE_MAX_CBACKS; xx++) {
888     if (nfa_ee_cb.p_ee_cback[xx] == p_cback) {
889       evt_data.ee_register = NFA_STATUS_OK;
890       found = true;
891       break;
892     }
893   }
894 
895   /* If no matching callback, allocated an entry */
896   if (!found) {
897     for (xx = 0; xx < NFA_EE_MAX_CBACKS; xx++) {
898       if (nfa_ee_cb.p_ee_cback[xx] == nullptr) {
899         nfa_ee_cb.p_ee_cback[xx] = p_cback;
900         evt_data.ee_register = NFA_STATUS_OK;
901         break;
902       }
903     }
904   }
905 
906   /* This callback is verified (not NULL) in NFA_EeRegister() */
907   (*p_cback)(NFA_EE_REGISTER_EVT, &evt_data);
908 
909   /* report NFCEE Discovery Request collected during booting up */
910   nfa_ee_build_discover_req_evt(&evt_data.discover_req);
911   (*p_cback)(NFA_EE_DISCOVER_REQ_EVT, &evt_data);
912 }
913 
914 /*******************************************************************************
915 **
916 ** Function         nfa_ee_api_deregister
917 **
918 ** Description      process de-register command from user
919 **
920 ** Returns          void
921 **
922 *******************************************************************************/
nfa_ee_api_deregister(tNFA_EE_MSG * p_data)923 void nfa_ee_api_deregister(tNFA_EE_MSG* p_data) {
924   tNFA_EE_CBACK* p_cback = nullptr;
925   int index = p_data->deregister.index;
926   tNFA_EE_CBACK_DATA evt_data = {0};
927 
928   LOG(VERBOSE) << StringPrintf("%s", __func__);
929 
930   p_cback = nfa_ee_cb.p_ee_cback[index];
931   nfa_ee_cb.p_ee_cback[index] = nullptr;
932   if (p_cback) (*p_cback)(NFA_EE_DEREGISTER_EVT, &evt_data);
933 }
934 
935 /*******************************************************************************
936 **
937 ** Function         nfa_ee_api_mode_set
938 **
939 ** Description      process mode set command from user
940 **
941 ** Returns          void
942 **
943 *******************************************************************************/
nfa_ee_api_mode_set(tNFA_EE_MSG * p_data)944 void nfa_ee_api_mode_set(tNFA_EE_MSG* p_data) {
945   tNFA_EE_ECB* p_cb = p_data->cfg_hdr.p_cb;
946   tNFA_EE_MODE_SET mode_set;
947   LOG(VERBOSE) << StringPrintf("%s: handle=0x%02x mode=%d", __func__,
948                                p_cb->nfcee_id, p_data->mode_set.mode);
949   mode_set.status = NFC_NfceeModeSet(p_cb->nfcee_id, p_data->mode_set.mode);
950   if (mode_set.status != NFC_STATUS_OK) {
951     /* the api is rejected at NFC layer, report the failure status right away */
952     mode_set.ee_handle = (tNFA_HANDLE)p_cb->nfcee_id | NFA_HANDLE_GROUP_EE;
953     mode_set.ee_status = p_data->mode_set.mode;
954     tNFA_EE_CBACK_DATA nfa_ee_cback_data;
955     nfa_ee_cback_data.mode_set = mode_set;
956     nfa_ee_report_event(nullptr, NFA_EE_MODE_SET_EVT, &nfa_ee_cback_data);
957     return;
958   }
959   /* set the NFA_EE_STATUS_PENDING bit to indicate the status is not exactly
960    * active */
961   if (p_data->mode_set.mode == NFC_MODE_ACTIVATE)
962     p_cb->ee_status = NFA_EE_STATUS_PENDING | NFA_EE_STATUS_ACTIVE;
963   else {
964     p_cb->ee_status = NFA_EE_STATUS_INACTIVE;
965     /* DH should release the NCI connection before deactivate the NFCEE */
966     if (p_cb->conn_st == NFA_EE_CONN_ST_CONN) {
967       p_cb->conn_st = NFA_EE_CONN_ST_DISC;
968       NFC_ConnClose(p_cb->conn_id);
969     }
970   }
971   /* report the NFA_EE_MODE_SET_EVT status on the response from NFCC */
972 }
973 
974 /*******************************************************************************
975 **
976 ** Function         nfa_ee_api_set_tech_cfg
977 **
978 ** Description      process set technology routing configuration from user
979 **                  start a 1 second timer. When the timer expires,
980 **                  the configuration collected in control block is sent to NFCC
981 **
982 ** Returns          void
983 **
984 *******************************************************************************/
nfa_ee_api_set_tech_cfg(tNFA_EE_MSG * p_data)985 void nfa_ee_api_set_tech_cfg(tNFA_EE_MSG* p_data) {
986   tNFA_EE_ECB* p_cb = p_data->cfg_hdr.p_cb;
987   tNFA_EE_CBACK_DATA evt_data = {0};
988   tNFA_TECHNOLOGY_MASK old_tech_switch_on = p_cb->tech_switch_on;
989   tNFA_TECHNOLOGY_MASK old_tech_switch_off = p_cb->tech_switch_off;
990   tNFA_TECHNOLOGY_MASK old_tech_battery_off = p_cb->tech_battery_off;
991   tNFA_TECHNOLOGY_MASK old_tech_screen_lock = p_cb->tech_screen_lock;
992   tNFA_TECHNOLOGY_MASK old_tech_screen_off = p_cb->tech_screen_off;
993   tNFA_TECHNOLOGY_MASK old_tech_screen_off_lock = p_cb->tech_screen_off_lock;
994   uint8_t old_size_mask_tech = p_cb->size_mask_tech;
995 
996   if ((p_cb->tech_switch_on == p_data->set_tech.technologies_switch_on) &&
997       (p_cb->tech_switch_off == p_data->set_tech.technologies_switch_off) &&
998       (p_cb->tech_battery_off == p_data->set_tech.technologies_battery_off) &&
999       (p_cb->tech_screen_lock == p_data->set_tech.technologies_screen_lock) &&
1000       (p_cb->tech_screen_off == p_data->set_tech.technologies_screen_off) &&
1001       (p_cb->tech_screen_off_lock ==
1002        p_data->set_tech.technologies_screen_off_lock)) {
1003     /* nothing to change */
1004     evt_data.status = NFA_STATUS_OK;
1005     nfa_ee_report_event(p_cb->p_ee_cback, NFA_EE_SET_TECH_CFG_EVT, &evt_data);
1006     return;
1007   }
1008 
1009   p_cb->tech_switch_on |= p_data->set_tech.technologies_switch_on;
1010   p_cb->tech_switch_off |= p_data->set_tech.technologies_switch_off;
1011   p_cb->tech_battery_off |= p_data->set_tech.technologies_battery_off;
1012   p_cb->tech_screen_lock |= p_data->set_tech.technologies_screen_lock;
1013   p_cb->tech_screen_off |= p_data->set_tech.technologies_screen_off;
1014   p_cb->tech_screen_off_lock |= p_data->set_tech.technologies_screen_off_lock;
1015   nfa_ee_update_route_size(p_cb);
1016   if (nfa_ee_total_lmrt_size() > NFC_GetLmrtSize()) {
1017     LOG(ERROR) << StringPrintf("%s: Exceed LMRT size", __func__);
1018     evt_data.status = NFA_STATUS_BUFFER_FULL;
1019     p_cb->tech_switch_on = old_tech_switch_on;
1020     p_cb->tech_switch_off = old_tech_switch_off;
1021     p_cb->tech_battery_off = old_tech_battery_off;
1022     p_cb->tech_screen_lock = old_tech_screen_lock;
1023     p_cb->tech_screen_off = old_tech_screen_off;
1024     p_cb->tech_screen_off_lock = old_tech_screen_off_lock;
1025     p_cb->size_mask_tech = old_size_mask_tech;
1026   } else {
1027     p_cb->ecb_flags |= NFA_EE_ECB_FLAGS_TECH;
1028     if (p_cb->tech_switch_on | p_cb->tech_switch_off | p_cb->tech_battery_off |
1029         p_cb->tech_screen_lock | p_cb->tech_screen_off |
1030         p_cb->tech_screen_off_lock) {
1031       /* if any technology in any power mode is configured, mark this entry as
1032        * configured */
1033       nfa_ee_cb.ee_cfged |= nfa_ee_ecb_to_mask(p_cb);
1034     }
1035     nfa_ee_start_timer();
1036   }
1037   nfa_ee_report_event(p_cb->p_ee_cback, NFA_EE_SET_TECH_CFG_EVT, &evt_data);
1038 }
1039 
1040 /*******************************************************************************
1041 **
1042 ** Function         nfa_ee_api_clear_tech_cfg
1043 **
1044 ** Description      process clear technology routing configuration from user
1045 **                  start a 1 second timer. When the timer expires,
1046 **                  the configuration collected in control block is sent to NFCC
1047 **
1048 ** Returns          void
1049 **
1050 *******************************************************************************/
nfa_ee_api_clear_tech_cfg(tNFA_EE_MSG * p_data)1051 void nfa_ee_api_clear_tech_cfg(tNFA_EE_MSG* p_data) {
1052   tNFA_EE_ECB* p_cb = p_data->cfg_hdr.p_cb;
1053   tNFA_EE_CBACK_DATA evt_data = {0};
1054 
1055   tNFA_TECHNOLOGY_MASK old_tech_switch_on = p_cb->tech_switch_on;
1056   tNFA_TECHNOLOGY_MASK old_tech_switch_off = p_cb->tech_switch_off;
1057   tNFA_TECHNOLOGY_MASK old_tech_battery_off = p_cb->tech_battery_off;
1058   tNFA_TECHNOLOGY_MASK old_tech_screen_lock = p_cb->tech_screen_lock;
1059   tNFA_TECHNOLOGY_MASK old_tech_screen_off = p_cb->tech_screen_off;
1060   tNFA_TECHNOLOGY_MASK old_tech_screen_off_lock = p_cb->tech_screen_off_lock;
1061 
1062   p_cb->tech_switch_on &= ~p_data->clear_tech.technologies_switch_on;
1063   p_cb->tech_switch_off &= ~p_data->clear_tech.technologies_switch_off;
1064   p_cb->tech_battery_off &= ~p_data->clear_tech.technologies_battery_off;
1065   p_cb->tech_screen_lock &= ~p_data->clear_tech.technologies_screen_lock;
1066   p_cb->tech_screen_off &= ~p_data->clear_tech.technologies_screen_off;
1067   p_cb->tech_screen_off_lock &=
1068       ~p_data->clear_tech.technologies_screen_off_lock;
1069 
1070   if ((p_cb->tech_switch_on == old_tech_switch_on) &&
1071       (p_cb->tech_switch_off == old_tech_switch_off) &&
1072       (p_cb->tech_battery_off == old_tech_battery_off) &&
1073       (p_cb->tech_screen_lock == old_tech_screen_lock) &&
1074       (p_cb->tech_screen_off == old_tech_screen_off) &&
1075       (p_cb->tech_screen_off_lock == old_tech_screen_off_lock)) {
1076     /* nothing to change */
1077     evt_data.status = NFA_STATUS_OK;
1078     nfa_ee_report_event(p_cb->p_ee_cback, NFA_EE_CLEAR_TECH_CFG_EVT, &evt_data);
1079     return;
1080   }
1081   nfa_ee_update_route_size(p_cb);
1082   p_cb->ecb_flags |= NFA_EE_ECB_FLAGS_TECH;
1083 
1084   nfa_ee_start_timer();
1085   nfa_ee_report_event(p_cb->p_ee_cback, NFA_EE_CLEAR_TECH_CFG_EVT, &evt_data);
1086 }
1087 
1088 /*******************************************************************************
1089 **
1090 ** Function         nfa_ee_api_set_proto_cfg
1091 **
1092 ** Description      process set protocol routing configuration from user
1093 **                  start a 1 second timer. When the timer expires,
1094 **                  the configuration collected in control block is sent to NFCC
1095 **
1096 ** Returns          void
1097 **
1098 *******************************************************************************/
nfa_ee_api_set_proto_cfg(tNFA_EE_MSG * p_data)1099 void nfa_ee_api_set_proto_cfg(tNFA_EE_MSG* p_data) {
1100   tNFA_EE_ECB* p_cb = p_data->cfg_hdr.p_cb;
1101   tNFA_EE_CBACK_DATA evt_data = {0};
1102   tNFA_PROTOCOL_MASK old_proto_switch_on = p_cb->proto_switch_on;
1103   tNFA_PROTOCOL_MASK old_proto_switch_off = p_cb->proto_switch_off;
1104   tNFA_PROTOCOL_MASK old_proto_battery_off = p_cb->proto_battery_off;
1105   tNFA_PROTOCOL_MASK old_proto_screen_lock = p_cb->proto_screen_lock;
1106   tNFA_PROTOCOL_MASK old_proto_screen_off = p_cb->proto_screen_off;
1107   tNFA_PROTOCOL_MASK old_proto_screen_off_lock = p_cb->proto_screen_off_lock;
1108   uint8_t old_size_mask_proto = p_cb->size_mask_proto;
1109 
1110   if ((p_cb->proto_switch_on == p_data->set_proto.protocols_switch_on) &&
1111       (p_cb->proto_switch_off == p_data->set_proto.protocols_switch_off) &&
1112       (p_cb->proto_battery_off == p_data->set_proto.protocols_battery_off) &&
1113       (p_cb->proto_screen_lock == p_data->set_proto.protocols_screen_lock) &&
1114       (p_cb->proto_screen_off == p_data->set_proto.protocols_screen_off) &&
1115       (p_cb->proto_screen_off_lock ==
1116        p_data->set_proto.protocols_screen_off_lock)) {
1117     /* nothing to change */
1118     evt_data.status = NFA_STATUS_OK;
1119     nfa_ee_report_event(p_cb->p_ee_cback, NFA_EE_SET_PROTO_CFG_EVT, &evt_data);
1120     return;
1121   }
1122 
1123   p_cb->proto_switch_on |= p_data->set_proto.protocols_switch_on;
1124   p_cb->proto_switch_off |= p_data->set_proto.protocols_switch_off;
1125   p_cb->proto_battery_off |= p_data->set_proto.protocols_battery_off;
1126   p_cb->proto_screen_lock |= p_data->set_proto.protocols_screen_lock;
1127   p_cb->proto_screen_off |= p_data->set_proto.protocols_screen_off;
1128   p_cb->proto_screen_off_lock |= p_data->set_proto.protocols_screen_off_lock;
1129   nfa_ee_update_route_size(p_cb);
1130   if (nfa_ee_total_lmrt_size() > NFC_GetLmrtSize()) {
1131     LOG(ERROR) << StringPrintf("%s: Exceed LMRT size", __func__);
1132     evt_data.status = NFA_STATUS_BUFFER_FULL;
1133     p_cb->proto_switch_on = old_proto_switch_on;
1134     p_cb->proto_switch_off = old_proto_switch_off;
1135     p_cb->proto_battery_off = old_proto_battery_off;
1136     p_cb->proto_screen_lock = old_proto_screen_lock;
1137     p_cb->proto_screen_off = old_proto_screen_off;
1138     p_cb->proto_screen_off_lock = old_proto_screen_off_lock;
1139     p_cb->size_mask_proto = old_size_mask_proto;
1140   } else {
1141     p_cb->ecb_flags |= NFA_EE_ECB_FLAGS_PROTO;
1142     if (p_cb->proto_switch_on | p_cb->proto_switch_off |
1143         p_cb->proto_battery_off | p_cb->proto_screen_lock |
1144         p_cb->proto_screen_off | p_cb->proto_screen_off_lock) {
1145       /* if any protocol in any power mode is configured, mark this entry as
1146        * configured */
1147       nfa_ee_cb.ee_cfged |= nfa_ee_ecb_to_mask(p_cb);
1148     }
1149     nfa_ee_start_timer();
1150   }
1151   nfa_ee_report_event(p_cb->p_ee_cback, NFA_EE_SET_PROTO_CFG_EVT, &evt_data);
1152 }
1153 
1154 /*******************************************************************************
1155 **
1156 ** Function         nfa_ee_api_clear_proto_cfg
1157 **
1158 ** Description      process clear protocol routing configuration from user
1159 **                  start a 1 second timer. When the timer expires,
1160 **                  the configuration collected in control block is sent to NFCC
1161 **
1162 ** Returns          void
1163 **
1164 *******************************************************************************/
nfa_ee_api_clear_proto_cfg(tNFA_EE_MSG * p_data)1165 void nfa_ee_api_clear_proto_cfg(tNFA_EE_MSG* p_data) {
1166   tNFA_EE_ECB* p_cb = p_data->cfg_hdr.p_cb;
1167   tNFA_EE_CBACK_DATA evt_data = {0};
1168 
1169   tNFA_TECHNOLOGY_MASK old_proto_switch_on = p_cb->proto_switch_on;
1170   tNFA_TECHNOLOGY_MASK old_proto_switch_off = p_cb->proto_switch_off;
1171   tNFA_TECHNOLOGY_MASK old_proto_battery_off = p_cb->proto_battery_off;
1172   tNFA_TECHNOLOGY_MASK old_proto_screen_lock = p_cb->proto_screen_lock;
1173   tNFA_TECHNOLOGY_MASK old_proto_screen_off = p_cb->proto_screen_off;
1174   tNFA_TECHNOLOGY_MASK old_proto_screen_off_lock = p_cb->proto_screen_off_lock;
1175 
1176   p_cb->proto_switch_on &= ~p_data->clear_proto.protocols_switch_on;
1177   p_cb->proto_switch_off &= ~p_data->clear_proto.protocols_switch_off;
1178   p_cb->proto_battery_off &= ~p_data->clear_proto.protocols_battery_off;
1179   p_cb->proto_screen_lock &= ~p_data->clear_proto.protocols_screen_lock;
1180   p_cb->proto_screen_off &= ~p_data->clear_proto.protocols_screen_off;
1181   p_cb->proto_screen_off_lock &= ~p_data->clear_proto.protocols_screen_off_lock;
1182 
1183   if ((p_cb->proto_switch_on == old_proto_switch_on) &&
1184       (p_cb->proto_switch_off == old_proto_switch_off) &&
1185       (p_cb->proto_battery_off == old_proto_battery_off) &&
1186       (p_cb->proto_screen_lock == old_proto_screen_lock) &&
1187       (p_cb->proto_screen_off == old_proto_screen_off) &&
1188       (p_cb->proto_screen_off_lock == old_proto_screen_off_lock)) {
1189     /* nothing to change */
1190     evt_data.status = NFA_STATUS_OK;
1191     nfa_ee_report_event(p_cb->p_ee_cback, NFA_EE_CLEAR_PROTO_CFG_EVT,
1192                         &evt_data);
1193     return;
1194   }
1195   nfa_ee_update_route_size(p_cb);
1196   p_cb->ecb_flags |= NFA_EE_ECB_FLAGS_PROTO;
1197 
1198   nfa_ee_start_timer();
1199   nfa_ee_report_event(p_cb->p_ee_cback, NFA_EE_CLEAR_PROTO_CFG_EVT, &evt_data);
1200 }
1201 
1202 /*******************************************************************************
1203 **
1204 ** Function         nfa_ee_api_add_aid
1205 **
1206 ** Description      process add an AID routing configuration from user
1207 **                  start a 1 second timer. When the timer expires,
1208 **                  the configuration collected in control block is sent to NFCC
1209 **
1210 ** Returns          void
1211 **
1212 *******************************************************************************/
nfa_ee_api_add_aid(tNFA_EE_MSG * p_data)1213 void nfa_ee_api_add_aid(tNFA_EE_MSG* p_data) {
1214   tNFA_EE_API_ADD_AID* p_add = &p_data->add_aid;
1215   tNFA_EE_ECB* p_cb = p_data->cfg_hdr.p_cb;
1216   tNFA_EE_ECB* p_chk_cb;
1217   uint8_t *p, *p_start;
1218   int len, len_needed;
1219   tNFA_EE_CBACK_DATA evt_data = {0};
1220   int offset = 0, entry = 0;
1221   uint16_t new_size;
1222 
1223   nfa_ee_trace_aid("nfa_ee_api_add_aid", p_cb->nfcee_id, p_add->aid_len,
1224                    p_add->p_aid);
1225   int max_aid_cfg_length = nfa_ee_find_max_aid_cfg_len();
1226   int max_aid_entries = max_aid_cfg_length / NFA_MIN_AID_LEN + 1;
1227 
1228   p_chk_cb =
1229       nfa_ee_find_aid_offset(p_add->aid_len, p_add->p_aid, &offset, &entry);
1230   if (p_chk_cb) {
1231     LOG(WARNING) << StringPrintf("%s: The AID entry is already in the database",
1232                                  __func__);
1233     if (p_chk_cb == p_cb) {
1234       p_cb->aid_rt_info[entry] |= NFA_EE_AE_ROUTE;
1235       p_cb->aid_info[entry] = p_add->aidInfo;
1236       new_size = nfa_ee_total_lmrt_size();
1237       if (new_size > NFC_GetLmrtSize()) {
1238         LOG(ERROR) << StringPrintf("%s: Exceed LMRT size=%d (add ROUTE)",
1239                                    __func__, new_size);
1240         evt_data.status = NFA_STATUS_BUFFER_FULL;
1241         p_cb->aid_rt_info[entry] &= ~NFA_EE_AE_ROUTE;
1242       } else {
1243         p_cb->aid_pwr_cfg[entry] = p_add->power_state;
1244       }
1245     } else {
1246       LOG(ERROR) << StringPrintf(
1247           "%s: The AID entry is already in the database for different NFCEE "
1248           "ID=0x%02x",
1249           __func__, p_chk_cb->nfcee_id);
1250       evt_data.status = NFA_STATUS_SEMANTIC_ERROR;
1251     }
1252   } else {
1253     /* Find the total length so far */
1254     len = nfa_ee_find_total_aid_len(p_cb, 0);
1255 
1256     /* make sure the control block has enough room to hold this entry */
1257     len_needed = p_add->aid_len + 2; /* tag/len */
1258 
1259     if ((len_needed + len) > max_aid_cfg_length) {
1260       LOG(ERROR) << StringPrintf(
1261           "%s: Exceed capacity: (len_needed=%d + len=%d) > "
1262           "NFA_EE_MAX_AID_CFG_LEN=%d",
1263           __func__, len_needed, len, max_aid_cfg_length);
1264       evt_data.status = NFA_STATUS_BUFFER_FULL;
1265     } else if (p_cb->aid_entries < max_aid_entries) {
1266       /* 4 = 1 (tag) + 1 (len) + 1(nfcee_id) + 1(power cfg) */
1267       new_size = nfa_ee_total_lmrt_size() + 4 + p_add->aid_len;
1268       if (new_size > NFC_GetLmrtSize()) {
1269         LOG(ERROR) << StringPrintf("%s: Exceed LMRT size=%d", __func__,
1270                                    new_size);
1271         evt_data.status = NFA_STATUS_BUFFER_FULL;
1272       } else {
1273         /* add AID */
1274         p_cb->aid_pwr_cfg[p_cb->aid_entries] = p_add->power_state;
1275         p_cb->aid_info[p_cb->aid_entries] = p_add->aidInfo;
1276         p_cb->aid_rt_info[p_cb->aid_entries] = NFA_EE_AE_ROUTE;
1277         p = p_cb->aid_cfg + len;
1278         p_start = p;
1279         *p++ = NFA_EE_AID_CFG_TAG_NAME;
1280         *p++ = p_add->aid_len;
1281         memcpy(p, p_add->p_aid, p_add->aid_len);
1282         p += p_add->aid_len;
1283 
1284         p_cb->aid_len[p_cb->aid_entries++] = (uint8_t)(p - p_start);
1285       }
1286     } else {
1287       LOG(ERROR) << StringPrintf("%s: Exceed NFA_EE_MAX_AID_ENTRIES=%d",
1288                                  __func__, max_aid_entries);
1289       evt_data.status = NFA_STATUS_BUFFER_FULL;
1290     }
1291   }
1292 
1293   if (evt_data.status == NFA_STATUS_OK) {
1294     /* mark AID changed */
1295     p_cb->ecb_flags |= NFA_EE_ECB_FLAGS_AID;
1296     nfa_ee_cb.ee_cfged |= nfa_ee_ecb_to_mask(p_cb);
1297     // Case default AID is on DH: one ecb for DH and one ecb for default AID
1298     // If default AID is DH then mask 0x10 (idx 4 is DH entry in ecb) is not set
1299     // If no other type of routing done on DH, then default AID route is not
1300     // taken into account
1301     for (int i = 0; i < NFA_EE_NUM_ECBS; i++) {
1302       if (nfa_ee_cb.ecb[i].nfcee_id == p_cb->nfcee_id) {
1303         nfa_ee_cb.ee_cfged |= nfa_ee_ecb_to_mask(&nfa_ee_cb.ecb[i]);
1304         /* mark AID changed */
1305         nfa_ee_cb.ecb[i].ecb_flags |= NFA_EE_ECB_FLAGS_AID;
1306         break;
1307       }
1308     }
1309     nfa_ee_update_route_aid_size(p_cb);
1310     nfa_ee_start_timer();
1311   }
1312   LOG(VERBOSE) << StringPrintf("%s: status=%d ee_cfged=0x%02x ", __func__,
1313                                evt_data.status, nfa_ee_cb.ee_cfged);
1314   if (evt_data.status == NFA_STATUS_BUFFER_FULL)
1315     nfc::stats::stats_write(nfc::stats::NFC_ERROR_OCCURRED,
1316                             (int32_t)AID_OVERFLOW, 0, 0);
1317   /* report the status of this operation */
1318   nfa_ee_report_event(p_cb->p_ee_cback, NFA_EE_ADD_AID_EVT, &evt_data);
1319 }
1320 
1321 /*******************************************************************************
1322 **
1323 ** Function         nfa_ee_api_remove_aid
1324 **
1325 ** Description      process remove an AID routing configuration from user
1326 **                  start a 1 second timer. When the timer expires,
1327 **                  the configuration collected in control block is sent to NFCC
1328 **
1329 ** Returns          void
1330 **
1331 *******************************************************************************/
nfa_ee_api_remove_aid(tNFA_EE_MSG * p_data)1332 void nfa_ee_api_remove_aid(tNFA_EE_MSG* p_data) {
1333   tNFA_EE_ECB* p_cb;
1334   tNFA_EE_CBACK_DATA evt_data = {0};
1335   int offset = 0, entry = 0, len;
1336   int rest_len;
1337   tNFA_EE_CBACK* p_cback = nullptr;
1338 
1339   nfa_ee_trace_aid("nfa_ee_api_remove_aid", 0, p_data->rm_aid.aid_len,
1340                    p_data->rm_aid.p_aid);
1341   p_cb = nfa_ee_find_aid_offset(p_data->rm_aid.aid_len, p_data->rm_aid.p_aid,
1342                                 &offset, &entry);
1343   if (p_cb && p_cb->aid_entries) {
1344     LOG(VERBOSE) << StringPrintf("%s: aid_rt_info[%d]=0x%02x", __func__, entry,
1345                                  p_cb->aid_rt_info[entry]);
1346     /* mark routing and VS changed */
1347     if (p_cb->aid_rt_info[entry] & NFA_EE_AE_ROUTE)
1348       p_cb->ecb_flags |= NFA_EE_ECB_FLAGS_AID;
1349 
1350     if (p_cb->aid_rt_info[entry] & NFA_EE_AE_VS)
1351       p_cb->ecb_flags |= NFA_EE_ECB_FLAGS_VS;
1352 
1353     /* remove the aid */
1354     if ((entry + 1) < p_cb->aid_entries) {
1355       /* not the last entry, move the aid entries in control block */
1356       /* Find the total len from the next entry to the last one */
1357       rest_len = nfa_ee_find_total_aid_len(p_cb, entry + 1);
1358 
1359       len = p_cb->aid_len[entry];
1360       LOG(VERBOSE) << StringPrintf("%s: len=%d, rest_len=%d", __func__, len,
1361                                    rest_len);
1362       GKI_shiftup(&p_cb->aid_cfg[offset], &p_cb->aid_cfg[offset + len],
1363                   rest_len);
1364       rest_len = p_cb->aid_entries - entry;
1365       GKI_shiftup(&p_cb->aid_len[entry], &p_cb->aid_len[entry + 1], rest_len);
1366       GKI_shiftup(&p_cb->aid_pwr_cfg[entry], &p_cb->aid_pwr_cfg[entry + 1],
1367                   rest_len);
1368       GKI_shiftup(&p_cb->aid_rt_info[entry], &p_cb->aid_rt_info[entry + 1],
1369                   rest_len);
1370     }
1371     /* else the last entry, just reduce the aid_entries by 1 */
1372     p_cb->aid_entries--;
1373     nfa_ee_cb.ee_cfged |= nfa_ee_ecb_to_mask(p_cb);
1374     nfa_ee_update_route_aid_size(p_cb);
1375     nfa_ee_start_timer();
1376     /* report NFA_EE_REMOVE_AID_EVT to the callback associated the NFCEE */
1377     p_cback = p_cb->p_ee_cback;
1378   } else if ((p_data->rm_aid.aid_len == sizeof(NFA_REMOVE_ALL_AID)) &&
1379              (0 == memcmp(NFA_REMOVE_ALL_AID, p_data->rm_aid.p_aid,
1380                           p_data->rm_aid.aid_len))) {
1381     int max_aid_cfg_length = nfa_ee_find_max_aid_cfg_len();
1382     int max_aid_entries = max_aid_cfg_length / NFA_MIN_AID_LEN + 1;
1383 
1384     /*Clear All AIDs*/
1385     uint32_t xx;
1386     tNFA_EE_ECB* p_cb = nfa_ee_cb.ecb;
1387     for (xx = 0; xx < NFA_EE_MAX_EE_SUPPORTED; xx++, p_cb++) {
1388       if (p_cb->aid_entries) {
1389         memset(&p_cb->aid_cfg[0], 0x00, sizeof(p_cb->aid_cfg));
1390         memset(&p_cb->aid_len[0], 0x00, max_aid_entries);
1391         memset(&p_cb->aid_pwr_cfg[0], 0x00, max_aid_entries);
1392         memset(&p_cb->aid_rt_info[0], 0x00, max_aid_entries);
1393         p_cb->aid_entries = 0;
1394 
1395         p_cb->size_aid = 0;
1396 
1397         nfa_ee_cb.ee_cfged |= nfa_ee_ecb_to_mask(p_cb);
1398       }
1399     }
1400 
1401     // Clear content of NFA_EE_CB_4_DH entry
1402     tNFA_EE_ECB* p_ecb = &nfa_ee_cb.ecb[NFA_EE_CB_4_DH];
1403     memset(&p_ecb->aid_cfg[0], 0x00, sizeof(p_ecb->aid_cfg));
1404     memset(&p_ecb->aid_len[0], 0x00, max_aid_entries);
1405     memset(&p_ecb->aid_pwr_cfg[0], 0x00, max_aid_entries);
1406     memset(&p_ecb->aid_rt_info[0], 0x00, max_aid_entries);
1407     p_ecb->aid_entries = 0;
1408     p_ecb->size_aid = 0;
1409 
1410     p_cb->ecb_flags |= NFA_EE_ECB_FLAGS_AID;
1411     nfa_ee_cb.ee_cfged |= nfa_ee_ecb_to_mask(p_ecb);
1412   } else {
1413     LOG(WARNING) << StringPrintf("%s: The AID entry is not in the database",
1414                                  __func__);
1415     evt_data.status = NFA_STATUS_INVALID_PARAM;
1416   }
1417   nfa_ee_report_event(p_cback, NFA_EE_REMOVE_AID_EVT, &evt_data);
1418 }
1419 
1420 /*******************************************************************************
1421  **
1422  ** Function         nfa_ee_api_add_sys_code
1423  **
1424  ** Description      Adds System Code routing configuration from user. When the
1425  **                  timer expires, the configuration collected in control block
1426  **                  is sent to NFCC
1427  **
1428  ** Returns          void
1429  **
1430  *******************************************************************************/
nfa_ee_api_add_sys_code(tNFA_EE_MSG * p_data)1431 void nfa_ee_api_add_sys_code(tNFA_EE_MSG* p_data) {
1432   tNFA_EE_CBACK_DATA evt_data = {0};
1433   tNFA_EE_API_ADD_SYSCODE* p_add = &p_data->add_syscode;
1434   tNFA_EE_ECB* p_cb = p_data->cfg_hdr.p_cb;
1435 
1436   LOG(VERBOSE) << StringPrintf("%s: id=0x%x SC=0x%X ", __func__,
1437                                p_add->nfcee_id, p_add->syscode);
1438 
1439   int offset = 0, entry = 0;
1440   tNFA_EE_ECB* p_chk_cb =
1441       nfa_ee_find_sys_code_offset(p_add->syscode, &offset, &entry);
1442 
1443   if (p_chk_cb) {
1444     LOG(VERBOSE) << StringPrintf(
1445         "%s: The SC entry already registered "
1446         "for this NFCEE id=0x%02x",
1447         __func__, p_add->nfcee_id);
1448 
1449     if (p_chk_cb == p_cb) {
1450       p_cb->sys_code_rt_loc_vs_info[entry] |= NFA_EE_AE_ROUTE;
1451       uint16_t new_size = nfa_ee_total_lmrt_size();
1452       if (new_size > NFC_GetLmrtSize()) {
1453         LOG(ERROR) << StringPrintf("%s: Exceeded LMRT size=%d (add SYSCODE)",
1454                                    __func__, new_size);
1455         evt_data.status = NFA_STATUS_BUFFER_FULL;
1456         p_cb->sys_code_rt_loc_vs_info[entry] &= ~NFA_EE_AE_ROUTE;
1457       } else {
1458         p_cb->sys_code_pwr_cfg[entry] = p_add->power_state;
1459       }
1460     } else {
1461       LOG(ERROR) << StringPrintf(
1462           "%s: SystemCode entry already registered for different "
1463           "NFCEE id=0x%02x",
1464           __func__, p_chk_cb->nfcee_id);
1465       evt_data.status = NFA_STATUS_REJECTED;
1466     }
1467   } else {
1468     /* Find the total length so far in sys_code_cfg */
1469     int total_sc_len = nfa_all_ee_find_total_sys_code_len();
1470     /* make sure the control block has enough room to hold this entry */
1471     if ((NFA_EE_SYSTEM_CODE_LEN + total_sc_len) >
1472         NFA_EE_MAX_SYSTEM_CODE_CFG_LEN) {
1473       LOG(ERROR) << StringPrintf(
1474           "%s: Exceeded capacity: (NFA_EE_SYSTEM_CODE_LEN=%d + "
1475           "total_sc_len=%d) > "
1476           "NFA_EE_MAX_SYSTEM_CODE_CFG_LEN=%d",
1477           __func__, NFA_EE_SYSTEM_CODE_LEN, total_sc_len,
1478           NFA_EE_MAX_SYSTEM_CODE_CFG_LEN);
1479       evt_data.status = NFA_STATUS_BUFFER_FULL;
1480     } else if (p_cb->sys_code_cfg_entries < NFA_EE_MAX_SYSTEM_CODE_ENTRIES) {
1481       /* 6 = 1 (tag) + 1 (len) + 1(nfcee_id) + 1(power cfg) + 2(system code)*/
1482       uint16_t new_size =
1483           nfa_ee_total_lmrt_size() + NFA_EE_SYSTEM_CODE_TLV_SIZE;
1484       if (new_size > NFC_GetLmrtSize()) {
1485         LOG(ERROR) << StringPrintf("%s: Exceeded LMRT size=%d", __func__,
1486                                    new_size);
1487         evt_data.status = NFA_STATUS_BUFFER_FULL;
1488       } else {
1489         /* add SC entry*/
1490         uint32_t p_cb_sc_len = nfa_ee_find_total_sys_code_len(p_cb, 0);
1491         p_cb->sys_code_pwr_cfg[p_cb->sys_code_cfg_entries] = p_add->power_state;
1492         p_cb->sys_code_rt_loc[p_cb->sys_code_cfg_entries] = p_add->nfcee_id;
1493         p_cb->sys_code_rt_loc_vs_info[p_cb->sys_code_cfg_entries] =
1494             NFA_EE_AE_ROUTE;
1495 
1496         uint8_t* p = p_cb->sys_code_cfg + p_cb_sc_len;
1497         memcpy(p, &p_add->syscode, NFA_EE_SYSTEM_CODE_LEN);
1498         p += NFA_EE_SYSTEM_CODE_LEN;
1499 
1500         p_cb->sys_code_cfg_entries++;
1501       }
1502     } else {
1503       LOG(ERROR) << StringPrintf(
1504           "%s: Exceeded NFA_EE_MAX_SYSTEM_CODE_ENTRIES=%d", __func__,
1505           NFA_EE_MAX_SYSTEM_CODE_ENTRIES);
1506       evt_data.status = NFA_STATUS_BUFFER_FULL;
1507     }
1508   }
1509 
1510   if (evt_data.status == NFA_STATUS_OK) {
1511     /* mark SC changed */
1512     p_cb->ecb_flags |= NFA_EE_ECB_FLAGS_SYSCODE;
1513     nfa_ee_cb.ee_cfged |= nfa_ee_ecb_to_mask(p_cb);
1514     nfa_ee_update_route_sys_code_size(p_cb);
1515     nfa_ee_start_timer();
1516   }
1517   LOG(VERBOSE) << StringPrintf("%s: status=%d ee_cfged=0x%02x ", __func__,
1518                                evt_data.status, nfa_ee_cb.ee_cfged);
1519 
1520   /* report the status of this operation */
1521   nfa_ee_report_event(p_cb->p_ee_cback, NFA_EE_ADD_SYSCODE_EVT, &evt_data);
1522 }
1523 
1524 /*******************************************************************************
1525 **
1526 ** Function         nfa_ee_api_remove_sys_code
1527 **
1528 ** Description      process remove an System Code routing configuration from
1529 **                  user start a 1 second timer. When the timer expires,
1530 **                  the configuration collected in control block is sent to NFCC
1531 **
1532 ** Returns          void
1533 **
1534 *******************************************************************************/
nfa_ee_api_remove_sys_code(tNFA_EE_MSG * p_data)1535 void nfa_ee_api_remove_sys_code(tNFA_EE_MSG* p_data) {
1536   tNFA_EE_CBACK_DATA evt_data = {0};
1537   tNFA_EE_API_REMOVE_SYSCODE* p_remove = &p_data->rm_syscode;
1538 
1539   LOG(VERBOSE) << StringPrintf("%s SC=0x%x", __func__, p_remove->syscode);
1540 
1541   int offset = 0, entry = 0;
1542   tNFA_EE_ECB* p_cb =
1543       nfa_ee_find_sys_code_offset(p_data->rm_syscode.syscode, &offset, &entry);
1544 
1545   if (p_cb && p_cb->sys_code_cfg_entries) {
1546     LOG(VERBOSE) << StringPrintf("%s: sys_code_rt_loc_vs_info[%d]=0x%02x",
1547                                  __func__, entry,
1548                                  p_cb->sys_code_rt_loc_vs_info[entry]);
1549     /* mark routing and VS changed */
1550     if (p_cb->sys_code_rt_loc_vs_info[entry] & NFA_EE_AE_ROUTE)
1551       p_cb->ecb_flags |= NFA_EE_ECB_FLAGS_SYSCODE;
1552 
1553     if (p_cb->sys_code_rt_loc_vs_info[entry] & NFA_EE_AE_VS)
1554       p_cb->ecb_flags |= NFA_EE_ECB_FLAGS_VS;
1555 
1556     /* remove the system code */
1557     if ((entry + 1) < p_cb->sys_code_cfg_entries) {
1558       /* not the last entry, move the SC entries in control block */
1559       /* Find the total len from the next entry to the last one */
1560       int total_len = nfa_ee_find_total_sys_code_len(p_cb, entry + 1);
1561 
1562       int rm_len = NFA_EE_SYSTEM_CODE_LEN;
1563 
1564       LOG(VERBOSE) << StringPrintf("%s: rm_len=%d, total_len=%d", __func__,
1565                                    rm_len, total_len);
1566 
1567       GKI_shiftup(&p_cb->sys_code_cfg[offset],
1568                   &p_cb->sys_code_cfg[offset + rm_len], total_len);
1569 
1570       total_len = p_cb->sys_code_cfg_entries - entry;
1571 
1572       GKI_shiftup(&p_cb->sys_code_pwr_cfg[entry],
1573                   &p_cb->sys_code_pwr_cfg[entry + 1], total_len);
1574 
1575       GKI_shiftup(&p_cb->sys_code_rt_loc_vs_info[entry],
1576                   &p_cb->sys_code_rt_loc_vs_info[entry + 1], total_len);
1577 
1578       GKI_shiftup(&p_cb->sys_code_rt_loc[entry],
1579                   &p_cb->sys_code_rt_loc[entry + 1], total_len);
1580     }
1581     /* else the last entry, just reduce the aid_entries by 1 */
1582     p_cb->sys_code_cfg_entries--;
1583     nfa_ee_cb.ee_cfged |= nfa_ee_ecb_to_mask(p_cb);
1584     nfa_ee_update_route_sys_code_size(p_cb);
1585     nfa_ee_start_timer();
1586   } else {
1587     LOG(ERROR) << StringPrintf("%s: The SC entry is not in the database",
1588                                __func__);
1589     evt_data.status = NFA_STATUS_INVALID_PARAM;
1590   }
1591   /* report the status of this operation */
1592   if (p_cb) {
1593     nfa_ee_report_event(p_cb->p_ee_cback, NFA_EE_REMOVE_SYSCODE_EVT, &evt_data);
1594   } else {
1595     nfa_ee_report_event(NULL, NFA_EE_REMOVE_SYSCODE_EVT, &evt_data);
1596   }
1597 }
1598 
1599 /*******************************************************************************
1600 **
1601 ** Function         nfa_ee_api_lmrt_size
1602 **
1603 ** Description      Reports the remaining size in the Listen Mode Routing Table
1604 **
1605 ** Returns          void
1606 **
1607 *******************************************************************************/
nfa_ee_api_lmrt_size(tNFA_EE_MSG * p_data)1608 void nfa_ee_api_lmrt_size(__attribute__((unused)) tNFA_EE_MSG* p_data) {
1609   tNFA_EE_CBACK_DATA evt_data = {0};
1610   uint16_t total_size = NFC_GetLmrtSize();
1611 
1612   evt_data.size = total_size - nfa_ee_total_lmrt_size();
1613   LOG(VERBOSE) << StringPrintf("%s: total size=%d remaining size=%d", __func__,
1614                                total_size, evt_data.size);
1615 
1616   nfa_ee_report_event(nullptr, NFA_EE_REMAINING_SIZE_EVT, &evt_data);
1617 }
1618 
1619 /*******************************************************************************
1620 **
1621 ** Function         nfa_ee_api_update_now
1622 **
1623 ** Description      Initiates connection creation process to the given NFCEE
1624 **
1625 ** Returns          void
1626 **
1627 *******************************************************************************/
nfa_ee_api_update_now(tNFA_EE_MSG * p_data)1628 void nfa_ee_api_update_now(tNFA_EE_MSG* p_data) {
1629   tNFA_EE_CBACK_DATA evt_data;
1630 
1631   if (nfa_ee_cb.ee_wait_evt & NFA_EE_WAIT_UPDATE_ALL) {
1632     LOG(ERROR) << StringPrintf(
1633         "%s: still waiting for update complete "
1634         "ee_wait_evt=0x%x wait_rsp=%d",
1635         __func__, nfa_ee_cb.ee_wait_evt, nfa_ee_cb.wait_rsp);
1636     evt_data.status = NFA_STATUS_SEMANTIC_ERROR;
1637     nfa_ee_report_event(nullptr, NFA_EE_UPDATED_EVT, &evt_data);
1638     return;
1639   }
1640   nfa_sys_stop_timer(&nfa_ee_cb.timer);
1641   nfa_ee_cb.ee_cfged |= NFA_EE_CFGED_UPDATE_NOW;
1642   nfa_ee_rout_timeout(p_data);
1643 }
1644 
1645 /*******************************************************************************
1646 **
1647 ** Function         nfa_ee_api_connect
1648 **
1649 ** Description      Initiates connection creation process to the given NFCEE
1650 **
1651 ** Returns          void
1652 **
1653 *******************************************************************************/
nfa_ee_api_connect(tNFA_EE_MSG * p_data)1654 void nfa_ee_api_connect(tNFA_EE_MSG* p_data) {
1655   tNFA_EE_ECB* p_cb = p_data->connect.p_cb;
1656   int xx;
1657   tNFA_EE_CBACK_DATA evt_data = {0};
1658 
1659   evt_data.connect.status = NFA_STATUS_FAILED;
1660   if (p_cb->conn_st == NFA_EE_CONN_ST_NONE) {
1661     for (xx = 0; xx < p_cb->num_interface; xx++) {
1662       if (p_data->connect.ee_interface == p_cb->ee_interface[xx]) {
1663         p_cb->p_ee_cback = p_data->connect.p_cback;
1664         p_cb->conn_st = NFA_EE_CONN_ST_WAIT;
1665         p_cb->use_interface = p_data->connect.ee_interface;
1666         evt_data.connect.status =
1667             NFC_ConnCreate(NCI_DEST_TYPE_NFCEE, p_data->connect.nfcee_id,
1668                            p_data->connect.ee_interface, nfa_ee_conn_cback);
1669         /* report the NFA_EE_CONNECT_EVT status on the response from NFCC */
1670         break;
1671       }
1672     }
1673   }
1674 
1675   if (evt_data.connect.status != NCI_STATUS_OK) {
1676     evt_data.connect.ee_handle =
1677         (tNFA_HANDLE)p_data->connect.nfcee_id | NFA_HANDLE_GROUP_EE;
1678     evt_data.connect.status = NFA_STATUS_INVALID_PARAM;
1679     evt_data.connect.ee_interface = p_data->connect.ee_interface;
1680     nfa_ee_report_event(p_data->connect.p_cback, NFA_EE_CONNECT_EVT, &evt_data);
1681   }
1682 }
1683 
1684 /*******************************************************************************
1685 **
1686 ** Function         nfa_ee_api_send_data
1687 **
1688 ** Description      Send the given data packet to the given NFCEE
1689 **
1690 ** Returns          void
1691 **
1692 *******************************************************************************/
nfa_ee_api_send_data(tNFA_EE_MSG * p_data)1693 void nfa_ee_api_send_data(tNFA_EE_MSG* p_data) {
1694   tNFA_EE_ECB* p_cb = p_data->send_data.p_cb;
1695   NFC_HDR* p_pkt;
1696   uint16_t size = NCI_MSG_OFFSET_SIZE + NCI_DATA_HDR_SIZE +
1697                   p_data->send_data.data_len + NFC_HDR_SIZE;
1698   uint8_t* p;
1699   tNFA_STATUS status = NFA_STATUS_FAILED;
1700 
1701   if (p_cb->conn_st == NFA_EE_CONN_ST_CONN) {
1702     p_pkt = (NFC_HDR*)GKI_getbuf(size);
1703     if (p_pkt) {
1704       p_pkt->offset = NCI_MSG_OFFSET_SIZE + NCI_DATA_HDR_SIZE;
1705       p_pkt->len = p_data->send_data.data_len;
1706       p = (uint8_t*)(p_pkt + 1) + p_pkt->offset;
1707       memcpy(p, p_data->send_data.p_data, p_pkt->len);
1708       NFC_SendData(p_cb->conn_id, p_pkt);
1709     } else {
1710       tNFA_EE_CBACK_DATA nfa_ee_cback_data;
1711       nfa_ee_cback_data.status = status;
1712       nfa_ee_report_event(p_cb->p_ee_cback, NFA_EE_NO_MEM_ERR_EVT,
1713                           &nfa_ee_cback_data);
1714     }
1715   } else {
1716     tNFA_EE_CBACK_DATA nfa_ee_cback_data;
1717     nfa_ee_cback_data.status = status;
1718     nfa_ee_report_event(p_cb->p_ee_cback, NFA_EE_NO_CB_ERR_EVT,
1719                         &nfa_ee_cback_data);
1720   }
1721 }
1722 
1723 /*******************************************************************************
1724 **
1725 ** Function         nfa_ee_api_disconnect
1726 **
1727 ** Description      Initiates closing of the connection to the given NFCEE
1728 **
1729 ** Returns          void
1730 **
1731 *******************************************************************************/
nfa_ee_api_disconnect(tNFA_EE_MSG * p_data)1732 void nfa_ee_api_disconnect(tNFA_EE_MSG* p_data) {
1733   tNFA_EE_ECB* p_cb = p_data->disconnect.p_cb;
1734   tNFA_EE_CBACK_DATA evt_data = {0};
1735 
1736   if (p_cb->conn_st == NFA_EE_CONN_ST_CONN) {
1737     p_cb->conn_st = NFA_EE_CONN_ST_DISC;
1738     NFC_ConnClose(p_cb->conn_id);
1739   }
1740   evt_data.handle = (tNFA_HANDLE)p_cb->nfcee_id | NFA_HANDLE_GROUP_EE;
1741   nfa_ee_report_event(p_cb->p_ee_cback, NFA_EE_DISCONNECT_EVT, &evt_data);
1742 }
1743 
1744 /*******************************************************************************
1745 **
1746 ** Function         nfa_ee_api_clear_routing_table
1747 **
1748 ** Description      As the name indicates
1749 **
1750 ** Returns          void
1751 **
1752 *******************************************************************************/
nfa_ee_api_clear_routing_table(tNFA_EE_MSG * p_data)1753 void nfa_ee_api_clear_routing_table(tNFA_EE_MSG* p_data) {
1754   LOG(DEBUG) << StringPrintf("%s", __func__);
1755 
1756   uint32_t xx;
1757   tNFA_EE_ECB* p_cb = nfa_ee_cb.ecb;
1758 
1759   tNFA_EE_ECB* p_ecb = &nfa_ee_cb.ecb[NFA_EE_CB_4_DH];
1760 
1761   /******************************************/
1762   /************* Clear All proto *************/
1763   /******************************************/
1764   if (p_data->clear_routing_table.clear_proto == true) {
1765     p_cb = nfa_ee_cb.ecb;
1766     for (xx = 0; xx < NFA_EE_MAX_EE_SUPPORTED; xx++, p_cb++) {
1767       p_cb->size_mask_proto = 0;
1768       p_cb->proto_battery_off = 0;
1769       p_cb->proto_screen_lock = 0;
1770       p_cb->proto_screen_off = 0;
1771       p_cb->proto_screen_off_lock = 0;
1772       p_cb->proto_switch_off = 0;
1773       p_cb->proto_switch_on = 0;
1774     }
1775 
1776     p_ecb->size_mask_proto = 0;
1777     p_ecb->proto_battery_off = 0;
1778     p_ecb->proto_screen_lock = 0;
1779     p_ecb->proto_screen_off = 0;
1780     p_ecb->proto_screen_off_lock = 0;
1781     p_ecb->proto_switch_off = 0;
1782     p_ecb->proto_switch_on = 0;
1783   }
1784 
1785   /******************************************/
1786   /************* Clear All tech *************/
1787   /******************************************/
1788   if (p_data->clear_routing_table.clear_tech == true) {
1789     p_cb = nfa_ee_cb.ecb;
1790     for (xx = 0; xx < NFA_EE_MAX_EE_SUPPORTED; xx++, p_cb++) {
1791       p_cb->size_mask_tech = 0;
1792       p_cb->tech_battery_off = 0;
1793       p_cb->tech_screen_lock = 0;
1794       p_cb->tech_screen_off = 0;
1795       p_cb->tech_screen_off_lock = 0;
1796       p_cb->tech_switch_off = 0;
1797       p_cb->tech_switch_on = 0;
1798     }
1799 
1800     p_ecb->size_mask_tech = 0;
1801     p_ecb->tech_battery_off = 0;
1802     p_ecb->tech_screen_lock = 0;
1803     p_ecb->tech_screen_off = 0;
1804     p_ecb->tech_screen_off_lock = 0;
1805     p_ecb->tech_switch_off = 0;
1806     p_ecb->tech_switch_on = 0;
1807   }
1808 
1809   /******************************************/
1810   /************* Clear All SC *************/
1811   /******************************************/
1812   if (p_data->clear_routing_table.clear_sc == true) {
1813     p_cb = nfa_ee_cb.ecb;
1814     for (xx = 0; xx < NFA_EE_MAX_EE_SUPPORTED; xx++, p_cb++) {
1815       memset(&p_cb->sys_code_cfg[0], 0x00, sizeof(p_cb->sys_code_cfg));
1816       memset(&p_cb->sys_code_pwr_cfg[0], 0x00, sizeof(p_cb->sys_code_pwr_cfg));
1817       memset(&p_cb->sys_code_rt_loc_vs_info[0], 0x00,
1818              sizeof(p_cb->sys_code_rt_loc_vs_info));
1819       memset(&p_cb->sys_code_rt_loc[0], 0x00, sizeof(p_cb->sys_code_rt_loc));
1820 
1821       p_cb->sys_code_cfg_entries = 0;
1822       p_cb->size_sys_code = 0;
1823     }
1824 
1825     memset(&p_ecb->sys_code_cfg[0], 0x00, sizeof(p_ecb->sys_code_cfg));
1826     memset(&p_ecb->sys_code_pwr_cfg[0], 0x00, sizeof(p_ecb->sys_code_pwr_cfg));
1827     memset(&p_ecb->sys_code_rt_loc_vs_info[0], 0x00,
1828            sizeof(p_ecb->sys_code_rt_loc_vs_info));
1829     memset(&p_ecb->sys_code_rt_loc[0], 0x00, sizeof(p_ecb->sys_code_rt_loc));
1830 
1831     p_ecb->sys_code_cfg_entries = 0;
1832     p_ecb->size_sys_code = 0;
1833   }
1834 }
1835 
1836 /*******************************************************************************
1837 **
1838 ** Function         nfa_ee_api_pwr_and_link_ctrl
1839 **
1840 ** Description      Initiates closing of the connection to the given NFCEE
1841 **
1842 ** Returns          void
1843 **
1844 *******************************************************************************/
nfa_ee_api_pwr_and_link_ctrl(tNFA_EE_MSG * p_data)1845 void nfa_ee_api_pwr_and_link_ctrl(tNFA_EE_MSG* p_data) {
1846   NFC_NfceePLConfig(p_data->pwr_and_link_ctrl.nfcee_id,
1847                     p_data->pwr_and_link_ctrl.config);
1848 }
1849 
1850 /*******************************************************************************
1851 **
1852 ** Function         nfa_ee_report_disc_done
1853 **
1854 ** Description      Process the callback for NFCEE discovery response
1855 **
1856 ** Returns          void
1857 **
1858 *******************************************************************************/
nfa_ee_report_disc_done(bool notify_enable_done)1859 void nfa_ee_report_disc_done(bool notify_enable_done) {
1860   tNFA_EE_CBACK* p_cback;
1861   tNFA_EE_CBACK_DATA evt_data = {0};
1862 
1863   if (nfa_ee_cb.num_ee_expecting == 0) {
1864     if (notify_enable_done) {
1865       if (nfa_ee_cb.em_state == NFA_EE_EM_STATE_INIT_DONE) {
1866         nfa_sys_cback_notify_enable_complete(NFA_ID_EE);
1867         if (nfa_ee_cb.p_enable_cback)
1868           (*nfa_ee_cb.p_enable_cback)(NFA_EE_DISC_STS_ON);
1869       } else if ((nfa_ee_cb.em_state == NFA_EE_EM_STATE_RESTORING) &&
1870                  (nfa_ee_cb.ee_flags & NFA_EE_FLAG_NOTIFY_HCI)) {
1871         nfa_ee_cb.ee_flags &= ~NFA_EE_FLAG_NOTIFY_HCI;
1872         if (nfa_ee_cb.p_enable_cback)
1873           (*nfa_ee_cb.p_enable_cback)(NFA_EE_DISC_STS_ON);
1874       }
1875     }
1876 
1877     if (nfa_ee_cb.p_ee_disc_cback) {
1878       /* notify API callback */
1879       p_cback = nfa_ee_cb.p_ee_disc_cback;
1880       nfa_ee_cb.p_ee_disc_cback = nullptr;
1881       evt_data.status = NFA_STATUS_OK;
1882       evt_data.ee_discover.num_ee = NFA_EE_MAX_EE_SUPPORTED;
1883       NFA_EeGetInfo(&evt_data.ee_discover.num_ee, evt_data.ee_discover.ee_info);
1884       nfa_ee_report_event(p_cback, NFA_EE_DISCOVER_EVT, &evt_data);
1885     }
1886     if ((nfa_hci_cb.hci_state == NFA_HCI_STATE_EE_RECOVERY) &&
1887         nfa_ee_cb.p_enable_cback)
1888       (*nfa_ee_cb.p_enable_cback)(NFA_EE_RECOVERY_REDISCOVERED);
1889   }
1890 }
1891 
1892 /*******************************************************************************
1893 **
1894 ** Function         nfa_ee_restore_ntf_done
1895 **
1896 ** Description      check if any ee_status still has NFA_EE_STATUS_PENDING bit
1897 **
1898 ** Returns          TRUE, if all NFA_EE_STATUS_PENDING bits are removed
1899 **
1900 *******************************************************************************/
nfa_ee_restore_ntf_done(void)1901 bool nfa_ee_restore_ntf_done(void) {
1902   tNFA_EE_ECB* p_cb;
1903   bool is_done = true;
1904   int xx;
1905 
1906   p_cb = nfa_ee_cb.ecb;
1907   for (xx = 0; xx < nfa_ee_cb.cur_ee; xx++, p_cb++) {
1908     if ((p_cb->nfcee_id != NFA_EE_INVALID) &&
1909         (p_cb->ee_old_status & NFA_EE_STATUS_RESTORING)) {
1910       is_done = false;
1911       break;
1912     }
1913   }
1914   return is_done;
1915 }
1916 
1917 /*******************************************************************************
1918 **
1919 ** Function         nfa_ee_remove_pending
1920 **
1921 ** Description      check if any ee_status still has NFA_EE_STATUS_RESTORING bit
1922 **
1923 ** Returns          TRUE, if all NFA_EE_STATUS_RESTORING bits are removed
1924 **
1925 *******************************************************************************/
nfa_ee_remove_pending(void)1926 static void nfa_ee_remove_pending(void) {
1927   tNFA_EE_ECB* p_cb;
1928   tNFA_EE_ECB *p_cb_n, *p_cb_end;
1929   int xx, num_removed = 0;
1930   int first_removed = NFA_EE_MAX_EE_SUPPORTED;
1931 
1932   p_cb = nfa_ee_cb.ecb;
1933   for (xx = 0; xx < nfa_ee_cb.cur_ee; xx++, p_cb++) {
1934     if ((p_cb->nfcee_id != NFA_EE_INVALID) &&
1935         (p_cb->ee_status & NFA_EE_STATUS_RESTORING)) {
1936       p_cb->nfcee_id = NFA_EE_INVALID;
1937       num_removed++;
1938       if (first_removed == NFA_EE_MAX_EE_SUPPORTED) first_removed = xx;
1939     }
1940   }
1941 
1942   LOG(VERBOSE) << StringPrintf("%s: cur_ee=%d, num_removed=%d first_removed=%d",
1943                                __func__, nfa_ee_cb.cur_ee, num_removed,
1944                                first_removed);
1945   if (num_removed && (first_removed != (nfa_ee_cb.cur_ee - num_removed))) {
1946     /* if the removes ECB entried are not at the end, move the entries up */
1947     p_cb_end = nullptr;
1948     if (nfa_ee_cb.cur_ee > 0) p_cb_end = &nfa_ee_cb.ecb[nfa_ee_cb.cur_ee - 1];
1949     p_cb = &nfa_ee_cb.ecb[first_removed];
1950     for (p_cb_n = p_cb + 1; p_cb_n <= p_cb_end;) {
1951       while ((p_cb_n->nfcee_id == NFA_EE_INVALID) && (p_cb_n <= p_cb_end)) {
1952         p_cb_n++;
1953       }
1954 
1955       if (p_cb_n <= p_cb_end) {
1956         memcpy(p_cb, p_cb_n, sizeof(tNFA_EE_ECB));
1957         p_cb_n->nfcee_id = NFA_EE_INVALID;
1958       }
1959       p_cb++;
1960       p_cb_n++;
1961     }
1962   }
1963   nfa_ee_cb.cur_ee -= (uint8_t)num_removed;
1964 }
1965 
1966 /*******************************************************************************
1967 **
1968 ** Function         nfa_ee_nci_disc_rsp
1969 **
1970 ** Description      Process the callback for NFCEE discovery response
1971 **
1972 ** Returns          void
1973 **
1974 *******************************************************************************/
nfa_ee_nci_disc_rsp(tNFA_EE_MSG * p_data)1975 void nfa_ee_nci_disc_rsp(tNFA_EE_MSG* p_data) {
1976   tNFC_NFCEE_DISCOVER_REVT* p_evt = p_data->disc_rsp.p_data;
1977   tNFA_EE_ECB* p_cb;
1978   uint8_t xx;
1979   uint8_t num_nfcee = p_evt->num_nfcee;
1980   bool notify_enable_done = false;
1981 
1982   LOG(VERBOSE) << StringPrintf("%s: em_state=%d cur_ee=%d, num_nfcee=%d",
1983                                __func__, nfa_ee_cb.em_state, nfa_ee_cb.cur_ee,
1984                                num_nfcee);
1985   switch (nfa_ee_cb.em_state) {
1986     case NFA_EE_EM_STATE_INIT:
1987       nfa_ee_cb.cur_ee = 0;
1988       nfa_ee_cb.num_ee_expecting = 0;
1989       if (num_nfcee == 0) {
1990         nfa_ee_cb.em_state = NFA_EE_EM_STATE_INIT_DONE;
1991         notify_enable_done = true;
1992         if (p_evt->status != NFC_STATUS_OK) {
1993           nfa_sys_stop_timer(&nfa_ee_cb.discv_timer);
1994         }
1995       }
1996       break;
1997 
1998     case NFA_EE_EM_STATE_INIT_DONE:
1999       if (num_nfcee) {
2000         /* if this is initiated by api function,
2001          * check if the number of NFCEE expected is more than what's currently
2002          * in CB */
2003         if (num_nfcee > NFA_EE_MAX_EE_SUPPORTED)
2004           num_nfcee = NFA_EE_MAX_EE_SUPPORTED;
2005         if (nfa_ee_cb.cur_ee < num_nfcee) {
2006           p_cb = &nfa_ee_cb.ecb[nfa_ee_cb.cur_ee];
2007           for (xx = nfa_ee_cb.cur_ee; xx < num_nfcee; xx++, p_cb++) {
2008             /* mark the new entries as a new one */
2009             p_cb->nfcee_id = NFA_EE_INVALID;
2010           }
2011         }
2012         nfa_ee_cb.cur_ee = num_nfcee;
2013       }
2014       break;
2015 
2016     case NFA_EE_EM_STATE_RESTORING:
2017       if (num_nfcee == 0) {
2018         nfa_ee_cb.em_state = NFA_EE_EM_STATE_INIT_DONE;
2019         nfa_ee_remove_pending();
2020         nfa_ee_check_restore_complete();
2021         if (p_evt->status != NFC_STATUS_OK) {
2022           nfa_sys_stop_timer(&nfa_ee_cb.discv_timer);
2023         }
2024       }
2025       break;
2026   }
2027 
2028   if (p_evt->status == NFC_STATUS_OK) {
2029     nfa_ee_cb.num_ee_expecting = p_evt->num_nfcee;
2030     if (nfa_ee_cb.num_ee_expecting > NFA_EE_MAX_EE_SUPPORTED) {
2031       LOG(ERROR) << StringPrintf("%s: NFA-EE num_ee_expecting=%d > max=%d",
2032                                  __func__, nfa_ee_cb.num_ee_expecting,
2033                                  NFA_EE_MAX_EE_SUPPORTED);
2034     }
2035   }
2036   nfa_ee_report_disc_done(notify_enable_done);
2037   LOG(VERBOSE) << StringPrintf("%s: em_state=%d cur_ee=%d num_ee_expecting=%d",
2038                                __func__, nfa_ee_cb.em_state, nfa_ee_cb.cur_ee,
2039                                nfa_ee_cb.num_ee_expecting);
2040 }
2041 
2042 /*******************************************************************************
2043 **
2044 ** Function         nfa_ee_nci_disc_ntf
2045 **
2046 ** Description      Process the callback for NFCEE discovery notification
2047 **
2048 ** Returns          void
2049 **
2050 *******************************************************************************/
nfa_ee_nci_disc_ntf(tNFA_EE_MSG * p_data)2051 void nfa_ee_nci_disc_ntf(tNFA_EE_MSG* p_data) {
2052   tNFC_NFCEE_INFO_REVT* p_ee = p_data->disc_ntf.p_data;
2053   tNFA_EE_ECB* p_cb = nullptr;
2054   bool notify_enable_done = false;
2055   bool notify_new_ee = false;
2056   bool notify_ndef_nfcee = false;
2057   bool store_info = true;
2058   tNFA_EE_CBACK_DATA evt_data = {0};
2059   tNFA_EE_INFO* p_info;
2060   tNFA_EE_EM_STATE new_em_state = NFA_EE_EM_STATE_MAX;
2061 
2062   LOG(VERBOSE) << StringPrintf(
2063       "%s: em_state=%d ee_flags=0x%x cur_ee=%d "
2064       "num_ee_expecting=%d",
2065       __func__, nfa_ee_cb.em_state, nfa_ee_cb.ee_flags, nfa_ee_cb.cur_ee,
2066       nfa_ee_cb.num_ee_expecting);
2067   if (nfa_ee_cb.num_ee_expecting) {
2068     nfa_ee_cb.num_ee_expecting--;
2069     if ((nfa_ee_cb.num_ee_expecting == 0) &&
2070         (nfa_ee_cb.p_ee_disc_cback != nullptr)) {
2071       /* Discovery triggered by API function */
2072       if (NFA_GetNCIVersion() < NCI_VERSION_2_0) NFC_NfceeDiscover(false);
2073     }
2074   }
2075   switch (nfa_ee_cb.em_state) {
2076     case NFA_EE_EM_STATE_INIT:
2077       if (nfa_ee_cb.cur_ee < NFA_EE_MAX_EE_SUPPORTED) {
2078         /* the cb can collect up to NFA_EE_MAX_EE_SUPPORTED ee_info */
2079         p_cb = &nfa_ee_cb.ecb[nfa_ee_cb.cur_ee++];
2080       }
2081 
2082       if (nfa_ee_cb.num_ee_expecting == 0) {
2083         /* notify init_done callback */
2084         nfa_ee_cb.em_state = NFA_EE_EM_STATE_INIT_DONE;
2085         notify_enable_done = true;
2086       }
2087       break;
2088 
2089     case NFA_EE_EM_STATE_INIT_DONE:
2090       p_cb = nfa_ee_find_ecb(p_ee->nfcee_id);
2091       if (p_cb == nullptr) {
2092         /* the NFCEE ID is not in the last NFCEE discovery
2093          * maybe it's a new one */
2094         p_cb = nfa_ee_find_ecb(NFA_EE_INVALID);
2095         if (p_cb) {
2096           nfa_ee_cb.cur_ee++;
2097           notify_new_ee = true;
2098         }
2099       } else if (p_cb->ecb_flags & NFA_EE_ECB_FLAGS_ORDER) {
2100         nfa_ee_cb.cur_ee++;
2101         notify_new_ee = true;
2102       } else {
2103         LOG(VERBOSE) << StringPrintf(
2104             "%s: cur_ee=%d ecb_flags=0x%02x  ee_status=0x%x", __func__,
2105             nfa_ee_cb.cur_ee, p_cb->ecb_flags, p_cb->ee_status);
2106       }
2107       break;
2108 
2109     case NFA_EE_EM_STATE_RESTORING:
2110       p_cb = nfa_ee_find_ecb(p_ee->nfcee_id);
2111       if (p_cb == nullptr) {
2112         /* the NFCEE ID is not in the last NFCEE discovery
2113          * maybe it's a new one */
2114         p_cb = nfa_ee_find_ecb(NFA_EE_INVALID);
2115         if (p_cb) {
2116           nfa_ee_cb.cur_ee++;
2117           notify_new_ee = true;
2118         }
2119       }
2120       if (nfa_ee_cb.num_ee_expecting == 0) {
2121         /* notify init_done callback */
2122         notify_enable_done = true;
2123         if (nfa_ee_restore_ntf_done()) {
2124           new_em_state = NFA_EE_EM_STATE_INIT_DONE;
2125         }
2126       }
2127       break;
2128   }
2129   LOG(VERBOSE) << StringPrintf("%s: cur_ee=%d", __func__, nfa_ee_cb.cur_ee);
2130 
2131   if (p_cb) {
2132     if (p_ee->ee_tlv[NFCEE_TAG_INDEX].tag == NFCEE_TYPE_NDEF) {
2133       int defaultNdefNfcee =
2134           NfcConfig::getUnsigned(NAME_DEFAULT_NDEF_NFCEE_ROUTE, 0x10);
2135       // First, check NFCEE Id matches
2136       if (defaultNdefNfcee == p_ee->nfcee_id) {
2137         // Second check that feature is configured
2138         if (nfa_t4tnfcee_is_config()) {
2139           // Allow normal processing
2140           notify_ndef_nfcee = true;
2141         } else {
2142           LOG(WARNING) << StringPrintf(
2143               "%s: NDEF-NFCEE not config but enabled in FW, discard data",
2144               __func__);
2145           store_info = false;
2146         }
2147       }
2148     }
2149 
2150     if (store_info) {
2151       p_cb->nfcee_id = p_ee->nfcee_id;
2152       p_cb->ee_status = p_ee->ee_status;
2153       p_cb->num_interface = p_ee->num_interface;
2154       memcpy(p_cb->ee_interface, p_ee->ee_interface, p_ee->num_interface);
2155       p_cb->num_tlvs = p_ee->num_tlvs;
2156       memcpy(p_cb->ee_tlv, p_ee->ee_tlv, p_ee->num_tlvs * sizeof(tNFA_EE_TLV));
2157       if (NFA_GetNCIVersion() >= NCI_VERSION_2_0)
2158         p_cb->ee_power_supply_status = p_ee->nfcee_power_ctrl;
2159     }
2160     if (nfa_ee_cb.em_state == NFA_EE_EM_STATE_RESTORING) {
2161       /* NCI spec says: An NFCEE_DISCOVER_NTF that contains a Protocol type of
2162        * "HCI Access"
2163        * SHALL NOT contain any other additional Protocol
2164        * i.e. check only first supported NFCEE interface is HCI access */
2165       /* NFA_HCI module handles restoring configurations for HCI access */
2166       if (p_cb->ee_interface[0] != NFC_NFCEE_INTERFACE_HCI_ACCESS) {
2167         if ((nfa_ee_cb.ee_flags & NFA_EE_FLAG_WAIT_HCI) == 0) {
2168           nfa_ee_restore_one_ecb(p_cb);
2169         }
2170         /* else wait for NFA-HCI module to restore the HCI network information
2171          * before enabling the NFCEE */
2172       }
2173     }
2174 
2175     if (notify_ndef_nfcee &&
2176         (p_cb->ee_tlv[NFCEE_TAG_INDEX].tag == NFCEE_TYPE_NDEF)) {
2177       nfa_t4tnfcee_set_ee_cback(p_cb);
2178       p_info = &evt_data.new_ee;
2179       p_info->ee_handle = (tNFA_HANDLE)p_cb->nfcee_id;
2180       p_info->ee_status = p_cb->ee_status;
2181       nfa_ee_report_event(p_cb->p_ee_cback, NFA_EE_DISCOVER_EVT, &evt_data);
2182     }
2183 
2184     // If all have been received, NDEF-NFCEE configured but no
2185     // NFCEE_DISCOVER_NTF received
2186     if (nfa_ee_cb.num_ee_expecting == 0) {
2187       if (nfa_t4tnfcee_is_config() && !nfa_t4tnfcee_is_discovered()) {
2188         LOG(WARNING) << StringPrintf(
2189             "%s: NDEF-NFCEE config but not enabled in FW, resetting flag",
2190             __func__);
2191         nfa_sys_cb.enable_cplt_mask &= ~(0x0001 << NFA_ID_T4TNFCEE);
2192       }
2193     }
2194 
2195     if ((nfa_ee_cb.p_ee_disc_cback == nullptr) && (notify_new_ee == true)) {
2196       if (nfa_dm_is_active() && (p_cb->ee_status != NFA_EE_STATUS_REMOVED)) {
2197         /* report this NFA_EE_NEW_EE_EVT only after NFA_DM_ENABLE_EVT is
2198          * reported */
2199         p_info = &evt_data.new_ee;
2200         p_info->ee_handle = NFA_HANDLE_GROUP_EE | (tNFA_HANDLE)p_cb->nfcee_id;
2201         p_info->ee_status = p_cb->ee_status;
2202         p_info->num_interface = p_cb->num_interface;
2203         p_info->num_tlvs = p_cb->num_tlvs;
2204         memcpy(p_info->ee_interface, p_cb->ee_interface, p_cb->num_interface);
2205         memcpy(p_info->ee_tlv, p_cb->ee_tlv,
2206                p_cb->num_tlvs * sizeof(tNFA_EE_TLV));
2207         if (NFA_GetNCIVersion() >= NCI_VERSION_2_0)
2208           p_info->ee_power_supply_status = p_cb->ee_power_supply_status;
2209         nfa_ee_report_event(nullptr, NFA_EE_NEW_EE_EVT, &evt_data);
2210       }
2211     } else
2212       nfa_ee_report_disc_done(notify_enable_done);
2213 
2214     if (p_cb->ecb_flags & NFA_EE_ECB_FLAGS_ORDER) {
2215       LOG(VERBOSE) << StringPrintf("%s: NFA_EE_ECB_FLAGS_ORDER", __func__);
2216       p_cb->ecb_flags &= ~NFA_EE_ECB_FLAGS_ORDER;
2217       nfa_ee_report_discover_req_evt();
2218     }
2219   }
2220 
2221   if (new_em_state != NFA_EE_EM_STATE_MAX) {
2222     nfa_ee_cb.em_state = new_em_state;
2223     nfa_ee_check_restore_complete();
2224   }
2225 
2226   if ((nfa_ee_cb.cur_ee == nfa_ee_max_ee_cfg) &&
2227       (nfa_ee_cb.em_state == NFA_EE_EM_STATE_INIT_DONE)) {
2228     if (nfa_ee_cb.discv_timer.in_use) {
2229       nfa_sys_stop_timer(&nfa_ee_cb.discv_timer);
2230       p_data->hdr.event = NFA_EE_DISCV_TIMEOUT_EVT;
2231       nfa_ee_evt_hdlr(&p_data->hdr);
2232     }
2233   }
2234 }
2235 
2236 /*******************************************************************************
2237 **
2238 ** Function         nfa_ee_nci_nfcee_status_ntf
2239 **
2240 ** Description      Process the callback for NFCEE status notification
2241 **                  Initialize ee rediscovery if NFC is initialized & RF is not
2242 **                  busy, else rediscovery will trigger after RF state update or
2243 **                  NFC state changed to idle.
2244 **
2245 ** Returns          void
2246 **
2247 *******************************************************************************/
nfa_ee_nci_nfcee_status_ntf(tNFA_EE_MSG * p_data)2248 void nfa_ee_nci_nfcee_status_ntf(tNFA_EE_MSG* p_data) {
2249   if (p_data != nullptr) {
2250     tNFA_DM_RF_DISC_STATE rf_state = nfa_dm_cb.disc_cb.disc_state;
2251     tNFC_NFCEE_STATUS_REVT* p_ee_data = p_data->nfcee_status_ntf.p_data;
2252     nfc_cb.is_nfcee_discovery_required = false;
2253     nfc_cb.nfcee_data = {};
2254     if ((NFA_GetNCIVersion() >= NCI_VERSION_2_0) &&
2255         (p_ee_data->nfcee_status == NFC_NFCEE_STATUS_UNRECOVERABLE_ERROR)) {
2256       // ongoing CE transaction shall not be impacted due to NFCEE events
2257       if (((rf_state == NFA_DM_RFST_IDLE) ||
2258            (rf_state == NFA_DM_RFST_DISCOVERY)) &&
2259           (nfa_hci_cb.hci_state == NFA_HCI_STATE_IDLE)) {
2260         tNFA_EE_ECB* p_cb = nfa_ee_find_ecb(p_ee_data->nfcee_id);
2261         if (p_cb && nfa_ee_cb.p_enable_cback) {
2262           (*nfa_ee_cb.p_enable_cback)(NFA_EE_RECOVERY_INIT);
2263           NFC_NfceeDiscover(true);
2264         }
2265       } else {
2266         LOG(VERBOSE) << StringPrintf("%s: rf is busy or NFC is not initialized",
2267                                      __func__);
2268         nfc_cb.is_nfcee_discovery_required = true;
2269         nfc_cb.nfcee_data.nfcee_status = *p_ee_data;
2270       }
2271     }
2272   }
2273 }
2274 
2275 /*******************************************************************************
2276 **
2277 ** Function         nfa_ee_check_restore_complete
2278 **
2279 ** Description      Check if restore the NFA-EE related configuration to the
2280 **                  state prior to low power mode is complete.
2281 **                  If complete, notify sys.
2282 **
2283 ** Returns          void
2284 **
2285 *******************************************************************************/
nfa_ee_check_restore_complete(void)2286 void nfa_ee_check_restore_complete(void) {
2287   uint32_t xx;
2288   tNFA_EE_ECB* p_cb;
2289   bool proc_complete = true;
2290 
2291   p_cb = nfa_ee_cb.ecb;
2292   for (xx = 0; xx < nfa_ee_cb.cur_ee; xx++, p_cb++) {
2293     if (p_cb->ecb_flags & NFA_EE_ECB_FLAGS_RESTORE) {
2294       /* NFA_HCI module handles restoring configurations for HCI access.
2295        * ignore the restoring status for HCI Access */
2296       if (p_cb->ee_interface[0] != NFC_NFCEE_INTERFACE_HCI_ACCESS) {
2297         proc_complete = false;
2298         break;
2299       }
2300     }
2301   }
2302 
2303   LOG(VERBOSE) << StringPrintf(
2304       "%s: nfa_ee_cb.ee_cfg_sts=0x%02x "
2305       "proc_complete=%d",
2306       __func__, nfa_ee_cb.ee_cfg_sts, proc_complete);
2307   if (proc_complete) {
2308     /* update routing table when NFA_EE_ROUT_TIMEOUT_EVT is received */
2309     if (nfa_ee_cb.ee_cfg_sts & NFA_EE_STS_PREV_ROUTING)
2310       nfa_ee_api_update_now(nullptr);
2311 
2312     nfa_ee_cb.em_state = NFA_EE_EM_STATE_INIT_DONE;
2313     nfa_sys_cback_notify_nfcc_power_mode_proc_complete(NFA_ID_EE);
2314   }
2315 }
2316 
2317 /*******************************************************************************
2318 **
2319 ** Function         nfa_ee_build_discover_req_evt
2320 **
2321 ** Description      Build NFA_EE_DISCOVER_REQ_EVT for all active NFCEE
2322 **
2323 ** Returns          void
2324 **
2325 *******************************************************************************/
nfa_ee_build_discover_req_evt(tNFA_EE_DISCOVER_REQ * p_evt_data)2326 static void nfa_ee_build_discover_req_evt(tNFA_EE_DISCOVER_REQ* p_evt_data) {
2327   tNFA_EE_ECB* p_cb;
2328   tNFA_EE_DISCOVER_INFO* p_info;
2329   uint8_t xx;
2330 
2331   if (!p_evt_data) return;
2332 
2333   p_evt_data->num_ee = 0;
2334   p_cb = nfa_ee_cb.ecb;
2335   p_info = p_evt_data->ee_disc_info;
2336 
2337   for (xx = 0; xx < nfa_ee_cb.cur_ee; xx++, p_cb++) {
2338     if ((p_cb->ee_status & NFA_EE_STATUS_INT_MASK) ||
2339         ((p_cb->ee_status != NFA_EE_STATUS_ACTIVE) &&
2340          (p_cb->ee_status !=
2341           (NFA_EE_STATUS_ACTIVE | NFA_EE_STATUS_MEP_MASK)))) {
2342       continue;
2343     }
2344 
2345     p_info->ee_handle = (tNFA_HANDLE)p_cb->nfcee_id | NFA_HANDLE_GROUP_EE;
2346     p_info->la_protocol = p_cb->la_protocol;
2347     p_info->lb_protocol = p_cb->lb_protocol;
2348     p_info->lf_protocol = p_cb->lf_protocol;
2349     p_info->lbp_protocol = p_cb->lbp_protocol;
2350     p_evt_data->num_ee++;
2351     p_info++;
2352 
2353     LOG(VERBOSE) << StringPrintf(
2354         "%s:  [%d] ee_handle=0x%x, listen protocol A=0x%x, B=0x%x, F=0x%x, "
2355         "BP=0x%x",
2356         __func__, p_evt_data->num_ee, p_cb->nfcee_id, p_cb->la_protocol,
2357         p_cb->lb_protocol, p_cb->lf_protocol, p_cb->lbp_protocol);
2358   }
2359   p_evt_data->status = NFA_STATUS_OK;
2360 }
2361 
2362 /*******************************************************************************
2363 **
2364 ** Function         nfa_ee_report_discover_req_evt
2365 **
2366 ** Description      Report NFA_EE_DISCOVER_REQ_EVT for all active NFCEE
2367 **
2368 ** Returns          void
2369 **
2370 *******************************************************************************/
nfa_ee_report_discover_req_evt(void)2371 static void nfa_ee_report_discover_req_evt(void) {
2372   if (nfa_ee_cb.p_enable_cback)
2373     (*nfa_ee_cb.p_enable_cback)(NFA_EE_DISC_STS_REQ);
2374 
2375   /* if this is restoring NFCC */
2376   if (!nfa_dm_is_active()) {
2377     LOG(VERBOSE) << StringPrintf("%s: DM is not active", __func__);
2378     return;
2379   }
2380 
2381   tNFA_EE_CBACK_DATA nfa_ee_cback_data;
2382   nfa_ee_build_discover_req_evt(&nfa_ee_cback_data.discover_req);
2383   nfa_ee_report_event(nullptr, NFA_EE_DISCOVER_REQ_EVT, &nfa_ee_cback_data);
2384 }
2385 
2386 /*******************************************************************************
2387 **
2388 ** Function         nfa_ee_nci_mode_set_rsp
2389 **
2390 ** Description      Process the result for NFCEE ModeSet response
2391 **
2392 ** Returns          void
2393 **
2394 *******************************************************************************/
nfa_ee_nci_mode_set_rsp(tNFA_EE_MSG * p_data)2395 void nfa_ee_nci_mode_set_rsp(tNFA_EE_MSG* p_data) {
2396   tNFA_EE_ECB* p_cb;
2397   tNFA_EE_MODE_SET mode_set;
2398   tNFC_NFCEE_MODE_SET_REVT* p_rsp = p_data->mode_set_rsp.p_data;
2399 
2400   LOG(VERBOSE) << StringPrintf("%s: handle=0x%02x mode=%d", __func__,
2401                                p_rsp->nfcee_id, p_rsp->mode);
2402   p_cb = nfa_ee_find_ecb(p_rsp->nfcee_id);
2403   if (p_cb == nullptr) {
2404     LOG(ERROR) << StringPrintf("%s: Can not find cb for handle=0x%02x",
2405                                __func__, p_rsp->nfcee_id);
2406     return;
2407   }
2408 
2409   /* Do not update routing table in EE_RECOVERY state */
2410   if (nfa_hci_cb.hci_state != NFA_HCI_STATE_EE_RECOVERY) {
2411     /* Start routing table update debounce timer */
2412     nfa_ee_start_timer();
2413   }
2414   LOG(VERBOSE) << StringPrintf("%s: p_rsp->status=0x%02x", __func__,
2415                                p_rsp->status);
2416   if (p_rsp->status == NFA_STATUS_OK) {
2417     if (p_rsp->mode == NFA_EE_MD_ACTIVATE) {
2418       p_cb->ee_status = NFC_NFCEE_STATUS_ACTIVE;
2419     } else {
2420       if (p_cb->tech_switch_on | p_cb->tech_switch_off |
2421           p_cb->tech_battery_off | p_cb->proto_switch_on |
2422           p_cb->proto_switch_off | p_cb->proto_battery_off |
2423           p_cb->aid_entries) {
2424         /* this NFCEE still has configuration when deactivated. clear the
2425          * configuration */
2426         nfa_ee_cb.ee_cfged &= ~nfa_ee_ecb_to_mask(p_cb);
2427         nfa_ee_cb.ee_cfg_sts |= NFA_EE_STS_CHANGED_ROUTING;
2428         LOG(VERBOSE) << StringPrintf(
2429             "%s: deactivating/still configured. Force update", __func__);
2430       }
2431       p_cb->tech_switch_on = p_cb->tech_switch_off = p_cb->tech_battery_off = 0;
2432       p_cb->proto_switch_on = p_cb->proto_switch_off = p_cb->proto_battery_off =
2433           0;
2434       p_cb->aid_entries = 0;
2435       p_cb->ee_status = NFC_NFCEE_STATUS_INACTIVE;
2436     }
2437   } else if (p_rsp->mode == NFA_EE_MD_ACTIVATE) {
2438     p_cb->ee_status = NFC_NFCEE_STATUS_REMOVED;
2439   }
2440   LOG(VERBOSE) << StringPrintf(
2441       "%s: status=%d ecb_flags  =0x%02x ee_cfged=0x%02x ee_status=%d", __func__,
2442       p_rsp->status, p_cb->ecb_flags, nfa_ee_cb.ee_cfged, p_cb->ee_status);
2443   if (p_cb->ecb_flags & NFA_EE_ECB_FLAGS_RESTORE) {
2444     if (p_cb->conn_st == NFA_EE_CONN_ST_CONN) {
2445       /* NFA_HCI module handles restoring configurations for HCI access */
2446       if (p_cb->ee_interface[0] != NFC_NFCEE_INTERFACE_HCI_ACCESS) {
2447         NFC_ConnCreate(NCI_DEST_TYPE_NFCEE, p_cb->nfcee_id, p_cb->use_interface,
2448                        nfa_ee_conn_cback);
2449       }
2450     } else {
2451       p_cb->ecb_flags &= ~NFA_EE_ECB_FLAGS_RESTORE;
2452       nfa_ee_check_restore_complete();
2453     }
2454   } else {
2455     mode_set.status = p_rsp->status;
2456     mode_set.ee_handle = (tNFA_HANDLE)p_rsp->nfcee_id | NFA_HANDLE_GROUP_EE;
2457     mode_set.ee_status = p_cb->ee_status;
2458 
2459     tNFA_EE_CBACK_DATA nfa_ee_cback_data;
2460     nfa_ee_cback_data.mode_set = mode_set;
2461     nfa_ee_report_event(p_cb->p_ee_cback, NFA_EE_MODE_SET_EVT,
2462                         &nfa_ee_cback_data);
2463 
2464     if ((p_cb->ee_status == NFC_NFCEE_STATUS_INACTIVE) ||
2465         (p_cb->ee_status == NFC_NFCEE_STATUS_ACTIVE)) {
2466       /* Report NFA_EE_DISCOVER_REQ_EVT for all active NFCEE */
2467       nfa_ee_report_discover_req_evt();
2468     }
2469   }
2470   if (nfa_ee_cb.p_enable_cback)
2471     (*nfa_ee_cb.p_enable_cback)(NFA_EE_MODE_SET_COMPLETE);
2472 }
2473 
2474 /*******************************************************************************
2475 **
2476 ** Function         nfa_ee_report_update_evt
2477 **
2478 ** Description      Check if need to report NFA_EE_UPDATED_EVT
2479 **
2480 ** Returns          void
2481 **
2482 *******************************************************************************/
nfa_ee_report_update_evt(void)2483 void nfa_ee_report_update_evt(void) {
2484   tNFA_EE_CBACK_DATA evt_data;
2485 
2486   LOG(VERBOSE) << StringPrintf("%s: ee_wait_evt=0x%x wait_rsp=%d", __func__,
2487                                nfa_ee_cb.ee_wait_evt, nfa_ee_cb.wait_rsp);
2488   if (nfa_ee_cb.wait_rsp == 0) {
2489     nfa_ee_cb.ee_wait_evt &= ~NFA_EE_WAIT_UPDATE_RSP;
2490 
2491     if (nfa_ee_cb.ee_wait_evt & NFA_EE_WAIT_UPDATE) {
2492       nfa_ee_cb.ee_wait_evt &= ~NFA_EE_WAIT_UPDATE;
2493       /* finished updating NFCC; record the committed listen mode routing
2494        * configuration command; report NFA_EE_UPDATED_EVT now */
2495       lmrt_update();
2496       evt_data.status = NFA_STATUS_OK;
2497       nfa_ee_report_event(nullptr, NFA_EE_UPDATED_EVT, &evt_data);
2498     }
2499   }
2500 }
2501 
2502 /*******************************************************************************
2503 **
2504 ** Function         nfa_ee_nci_wait_rsp
2505 **
2506 ** Description      Process the result for NCI response
2507 **
2508 ** Returns          void
2509 **
2510 *******************************************************************************/
nfa_ee_nci_wait_rsp(tNFA_EE_MSG * p_data)2511 void nfa_ee_nci_wait_rsp(tNFA_EE_MSG* p_data) {
2512   tNFA_EE_NCI_WAIT_RSP* p_rsp = &p_data->wait_rsp;
2513 
2514   LOG(VERBOSE) << StringPrintf("%s: ee_wait_evt=0x%x wait_rsp=%d", __func__,
2515                                nfa_ee_cb.ee_wait_evt, nfa_ee_cb.wait_rsp);
2516   if (nfa_ee_cb.wait_rsp) {
2517     if (p_rsp->opcode == NCI_MSG_RF_SET_ROUTING) nfa_ee_cb.wait_rsp--;
2518   }
2519   nfa_ee_report_update_evt();
2520 }
2521 
2522 /*******************************************************************************
2523 **
2524 ** Function         nfa_ee_pwr_and_link_ctrl_rsp
2525 **
2526 ** Description      Process the result for NCI response
2527 **
2528 ** Returns          void
2529 **
2530 *******************************************************************************/
nfa_ee_pwr_and_link_ctrl_rsp(tNFA_EE_MSG * p_data)2531 void nfa_ee_pwr_and_link_ctrl_rsp(tNFA_EE_MSG* p_data) {
2532   tNFA_EE_CBACK_DATA evt_data;
2533   if (p_data != nullptr) {
2534     evt_data.status = NFA_STATUS_OK;
2535     nfa_ee_report_event(nullptr, NFA_EE_PWR_AND_LINK_CTRL_EVT, &evt_data);
2536   }
2537 }
2538 
2539 /*******************************************************************************
2540 **
2541 ** Function         nfa_ee_nci_conn
2542 **
2543 ** Description      process the connection callback events
2544 **
2545 ** Returns          void
2546 **
2547 *******************************************************************************/
nfa_ee_nci_conn(tNFA_EE_MSG * p_data)2548 void nfa_ee_nci_conn(tNFA_EE_MSG* p_data) {
2549   tNFA_EE_ECB* p_cb;
2550   tNFA_EE_NCI_CONN* p_cbk = &p_data->conn;
2551   tNFC_CONN* p_conn = p_data->conn.p_data;
2552   NFC_HDR* p_pkt = nullptr;
2553   tNFA_EE_CBACK_DATA evt_data = {0};
2554   tNFA_EE_EVT event = NFA_EE_INVALID;
2555   tNFA_EE_CBACK* p_cback = nullptr;
2556 
2557   if (p_cbk->event == NFC_CONN_CREATE_CEVT) {
2558     p_cb = nfa_ee_find_ecb(p_cbk->p_data->conn_create.id);
2559   } else {
2560     p_cb = nfa_ee_find_ecb_by_conn_id(p_cbk->conn_id);
2561     if (p_cbk->event == NFC_DATA_CEVT) p_pkt = p_conn->data.p_data;
2562   }
2563 
2564   if (p_cb) {
2565     p_cback = p_cb->p_ee_cback;
2566     evt_data.handle = (tNFA_HANDLE)p_cb->nfcee_id | NFA_HANDLE_GROUP_EE;
2567     switch (p_cbk->event) {
2568       case NFC_CONN_CREATE_CEVT:
2569         if (p_conn->conn_create.status == NFC_STATUS_OK) {
2570           p_cb->conn_id = p_cbk->conn_id;
2571           p_cb->conn_st = NFA_EE_CONN_ST_CONN;
2572         } else {
2573           p_cb->conn_st = NFA_EE_CONN_ST_NONE;
2574         }
2575         if (p_cb->ecb_flags & NFA_EE_ECB_FLAGS_RESTORE) {
2576           p_cb->ecb_flags &= ~NFA_EE_ECB_FLAGS_RESTORE;
2577           nfa_ee_check_restore_complete();
2578         } else {
2579           evt_data.connect.status = p_conn->conn_create.status;
2580           evt_data.connect.ee_interface = p_cb->use_interface;
2581           event = NFA_EE_CONNECT_EVT;
2582         }
2583         break;
2584 
2585       case NFC_CONN_CLOSE_CEVT:
2586         if (p_cb->conn_st != NFA_EE_CONN_ST_DISC) event = NFA_EE_DISCONNECT_EVT;
2587         p_cb->conn_st = NFA_EE_CONN_ST_NONE;
2588         p_cb->p_ee_cback = nullptr;
2589         p_cb->conn_id = 0;
2590         if (nfa_ee_cb.em_state == NFA_EE_EM_STATE_DISABLING) {
2591           if (nfa_ee_cb.ee_flags & NFA_EE_FLAG_WAIT_DISCONN) {
2592             if (nfa_ee_cb.num_ee_expecting) {
2593               nfa_ee_cb.num_ee_expecting--;
2594             }
2595           }
2596           if (nfa_ee_cb.num_ee_expecting == 0) {
2597             nfa_ee_cb.ee_flags &= ~NFA_EE_FLAG_WAIT_DISCONN;
2598             nfa_ee_check_disable();
2599           }
2600         }
2601         break;
2602 
2603       case NFC_DATA_CEVT:
2604         if (p_cb->conn_st == NFA_EE_CONN_ST_CONN) {
2605           /* report data event only in connected state */
2606           if (p_cb->p_ee_cback && p_pkt) {
2607             evt_data.data.len = p_pkt->len;
2608             evt_data.data.p_buf = (uint8_t*)(p_pkt + 1) + p_pkt->offset;
2609             event = NFA_EE_DATA_EVT;
2610             p_pkt = nullptr;
2611             /* so this function does not free this GKI buffer */
2612           }
2613         }
2614         break;
2615     }
2616 
2617     if ((event != NFA_EE_INVALID) && (p_cback)) (*p_cback)(event, &evt_data);
2618   }
2619   if (p_pkt) GKI_freebuf(p_pkt);
2620 }
2621 
2622 /*******************************************************************************
2623 **
2624 ** Function         nfa_ee_nci_action_ntf
2625 **
2626 ** Description      process the NFCEE action callback event
2627 **
2628 ** Returns          void
2629 **
2630 *******************************************************************************/
nfa_ee_nci_action_ntf(tNFA_EE_MSG * p_data)2631 void nfa_ee_nci_action_ntf(tNFA_EE_MSG* p_data) {
2632   tNFC_EE_ACTION_REVT* p_cbk = p_data->act.p_data;
2633   tNFA_EE_ACTION evt_data;
2634 
2635   evt_data.ee_handle = (tNFA_HANDLE)p_cbk->nfcee_id | NFA_HANDLE_GROUP_EE;
2636   evt_data.trigger = p_cbk->act_data.trigger;
2637   memcpy(&(evt_data.param), &(p_cbk->act_data.param),
2638          sizeof(tNFA_EE_ACTION_PARAM));
2639   tNFA_EE_CBACK_DATA nfa_ee_cback_data;
2640   nfa_ee_cback_data.action = evt_data;
2641   nfa_ee_report_event(nullptr, NFA_EE_ACTION_EVT, &nfa_ee_cback_data);
2642 }
2643 
2644 /*******************************************************************************
2645 **
2646 ** Function         nfa_ee_nci_disc_req_ntf
2647 **
2648 ** Description      process the NFCEE discover request callback event
2649 **
2650 ** Returns          void
2651 **
2652 *******************************************************************************/
nfa_ee_nci_disc_req_ntf(tNFA_EE_MSG * p_data)2653 void nfa_ee_nci_disc_req_ntf(tNFA_EE_MSG* p_data) {
2654   tNFC_EE_DISCOVER_REQ_REVT* p_cbk = p_data->disc_req.p_data;
2655   tNFA_EE_ECB* p_cb = nullptr;
2656   uint8_t report_ntf = 0;
2657   uint8_t xx;
2658   std::vector<uint8_t> uicc_ids;
2659 
2660   LOG(VERBOSE) << StringPrintf("%s: num_info=%d cur_ee=%d", __func__,
2661                                p_cbk->num_info, nfa_ee_cb.cur_ee);
2662 
2663   if (NfcConfig::hasKey(NAME_OFFHOST_ROUTE_UICC)) {
2664     uicc_ids = NfcConfig::getBytes(NAME_OFFHOST_ROUTE_UICC);
2665   }
2666 
2667   for (xx = 0; xx < p_cbk->num_info; xx++) {
2668     LOG(VERBOSE) << StringPrintf("%s: processing nfceeId=0x%x", __func__,
2669                                  p_cbk->info[xx].nfcee_id);
2670     p_cb = nfa_ee_find_ecb(p_cbk->info[xx].nfcee_id);
2671     // If not found, but Id is in NAME_OFFHOST_ROUTE_UICC
2672     // it is a MEP NFCEE
2673     if (!p_cb) {
2674       for (int i = 0; i < uicc_ids.size(); i++) {
2675         if (p_cbk->info[xx].nfcee_id == uicc_ids[i]) {
2676           p_cb = nfa_ee_add_mep_ecb(p_cbk->info[xx].nfcee_id);
2677           break;
2678         }
2679       }
2680     }
2681     if (!p_cb) {
2682       LOG(VERBOSE) << StringPrintf("%s: Cannot find cb for NFCEE=0x%x",
2683                                    __func__, p_cbk->info[xx].nfcee_id);
2684       p_cb = nfa_ee_find_ecb(NFA_EE_INVALID);
2685       if (p_cb) {
2686         p_cb->nfcee_id = p_cbk->info[xx].nfcee_id;
2687         p_cb->ecb_flags |= NFA_EE_ECB_FLAGS_ORDER;
2688       } else {
2689         LOG(ERROR) << StringPrintf("%s: Cannot allocate cb for NFCEE=0x%x",
2690                                    __func__, p_cbk->info[xx].nfcee_id);
2691         continue;
2692       }
2693     } else {
2694       report_ntf |= nfa_ee_ecb_to_mask(p_cb);
2695     }
2696 
2697     p_cb->ecb_flags |= NFA_EE_ECB_FLAGS_DISC_REQ;
2698     if (p_cbk->info[xx].op == NFC_EE_DISC_OP_ADD) {
2699       // Check if MEP NFCEE, set active and keep MEP flag
2700       if (p_cb->ee_status & NFA_EE_STATUS_MEP_MASK) {
2701         LOG(DEBUG) << StringPrintf("%s: Set MEP nfceeId=0x%x active", __func__,
2702                                    p_cbk->info[xx].nfcee_id);
2703         p_cb->ee_status = NFA_EE_STATUS_ACTIVE | NFA_EE_STATUS_MEP_MASK;
2704       }
2705       if (p_cbk->info[xx].tech_n_mode == NFC_DISCOVERY_TYPE_LISTEN_A) {
2706         p_cb->la_protocol = p_cbk->info[xx].protocol;
2707       } else if (p_cbk->info[xx].tech_n_mode == NFC_DISCOVERY_TYPE_LISTEN_B) {
2708         p_cb->lb_protocol = p_cbk->info[xx].protocol;
2709       } else if (p_cbk->info[xx].tech_n_mode == NFC_DISCOVERY_TYPE_LISTEN_F) {
2710         p_cb->lf_protocol = p_cbk->info[xx].protocol;
2711       } else if (p_cbk->info[xx].tech_n_mode ==
2712                  NFC_DISCOVERY_TYPE_LISTEN_B_PRIME) {
2713         p_cb->lbp_protocol = p_cbk->info[xx].protocol;
2714       }
2715       if (p_cb->ee_tlv[NFCEE_TAG_INDEX].tag == NFCEE_TYPE_NDEF) {
2716         tNFA_EE_CBACK_DATA nfa_ee_cback_data = {0};
2717         nfa_ee_report_event(p_cb->p_ee_cback, NFA_EE_DISCOVER_REQ_EVT,
2718                             &nfa_ee_cback_data);
2719       }
2720       LOG(VERBOSE) << StringPrintf(
2721           "%s:  nfcee_id=0x%x ee_status=0x%x ecb_flags=0x%x la_protocol=0x%x "
2722           "lb_protocol=0x%x lf_protocol=0x%x",
2723           __func__, p_cb->nfcee_id, p_cb->ee_status, p_cb->ecb_flags,
2724           p_cb->la_protocol, p_cb->lb_protocol, p_cb->lf_protocol);
2725     } else {
2726       if (p_cbk->info[xx].tech_n_mode == NFC_DISCOVERY_TYPE_LISTEN_A) {
2727         p_cb->la_protocol = 0;
2728       } else if (p_cbk->info[xx].tech_n_mode == NFC_DISCOVERY_TYPE_LISTEN_B) {
2729         p_cb->lb_protocol = 0;
2730       } else if (p_cbk->info[xx].tech_n_mode == NFC_DISCOVERY_TYPE_LISTEN_F) {
2731         p_cb->lf_protocol = 0;
2732       } else if (p_cbk->info[xx].tech_n_mode ==
2733                  NFC_DISCOVERY_TYPE_LISTEN_B_PRIME) {
2734         p_cb->lbp_protocol = 0;
2735       }
2736       // Check if MEP NFCEE, set inactive and keep MEP flag
2737       if (p_cb->ee_status & NFA_EE_STATUS_MEP_MASK) {
2738         LOG(DEBUG) << StringPrintf("%s: Set MEP nfceeId=0x%x inactive",
2739                                    __func__, p_cbk->info[xx].nfcee_id);
2740         p_cb->ee_status = NFA_EE_STATUS_INACTIVE | NFA_EE_STATUS_MEP_MASK;
2741       }
2742     }
2743   }
2744 
2745   /* Report NFA_EE_DISCOVER_REQ_EVT for all active NFCEE */
2746   if (report_ntf) nfa_ee_report_discover_req_evt();
2747 }
2748 
2749 /*******************************************************************************
2750 **
2751 ** Function         nfa_ee_is_active
2752 **
2753 ** Description      Check if the given NFCEE is active
2754 **
2755 ** Returns          TRUE if the given NFCEE is active
2756 **
2757 *******************************************************************************/
nfa_ee_is_active(tNFA_HANDLE nfcee_id)2758 bool nfa_ee_is_active(tNFA_HANDLE nfcee_id) {
2759   bool is_active = false;
2760   int xx;
2761   tNFA_EE_ECB* p_cb = nfa_ee_cb.ecb;
2762 
2763   if ((NFA_HANDLE_GROUP_MASK & nfcee_id) == NFA_HANDLE_GROUP_EE)
2764     nfcee_id &= NFA_HANDLE_MASK;
2765 
2766   if (nfcee_id == NFC_DH_ID) return true;
2767 
2768   /* compose output */
2769   for (xx = 0; xx < nfa_ee_cb.cur_ee; xx++, p_cb++) {
2770     if ((tNFA_HANDLE)p_cb->nfcee_id == nfcee_id) {
2771       if (p_cb->ee_status == NFA_EE_STATUS_ACTIVE) {
2772         is_active = true;
2773       }
2774       break;
2775     }
2776   }
2777   return is_active;
2778 }
2779 
2780 /*******************************************************************************
2781 **
2782 ** Function         nfa_ee_get_tech_route
2783 **
2784 ** Description      Given a power state, find the technology routing
2785 **                  destination. The result is filled in the given p_handles
2786 **                  in the order of A, B, F, Bprime
2787 **
2788 ** Returns          None
2789 **
2790 *******************************************************************************/
nfa_ee_get_tech_route(uint8_t power_state,uint8_t * p_handles)2791 void nfa_ee_get_tech_route(uint8_t power_state, uint8_t* p_handles) {
2792   int xx, yy;
2793   tNFA_EE_ECB* p_cb;
2794   uint8_t tech_mask_list[NFA_EE_MAX_TECH_ROUTE] = {
2795       NFA_TECHNOLOGY_MASK_A, NFA_TECHNOLOGY_MASK_B, NFA_TECHNOLOGY_MASK_F,
2796       NFA_TECHNOLOGY_MASK_B_PRIME};
2797 
2798   for (xx = 0; xx < NFA_EE_MAX_TECH_ROUTE; xx++) {
2799     p_handles[xx] = NFC_DH_ID;
2800     if (nfa_ee_cb.cur_ee > 0) p_cb = &nfa_ee_cb.ecb[nfa_ee_cb.cur_ee - 1];
2801     for (yy = 0; yy < nfa_ee_cb.cur_ee; yy++, p_cb--) {
2802       if ((p_cb->ee_status & ~NFA_EE_STATUS_MEP_MASK) ==
2803           NFC_NFCEE_STATUS_ACTIVE) {
2804         switch (power_state) {
2805           case NFA_EE_PWR_STATE_ON:
2806             if (p_cb->tech_switch_on & tech_mask_list[xx])
2807               p_handles[xx] = p_cb->nfcee_id;
2808             break;
2809           case NFA_EE_PWR_STATE_SWITCH_OFF:
2810             if (p_cb->tech_switch_off & tech_mask_list[xx])
2811               p_handles[xx] = p_cb->nfcee_id;
2812             break;
2813           case NFA_EE_PWR_STATE_BATT_OFF:
2814             if (p_cb->tech_battery_off & tech_mask_list[xx])
2815               p_handles[xx] = p_cb->nfcee_id;
2816             break;
2817         }
2818       }
2819     }
2820   }
2821   LOG(VERBOSE) << StringPrintf("%s: 0x%x, 0x%x, 0x%x, 0x%x", __func__,
2822                                p_handles[0], p_handles[1], p_handles[2],
2823                                p_handles[3]);
2824 }
2825 
2826 /*******************************************************************************
2827 **
2828 ** Function         nfa_ee_check_set_routing
2829 **
2830 ** Description      If the new size exceeds the capacity of next block,
2831 **                  send the routing command now and reset the related
2832 **                  parameters.
2833 **
2834 ** Returns          void
2835 **
2836 *******************************************************************************/
nfa_ee_check_set_routing(uint16_t new_size,int * p_max_len,uint8_t * p,int * p_cur_offset)2837 void nfa_ee_check_set_routing(uint16_t new_size, int* p_max_len, uint8_t* p,
2838                               int* p_cur_offset) {
2839   uint8_t max_tlv = (uint8_t)((*p_max_len > NFA_EE_ROUT_MAX_TLV_SIZE)
2840                                   ? NFA_EE_ROUT_MAX_TLV_SIZE
2841                                   : *p_max_len);
2842 
2843   if (new_size + *p_cur_offset > max_tlv) {
2844     if (NFC_SetRouting(true, *p, *p_cur_offset, p + 1) == NFA_STATUS_OK) {
2845       nfa_ee_cb.wait_rsp++;
2846     }
2847     /* after the routing command is sent, re-use the same buffer to send the
2848      * next routing command.
2849      * reset the related parameters */
2850     if (*p_max_len > *p_cur_offset)
2851       *p_max_len -= *p_cur_offset; /* the max is reduced */
2852     else
2853       *p_max_len = 0;
2854     *p_cur_offset = 0; /* nothing is in queue any more */
2855     *p = 0;            /* num_tlv=0 */
2856   }
2857 }
2858 
2859 /*******************************************************************************
2860 **
2861 ** Function         nfa_ee_route_add_one_ecb_order
2862 **
2863 ** Description      Add the routing entries for NFCEE/DH in order defined
2864 **
2865 ** Returns          NFA_STATUS_OK, if ok to continue
2866 **
2867 *******************************************************************************/
nfa_ee_route_add_one_ecb_by_route_order(tNFA_EE_ECB * p_cb,int rout_type,int * p_max_len,bool more,uint8_t * ps,int * p_cur_offset,tNFA_EE_EMPTY_AID_ECB & empty_aid_ecb)2868 void nfa_ee_route_add_one_ecb_by_route_order(
2869     tNFA_EE_ECB* p_cb, int rout_type, int* p_max_len, bool more, uint8_t* ps,
2870     int* p_cur_offset, tNFA_EE_EMPTY_AID_ECB& empty_aid_ecb) {
2871   /* use the first byte of the buffer (ps) to keep the num_tlv */
2872   uint8_t num_tlv = *ps;
2873   uint8_t* pp = ps + 1 + *p_cur_offset;
2874   uint8_t* p = pp;
2875   uint16_t tlv_size = (uint8_t)*p_cur_offset;
2876 
2877   switch (rout_type) {
2878     case NCI_ROUTE_ORDER_TECHNOLOGY: {
2879       nfa_ee_check_set_routing(p_cb->size_mask_tech, p_max_len, ps,
2880                                p_cur_offset);
2881       pp = ps + 1 + *p_cur_offset;
2882       p = pp;
2883       nfa_ee_add_tech_route_to_ecb(p_cb, pp, p, ps, p_cur_offset);
2884     } break;
2885 
2886     case NCI_ROUTE_ORDER_PROTOCOL: {
2887       nfa_ee_check_set_routing(p_cb->size_mask_proto, p_max_len, ps,
2888                                p_cur_offset);
2889       pp = ps + 1 + *p_cur_offset;
2890       p = pp;
2891       nfa_ee_add_proto_route_to_ecb(p_cb, pp, p, ps, p_cur_offset);
2892     } break;
2893     case NCI_ROUTE_ORDER_AID: {
2894       nfa_ee_add_aid_route_to_ecb(p_cb, pp, p, ps, p_cur_offset, p_max_len,
2895                                   empty_aid_ecb);
2896     } break;
2897     case NCI_ROUTE_ORDER_SYS_CODE: {
2898       nfa_ee_add_sys_code_route_to_ecb(p_cb, pp, p, ps, p_cur_offset,
2899                                        p_max_len);
2900     } break;
2901     default: {
2902     }
2903   }
2904 
2905   /* update the total number of entries */
2906   num_tlv = *ps;
2907 
2908   tlv_size = nfa_ee_total_lmrt_size();
2909   if (tlv_size) {
2910     nfa_ee_cb.ee_cfged |= nfa_ee_ecb_to_mask(p_cb);
2911   }
2912   if (p_cb->ecb_flags & NFA_EE_ECB_FLAGS_ROUTING) {
2913     nfa_ee_cb.ee_cfg_sts |= NFA_EE_STS_CHANGED_ROUTING;
2914   }
2915 
2916   if (more == false) {
2917     /* last entry. update routing table now */
2918     if (nfa_ee_cb.ee_cfg_sts & NFA_EE_STS_CHANGED_ROUTING) {
2919       if (tlv_size) {
2920         nfa_ee_cb.ee_cfg_sts |= NFA_EE_STS_PREV_ROUTING;
2921       } else {
2922         nfa_ee_cb.ee_cfg_sts &= ~NFA_EE_STS_PREV_ROUTING;
2923       }
2924       LOG(VERBOSE) << StringPrintf("%s: set routing num_tlv=%d tlv_size=%d",
2925                                    __func__, num_tlv, tlv_size);
2926       if (NFC_SetRouting(more, num_tlv, (uint8_t)(*p_cur_offset), ps + 1) ==
2927           NFA_STATUS_OK) {
2928         nfa_ee_cb.wait_rsp++;
2929       }
2930     } else if (nfa_ee_cb.ee_cfg_sts & NFA_EE_STS_PREV_ROUTING) {
2931       if (tlv_size == 0) {
2932         nfa_ee_cb.ee_cfg_sts &= ~NFA_EE_STS_PREV_ROUTING;
2933         /* indicated routing is configured to NFCC */
2934         nfa_ee_cb.ee_cfg_sts |= NFA_EE_STS_CHANGED_ROUTING;
2935         if (NFC_SetRouting(more, 0, 0, ps + 1) == NFA_STATUS_OK) {
2936           nfa_ee_cb.wait_rsp++;
2937         }
2938       }
2939     }
2940   }
2941 }
2942 
2943 /*******************************************************************************
2944 **
2945 ** Function         nfa_ee_need_recfg
2946 **
2947 ** Description      Check if any API function to configure the routing table or
2948 **                  VS is called since last update
2949 **
2950 **                  The algorithm for the NFCEE configuration handling is as
2951 **                  follows:
2952 **
2953 **                  Each NFCEE_ID/DH has its own control block - tNFA_EE_ECB
2954 **                  Each control block uses ecb_flags to keep track if an API
2955 **                  that changes routing/VS is invoked. This ecb_flags is
2956 **                  cleared at the end of nfa_ee_update_rout().
2957 **
2958 **                  nfa_ee_cb.ee_cfged is the bitmask of the control blocks with
2959 **                  routing/VS configuration and NFA_EE_CFGED_UPDATE_NOW.
2960 **                  nfa_ee_cb.ee_cfged is cleared and re-calculated at the end
2961 **                  of nfa_ee_update_rout().
2962 **
2963 **                  nfa_ee_cb.ee_cfg_sts is used to check is any status is
2964 **                  changed and the associated command is issued to NFCC.
2965 **                  nfa_ee_cb.ee_cfg_sts is AND with NFA_EE_STS_PREV at the end
2966 **                  of nfa_ee_update_rout() to clear the NFA_EE_STS_CHANGED bits
2967 **                  (except NFA_EE_STS_CHANGED_CANNED_VS is cleared in
2968 **                  nfa_ee_vs_cback)
2969 **
2970 ** Returns          TRUE if any configuration is changed
2971 **
2972 *******************************************************************************/
nfa_ee_need_recfg(void)2973 static bool nfa_ee_need_recfg(void) {
2974   bool needed = false;
2975   uint32_t xx;
2976   tNFA_EE_ECB* p_cb;
2977   uint8_t mask;
2978 
2979   LOG(VERBOSE) << StringPrintf("%s: ee_cfged=0x%02x ee_cfg_sts=0x%02x",
2980                                __func__, nfa_ee_cb.ee_cfged,
2981                                nfa_ee_cb.ee_cfg_sts);
2982   /* if no routing/vs is configured, do not need to send the info to NFCC */
2983   if (nfa_ee_cb.ee_cfged || nfa_ee_cb.ee_cfg_sts) {
2984     if (nfa_ee_cb.ee_cfg_sts & NFA_EE_STS_CHANGED) {
2985       needed = true;
2986     } else {
2987       p_cb = &nfa_ee_cb.ecb[NFA_EE_CB_4_DH];
2988       mask = 1 << NFA_EE_CB_4_DH;
2989       for (xx = 0; xx <= nfa_ee_cb.cur_ee; xx++) {
2990         LOG(VERBOSE) << StringPrintf("%s: %d ecb_flags  =0x%02x, mask=0x%02x",
2991                                      __func__, xx, p_cb->ecb_flags, mask);
2992         if ((p_cb->ecb_flags) && (nfa_ee_cb.ee_cfged & mask)) {
2993           needed = true;
2994           break;
2995         }
2996         p_cb = &nfa_ee_cb.ecb[xx];
2997         mask = 1 << xx;
2998       }
2999     }
3000   }
3001 
3002   return needed;
3003 }
3004 
3005 /*******************************************************************************
3006 **
3007 ** Function         nfa_ee_rout_timeout
3008 **
3009 ** Description      Anytime VS or routing entries are changed,
3010 **                  a 1 second timer is started. This function is called when
3011 **                  the timer expires or NFA_EeUpdateNow() is called.
3012 **
3013 ** Returns          void
3014 **
3015 *******************************************************************************/
nfa_ee_rout_timeout(tNFA_EE_MSG * p_data)3016 void nfa_ee_rout_timeout(__attribute__((unused)) tNFA_EE_MSG* p_data) {
3017   uint8_t ee_cfged = nfa_ee_cb.ee_cfged;
3018 
3019   LOG(VERBOSE) << __func__;
3020   if (nfa_ee_need_recfg()) {
3021     /* discovery is not started */
3022     nfa_ee_update_rout();
3023   }
3024 
3025   if (nfa_ee_cb.wait_rsp) nfa_ee_cb.ee_wait_evt |= NFA_EE_WAIT_UPDATE_RSP;
3026   if (ee_cfged & NFA_EE_CFGED_UPDATE_NOW) {
3027     /* need to report NFA_EE_UPDATED_EVT when done updating NFCC */
3028     nfa_ee_cb.ee_wait_evt |= NFA_EE_WAIT_UPDATE;
3029     if (!nfa_ee_cb.wait_rsp) {
3030       nfa_ee_report_update_evt();
3031     }
3032   }
3033 }
3034 
3035 /*******************************************************************************
3036 **
3037 ** Function         nfa_ee_discv_timeout
3038 **
3039 ** Description
3040 **
3041 **
3042 **
3043 ** Returns          void
3044 **
3045 *******************************************************************************/
nfa_ee_discv_timeout(tNFA_EE_MSG * p_data)3046 void nfa_ee_discv_timeout(__attribute__((unused)) tNFA_EE_MSG* p_data) {
3047   if (NFA_GetNCIVersion() < NCI_VERSION_2_0) NFC_NfceeDiscover(false);
3048   if (nfa_ee_cb.p_enable_cback)
3049     (*nfa_ee_cb.p_enable_cback)(NFA_EE_DISC_STS_OFF);
3050 }
3051 
3052 /*******************************************************************************
3053 **
3054 ** Function         nfa_ee_lmrt_to_nfcc
3055 **
3056 ** Description      This function would set the listen mode routing table
3057 **                  to NFCC.
3058 **
3059 ** Returns          void
3060 **
3061 *******************************************************************************/
nfa_ee_lmrt_to_nfcc(tNFA_EE_MSG * p_data)3062 void nfa_ee_lmrt_to_nfcc(__attribute__((unused)) tNFA_EE_MSG* p_data) {
3063   int xx;
3064   tNFA_EE_ECB* p_cb;
3065   uint8_t* p = nullptr;
3066   bool more = true;
3067   bool check = true;
3068   uint8_t last_active = NFA_EE_INVALID;
3069   int max_len;
3070   tNFA_STATUS status = NFA_STATUS_FAILED;
3071   int cur_offset;
3072 
3073   /* update routing table: DH and the activated NFCEEs */
3074   max_len = (NFC_GetLmrtSize() > NFA_EE_ROUT_BUF_SIZE) ? NFC_GetLmrtSize()
3075                                                        : NFA_EE_ROUT_BUF_SIZE;
3076   p = (uint8_t*)GKI_getbuf(max_len);
3077   if (p == nullptr) {
3078     LOG(ERROR) << StringPrintf("%s: no buffer to send routing info", __func__);
3079     tNFA_EE_CBACK_DATA nfa_ee_cback_data;
3080     nfa_ee_cback_data.status = status;
3081     nfa_ee_report_event(nullptr, NFA_EE_NO_MEM_ERR_EVT, &nfa_ee_cback_data);
3082     return;
3083   }
3084 
3085   /* find the last active NFCEE. */
3086   if (nfa_ee_cb.cur_ee > 0) p_cb = &nfa_ee_cb.ecb[nfa_ee_cb.cur_ee - 1];
3087 
3088   for (xx = 0; xx < nfa_ee_cb.cur_ee; xx++, p_cb--) {
3089     if ((p_cb->ee_status & ~NFA_EE_STATUS_MEP_MASK) ==
3090         NFC_NFCEE_STATUS_ACTIVE) {
3091       if (last_active == NFA_EE_INVALID) {
3092         last_active = p_cb->nfcee_id;
3093         LOG(VERBOSE) << StringPrintf("%s:  active NFCEE=0x%x", __func__,
3094                                      last_active);
3095       }
3096     }
3097   }
3098   if (last_active == NFA_EE_INVALID) {
3099     check = false;
3100   }
3101   cur_offset = 0;
3102   /* use the first byte of the buffer (p) to keep the num_tlv */
3103   *p = 0;
3104   tNFA_EE_EMPTY_AID_ECB empty_aid_ecb;
3105   memset(&empty_aid_ecb, 0x00, sizeof(tNFA_EE_EMPTY_AID_ECB));
3106 
3107   for (int rt = NCI_ROUTE_ORDER_AID; rt <= NCI_ROUTE_ORDER_TECHNOLOGY; rt++) {
3108     /* add the routing entries for NFCEEs */
3109     p_cb = &nfa_ee_cb.ecb[0];
3110 
3111     for (xx = 0; (xx < nfa_ee_cb.cur_ee) && check; xx++, p_cb++) {
3112       if ((p_cb->ee_status & ~NFA_EE_STATUS_MEP_MASK) ==
3113           NFC_NFCEE_STATUS_ACTIVE) {
3114         nfa_ee_route_add_one_ecb_by_route_order(p_cb, rt, &max_len, more, p,
3115                                                 &cur_offset, empty_aid_ecb);
3116       }
3117     }
3118     if (rt == NCI_ROUTE_ORDER_TECHNOLOGY) more = false;
3119     /* add the routing entries for DH */
3120     nfa_ee_route_add_one_ecb_by_route_order(&nfa_ee_cb.ecb[NFA_EE_CB_4_DH], rt,
3121                                             &max_len, more, p, &cur_offset,
3122                                             empty_aid_ecb);
3123 
3124     if (rt == NCI_ROUTE_ORDER_AID) {
3125       if (empty_aid_ecb.p_cb) {
3126         LOG(VERBOSE) << StringPrintf(
3127             "%s: add the routing for Empty Aid on NfceeId 0x%x!!", __func__,
3128             empty_aid_ecb.p_cb->nfcee_id);
3129         empty_aid_ecb.addEmptyAidRoute = true;
3130         nfa_ee_route_add_one_ecb_by_route_order(empty_aid_ecb.p_cb, rt,
3131                                                 &max_len, more, p, &cur_offset,
3132                                                 empty_aid_ecb);
3133       }
3134     }
3135   }
3136 
3137   GKI_freebuf(p);
3138 }
3139 
3140 /*******************************************************************************
3141 **
3142 ** Function         nfa_ee_update_rout
3143 **
3144 ** Description      This function would set the VS and listen mode routing table
3145 **                  to NFCC.
3146 **
3147 ** Returns          void
3148 **
3149 *******************************************************************************/
nfa_ee_update_rout(void)3150 void nfa_ee_update_rout(void) {
3151   int xx;
3152   tNFA_EE_ECB* p_cb;
3153   uint8_t mask;
3154   tNFA_EE_MSG nfa_ee_msg;
3155 
3156   LOG(VERBOSE) << StringPrintf("%s: ee_cfg_sts=0x%02x", __func__,
3157                                nfa_ee_cb.ee_cfg_sts);
3158 
3159   /* use action function to send routing and VS configuration to NFCC */
3160   nfa_ee_msg.hdr.event = NFA_EE_CFG_TO_NFCC_EVT;
3161   nfa_ee_evt_hdlr(&nfa_ee_msg.hdr);
3162 
3163   /* all configuration is updated to NFCC, clear the status mask */
3164   nfa_ee_cb.ee_cfg_sts &= NFA_EE_STS_PREV;
3165   nfa_ee_cb.ee_cfged = 0;
3166   p_cb = &nfa_ee_cb.ecb[0];
3167   for (xx = 0; xx < NFA_EE_NUM_ECBS; xx++, p_cb++) {
3168     p_cb->ecb_flags = 0;
3169     mask = (1 << xx);
3170     if (p_cb->tech_switch_on | p_cb->tech_switch_off | p_cb->tech_battery_off |
3171         p_cb->proto_switch_on | p_cb->proto_switch_off |
3172         p_cb->proto_battery_off | p_cb->aid_entries |
3173         p_cb->sys_code_cfg_entries) {
3174       /* this entry has routing configuration. mark it configured */
3175       nfa_ee_cb.ee_cfged |= mask;
3176     }
3177   }
3178   LOG(VERBOSE) << StringPrintf("%s: ee_cfg_sts=0x%02x ee_cfged=0x%02x",
3179                                __func__, nfa_ee_cb.ee_cfg_sts,
3180                                nfa_ee_cb.ee_cfged);
3181 }
3182