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