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