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