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