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