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