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