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