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