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