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