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