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