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