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/stringprintf.h>
26 #include <base/logging.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 extern bool nfc_debug_enabled;
42
43 /* Static local functions */
44 static void rw_t2t_proc_data(uint8_t conn_id, tNFC_DATA_CEVT* p_data);
45 static tNFC_STATUS rw_t2t_send_cmd(uint8_t opcode, uint8_t* p_dat);
46 static void rw_t2t_process_error(void);
47 static void rw_t2t_process_frame_error(void);
48 static void rw_t2t_handle_presence_check_rsp(tNFC_STATUS status);
49 static void rw_t2t_resume_op(void);
50
51 static std::string rw_t2t_get_state_name(uint8_t state);
52 static std::string rw_t2t_get_substate_name(uint8_t substate);
53
54 /*******************************************************************************
55 **
56 ** Function rw_t2t_proc_data
57 **
58 ** Description This function handles data evt received from NFC Controller.
59 **
60 ** Returns none
61 **
62 *******************************************************************************/
rw_t2t_proc_data(uint8_t conn_id,tNFC_DATA_CEVT * p_data)63 static void rw_t2t_proc_data(uint8_t conn_id, tNFC_DATA_CEVT* p_data) {
64 tRW_EVENT rw_event = RW_RAW_FRAME_EVT;
65 tRW_T2T_CB* p_t2t = &rw_cb.tcb.t2t;
66 NFC_HDR* p_pkt = p_data->p_data;
67 bool b_notify = true;
68 bool b_release = true;
69 uint8_t* p;
70 tRW_READ_DATA evt_data = {};
71 tT2T_CMD_RSP_INFO* p_cmd_rsp_info =
72 (tT2T_CMD_RSP_INFO*)rw_cb.tcb.t2t.p_cmd_rsp_info;
73 tRW_DETECT_NDEF_DATA ndef_data;
74 uint8_t begin_state = p_t2t->state;
75
76 if ((p_t2t->state == RW_T2T_STATE_IDLE) || (p_cmd_rsp_info == nullptr)) {
77 DLOG_IF(INFO, nfc_debug_enabled)
78 << StringPrintf("RW T2T Raw Frame: Len [0x%X] Status [%s]", p_pkt->len,
79 NFC_GetStatusName(p_data->status).c_str());
80 evt_data.status = p_data->status;
81 evt_data.p_data = p_pkt;
82 tRW_DATA rw_data;
83 rw_data.data = evt_data;
84 (*rw_cb.p_cback)(RW_T2T_RAW_FRAME_EVT, &rw_data);
85 return;
86 }
87 #if (RW_STATS_INCLUDED == TRUE)
88 /* Update rx stats */
89 rw_main_update_rx_stats(p_pkt->len);
90 #endif
91 /* Stop timer as response is received */
92 nfc_stop_quick_timer(&p_t2t->t2_timer);
93
94 DLOG_IF(INFO, nfc_debug_enabled)
95 << StringPrintf("RW RECV [%s]:0x%x RSP", t2t_info_to_str(p_cmd_rsp_info),
96 p_cmd_rsp_info->opcode);
97
98 if (((p_pkt->len != p_cmd_rsp_info->rsp_len) &&
99 (p_pkt->len != p_cmd_rsp_info->nack_rsp_len) &&
100 (p_t2t->substate != RW_T2T_SUBSTATE_WAIT_SELECT_SECTOR)) ||
101 (p_t2t->state == RW_T2T_STATE_HALT)) {
102 LOG(ERROR) << StringPrintf("T2T Frame error. state=%s ",
103 rw_t2t_get_state_name(p_t2t->state).c_str());
104 if (p_t2t->state != RW_T2T_STATE_HALT) {
105 /* Retrasmit the last sent command if retry-count < max retry */
106 rw_t2t_process_frame_error();
107 p_t2t->check_tag_halt = false;
108 }
109 GKI_freebuf(p_pkt);
110 return;
111 }
112 rw_cb.cur_retry = 0;
113
114 /* Assume the data is just the response byte sequence */
115 p = (uint8_t*)(p_pkt + 1) + p_pkt->offset;
116
117 DLOG_IF(INFO, nfc_debug_enabled) << StringPrintf(
118 "rw_t2t_proc_data State: %u conn_id: %u len: %u data[0]: 0x%02x",
119 p_t2t->state, conn_id, p_pkt->len, *p);
120
121 evt_data.p_data = nullptr;
122
123 if (p_t2t->substate == RW_T2T_SUBSTATE_WAIT_SELECT_SECTOR_SUPPORT) {
124 /* The select process happens in two steps */
125 if ((*p & 0x0f) == T2T_RSP_ACK) {
126 if (rw_t2t_sector_change(p_t2t->select_sector) == NFC_STATUS_OK)
127 b_notify = false;
128 else
129 evt_data.status = NFC_STATUS_FAILED;
130 } else {
131 DLOG_IF(INFO, nfc_debug_enabled) << StringPrintf(
132 "rw_t2t_proc_data - Received NACK response(0x%x) to SEC-SELCT CMD",
133 (*p & 0x0f));
134 evt_data.status = NFC_STATUS_REJECTED;
135 }
136 } else if (p_t2t->substate == RW_T2T_SUBSTATE_WAIT_SELECT_SECTOR) {
137 evt_data.status = NFC_STATUS_FAILED;
138 } else if ((p_pkt->len != p_cmd_rsp_info->rsp_len) ||
139 ((p_cmd_rsp_info->opcode == T2T_CMD_WRITE) &&
140 ((*p & 0x0f) != T2T_RSP_ACK))) {
141 /* Received NACK response */
142 evt_data.p_data = p_pkt;
143 if (p_t2t->state == RW_T2T_STATE_READ) b_release = false;
144
145 DLOG_IF(INFO, nfc_debug_enabled) << StringPrintf(
146 "rw_t2t_proc_data - Received NACK response(0x%x)", (*p & 0x0f));
147
148 if (!p_t2t->check_tag_halt) {
149 /* Just received first NACK. Retry just one time to find if tag went in to
150 * HALT State */
151 b_notify = false;
152 rw_t2t_process_error();
153 /* Assume Tag is in HALT State, untill we get response to retry command */
154 p_t2t->check_tag_halt = true;
155 } else {
156 p_t2t->check_tag_halt = false;
157 /* Got consecutive NACK so tag not really halt after first NACK, but
158 * current operation failed */
159 evt_data.status = NFC_STATUS_FAILED;
160 }
161 } else {
162 /* If the response length indicates positive response or cannot be known
163 * from length then assume success */
164 evt_data.status = NFC_STATUS_OK;
165 p_t2t->check_tag_halt = false;
166
167 /* The response data depends on what the current operation was */
168 switch (p_t2t->state) {
169 case RW_T2T_STATE_CHECK_PRESENCE:
170 b_notify = false;
171 rw_t2t_handle_presence_check_rsp(NFC_STATUS_OK);
172 break;
173
174 case RW_T2T_STATE_READ:
175 evt_data.p_data = p_pkt;
176 b_release = false;
177 if (p_t2t->block_read == 0) {
178 p_t2t->b_read_hdr = true;
179 memcpy(p_t2t->tag_hdr, p, T2T_READ_DATA_LEN);
180 }
181 break;
182
183 case RW_T2T_STATE_WRITE:
184 /* Write operation completed successfully */
185 break;
186
187 default:
188 /* NDEF/other Tlv Operation/Format-Tag/Config Tag as Read only */
189 b_notify = false;
190 rw_t2t_handle_rsp(p);
191 break;
192 }
193 }
194
195 if (b_notify) {
196 rw_event = rw_t2t_info_to_event(p_cmd_rsp_info);
197
198 if (rw_event == RW_T2T_NDEF_DETECT_EVT) {
199 ndef_data.status = evt_data.status;
200 ndef_data.protocol = NFC_PROTOCOL_T2T;
201 ndef_data.flags = RW_NDEF_FL_UNKNOWN;
202 if (p_t2t->substate == RW_T2T_SUBSTATE_WAIT_READ_LOCKS)
203 ndef_data.flags = RW_NDEF_FL_FORMATED;
204 ndef_data.max_size = 0;
205 ndef_data.cur_size = 0;
206 /* Move back to idle state */
207 rw_t2t_handle_op_complete();
208 tRW_DATA rw_data;
209 rw_data.ndef = ndef_data;
210 (*rw_cb.p_cback)(rw_event, &rw_data);
211 } else {
212 /* Move back to idle state */
213 rw_t2t_handle_op_complete();
214 tRW_DATA rw_data;
215 rw_data.data = evt_data;
216 (*rw_cb.p_cback)(rw_event, &rw_data);
217 }
218 }
219
220 if (b_release) GKI_freebuf(p_pkt);
221
222 if (begin_state != p_t2t->state) {
223 DLOG_IF(INFO, nfc_debug_enabled)
224 << StringPrintf("RW T2T state changed:<%s> -> <%s>",
225 rw_t2t_get_state_name(begin_state).c_str(),
226 rw_t2t_get_state_name(p_t2t->state).c_str());
227 }
228 }
229
230 /*******************************************************************************
231 **
232 ** Function rw_t2t_conn_cback
233 **
234 ** Description This callback function receives events/data from NFCC.
235 **
236 ** Returns none
237 **
238 *******************************************************************************/
rw_t2t_conn_cback(uint8_t conn_id,tNFC_CONN_EVT event,tNFC_CONN * p_data)239 void rw_t2t_conn_cback(uint8_t conn_id, tNFC_CONN_EVT event,
240 tNFC_CONN* p_data) {
241 tRW_T2T_CB* p_t2t = &rw_cb.tcb.t2t;
242 tRW_READ_DATA evt_data;
243
244 DLOG_IF(INFO, nfc_debug_enabled)
245 << StringPrintf("rw_t2t_conn_cback: conn_id=%i, evt=%i", conn_id, event);
246 /* Only handle static conn_id */
247 if (conn_id != NFC_RF_CONN_ID) {
248 return;
249 }
250
251 switch (event) {
252 case NFC_CONN_CREATE_CEVT:
253 case NFC_CONN_CLOSE_CEVT:
254 break;
255
256 case NFC_DEACTIVATE_CEVT:
257 #if (RW_STATS_INCLUDED == TRUE)
258 /* Display stats */
259 rw_main_log_stats();
260 #endif
261 /* Stop t2t timer (if started) */
262 nfc_stop_quick_timer(&p_t2t->t2_timer);
263
264 /* Free cmd buf for retransmissions */
265 if (p_t2t->p_cur_cmd_buf) {
266 GKI_freebuf(p_t2t->p_cur_cmd_buf);
267 p_t2t->p_cur_cmd_buf = nullptr;
268 }
269 /* Free cmd buf used to hold command before sector change */
270 if (p_t2t->p_sec_cmd_buf) {
271 GKI_freebuf(p_t2t->p_sec_cmd_buf);
272 p_t2t->p_sec_cmd_buf = nullptr;
273 }
274
275 p_t2t->state = RW_T2T_STATE_NOT_ACTIVATED;
276 NFC_SetStaticRfCback(nullptr);
277 break;
278
279 case NFC_DATA_CEVT:
280 if (p_data != nullptr) {
281 if ((p_data->data.status == NFC_STATUS_OK) ||
282 (p_data->data.status == NFC_STATUS_CONTINUE)) {
283 rw_t2t_proc_data(conn_id, &(p_data->data));
284 break;
285 } else if (p_data->data.p_data != nullptr) {
286 /* Free the response buffer in case of error response */
287 GKI_freebuf((NFC_HDR*)(p_data->data.p_data));
288 p_data->data.p_data = nullptr;
289 }
290 }
291 /* Data event with error status...fall through to NFC_ERROR_CEVT case */
292 FALLTHROUGH_INTENDED;
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 = nullptr;
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_RF_FRAME_CORRUPTED);
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 *******************************************************************************/
rw_t2t_send_cmd(uint8_t opcode,uint8_t * p_dat)347 tNFC_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 *******************************************************************************/
rw_t2t_process_timeout()411 void 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_RF_FRAME_CORRUPTED);
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 = nullptr;
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 *******************************************************************************/
rw_t2t_process_frame_error(void)458 static 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 *******************************************************************************/
rw_t2t_process_error(void)478 static 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 != nullptr) {
500 memcpy(p_cmd_buf, p_t2t->p_cur_cmd_buf,
501 sizeof(NFC_HDR) + 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 = nullptr;
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 *****************************************************************************/
rw_t2t_handle_presence_check_rsp(tNFC_STATUS status)572 void 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 *******************************************************************************/
rw_t2t_resume_op(void)592 static 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 != nullptr) {
611 memcpy(p_cmd_buf, p_t2t->p_sec_cmd_buf,
612 sizeof(NFC_HDR) + 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 = nullptr;
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 *******************************************************************************/
rw_t2t_sector_change(uint8_t sector)650 tNFC_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 == nullptr) {
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 = nullptr;
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 *******************************************************************************/
rw_t2t_read(uint16_t block)705 tNFC_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 *******************************************************************************/
rw_t2t_write(uint16_t block,uint8_t * p_write_data)762 tNFC_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 *******************************************************************************/
rw_t2t_select(void)816 tNFC_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 == nullptr) {
824 p_t2t->p_cur_cmd_buf = (NFC_HDR*)GKI_getpoolbuf(NFC_RW_POOL_ID);
825 if (p_t2t->p_cur_cmd_buf == nullptr) {
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 == nullptr) {
833 p_t2t->p_sec_cmd_buf = (NFC_HDR*)GKI_getpoolbuf(NFC_RW_POOL_ID);
834 if (p_t2t->p_sec_cmd_buf == nullptr) {
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 *****************************************************************************/
rw_t2t_handle_op_complete(void)857 void 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 *****************************************************************************/
RW_T2tPresenceCheck(void)886 tNFC_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 *******************************************************************************/
RW_T2tRead(uint16_t block)929 tNFC_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 *******************************************************************************/
RW_T2tWrite(uint16_t block,uint8_t * p_write_data)962 tNFC_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 *******************************************************************************/
RW_T2tSectorSelect(uint8_t sector)1004 tNFC_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 *******************************************************************************/
rw_t2t_get_state_name(uint8_t state)1049 static 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 *******************************************************************************/
rw_t2t_get_substate_name(uint8_t substate)1087 static 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