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