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