• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /******************************************************************************
2  *
3  *  Copyright (C) 2010-2014 Broadcom Corporation
4  *
5  *  Licensed under the Apache License, Version 2.0 (the "License");
6  *  you may not use this file except in compliance with the License.
7  *  You may obtain a copy of the License at:
8  *
9  *  http://www.apache.org/licenses/LICENSE-2.0
10  *
11  *  Unless required by applicable law or agreed to in writing, software
12  *  distributed under the License is distributed on an "AS IS" BASIS,
13  *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  *  See the License for the specific language governing permissions and
15  *  limitations under the License.
16  *
17  ******************************************************************************/
18 
19 /******************************************************************************
20  *
21  *  This file contains the action functions for NFA-EE
22  *
23  ******************************************************************************/
24 #include <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   if (nfa_ee_cb.cur_ee > 0) 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 = nullptr;
1746     if (nfa_ee_cb.cur_ee > 0) p_cb_end = &nfa_ee_cb.ecb[nfa_ee_cb.cur_ee - 1];
1747     p_cb = &nfa_ee_cb.ecb[first_removed];
1748     for (p_cb_n = p_cb + 1; p_cb_n <= p_cb_end;) {
1749       while ((p_cb_n->nfcee_id == NFA_EE_INVALID) && (p_cb_n <= p_cb_end)) {
1750         p_cb_n++;
1751       }
1752 
1753       if (p_cb_n <= p_cb_end) {
1754         memcpy(p_cb, p_cb_n, sizeof(tNFA_EE_ECB));
1755         p_cb_n->nfcee_id = NFA_EE_INVALID;
1756       }
1757       p_cb++;
1758       p_cb_n++;
1759     }
1760   }
1761   nfa_ee_cb.cur_ee -= (uint8_t)num_removed;
1762 }
1763 
1764 /*******************************************************************************
1765 **
1766 ** Function         nfa_ee_nci_disc_rsp
1767 **
1768 ** Description      Process the callback for NFCEE discovery response
1769 **
1770 ** Returns          void
1771 **
1772 *******************************************************************************/
nfa_ee_nci_disc_rsp(tNFA_EE_MSG * p_data)1773 void nfa_ee_nci_disc_rsp(tNFA_EE_MSG* p_data) {
1774   tNFC_NFCEE_DISCOVER_REVT* p_evt = p_data->disc_rsp.p_data;
1775   tNFA_EE_ECB* p_cb;
1776   uint8_t xx;
1777   uint8_t num_nfcee = p_evt->num_nfcee;
1778   bool notify_enable_done = false;
1779 
1780   DLOG_IF(INFO, nfc_debug_enabled)
1781       << StringPrintf("em_state:%d cur_ee:%d, num_nfcee:%d", nfa_ee_cb.em_state,
1782                       nfa_ee_cb.cur_ee, num_nfcee);
1783   switch (nfa_ee_cb.em_state) {
1784     case NFA_EE_EM_STATE_INIT:
1785       nfa_ee_cb.cur_ee = 0;
1786       nfa_ee_cb.num_ee_expecting = 0;
1787       if (num_nfcee == 0) {
1788         nfa_ee_cb.em_state = NFA_EE_EM_STATE_INIT_DONE;
1789         notify_enable_done = true;
1790         if (p_evt->status != NFC_STATUS_OK) {
1791           nfa_sys_stop_timer(&nfa_ee_cb.discv_timer);
1792         }
1793       }
1794       break;
1795 
1796     case NFA_EE_EM_STATE_INIT_DONE:
1797       if (num_nfcee) {
1798         /* if this is initiated by api function,
1799          * check if the number of NFCEE expected is more than what's currently
1800          * in CB */
1801         if (num_nfcee > NFA_EE_MAX_EE_SUPPORTED)
1802           num_nfcee = NFA_EE_MAX_EE_SUPPORTED;
1803         if (nfa_ee_cb.cur_ee < num_nfcee) {
1804           p_cb = &nfa_ee_cb.ecb[nfa_ee_cb.cur_ee];
1805           for (xx = nfa_ee_cb.cur_ee; xx < num_nfcee; xx++, p_cb++) {
1806             /* mark the new entries as a new one */
1807             p_cb->nfcee_id = NFA_EE_INVALID;
1808           }
1809         }
1810         nfa_ee_cb.cur_ee = num_nfcee;
1811       }
1812       break;
1813 
1814     case NFA_EE_EM_STATE_RESTORING:
1815       if (num_nfcee == 0) {
1816         nfa_ee_cb.em_state = NFA_EE_EM_STATE_INIT_DONE;
1817         nfa_ee_remove_pending();
1818         nfa_ee_check_restore_complete();
1819         if (p_evt->status != NFC_STATUS_OK) {
1820           nfa_sys_stop_timer(&nfa_ee_cb.discv_timer);
1821         }
1822       }
1823       break;
1824   }
1825 
1826   if (p_evt->status == NFC_STATUS_OK) {
1827     nfa_ee_cb.num_ee_expecting = p_evt->num_nfcee;
1828     if (nfa_ee_cb.num_ee_expecting > NFA_EE_MAX_EE_SUPPORTED) {
1829       LOG(ERROR) << StringPrintf("NFA-EE num_ee_expecting:%d > max:%d",
1830                                  nfa_ee_cb.num_ee_expecting,
1831                                  NFA_EE_MAX_EE_SUPPORTED);
1832     }
1833   }
1834   nfa_ee_report_disc_done(notify_enable_done);
1835   DLOG_IF(INFO, nfc_debug_enabled) << StringPrintf(
1836       "em_state:%d cur_ee:%d num_ee_expecting:%d", nfa_ee_cb.em_state,
1837       nfa_ee_cb.cur_ee, nfa_ee_cb.num_ee_expecting);
1838 }
1839 
1840 /*******************************************************************************
1841 **
1842 ** Function         nfa_ee_nci_disc_ntf
1843 **
1844 ** Description      Process the callback for NFCEE discovery notification
1845 **
1846 ** Returns          void
1847 **
1848 *******************************************************************************/
nfa_ee_nci_disc_ntf(tNFA_EE_MSG * p_data)1849 void nfa_ee_nci_disc_ntf(tNFA_EE_MSG* p_data) {
1850   tNFC_NFCEE_INFO_REVT* p_ee = p_data->disc_ntf.p_data;
1851   tNFA_EE_ECB* p_cb = nullptr;
1852   bool notify_enable_done = false;
1853   bool notify_new_ee = false;
1854   tNFA_EE_CBACK_DATA evt_data = {0};
1855   tNFA_EE_INFO* p_info;
1856   tNFA_EE_EM_STATE new_em_state = NFA_EE_EM_STATE_MAX;
1857 
1858   DLOG_IF(INFO, nfc_debug_enabled) << StringPrintf(
1859       "em_state:%d ee_flags:0x%x cur_ee:%d "
1860       "num_ee_expecting:%d",
1861       nfa_ee_cb.em_state, nfa_ee_cb.ee_flags, nfa_ee_cb.cur_ee,
1862       nfa_ee_cb.num_ee_expecting);
1863   if (nfa_ee_cb.num_ee_expecting) {
1864     nfa_ee_cb.num_ee_expecting--;
1865     if ((nfa_ee_cb.num_ee_expecting == 0) &&
1866         (nfa_ee_cb.p_ee_disc_cback != nullptr)) {
1867       /* Discovery triggered by API function */
1868       if (NFA_GetNCIVersion() != NCI_VERSION_2_0) NFC_NfceeDiscover(false);
1869     }
1870   }
1871   switch (nfa_ee_cb.em_state) {
1872     case NFA_EE_EM_STATE_INIT:
1873       if (nfa_ee_cb.cur_ee < NFA_EE_MAX_EE_SUPPORTED) {
1874         /* the cb can collect up to NFA_EE_MAX_EE_SUPPORTED ee_info */
1875         p_cb = &nfa_ee_cb.ecb[nfa_ee_cb.cur_ee++];
1876       }
1877 
1878       if (nfa_ee_cb.num_ee_expecting == 0) {
1879         /* notify init_done callback */
1880         nfa_ee_cb.em_state = NFA_EE_EM_STATE_INIT_DONE;
1881         notify_enable_done = true;
1882       }
1883       break;
1884 
1885     case NFA_EE_EM_STATE_INIT_DONE:
1886       p_cb = nfa_ee_find_ecb(p_ee->nfcee_id);
1887       if (p_cb == nullptr) {
1888         /* the NFCEE ID is not in the last NFCEE discovery
1889          * maybe it's a new one */
1890         p_cb = nfa_ee_find_ecb(NFA_EE_INVALID);
1891         if (p_cb) {
1892           nfa_ee_cb.cur_ee++;
1893           notify_new_ee = true;
1894         }
1895       } else if (p_cb->ecb_flags & NFA_EE_ECB_FLAGS_ORDER) {
1896         nfa_ee_cb.cur_ee++;
1897         notify_new_ee = true;
1898       } else {
1899         DLOG_IF(INFO, nfc_debug_enabled)
1900             << StringPrintf("cur_ee:%d ecb_flags=0x%02x  ee_status=0x%x",
1901                             nfa_ee_cb.cur_ee, p_cb->ecb_flags, p_cb->ee_status);
1902       }
1903       break;
1904 
1905     case NFA_EE_EM_STATE_RESTORING:
1906       p_cb = nfa_ee_find_ecb(p_ee->nfcee_id);
1907       if (p_cb == nullptr) {
1908         /* the NFCEE ID is not in the last NFCEE discovery
1909          * maybe it's a new one */
1910         p_cb = nfa_ee_find_ecb(NFA_EE_INVALID);
1911         if (p_cb) {
1912           nfa_ee_cb.cur_ee++;
1913           notify_new_ee = true;
1914         }
1915       }
1916       if (nfa_ee_cb.num_ee_expecting == 0) {
1917         /* notify init_done callback */
1918         notify_enable_done = true;
1919         if (nfa_ee_restore_ntf_done()) {
1920           new_em_state = NFA_EE_EM_STATE_INIT_DONE;
1921         }
1922       }
1923       break;
1924   }
1925   DLOG_IF(INFO, nfc_debug_enabled)
1926       << StringPrintf("nfa_ee_nci_disc_ntf cur_ee:%d", nfa_ee_cb.cur_ee);
1927 
1928   if (p_cb) {
1929     p_cb->nfcee_id = p_ee->nfcee_id;
1930     p_cb->ee_status = p_ee->ee_status;
1931     p_cb->num_interface = p_ee->num_interface;
1932     memcpy(p_cb->ee_interface, p_ee->ee_interface, p_ee->num_interface);
1933     p_cb->num_tlvs = p_ee->num_tlvs;
1934     memcpy(p_cb->ee_tlv, p_ee->ee_tlv, p_ee->num_tlvs * sizeof(tNFA_EE_TLV));
1935     if (NFA_GetNCIVersion() == NCI_VERSION_2_0)
1936       p_cb->ee_power_supply_status = p_ee->nfcee_power_ctrl;
1937     if (nfa_ee_cb.em_state == NFA_EE_EM_STATE_RESTORING) {
1938       /* NCI spec says: An NFCEE_DISCOVER_NTF that contains a Protocol type of
1939        * "HCI Access"
1940        * SHALL NOT contain any other additional Protocol
1941        * i.e. check only first supported NFCEE interface is HCI access */
1942       /* NFA_HCI module handles restoring configurations for HCI access */
1943       if (p_cb->ee_interface[0] != NFC_NFCEE_INTERFACE_HCI_ACCESS) {
1944         if ((nfa_ee_cb.ee_flags & NFA_EE_FLAG_WAIT_HCI) == 0) {
1945           nfa_ee_restore_one_ecb(p_cb);
1946         }
1947         /* else wait for NFA-HCI module to restore the HCI network information
1948          * before enabling the NFCEE */
1949       }
1950     }
1951 
1952     if ((nfa_ee_cb.p_ee_disc_cback == nullptr) && (notify_new_ee == true)) {
1953       if (nfa_dm_is_active() && (p_cb->ee_status != NFA_EE_STATUS_REMOVED)) {
1954         /* report this NFA_EE_NEW_EE_EVT only after NFA_DM_ENABLE_EVT is
1955          * reported */
1956         p_info = &evt_data.new_ee;
1957         p_info->ee_handle = NFA_HANDLE_GROUP_EE | (tNFA_HANDLE)p_cb->nfcee_id;
1958         p_info->ee_status = p_cb->ee_status;
1959         p_info->num_interface = p_cb->num_interface;
1960         p_info->num_tlvs = p_cb->num_tlvs;
1961         memcpy(p_info->ee_interface, p_cb->ee_interface, p_cb->num_interface);
1962         memcpy(p_info->ee_tlv, p_cb->ee_tlv,
1963                p_cb->num_tlvs * sizeof(tNFA_EE_TLV));
1964         if (NFA_GetNCIVersion() == NCI_VERSION_2_0)
1965           p_info->ee_power_supply_status = p_cb->ee_power_supply_status;
1966         nfa_ee_report_event(nullptr, NFA_EE_NEW_EE_EVT, &evt_data);
1967       }
1968     } else
1969       nfa_ee_report_disc_done(notify_enable_done);
1970 
1971     if (p_cb->ecb_flags & NFA_EE_ECB_FLAGS_ORDER) {
1972       DLOG_IF(INFO, nfc_debug_enabled)
1973           << StringPrintf("NFA_EE_ECB_FLAGS_ORDER");
1974       p_cb->ecb_flags &= ~NFA_EE_ECB_FLAGS_ORDER;
1975       nfa_ee_report_discover_req_evt();
1976     }
1977   }
1978 
1979   if (new_em_state != NFA_EE_EM_STATE_MAX) {
1980     nfa_ee_cb.em_state = new_em_state;
1981     nfa_ee_check_restore_complete();
1982   }
1983 
1984   if ((nfa_ee_cb.cur_ee == nfa_ee_max_ee_cfg) &&
1985       (nfa_ee_cb.em_state == NFA_EE_EM_STATE_INIT_DONE)) {
1986     if (nfa_ee_cb.discv_timer.in_use) {
1987       nfa_sys_stop_timer(&nfa_ee_cb.discv_timer);
1988       p_data->hdr.event = NFA_EE_DISCV_TIMEOUT_EVT;
1989       nfa_ee_evt_hdlr(&p_data->hdr);
1990     }
1991   }
1992 }
1993 
1994 /*******************************************************************************
1995 **
1996 ** Function         nfa_ee_nci_nfcee_status_ntf
1997 **
1998 ** Description      Process the callback for NFCEE status notification
1999 **
2000 ** Returns          void
2001 **
2002 *******************************************************************************/
nfa_ee_nci_nfcee_status_ntf(tNFA_EE_MSG * p_data)2003 void nfa_ee_nci_nfcee_status_ntf(tNFA_EE_MSG* p_data) {
2004   if (p_data != nullptr) {
2005     tNFC_NFCEE_STATUS_REVT* p_ee_data = p_data->nfcee_status_ntf.p_data;
2006     if ((NFA_GetNCIVersion() == NCI_VERSION_2_0) &&
2007         (p_ee_data->nfcee_status == NFC_NFCEE_STATUS_UNRECOVERABLE_ERROR)) {
2008       tNFA_EE_ECB* p_cb = nfa_ee_find_ecb(p_ee_data->nfcee_id);
2009       if (p_cb && nfa_ee_cb.p_enable_cback) {
2010         (*nfa_ee_cb.p_enable_cback)(NFA_EE_RECOVERY_INIT);
2011         NFC_NfceeDiscover(true);
2012       }
2013     }
2014   }
2015 }
2016 
2017 /*******************************************************************************
2018 **
2019 ** Function         nfa_ee_check_restore_complete
2020 **
2021 ** Description      Check if restore the NFA-EE related configuration to the
2022 **                  state prior to low power mode is complete.
2023 **                  If complete, notify sys.
2024 **
2025 ** Returns          void
2026 **
2027 *******************************************************************************/
nfa_ee_check_restore_complete(void)2028 void nfa_ee_check_restore_complete(void) {
2029   uint32_t xx;
2030   tNFA_EE_ECB* p_cb;
2031   bool proc_complete = true;
2032 
2033   p_cb = nfa_ee_cb.ecb;
2034   for (xx = 0; xx < nfa_ee_cb.cur_ee; xx++, p_cb++) {
2035     if (p_cb->ecb_flags & NFA_EE_ECB_FLAGS_RESTORE) {
2036       /* NFA_HCI module handles restoring configurations for HCI access.
2037        * ignore the restoring status for HCI Access */
2038       if (p_cb->ee_interface[0] != NFC_NFCEE_INTERFACE_HCI_ACCESS) {
2039         proc_complete = false;
2040         break;
2041       }
2042     }
2043   }
2044 
2045   DLOG_IF(INFO, nfc_debug_enabled) << StringPrintf(
2046       "nfa_ee_check_restore_complete nfa_ee_cb.ee_cfg_sts:0x%02x "
2047       "proc_complete:%d",
2048       nfa_ee_cb.ee_cfg_sts, proc_complete);
2049   if (proc_complete) {
2050     /* update routing table when NFA_EE_ROUT_TIMEOUT_EVT is received */
2051     if (nfa_ee_cb.ee_cfg_sts & NFA_EE_STS_PREV_ROUTING)
2052       nfa_ee_api_update_now(nullptr);
2053 
2054     nfa_ee_cb.em_state = NFA_EE_EM_STATE_INIT_DONE;
2055     nfa_sys_cback_notify_nfcc_power_mode_proc_complete(NFA_ID_EE);
2056   }
2057 }
2058 
2059 /*******************************************************************************
2060 **
2061 ** Function         nfa_ee_build_discover_req_evt
2062 **
2063 ** Description      Build NFA_EE_DISCOVER_REQ_EVT for all active NFCEE
2064 **
2065 ** Returns          void
2066 **
2067 *******************************************************************************/
nfa_ee_build_discover_req_evt(tNFA_EE_DISCOVER_REQ * p_evt_data)2068 static void nfa_ee_build_discover_req_evt(tNFA_EE_DISCOVER_REQ* p_evt_data) {
2069   tNFA_EE_ECB* p_cb;
2070   tNFA_EE_DISCOVER_INFO* p_info;
2071   uint8_t xx;
2072 
2073   if (!p_evt_data) return;
2074 
2075   p_evt_data->num_ee = 0;
2076   p_cb = nfa_ee_cb.ecb;
2077   p_info = p_evt_data->ee_disc_info;
2078 
2079   for (xx = 0; xx < nfa_ee_cb.cur_ee; xx++, p_cb++) {
2080     if ((p_cb->ee_status & NFA_EE_STATUS_INT_MASK) ||
2081         (p_cb->ee_status != NFA_EE_STATUS_ACTIVE)) {
2082       continue;
2083     }
2084     p_info->ee_handle = (tNFA_HANDLE)p_cb->nfcee_id | NFA_HANDLE_GROUP_EE;
2085     p_info->la_protocol = p_cb->la_protocol;
2086     p_info->lb_protocol = p_cb->lb_protocol;
2087     p_info->lf_protocol = p_cb->lf_protocol;
2088     p_info->lbp_protocol = p_cb->lbp_protocol;
2089     p_evt_data->num_ee++;
2090     p_info++;
2091 
2092     DLOG_IF(INFO, nfc_debug_enabled) << StringPrintf(
2093         "[%d] ee_handle:0x%x, listen protocol A:%d, B:%d, F:%d, BP:%d",
2094         p_evt_data->num_ee, p_cb->nfcee_id, p_cb->la_protocol,
2095         p_cb->lb_protocol, p_cb->lf_protocol, p_cb->lbp_protocol);
2096   }
2097 
2098   p_evt_data->status = NFA_STATUS_OK;
2099 }
2100 
2101 /*******************************************************************************
2102 **
2103 ** Function         nfa_ee_report_discover_req_evt
2104 **
2105 ** Description      Report NFA_EE_DISCOVER_REQ_EVT for all active NFCEE
2106 **
2107 ** Returns          void
2108 **
2109 *******************************************************************************/
nfa_ee_report_discover_req_evt(void)2110 static void nfa_ee_report_discover_req_evt(void) {
2111   if (nfa_ee_cb.p_enable_cback)
2112     (*nfa_ee_cb.p_enable_cback)(NFA_EE_DISC_STS_REQ);
2113 
2114   /* if this is restoring NFCC */
2115   if (!nfa_dm_is_active()) {
2116     DLOG_IF(INFO, nfc_debug_enabled)
2117         << StringPrintf("nfa_ee_report_discover_req_evt DM is not active");
2118     return;
2119   }
2120 
2121   tNFA_EE_CBACK_DATA nfa_ee_cback_data;
2122   nfa_ee_build_discover_req_evt(&nfa_ee_cback_data.discover_req);
2123   nfa_ee_report_event(nullptr, NFA_EE_DISCOVER_REQ_EVT, &nfa_ee_cback_data);
2124 }
2125 
2126 /*******************************************************************************
2127 **
2128 ** Function         nfa_ee_nci_mode_set_rsp
2129 **
2130 ** Description      Process the result for NFCEE ModeSet response
2131 **
2132 ** Returns          void
2133 **
2134 *******************************************************************************/
nfa_ee_nci_mode_set_rsp(tNFA_EE_MSG * p_data)2135 void nfa_ee_nci_mode_set_rsp(tNFA_EE_MSG* p_data) {
2136   tNFA_EE_ECB* p_cb;
2137   tNFA_EE_MODE_SET mode_set;
2138   tNFC_NFCEE_MODE_SET_REVT* p_rsp = p_data->mode_set_rsp.p_data;
2139 
2140   DLOG_IF(INFO, nfc_debug_enabled) << StringPrintf(
2141       "%s handle:0x%02x mode:%d", __func__, p_rsp->nfcee_id, p_rsp->mode);
2142   p_cb = nfa_ee_find_ecb(p_rsp->nfcee_id);
2143   if (p_cb == nullptr) {
2144     LOG(ERROR) << StringPrintf("%s Can not find cb for handle:0x%02x", __func__,
2145                                p_rsp->nfcee_id);
2146     return;
2147   }
2148 
2149   /* Do not update routing table in EE_RECOVERY state */
2150   if (nfa_hci_cb.hci_state != NFA_HCI_STATE_EE_RECOVERY) {
2151     /* Start routing table update debounce timer */
2152     nfa_ee_start_timer();
2153   }
2154   LOG(ERROR) << StringPrintf("%s p_rsp->status:0x%02x", __func__,
2155                              p_rsp->status);
2156   if (p_rsp->status == NFA_STATUS_OK) {
2157     if (p_rsp->mode == NFA_EE_MD_ACTIVATE) {
2158       p_cb->ee_status = NFC_NFCEE_STATUS_ACTIVE;
2159     } else {
2160       if (p_cb->tech_switch_on | p_cb->tech_switch_off |
2161           p_cb->tech_battery_off | p_cb->proto_switch_on |
2162           p_cb->proto_switch_off | p_cb->proto_battery_off |
2163           p_cb->aid_entries) {
2164         /* this NFCEE still has configuration when deactivated. clear the
2165          * configuration */
2166         nfa_ee_cb.ee_cfged &= ~nfa_ee_ecb_to_mask(p_cb);
2167         nfa_ee_cb.ee_cfg_sts |= NFA_EE_STS_CHANGED_ROUTING;
2168         DLOG_IF(INFO, nfc_debug_enabled)
2169             << StringPrintf("deactivating/still configured. Force update");
2170       }
2171       p_cb->tech_switch_on = p_cb->tech_switch_off = p_cb->tech_battery_off = 0;
2172       p_cb->proto_switch_on = p_cb->proto_switch_off = p_cb->proto_battery_off =
2173           0;
2174       p_cb->aid_entries = 0;
2175       p_cb->ee_status = NFC_NFCEE_STATUS_INACTIVE;
2176     }
2177   } else if (p_rsp->mode == NFA_EE_MD_ACTIVATE) {
2178     p_cb->ee_status = NFC_NFCEE_STATUS_REMOVED;
2179   }
2180   DLOG_IF(INFO, nfc_debug_enabled) << StringPrintf(
2181       "status:%d ecb_flags  :0x%02x ee_cfged:0x%02x ee_status:%d",
2182       p_rsp->status, p_cb->ecb_flags, nfa_ee_cb.ee_cfged, p_cb->ee_status);
2183   if (p_cb->ecb_flags & NFA_EE_ECB_FLAGS_RESTORE) {
2184     if (p_cb->conn_st == NFA_EE_CONN_ST_CONN) {
2185       /* NFA_HCI module handles restoring configurations for HCI access */
2186       if (p_cb->ee_interface[0] != NFC_NFCEE_INTERFACE_HCI_ACCESS) {
2187         NFC_ConnCreate(NCI_DEST_TYPE_NFCEE, p_cb->nfcee_id, p_cb->use_interface,
2188                        nfa_ee_conn_cback);
2189       }
2190     } else {
2191       p_cb->ecb_flags &= ~NFA_EE_ECB_FLAGS_RESTORE;
2192       nfa_ee_check_restore_complete();
2193     }
2194   } else {
2195     mode_set.status = p_rsp->status;
2196     mode_set.ee_handle = (tNFA_HANDLE)p_rsp->nfcee_id | NFA_HANDLE_GROUP_EE;
2197     mode_set.ee_status = p_cb->ee_status;
2198 
2199     tNFA_EE_CBACK_DATA nfa_ee_cback_data;
2200     nfa_ee_cback_data.mode_set = mode_set;
2201     nfa_ee_report_event(p_cb->p_ee_cback, NFA_EE_MODE_SET_EVT,
2202                         &nfa_ee_cback_data);
2203 
2204     if ((p_cb->ee_status == NFC_NFCEE_STATUS_INACTIVE) ||
2205         (p_cb->ee_status == NFC_NFCEE_STATUS_ACTIVE)) {
2206       /* Report NFA_EE_DISCOVER_REQ_EVT for all active NFCEE */
2207       nfa_ee_report_discover_req_evt();
2208     }
2209   }
2210   if (nfa_ee_cb.p_enable_cback)
2211     (*nfa_ee_cb.p_enable_cback)(NFA_EE_MODE_SET_COMPLETE);
2212 }
2213 
2214 /*******************************************************************************
2215 **
2216 ** Function         nfa_ee_report_update_evt
2217 **
2218 ** Description      Check if need to report NFA_EE_UPDATED_EVT
2219 **
2220 ** Returns          void
2221 **
2222 *******************************************************************************/
nfa_ee_report_update_evt(void)2223 void nfa_ee_report_update_evt(void) {
2224   tNFA_EE_CBACK_DATA evt_data;
2225 
2226   DLOG_IF(INFO, nfc_debug_enabled)
2227       << StringPrintf("nfa_ee_report_update_evt ee_wait_evt:0x%x wait_rsp:%d",
2228                       nfa_ee_cb.ee_wait_evt, nfa_ee_cb.wait_rsp);
2229   if (nfa_ee_cb.wait_rsp == 0) {
2230     nfa_ee_cb.ee_wait_evt &= ~NFA_EE_WAIT_UPDATE_RSP;
2231 
2232     if (nfa_ee_cb.ee_wait_evt & NFA_EE_WAIT_UPDATE) {
2233       nfa_ee_cb.ee_wait_evt &= ~NFA_EE_WAIT_UPDATE;
2234       /* finished updating NFCC; report NFA_EE_UPDATED_EVT now */
2235       evt_data.status = NFA_STATUS_OK;
2236       nfa_ee_report_event(nullptr, NFA_EE_UPDATED_EVT, &evt_data);
2237     }
2238   }
2239 }
2240 
2241 /*******************************************************************************
2242 **
2243 ** Function         nfa_ee_nci_wait_rsp
2244 **
2245 ** Description      Process the result for NCI response
2246 **
2247 ** Returns          void
2248 **
2249 *******************************************************************************/
nfa_ee_nci_wait_rsp(tNFA_EE_MSG * p_data)2250 void nfa_ee_nci_wait_rsp(tNFA_EE_MSG* p_data) {
2251   tNFA_EE_NCI_WAIT_RSP* p_rsp = &p_data->wait_rsp;
2252 
2253   DLOG_IF(INFO, nfc_debug_enabled)
2254       << StringPrintf("ee_wait_evt:0x%x wait_rsp:%d", nfa_ee_cb.ee_wait_evt,
2255                       nfa_ee_cb.wait_rsp);
2256   if (nfa_ee_cb.wait_rsp) {
2257     if (p_rsp->opcode == NCI_MSG_RF_SET_ROUTING) nfa_ee_cb.wait_rsp--;
2258   }
2259   nfa_ee_report_update_evt();
2260 }
2261 
2262 /*******************************************************************************
2263 **
2264 ** Function         nfa_ee_nci_conn
2265 **
2266 ** Description      process the connection callback events
2267 **
2268 ** Returns          void
2269 **
2270 *******************************************************************************/
nfa_ee_nci_conn(tNFA_EE_MSG * p_data)2271 void nfa_ee_nci_conn(tNFA_EE_MSG* p_data) {
2272   tNFA_EE_ECB* p_cb;
2273   tNFA_EE_NCI_CONN* p_cbk = &p_data->conn;
2274   tNFC_CONN* p_conn = p_data->conn.p_data;
2275   NFC_HDR* p_pkt = nullptr;
2276   tNFA_EE_CBACK_DATA evt_data = {0};
2277   tNFA_EE_EVT event = NFA_EE_INVALID;
2278   tNFA_EE_CBACK* p_cback = nullptr;
2279 
2280   if (p_cbk->event == NFC_CONN_CREATE_CEVT) {
2281     p_cb = nfa_ee_find_ecb(p_cbk->p_data->conn_create.id);
2282   } else {
2283     p_cb = nfa_ee_find_ecb_by_conn_id(p_cbk->conn_id);
2284     if (p_cbk->event == NFC_DATA_CEVT) p_pkt = p_conn->data.p_data;
2285   }
2286 
2287   if (p_cb) {
2288     p_cback = p_cb->p_ee_cback;
2289     evt_data.handle = (tNFA_HANDLE)p_cb->nfcee_id | NFA_HANDLE_GROUP_EE;
2290     switch (p_cbk->event) {
2291       case NFC_CONN_CREATE_CEVT:
2292         if (p_conn->conn_create.status == NFC_STATUS_OK) {
2293           p_cb->conn_id = p_cbk->conn_id;
2294           p_cb->conn_st = NFA_EE_CONN_ST_CONN;
2295         } else {
2296           p_cb->conn_st = NFA_EE_CONN_ST_NONE;
2297         }
2298         if (p_cb->ecb_flags & NFA_EE_ECB_FLAGS_RESTORE) {
2299           p_cb->ecb_flags &= ~NFA_EE_ECB_FLAGS_RESTORE;
2300           nfa_ee_check_restore_complete();
2301         } else {
2302           evt_data.connect.status = p_conn->conn_create.status;
2303           evt_data.connect.ee_interface = p_cb->use_interface;
2304           event = NFA_EE_CONNECT_EVT;
2305         }
2306         break;
2307 
2308       case NFC_CONN_CLOSE_CEVT:
2309         if (p_cb->conn_st != NFA_EE_CONN_ST_DISC) event = NFA_EE_DISCONNECT_EVT;
2310         p_cb->conn_st = NFA_EE_CONN_ST_NONE;
2311         p_cb->p_ee_cback = nullptr;
2312         p_cb->conn_id = 0;
2313         if (nfa_ee_cb.em_state == NFA_EE_EM_STATE_DISABLING) {
2314           if (nfa_ee_cb.ee_flags & NFA_EE_FLAG_WAIT_DISCONN) {
2315             if (nfa_ee_cb.num_ee_expecting) {
2316               nfa_ee_cb.num_ee_expecting--;
2317             }
2318           }
2319           if (nfa_ee_cb.num_ee_expecting == 0) {
2320             nfa_ee_cb.ee_flags &= ~NFA_EE_FLAG_WAIT_DISCONN;
2321             nfa_ee_check_disable();
2322           }
2323         }
2324         break;
2325 
2326       case NFC_DATA_CEVT:
2327         if (p_cb->conn_st == NFA_EE_CONN_ST_CONN) {
2328           /* report data event only in connected state */
2329           if (p_cb->p_ee_cback && p_pkt) {
2330             evt_data.data.len = p_pkt->len;
2331             evt_data.data.p_buf = (uint8_t*)(p_pkt + 1) + p_pkt->offset;
2332             event = NFA_EE_DATA_EVT;
2333             p_pkt = nullptr; /* so this function does not free this GKI buffer */
2334           }
2335         }
2336         break;
2337     }
2338 
2339     if ((event != NFA_EE_INVALID) && (p_cback)) (*p_cback)(event, &evt_data);
2340   }
2341   if (p_pkt) GKI_freebuf(p_pkt);
2342 }
2343 
2344 /*******************************************************************************
2345 **
2346 ** Function         nfa_ee_nci_action_ntf
2347 **
2348 ** Description      process the NFCEE action callback event
2349 **
2350 ** Returns          void
2351 **
2352 *******************************************************************************/
nfa_ee_nci_action_ntf(tNFA_EE_MSG * p_data)2353 void nfa_ee_nci_action_ntf(tNFA_EE_MSG* p_data) {
2354   tNFC_EE_ACTION_REVT* p_cbk = p_data->act.p_data;
2355   tNFA_EE_ACTION evt_data;
2356 
2357   evt_data.ee_handle = (tNFA_HANDLE)p_cbk->nfcee_id | NFA_HANDLE_GROUP_EE;
2358   evt_data.trigger = p_cbk->act_data.trigger;
2359   memcpy(&(evt_data.param), &(p_cbk->act_data.param),
2360          sizeof(tNFA_EE_ACTION_PARAM));
2361   tNFA_EE_CBACK_DATA nfa_ee_cback_data;
2362   nfa_ee_cback_data.action = evt_data;
2363   nfa_ee_report_event(nullptr, NFA_EE_ACTION_EVT, &nfa_ee_cback_data);
2364 }
2365 
2366 /*******************************************************************************
2367 **
2368 ** Function         nfa_ee_nci_disc_req_ntf
2369 **
2370 ** Description      process the NFCEE discover request callback event
2371 **
2372 ** Returns          void
2373 **
2374 *******************************************************************************/
nfa_ee_nci_disc_req_ntf(tNFA_EE_MSG * p_data)2375 void nfa_ee_nci_disc_req_ntf(tNFA_EE_MSG* p_data) {
2376   tNFC_EE_DISCOVER_REQ_REVT* p_cbk = p_data->disc_req.p_data;
2377   tNFA_HANDLE ee_handle;
2378   tNFA_EE_ECB* p_cb = nullptr;
2379   uint8_t report_ntf = 0;
2380   uint8_t xx;
2381 
2382   DLOG_IF(INFO, nfc_debug_enabled) << StringPrintf(
2383       "num_info: %d cur_ee:%d", p_cbk->num_info, nfa_ee_cb.cur_ee);
2384 
2385   for (xx = 0; xx < p_cbk->num_info; xx++) {
2386     ee_handle = NFA_HANDLE_GROUP_EE | p_cbk->info[xx].nfcee_id;
2387 
2388     p_cb = nfa_ee_find_ecb(p_cbk->info[xx].nfcee_id);
2389     if (!p_cb) {
2390       DLOG_IF(INFO, nfc_debug_enabled) << StringPrintf(
2391           "Cannot find cb for NFCEE: 0x%x", p_cbk->info[xx].nfcee_id);
2392       p_cb = nfa_ee_find_ecb(NFA_EE_INVALID);
2393       if (p_cb) {
2394         p_cb->nfcee_id = p_cbk->info[xx].nfcee_id;
2395         p_cb->ecb_flags |= NFA_EE_ECB_FLAGS_ORDER;
2396       } else {
2397         LOG(ERROR) << StringPrintf("Cannot allocate cb for NFCEE: 0x%x",
2398                                    p_cbk->info[xx].nfcee_id);
2399         continue;
2400       }
2401     } else {
2402       report_ntf |= nfa_ee_ecb_to_mask(p_cb);
2403     }
2404 
2405     p_cb->ecb_flags |= NFA_EE_ECB_FLAGS_DISC_REQ;
2406     if (p_cbk->info[xx].op == NFC_EE_DISC_OP_ADD) {
2407       if (p_cbk->info[xx].tech_n_mode == NFC_DISCOVERY_TYPE_LISTEN_A) {
2408         p_cb->la_protocol = p_cbk->info[xx].protocol;
2409       } else if (p_cbk->info[xx].tech_n_mode == NFC_DISCOVERY_TYPE_LISTEN_B) {
2410         p_cb->lb_protocol = p_cbk->info[xx].protocol;
2411       } else if (p_cbk->info[xx].tech_n_mode == NFC_DISCOVERY_TYPE_LISTEN_F) {
2412         p_cb->lf_protocol = p_cbk->info[xx].protocol;
2413       } else if (p_cbk->info[xx].tech_n_mode ==
2414                  NFC_DISCOVERY_TYPE_LISTEN_B_PRIME) {
2415         p_cb->lbp_protocol = p_cbk->info[xx].protocol;
2416       }
2417       DLOG_IF(INFO, nfc_debug_enabled) << StringPrintf(
2418           "nfcee_id=0x%x ee_status=0x%x ecb_flags=0x%x la_protocol=0x%x "
2419           "la_protocol=0x%x la_protocol=0x%x",
2420           p_cb->nfcee_id, p_cb->ee_status, p_cb->ecb_flags, p_cb->la_protocol,
2421           p_cb->lb_protocol, p_cb->lf_protocol);
2422     } else {
2423       if (p_cbk->info[xx].tech_n_mode == NFC_DISCOVERY_TYPE_LISTEN_A) {
2424         p_cb->la_protocol = 0;
2425       } else if (p_cbk->info[xx].tech_n_mode == NFC_DISCOVERY_TYPE_LISTEN_B) {
2426         p_cb->lb_protocol = 0;
2427       } else if (p_cbk->info[xx].tech_n_mode == NFC_DISCOVERY_TYPE_LISTEN_F) {
2428         p_cb->lf_protocol = 0;
2429       } else if (p_cbk->info[xx].tech_n_mode ==
2430                  NFC_DISCOVERY_TYPE_LISTEN_B_PRIME) {
2431         p_cb->lbp_protocol = 0;
2432       }
2433     }
2434   }
2435 
2436   /* Report NFA_EE_DISCOVER_REQ_EVT for all active NFCEE */
2437   if (report_ntf) nfa_ee_report_discover_req_evt();
2438 }
2439 
2440 /*******************************************************************************
2441 **
2442 ** Function         nfa_ee_is_active
2443 **
2444 ** Description      Check if the given NFCEE is active
2445 **
2446 ** Returns          TRUE if the given NFCEE is active
2447 **
2448 *******************************************************************************/
nfa_ee_is_active(tNFA_HANDLE nfcee_id)2449 bool nfa_ee_is_active(tNFA_HANDLE nfcee_id) {
2450   bool is_active = false;
2451   int xx;
2452   tNFA_EE_ECB* p_cb = nfa_ee_cb.ecb;
2453 
2454   if ((NFA_HANDLE_GROUP_MASK & nfcee_id) == NFA_HANDLE_GROUP_EE)
2455     nfcee_id &= NFA_HANDLE_MASK;
2456 
2457   if (nfcee_id == NFC_DH_ID) return true;
2458 
2459   /* compose output */
2460   for (xx = 0; xx < nfa_ee_cb.cur_ee; xx++, p_cb++) {
2461     if ((tNFA_HANDLE)p_cb->nfcee_id == nfcee_id) {
2462       if (p_cb->ee_status == NFA_EE_STATUS_ACTIVE) {
2463         is_active = true;
2464       }
2465       break;
2466     }
2467   }
2468   return is_active;
2469 }
2470 
2471 /*******************************************************************************
2472 **
2473 ** Function         nfa_ee_get_tech_route
2474 **
2475 ** Description      Given a power state, find the technology routing
2476 **                  destination. The result is filled in the given p_handles
2477 **                  in the order of A, B, F, Bprime
2478 **
2479 ** Returns          None
2480 **
2481 *******************************************************************************/
nfa_ee_get_tech_route(uint8_t power_state,uint8_t * p_handles)2482 void nfa_ee_get_tech_route(uint8_t power_state, uint8_t* p_handles) {
2483   int xx, yy;
2484   tNFA_EE_ECB* p_cb;
2485   uint8_t tech_mask_list[NFA_EE_MAX_TECH_ROUTE] = {
2486       NFA_TECHNOLOGY_MASK_A, NFA_TECHNOLOGY_MASK_B, NFA_TECHNOLOGY_MASK_F,
2487       NFA_TECHNOLOGY_MASK_B_PRIME};
2488 
2489   DLOG_IF(INFO, nfc_debug_enabled) << StringPrintf("%d", power_state);
2490 
2491   for (xx = 0; xx < NFA_EE_MAX_TECH_ROUTE; xx++) {
2492     p_handles[xx] = NFC_DH_ID;
2493     if (nfa_ee_cb.cur_ee > 0) p_cb = &nfa_ee_cb.ecb[nfa_ee_cb.cur_ee - 1];
2494     for (yy = 0; yy < nfa_ee_cb.cur_ee; yy++, p_cb--) {
2495       if (p_cb->ee_status == NFC_NFCEE_STATUS_ACTIVE) {
2496         switch (power_state) {
2497           case NFA_EE_PWR_STATE_ON:
2498             if (p_cb->tech_switch_on & tech_mask_list[xx])
2499               p_handles[xx] = p_cb->nfcee_id;
2500             break;
2501           case NFA_EE_PWR_STATE_SWITCH_OFF:
2502             if (p_cb->tech_switch_off & tech_mask_list[xx])
2503               p_handles[xx] = p_cb->nfcee_id;
2504             break;
2505           case NFA_EE_PWR_STATE_BATT_OFF:
2506             if (p_cb->tech_battery_off & tech_mask_list[xx])
2507               p_handles[xx] = p_cb->nfcee_id;
2508             break;
2509         }
2510       }
2511     }
2512   }
2513   DLOG_IF(INFO, nfc_debug_enabled)
2514       << StringPrintf("0x%x, 0x%x, 0x%x, 0x%x", p_handles[0], p_handles[1],
2515                       p_handles[2], p_handles[3]);
2516 }
2517 
2518 /*******************************************************************************
2519 **
2520 ** Function         nfa_ee_check_set_routing
2521 **
2522 ** Description      If the new size exceeds the capacity of next block,
2523 **                  send the routing command now and reset the related
2524 **                  parameters.
2525 **
2526 ** Returns          void
2527 **
2528 *******************************************************************************/
nfa_ee_check_set_routing(uint16_t new_size,int * p_max_len,uint8_t * p,int * p_cur_offset)2529 void nfa_ee_check_set_routing(uint16_t new_size, int* p_max_len, uint8_t* p,
2530                               int* p_cur_offset) {
2531   uint8_t max_tlv = (uint8_t)((*p_max_len > NFA_EE_ROUT_MAX_TLV_SIZE)
2532                                   ? NFA_EE_ROUT_MAX_TLV_SIZE
2533                                   : *p_max_len);
2534 
2535   if (new_size + *p_cur_offset > max_tlv) {
2536     if (NFC_SetRouting(true, *p, *p_cur_offset, p + 1) == NFA_STATUS_OK) {
2537       nfa_ee_cb.wait_rsp++;
2538     }
2539     /* after the routing command is sent, re-use the same buffer to send the
2540      * next routing command.
2541      * reset the related parameters */
2542     if (*p_max_len > *p_cur_offset)
2543       *p_max_len -= *p_cur_offset; /* the max is reduced */
2544     else
2545       *p_max_len = 0;
2546     *p_cur_offset = 0; /* nothing is in queue any more */
2547     *p = 0;            /* num_tlv=0 */
2548   }
2549 }
2550 
2551 /*******************************************************************************
2552 **
2553 ** Function         nfa_ee_route_add_one_ecb_order
2554 **
2555 ** Description      Add the routing entries for NFCEE/DH in order defined
2556 **
2557 ** Returns          NFA_STATUS_OK, if ok to continue
2558 **
2559 *******************************************************************************/
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)2560 void nfa_ee_route_add_one_ecb_by_route_order(tNFA_EE_ECB* p_cb, int rout_type,
2561                                              int* p_max_len, bool more,
2562                                              uint8_t* ps, int* p_cur_offset) {
2563   /* use the first byte of the buffer (ps) to keep the num_tlv */
2564   uint8_t num_tlv = *ps;
2565   DLOG_IF(INFO, nfc_debug_enabled) << StringPrintf(
2566       "%s - max_len:%d, cur_offset:%d, more:%d, num_tlv:%d,rout_type:- %d",
2567       __func__, *p_max_len, *p_cur_offset, more, num_tlv, rout_type);
2568   uint8_t* pp = ps + 1 + *p_cur_offset;
2569   uint8_t* p = pp;
2570   uint16_t tlv_size = (uint8_t)*p_cur_offset;
2571 
2572   switch (rout_type) {
2573     case NCI_ROUTE_ORDER_TECHNOLOGY: {
2574       nfa_ee_check_set_routing(p_cb->size_mask_tech, p_max_len, ps,
2575                                p_cur_offset);
2576       pp = ps + 1 + *p_cur_offset;
2577       p = pp;
2578       nfa_ee_add_tech_route_to_ecb(p_cb, pp, p, ps, p_cur_offset);
2579     } break;
2580 
2581     case NCI_ROUTE_ORDER_PROTOCOL: {
2582       nfa_ee_check_set_routing(p_cb->size_mask_proto, p_max_len, ps,
2583                                p_cur_offset);
2584       pp = ps + 1 + *p_cur_offset;
2585       p = pp;
2586       nfa_ee_add_proto_route_to_ecb(p_cb, pp, p, ps, p_cur_offset);
2587     } break;
2588     case NCI_ROUTE_ORDER_AID: {
2589       nfa_ee_add_aid_route_to_ecb(p_cb, pp, p, ps, p_cur_offset, p_max_len);
2590     } break;
2591     case NCI_ROUTE_ORDER_SYS_CODE: {
2592       nfa_ee_add_sys_code_route_to_ecb(p_cb, pp, p, ps, p_cur_offset,
2593                                        p_max_len);
2594     } break;
2595     default: {
2596       DLOG_IF(INFO, nfc_debug_enabled)
2597           << StringPrintf("%s -  Route type - NA:- %d", __func__, rout_type);
2598     }
2599   }
2600 
2601   /* update the total number of entries */
2602   num_tlv = *ps;
2603 
2604   tlv_size = nfa_ee_total_lmrt_size();
2605   if (tlv_size) {
2606     nfa_ee_cb.ee_cfged |= nfa_ee_ecb_to_mask(p_cb);
2607   }
2608   if (p_cb->ecb_flags & NFA_EE_ECB_FLAGS_ROUTING) {
2609     nfa_ee_cb.ee_cfg_sts |= NFA_EE_STS_CHANGED_ROUTING;
2610   }
2611   DLOG_IF(INFO, nfc_debug_enabled) << StringPrintf(
2612       "ee_cfg_sts:0x%02x lmrt_size:%d", nfa_ee_cb.ee_cfg_sts, tlv_size);
2613 
2614   if (more == false) {
2615     /* last entry. update routing table now */
2616     if (nfa_ee_cb.ee_cfg_sts & NFA_EE_STS_CHANGED_ROUTING) {
2617       if (tlv_size) {
2618         nfa_ee_cb.ee_cfg_sts |= NFA_EE_STS_PREV_ROUTING;
2619       } else {
2620         nfa_ee_cb.ee_cfg_sts &= ~NFA_EE_STS_PREV_ROUTING;
2621       }
2622       DLOG_IF(INFO, nfc_debug_enabled)
2623           << StringPrintf("%s : set routing num_tlv:%d tlv_size:%d", __func__,
2624                           num_tlv, tlv_size);
2625       if (NFC_SetRouting(more, num_tlv, (uint8_t)(*p_cur_offset), ps + 1) ==
2626           NFA_STATUS_OK) {
2627         nfa_ee_cb.wait_rsp++;
2628       }
2629     } else if (nfa_ee_cb.ee_cfg_sts & NFA_EE_STS_PREV_ROUTING) {
2630       if (tlv_size == 0) {
2631         nfa_ee_cb.ee_cfg_sts &= ~NFA_EE_STS_PREV_ROUTING;
2632         /* indicated routing is configured to NFCC */
2633         nfa_ee_cb.ee_cfg_sts |= NFA_EE_STS_CHANGED_ROUTING;
2634         if (NFC_SetRouting(more, 0, 0, ps + 1) == NFA_STATUS_OK) {
2635           nfa_ee_cb.wait_rsp++;
2636         }
2637       }
2638     }
2639   }
2640 }
2641 
2642 /*******************************************************************************
2643 **
2644 ** Function         nfa_ee_need_recfg
2645 **
2646 ** Description      Check if any API function to configure the routing table or
2647 **                  VS is called since last update
2648 **
2649 **                  The algorithm for the NFCEE configuration handling is as
2650 **                  follows:
2651 **
2652 **                  Each NFCEE_ID/DH has its own control block - tNFA_EE_ECB
2653 **                  Each control block uses ecb_flags to keep track if an API
2654 **                  that changes routing/VS is invoked. This ecb_flags is
2655 **                  cleared at the end of nfa_ee_update_rout().
2656 **
2657 **                  nfa_ee_cb.ee_cfged is the bitmask of the control blocks with
2658 **                  routing/VS configuration and NFA_EE_CFGED_UPDATE_NOW.
2659 **                  nfa_ee_cb.ee_cfged is cleared and re-calculated at the end
2660 **                  of nfa_ee_update_rout().
2661 **
2662 **                  nfa_ee_cb.ee_cfg_sts is used to check is any status is
2663 **                  changed and the associated command is issued to NFCC.
2664 **                  nfa_ee_cb.ee_cfg_sts is AND with NFA_EE_STS_PREV at the end
2665 **                  of nfa_ee_update_rout() to clear the NFA_EE_STS_CHANGED bits
2666 **                  (except NFA_EE_STS_CHANGED_CANNED_VS is cleared in
2667 **                  nfa_ee_vs_cback)
2668 **
2669 ** Returns          TRUE if any configuration is changed
2670 **
2671 *******************************************************************************/
nfa_ee_need_recfg(void)2672 static bool nfa_ee_need_recfg(void) {
2673   bool needed = false;
2674   uint32_t xx;
2675   tNFA_EE_ECB* p_cb;
2676   uint8_t mask;
2677 
2678   DLOG_IF(INFO, nfc_debug_enabled)
2679       << StringPrintf("ee_cfged: 0x%02x ee_cfg_sts: 0x%02x", nfa_ee_cb.ee_cfged,
2680                       nfa_ee_cb.ee_cfg_sts);
2681   /* if no routing/vs is configured, do not need to send the info to NFCC */
2682   if (nfa_ee_cb.ee_cfged || nfa_ee_cb.ee_cfg_sts) {
2683     if (nfa_ee_cb.ee_cfg_sts & NFA_EE_STS_CHANGED) {
2684       needed = true;
2685     } else {
2686       p_cb = &nfa_ee_cb.ecb[NFA_EE_CB_4_DH];
2687       mask = 1 << NFA_EE_CB_4_DH;
2688       for (xx = 0; xx <= nfa_ee_cb.cur_ee; xx++) {
2689         DLOG_IF(INFO, nfc_debug_enabled) << StringPrintf(
2690             "%d: ecb_flags  : 0x%02x, mask: 0x%02x", xx, p_cb->ecb_flags, mask);
2691         if ((p_cb->ecb_flags) && (nfa_ee_cb.ee_cfged & mask)) {
2692           needed = true;
2693           break;
2694         }
2695         p_cb = &nfa_ee_cb.ecb[xx];
2696         mask = 1 << xx;
2697       }
2698     }
2699   }
2700 
2701   return needed;
2702 }
2703 
2704 /*******************************************************************************
2705 **
2706 ** Function         nfa_ee_rout_timeout
2707 **
2708 ** Description      Anytime VS or routing entries are changed,
2709 **                  a 1 second timer is started. This function is called when
2710 **                  the timer expires or NFA_EeUpdateNow() is called.
2711 **
2712 ** Returns          void
2713 **
2714 *******************************************************************************/
nfa_ee_rout_timeout(tNFA_EE_MSG * p_data)2715 void nfa_ee_rout_timeout(__attribute__((unused)) tNFA_EE_MSG* p_data) {
2716   uint8_t ee_cfged = nfa_ee_cb.ee_cfged;
2717 
2718   DLOG_IF(INFO, nfc_debug_enabled) << __func__;
2719   if (nfa_ee_need_recfg()) {
2720     /* discovery is not started */
2721     nfa_ee_update_rout();
2722   }
2723 
2724   if (nfa_ee_cb.wait_rsp) nfa_ee_cb.ee_wait_evt |= NFA_EE_WAIT_UPDATE_RSP;
2725   if (ee_cfged & NFA_EE_CFGED_UPDATE_NOW) {
2726     /* need to report NFA_EE_UPDATED_EVT when done updating NFCC */
2727     nfa_ee_cb.ee_wait_evt |= NFA_EE_WAIT_UPDATE;
2728     if (!nfa_ee_cb.wait_rsp) {
2729       nfa_ee_report_update_evt();
2730     }
2731   }
2732 }
2733 
2734 /*******************************************************************************
2735 **
2736 ** Function         nfa_ee_discv_timeout
2737 **
2738 ** Description
2739 **
2740 **
2741 **
2742 ** Returns          void
2743 **
2744 *******************************************************************************/
nfa_ee_discv_timeout(tNFA_EE_MSG * p_data)2745 void nfa_ee_discv_timeout(__attribute__((unused)) tNFA_EE_MSG* p_data) {
2746   if (NFA_GetNCIVersion() != NCI_VERSION_2_0) NFC_NfceeDiscover(false);
2747   if (nfa_ee_cb.p_enable_cback)
2748     (*nfa_ee_cb.p_enable_cback)(NFA_EE_DISC_STS_OFF);
2749 }
2750 
2751 /*******************************************************************************
2752 **
2753 ** Function         nfa_ee_lmrt_to_nfcc
2754 **
2755 ** Description      This function would set the listen mode routing table
2756 **                  to NFCC.
2757 **
2758 ** Returns          void
2759 **
2760 *******************************************************************************/
nfa_ee_lmrt_to_nfcc(tNFA_EE_MSG * p_data)2761 void nfa_ee_lmrt_to_nfcc(__attribute__((unused)) tNFA_EE_MSG* p_data) {
2762   int xx;
2763   tNFA_EE_ECB* p_cb;
2764   uint8_t* p = nullptr;
2765   bool more = true;
2766   bool check = true;
2767   uint8_t last_active = NFA_EE_INVALID;
2768   int max_len;
2769   tNFA_STATUS status = NFA_STATUS_FAILED;
2770   int cur_offset;
2771   uint8_t max_tlv;
2772 
2773   /* update routing table: DH and the activated NFCEEs */
2774   max_len = (NFC_GetLmrtSize() > NFA_EE_ROUT_BUF_SIZE) ? NFC_GetLmrtSize()
2775                                                        : NFA_EE_ROUT_BUF_SIZE;
2776   p = (uint8_t*)GKI_getbuf(max_len);
2777   if (p == nullptr) {
2778     LOG(ERROR) << StringPrintf("no buffer to send routing info.");
2779     tNFA_EE_CBACK_DATA nfa_ee_cback_data;
2780     nfa_ee_cback_data.status = status;
2781     nfa_ee_report_event(nullptr, NFA_EE_NO_MEM_ERR_EVT, &nfa_ee_cback_data);
2782     return;
2783   }
2784 
2785   /* find the last active NFCEE. */
2786   if (nfa_ee_cb.cur_ee > 0) p_cb = &nfa_ee_cb.ecb[nfa_ee_cb.cur_ee - 1];
2787 
2788   for (xx = 0; xx < nfa_ee_cb.cur_ee; xx++, p_cb--) {
2789     if (p_cb->ee_status == NFC_NFCEE_STATUS_ACTIVE) {
2790       if (last_active == NFA_EE_INVALID) {
2791         last_active = p_cb->nfcee_id;
2792         DLOG_IF(INFO, nfc_debug_enabled)
2793             << StringPrintf("last_active: 0x%x", last_active);
2794       }
2795     }
2796   }
2797   if (last_active == NFA_EE_INVALID) {
2798     check = false;
2799   }
2800 
2801   max_tlv =
2802       (uint8_t)((max_len > NFA_EE_ROUT_MAX_TLV_SIZE) ? NFA_EE_ROUT_MAX_TLV_SIZE
2803                                                      : max_len);
2804   cur_offset = 0;
2805   /* use the first byte of the buffer (p) to keep the num_tlv */
2806   *p = 0;
2807   for (int rt = NCI_ROUTE_ORDER_AID; rt <= NCI_ROUTE_ORDER_TECHNOLOGY; rt++) {
2808     /* add the routing entries for NFCEEs */
2809     p_cb = &nfa_ee_cb.ecb[0];
2810 
2811     for (xx = 0; (xx < nfa_ee_cb.cur_ee) && check; xx++, p_cb++) {
2812       if (p_cb->ee_status == NFC_NFCEE_STATUS_ACTIVE) {
2813         DLOG_IF(INFO, nfc_debug_enabled)
2814             << StringPrintf("%s --add the routing for NFCEEs!!", __func__);
2815         nfa_ee_route_add_one_ecb_by_route_order(p_cb, rt, &max_len, more, p,
2816                                                 &cur_offset);
2817       }
2818     }
2819     if (rt == NCI_ROUTE_ORDER_TECHNOLOGY) more = false;
2820     /* add the routing entries for DH */
2821     DLOG_IF(INFO, nfc_debug_enabled)
2822         << StringPrintf("%s --add the routing for DH!!", __func__);
2823     nfa_ee_route_add_one_ecb_by_route_order(&nfa_ee_cb.ecb[NFA_EE_CB_4_DH], rt,
2824                                             &max_len, more, p, &cur_offset);
2825   }
2826 
2827   GKI_freebuf(p);
2828 }
2829 
2830 /*******************************************************************************
2831 **
2832 ** Function         nfa_ee_update_rout
2833 **
2834 ** Description      This function would set the VS and listen mode routing table
2835 **                  to NFCC.
2836 **
2837 ** Returns          void
2838 **
2839 *******************************************************************************/
nfa_ee_update_rout(void)2840 void nfa_ee_update_rout(void) {
2841   int xx;
2842   tNFA_EE_ECB* p_cb;
2843   uint8_t mask;
2844   tNFA_EE_MSG nfa_ee_msg;
2845 
2846   DLOG_IF(INFO, nfc_debug_enabled) << StringPrintf(
2847       "nfa_ee_update_rout ee_cfg_sts:0x%02x", nfa_ee_cb.ee_cfg_sts);
2848 
2849   /* use action function to send routing and VS configuration to NFCC */
2850   nfa_ee_msg.hdr.event = NFA_EE_CFG_TO_NFCC_EVT;
2851   nfa_ee_evt_hdlr(&nfa_ee_msg.hdr);
2852 
2853   /* all configuration is updated to NFCC, clear the status mask */
2854   nfa_ee_cb.ee_cfg_sts &= NFA_EE_STS_PREV;
2855   nfa_ee_cb.ee_cfged = 0;
2856   p_cb = &nfa_ee_cb.ecb[0];
2857   for (xx = 0; xx < NFA_EE_NUM_ECBS; xx++, p_cb++) {
2858     p_cb->ecb_flags = 0;
2859     mask = (1 << xx);
2860     if (p_cb->tech_switch_on | p_cb->tech_switch_off | p_cb->tech_battery_off |
2861         p_cb->proto_switch_on | p_cb->proto_switch_off |
2862         p_cb->proto_battery_off | p_cb->aid_entries |
2863         p_cb->sys_code_cfg_entries) {
2864       /* this entry has routing configuration. mark it configured */
2865       nfa_ee_cb.ee_cfged |= mask;
2866     }
2867   }
2868   DLOG_IF(INFO, nfc_debug_enabled)
2869       << StringPrintf("nfa_ee_update_rout ee_cfg_sts:0x%02x ee_cfged:0x%02x",
2870                       nfa_ee_cb.ee_cfg_sts, nfa_ee_cb.ee_cfged);
2871 }
2872