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