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