1 /******************************************************************************
2 *
3 * Copyright (C) 2011-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 the NFA_CE state machine.
22 *
23 ******************************************************************************/
24 #include <log/log.h>
25 #include <string.h>
26
27 #include <android-base/stringprintf.h>
28 #include <base/logging.h>
29
30 #include "ce_api.h"
31 #include "ndef_utils.h"
32 #include "nfa_ce_int.h"
33 #include "nfa_mem_co.h"
34
35 #if (NFC_NFCEE_INCLUDED == TRUE)
36 #include "nfa_ee_int.h"
37 #endif
38
39 using android::base::StringPrintf;
40
41 extern bool nfc_debug_enabled;
42
43 /*****************************************************************************
44 * Protocol-specific event handlers
45 *****************************************************************************/
46
47 /*******************************************************************************
48 **
49 ** Function nfa_ce_handle_t3t_evt
50 **
51 ** Description Handler for Type-3 tag card emulation events
52 **
53 ** Returns Nothing
54 **
55 *******************************************************************************/
nfa_ce_handle_t3t_evt(tCE_EVENT event,tCE_DATA * p_ce_data)56 void nfa_ce_handle_t3t_evt(tCE_EVENT event, tCE_DATA* p_ce_data) {
57 tNFA_CE_CB* p_cb = &nfa_ce_cb;
58 tNFA_CONN_EVT_DATA conn_evt;
59
60 DLOG_IF(INFO, nfc_debug_enabled)
61 << StringPrintf("nfa_ce_handle_t3t_evt: event 0x%x", event);
62 /* For the felica on host for nfcFcallback */
63 for (uint8_t idx = 0; idx < NFA_CE_LISTEN_INFO_IDX_INVALID; idx++) {
64 if ((p_cb->listen_info[idx].flags & NFA_CE_LISTEN_INFO_IN_USE) &&
65 (p_cb->listen_info[idx].flags & NFA_CE_LISTEN_INFO_FELICA) &&
66 (p_cb->listen_info[idx].flags & NFA_CE_LISTEN_INFO_T3T_ACTIVATE_PND)) {
67 p_cb->idx_cur_active = idx;
68 p_cb->p_active_conn_cback =
69 p_cb->listen_info[p_cb->idx_cur_active].p_conn_cback;
70 break;
71 }
72 }
73 switch (event) {
74 case CE_T3T_NDEF_UPDATE_START_EVT:
75 /* Notify app using callback associated with the active ndef */
76 if (p_cb->idx_cur_active == NFA_CE_LISTEN_INFO_IDX_NDEF) {
77 conn_evt.status = NFA_STATUS_OK;
78 (*p_cb->p_active_conn_cback)(NFA_CE_NDEF_WRITE_START_EVT, &conn_evt);
79 } else {
80 LOG(ERROR) << StringPrintf(
81 "nfa_ce_handle_t3t_evt: got CE_T3T_UPDATE_START_EVT, but no active "
82 "NDEF");
83 }
84 break;
85
86 case CE_T3T_NDEF_UPDATE_CPLT_EVT:
87 /* Notify app using callback associated with the active ndef */
88 if (p_cb->idx_cur_active == NFA_CE_LISTEN_INFO_IDX_NDEF) {
89 conn_evt.ndef_write_cplt.status = NFA_STATUS_OK;
90 conn_evt.ndef_write_cplt.len = p_ce_data->update_info.length;
91 conn_evt.ndef_write_cplt.p_data = p_ce_data->update_info.p_data;
92 (*p_cb->p_active_conn_cback)(NFA_CE_NDEF_WRITE_CPLT_EVT, &conn_evt);
93 } else {
94 LOG(ERROR) << StringPrintf(
95 "nfa_ce_handle_t3t_evt: got CE_T3T_UPDATE_CPLT_EVT, but no active "
96 "NDEF");
97 }
98 break;
99
100 case CE_T3T_RAW_FRAME_EVT:
101 if (p_cb->idx_cur_active == NFA_CE_LISTEN_INFO_IDX_NDEF) {
102 conn_evt.data.status = p_ce_data->raw_frame.status;
103 conn_evt.data.p_data = (uint8_t*)(p_ce_data->raw_frame.p_data + 1) +
104 p_ce_data->raw_frame.p_data->offset;
105 conn_evt.data.len = p_ce_data->raw_frame.p_data->len;
106 (*p_cb->p_active_conn_cback)(NFA_DATA_EVT, &conn_evt);
107 } else {
108 /* If we have not notified the app of activation, do so now */
109 if (p_cb->listen_info[p_cb->idx_cur_active].flags &
110 NFA_CE_LISTEN_INFO_T3T_ACTIVATE_PND) {
111 p_cb->listen_info[p_cb->idx_cur_active].flags &=
112 ~NFA_CE_LISTEN_INFO_T3T_ACTIVATE_PND;
113
114 conn_evt.ce_activated.handle =
115 NFA_HANDLE_GROUP_CE | ((tNFA_HANDLE)p_cb->idx_cur_active);
116 memcpy(&(conn_evt.ce_activated.activate_ntf),
117 &p_cb->activation_params, sizeof(tNFC_ACTIVATE_DEVT));
118 conn_evt.ce_activated.status = NFA_STATUS_OK;
119
120 (*p_cb->p_active_conn_cback)(NFA_CE_ACTIVATED_EVT, &conn_evt);
121 }
122 /* Notify app of t3t raw data */
123 conn_evt.ce_data.status = p_ce_data->raw_frame.status;
124 conn_evt.ce_data.handle =
125 (NFA_HANDLE_GROUP_CE | ((tNFA_HANDLE)p_cb->idx_cur_active));
126 conn_evt.ce_data.p_data = (uint8_t*)(p_ce_data->raw_frame.p_data + 1) +
127 p_ce_data->raw_frame.p_data->offset;
128 conn_evt.ce_data.len = p_ce_data->raw_frame.p_data->len;
129 (*p_cb->p_active_conn_cback)(NFA_CE_DATA_EVT, &conn_evt);
130 }
131 GKI_freebuf(p_ce_data->raw_frame.p_data);
132 break;
133
134 default:
135 DLOG_IF(INFO, nfc_debug_enabled) << StringPrintf(
136 "nfa_ce_handle_t3t_evt unhandled event=0x%02x", event);
137 break;
138 }
139 }
140
141 /*******************************************************************************
142 **
143 ** Function nfa_ce_handle_t4t_evt
144 **
145 ** Description Handler for Type-4 tag card emulation events (for NDEF case)
146 **
147 ** Returns Nothing
148 **
149 *******************************************************************************/
nfa_ce_handle_t4t_evt(tCE_EVENT event,tCE_DATA * p_ce_data)150 void nfa_ce_handle_t4t_evt(tCE_EVENT event, tCE_DATA* p_ce_data) {
151 tNFA_CE_CB* p_cb = &nfa_ce_cb;
152 tNFA_CONN_EVT_DATA conn_evt;
153
154 DLOG_IF(INFO, nfc_debug_enabled)
155 << StringPrintf("nfa_ce_handle_t4t_evt: event 0x%x", event);
156
157 /* AID for NDEF selected. we had notified the app of activation. */
158 p_cb->idx_cur_active = NFA_CE_LISTEN_INFO_IDX_NDEF;
159 if (p_cb->listen_info[p_cb->idx_cur_active].flags &
160 NFA_CE_LISTEN_INFO_T4T_ACTIVATE_PND) {
161 p_cb->p_active_conn_cback =
162 p_cb->listen_info[p_cb->idx_cur_active].p_conn_cback;
163 }
164
165 switch (event) {
166 case CE_T4T_NDEF_UPDATE_START_EVT:
167 conn_evt.status = NFA_STATUS_OK;
168 (*p_cb->p_active_conn_cback)(NFA_CE_NDEF_WRITE_START_EVT, &conn_evt);
169 break;
170
171 case CE_T4T_NDEF_UPDATE_CPLT_EVT:
172 conn_evt.ndef_write_cplt.len = p_ce_data->update_info.length;
173 conn_evt.ndef_write_cplt.p_data = p_ce_data->update_info.p_data;
174
175 if (NDEF_MsgValidate(p_ce_data->update_info.p_data,
176 p_ce_data->update_info.length, true) != NDEF_OK)
177 conn_evt.ndef_write_cplt.status = NFA_STATUS_FAILED;
178 else
179 conn_evt.ndef_write_cplt.status = NFA_STATUS_OK;
180
181 (*p_cb->p_active_conn_cback)(NFA_CE_NDEF_WRITE_CPLT_EVT, &conn_evt);
182 break;
183
184 case CE_T4T_NDEF_UPDATE_ABORT_EVT:
185 conn_evt.ndef_write_cplt.len = 0;
186 conn_evt.ndef_write_cplt.status = NFA_STATUS_FAILED;
187 conn_evt.ndef_write_cplt.p_data = nullptr;
188 (*p_cb->p_active_conn_cback)(NFA_CE_NDEF_WRITE_CPLT_EVT, &conn_evt);
189 break;
190
191 default:
192 /* CE_T4T_RAW_FRAME_EVT is not used in NFA CE */
193 DLOG_IF(INFO, nfc_debug_enabled) << StringPrintf(
194 "nfa_ce_handle_t4t_evt unhandled event=0x%02x", event);
195 break;
196 }
197 }
198
199 /*******************************************************************************
200 **
201 ** Function nfa_ce_handle_t4t_aid_evt
202 **
203 ** Description Handler for Type-4 tag AID events (for AIDs registered using
204 ** NFA_CeRegisterT4tAidOnDH)
205 **
206 ** Returns Nothing
207 **
208 *******************************************************************************/
nfa_ce_handle_t4t_aid_evt(tCE_EVENT event,tCE_DATA * p_ce_data)209 void nfa_ce_handle_t4t_aid_evt(tCE_EVENT event, tCE_DATA* p_ce_data) {
210 tNFA_CE_CB* p_cb = &nfa_ce_cb;
211 uint8_t listen_info_idx;
212 tNFA_CONN_EVT_DATA conn_evt;
213
214 DLOG_IF(INFO, nfc_debug_enabled)
215 << StringPrintf("nfa_ce_handle_t4t_aid_evt: event 0x%x", event);
216
217 /* Get listen_info for this aid callback */
218 for (listen_info_idx = 0; listen_info_idx < NFA_CE_LISTEN_INFO_IDX_INVALID;
219 listen_info_idx++) {
220 if ((p_cb->listen_info[listen_info_idx].flags &
221 NFA_CE_LISTEN_INFO_IN_USE) &&
222 (p_cb->listen_info[listen_info_idx].flags &
223 NFA_CE_LISTEN_INFO_T4T_AID) &&
224 (p_cb->listen_info[listen_info_idx].t4t_aid_handle ==
225 p_ce_data->raw_frame.aid_handle)) {
226 p_cb->idx_cur_active = listen_info_idx;
227 p_cb->p_active_conn_cback =
228 p_cb->listen_info[p_cb->idx_cur_active].p_conn_cback;
229 break;
230 }
231 }
232
233 if (event == CE_T4T_RAW_FRAME_EVT) {
234 if (listen_info_idx != NFA_CE_LISTEN_INFO_IDX_INVALID) {
235 /* Found listen_info entry */
236 conn_evt.ce_activated.handle =
237 NFA_HANDLE_GROUP_CE | ((tNFA_HANDLE)p_cb->idx_cur_active);
238
239 /* If we have not notified the app of activation, do so now */
240 if (p_cb->listen_info[p_cb->idx_cur_active].flags &
241 NFA_CE_LISTEN_INFO_T4T_ACTIVATE_PND) {
242 p_cb->listen_info[p_cb->idx_cur_active].flags &=
243 ~NFA_CE_LISTEN_INFO_T4T_ACTIVATE_PND;
244
245 memcpy(&(conn_evt.ce_activated.activate_ntf), &p_cb->activation_params,
246 sizeof(tNFC_ACTIVATE_DEVT));
247 conn_evt.ce_activated.status = NFA_STATUS_OK;
248 (*p_cb->p_active_conn_cback)(NFA_CE_ACTIVATED_EVT, &conn_evt);
249 }
250
251 /* Notify app of AID data */
252 conn_evt.ce_data.status = p_ce_data->raw_frame.status;
253 conn_evt.ce_data.handle =
254 NFA_HANDLE_GROUP_CE | ((tNFA_HANDLE)p_cb->idx_cur_active);
255 conn_evt.ce_data.p_data = (uint8_t*)(p_ce_data->raw_frame.p_data + 1) +
256 p_ce_data->raw_frame.p_data->offset;
257 conn_evt.ce_data.len = p_ce_data->raw_frame.p_data->len;
258 (*p_cb->p_active_conn_cback)(NFA_CE_DATA_EVT, &conn_evt);
259 } else {
260 LOG(ERROR) << StringPrintf(
261 "nfa_ce_handle_t4t_aid_evt: unable to find listen_info for aid hdl "
262 "%i",
263 p_ce_data->raw_frame.aid_handle);
264 }
265
266 GKI_freebuf(p_ce_data->raw_frame.p_data);
267 }
268 }
269
270 /*****************************************************************************
271 * Discovery configuration and discovery event handlers
272 *****************************************************************************/
273
274 /*******************************************************************************
275 **
276 ** Function nfa_ce_discovery_cback
277 **
278 ** Description Processing event from discovery callback
279 **
280 ** Returns None
281 **
282 *******************************************************************************/
nfa_ce_discovery_cback(tNFA_DM_RF_DISC_EVT event,tNFC_DISCOVER * p_data)283 void nfa_ce_discovery_cback(tNFA_DM_RF_DISC_EVT event, tNFC_DISCOVER* p_data) {
284 tNFA_CE_MSG ce_msg;
285 DLOG_IF(INFO, nfc_debug_enabled) << StringPrintf("event:0x%02X", event);
286
287 switch (event) {
288 case NFA_DM_RF_DISC_START_EVT:
289 DLOG_IF(INFO, nfc_debug_enabled) << StringPrintf(
290 "nfa_ce_handle_disc_start (status=0x%x)", p_data->start);
291 break;
292
293 case NFA_DM_RF_DISC_ACTIVATED_EVT:
294 ce_msg.activate_ntf.hdr.event = NFA_CE_ACTIVATE_NTF_EVT;
295 ce_msg.activate_ntf.p_activation_params = &p_data->activate;
296 nfa_ce_hdl_event((NFC_HDR*)&ce_msg);
297 break;
298
299 case NFA_DM_RF_DISC_DEACTIVATED_EVT:
300 /* DM broadcasts deactivaiton event in listen sleep state, so check before
301 * processing */
302 if (nfa_ce_cb.flags & NFA_CE_FLAGS_LISTEN_ACTIVE_SLEEP) {
303 ce_msg.hdr.event = NFA_CE_DEACTIVATE_NTF_EVT;
304 ce_msg.hdr.layer_specific = p_data->deactivate.type;
305 nfa_ce_hdl_event((NFC_HDR*)&ce_msg);
306 }
307 break;
308
309 default:
310 LOG(ERROR) << StringPrintf("Unexpected event");
311 break;
312 }
313 }
314
315 /*******************************************************************************
316 **
317 ** Function nfc_ce_t3t_set_listen_params
318 **
319 ** Description Set t3t listening parameters
320 **
321 ** Returns Nothing
322 **
323 *******************************************************************************/
nfc_ce_t3t_set_listen_params(void)324 void nfc_ce_t3t_set_listen_params(void) {
325 uint8_t i;
326 tNFA_CE_CB* p_cb = &nfa_ce_cb;
327 uint8_t tlv[128], *p_params;
328 uint8_t tlv_size;
329 uint16_t t3t_flags2_mask = 0xFFFF; /* Mask of which T3T_IDs are disabled */
330 uint8_t t3t_idx = 0;
331 uint8_t adv_Feat = 1;
332 uint8_t t3tPMM[NCI_T3T_PMM_LEN] = {0xFF, 0xFF, 0xFF, 0xFF,
333 0xFF, 0xFF, 0xFF, 0xFF};
334
335 /* Point to start of tlv buffer */
336 p_params = tlv;
337
338 /* Set system code and NFCID2 */
339 for (i = 0; i < NFA_CE_LISTEN_INFO_MAX; i++) {
340 if ((p_cb->listen_info[i].flags & NFA_CE_LISTEN_INFO_IN_USE) &&
341 (p_cb->listen_info[i].protocol_mask & NFA_PROTOCOL_MASK_T3T)) {
342 /* Set tag's system code and NFCID2 */
343 UINT8_TO_STREAM(p_params, NFC_PMID_LF_T3T_ID1 + t3t_idx); /* type */
344 /* length */
345 UINT8_TO_STREAM(p_params, NCI_PARAM_LEN_LF_T3T_ID(NFC_GetNCIVersion()));
346 /* System Code */
347 UINT16_TO_BE_STREAM(p_params, p_cb->listen_info[i].t3t_system_code);
348 ARRAY_TO_BE_STREAM(p_params, p_cb->listen_info[i].t3t_nfcid2,
349 NCI_RF_F_UID_LEN);
350 if (NFC_GetNCIVersion() == NCI_VERSION_2_0) {
351 ARRAY_TO_BE_STREAM(p_params, p_cb->listen_info[i].t3t_pmm,
352 NCI_T3T_PMM_LEN);
353 }
354 /* Set mask for this ID */
355 t3t_flags2_mask &= ~((uint16_t)(1 << t3t_idx));
356 t3t_idx++;
357 }
358 }
359
360 /* For NCI draft 22+, the polarity of NFC_PMID_LF_T3T_FLAGS2 is flipped */
361 t3t_flags2_mask = ~t3t_flags2_mask;
362
363 UINT8_TO_STREAM(p_params, NFC_PMID_LF_T3T_FLAGS2); /* type */
364 UINT8_TO_STREAM(p_params, NCI_PARAM_LEN_LF_T3T_FLAGS2); /* length */
365 /* Mask of IDs to disable listening */
366 UINT16_TO_STREAM(p_params, t3t_flags2_mask);
367
368 if (NFC_GetNCIVersion() == NCI_VERSION_2_0) {
369 /*Name changed in NCI2.0*/
370 UINT8_TO_STREAM(p_params, NCI_PARAM_ID_LF_T3T_RD_ALLOWED); /* type */
371 UINT8_TO_STREAM(p_params, NCI_PARAM_LEN_LF_T3T_RD_ALLOWED); /* length */
372 } else {
373 UINT8_TO_STREAM(p_params, NCI_PARAM_ID_LF_CON_ADV_FEAT); /* type */
374 UINT8_TO_STREAM(p_params, NCI_PARAM_LEN_LF_CON_ADV_FEAT); /* length */
375 }
376 UINT8_TO_STREAM(p_params, adv_Feat);
377
378 if (NFC_GetNCIVersion() != NCI_VERSION_2_0) {
379 UINT8_TO_STREAM(p_params, NCI_PARAM_ID_LF_T3T_PMM); /* type */
380 UINT8_TO_STREAM(p_params, NCI_PARAM_LEN_LF_T3T_PMM); /* length */
381 ARRAY_TO_BE_STREAM(p_params, t3tPMM, NCI_T3T_PMM_LEN);
382 }
383 tlv_size = (uint8_t)(p_params - tlv);
384 if (appl_dta_mode_flag == 0x01) {
385 nfa_dm_cb.eDtaMode |= NFA_DTA_HCEF_MODE;
386 }
387 nfa_dm_check_set_config(tlv_size, (uint8_t*)tlv, false);
388 }
389
390 /*******************************************************************************
391 **
392 ** Function nfa_ce_t3t_generate_rand_nfcid
393 **
394 ** Description Generate a random NFCID2 for Type-3 tag
395 **
396 ** Returns Nothing
397 **
398 *******************************************************************************/
nfa_ce_t3t_generate_rand_nfcid(uint8_t nfcid2[NCI_RF_F_UID_LEN])399 void nfa_ce_t3t_generate_rand_nfcid(uint8_t nfcid2[NCI_RF_F_UID_LEN]) {
400 uint32_t rand_seed = GKI_get_tick_count();
401
402 /* For Type-3 tag, nfcid2 starts witn 02:fe */
403 nfcid2[0] = 0x02;
404 nfcid2[1] = 0xFE;
405
406 /* The remaining 6 bytes are random */
407 nfcid2[2] = (uint8_t)(rand_seed & 0xFF);
408 nfcid2[3] = (uint8_t)(rand_seed >> 8 & 0xFF);
409 rand_seed >>= (rand_seed & 3);
410 nfcid2[4] = (uint8_t)(rand_seed & 0xFF);
411 nfcid2[5] = (uint8_t)(rand_seed >> 8 & 0xFF);
412 rand_seed >>= (rand_seed & 3);
413 nfcid2[6] = (uint8_t)(rand_seed & 0xFF);
414 nfcid2[7] = (uint8_t)(rand_seed >> 8 & 0xFF);
415 }
416
417 /*******************************************************************************
418 **
419 ** Function nfa_ce_start_listening
420 **
421 ** Description Start listening
422 **
423 ** Returns NFA_STATUS_OK if successful
424 **
425 *******************************************************************************/
nfa_ce_start_listening(void)426 tNFA_STATUS nfa_ce_start_listening(void) {
427 tNFA_DM_DISC_TECH_PROTO_MASK listen_mask;
428 tNFA_CE_CB* p_cb = &nfa_ce_cb;
429 tNFA_HANDLE disc_handle;
430 uint8_t listen_info_idx;
431
432 /*************************************************************************/
433 /* Construct protocol preference list to listen for */
434
435 /* First, get protocol preference for active NDEF (if any) */
436 if ((p_cb->listen_info[NFA_CE_LISTEN_INFO_IDX_NDEF].flags &
437 NFA_CE_LISTEN_INFO_IN_USE) &&
438 (p_cb->listen_info[NFA_CE_LISTEN_INFO_IDX_NDEF].rf_disc_handle ==
439 NFA_HANDLE_INVALID)) {
440 listen_mask = 0;
441
442 if (p_cb->listen_info[NFA_CE_LISTEN_INFO_IDX_NDEF].protocol_mask &
443 NFA_PROTOCOL_MASK_T3T) {
444 /* set T3T config params */
445 nfc_ce_t3t_set_listen_params();
446
447 listen_mask |= NFA_DM_DISC_MASK_LF_T3T;
448 }
449
450 if (p_cb->listen_info[NFA_CE_LISTEN_INFO_IDX_NDEF].protocol_mask &
451 NFA_PROTOCOL_MASK_ISO_DEP) {
452 listen_mask |= nfa_ce_cb.isodep_disc_mask;
453 }
454
455 disc_handle = nfa_dm_add_rf_discover(listen_mask, NFA_DM_DISC_HOST_ID_DH,
456 nfa_ce_discovery_cback);
457
458 if (disc_handle == NFA_HANDLE_INVALID)
459 return (NFA_STATUS_FAILED);
460 else
461 p_cb->listen_info[NFA_CE_LISTEN_INFO_IDX_NDEF].rf_disc_handle =
462 disc_handle;
463 }
464
465 /* Next, add protocols from non-NDEF, if any */
466 for (listen_info_idx = 0; listen_info_idx < NFA_CE_LISTEN_INFO_IDX_INVALID;
467 listen_info_idx++) {
468 /* add RF discovery to DM only if it is not added yet */
469 if ((p_cb->listen_info[listen_info_idx].flags &
470 NFA_CE_LISTEN_INFO_IN_USE) &&
471 (p_cb->listen_info[listen_info_idx].rf_disc_handle ==
472 NFA_HANDLE_INVALID)) {
473 if (p_cb->listen_info[listen_info_idx].flags &
474 NFA_CE_LISTEN_INFO_FELICA) {
475 /* set T3T config params */
476 nfc_ce_t3t_set_listen_params();
477
478 disc_handle = nfa_dm_add_rf_discover(NFA_DM_DISC_MASK_LF_T3T,
479 NFA_DM_DISC_HOST_ID_DH,
480 nfa_ce_discovery_cback);
481
482 if (disc_handle == NFA_HANDLE_INVALID)
483 return (NFA_STATUS_FAILED);
484 else
485 p_cb->listen_info[listen_info_idx].rf_disc_handle = disc_handle;
486 } else if (p_cb->listen_info[listen_info_idx].flags &
487 NFA_CE_LISTEN_INFO_T4T_AID) {
488 disc_handle = nfa_dm_add_rf_discover(nfa_ce_cb.isodep_disc_mask,
489 NFA_DM_DISC_HOST_ID_DH,
490 nfa_ce_discovery_cback);
491
492 if (disc_handle == NFA_HANDLE_INVALID)
493 return (NFA_STATUS_FAILED);
494 else
495 p_cb->listen_info[listen_info_idx].rf_disc_handle = disc_handle;
496 }
497 #if (NFC_NFCEE_INCLUDED == TRUE)
498 else if (p_cb->listen_info[listen_info_idx].flags &
499 NFA_CE_LISTEN_INFO_UICC) {
500 listen_mask = 0;
501 if (nfa_ee_is_active(p_cb->listen_info[listen_info_idx].ee_handle)) {
502 if (p_cb->listen_info[listen_info_idx].tech_mask &
503 NFA_TECHNOLOGY_MASK_A) {
504 listen_mask |= NFA_DM_DISC_MASK_LA_ISO_DEP;
505 }
506 if (p_cb->listen_info[listen_info_idx].tech_mask &
507 NFA_TECHNOLOGY_MASK_B) {
508 listen_mask |= NFA_DM_DISC_MASK_LB_ISO_DEP;
509 }
510 if (p_cb->listen_info[listen_info_idx].tech_mask &
511 NFA_TECHNOLOGY_MASK_F) {
512 listen_mask |= NFA_DM_DISC_MASK_LF_T3T;
513 }
514 if (p_cb->listen_info[listen_info_idx].tech_mask &
515 NFA_TECHNOLOGY_MASK_B_PRIME) {
516 listen_mask |= NFA_DM_DISC_MASK_L_B_PRIME;
517 }
518 }
519
520 if (listen_mask) {
521 /* Start listening for requested technologies */
522 /* register discovery callback to NFA DM */
523 disc_handle = nfa_dm_add_rf_discover(
524 listen_mask,
525 (tNFA_DM_DISC_HOST_ID)(
526 p_cb->listen_info[listen_info_idx].ee_handle & 0x00FF),
527 nfa_ce_discovery_cback);
528
529 if (disc_handle == NFA_HANDLE_INVALID)
530 return (NFA_STATUS_FAILED);
531 else {
532 p_cb->listen_info[listen_info_idx].rf_disc_handle = disc_handle;
533 p_cb->listen_info[listen_info_idx].tech_proto_mask = listen_mask;
534 }
535 } else {
536 LOG(ERROR) << StringPrintf(
537 "UICC[0x%x] is not activated",
538 p_cb->listen_info[listen_info_idx].ee_handle);
539 }
540 }
541 #endif
542 }
543 }
544
545 return NFA_STATUS_OK;
546 }
547
548 /*******************************************************************************
549 **
550 ** Function nfa_ce_restart_listen_check
551 **
552 ** Description Called on deactivation. Check if any active listen_info
553 ** entries to listen for
554 **
555 ** Returns TRUE if listening is restarted.
556 ** FALSE if listening not restarted
557 **
558 *******************************************************************************/
nfa_ce_restart_listen_check(void)559 bool nfa_ce_restart_listen_check(void) {
560 tNFA_CE_CB* p_cb = &nfa_ce_cb;
561 uint8_t listen_info_idx;
562
563 /* Check if any active entries in listen_info table */
564 for (listen_info_idx = 0; listen_info_idx < NFA_CE_LISTEN_INFO_MAX;
565 listen_info_idx++) {
566 if (p_cb->listen_info[listen_info_idx].flags & NFA_CE_LISTEN_INFO_IN_USE)
567 break;
568 }
569
570 /* Restart listening if there are any active listen_info entries */
571 if (listen_info_idx != NFA_CE_LISTEN_INFO_IDX_INVALID) {
572 /* restart listening */
573 nfa_ce_start_listening();
574 } else {
575 /* No active listen_info entries */
576 return false;
577 }
578
579 return true;
580 }
581
582 /*******************************************************************************
583 **
584 ** Function nfa_ce_remove_listen_info_entry
585 **
586 ** Description Remove entry from listen_info table. (when API deregister is
587 ** called or listen_start failed)
588 **
589 **
590 ** Returns Nothing
591 **
592 *******************************************************************************/
nfa_ce_remove_listen_info_entry(uint8_t listen_info_idx,bool notify_app)593 void nfa_ce_remove_listen_info_entry(uint8_t listen_info_idx, bool notify_app) {
594 tNFA_CE_CB* p_cb = &nfa_ce_cb;
595 tNFA_CONN_EVT_DATA conn_evt;
596
597 DLOG_IF(INFO, nfc_debug_enabled)
598 << StringPrintf("NFA_CE: removing listen_info entry %i", listen_info_idx);
599
600 /* Notify app that listening has stopped if requested (for API deregister) */
601 /* For LISTEN_START failures, app has already notified of NFA_LISTEN_START_EVT
602 * failure */
603 if (notify_app) {
604 if (listen_info_idx == NFA_CE_LISTEN_INFO_IDX_NDEF) {
605 conn_evt.status = NFA_STATUS_OK;
606 (*p_cb->listen_info[listen_info_idx].p_conn_cback)(
607 NFA_CE_LOCAL_TAG_CONFIGURED_EVT, &conn_evt);
608 }
609 #if (NFC_NFCEE_INCLUDED == TRUE)
610 else if (p_cb->listen_info[listen_info_idx].flags &
611 NFA_CE_LISTEN_INFO_UICC) {
612 conn_evt.status = NFA_STATUS_OK;
613 (*p_cb->listen_info[listen_info_idx].p_conn_cback)(
614 NFA_CE_UICC_LISTEN_CONFIGURED_EVT, &conn_evt);
615 }
616 #endif
617 else {
618 conn_evt.ce_deregistered.handle = NFA_HANDLE_GROUP_CE | listen_info_idx;
619 (*p_cb->listen_info[listen_info_idx].p_conn_cback)(
620 NFA_CE_DEREGISTERED_EVT, &conn_evt);
621 }
622 }
623
624 /* Handle NDEF stopping */
625 if (listen_info_idx == NFA_CE_LISTEN_INFO_IDX_NDEF) {
626 /* clear NDEF contents */
627 CE_T3tSetLocalNDEFMsg(true, 0, 0, nullptr, nullptr);
628 CE_T4tSetLocalNDEFMsg(true, 0, 0, nullptr, nullptr);
629
630 if (p_cb->listen_info[listen_info_idx].protocol_mask &
631 NFA_PROTOCOL_MASK_T3T) {
632 p_cb->listen_info[listen_info_idx].protocol_mask = 0;
633
634 /* clear T3T Flags for NDEF */
635 nfc_ce_t3t_set_listen_params();
636 }
637
638 /* Free scratch buffer for this NDEF, if one was allocated */
639 nfa_ce_free_scratch_buf();
640 }
641 /* If stopping listening Felica system code, then clear T3T Flags for this */
642 else if (p_cb->listen_info[listen_info_idx].flags &
643 NFA_CE_LISTEN_INFO_FELICA) {
644 p_cb->listen_info[listen_info_idx].protocol_mask = 0;
645
646 /* clear T3T Flags for registered Felica system code */
647 nfc_ce_t3t_set_listen_params();
648 }
649 /* If stopping listening T4T AID, then deregister this AID from CE_T4T */
650 else if (p_cb->listen_info[listen_info_idx].flags &
651 NFA_CE_LISTEN_INFO_T4T_AID) {
652 /* Free t4t_aid_cback used by this AID */
653 CE_T4tDeregisterAID(p_cb->listen_info[listen_info_idx].t4t_aid_handle);
654 }
655
656 if (p_cb->listen_info[listen_info_idx].rf_disc_handle != NFA_HANDLE_INVALID) {
657 nfa_dm_delete_rf_discover(
658 p_cb->listen_info[listen_info_idx].rf_disc_handle);
659 p_cb->listen_info[listen_info_idx].rf_disc_handle = NFA_HANDLE_INVALID;
660 }
661
662 /* Remove entry from listen_info table */
663 p_cb->listen_info[listen_info_idx].flags = 0;
664 }
665
666 /*******************************************************************************
667 **
668 ** Function nfa_ce_free_scratch_buf
669 **
670 ** Description free scratch buffer (if one is allocated)
671 **
672 ** Returns nothing
673 **
674 *******************************************************************************/
nfa_ce_free_scratch_buf(void)675 void nfa_ce_free_scratch_buf(void) {
676 tNFA_CE_CB* p_cb = &nfa_ce_cb;
677 if (p_cb->p_scratch_buf) {
678 nfa_mem_co_free(p_cb->p_scratch_buf);
679 p_cb->p_scratch_buf = nullptr;
680 }
681 }
682
683 /*******************************************************************************
684 **
685 ** Function nfa_ce_realloc_scratch_buffer
686 **
687 ** Description Set scratch buffer if necessary (for writable NDEF messages)
688 **
689 ** Returns NFA_STATUS_OK if successful
690 **
691 *******************************************************************************/
nfa_ce_realloc_scratch_buffer(void)692 tNFA_STATUS nfa_ce_realloc_scratch_buffer(void) {
693 tNFA_STATUS result = NFA_STATUS_OK;
694
695 /* If current NDEF message is read-only, then we do not need a scratch buffer
696 */
697 if (nfa_ce_cb.listen_info[NFA_CE_LISTEN_INFO_IDX_NDEF].flags &
698 NFC_CE_LISTEN_INFO_READONLY_NDEF) {
699 /* Free existing scratch buffer, if one was allocated */
700 nfa_ce_free_scratch_buf();
701 } else {
702 /* If no scratch buffer allocated yet, or if current scratch buffer size is
703 * different from current ndef size, */
704 /* then allocate a new scratch buffer. */
705 if ((nfa_ce_cb.p_scratch_buf == nullptr) ||
706 (nfa_ce_cb.scratch_buf_size != nfa_ce_cb.ndef_max_size)) {
707 /* Free existing scratch buffer, if one was allocated */
708 nfa_ce_free_scratch_buf();
709
710 nfa_ce_cb.p_scratch_buf =
711 (uint8_t*)nfa_mem_co_alloc(nfa_ce_cb.ndef_max_size);
712 if (nfa_ce_cb.p_scratch_buf != nullptr) {
713 nfa_ce_cb.scratch_buf_size = nfa_ce_cb.ndef_max_size;
714 } else {
715 LOG(ERROR) << StringPrintf(
716 "Unable to allocate scratch buffer for writable NDEF message (%i "
717 "bytes)",
718 nfa_ce_cb.ndef_max_size);
719 result = NFA_STATUS_FAILED;
720 }
721 }
722 }
723
724 return (result);
725 }
726
727 /*******************************************************************************
728 **
729 ** Function nfa_ce_set_content
730 **
731 ** Description Set NDEF contents
732 **
733 ** Returns void
734 **
735 *******************************************************************************/
nfa_ce_set_content(void)736 tNFC_STATUS nfa_ce_set_content(void) {
737 tNFC_STATUS status;
738 tNFA_CE_CB* p_cb = &nfa_ce_cb;
739 tNFA_PROTOCOL_MASK ndef_protocol_mask;
740 bool readonly;
741
742 /* Check if listening for NDEF */
743 if (!(p_cb->listen_info[NFA_CE_LISTEN_INFO_IDX_NDEF].flags &
744 NFA_CE_LISTEN_INFO_IN_USE)) {
745 /* Not listening for NDEF */
746 return (NFA_STATUS_OK);
747 }
748
749 DLOG_IF(INFO, nfc_debug_enabled) << StringPrintf("Setting NDEF contents");
750
751 readonly = (p_cb->listen_info[NFA_CE_LISTEN_INFO_IDX_NDEF].flags &
752 NFC_CE_LISTEN_INFO_READONLY_NDEF)
753 ? true
754 : false;
755 ndef_protocol_mask =
756 p_cb->listen_info[NFA_CE_LISTEN_INFO_IDX_NDEF].protocol_mask;
757
758 /* Allocate a scratch buffer if needed (for handling write-requests) */
759 status = nfa_ce_realloc_scratch_buffer();
760 if (status == NFA_STATUS_OK) {
761 if ((ndef_protocol_mask & NFA_PROTOCOL_MASK_T3T) &&
762 (status == NFA_STATUS_OK)) {
763 /* Type3Tag - NFC-F */
764 status = CE_T3tSetLocalNDEFMsg(readonly, p_cb->ndef_max_size,
765 p_cb->ndef_cur_size, p_cb->p_ndef_data,
766 p_cb->p_scratch_buf);
767 }
768
769 if ((ndef_protocol_mask & NFA_PROTOCOL_MASK_ISO_DEP) &&
770 (status == NFA_STATUS_OK)) {
771 /* ISODEP/4A,4B- NFC-A or NFC-B */
772 status = CE_T4tSetLocalNDEFMsg(readonly, p_cb->ndef_max_size,
773 p_cb->ndef_cur_size, p_cb->p_ndef_data,
774 p_cb->p_scratch_buf);
775 }
776 }
777
778 if (status != NFA_STATUS_OK) {
779 /* clear NDEF contents */
780 CE_T3tSetLocalNDEFMsg(true, 0, 0, nullptr, nullptr);
781 CE_T4tSetLocalNDEFMsg(true, 0, 0, nullptr, nullptr);
782
783 LOG(ERROR) << StringPrintf("Unable to set contents (error %02x)", status);
784 }
785
786 return (status);
787 }
788
789 /*******************************************************************************
790 **
791 ** Function nfa_ce_activate_ntf
792 **
793 ** Description Action when activation has occured (NFA_CE_ACTIVATE_NTF_EVT)
794 **
795 ** - Find the listen_info entry assocated with this activation
796 ** - get the app callback that registered for this listen
797 ** - call CE_SetActivatedTagType with activation parameters
798 **
799 ** Returns TRUE (message buffer to be freed by caller)
800 **
801 *******************************************************************************/
nfa_ce_activate_ntf(tNFA_CE_MSG * p_ce_msg)802 bool nfa_ce_activate_ntf(tNFA_CE_MSG* p_ce_msg) {
803 tNFC_ACTIVATE_DEVT* p_activation_params =
804 p_ce_msg->activate_ntf.p_activation_params;
805 tNFA_CE_CB* p_cb = &nfa_ce_cb;
806 tNFA_CONN_EVT_DATA conn_evt;
807 tCE_CBACK* p_ce_cback = nullptr;
808 uint16_t t3t_system_code = 0xFFFF;
809 uint8_t listen_info_idx = NFA_CE_LISTEN_INFO_IDX_INVALID;
810 uint8_t* p_nfcid2 = nullptr;
811 uint8_t i;
812 bool t4t_activate_pending = false;
813
814 bool t3t_activate_pending = false;
815 bool t3t_offhost_entry_found = false;
816 uint8_t t3t_activate_idx = 0;
817 uint8_t t3t_offhost_idx = 0;
818
819 DLOG_IF(INFO, nfc_debug_enabled) << StringPrintf(
820 "protocol=%d", p_ce_msg->activate_ntf.p_activation_params->protocol);
821
822 /* Tag is in listen active state */
823 p_cb->flags |= NFA_CE_FLAGS_LISTEN_ACTIVE_SLEEP;
824
825 /* Store activation parameters */
826 memcpy(&p_cb->activation_params, p_activation_params,
827 sizeof(tNFC_ACTIVATE_DEVT));
828
829 /* Find the listen_info entry corresponding to this activation */
830 if (p_cb->activation_params.protocol == NFA_PROTOCOL_T3T) {
831 /* Look for T3T entries in listen_info table that match activated system
832 * code and NFCID2 */
833 for (listen_info_idx = 0; listen_info_idx < NFA_CE_LISTEN_INFO_IDX_INVALID;
834 listen_info_idx++) {
835 /* Look for entries with NFA_PROTOCOL_MASK_T3T */
836 if (p_cb->listen_info[listen_info_idx].flags &
837 NFA_CE_LISTEN_INFO_IN_USE) {
838 if (p_cb->listen_info[listen_info_idx].protocol_mask &
839 NFA_PROTOCOL_MASK_T3T) {
840 /* Check if system_code and nfcid2 that matches activation params */
841 p_nfcid2 = p_cb->listen_info[listen_info_idx].t3t_nfcid2;
842 t3t_system_code = p_cb->listen_info[listen_info_idx].t3t_system_code;
843
844 /* Compare NFCID2 (note: NFCC currently does not return system code in
845 * activation parameters) */
846 if ((memcmp(p_nfcid2,
847 p_cb->activation_params.rf_tech_param.param.lf.nfcid2,
848 NCI_RF_F_UID_LEN) == 0)
849 /* && (t3t_system_code == p_ce_msg->activation.p_activate_info->rf_tech_param.param.lf.system_code) */) {
850 p_cb->listen_info[listen_info_idx].flags |=
851 NFA_CE_LISTEN_INFO_T3T_ACTIVATE_PND;
852 t3t_activate_pending = true;
853 t3t_activate_idx = listen_info_idx;
854 }
855 }
856
857 /* Check if entry is for T3T UICC */
858 if ((p_cb->listen_info[listen_info_idx].flags &
859 NFA_CE_LISTEN_INFO_UICC) &&
860 (p_cb->listen_info[listen_info_idx].tech_mask &
861 NFA_TECHNOLOGY_MASK_F)) {
862 t3t_offhost_entry_found = true;
863 t3t_offhost_idx = listen_info_idx;
864 }
865 }
866 }
867
868 p_ce_cback = nfa_ce_handle_t3t_evt;
869 /* If listening for PROTO_T3T on DH and eSE/UICC, then notify CE module
870 * now and wait for reader/writer to SELECT a target */
871 if (t3t_activate_pending && t3t_offhost_entry_found) {
872 CE_SetActivatedTagType(&p_cb->activation_params, t3t_system_code,
873 p_ce_cback);
874 return true;
875 } else if (t3t_activate_pending) {
876 listen_info_idx = t3t_activate_idx;
877 } else if (t3t_offhost_entry_found) {
878 listen_info_idx = t3t_offhost_idx;
879 }
880 } else if (p_cb->activation_params.protocol == NFA_PROTOCOL_ISO_DEP) {
881 p_ce_cback = nfa_ce_handle_t4t_evt;
882
883 /* For T4T, we do not know which AID will be selected yet */
884
885 /* For all T4T entries in listen_info, set T4T_ACTIVATE_NOTIFY_PENDING flag
886 */
887 for (i = 0; i < NFA_CE_LISTEN_INFO_IDX_INVALID; i++) {
888 if (p_cb->listen_info[i].flags & NFA_CE_LISTEN_INFO_IN_USE) {
889 if (p_cb->listen_info[i].protocol_mask & NFA_PROTOCOL_MASK_ISO_DEP) {
890 /* Found listen_info table entry for T4T raw listen */
891 p_cb->listen_info[i].flags |= NFA_CE_LISTEN_INFO_T4T_ACTIVATE_PND;
892
893 /* If entry if for NDEF, select it, so application gets nofitifed of
894 * ACTIVATE_EVT now */
895 if (i == NFA_CE_LISTEN_INFO_IDX_NDEF) {
896 listen_info_idx = NFA_CE_LISTEN_INFO_IDX_NDEF;
897 }
898
899 t4t_activate_pending = true;
900 }
901
902 #if (NFC_NFCEE_INCLUDED == TRUE)
903 /* Check if entry is for ISO_DEP UICC */
904 if (p_cb->listen_info[i].flags & NFA_CE_LISTEN_INFO_UICC) {
905 if (((p_cb->activation_params.rf_tech_param.mode ==
906 NFC_DISCOVERY_TYPE_LISTEN_A) &&
907 (p_cb->listen_info[i].tech_proto_mask &
908 NFA_DM_DISC_MASK_LA_ISO_DEP)) ||
909 ((p_cb->activation_params.rf_tech_param.mode ==
910 NFC_DISCOVERY_TYPE_LISTEN_B) &&
911 (p_cb->listen_info[i].tech_proto_mask &
912 NFA_DM_DISC_MASK_LB_ISO_DEP))) {
913 listen_info_idx = i;
914 }
915 }
916 #endif
917 }
918 }
919
920 /* If listening for ISO_DEP, but not NDEF nor UICC, then notify CE module
921 * now and wait for reader/writer to SELECT an AID */
922 if (t4t_activate_pending &&
923 (listen_info_idx == NFA_CE_LISTEN_INFO_IDX_INVALID)) {
924 CE_SetActivatedTagType(&p_cb->activation_params, 0, p_ce_cback);
925 return true;
926 }
927 } else if (p_cb->activation_params.intf_param.type ==
928 NFC_INTERFACE_EE_DIRECT_RF) {
929 /* search any entry listening UICC */
930 for (i = 0; i < NFA_CE_LISTEN_INFO_IDX_INVALID; i++) {
931 if ((p_cb->listen_info[i].flags & NFA_CE_LISTEN_INFO_IN_USE) &&
932 (p_cb->listen_info[i].flags & NFA_CE_LISTEN_INFO_UICC)) {
933 listen_info_idx = i;
934 break;
935 }
936 }
937 }
938
939 /* Check if valid listen_info entry was found */
940 if ((listen_info_idx == NFA_CE_LISTEN_INFO_IDX_INVALID) ||
941 ((listen_info_idx == NFA_CE_LISTEN_INFO_IDX_NDEF) &&
942 !(p_cb->listen_info[NFA_CE_LISTEN_INFO_IDX_NDEF].flags &
943 NFA_CE_LISTEN_INFO_IN_USE))) {
944 DLOG_IF(INFO, nfc_debug_enabled) << StringPrintf(
945 "No listen_info found for this activation. listen_info_idx=%d",
946 listen_info_idx);
947 return true;
948 }
949
950 p_cb->listen_info[listen_info_idx].flags &=
951 ~NFA_CE_LISTEN_INFO_T4T_ACTIVATE_PND;
952 p_cb->listen_info[listen_info_idx].flags &=
953 ~NFA_CE_LISTEN_INFO_T3T_ACTIVATE_PND;
954
955 /* Get CONN_CBACK for this activation */
956 p_cb->p_active_conn_cback = p_cb->listen_info[listen_info_idx].p_conn_cback;
957 p_cb->idx_cur_active = listen_info_idx;
958
959 if ((p_cb->idx_cur_active == NFA_CE_LISTEN_INFO_IDX_NDEF) ||
960 (p_cb->listen_info[p_cb->idx_cur_active].flags &
961 NFA_CE_LISTEN_INFO_UICC)) {
962 memcpy(&(conn_evt.activated.activate_ntf), &p_cb->activation_params,
963 sizeof(tNFC_ACTIVATE_DEVT));
964
965 (*p_cb->p_active_conn_cback)(NFA_ACTIVATED_EVT, &conn_evt);
966 } else {
967 conn_evt.ce_activated.handle =
968 NFA_HANDLE_GROUP_CE | ((tNFA_HANDLE)p_cb->idx_cur_active);
969 memcpy(&(conn_evt.ce_activated.activate_ntf), &p_cb->activation_params,
970 sizeof(tNFC_ACTIVATE_DEVT));
971 conn_evt.ce_activated.status = NFA_STATUS_OK;
972
973 (*p_cb->p_active_conn_cback)(NFA_CE_ACTIVATED_EVT, &conn_evt);
974 }
975
976 /* we don't need any CE subsystem in case of NFCEE direct RF interface */
977 if (p_ce_cback) {
978 /* Notify CE subsystem */
979 CE_SetActivatedTagType(&p_cb->activation_params, t3t_system_code,
980 p_ce_cback);
981 }
982 return true;
983 }
984
985 /*******************************************************************************
986 **
987 ** Function nfa_ce_deactivate_ntf
988 **
989 ** Description Action when deactivate occurs. (NFA_CE_DEACTIVATE_NTF_EVT)
990 **
991 ** - If deactivate due to API deregister, then remove its entry
992 ** from listen_info table
993 **
994 ** - If NDEF was modified while activated, then restore
995 ** original NDEF contents
996 **
997 ** - Restart listening (if any active entries in listen table)
998 **
999 ** Returns TRUE (message buffer to be freed by caller)
1000 **
1001 *******************************************************************************/
nfa_ce_deactivate_ntf(tNFA_CE_MSG * p_ce_msg)1002 bool nfa_ce_deactivate_ntf(tNFA_CE_MSG* p_ce_msg) {
1003 tNFC_DEACT_TYPE deact_type = (tNFC_DEACT_TYPE)p_ce_msg->hdr.layer_specific;
1004 tNFA_CE_CB* p_cb = &nfa_ce_cb;
1005 tNFA_CONN_EVT_DATA conn_evt;
1006 uint8_t i;
1007
1008 DLOG_IF(INFO, nfc_debug_enabled) << StringPrintf("deact_type=%d", deact_type);
1009
1010 /* Check if deactivating to SLEEP mode */
1011 if ((deact_type == NFC_DEACTIVATE_TYPE_SLEEP) ||
1012 (deact_type == NFC_DEACTIVATE_TYPE_SLEEP_AF)) {
1013 if (nfa_ce_cb.idx_wild_card == NFA_CE_LISTEN_INFO_IDX_INVALID) {
1014 /* notify deactivated as sleep and wait for reactivation or deactivation
1015 * to idle */
1016 conn_evt.deactivated.type = deact_type;
1017
1018 /* if T4T AID application has not been selected then p_active_conn_cback
1019 * could be NULL */
1020 if (p_cb->p_active_conn_cback)
1021 (*p_cb->p_active_conn_cback)(NFA_DEACTIVATED_EVT, &conn_evt);
1022 } else {
1023 conn_evt.ce_deactivated.handle =
1024 NFA_HANDLE_GROUP_CE | ((tNFA_HANDLE)nfa_ce_cb.idx_wild_card);
1025 conn_evt.ce_deactivated.type = deact_type;
1026 if (p_cb->p_active_conn_cback)
1027 (*p_cb->p_active_conn_cback)(NFA_CE_DEACTIVATED_EVT, &conn_evt);
1028 }
1029
1030 return true;
1031 } else {
1032 deact_type = NFC_DEACTIVATE_TYPE_IDLE;
1033 }
1034
1035 /* Tag is in idle state */
1036 p_cb->flags &= ~NFA_CE_FLAGS_LISTEN_ACTIVE_SLEEP;
1037
1038 /* First, notify app of deactivation */
1039 for (i = 0; i < NFA_CE_LISTEN_INFO_IDX_INVALID; i++) {
1040 if (p_cb->listen_info[i].flags & NFA_CE_LISTEN_INFO_IN_USE) {
1041 if ((p_cb->listen_info[i].flags & NFA_CE_LISTEN_INFO_UICC) &&
1042 (i == p_cb->idx_cur_active)) {
1043 conn_evt.deactivated.type = deact_type;
1044 if (p_cb->p_active_conn_cback)
1045 (*p_cb->p_active_conn_cback)(NFA_DEACTIVATED_EVT, &conn_evt);
1046 } else if ((p_cb->activation_params.protocol == NFA_PROTOCOL_ISO_DEP) &&
1047 (p_cb->listen_info[i].protocol_mask &
1048 NFA_PROTOCOL_MASK_ISO_DEP)) {
1049 /* Don't send NFA_DEACTIVATED_EVT if NFA_ACTIVATED_EVT wasn't sent */
1050 if (!(p_cb->listen_info[i].flags &
1051 NFA_CE_LISTEN_INFO_T4T_ACTIVATE_PND)) {
1052 if (i == NFA_CE_LISTEN_INFO_IDX_NDEF) {
1053 conn_evt.deactivated.type = deact_type;
1054 if (p_cb->p_active_conn_cback)
1055 (*p_cb->p_active_conn_cback)(NFA_DEACTIVATED_EVT, &conn_evt);
1056 } else {
1057 conn_evt.ce_deactivated.handle =
1058 NFA_HANDLE_GROUP_CE | ((tNFA_HANDLE)i);
1059 conn_evt.ce_deactivated.type = deact_type;
1060 if (p_cb->p_active_conn_cback)
1061 (*p_cb->p_active_conn_cback)(NFA_CE_DEACTIVATED_EVT, &conn_evt);
1062 }
1063 }
1064 } else if ((p_cb->activation_params.protocol == NFA_PROTOCOL_T3T) &&
1065 (p_cb->listen_info[i].protocol_mask & NFA_PROTOCOL_MASK_T3T)) {
1066 /* Don't send NFA_DEACTIVATED_EVT if NFA_ACTIVATED_EVT wasn't sent */
1067 if (!(p_cb->listen_info[i].flags &
1068 NFA_CE_LISTEN_INFO_T3T_ACTIVATE_PND)) {
1069 if (i == NFA_CE_LISTEN_INFO_IDX_NDEF) {
1070 conn_evt.deactivated.type = deact_type;
1071 if (p_cb->p_active_conn_cback)
1072 (*p_cb->p_active_conn_cback)(NFA_DEACTIVATED_EVT, &conn_evt);
1073 } else {
1074 conn_evt.ce_deactivated.handle =
1075 NFA_HANDLE_GROUP_CE | ((tNFA_HANDLE)i);
1076 conn_evt.ce_deactivated.type = deact_type;
1077 if (p_cb->p_active_conn_cback) {
1078 (*p_cb->p_active_conn_cback)(NFA_CE_DEACTIVATED_EVT, &conn_evt);
1079 } else {
1080 android_errorWriteLog(0x534e4554, "120846143");
1081 }
1082 }
1083 }
1084 }
1085 }
1086 }
1087
1088 /* Check if app initiated the deactivation (due to API deregister). If so,
1089 * remove entry from listen_info table. */
1090 if (p_cb->flags & NFA_CE_FLAGS_APP_INIT_DEACTIVATION) {
1091 p_cb->flags &= ~NFA_CE_FLAGS_APP_INIT_DEACTIVATION;
1092 nfa_ce_remove_listen_info_entry(p_cb->idx_cur_active, true);
1093 }
1094
1095 p_cb->p_active_conn_cback = nullptr;
1096 p_cb->idx_cur_active = NFA_CE_LISTEN_INFO_IDX_INVALID;
1097
1098 /* Restart listening (if any listen_info entries are still active) */
1099 nfa_ce_restart_listen_check();
1100
1101 return true;
1102 }
1103
1104 /*******************************************************************************
1105 **
1106 ** Function nfa_ce_disable_local_tag
1107 **
1108 ** Description Disable local NDEF tag
1109 ** - clean up control block
1110 ** - remove NDEF discovery configuration
1111 **
1112 ** Returns Nothing
1113 **
1114 *******************************************************************************/
nfa_ce_disable_local_tag(void)1115 void nfa_ce_disable_local_tag(void) {
1116 tNFA_CE_CB* p_cb = &nfa_ce_cb;
1117 tNFA_CONN_EVT_DATA evt_data;
1118
1119 DLOG_IF(INFO, nfc_debug_enabled) << StringPrintf("Disabling local NDEF tag");
1120
1121 /* If local NDEF tag is in use, then disable it */
1122 if (p_cb->listen_info[NFA_CE_LISTEN_INFO_IDX_NDEF].flags &
1123 NFA_CE_LISTEN_INFO_IN_USE) {
1124 /* NDEF Tag is in not idle state */
1125 if ((p_cb->flags & NFA_CE_FLAGS_LISTEN_ACTIVE_SLEEP) &&
1126 (p_cb->idx_cur_active == NFA_CE_LISTEN_INFO_IDX_NDEF)) {
1127 /* wait for deactivation */
1128 p_cb->flags |= NFA_CE_FLAGS_APP_INIT_DEACTIVATION;
1129 nfa_dm_rf_deactivate(NFA_DEACTIVATE_TYPE_IDLE);
1130 } else {
1131 /* Notify DM to stop listening for ndef */
1132 if (p_cb->listen_info[NFA_CE_LISTEN_INFO_IDX_NDEF].rf_disc_handle !=
1133 NFA_HANDLE_INVALID) {
1134 nfa_dm_delete_rf_discover(
1135 p_cb->listen_info[NFA_CE_LISTEN_INFO_IDX_NDEF].rf_disc_handle);
1136 p_cb->listen_info[NFA_CE_LISTEN_INFO_IDX_NDEF].rf_disc_handle =
1137 NFA_HANDLE_INVALID;
1138 }
1139 nfa_ce_remove_listen_info_entry(NFA_CE_LISTEN_INFO_IDX_NDEF, true);
1140 }
1141 } else {
1142 /* Notify application */
1143 evt_data.status = NFA_STATUS_OK;
1144 nfa_dm_conn_cback_event_notify(NFA_CE_LOCAL_TAG_CONFIGURED_EVT, &evt_data);
1145 }
1146 }
1147
1148 /*******************************************************************************
1149 **
1150 ** Function nfa_ce_api_cfg_local_tag
1151 **
1152 ** Description Configure local NDEF tag
1153 ** - store ndef attributes in to control block
1154 ** - update discovery configuration
1155 **
1156 ** Returns TRUE (message buffer to be freed by caller)
1157 **
1158 *******************************************************************************/
nfa_ce_api_cfg_local_tag(tNFA_CE_MSG * p_ce_msg)1159 bool nfa_ce_api_cfg_local_tag(tNFA_CE_MSG* p_ce_msg) {
1160 tNFA_CE_CB* p_cb = &nfa_ce_cb;
1161 tNFA_CONN_EVT_DATA conn_evt;
1162
1163 /* Check if disabling local tag */
1164 if (p_ce_msg->local_tag.protocol_mask == 0) {
1165 nfa_ce_disable_local_tag();
1166 return true;
1167 }
1168
1169 DLOG_IF(INFO, nfc_debug_enabled) << StringPrintf(
1170 "Configuring local NDEF tag: protocol_mask=%01x cur_size=%i, "
1171 "max_size=%i, readonly=%i uid_len=%i",
1172 p_ce_msg->local_tag.protocol_mask, p_ce_msg->local_tag.ndef_cur_size,
1173 p_ce_msg->local_tag.ndef_max_size, p_ce_msg->local_tag.read_only,
1174 p_ce_msg->local_tag.uid_len);
1175
1176 /* If local tag was already set, then check if NFA_CeConfigureLocalTag called
1177 * to change protocol mask */
1178 if ((p_cb->listen_info[NFA_CE_LISTEN_INFO_IDX_NDEF].flags &
1179 NFA_CE_LISTEN_INFO_IN_USE) &&
1180 (p_cb->listen_info[NFA_CE_LISTEN_INFO_IDX_NDEF].rf_disc_handle !=
1181 NFA_HANDLE_INVALID) &&
1182 ((p_cb->listen_info[NFA_CE_LISTEN_INFO_IDX_NDEF].protocol_mask &
1183 (NFA_PROTOCOL_MASK_T3T | NFA_PROTOCOL_MASK_ISO_DEP)) !=
1184 (p_ce_msg->local_tag.protocol_mask &
1185 (NFA_PROTOCOL_MASK_T3T | NFA_PROTOCOL_MASK_ISO_DEP)))) {
1186 /* Listening for different tag protocols. Stop discovery */
1187 nfa_dm_delete_rf_discover(
1188 p_cb->listen_info[NFA_CE_LISTEN_INFO_IDX_NDEF].rf_disc_handle);
1189 p_cb->listen_info[NFA_CE_LISTEN_INFO_IDX_NDEF].rf_disc_handle =
1190 NFA_HANDLE_INVALID;
1191
1192 /* clear NDEF contents */
1193 CE_T3tSetLocalNDEFMsg(true, 0, 0, nullptr, nullptr);
1194 CE_T4tSetLocalNDEFMsg(true, 0, 0, nullptr, nullptr);
1195 }
1196
1197 /* Store NDEF info to control block */
1198 p_cb->p_ndef_data = p_ce_msg->local_tag.p_ndef_data;
1199 p_cb->ndef_cur_size = p_ce_msg->local_tag.ndef_cur_size;
1200 p_cb->ndef_max_size = p_ce_msg->local_tag.ndef_max_size;
1201
1202 /* Fill in LISTEN_INFO entry for NDEF */
1203 p_cb->listen_info[NFA_CE_LISTEN_INFO_IDX_NDEF].flags =
1204 NFA_CE_LISTEN_INFO_IN_USE;
1205 p_cb->listen_info[NFA_CE_LISTEN_INFO_IDX_NDEF].protocol_mask =
1206 p_ce_msg->local_tag.protocol_mask;
1207 p_cb->listen_info[NFA_CE_LISTEN_INFO_IDX_NDEF].p_conn_cback =
1208 nfa_dm_conn_cback_event_notify;
1209 if (p_ce_msg->local_tag.read_only)
1210 p_cb->listen_info[NFA_CE_LISTEN_INFO_IDX_NDEF].flags |=
1211 NFC_CE_LISTEN_INFO_READONLY_NDEF;
1212 p_cb->listen_info[NFA_CE_LISTEN_INFO_IDX_NDEF].t3t_system_code =
1213 T3T_SYSTEM_CODE_NDEF;
1214
1215 /* Set NDEF contents */
1216 conn_evt.status = NFA_STATUS_FAILED;
1217
1218 if (p_cb->listen_info[NFA_CE_LISTEN_INFO_IDX_NDEF].protocol_mask &
1219 (NFA_PROTOCOL_MASK_T3T | NFA_PROTOCOL_MASK_ISO_DEP)) {
1220 /* Ok to set contents now */
1221 if (nfa_ce_set_content() != NFA_STATUS_OK) {
1222 LOG(ERROR) << StringPrintf(
1223 "nfa_ce_api_cfg_local_tag: could not set contents");
1224 nfa_dm_conn_cback_event_notify(NFA_CE_LOCAL_TAG_CONFIGURED_EVT,
1225 &conn_evt);
1226 return true;
1227 }
1228
1229 /* Start listening and notify app of status */
1230 conn_evt.status = nfa_ce_start_listening();
1231 nfa_dm_conn_cback_event_notify(NFA_CE_LOCAL_TAG_CONFIGURED_EVT, &conn_evt);
1232 }
1233
1234 return true;
1235 }
1236
1237 /*******************************************************************************
1238 **
1239 ** Function nfa_ce_api_reg_listen
1240 **
1241 ** Description Register listen params for Felica system code, T4T AID,
1242 ** or UICC
1243 **
1244 ** Returns TRUE (message buffer to be freed by caller)
1245 **
1246 *******************************************************************************/
nfa_ce_api_reg_listen(tNFA_CE_MSG * p_ce_msg)1247 bool nfa_ce_api_reg_listen(tNFA_CE_MSG* p_ce_msg) {
1248 tNFA_CE_CB* p_cb = &nfa_ce_cb;
1249 tNFA_CONN_EVT_DATA conn_evt;
1250 uint8_t i;
1251 uint8_t listen_info_idx = NFA_CE_LISTEN_INFO_IDX_INVALID;
1252
1253 DLOG_IF(INFO, nfc_debug_enabled)
1254 << StringPrintf("Registering UICC/Felica/Type-4 tag listener. Type=%i",
1255 p_ce_msg->reg_listen.listen_type);
1256
1257 /* Look for available entry in listen_info table */
1258 /* - If registering UICC listen, make sure there isn't another entry for the
1259 * ee_handle */
1260 /* - Skip over entry 0 (reserved for local NDEF tag) */
1261 for (i = 1; i < NFA_CE_LISTEN_INFO_MAX; i++) {
1262 if ((p_ce_msg->reg_listen.listen_type == NFA_CE_REG_TYPE_UICC) &&
1263 (p_cb->listen_info[i].flags & NFA_CE_LISTEN_INFO_IN_USE) &&
1264 (p_cb->listen_info[i].flags & NFA_CE_LISTEN_INFO_UICC) &&
1265 (p_cb->listen_info[i].ee_handle == p_ce_msg->reg_listen.ee_handle)) {
1266 if(p_cb->listen_info[i].tech_mask == p_ce_msg->reg_listen.tech_mask) {
1267 LOG(ERROR) << StringPrintf("UICC (0x%x) listening already specified",
1268 p_ce_msg->reg_listen.ee_handle);
1269 conn_evt.status = NFA_STATUS_FAILED;
1270 nfa_dm_conn_cback_event_notify(NFA_CE_UICC_LISTEN_CONFIGURED_EVT,
1271 &conn_evt);
1272 return true;
1273 } else {
1274 DLOG_IF(INFO, nfc_debug_enabled)
1275 << StringPrintf("UICC (0x%x) listening parameter changed to %x",
1276 p_ce_msg->reg_listen.ee_handle, p_ce_msg->reg_listen.tech_mask);
1277 listen_info_idx = i;
1278 break;
1279 }
1280 }
1281 /* If this is a free entry, and we haven't found one yet, remember it */
1282 else if ((!(p_cb->listen_info[i].flags & NFA_CE_LISTEN_INFO_IN_USE)) &&
1283 (listen_info_idx == NFA_CE_LISTEN_INFO_IDX_INVALID)) {
1284 listen_info_idx = i;
1285 }
1286 }
1287
1288 /* Add new entry to listen_info table */
1289 if (listen_info_idx == NFA_CE_LISTEN_INFO_IDX_INVALID) {
1290 LOG(ERROR) << StringPrintf("Maximum listen callbacks exceeded (%i)",
1291 NFA_CE_LISTEN_INFO_MAX);
1292
1293 if (p_ce_msg->reg_listen.listen_type == NFA_CE_REG_TYPE_UICC) {
1294 conn_evt.status = NFA_STATUS_FAILED;
1295 nfa_dm_conn_cback_event_notify(NFA_CE_UICC_LISTEN_CONFIGURED_EVT,
1296 &conn_evt);
1297 } else {
1298 /* Notify application */
1299 conn_evt.ce_registered.handle = NFA_HANDLE_INVALID;
1300 conn_evt.ce_registered.status = NFA_STATUS_FAILED;
1301 (*p_ce_msg->reg_listen.p_conn_cback)(NFA_CE_REGISTERED_EVT, &conn_evt);
1302 }
1303 return true;
1304 } else {
1305 DLOG_IF(INFO, nfc_debug_enabled)
1306 << StringPrintf("NFA_CE: adding listen_info entry %i", listen_info_idx);
1307
1308 /* Store common parameters */
1309 /* Mark entry as 'in-use', and NFA_CE_LISTEN_INFO_START_NTF_PND */
1310 /* (LISTEN_START_EVT will be notified when discovery successfully starts */
1311 p_cb->listen_info[listen_info_idx].flags =
1312 NFA_CE_LISTEN_INFO_IN_USE | NFA_CE_LISTEN_INFO_START_NTF_PND;
1313 p_cb->listen_info[listen_info_idx].rf_disc_handle = NFA_HANDLE_INVALID;
1314 p_cb->listen_info[listen_info_idx].protocol_mask = 0;
1315
1316 /* Store type-specific parameters */
1317 switch (p_ce_msg->reg_listen.listen_type) {
1318 case NFA_CE_REG_TYPE_ISO_DEP:
1319 p_cb->listen_info[listen_info_idx].protocol_mask =
1320 NFA_PROTOCOL_MASK_ISO_DEP;
1321 p_cb->listen_info[listen_info_idx].flags |= NFA_CE_LISTEN_INFO_T4T_AID;
1322 p_cb->listen_info[listen_info_idx].p_conn_cback =
1323 p_ce_msg->reg_listen.p_conn_cback;
1324
1325 /* Register this AID with CE_T4T */
1326 p_cb->listen_info[listen_info_idx].t4t_aid_handle = CE_T4tRegisterAID(
1327 p_ce_msg->reg_listen.aid_len, p_ce_msg->reg_listen.aid,
1328 nfa_ce_handle_t4t_aid_evt);
1329 if (p_cb->listen_info[listen_info_idx].t4t_aid_handle ==
1330 CE_T4T_AID_HANDLE_INVALID) {
1331 LOG(ERROR) << StringPrintf("Unable to register AID");
1332 p_cb->listen_info[listen_info_idx].flags = 0;
1333
1334 /* Notify application */
1335 conn_evt.ce_registered.handle = NFA_HANDLE_INVALID;
1336 conn_evt.ce_registered.status = NFA_STATUS_FAILED;
1337 (*p_ce_msg->reg_listen.p_conn_cback)(NFA_CE_REGISTERED_EVT,
1338 &conn_evt);
1339
1340 return true;
1341 }
1342 if (p_cb->listen_info[listen_info_idx].t4t_aid_handle ==
1343 CE_T4T_WILDCARD_AID_HANDLE)
1344 nfa_ce_cb.idx_wild_card = listen_info_idx;
1345 break;
1346
1347 case NFA_CE_REG_TYPE_FELICA:
1348 p_cb->listen_info[listen_info_idx].protocol_mask =
1349 NFA_PROTOCOL_MASK_T3T;
1350 p_cb->listen_info[listen_info_idx].flags |= NFA_CE_LISTEN_INFO_FELICA;
1351 p_cb->listen_info[listen_info_idx].p_conn_cback =
1352 p_ce_msg->reg_listen.p_conn_cback;
1353
1354 /* Store system code and nfcid2 */
1355 p_cb->listen_info[listen_info_idx].t3t_system_code =
1356 p_ce_msg->reg_listen.system_code;
1357 memcpy(p_cb->listen_info[listen_info_idx].t3t_nfcid2,
1358 p_ce_msg->reg_listen.nfcid2, NCI_RF_F_UID_LEN);
1359 memcpy(p_cb->listen_info[listen_info_idx].t3t_pmm,
1360 p_ce_msg->reg_listen.t3tPmm, NCI_T3T_PMM_LEN);
1361 break;
1362
1363 #if (NFC_NFCEE_INCLUDED == TRUE)
1364 case NFA_CE_REG_TYPE_UICC:
1365 p_cb->listen_info[listen_info_idx].flags |= NFA_CE_LISTEN_INFO_UICC;
1366 p_cb->listen_info[listen_info_idx].p_conn_cback =
1367 &nfa_dm_conn_cback_event_notify;
1368
1369 /* Store EE handle and Tech */
1370 p_cb->listen_info[listen_info_idx].ee_handle =
1371 p_ce_msg->reg_listen.ee_handle;
1372 p_cb->listen_info[listen_info_idx].tech_mask =
1373 p_ce_msg->reg_listen.tech_mask;
1374 break;
1375 #endif
1376 }
1377 }
1378
1379 /* Start listening */
1380 conn_evt.status = nfa_ce_start_listening();
1381 if (conn_evt.status != NFA_STATUS_OK) {
1382 LOG(ERROR) << StringPrintf(
1383 "nfa_ce_api_reg_listen: unable to register new listen params with DM");
1384 p_cb->listen_info[listen_info_idx].flags = 0;
1385 }
1386
1387 /* Nofitify app of status */
1388 if (p_ce_msg->reg_listen.listen_type == NFA_CE_REG_TYPE_UICC) {
1389 (*p_cb->listen_info[listen_info_idx].p_conn_cback)(
1390 NFA_CE_UICC_LISTEN_CONFIGURED_EVT, &conn_evt);
1391 } else {
1392 conn_evt.ce_registered.handle = NFA_HANDLE_GROUP_CE | listen_info_idx;
1393 DLOG_IF(INFO, nfc_debug_enabled)
1394 << StringPrintf("nfa_ce_api_reg_listen: registered handle 0x%04X",
1395 conn_evt.ce_registered.handle);
1396 (*p_cb->listen_info[listen_info_idx].p_conn_cback)(NFA_CE_REGISTERED_EVT,
1397 &conn_evt);
1398 }
1399
1400 return true;
1401 }
1402
1403 /*******************************************************************************
1404 **
1405 ** Function nfa_ce_api_dereg_listen
1406 **
1407 ** Description Deregister listen params
1408 **
1409 ** Returns TRUE (message buffer to be freed by caller)
1410 **
1411 *******************************************************************************/
nfa_ce_api_dereg_listen(tNFA_CE_MSG * p_ce_msg)1412 bool nfa_ce_api_dereg_listen(tNFA_CE_MSG* p_ce_msg) {
1413 tNFA_CE_CB* p_cb = &nfa_ce_cb;
1414 uint8_t listen_info_idx;
1415 tNFA_CONN_EVT_DATA conn_evt;
1416
1417 #if (NFC_NFCEE_INCLUDED == TRUE)
1418 /* Check if deregistering UICC , or virtual secure element listen */
1419 if (p_ce_msg->dereg_listen.listen_info == NFA_CE_LISTEN_INFO_UICC) {
1420 /* Deregistering UICC listen. Look for listen_info for this UICC ee handle
1421 */
1422 for (listen_info_idx = 0; listen_info_idx < NFA_CE_LISTEN_INFO_MAX;
1423 listen_info_idx++) {
1424 if ((p_cb->listen_info[listen_info_idx].flags &
1425 NFA_CE_LISTEN_INFO_IN_USE) &&
1426 (p_cb->listen_info[listen_info_idx].flags &
1427 NFA_CE_LISTEN_INFO_UICC) &&
1428 (p_cb->listen_info[listen_info_idx].ee_handle ==
1429 p_ce_msg->dereg_listen.handle)) {
1430 /* UICC is in not idle state */
1431 if ((p_cb->flags & NFA_CE_FLAGS_LISTEN_ACTIVE_SLEEP) &&
1432 (p_cb->idx_cur_active == listen_info_idx)) {
1433 /* wait for deactivation */
1434 p_cb->flags |= NFA_CE_FLAGS_APP_INIT_DEACTIVATION;
1435 nfa_dm_rf_deactivate(NFA_DEACTIVATE_TYPE_IDLE);
1436 } else {
1437 /* Stop listening */
1438 if (p_cb->listen_info[listen_info_idx].rf_disc_handle !=
1439 NFA_HANDLE_INVALID) {
1440 nfa_dm_delete_rf_discover(
1441 p_cb->listen_info[listen_info_idx].rf_disc_handle);
1442 p_cb->listen_info[listen_info_idx].rf_disc_handle =
1443 NFA_HANDLE_INVALID;
1444 }
1445
1446 /* Remove entry and notify application */
1447 nfa_ce_remove_listen_info_entry(listen_info_idx, true);
1448 }
1449 break;
1450 }
1451 }
1452
1453 if (listen_info_idx == NFA_CE_LISTEN_INFO_MAX) {
1454 LOG(ERROR) << StringPrintf("cannot find listen_info for UICC");
1455 conn_evt.status = NFA_STATUS_INVALID_PARAM;
1456 nfa_dm_conn_cback_event_notify(NFA_CE_UICC_LISTEN_CONFIGURED_EVT,
1457 &conn_evt);
1458 }
1459 } else
1460 #endif
1461 {
1462 /* Deregistering virtual secure element listen */
1463 listen_info_idx = p_ce_msg->dereg_listen.handle & NFA_HANDLE_MASK;
1464 if (nfa_ce_cb.idx_wild_card == listen_info_idx) {
1465 nfa_ce_cb.idx_wild_card = NFA_CE_LISTEN_INFO_IDX_INVALID;
1466 }
1467
1468 if ((listen_info_idx < NFA_CE_LISTEN_INFO_MAX) &&
1469 (p_cb->listen_info[listen_info_idx].flags &
1470 NFA_CE_LISTEN_INFO_IN_USE)) {
1471 /* virtual secure element is in not idle state */
1472 if ((p_cb->flags & NFA_CE_FLAGS_LISTEN_ACTIVE_SLEEP) &&
1473 (p_cb->idx_cur_active == listen_info_idx)) {
1474 /* wait for deactivation */
1475 p_cb->flags |= NFA_CE_FLAGS_APP_INIT_DEACTIVATION;
1476 nfa_dm_rf_deactivate(NFA_DEACTIVATE_TYPE_IDLE);
1477 } else {
1478 /* Stop listening */
1479 if (p_cb->listen_info[listen_info_idx].rf_disc_handle !=
1480 NFA_HANDLE_INVALID) {
1481 nfa_dm_delete_rf_discover(
1482 p_cb->listen_info[listen_info_idx].rf_disc_handle);
1483 p_cb->listen_info[listen_info_idx].rf_disc_handle =
1484 NFA_HANDLE_INVALID;
1485 }
1486
1487 /* Remove entry and notify application */
1488 nfa_ce_remove_listen_info_entry(listen_info_idx, true);
1489 }
1490 } else {
1491 LOG(ERROR) << StringPrintf(
1492 "cannot find listen_info for "
1493 "Felica/T4tAID");
1494 conn_evt.status = NFA_STATUS_INVALID_PARAM;
1495 nfa_dm_conn_cback_event_notify(NFA_CE_DEREGISTERED_EVT, &conn_evt);
1496 }
1497 }
1498
1499 return true;
1500 }
1501
1502 /*******************************************************************************
1503 **
1504 ** Function nfa_ce_api_cfg_isodep_tech
1505 **
1506 ** Description Configure the technologies (NFC-A and/or NFC-B) to listen
1507 ** for ISO-DEP
1508 **
1509 ** Returns TRUE (message buffer to be freed by caller)
1510 **
1511 *******************************************************************************/
nfa_ce_api_cfg_isodep_tech(tNFA_CE_MSG * p_ce_msg)1512 bool nfa_ce_api_cfg_isodep_tech(tNFA_CE_MSG* p_ce_msg) {
1513 nfa_ce_cb.isodep_disc_mask = 0;
1514 if (p_ce_msg->hdr.layer_specific & NFA_TECHNOLOGY_MASK_A)
1515 nfa_ce_cb.isodep_disc_mask = NFA_DM_DISC_MASK_LA_ISO_DEP;
1516
1517 if (p_ce_msg->hdr.layer_specific & NFA_TECHNOLOGY_MASK_B)
1518 nfa_ce_cb.isodep_disc_mask |= NFA_DM_DISC_MASK_LB_ISO_DEP;
1519 return true;
1520 }
1521