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