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     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     nfa_ee_update_route_size(p_cb);
544     if (nfa_ee_total_lmrt_size() > NFC_GetLmrtSize())
545     {
546         NFA_TRACE_ERROR0 ("nfa_ee_api_set_tech_cfg Exceed LMRT size");
547         evt_data.status        = NFA_STATUS_BUFFER_FULL;
548         p_cb->tech_switch_on   = old_tech_switch_on;
549         p_cb->tech_switch_off  = old_tech_switch_off;
550         p_cb->tech_battery_off = old_tech_battery_off;
551         p_cb->size_mask        = old_size_mask;
552     }
553     else
554     {
555         p_cb->ecb_flags       |= NFA_EE_ECB_FLAGS_TECH;
556         if (p_cb->tech_switch_on | p_cb->tech_switch_off | p_cb->tech_battery_off)
557         {
558             /* if any technology in any power mode is configured, mark this entry as configured */
559             nfa_ee_cb.ee_cfged    |= nfa_ee_ecb_to_mask(p_cb);
560         }
561         nfa_ee_start_timer();
562     }
563     nfa_ee_report_event (p_cb->p_ee_cback, NFA_EE_SET_TECH_CFG_EVT, &evt_data);
564 }
565 
566 /*******************************************************************************
567 **
568 ** Function         nfa_ee_api_set_proto_cfg
569 **
570 ** Description      process set protocol routing configuration from user
571 **                  start a 1 second timer. When the timer expires,
572 **                  the configuration collected in control block is sent to NFCC
573 **
574 ** Returns          void
575 **
576 *******************************************************************************/
nfa_ee_api_set_proto_cfg(tNFA_EE_MSG * p_data)577 void nfa_ee_api_set_proto_cfg(tNFA_EE_MSG *p_data)
578 {
579     tNFA_EE_ECB *p_cb = p_data->cfg_hdr.p_cb;
580     tNFA_EE_CBACK_DATA  evt_data = {0};
581     tNFA_PROTOCOL_MASK    old_proto_switch_on   = p_cb->proto_switch_on;
582     tNFA_PROTOCOL_MASK    old_proto_switch_off  = p_cb->proto_switch_off;
583     tNFA_PROTOCOL_MASK    old_proto_battery_off = p_cb->proto_battery_off;
584     UINT8                   old_size_mask        = p_cb->size_mask;
585 
586     p_cb->proto_switch_on       = p_data->set_proto.protocols_switch_on;
587     p_cb->proto_switch_off      = p_data->set_proto.protocols_switch_off;
588     p_cb->proto_battery_off     = p_data->set_proto.protocols_battery_off;
589     nfa_ee_update_route_size(p_cb);
590     if (nfa_ee_total_lmrt_size() > NFC_GetLmrtSize())
591     {
592         NFA_TRACE_ERROR0 ("nfa_ee_api_set_proto_cfg Exceed LMRT size");
593         evt_data.status         = NFA_STATUS_BUFFER_FULL;
594         p_cb->proto_switch_on   = old_proto_switch_on;
595         p_cb->proto_switch_off  = old_proto_switch_off;
596         p_cb->proto_battery_off = old_proto_battery_off;
597         p_cb->size_mask         = old_size_mask;
598     }
599     else
600     {
601         p_cb->ecb_flags            |= NFA_EE_ECB_FLAGS_PROTO;
602         if (p_cb->proto_switch_on | p_cb->proto_switch_off | p_cb->proto_battery_off)
603         {
604             /* if any protocol in any power mode is configured, mark this entry as configured */
605             nfa_ee_cb.ee_cfged         |= nfa_ee_ecb_to_mask(p_cb);
606         }
607         nfa_ee_start_timer();
608     }
609     nfa_ee_report_event (p_cb->p_ee_cback, NFA_EE_SET_PROTO_CFG_EVT, &evt_data);
610 }
611 
612 /*******************************************************************************
613 **
614 ** Function         nfa_ee_api_add_aid
615 **
616 ** Description      process add an AID routing configuration from user
617 **                  start a 1 second timer. When the timer expires,
618 **                  the configuration collected in control block is sent to NFCC
619 **
620 ** Returns          void
621 **
622 *******************************************************************************/
nfa_ee_api_add_aid(tNFA_EE_MSG * p_data)623 void nfa_ee_api_add_aid(tNFA_EE_MSG *p_data)
624 {
625     tNFA_EE_API_ADD_AID *p_add = &p_data->add_aid;
626     tNFA_EE_ECB *p_cb = p_data->cfg_hdr.p_cb;
627     tNFA_EE_ECB *p_chk_cb;
628     UINT8   *p, *p_start;
629     int     len, len_needed;
630     tNFA_EE_CBACK_DATA  evt_data = {0};
631     int offset = 0, entry = 0;
632     UINT16  new_size;
633 
634     nfa_ee_trace_aid ("nfa_ee_api_add_aid", p_cb->nfcee_id, p_add->aid_len, p_add->p_aid);
635     p_chk_cb = nfa_ee_find_aid_offset(p_add->aid_len, p_add->p_aid, &offset, &entry);
636     if (p_chk_cb)
637     {
638         NFA_TRACE_DEBUG0 ("nfa_ee_api_add_aid The AID entry is already in the database");
639         if (p_chk_cb == p_cb)
640         {
641             p_cb->aid_rt_info[entry]    |= NFA_EE_AE_ROUTE;
642             new_size = nfa_ee_total_lmrt_size();
643             if (new_size > NFC_GetLmrtSize())
644             {
645                 NFA_TRACE_ERROR1 ("Exceed LMRT size:%d (add ROUTE)", new_size);
646                 evt_data.status             = NFA_STATUS_BUFFER_FULL;
647                 p_cb->aid_rt_info[entry]    &= ~NFA_EE_AE_ROUTE;
648             }
649             else
650             {
651                 p_cb->aid_pwr_cfg[entry]     = p_add->power_state;
652             }
653         }
654         else
655         {
656             NFA_TRACE_ERROR1 ("The AID entry is already in the database for different NFCEE ID:0x%02x", p_chk_cb->nfcee_id);
657             evt_data.status = NFA_STATUS_SEMANTIC_ERROR;
658         }
659     }
660     else
661     {
662         /* Find the total length so far */
663         len = nfa_ee_find_total_aid_len(p_cb, 0);
664 
665         /* make sure the control block has enough room to hold this entry */
666         len_needed  = p_add->aid_len + 2; /* tag/len */
667 
668         if ((len_needed + len) > NFA_EE_MAX_AID_CFG_LEN)
669         {
670             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);
671             evt_data.status = NFA_STATUS_BUFFER_FULL;
672         }
673         else if (p_cb->aid_entries < NFA_EE_MAX_AID_ENTRIES)
674         {
675             new_size = nfa_ee_total_lmrt_size() + 4 + p_add->aid_len; /* 4 = 1 (tag) + 1 (len) + 1(nfcee_id) + 1(power cfg) */
676             if (new_size > NFC_GetLmrtSize())
677             {
678                 NFA_TRACE_ERROR1 ("Exceed LMRT size:%d", new_size);
679                 evt_data.status        = NFA_STATUS_BUFFER_FULL;
680             }
681             else
682             {
683                 /* add AID */
684                 p_cb->aid_pwr_cfg[p_cb->aid_entries]    = p_add->power_state;
685                 p_cb->aid_rt_info[p_cb->aid_entries]    = NFA_EE_AE_ROUTE;
686                 p       = p_cb->aid_cfg + len;
687                 p_start = p;
688                 *p++    = NFA_EE_AID_CFG_TAG_NAME;
689                 *p++    = p_add->aid_len;
690                 memcpy(p, p_add->p_aid, p_add->aid_len);
691                 p      += p_add->aid_len;
692 
693                 p_cb->aid_len[p_cb->aid_entries++]     = (UINT8)(p - p_start);
694             }
695         }
696         else
697         {
698             NFA_TRACE_ERROR1 ("Exceed NFA_EE_MAX_AID_ENTRIES:%d", NFA_EE_MAX_AID_ENTRIES);
699             evt_data.status = NFA_STATUS_BUFFER_FULL;
700         }
701     }
702 
703     if (evt_data.status == NFA_STATUS_OK)
704     {
705         /* mark AID changed */
706         p_cb->ecb_flags                       |= NFA_EE_ECB_FLAGS_AID;
707         nfa_ee_cb.ee_cfged                    |= nfa_ee_ecb_to_mask(p_cb);
708         nfa_ee_update_route_aid_size(p_cb);
709         nfa_ee_start_timer();
710     }
711     NFA_TRACE_DEBUG2 ("status:%d ee_cfged:0x%02x ",evt_data.status, nfa_ee_cb.ee_cfged);
712     /* report the status of this operation */
713     nfa_ee_report_event (p_cb->p_ee_cback, NFA_EE_ADD_AID_EVT, &evt_data);
714 }
715 
716 /*******************************************************************************
717 **
718 ** Function         nfa_ee_api_remove_aid
719 **
720 ** Description      process remove an AID routing configuration from user
721 **                  start a 1 second timer. When the timer expires,
722 **                  the configuration collected in control block is sent to NFCC
723 **
724 ** Returns          void
725 **
726 *******************************************************************************/
nfa_ee_api_remove_aid(tNFA_EE_MSG * p_data)727 void nfa_ee_api_remove_aid(tNFA_EE_MSG *p_data)
728 {
729     tNFA_EE_ECB  *p_cb;
730     tNFA_EE_CBACK_DATA  evt_data = {0};
731     int offset = 0, entry = 0, len;
732     int rest_len;
733     tNFA_EE_CBACK *p_cback = NULL;
734 
735     nfa_ee_trace_aid ("nfa_ee_api_remove_aid", 0, p_data->rm_aid.aid_len, p_data->rm_aid.p_aid);
736     p_cb = nfa_ee_find_aid_offset(p_data->rm_aid.aid_len, p_data->rm_aid.p_aid, &offset, &entry);
737     if (p_cb && p_cb->aid_entries)
738     {
739         NFA_TRACE_DEBUG2 ("aid_rt_info[%d]: 0x%02x", entry, p_cb->aid_rt_info[entry]);
740         /* mark routing and VS changed */
741         if (p_cb->aid_rt_info[entry] & NFA_EE_AE_ROUTE)
742             p_cb->ecb_flags         |= NFA_EE_ECB_FLAGS_AID;
743 
744         if (p_cb->aid_rt_info[entry] & NFA_EE_AE_VS)
745             p_cb->ecb_flags         |= NFA_EE_ECB_FLAGS_VS;
746 
747         /* remove the aid */
748         if ((entry+1) < p_cb->aid_entries)
749         {
750             /* not the last entry, move the aid entries in control block */
751             /* Find the total len from the next entry to the last one */
752             rest_len = nfa_ee_find_total_aid_len(p_cb, entry + 1);
753 
754             len = p_cb->aid_len[entry];
755             NFA_TRACE_DEBUG2 ("nfa_ee_api_remove_aid len:%d, rest_len:%d", len, rest_len);
756             GKI_shiftup (&p_cb->aid_cfg[offset], &p_cb->aid_cfg[offset+ len], rest_len);
757             rest_len = p_cb->aid_entries - entry;
758             GKI_shiftup (&p_cb->aid_len[entry], &p_cb->aid_len[entry + 1], rest_len);
759             GKI_shiftup (&p_cb->aid_pwr_cfg[entry], &p_cb->aid_pwr_cfg[entry + 1], rest_len);
760             GKI_shiftup (&p_cb->aid_rt_info[entry], &p_cb->aid_rt_info[entry + 1], rest_len);
761         }
762         /* else the last entry, just reduce the aid_entries by 1 */
763         p_cb->aid_entries--;
764         nfa_ee_cb.ee_cfged      |= nfa_ee_ecb_to_mask(p_cb);
765         nfa_ee_update_route_aid_size(p_cb);
766         nfa_ee_start_timer();
767         /* report NFA_EE_REMOVE_AID_EVT to the callback associated the NFCEE */
768         p_cback = p_cb->p_ee_cback;
769     }
770     else
771     {
772         NFA_TRACE_ERROR0 ("nfa_ee_api_remove_aid The AID entry is not in the database");
773         evt_data.status = NFA_STATUS_INVALID_PARAM;
774     }
775     nfa_ee_report_event (p_cback, NFA_EE_REMOVE_AID_EVT, &evt_data);
776 }
777 
778 /*******************************************************************************
779 **
780 ** Function         nfa_ee_api_lmrt_size
781 **
782 ** Description      Reports the remaining size in the Listen Mode Routing Table
783 **
784 ** Returns          void
785 **
786 *******************************************************************************/
nfa_ee_api_lmrt_size(tNFA_EE_MSG * p_data)787 void nfa_ee_api_lmrt_size(tNFA_EE_MSG *p_data)
788 {
789     tNFA_EE_CBACK_DATA  evt_data = {0};
790     UINT16 total_size = NFC_GetLmrtSize();
791 
792     evt_data.size       = total_size - nfa_ee_total_lmrt_size();
793     NFA_TRACE_DEBUG2 ("nfa_ee_api_lmrt_size total size:%d remaining size:%d", total_size, evt_data.size);
794 
795     nfa_ee_report_event (NULL, NFA_EE_REMAINING_SIZE_EVT, &evt_data);
796 }
797 
798 /*******************************************************************************
799 **
800 ** Function         nfa_ee_api_update_now
801 **
802 ** Description      Initiates connection creation process to the given NFCEE
803 **
804 ** Returns          void
805 **
806 *******************************************************************************/
nfa_ee_api_update_now(tNFA_EE_MSG * p_data)807 void nfa_ee_api_update_now(tNFA_EE_MSG *p_data)
808 {
809     tNFA_EE_CBACK_DATA  evt_data;
810 
811     if (nfa_ee_cb.ee_wait_evt & NFA_EE_WAIT_UPDATE_ALL)
812     {
813         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);
814         evt_data.status       = NFA_STATUS_SEMANTIC_ERROR;
815         nfa_ee_report_event (NULL, NFA_EE_UPDATED_EVT, &evt_data);
816         return;
817     }
818     nfa_sys_stop_timer(&nfa_ee_cb.timer);
819     nfa_ee_cb.ee_cfged  |= NFA_EE_CFGED_UPDATE_NOW;
820     nfa_ee_rout_timeout(p_data);
821 }
822 
823 /*******************************************************************************
824 **
825 ** Function         nfa_ee_api_connect
826 **
827 ** Description      Initiates connection creation process to the given NFCEE
828 **
829 ** Returns          void
830 **
831 *******************************************************************************/
nfa_ee_api_connect(tNFA_EE_MSG * p_data)832 void nfa_ee_api_connect(tNFA_EE_MSG *p_data)
833 {
834     tNFA_EE_ECB  *p_cb = p_data->connect.p_cb;
835     int xx;
836     tNFA_EE_CBACK_DATA  evt_data = {0};
837 
838     evt_data.connect.status       = NFA_STATUS_FAILED;
839     if (p_cb->conn_st == NFA_EE_CONN_ST_NONE)
840     {
841         for (xx = 0; xx < p_cb->num_interface; xx++)
842         {
843             if (p_data->connect.ee_interface == p_cb->ee_interface[xx])
844             {
845                 p_cb->p_ee_cback        = p_data->connect.p_cback;
846                 p_cb->conn_st           = NFA_EE_CONN_ST_WAIT;
847                 p_cb->use_interface     = p_data->connect.ee_interface;
848                 evt_data.connect.status = NFC_ConnCreate(NCI_DEST_TYPE_NFCEE, p_data->connect.nfcee_id,
849                     p_data->connect.ee_interface, nfa_ee_conn_cback);
850                 /* report the NFA_EE_CONNECT_EVT status on the response from NFCC */
851                 break;
852             }
853         }
854     }
855 
856     if (evt_data.connect.status != NCI_STATUS_OK)
857     {
858         evt_data.connect.ee_handle    = (tNFA_HANDLE)p_data->connect.nfcee_id | NFA_HANDLE_GROUP_EE;
859         evt_data.connect.status       = NFA_STATUS_INVALID_PARAM;
860         evt_data.connect.ee_interface = p_data->connect.ee_interface;
861         nfa_ee_report_event (p_data->connect.p_cback, NFA_EE_CONNECT_EVT, &evt_data);
862     }
863 }
864 
865 /*******************************************************************************
866 **
867 ** Function         nfa_ee_api_send_data
868 **
869 ** Description      Send the given data packet to the given NFCEE
870 **
871 ** Returns          void
872 **
873 *******************************************************************************/
nfa_ee_api_send_data(tNFA_EE_MSG * p_data)874 void nfa_ee_api_send_data(tNFA_EE_MSG *p_data)
875 {
876     tNFA_EE_ECB  *p_cb = p_data->send_data.p_cb;
877     BT_HDR *p_pkt;
878     UINT16 size = NCI_MSG_OFFSET_SIZE + NCI_DATA_HDR_SIZE + p_data->send_data.data_len + BT_HDR_SIZE;
879     UINT8  *p;
880     tNFA_STATUS status = NFA_STATUS_FAILED;
881 
882     if (p_cb->conn_st == NFA_EE_CONN_ST_CONN)
883     {
884         p_pkt = (BT_HDR *)GKI_getbuf(size);
885         if (p_pkt)
886         {
887             p_pkt->offset   = NCI_MSG_OFFSET_SIZE + NCI_DATA_HDR_SIZE;
888             p_pkt->len      = p_data->send_data.data_len;
889             p               = (UINT8 *)(p_pkt+1) + p_pkt->offset;
890             memcpy(p, p_data->send_data.p_data, p_pkt->len);
891             NFC_SendData (p_cb->conn_id, p_pkt);
892         }
893         else
894         {
895             nfa_ee_report_event( p_cb->p_ee_cback, NFA_EE_NO_MEM_ERR_EVT, (tNFA_EE_CBACK_DATA *)&status);
896         }
897     }
898     else
899     {
900         nfa_ee_report_event( p_cb->p_ee_cback, NFA_EE_NO_CB_ERR_EVT, (tNFA_EE_CBACK_DATA *)&status);
901     }
902 }
903 
904 /*******************************************************************************
905 **
906 ** Function         nfa_ee_api_disconnect
907 **
908 ** Description      Initiates closing of the connection to the given NFCEE
909 **
910 ** Returns          void
911 **
912 *******************************************************************************/
nfa_ee_api_disconnect(tNFA_EE_MSG * p_data)913 void nfa_ee_api_disconnect(tNFA_EE_MSG *p_data)
914 {
915     tNFA_EE_ECB  *p_cb = p_data->disconnect.p_cb;
916     tNFA_EE_CBACK_DATA  evt_data = {0};
917 
918     if (p_cb->conn_st == NFA_EE_CONN_ST_CONN)
919     {
920         p_cb->conn_st = NFA_EE_CONN_ST_DISC;
921         NFC_ConnClose(p_cb->conn_id);
922     }
923     evt_data.handle = (tNFA_HANDLE)p_cb->nfcee_id | NFA_HANDLE_GROUP_EE;
924     nfa_ee_report_event(p_cb->p_ee_cback, NFA_EE_DISCONNECT_EVT, &evt_data);
925 }
926 
927 /*******************************************************************************
928 **
929 ** Function         nfa_ee_report_disc_done
930 **
931 ** Description      Process the callback for NFCEE discovery response
932 **
933 ** Returns          void
934 **
935 *******************************************************************************/
nfa_ee_report_disc_done(BOOLEAN notify_enable_done)936 void nfa_ee_report_disc_done(BOOLEAN notify_enable_done)
937 {
938     tNFA_EE_CBACK           *p_cback;
939     tNFA_EE_CBACK_DATA      evt_data = {0};
940 
941     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);
942     if (nfa_ee_cb.num_ee_expecting == 0)
943     {
944         if (notify_enable_done)
945         {
946             if (nfa_ee_cb.em_state == NFA_EE_EM_STATE_INIT_DONE)
947             {
948                 nfa_sys_cback_notify_enable_complete (NFA_ID_EE);
949                 if (nfa_ee_cb.p_enable_cback)
950                     (*nfa_ee_cb.p_enable_cback)(NFA_EE_DISC_STS_ON);
951             }
952             else if ((nfa_ee_cb.em_state == NFA_EE_EM_STATE_RESTORING) && (nfa_ee_cb.ee_flags & NFA_EE_FLAG_NOTIFY_HCI) )
953             {
954                 nfa_ee_cb.ee_flags   &= ~NFA_EE_FLAG_NOTIFY_HCI;
955                 if (nfa_ee_cb.p_enable_cback)
956                     (*nfa_ee_cb.p_enable_cback)(NFA_EE_DISC_STS_ON);
957             }
958         }
959 
960 
961         if (nfa_ee_cb.p_ee_disc_cback)
962         {
963             /* notify API callback */
964             p_cback                         = nfa_ee_cb.p_ee_disc_cback;
965             nfa_ee_cb.p_ee_disc_cback       = NULL;
966             evt_data.status                         = NFA_STATUS_OK;
967             evt_data.ee_discover.num_ee             = NFA_EE_MAX_EE_SUPPORTED;
968             NFA_EeGetInfo(&evt_data.ee_discover.num_ee, evt_data.ee_discover.ee_info);
969             nfa_ee_report_event (p_cback, NFA_EE_DISCOVER_EVT, &evt_data);
970         }
971     }
972 }
973 
974 /*******************************************************************************
975 **
976 ** Function         nfa_ee_restore_ntf_done
977 **
978 ** Description      check if any ee_status still has NFA_EE_STATUS_PENDING bit
979 **
980 ** Returns          TRUE, if all NFA_EE_STATUS_PENDING bits are removed
981 **
982 *******************************************************************************/
nfa_ee_restore_ntf_done(void)983 BOOLEAN nfa_ee_restore_ntf_done(void)
984 {
985     tNFA_EE_ECB     *p_cb;
986     BOOLEAN         is_done = TRUE;
987     int             xx;
988 
989     p_cb = nfa_ee_cb.ecb;
990     for (xx = 0; xx < nfa_ee_cb.cur_ee; xx++, p_cb++)
991     {
992         if ((p_cb->nfcee_id != NFA_EE_INVALID) && (p_cb->ee_old_status & NFA_EE_STATUS_RESTORING))
993         {
994             is_done = FALSE;
995             break;
996         }
997     }
998     return is_done;
999 }
1000 
1001 /*******************************************************************************
1002 **
1003 ** Function         nfa_ee_remove_pending
1004 **
1005 ** Description      check if any ee_status still has NFA_EE_STATUS_RESTORING bit
1006 **
1007 ** Returns          TRUE, if all NFA_EE_STATUS_RESTORING bits are removed
1008 **
1009 *******************************************************************************/
nfa_ee_remove_pending(void)1010 static void nfa_ee_remove_pending(void)
1011 {
1012     tNFA_EE_ECB     *p_cb;
1013     tNFA_EE_ECB     *p_cb_n, *p_cb_end;
1014     int             xx, num_removed = 0;
1015     int             first_removed = NFA_EE_MAX_EE_SUPPORTED;
1016 
1017     p_cb = nfa_ee_cb.ecb;
1018     for (xx = 0; xx < nfa_ee_cb.cur_ee; xx++, p_cb++)
1019     {
1020         if ((p_cb->nfcee_id != NFA_EE_INVALID) && (p_cb->ee_status & NFA_EE_STATUS_RESTORING))
1021         {
1022             p_cb->nfcee_id  = NFA_EE_INVALID;
1023             num_removed ++;
1024             if (first_removed == NFA_EE_MAX_EE_SUPPORTED)
1025                 first_removed   = xx;
1026         }
1027     }
1028 
1029     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);
1030     if (num_removed && (first_removed != (nfa_ee_cb.cur_ee - num_removed)))
1031     {
1032         /* if the removes ECB entried are not at the end, move the entries up */
1033         p_cb_end = &nfa_ee_cb.ecb[nfa_ee_cb.cur_ee - 1];
1034         p_cb = &nfa_ee_cb.ecb[first_removed];
1035         for (p_cb_n = p_cb + 1; p_cb_n <= p_cb_end;)
1036         {
1037             while ((p_cb_n->nfcee_id == NFA_EE_INVALID) && (p_cb_n <= p_cb_end))
1038             {
1039                 p_cb_n++;
1040             }
1041 
1042             if (p_cb_n <= p_cb_end)
1043             {
1044                 memcpy(p_cb, p_cb_n, sizeof(tNFA_EE_ECB));
1045                 p_cb_n->nfcee_id = NFA_EE_INVALID;
1046             }
1047             p_cb++;
1048             p_cb_n++;
1049         }
1050     }
1051     nfa_ee_cb.cur_ee -= (UINT8)num_removed;
1052 }
1053 
1054 
1055 /*******************************************************************************
1056 **
1057 ** Function         nfa_ee_nci_disc_rsp
1058 **
1059 ** Description      Process the callback for NFCEE discovery response
1060 **
1061 ** Returns          void
1062 **
1063 *******************************************************************************/
nfa_ee_nci_disc_rsp(tNFA_EE_MSG * p_data)1064 void nfa_ee_nci_disc_rsp(tNFA_EE_MSG *p_data)
1065 {
1066     tNFC_NFCEE_DISCOVER_REVT    *p_evt = p_data->disc_rsp.p_data;
1067     tNFA_EE_ECB              *p_cb;
1068     UINT8   xx;
1069     UINT8   num_nfcee = p_evt->num_nfcee;
1070     BOOLEAN notify_enable_done = FALSE;
1071 
1072     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);
1073     switch (nfa_ee_cb.em_state)
1074     {
1075     case NFA_EE_EM_STATE_INIT:
1076         nfa_ee_cb.cur_ee            = 0;
1077         nfa_ee_cb.num_ee_expecting  = 0;
1078         if (num_nfcee == 0)
1079         {
1080             nfa_ee_cb.em_state = NFA_EE_EM_STATE_INIT_DONE;
1081             notify_enable_done = TRUE;
1082             if (p_evt->status != NFC_STATUS_OK)
1083             {
1084                 nfa_sys_stop_timer(&nfa_ee_cb.discv_timer);
1085             }
1086         }
1087         break;
1088 
1089     case NFA_EE_EM_STATE_INIT_DONE:
1090         if (num_nfcee)
1091         {
1092             /* if this is initiated by api function,
1093              * check if the number of NFCEE expected is more than what's currently in CB */
1094             if (num_nfcee > NFA_EE_MAX_EE_SUPPORTED)
1095                 num_nfcee = NFA_EE_MAX_EE_SUPPORTED;
1096             if (nfa_ee_cb.cur_ee < num_nfcee)
1097             {
1098                 p_cb = &nfa_ee_cb.ecb[nfa_ee_cb.cur_ee];
1099                 for (xx = nfa_ee_cb.cur_ee; xx < num_nfcee; xx++, p_cb++)
1100                 {
1101                     /* mark the new entries as a new one */
1102                     p_cb->nfcee_id = NFA_EE_INVALID;
1103                 }
1104             }
1105             nfa_ee_cb.cur_ee = num_nfcee;
1106         }
1107         break;
1108 
1109     case NFA_EE_EM_STATE_RESTORING:
1110         if (num_nfcee == 0)
1111         {
1112             nfa_ee_cb.em_state = NFA_EE_EM_STATE_INIT_DONE;
1113             nfa_ee_remove_pending();
1114             nfa_ee_check_restore_complete();
1115             if (p_evt->status != NFC_STATUS_OK)
1116             {
1117                 nfa_sys_stop_timer(&nfa_ee_cb.discv_timer);
1118             }
1119         }
1120         break;
1121     }
1122 
1123     if (p_evt->status == NFC_STATUS_OK)
1124     {
1125         nfa_ee_cb.num_ee_expecting = p_evt->num_nfcee;
1126         if (nfa_ee_cb.num_ee_expecting > NFA_EE_MAX_EE_SUPPORTED)
1127         {
1128             NFA_TRACE_ERROR2 ("NFA-EE num_ee_expecting:%d > max:%d", nfa_ee_cb.num_ee_expecting, NFA_EE_MAX_EE_SUPPORTED);
1129         }
1130     }
1131     nfa_ee_report_disc_done(notify_enable_done);
1132     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);
1133 }
1134 
1135 /*******************************************************************************
1136 **
1137 ** Function         nfa_ee_nci_disc_ntf
1138 **
1139 ** Description      Process the callback for NFCEE discovery notification
1140 **
1141 ** Returns          void
1142 **
1143 *******************************************************************************/
nfa_ee_nci_disc_ntf(tNFA_EE_MSG * p_data)1144 void nfa_ee_nci_disc_ntf(tNFA_EE_MSG *p_data)
1145 {
1146     tNFC_NFCEE_INFO_REVT    *p_ee = p_data->disc_ntf.p_data;
1147     tNFA_EE_ECB             *p_cb = NULL;
1148     BOOLEAN                 notify_enable_done = FALSE;
1149     BOOLEAN                 notify_new_ee = FALSE;
1150     tNFA_EE_CBACK_DATA      evt_data = {0};
1151     tNFA_EE_INFO            *p_info;
1152     tNFA_EE_EM_STATE        new_em_state = NFA_EE_EM_STATE_MAX;
1153 
1154     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);
1155     if (nfa_ee_cb.num_ee_expecting)
1156     {
1157         nfa_ee_cb.num_ee_expecting--;
1158         if ((nfa_ee_cb.num_ee_expecting == 0) && (nfa_ee_cb.p_ee_disc_cback != NULL))
1159         {
1160             /* Discovery triggered by API function */
1161             NFC_NfceeDiscover(FALSE);
1162         }
1163     }
1164     switch (nfa_ee_cb.em_state)
1165     {
1166     case NFA_EE_EM_STATE_INIT:
1167         if (nfa_ee_cb.cur_ee < NFA_EE_MAX_EE_SUPPORTED)
1168         {
1169             /* the cb can collect up to NFA_EE_MAX_EE_SUPPORTED ee_info */
1170             p_cb = &nfa_ee_cb.ecb[nfa_ee_cb.cur_ee++];
1171         }
1172 
1173         if (nfa_ee_cb.num_ee_expecting == 0)
1174         {
1175             /* notify init_done callback */
1176             nfa_ee_cb.em_state = NFA_EE_EM_STATE_INIT_DONE;
1177             notify_enable_done = TRUE;
1178         }
1179         break;
1180 
1181     case NFA_EE_EM_STATE_INIT_DONE:
1182         p_cb = nfa_ee_find_ecb (p_ee->nfcee_id);
1183         if (p_cb == NULL)
1184         {
1185             /* the NFCEE ID is not in the last NFCEE discovery
1186              * maybe it's a new one */
1187             p_cb = nfa_ee_find_ecb (NFA_EE_INVALID);
1188             if (p_cb)
1189             {
1190                 nfa_ee_cb.cur_ee++;
1191                 notify_new_ee = TRUE;
1192             }
1193         }
1194         else if (p_cb->ecb_flags & NFA_EE_ECB_FLAGS_ORDER)
1195         {
1196             nfa_ee_cb.cur_ee++;
1197             notify_new_ee = TRUE;
1198         }
1199         else
1200         {
1201             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);
1202         }
1203         break;
1204 
1205     case NFA_EE_EM_STATE_RESTORING:
1206         p_cb = nfa_ee_find_ecb (p_ee->nfcee_id);
1207         if (p_cb == NULL)
1208         {
1209             /* the NFCEE ID is not in the last NFCEE discovery
1210              * maybe it's a new one */
1211             p_cb = nfa_ee_find_ecb (NFA_EE_INVALID);
1212             if (p_cb)
1213             {
1214                 nfa_ee_cb.cur_ee++;
1215                 notify_new_ee = TRUE;
1216             }
1217         }
1218         if (nfa_ee_cb.num_ee_expecting == 0)
1219         {
1220             /* notify init_done callback */
1221             notify_enable_done = TRUE;
1222             if (nfa_ee_restore_ntf_done())
1223             {
1224                 new_em_state       = NFA_EE_EM_STATE_INIT_DONE;
1225             }
1226         }
1227         break;
1228     }
1229     NFA_TRACE_DEBUG1 ("nfa_ee_nci_disc_ntf cur_ee:%d", nfa_ee_cb.cur_ee);
1230 
1231     if (p_cb)
1232     {
1233         p_cb->nfcee_id      = p_ee->nfcee_id;
1234         p_cb->ee_status     = p_ee->ee_status;
1235         p_cb->num_interface = p_ee->num_interface;
1236         memcpy(p_cb->ee_interface, p_ee->ee_interface, p_ee->num_interface);
1237         p_cb->num_tlvs      = p_ee->num_tlvs;
1238         memcpy(p_cb->ee_tlv, p_ee->ee_tlv, p_ee->num_tlvs * sizeof(tNFA_EE_TLV));
1239 
1240         if (nfa_ee_cb.em_state == NFA_EE_EM_STATE_RESTORING)
1241         {
1242             /* NCI spec says: An NFCEE_DISCOVER_NTF that contains a Protocol type of "HCI Access"
1243              * SHALL NOT contain any other additional Protocol
1244              * i.e. check only first supported NFCEE interface is HCI access */
1245             /* NFA_HCI module handles restoring configurations for HCI access */
1246             if (p_cb->ee_interface[0] != NFC_NFCEE_INTERFACE_HCI_ACCESS)
1247             {
1248                 if ((nfa_ee_cb.ee_flags & NFA_EE_FLAG_WAIT_HCI) == 0)
1249                 {
1250                     nfa_ee_restore_one_ecb (p_cb);
1251                 }
1252                 /* else wait for NFA-HCI module to restore the HCI network information before enabling the NFCEE */
1253             }
1254         }
1255 
1256         if ((nfa_ee_cb.p_ee_disc_cback == NULL) && (notify_new_ee == TRUE))
1257         {
1258             if (nfa_dm_is_active() && (p_cb->ee_status != NFA_EE_STATUS_REMOVED))
1259             {
1260                 /* report this NFA_EE_NEW_EE_EVT only after NFA_DM_ENABLE_EVT is reported */
1261                 p_info                  = &evt_data.new_ee;
1262                 p_info->ee_handle       = NFA_HANDLE_GROUP_EE | (tNFA_HANDLE)p_cb->nfcee_id;
1263                 p_info->ee_status       = p_cb->ee_status;
1264                 p_info->num_interface   = p_cb->num_interface;
1265                 p_info->num_tlvs        = p_cb->num_tlvs;
1266                 memcpy(p_info->ee_interface, p_cb->ee_interface, p_cb->num_interface);
1267                 memcpy(p_info->ee_tlv, p_cb->ee_tlv, p_cb->num_tlvs * sizeof(tNFA_EE_TLV));
1268                 nfa_ee_report_event (NULL, NFA_EE_NEW_EE_EVT, &evt_data);
1269             }
1270         }
1271         else
1272             nfa_ee_report_disc_done(notify_enable_done);
1273 
1274         if (p_cb->ecb_flags & NFA_EE_ECB_FLAGS_ORDER)
1275         {
1276             NFA_TRACE_DEBUG0 ("NFA_EE_ECB_FLAGS_ORDER");
1277             p_cb->ecb_flags &= ~NFA_EE_ECB_FLAGS_ORDER;
1278             nfa_ee_report_discover_req_evt();
1279         }
1280 
1281     }
1282 
1283     if (new_em_state != NFA_EE_EM_STATE_MAX)
1284     {
1285         nfa_ee_cb.em_state = new_em_state;
1286         nfa_ee_check_restore_complete();
1287     }
1288 
1289     if ((nfa_ee_cb.cur_ee == nfa_ee_max_ee_cfg) && (nfa_ee_cb.em_state == NFA_EE_EM_STATE_INIT_DONE) )
1290     {
1291         if (nfa_ee_cb.discv_timer.in_use)
1292         {
1293             nfa_sys_stop_timer (&nfa_ee_cb.discv_timer);
1294             p_data->hdr.event = NFA_EE_DISCV_TIMEOUT_EVT;
1295             nfa_ee_evt_hdlr((BT_HDR *)p_data);
1296         }
1297     }
1298 }
1299 
1300 /*******************************************************************************
1301 **
1302 ** Function         nfa_ee_check_restore_complete
1303 **
1304 ** Description      Check if restore the NFA-EE related configuration to the
1305 **                  state prior to low power mode is complete.
1306 **                  If complete, notify sys.
1307 **
1308 ** Returns          void
1309 **
1310 *******************************************************************************/
nfa_ee_check_restore_complete(void)1311 void nfa_ee_check_restore_complete(void)
1312 {
1313     UINT32  xx;
1314     tNFA_EE_ECB     *p_cb;
1315     BOOLEAN         proc_complete = TRUE;
1316 
1317     p_cb = nfa_ee_cb.ecb;
1318     for (xx = 0; xx < nfa_ee_cb.cur_ee; xx++, p_cb++)
1319     {
1320         if (p_cb->ecb_flags & NFA_EE_ECB_FLAGS_RESTORE)
1321         {
1322             /* NFA_HCI module handles restoring configurations for HCI access.
1323              * ignore the restoring status for HCI Access */
1324             if (p_cb->ee_interface[0] != NFC_NFCEE_INTERFACE_HCI_ACCESS)
1325             {
1326                 proc_complete = FALSE;
1327                 break;
1328             }
1329         }
1330     }
1331 
1332     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);
1333     if (proc_complete)
1334     {
1335         /* update routing table when NFA_EE_ROUT_TIMEOUT_EVT is received */
1336         if (nfa_ee_cb.ee_cfg_sts & NFA_EE_STS_PREV_ROUTING)
1337             nfa_ee_api_update_now(NULL);
1338 
1339         nfa_ee_cb.em_state = NFA_EE_EM_STATE_INIT_DONE;
1340         nfa_sys_cback_notify_nfcc_power_mode_proc_complete (NFA_ID_EE);
1341     }
1342 }
1343 
1344 /*******************************************************************************
1345 **
1346 ** Function         nfa_ee_build_discover_req_evt
1347 **
1348 ** Description      Build NFA_EE_DISCOVER_REQ_EVT for all active NFCEE
1349 **
1350 ** Returns          void
1351 **
1352 *******************************************************************************/
nfa_ee_build_discover_req_evt(tNFA_EE_DISCOVER_REQ * p_evt_data)1353 static void nfa_ee_build_discover_req_evt (tNFA_EE_DISCOVER_REQ *p_evt_data)
1354 {
1355     tNFA_EE_ECB           *p_cb;
1356     tNFA_EE_DISCOVER_INFO *p_info;
1357     UINT8                 xx;
1358 
1359     if (!p_evt_data)
1360         return;
1361 
1362     p_evt_data->num_ee = 0;
1363     p_cb               = nfa_ee_cb.ecb;
1364     p_info             = p_evt_data->ee_disc_info;
1365 
1366     for (xx = 0; xx < nfa_ee_cb.cur_ee; xx++, p_cb++)
1367     {
1368         if (  (p_cb->ee_status & NFA_EE_STATUS_INT_MASK)
1369             ||(p_cb->ee_status != NFA_EE_STATUS_ACTIVE)
1370             ||((p_cb->ecb_flags & NFA_EE_ECB_FLAGS_DISC_REQ) == 0)  )
1371         {
1372             continue;
1373         }
1374         p_info->ee_handle       = (tNFA_HANDLE)p_cb->nfcee_id | NFA_HANDLE_GROUP_EE;
1375         p_info->la_protocol     = p_cb->la_protocol;
1376         p_info->lb_protocol     = p_cb->lb_protocol;
1377         p_info->lf_protocol     = p_cb->lf_protocol;
1378         p_info->lbp_protocol    = p_cb->lbp_protocol;
1379         p_evt_data->num_ee++;
1380         p_info++;
1381 
1382         NFA_TRACE_DEBUG6 ("[%d] ee_handle:0x%x, listen protocol A:%d, B:%d, F:%d, BP:%d",
1383                           p_evt_data->num_ee, p_cb->nfcee_id,
1384                           p_cb->la_protocol, p_cb->lb_protocol, p_cb->lf_protocol, p_cb->lbp_protocol);
1385     }
1386 
1387     p_evt_data->status     = NFA_STATUS_OK;
1388 }
1389 
1390 /*******************************************************************************
1391 **
1392 ** Function         nfa_ee_report_discover_req_evt
1393 **
1394 ** Description      Report NFA_EE_DISCOVER_REQ_EVT for all active NFCEE
1395 **
1396 ** Returns          void
1397 **
1398 *******************************************************************************/
nfa_ee_report_discover_req_evt(void)1399 static void nfa_ee_report_discover_req_evt(void)
1400 {
1401     tNFA_EE_DISCOVER_REQ    evt_data;
1402 
1403     if (nfa_ee_cb.p_enable_cback)
1404         (*nfa_ee_cb.p_enable_cback) (NFA_EE_DISC_STS_REQ);
1405 
1406 
1407     /* if this is restoring NFCC */
1408     if (!nfa_dm_is_active ())
1409     {
1410         NFA_TRACE_DEBUG0 ("nfa_ee_report_discover_req_evt DM is not active");
1411         return;
1412     }
1413 
1414     nfa_ee_build_discover_req_evt (&evt_data);
1415     nfa_ee_report_event(NULL, NFA_EE_DISCOVER_REQ_EVT, (tNFA_EE_CBACK_DATA *)&evt_data);
1416 }
1417 
1418 /*******************************************************************************
1419 **
1420 ** Function         nfa_ee_nci_mode_set_rsp
1421 **
1422 ** Description      Process the result for NFCEE ModeSet response
1423 **
1424 ** Returns          void
1425 **
1426 *******************************************************************************/
nfa_ee_nci_mode_set_rsp(tNFA_EE_MSG * p_data)1427 void nfa_ee_nci_mode_set_rsp(tNFA_EE_MSG *p_data)
1428 {
1429     tNFA_EE_ECB *p_cb;
1430     tNFA_EE_MODE_SET    mode_set;
1431     tNFC_NFCEE_MODE_SET_REVT    *p_rsp = p_data->mode_set_rsp.p_data;
1432 
1433     NFA_TRACE_DEBUG2 ("nfa_ee_nci_mode_set_rsp() handle:0x%02x mode:%d", p_rsp->nfcee_id, p_rsp->mode);
1434     p_cb = nfa_ee_find_ecb (p_rsp->nfcee_id);
1435     if (p_cb == NULL)
1436     {
1437         NFA_TRACE_ERROR1 ("nfa_ee_nci_mode_set_rsp() Can not find cb for handle:0x%02x", p_rsp->nfcee_id);
1438         return;
1439     }
1440 
1441     /* update routing table and vs on mode change */
1442     nfa_ee_start_timer();
1443 
1444     if (p_rsp->status == NFA_STATUS_OK)
1445     {
1446 
1447         if (p_rsp->mode == NFA_EE_MD_ACTIVATE)
1448         {
1449             p_cb->ee_status = NFC_NFCEE_STATUS_ACTIVE;
1450         }
1451         else
1452         {
1453             if (p_cb->tech_switch_on | p_cb->tech_switch_off | p_cb->tech_battery_off |
1454                 p_cb->proto_switch_on| p_cb->proto_switch_off| p_cb->proto_battery_off |
1455                 p_cb->aid_entries)
1456             {
1457                 /* this NFCEE still has configuration when deactivated. clear the configuration */
1458                 nfa_ee_cb.ee_cfged  &= ~nfa_ee_ecb_to_mask(p_cb);
1459                 nfa_ee_cb.ee_cfg_sts|= NFA_EE_STS_CHANGED_ROUTING;
1460                 NFA_TRACE_DEBUG0("deactivating/still configured. Force update");
1461             }
1462             p_cb->tech_switch_on    = p_cb->tech_switch_off = p_cb->tech_battery_off    = 0;
1463             p_cb->proto_switch_on   = p_cb->proto_switch_off= p_cb->proto_battery_off   = 0;
1464             p_cb->aid_entries       = 0;
1465             p_cb->ee_status = NFC_NFCEE_STATUS_INACTIVE;
1466         }
1467     }
1468     NFA_TRACE_DEBUG4 ("status:%d ecb_flags  :0x%02x ee_cfged:0x%02x ee_status:%d",
1469         p_rsp->status, p_cb->ecb_flags  , nfa_ee_cb.ee_cfged, p_cb->ee_status);
1470     if (p_cb->ecb_flags   & NFA_EE_ECB_FLAGS_RESTORE)
1471     {
1472         if (p_cb->conn_st == NFA_EE_CONN_ST_CONN)
1473         {
1474             /* NFA_HCI module handles restoring configurations for HCI access */
1475             if (p_cb->ee_interface[0] != NFC_NFCEE_INTERFACE_HCI_ACCESS)
1476             {
1477                 NFC_ConnCreate(NCI_DEST_TYPE_NFCEE, p_cb->nfcee_id,  p_cb->use_interface, nfa_ee_conn_cback);
1478             }
1479         }
1480         else
1481         {
1482             p_cb->ecb_flags   &= ~NFA_EE_ECB_FLAGS_RESTORE;
1483             nfa_ee_check_restore_complete();
1484         }
1485     }
1486     else
1487     {
1488         mode_set.status     = p_rsp->status;
1489         mode_set.ee_handle  = (tNFA_HANDLE)p_rsp->nfcee_id | NFA_HANDLE_GROUP_EE;
1490         mode_set.ee_status  = p_cb->ee_status;
1491 
1492         nfa_ee_report_event(p_cb->p_ee_cback, NFA_EE_MODE_SET_EVT, (tNFA_EE_CBACK_DATA *)&mode_set);
1493 
1494         if ((p_cb->ee_status == NFC_NFCEE_STATUS_INACTIVE)
1495             || (p_cb->ee_status == NFC_NFCEE_STATUS_ACTIVE))
1496         {
1497             /* Report NFA_EE_DISCOVER_REQ_EVT for all active NFCEE */
1498             nfa_ee_report_discover_req_evt();
1499         }
1500     }
1501 }
1502 
1503 /*******************************************************************************
1504 **
1505 ** Function         nfa_ee_report_update_evt
1506 **
1507 ** Description      Check if need to report NFA_EE_UPDATED_EVT
1508 **
1509 ** Returns          void
1510 **
1511 *******************************************************************************/
nfa_ee_report_update_evt(void)1512 void nfa_ee_report_update_evt (void)
1513 {
1514     tNFA_EE_CBACK_DATA  evt_data;
1515 
1516     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);
1517     if (nfa_ee_cb.wait_rsp == 0)
1518     {
1519         nfa_ee_cb.ee_wait_evt &= ~NFA_EE_WAIT_UPDATE_RSP;
1520 
1521         if (nfa_ee_cb.ee_wait_evt & NFA_EE_WAIT_UPDATE)
1522         {
1523             nfa_ee_cb.ee_wait_evt &= ~NFA_EE_WAIT_UPDATE;
1524             /* finished updating NFCC; report NFA_EE_UPDATED_EVT now */
1525             evt_data.status       = NFA_STATUS_OK;
1526             nfa_ee_report_event (NULL, NFA_EE_UPDATED_EVT, &evt_data);
1527         }
1528     }
1529 }
1530 
1531 /*******************************************************************************
1532 **
1533 ** Function         nfa_ee_nci_wait_rsp
1534 **
1535 ** Description      Process the result for NCI response
1536 **
1537 ** Returns          void
1538 **
1539 *******************************************************************************/
nfa_ee_nci_wait_rsp(tNFA_EE_MSG * p_data)1540 void nfa_ee_nci_wait_rsp(tNFA_EE_MSG *p_data)
1541 {
1542     tNFA_EE_NCI_WAIT_RSP *p_rsp = &p_data->wait_rsp;
1543 
1544     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);
1545     if (nfa_ee_cb.wait_rsp)
1546     {
1547         if (p_rsp->opcode == NCI_MSG_RF_SET_ROUTING)
1548             nfa_ee_cb.wait_rsp--;
1549     }
1550     nfa_ee_report_update_evt ();
1551 }
1552 
1553 /*******************************************************************************
1554 **
1555 ** Function         nfa_ee_nci_conn
1556 **
1557 ** Description      process the connection callback events
1558 **
1559 ** Returns          void
1560 **
1561 *******************************************************************************/
nfa_ee_nci_conn(tNFA_EE_MSG * p_data)1562 void nfa_ee_nci_conn(tNFA_EE_MSG *p_data)
1563 {
1564     tNFA_EE_ECB      *p_cb;
1565     tNFA_EE_NCI_CONN    *p_cbk   = &p_data->conn;
1566     tNFC_CONN           *p_conn  = p_data->conn.p_data;
1567     BT_HDR              *p_pkt   = NULL;
1568     tNFA_EE_CBACK_DATA  evt_data = {0};
1569     tNFA_EE_EVT         event    = NFA_EE_INVALID;
1570     tNFA_EE_CBACK       *p_cback = NULL;
1571 
1572     if (p_cbk->event == NFC_CONN_CREATE_CEVT)
1573     {
1574         p_cb = nfa_ee_find_ecb (p_cbk->p_data->conn_create.id);
1575     }
1576     else
1577     {
1578         p_cb = nfa_ee_find_ecb_by_conn_id (p_cbk->conn_id);
1579         if (p_cbk->event == NFC_DATA_CEVT)
1580             p_pkt = p_conn->data.p_data;
1581     }
1582 
1583     if (p_cb)
1584     {
1585         p_cback         = p_cb->p_ee_cback;
1586         evt_data.handle = (tNFA_HANDLE)p_cb->nfcee_id | NFA_HANDLE_GROUP_EE;
1587         switch (p_cbk->event)
1588         {
1589         case NFC_CONN_CREATE_CEVT:
1590             if (p_conn->conn_create.status == NFC_STATUS_OK)
1591             {
1592                 p_cb->conn_id = p_cbk->conn_id;
1593                 p_cb->conn_st = NFA_EE_CONN_ST_CONN;
1594             }
1595             else
1596             {
1597                 p_cb->conn_st = NFA_EE_CONN_ST_NONE;
1598             }
1599             if (p_cb->ecb_flags & NFA_EE_ECB_FLAGS_RESTORE)
1600             {
1601                 p_cb->ecb_flags &= ~NFA_EE_ECB_FLAGS_RESTORE;
1602                 nfa_ee_check_restore_complete();
1603             }
1604             else
1605             {
1606                 evt_data.connect.status       = p_conn->conn_create.status;
1607                 evt_data.connect.ee_interface = p_cb->use_interface;
1608                 event = NFA_EE_CONNECT_EVT;
1609             }
1610             break;
1611 
1612         case NFC_CONN_CLOSE_CEVT:
1613             if (p_cb->conn_st != NFA_EE_CONN_ST_DISC)
1614                 event = NFA_EE_DISCONNECT_EVT;
1615             p_cb->conn_st    = NFA_EE_CONN_ST_NONE;
1616             p_cb->p_ee_cback = NULL;
1617             p_cb->conn_id    = 0;
1618             if (nfa_ee_cb.em_state == NFA_EE_EM_STATE_DISABLING)
1619             {
1620                 if (nfa_ee_cb.ee_flags & NFA_EE_FLAG_WAIT_DISCONN)
1621                 {
1622                     if (nfa_ee_cb.num_ee_expecting)
1623                     {
1624                         nfa_ee_cb.num_ee_expecting--;
1625                     }
1626                 }
1627                 if (nfa_ee_cb.num_ee_expecting == 0)
1628                 {
1629                     nfa_ee_cb.ee_flags &= ~NFA_EE_FLAG_WAIT_DISCONN;
1630                     nfa_ee_check_disable();
1631                 }
1632             }
1633             break;
1634 
1635         case NFC_DATA_CEVT:
1636             if (p_cb->conn_st == NFA_EE_CONN_ST_CONN)
1637             {
1638                 /* report data event only in connected state */
1639                 if (p_cb->p_ee_cback && p_pkt)
1640                 {
1641                     evt_data.data.len   = p_pkt->len;
1642                     evt_data.data.p_buf = (UINT8 *)(p_pkt+1) + p_pkt->offset;
1643                     event               = NFA_EE_DATA_EVT;
1644                     p_pkt               = NULL; /* so this function does not free this GKI buffer */
1645                 }
1646             }
1647             break;
1648         }
1649 
1650         if ((event != NFA_EE_INVALID) && (p_cback))
1651             (*p_cback)(event, &evt_data);
1652     }
1653     if (p_pkt)
1654         GKI_freebuf (p_pkt);
1655 }
1656 
1657 
1658 /*******************************************************************************
1659 **
1660 ** Function         nfa_ee_nci_action_ntf
1661 **
1662 ** Description      process the NFCEE action callback event
1663 **
1664 ** Returns          void
1665 **
1666 *******************************************************************************/
nfa_ee_nci_action_ntf(tNFA_EE_MSG * p_data)1667 void nfa_ee_nci_action_ntf(tNFA_EE_MSG *p_data)
1668 {
1669     tNFC_EE_ACTION_REVT *p_cbk = p_data->act.p_data;
1670     tNFA_EE_ACTION      evt_data;
1671 
1672     evt_data.ee_handle  = (tNFA_HANDLE)p_cbk->nfcee_id | NFA_HANDLE_GROUP_EE;
1673     evt_data.trigger    = p_cbk->act_data.trigger;
1674     memcpy (&(evt_data.param), &(p_cbk->act_data.param), sizeof (tNFA_EE_ACTION_PARAM));
1675     nfa_ee_report_event(NULL, NFA_EE_ACTION_EVT, (tNFA_EE_CBACK_DATA *)&evt_data);
1676 }
1677 
1678 /*******************************************************************************
1679 **
1680 ** Function         nfa_ee_nci_disc_req_ntf
1681 **
1682 ** Description      process the NFCEE discover request callback event
1683 **
1684 ** Returns          void
1685 **
1686 *******************************************************************************/
nfa_ee_nci_disc_req_ntf(tNFA_EE_MSG * p_data)1687 void nfa_ee_nci_disc_req_ntf(tNFA_EE_MSG *p_data)
1688 {
1689     tNFC_EE_DISCOVER_REQ_REVT   *p_cbk = p_data->disc_req.p_data;
1690     tNFA_HANDLE         ee_handle;
1691     tNFA_EE_ECB         *p_cb = NULL;
1692     UINT8               report_ntf = 0;
1693     UINT8 xx;
1694 
1695     NFA_TRACE_DEBUG2 ("nfa_ee_nci_disc_req_ntf () num_info: %d cur_ee:%d", p_cbk->num_info, nfa_ee_cb.cur_ee );
1696 
1697     for (xx = 0; xx < p_cbk->num_info; xx++)
1698     {
1699         ee_handle = NFA_HANDLE_GROUP_EE|p_cbk->info[xx].nfcee_id;
1700 
1701         p_cb = nfa_ee_find_ecb (p_cbk->info[xx].nfcee_id);
1702         if (!p_cb)
1703         {
1704             NFA_TRACE_DEBUG1 ("Cannot find cb for NFCEE: 0x%x", p_cbk->info[xx].nfcee_id);
1705             p_cb = nfa_ee_find_ecb (NFA_EE_INVALID);
1706             if (p_cb)
1707             {
1708                 p_cb->nfcee_id   = p_cbk->info[xx].nfcee_id;
1709                 p_cb->ecb_flags |= NFA_EE_ECB_FLAGS_ORDER;
1710             }
1711             else
1712             {
1713                 NFA_TRACE_ERROR1 ("Cannot allocate cb for NFCEE: 0x%x", p_cbk->info[xx].nfcee_id);
1714                 continue;
1715             }
1716         }
1717         else
1718         {
1719             report_ntf  |= nfa_ee_ecb_to_mask (p_cb);
1720         }
1721 
1722         p_cb->ecb_flags |= NFA_EE_ECB_FLAGS_DISC_REQ;
1723         if (p_cbk->info[xx].op == NFC_EE_DISC_OP_ADD)
1724         {
1725             if (p_cbk->info[xx].tech_n_mode == NFC_DISCOVERY_TYPE_LISTEN_A)
1726             {
1727                 p_cb->la_protocol = p_cbk->info[xx].protocol;
1728             }
1729             else if (p_cbk->info[xx].tech_n_mode == NFC_DISCOVERY_TYPE_LISTEN_B)
1730             {
1731                 p_cb->lb_protocol = p_cbk->info[xx].protocol;
1732             }
1733             else if (p_cbk->info[xx].tech_n_mode == NFC_DISCOVERY_TYPE_LISTEN_F)
1734             {
1735                 p_cb->lf_protocol = p_cbk->info[xx].protocol;
1736             }
1737             else if (p_cbk->info[xx].tech_n_mode == NFC_DISCOVERY_TYPE_LISTEN_B_PRIME)
1738             {
1739                 p_cb->lbp_protocol = p_cbk->info[xx].protocol;
1740             }
1741             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",
1742                 p_cb->nfcee_id, p_cb->ee_status, p_cb->ecb_flags,
1743                 p_cb->la_protocol, p_cb->lb_protocol, p_cb->lf_protocol);
1744         }
1745         else
1746         {
1747             if (p_cbk->info[xx].tech_n_mode == NFC_DISCOVERY_TYPE_LISTEN_A)
1748             {
1749                 p_cb->la_protocol = 0;
1750             }
1751             else if (p_cbk->info[xx].tech_n_mode == NFC_DISCOVERY_TYPE_LISTEN_B)
1752             {
1753                 p_cb->lb_protocol = 0;
1754             }
1755             else if (p_cbk->info[xx].tech_n_mode == NFC_DISCOVERY_TYPE_LISTEN_F)
1756             {
1757                 p_cb->lf_protocol = 0;
1758             }
1759             else if (p_cbk->info[xx].tech_n_mode == NFC_DISCOVERY_TYPE_LISTEN_B_PRIME)
1760             {
1761                 p_cb->lbp_protocol = 0;
1762             }
1763         }
1764     }
1765 
1766 
1767     /* Report NFA_EE_DISCOVER_REQ_EVT for all active NFCEE */
1768     if (report_ntf)
1769         nfa_ee_report_discover_req_evt();
1770 
1771 }
1772 
1773 /*******************************************************************************
1774 **
1775 ** Function         nfa_ee_is_active
1776 **
1777 ** Description      Check if the given NFCEE is active
1778 **
1779 ** Returns          TRUE if the given NFCEE is active
1780 **
1781 *******************************************************************************/
nfa_ee_is_active(tNFA_HANDLE nfcee_id)1782 BOOLEAN nfa_ee_is_active (tNFA_HANDLE nfcee_id)
1783 {
1784     BOOLEAN is_active = FALSE;
1785     int     xx;
1786     tNFA_EE_ECB  *p_cb = nfa_ee_cb.ecb;
1787 
1788     if ((NFA_HANDLE_GROUP_MASK & nfcee_id) == NFA_HANDLE_GROUP_EE)
1789         nfcee_id    &= NFA_HANDLE_MASK;
1790 
1791     /* compose output */
1792     for (xx = 0; xx < nfa_ee_cb.cur_ee; xx++, p_cb++)
1793     {
1794         if ((tNFA_HANDLE)p_cb->nfcee_id == nfcee_id)
1795         {
1796             if (p_cb->ee_status == NFA_EE_STATUS_ACTIVE)
1797             {
1798                 is_active = TRUE;
1799             }
1800             break;
1801         }
1802     }
1803     return is_active;
1804 }
1805 
1806 /*******************************************************************************
1807 **
1808 ** Function         nfa_ee_get_tech_route
1809 **
1810 ** Description      Given a power state, find the technology routing destination.
1811 **                  The result is filled in the given p_handles
1812 **                  in the order of A, B, F, Bprime
1813 **
1814 ** Returns          None
1815 **
1816 *******************************************************************************/
nfa_ee_get_tech_route(UINT8 power_state,UINT8 * p_handles)1817 void nfa_ee_get_tech_route (UINT8 power_state, UINT8 *p_handles)
1818 {
1819     int     xx, yy;
1820     tNFA_EE_ECB *p_cb;
1821     UINT8   tech_mask_list[NFA_EE_MAX_TECH_ROUTE] =
1822     {
1823         NFA_TECHNOLOGY_MASK_A,
1824         NFA_TECHNOLOGY_MASK_B,
1825         NFA_TECHNOLOGY_MASK_F,
1826         NFA_TECHNOLOGY_MASK_B_PRIME
1827     };
1828 
1829     NFA_TRACE_DEBUG1("nfa_ee_get_tech_route(): %d", power_state);
1830 
1831     for (xx = 0; xx < NFA_EE_MAX_TECH_ROUTE; xx++)
1832     {
1833         p_handles[xx] = NFC_DH_ID;
1834         p_cb = &nfa_ee_cb.ecb[nfa_ee_cb.cur_ee - 1];
1835         for (yy = 0; yy < nfa_ee_cb.cur_ee; yy++, p_cb--)
1836         {
1837             if (p_cb->ee_status == NFC_NFCEE_STATUS_ACTIVE)
1838             {
1839                 switch (power_state)
1840                 {
1841                 case NFA_EE_PWR_STATE_ON:
1842                     if (p_cb->tech_switch_on & tech_mask_list[xx])
1843                         p_handles[xx] = p_cb->nfcee_id;
1844                     break;
1845                 case NFA_EE_PWR_STATE_SWITCH_OFF:
1846                     if (p_cb->tech_switch_off & tech_mask_list[xx])
1847                         p_handles[xx] = p_cb->nfcee_id;
1848                     break;
1849                 case NFA_EE_PWR_STATE_BATT_OFF:
1850                     if (p_cb->tech_battery_off & tech_mask_list[xx])
1851                         p_handles[xx] = p_cb->nfcee_id;
1852                     break;
1853                 }
1854             }
1855         }
1856     }
1857     NFA_TRACE_DEBUG4("0x%x, 0x%x, 0x%x, 0x%x", p_handles[0], p_handles[1], p_handles[2], p_handles[3]);
1858 }
1859 
1860 /*******************************************************************************
1861 **
1862 ** Function         nfa_ee_check_set_routing
1863 **
1864 ** Description      If the new size exceeds the capacity of next block,
1865 **                  send the routing command now and reset the related parameters
1866 **
1867 ** Returns          void
1868 **
1869 *******************************************************************************/
nfa_ee_check_set_routing(UINT16 new_size,int * p_max_len,UINT8 * p,int * p_cur_offset)1870 void nfa_ee_check_set_routing(UINT16 new_size, int *p_max_len, UINT8 *p, int *p_cur_offset)
1871 {
1872     UINT8   max_tlv = (UINT8)((*p_max_len > NFA_EE_ROUT_MAX_TLV_SIZE)?NFA_EE_ROUT_MAX_TLV_SIZE:*p_max_len);
1873     tNFA_STATUS status = NFA_STATUS_OK;
1874 
1875     if (new_size + *p_cur_offset > max_tlv)
1876     {
1877         if (NFC_SetRouting(TRUE, *p, *p_cur_offset, p + 1) == NFA_STATUS_OK)
1878         {
1879             nfa_ee_cb.wait_rsp++;
1880         }
1881         /* after the routing command is sent, re-use the same buffer to send the next routing command.
1882          * reset the related parameters */
1883         if (*p_max_len > *p_cur_offset)
1884             *p_max_len     -= *p_cur_offset;/* the max is reduced */
1885         else
1886             *p_max_len      = 0;
1887         *p_cur_offset   = 0;                /* nothing is in queue any more */
1888         *p              = 0;                /* num_tlv=0 */
1889     }
1890 }
1891 
1892 /*******************************************************************************
1893 **
1894 ** Function         nfa_ee_route_add_one_ecb
1895 **
1896 ** Description      Add the routing entries for one NFCEE/DH
1897 **
1898 ** Returns          NFA_STATUS_OK, if ok to continue
1899 **
1900 *******************************************************************************/
nfa_ee_route_add_one_ecb(tNFA_EE_ECB * p_cb,int * p_max_len,BOOLEAN more,UINT8 * ps,int * p_cur_offset)1901 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)
1902 {
1903     UINT8   *p, *pa;
1904     UINT16  tlv_size;
1905     UINT8   num_tlv, len;
1906     int     xx;
1907     int     start_offset;
1908     UINT8   power_cfg = 0;
1909     UINT8   *pp = ps + *p_cur_offset;
1910     UINT8   entry_size;
1911     UINT8   max_tlv;
1912     UINT8   *p_start;
1913     UINT8   new_size;
1914     tNFA_STATUS status = NFA_STATUS_OK;
1915 
1916     nfa_ee_check_set_routing (p_cb->size_mask, p_max_len, ps, p_cur_offset);
1917     max_tlv = (UINT8)((*p_max_len > NFA_EE_ROUT_MAX_TLV_SIZE)?NFA_EE_ROUT_MAX_TLV_SIZE:*p_max_len);
1918     /* use the first byte of the buffer (ps) to keep the num_tlv */
1919     num_tlv  = *ps;
1920     NFA_TRACE_DEBUG5 ("nfa_ee_route_add_one_ecb max_len:%d, max_tlv:%d, cur_offset:%d, more:%d, num_tlv:%d",
1921         *p_max_len, max_tlv, *p_cur_offset, more, num_tlv);
1922     pp       = ps + 1 + *p_cur_offset;
1923     p        = pp;
1924     tlv_size = (UINT8)*p_cur_offset;
1925     /* add the Technology based routing */
1926     for (xx = 0; xx < NFA_EE_NUM_TECH; xx++)
1927     {
1928         power_cfg = 0;
1929         if (p_cb->tech_switch_on & nfa_ee_tech_mask_list[xx])
1930             power_cfg |= NCI_ROUTE_PWR_STATE_ON;
1931         if (p_cb->tech_switch_off & nfa_ee_tech_mask_list[xx])
1932             power_cfg |= NCI_ROUTE_PWR_STATE_SWITCH_OFF;
1933         if (p_cb->tech_battery_off & nfa_ee_tech_mask_list[xx])
1934             power_cfg |= NCI_ROUTE_PWR_STATE_BATT_OFF;
1935         if (power_cfg)
1936         {
1937             *pp++   = NFC_ROUTE_TAG_TECH;
1938             *pp++   = 3;
1939             *pp++   = p_cb->nfcee_id;
1940             *pp++   = power_cfg;
1941             *pp++   = nfa_ee_tech_list[xx];
1942             num_tlv++;
1943             if (power_cfg != NCI_ROUTE_PWR_STATE_ON)
1944                 nfa_ee_cb.ee_cfged  |= NFA_EE_CFGED_OFF_ROUTING;
1945         }
1946     }
1947 
1948     /* add the Protocol based routing */
1949     for (xx = 0; xx < NFA_EE_NUM_PROTO; xx++)
1950     {
1951         power_cfg = 0;
1952         if (p_cb->proto_switch_on & nfa_ee_proto_mask_list[xx])
1953             power_cfg |= NCI_ROUTE_PWR_STATE_ON;
1954         if (p_cb->proto_switch_off & nfa_ee_proto_mask_list[xx])
1955             power_cfg |= NCI_ROUTE_PWR_STATE_SWITCH_OFF;
1956         if (p_cb->proto_battery_off & nfa_ee_proto_mask_list[xx])
1957             power_cfg |= NCI_ROUTE_PWR_STATE_BATT_OFF;
1958         if (power_cfg)
1959         {
1960             *pp++   = NFC_ROUTE_TAG_PROTO;
1961             *pp++   = 3;
1962             *pp++   = p_cb->nfcee_id;
1963             *pp++   = power_cfg;
1964             *pp++   = nfa_ee_proto_list[xx];
1965             num_tlv++;
1966             if (power_cfg != NCI_ROUTE_PWR_STATE_ON)
1967                 nfa_ee_cb.ee_cfged  |= NFA_EE_CFGED_OFF_ROUTING;
1968         }
1969     }
1970 
1971     /* add NFC-DEP routing to HOST */
1972     if (p_cb->nfcee_id == NFC_DH_ID)
1973     {
1974         *pp++   = NFC_ROUTE_TAG_PROTO;
1975         *pp++   = 3;
1976         *pp++   = NFC_DH_ID;
1977         *pp++   = NCI_ROUTE_PWR_STATE_ON;
1978         *pp++   = NFC_PROTOCOL_NFC_DEP;
1979         num_tlv++;
1980     }
1981 
1982     /* update the num_tlv and current offset */
1983     entry_size       = (UINT8)(pp - p);
1984     *p_cur_offset   += entry_size;
1985     *ps              = num_tlv;
1986     /* add the AID routing */
1987     if (p_cb->aid_entries)
1988     {
1989         start_offset = 0;
1990         for (xx = 0; xx < p_cb->aid_entries; xx++)
1991         {
1992             p_start     = pp; /* rememebr the beginning of this AID routing entry, just in case we need to put it in next command */
1993             /* add one AID entry */
1994             if (p_cb->aid_rt_info[xx] & NFA_EE_AE_ROUTE)
1995             {
1996                 num_tlv++;
1997                 pa      = &p_cb->aid_cfg[start_offset];
1998                 pa ++; /* EMV tag */
1999                 len     = *pa++; /* aid_len */
2000                 *pp++   = NFC_ROUTE_TAG_AID;
2001                 *pp++   = len + 2;
2002                 *pp++   = p_cb->nfcee_id;
2003                 *pp++   = p_cb->aid_pwr_cfg[xx];
2004                 /* copy the AID */
2005                 memcpy(pp, pa, len);
2006                 pp     += len;
2007             }
2008             start_offset += p_cb->aid_len[xx];
2009             new_size        = (UINT8)(pp - p_start);
2010             nfa_ee_check_set_routing(new_size, p_max_len, ps, p_cur_offset);
2011             if (*ps == 0)
2012             {
2013                 /* just sent routing command, update local */
2014                 *ps      = 1;
2015                 num_tlv  = *ps;
2016                 *p_cur_offset = new_size;
2017                 pp       = ps + 1;
2018                 p        = pp;
2019                 tlv_size = (UINT8)*p_cur_offset;
2020                 max_tlv  = (UINT8)((*p_max_len > NFA_EE_ROUT_MAX_TLV_SIZE)?NFA_EE_ROUT_MAX_TLV_SIZE:*p_max_len);
2021                 memcpy (p, p_start, new_size);
2022                 pp      += new_size;
2023             }
2024             else
2025             {
2026                 /* add the new entry */
2027                 *ps              = num_tlv;
2028                 *p_cur_offset   += new_size;
2029             }
2030         }
2031     }
2032 
2033     tlv_size   = nfa_ee_total_lmrt_size();
2034     if (tlv_size)
2035     {
2036         nfa_ee_cb.ee_cfged |= nfa_ee_ecb_to_mask(p_cb);
2037     }
2038     if (p_cb->ecb_flags   & NFA_EE_ECB_FLAGS_ROUTING)
2039     {
2040         nfa_ee_cb.ee_cfg_sts   |= NFA_EE_STS_CHANGED_ROUTING;
2041     }
2042     NFA_TRACE_DEBUG2 ("ee_cfg_sts:0x%02x lmrt_size:%d", nfa_ee_cb.ee_cfg_sts, tlv_size);
2043 
2044     if (more == FALSE)
2045     {
2046         /* last entry. update routing table now */
2047         if (nfa_ee_cb.ee_cfg_sts & NFA_EE_STS_CHANGED_ROUTING)
2048         {
2049             if (tlv_size)
2050             {
2051                 nfa_ee_cb.ee_cfg_sts       |= NFA_EE_STS_PREV_ROUTING;
2052             }
2053             else
2054             {
2055                 nfa_ee_cb.ee_cfg_sts       &= ~NFA_EE_STS_PREV_ROUTING;
2056             }
2057             NFA_TRACE_DEBUG2 ("nfa_ee_route_add_one_ecb: set routing num_tlv:%d tlv_size:%d", num_tlv, tlv_size);
2058             if (NFC_SetRouting(more, num_tlv, (UINT8)(*p_cur_offset), ps + 1) == NFA_STATUS_OK)
2059             {
2060                 nfa_ee_cb.wait_rsp++;
2061             }
2062         }
2063         else if (nfa_ee_cb.ee_cfg_sts & NFA_EE_STS_PREV_ROUTING)
2064         {
2065             if (tlv_size == 0)
2066             {
2067                 nfa_ee_cb.ee_cfg_sts       &= ~NFA_EE_STS_PREV_ROUTING;
2068                 /* indicated routing is configured to NFCC */
2069                 nfa_ee_cb.ee_cfg_sts       |= NFA_EE_STS_CHANGED_ROUTING;
2070                 if (NFC_SetRouting(more, 0, 0, ps + 1) == NFA_STATUS_OK)
2071                 {
2072                     nfa_ee_cb.wait_rsp++;
2073                 }
2074             }
2075         }
2076     }
2077 
2078     return status;
2079 }
2080 
2081 
2082 /*******************************************************************************
2083 **
2084 ** Function         nfa_ee_need_recfg
2085 **
2086 ** Description      Check if any API function to configure the routing table or
2087 **                  VS is called since last update
2088 **
2089 **                  The algorithm for the NFCEE configuration handling is as follows:
2090 **
2091 **                  Each NFCEE_ID/DH has its own control block - tNFA_EE_ECB
2092 **                  Each control block uses ecb_flags to keep track if an API
2093 **                  that changes routing/VS is invoked.
2094 **                  This ecb_flags is cleared at the end of nfa_ee_update_rout().
2095 **
2096 **                  nfa_ee_cb.ee_cfged is the bitmask of the control blocks with
2097 **                  routing/VS configuration and NFA_EE_CFGED_UPDATE_NOW.
2098 **                  nfa_ee_cb.ee_cfged is cleared and re-calculated at the end of
2099 **                  nfa_ee_update_rout().
2100 **
2101 **                  nfa_ee_cb.ee_cfg_sts is used to check is any status is changed
2102 **                  and the associated command is issued to NFCC.
2103 **                  nfa_ee_cb.ee_cfg_sts is AND with NFA_EE_STS_PREV at the end of
2104 **                  nfa_ee_update_rout() to clear the NFA_EE_STS_CHANGED bits
2105 **                  (except NFA_EE_STS_CHANGED_CANNED_VS is cleared in nfa_ee_vs_cback)
2106 **
2107 ** Returns          TRUE if any configuration is changed
2108 **
2109 *******************************************************************************/
nfa_ee_need_recfg(void)2110 static BOOLEAN nfa_ee_need_recfg(void)
2111 {
2112     BOOLEAN needed = FALSE;
2113     UINT32  xx;
2114     tNFA_EE_ECB  *p_cb;
2115     UINT8   mask;
2116 
2117     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);
2118     /* if no routing/vs is configured, do not need to send the info to NFCC */
2119     if (nfa_ee_cb.ee_cfged || nfa_ee_cb.ee_cfg_sts)
2120     {
2121         if (nfa_ee_cb.ee_cfg_sts & NFA_EE_STS_CHANGED)
2122         {
2123             needed = TRUE;
2124         }
2125         else
2126         {
2127             p_cb = &nfa_ee_cb.ecb[NFA_EE_CB_4_DH];
2128             mask = 1 << NFA_EE_CB_4_DH;
2129             for (xx = 0; xx <= nfa_ee_cb.cur_ee; xx++)
2130             {
2131                 NFA_TRACE_DEBUG3("%d: ecb_flags  : 0x%02x, mask: 0x%02x", xx, p_cb->ecb_flags  , mask);
2132                 if ((p_cb->ecb_flags  ) && (nfa_ee_cb.ee_cfged & mask))
2133                 {
2134                     needed = TRUE;
2135                     break;
2136                 }
2137                 p_cb = &nfa_ee_cb.ecb[xx];
2138                 mask = 1 << xx;
2139             }
2140         }
2141     }
2142 
2143     return needed;
2144 }
2145 
2146 /*******************************************************************************
2147 **
2148 ** Function         nfa_ee_rout_timeout
2149 **
2150 ** Description      Anytime VS or routing entries are changed,
2151 **                  a 1 second timer is started. This function is called when
2152 **                  the timer expires or NFA_EeUpdateNow() is called.
2153 **
2154 ** Returns          void
2155 **
2156 *******************************************************************************/
nfa_ee_rout_timeout(tNFA_EE_MSG * p_data)2157 void nfa_ee_rout_timeout(tNFA_EE_MSG *p_data)
2158 {
2159     UINT8               ee_cfged = nfa_ee_cb.ee_cfged;
2160 
2161     NFA_TRACE_DEBUG0("nfa_ee_rout_timeout()");
2162     if (nfa_ee_need_recfg())
2163     {
2164         /* discovery is not started */
2165         nfa_ee_update_rout();
2166     }
2167 
2168     if (nfa_ee_cb.wait_rsp)
2169         nfa_ee_cb.ee_wait_evt   |= NFA_EE_WAIT_UPDATE_RSP;
2170     if (ee_cfged & NFA_EE_CFGED_UPDATE_NOW)
2171     {
2172         /* need to report NFA_EE_UPDATED_EVT when done updating NFCC */
2173         nfa_ee_cb.ee_wait_evt   |= NFA_EE_WAIT_UPDATE;
2174         if (!nfa_ee_cb.wait_rsp)
2175         {
2176             nfa_ee_report_update_evt();
2177         }
2178     }
2179 }
2180 
2181 /*******************************************************************************
2182 **
2183 ** Function         nfa_ee_discv_timeout
2184 **
2185 ** Description
2186 **
2187 **
2188 **
2189 ** Returns          void
2190 **
2191 *******************************************************************************/
nfa_ee_discv_timeout(tNFA_EE_MSG * p_data)2192 void nfa_ee_discv_timeout(tNFA_EE_MSG *p_data)
2193 {
2194     NFC_NfceeDiscover(FALSE);
2195     if (nfa_ee_cb.p_enable_cback)
2196         (*nfa_ee_cb.p_enable_cback)(NFA_EE_DISC_STS_OFF);
2197 }
2198 
2199 /*******************************************************************************
2200 **
2201 ** Function         nfa_ee_lmrt_to_nfcc
2202 **
2203 ** Description      This function would set the listen mode routing table
2204 **                  to NFCC.
2205 **
2206 ** Returns          void
2207 **
2208 *******************************************************************************/
nfa_ee_lmrt_to_nfcc(tNFA_EE_MSG * p_data)2209 void nfa_ee_lmrt_to_nfcc(tNFA_EE_MSG *p_data)
2210 {
2211     int xx;
2212     tNFA_EE_ECB          *p_cb;
2213     UINT8   *p = NULL;
2214     BOOLEAN more = TRUE;
2215     UINT8   last_active = NFA_EE_INVALID;
2216     int     max_len, len;
2217     tNFA_STATUS status = NFA_STATUS_FAILED;
2218     int     cur_offset;
2219     UINT8   max_tlv;
2220 
2221     /* update routing table: DH and the activated NFCEEs */
2222     p = (UINT8 *)GKI_getbuf(NFA_EE_ROUT_BUF_SIZE);
2223     if (p == NULL)
2224     {
2225         NFA_TRACE_ERROR0 ("nfa_ee_lmrt_to_nfcc() no buffer to send routing info.");
2226         nfa_ee_report_event( NULL, NFA_EE_NO_MEM_ERR_EVT, (tNFA_EE_CBACK_DATA *)&status);
2227         return;
2228     }
2229 
2230     /* find the last active NFCEE. */
2231     p_cb = &nfa_ee_cb.ecb[nfa_ee_cb.cur_ee - 1];
2232     for (xx = 0; xx < nfa_ee_cb.cur_ee; xx++, p_cb--)
2233     {
2234         if (p_cb->ee_status == NFC_NFCEE_STATUS_ACTIVE)
2235         {
2236             if (last_active == NFA_EE_INVALID)
2237             {
2238                 last_active = p_cb->nfcee_id;
2239                 NFA_TRACE_DEBUG1 ("last_active: 0x%x", last_active);
2240             }
2241         }
2242     }
2243     if (last_active == NFA_EE_INVALID)
2244     {
2245         more = FALSE;
2246     }
2247 
2248     /* add the routing for DH first */
2249     status  = NFA_STATUS_OK;
2250     max_len = NFC_GetLmrtSize();
2251     max_tlv = (UINT8)((max_len > NFA_EE_ROUT_MAX_TLV_SIZE)?NFA_EE_ROUT_MAX_TLV_SIZE:max_len);
2252     cur_offset  = 0;
2253     /* use the first byte of the buffer (p) to keep the num_tlv */
2254     *p          = 0;
2255     status = nfa_ee_route_add_one_ecb(&nfa_ee_cb.ecb[NFA_EE_CB_4_DH], &max_len, more, p, &cur_offset);
2256 
2257     /* add only what is supported by NFCC. report overflow */
2258     if (status == NFA_STATUS_OK)
2259     {
2260         /* add the routing for NFCEEs */
2261         p_cb = &nfa_ee_cb.ecb[0];
2262         for (xx = 0; (xx < nfa_ee_cb.cur_ee) && more; xx++, p_cb++)
2263         {
2264             len = 0;
2265             if (p_cb->ee_status == NFC_NFCEE_STATUS_ACTIVE)
2266             {
2267                 NFA_TRACE_DEBUG2 ("nfcee_id:0x%x, last_active: 0x%x", p_cb->nfcee_id, last_active);
2268                 if (last_active == p_cb->nfcee_id)
2269                     more = FALSE;
2270                 status = nfa_ee_route_add_one_ecb(p_cb, &max_len, more, p, &cur_offset);
2271                 if (status != NFA_STATUS_OK)
2272                 {
2273                     more    = FALSE;
2274                 }
2275             }
2276         }
2277     }
2278     if (status != NFA_STATUS_OK)
2279     {
2280         nfa_ee_report_event( NULL, NFA_EE_ROUT_ERR_EVT, (tNFA_EE_CBACK_DATA *)&status);
2281     }
2282     GKI_freebuf(p);
2283 }
2284 
2285 /*******************************************************************************
2286 **
2287 ** Function         nfa_ee_update_rout
2288 **
2289 ** Description      This function would set the VS and listen mode routing table
2290 **                  to NFCC.
2291 **
2292 ** Returns          void
2293 **
2294 *******************************************************************************/
nfa_ee_update_rout(void)2295 void nfa_ee_update_rout(void)
2296 {
2297     int xx;
2298     tNFA_EE_ECB          *p_cb;
2299     UINT8   mask;
2300     BT_HDR  msg;
2301 
2302     NFA_TRACE_DEBUG1 ("nfa_ee_update_rout ee_cfg_sts:0x%02x", nfa_ee_cb.ee_cfg_sts);
2303 
2304     /* use action function to send routing and VS configuration to NFCC */
2305     msg.event = NFA_EE_CFG_TO_NFCC_EVT;
2306     nfa_ee_evt_hdlr (&msg);
2307 
2308     /* all configuration is updated to NFCC, clear the status mask */
2309     nfa_ee_cb.ee_cfg_sts   &= NFA_EE_STS_PREV;
2310     nfa_ee_cb.ee_cfged  = 0;
2311     p_cb                = &nfa_ee_cb.ecb[0];
2312     for (xx = 0; xx < NFA_EE_NUM_ECBS; xx++, p_cb++)
2313     {
2314         p_cb->ecb_flags     = 0;
2315         mask                = (1 << xx);
2316         if (p_cb->tech_switch_on | p_cb->tech_switch_off | p_cb->tech_battery_off |
2317             p_cb->proto_switch_on| p_cb->proto_switch_off| p_cb->proto_battery_off |
2318             p_cb->aid_entries)
2319         {
2320             /* this entry has routing configuration. mark it configured */
2321             nfa_ee_cb.ee_cfged  |= mask;
2322         }
2323     }
2324     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);
2325 }
2326 
2327 
2328