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