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