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