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 implementation for Type 2 tag in Reader/Writer 22 * mode. 23 * 24 ******************************************************************************/ 25#include <string> 26 27#include <android-base/stringprintf.h> 28#include <base/logging.h> 29 30#include "nfc_target.h" 31 32#include "bt_types.h" 33#include "gki.h" 34#include "nci_hmsgs.h" 35#include "nfc_api.h" 36#include "nfc_int.h" 37#include "rw_api.h" 38#include "rw_int.h" 39 40using android::base::StringPrintf; 41 42extern bool nfc_debug_enabled; 43 44/* Static local functions */ 45static void rw_t2t_proc_data(uint8_t conn_id, tNFC_DATA_CEVT* p_data); 46static tNFC_STATUS rw_t2t_send_cmd(uint8_t opcode, uint8_t* p_dat); 47static void rw_t2t_process_error(void); 48static void rw_t2t_process_frame_error(void); 49static void rw_t2t_handle_presence_check_rsp(tNFC_STATUS status); 50static void rw_t2t_resume_op(void); 51 52static std::string rw_t2t_get_state_name(uint8_t state); 53static std::string rw_t2t_get_substate_name(uint8_t substate); 54 55/******************************************************************************* 56** 57** Function rw_t2t_proc_data 58** 59** Description This function handles data evt received from NFC Controller. 60** 61** Returns none 62** 63*******************************************************************************/ 64static void rw_t2t_proc_data(uint8_t conn_id, tNFC_DATA_CEVT* p_data) { 65 tRW_EVENT rw_event = RW_RAW_FRAME_EVT; 66 tRW_T2T_CB* p_t2t = &rw_cb.tcb.t2t; 67 NFC_HDR* p_pkt = p_data->p_data; 68 bool b_notify = true; 69 bool b_release = true; 70 uint8_t* p; 71 tRW_READ_DATA evt_data = {}; 72 tT2T_CMD_RSP_INFO* p_cmd_rsp_info = 73 (tT2T_CMD_RSP_INFO*)rw_cb.tcb.t2t.p_cmd_rsp_info; 74 tRW_DETECT_NDEF_DATA ndef_data; 75 uint8_t begin_state = p_t2t->state; 76 77 if ((p_t2t->state == RW_T2T_STATE_IDLE) || (p_cmd_rsp_info == NULL)) { 78 DLOG_IF(INFO, nfc_debug_enabled) 79 << StringPrintf("RW T2T Raw Frame: Len [0x%X] Status [%s]", p_pkt->len, 80 NFC_GetStatusName(p_data->status).c_str()); 81 evt_data.status = p_data->status; 82 evt_data.p_data = p_pkt; 83 tRW_DATA rw_data; 84 rw_data.data = evt_data; 85 (*rw_cb.p_cback)(RW_T2T_RAW_FRAME_EVT, &rw_data); 86 return; 87 } 88#if (RW_STATS_INCLUDED == TRUE) 89 /* Update rx stats */ 90 rw_main_update_rx_stats(p_pkt->len); 91#endif 92 /* Stop timer as response is received */ 93 nfc_stop_quick_timer(&p_t2t->t2_timer); 94 95 DLOG_IF(INFO, nfc_debug_enabled) 96 << StringPrintf("RW RECV [%s]:0x%x RSP", t2t_info_to_str(p_cmd_rsp_info), 97 p_cmd_rsp_info->opcode); 98 99 if (((p_pkt->len != p_cmd_rsp_info->rsp_len) && 100 (p_pkt->len != p_cmd_rsp_info->nack_rsp_len) && 101 (p_t2t->substate != RW_T2T_SUBSTATE_WAIT_SELECT_SECTOR)) || 102 (p_t2t->state == RW_T2T_STATE_HALT)) { 103 LOG(ERROR) << StringPrintf("T2T Frame error. state=%s ", 104 rw_t2t_get_state_name(p_t2t->state).c_str()); 105 if (p_t2t->state != RW_T2T_STATE_HALT) { 106 /* Retrasmit the last sent command if retry-count < max retry */ 107 rw_t2t_process_frame_error(); 108 p_t2t->check_tag_halt = false; 109 } 110 GKI_freebuf(p_pkt); 111 return; 112 } 113 rw_cb.cur_retry = 0; 114 115 /* Assume the data is just the response byte sequence */ 116 p = (uint8_t*)(p_pkt + 1) + p_pkt->offset; 117 118 DLOG_IF(INFO, nfc_debug_enabled) << StringPrintf( 119 "rw_t2t_proc_data State: %u conn_id: %u len: %u data[0]: 0x%02x", 120 p_t2t->state, conn_id, p_pkt->len, *p); 121 122 evt_data.p_data = NULL; 123 124 if (p_t2t->substate == RW_T2T_SUBSTATE_WAIT_SELECT_SECTOR_SUPPORT) { 125 /* The select process happens in two steps */ 126 if ((*p & 0x0f) == T2T_RSP_ACK) { 127 if (rw_t2t_sector_change(p_t2t->select_sector) == NFC_STATUS_OK) 128 b_notify = false; 129 else 130 evt_data.status = NFC_STATUS_FAILED; 131 } else { 132 DLOG_IF(INFO, nfc_debug_enabled) << StringPrintf( 133 "rw_t2t_proc_data - Received NACK response(0x%x) to SEC-SELCT CMD", 134 (*p & 0x0f)); 135 evt_data.status = NFC_STATUS_REJECTED; 136 } 137 } else if (p_t2t->substate == RW_T2T_SUBSTATE_WAIT_SELECT_SECTOR) { 138 evt_data.status = NFC_STATUS_FAILED; 139 } else if ((p_pkt->len != p_cmd_rsp_info->rsp_len) || 140 ((p_cmd_rsp_info->opcode == T2T_CMD_WRITE) && 141 ((*p & 0x0f) != T2T_RSP_ACK))) { 142 /* Received NACK response */ 143 evt_data.p_data = p_pkt; 144 if (p_t2t->state == RW_T2T_STATE_READ) b_release = false; 145 146 DLOG_IF(INFO, nfc_debug_enabled) << StringPrintf( 147 "rw_t2t_proc_data - Received NACK response(0x%x)", (*p & 0x0f)); 148 149 if (!p_t2t->check_tag_halt) { 150 /* Just received first NACK. Retry just one time to find if tag went in to 151 * HALT State */ 152 b_notify = false; 153 rw_t2t_process_error(); 154 /* Assume Tag is in HALT State, untill we get response to retry command */ 155 p_t2t->check_tag_halt = true; 156 } else { 157 p_t2t->check_tag_halt = false; 158 /* Got consecutive NACK so tag not really halt after first NACK, but 159 * current operation failed */ 160 evt_data.status = NFC_STATUS_FAILED; 161 } 162 } else { 163 /* If the response length indicates positive response or cannot be known 164 * from length then assume success */ 165 evt_data.status = NFC_STATUS_OK; 166 p_t2t->check_tag_halt = false; 167 168 /* The response data depends on what the current operation was */ 169 switch (p_t2t->state) { 170 case RW_T2T_STATE_CHECK_PRESENCE: 171 b_notify = false; 172 rw_t2t_handle_presence_check_rsp(NFC_STATUS_OK); 173 break; 174 175 case RW_T2T_STATE_READ: 176 evt_data.p_data = p_pkt; 177 b_release = false; 178 if (p_t2t->block_read == 0) { 179 p_t2t->b_read_hdr = true; 180 memcpy(p_t2t->tag_hdr, p, T2T_READ_DATA_LEN); 181 } 182 break; 183 184 case RW_T2T_STATE_WRITE: 185 /* Write operation completed successfully */ 186 break; 187 188 default: 189 /* NDEF/other Tlv Operation/Format-Tag/Config Tag as Read only */ 190 b_notify = false; 191 rw_t2t_handle_rsp(p); 192 break; 193 } 194 } 195 196 if (b_notify) { 197 rw_event = rw_t2t_info_to_event(p_cmd_rsp_info); 198 199 if (rw_event == RW_T2T_NDEF_DETECT_EVT) { 200 ndef_data.status = evt_data.status; 201 ndef_data.protocol = NFC_PROTOCOL_T2T; 202 ndef_data.flags = RW_NDEF_FL_UNKNOWN; 203 if (p_t2t->substate == RW_T2T_SUBSTATE_WAIT_READ_LOCKS) 204 ndef_data.flags = RW_NDEF_FL_FORMATED; 205 ndef_data.max_size = 0; 206 ndef_data.cur_size = 0; 207 /* Move back to idle state */ 208 rw_t2t_handle_op_complete(); 209 tRW_DATA rw_data; 210 rw_data.ndef = ndef_data; 211 (*rw_cb.p_cback)(rw_event, &rw_data); 212 } else { 213 /* Move back to idle state */ 214 rw_t2t_handle_op_complete(); 215 tRW_DATA rw_data; 216 rw_data.data = evt_data; 217 (*rw_cb.p_cback)(rw_event, &rw_data); 218 } 219 } 220 221 if (b_release) GKI_freebuf(p_pkt); 222 223 if (begin_state != p_t2t->state) { 224 DLOG_IF(INFO, nfc_debug_enabled) 225 << StringPrintf("RW T2T state changed:<%s> -> <%s>", 226 rw_t2t_get_state_name(begin_state).c_str(), 227 rw_t2t_get_state_name(p_t2t->state).c_str()); 228 } 229} 230 231/******************************************************************************* 232** 233** Function rw_t2t_conn_cback 234** 235** Description This callback function receives events/data from NFCC. 236** 237** Returns none 238** 239*******************************************************************************/ 240void rw_t2t_conn_cback(uint8_t conn_id, tNFC_CONN_EVT event, 241 tNFC_CONN* p_data) { 242 tRW_T2T_CB* p_t2t = &rw_cb.tcb.t2t; 243 tRW_READ_DATA evt_data; 244 245 DLOG_IF(INFO, nfc_debug_enabled) 246 << StringPrintf("rw_t2t_conn_cback: conn_id=%i, evt=%i", conn_id, event); 247 /* Only handle static conn_id */ 248 if (conn_id != NFC_RF_CONN_ID) { 249 return; 250 } 251 252 switch (event) { 253 case NFC_CONN_CREATE_CEVT: 254 case NFC_CONN_CLOSE_CEVT: 255 break; 256 257 case NFC_DEACTIVATE_CEVT: 258#if (RW_STATS_INCLUDED == TRUE) 259 /* Display stats */ 260 rw_main_log_stats(); 261#endif 262 /* Stop t2t timer (if started) */ 263 nfc_stop_quick_timer(&p_t2t->t2_timer); 264 265 /* Free cmd buf for retransmissions */ 266 if (p_t2t->p_cur_cmd_buf) { 267 GKI_freebuf(p_t2t->p_cur_cmd_buf); 268 p_t2t->p_cur_cmd_buf = NULL; 269 } 270 /* Free cmd buf used to hold command before sector change */ 271 if (p_t2t->p_sec_cmd_buf) { 272 GKI_freebuf(p_t2t->p_sec_cmd_buf); 273 p_t2t->p_sec_cmd_buf = NULL; 274 } 275 276 p_t2t->state = RW_T2T_STATE_NOT_ACTIVATED; 277 NFC_SetStaticRfCback(NULL); 278 break; 279 280 case NFC_DATA_CEVT: 281 if (p_data != NULL) { 282 if ((p_data->data.status == NFC_STATUS_OK) || 283 (p_data->data.status == NFC_STATUS_CONTINUE)) { 284 rw_t2t_proc_data(conn_id, &(p_data->data)); 285 break; 286 } else if (p_data->data.p_data != NULL) { 287 /* Free the response buffer in case of error response */ 288 GKI_freebuf((NFC_HDR*)(p_data->data.p_data)); 289 p_data->data.p_data = NULL; 290 } 291 } 292 /* Data event with error status...fall through to NFC_ERROR_CEVT case */ 293 294 case NFC_ERROR_CEVT: 295 if ((p_t2t->state == RW_T2T_STATE_NOT_ACTIVATED) || 296 (p_t2t->state == RW_T2T_STATE_IDLE) || 297 (p_t2t->state == RW_T2T_STATE_HALT)) { 298#if (RW_STATS_INCLUDED == TRUE) 299 rw_main_update_trans_error_stats(); 300#endif /* RW_STATS_INCLUDED */ 301 if (event == NFC_ERROR_CEVT) 302 evt_data.status = (tNFC_STATUS)(*(uint8_t*)p_data); 303 else if (p_data) 304 evt_data.status = p_data->status; 305 else 306 evt_data.status = NFC_STATUS_FAILED; 307 308 evt_data.p_data = NULL; 309 tRW_DATA rw_data; 310 rw_data.data = evt_data; 311 (*rw_cb.p_cback)(RW_T2T_INTF_ERROR_EVT, &rw_data); 312 break; 313 } 314 nfc_stop_quick_timer(&p_t2t->t2_timer); 315#if (RW_STATS_INCLUDED == TRUE) 316 rw_main_update_trans_error_stats(); 317#endif 318 if (p_t2t->state == RW_T2T_STATE_CHECK_PRESENCE) { 319 if (p_t2t->check_tag_halt) { 320 p_t2t->state = RW_T2T_STATE_HALT; 321 rw_t2t_handle_presence_check_rsp(NFC_STATUS_REJECTED); 322 } else { 323 /* Move back to idle state */ 324 rw_t2t_handle_presence_check_rsp(NFC_STATUS_FAILED); 325 } 326 } else { 327 rw_t2t_process_error(); 328 } 329 break; 330 331 default: 332 break; 333 } 334} 335 336/******************************************************************************* 337** 338** Function rw_t2t_send_cmd 339** 340** Description This function composes a Type 2 Tag command and send it via 341** NCI to NFCC. 342** 343** Returns NFC_STATUS_OK if the command is successfuly sent to NCI 344** otherwise, error status 345** 346*******************************************************************************/ 347tNFC_STATUS rw_t2t_send_cmd(uint8_t opcode, uint8_t* p_dat) { 348 tNFC_STATUS status = NFC_STATUS_FAILED; 349 tRW_T2T_CB* p_t2t = &rw_cb.tcb.t2t; 350 const tT2T_CMD_RSP_INFO* p_cmd_rsp_info = t2t_cmd_to_rsp_info(opcode); 351 NFC_HDR* p_data; 352 uint8_t* p; 353 354 if (p_cmd_rsp_info) { 355 /* a valid opcode for RW */ 356 p_data = (NFC_HDR*)GKI_getpoolbuf(NFC_RW_POOL_ID); 357 if (p_data) { 358 p_t2t->p_cmd_rsp_info = (tT2T_CMD_RSP_INFO*)p_cmd_rsp_info; 359 p_data->offset = NCI_MSG_OFFSET_SIZE + NCI_DATA_HDR_SIZE; 360 p = (uint8_t*)(p_data + 1) + p_data->offset; 361 362 UINT8_TO_STREAM(p, opcode); 363 364 if (p_dat) { 365 ARRAY_TO_STREAM(p, p_dat, (p_cmd_rsp_info->cmd_len - 1)); 366 } 367 368 p_data->len = p_cmd_rsp_info->cmd_len; 369 370 /* Indicate first attempt to send command, back up cmd buffer in case 371 * needed for retransmission */ 372 rw_cb.cur_retry = 0; 373 memcpy(p_t2t->p_cur_cmd_buf, p_data, 374 sizeof(NFC_HDR) + p_data->offset + p_data->len); 375 376#if (RW_STATS_INCLUDED == TRUE) 377 /* Update stats */ 378 rw_main_update_tx_stats(p_data->len, false); 379#endif 380 DLOG_IF(INFO, nfc_debug_enabled) << StringPrintf( 381 "RW SENT [%s]:0x%x CMD", t2t_info_to_str(p_cmd_rsp_info), 382 p_cmd_rsp_info->opcode); 383 384 status = NFC_SendData(NFC_RF_CONN_ID, p_data); 385 if (status == NFC_STATUS_OK) { 386 nfc_start_quick_timer( 387 &p_t2t->t2_timer, NFC_TTYPE_RW_T2T_RESPONSE, 388 (RW_T2T_TOUT_RESP * QUICK_TIMER_TICKS_PER_SEC) / 1000); 389 } else { 390 LOG(ERROR) << StringPrintf( 391 "T2T NFC Send data failed. state=%s substate=%s ", 392 rw_t2t_get_state_name(p_t2t->state).c_str(), 393 rw_t2t_get_substate_name(p_t2t->substate).c_str()); 394 } 395 } else { 396 status = NFC_STATUS_NO_BUFFERS; 397 } 398 } 399 return status; 400} 401 402/******************************************************************************* 403** 404** Function rw_t2t_process_timeout 405** 406** Description handles timeout event 407** 408** Returns none 409** 410*******************************************************************************/ 411void rw_t2t_process_timeout() { 412 tRW_READ_DATA evt_data; 413 tRW_T2T_CB* p_t2t = &rw_cb.tcb.t2t; 414 415 if (p_t2t->state == RW_T2T_STATE_CHECK_PRESENCE) { 416 if (p_t2t->check_tag_halt) { 417 p_t2t->state = RW_T2T_STATE_HALT; 418 rw_t2t_handle_presence_check_rsp(NFC_STATUS_REJECTED); 419 } else { 420 /* Move back to idle state */ 421 rw_t2t_handle_presence_check_rsp(NFC_STATUS_FAILED); 422 } 423 return; 424 } 425 426 if (p_t2t->substate == RW_T2T_SUBSTATE_WAIT_SELECT_SECTOR) { 427 p_t2t->sector = p_t2t->select_sector; 428 /* Here timeout is an acknowledgment for successfull sector change */ 429 if (p_t2t->state == RW_T2T_STATE_SELECT_SECTOR) { 430 /* Notify that select sector op is successfull */ 431 rw_t2t_handle_op_complete(); 432 evt_data.status = NFC_STATUS_OK; 433 evt_data.p_data = NULL; 434 tRW_DATA rw_data; 435 rw_data.data = evt_data; 436 (*rw_cb.p_cback)(RW_T2T_SELECT_CPLT_EVT, &rw_data); 437 } else { 438 /* Resume operation from where we stopped before sector change */ 439 rw_t2t_resume_op(); 440 } 441 } else if (p_t2t->state != RW_T2T_STATE_IDLE) { 442 LOG(ERROR) << StringPrintf("T2T timeout. state=%s ", 443 rw_t2t_get_state_name(p_t2t->state).c_str()); 444 /* Handle timeout error as no response to the command sent */ 445 rw_t2t_process_error(); 446 } 447} 448 449/******************************************************************************* 450** 451** Function rw_t2t_process_frame_error 452** 453** Description handles frame crc error 454** 455** Returns none 456** 457*******************************************************************************/ 458static void rw_t2t_process_frame_error(void) { 459#if (RW_STATS_INCLUDED == TRUE) 460 /* Update stats */ 461 rw_main_update_crc_error_stats(); 462#endif 463 /* Process the error */ 464 rw_t2t_process_error(); 465} 466 467/******************************************************************************* 468** 469** Function rw_t2t_process_error 470** 471** Description Process error including Timeout, Frame error. This function 472** will retry atleast till RW_MAX_RETRIES before give up and 473** sending negative notification to upper layer 474** 475** Returns none 476** 477*******************************************************************************/ 478static void rw_t2t_process_error(void) { 479 tRW_READ_DATA evt_data; 480 tRW_EVENT rw_event; 481 NFC_HDR* p_cmd_buf; 482 tRW_T2T_CB* p_t2t = &rw_cb.tcb.t2t; 483 tT2T_CMD_RSP_INFO* p_cmd_rsp_info = 484 (tT2T_CMD_RSP_INFO*)rw_cb.tcb.t2t.p_cmd_rsp_info; 485 tRW_DETECT_NDEF_DATA ndef_data; 486 487 DLOG_IF(INFO, nfc_debug_enabled) << StringPrintf("State: %u", p_t2t->state); 488 489 /* Retry sending command if retry-count < max */ 490 if ((!p_t2t->check_tag_halt) && (rw_cb.cur_retry < RW_MAX_RETRIES)) { 491 /* retry sending the command */ 492 rw_cb.cur_retry++; 493 494 DLOG_IF(INFO, nfc_debug_enabled) << StringPrintf( 495 "T2T retransmission attempt %i of %i", rw_cb.cur_retry, RW_MAX_RETRIES); 496 497 /* allocate a new buffer for message */ 498 p_cmd_buf = (NFC_HDR*)GKI_getpoolbuf(NFC_RW_POOL_ID); 499 if (p_cmd_buf != NULL) { 500 memcpy(p_cmd_buf, p_t2t->p_cur_cmd_buf, sizeof(NFC_HDR) + 501 p_t2t->p_cur_cmd_buf->offset + 502 p_t2t->p_cur_cmd_buf->len); 503#if (RW_STATS_INCLUDED == TRUE) 504 /* Update stats */ 505 rw_main_update_tx_stats(p_cmd_buf->len, true); 506#endif 507 if (NFC_SendData(NFC_RF_CONN_ID, p_cmd_buf) == NFC_STATUS_OK) { 508 /* Start timer for waiting for response */ 509 nfc_start_quick_timer( 510 &p_t2t->t2_timer, NFC_TTYPE_RW_T2T_RESPONSE, 511 (RW_T2T_TOUT_RESP * QUICK_TIMER_TICKS_PER_SEC) / 1000); 512 513 return; 514 } 515 } 516 } else { 517 if (p_t2t->check_tag_halt) { 518 DLOG_IF(INFO, nfc_debug_enabled) 519 << StringPrintf("T2T Went to HALT State!"); 520 } else { 521 DLOG_IF(INFO, nfc_debug_enabled) << StringPrintf( 522 "T2T maximum retransmission attempts reached (%i)", RW_MAX_RETRIES); 523 } 524 } 525 rw_event = rw_t2t_info_to_event(p_cmd_rsp_info); 526#if (RW_STATS_INCLUDED == TRUE) 527 /* update failure count */ 528 rw_main_update_fail_stats(); 529#endif 530 if (p_t2t->check_tag_halt) { 531 evt_data.status = NFC_STATUS_REJECTED; 532 p_t2t->state = RW_T2T_STATE_HALT; 533 } else { 534 evt_data.status = NFC_STATUS_TIMEOUT; 535 } 536 537 if (rw_event == RW_T2T_NDEF_DETECT_EVT) { 538 ndef_data.status = evt_data.status; 539 ndef_data.protocol = NFC_PROTOCOL_T2T; 540 ndef_data.flags = RW_NDEF_FL_UNKNOWN; 541 if (p_t2t->substate == RW_T2T_SUBSTATE_WAIT_READ_LOCKS) 542 ndef_data.flags = RW_NDEF_FL_FORMATED; 543 ndef_data.max_size = 0; 544 ndef_data.cur_size = 0; 545 /* If not Halt move to idle state */ 546 rw_t2t_handle_op_complete(); 547 548 tRW_DATA rw_data; 549 rw_data.ndef = ndef_data; 550 (*rw_cb.p_cback)(rw_event, &rw_data); 551 } else { 552 evt_data.p_data = NULL; 553 /* If activated and not Halt move to idle state */ 554 if (p_t2t->state != RW_T2T_STATE_NOT_ACTIVATED) rw_t2t_handle_op_complete(); 555 556 p_t2t->substate = RW_T2T_SUBSTATE_NONE; 557 tRW_DATA rw_data; 558 rw_data.data = evt_data; 559 (*rw_cb.p_cback)(rw_event, &rw_data); 560 } 561} 562 563/***************************************************************************** 564** 565** Function rw_t2t_handle_presence_check_rsp 566** 567** Description Handle response to presence check 568** 569** Returns Nothing 570** 571*****************************************************************************/ 572void rw_t2t_handle_presence_check_rsp(tNFC_STATUS status) { 573 tRW_DATA rw_data; 574 575 /* Notify, Tag is present or not */ 576 rw_data.data.status = status; 577 rw_t2t_handle_op_complete(); 578 579 (*rw_cb.p_cback)(RW_T2T_PRESENCE_CHECK_EVT, &rw_data); 580} 581 582/******************************************************************************* 583** 584** Function rw_t2t_resume_op 585** 586** Description This function will continue operation after moving to new 587** sector 588** 589** Returns tNFC_STATUS 590** 591*******************************************************************************/ 592static void rw_t2t_resume_op(void) { 593 tRW_T2T_CB* p_t2t = &rw_cb.tcb.t2t; 594 tRW_READ_DATA evt_data; 595 NFC_HDR* p_cmd_buf; 596 tRW_EVENT event; 597 const tT2T_CMD_RSP_INFO* p_cmd_rsp_info = 598 (tT2T_CMD_RSP_INFO*)rw_cb.tcb.t2t.p_cmd_rsp_info; 599 uint8_t* p; 600 601 /* Move back to the substate where we were before changing sector */ 602 p_t2t->substate = p_t2t->prev_substate; 603 604 p = (uint8_t*)(p_t2t->p_sec_cmd_buf + 1) + p_t2t->p_sec_cmd_buf->offset; 605 p_cmd_rsp_info = t2t_cmd_to_rsp_info((uint8_t)*p); 606 p_t2t->p_cmd_rsp_info = (tT2T_CMD_RSP_INFO*)p_cmd_rsp_info; 607 608 /* allocate a new buffer for message */ 609 p_cmd_buf = (NFC_HDR*)GKI_getpoolbuf(NFC_RW_POOL_ID); 610 if (p_cmd_buf != NULL) { 611 memcpy(p_cmd_buf, p_t2t->p_sec_cmd_buf, sizeof(NFC_HDR) + 612 p_t2t->p_sec_cmd_buf->offset + 613 p_t2t->p_sec_cmd_buf->len); 614 memcpy(p_t2t->p_cur_cmd_buf, p_t2t->p_sec_cmd_buf, 615 sizeof(NFC_HDR) + p_t2t->p_sec_cmd_buf->offset + 616 p_t2t->p_sec_cmd_buf->len); 617 618#if (RW_STATS_INCLUDED == TRUE) 619 /* Update stats */ 620 rw_main_update_tx_stats(p_cmd_buf->len, true); 621#endif 622 if (NFC_SendData(NFC_RF_CONN_ID, p_cmd_buf) == NFC_STATUS_OK) { 623 /* Start timer for waiting for response */ 624 nfc_start_quick_timer( 625 &p_t2t->t2_timer, NFC_TTYPE_RW_T2T_RESPONSE, 626 (RW_T2T_TOUT_RESP * QUICK_TIMER_TICKS_PER_SEC) / 1000); 627 } else { 628 /* failure - could not send buffer */ 629 evt_data.p_data = NULL; 630 evt_data.status = NFC_STATUS_FAILED; 631 event = rw_t2t_info_to_event(p_cmd_rsp_info); 632 rw_t2t_handle_op_complete(); 633 tRW_DATA rw_data; 634 rw_data.data = evt_data; 635 (*rw_cb.p_cback)(event, &rw_data); 636 } 637 } 638} 639 640/******************************************************************************* 641** 642** Function rw_t2t_sector_change 643** 644** Description This function issues Type 2 Tag SECTOR-SELECT command 645** packet 1. 646** 647** Returns tNFC_STATUS 648** 649*******************************************************************************/ 650tNFC_STATUS rw_t2t_sector_change(uint8_t sector) { 651 tNFC_STATUS status; 652 NFC_HDR* p_data; 653 uint8_t* p; 654 tRW_T2T_CB* p_t2t = &rw_cb.tcb.t2t; 655 656 p_data = (NFC_HDR*)GKI_getpoolbuf(NFC_RW_POOL_ID); 657 if (p_data == NULL) { 658 LOG(ERROR) << StringPrintf("rw_t2t_sector_change - No buffer"); 659 return (NFC_STATUS_NO_BUFFERS); 660 } 661 662 p_data->offset = NCI_MSG_OFFSET_SIZE + NCI_DATA_HDR_SIZE; 663 p = (uint8_t*)(p_data + 1) + p_data->offset; 664 665 UINT8_TO_BE_STREAM(p, sector); 666 UINT8_TO_BE_STREAM(p, 0x00); 667 UINT8_TO_BE_STREAM(p, 0x00); 668 UINT8_TO_BE_STREAM(p, 0x00); 669 670 p_data->len = 4; 671 672 status = NFC_SendData(NFC_RF_CONN_ID, p_data); 673 if (status == NFC_STATUS_OK) { 674 /* Passive rsp command and suppose not to get response to this command */ 675 p_t2t->p_cmd_rsp_info = NULL; 676 p_t2t->substate = RW_T2T_SUBSTATE_WAIT_SELECT_SECTOR; 677 678 DLOG_IF(INFO, nfc_debug_enabled) 679 << StringPrintf("rw_t2t_sector_change Sent Second Command"); 680 nfc_start_quick_timer( 681 &p_t2t->t2_timer, NFC_TTYPE_RW_T2T_RESPONSE, 682 (RW_T2T_SEC_SEL_TOUT_RESP * QUICK_TIMER_TICKS_PER_SEC) / 1000); 683 } else { 684 LOG(ERROR) << StringPrintf( 685 "rw_t2t_sector_change Send failed at rw_t2t_send_cmd, error: %u", 686 status); 687 } 688 689 return status; 690} 691 692/******************************************************************************* 693** 694** Function rw_t2t_read 695** 696** Description This function issues Type 2 Tag READ command for the 697** specified block. If the specified block is in different 698** sector then it first sends command to move to new sector 699** and after the tag moves to new sector it issues the read 700** command for the block. 701** 702** Returns tNFC_STATUS 703** 704*******************************************************************************/ 705tNFC_STATUS rw_t2t_read(uint16_t block) { 706 tNFC_STATUS status; 707 uint8_t* p; 708 tRW_T2T_CB* p_t2t = &rw_cb.tcb.t2t; 709 uint8_t sector_byte2[1]; 710 uint8_t read_cmd[1]; 711 712 read_cmd[0] = block % T2T_BLOCKS_PER_SECTOR; 713 if (p_t2t->sector != block / T2T_BLOCKS_PER_SECTOR) { 714 sector_byte2[0] = 0xFF; 715 /* First Move to new sector before sending Read command */ 716 status = rw_t2t_send_cmd(T2T_CMD_SEC_SEL, sector_byte2); 717 if (status == NFC_STATUS_OK) { 718 /* Prepare command that needs to be sent after sector change op is 719 * completed */ 720 p_t2t->select_sector = (uint8_t)(block / T2T_BLOCKS_PER_SECTOR); 721 p_t2t->p_sec_cmd_buf->offset = NCI_MSG_OFFSET_SIZE + NCI_DATA_HDR_SIZE; 722 723 p = (uint8_t*)(p_t2t->p_sec_cmd_buf + 1) + p_t2t->p_sec_cmd_buf->offset; 724 UINT8_TO_BE_STREAM(p, T2T_CMD_READ); 725 UINT8_TO_BE_STREAM(p, read_cmd[0]); 726 p_t2t->p_sec_cmd_buf->len = 2; 727 p_t2t->block_read = block; 728 729 /* Backup the current substate to move back to this substate after 730 * changing sector */ 731 p_t2t->prev_substate = p_t2t->substate; 732 p_t2t->substate = RW_T2T_SUBSTATE_WAIT_SELECT_SECTOR_SUPPORT; 733 return NFC_STATUS_OK; 734 } 735 return NFC_STATUS_FAILED; 736 } 737 738 /* Send Read command as sector change is not needed */ 739 status = rw_t2t_send_cmd(T2T_CMD_READ, (uint8_t*)read_cmd); 740 if (status == NFC_STATUS_OK) { 741 p_t2t->block_read = block; 742 DLOG_IF(INFO, nfc_debug_enabled) 743 << StringPrintf("rw_t2t_read Sent Command for Block: %u", block); 744 } 745 746 return status; 747} 748 749/******************************************************************************* 750** 751** Function rw_t2t_write 752** 753** Description This function issues Type 2 Tag WRITE command for the 754** specified block. If the specified block is in different 755** sector then it first sends command to move to new sector 756** and after the tag moves to new sector it issues the write 757** command for the block. 758** 759** Returns tNFC_STATUS 760** 761*******************************************************************************/ 762tNFC_STATUS rw_t2t_write(uint16_t block, uint8_t* p_write_data) { 763 tNFC_STATUS status; 764 uint8_t* p; 765 tRW_T2T_CB* p_t2t = &rw_cb.tcb.t2t; 766 uint8_t write_cmd[T2T_WRITE_DATA_LEN + 1]; 767 uint8_t sector_byte2[1]; 768 769 p_t2t->block_written = block; 770 write_cmd[0] = (uint8_t)(block % T2T_BLOCKS_PER_SECTOR); 771 memcpy(&write_cmd[1], p_write_data, T2T_WRITE_DATA_LEN); 772 773 if (p_t2t->sector != block / T2T_BLOCKS_PER_SECTOR) { 774 sector_byte2[0] = 0xFF; 775 /* First Move to new sector before sending Write command */ 776 status = rw_t2t_send_cmd(T2T_CMD_SEC_SEL, sector_byte2); 777 if (status == NFC_STATUS_OK) { 778 /* Prepare command that needs to be sent after sector change op is 779 * completed */ 780 p_t2t->select_sector = (uint8_t)(block / T2T_BLOCKS_PER_SECTOR); 781 p_t2t->p_sec_cmd_buf->offset = NCI_MSG_OFFSET_SIZE + NCI_DATA_HDR_SIZE; 782 p = (uint8_t*)(p_t2t->p_sec_cmd_buf + 1) + p_t2t->p_sec_cmd_buf->offset; 783 UINT8_TO_BE_STREAM(p, T2T_CMD_WRITE); 784 memcpy(p, write_cmd, T2T_WRITE_DATA_LEN + 1); 785 p_t2t->p_sec_cmd_buf->len = 2 + T2T_WRITE_DATA_LEN; 786 p_t2t->block_written = block; 787 788 /* Backup the current substate to move back to this substate after 789 * changing sector */ 790 p_t2t->prev_substate = p_t2t->substate; 791 p_t2t->substate = RW_T2T_SUBSTATE_WAIT_SELECT_SECTOR_SUPPORT; 792 return NFC_STATUS_OK; 793 } 794 return NFC_STATUS_FAILED; 795 } 796 797 /* Send Write command as sector change is not needed */ 798 status = rw_t2t_send_cmd(T2T_CMD_WRITE, write_cmd); 799 if (status == NFC_STATUS_OK) { 800 DLOG_IF(INFO, nfc_debug_enabled) 801 << StringPrintf("rw_t2t_write Sent Command for Block: %u", block); 802 } 803 804 return status; 805} 806 807/******************************************************************************* 808** 809** Function rw_t2t_select 810** 811** Description This function selects type 2 tag. 812** 813** Returns Tag selection status 814** 815*******************************************************************************/ 816tNFC_STATUS rw_t2t_select(void) { 817 tRW_T2T_CB* p_t2t = &rw_cb.tcb.t2t; 818 819 p_t2t->state = RW_T2T_STATE_IDLE; 820 p_t2t->ndef_status = T2T_NDEF_NOT_DETECTED; 821 822 /* Alloc cmd buf for retransmissions */ 823 if (p_t2t->p_cur_cmd_buf == NULL) { 824 p_t2t->p_cur_cmd_buf = (NFC_HDR*)GKI_getpoolbuf(NFC_RW_POOL_ID); 825 if (p_t2t->p_cur_cmd_buf == NULL) { 826 LOG(ERROR) << StringPrintf( 827 "rw_t2t_select: unable to allocate buffer for retransmission"); 828 return (NFC_STATUS_FAILED); 829 } 830 } 831 /* Alloc cmd buf for holding a command untill sector changes */ 832 if (p_t2t->p_sec_cmd_buf == NULL) { 833 p_t2t->p_sec_cmd_buf = (NFC_HDR*)GKI_getpoolbuf(NFC_RW_POOL_ID); 834 if (p_t2t->p_sec_cmd_buf == NULL) { 835 LOG(ERROR) << StringPrintf( 836 "rw_t2t_select: unable to allocate buffer used during sector change"); 837 return (NFC_STATUS_FAILED); 838 } 839 } 840 841 NFC_SetStaticRfCback(rw_t2t_conn_cback); 842 rw_t2t_handle_op_complete(); 843 p_t2t->check_tag_halt = false; 844 845 return NFC_STATUS_OK; 846} 847 848/***************************************************************************** 849** 850** Function rw_t2t_handle_op_complete 851** 852** Description Reset to IDLE state 853** 854** Returns Nothing 855** 856*****************************************************************************/ 857void rw_t2t_handle_op_complete(void) { 858 tRW_T2T_CB* p_t2t = &rw_cb.tcb.t2t; 859 860 if ((p_t2t->state == RW_T2T_STATE_READ_NDEF) || 861 (p_t2t->state == RW_T2T_STATE_WRITE_NDEF)) { 862 p_t2t->b_read_data = false; 863 } 864 865 if (p_t2t->state != RW_T2T_STATE_HALT) p_t2t->state = RW_T2T_STATE_IDLE; 866 p_t2t->substate = RW_T2T_SUBSTATE_NONE; 867 return; 868} 869 870/***************************************************************************** 871** 872** Function RW_T2tPresenceCheck 873** 874** Description 875** Check if the tag is still in the field. 876** 877** The RW_T2T_PRESENCE_CHECK_EVT w/ status is used to indicate presence 878** or non-presence. 879** 880** Returns 881** NFC_STATUS_OK, if raw data frame sent 882** NFC_STATUS_NO_BUFFERS: unable to allocate a buffer for this operation 883** NFC_STATUS_FAILED: other error 884** 885*****************************************************************************/ 886tNFC_STATUS RW_T2tPresenceCheck(void) { 887 tNFC_STATUS retval = NFC_STATUS_OK; 888 tRW_DATA evt_data; 889 tRW_CB* p_rw_cb = &rw_cb; 890 uint8_t sector_blk = 0; /* block 0 of current sector */ 891 892 DLOG_IF(INFO, nfc_debug_enabled) << __func__; 893 894 /* If RW_SelectTagType was not called (no conn_callback) return failure */ 895 if (!p_rw_cb->p_cback) { 896 retval = NFC_STATUS_FAILED; 897 } 898 /* If we are not activated, then RW_T2T_PRESENCE_CHECK_EVT status=FAIL */ 899 else if (p_rw_cb->tcb.t2t.state == RW_T2T_STATE_NOT_ACTIVATED) { 900 evt_data.status = NFC_STATUS_FAILED; 901 (*p_rw_cb->p_cback)(RW_T2T_PRESENCE_CHECK_EVT, &evt_data); 902 } 903 /* If command is pending, assume tag is still present */ 904 else if (p_rw_cb->tcb.t2t.state != RW_T2T_STATE_IDLE) { 905 evt_data.status = NFC_STATUS_OK; 906 (*p_rw_cb->p_cback)(RW_T2T_PRESENCE_CHECK_EVT, &evt_data); 907 } else { 908 /* IDLE state: send a READ command to block 0 of the current sector */ 909 retval = rw_t2t_send_cmd(T2T_CMD_READ, §or_blk); 910 if (retval == NFC_STATUS_OK) { 911 p_rw_cb->tcb.t2t.state = RW_T2T_STATE_CHECK_PRESENCE; 912 } 913 } 914 915 return (retval); 916} 917 918/******************************************************************************* 919** 920** Function RW_T2tRead 921** 922** Description This function issues the Type 2 Tag READ command. When the 923** operation is complete the callback function will be called 924** with a RW_T2T_READ_EVT. 925** 926** Returns tNFC_STATUS 927** 928*******************************************************************************/ 929tNFC_STATUS RW_T2tRead(uint16_t block) { 930 tRW_T2T_CB* p_t2t = &rw_cb.tcb.t2t; 931 tNFC_STATUS status; 932 933 if (p_t2t->state != RW_T2T_STATE_IDLE) { 934 LOG(ERROR) << StringPrintf( 935 "Error: Type 2 tag not activated or Busy - State: %u", p_t2t->state); 936 return (NFC_STATUS_FAILED); 937 } 938 939 status = rw_t2t_read(block); 940 if (status == NFC_STATUS_OK) { 941 p_t2t->state = RW_T2T_STATE_READ; 942 DLOG_IF(INFO, nfc_debug_enabled) 943 << StringPrintf("RW_T2tRead Sent Read command"); 944 } 945 946 return status; 947} 948 949/******************************************************************************* 950** 951** Function RW_T2tWrite 952** 953** Description This function issues the Type 2 Tag WRITE command. When the 954** operation is complete the callback function will be called 955** with a RW_T2T_WRITE_EVT. 956** 957** p_new_bytes points to the array of 4 bytes to be written 958** 959** Returns tNFC_STATUS 960** 961*******************************************************************************/ 962tNFC_STATUS RW_T2tWrite(uint16_t block, uint8_t* p_write_data) { 963 tRW_T2T_CB* p_t2t = &rw_cb.tcb.t2t; 964 tNFC_STATUS status; 965 966 if (p_t2t->state != RW_T2T_STATE_IDLE) { 967 LOG(ERROR) << StringPrintf( 968 "Error: Type 2 tag not activated or Busy - State: %u", p_t2t->state); 969 return (NFC_STATUS_FAILED); 970 } 971 972 status = rw_t2t_write(block, p_write_data); 973 if (status == NFC_STATUS_OK) { 974 p_t2t->state = RW_T2T_STATE_WRITE; 975 if (block < T2T_FIRST_DATA_BLOCK) 976 p_t2t->b_read_hdr = false; 977 else if (block < (T2T_FIRST_DATA_BLOCK + T2T_READ_BLOCKS)) 978 p_t2t->b_read_data = false; 979 DLOG_IF(INFO, nfc_debug_enabled) 980 << StringPrintf("RW_T2tWrite Sent Write command"); 981 } 982 983 return status; 984} 985 986/******************************************************************************* 987** 988** Function RW_T2tSectorSelect 989** 990** Description This function issues the Type 2 Tag SECTOR-SELECT command 991** packet 1. If a NACK is received as the response, the 992** callback function will be called with a 993** RW_T2T_SECTOR_SELECT_EVT. If an ACK is received as the 994** response, the command packet 2 with the given sector number 995** is sent to the peer device. When the response for packet 2 996** is received, the callback function will be called with a 997** RW_T2T_SECTOR_SELECT_EVT. 998** 999** A sector is 256 contiguous blocks (1024 bytes). 1000** 1001** Returns tNFC_STATUS 1002** 1003*******************************************************************************/ 1004tNFC_STATUS RW_T2tSectorSelect(uint8_t sector) { 1005 tNFC_STATUS status; 1006 tRW_T2T_CB* p_t2t = &rw_cb.tcb.t2t; 1007 uint8_t sector_byte2[1]; 1008 1009 if (p_t2t->state != RW_T2T_STATE_IDLE) { 1010 LOG(ERROR) << StringPrintf( 1011 "Error: Type 2 tag not activated or Busy - State: %u", p_t2t->state); 1012 return (NFC_STATUS_FAILED); 1013 } 1014 1015 if (sector >= T2T_MAX_SECTOR) { 1016 LOG(ERROR) << StringPrintf( 1017 "RW_T2tSectorSelect - Invalid sector: %u, T2 Max supported sector " 1018 "value: %u", 1019 sector, T2T_MAX_SECTOR - 1); 1020 return (NFC_STATUS_FAILED); 1021 } 1022 1023 sector_byte2[0] = 0xFF; 1024 1025 status = rw_t2t_send_cmd(T2T_CMD_SEC_SEL, sector_byte2); 1026 if (status == NFC_STATUS_OK) { 1027 p_t2t->state = RW_T2T_STATE_SELECT_SECTOR; 1028 p_t2t->select_sector = sector; 1029 p_t2t->substate = RW_T2T_SUBSTATE_WAIT_SELECT_SECTOR_SUPPORT; 1030 1031 DLOG_IF(INFO, nfc_debug_enabled) 1032 << StringPrintf("RW_T2tSectorSelect Sent Sector select first command"); 1033 } 1034 1035 return status; 1036} 1037 1038/******************************************************************************* 1039** 1040** Function rw_t2t_get_state_name 1041** 1042** Description This function returns the state name. 1043** 1044** NOTE conditionally compiled to save memory. 1045** 1046** Returns string 1047** 1048*******************************************************************************/ 1049static std::string rw_t2t_get_state_name(uint8_t state) { 1050 switch (state) { 1051 case RW_T2T_STATE_NOT_ACTIVATED: 1052 return "NOT_ACTIVATED"; 1053 case RW_T2T_STATE_IDLE: 1054 return "IDLE"; 1055 case RW_T2T_STATE_READ: 1056 return "APP_READ"; 1057 case RW_T2T_STATE_WRITE: 1058 return "APP_WRITE"; 1059 case RW_T2T_STATE_SELECT_SECTOR: 1060 return "SECTOR_SELECT"; 1061 case RW_T2T_STATE_DETECT_TLV: 1062 return "TLV_DETECT"; 1063 case RW_T2T_STATE_READ_NDEF: 1064 return "READ_NDEF"; 1065 case RW_T2T_STATE_WRITE_NDEF: 1066 return "WRITE_NDEF"; 1067 case RW_T2T_STATE_SET_TAG_RO: 1068 return "SET_TAG_RO"; 1069 case RW_T2T_STATE_CHECK_PRESENCE: 1070 return "CHECK_PRESENCE"; 1071 default: 1072 return "???? UNKNOWN STATE"; 1073 } 1074} 1075 1076/******************************************************************************* 1077** 1078** Function rw_t2t_get_substate_name 1079** 1080** Description This function returns the substate name. 1081** 1082** NOTE conditionally compiled to save memory. 1083** 1084** Returns pointer to the name 1085** 1086*******************************************************************************/ 1087static std::string rw_t2t_get_substate_name(uint8_t substate) { 1088 switch (substate) { 1089 case RW_T2T_SUBSTATE_NONE: 1090 return "RW_T2T_SUBSTATE_NONE"; 1091 case RW_T2T_SUBSTATE_WAIT_SELECT_SECTOR_SUPPORT: 1092 return "RW_T2T_SUBSTATE_WAIT_SELECT_SECTOR_SUPPORT"; 1093 case RW_T2T_SUBSTATE_WAIT_SELECT_SECTOR: 1094 return "RW_T2T_SUBSTATE_WAIT_SELECT_SECTOR"; 1095 case RW_T2T_SUBSTATE_WAIT_READ_CC: 1096 return "RW_T2T_SUBSTATE_WAIT_READ_CC"; 1097 case RW_T2T_SUBSTATE_WAIT_TLV_DETECT: 1098 return "RW_T2T_SUBSTATE_WAIT_TLV_DETECT"; 1099 case RW_T2T_SUBSTATE_WAIT_FIND_LEN_FIELD_LEN: 1100 return "RW_T2T_SUBSTATE_WAIT_FIND_LEN_FIELD_LEN"; 1101 case RW_T2T_SUBSTATE_WAIT_READ_TLV_LEN0: 1102 return "RW_T2T_SUBSTATE_WAIT_READ_TLV_LEN0"; 1103 case RW_T2T_SUBSTATE_WAIT_READ_TLV_LEN1: 1104 return "RW_T2T_SUBSTATE_WAIT_READ_TLV_LEN1"; 1105 case RW_T2T_SUBSTATE_WAIT_READ_TLV_VALUE: 1106 return "RW_T2T_SUBSTATE_WAIT_READ_TLV_VALUE"; 1107 case RW_T2T_SUBSTATE_WAIT_READ_LOCKS: 1108 return "RW_T2T_SUBSTATE_WAIT_READ_LOCKS"; 1109 case RW_T2T_SUBSTATE_WAIT_READ_NDEF_FIRST_BLOCK: 1110 return "RW_T2T_SUBSTATE_WAIT_READ_NDEF_FIRST_BLOCK"; 1111 case RW_T2T_SUBSTATE_WAIT_READ_NDEF_LAST_BLOCK: 1112 return "RW_T2T_SUBSTATE_WAIT_READ_NDEF_LAST_BLOCK"; 1113 case RW_T2T_SUBSTATE_WAIT_READ_TERM_TLV_BLOCK: 1114 return "RW_T2T_SUBSTATE_WAIT_READ_TERM_TLV_BLOCK"; 1115 case RW_T2T_SUBSTATE_WAIT_READ_NDEF_NEXT_BLOCK: 1116 return "RW_T2T_SUBSTATE_WAIT_READ_NDEF_NEXT_BLOCK"; 1117 case RW_T2T_SUBSTATE_WAIT_WRITE_NDEF_NEXT_BLOCK: 1118 return "RW_T2T_SUBSTATE_WAIT_WRITE_NDEF_NEXT_BLOCK"; 1119 case RW_T2T_SUBSTATE_WAIT_WRITE_NDEF_LAST_BLOCK: 1120 return "RW_T2T_SUBSTATE_WAIT_WRITE_NDEF_LAST_BLOCK"; 1121 case RW_T2T_SUBSTATE_WAIT_READ_NDEF_LEN_BLOCK: 1122 return "RW_T2T_SUBSTATE_WAIT_READ_NDEF_LEN_BLOCK"; 1123 case RW_T2T_SUBSTATE_WAIT_WRITE_NDEF_LEN_BLOCK: 1124 return "RW_T2T_SUBSTATE_WAIT_WRITE_NDEF_LEN_BLOCK"; 1125 case RW_T2T_SUBSTATE_WAIT_WRITE_NDEF_LEN_NEXT_BLOCK: 1126 return "RW_T2T_SUBSTATE_WAIT_WRITE_NDEF_LEN_NEXT_BLOCK"; 1127 case RW_T2T_SUBSTATE_WAIT_WRITE_TERM_TLV_CMPLT: 1128 return "RW_T2T_SUBSTATE_WAIT_WRITE_TERM_TLV_CMPLT"; 1129 default: 1130 return "???? UNKNOWN SUBSTATE"; 1131 } 1132} 1133