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