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