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