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