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