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