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