1/****************************************************************************** 2 * 3 * Copyright (C) 2010-2014 Broadcom Corporation 4 * 5 * Licensed under the Apache License, Version 2.0 (the "License"); 6 * you may not use this file except in compliance with the License. 7 * You may obtain a copy of the License at: 8 * 9 * http://www.apache.org/licenses/LICENSE-2.0 10 * 11 * Unless required by applicable law or agreed to in writing, software 12 * distributed under the License is distributed on an "AS IS" BASIS, 13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 * See the License for the specific language governing permissions and 15 * limitations under the License. 16 * 17 ******************************************************************************/ 18 19 20/****************************************************************************** 21 * 22 * This file contains the action functions the NFA_RW state machine. 23 * 24 ******************************************************************************/ 25#include <string.h> 26#include "nfa_rw_int.h" 27#include "nfa_dm_int.h" 28#include "nfa_sys_int.h" 29#include "nfa_mem_co.h" 30#include "ndef_utils.h" 31#include "rw_api.h" 32 33#define NFA_RW_OPTION_INVALID 0xFF 34 35/* Local static function prototypes */ 36static tNFC_STATUS nfa_rw_start_ndef_read(void); 37static tNFC_STATUS nfa_rw_start_ndef_write(void); 38static tNFC_STATUS nfa_rw_start_ndef_detection(void); 39static tNFC_STATUS nfa_rw_config_tag_ro(BOOLEAN b_hard_lock); 40static BOOLEAN nfa_rw_op_req_while_busy(tNFA_RW_MSG *p_data); 41static void nfa_rw_error_cleanup (UINT8 event); 42static void nfa_rw_presence_check (tNFA_RW_MSG *p_data); 43static void nfa_rw_handle_t2t_evt (tRW_EVENT event, tRW_DATA *p_rw_data); 44static BOOLEAN nfa_rw_detect_ndef(tNFA_RW_MSG *p_data); 45static void nfa_rw_cback (tRW_EVENT event, tRW_DATA *p_rw_data); 46 47/******************************************************************************* 48** 49** Function nfa_rw_free_ndef_rx_buf 50** 51** Description Free buffer allocated to hold incoming NDEF message 52** 53** Returns Nothing 54** 55*******************************************************************************/ 56void nfa_rw_free_ndef_rx_buf(void) 57{ 58 if (nfa_rw_cb.p_ndef_buf) 59 { 60 nfa_mem_co_free(nfa_rw_cb.p_ndef_buf); 61 nfa_rw_cb.p_ndef_buf = NULL; 62 } 63} 64 65/******************************************************************************* 66** 67** Function nfa_rw_store_ndef_rx_buf 68** 69** Description Store data into NDEF buffer 70** 71** Returns Nothing 72** 73*******************************************************************************/ 74static void nfa_rw_store_ndef_rx_buf (tRW_DATA *p_rw_data) 75{ 76 UINT8 *p; 77 78 p = (UINT8 *)(p_rw_data->data.p_data + 1) + p_rw_data->data.p_data->offset; 79 80 /* Save data into buffer */ 81 memcpy(&nfa_rw_cb.p_ndef_buf[nfa_rw_cb.ndef_rd_offset], p, p_rw_data->data.p_data->len); 82 nfa_rw_cb.ndef_rd_offset += p_rw_data->data.p_data->len; 83 84 GKI_freebuf(p_rw_data->data.p_data); 85 p_rw_data->data.p_data = NULL; 86} 87 88/******************************************************************************* 89** 90** Function nfa_rw_send_data_to_upper 91** 92** Description Send data to upper layer 93** 94** Returns Nothing 95** 96*******************************************************************************/ 97static void nfa_rw_send_data_to_upper (tRW_DATA *p_rw_data) 98{ 99 tNFA_CONN_EVT_DATA conn_evt_data; 100 101 if ( (p_rw_data->status == NFC_STATUS_TIMEOUT) 102 ||(p_rw_data->data.p_data == NULL) ) 103 return; 104 105#if (BT_TRACE_VERBOSE == TRUE) 106 NFA_TRACE_DEBUG2 ("nfa_rw_send_data_to_upper: Len [0x%X] Status [%s]", p_rw_data->data.p_data->len, NFC_GetStatusName (p_rw_data->data.status)); 107#else 108 NFA_TRACE_DEBUG2 ("nfa_rw_send_data_to_upper: Len [0x%X] Status [0x%X]", p_rw_data->data.p_data->len, p_rw_data->data.status); 109#endif 110 111 /* Notify conn cback of NFA_DATA_EVT */ 112 conn_evt_data.data.status = p_rw_data->data.status; 113 conn_evt_data.data.p_data = (UINT8 *)(p_rw_data->data.p_data + 1) + p_rw_data->data.p_data->offset; 114 conn_evt_data.data.len = p_rw_data->data.p_data->len; 115 116 nfa_dm_act_conn_cback_notify(NFA_DATA_EVT, &conn_evt_data); 117 118 GKI_freebuf(p_rw_data->data.p_data); 119 p_rw_data->data.p_data = NULL; 120} 121 122/******************************************************************************* 123** 124** Function nfa_rw_error_cleanup 125** 126** Description Handle failure - signal command complete and notify app 127** 128** Returns Nothing 129** 130*******************************************************************************/ 131static void nfa_rw_error_cleanup (UINT8 event) 132{ 133 tNFA_CONN_EVT_DATA conn_evt_data; 134 135 nfa_rw_command_complete(); 136 137 conn_evt_data.status = NFA_STATUS_FAILED; 138 139 nfa_dm_act_conn_cback_notify (event, &conn_evt_data); 140} 141 142/******************************************************************************* 143** 144** Function nfa_rw_check_start_presence_check_timer 145** 146** Description Start timer to wait for specified time before presence check 147** 148** Returns Nothing 149** 150*******************************************************************************/ 151static void nfa_rw_check_start_presence_check_timer (UINT16 presence_check_start_delay) 152{ 153 if (!p_nfa_dm_cfg->auto_presence_check) 154 return; 155 156 if (nfa_rw_cb.flags & NFA_RW_FL_NOT_EXCL_RF_MODE) 157 { 158 if (presence_check_start_delay) 159 { 160 NFA_TRACE_DEBUG0("Starting presence check timer..."); 161 nfa_sys_start_timer(&nfa_rw_cb.tle, NFA_RW_PRESENCE_CHECK_TICK_EVT, presence_check_start_delay); 162 } 163 else 164 { 165 /* Presence check now */ 166 nfa_rw_presence_check (NULL); 167 } 168 } 169} 170 171/******************************************************************************* 172** 173** Function nfa_rw_stop_presence_check_timer 174** 175** Description Stop timer for presence check 176** 177** Returns Nothing 178** 179*******************************************************************************/ 180void nfa_rw_stop_presence_check_timer(void) 181{ 182 nfa_sys_stop_timer(&nfa_rw_cb.tle); 183 NFA_TRACE_DEBUG0("Stopped presence check timer (if started)"); 184} 185 186/******************************************************************************* 187** 188** Function nfa_rw_handle_ndef_detect 189** 190** Description Handler for NDEF detection reader/writer event 191** 192** Returns Nothing 193** 194*******************************************************************************/ 195static void nfa_rw_handle_ndef_detect(tRW_EVENT event, tRW_DATA *p_rw_data) 196{ 197 tNFA_CONN_EVT_DATA conn_evt_data; 198 199 NFA_TRACE_DEBUG3("NDEF Detection completed: cur_size=%i, max_size=%i, flags=0x%x", 200 p_rw_data->ndef.cur_size, p_rw_data->ndef.max_size, p_rw_data->ndef.flags); 201 202 /* Check if NDEF detection succeeded */ 203 if (p_rw_data->ndef.status == NFC_STATUS_OK) 204 { 205 /* Set NDEF detection state */ 206 nfa_rw_cb.ndef_st = NFA_RW_NDEF_ST_TRUE; 207 nfa_rw_cb.flags |= NFA_RW_FL_NDEF_OK; 208 209 /* Store ndef properties */ 210 conn_evt_data.ndef_detect.status = NFA_STATUS_OK; 211 conn_evt_data.ndef_detect.protocol = p_rw_data->ndef.protocol; 212 conn_evt_data.ndef_detect.cur_size = nfa_rw_cb.ndef_cur_size = p_rw_data->ndef.cur_size; 213 conn_evt_data.ndef_detect.max_size = nfa_rw_cb.ndef_max_size = p_rw_data->ndef.max_size; 214 conn_evt_data.ndef_detect.flags = p_rw_data->ndef.flags; 215 216 if (p_rw_data->ndef.flags & RW_NDEF_FL_READ_ONLY) 217 nfa_rw_cb.flags |= NFA_RW_FL_TAG_IS_READONLY; 218 else 219 nfa_rw_cb.flags &= ~NFA_RW_FL_TAG_IS_READONLY; 220 221 /* Determine what operation triggered the NDEF detection procedure */ 222 if (nfa_rw_cb.cur_op == NFA_RW_OP_READ_NDEF) 223 { 224 /* if ndef detection was done as part of ndef-read operation, then perform ndef read now */ 225 if ((conn_evt_data.status = nfa_rw_start_ndef_read()) != NFA_STATUS_OK) 226 { 227 /* Failed to start NDEF Read */ 228 229 /* Command complete - perform cleanup, notify app */ 230 nfa_rw_command_complete(); 231 nfa_dm_act_conn_cback_notify(NFA_READ_CPLT_EVT, &conn_evt_data); 232 } 233 } 234 else if (nfa_rw_cb.cur_op == NFA_RW_OP_WRITE_NDEF) 235 { 236 /* if ndef detection was done as part of ndef-write operation, then perform ndef write now */ 237 if ((conn_evt_data.status = nfa_rw_start_ndef_write()) != NFA_STATUS_OK) 238 { 239 /* Failed to start NDEF Write. */ 240 241 /* Command complete - perform cleanup, notify app */ 242 nfa_rw_command_complete(); 243 nfa_dm_act_conn_cback_notify(NFA_WRITE_CPLT_EVT, &conn_evt_data); 244 } 245 } 246 else 247 { 248 /* current op was stand-alone NFA_DetectNDef. Command complete - perform cleanup and notify app */ 249 nfa_rw_cb.cur_op = NFA_RW_OP_MAX; 250 nfa_rw_command_complete(); 251 252 nfa_dm_act_conn_cback_notify(NFA_NDEF_DETECT_EVT, &conn_evt_data); 253 } 254 } 255 else 256 { 257 /* NDEF detection failed... */ 258 259 /* Command complete - perform cleanup, notify app */ 260 nfa_rw_command_complete(); 261 nfa_rw_cb.ndef_st = NFA_RW_NDEF_ST_FALSE; 262 conn_evt_data.status = p_rw_data->ndef.status; 263 264 if (nfa_rw_cb.cur_op == NFA_RW_OP_READ_NDEF) 265 { 266 /* if ndef detection was done as part of ndef-read operation, then notify NDEF handlers of failure */ 267 nfa_dm_ndef_handle_message(NFA_STATUS_FAILED, NULL, 0); 268 269 /* Notify app of read status */ 270 nfa_dm_act_conn_cback_notify(NFA_READ_CPLT_EVT, &conn_evt_data); 271 } 272 else if (nfa_rw_cb.cur_op == NFA_RW_OP_WRITE_NDEF) 273 { 274 /* if ndef detection was done as part of ndef-write operation, then notify app of failure */ 275 nfa_dm_act_conn_cback_notify(NFA_WRITE_CPLT_EVT, &conn_evt_data); 276 } 277 else if (nfa_rw_cb.cur_op == NFA_RW_OP_DETECT_NDEF) 278 { 279 conn_evt_data.ndef_detect.protocol = p_rw_data->ndef.protocol; 280 /* current op was stand-alone NFA_DetectNDef. Notify app of failure */ 281 if (p_rw_data->ndef.status == NFC_STATUS_TIMEOUT) 282 { 283 /* Tag could have moved away */ 284 conn_evt_data.ndef_detect.cur_size = 0; 285 conn_evt_data.ndef_detect.max_size = 0; 286 conn_evt_data.ndef_detect.flags = RW_NDEF_FL_UNKNOWN; 287 } 288 else 289 { 290 /* NDEF Detection failed for other reasons */ 291 conn_evt_data.ndef_detect.cur_size = nfa_rw_cb.ndef_cur_size = p_rw_data->ndef.cur_size; 292 conn_evt_data.ndef_detect.max_size = nfa_rw_cb.ndef_max_size = p_rw_data->ndef.max_size; 293 conn_evt_data.ndef_detect.flags = p_rw_data->ndef.flags; 294 } 295 nfa_dm_act_conn_cback_notify(NFA_NDEF_DETECT_EVT, &conn_evt_data); 296 } 297 298 nfa_rw_cb.cur_op = NFA_RW_OP_MAX; /* clear current operation */ 299 } 300} 301 302/******************************************************************************* 303** 304** Function nfa_rw_handle_tlv_detect 305** 306** Description Handler for TLV detection reader/writer event 307** 308** Returns Nothing 309** 310*******************************************************************************/ 311static void nfa_rw_handle_tlv_detect(tRW_EVENT event, tRW_DATA *p_rw_data) 312{ 313 tNFA_CONN_EVT_DATA conn_evt_data; 314 315 /* Set TLV detection state */ 316 if (nfa_rw_cb.cur_op == NFA_RW_OP_SET_TAG_RO) 317 { 318 if(nfa_rw_cb.tlv_st == NFA_RW_TLV_DETECT_ST_OP_NOT_STARTED) 319 { 320 nfa_rw_cb.tlv_st = NFA_RW_TLV_DETECT_ST_LOCK_TLV_OP_COMPLETE; 321 } 322 else 323 { 324 nfa_rw_cb.tlv_st = NFA_RW_TLV_DETECT_ST_COMPLETE; 325 } 326 } 327 else 328 { 329 if(nfa_rw_cb.cur_op == NFA_RW_OP_DETECT_LOCK_TLV) 330 { 331 nfa_rw_cb.tlv_st |= NFA_RW_TLV_DETECT_ST_LOCK_TLV_OP_COMPLETE; 332 } 333 else if(nfa_rw_cb.cur_op == NFA_RW_OP_DETECT_MEM_TLV) 334 { 335 nfa_rw_cb.tlv_st |= NFA_RW_TLV_DETECT_ST_MEM_TLV_OP_COMPLETE; 336 } 337 } 338 339 /* Check if TLV detection succeeded */ 340 if (p_rw_data->tlv.status == NFC_STATUS_OK) 341 { 342 NFA_TRACE_DEBUG1("TLV Detection succeeded: num_bytes=%i",p_rw_data->tlv.num_bytes); 343 344 /* Store tlv properties */ 345 conn_evt_data.tlv_detect.status = NFA_STATUS_OK; 346 conn_evt_data.tlv_detect.protocol = p_rw_data->tlv.protocol; 347 conn_evt_data.tlv_detect.num_bytes = p_rw_data->tlv.num_bytes; 348 349 350 /* Determine what operation triggered the TLV detection procedure */ 351 if(nfa_rw_cb.cur_op == NFA_RW_OP_SET_TAG_RO) 352 { 353 if (nfa_rw_config_tag_ro(nfa_rw_cb.b_hard_lock) != NFC_STATUS_OK) 354 { 355 /* Failed to set tag read only */ 356 conn_evt_data.tlv_detect.status = NFA_STATUS_FAILED; 357 nfa_dm_act_conn_cback_notify(NFA_SET_TAG_RO_EVT, &conn_evt_data); 358 } 359 } 360 else 361 { 362 /* current op was stand-alone NFA_DetectTlv. Command complete - perform cleanup and notify app */ 363 nfa_rw_command_complete(); 364 nfa_dm_act_conn_cback_notify(NFA_TLV_DETECT_EVT, &conn_evt_data); 365 } 366 } 367 368 /* Handle failures */ 369 if (p_rw_data->tlv.status != NFC_STATUS_OK) 370 { 371 /* Command complete - perform cleanup, notify the app */ 372 nfa_rw_command_complete(); 373 374 conn_evt_data.tlv_detect.status = NFA_STATUS_FAILED; 375 if( (nfa_rw_cb.cur_op == NFA_RW_OP_DETECT_LOCK_TLV) 376 ||(nfa_rw_cb.cur_op == NFA_RW_OP_DETECT_MEM_TLV) ) 377 { 378 nfa_dm_act_conn_cback_notify(NFA_TLV_DETECT_EVT, &conn_evt_data); 379 } 380 else if(nfa_rw_cb.cur_op == NFA_RW_OP_SET_TAG_RO) 381 { 382 if (nfa_rw_config_tag_ro(nfa_rw_cb.b_hard_lock) != NFC_STATUS_OK) 383 { 384 /* Failed to set tag read only */ 385 conn_evt_data.tlv_detect.status = NFA_STATUS_FAILED; 386 nfa_dm_act_conn_cback_notify(NFA_SET_TAG_RO_EVT, &conn_evt_data); 387 } 388 } 389 } 390} 391 392/******************************************************************************* 393** 394** Function nfa_rw_handle_sleep_wakeup_rsp 395** 396** Description Handl sleep wakeup 397** 398** Returns Nothing 399** 400*******************************************************************************/ 401void nfa_rw_handle_sleep_wakeup_rsp (tNFC_STATUS status) 402{ 403 tNFC_ACTIVATE_DEVT activate_params; 404 tRW_EVENT event; 405 406 if ( (nfa_rw_cb.halt_event != RW_T2T_MAX_EVT) 407 &&(nfa_rw_cb.activated_tech_mode == NFC_DISCOVERY_TYPE_POLL_A) 408 &&(nfa_rw_cb.protocol == NFC_PROTOCOL_T2T) 409 &&(nfa_rw_cb.pa_sel_res == NFC_SEL_RES_NFC_FORUM_T2T) ) 410 { 411 NFA_TRACE_DEBUG0("nfa_rw_handle_sleep_wakeup_rsp; Attempt to wake up Type 2 tag from HALT State is complete"); 412 if (status == NFC_STATUS_OK) 413 { 414 /* Type 2 Tag is wakeup from HALT state */ 415 NFA_TRACE_DEBUG0("nfa_rw_handle_sleep_wakeup_rsp; Handle the NACK rsp received now"); 416 /* Initialize control block */ 417 activate_params.protocol = nfa_rw_cb.protocol; 418 activate_params.rf_tech_param.param.pa.sel_rsp = nfa_rw_cb.pa_sel_res; 419 activate_params.rf_tech_param.mode = nfa_rw_cb.activated_tech_mode; 420 421 /* Initialize RW module */ 422 if ((RW_SetActivatedTagType (&activate_params, nfa_rw_cback)) != NFC_STATUS_OK) 423 { 424 /* Log error (stay in NFA_RW_ST_ACTIVATED state until deactivation) */ 425 NFA_TRACE_ERROR0("RW_SetActivatedTagType failed."); 426 if (nfa_rw_cb.halt_event == RW_T2T_READ_CPLT_EVT) 427 { 428 if (nfa_rw_cb.rw_data.data.p_data) 429 GKI_freebuf(nfa_rw_cb.rw_data.data.p_data); 430 nfa_rw_cb.rw_data.data.p_data = NULL; 431 } 432 /* Do not try to detect NDEF again but just notify current operation failed */ 433 nfa_rw_cb.halt_event = RW_T2T_MAX_EVT; 434 } 435 } 436 437 /* The current operation failed with NACK rsp from type 2 tag */ 438 nfa_rw_cb.rw_data.status = NFC_STATUS_FAILED; 439 event = nfa_rw_cb.halt_event; 440 441 /* Got NACK rsp during presence check and legacy presence check performed */ 442 if (nfa_rw_cb.cur_op == NFA_RW_OP_PRESENCE_CHECK) 443 nfa_rw_cb.rw_data.status = status; 444 445 /* If cannot Sleep wakeup tag, then NDEF Detect operation is complete */ 446 if ((status != NFC_STATUS_OK) && (nfa_rw_cb.halt_event == RW_T2T_NDEF_DETECT_EVT)) 447 nfa_rw_cb.halt_event = RW_T2T_MAX_EVT; 448 449 nfa_rw_handle_t2t_evt (event, &nfa_rw_cb.rw_data); 450 nfa_rw_cb.halt_event = RW_T2T_MAX_EVT; 451 452 /* If Type 2 tag sleep wakeup failed and If in normal mode (not-exclusive RF mode) then deactivate the link if sleep wakeup failed */ 453 if ((nfa_rw_cb.flags & NFA_RW_FL_NOT_EXCL_RF_MODE) && (status != NFC_STATUS_OK)) 454 { 455 NFA_TRACE_DEBUG0("Sleep wakeup failed. Deactivating..."); 456 nfa_dm_rf_deactivate (NFA_DEACTIVATE_TYPE_DISCOVERY); 457 } 458 } 459 else 460 { 461 NFA_TRACE_DEBUG0("nfa_rw_handle_sleep_wakeup_rsp; Legacy presence check performed"); 462 /* Legacy presence check performed */ 463 nfa_rw_handle_presence_check_rsp (status); 464 } 465} 466 467/******************************************************************************* 468** 469** Function nfa_rw_handle_presence_check_rsp 470** 471** Description Handler RW_T#t_PRESENCE_CHECK_EVT 472** 473** Returns Nothing 474** 475*******************************************************************************/ 476void nfa_rw_handle_presence_check_rsp (tNFC_STATUS status) 477{ 478 BT_HDR *p_pending_msg; 479 480 /* Stop the presence check timer - timer may have been started when presence check started */ 481 nfa_rw_stop_presence_check_timer(); 482 if (status == NFA_STATUS_OK) 483 { 484 /* Clear the BUSY flag and restart the presence-check timer */ 485 nfa_rw_command_complete(); 486 } 487 else 488 { 489 /* If presence check failed just clear the BUSY flag */ 490 nfa_rw_cb.flags &= ~NFA_RW_FL_API_BUSY; 491 } 492 493 /* Handle presence check due to auto-presence-check */ 494 if (nfa_rw_cb.flags & NFA_RW_FL_AUTO_PRESENCE_CHECK_BUSY) 495 { 496 nfa_rw_cb.flags &= ~NFA_RW_FL_AUTO_PRESENCE_CHECK_BUSY; 497 498 /* If an API was called during auto-presence-check, then handle it now */ 499 if (nfa_rw_cb.p_pending_msg) 500 { 501 /* If NFA_RwPresenceCheck was called during auto-presence-check, notify app of result */ 502 if (nfa_rw_cb.p_pending_msg->op_req.op == NFA_RW_OP_PRESENCE_CHECK) 503 { 504 /* Notify app of presence check status */ 505 nfa_dm_act_conn_cback_notify(NFA_PRESENCE_CHECK_EVT, (tNFA_CONN_EVT_DATA *)&status); 506 GKI_freebuf(nfa_rw_cb.p_pending_msg); 507 nfa_rw_cb.p_pending_msg = NULL; 508 } 509 /* For all other APIs called during auto-presence check, perform the command now (if tag is still present) */ 510 else if (status == NFC_STATUS_OK) 511 { 512 NFA_TRACE_DEBUG0("Performing deferred operation after presence check..."); 513 p_pending_msg = (BT_HDR *)nfa_rw_cb.p_pending_msg; 514 nfa_rw_cb.p_pending_msg = NULL; 515 nfa_rw_handle_event(p_pending_msg); 516 GKI_freebuf (p_pending_msg); 517 } 518 else 519 { 520 /* Tag no longer present. Free command for pending API command */ 521 GKI_freebuf(nfa_rw_cb.p_pending_msg); 522 nfa_rw_cb.p_pending_msg = NULL; 523 } 524 } 525 526 /* Auto-presence check failed. Deactivate */ 527 if (status != NFC_STATUS_OK) 528 { 529 NFA_TRACE_DEBUG0("Auto presence check failed. Deactivating..."); 530 nfa_dm_rf_deactivate (NFA_DEACTIVATE_TYPE_DISCOVERY); 531 } 532 } 533 /* Handle presence check due to NFA_RwPresenceCheck API call */ 534 else 535 { 536 /* Notify app of presence check status */ 537 nfa_dm_act_conn_cback_notify(NFA_PRESENCE_CHECK_EVT, (tNFA_CONN_EVT_DATA *)&status); 538 539 /* If in normal mode (not-exclusive RF mode) then deactivate the link if presence check failed */ 540 if ((nfa_rw_cb.flags & NFA_RW_FL_NOT_EXCL_RF_MODE) && (status != NFC_STATUS_OK)) 541 { 542 NFA_TRACE_DEBUG0("Presence check failed. Deactivating..."); 543 nfa_dm_rf_deactivate (NFA_DEACTIVATE_TYPE_DISCOVERY); 544 } 545 } 546} 547 548/******************************************************************************* 549** 550** Function nfa_rw_handle_t1t_evt 551** 552** Description Handler for Type-1 tag reader/writer events 553** 554** Returns Nothing 555** 556*******************************************************************************/ 557static void nfa_rw_handle_t1t_evt (tRW_EVENT event, tRW_DATA *p_rw_data) 558{ 559 tNFA_CONN_EVT_DATA conn_evt_data; 560 561 conn_evt_data.status = p_rw_data->data.status; 562 switch (event) 563 { 564 case RW_T1T_RID_EVT: 565 case RW_T1T_RALL_CPLT_EVT: 566 case RW_T1T_READ_CPLT_EVT: 567 case RW_T1T_RSEG_CPLT_EVT: 568 case RW_T1T_READ8_CPLT_EVT: 569 nfa_rw_send_data_to_upper (p_rw_data); 570 571 /* Command complete - perform cleanup, notify the app */ 572 nfa_rw_command_complete(); 573 nfa_dm_act_conn_cback_notify(NFA_READ_CPLT_EVT, &conn_evt_data); 574 break; 575 576 case RW_T1T_WRITE_E_CPLT_EVT: 577 case RW_T1T_WRITE_NE_CPLT_EVT: 578 case RW_T1T_WRITE_E8_CPLT_EVT: 579 case RW_T1T_WRITE_NE8_CPLT_EVT: 580 nfa_rw_send_data_to_upper (p_rw_data); 581 582 /* Command complete - perform cleanup, notify the app */ 583 nfa_rw_command_complete(); 584 nfa_dm_act_conn_cback_notify(NFA_WRITE_CPLT_EVT, &conn_evt_data); 585 break; 586 587 case RW_T1T_TLV_DETECT_EVT: 588 nfa_rw_handle_tlv_detect(event, p_rw_data); 589 break; 590 591 case RW_T1T_NDEF_DETECT_EVT: 592 nfa_rw_cb.tlv_st = NFA_RW_TLV_DETECT_ST_COMPLETE; 593 594 if ( (p_rw_data->status != NFC_STATUS_OK) 595 &&(nfa_rw_cb.cur_op == NFA_RW_OP_WRITE_NDEF) 596 &&(p_rw_data->ndef.flags & NFA_RW_NDEF_FL_FORMATABLE) && (!(p_rw_data->ndef.flags & NFA_RW_NDEF_FL_FORMATED)) && (p_rw_data->ndef.flags & NFA_RW_NDEF_FL_SUPPORTED) ) 597 { 598 /* Tag is in Initialized state, Format the tag first and then Write NDEF */ 599 if (RW_T1tFormatNDef() == NFC_STATUS_OK) 600 break; 601 } 602 603 nfa_rw_handle_ndef_detect(event, p_rw_data); 604 605 break; 606 607 case RW_T1T_NDEF_READ_EVT: 608 nfa_rw_cb.tlv_st = NFA_RW_TLV_DETECT_ST_COMPLETE; 609 if (p_rw_data->status == NFC_STATUS_OK) 610 { 611 /* Process the ndef record */ 612 nfa_dm_ndef_handle_message(NFA_STATUS_OK, nfa_rw_cb.p_ndef_buf, nfa_rw_cb.ndef_cur_size); 613 } 614 else 615 { 616 /* Notify app of failure */ 617 if (nfa_rw_cb.cur_op == NFA_RW_OP_READ_NDEF) 618 { 619 /* If current operation is READ_NDEF, then notify ndef handlers of failure */ 620 nfa_dm_ndef_handle_message(NFA_STATUS_FAILED, NULL, 0); 621 } 622 } 623 624 /* Command complete - perform cleanup, notify the app */ 625 nfa_rw_command_complete(); 626 nfa_dm_act_conn_cback_notify(NFA_READ_CPLT_EVT, &conn_evt_data); 627 628 /* Free ndef buffer */ 629 nfa_rw_free_ndef_rx_buf(); 630 break; 631 632 case RW_T1T_NDEF_WRITE_EVT: 633 if (p_rw_data->data.status != NFA_STATUS_OK) 634 nfa_rw_cb.ndef_st = NFA_RW_NDEF_ST_UNKNOWN; 635 nfa_rw_cb.tlv_st = NFA_RW_TLV_DETECT_ST_COMPLETE; 636 637 638 /* Command complete - perform cleanup, notify the app */ 639 nfa_rw_command_complete(); 640 641 /* Notify app */ 642 conn_evt_data.status = (p_rw_data->data.status == NFC_STATUS_OK) ? NFA_STATUS_OK : NFA_STATUS_FAILED; 643 if (nfa_rw_cb.cur_op == NFA_RW_OP_WRITE_NDEF) 644 { 645 /* Update local cursize of ndef message */ 646 nfa_rw_cb.ndef_cur_size = nfa_rw_cb.ndef_wr_len; 647 } 648 649 /* Notify app of ndef write complete status */ 650 nfa_dm_act_conn_cback_notify(NFA_WRITE_CPLT_EVT, &conn_evt_data); 651 break; 652 653 case RW_T1T_SET_TAG_RO_EVT: 654 /* Command complete - perform cleanup, notify the app */ 655 nfa_rw_command_complete(); 656 nfa_dm_act_conn_cback_notify(NFA_SET_TAG_RO_EVT, &conn_evt_data); 657 break; 658 659 case RW_T1T_RAW_FRAME_EVT: 660 nfa_rw_send_data_to_upper (p_rw_data); 661 /* Command complete - perform cleanup */ 662 nfa_rw_command_complete(); 663 break; 664 665 case RW_T1T_PRESENCE_CHECK_EVT: /* Presence check completed */ 666 nfa_rw_handle_presence_check_rsp(p_rw_data->status); 667 break; 668 669 case RW_T1T_FORMAT_CPLT_EVT: 670 671 if (p_rw_data->data.status == NFA_STATUS_OK) 672 nfa_rw_cb.ndef_st = NFA_RW_NDEF_ST_UNKNOWN; 673 674 if (nfa_rw_cb.cur_op == NFA_RW_OP_WRITE_NDEF) 675 { 676 /* if format operation was done as part of ndef-write operation, now start NDEF Write */ 677 if ( (p_rw_data->data.status != NFA_STATUS_OK) 678 ||((conn_evt_data.status = RW_T1tDetectNDef ()) != NFC_STATUS_OK) ) 679 { 680 /* Command complete - perform cleanup, notify app */ 681 nfa_rw_command_complete(); 682 nfa_rw_cb.ndef_st = NFA_RW_NDEF_ST_FALSE; 683 684 685 /* if format operation failed or ndef detection did not start, then notify app of ndef-write operation failure */ 686 conn_evt_data.status = NFA_STATUS_FAILED; 687 nfa_dm_act_conn_cback_notify(NFA_WRITE_CPLT_EVT, &conn_evt_data); 688 } 689 } 690 else 691 { 692 /* Command complete - perform cleanup, notify the app */ 693 nfa_rw_command_complete(); 694 nfa_dm_act_conn_cback_notify(NFA_FORMAT_CPLT_EVT, &conn_evt_data); 695 } 696 break; 697 698 case RW_T1T_INTF_ERROR_EVT: 699 nfa_dm_act_conn_cback_notify(NFA_RW_INTF_ERROR_EVT, &conn_evt_data); 700 break; 701 } 702} 703 704/******************************************************************************* 705** 706** Function nfa_rw_handle_t2t_evt 707** 708** Description Handler for Type-2 tag reader/writer events 709** 710** Returns Nothing 711** 712*******************************************************************************/ 713static void nfa_rw_handle_t2t_evt (tRW_EVENT event, tRW_DATA *p_rw_data) 714{ 715 tNFA_CONN_EVT_DATA conn_evt_data; 716 717 conn_evt_data.status = p_rw_data->status; 718 719 if (p_rw_data->status == NFC_STATUS_REJECTED) 720 { 721 NFA_TRACE_DEBUG0("nfa_rw_handle_t2t_evt(); Waking the tag first before handling the response!"); 722 /* Received NACK. Let DM wakeup the tag first (by putting tag to sleep and then waking it up) */ 723 if ((p_rw_data->status = nfa_dm_disc_sleep_wakeup ()) == NFC_STATUS_OK) 724 { 725 nfa_rw_cb.halt_event = event; 726 memcpy (&nfa_rw_cb.rw_data, p_rw_data, sizeof (tRW_DATA)); 727 return; 728 } 729 } 730 731 switch (event) 732 { 733 case RW_T2T_READ_CPLT_EVT: /* Read completed */ 734 nfa_rw_send_data_to_upper (p_rw_data); 735 /* Command complete - perform cleanup, notify the app */ 736 nfa_rw_command_complete(); 737 nfa_dm_act_conn_cback_notify (NFA_READ_CPLT_EVT, &conn_evt_data); 738 break; 739 740 case RW_T2T_WRITE_CPLT_EVT: /* Write completed */ 741 /* Command complete - perform cleanup, notify the app */ 742 nfa_rw_command_complete(); 743 nfa_dm_act_conn_cback_notify (NFA_WRITE_CPLT_EVT, &conn_evt_data); 744 break; 745 746 case RW_T2T_SELECT_CPLT_EVT: /* Sector select completed */ 747 /* Command complete - perform cleanup, notify the app */ 748 nfa_rw_command_complete(); 749 nfa_dm_act_conn_cback_notify (NFA_SELECT_CPLT_EVT, &conn_evt_data); 750 break; 751 752 case RW_T2T_NDEF_DETECT_EVT: /* NDEF detection complete */ 753 if ( (p_rw_data->status == NFC_STATUS_OK) 754 ||((p_rw_data->status == NFC_STATUS_FAILED) && ((p_rw_data->ndef.flags == NFA_RW_NDEF_FL_UNKNOWN) || (nfa_rw_cb.halt_event == RW_T2T_MAX_EVT))) 755 ||(nfa_rw_cb.skip_dyn_locks == TRUE) ) 756 { 757 /* NDEF Detection is complete */ 758 nfa_rw_cb.skip_dyn_locks = FALSE; 759 nfa_rw_handle_ndef_detect (event, p_rw_data); 760 } 761 else 762 { 763 /* Try to detect NDEF again, this time without reading dynamic lock bytes */ 764 nfa_rw_cb.skip_dyn_locks = TRUE; 765 nfa_rw_detect_ndef (NULL); 766 } 767 break; 768 769 case RW_T2T_TLV_DETECT_EVT: /* Lock control/Mem/Prop tlv detection complete */ 770 nfa_rw_handle_tlv_detect(event, p_rw_data); 771 break; 772 773 case RW_T2T_NDEF_READ_EVT: /* NDEF read completed */ 774 if (p_rw_data->status == NFC_STATUS_OK) 775 { 776 /* Process the ndef record */ 777 nfa_dm_ndef_handle_message(NFA_STATUS_OK, nfa_rw_cb.p_ndef_buf, nfa_rw_cb.ndef_cur_size); 778 } 779 else 780 { 781 /* Notify app of failure */ 782 if (nfa_rw_cb.cur_op == NFA_RW_OP_READ_NDEF) 783 { 784 /* If current operation is READ_NDEF, then notify ndef handlers of failure */ 785 nfa_dm_ndef_handle_message(NFA_STATUS_FAILED, NULL, 0); 786 } 787 } 788 789 /* Notify app of read status */ 790 conn_evt_data.status = p_rw_data->status; 791 nfa_dm_act_conn_cback_notify(NFA_READ_CPLT_EVT, &conn_evt_data); 792 /* Free ndef buffer */ 793 nfa_rw_free_ndef_rx_buf(); 794 795 /* Command complete - perform cleanup */ 796 nfa_rw_command_complete(); 797 break; 798 799 case RW_T2T_NDEF_WRITE_EVT: /* NDEF write complete */ 800 801 /* Command complete - perform cleanup, notify the app */ 802 nfa_rw_command_complete(); 803 804 /* Notify app */ 805 conn_evt_data.status = (p_rw_data->data.status == NFC_STATUS_OK) ? NFA_STATUS_OK : NFA_STATUS_FAILED; 806 if (nfa_rw_cb.cur_op == NFA_RW_OP_WRITE_NDEF) 807 { 808 /* Update local cursize of ndef message */ 809 nfa_rw_cb.ndef_cur_size = nfa_rw_cb.ndef_wr_len; 810 } 811 812 /* Notify app of ndef write complete status */ 813 nfa_dm_act_conn_cback_notify(NFA_WRITE_CPLT_EVT, &conn_evt_data); 814 815 break; 816 817 case RW_T2T_SET_TAG_RO_EVT: 818 /* Command complete - perform cleanup, notify the app */ 819 nfa_rw_command_complete(); 820 nfa_dm_act_conn_cback_notify(NFA_SET_TAG_RO_EVT, &conn_evt_data); 821 break; 822 823 case RW_T2T_RAW_FRAME_EVT: 824 nfa_rw_send_data_to_upper (p_rw_data); 825 /* Command complete - perform cleanup */ 826 if (p_rw_data->status != NFC_STATUS_CONTINUE) 827 { 828 nfa_rw_command_complete(); 829 } 830 break; 831 832 case RW_T2T_PRESENCE_CHECK_EVT: /* Presence check completed */ 833 nfa_rw_handle_presence_check_rsp(p_rw_data->status); 834 break; 835 836 case RW_T2T_FORMAT_CPLT_EVT: 837 if (p_rw_data->data.status == NFA_STATUS_OK) 838 nfa_rw_cb.ndef_st = NFA_RW_NDEF_ST_UNKNOWN; 839 840 /* Command complete - perform cleanup, notify the app */ 841 nfa_rw_command_complete(); 842 nfa_dm_act_conn_cback_notify(NFA_FORMAT_CPLT_EVT, &conn_evt_data); 843 break; 844 845 case RW_T2T_INTF_ERROR_EVT: 846 nfa_dm_act_conn_cback_notify(NFA_RW_INTF_ERROR_EVT, &conn_evt_data); 847 break; 848 } 849} 850 851/******************************************************************************* 852** 853** Function nfa_rw_handle_t3t_evt 854** 855** Description Handler for Type-3 tag reader/writer events 856** 857** Returns Nothing 858** 859*******************************************************************************/ 860static void nfa_rw_handle_t3t_evt (tRW_EVENT event, tRW_DATA *p_rw_data) 861{ 862 tNFA_CONN_EVT_DATA conn_evt_data; 863 tNFA_TAG_PARAMS tag_params; 864 865 switch (event) 866 { 867 case RW_T3T_NDEF_DETECT_EVT: /* NDEF detection complete */ 868 nfa_rw_handle_ndef_detect(event, p_rw_data); 869 break; 870 871 case RW_T3T_UPDATE_CPLT_EVT: /* Write completed */ 872 /* Command complete - perform cleanup, notify the app */ 873 nfa_rw_command_complete(); 874 875 /* Notify app */ 876 conn_evt_data.status = (p_rw_data->data.status == NFC_STATUS_OK) ? NFA_STATUS_OK : NFA_STATUS_FAILED; 877 if (nfa_rw_cb.cur_op == NFA_RW_OP_WRITE_NDEF) 878 { 879 /* Update local cursize of ndef message */ 880 nfa_rw_cb.ndef_cur_size = nfa_rw_cb.ndef_wr_len; 881 } 882 883 /* Notify app of ndef write complete status */ 884 nfa_dm_act_conn_cback_notify(NFA_WRITE_CPLT_EVT, &conn_evt_data); 885 886 break; 887 888 case RW_T3T_CHECK_CPLT_EVT: /* Read completed */ 889 if (p_rw_data->status == NFC_STATUS_OK) 890 { 891 /* Process the ndef record */ 892 nfa_dm_ndef_handle_message(NFA_STATUS_OK, nfa_rw_cb.p_ndef_buf, nfa_rw_cb.ndef_cur_size); 893 } 894 else 895 { 896 /* Notify app of failure */ 897 if (nfa_rw_cb.cur_op == NFA_RW_OP_READ_NDEF) 898 { 899 /* If current operation is READ_NDEF, then notify ndef handlers of failure */ 900 nfa_dm_ndef_handle_message(NFA_STATUS_FAILED, NULL, 0); 901 } 902 } 903 904 /* Free ndef buffer */ 905 nfa_rw_free_ndef_rx_buf(); 906 907 /* Command complete - perform cleanup, notify the app */ 908 nfa_rw_command_complete(); 909 conn_evt_data.status = p_rw_data->status; 910 nfa_dm_act_conn_cback_notify(NFA_READ_CPLT_EVT, &conn_evt_data); 911 break; 912 913 case RW_T3T_CHECK_EVT: /* Segment of data received from type 3 tag */ 914 if (nfa_rw_cb.cur_op == NFA_RW_OP_READ_NDEF) 915 { 916 nfa_rw_store_ndef_rx_buf (p_rw_data); 917 } 918 else 919 { 920 nfa_rw_send_data_to_upper (p_rw_data); 921 } 922 break; 923 924 case RW_T3T_RAW_FRAME_EVT: /* SendRawFrame response */ 925 nfa_rw_send_data_to_upper (p_rw_data); 926 927 if (p_rw_data->status != NFC_STATUS_CONTINUE) 928 { 929 /* Command complete - perform cleanup */ 930 nfa_rw_command_complete(); 931 } 932 break; 933 934 case RW_T3T_PRESENCE_CHECK_EVT: /* Presence check completed */ 935 nfa_rw_handle_presence_check_rsp(p_rw_data->status); 936 break; 937 938 case RW_T3T_GET_SYSTEM_CODES_EVT: /* Presence check completed */ 939 /* Command complete - perform cleanup */ 940 nfa_rw_command_complete(); 941 942 /* System codes retrieved - notify app of ACTIVATION */ 943 if (p_rw_data->status == NFC_STATUS_OK) 944 { 945 tag_params.t3t.num_system_codes = p_rw_data->t3t_sc.num_system_codes; 946 tag_params.t3t.p_system_codes = p_rw_data->t3t_sc.p_system_codes; 947 } 948 else 949 { 950 tag_params.t3t.num_system_codes = 0; 951 tag_params.t3t.p_system_codes = NULL; 952 } 953 954 nfa_dm_notify_activation_status(NFA_STATUS_OK, &tag_params); 955 break; 956 957 case RW_T3T_FORMAT_CPLT_EVT: /* Format completed */ 958 /* Command complete - perform cleanup, notify the app */ 959 nfa_rw_command_complete(); 960 961 /* Notify app */ 962 conn_evt_data.status = (p_rw_data->data.status == NFC_STATUS_OK) ? NFA_STATUS_OK : NFA_STATUS_FAILED; 963 964 /* Notify app of ndef write complete status */ 965 nfa_dm_act_conn_cback_notify(NFA_FORMAT_CPLT_EVT, &conn_evt_data); 966 break; 967 968 969 case RW_T3T_INTF_ERROR_EVT: 970 conn_evt_data.status = p_rw_data->status; 971 nfa_dm_act_conn_cback_notify(NFA_RW_INTF_ERROR_EVT, &conn_evt_data); 972 break; 973 974 case RW_T3T_SET_READ_ONLY_CPLT_EVT: 975 /* Command complete - perform cleanup, notify the app */ 976 nfa_rw_command_complete(); 977 978 conn_evt_data.status = p_rw_data->status; 979 nfa_dm_act_conn_cback_notify(NFA_SET_TAG_RO_EVT, &conn_evt_data); 980 break; 981 982 default: 983 NFA_TRACE_DEBUG1("nfa_rw_handle_t3t_evt(); Unhandled RW event 0x%X", event); 984 break; 985 } 986} 987 988 989/******************************************************************************* 990** 991** Function nfa_rw_handle_t4t_evt 992** 993** Description Handler for Type-4 tag reader/writer events 994** 995** Returns Nothing 996** 997*******************************************************************************/ 998static void nfa_rw_handle_t4t_evt (tRW_EVENT event, tRW_DATA *p_rw_data) 999{ 1000 tNFA_CONN_EVT_DATA conn_evt_data; 1001 1002 switch (event) 1003 { 1004 case RW_T4T_NDEF_DETECT_EVT : /* Result of NDEF detection procedure */ 1005 nfa_rw_handle_ndef_detect(event, p_rw_data); 1006 break; 1007 1008 case RW_T4T_NDEF_READ_EVT: /* Segment of data received from type 4 tag */ 1009 if (nfa_rw_cb.cur_op == NFA_RW_OP_READ_NDEF) 1010 { 1011 nfa_rw_store_ndef_rx_buf (p_rw_data); 1012 } 1013 else 1014 { 1015 nfa_rw_send_data_to_upper (p_rw_data); 1016 } 1017 break; 1018 1019 case RW_T4T_NDEF_READ_CPLT_EVT: /* Read operation completed */ 1020 if (nfa_rw_cb.cur_op == NFA_RW_OP_READ_NDEF) 1021 { 1022 nfa_rw_store_ndef_rx_buf (p_rw_data); 1023 1024 /* Process the ndef record */ 1025 nfa_dm_ndef_handle_message (NFA_STATUS_OK, nfa_rw_cb.p_ndef_buf, nfa_rw_cb.ndef_cur_size); 1026 1027 /* Free ndef buffer */ 1028 nfa_rw_free_ndef_rx_buf(); 1029 } 1030 else 1031 { 1032 nfa_rw_send_data_to_upper (p_rw_data); 1033 } 1034 1035 /* Command complete - perform cleanup, notify the app */ 1036 nfa_rw_command_complete(); 1037 nfa_rw_cb.cur_op = NFA_RW_OP_MAX; 1038 conn_evt_data.status = NFC_STATUS_OK; 1039 nfa_dm_act_conn_cback_notify(NFA_READ_CPLT_EVT, &conn_evt_data); 1040 break; 1041 1042 case RW_T4T_NDEF_READ_FAIL_EVT: /* Read operation failed */ 1043 if (nfa_rw_cb.cur_op == NFA_RW_OP_READ_NDEF) 1044 { 1045 /* If current operation is READ_NDEF, then notify ndef handlers of failure */ 1046 nfa_dm_ndef_handle_message(NFA_STATUS_FAILED, NULL, 0); 1047 1048 /* Free ndef buffer */ 1049 nfa_rw_free_ndef_rx_buf(); 1050 } 1051 1052 /* Command complete - perform cleanup, notify the app */ 1053 nfa_rw_command_complete(); 1054 nfa_rw_cb.cur_op = NFA_RW_OP_MAX; 1055 conn_evt_data.status = NFA_STATUS_FAILED; 1056 nfa_dm_act_conn_cback_notify(NFA_READ_CPLT_EVT, &conn_evt_data); 1057 break; 1058 1059 case RW_T4T_NDEF_UPDATE_CPLT_EVT: /* Update operation completed */ 1060 case RW_T4T_NDEF_UPDATE_FAIL_EVT: /* Update operation failed */ 1061 1062 if (nfa_rw_cb.cur_op == NFA_RW_OP_WRITE_NDEF) 1063 { 1064 /* Update local cursize of ndef message */ 1065 nfa_rw_cb.ndef_cur_size = nfa_rw_cb.ndef_wr_len; 1066 } 1067 1068 /* Notify app */ 1069 if (event == RW_T4T_NDEF_UPDATE_CPLT_EVT) 1070 conn_evt_data.status = NFA_STATUS_OK; 1071 else 1072 conn_evt_data.status = NFA_STATUS_FAILED; 1073 1074 /* Command complete - perform cleanup, notify the app */ 1075 nfa_rw_command_complete(); 1076 nfa_rw_cb.cur_op = NFA_RW_OP_MAX; 1077 nfa_dm_act_conn_cback_notify(NFA_WRITE_CPLT_EVT, &conn_evt_data); 1078 break; 1079 1080 case RW_T4T_RAW_FRAME_EVT: /* Raw Frame data event */ 1081 nfa_rw_send_data_to_upper (p_rw_data); 1082 1083 if (p_rw_data->status != NFC_STATUS_CONTINUE) 1084 { 1085 /* Command complete - perform cleanup */ 1086 nfa_rw_command_complete(); 1087 nfa_rw_cb.cur_op = NFA_RW_OP_MAX; 1088 } 1089 break; 1090 1091 case RW_T4T_SET_TO_RO_EVT: /* Tag is set as read only */ 1092 conn_evt_data.status = p_rw_data->status; 1093 nfa_dm_act_conn_cback_notify(NFA_SET_TAG_RO_EVT, &conn_evt_data); 1094 1095 nfa_rw_command_complete(); 1096 nfa_rw_cb.cur_op = NFA_RW_OP_MAX; 1097 break; 1098 1099 case RW_T4T_INTF_ERROR_EVT: /* RF Interface error event */ 1100 conn_evt_data.status = p_rw_data->status; 1101 nfa_dm_act_conn_cback_notify(NFA_RW_INTF_ERROR_EVT, &conn_evt_data); 1102 1103 nfa_rw_command_complete(); 1104 nfa_rw_cb.cur_op = NFA_RW_OP_MAX; 1105 break; 1106 1107 case RW_T4T_PRESENCE_CHECK_EVT: /* Presence check completed */ 1108 nfa_rw_handle_presence_check_rsp(p_rw_data->status); 1109 break; 1110 1111 default: 1112 NFA_TRACE_DEBUG1("nfa_rw_handle_t4t_evt(); Unhandled RW event 0x%X", event); 1113 break; 1114 } 1115} 1116 1117/******************************************************************************* 1118** 1119** Function nfa_rw_handle_i93_evt 1120** 1121** Description Handler for ISO 15693 tag reader/writer events 1122** 1123** Returns Nothing 1124** 1125*******************************************************************************/ 1126static void nfa_rw_handle_i93_evt (tRW_EVENT event, tRW_DATA *p_rw_data) 1127{ 1128 tNFA_CONN_EVT_DATA conn_evt_data; 1129 tNFA_TAG_PARAMS i93_params; 1130 1131 switch (event) 1132 { 1133 case RW_I93_NDEF_DETECT_EVT : /* Result of NDEF detection procedure */ 1134 nfa_rw_handle_ndef_detect(event, p_rw_data); 1135 break; 1136 1137 case RW_I93_NDEF_READ_EVT: /* Segment of data received from type 4 tag */ 1138 if (nfa_rw_cb.cur_op == NFA_RW_OP_READ_NDEF) 1139 { 1140 nfa_rw_store_ndef_rx_buf (p_rw_data); 1141 } 1142 else 1143 { 1144 nfa_rw_send_data_to_upper (p_rw_data); 1145 } 1146 break; 1147 1148 case RW_I93_NDEF_READ_CPLT_EVT: /* Read operation completed */ 1149 if (nfa_rw_cb.cur_op == NFA_RW_OP_READ_NDEF) 1150 { 1151 nfa_rw_store_ndef_rx_buf (p_rw_data); 1152 1153 /* Process the ndef record */ 1154 nfa_dm_ndef_handle_message (NFA_STATUS_OK, nfa_rw_cb.p_ndef_buf, nfa_rw_cb.ndef_cur_size); 1155 1156 /* Free ndef buffer */ 1157 nfa_rw_free_ndef_rx_buf(); 1158 } 1159 else 1160 { 1161 nfa_rw_send_data_to_upper (p_rw_data); 1162 } 1163 1164 /* Command complete - perform cleanup, notify app */ 1165 nfa_rw_command_complete(); 1166 nfa_rw_cb.cur_op = NFA_RW_OP_MAX; /* clear current operation */ 1167 conn_evt_data.status = NFC_STATUS_OK; 1168 nfa_dm_act_conn_cback_notify(NFA_READ_CPLT_EVT, &conn_evt_data); 1169 break; 1170 1171 case RW_I93_NDEF_READ_FAIL_EVT: /* Read operation failed */ 1172 if (nfa_rw_cb.cur_op == NFA_RW_OP_READ_NDEF) 1173 { 1174 /* If current operation is READ_NDEF, then notify ndef handlers of failure */ 1175 nfa_dm_ndef_handle_message(NFA_STATUS_FAILED, NULL, 0); 1176 1177 /* Free ndef buffer */ 1178 nfa_rw_free_ndef_rx_buf(); 1179 } 1180 1181 /* Command complete - perform cleanup, notify app */ 1182 nfa_rw_command_complete(); 1183 nfa_rw_cb.cur_op = NFA_RW_OP_MAX; /* clear current operation */ 1184 conn_evt_data.status = NFA_STATUS_FAILED; 1185 nfa_dm_act_conn_cback_notify(NFA_READ_CPLT_EVT, &conn_evt_data); 1186 break; 1187 1188 case RW_I93_NDEF_UPDATE_CPLT_EVT: /* Update operation completed */ 1189 case RW_I93_NDEF_UPDATE_FAIL_EVT: /* Update operation failed */ 1190 1191 if (nfa_rw_cb.cur_op == NFA_RW_OP_WRITE_NDEF) 1192 { 1193 /* Update local cursize of ndef message */ 1194 nfa_rw_cb.ndef_cur_size = nfa_rw_cb.ndef_wr_len; 1195 } 1196 1197 /* Command complete - perform cleanup, notify app */ 1198 nfa_rw_command_complete(); 1199 nfa_rw_cb.cur_op = NFA_RW_OP_MAX; /* clear current operation */ 1200 1201 if (event == RW_I93_NDEF_UPDATE_CPLT_EVT) 1202 conn_evt_data.status = NFA_STATUS_OK; 1203 else 1204 conn_evt_data.status = NFA_STATUS_FAILED; 1205 1206 /* Notify app of ndef write complete status */ 1207 nfa_dm_act_conn_cback_notify(NFA_WRITE_CPLT_EVT, &conn_evt_data); 1208 break; 1209 1210 case RW_I93_RAW_FRAME_EVT: /* Raw Frame data event */ 1211 nfa_rw_send_data_to_upper (p_rw_data); 1212 if (p_rw_data->status != NFC_STATUS_CONTINUE) 1213 { 1214 /* Command complete - perform cleanup */ 1215 nfa_rw_command_complete(); 1216 } 1217 break; 1218 1219 case RW_I93_INTF_ERROR_EVT: /* RF Interface error event */ 1220 /* Command complete - perform cleanup, notify app */ 1221 nfa_rw_command_complete(); 1222 1223 if (nfa_rw_cb.flags & NFA_RW_FL_ACTIVATION_NTF_PENDING) 1224 { 1225 nfa_rw_cb.flags &= ~NFA_RW_FL_ACTIVATION_NTF_PENDING; 1226 1227 memset (&i93_params, 0x00, sizeof (tNFA_TAG_PARAMS)); 1228 memcpy (i93_params.i93.uid, nfa_rw_cb.i93_uid, I93_UID_BYTE_LEN); 1229 1230 nfa_dm_notify_activation_status (NFA_STATUS_OK, &i93_params); 1231 } 1232 else 1233 { 1234 conn_evt_data.status = p_rw_data->status; 1235 nfa_dm_act_conn_cback_notify(NFA_RW_INTF_ERROR_EVT, &conn_evt_data); 1236 } 1237 1238 nfa_rw_cb.cur_op = NFA_RW_OP_MAX; /* clear current operation */ 1239 break; 1240 1241 1242 case RW_I93_PRESENCE_CHECK_EVT: /* Presence check completed */ 1243 nfa_rw_handle_presence_check_rsp(p_rw_data->status); 1244 break; 1245 1246 case RW_I93_FORMAT_CPLT_EVT: /* Format procedure complete */ 1247 if (p_rw_data->data.status == NFA_STATUS_OK) 1248 nfa_rw_cb.ndef_st = NFA_RW_NDEF_ST_UNKNOWN; 1249 1250 /* Command complete - perform cleanup, notify app */ 1251 nfa_rw_command_complete(); 1252 nfa_rw_cb.cur_op = NFA_RW_OP_MAX; /* clear current operation */ 1253 conn_evt_data.status = p_rw_data->status; 1254 nfa_dm_act_conn_cback_notify(NFA_FORMAT_CPLT_EVT, &conn_evt_data); 1255 break; 1256 1257 case RW_I93_SET_TAG_RO_EVT: /* Set read-only procedure complete */ 1258 nfa_rw_cb.flags |= NFA_RW_FL_TAG_IS_READONLY; 1259 1260 /* Command complete - perform cleanup, notify app */ 1261 nfa_rw_command_complete(); 1262 nfa_rw_cb.cur_op = NFA_RW_OP_MAX; /* clear current operation */ 1263 conn_evt_data.status = p_rw_data->status; 1264 nfa_dm_act_conn_cback_notify(NFA_SET_TAG_RO_EVT, &conn_evt_data); 1265 break; 1266 1267 case RW_I93_INVENTORY_EVT: /* Response of Inventory */ 1268 1269 /* Command complete - perform cleanup, notify app */ 1270 nfa_rw_command_complete(); 1271 1272 conn_evt_data.i93_cmd_cplt.status = p_rw_data->i93_inventory.status; 1273 conn_evt_data.i93_cmd_cplt.sent_command = I93_CMD_INVENTORY; 1274 1275 conn_evt_data.i93_cmd_cplt.params.inventory.dsfid = p_rw_data->i93_inventory.dsfid; 1276 memcpy (conn_evt_data.i93_cmd_cplt.params.inventory.uid, 1277 p_rw_data->i93_inventory.uid, 1278 I93_UID_BYTE_LEN); 1279 1280 nfa_dm_act_conn_cback_notify(NFA_I93_CMD_CPLT_EVT, &conn_evt_data); 1281 1282 nfa_rw_cb.cur_op = NFA_RW_OP_MAX; /* clear current operation */ 1283 break; 1284 1285 case RW_I93_DATA_EVT: /* Response of Read, Get Multi Security */ 1286 1287 /* Command complete - perform cleanup, notify app */ 1288 nfa_rw_command_complete(); 1289 1290 conn_evt_data.data.p_data = (UINT8 *)(p_rw_data->i93_data.p_data + 1) + p_rw_data->i93_data.p_data->offset; 1291 1292 if (nfa_rw_cb.flags & NFA_RW_FL_ACTIVATION_NTF_PENDING) 1293 { 1294 nfa_rw_cb.flags &= ~NFA_RW_FL_ACTIVATION_NTF_PENDING; 1295 1296 i93_params.i93.info_flags = (I93_INFO_FLAG_DSFID|I93_INFO_FLAG_MEM_SIZE|I93_INFO_FLAG_AFI); 1297 i93_params.i93.afi = *(conn_evt_data.data.p_data + nfa_rw_cb.i93_afi_location % nfa_rw_cb.i93_block_size); 1298 i93_params.i93.dsfid = nfa_rw_cb.i93_dsfid; 1299 i93_params.i93.block_size = nfa_rw_cb.i93_block_size; 1300 i93_params.i93.num_block = nfa_rw_cb.i93_num_block; 1301 memcpy (i93_params.i93.uid, nfa_rw_cb.i93_uid, I93_UID_BYTE_LEN); 1302 1303 nfa_dm_notify_activation_status (NFA_STATUS_OK, &i93_params); 1304 } 1305 else 1306 { 1307 conn_evt_data.data.len = p_rw_data->i93_data.p_data->len; 1308 1309 nfa_dm_act_conn_cback_notify(NFA_DATA_EVT, &conn_evt_data); 1310 } 1311 1312 GKI_freebuf(p_rw_data->i93_data.p_data); 1313 p_rw_data->i93_data.p_data = NULL; 1314 1315 nfa_rw_cb.cur_op = NFA_RW_OP_MAX; /* clear current operation */ 1316 break; 1317 1318 case RW_I93_SYS_INFO_EVT: /* Response of System Information */ 1319 1320 /* Command complete - perform cleanup, notify app */ 1321 nfa_rw_command_complete(); 1322 1323 if (nfa_rw_cb.flags & NFA_RW_FL_ACTIVATION_NTF_PENDING) 1324 { 1325 nfa_rw_cb.flags &= ~NFA_RW_FL_ACTIVATION_NTF_PENDING; 1326 1327 nfa_rw_cb.i93_block_size = p_rw_data->i93_sys_info.block_size; 1328 nfa_rw_cb.i93_num_block = p_rw_data->i93_sys_info.num_block; 1329 1330 i93_params.i93.info_flags = p_rw_data->i93_sys_info.info_flags; 1331 i93_params.i93.dsfid = p_rw_data->i93_sys_info.dsfid; 1332 i93_params.i93.afi = p_rw_data->i93_sys_info.afi; 1333 i93_params.i93.num_block = p_rw_data->i93_sys_info.num_block; 1334 i93_params.i93.block_size = p_rw_data->i93_sys_info.block_size; 1335 i93_params.i93.IC_reference = p_rw_data->i93_sys_info.IC_reference; 1336 memcpy (i93_params.i93.uid, p_rw_data->i93_sys_info.uid, I93_UID_BYTE_LEN); 1337 1338 nfa_dm_notify_activation_status (NFA_STATUS_OK, &i93_params); 1339 } 1340 else 1341 { 1342 conn_evt_data.i93_cmd_cplt.status = p_rw_data->i93_sys_info.status; 1343 conn_evt_data.i93_cmd_cplt.sent_command = I93_CMD_GET_SYS_INFO; 1344 1345 conn_evt_data.i93_cmd_cplt.params.sys_info.info_flags = p_rw_data->i93_sys_info.info_flags; 1346 memcpy (conn_evt_data.i93_cmd_cplt.params.sys_info.uid, 1347 p_rw_data->i93_sys_info.uid, 1348 I93_UID_BYTE_LEN); 1349 conn_evt_data.i93_cmd_cplt.params.sys_info.dsfid = p_rw_data->i93_sys_info.dsfid; 1350 conn_evt_data.i93_cmd_cplt.params.sys_info.afi = p_rw_data->i93_sys_info.afi; 1351 conn_evt_data.i93_cmd_cplt.params.sys_info.num_block = p_rw_data->i93_sys_info.num_block; 1352 conn_evt_data.i93_cmd_cplt.params.sys_info.block_size = p_rw_data->i93_sys_info.block_size; 1353 conn_evt_data.i93_cmd_cplt.params.sys_info.IC_reference = p_rw_data->i93_sys_info.IC_reference; 1354 1355 /* store tag memory information for writing blocks */ 1356 nfa_rw_cb.i93_block_size = p_rw_data->i93_sys_info.block_size; 1357 nfa_rw_cb.i93_num_block = p_rw_data->i93_sys_info.num_block; 1358 1359 nfa_dm_act_conn_cback_notify(NFA_I93_CMD_CPLT_EVT, &conn_evt_data); 1360 } 1361 1362 nfa_rw_cb.cur_op = NFA_RW_OP_MAX; /* clear current operation */ 1363 break; 1364 1365 case RW_I93_CMD_CMPL_EVT: /* Command complete */ 1366 /* Command complete - perform cleanup, notify app */ 1367 nfa_rw_command_complete(); 1368 1369 if (nfa_rw_cb.flags & NFA_RW_FL_ACTIVATION_NTF_PENDING) 1370 { 1371 /* Reader got error code from tag */ 1372 1373 nfa_rw_cb.flags &= ~NFA_RW_FL_ACTIVATION_NTF_PENDING; 1374 1375 memset (&i93_params, 0x00, sizeof(i93_params)); 1376 memcpy (i93_params.i93.uid, nfa_rw_cb.i93_uid, I93_UID_BYTE_LEN); 1377 1378 nfa_dm_notify_activation_status (NFA_STATUS_OK, &i93_params); 1379 } 1380 else 1381 { 1382 conn_evt_data.i93_cmd_cplt.status = p_rw_data->i93_cmd_cmpl.status; 1383 conn_evt_data.i93_cmd_cplt.sent_command = p_rw_data->i93_cmd_cmpl.command; 1384 1385 if (conn_evt_data.i93_cmd_cplt.status != NFC_STATUS_OK) 1386 conn_evt_data.i93_cmd_cplt.params.error_code = p_rw_data->i93_cmd_cmpl.error_code; 1387 1388 nfa_dm_act_conn_cback_notify(NFA_I93_CMD_CPLT_EVT, &conn_evt_data); 1389 } 1390 1391 nfa_rw_cb.cur_op = NFA_RW_OP_MAX; /* clear current operation */ 1392 break; 1393 1394 default: 1395 NFA_TRACE_DEBUG1("nfa_rw_handle_i93_evt(); Unhandled RW event 0x%X", event); 1396 break; 1397 } 1398} 1399 1400/******************************************************************************* 1401** 1402** Function nfa_rw_cback 1403** 1404** Description Callback for reader/writer event notification 1405** 1406** Returns Nothing 1407** 1408*******************************************************************************/ 1409static void nfa_rw_cback (tRW_EVENT event, tRW_DATA *p_rw_data) 1410{ 1411 NFA_TRACE_DEBUG1("nfa_rw_cback: event=0x%02x", event); 1412 1413 /* Call appropriate event handler for tag type */ 1414 if (event < RW_T1T_MAX_EVT) 1415 { 1416 /* Handle Type-1 tag events */ 1417 nfa_rw_handle_t1t_evt(event, p_rw_data); 1418 } 1419 else if (event < RW_T2T_MAX_EVT) 1420 { 1421 /* Handle Type-2 tag events */ 1422 nfa_rw_handle_t2t_evt(event, p_rw_data); 1423 } 1424 else if (event < RW_T3T_MAX_EVT) 1425 { 1426 /* Handle Type-3 tag events */ 1427 nfa_rw_handle_t3t_evt(event, p_rw_data); 1428 } 1429 else if (event < RW_T4T_MAX_EVT) 1430 { 1431 /* Handle Type-4 tag events */ 1432 nfa_rw_handle_t4t_evt(event, p_rw_data); 1433 } 1434 else if (event < RW_I93_MAX_EVT) 1435 { 1436 /* Handle ISO 15693 tag events */ 1437 nfa_rw_handle_i93_evt(event, p_rw_data); 1438 } 1439 else 1440 { 1441 NFA_TRACE_ERROR1("nfa_rw_cback: unhandled event=0x%02x", event); 1442 } 1443} 1444 1445/******************************************************************************* 1446** 1447** Function nfa_rw_start_ndef_detection 1448** 1449** Description Start NDEF detection on activated tag 1450** 1451** Returns Nothing 1452** 1453*******************************************************************************/ 1454static tNFC_STATUS nfa_rw_start_ndef_detection(void) 1455{ 1456 tNFC_PROTOCOL protocol = nfa_rw_cb.protocol; 1457 tNFC_STATUS status = NFC_STATUS_FAILED; 1458 1459 switch (protocol) 1460 { 1461 case NFC_PROTOCOL_T1T: /* Type1Tag - NFC-A */ 1462 status = RW_T1tDetectNDef(); 1463 break; 1464 1465 case NFC_PROTOCOL_T2T: /* Type2Tag - NFC-A */ 1466 if (nfa_rw_cb.pa_sel_res == NFC_SEL_RES_NFC_FORUM_T2T) 1467 { 1468 status = RW_T2tDetectNDef(nfa_rw_cb.skip_dyn_locks); 1469 } 1470 break; 1471 1472 case NFC_PROTOCOL_T3T: /* Type3Tag - NFC-F */ 1473 status = RW_T3tDetectNDef(); 1474 break; 1475 1476 case NFC_PROTOCOL_ISO_DEP: /* ISODEP/4A,4B- NFC-A or NFC-B */ 1477 status = RW_T4tDetectNDef(); 1478 break; 1479 1480 case NFC_PROTOCOL_15693: /* ISO 15693 */ 1481 status = RW_I93DetectNDef(); 1482 break; 1483 1484 default: 1485 break; 1486 } 1487 1488 return(status); 1489} 1490 1491/******************************************************************************* 1492** 1493** Function nfa_rw_start_ndef_read 1494** 1495** Description Start NDEF read on activated tag 1496** 1497** Returns Nothing 1498** 1499*******************************************************************************/ 1500static tNFC_STATUS nfa_rw_start_ndef_read(void) 1501{ 1502 tNFC_PROTOCOL protocol = nfa_rw_cb.protocol; 1503 tNFC_STATUS status = NFC_STATUS_FAILED; 1504 tNFA_CONN_EVT_DATA conn_evt_data; 1505 1506 /* Handle zero length NDEF message */ 1507 if (nfa_rw_cb.ndef_cur_size == 0) 1508 { 1509 NFA_TRACE_DEBUG0("NDEF message is zero-length"); 1510 1511 /* Send zero-lengh NDEF message to ndef callback */ 1512 nfa_dm_ndef_handle_message(NFA_STATUS_OK, NULL, 0); 1513 1514 /* Command complete - perform cleanup, notify app */ 1515 nfa_rw_command_complete(); 1516 conn_evt_data.status = NFA_STATUS_OK; 1517 nfa_dm_act_conn_cback_notify(NFA_READ_CPLT_EVT, &conn_evt_data); 1518 return NFC_STATUS_OK; 1519 } 1520 1521 /* Allocate buffer for incoming NDEF message (free previous NDEF rx buffer, if needed) */ 1522 nfa_rw_free_ndef_rx_buf (); 1523 if ((nfa_rw_cb.p_ndef_buf = (UINT8 *)nfa_mem_co_alloc(nfa_rw_cb.ndef_cur_size)) == NULL) 1524 { 1525 NFA_TRACE_ERROR1("Unable to allocate a buffer for reading NDEF (size=%i)", nfa_rw_cb.ndef_cur_size); 1526 1527 /* Command complete - perform cleanup, notify app */ 1528 nfa_rw_command_complete(); 1529 conn_evt_data.status = NFA_STATUS_FAILED; 1530 nfa_dm_act_conn_cback_notify(NFA_READ_CPLT_EVT, &conn_evt_data); 1531 return NFC_STATUS_FAILED; 1532 } 1533 nfa_rw_cb.ndef_rd_offset = 0; 1534 1535 switch (protocol) 1536 { 1537 case NFC_PROTOCOL_T1T: /* Type1Tag - NFC-A */ 1538 status = RW_T1tReadNDef(nfa_rw_cb.p_ndef_buf,(UINT16)nfa_rw_cb.ndef_cur_size); 1539 break; 1540 1541 case NFC_PROTOCOL_T2T: /* Type2Tag - NFC-A */ 1542 if (nfa_rw_cb.pa_sel_res == NFC_SEL_RES_NFC_FORUM_T2T) 1543 { 1544 status = RW_T2tReadNDef(nfa_rw_cb.p_ndef_buf,(UINT16)nfa_rw_cb.ndef_cur_size); 1545 } 1546 break; 1547 1548 case NFC_PROTOCOL_T3T: /* Type3Tag - NFC-F */ 1549 status = RW_T3tCheckNDef(); 1550 break; 1551 1552 case NFC_PROTOCOL_ISO_DEP: /* ISODEP/4A,4B- NFC-A or NFC-B */ 1553 status = RW_T4tReadNDef(); 1554 break; 1555 1556 case NFC_PROTOCOL_15693: /* ISO 15693 */ 1557 status = RW_I93ReadNDef(); 1558 break; 1559 1560 default: 1561 break; 1562 } 1563 return(status); 1564} 1565 1566/******************************************************************************* 1567** 1568** Function nfa_rw_detect_ndef 1569** 1570** Description Handler for NFA_RW_API_DETECT_NDEF_EVT 1571** 1572** Returns TRUE (message buffer to be freed by caller) 1573** 1574*******************************************************************************/ 1575static BOOLEAN nfa_rw_detect_ndef(tNFA_RW_MSG *p_data) 1576{ 1577 tNFA_CONN_EVT_DATA conn_evt_data; 1578 NFA_TRACE_DEBUG0("nfa_rw_detect_ndef"); 1579 1580 if ((conn_evt_data.ndef_detect.status = nfa_rw_start_ndef_detection()) != NFC_STATUS_OK) 1581 { 1582 /* Command complete - perform cleanup, notify app */ 1583 nfa_rw_command_complete(); 1584 conn_evt_data.ndef_detect.cur_size = 0; 1585 conn_evt_data.ndef_detect.max_size = 0; 1586 conn_evt_data.ndef_detect.flags = RW_NDEF_FL_UNKNOWN; 1587 nfa_dm_act_conn_cback_notify(NFA_NDEF_DETECT_EVT, &conn_evt_data); 1588 } 1589 1590 return TRUE; 1591} 1592 1593/******************************************************************************* 1594** 1595** Function nfa_rw_start_ndef_write 1596** 1597** Description Start NDEF write on activated tag 1598** 1599** Returns Nothing 1600** 1601*******************************************************************************/ 1602static tNFC_STATUS nfa_rw_start_ndef_write(void) 1603{ 1604 tNFC_PROTOCOL protocol = nfa_rw_cb.protocol; 1605 tNFC_STATUS status = NFC_STATUS_FAILED; 1606 1607 if (nfa_rw_cb.flags & NFA_RW_FL_TAG_IS_READONLY) 1608 { 1609 /* error: ndef tag is read-only */ 1610 status = NFC_STATUS_FAILED; 1611 NFA_TRACE_ERROR0("Unable to write NDEF. Tag is read-only") 1612 } 1613 else if (nfa_rw_cb.ndef_max_size < nfa_rw_cb.ndef_wr_len) 1614 { 1615 /* error: ndef tag size is too small */ 1616 status = NFC_STATUS_BUFFER_FULL; 1617 NFA_TRACE_ERROR2("Unable to write NDEF. Tag maxsize=%i, request write size=%i", nfa_rw_cb.ndef_max_size, nfa_rw_cb.ndef_wr_len) 1618 } 1619 else 1620 { 1621 switch (protocol) 1622 { 1623 case NFC_PROTOCOL_T1T: /* Type1Tag - NFC-A */ 1624 status = RW_T1tWriteNDef((UINT16)nfa_rw_cb.ndef_wr_len, nfa_rw_cb.p_ndef_wr_buf); 1625 break; 1626 1627 case NFC_PROTOCOL_T2T: /* Type2Tag - NFC-A */ 1628 1629 if (nfa_rw_cb.pa_sel_res == NFC_SEL_RES_NFC_FORUM_T2T) 1630 { 1631 status = RW_T2tWriteNDef((UINT16)nfa_rw_cb.ndef_wr_len, nfa_rw_cb.p_ndef_wr_buf); 1632 } 1633 break; 1634 1635 case NFC_PROTOCOL_T3T: /* Type3Tag - NFC-F */ 1636 status = RW_T3tUpdateNDef(nfa_rw_cb.ndef_wr_len, nfa_rw_cb.p_ndef_wr_buf); 1637 break; 1638 1639 case NFC_PROTOCOL_ISO_DEP: /* ISODEP/4A,4B- NFC-A or NFC-B */ 1640 status = RW_T4tUpdateNDef((UINT16)nfa_rw_cb.ndef_wr_len, nfa_rw_cb.p_ndef_wr_buf); 1641 break; 1642 1643 case NFC_PROTOCOL_15693: /* ISO 15693 */ 1644 status = RW_I93UpdateNDef((UINT16)nfa_rw_cb.ndef_wr_len, nfa_rw_cb.p_ndef_wr_buf); 1645 break; 1646 1647 default: 1648 break; 1649 } 1650 } 1651 1652 return(status); 1653} 1654 1655/******************************************************************************* 1656** 1657** Function nfa_rw_read_ndef 1658** 1659** Description Handler for NFA_RW_API_READ_NDEF_EVT 1660** 1661** Returns TRUE (message buffer to be freed by caller) 1662** 1663*******************************************************************************/ 1664static BOOLEAN nfa_rw_read_ndef(tNFA_RW_MSG *p_data) 1665{ 1666 tNFA_STATUS status = NFA_STATUS_OK; 1667 tNFA_CONN_EVT_DATA conn_evt_data; 1668 1669 NFA_TRACE_DEBUG0("nfa_rw_read_ndef"); 1670 1671 /* Check if ndef detection has been performed yet */ 1672 if (nfa_rw_cb.ndef_st == NFA_RW_NDEF_ST_UNKNOWN) 1673 { 1674 /* Perform ndef detection first */ 1675 status = nfa_rw_start_ndef_detection(); 1676 } 1677 else if (nfa_rw_cb.ndef_st == NFA_RW_NDEF_ST_FALSE) 1678 { 1679 /* Tag is not NDEF */ 1680 status = NFA_STATUS_FAILED; 1681 } 1682 else 1683 { 1684 /* Perform the NDEF read operation */ 1685 status = nfa_rw_start_ndef_read(); 1686 } 1687 1688 /* Handle failure */ 1689 if (status != NFA_STATUS_OK) 1690 { 1691 /* Command complete - perform cleanup, notify app */ 1692 nfa_rw_command_complete(); 1693 conn_evt_data.status = status; 1694 nfa_dm_act_conn_cback_notify(NFA_READ_CPLT_EVT, &conn_evt_data); 1695 } 1696 1697 1698 return TRUE; 1699} 1700 1701/******************************************************************************* 1702** 1703** Function nfa_rw_write_ndef 1704** 1705** Description Handler for NFA_RW_API_WRITE_NDEF_EVT 1706** 1707** Returns TRUE (message buffer to be freed by caller) 1708** 1709*******************************************************************************/ 1710static BOOLEAN nfa_rw_write_ndef(tNFA_RW_MSG *p_data) 1711{ 1712 tNDEF_STATUS ndef_status; 1713 tNFA_STATUS write_status = NFA_STATUS_OK; 1714 tNFA_CONN_EVT_DATA conn_evt_data; 1715 NFA_TRACE_DEBUG0("nfa_rw_write_ndef"); 1716 1717 /* Validate NDEF message */ 1718 if ((ndef_status = NDEF_MsgValidate(p_data->op_req.params.write_ndef.p_data, p_data->op_req.params.write_ndef.len, FALSE)) != NDEF_OK) 1719 { 1720 NFA_TRACE_ERROR1("Invalid NDEF message. NDEF_MsgValidate returned %i", ndef_status); 1721 1722 /* Command complete - perform cleanup, notify app */ 1723 nfa_rw_command_complete(); 1724 conn_evt_data.status = NFA_STATUS_FAILED; 1725 nfa_dm_act_conn_cback_notify(NFA_WRITE_CPLT_EVT, &conn_evt_data); 1726 return TRUE; 1727 } 1728 1729 /* Store pointer to source NDEF */ 1730 nfa_rw_cb.p_ndef_wr_buf = p_data->op_req.params.write_ndef.p_data; 1731 nfa_rw_cb.ndef_wr_len = p_data->op_req.params.write_ndef.len; 1732 1733 /* Check if ndef detection has been performed yet */ 1734 if (nfa_rw_cb.ndef_st == NFA_RW_NDEF_ST_UNKNOWN) 1735 { 1736 /* Perform ndef detection first */ 1737 write_status = nfa_rw_start_ndef_detection(); 1738 } 1739 else if (nfa_rw_cb.ndef_st == NFA_RW_NDEF_ST_FALSE) 1740 { 1741 if (nfa_rw_cb.protocol == NFC_PROTOCOL_T1T) 1742 { 1743 /* For Type 1 tag, NDEF can be written on Initialized tag 1744 * Perform ndef detection first to check if tag is in Initialized state to Write NDEF */ 1745 write_status = nfa_rw_start_ndef_detection(); 1746 } 1747 else 1748 { 1749 /* Tag is not NDEF */ 1750 write_status = NFA_STATUS_FAILED; 1751 } 1752 } 1753 else 1754 { 1755 /* Perform the NDEF read operation */ 1756 write_status = nfa_rw_start_ndef_write(); 1757 } 1758 1759 /* Handle failure */ 1760 if (write_status != NFA_STATUS_OK) 1761 { 1762 /* Command complete - perform cleanup, notify app */ 1763 nfa_rw_command_complete(); 1764 conn_evt_data.status = write_status; 1765 nfa_dm_act_conn_cback_notify(NFA_WRITE_CPLT_EVT, &conn_evt_data); 1766 } 1767 1768 return TRUE; 1769} 1770 1771/******************************************************************************* 1772** 1773** Function nfa_rw_presence_check 1774** 1775** Description Handler for NFA_RW_API_PRESENCE_CHECK 1776** 1777** Returns Nothing 1778** 1779*******************************************************************************/ 1780void nfa_rw_presence_check (tNFA_RW_MSG *p_data) 1781{ 1782 tNFC_PROTOCOL protocol = nfa_rw_cb.protocol; 1783 UINT8 sel_res = nfa_rw_cb.pa_sel_res; 1784 tNFC_STATUS status = NFC_STATUS_FAILED; 1785 BOOLEAN unsupported = FALSE; 1786 UINT8 option = NFA_RW_OPTION_INVALID; 1787 tNFA_RW_PRES_CHK_OPTION op_param = NFA_RW_PRES_CHK_DEFAULT; 1788 1789 switch (protocol) 1790 { 1791 case NFC_PROTOCOL_T1T: /* Type1Tag - NFC-A */ 1792 status = RW_T1tPresenceCheck(); 1793 break; 1794 1795 case NFC_PROTOCOL_T3T: /* Type3Tag - NFC-F */ 1796 status = RW_T3tPresenceCheck(); 1797 break; 1798 1799 case NFC_PROTOCOL_ISO_DEP: /* ISODEP/4A,4B- NFC-A or NFC-B */ 1800 if (p_data) 1801 { 1802 op_param = p_data->op_req.params.option; 1803 } 1804 1805 switch (op_param) 1806 { 1807 case NFA_RW_PRES_CHK_I_BLOCK: 1808 option = RW_T4T_CHK_EMPTY_I_BLOCK; 1809 break; 1810 1811 case NFA_RW_PRES_CHK_RESET: 1812 /* option is initialized to NFA_RW_OPTION_INVALID, which will Deactivate to Sleep; Re-activate */ 1813 break; 1814 1815 case NFA_RW_PRES_CHK_RB_CH0: 1816 option = RW_T4T_CHK_READ_BINARY_CH0; 1817 break; 1818 1819 case NFA_RW_PRES_CHK_RB_CH3: 1820 option = RW_T4T_CHK_READ_BINARY_CH3; 1821 break; 1822 1823 default: 1824 if (nfa_rw_cb.flags & NFA_RW_FL_NDEF_OK) 1825 { 1826 /* read binary on channel 0 */ 1827 option = RW_T4T_CHK_READ_BINARY_CH0; 1828 } 1829 else 1830 { 1831 /* NDEF DETECT failed.*/ 1832 if ( nfa_dm_is_raw_frame_session()) 1833 { 1834 /* NFA_SendRawFrame() is called */ 1835 if (p_nfa_dm_cfg->presence_check_option & NFA_DM_PCO_EMPTY_I_BLOCK) 1836 { 1837 /* empty I block */ 1838 option = RW_T4T_CHK_EMPTY_I_BLOCK; 1839 } 1840 else 1841 { 1842 /* read binary on channel 3 */ 1843 option = RW_T4T_CHK_READ_BINARY_CH3; 1844 } 1845 } 1846 else if (!(p_nfa_dm_cfg->presence_check_option & NFA_DM_PCO_ISO_SLEEP_WAKE) && (nfa_rw_cb.intf_type == NFC_INTERFACE_ISO_DEP)) 1847 { 1848 /* the option indicates to use empty I block && ISODEP interface is activated */ 1849 option = RW_T4T_CHK_EMPTY_I_BLOCK; 1850 } 1851 } 1852 } 1853 1854 if (option != NFA_RW_OPTION_INVALID) 1855 { 1856 /* use the presence check with the chosen option */ 1857 status = RW_T4tPresenceCheck (option); 1858 } 1859 else 1860 { 1861 /* use sleep/wake for presence check */ 1862 unsupported = TRUE; 1863 } 1864 1865 1866 break; 1867 1868 case NFC_PROTOCOL_15693: /* ISO 15693 */ 1869 status = RW_I93PresenceCheck(); 1870 break; 1871 1872 case NFC_PROTOCOL_T2T: /* Type2Tag - NFC-A */ 1873 /* If T2T NFC-Forum, then let RW handle presence check; otherwise fall through */ 1874 if (sel_res == NFC_SEL_RES_NFC_FORUM_T2T) 1875 { 1876 /* Type 2 tag have not sent NACK after activation */ 1877 status = RW_T2tPresenceCheck(); 1878 break; 1879 } 1880 1881 default: 1882 /* Protocol unsupported by RW module... */ 1883 unsupported = TRUE; 1884 break; 1885 } 1886 1887 if (unsupported) 1888 { 1889 if (nfa_rw_cb.activated_tech_mode == NFC_DISCOVERY_TYPE_POLL_KOVIO) 1890 { 1891 /* start Kovio presence check (deactivate and wait for activation) */ 1892 status = nfa_dm_disc_start_kovio_presence_check (); 1893 } 1894 else 1895 { 1896 /* Let DM perform presence check (by putting tag to sleep and then waking it up) */ 1897 status = nfa_dm_disc_sleep_wakeup(); 1898 } 1899 } 1900 1901 /* Handle presence check failure */ 1902 if (status != NFC_STATUS_OK) 1903 nfa_rw_handle_presence_check_rsp(NFC_STATUS_FAILED); 1904 else if (!unsupported) 1905 { 1906 nfa_sys_start_timer (&nfa_rw_cb.tle, NFA_RW_PRESENCE_CHECK_TIMEOUT_EVT, p_nfa_dm_cfg->presence_check_timeout); 1907 } 1908} 1909 1910 1911/******************************************************************************* 1912** 1913** Function nfa_rw_presence_check_tick 1914** 1915** Description Called on expiration of NFA_RW_PRESENCE_CHECK_INTERVAL 1916** Initiate presence check 1917** 1918** Returns TRUE (caller frees message buffer) 1919** 1920*******************************************************************************/ 1921BOOLEAN nfa_rw_presence_check_tick(tNFA_RW_MSG *p_data) 1922{ 1923 /* Store the current operation */ 1924 nfa_rw_cb.cur_op = NFA_RW_OP_PRESENCE_CHECK; 1925 nfa_rw_cb.flags |= NFA_RW_FL_AUTO_PRESENCE_CHECK_BUSY; 1926 NFA_TRACE_DEBUG0("Auto-presence check starting..."); 1927 1928 /* Perform presence check */ 1929 nfa_rw_presence_check(NULL); 1930 1931 return TRUE; 1932} 1933 1934/******************************************************************************* 1935** 1936** Function nfa_rw_presence_check_timeout 1937** 1938** Description presence check timeout: report presence check failure 1939** 1940** Returns TRUE (caller frees message buffer) 1941** 1942*******************************************************************************/ 1943BOOLEAN nfa_rw_presence_check_timeout (tNFA_RW_MSG *p_data) 1944{ 1945 nfa_rw_handle_presence_check_rsp(NFC_STATUS_FAILED); 1946 return TRUE; 1947} 1948 1949/******************************************************************************* 1950** 1951** Function nfa_rw_format_tag 1952** 1953** Description Handler for NFA_RW_API_FORMAT_TAG 1954** 1955** Returns Nothing 1956** 1957*******************************************************************************/ 1958static void nfa_rw_format_tag (tNFA_RW_MSG *p_data) 1959{ 1960 tNFC_PROTOCOL protocol = nfa_rw_cb.protocol; 1961 tNFC_STATUS status = NFC_STATUS_FAILED; 1962 1963 if (protocol == NFC_PROTOCOL_T1T) 1964 { 1965 status = RW_T1tFormatNDef(); 1966 } 1967 else if ( (protocol == NFC_PROTOCOL_T2T) 1968 &&(nfa_rw_cb.pa_sel_res == NFC_SEL_RES_NFC_FORUM_T2T) ) 1969 { 1970 status = RW_T2tFormatNDef(); 1971 } 1972 else if (protocol == NFC_PROTOCOL_T3T) 1973 { 1974 status = RW_T3tFormatNDef(); 1975 } 1976 else if (protocol == NFC_PROTOCOL_15693) 1977 { 1978 status = RW_I93FormatNDef(); 1979 } 1980 1981 /* If unable to format NDEF, notify the app */ 1982 if (status != NFC_STATUS_OK) 1983 nfa_rw_error_cleanup (NFA_FORMAT_CPLT_EVT); 1984} 1985 1986/******************************************************************************* 1987** 1988** Function nfa_rw_detect_tlv 1989** 1990** Description Handler for NFA_RW_API_DETECT_NDEF_EVT 1991** 1992** Returns TRUE (message buffer to be freed by caller) 1993** 1994*******************************************************************************/ 1995static BOOLEAN nfa_rw_detect_tlv (tNFA_RW_MSG *p_data, UINT8 tlv) 1996{ 1997 NFA_TRACE_DEBUG0("nfa_rw_detect_tlv"); 1998 1999 switch (nfa_rw_cb.protocol) 2000 { 2001 case NFC_PROTOCOL_T1T: 2002 if (RW_T1tLocateTlv(tlv) != NFC_STATUS_OK) 2003 nfa_rw_error_cleanup (NFA_TLV_DETECT_EVT); 2004 break; 2005 2006 case NFC_PROTOCOL_T2T: 2007 if (nfa_rw_cb.pa_sel_res == NFC_SEL_RES_NFC_FORUM_T2T) 2008 { 2009 if (RW_T2tLocateTlv(tlv) != NFC_STATUS_OK) 2010 nfa_rw_error_cleanup (NFA_TLV_DETECT_EVT); 2011 } 2012 break; 2013 2014 default: 2015 break; 2016 } 2017 2018 return TRUE; 2019} 2020 2021/******************************************************************************* 2022** 2023** Function nfa_rw_config_tag_ro 2024** 2025** Description Handler for NFA_RW_OP_SET_TAG_RO 2026** 2027** Returns TRUE (message buffer to be freed by caller) 2028** 2029*******************************************************************************/ 2030static tNFC_STATUS nfa_rw_config_tag_ro (BOOLEAN b_hard_lock) 2031{ 2032 tNFC_PROTOCOL protocol = nfa_rw_cb.protocol; 2033 tNFC_STATUS status = NFC_STATUS_FAILED; 2034 2035 NFA_TRACE_DEBUG0 ("nfa_rw_config_tag_ro ()"); 2036 2037 switch (protocol) 2038 { 2039 case NFC_PROTOCOL_T1T: 2040 if( (nfa_rw_cb.tlv_st == NFA_RW_TLV_DETECT_ST_OP_NOT_STARTED) 2041 ||(nfa_rw_cb.tlv_st == NFA_RW_TLV_DETECT_ST_MEM_TLV_OP_COMPLETE) ) 2042 { 2043 status = RW_T1tLocateTlv(TAG_LOCK_CTRL_TLV); 2044 return (status); 2045 } 2046 else 2047 { 2048 status = RW_T1tSetTagReadOnly(b_hard_lock); 2049 } 2050 break; 2051 2052 case NFC_PROTOCOL_T2T: 2053 if (nfa_rw_cb.pa_sel_res == NFC_SEL_RES_NFC_FORUM_T2T) 2054 { 2055 status = RW_T2tSetTagReadOnly(b_hard_lock); 2056 } 2057 break; 2058 2059 case NFC_PROTOCOL_T3T: 2060 status = RW_T3tSetReadOnly(b_hard_lock); 2061 break; 2062 2063 case NFC_PROTOCOL_ISO_DEP: 2064 status = RW_T4tSetNDefReadOnly(); 2065 break; 2066 2067 case NFC_PROTOCOL_15693: 2068 status = RW_I93SetTagReadOnly(); 2069 break; 2070 2071 default: 2072 break; 2073 2074 } 2075 2076 if (status == NFC_STATUS_OK) 2077 { 2078 nfa_rw_cb.ndef_st = NFA_RW_NDEF_ST_UNKNOWN; 2079 } 2080 else 2081 { 2082 nfa_rw_error_cleanup (NFA_SET_TAG_RO_EVT); 2083 } 2084 2085 return (status); 2086} 2087 2088/******************************************************************************* 2089** 2090** Function nfa_rw_t1t_rid 2091** 2092** Description Handler for T1T_RID API 2093** 2094** Returns TRUE (message buffer to be freed by caller) 2095** 2096*******************************************************************************/ 2097static BOOLEAN nfa_rw_t1t_rid(tNFA_RW_MSG *p_data) 2098{ 2099 if (RW_T1tRid () != NFC_STATUS_OK) 2100 nfa_rw_error_cleanup (NFA_READ_CPLT_EVT); 2101 2102 return TRUE; 2103} 2104 2105/******************************************************************************* 2106** 2107** Function nfa_rw_t1t_rall 2108** 2109** Description Handler for T1T_ReadAll API 2110** 2111** Returns TRUE (message buffer to be freed by caller) 2112** 2113*******************************************************************************/ 2114static BOOLEAN nfa_rw_t1t_rall(tNFA_RW_MSG *p_data) 2115{ 2116 if (RW_T1tReadAll() != NFC_STATUS_OK) 2117 nfa_rw_error_cleanup (NFA_READ_CPLT_EVT); 2118 2119 return TRUE; 2120} 2121 2122/******************************************************************************* 2123** 2124** Function nfa_rw_t1t_read 2125** 2126** Description Handler for T1T_Read API 2127** 2128** Returns TRUE (message buffer to be freed by caller) 2129** 2130*******************************************************************************/ 2131static BOOLEAN nfa_rw_t1t_read (tNFA_RW_MSG *p_data) 2132{ 2133 tNFA_RW_OP_PARAMS_T1T_READ *p_t1t_read = (tNFA_RW_OP_PARAMS_T1T_READ *)&(p_data->op_req.params.t1t_read); 2134 2135 if (RW_T1tRead (p_t1t_read->block_number, p_t1t_read->index) != NFC_STATUS_OK) 2136 nfa_rw_error_cleanup (NFA_READ_CPLT_EVT); 2137 2138 return TRUE; 2139} 2140 2141/******************************************************************************* 2142** 2143** Function nfa_rw_t1t_write 2144** 2145** Description Handler for T1T_WriteErase/T1T_WriteNoErase API 2146** 2147** Returns TRUE (message buffer to be freed by caller) 2148** 2149*******************************************************************************/ 2150static BOOLEAN nfa_rw_t1t_write (tNFA_RW_MSG *p_data) 2151{ 2152 tNFA_RW_OP_PARAMS_T1T_WRITE *p_t1t_write = (tNFA_RW_OP_PARAMS_T1T_WRITE *)&(p_data->op_req.params.t1t_write); 2153 tNFC_STATUS status; 2154 2155 if (p_t1t_write->b_erase) 2156 { 2157 status = RW_T1tWriteErase (p_t1t_write->block_number,p_t1t_write->index,p_t1t_write->p_block_data[0]); 2158 } 2159 else 2160 { 2161 status = RW_T1tWriteNoErase (p_t1t_write->block_number,p_t1t_write->index,p_t1t_write->p_block_data[0]); 2162 } 2163 2164 if (status != NFC_STATUS_OK) 2165 { 2166 nfa_rw_error_cleanup (NFA_WRITE_CPLT_EVT); 2167 } 2168 else 2169 { 2170 if (p_t1t_write->block_number == 0x01) 2171 nfa_rw_cb.ndef_st = NFA_RW_NDEF_ST_UNKNOWN; 2172 } 2173 2174 return TRUE; 2175} 2176 2177/******************************************************************************* 2178** 2179** Function nfa_rw_t1t_rseg 2180** 2181** Description Handler for T1t_ReadSeg API 2182** 2183** Returns TRUE (message buffer to be freed by caller) 2184** 2185*******************************************************************************/ 2186static BOOLEAN nfa_rw_t1t_rseg (tNFA_RW_MSG *p_data) 2187{ 2188 tNFA_RW_OP_PARAMS_T1T_READ *p_t1t_read = (tNFA_RW_OP_PARAMS_T1T_READ *)&(p_data->op_req.params.t1t_read); 2189 2190 if (RW_T1tReadSeg (p_t1t_read->segment_number) != NFC_STATUS_OK) 2191 nfa_rw_error_cleanup (NFA_READ_CPLT_EVT); 2192 2193 return TRUE; 2194} 2195 2196/******************************************************************************* 2197** 2198** Function nfa_rw_t1t_read8 2199** 2200** Description Handler for T1T_Read8 API 2201** 2202** Returns TRUE (message buffer to be freed by caller) 2203** 2204*******************************************************************************/ 2205static BOOLEAN nfa_rw_t1t_read8 (tNFA_RW_MSG *p_data) 2206{ 2207 tNFA_RW_OP_PARAMS_T1T_READ *p_t1t_read = (tNFA_RW_OP_PARAMS_T1T_READ *)&(p_data->op_req.params.t1t_read); 2208 2209 if (RW_T1tRead8 (p_t1t_read->block_number) != NFC_STATUS_OK) 2210 nfa_rw_error_cleanup (NFA_READ_CPLT_EVT); 2211 2212 return TRUE; 2213} 2214 2215/******************************************************************************* 2216** 2217** Function nfa_rw_t1t_write8 2218** 2219** Description Handler for T1T_WriteErase8/T1T_WriteNoErase8 API 2220** 2221** Returns TRUE (message buffer to be freed by caller) 2222** 2223*******************************************************************************/ 2224static BOOLEAN nfa_rw_t1t_write8 (tNFA_RW_MSG *p_data) 2225{ 2226 tNFA_RW_OP_PARAMS_T1T_WRITE *p_t1t_write = (tNFA_RW_OP_PARAMS_T1T_WRITE *)&(p_data->op_req.params.t1t_write); 2227 tNFC_STATUS status; 2228 2229 if (p_t1t_write->b_erase) 2230 { 2231 status = RW_T1tWriteErase8 (p_t1t_write->block_number,p_t1t_write->p_block_data); 2232 } 2233 else 2234 { 2235 status = RW_T1tWriteNoErase8 (p_t1t_write->block_number,p_t1t_write->p_block_data); 2236 } 2237 2238 if (status != NFC_STATUS_OK) 2239 { 2240 nfa_rw_error_cleanup (NFA_WRITE_CPLT_EVT); 2241 } 2242 else 2243 { 2244 if (p_t1t_write->block_number == 0x01) 2245 nfa_rw_cb.ndef_st = NFA_RW_NDEF_ST_UNKNOWN; 2246 } 2247 2248 return TRUE; 2249} 2250 2251/******************************************************************************* 2252** 2253** Function nfa_rw_t2t_read 2254** 2255** Description Handler for T2T_Read API 2256** 2257** Returns TRUE (message buffer to be freed by caller) 2258** 2259*******************************************************************************/ 2260static BOOLEAN nfa_rw_t2t_read (tNFA_RW_MSG *p_data) 2261{ 2262 tNFA_RW_OP_PARAMS_T2T_READ *p_t2t_read = (tNFA_RW_OP_PARAMS_T2T_READ *)&(p_data->op_req.params.t2t_read); 2263 tNFC_STATUS status = NFC_STATUS_FAILED; 2264 2265 if (nfa_rw_cb.pa_sel_res == NFC_SEL_RES_NFC_FORUM_T2T) 2266 status = RW_T2tRead (p_t2t_read->block_number); 2267 2268 if (status != NFC_STATUS_OK) 2269 nfa_rw_error_cleanup (NFA_READ_CPLT_EVT); 2270 2271 return TRUE; 2272} 2273 2274/******************************************************************************* 2275** 2276** Function nfa_rw_t2t_write 2277** 2278** Description Handler for T2T_Write API 2279** 2280** Returns TRUE (message buffer to be freed by caller) 2281** 2282*******************************************************************************/ 2283static BOOLEAN nfa_rw_t2t_write (tNFA_RW_MSG *p_data) 2284{ 2285 tNFA_RW_OP_PARAMS_T2T_WRITE *p_t2t_write = (tNFA_RW_OP_PARAMS_T2T_WRITE *)&(p_data->op_req.params.t2t_write); 2286 2287 if (RW_T2tWrite (p_t2t_write->block_number,p_t2t_write->p_block_data) != NFC_STATUS_OK) 2288 { 2289 nfa_rw_error_cleanup (NFA_WRITE_CPLT_EVT); 2290 } 2291 else 2292 { 2293 if (p_t2t_write->block_number == 0x03) 2294 nfa_rw_cb.ndef_st = NFA_RW_NDEF_ST_UNKNOWN; 2295 } 2296 2297 return TRUE; 2298} 2299 2300/******************************************************************************* 2301** 2302** Function nfa_rw_t2t_sector_select 2303** 2304** Description Handler for T2T_Sector_Select API 2305** 2306** Returns TRUE (message buffer to be freed by caller) 2307** 2308*******************************************************************************/ 2309static BOOLEAN nfa_rw_t2t_sector_select(tNFA_RW_MSG *p_data) 2310{ 2311 tNFA_RW_OP_PARAMS_T2T_SECTOR_SELECT *p_t2t_sector_select = (tNFA_RW_OP_PARAMS_T2T_SECTOR_SELECT *)&(p_data->op_req.params.t2t_sector_select); 2312 2313 if (RW_T2tSectorSelect (p_t2t_sector_select->sector_number) != NFC_STATUS_OK) 2314 nfa_rw_error_cleanup (NFA_SELECT_CPLT_EVT); 2315 2316 return TRUE; 2317} 2318 2319/******************************************************************************* 2320** 2321** Function nfa_rw_t3t_read 2322** 2323** Description Handler for T3T_Read API 2324** 2325** Returns TRUE (message buffer to be freed by caller) 2326** 2327*******************************************************************************/ 2328static BOOLEAN nfa_rw_t3t_read (tNFA_RW_MSG *p_data) 2329{ 2330 tNFA_RW_OP_PARAMS_T3T_READ *p_t3t_read = (tNFA_RW_OP_PARAMS_T3T_READ *)&(p_data->op_req.params.t3t_read); 2331 2332 if (RW_T3tCheck (p_t3t_read->num_blocks, (tT3T_BLOCK_DESC *)p_t3t_read->p_block_desc) != NFC_STATUS_OK) 2333 nfa_rw_error_cleanup (NFA_READ_CPLT_EVT); 2334 2335 return TRUE; 2336} 2337 2338/******************************************************************************* 2339** 2340** Function nfa_rw_t3t_write 2341** 2342** Description Handler for T3T_Write API 2343** 2344** Returns TRUE (message buffer to be freed by caller) 2345** 2346*******************************************************************************/ 2347static BOOLEAN nfa_rw_t3t_write (tNFA_RW_MSG *p_data) 2348{ 2349 tNFA_RW_OP_PARAMS_T3T_WRITE *p_t3t_write = (tNFA_RW_OP_PARAMS_T3T_WRITE *)&(p_data->op_req.params.t3t_write); 2350 2351 if (RW_T3tUpdate (p_t3t_write->num_blocks, (tT3T_BLOCK_DESC *)p_t3t_write->p_block_desc, p_t3t_write->p_block_data) != NFC_STATUS_OK) 2352 nfa_rw_error_cleanup (NFA_WRITE_CPLT_EVT); 2353 2354 return TRUE; 2355} 2356 2357/******************************************************************************* 2358** 2359** Function nfa_rw_t3t_get_system_codes 2360** 2361** Description Get system codes (initiated by NFA after activation) 2362** 2363** Returns TRUE (message buffer to be freed by caller) 2364** 2365*******************************************************************************/ 2366static BOOLEAN nfa_rw_t3t_get_system_codes (tNFA_RW_MSG *p_data) 2367{ 2368 tNFC_STATUS status; 2369 tNFA_TAG_PARAMS tag_params; 2370 2371 status = RW_T3tGetSystemCodes(); 2372 2373 if (status != NFC_STATUS_OK) 2374 { 2375 /* Command complete - perform cleanup, notify app */ 2376 nfa_rw_command_complete(); 2377 tag_params.t3t.num_system_codes = 0; 2378 tag_params.t3t.p_system_codes = NULL; 2379 2380 nfa_dm_notify_activation_status (NFA_STATUS_OK, &tag_params); 2381 } 2382 2383 return TRUE; 2384} 2385 2386/******************************************************************************* 2387** 2388** Function nfa_rw_i93_command 2389** 2390** Description Handler for ISO 15693 command 2391** 2392** Returns TRUE (message buffer to be freed by caller) 2393** 2394*******************************************************************************/ 2395static BOOLEAN nfa_rw_i93_command (tNFA_RW_MSG *p_data) 2396{ 2397 tNFA_CONN_EVT_DATA conn_evt_data; 2398 tNFC_STATUS status = NFC_STATUS_OK; 2399 UINT8 i93_command = I93_CMD_STAY_QUIET; 2400 2401 switch (p_data->op_req.op) 2402 { 2403 case NFA_RW_OP_I93_INVENTORY: 2404 i93_command = I93_CMD_INVENTORY; 2405 if (p_data->op_req.params.i93_cmd.uid_present) 2406 { 2407 status = RW_I93Inventory (p_data->op_req.params.i93_cmd.afi_present, 2408 p_data->op_req.params.i93_cmd.afi, 2409 p_data->op_req.params.i93_cmd.uid); 2410 } 2411 else 2412 { 2413 status = RW_I93Inventory (p_data->op_req.params.i93_cmd.afi_present, 2414 p_data->op_req.params.i93_cmd.afi, 2415 NULL); 2416 } 2417 break; 2418 2419 case NFA_RW_OP_I93_STAY_QUIET: 2420 i93_command = I93_CMD_STAY_QUIET; 2421 status = RW_I93StayQuiet (); 2422 break; 2423 2424 case NFA_RW_OP_I93_READ_SINGLE_BLOCK: 2425 i93_command = I93_CMD_READ_SINGLE_BLOCK; 2426 status = RW_I93ReadSingleBlock (p_data->op_req.params.i93_cmd.first_block_number); 2427 break; 2428 2429 case NFA_RW_OP_I93_WRITE_SINGLE_BLOCK: 2430 i93_command = I93_CMD_WRITE_SINGLE_BLOCK; 2431 status = RW_I93WriteSingleBlock (p_data->op_req.params.i93_cmd.first_block_number, 2432 p_data->op_req.params.i93_cmd.p_data); 2433 break; 2434 2435 case NFA_RW_OP_I93_LOCK_BLOCK: 2436 i93_command = I93_CMD_LOCK_BLOCK; 2437 status = RW_I93LockBlock ((UINT8)p_data->op_req.params.i93_cmd.first_block_number); 2438 break; 2439 2440 case NFA_RW_OP_I93_READ_MULTI_BLOCK: 2441 i93_command = I93_CMD_READ_MULTI_BLOCK; 2442 status = RW_I93ReadMultipleBlocks (p_data->op_req.params.i93_cmd.first_block_number, 2443 p_data->op_req.params.i93_cmd.number_blocks); 2444 break; 2445 2446 case NFA_RW_OP_I93_WRITE_MULTI_BLOCK: 2447 i93_command = I93_CMD_WRITE_MULTI_BLOCK; 2448 status = RW_I93WriteMultipleBlocks ((UINT8)p_data->op_req.params.i93_cmd.first_block_number, 2449 p_data->op_req.params.i93_cmd.number_blocks, 2450 p_data->op_req.params.i93_cmd.p_data); 2451 break; 2452 2453 case NFA_RW_OP_I93_SELECT: 2454 i93_command = I93_CMD_SELECT; 2455 status = RW_I93Select (p_data->op_req.params.i93_cmd.p_data); 2456 break; 2457 2458 case NFA_RW_OP_I93_RESET_TO_READY: 2459 i93_command = I93_CMD_RESET_TO_READY; 2460 status = RW_I93ResetToReady (); 2461 break; 2462 2463 case NFA_RW_OP_I93_WRITE_AFI: 2464 i93_command = I93_CMD_WRITE_AFI; 2465 status = RW_I93WriteAFI (p_data->op_req.params.i93_cmd.afi); 2466 break; 2467 2468 case NFA_RW_OP_I93_LOCK_AFI: 2469 i93_command = I93_CMD_LOCK_AFI; 2470 status = RW_I93LockAFI (); 2471 break; 2472 2473 case NFA_RW_OP_I93_WRITE_DSFID: 2474 i93_command = I93_CMD_WRITE_DSFID; 2475 status = RW_I93WriteDSFID (p_data->op_req.params.i93_cmd.dsfid); 2476 break; 2477 2478 case NFA_RW_OP_I93_LOCK_DSFID: 2479 i93_command = I93_CMD_LOCK_DSFID; 2480 status = RW_I93LockDSFID (); 2481 break; 2482 2483 case NFA_RW_OP_I93_GET_SYS_INFO: 2484 i93_command = I93_CMD_GET_SYS_INFO; 2485 if (p_data->op_req.params.i93_cmd.uid_present) 2486 { 2487 status = RW_I93GetSysInfo (p_data->op_req.params.i93_cmd.uid); 2488 } 2489 else 2490 { 2491 status = RW_I93GetSysInfo (NULL); 2492 } 2493 break; 2494 2495 case NFA_RW_OP_I93_GET_MULTI_BLOCK_STATUS: 2496 i93_command = I93_CMD_GET_MULTI_BLK_SEC; 2497 status = RW_I93GetMultiBlockSecurityStatus (p_data->op_req.params.i93_cmd.first_block_number, 2498 p_data->op_req.params.i93_cmd.number_blocks); 2499 break; 2500 2501 default: 2502 break; 2503 } 2504 2505 if (status != NFC_STATUS_OK) 2506 { 2507 /* Command complete - perform cleanup, notify app */ 2508 nfa_rw_command_complete(); 2509 2510 conn_evt_data.i93_cmd_cplt.status = NFA_STATUS_FAILED; 2511 conn_evt_data.i93_cmd_cplt.sent_command = i93_command; 2512 2513 nfa_dm_act_conn_cback_notify(NFA_I93_CMD_CPLT_EVT, &conn_evt_data); 2514 } 2515 2516 return TRUE; 2517} 2518 2519/******************************************************************************* 2520** 2521** Function nfa_rw_raw_mode_data_cback 2522** 2523** Description Handler for incoming tag data for unsupported tag protocols 2524** (forward data to upper layer) 2525** 2526** Returns nothing 2527** 2528*******************************************************************************/ 2529static void nfa_rw_raw_mode_data_cback (UINT8 conn_id, tNFC_CONN_EVT event, tNFC_CONN *p_data) 2530{ 2531 BT_HDR *p_msg; 2532 tNFA_CONN_EVT_DATA evt_data; 2533 2534 NFA_TRACE_DEBUG1 ("nfa_rw_raw_mode_data_cback(): event = 0x%X", event); 2535 2536 if ( (event == NFC_DATA_CEVT) 2537 &&( (p_data->data.status == NFC_STATUS_OK) 2538 ||(p_data->data.status == NFC_STATUS_CONTINUE) ) ) 2539 { 2540 p_msg = (BT_HDR *)p_data->data.p_data; 2541 2542 if (p_msg) 2543 { 2544 evt_data.data.status = p_data->data.status; 2545 evt_data.data.p_data = (UINT8 *)(p_msg + 1) + p_msg->offset; 2546 evt_data.data.len = p_msg->len; 2547 2548 nfa_dm_conn_cback_event_notify (NFA_DATA_EVT, &evt_data); 2549 2550 GKI_freebuf (p_msg); 2551 } 2552 else 2553 { 2554 NFA_TRACE_ERROR0 ("nfa_rw_raw_mode_data_cback (): received NFC_DATA_CEVT with NULL data pointer"); 2555 } 2556 } 2557 else if (event == NFC_DEACTIVATE_CEVT) 2558 { 2559 NFC_SetStaticRfCback (NULL); 2560 } 2561} 2562 2563 2564/******************************************************************************* 2565** 2566** Function nfa_rw_activate_ntf 2567** 2568** Description Handler for NFA_RW_ACTIVATE_NTF 2569** 2570** Returns TRUE (message buffer to be freed by caller) 2571** 2572*******************************************************************************/ 2573BOOLEAN nfa_rw_activate_ntf(tNFA_RW_MSG *p_data) 2574{ 2575 tNFC_ACTIVATE_DEVT *p_activate_params = p_data->activate_ntf.p_activate_params; 2576 tNFA_TAG_PARAMS tag_params; 2577 tNFA_RW_OPERATION msg; 2578 BOOLEAN activate_notify = TRUE; 2579 UINT8 *p; 2580 2581 if ( (nfa_rw_cb.halt_event != RW_T2T_MAX_EVT) 2582 &&(nfa_rw_cb.activated_tech_mode == NFC_DISCOVERY_TYPE_POLL_A) 2583 &&(nfa_rw_cb.protocol == NFC_PROTOCOL_T2T) 2584 &&(nfa_rw_cb.pa_sel_res == NFC_SEL_RES_NFC_FORUM_T2T) ) 2585 { 2586 /* Type 2 tag is wake up from HALT State */ 2587 NFA_TRACE_DEBUG0("nfa_rw_activate_ntf () - Type 2 tag wake up from HALT State"); 2588 return TRUE; 2589 } 2590 2591 NFA_TRACE_DEBUG0("nfa_rw_activate_ntf"); 2592 2593 /* Initialize control block */ 2594 nfa_rw_cb.protocol = p_activate_params->protocol; 2595 nfa_rw_cb.intf_type = p_activate_params->intf_param.type; 2596 nfa_rw_cb.pa_sel_res = p_activate_params->rf_tech_param.param.pa.sel_rsp; 2597 nfa_rw_cb.activated_tech_mode = p_activate_params->rf_tech_param.mode; 2598 nfa_rw_cb.flags = NFA_RW_FL_ACTIVATED; 2599 nfa_rw_cb.cur_op = NFA_RW_OP_MAX; 2600 nfa_rw_cb.halt_event = RW_T2T_MAX_EVT; 2601 nfa_rw_cb.skip_dyn_locks = FALSE; 2602 nfa_rw_cb.ndef_st = NFA_RW_NDEF_ST_UNKNOWN; 2603 nfa_rw_cb.tlv_st = NFA_RW_TLV_DETECT_ST_OP_NOT_STARTED; 2604 2605 memset (&tag_params, 0, sizeof(tNFA_TAG_PARAMS)); 2606 2607 /* Check if we are in exclusive RF mode */ 2608 if (p_data->activate_ntf.excl_rf_not_active) 2609 { 2610 /* Not in exclusive RF mode */ 2611 nfa_rw_cb.flags |= NFA_RW_FL_NOT_EXCL_RF_MODE; 2612 } 2613 2614 /* check if the protocol is activated with supported interface */ 2615 if (p_activate_params->intf_param.type == NCI_INTERFACE_FRAME) 2616 { 2617 if ( (p_activate_params->protocol != NFA_PROTOCOL_T1T) 2618 &&(p_activate_params->protocol != NFA_PROTOCOL_T2T) 2619 &&(p_activate_params->protocol != NFA_PROTOCOL_T3T) 2620 &&(p_activate_params->protocol != NFC_PROTOCOL_15693) ) 2621 { 2622 nfa_rw_cb.protocol = NFA_PROTOCOL_INVALID; 2623 } 2624 } 2625 else if (p_activate_params->intf_param.type == NCI_INTERFACE_ISO_DEP) 2626 { 2627 if (p_activate_params->protocol != NFA_PROTOCOL_ISO_DEP) 2628 { 2629 nfa_rw_cb.protocol = NFA_PROTOCOL_INVALID; 2630 } 2631 } 2632 2633 if (nfa_rw_cb.protocol == NFA_PROTOCOL_INVALID) 2634 { 2635 /* Only sending raw frame and presence check are supported in this state */ 2636 2637 NFC_SetStaticRfCback(nfa_rw_raw_mode_data_cback); 2638 2639 /* Notify app of NFA_ACTIVATED_EVT and start presence check timer */ 2640 nfa_dm_notify_activation_status (NFA_STATUS_OK, NULL); 2641 nfa_rw_check_start_presence_check_timer (NFA_RW_PRESENCE_CHECK_INTERVAL); 2642 return TRUE; 2643 } 2644 2645 /* If protocol not supported by RW module, notify app of NFA_ACTIVATED_EVT and start presence check if needed */ 2646 if (!nfa_dm_is_protocol_supported(p_activate_params->protocol, p_activate_params->rf_tech_param.param.pa.sel_rsp)) 2647 { 2648 /* Notify upper layer of NFA_ACTIVATED_EVT if needed, and start presence check timer */ 2649 /* Set data callback (pass all incoming data to upper layer using NFA_DATA_EVT) */ 2650 NFC_SetStaticRfCback(nfa_rw_raw_mode_data_cback); 2651 2652 /* Notify app of NFA_ACTIVATED_EVT and start presence check timer */ 2653 nfa_dm_notify_activation_status (NFA_STATUS_OK, NULL); 2654 nfa_rw_check_start_presence_check_timer (NFA_RW_PRESENCE_CHECK_INTERVAL); 2655 return TRUE; 2656 } 2657 2658 /* Initialize RW module */ 2659 if ((RW_SetActivatedTagType (p_activate_params, nfa_rw_cback)) != NFC_STATUS_OK) 2660 { 2661 /* Log error (stay in NFA_RW_ST_ACTIVATED state until deactivation) */ 2662 NFA_TRACE_ERROR0("RW_SetActivatedTagType failed."); 2663 return TRUE; 2664 } 2665 2666 /* Perform protocol-specific actions */ 2667 switch (nfa_rw_cb.protocol) 2668 { 2669 case NFC_PROTOCOL_T1T: 2670 /* Retrieve HR and UID fields from activation notification */ 2671 memcpy (tag_params.t1t.hr, p_activate_params->intf_param.intf_param.frame.param, NFA_T1T_HR_LEN); 2672 memcpy (tag_params.t1t.uid, p_activate_params->rf_tech_param.param.pa.nfcid1, p_activate_params->rf_tech_param.param.pa.nfcid1_len); 2673 break; 2674 2675 case NFC_PROTOCOL_T2T: 2676 /* Retrieve UID fields from activation notification */ 2677 memcpy (tag_params.t2t.uid, p_activate_params->rf_tech_param.param.pa.nfcid1, p_activate_params->rf_tech_param.param.pa.nfcid1_len); 2678 break; 2679 2680 case NFC_PROTOCOL_T3T: 2681 /* Issue command to get Felica system codes */ 2682 activate_notify = FALSE; /* Delay notifying upper layer of NFA_ACTIVATED_EVT until system codes are retrieved */ 2683 msg.op = NFA_RW_OP_T3T_GET_SYSTEM_CODES; 2684 nfa_rw_handle_op_req((tNFA_RW_MSG *)&msg); 2685 break; 2686 2687 case NFC_PROTOCOL_15693: 2688 /* Delay notifying upper layer of NFA_ACTIVATED_EVT to retrieve additional tag infomation */ 2689 nfa_rw_cb.flags |= NFA_RW_FL_ACTIVATION_NTF_PENDING; 2690 activate_notify = FALSE; 2691 2692 /* store DSFID and UID from activation NTF */ 2693 nfa_rw_cb.i93_dsfid = p_activate_params->rf_tech_param.param.pi93.dsfid; 2694 2695 p = nfa_rw_cb.i93_uid; 2696 ARRAY8_TO_STREAM (p, p_activate_params->rf_tech_param.param.pi93.uid); 2697 2698 if ((nfa_rw_cb.i93_uid[1] == I93_UID_IC_MFG_CODE_TI) 2699 &&(((nfa_rw_cb.i93_uid[2] & I93_UID_TAG_IT_HF_I_PRODUCT_ID_MASK) == I93_UID_TAG_IT_HF_I_STD_CHIP_INLAY) 2700 ||((nfa_rw_cb.i93_uid[2] & I93_UID_TAG_IT_HF_I_PRODUCT_ID_MASK) == I93_UID_TAG_IT_HF_I_PRO_CHIP_INLAY))) 2701 { 2702 /* these don't support Get System Information Command */ 2703 nfa_rw_cb.i93_block_size = I93_TAG_IT_HF_I_STD_PRO_CHIP_INLAY_BLK_SIZE; 2704 nfa_rw_cb.i93_afi_location = I93_TAG_IT_HF_I_STD_PRO_CHIP_INLAY_AFI_LOCATION; 2705 2706 if ((nfa_rw_cb.i93_uid[2] & I93_UID_TAG_IT_HF_I_PRODUCT_ID_MASK) == I93_UID_TAG_IT_HF_I_STD_CHIP_INLAY) 2707 { 2708 nfa_rw_cb.i93_num_block = I93_TAG_IT_HF_I_STD_CHIP_INLAY_NUM_TOTAL_BLK; 2709 } 2710 else 2711 { 2712 nfa_rw_cb.i93_num_block = I93_TAG_IT_HF_I_PRO_CHIP_INLAY_NUM_TOTAL_BLK; 2713 } 2714 2715 /* read AFI */ 2716 if (RW_I93ReadSingleBlock ((UINT8)(nfa_rw_cb.i93_afi_location / nfa_rw_cb.i93_block_size)) != NFC_STATUS_OK) 2717 { 2718 /* notify activation without AFI/IC-Ref */ 2719 nfa_rw_cb.flags &= ~NFA_RW_FL_ACTIVATION_NTF_PENDING; 2720 activate_notify = TRUE; 2721 2722 tag_params.i93.info_flags = (I93_INFO_FLAG_DSFID|I93_INFO_FLAG_MEM_SIZE); 2723 tag_params.i93.dsfid = nfa_rw_cb.i93_dsfid; 2724 tag_params.i93.block_size = nfa_rw_cb.i93_block_size; 2725 tag_params.i93.num_block = nfa_rw_cb.i93_num_block; 2726 memcpy (tag_params.i93.uid, nfa_rw_cb.i93_uid, I93_UID_BYTE_LEN); 2727 } 2728 } 2729 else 2730 { 2731 /* All of ICODE supports Get System Information Command */ 2732 /* Tag-it HF-I Plus Chip/Inlay supports Get System Information Command */ 2733 /* just try for others */ 2734 2735 if (RW_I93GetSysInfo (nfa_rw_cb.i93_uid) != NFC_STATUS_OK) 2736 { 2737 /* notify activation without AFI/MEM size/IC-Ref */ 2738 nfa_rw_cb.flags &= ~NFA_RW_FL_ACTIVATION_NTF_PENDING; 2739 activate_notify = TRUE; 2740 2741 tag_params.i93.info_flags = I93_INFO_FLAG_DSFID; 2742 tag_params.i93.dsfid = nfa_rw_cb.i93_dsfid; 2743 tag_params.i93.block_size = 0; 2744 tag_params.i93.num_block = 0; 2745 memcpy (tag_params.i93.uid, nfa_rw_cb.i93_uid, I93_UID_BYTE_LEN); 2746 } 2747 else 2748 { 2749 /* reset memory size */ 2750 nfa_rw_cb.i93_block_size = 0; 2751 nfa_rw_cb.i93_num_block = 0; 2752 } 2753 } 2754 break; 2755 2756 2757 default: 2758 /* No action needed for other protocols */ 2759 break; 2760 } 2761 2762 /* Notify upper layer of NFA_ACTIVATED_EVT if needed, and start presence check timer */ 2763 if (activate_notify) 2764 { 2765 nfa_dm_notify_activation_status (NFA_STATUS_OK, &tag_params); 2766 nfa_rw_check_start_presence_check_timer (NFA_RW_PRESENCE_CHECK_INTERVAL); 2767 } 2768 2769 2770 return TRUE; 2771} 2772 2773 2774/******************************************************************************* 2775** 2776** Function nfa_rw_deactivate_ntf 2777** 2778** Description Handler for NFA_RW_DEACTIVATE_NTF 2779** 2780** Returns TRUE (message buffer to be freed by caller) 2781** 2782*******************************************************************************/ 2783BOOLEAN nfa_rw_deactivate_ntf(tNFA_RW_MSG *p_data) 2784{ 2785 /* Clear the activated flag */ 2786 nfa_rw_cb.flags &= ~NFA_RW_FL_ACTIVATED; 2787 2788 /* Free buffer for incoming NDEF message, in case we were in the middle of a read operation */ 2789 nfa_rw_free_ndef_rx_buf(); 2790 2791 /* If there is a pending command message, then free it */ 2792 if (nfa_rw_cb.p_pending_msg) 2793 { 2794 if ( (nfa_rw_cb.p_pending_msg->op_req.op == NFA_RW_OP_SEND_RAW_FRAME) 2795 &&(nfa_rw_cb.p_pending_msg->op_req.params.send_raw_frame.p_data) ) 2796 { 2797 GKI_freebuf(nfa_rw_cb.p_pending_msg->op_req.params.send_raw_frame.p_data); 2798 } 2799 2800 GKI_freebuf(nfa_rw_cb.p_pending_msg); 2801 nfa_rw_cb.p_pending_msg = NULL; 2802 } 2803 2804 /* If we are in the process of waking up tag from HALT state */ 2805 if (nfa_rw_cb.halt_event == RW_T2T_READ_CPLT_EVT) 2806 { 2807 if (nfa_rw_cb.rw_data.data.p_data) 2808 GKI_freebuf(nfa_rw_cb.rw_data.data.p_data); 2809 nfa_rw_cb.rw_data.data.p_data = NULL; 2810 } 2811 2812 /* Stop presence check timer (if started) */ 2813 nfa_rw_stop_presence_check_timer(); 2814 2815 return TRUE; 2816} 2817 2818/******************************************************************************* 2819** 2820** Function nfa_rw_handle_op_req 2821** 2822** Description Handler for NFA_RW_OP_REQUEST_EVT, operation request 2823** 2824** Returns TRUE if caller should free p_data 2825** FALSE if caller does not need to free p_data 2826** 2827*******************************************************************************/ 2828BOOLEAN nfa_rw_handle_op_req (tNFA_RW_MSG *p_data) 2829{ 2830 BOOLEAN freebuf = TRUE; 2831 UINT16 presence_check_start_delay = 0; 2832 2833 /* Check if activated */ 2834 if (!(nfa_rw_cb.flags & NFA_RW_FL_ACTIVATED)) 2835 { 2836 NFA_TRACE_ERROR0("nfa_rw_handle_op_req: not activated"); 2837 return TRUE; 2838 } 2839 /* Check if currently busy with another API call */ 2840 else if (nfa_rw_cb.flags & NFA_RW_FL_API_BUSY) 2841 { 2842 return (nfa_rw_op_req_while_busy(p_data)); 2843 } 2844 /* Check if currently busy with auto-presence check */ 2845 else if (nfa_rw_cb.flags & NFA_RW_FL_AUTO_PRESENCE_CHECK_BUSY) 2846 { 2847 /* Cache the command (will be handled once auto-presence check is completed) */ 2848 NFA_TRACE_DEBUG1("Deferring operation %i until after auto-presence check is completed", p_data->op_req.op); 2849 nfa_rw_cb.p_pending_msg = p_data; 2850 nfa_rw_cb.flags |= NFA_RW_FL_API_BUSY; 2851 return (FALSE); 2852 } 2853 2854 NFA_TRACE_DEBUG1("nfa_rw_handle_op_req: op=0x%02x", p_data->op_req.op); 2855 2856 nfa_rw_cb.flags |= NFA_RW_FL_API_BUSY; 2857 2858 /* Stop the presence check timer */ 2859 nfa_rw_stop_presence_check_timer(); 2860 2861 /* Store the current operation */ 2862 nfa_rw_cb.cur_op = p_data->op_req.op; 2863 2864 /* Call appropriate handler for requested operation */ 2865 switch (p_data->op_req.op) 2866 { 2867 case NFA_RW_OP_DETECT_NDEF: 2868 nfa_rw_cb.skip_dyn_locks = FALSE; 2869 nfa_rw_detect_ndef(p_data); 2870 break; 2871 2872 case NFA_RW_OP_READ_NDEF: 2873 nfa_rw_read_ndef(p_data); 2874 break; 2875 2876 case NFA_RW_OP_WRITE_NDEF: 2877 nfa_rw_write_ndef(p_data); 2878 break; 2879 2880 case NFA_RW_OP_SEND_RAW_FRAME: 2881 presence_check_start_delay = p_data->op_req.params.send_raw_frame.p_data->layer_specific; 2882 2883 NFC_SendData (NFC_RF_CONN_ID, p_data->op_req.params.send_raw_frame.p_data); 2884 2885 /* Clear the busy flag */ 2886 nfa_rw_cb.flags &= ~NFA_RW_FL_API_BUSY; 2887 2888 /* Start presence_check after specified delay */ 2889 nfa_rw_check_start_presence_check_timer (presence_check_start_delay); 2890 break; 2891 2892 case NFA_RW_OP_PRESENCE_CHECK: 2893 nfa_rw_presence_check(p_data); 2894 break; 2895 2896 case NFA_RW_OP_FORMAT_TAG: 2897 nfa_rw_format_tag(p_data); 2898 break; 2899 2900 case NFA_RW_OP_DETECT_LOCK_TLV: 2901 nfa_rw_detect_tlv(p_data, TAG_LOCK_CTRL_TLV); 2902 break; 2903 2904 case NFA_RW_OP_DETECT_MEM_TLV: 2905 nfa_rw_detect_tlv(p_data, TAG_MEM_CTRL_TLV); 2906 break; 2907 2908 case NFA_RW_OP_SET_TAG_RO: 2909 nfa_rw_cb.b_hard_lock = p_data->op_req.params.set_readonly.b_hard_lock; 2910 nfa_rw_config_tag_ro(nfa_rw_cb.b_hard_lock); 2911 break; 2912 2913 case NFA_RW_OP_T1T_RID: 2914 nfa_rw_t1t_rid(p_data); 2915 break; 2916 2917 case NFA_RW_OP_T1T_RALL: 2918 nfa_rw_t1t_rall(p_data); 2919 break; 2920 2921 case NFA_RW_OP_T1T_READ: 2922 nfa_rw_t1t_read(p_data); 2923 break; 2924 2925 case NFA_RW_OP_T1T_WRITE: 2926 nfa_rw_t1t_write(p_data); 2927 break; 2928 2929 case NFA_RW_OP_T1T_RSEG: 2930 nfa_rw_t1t_rseg(p_data); 2931 break; 2932 2933 case NFA_RW_OP_T1T_READ8: 2934 nfa_rw_t1t_read8(p_data); 2935 break; 2936 2937 case NFA_RW_OP_T1T_WRITE8: 2938 nfa_rw_t1t_write8(p_data); 2939 break; 2940 2941 /* Type-2 tag commands */ 2942 case NFA_RW_OP_T2T_READ: 2943 nfa_rw_t2t_read(p_data); 2944 break; 2945 2946 case NFA_RW_OP_T2T_WRITE: 2947 nfa_rw_t2t_write(p_data); 2948 break; 2949 2950 case NFA_RW_OP_T2T_SECTOR_SELECT: 2951 nfa_rw_t2t_sector_select(p_data); 2952 break; 2953 2954 /* Type-3 tag commands */ 2955 case NFA_RW_OP_T3T_READ: 2956 nfa_rw_t3t_read(p_data); 2957 break; 2958 2959 case NFA_RW_OP_T3T_WRITE: 2960 nfa_rw_t3t_write(p_data); 2961 break; 2962 2963 case NFA_RW_OP_T3T_GET_SYSTEM_CODES: 2964 nfa_rw_t3t_get_system_codes(p_data); 2965 break; 2966 2967 /* ISO 15693 tag commands */ 2968 case NFA_RW_OP_I93_INVENTORY: 2969 case NFA_RW_OP_I93_STAY_QUIET: 2970 case NFA_RW_OP_I93_READ_SINGLE_BLOCK: 2971 case NFA_RW_OP_I93_WRITE_SINGLE_BLOCK: 2972 case NFA_RW_OP_I93_LOCK_BLOCK: 2973 case NFA_RW_OP_I93_READ_MULTI_BLOCK: 2974 case NFA_RW_OP_I93_WRITE_MULTI_BLOCK: 2975 case NFA_RW_OP_I93_SELECT: 2976 case NFA_RW_OP_I93_RESET_TO_READY: 2977 case NFA_RW_OP_I93_WRITE_AFI: 2978 case NFA_RW_OP_I93_LOCK_AFI: 2979 case NFA_RW_OP_I93_WRITE_DSFID: 2980 case NFA_RW_OP_I93_LOCK_DSFID: 2981 case NFA_RW_OP_I93_GET_SYS_INFO: 2982 case NFA_RW_OP_I93_GET_MULTI_BLOCK_STATUS: 2983 nfa_rw_i93_command (p_data); 2984 break; 2985 2986 default: 2987 NFA_TRACE_ERROR1("nfa_rw_handle_api: unhandled operation: %i", p_data->op_req.op); 2988 break; 2989 } 2990 2991 return (freebuf); 2992} 2993 2994 2995/******************************************************************************* 2996** 2997** Function nfa_rw_op_req_while_busy 2998** 2999** Description Handle operation request while busy 3000** 3001** Returns TRUE if caller should free p_data 3002** FALSE if caller does not need to free p_data 3003** 3004*******************************************************************************/ 3005static BOOLEAN nfa_rw_op_req_while_busy(tNFA_RW_MSG *p_data) 3006{ 3007 BOOLEAN freebuf = TRUE; 3008 tNFA_CONN_EVT_DATA conn_evt_data; 3009 UINT8 event; 3010 3011 NFA_TRACE_ERROR0("nfa_rw_op_req_while_busy: unable to handle API"); 3012 3013 /* Return appropriate event for requested API, with status=BUSY */ 3014 conn_evt_data.status = NFA_STATUS_BUSY; 3015 3016 switch (p_data->op_req.op) 3017 { 3018 case NFA_RW_OP_DETECT_NDEF: 3019 conn_evt_data.ndef_detect.cur_size = 0; 3020 conn_evt_data.ndef_detect.max_size = 0; 3021 conn_evt_data.ndef_detect.flags = RW_NDEF_FL_UNKNOWN; 3022 event = NFA_NDEF_DETECT_EVT; 3023 break; 3024 case NFA_RW_OP_READ_NDEF: 3025 case NFA_RW_OP_T1T_RID: 3026 case NFA_RW_OP_T1T_RALL: 3027 case NFA_RW_OP_T1T_READ: 3028 case NFA_RW_OP_T1T_RSEG: 3029 case NFA_RW_OP_T1T_READ8: 3030 case NFA_RW_OP_T2T_READ: 3031 case NFA_RW_OP_T3T_READ: 3032 event = NFA_READ_CPLT_EVT; 3033 break; 3034 case NFA_RW_OP_WRITE_NDEF: 3035 case NFA_RW_OP_T1T_WRITE: 3036 case NFA_RW_OP_T1T_WRITE8: 3037 case NFA_RW_OP_T2T_WRITE: 3038 case NFA_RW_OP_T3T_WRITE: 3039 event = NFA_WRITE_CPLT_EVT; 3040 break; 3041 case NFA_RW_OP_FORMAT_TAG: 3042 event = NFA_FORMAT_CPLT_EVT; 3043 break; 3044 case NFA_RW_OP_DETECT_LOCK_TLV: 3045 case NFA_RW_OP_DETECT_MEM_TLV: 3046 event = NFA_TLV_DETECT_EVT; 3047 break; 3048 case NFA_RW_OP_SET_TAG_RO: 3049 event = NFA_SET_TAG_RO_EVT; 3050 break; 3051 case NFA_RW_OP_T2T_SECTOR_SELECT: 3052 event = NFA_SELECT_CPLT_EVT; 3053 break; 3054 case NFA_RW_OP_I93_INVENTORY: 3055 case NFA_RW_OP_I93_STAY_QUIET: 3056 case NFA_RW_OP_I93_READ_SINGLE_BLOCK: 3057 case NFA_RW_OP_I93_WRITE_SINGLE_BLOCK: 3058 case NFA_RW_OP_I93_LOCK_BLOCK: 3059 case NFA_RW_OP_I93_READ_MULTI_BLOCK: 3060 case NFA_RW_OP_I93_WRITE_MULTI_BLOCK: 3061 case NFA_RW_OP_I93_SELECT: 3062 case NFA_RW_OP_I93_RESET_TO_READY: 3063 case NFA_RW_OP_I93_WRITE_AFI: 3064 case NFA_RW_OP_I93_LOCK_AFI: 3065 case NFA_RW_OP_I93_WRITE_DSFID: 3066 case NFA_RW_OP_I93_LOCK_DSFID: 3067 case NFA_RW_OP_I93_GET_SYS_INFO: 3068 case NFA_RW_OP_I93_GET_MULTI_BLOCK_STATUS: 3069 event = NFA_I93_CMD_CPLT_EVT; 3070 break; 3071 default: 3072 return (freebuf); 3073 } 3074 nfa_dm_act_conn_cback_notify(event, &conn_evt_data); 3075 3076 return (freebuf); 3077} 3078 3079/******************************************************************************* 3080** 3081** Function nfa_rw_command_complete 3082** 3083** Description Handle command complete: clear the busy flag, 3084** and start the presence check timer if applicable. 3085** 3086** Returns None 3087** 3088*******************************************************************************/ 3089void nfa_rw_command_complete(void) 3090{ 3091 /* Clear the busy flag */ 3092 nfa_rw_cb.flags &= ~NFA_RW_FL_API_BUSY; 3093 3094 /* Restart presence_check timer */ 3095 nfa_rw_check_start_presence_check_timer (NFA_RW_PRESENCE_CHECK_INTERVAL); 3096} 3097