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