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