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 38using android::base::StringPrintf; 39 40extern 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*******************************************************************************/ 55void 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*******************************************************************************/ 149void 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*******************************************************************************/ 208void 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*******************************************************************************/ 282void 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*******************************************************************************/ 323void 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*******************************************************************************/ 398void 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*******************************************************************************/ 425tNFA_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*******************************************************************************/ 558bool 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*******************************************************************************/ 592void 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*******************************************************************************/ 674void 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*******************************************************************************/ 691tNFA_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*******************************************************************************/ 735tNFC_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*******************************************************************************/ 801bool 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*******************************************************************************/ 1001bool 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*******************************************************************************/ 1106void 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*******************************************************************************/ 1150bool 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*******************************************************************************/ 1238bool 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*******************************************************************************/ 1395bool 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*******************************************************************************/ 1495bool 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