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 #include "nfa_api.h"
26 #include "nfa_dm_int.h"
27 #include "nfa_ee_int.h"
28 #include "nfa_sys.h"
29 #include "nfa_sys_int.h"
30 #include "nfc_api.h"
31 
32 /* the de-bounce timer:
33  * The NFA-EE API functions are called to set the routing and VS configuration.
34  * When this timer expires, the configuration is sent to NFCC all at once.
35  * This is the timeout value for the de-bounce timer. */
36 #ifndef NFA_EE_ROUT_TIMEOUT_VAL
37 #define NFA_EE_ROUT_TIMEOUT_VAL 1000
38 #endif
39 
40 #define NFA_EE_ROUT_BUF_SIZE 540
41 #define NFA_EE_ROUT_MAX_TLV_SIZE 0xFD
42 
43 /* the following 2 tables convert the technology mask in API and control block
44  * to the command for NFCC */
45 #define NFA_EE_NUM_TECH 3
46 const uint8_t nfa_ee_tech_mask_list[NFA_EE_NUM_TECH] = {
47     NFA_TECHNOLOGY_MASK_A, NFA_TECHNOLOGY_MASK_B, NFA_TECHNOLOGY_MASK_F};
48 
49 const uint8_t nfa_ee_tech_list[NFA_EE_NUM_TECH] = {
50     NFC_RF_TECHNOLOGY_A, NFC_RF_TECHNOLOGY_B, NFC_RF_TECHNOLOGY_F};
51 
52 /* the following 2 tables convert the protocol mask in API and control block to
53  * the command for NFCC */
54 #define NFA_EE_NUM_PROTO 5
55 const uint8_t nfa_ee_proto_mask_list[NFA_EE_NUM_PROTO] = {
56     NFA_PROTOCOL_MASK_T1T, NFA_PROTOCOL_MASK_T2T, NFA_PROTOCOL_MASK_T3T,
57     NFA_PROTOCOL_MASK_ISO_DEP, NFA_PROTOCOL_MASK_NFC_DEP};
58 
59 const uint8_t nfa_ee_proto_list[NFA_EE_NUM_PROTO] = {
60     NFC_PROTOCOL_T1T, NFC_PROTOCOL_T2T, NFC_PROTOCOL_T3T, NFC_PROTOCOL_ISO_DEP,
61     NFC_PROTOCOL_NFC_DEP};
62 
63 static void nfa_ee_report_discover_req_evt(void);
64 static void nfa_ee_build_discover_req_evt(tNFA_EE_DISCOVER_REQ* p_evt_data);
65 /*******************************************************************************
66 **
67 ** Function         nfa_ee_trace_aid
68 **
69 ** Description      trace AID
70 **
71 ** Returns          void
72 **
73 *******************************************************************************/
nfa_ee_trace_aid(char * p_str,uint8_t id,uint8_t aid_len,uint8_t * p)74 static void nfa_ee_trace_aid(char* p_str, uint8_t id, uint8_t aid_len,
75                              uint8_t* p) {
76   int len = aid_len;
77   int xx, yy = 0;
78   char buff[100];
79 
80   buff[0] = 0;
81   if (aid_len > NFA_MAX_AID_LEN) {
82     NFA_TRACE_ERROR2("aid_len: %d exceeds max(%d)", aid_len, NFA_MAX_AID_LEN);
83     len = NFA_MAX_AID_LEN;
84   }
85   for (xx = 0; xx < len; xx++) {
86     yy += sprintf(&buff[yy], "%02x ", *p);
87     p++;
88   }
89   NFA_TRACE_DEBUG4("%s id:0x%x len=%d aid:%s", p_str, id, aid_len, buff);
90 }
91 
92 /*******************************************************************************
93 **
94 ** Function         nfa_ee_update_route_size
95 **
96 ** Description      Update the size required for technology and protocol routing
97 **                  of the given NFCEE ID.
98 **
99 ** Returns          void
100 **
101 *******************************************************************************/
nfa_ee_update_route_size(tNFA_EE_ECB * p_cb)102 static void nfa_ee_update_route_size(tNFA_EE_ECB* p_cb) {
103   int xx;
104   uint8_t power_cfg = 0;
105 
106   p_cb->size_mask = 0;
107   /* add the Technology based routing */
108   for (xx = 0; xx < NFA_EE_NUM_TECH; xx++) {
109     power_cfg = 0;
110     if (p_cb->tech_switch_on & nfa_ee_tech_mask_list[xx])
111       power_cfg |= NCI_ROUTE_PWR_STATE_ON;
112     if (p_cb->tech_switch_off & nfa_ee_tech_mask_list[xx])
113       power_cfg |= NCI_ROUTE_PWR_STATE_SWITCH_OFF;
114     if (p_cb->tech_battery_off & nfa_ee_tech_mask_list[xx])
115       power_cfg |= NCI_ROUTE_PWR_STATE_BATT_OFF;
116     if (power_cfg) {
117       /* 5 = 1 (tag) + 1 (len) + 1(nfcee_id) + 1(power cfg) + 1 (techonogy) */
118       p_cb->size_mask += 5;
119     }
120   }
121 
122   /* add the Protocol based routing */
123   for (xx = 0; xx < NFA_EE_NUM_PROTO; xx++) {
124     power_cfg = 0;
125     if (p_cb->proto_switch_on & nfa_ee_proto_mask_list[xx])
126       power_cfg |= NCI_ROUTE_PWR_STATE_ON;
127     if (p_cb->proto_switch_off & nfa_ee_proto_mask_list[xx])
128       power_cfg |= NCI_ROUTE_PWR_STATE_SWITCH_OFF;
129     if (p_cb->proto_battery_off & nfa_ee_proto_mask_list[xx])
130       power_cfg |= NCI_ROUTE_PWR_STATE_BATT_OFF;
131     if (power_cfg) {
132       /* 5 = 1 (tag) + 1 (len) + 1(nfcee_id) + 1(power cfg) + 1 (protocol) */
133       p_cb->size_mask += 5;
134     }
135   }
136   NFA_TRACE_DEBUG2("nfa_ee_update_route_size nfcee_id:0x%x size_mask:%d",
137                    p_cb->nfcee_id, p_cb->size_mask);
138 }
139 
140 /*******************************************************************************
141 **
142 ** Function         nfa_ee_update_route_aid_size
143 **
144 ** Description      Update the size required for AID routing
145 **                  of the given NFCEE ID.
146 **
147 ** Returns          void
148 **
149 *******************************************************************************/
nfa_ee_update_route_aid_size(tNFA_EE_ECB * p_cb)150 static void nfa_ee_update_route_aid_size(tNFA_EE_ECB* p_cb) {
151   uint8_t *pa, len;
152   int start_offset;
153   int xx;
154 
155   p_cb->size_aid = 0;
156   if (p_cb->aid_entries) {
157     start_offset = 0;
158     for (xx = 0; xx < p_cb->aid_entries; xx++) {
159       /* add one AID entry */
160       if (p_cb->aid_rt_info[xx] & NFA_EE_AE_ROUTE) {
161         pa = &p_cb->aid_cfg[start_offset];
162         pa++;        /* EMV tag */
163         len = *pa++; /* aid_len */
164         /* 4 = 1 (tag) + 1 (len) + 1(nfcee_id) + 1(power cfg) */
165         p_cb->size_aid += 4;
166         p_cb->size_aid += len;
167       }
168       start_offset += p_cb->aid_len[xx];
169     }
170   }
171   NFA_TRACE_DEBUG2("nfa_ee_update_route_aid_size nfcee_id:0x%x size_aid:%d",
172                    p_cb->nfcee_id, p_cb->size_aid);
173 }
174 
175 /*******************************************************************************
176 **
177 ** Function         nfa_ee_total_lmrt_size
178 **
179 ** Description      the total listen mode routing table size
180 **
181 ** Returns          uint16_t
182 **
183 *******************************************************************************/
nfa_ee_total_lmrt_size(void)184 static uint16_t nfa_ee_total_lmrt_size(void) {
185   int xx;
186   uint16_t lmrt_size = 0;
187   tNFA_EE_ECB* p_cb;
188 
189   p_cb = &nfa_ee_cb.ecb[NFA_EE_CB_4_DH];
190   lmrt_size += p_cb->size_mask;
191   lmrt_size += p_cb->size_aid;
192   p_cb = &nfa_ee_cb.ecb[nfa_ee_cb.cur_ee - 1];
193   for (xx = 0; xx < nfa_ee_cb.cur_ee; xx++, p_cb--) {
194     if (p_cb->ee_status == NFC_NFCEE_STATUS_ACTIVE) {
195       lmrt_size += p_cb->size_mask;
196       lmrt_size += p_cb->size_aid;
197     }
198   }
199   NFA_TRACE_DEBUG1("nfa_ee_total_lmrt_size size:%d", lmrt_size);
200   return lmrt_size;
201 }
202 
203 /*******************************************************************************
204 **
205 ** Function         nfa_ee_conn_cback
206 **
207 ** Description      process connection callback event from stack
208 **
209 ** Returns          void
210 **
211 *******************************************************************************/
nfa_ee_conn_cback(uint8_t conn_id,tNFC_CONN_EVT event,tNFC_CONN * p_data)212 static void nfa_ee_conn_cback(uint8_t conn_id, tNFC_CONN_EVT event,
213                               tNFC_CONN* p_data) {
214   NFC_HDR* p_msg;
215   tNFA_EE_NCI_CONN cbk;
216 
217   NFA_TRACE_DEBUG2("nfa_ee_conn_cback: conn_id: %d, event=0x%02x", conn_id,
218                    event);
219 
220   cbk.hdr.event = NFA_EE_NCI_CONN_EVT;
221   if (event == NFC_DATA_CEVT) {
222     /* Treat data event specially to avoid potential memory leak */
223     cbk.hdr.event = NFA_EE_NCI_DATA_EVT;
224   }
225   cbk.conn_id = conn_id;
226   cbk.event = event;
227   cbk.p_data = p_data;
228   p_msg = (NFC_HDR*)&cbk;
229 
230   nfa_ee_evt_hdlr(p_msg);
231 }
232 
233 /*******************************************************************************
234 **
235 ** Function         nfa_ee_find_total_aid_len
236 **
237 ** Description      Find the total len in aid_cfg from start_entry to the last
238 **
239 ** Returns          void
240 **
241 *******************************************************************************/
nfa_ee_find_total_aid_len(tNFA_EE_ECB * p_cb,int start_entry)242 int nfa_ee_find_total_aid_len(tNFA_EE_ECB* p_cb, int start_entry) {
243   int len = 0, xx;
244 
245   if (p_cb->aid_entries > start_entry) {
246     for (xx = start_entry; xx < p_cb->aid_entries; xx++) {
247       len += p_cb->aid_len[xx];
248     }
249   }
250   return len;
251 }
252 
253 /*******************************************************************************
254 **
255 ** Function         nfa_ee_find_aid_offset
256 **
257 ** Description      Given the AID, find the associated tNFA_EE_ECB and the
258 **                  offset in aid_cfg[]. *p_entry is the index.
259 **
260 ** Returns          void
261 **
262 *******************************************************************************/
nfa_ee_find_aid_offset(uint8_t aid_len,uint8_t * p_aid,int * p_offset,int * p_entry)263 tNFA_EE_ECB* nfa_ee_find_aid_offset(uint8_t aid_len, uint8_t* p_aid,
264                                     int* p_offset, int* p_entry) {
265   int xx, yy, aid_len_offset, offset;
266   tNFA_EE_ECB *p_ret = NULL, *p_ecb;
267 
268   p_ecb = &nfa_ee_cb.ecb[NFA_EE_CB_4_DH];
269   aid_len_offset = 1; /* skip the tag */
270   for (yy = 0; yy < nfa_ee_cb.cur_ee; yy++, p_ecb++) {
271     if (p_ecb->aid_entries) {
272       offset = 0;
273       for (xx = 0; xx < p_ecb->aid_entries; xx++) {
274         if ((p_ecb->aid_cfg[offset + aid_len_offset] == aid_len) &&
275             (memcmp(&p_ecb->aid_cfg[offset + aid_len_offset + 1], p_aid,
276                     aid_len) == 0)) {
277           p_ret = p_ecb;
278           if (p_offset) *p_offset = offset;
279           if (p_entry) *p_entry = xx;
280           break;
281         }
282         offset += p_ecb->aid_len[xx];
283       }
284 
285       if (p_ret) {
286         /* found the entry already */
287         break;
288       }
289     }
290     p_ecb = &nfa_ee_cb.ecb[yy];
291   }
292 
293   return p_ret;
294 }
295 
296 /*******************************************************************************
297 **
298 ** Function         nfa_ee_report_event
299 **
300 ** Description      report the given event to the callback
301 **
302 ** Returns          void
303 **
304 *******************************************************************************/
nfa_ee_report_event(tNFA_EE_CBACK * p_cback,tNFA_EE_EVT event,tNFA_EE_CBACK_DATA * p_data)305 void nfa_ee_report_event(tNFA_EE_CBACK* p_cback, tNFA_EE_EVT event,
306                          tNFA_EE_CBACK_DATA* p_data) {
307   int xx;
308 
309   /* use the given callback, if not NULL */
310   if (p_cback) {
311     (*p_cback)(event, p_data);
312     return;
313   }
314   /* if the given is NULL, report to all registered ones */
315   for (xx = 0; xx < NFA_EE_MAX_CBACKS; xx++) {
316     if (nfa_ee_cb.p_ee_cback[xx] != NULL) {
317       (*nfa_ee_cb.p_ee_cback[xx])(event, p_data);
318     }
319   }
320 }
321 /*******************************************************************************
322 **
323 ** Function         nfa_ee_start_timer
324 **
325 ** Description      start the de-bounce timer
326 **
327 ** Returns          void
328 **
329 *******************************************************************************/
nfa_ee_start_timer(void)330 void nfa_ee_start_timer(void) {
331   if (nfa_dm_is_active())
332     nfa_sys_start_timer(&nfa_ee_cb.timer, NFA_EE_ROUT_TIMEOUT_EVT,
333                         NFA_EE_ROUT_TIMEOUT_VAL);
334 }
335 
336 /*******************************************************************************
337 **
338 ** Function         nfa_ee_api_discover
339 **
340 ** Description      process discover command from user
341 **
342 ** Returns          void
343 **
344 *******************************************************************************/
nfa_ee_api_discover(tNFA_EE_MSG * p_data)345 void nfa_ee_api_discover(tNFA_EE_MSG* p_data) {
346   tNFA_EE_CBACK* p_cback = p_data->ee_discover.p_cback;
347   tNFA_EE_CBACK_DATA evt_data = {0};
348 
349   NFA_TRACE_DEBUG1("nfa_ee_api_discover() in_use:%d",
350                    nfa_ee_cb.discv_timer.in_use);
351   if (nfa_ee_cb.discv_timer.in_use) {
352     nfa_sys_stop_timer(&nfa_ee_cb.discv_timer);
353     NFC_NfceeDiscover(false);
354   }
355   if (nfa_ee_cb.p_ee_disc_cback == NULL &&
356       NFC_NfceeDiscover(true) == NFC_STATUS_OK) {
357     nfa_ee_cb.p_ee_disc_cback = p_cback;
358   } else {
359     evt_data.status = NFA_STATUS_FAILED;
360     nfa_ee_report_event(p_cback, NFA_EE_DISCOVER_EVT, &evt_data);
361   }
362 }
363 
364 /*******************************************************************************
365 **
366 ** Function         nfa_ee_api_register
367 **
368 ** Description      process register command from user
369 **
370 ** Returns          void
371 **
372 *******************************************************************************/
nfa_ee_api_register(tNFA_EE_MSG * p_data)373 void nfa_ee_api_register(tNFA_EE_MSG* p_data) {
374   int xx;
375   tNFA_EE_CBACK* p_cback = p_data->ee_register.p_cback;
376   tNFA_EE_CBACK_DATA evt_data = {0};
377   bool found = false;
378 
379   evt_data.ee_register = NFA_STATUS_FAILED;
380   /* loop through all entries to see if there's a matching callback */
381   for (xx = 0; xx < NFA_EE_MAX_CBACKS; xx++) {
382     if (nfa_ee_cb.p_ee_cback[xx] == p_cback) {
383       evt_data.ee_register = NFA_STATUS_OK;
384       found = true;
385       break;
386     }
387   }
388 
389   /* If no matching callback, allocated an entry */
390   if (!found) {
391     for (xx = 0; xx < NFA_EE_MAX_CBACKS; xx++) {
392       if (nfa_ee_cb.p_ee_cback[xx] == NULL) {
393         nfa_ee_cb.p_ee_cback[xx] = p_cback;
394         evt_data.ee_register = NFA_STATUS_OK;
395         break;
396       }
397     }
398   }
399   /* This callback is verified (not NULL) in NFA_EeRegister() */
400   (*p_cback)(NFA_EE_REGISTER_EVT, &evt_data);
401 
402   /* report NFCEE Discovery Request collected during booting up */
403   nfa_ee_build_discover_req_evt(&evt_data.discover_req);
404   (*p_cback)(NFA_EE_DISCOVER_REQ_EVT, &evt_data);
405 }
406 
407 /*******************************************************************************
408 **
409 ** Function         nfa_ee_api_deregister
410 **
411 ** Description      process de-register command from user
412 **
413 ** Returns          void
414 **
415 *******************************************************************************/
nfa_ee_api_deregister(tNFA_EE_MSG * p_data)416 void nfa_ee_api_deregister(tNFA_EE_MSG* p_data) {
417   tNFA_EE_CBACK* p_cback = NULL;
418   int index = p_data->deregister.index;
419   tNFA_EE_CBACK_DATA evt_data = {0};
420 
421   NFA_TRACE_DEBUG0("nfa_ee_api_deregister");
422   p_cback = nfa_ee_cb.p_ee_cback[index];
423   nfa_ee_cb.p_ee_cback[index] = NULL;
424   if (p_cback) (*p_cback)(NFA_EE_DEREGISTER_EVT, &evt_data);
425 }
426 
427 /*******************************************************************************
428 **
429 ** Function         nfa_ee_api_mode_set
430 **
431 ** Description      process mode set command from user
432 **
433 ** Returns          void
434 **
435 *******************************************************************************/
nfa_ee_api_mode_set(tNFA_EE_MSG * p_data)436 void nfa_ee_api_mode_set(tNFA_EE_MSG* p_data) {
437   tNFA_EE_ECB* p_cb = p_data->cfg_hdr.p_cb;
438 
439   NFA_TRACE_DEBUG2("nfa_ee_api_mode_set() handle:0x%02x mode:%d",
440                    p_cb->nfcee_id, p_data->mode_set.mode);
441   NFC_NfceeModeSet(p_cb->nfcee_id, p_data->mode_set.mode);
442   /* set the NFA_EE_STATUS_PENDING bit to indicate the status is not exactly
443    * active */
444   if (p_data->mode_set.mode == NFC_MODE_ACTIVATE)
445     p_cb->ee_status = NFA_EE_STATUS_PENDING | NFA_EE_STATUS_ACTIVE;
446   else {
447     p_cb->ee_status = NFA_EE_STATUS_INACTIVE;
448     /* DH should release the NCI connection before deactivate the NFCEE */
449     if (p_cb->conn_st == NFA_EE_CONN_ST_CONN) {
450       p_cb->conn_st = NFA_EE_CONN_ST_DISC;
451       NFC_ConnClose(p_cb->conn_id);
452     }
453   }
454   /* report the NFA_EE_MODE_SET_EVT status on the response from NFCC */
455 }
456 
457 /*******************************************************************************
458 **
459 ** Function         nfa_ee_api_set_tech_cfg
460 **
461 ** Description      process set technology routing configuration from user
462 **                  start a 1 second timer. When the timer expires,
463 **                  the configuration collected in control block is sent to NFCC
464 **
465 ** Returns          void
466 **
467 *******************************************************************************/
nfa_ee_api_set_tech_cfg(tNFA_EE_MSG * p_data)468 void nfa_ee_api_set_tech_cfg(tNFA_EE_MSG* p_data) {
469   tNFA_EE_ECB* p_cb = p_data->cfg_hdr.p_cb;
470   tNFA_EE_CBACK_DATA evt_data = {0};
471   tNFA_TECHNOLOGY_MASK old_tech_switch_on = p_cb->tech_switch_on;
472   tNFA_TECHNOLOGY_MASK old_tech_switch_off = p_cb->tech_switch_off;
473   tNFA_TECHNOLOGY_MASK old_tech_battery_off = p_cb->tech_battery_off;
474   uint8_t old_size_mask = p_cb->size_mask;
475 
476   if ((p_cb->tech_switch_on == p_data->set_tech.technologies_switch_on) &&
477       (p_cb->tech_switch_off == p_data->set_tech.technologies_switch_off) &&
478       (p_cb->tech_battery_off == p_data->set_tech.technologies_battery_off)) {
479     /* nothing to change */
480     evt_data.status = NFA_STATUS_OK;
481     nfa_ee_report_event(p_cb->p_ee_cback, NFA_EE_SET_TECH_CFG_EVT, &evt_data);
482     return;
483   }
484 
485   p_cb->tech_switch_on = p_data->set_tech.technologies_switch_on;
486   p_cb->tech_switch_off = p_data->set_tech.technologies_switch_off;
487   p_cb->tech_battery_off = p_data->set_tech.technologies_battery_off;
488   nfa_ee_update_route_size(p_cb);
489   if (nfa_ee_total_lmrt_size() > NFC_GetLmrtSize()) {
490     NFA_TRACE_ERROR0("nfa_ee_api_set_tech_cfg Exceed LMRT size");
491     evt_data.status = NFA_STATUS_BUFFER_FULL;
492     p_cb->tech_switch_on = old_tech_switch_on;
493     p_cb->tech_switch_off = old_tech_switch_off;
494     p_cb->tech_battery_off = old_tech_battery_off;
495     p_cb->size_mask = old_size_mask;
496   } else {
497     p_cb->ecb_flags |= NFA_EE_ECB_FLAGS_TECH;
498     if (p_cb->tech_switch_on | p_cb->tech_switch_off | p_cb->tech_battery_off) {
499       /* if any technology in any power mode is configured, mark this entry as
500        * configured */
501       nfa_ee_cb.ee_cfged |= nfa_ee_ecb_to_mask(p_cb);
502     }
503     nfa_ee_start_timer();
504   }
505   nfa_ee_report_event(p_cb->p_ee_cback, NFA_EE_SET_TECH_CFG_EVT, &evt_data);
506 }
507 
508 /*******************************************************************************
509 **
510 ** Function         nfa_ee_api_set_proto_cfg
511 **
512 ** Description      process set protocol routing configuration from user
513 **                  start a 1 second timer. When the timer expires,
514 **                  the configuration collected in control block is sent to NFCC
515 **
516 ** Returns          void
517 **
518 *******************************************************************************/
nfa_ee_api_set_proto_cfg(tNFA_EE_MSG * p_data)519 void nfa_ee_api_set_proto_cfg(tNFA_EE_MSG* p_data) {
520   tNFA_EE_ECB* p_cb = p_data->cfg_hdr.p_cb;
521   tNFA_EE_CBACK_DATA evt_data = {0};
522   tNFA_PROTOCOL_MASK old_proto_switch_on = p_cb->proto_switch_on;
523   tNFA_PROTOCOL_MASK old_proto_switch_off = p_cb->proto_switch_off;
524   tNFA_PROTOCOL_MASK old_proto_battery_off = p_cb->proto_battery_off;
525   uint8_t old_size_mask = p_cb->size_mask;
526 
527   if ((p_cb->proto_switch_on == p_data->set_proto.protocols_switch_on) &&
528       (p_cb->proto_switch_off == p_data->set_proto.protocols_switch_off) &&
529       (p_cb->proto_battery_off == p_data->set_proto.protocols_battery_off)) {
530     /* nothing to change */
531     evt_data.status = NFA_STATUS_OK;
532     nfa_ee_report_event(p_cb->p_ee_cback, NFA_EE_SET_PROTO_CFG_EVT, &evt_data);
533     return;
534   }
535 
536   p_cb->proto_switch_on = p_data->set_proto.protocols_switch_on;
537   p_cb->proto_switch_off = p_data->set_proto.protocols_switch_off;
538   p_cb->proto_battery_off = p_data->set_proto.protocols_battery_off;
539   nfa_ee_update_route_size(p_cb);
540   if (nfa_ee_total_lmrt_size() > NFC_GetLmrtSize()) {
541     NFA_TRACE_ERROR0("nfa_ee_api_set_proto_cfg Exceed LMRT size");
542     evt_data.status = NFA_STATUS_BUFFER_FULL;
543     p_cb->proto_switch_on = old_proto_switch_on;
544     p_cb->proto_switch_off = old_proto_switch_off;
545     p_cb->proto_battery_off = old_proto_battery_off;
546     p_cb->size_mask = old_size_mask;
547   } else {
548     p_cb->ecb_flags |= NFA_EE_ECB_FLAGS_PROTO;
549     if (p_cb->proto_switch_on | p_cb->proto_switch_off |
550         p_cb->proto_battery_off) {
551       /* if any protocol in any power mode is configured, mark this entry as
552        * configured */
553       nfa_ee_cb.ee_cfged |= nfa_ee_ecb_to_mask(p_cb);
554     }
555     nfa_ee_start_timer();
556   }
557   nfa_ee_report_event(p_cb->p_ee_cback, NFA_EE_SET_PROTO_CFG_EVT, &evt_data);
558 }
559 
560 /*******************************************************************************
561 **
562 ** Function         nfa_ee_api_add_aid
563 **
564 ** Description      process add an AID routing configuration from user
565 **                  start a 1 second timer. When the timer expires,
566 **                  the configuration collected in control block is sent to NFCC
567 **
568 ** Returns          void
569 **
570 *******************************************************************************/
nfa_ee_api_add_aid(tNFA_EE_MSG * p_data)571 void nfa_ee_api_add_aid(tNFA_EE_MSG* p_data) {
572   tNFA_EE_API_ADD_AID* p_add = &p_data->add_aid;
573   tNFA_EE_ECB* p_cb = p_data->cfg_hdr.p_cb;
574   tNFA_EE_ECB* p_chk_cb;
575   uint8_t *p, *p_start;
576   int len, len_needed;
577   tNFA_EE_CBACK_DATA evt_data = {0};
578   int offset = 0, entry = 0;
579   uint16_t new_size;
580 
581   nfa_ee_trace_aid("nfa_ee_api_add_aid", p_cb->nfcee_id, p_add->aid_len,
582                    p_add->p_aid);
583   p_chk_cb =
584       nfa_ee_find_aid_offset(p_add->aid_len, p_add->p_aid, &offset, &entry);
585   if (p_chk_cb) {
586     NFA_TRACE_DEBUG0(
587         "nfa_ee_api_add_aid The AID entry is already in the database");
588     if (p_chk_cb == p_cb) {
589       p_cb->aid_rt_info[entry] |= NFA_EE_AE_ROUTE;
590       new_size = nfa_ee_total_lmrt_size();
591       if (new_size > NFC_GetLmrtSize()) {
592         NFA_TRACE_ERROR1("Exceed LMRT size:%d (add ROUTE)", new_size);
593         evt_data.status = NFA_STATUS_BUFFER_FULL;
594         p_cb->aid_rt_info[entry] &= ~NFA_EE_AE_ROUTE;
595       } else {
596         p_cb->aid_pwr_cfg[entry] = p_add->power_state;
597       }
598     } else {
599       NFA_TRACE_ERROR1(
600           "The AID entry is already in the database for different NFCEE "
601           "ID:0x%02x",
602           p_chk_cb->nfcee_id);
603       evt_data.status = NFA_STATUS_SEMANTIC_ERROR;
604     }
605   } else {
606     /* Find the total length so far */
607     len = nfa_ee_find_total_aid_len(p_cb, 0);
608 
609     /* make sure the control block has enough room to hold this entry */
610     len_needed = p_add->aid_len + 2; /* tag/len */
611 
612     if ((len_needed + len) > NFA_EE_MAX_AID_CFG_LEN) {
613       NFA_TRACE_ERROR3(
614           "Exceed capacity: (len_needed:%d + len:%d) > "
615           "NFA_EE_MAX_AID_CFG_LEN:%d",
616           len_needed, len, NFA_EE_MAX_AID_CFG_LEN);
617       evt_data.status = NFA_STATUS_BUFFER_FULL;
618     } else if (p_cb->aid_entries < NFA_EE_MAX_AID_ENTRIES) {
619       /* 4 = 1 (tag) + 1 (len) + 1(nfcee_id) + 1(power cfg) */
620       new_size = nfa_ee_total_lmrt_size() + 4 + p_add->aid_len;
621       if (new_size > NFC_GetLmrtSize()) {
622         NFA_TRACE_ERROR1("Exceed LMRT size:%d", new_size);
623         evt_data.status = NFA_STATUS_BUFFER_FULL;
624       } else {
625         /* add AID */
626         p_cb->aid_pwr_cfg[p_cb->aid_entries] = p_add->power_state;
627         p_cb->aid_rt_info[p_cb->aid_entries] = NFA_EE_AE_ROUTE;
628         p = p_cb->aid_cfg + len;
629         p_start = p;
630         *p++ = NFA_EE_AID_CFG_TAG_NAME;
631         *p++ = p_add->aid_len;
632         memcpy(p, p_add->p_aid, p_add->aid_len);
633         p += p_add->aid_len;
634 
635         p_cb->aid_len[p_cb->aid_entries++] = (uint8_t)(p - p_start);
636       }
637     } else {
638       NFA_TRACE_ERROR1("Exceed NFA_EE_MAX_AID_ENTRIES:%d",
639                        NFA_EE_MAX_AID_ENTRIES);
640       evt_data.status = NFA_STATUS_BUFFER_FULL;
641     }
642   }
643 
644   if (evt_data.status == NFA_STATUS_OK) {
645     /* mark AID changed */
646     p_cb->ecb_flags |= NFA_EE_ECB_FLAGS_AID;
647     nfa_ee_cb.ee_cfged |= nfa_ee_ecb_to_mask(p_cb);
648     nfa_ee_update_route_aid_size(p_cb);
649     nfa_ee_start_timer();
650   }
651   NFA_TRACE_DEBUG2("status:%d ee_cfged:0x%02x ", evt_data.status,
652                    nfa_ee_cb.ee_cfged);
653   /* report the status of this operation */
654   nfa_ee_report_event(p_cb->p_ee_cback, NFA_EE_ADD_AID_EVT, &evt_data);
655 }
656 
657 /*******************************************************************************
658 **
659 ** Function         nfa_ee_api_remove_aid
660 **
661 ** Description      process remove an AID routing configuration from user
662 **                  start a 1 second timer. When the timer expires,
663 **                  the configuration collected in control block is sent to NFCC
664 **
665 ** Returns          void
666 **
667 *******************************************************************************/
nfa_ee_api_remove_aid(tNFA_EE_MSG * p_data)668 void nfa_ee_api_remove_aid(tNFA_EE_MSG* p_data) {
669   tNFA_EE_ECB* p_cb;
670   tNFA_EE_CBACK_DATA evt_data = {0};
671   int offset = 0, entry = 0, len;
672   int rest_len;
673   tNFA_EE_CBACK* p_cback = NULL;
674 
675   nfa_ee_trace_aid("nfa_ee_api_remove_aid", 0, p_data->rm_aid.aid_len,
676                    p_data->rm_aid.p_aid);
677   p_cb = nfa_ee_find_aid_offset(p_data->rm_aid.aid_len, p_data->rm_aid.p_aid,
678                                 &offset, &entry);
679   if (p_cb && p_cb->aid_entries) {
680     NFA_TRACE_DEBUG2("aid_rt_info[%d]: 0x%02x", entry,
681                      p_cb->aid_rt_info[entry]);
682     /* mark routing and VS changed */
683     if (p_cb->aid_rt_info[entry] & NFA_EE_AE_ROUTE)
684       p_cb->ecb_flags |= NFA_EE_ECB_FLAGS_AID;
685 
686     if (p_cb->aid_rt_info[entry] & NFA_EE_AE_VS)
687       p_cb->ecb_flags |= NFA_EE_ECB_FLAGS_VS;
688 
689     /* remove the aid */
690     if ((entry + 1) < p_cb->aid_entries) {
691       /* not the last entry, move the aid entries in control block */
692       /* Find the total len from the next entry to the last one */
693       rest_len = nfa_ee_find_total_aid_len(p_cb, entry + 1);
694 
695       len = p_cb->aid_len[entry];
696       NFA_TRACE_DEBUG2("nfa_ee_api_remove_aid len:%d, rest_len:%d", len,
697                        rest_len);
698       GKI_shiftup(&p_cb->aid_cfg[offset], &p_cb->aid_cfg[offset + len],
699                   rest_len);
700       rest_len = p_cb->aid_entries - entry;
701       GKI_shiftup(&p_cb->aid_len[entry], &p_cb->aid_len[entry + 1], rest_len);
702       GKI_shiftup(&p_cb->aid_pwr_cfg[entry], &p_cb->aid_pwr_cfg[entry + 1],
703                   rest_len);
704       GKI_shiftup(&p_cb->aid_rt_info[entry], &p_cb->aid_rt_info[entry + 1],
705                   rest_len);
706     }
707     /* else the last entry, just reduce the aid_entries by 1 */
708     p_cb->aid_entries--;
709     nfa_ee_cb.ee_cfged |= nfa_ee_ecb_to_mask(p_cb);
710     nfa_ee_update_route_aid_size(p_cb);
711     nfa_ee_start_timer();
712     /* report NFA_EE_REMOVE_AID_EVT to the callback associated the NFCEE */
713     p_cback = p_cb->p_ee_cback;
714   } else {
715     NFA_TRACE_ERROR0(
716         "nfa_ee_api_remove_aid The AID entry is not in the database");
717     evt_data.status = NFA_STATUS_INVALID_PARAM;
718   }
719   nfa_ee_report_event(p_cback, NFA_EE_REMOVE_AID_EVT, &evt_data);
720 }
721 
722 /*******************************************************************************
723 **
724 ** Function         nfa_ee_api_lmrt_size
725 **
726 ** Description      Reports the remaining size in the Listen Mode Routing Table
727 **
728 ** Returns          void
729 **
730 *******************************************************************************/
nfa_ee_api_lmrt_size(tNFA_EE_MSG * p_data)731 void nfa_ee_api_lmrt_size(tNFA_EE_MSG* p_data) {
732   tNFA_EE_CBACK_DATA evt_data = {0};
733   uint16_t total_size = NFC_GetLmrtSize();
734 
735   evt_data.size = total_size - nfa_ee_total_lmrt_size();
736   NFA_TRACE_DEBUG2("nfa_ee_api_lmrt_size total size:%d remaining size:%d",
737                    total_size, evt_data.size);
738 
739   nfa_ee_report_event(NULL, NFA_EE_REMAINING_SIZE_EVT, &evt_data);
740 }
741 
742 /*******************************************************************************
743 **
744 ** Function         nfa_ee_api_update_now
745 **
746 ** Description      Initiates connection creation process to the given NFCEE
747 **
748 ** Returns          void
749 **
750 *******************************************************************************/
nfa_ee_api_update_now(tNFA_EE_MSG * p_data)751 void nfa_ee_api_update_now(tNFA_EE_MSG* p_data) {
752   tNFA_EE_CBACK_DATA evt_data;
753 
754   if (nfa_ee_cb.ee_wait_evt & NFA_EE_WAIT_UPDATE_ALL) {
755     NFA_TRACE_ERROR2(
756         "nfa_ee_api_update_now still waiting for update complete "
757         "ee_wait_evt:0x%x wait_rsp:%d",
758         nfa_ee_cb.ee_wait_evt, nfa_ee_cb.wait_rsp);
759     evt_data.status = NFA_STATUS_SEMANTIC_ERROR;
760     nfa_ee_report_event(NULL, NFA_EE_UPDATED_EVT, &evt_data);
761     return;
762   }
763   nfa_sys_stop_timer(&nfa_ee_cb.timer);
764   nfa_ee_cb.ee_cfged |= NFA_EE_CFGED_UPDATE_NOW;
765   nfa_ee_rout_timeout(p_data);
766 }
767 
768 /*******************************************************************************
769 **
770 ** Function         nfa_ee_api_connect
771 **
772 ** Description      Initiates connection creation process to the given NFCEE
773 **
774 ** Returns          void
775 **
776 *******************************************************************************/
nfa_ee_api_connect(tNFA_EE_MSG * p_data)777 void nfa_ee_api_connect(tNFA_EE_MSG* p_data) {
778   tNFA_EE_ECB* p_cb = p_data->connect.p_cb;
779   int xx;
780   tNFA_EE_CBACK_DATA evt_data = {0};
781 
782   evt_data.connect.status = NFA_STATUS_FAILED;
783   if (p_cb->conn_st == NFA_EE_CONN_ST_NONE) {
784     for (xx = 0; xx < p_cb->num_interface; xx++) {
785       if (p_data->connect.ee_interface == p_cb->ee_interface[xx]) {
786         p_cb->p_ee_cback = p_data->connect.p_cback;
787         p_cb->conn_st = NFA_EE_CONN_ST_WAIT;
788         p_cb->use_interface = p_data->connect.ee_interface;
789         evt_data.connect.status =
790             NFC_ConnCreate(NCI_DEST_TYPE_NFCEE, p_data->connect.nfcee_id,
791                            p_data->connect.ee_interface, nfa_ee_conn_cback);
792         /* report the NFA_EE_CONNECT_EVT status on the response from NFCC */
793         break;
794       }
795     }
796   }
797 
798   if (evt_data.connect.status != NCI_STATUS_OK) {
799     evt_data.connect.ee_handle =
800         (tNFA_HANDLE)p_data->connect.nfcee_id | NFA_HANDLE_GROUP_EE;
801     evt_data.connect.status = NFA_STATUS_INVALID_PARAM;
802     evt_data.connect.ee_interface = p_data->connect.ee_interface;
803     nfa_ee_report_event(p_data->connect.p_cback, NFA_EE_CONNECT_EVT, &evt_data);
804   }
805 }
806 
807 /*******************************************************************************
808 **
809 ** Function         nfa_ee_api_send_data
810 **
811 ** Description      Send the given data packet to the given NFCEE
812 **
813 ** Returns          void
814 **
815 *******************************************************************************/
nfa_ee_api_send_data(tNFA_EE_MSG * p_data)816 void nfa_ee_api_send_data(tNFA_EE_MSG* p_data) {
817   tNFA_EE_ECB* p_cb = p_data->send_data.p_cb;
818   NFC_HDR* p_pkt;
819   uint16_t size = NCI_MSG_OFFSET_SIZE + NCI_DATA_HDR_SIZE +
820                   p_data->send_data.data_len + NFC_HDR_SIZE;
821   uint8_t* p;
822   tNFA_STATUS status = NFA_STATUS_FAILED;
823 
824   if (p_cb->conn_st == NFA_EE_CONN_ST_CONN) {
825     p_pkt = (NFC_HDR*)GKI_getbuf(size);
826     if (p_pkt) {
827       p_pkt->offset = NCI_MSG_OFFSET_SIZE + NCI_DATA_HDR_SIZE;
828       p_pkt->len = p_data->send_data.data_len;
829       p = (uint8_t*)(p_pkt + 1) + p_pkt->offset;
830       memcpy(p, p_data->send_data.p_data, p_pkt->len);
831       NFC_SendData(p_cb->conn_id, p_pkt);
832     } else {
833       nfa_ee_report_event(p_cb->p_ee_cback, NFA_EE_NO_MEM_ERR_EVT,
834                           (tNFA_EE_CBACK_DATA*)&status);
835     }
836   } else {
837     nfa_ee_report_event(p_cb->p_ee_cback, NFA_EE_NO_CB_ERR_EVT,
838                         (tNFA_EE_CBACK_DATA*)&status);
839   }
840 }
841 
842 /*******************************************************************************
843 **
844 ** Function         nfa_ee_api_disconnect
845 **
846 ** Description      Initiates closing of the connection to the given NFCEE
847 **
848 ** Returns          void
849 **
850 *******************************************************************************/
nfa_ee_api_disconnect(tNFA_EE_MSG * p_data)851 void nfa_ee_api_disconnect(tNFA_EE_MSG* p_data) {
852   tNFA_EE_ECB* p_cb = p_data->disconnect.p_cb;
853   tNFA_EE_CBACK_DATA evt_data = {0};
854 
855   if (p_cb->conn_st == NFA_EE_CONN_ST_CONN) {
856     p_cb->conn_st = NFA_EE_CONN_ST_DISC;
857     NFC_ConnClose(p_cb->conn_id);
858   }
859   evt_data.handle = (tNFA_HANDLE)p_cb->nfcee_id | NFA_HANDLE_GROUP_EE;
860   nfa_ee_report_event(p_cb->p_ee_cback, NFA_EE_DISCONNECT_EVT, &evt_data);
861 }
862 
863 /*******************************************************************************
864 **
865 ** Function         nfa_ee_report_disc_done
866 **
867 ** Description      Process the callback for NFCEE discovery response
868 **
869 ** Returns          void
870 **
871 *******************************************************************************/
nfa_ee_report_disc_done(bool notify_enable_done)872 void nfa_ee_report_disc_done(bool notify_enable_done) {
873   tNFA_EE_CBACK* p_cback;
874   tNFA_EE_CBACK_DATA evt_data = {0};
875 
876   NFA_TRACE_DEBUG3(
877       "nfa_ee_report_disc_done() em_state:%d num_ee_expecting:%d "
878       "notify_enable_done:%d",
879       nfa_ee_cb.em_state, nfa_ee_cb.num_ee_expecting, notify_enable_done);
880   if (nfa_ee_cb.num_ee_expecting == 0) {
881     if (notify_enable_done) {
882       if (nfa_ee_cb.em_state == NFA_EE_EM_STATE_INIT_DONE) {
883         nfa_sys_cback_notify_enable_complete(NFA_ID_EE);
884         if (nfa_ee_cb.p_enable_cback)
885           (*nfa_ee_cb.p_enable_cback)(NFA_EE_DISC_STS_ON);
886       } else if ((nfa_ee_cb.em_state == NFA_EE_EM_STATE_RESTORING) &&
887                  (nfa_ee_cb.ee_flags & NFA_EE_FLAG_NOTIFY_HCI)) {
888         nfa_ee_cb.ee_flags &= ~NFA_EE_FLAG_NOTIFY_HCI;
889         if (nfa_ee_cb.p_enable_cback)
890           (*nfa_ee_cb.p_enable_cback)(NFA_EE_DISC_STS_ON);
891       }
892     }
893 
894     if (nfa_ee_cb.p_ee_disc_cback) {
895       /* notify API callback */
896       p_cback = nfa_ee_cb.p_ee_disc_cback;
897       nfa_ee_cb.p_ee_disc_cback = NULL;
898       evt_data.status = NFA_STATUS_OK;
899       evt_data.ee_discover.num_ee = NFA_EE_MAX_EE_SUPPORTED;
900       NFA_EeGetInfo(&evt_data.ee_discover.num_ee, evt_data.ee_discover.ee_info);
901       nfa_ee_report_event(p_cback, NFA_EE_DISCOVER_EVT, &evt_data);
902     }
903   }
904 }
905 
906 /*******************************************************************************
907 **
908 ** Function         nfa_ee_restore_ntf_done
909 **
910 ** Description      check if any ee_status still has NFA_EE_STATUS_PENDING bit
911 **
912 ** Returns          TRUE, if all NFA_EE_STATUS_PENDING bits are removed
913 **
914 *******************************************************************************/
nfa_ee_restore_ntf_done(void)915 bool nfa_ee_restore_ntf_done(void) {
916   tNFA_EE_ECB* p_cb;
917   bool is_done = true;
918   int xx;
919 
920   p_cb = nfa_ee_cb.ecb;
921   for (xx = 0; xx < nfa_ee_cb.cur_ee; xx++, p_cb++) {
922     if ((p_cb->nfcee_id != NFA_EE_INVALID) &&
923         (p_cb->ee_old_status & NFA_EE_STATUS_RESTORING)) {
924       is_done = false;
925       break;
926     }
927   }
928   return is_done;
929 }
930 
931 /*******************************************************************************
932 **
933 ** Function         nfa_ee_remove_pending
934 **
935 ** Description      check if any ee_status still has NFA_EE_STATUS_RESTORING bit
936 **
937 ** Returns          TRUE, if all NFA_EE_STATUS_RESTORING bits are removed
938 **
939 *******************************************************************************/
nfa_ee_remove_pending(void)940 static void nfa_ee_remove_pending(void) {
941   tNFA_EE_ECB* p_cb;
942   tNFA_EE_ECB *p_cb_n, *p_cb_end;
943   int xx, num_removed = 0;
944   int first_removed = NFA_EE_MAX_EE_SUPPORTED;
945 
946   p_cb = nfa_ee_cb.ecb;
947   for (xx = 0; xx < nfa_ee_cb.cur_ee; xx++, p_cb++) {
948     if ((p_cb->nfcee_id != NFA_EE_INVALID) &&
949         (p_cb->ee_status & NFA_EE_STATUS_RESTORING)) {
950       p_cb->nfcee_id = NFA_EE_INVALID;
951       num_removed++;
952       if (first_removed == NFA_EE_MAX_EE_SUPPORTED) first_removed = xx;
953     }
954   }
955 
956   NFA_TRACE_DEBUG3(
957       "nfa_ee_remove_pending() cur_ee:%d, num_removed:%d first_removed:%d",
958       nfa_ee_cb.cur_ee, num_removed, first_removed);
959   if (num_removed && (first_removed != (nfa_ee_cb.cur_ee - num_removed))) {
960     /* if the removes ECB entried are not at the end, move the entries up */
961     p_cb_end = &nfa_ee_cb.ecb[nfa_ee_cb.cur_ee - 1];
962     p_cb = &nfa_ee_cb.ecb[first_removed];
963     for (p_cb_n = p_cb + 1; p_cb_n <= p_cb_end;) {
964       while ((p_cb_n->nfcee_id == NFA_EE_INVALID) && (p_cb_n <= p_cb_end)) {
965         p_cb_n++;
966       }
967 
968       if (p_cb_n <= p_cb_end) {
969         memcpy(p_cb, p_cb_n, sizeof(tNFA_EE_ECB));
970         p_cb_n->nfcee_id = NFA_EE_INVALID;
971       }
972       p_cb++;
973       p_cb_n++;
974     }
975   }
976   nfa_ee_cb.cur_ee -= (uint8_t)num_removed;
977 }
978 
979 /*******************************************************************************
980 **
981 ** Function         nfa_ee_nci_disc_rsp
982 **
983 ** Description      Process the callback for NFCEE discovery response
984 **
985 ** Returns          void
986 **
987 *******************************************************************************/
nfa_ee_nci_disc_rsp(tNFA_EE_MSG * p_data)988 void nfa_ee_nci_disc_rsp(tNFA_EE_MSG* p_data) {
989   tNFC_NFCEE_DISCOVER_REVT* p_evt = p_data->disc_rsp.p_data;
990   tNFA_EE_ECB* p_cb;
991   uint8_t xx;
992   uint8_t num_nfcee = p_evt->num_nfcee;
993   bool notify_enable_done = false;
994 
995   NFA_TRACE_DEBUG3("nfa_ee_nci_disc_rsp() em_state:%d cur_ee:%d, num_nfcee:%d",
996                    nfa_ee_cb.em_state, nfa_ee_cb.cur_ee, num_nfcee);
997   switch (nfa_ee_cb.em_state) {
998     case NFA_EE_EM_STATE_INIT:
999       nfa_ee_cb.cur_ee = 0;
1000       nfa_ee_cb.num_ee_expecting = 0;
1001       if (num_nfcee == 0) {
1002         nfa_ee_cb.em_state = NFA_EE_EM_STATE_INIT_DONE;
1003         notify_enable_done = true;
1004         if (p_evt->status != NFC_STATUS_OK) {
1005           nfa_sys_stop_timer(&nfa_ee_cb.discv_timer);
1006         }
1007       }
1008       break;
1009 
1010     case NFA_EE_EM_STATE_INIT_DONE:
1011       if (num_nfcee) {
1012         /* if this is initiated by api function,
1013          * check if the number of NFCEE expected is more than what's currently
1014          * in CB */
1015         if (num_nfcee > NFA_EE_MAX_EE_SUPPORTED)
1016           num_nfcee = NFA_EE_MAX_EE_SUPPORTED;
1017         if (nfa_ee_cb.cur_ee < num_nfcee) {
1018           p_cb = &nfa_ee_cb.ecb[nfa_ee_cb.cur_ee];
1019           for (xx = nfa_ee_cb.cur_ee; xx < num_nfcee; xx++, p_cb++) {
1020             /* mark the new entries as a new one */
1021             p_cb->nfcee_id = NFA_EE_INVALID;
1022           }
1023         }
1024         nfa_ee_cb.cur_ee = num_nfcee;
1025       }
1026       break;
1027 
1028     case NFA_EE_EM_STATE_RESTORING:
1029       if (num_nfcee == 0) {
1030         nfa_ee_cb.em_state = NFA_EE_EM_STATE_INIT_DONE;
1031         nfa_ee_remove_pending();
1032         nfa_ee_check_restore_complete();
1033         if (p_evt->status != NFC_STATUS_OK) {
1034           nfa_sys_stop_timer(&nfa_ee_cb.discv_timer);
1035         }
1036       }
1037       break;
1038   }
1039 
1040   if (p_evt->status == NFC_STATUS_OK) {
1041     nfa_ee_cb.num_ee_expecting = p_evt->num_nfcee;
1042     if (nfa_ee_cb.num_ee_expecting > NFA_EE_MAX_EE_SUPPORTED) {
1043       NFA_TRACE_ERROR2("NFA-EE num_ee_expecting:%d > max:%d",
1044                        nfa_ee_cb.num_ee_expecting, NFA_EE_MAX_EE_SUPPORTED);
1045     }
1046   }
1047   nfa_ee_report_disc_done(notify_enable_done);
1048   NFA_TRACE_DEBUG3(
1049       "nfa_ee_nci_disc_rsp() em_state:%d cur_ee:%d num_ee_expecting:%d",
1050       nfa_ee_cb.em_state, nfa_ee_cb.cur_ee, nfa_ee_cb.num_ee_expecting);
1051 }
1052 
1053 /*******************************************************************************
1054 **
1055 ** Function         nfa_ee_nci_disc_ntf
1056 **
1057 ** Description      Process the callback for NFCEE discovery notification
1058 **
1059 ** Returns          void
1060 **
1061 *******************************************************************************/
nfa_ee_nci_disc_ntf(tNFA_EE_MSG * p_data)1062 void nfa_ee_nci_disc_ntf(tNFA_EE_MSG* p_data) {
1063   tNFC_NFCEE_INFO_REVT* p_ee = p_data->disc_ntf.p_data;
1064   tNFA_EE_ECB* p_cb = NULL;
1065   bool notify_enable_done = false;
1066   bool notify_new_ee = false;
1067   tNFA_EE_CBACK_DATA evt_data = {0};
1068   tNFA_EE_INFO* p_info;
1069   tNFA_EE_EM_STATE new_em_state = NFA_EE_EM_STATE_MAX;
1070 
1071   NFA_TRACE_DEBUG4(
1072       "nfa_ee_nci_disc_ntf() em_state:%d ee_flags:0x%x cur_ee:%d "
1073       "num_ee_expecting:%d",
1074       nfa_ee_cb.em_state, nfa_ee_cb.ee_flags, nfa_ee_cb.cur_ee,
1075       nfa_ee_cb.num_ee_expecting);
1076   if (nfa_ee_cb.num_ee_expecting) {
1077     nfa_ee_cb.num_ee_expecting--;
1078     if ((nfa_ee_cb.num_ee_expecting == 0) &&
1079         (nfa_ee_cb.p_ee_disc_cback != NULL)) {
1080       /* Discovery triggered by API function */
1081       NFC_NfceeDiscover(false);
1082     }
1083   }
1084   switch (nfa_ee_cb.em_state) {
1085     case NFA_EE_EM_STATE_INIT:
1086       if (nfa_ee_cb.cur_ee < NFA_EE_MAX_EE_SUPPORTED) {
1087         /* the cb can collect up to NFA_EE_MAX_EE_SUPPORTED ee_info */
1088         p_cb = &nfa_ee_cb.ecb[nfa_ee_cb.cur_ee++];
1089       }
1090 
1091       if (nfa_ee_cb.num_ee_expecting == 0) {
1092         /* notify init_done callback */
1093         nfa_ee_cb.em_state = NFA_EE_EM_STATE_INIT_DONE;
1094         notify_enable_done = true;
1095       }
1096       break;
1097 
1098     case NFA_EE_EM_STATE_INIT_DONE:
1099       p_cb = nfa_ee_find_ecb(p_ee->nfcee_id);
1100       if (p_cb == NULL) {
1101         /* the NFCEE ID is not in the last NFCEE discovery
1102          * maybe it's a new one */
1103         p_cb = nfa_ee_find_ecb(NFA_EE_INVALID);
1104         if (p_cb) {
1105           nfa_ee_cb.cur_ee++;
1106           notify_new_ee = true;
1107         }
1108       } else if (p_cb->ecb_flags & NFA_EE_ECB_FLAGS_ORDER) {
1109         nfa_ee_cb.cur_ee++;
1110         notify_new_ee = true;
1111       } else {
1112         NFA_TRACE_DEBUG3("cur_ee:%d ecb_flags=0x%02x  ee_status=0x%x",
1113                          nfa_ee_cb.cur_ee, p_cb->ecb_flags, p_cb->ee_status);
1114       }
1115       break;
1116 
1117     case NFA_EE_EM_STATE_RESTORING:
1118       p_cb = nfa_ee_find_ecb(p_ee->nfcee_id);
1119       if (p_cb == NULL) {
1120         /* the NFCEE ID is not in the last NFCEE discovery
1121          * maybe it's a new one */
1122         p_cb = nfa_ee_find_ecb(NFA_EE_INVALID);
1123         if (p_cb) {
1124           nfa_ee_cb.cur_ee++;
1125           notify_new_ee = true;
1126         }
1127       }
1128       if (nfa_ee_cb.num_ee_expecting == 0) {
1129         /* notify init_done callback */
1130         notify_enable_done = true;
1131         if (nfa_ee_restore_ntf_done()) {
1132           new_em_state = NFA_EE_EM_STATE_INIT_DONE;
1133         }
1134       }
1135       break;
1136   }
1137   NFA_TRACE_DEBUG1("nfa_ee_nci_disc_ntf cur_ee:%d", nfa_ee_cb.cur_ee);
1138 
1139   if (p_cb) {
1140     p_cb->nfcee_id = p_ee->nfcee_id;
1141     p_cb->ee_status = p_ee->ee_status;
1142     p_cb->num_interface = p_ee->num_interface;
1143     memcpy(p_cb->ee_interface, p_ee->ee_interface, p_ee->num_interface);
1144     p_cb->num_tlvs = p_ee->num_tlvs;
1145     memcpy(p_cb->ee_tlv, p_ee->ee_tlv, p_ee->num_tlvs * sizeof(tNFA_EE_TLV));
1146 
1147     if (nfa_ee_cb.em_state == NFA_EE_EM_STATE_RESTORING) {
1148       /* NCI spec says: An NFCEE_DISCOVER_NTF that contains a Protocol type of
1149        * "HCI Access"
1150        * SHALL NOT contain any other additional Protocol
1151        * i.e. check only first supported NFCEE interface is HCI access */
1152       /* NFA_HCI module handles restoring configurations for HCI access */
1153       if (p_cb->ee_interface[0] != NFC_NFCEE_INTERFACE_HCI_ACCESS) {
1154         if ((nfa_ee_cb.ee_flags & NFA_EE_FLAG_WAIT_HCI) == 0) {
1155           nfa_ee_restore_one_ecb(p_cb);
1156         }
1157         /* else wait for NFA-HCI module to restore the HCI network information
1158          * before enabling the NFCEE */
1159       }
1160     }
1161 
1162     if ((nfa_ee_cb.p_ee_disc_cback == NULL) && (notify_new_ee == true)) {
1163       if (nfa_dm_is_active() && (p_cb->ee_status != NFA_EE_STATUS_REMOVED)) {
1164         /* report this NFA_EE_NEW_EE_EVT only after NFA_DM_ENABLE_EVT is
1165          * reported */
1166         p_info = &evt_data.new_ee;
1167         p_info->ee_handle = NFA_HANDLE_GROUP_EE | (tNFA_HANDLE)p_cb->nfcee_id;
1168         p_info->ee_status = p_cb->ee_status;
1169         p_info->num_interface = p_cb->num_interface;
1170         p_info->num_tlvs = p_cb->num_tlvs;
1171         memcpy(p_info->ee_interface, p_cb->ee_interface, p_cb->num_interface);
1172         memcpy(p_info->ee_tlv, p_cb->ee_tlv,
1173                p_cb->num_tlvs * sizeof(tNFA_EE_TLV));
1174         nfa_ee_report_event(NULL, NFA_EE_NEW_EE_EVT, &evt_data);
1175       }
1176     } else
1177       nfa_ee_report_disc_done(notify_enable_done);
1178 
1179     if (p_cb->ecb_flags & NFA_EE_ECB_FLAGS_ORDER) {
1180       NFA_TRACE_DEBUG0("NFA_EE_ECB_FLAGS_ORDER");
1181       p_cb->ecb_flags &= ~NFA_EE_ECB_FLAGS_ORDER;
1182       nfa_ee_report_discover_req_evt();
1183     }
1184   }
1185 
1186   if (new_em_state != NFA_EE_EM_STATE_MAX) {
1187     nfa_ee_cb.em_state = new_em_state;
1188     nfa_ee_check_restore_complete();
1189   }
1190 
1191   if ((nfa_ee_cb.cur_ee == nfa_ee_max_ee_cfg) &&
1192       (nfa_ee_cb.em_state == NFA_EE_EM_STATE_INIT_DONE)) {
1193     if (nfa_ee_cb.discv_timer.in_use) {
1194       nfa_sys_stop_timer(&nfa_ee_cb.discv_timer);
1195       p_data->hdr.event = NFA_EE_DISCV_TIMEOUT_EVT;
1196       nfa_ee_evt_hdlr((NFC_HDR*)p_data);
1197     }
1198   }
1199 }
1200 
1201 /*******************************************************************************
1202 **
1203 ** Function         nfa_ee_check_restore_complete
1204 **
1205 ** Description      Check if restore the NFA-EE related configuration to the
1206 **                  state prior to low power mode is complete.
1207 **                  If complete, notify sys.
1208 **
1209 ** Returns          void
1210 **
1211 *******************************************************************************/
nfa_ee_check_restore_complete(void)1212 void nfa_ee_check_restore_complete(void) {
1213   uint32_t xx;
1214   tNFA_EE_ECB* p_cb;
1215   bool proc_complete = true;
1216 
1217   p_cb = nfa_ee_cb.ecb;
1218   for (xx = 0; xx < nfa_ee_cb.cur_ee; xx++, p_cb++) {
1219     if (p_cb->ecb_flags & NFA_EE_ECB_FLAGS_RESTORE) {
1220       /* NFA_HCI module handles restoring configurations for HCI access.
1221        * ignore the restoring status for HCI Access */
1222       if (p_cb->ee_interface[0] != NFC_NFCEE_INTERFACE_HCI_ACCESS) {
1223         proc_complete = false;
1224         break;
1225       }
1226     }
1227   }
1228 
1229   NFA_TRACE_DEBUG2(
1230       "nfa_ee_check_restore_complete nfa_ee_cb.ee_cfg_sts:0x%02x "
1231       "proc_complete:%d",
1232       nfa_ee_cb.ee_cfg_sts, proc_complete);
1233   if (proc_complete) {
1234     /* update routing table when NFA_EE_ROUT_TIMEOUT_EVT is received */
1235     if (nfa_ee_cb.ee_cfg_sts & NFA_EE_STS_PREV_ROUTING)
1236       nfa_ee_api_update_now(NULL);
1237 
1238     nfa_ee_cb.em_state = NFA_EE_EM_STATE_INIT_DONE;
1239     nfa_sys_cback_notify_nfcc_power_mode_proc_complete(NFA_ID_EE);
1240   }
1241 }
1242 
1243 /*******************************************************************************
1244 **
1245 ** Function         nfa_ee_build_discover_req_evt
1246 **
1247 ** Description      Build NFA_EE_DISCOVER_REQ_EVT for all active NFCEE
1248 **
1249 ** Returns          void
1250 **
1251 *******************************************************************************/
nfa_ee_build_discover_req_evt(tNFA_EE_DISCOVER_REQ * p_evt_data)1252 static void nfa_ee_build_discover_req_evt(tNFA_EE_DISCOVER_REQ* p_evt_data) {
1253   tNFA_EE_ECB* p_cb;
1254   tNFA_EE_DISCOVER_INFO* p_info;
1255   uint8_t xx;
1256 
1257   if (!p_evt_data) return;
1258 
1259   p_evt_data->num_ee = 0;
1260   p_cb = nfa_ee_cb.ecb;
1261   p_info = p_evt_data->ee_disc_info;
1262 
1263   for (xx = 0; xx < nfa_ee_cb.cur_ee; xx++, p_cb++) {
1264     if ((p_cb->ee_status & NFA_EE_STATUS_INT_MASK) ||
1265         (p_cb->ee_status != NFA_EE_STATUS_ACTIVE) ||
1266         ((p_cb->ecb_flags & NFA_EE_ECB_FLAGS_DISC_REQ) == 0)) {
1267       continue;
1268     }
1269     p_info->ee_handle = (tNFA_HANDLE)p_cb->nfcee_id | NFA_HANDLE_GROUP_EE;
1270     p_info->la_protocol = p_cb->la_protocol;
1271     p_info->lb_protocol = p_cb->lb_protocol;
1272     p_info->lf_protocol = p_cb->lf_protocol;
1273     p_info->lbp_protocol = p_cb->lbp_protocol;
1274     p_evt_data->num_ee++;
1275     p_info++;
1276 
1277     NFA_TRACE_DEBUG6(
1278         "[%d] ee_handle:0x%x, listen protocol A:%d, B:%d, F:%d, BP:%d",
1279         p_evt_data->num_ee, p_cb->nfcee_id, p_cb->la_protocol,
1280         p_cb->lb_protocol, p_cb->lf_protocol, p_cb->lbp_protocol);
1281   }
1282 
1283   p_evt_data->status = NFA_STATUS_OK;
1284 }
1285 
1286 /*******************************************************************************
1287 **
1288 ** Function         nfa_ee_report_discover_req_evt
1289 **
1290 ** Description      Report NFA_EE_DISCOVER_REQ_EVT for all active NFCEE
1291 **
1292 ** Returns          void
1293 **
1294 *******************************************************************************/
nfa_ee_report_discover_req_evt(void)1295 static void nfa_ee_report_discover_req_evt(void) {
1296   tNFA_EE_DISCOVER_REQ evt_data;
1297 
1298   if (nfa_ee_cb.p_enable_cback)
1299     (*nfa_ee_cb.p_enable_cback)(NFA_EE_DISC_STS_REQ);
1300 
1301   /* if this is restoring NFCC */
1302   if (!nfa_dm_is_active()) {
1303     NFA_TRACE_DEBUG0("nfa_ee_report_discover_req_evt DM is not active");
1304     return;
1305   }
1306 
1307   nfa_ee_build_discover_req_evt(&evt_data);
1308   nfa_ee_report_event(NULL, NFA_EE_DISCOVER_REQ_EVT,
1309                       (tNFA_EE_CBACK_DATA*)&evt_data);
1310 }
1311 
1312 /*******************************************************************************
1313 **
1314 ** Function         nfa_ee_nci_mode_set_rsp
1315 **
1316 ** Description      Process the result for NFCEE ModeSet response
1317 **
1318 ** Returns          void
1319 **
1320 *******************************************************************************/
nfa_ee_nci_mode_set_rsp(tNFA_EE_MSG * p_data)1321 void nfa_ee_nci_mode_set_rsp(tNFA_EE_MSG* p_data) {
1322   tNFA_EE_ECB* p_cb;
1323   tNFA_EE_MODE_SET mode_set;
1324   tNFC_NFCEE_MODE_SET_REVT* p_rsp = p_data->mode_set_rsp.p_data;
1325 
1326   NFA_TRACE_DEBUG2("nfa_ee_nci_mode_set_rsp() handle:0x%02x mode:%d",
1327                    p_rsp->nfcee_id, p_rsp->mode);
1328   p_cb = nfa_ee_find_ecb(p_rsp->nfcee_id);
1329   if (p_cb == NULL) {
1330     NFA_TRACE_ERROR1(
1331         "nfa_ee_nci_mode_set_rsp() Can not find cb for handle:0x%02x",
1332         p_rsp->nfcee_id);
1333     return;
1334   }
1335 
1336   /* update routing table and vs on mode change */
1337   nfa_ee_start_timer();
1338 
1339   if (p_rsp->status == NFA_STATUS_OK) {
1340     if (p_rsp->mode == NFA_EE_MD_ACTIVATE) {
1341       p_cb->ee_status = NFC_NFCEE_STATUS_ACTIVE;
1342     } else {
1343       if (p_cb->tech_switch_on | p_cb->tech_switch_off |
1344           p_cb->tech_battery_off | p_cb->proto_switch_on |
1345           p_cb->proto_switch_off | p_cb->proto_battery_off |
1346           p_cb->aid_entries) {
1347         /* this NFCEE still has configuration when deactivated. clear the
1348          * configuration */
1349         nfa_ee_cb.ee_cfged &= ~nfa_ee_ecb_to_mask(p_cb);
1350         nfa_ee_cb.ee_cfg_sts |= NFA_EE_STS_CHANGED_ROUTING;
1351         NFA_TRACE_DEBUG0("deactivating/still configured. Force update");
1352       }
1353       p_cb->tech_switch_on = p_cb->tech_switch_off = p_cb->tech_battery_off = 0;
1354       p_cb->proto_switch_on = p_cb->proto_switch_off = p_cb->proto_battery_off =
1355           0;
1356       p_cb->aid_entries = 0;
1357       p_cb->ee_status = NFC_NFCEE_STATUS_INACTIVE;
1358     }
1359   }
1360   NFA_TRACE_DEBUG4("status:%d ecb_flags  :0x%02x ee_cfged:0x%02x ee_status:%d",
1361                    p_rsp->status, p_cb->ecb_flags, nfa_ee_cb.ee_cfged,
1362                    p_cb->ee_status);
1363   if (p_cb->ecb_flags & NFA_EE_ECB_FLAGS_RESTORE) {
1364     if (p_cb->conn_st == NFA_EE_CONN_ST_CONN) {
1365       /* NFA_HCI module handles restoring configurations for HCI access */
1366       if (p_cb->ee_interface[0] != NFC_NFCEE_INTERFACE_HCI_ACCESS) {
1367         NFC_ConnCreate(NCI_DEST_TYPE_NFCEE, p_cb->nfcee_id, p_cb->use_interface,
1368                        nfa_ee_conn_cback);
1369       }
1370     } else {
1371       p_cb->ecb_flags &= ~NFA_EE_ECB_FLAGS_RESTORE;
1372       nfa_ee_check_restore_complete();
1373     }
1374   } else {
1375     mode_set.status = p_rsp->status;
1376     mode_set.ee_handle = (tNFA_HANDLE)p_rsp->nfcee_id | NFA_HANDLE_GROUP_EE;
1377     mode_set.ee_status = p_cb->ee_status;
1378 
1379     nfa_ee_report_event(p_cb->p_ee_cback, NFA_EE_MODE_SET_EVT,
1380                         (tNFA_EE_CBACK_DATA*)&mode_set);
1381 
1382     if ((p_cb->ee_status == NFC_NFCEE_STATUS_INACTIVE) ||
1383         (p_cb->ee_status == NFC_NFCEE_STATUS_ACTIVE)) {
1384       /* Report NFA_EE_DISCOVER_REQ_EVT for all active NFCEE */
1385       nfa_ee_report_discover_req_evt();
1386     }
1387   }
1388 }
1389 
1390 /*******************************************************************************
1391 **
1392 ** Function         nfa_ee_report_update_evt
1393 **
1394 ** Description      Check if need to report NFA_EE_UPDATED_EVT
1395 **
1396 ** Returns          void
1397 **
1398 *******************************************************************************/
nfa_ee_report_update_evt(void)1399 void nfa_ee_report_update_evt(void) {
1400   tNFA_EE_CBACK_DATA evt_data;
1401 
1402   NFA_TRACE_DEBUG2("nfa_ee_report_update_evt ee_wait_evt:0x%x wait_rsp:%d",
1403                    nfa_ee_cb.ee_wait_evt, nfa_ee_cb.wait_rsp);
1404   if (nfa_ee_cb.wait_rsp == 0) {
1405     nfa_ee_cb.ee_wait_evt &= ~NFA_EE_WAIT_UPDATE_RSP;
1406 
1407     if (nfa_ee_cb.ee_wait_evt & NFA_EE_WAIT_UPDATE) {
1408       nfa_ee_cb.ee_wait_evt &= ~NFA_EE_WAIT_UPDATE;
1409       /* finished updating NFCC; report NFA_EE_UPDATED_EVT now */
1410       evt_data.status = NFA_STATUS_OK;
1411       nfa_ee_report_event(NULL, NFA_EE_UPDATED_EVT, &evt_data);
1412     }
1413   }
1414 }
1415 
1416 /*******************************************************************************
1417 **
1418 ** Function         nfa_ee_nci_wait_rsp
1419 **
1420 ** Description      Process the result for NCI response
1421 **
1422 ** Returns          void
1423 **
1424 *******************************************************************************/
nfa_ee_nci_wait_rsp(tNFA_EE_MSG * p_data)1425 void nfa_ee_nci_wait_rsp(tNFA_EE_MSG* p_data) {
1426   tNFA_EE_NCI_WAIT_RSP* p_rsp = &p_data->wait_rsp;
1427 
1428   NFA_TRACE_DEBUG2("nfa_ee_nci_wait_rsp() ee_wait_evt:0x%x wait_rsp:%d",
1429                    nfa_ee_cb.ee_wait_evt, nfa_ee_cb.wait_rsp);
1430   if (nfa_ee_cb.wait_rsp) {
1431     if (p_rsp->opcode == NCI_MSG_RF_SET_ROUTING) nfa_ee_cb.wait_rsp--;
1432   }
1433   nfa_ee_report_update_evt();
1434 }
1435 
1436 /*******************************************************************************
1437 **
1438 ** Function         nfa_ee_nci_conn
1439 **
1440 ** Description      process the connection callback events
1441 **
1442 ** Returns          void
1443 **
1444 *******************************************************************************/
nfa_ee_nci_conn(tNFA_EE_MSG * p_data)1445 void nfa_ee_nci_conn(tNFA_EE_MSG* p_data) {
1446   tNFA_EE_ECB* p_cb;
1447   tNFA_EE_NCI_CONN* p_cbk = &p_data->conn;
1448   tNFC_CONN* p_conn = p_data->conn.p_data;
1449   NFC_HDR* p_pkt = NULL;
1450   tNFA_EE_CBACK_DATA evt_data = {0};
1451   tNFA_EE_EVT event = NFA_EE_INVALID;
1452   tNFA_EE_CBACK* p_cback = NULL;
1453 
1454   if (p_cbk->event == NFC_CONN_CREATE_CEVT) {
1455     p_cb = nfa_ee_find_ecb(p_cbk->p_data->conn_create.id);
1456   } else {
1457     p_cb = nfa_ee_find_ecb_by_conn_id(p_cbk->conn_id);
1458     if (p_cbk->event == NFC_DATA_CEVT) p_pkt = p_conn->data.p_data;
1459   }
1460 
1461   if (p_cb) {
1462     p_cback = p_cb->p_ee_cback;
1463     evt_data.handle = (tNFA_HANDLE)p_cb->nfcee_id | NFA_HANDLE_GROUP_EE;
1464     switch (p_cbk->event) {
1465       case NFC_CONN_CREATE_CEVT:
1466         if (p_conn->conn_create.status == NFC_STATUS_OK) {
1467           p_cb->conn_id = p_cbk->conn_id;
1468           p_cb->conn_st = NFA_EE_CONN_ST_CONN;
1469         } else {
1470           p_cb->conn_st = NFA_EE_CONN_ST_NONE;
1471         }
1472         if (p_cb->ecb_flags & NFA_EE_ECB_FLAGS_RESTORE) {
1473           p_cb->ecb_flags &= ~NFA_EE_ECB_FLAGS_RESTORE;
1474           nfa_ee_check_restore_complete();
1475         } else {
1476           evt_data.connect.status = p_conn->conn_create.status;
1477           evt_data.connect.ee_interface = p_cb->use_interface;
1478           event = NFA_EE_CONNECT_EVT;
1479         }
1480         break;
1481 
1482       case NFC_CONN_CLOSE_CEVT:
1483         if (p_cb->conn_st != NFA_EE_CONN_ST_DISC) event = NFA_EE_DISCONNECT_EVT;
1484         p_cb->conn_st = NFA_EE_CONN_ST_NONE;
1485         p_cb->p_ee_cback = NULL;
1486         p_cb->conn_id = 0;
1487         if (nfa_ee_cb.em_state == NFA_EE_EM_STATE_DISABLING) {
1488           if (nfa_ee_cb.ee_flags & NFA_EE_FLAG_WAIT_DISCONN) {
1489             if (nfa_ee_cb.num_ee_expecting) {
1490               nfa_ee_cb.num_ee_expecting--;
1491             }
1492           }
1493           if (nfa_ee_cb.num_ee_expecting == 0) {
1494             nfa_ee_cb.ee_flags &= ~NFA_EE_FLAG_WAIT_DISCONN;
1495             nfa_ee_check_disable();
1496           }
1497         }
1498         break;
1499 
1500       case NFC_DATA_CEVT:
1501         if (p_cb->conn_st == NFA_EE_CONN_ST_CONN) {
1502           /* report data event only in connected state */
1503           if (p_cb->p_ee_cback && p_pkt) {
1504             evt_data.data.len = p_pkt->len;
1505             evt_data.data.p_buf = (uint8_t*)(p_pkt + 1) + p_pkt->offset;
1506             event = NFA_EE_DATA_EVT;
1507             p_pkt = NULL; /* so this function does not free this GKI buffer */
1508           }
1509         }
1510         break;
1511     }
1512 
1513     if ((event != NFA_EE_INVALID) && (p_cback)) (*p_cback)(event, &evt_data);
1514   }
1515   if (p_pkt) GKI_freebuf(p_pkt);
1516 }
1517 
1518 /*******************************************************************************
1519 **
1520 ** Function         nfa_ee_nci_action_ntf
1521 **
1522 ** Description      process the NFCEE action callback event
1523 **
1524 ** Returns          void
1525 **
1526 *******************************************************************************/
nfa_ee_nci_action_ntf(tNFA_EE_MSG * p_data)1527 void nfa_ee_nci_action_ntf(tNFA_EE_MSG* p_data) {
1528   tNFC_EE_ACTION_REVT* p_cbk = p_data->act.p_data;
1529   tNFA_EE_ACTION evt_data;
1530 
1531   evt_data.ee_handle = (tNFA_HANDLE)p_cbk->nfcee_id | NFA_HANDLE_GROUP_EE;
1532   evt_data.trigger = p_cbk->act_data.trigger;
1533   memcpy(&(evt_data.param), &(p_cbk->act_data.param),
1534          sizeof(tNFA_EE_ACTION_PARAM));
1535   nfa_ee_report_event(NULL, NFA_EE_ACTION_EVT, (tNFA_EE_CBACK_DATA*)&evt_data);
1536 }
1537 
1538 /*******************************************************************************
1539 **
1540 ** Function         nfa_ee_nci_disc_req_ntf
1541 **
1542 ** Description      process the NFCEE discover request callback event
1543 **
1544 ** Returns          void
1545 **
1546 *******************************************************************************/
nfa_ee_nci_disc_req_ntf(tNFA_EE_MSG * p_data)1547 void nfa_ee_nci_disc_req_ntf(tNFA_EE_MSG* p_data) {
1548   tNFC_EE_DISCOVER_REQ_REVT* p_cbk = p_data->disc_req.p_data;
1549   tNFA_HANDLE ee_handle;
1550   tNFA_EE_ECB* p_cb = NULL;
1551   uint8_t report_ntf = 0;
1552   uint8_t xx;
1553 
1554   NFA_TRACE_DEBUG2("nfa_ee_nci_disc_req_ntf () num_info: %d cur_ee:%d",
1555                    p_cbk->num_info, nfa_ee_cb.cur_ee);
1556 
1557   for (xx = 0; xx < p_cbk->num_info; xx++) {
1558     ee_handle = NFA_HANDLE_GROUP_EE | p_cbk->info[xx].nfcee_id;
1559 
1560     p_cb = nfa_ee_find_ecb(p_cbk->info[xx].nfcee_id);
1561     if (!p_cb) {
1562       NFA_TRACE_DEBUG1("Cannot find cb for NFCEE: 0x%x",
1563                        p_cbk->info[xx].nfcee_id);
1564       p_cb = nfa_ee_find_ecb(NFA_EE_INVALID);
1565       if (p_cb) {
1566         p_cb->nfcee_id = p_cbk->info[xx].nfcee_id;
1567         p_cb->ecb_flags |= NFA_EE_ECB_FLAGS_ORDER;
1568       } else {
1569         NFA_TRACE_ERROR1("Cannot allocate cb for NFCEE: 0x%x",
1570                          p_cbk->info[xx].nfcee_id);
1571         continue;
1572       }
1573     } else {
1574       report_ntf |= nfa_ee_ecb_to_mask(p_cb);
1575     }
1576 
1577     p_cb->ecb_flags |= NFA_EE_ECB_FLAGS_DISC_REQ;
1578     if (p_cbk->info[xx].op == NFC_EE_DISC_OP_ADD) {
1579       if (p_cbk->info[xx].tech_n_mode == NFC_DISCOVERY_TYPE_LISTEN_A) {
1580         p_cb->la_protocol = p_cbk->info[xx].protocol;
1581       } else if (p_cbk->info[xx].tech_n_mode == NFC_DISCOVERY_TYPE_LISTEN_B) {
1582         p_cb->lb_protocol = p_cbk->info[xx].protocol;
1583       } else if (p_cbk->info[xx].tech_n_mode == NFC_DISCOVERY_TYPE_LISTEN_F) {
1584         p_cb->lf_protocol = p_cbk->info[xx].protocol;
1585       } else if (p_cbk->info[xx].tech_n_mode ==
1586                  NFC_DISCOVERY_TYPE_LISTEN_B_PRIME) {
1587         p_cb->lbp_protocol = p_cbk->info[xx].protocol;
1588       }
1589       NFA_TRACE_DEBUG6(
1590           "nfcee_id=0x%x ee_status=0x%x ecb_flags=0x%x la_protocol=0x%x "
1591           "la_protocol=0x%x la_protocol=0x%x",
1592           p_cb->nfcee_id, p_cb->ee_status, p_cb->ecb_flags, p_cb->la_protocol,
1593           p_cb->lb_protocol, p_cb->lf_protocol);
1594     } else {
1595       if (p_cbk->info[xx].tech_n_mode == NFC_DISCOVERY_TYPE_LISTEN_A) {
1596         p_cb->la_protocol = 0;
1597       } else if (p_cbk->info[xx].tech_n_mode == NFC_DISCOVERY_TYPE_LISTEN_B) {
1598         p_cb->lb_protocol = 0;
1599       } else if (p_cbk->info[xx].tech_n_mode == NFC_DISCOVERY_TYPE_LISTEN_F) {
1600         p_cb->lf_protocol = 0;
1601       } else if (p_cbk->info[xx].tech_n_mode ==
1602                  NFC_DISCOVERY_TYPE_LISTEN_B_PRIME) {
1603         p_cb->lbp_protocol = 0;
1604       }
1605     }
1606   }
1607 
1608   /* Report NFA_EE_DISCOVER_REQ_EVT for all active NFCEE */
1609   if (report_ntf) nfa_ee_report_discover_req_evt();
1610 }
1611 
1612 /*******************************************************************************
1613 **
1614 ** Function         nfa_ee_is_active
1615 **
1616 ** Description      Check if the given NFCEE is active
1617 **
1618 ** Returns          TRUE if the given NFCEE is active
1619 **
1620 *******************************************************************************/
nfa_ee_is_active(tNFA_HANDLE nfcee_id)1621 bool nfa_ee_is_active(tNFA_HANDLE nfcee_id) {
1622   bool is_active = false;
1623   int xx;
1624   tNFA_EE_ECB* p_cb = nfa_ee_cb.ecb;
1625 
1626   if ((NFA_HANDLE_GROUP_MASK & nfcee_id) == NFA_HANDLE_GROUP_EE)
1627     nfcee_id &= NFA_HANDLE_MASK;
1628 
1629   /* compose output */
1630   for (xx = 0; xx < nfa_ee_cb.cur_ee; xx++, p_cb++) {
1631     if ((tNFA_HANDLE)p_cb->nfcee_id == nfcee_id) {
1632       if (p_cb->ee_status == NFA_EE_STATUS_ACTIVE) {
1633         is_active = true;
1634       }
1635       break;
1636     }
1637   }
1638   return is_active;
1639 }
1640 
1641 /*******************************************************************************
1642 **
1643 ** Function         nfa_ee_get_tech_route
1644 **
1645 ** Description      Given a power state, find the technology routing
1646 **                  destination. The result is filled in the given p_handles
1647 **                  in the order of A, B, F, Bprime
1648 **
1649 ** Returns          None
1650 **
1651 *******************************************************************************/
nfa_ee_get_tech_route(uint8_t power_state,uint8_t * p_handles)1652 void nfa_ee_get_tech_route(uint8_t power_state, uint8_t* p_handles) {
1653   int xx, yy;
1654   tNFA_EE_ECB* p_cb;
1655   uint8_t tech_mask_list[NFA_EE_MAX_TECH_ROUTE] = {
1656       NFA_TECHNOLOGY_MASK_A, NFA_TECHNOLOGY_MASK_B, NFA_TECHNOLOGY_MASK_F,
1657       NFA_TECHNOLOGY_MASK_B_PRIME};
1658 
1659   NFA_TRACE_DEBUG1("nfa_ee_get_tech_route(): %d", power_state);
1660 
1661   for (xx = 0; xx < NFA_EE_MAX_TECH_ROUTE; xx++) {
1662     p_handles[xx] = NFC_DH_ID;
1663     p_cb = &nfa_ee_cb.ecb[nfa_ee_cb.cur_ee - 1];
1664     for (yy = 0; yy < nfa_ee_cb.cur_ee; yy++, p_cb--) {
1665       if (p_cb->ee_status == NFC_NFCEE_STATUS_ACTIVE) {
1666         switch (power_state) {
1667           case NFA_EE_PWR_STATE_ON:
1668             if (p_cb->tech_switch_on & tech_mask_list[xx])
1669               p_handles[xx] = p_cb->nfcee_id;
1670             break;
1671           case NFA_EE_PWR_STATE_SWITCH_OFF:
1672             if (p_cb->tech_switch_off & tech_mask_list[xx])
1673               p_handles[xx] = p_cb->nfcee_id;
1674             break;
1675           case NFA_EE_PWR_STATE_BATT_OFF:
1676             if (p_cb->tech_battery_off & tech_mask_list[xx])
1677               p_handles[xx] = p_cb->nfcee_id;
1678             break;
1679         }
1680       }
1681     }
1682   }
1683   NFA_TRACE_DEBUG4("0x%x, 0x%x, 0x%x, 0x%x", p_handles[0], p_handles[1],
1684                    p_handles[2], p_handles[3]);
1685 }
1686 
1687 /*******************************************************************************
1688 **
1689 ** Function         nfa_ee_check_set_routing
1690 **
1691 ** Description      If the new size exceeds the capacity of next block,
1692 **                  send the routing command now and reset the related
1693 **                  parameters.
1694 **
1695 ** Returns          void
1696 **
1697 *******************************************************************************/
nfa_ee_check_set_routing(uint16_t new_size,int * p_max_len,uint8_t * p,int * p_cur_offset)1698 void nfa_ee_check_set_routing(uint16_t new_size, int* p_max_len, uint8_t* p,
1699                               int* p_cur_offset) {
1700   uint8_t max_tlv = (uint8_t)((*p_max_len > NFA_EE_ROUT_MAX_TLV_SIZE)
1701                                   ? NFA_EE_ROUT_MAX_TLV_SIZE
1702                                   : *p_max_len);
1703   tNFA_STATUS status = NFA_STATUS_OK;
1704 
1705   if (new_size + *p_cur_offset > max_tlv) {
1706     if (NFC_SetRouting(true, *p, *p_cur_offset, p + 1) == NFA_STATUS_OK) {
1707       nfa_ee_cb.wait_rsp++;
1708     }
1709     /* after the routing command is sent, re-use the same buffer to send the
1710      * next routing command.
1711      * reset the related parameters */
1712     if (*p_max_len > *p_cur_offset)
1713       *p_max_len -= *p_cur_offset; /* the max is reduced */
1714     else
1715       *p_max_len = 0;
1716     *p_cur_offset = 0; /* nothing is in queue any more */
1717     *p = 0;            /* num_tlv=0 */
1718   }
1719 }
1720 
1721 /*******************************************************************************
1722 **
1723 ** Function         nfa_ee_route_add_one_ecb
1724 **
1725 ** Description      Add the routing entries for one NFCEE/DH
1726 **
1727 ** Returns          NFA_STATUS_OK, if ok to continue
1728 **
1729 *******************************************************************************/
nfa_ee_route_add_one_ecb(tNFA_EE_ECB * p_cb,int * p_max_len,bool more,uint8_t * ps,int * p_cur_offset)1730 tNFA_STATUS nfa_ee_route_add_one_ecb(tNFA_EE_ECB* p_cb, int* p_max_len,
1731                                      bool more, uint8_t* ps,
1732                                      int* p_cur_offset) {
1733   uint8_t *p, *pa;
1734   uint16_t tlv_size;
1735   uint8_t num_tlv, len;
1736   int xx;
1737   int start_offset;
1738   uint8_t power_cfg = 0;
1739   uint8_t* pp = ps + *p_cur_offset;
1740   uint8_t entry_size;
1741   uint8_t max_tlv;
1742   uint8_t* p_start;
1743   uint8_t new_size;
1744   tNFA_STATUS status = NFA_STATUS_OK;
1745 
1746   nfa_ee_check_set_routing(p_cb->size_mask, p_max_len, ps, p_cur_offset);
1747   max_tlv = (uint8_t)((*p_max_len > NFA_EE_ROUT_MAX_TLV_SIZE)
1748                           ? NFA_EE_ROUT_MAX_TLV_SIZE
1749                           : *p_max_len);
1750   /* use the first byte of the buffer (ps) to keep the num_tlv */
1751   num_tlv = *ps;
1752   NFA_TRACE_DEBUG5(
1753       "nfa_ee_route_add_one_ecb max_len:%d, max_tlv:%d, cur_offset:%d, "
1754       "more:%d, num_tlv:%d",
1755       *p_max_len, max_tlv, *p_cur_offset, more, num_tlv);
1756   pp = ps + 1 + *p_cur_offset;
1757   p = pp;
1758   tlv_size = (uint8_t)*p_cur_offset;
1759   /* add the Technology based routing */
1760   for (xx = 0; xx < NFA_EE_NUM_TECH; xx++) {
1761     power_cfg = 0;
1762     if (p_cb->tech_switch_on & nfa_ee_tech_mask_list[xx])
1763       power_cfg |= NCI_ROUTE_PWR_STATE_ON;
1764     if (p_cb->tech_switch_off & nfa_ee_tech_mask_list[xx])
1765       power_cfg |= NCI_ROUTE_PWR_STATE_SWITCH_OFF;
1766     if (p_cb->tech_battery_off & nfa_ee_tech_mask_list[xx])
1767       power_cfg |= NCI_ROUTE_PWR_STATE_BATT_OFF;
1768     if (power_cfg) {
1769       *pp++ = NFC_ROUTE_TAG_TECH;
1770       *pp++ = 3;
1771       *pp++ = p_cb->nfcee_id;
1772       *pp++ = power_cfg;
1773       *pp++ = nfa_ee_tech_list[xx];
1774       num_tlv++;
1775       if (power_cfg != NCI_ROUTE_PWR_STATE_ON)
1776         nfa_ee_cb.ee_cfged |= NFA_EE_CFGED_OFF_ROUTING;
1777     }
1778   }
1779 
1780   /* add the Protocol based routing */
1781   for (xx = 0; xx < NFA_EE_NUM_PROTO; xx++) {
1782     power_cfg = 0;
1783     if (p_cb->proto_switch_on & nfa_ee_proto_mask_list[xx])
1784       power_cfg |= NCI_ROUTE_PWR_STATE_ON;
1785     if (p_cb->proto_switch_off & nfa_ee_proto_mask_list[xx])
1786       power_cfg |= NCI_ROUTE_PWR_STATE_SWITCH_OFF;
1787     if (p_cb->proto_battery_off & nfa_ee_proto_mask_list[xx])
1788       power_cfg |= NCI_ROUTE_PWR_STATE_BATT_OFF;
1789     if (power_cfg) {
1790       *pp++ = NFC_ROUTE_TAG_PROTO;
1791       *pp++ = 3;
1792       *pp++ = p_cb->nfcee_id;
1793       *pp++ = power_cfg;
1794       *pp++ = nfa_ee_proto_list[xx];
1795       num_tlv++;
1796       if (power_cfg != NCI_ROUTE_PWR_STATE_ON)
1797         nfa_ee_cb.ee_cfged |= NFA_EE_CFGED_OFF_ROUTING;
1798     }
1799   }
1800 
1801   /* add NFC-DEP routing to HOST */
1802   if (p_cb->nfcee_id == NFC_DH_ID) {
1803     *pp++ = NFC_ROUTE_TAG_PROTO;
1804     *pp++ = 3;
1805     *pp++ = NFC_DH_ID;
1806     *pp++ = NCI_ROUTE_PWR_STATE_ON;
1807     *pp++ = NFC_PROTOCOL_NFC_DEP;
1808     num_tlv++;
1809   }
1810 
1811   /* update the num_tlv and current offset */
1812   entry_size = (uint8_t)(pp - p);
1813   *p_cur_offset += entry_size;
1814   *ps = num_tlv;
1815   /* add the AID routing */
1816   if (p_cb->aid_entries) {
1817     start_offset = 0;
1818     for (xx = 0; xx < p_cb->aid_entries; xx++) {
1819       /* rememebr the beginning of this AID routing entry, just in case we need
1820        * to put it in next command */
1821       p_start = pp;
1822       /* add one AID entry */
1823       if (p_cb->aid_rt_info[xx] & NFA_EE_AE_ROUTE) {
1824         num_tlv++;
1825         pa = &p_cb->aid_cfg[start_offset];
1826         pa++;        /* EMV tag */
1827         len = *pa++; /* aid_len */
1828         *pp++ = NFC_ROUTE_TAG_AID;
1829         *pp++ = len + 2;
1830         *pp++ = p_cb->nfcee_id;
1831         *pp++ = p_cb->aid_pwr_cfg[xx];
1832         /* copy the AID */
1833         memcpy(pp, pa, len);
1834         pp += len;
1835       }
1836       start_offset += p_cb->aid_len[xx];
1837       new_size = (uint8_t)(pp - p_start);
1838       nfa_ee_check_set_routing(new_size, p_max_len, ps, p_cur_offset);
1839       if (*ps == 0) {
1840         /* just sent routing command, update local */
1841         *ps = 1;
1842         num_tlv = *ps;
1843         *p_cur_offset = new_size;
1844         pp = ps + 1;
1845         p = pp;
1846         tlv_size = (uint8_t)*p_cur_offset;
1847         max_tlv = (uint8_t)((*p_max_len > NFA_EE_ROUT_MAX_TLV_SIZE)
1848                                 ? NFA_EE_ROUT_MAX_TLV_SIZE
1849                                 : *p_max_len);
1850         memcpy(p, p_start, new_size);
1851         pp += new_size;
1852       } else {
1853         /* add the new entry */
1854         *ps = num_tlv;
1855         *p_cur_offset += new_size;
1856       }
1857     }
1858   }
1859 
1860   tlv_size = nfa_ee_total_lmrt_size();
1861   if (tlv_size) {
1862     nfa_ee_cb.ee_cfged |= nfa_ee_ecb_to_mask(p_cb);
1863   }
1864   if (p_cb->ecb_flags & NFA_EE_ECB_FLAGS_ROUTING) {
1865     nfa_ee_cb.ee_cfg_sts |= NFA_EE_STS_CHANGED_ROUTING;
1866   }
1867   NFA_TRACE_DEBUG2("ee_cfg_sts:0x%02x lmrt_size:%d", nfa_ee_cb.ee_cfg_sts,
1868                    tlv_size);
1869 
1870   if (more == false) {
1871     /* last entry. update routing table now */
1872     if (nfa_ee_cb.ee_cfg_sts & NFA_EE_STS_CHANGED_ROUTING) {
1873       if (tlv_size) {
1874         nfa_ee_cb.ee_cfg_sts |= NFA_EE_STS_PREV_ROUTING;
1875       } else {
1876         nfa_ee_cb.ee_cfg_sts &= ~NFA_EE_STS_PREV_ROUTING;
1877       }
1878       NFA_TRACE_DEBUG2(
1879           "nfa_ee_route_add_one_ecb: set routing num_tlv:%d tlv_size:%d",
1880           num_tlv, tlv_size);
1881       if (NFC_SetRouting(more, num_tlv, (uint8_t)(*p_cur_offset), ps + 1) ==
1882           NFA_STATUS_OK) {
1883         nfa_ee_cb.wait_rsp++;
1884       }
1885     } else if (nfa_ee_cb.ee_cfg_sts & NFA_EE_STS_PREV_ROUTING) {
1886       if (tlv_size == 0) {
1887         nfa_ee_cb.ee_cfg_sts &= ~NFA_EE_STS_PREV_ROUTING;
1888         /* indicated routing is configured to NFCC */
1889         nfa_ee_cb.ee_cfg_sts |= NFA_EE_STS_CHANGED_ROUTING;
1890         if (NFC_SetRouting(more, 0, 0, ps + 1) == NFA_STATUS_OK) {
1891           nfa_ee_cb.wait_rsp++;
1892         }
1893       }
1894     }
1895   }
1896 
1897   return status;
1898 }
1899 
1900 /*******************************************************************************
1901 **
1902 ** Function         nfa_ee_need_recfg
1903 **
1904 ** Description      Check if any API function to configure the routing table or
1905 **                  VS is called since last update
1906 **
1907 **                  The algorithm for the NFCEE configuration handling is as
1908 **                  follows:
1909 **
1910 **                  Each NFCEE_ID/DH has its own control block - tNFA_EE_ECB
1911 **                  Each control block uses ecb_flags to keep track if an API
1912 **                  that changes routing/VS is invoked. This ecb_flags is
1913 **                  cleared at the end of nfa_ee_update_rout().
1914 **
1915 **                  nfa_ee_cb.ee_cfged is the bitmask of the control blocks with
1916 **                  routing/VS configuration and NFA_EE_CFGED_UPDATE_NOW.
1917 **                  nfa_ee_cb.ee_cfged is cleared and re-calculated at the end
1918 **                  of nfa_ee_update_rout().
1919 **
1920 **                  nfa_ee_cb.ee_cfg_sts is used to check is any status is
1921 **                  changed and the associated command is issued to NFCC.
1922 **                  nfa_ee_cb.ee_cfg_sts is AND with NFA_EE_STS_PREV at the end
1923 **                  of nfa_ee_update_rout() to clear the NFA_EE_STS_CHANGED bits
1924 **                  (except NFA_EE_STS_CHANGED_CANNED_VS is cleared in
1925 **                  nfa_ee_vs_cback)
1926 **
1927 ** Returns          TRUE if any configuration is changed
1928 **
1929 *******************************************************************************/
nfa_ee_need_recfg(void)1930 static bool nfa_ee_need_recfg(void) {
1931   bool needed = false;
1932   uint32_t xx;
1933   tNFA_EE_ECB* p_cb;
1934   uint8_t mask;
1935 
1936   NFA_TRACE_DEBUG2("nfa_ee_need_recfg() ee_cfged: 0x%02x ee_cfg_sts: 0x%02x",
1937                    nfa_ee_cb.ee_cfged, nfa_ee_cb.ee_cfg_sts);
1938   /* if no routing/vs is configured, do not need to send the info to NFCC */
1939   if (nfa_ee_cb.ee_cfged || nfa_ee_cb.ee_cfg_sts) {
1940     if (nfa_ee_cb.ee_cfg_sts & NFA_EE_STS_CHANGED) {
1941       needed = true;
1942     } else {
1943       p_cb = &nfa_ee_cb.ecb[NFA_EE_CB_4_DH];
1944       mask = 1 << NFA_EE_CB_4_DH;
1945       for (xx = 0; xx <= nfa_ee_cb.cur_ee; xx++) {
1946         NFA_TRACE_DEBUG3("%d: ecb_flags  : 0x%02x, mask: 0x%02x", xx,
1947                          p_cb->ecb_flags, mask);
1948         if ((p_cb->ecb_flags) && (nfa_ee_cb.ee_cfged & mask)) {
1949           needed = true;
1950           break;
1951         }
1952         p_cb = &nfa_ee_cb.ecb[xx];
1953         mask = 1 << xx;
1954       }
1955     }
1956   }
1957 
1958   return needed;
1959 }
1960 
1961 /*******************************************************************************
1962 **
1963 ** Function         nfa_ee_rout_timeout
1964 **
1965 ** Description      Anytime VS or routing entries are changed,
1966 **                  a 1 second timer is started. This function is called when
1967 **                  the timer expires or NFA_EeUpdateNow() is called.
1968 **
1969 ** Returns          void
1970 **
1971 *******************************************************************************/
nfa_ee_rout_timeout(tNFA_EE_MSG * p_data)1972 void nfa_ee_rout_timeout(tNFA_EE_MSG* p_data) {
1973   uint8_t ee_cfged = nfa_ee_cb.ee_cfged;
1974 
1975   NFA_TRACE_DEBUG0("nfa_ee_rout_timeout()");
1976   if (nfa_ee_need_recfg()) {
1977     /* discovery is not started */
1978     nfa_ee_update_rout();
1979   }
1980 
1981   if (nfa_ee_cb.wait_rsp) nfa_ee_cb.ee_wait_evt |= NFA_EE_WAIT_UPDATE_RSP;
1982   if (ee_cfged & NFA_EE_CFGED_UPDATE_NOW) {
1983     /* need to report NFA_EE_UPDATED_EVT when done updating NFCC */
1984     nfa_ee_cb.ee_wait_evt |= NFA_EE_WAIT_UPDATE;
1985     if (!nfa_ee_cb.wait_rsp) {
1986       nfa_ee_report_update_evt();
1987     }
1988   }
1989 }
1990 
1991 /*******************************************************************************
1992 **
1993 ** Function         nfa_ee_discv_timeout
1994 **
1995 ** Description
1996 **
1997 **
1998 **
1999 ** Returns          void
2000 **
2001 *******************************************************************************/
nfa_ee_discv_timeout(tNFA_EE_MSG * p_data)2002 void nfa_ee_discv_timeout(tNFA_EE_MSG* p_data) {
2003   NFC_NfceeDiscover(false);
2004   if (nfa_ee_cb.p_enable_cback)
2005     (*nfa_ee_cb.p_enable_cback)(NFA_EE_DISC_STS_OFF);
2006 }
2007 
2008 /*******************************************************************************
2009 **
2010 ** Function         nfa_ee_lmrt_to_nfcc
2011 **
2012 ** Description      This function would set the listen mode routing table
2013 **                  to NFCC.
2014 **
2015 ** Returns          void
2016 **
2017 *******************************************************************************/
nfa_ee_lmrt_to_nfcc(tNFA_EE_MSG * p_data)2018 void nfa_ee_lmrt_to_nfcc(tNFA_EE_MSG* p_data) {
2019   int xx;
2020   tNFA_EE_ECB* p_cb;
2021   uint8_t* p = NULL;
2022   bool more = true;
2023   uint8_t last_active = NFA_EE_INVALID;
2024   int max_len, len;
2025   tNFA_STATUS status = NFA_STATUS_FAILED;
2026   int cur_offset;
2027   uint8_t max_tlv;
2028 
2029   /* update routing table: DH and the activated NFCEEs */
2030   p = (uint8_t*)GKI_getbuf(NFA_EE_ROUT_BUF_SIZE);
2031   if (p == NULL) {
2032     NFA_TRACE_ERROR0("nfa_ee_lmrt_to_nfcc() no buffer to send routing info.");
2033     nfa_ee_report_event(NULL, NFA_EE_NO_MEM_ERR_EVT,
2034                         (tNFA_EE_CBACK_DATA*)&status);
2035     return;
2036   }
2037 
2038   /* find the last active NFCEE. */
2039   p_cb = &nfa_ee_cb.ecb[nfa_ee_cb.cur_ee - 1];
2040   for (xx = 0; xx < nfa_ee_cb.cur_ee; xx++, p_cb--) {
2041     if (p_cb->ee_status == NFC_NFCEE_STATUS_ACTIVE) {
2042       if (last_active == NFA_EE_INVALID) {
2043         last_active = p_cb->nfcee_id;
2044         NFA_TRACE_DEBUG1("last_active: 0x%x", last_active);
2045       }
2046     }
2047   }
2048   if (last_active == NFA_EE_INVALID) {
2049     more = false;
2050   }
2051 
2052   /* add the routing for DH first */
2053   status = NFA_STATUS_OK;
2054   max_len = NFC_GetLmrtSize();
2055   max_tlv =
2056       (uint8_t)((max_len > NFA_EE_ROUT_MAX_TLV_SIZE) ? NFA_EE_ROUT_MAX_TLV_SIZE
2057                                                      : max_len);
2058   cur_offset = 0;
2059   /* use the first byte of the buffer (p) to keep the num_tlv */
2060   *p = 0;
2061   status = nfa_ee_route_add_one_ecb(&nfa_ee_cb.ecb[NFA_EE_CB_4_DH], &max_len,
2062                                     more, p, &cur_offset);
2063 
2064   /* add only what is supported by NFCC. report overflow */
2065   if (status == NFA_STATUS_OK) {
2066     /* add the routing for NFCEEs */
2067     p_cb = &nfa_ee_cb.ecb[0];
2068     for (xx = 0; (xx < nfa_ee_cb.cur_ee) && more; xx++, p_cb++) {
2069       len = 0;
2070       if (p_cb->ee_status == NFC_NFCEE_STATUS_ACTIVE) {
2071         NFA_TRACE_DEBUG2("nfcee_id:0x%x, last_active: 0x%x", p_cb->nfcee_id,
2072                          last_active);
2073         if (last_active == p_cb->nfcee_id) more = false;
2074         status = nfa_ee_route_add_one_ecb(p_cb, &max_len, more, p, &cur_offset);
2075         if (status != NFA_STATUS_OK) {
2076           more = false;
2077         }
2078       }
2079     }
2080   }
2081   if (status != NFA_STATUS_OK) {
2082     nfa_ee_report_event(NULL, NFA_EE_ROUT_ERR_EVT,
2083                         (tNFA_EE_CBACK_DATA*)&status);
2084   }
2085   GKI_freebuf(p);
2086 }
2087 
2088 /*******************************************************************************
2089 **
2090 ** Function         nfa_ee_update_rout
2091 **
2092 ** Description      This function would set the VS and listen mode routing table
2093 **                  to NFCC.
2094 **
2095 ** Returns          void
2096 **
2097 *******************************************************************************/
nfa_ee_update_rout(void)2098 void nfa_ee_update_rout(void) {
2099   int xx;
2100   tNFA_EE_ECB* p_cb;
2101   uint8_t mask;
2102   NFC_HDR msg;
2103 
2104   NFA_TRACE_DEBUG1("nfa_ee_update_rout ee_cfg_sts:0x%02x",
2105                    nfa_ee_cb.ee_cfg_sts);
2106 
2107   /* use action function to send routing and VS configuration to NFCC */
2108   msg.event = NFA_EE_CFG_TO_NFCC_EVT;
2109   nfa_ee_evt_hdlr(&msg);
2110 
2111   /* all configuration is updated to NFCC, clear the status mask */
2112   nfa_ee_cb.ee_cfg_sts &= NFA_EE_STS_PREV;
2113   nfa_ee_cb.ee_cfged = 0;
2114   p_cb = &nfa_ee_cb.ecb[0];
2115   for (xx = 0; xx < NFA_EE_NUM_ECBS; xx++, p_cb++) {
2116     p_cb->ecb_flags = 0;
2117     mask = (1 << xx);
2118     if (p_cb->tech_switch_on | p_cb->tech_switch_off | p_cb->tech_battery_off |
2119         p_cb->proto_switch_on | p_cb->proto_switch_off |
2120         p_cb->proto_battery_off | p_cb->aid_entries) {
2121       /* this entry has routing configuration. mark it configured */
2122       nfa_ee_cb.ee_cfged |= mask;
2123     }
2124   }
2125   NFA_TRACE_DEBUG2("nfa_ee_update_rout ee_cfg_sts:0x%02x ee_cfged:0x%02x",
2126                    nfa_ee_cb.ee_cfg_sts, nfa_ee_cb.ee_cfged);
2127 }
2128