blob: a05c942a81cccde9df8d13ce8a244f79c90d0da8 [file] [log] [blame]
nxpandroidc7611652015-09-23 16:42:05 +05301/******************************************************************************
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 *
nxpandroidc7611652015-09-23 16:42:05 +053021 * This file contains the implementation for Type 2 tag in Reader/Writer
22 * mode.
23 *
24 ******************************************************************************/
nxf24591c1cbeab2018-02-21 17:32:26 +053025#include <string>
nxpandroidc7611652015-09-23 16:42:05 +053026
nxf24591c1cbeab2018-02-21 17:32:26 +053027#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"
nxpandroidc7611652015-09-23 16:42:05 +053034#include "nci_hmsgs.h"
nxf24591c1cbeab2018-02-21 17:32:26 +053035#include "nfc_api.h"
36#include "nfc_int.h"
nxpandroidc7611652015-09-23 16:42:05 +053037#include "rw_api.h"
38#include "rw_int.h"
nxf24591c1cbeab2018-02-21 17:32:26 +053039
40using android::base::StringPrintf;
41
42extern bool nfc_debug_enabled;
nxpandroidc7611652015-09-23 16:42:05 +053043
44/* Static local functions */
nxpandroid8f6d0532017-07-12 18:25:30 +053045static void rw_t2t_proc_data(uint8_t conn_id, tNFC_DATA_CEVT* p_data);
46static tNFC_STATUS rw_t2t_send_cmd(uint8_t opcode, uint8_t* p_dat);
47static void rw_t2t_process_error(void);
48static void rw_t2t_process_frame_error(void);
49static void rw_t2t_handle_presence_check_rsp(tNFC_STATUS status);
50static void rw_t2t_resume_op(void);
nxpandroidc7611652015-09-23 16:42:05 +053051
nxf24591c1cbeab2018-02-21 17:32:26 +053052static std::string rw_t2t_get_state_name(uint8_t state);
53static std::string rw_t2t_get_substate_name(uint8_t substate);
nxpandroidc7611652015-09-23 16:42:05 +053054
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*******************************************************************************/
nxpandroid8f6d0532017-07-12 18:25:30 +053064static 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;
nxf24591c1cbeab2018-02-21 17:32:26 +053071 tRW_READ_DATA evt_data = {};
nxpandroid8f6d0532017-07-12 18:25:30 +053072 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;
nxpandroid8f6d0532017-07-12 18:25:30 +053075 uint8_t begin_state = p_t2t->state;
nxpandroidc7611652015-09-23 16:42:05 +053076
nxpandroid8f6d0532017-07-12 18:25:30 +053077 if ((p_t2t->state == RW_T2T_STATE_IDLE) || (p_cmd_rsp_info == NULL)) {
nxf24591c1cbeab2018-02-21 17:32:26 +053078 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());
nxpandroid8f6d0532017-07-12 18:25:30 +053081 evt_data.status = p_data->status;
82 evt_data.p_data = p_pkt;
nxf24591c1cbeab2018-02-21 17:32:26 +053083 tRW_DATA rw_data;
84 rw_data.data = evt_data;
85 (*rw_cb.p_cback)(RW_T2T_RAW_FRAME_EVT, &rw_data);
nxpandroid8f6d0532017-07-12 18:25:30 +053086 return;
87 }
nxf24591c1cbeab2018-02-21 17:32:26 +053088#if (RW_STATS_INCLUDED == TRUE)
nxpandroid8f6d0532017-07-12 18:25:30 +053089 /* Update rx stats */
90 rw_main_update_rx_stats(p_pkt->len);
nxpandroidc7611652015-09-23 16:42:05 +053091#endif
nxpandroid8f6d0532017-07-12 18:25:30 +053092 /* Stop timer as response is received */
93 nfc_stop_quick_timer(&p_t2t->t2_timer);
nxpandroidc7611652015-09-23 16:42:05 +053094
nxf24591c1cbeab2018-02-21 17:32:26 +053095 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);
nxpandroidc7611652015-09-23 16:42:05 +053098
nxpandroid8f6d0532017-07-12 18:25:30 +053099 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)) {
nxf24591c1cbeab2018-02-21 17:32:26 +0530103 LOG(ERROR) << StringPrintf("T2T Frame error. state=%s ",
104 rw_t2t_get_state_name(p_t2t->state).c_str());
nxpandroid8f6d0532017-07-12 18:25:30 +0530105 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;
nxpandroidc7611652015-09-23 16:42:05 +0530109 }
nxpandroid8f6d0532017-07-12 18:25:30 +0530110 GKI_freebuf(p_pkt);
111 return;
112 }
113 rw_cb.cur_retry = 0;
nxpandroidc7611652015-09-23 16:42:05 +0530114
nxpandroid8f6d0532017-07-12 18:25:30 +0530115 /* Assume the data is just the response byte sequence */
116 p = (uint8_t*)(p_pkt + 1) + p_pkt->offset;
nxpandroidc7611652015-09-23 16:42:05 +0530117
nxf24591c1cbeab2018-02-21 17:32:26 +0530118 DLOG_IF(INFO, nfc_debug_enabled) << StringPrintf(
nxpandroid8f6d0532017-07-12 18:25:30 +0530119 "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);
nxpandroidc7611652015-09-23 16:42:05 +0530121
nxpandroid8f6d0532017-07-12 18:25:30 +0530122 evt_data.p_data = NULL;
nxpandroidc7611652015-09-23 16:42:05 +0530123
nxpandroid8f6d0532017-07-12 18:25:30 +0530124 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
nxpandroidc7611652015-09-23 16:42:05 +0530130 evt_data.status = NFC_STATUS_FAILED;
nxpandroid8f6d0532017-07-12 18:25:30 +0530131 } else {
nxf24591c1cbeab2018-02-21 17:32:26 +0530132 DLOG_IF(INFO, nfc_debug_enabled) << StringPrintf(
nxpandroid8f6d0532017-07-12 18:25:30 +0530133 "rw_t2t_proc_data - Received NACK response(0x%x) to SEC-SELCT CMD",
134 (*p & 0x0f));
135 evt_data.status = NFC_STATUS_REJECTED;
nxpandroidc7611652015-09-23 16:42:05 +0530136 }
nxpandroid8f6d0532017-07-12 18:25:30 +0530137 } 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
nxf24591c1cbeab2018-02-21 17:32:26 +0530146 DLOG_IF(INFO, nfc_debug_enabled) << StringPrintf(
147 "rw_t2t_proc_data - Received NACK response(0x%x)", (*p & 0x0f));
nxpandroid8f6d0532017-07-12 18:25:30 +0530148
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:
nxpandroidc7611652015-09-23 16:42:05 +0530176 evt_data.p_data = p_pkt;
nxpandroid8f6d0532017-07-12 18:25:30 +0530177 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);
nxpandroidc7611652015-09-23 16:42:05 +0530181 }
nxpandroid8f6d0532017-07-12 18:25:30 +0530182 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;
nxpandroidc7611652015-09-23 16:42:05 +0530193 }
nxpandroid8f6d0532017-07-12 18:25:30 +0530194 }
nxpandroidc7611652015-09-23 16:42:05 +0530195
nxpandroid8f6d0532017-07-12 18:25:30 +0530196 if (b_notify) {
197 rw_event = rw_t2t_info_to_event(p_cmd_rsp_info);
nxpandroidc7611652015-09-23 16:42:05 +0530198
nxpandroid8f6d0532017-07-12 18:25:30 +0530199 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();
nxf24591c1cbeab2018-02-21 17:32:26 +0530209 tRW_DATA rw_data;
210 rw_data.ndef = ndef_data;
211 (*rw_cb.p_cback)(rw_event, &rw_data);
nxpandroid8f6d0532017-07-12 18:25:30 +0530212 } else {
213 /* Move back to idle state */
214 rw_t2t_handle_op_complete();
nxf24591c1cbeab2018-02-21 17:32:26 +0530215 tRW_DATA rw_data;
216 rw_data.data = evt_data;
217 (*rw_cb.p_cback)(rw_event, &rw_data);
nxpandroidc7611652015-09-23 16:42:05 +0530218 }
nxpandroid8f6d0532017-07-12 18:25:30 +0530219 }
nxpandroidc7611652015-09-23 16:42:05 +0530220
nxpandroid8f6d0532017-07-12 18:25:30 +0530221 if (b_release) GKI_freebuf(p_pkt);
nxpandroidc7611652015-09-23 16:42:05 +0530222
nxpandroid8f6d0532017-07-12 18:25:30 +0530223 if (begin_state != p_t2t->state) {
nxf24591c1cbeab2018-02-21 17:32:26 +0530224 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());
nxpandroid8f6d0532017-07-12 18:25:30 +0530228 }
nxpandroidc7611652015-09-23 16:42:05 +0530229}
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*******************************************************************************/
nxpandroid8f6d0532017-07-12 18:25:30 +0530240void 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;
nxpandroidc7611652015-09-23 16:42:05 +0530244
nxf24591c1cbeab2018-02-21 17:32:26 +0530245 DLOG_IF(INFO, nfc_debug_enabled)
246 << StringPrintf("rw_t2t_conn_cback: conn_id=%i, evt=%i", conn_id, event);
nxpandroid8f6d0532017-07-12 18:25:30 +0530247 /* Only handle static conn_id */
248 if (conn_id != NFC_RF_CONN_ID) {
249 return;
250 }
nxpandroidc7611652015-09-23 16:42:05 +0530251
nxpandroid8f6d0532017-07-12 18:25:30 +0530252 switch (event) {
nxpandroidc7611652015-09-23 16:42:05 +0530253 case NFC_CONN_CREATE_CEVT:
254 case NFC_CONN_CLOSE_CEVT:
nxpandroid8f6d0532017-07-12 18:25:30 +0530255 break;
nxpandroidc7611652015-09-23 16:42:05 +0530256
257 case NFC_DEACTIVATE_CEVT:
nxf24591c1cbeab2018-02-21 17:32:26 +0530258#if (RW_STATS_INCLUDED == TRUE)
nxpandroid8f6d0532017-07-12 18:25:30 +0530259 /* Display stats */
260 rw_main_log_stats();
nxpandroidc7611652015-09-23 16:42:05 +0530261#endif
nxpandroid8f6d0532017-07-12 18:25:30 +0530262 /* Stop t2t timer (if started) */
263 nfc_stop_quick_timer(&p_t2t->t2_timer);
nxpandroidc7611652015-09-23 16:42:05 +0530264
nxpandroid8f6d0532017-07-12 18:25:30 +0530265 /* Free cmd buf for retransmissions */
266 if (p_t2t->p_cur_cmd_buf) {
267 GKI_freebuf(p_t2t->p_cur_cmd_buf);
268 p_t2t->p_cur_cmd_buf = NULL;
269 }
270 /* Free cmd buf used to hold command before sector change */
271 if (p_t2t->p_sec_cmd_buf) {
272 GKI_freebuf(p_t2t->p_sec_cmd_buf);
273 p_t2t->p_sec_cmd_buf = NULL;
274 }
nxpandroidc7611652015-09-23 16:42:05 +0530275
nxpandroid8f6d0532017-07-12 18:25:30 +0530276 p_t2t->state = RW_T2T_STATE_NOT_ACTIVATED;
277 NFC_SetStaticRfCback(NULL);
278 break;
nxpandroidc7611652015-09-23 16:42:05 +0530279
280 case NFC_DATA_CEVT:
nxpandroid8f6d0532017-07-12 18:25:30 +0530281 if (p_data != NULL) {
282 if ((p_data->data.status == NFC_STATUS_OK) ||
283 (p_data->data.status == NFC_STATUS_CONTINUE)) {
284 rw_t2t_proc_data(conn_id, &(p_data->data));
285 break;
286 } else if (p_data->data.p_data != NULL) {
287 /* Free the response buffer in case of error response */
288 GKI_freebuf((NFC_HDR*)(p_data->data.p_data));
289 p_data->data.p_data = NULL;
nxpandroidc7611652015-09-23 16:42:05 +0530290 }
nxpandroid8f6d0532017-07-12 18:25:30 +0530291 }
292 /* Data event with error status...fall through to NFC_ERROR_CEVT case */
nxpandroidc7611652015-09-23 16:42:05 +0530293
294 case NFC_ERROR_CEVT:
nxpandroid8f6d0532017-07-12 18:25:30 +0530295 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)) {
nxf24591c1cbeab2018-02-21 17:32:26 +0530298#if (RW_STATS_INCLUDED == TRUE)
nxpandroid8f6d0532017-07-12 18:25:30 +0530299 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;
nxpandroidc7611652015-09-23 16:42:05 +0530305 else
nxpandroid8f6d0532017-07-12 18:25:30 +0530306 evt_data.status = NFC_STATUS_FAILED;
307
308 evt_data.p_data = NULL;
nxf24591c1cbeab2018-02-21 17:32:26 +0530309 tRW_DATA rw_data;
310 rw_data.data = evt_data;
311 (*rw_cb.p_cback)(RW_T2T_INTF_ERROR_EVT, &rw_data);
nxpandroidc7611652015-09-23 16:42:05 +0530312 break;
nxpandroid8f6d0532017-07-12 18:25:30 +0530313 }
314 nfc_stop_quick_timer(&p_t2t->t2_timer);
nxf24591c1cbeab2018-02-21 17:32:26 +0530315#if (RW_STATS_INCLUDED == TRUE)
nxpandroid8f6d0532017-07-12 18:25:30 +0530316 rw_main_update_trans_error_stats();
317#endif
318 if (p_t2t->state == RW_T2T_STATE_CHECK_PRESENCE) {
319 if (p_t2t->check_tag_halt) {
320 p_t2t->state = RW_T2T_STATE_HALT;
321 rw_t2t_handle_presence_check_rsp(NFC_STATUS_REJECTED);
322 } else {
323 /* Move back to idle state */
324 rw_t2t_handle_presence_check_rsp(NFC_STATUS_FAILED);
325 }
326 } else {
327 rw_t2t_process_error();
328 }
329 break;
nxpandroidc7611652015-09-23 16:42:05 +0530330
331 default:
nxpandroid8f6d0532017-07-12 18:25:30 +0530332 break;
333 }
nxpandroidc7611652015-09-23 16:42:05 +0530334}
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*******************************************************************************/
nxpandroid8f6d0532017-07-12 18:25:30 +0530347tNFC_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;
nxpandroidc7611652015-09-23 16:42:05 +0530353
nxpandroid8f6d0532017-07-12 18:25:30 +0530354 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;
nxpandroidc7611652015-09-23 16:42:05 +0530361
nxpandroid8f6d0532017-07-12 18:25:30 +0530362 UINT8_TO_STREAM(p, opcode);
nxpandroidc7611652015-09-23 16:42:05 +0530363
nxpandroid8f6d0532017-07-12 18:25:30 +0530364 if (p_dat) {
365 ARRAY_TO_STREAM(p, p_dat, (p_cmd_rsp_info->cmd_len - 1));
366 }
nxpandroidc7611652015-09-23 16:42:05 +0530367
nxpandroid8f6d0532017-07-12 18:25:30 +0530368 p_data->len = p_cmd_rsp_info->cmd_len;
nxpandroidc7611652015-09-23 16:42:05 +0530369
nxpandroid8f6d0532017-07-12 18:25:30 +0530370 /* 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);
nxpandroidc7611652015-09-23 16:42:05 +0530375
nxf24591c1cbeab2018-02-21 17:32:26 +0530376#if (RW_STATS_INCLUDED == TRUE)
nxpandroid8f6d0532017-07-12 18:25:30 +0530377 /* Update stats */
378 rw_main_update_tx_stats(p_data->len, false);
nxpandroidc7611652015-09-23 16:42:05 +0530379#endif
nxf24591c1cbeab2018-02-21 17:32:26 +0530380 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);
nxpandroidc7611652015-09-23 16:42:05 +0530383
nxpandroid8f6d0532017-07-12 18:25:30 +0530384 status = NFC_SendData(NFC_RF_CONN_ID, p_data);
385 if (status == NFC_STATUS_OK) {
nxpandroid8f6d0532017-07-12 18:25:30 +0530386 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 {
nxf24591c1cbeab2018-02-21 17:32:26 +0530390 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());
nxpandroid8f6d0532017-07-12 18:25:30 +0530394 }
395 } else {
396 status = NFC_STATUS_NO_BUFFERS;
nxpandroidc7611652015-09-23 16:42:05 +0530397 }
nxpandroid8f6d0532017-07-12 18:25:30 +0530398 }
399 return status;
nxpandroidc7611652015-09-23 16:42:05 +0530400}
401
402/*******************************************************************************
403**
404** Function rw_t2t_process_timeout
405**
406** Description handles timeout event
407**
408** Returns none
409**
410*******************************************************************************/
nxf24591c1cbeab2018-02-21 17:32:26 +0530411void rw_t2t_process_timeout() {
nxpandroid8f6d0532017-07-12 18:25:30 +0530412 tRW_READ_DATA evt_data;
413 tRW_T2T_CB* p_t2t = &rw_cb.tcb.t2t;
nxpandroidc7611652015-09-23 16:42:05 +0530414
nxpandroid8f6d0532017-07-12 18:25:30 +0530415 if (p_t2t->state == RW_T2T_STATE_CHECK_PRESENCE) {
416 if (p_t2t->check_tag_halt) {
417 p_t2t->state = RW_T2T_STATE_HALT;
418 rw_t2t_handle_presence_check_rsp(NFC_STATUS_REJECTED);
419 } else {
420 /* Move back to idle state */
421 rw_t2t_handle_presence_check_rsp(NFC_STATUS_FAILED);
nxpandroidc7611652015-09-23 16:42:05 +0530422 }
nxpandroid8f6d0532017-07-12 18:25:30 +0530423 return;
424 }
nxpandroidc7611652015-09-23 16:42:05 +0530425
nxpandroid8f6d0532017-07-12 18:25:30 +0530426 if (p_t2t->substate == RW_T2T_SUBSTATE_WAIT_SELECT_SECTOR) {
427 p_t2t->sector = p_t2t->select_sector;
428 /* Here timeout is an acknowledgment for successfull sector change */
429 if (p_t2t->state == RW_T2T_STATE_SELECT_SECTOR) {
430 /* Notify that select sector op is successfull */
431 rw_t2t_handle_op_complete();
432 evt_data.status = NFC_STATUS_OK;
433 evt_data.p_data = NULL;
nxf24591c1cbeab2018-02-21 17:32:26 +0530434 tRW_DATA rw_data;
435 rw_data.data = evt_data;
436 (*rw_cb.p_cback)(RW_T2T_SELECT_CPLT_EVT, &rw_data);
nxpandroid8f6d0532017-07-12 18:25:30 +0530437 } else {
438 /* Resume operation from where we stopped before sector change */
439 rw_t2t_resume_op();
nxpandroidc7611652015-09-23 16:42:05 +0530440 }
nxpandroid8f6d0532017-07-12 18:25:30 +0530441 } else if (p_t2t->state != RW_T2T_STATE_IDLE) {
nxf24591c1cbeab2018-02-21 17:32:26 +0530442 LOG(ERROR) << StringPrintf("T2T timeout. state=%s ",
443 rw_t2t_get_state_name(p_t2t->state).c_str());
nxpandroid8f6d0532017-07-12 18:25:30 +0530444 /* Handle timeout error as no response to the command sent */
445 rw_t2t_process_error();
446 }
nxpandroidc7611652015-09-23 16:42:05 +0530447}
448
449/*******************************************************************************
450**
451** Function rw_t2t_process_frame_error
452**
453** Description handles frame crc error
454**
455** Returns none
456**
457*******************************************************************************/
nxpandroid8f6d0532017-07-12 18:25:30 +0530458static void rw_t2t_process_frame_error(void) {
nxf24591c1cbeab2018-02-21 17:32:26 +0530459#if (RW_STATS_INCLUDED == TRUE)
nxpandroid8f6d0532017-07-12 18:25:30 +0530460 /* Update stats */
461 rw_main_update_crc_error_stats();
nxpandroidc7611652015-09-23 16:42:05 +0530462#endif
nxpandroid8f6d0532017-07-12 18:25:30 +0530463 /* Process the error */
464 rw_t2t_process_error();
nxpandroidc7611652015-09-23 16:42:05 +0530465}
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*******************************************************************************/
nxpandroid8f6d0532017-07-12 18:25:30 +0530478static 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;
nxpandroidc7611652015-09-23 16:42:05 +0530486
nxf24591c1cbeab2018-02-21 17:32:26 +0530487 DLOG_IF(INFO, nfc_debug_enabled) << StringPrintf("State: %u", p_t2t->state);
nxpandroidc7611652015-09-23 16:42:05 +0530488
nxpandroid8f6d0532017-07-12 18:25:30 +0530489 /* 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++;
nxpandroidc7611652015-09-23 16:42:05 +0530493
nxf24591c1cbeab2018-02-21 17:32:26 +0530494 DLOG_IF(INFO, nfc_debug_enabled) << StringPrintf(
495 "T2T retransmission attempt %i of %i", rw_cb.cur_retry, RW_MAX_RETRIES);
nxpandroidc7611652015-09-23 16:42:05 +0530496
nxpandroid8f6d0532017-07-12 18:25:30 +0530497 /* allocate a new buffer for message */
498 p_cmd_buf = (NFC_HDR*)GKI_getpoolbuf(NFC_RW_POOL_ID);
499 if (p_cmd_buf != NULL) {
500 memcpy(p_cmd_buf, p_t2t->p_cur_cmd_buf, sizeof(NFC_HDR) +
501 p_t2t->p_cur_cmd_buf->offset +
502 p_t2t->p_cur_cmd_buf->len);
nxf24591c1cbeab2018-02-21 17:32:26 +0530503#if (RW_STATS_INCLUDED == TRUE)
nxpandroid8f6d0532017-07-12 18:25:30 +0530504 /* Update stats */
505 rw_main_update_tx_stats(p_cmd_buf->len, true);
nxpandroidc7611652015-09-23 16:42:05 +0530506#endif
nxpandroid8f6d0532017-07-12 18:25:30 +0530507 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);
nxpandroidc7611652015-09-23 16:42:05 +0530512
nxpandroid8f6d0532017-07-12 18:25:30 +0530513 return;
514 }
nxpandroidc7611652015-09-23 16:42:05 +0530515 }
nxpandroid8f6d0532017-07-12 18:25:30 +0530516 } else {
517 if (p_t2t->check_tag_halt) {
nxf24591c1cbeab2018-02-21 17:32:26 +0530518 DLOG_IF(INFO, nfc_debug_enabled)
519 << StringPrintf("T2T Went to HALT State!");
nxpandroid8f6d0532017-07-12 18:25:30 +0530520 } else {
nxf24591c1cbeab2018-02-21 17:32:26 +0530521 DLOG_IF(INFO, nfc_debug_enabled) << StringPrintf(
522 "T2T maximum retransmission attempts reached (%i)", RW_MAX_RETRIES);
nxpandroidc7611652015-09-23 16:42:05 +0530523 }
nxpandroid8f6d0532017-07-12 18:25:30 +0530524 }
525 rw_event = rw_t2t_info_to_event(p_cmd_rsp_info);
nxf24591c1cbeab2018-02-21 17:32:26 +0530526#if (RW_STATS_INCLUDED == TRUE)
nxpandroid8f6d0532017-07-12 18:25:30 +0530527 /* update failure count */
528 rw_main_update_fail_stats();
nxpandroidc7611652015-09-23 16:42:05 +0530529#endif
nxpandroid8f6d0532017-07-12 18:25:30 +0530530 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 }
nxpandroidc7611652015-09-23 16:42:05 +0530536
nxpandroid8f6d0532017-07-12 18:25:30 +0530537 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();
nxpandroidc7611652015-09-23 16:42:05 +0530547
nxf24591c1cbeab2018-02-21 17:32:26 +0530548 tRW_DATA rw_data;
549 rw_data.ndef = ndef_data;
550 (*rw_cb.p_cback)(rw_event, &rw_data);
nxpandroid8f6d0532017-07-12 18:25:30 +0530551 } else {
552 evt_data.p_data = NULL;
553 /* If activated and not Halt move to idle state */
554 if (p_t2t->state != RW_T2T_STATE_NOT_ACTIVATED) rw_t2t_handle_op_complete();
nxpandroidc7611652015-09-23 16:42:05 +0530555
nxpandroid8f6d0532017-07-12 18:25:30 +0530556 p_t2t->substate = RW_T2T_SUBSTATE_NONE;
nxf24591c1cbeab2018-02-21 17:32:26 +0530557 tRW_DATA rw_data;
558 rw_data.data = evt_data;
559 (*rw_cb.p_cback)(rw_event, &rw_data);
nxpandroid8f6d0532017-07-12 18:25:30 +0530560 }
nxpandroidc7611652015-09-23 16:42:05 +0530561}
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*****************************************************************************/
nxpandroid8f6d0532017-07-12 18:25:30 +0530572void rw_t2t_handle_presence_check_rsp(tNFC_STATUS status) {
nxf24591c1cbeab2018-02-21 17:32:26 +0530573 tRW_DATA rw_data;
nxpandroidc7611652015-09-23 16:42:05 +0530574
nxpandroid8f6d0532017-07-12 18:25:30 +0530575 /* Notify, Tag is present or not */
nxf24591c1cbeab2018-02-21 17:32:26 +0530576 rw_data.data.status = status;
nxpandroid8f6d0532017-07-12 18:25:30 +0530577 rw_t2t_handle_op_complete();
nxpandroidc7611652015-09-23 16:42:05 +0530578
nxf24591c1cbeab2018-02-21 17:32:26 +0530579 (*rw_cb.p_cback)(RW_T2T_PRESENCE_CHECK_EVT, &rw_data);
nxpandroidc7611652015-09-23 16:42:05 +0530580}
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*******************************************************************************/
nxpandroid8f6d0532017-07-12 18:25:30 +0530592static 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;
nxpandroidc7611652015-09-23 16:42:05 +0530600
nxpandroid8f6d0532017-07-12 18:25:30 +0530601 /* Move back to the substate where we were before changing sector */
602 p_t2t->substate = p_t2t->prev_substate;
nxpandroidc7611652015-09-23 16:42:05 +0530603
nxpandroid8f6d0532017-07-12 18:25:30 +0530604 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;
nxpandroidc7611652015-09-23 16:42:05 +0530607
nxpandroid8f6d0532017-07-12 18:25:30 +0530608 /* allocate a new buffer for message */
609 p_cmd_buf = (NFC_HDR*)GKI_getpoolbuf(NFC_RW_POOL_ID);
610 if (p_cmd_buf != NULL) {
611 memcpy(p_cmd_buf, p_t2t->p_sec_cmd_buf, sizeof(NFC_HDR) +
612 p_t2t->p_sec_cmd_buf->offset +
613 p_t2t->p_sec_cmd_buf->len);
614 memcpy(p_t2t->p_cur_cmd_buf, p_t2t->p_sec_cmd_buf,
615 sizeof(NFC_HDR) + p_t2t->p_sec_cmd_buf->offset +
616 p_t2t->p_sec_cmd_buf->len);
nxpandroidc7611652015-09-23 16:42:05 +0530617
nxf24591c1cbeab2018-02-21 17:32:26 +0530618#if (RW_STATS_INCLUDED == TRUE)
nxpandroid8f6d0532017-07-12 18:25:30 +0530619 /* Update stats */
620 rw_main_update_tx_stats(p_cmd_buf->len, true);
nxpandroidc7611652015-09-23 16:42:05 +0530621#endif
nxpandroid8f6d0532017-07-12 18:25:30 +0530622 if (NFC_SendData(NFC_RF_CONN_ID, p_cmd_buf) == NFC_STATUS_OK) {
623 /* Start timer for waiting for response */
624 nfc_start_quick_timer(
625 &p_t2t->t2_timer, NFC_TTYPE_RW_T2T_RESPONSE,
626 (RW_T2T_TOUT_RESP * QUICK_TIMER_TICKS_PER_SEC) / 1000);
627 } else {
628 /* failure - could not send buffer */
629 evt_data.p_data = NULL;
630 evt_data.status = NFC_STATUS_FAILED;
631 event = rw_t2t_info_to_event(p_cmd_rsp_info);
632 rw_t2t_handle_op_complete();
nxf24591c1cbeab2018-02-21 17:32:26 +0530633 tRW_DATA rw_data;
634 rw_data.data = evt_data;
635 (*rw_cb.p_cback)(event, &rw_data);
nxpandroidc7611652015-09-23 16:42:05 +0530636 }
nxpandroid8f6d0532017-07-12 18:25:30 +0530637 }
nxpandroidc7611652015-09-23 16:42:05 +0530638}
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*******************************************************************************/
nxpandroid8f6d0532017-07-12 18:25:30 +0530650tNFC_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;
nxpandroidc7611652015-09-23 16:42:05 +0530655
nxpandroid8f6d0532017-07-12 18:25:30 +0530656 p_data = (NFC_HDR*)GKI_getpoolbuf(NFC_RW_POOL_ID);
657 if (p_data == NULL) {
nxf24591c1cbeab2018-02-21 17:32:26 +0530658 LOG(ERROR) << StringPrintf("rw_t2t_sector_change - No buffer");
nxpandroid8f6d0532017-07-12 18:25:30 +0530659 return (NFC_STATUS_NO_BUFFERS);
660 }
nxpandroidc7611652015-09-23 16:42:05 +0530661
nxpandroid8f6d0532017-07-12 18:25:30 +0530662 p_data->offset = NCI_MSG_OFFSET_SIZE + NCI_DATA_HDR_SIZE;
663 p = (uint8_t*)(p_data + 1) + p_data->offset;
nxpandroidc7611652015-09-23 16:42:05 +0530664
nxpandroid8f6d0532017-07-12 18:25:30 +0530665 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);
nxpandroidc7611652015-09-23 16:42:05 +0530669
nxpandroid8f6d0532017-07-12 18:25:30 +0530670 p_data->len = 4;
nxpandroidc7611652015-09-23 16:42:05 +0530671
nxpandroid8f6d0532017-07-12 18:25:30 +0530672 status = NFC_SendData(NFC_RF_CONN_ID, p_data);
673 if (status == NFC_STATUS_OK) {
674 /* Passive rsp command and suppose not to get response to this command */
675 p_t2t->p_cmd_rsp_info = NULL;
676 p_t2t->substate = RW_T2T_SUBSTATE_WAIT_SELECT_SECTOR;
nxpandroidc7611652015-09-23 16:42:05 +0530677
nxf24591c1cbeab2018-02-21 17:32:26 +0530678 DLOG_IF(INFO, nfc_debug_enabled)
679 << StringPrintf("rw_t2t_sector_change Sent Second Command");
nxpandroid8f6d0532017-07-12 18:25:30 +0530680 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 {
nxf24591c1cbeab2018-02-21 17:32:26 +0530684 LOG(ERROR) << StringPrintf(
nxpandroid8f6d0532017-07-12 18:25:30 +0530685 "rw_t2t_sector_change Send failed at rw_t2t_send_cmd, error: %u",
686 status);
687 }
nxpandroidc7611652015-09-23 16:42:05 +0530688
nxpandroid8f6d0532017-07-12 18:25:30 +0530689 return status;
nxpandroidc7611652015-09-23 16:42:05 +0530690}
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*******************************************************************************/
nxpandroid8f6d0532017-07-12 18:25:30 +0530705tNFC_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];
nxpandroidc7611652015-09-23 16:42:05 +0530711
nxpandroid8f6d0532017-07-12 18:25:30 +0530712 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;
nxpandroidc7611652015-09-23 16:42:05 +0530722
nxpandroid8f6d0532017-07-12 18:25:30 +0530723 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;
nxpandroidc7611652015-09-23 16:42:05 +0530728
nxpandroid8f6d0532017-07-12 18:25:30 +0530729 /* 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;
nxpandroidc7611652015-09-23 16:42:05 +0530734 }
nxpandroid8f6d0532017-07-12 18:25:30 +0530735 return NFC_STATUS_FAILED;
736 }
nxpandroidc7611652015-09-23 16:42:05 +0530737
nxpandroid8f6d0532017-07-12 18:25:30 +0530738 /* 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;
nxf24591c1cbeab2018-02-21 17:32:26 +0530742 DLOG_IF(INFO, nfc_debug_enabled)
743 << StringPrintf("rw_t2t_read Sent Command for Block: %u", block);
nxpandroid8f6d0532017-07-12 18:25:30 +0530744 }
nxpandroidc7611652015-09-23 16:42:05 +0530745
nxpandroid8f6d0532017-07-12 18:25:30 +0530746 return status;
nxpandroidc7611652015-09-23 16:42:05 +0530747}
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*******************************************************************************/
nxpandroid8f6d0532017-07-12 18:25:30 +0530762tNFC_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];
nxpandroidc7611652015-09-23 16:42:05 +0530768
nxpandroid8f6d0532017-07-12 18:25:30 +0530769 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);
nxpandroidc7611652015-09-23 16:42:05 +0530772
nxpandroid8f6d0532017-07-12 18:25:30 +0530773 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;
nxpandroidc7611652015-09-23 16:42:05 +0530787
nxpandroid8f6d0532017-07-12 18:25:30 +0530788 /* 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;
nxpandroidc7611652015-09-23 16:42:05 +0530793 }
nxpandroid8f6d0532017-07-12 18:25:30 +0530794 return NFC_STATUS_FAILED;
795 }
nxpandroidc7611652015-09-23 16:42:05 +0530796
nxpandroid8f6d0532017-07-12 18:25:30 +0530797 /* 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) {
nxf24591c1cbeab2018-02-21 17:32:26 +0530800 DLOG_IF(INFO, nfc_debug_enabled)
801 << StringPrintf("rw_t2t_write Sent Command for Block: %u", block);
nxpandroid8f6d0532017-07-12 18:25:30 +0530802 }
nxpandroidc7611652015-09-23 16:42:05 +0530803
nxpandroid8f6d0532017-07-12 18:25:30 +0530804 return status;
nxpandroidc7611652015-09-23 16:42:05 +0530805}
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*******************************************************************************/
nxpandroid8f6d0532017-07-12 18:25:30 +0530816tNFC_STATUS rw_t2t_select(void) {
817 tRW_T2T_CB* p_t2t = &rw_cb.tcb.t2t;
nxpandroidc7611652015-09-23 16:42:05 +0530818
nxpandroid8f6d0532017-07-12 18:25:30 +0530819 p_t2t->state = RW_T2T_STATE_IDLE;
820 p_t2t->ndef_status = T2T_NDEF_NOT_DETECTED;
nxpandroidc7611652015-09-23 16:42:05 +0530821
nxpandroid8f6d0532017-07-12 18:25:30 +0530822 /* Alloc cmd buf for retransmissions */
823 if (p_t2t->p_cur_cmd_buf == NULL) {
824 p_t2t->p_cur_cmd_buf = (NFC_HDR*)GKI_getpoolbuf(NFC_RW_POOL_ID);
825 if (p_t2t->p_cur_cmd_buf == NULL) {
nxf24591c1cbeab2018-02-21 17:32:26 +0530826 LOG(ERROR) << StringPrintf(
nxpandroid8f6d0532017-07-12 18:25:30 +0530827 "rw_t2t_select: unable to allocate buffer for retransmission");
828 return (NFC_STATUS_FAILED);
nxpandroidc7611652015-09-23 16:42:05 +0530829 }
nxpandroid8f6d0532017-07-12 18:25:30 +0530830 }
831 /* Alloc cmd buf for holding a command untill sector changes */
832 if (p_t2t->p_sec_cmd_buf == NULL) {
833 p_t2t->p_sec_cmd_buf = (NFC_HDR*)GKI_getpoolbuf(NFC_RW_POOL_ID);
834 if (p_t2t->p_sec_cmd_buf == NULL) {
nxf24591c1cbeab2018-02-21 17:32:26 +0530835 LOG(ERROR) << StringPrintf(
nxpandroid8f6d0532017-07-12 18:25:30 +0530836 "rw_t2t_select: unable to allocate buffer used during sector change");
837 return (NFC_STATUS_FAILED);
nxpandroidc7611652015-09-23 16:42:05 +0530838 }
nxpandroid8f6d0532017-07-12 18:25:30 +0530839 }
nxpandroidc7611652015-09-23 16:42:05 +0530840
nxpandroid8f6d0532017-07-12 18:25:30 +0530841 NFC_SetStaticRfCback(rw_t2t_conn_cback);
842 rw_t2t_handle_op_complete();
843 p_t2t->check_tag_halt = false;
nxpandroidc7611652015-09-23 16:42:05 +0530844
nxpandroid8f6d0532017-07-12 18:25:30 +0530845 return NFC_STATUS_OK;
nxpandroidc7611652015-09-23 16:42:05 +0530846}
847
848/*****************************************************************************
849**
850** Function rw_t2t_handle_op_complete
851**
852** Description Reset to IDLE state
853**
854** Returns Nothing
855**
856*****************************************************************************/
nxpandroid8f6d0532017-07-12 18:25:30 +0530857void rw_t2t_handle_op_complete(void) {
858 tRW_T2T_CB* p_t2t = &rw_cb.tcb.t2t;
nxpandroidc7611652015-09-23 16:42:05 +0530859
nxpandroid8f6d0532017-07-12 18:25:30 +0530860 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 }
nxpandroidc7611652015-09-23 16:42:05 +0530864
nxpandroid8f6d0532017-07-12 18:25:30 +0530865 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;
nxpandroidc7611652015-09-23 16:42:05 +0530868}
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*****************************************************************************/
nxpandroid8f6d0532017-07-12 18:25:30 +0530886tNFC_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 */
nxpandroidc7611652015-09-23 16:42:05 +0530891
nxf24591c1cbeab2018-02-21 17:32:26 +0530892 DLOG_IF(INFO, nfc_debug_enabled) << __func__;
nxpandroidc7611652015-09-23 16:42:05 +0530893
nxpandroid8f6d0532017-07-12 18:25:30 +0530894 /* 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, &sector_blk);
910 if (retval == NFC_STATUS_OK) {
911 p_rw_cb->tcb.t2t.state = RW_T2T_STATE_CHECK_PRESENCE;
nxpandroidc7611652015-09-23 16:42:05 +0530912 }
nxpandroid8f6d0532017-07-12 18:25:30 +0530913 }
nxpandroidc7611652015-09-23 16:42:05 +0530914
nxpandroid8f6d0532017-07-12 18:25:30 +0530915 return (retval);
nxpandroidc7611652015-09-23 16:42:05 +0530916}
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*******************************************************************************/
nxpandroid8f6d0532017-07-12 18:25:30 +0530929tNFC_STATUS RW_T2tRead(uint16_t block) {
930 tRW_T2T_CB* p_t2t = &rw_cb.tcb.t2t;
931 tNFC_STATUS status;
nxpandroidc7611652015-09-23 16:42:05 +0530932
nxpandroid8f6d0532017-07-12 18:25:30 +0530933 if (p_t2t->state != RW_T2T_STATE_IDLE) {
nxf24591c1cbeab2018-02-21 17:32:26 +0530934 LOG(ERROR) << StringPrintf(
935 "Error: Type 2 tag not activated or Busy - State: %u", p_t2t->state);
nxpandroid8f6d0532017-07-12 18:25:30 +0530936 return (NFC_STATUS_FAILED);
937 }
nxpandroidc7611652015-09-23 16:42:05 +0530938
nxpandroid8f6d0532017-07-12 18:25:30 +0530939 status = rw_t2t_read(block);
940 if (status == NFC_STATUS_OK) {
941 p_t2t->state = RW_T2T_STATE_READ;
nxf24591c1cbeab2018-02-21 17:32:26 +0530942 DLOG_IF(INFO, nfc_debug_enabled)
943 << StringPrintf("RW_T2tRead Sent Read command");
nxpandroid8f6d0532017-07-12 18:25:30 +0530944 }
nxpandroidc7611652015-09-23 16:42:05 +0530945
nxpandroid8f6d0532017-07-12 18:25:30 +0530946 return status;
nxpandroidc7611652015-09-23 16:42:05 +0530947}
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*******************************************************************************/
nxpandroid8f6d0532017-07-12 18:25:30 +0530962tNFC_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;
nxpandroidc7611652015-09-23 16:42:05 +0530965
nxpandroid8f6d0532017-07-12 18:25:30 +0530966 if (p_t2t->state != RW_T2T_STATE_IDLE) {
nxf24591c1cbeab2018-02-21 17:32:26 +0530967 LOG(ERROR) << StringPrintf(
968 "Error: Type 2 tag not activated or Busy - State: %u", p_t2t->state);
nxpandroid8f6d0532017-07-12 18:25:30 +0530969 return (NFC_STATUS_FAILED);
970 }
nxpandroidc7611652015-09-23 16:42:05 +0530971
nxpandroid8f6d0532017-07-12 18:25:30 +0530972 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;
nxf24591c1cbeab2018-02-21 17:32:26 +0530979 DLOG_IF(INFO, nfc_debug_enabled)
980 << StringPrintf("RW_T2tWrite Sent Write command");
nxpandroid8f6d0532017-07-12 18:25:30 +0530981 }
nxpandroidc7611652015-09-23 16:42:05 +0530982
nxpandroid8f6d0532017-07-12 18:25:30 +0530983 return status;
nxpandroidc7611652015-09-23 16:42:05 +0530984}
985
986/*******************************************************************************
987**
988** Function RW_T2tSectorSelect
989**
990** Description This function issues the Type 2 Tag SECTOR-SELECT command
nxpandroid8f6d0532017-07-12 18:25:30 +0530991** 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.
nxpandroidc7611652015-09-23 16:42:05 +0530998**
999** A sector is 256 contiguous blocks (1024 bytes).
1000**
1001** Returns tNFC_STATUS
1002**
1003*******************************************************************************/
nxpandroid8f6d0532017-07-12 18:25:30 +05301004tNFC_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];
nxpandroidc7611652015-09-23 16:42:05 +05301008
nxpandroid8f6d0532017-07-12 18:25:30 +05301009 if (p_t2t->state != RW_T2T_STATE_IDLE) {
nxf24591c1cbeab2018-02-21 17:32:26 +05301010 LOG(ERROR) << StringPrintf(
1011 "Error: Type 2 tag not activated or Busy - State: %u", p_t2t->state);
nxpandroid8f6d0532017-07-12 18:25:30 +05301012 return (NFC_STATUS_FAILED);
1013 }
nxpandroidc7611652015-09-23 16:42:05 +05301014
nxpandroid8f6d0532017-07-12 18:25:30 +05301015 if (sector >= T2T_MAX_SECTOR) {
nxf24591c1cbeab2018-02-21 17:32:26 +05301016 LOG(ERROR) << StringPrintf(
nxpandroid8f6d0532017-07-12 18:25:30 +05301017 "RW_T2tSectorSelect - Invalid sector: %u, T2 Max supported sector "
1018 "value: %u",
1019 sector, T2T_MAX_SECTOR - 1);
1020 return (NFC_STATUS_FAILED);
1021 }
nxpandroidc7611652015-09-23 16:42:05 +05301022
nxpandroid8f6d0532017-07-12 18:25:30 +05301023 sector_byte2[0] = 0xFF;
nxpandroidc7611652015-09-23 16:42:05 +05301024
nxpandroid8f6d0532017-07-12 18:25:30 +05301025 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;
nxpandroidc7611652015-09-23 16:42:05 +05301030
nxf24591c1cbeab2018-02-21 17:32:26 +05301031 DLOG_IF(INFO, nfc_debug_enabled)
1032 << StringPrintf("RW_T2tSectorSelect Sent Sector select first command");
nxpandroid8f6d0532017-07-12 18:25:30 +05301033 }
nxpandroidc7611652015-09-23 16:42:05 +05301034
nxpandroid8f6d0532017-07-12 18:25:30 +05301035 return status;
nxpandroidc7611652015-09-23 16:42:05 +05301036}
1037
nxpandroidc7611652015-09-23 16:42:05 +05301038/*******************************************************************************
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**
nxf24591c1cbeab2018-02-21 17:32:26 +05301046** Returns string
nxpandroidc7611652015-09-23 16:42:05 +05301047**
1048*******************************************************************************/
nxf24591c1cbeab2018-02-21 17:32:26 +05301049static std::string rw_t2t_get_state_name(uint8_t state) {
nxpandroid8f6d0532017-07-12 18:25:30 +05301050 switch (state) {
nxpandroidc7611652015-09-23 16:42:05 +05301051 case RW_T2T_STATE_NOT_ACTIVATED:
nxf24591c1cbeab2018-02-21 17:32:26 +05301052 return "NOT_ACTIVATED";
nxpandroidc7611652015-09-23 16:42:05 +05301053 case RW_T2T_STATE_IDLE:
nxf24591c1cbeab2018-02-21 17:32:26 +05301054 return "IDLE";
nxpandroidc7611652015-09-23 16:42:05 +05301055 case RW_T2T_STATE_READ:
nxf24591c1cbeab2018-02-21 17:32:26 +05301056 return "APP_READ";
nxpandroidc7611652015-09-23 16:42:05 +05301057 case RW_T2T_STATE_WRITE:
nxf24591c1cbeab2018-02-21 17:32:26 +05301058 return "APP_WRITE";
nxpandroidc7611652015-09-23 16:42:05 +05301059 case RW_T2T_STATE_SELECT_SECTOR:
nxf24591c1cbeab2018-02-21 17:32:26 +05301060 return "SECTOR_SELECT";
nxpandroidc7611652015-09-23 16:42:05 +05301061 case RW_T2T_STATE_DETECT_TLV:
nxf24591c1cbeab2018-02-21 17:32:26 +05301062 return "TLV_DETECT";
nxpandroidc7611652015-09-23 16:42:05 +05301063 case RW_T2T_STATE_READ_NDEF:
nxf24591c1cbeab2018-02-21 17:32:26 +05301064 return "READ_NDEF";
nxpandroidc7611652015-09-23 16:42:05 +05301065 case RW_T2T_STATE_WRITE_NDEF:
nxf24591c1cbeab2018-02-21 17:32:26 +05301066 return "WRITE_NDEF";
nxpandroidc7611652015-09-23 16:42:05 +05301067 case RW_T2T_STATE_SET_TAG_RO:
nxf24591c1cbeab2018-02-21 17:32:26 +05301068 return "SET_TAG_RO";
nxpandroidc7611652015-09-23 16:42:05 +05301069 case RW_T2T_STATE_CHECK_PRESENCE:
nxf24591c1cbeab2018-02-21 17:32:26 +05301070 return "CHECK_PRESENCE";
nxpandroidc7611652015-09-23 16:42:05 +05301071 default:
nxf24591c1cbeab2018-02-21 17:32:26 +05301072 return "???? UNKNOWN STATE";
nxpandroid8f6d0532017-07-12 18:25:30 +05301073 }
nxpandroidc7611652015-09-23 16:42:05 +05301074}
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*******************************************************************************/
nxf24591c1cbeab2018-02-21 17:32:26 +05301087static std::string rw_t2t_get_substate_name(uint8_t substate) {
nxpandroid8f6d0532017-07-12 18:25:30 +05301088 switch (substate) {
nxpandroidc7611652015-09-23 16:42:05 +05301089 case RW_T2T_SUBSTATE_NONE:
nxf24591c1cbeab2018-02-21 17:32:26 +05301090 return "RW_T2T_SUBSTATE_NONE";
nxpandroidc7611652015-09-23 16:42:05 +05301091 case RW_T2T_SUBSTATE_WAIT_SELECT_SECTOR_SUPPORT:
nxf24591c1cbeab2018-02-21 17:32:26 +05301092 return "RW_T2T_SUBSTATE_WAIT_SELECT_SECTOR_SUPPORT";
nxpandroidc7611652015-09-23 16:42:05 +05301093 case RW_T2T_SUBSTATE_WAIT_SELECT_SECTOR:
nxf24591c1cbeab2018-02-21 17:32:26 +05301094 return "RW_T2T_SUBSTATE_WAIT_SELECT_SECTOR";
nxpandroidc7611652015-09-23 16:42:05 +05301095 case RW_T2T_SUBSTATE_WAIT_READ_CC:
nxf24591c1cbeab2018-02-21 17:32:26 +05301096 return "RW_T2T_SUBSTATE_WAIT_READ_CC";
nxpandroidc7611652015-09-23 16:42:05 +05301097 case RW_T2T_SUBSTATE_WAIT_TLV_DETECT:
nxf24591c1cbeab2018-02-21 17:32:26 +05301098 return "RW_T2T_SUBSTATE_WAIT_TLV_DETECT";
nxpandroidc7611652015-09-23 16:42:05 +05301099 case RW_T2T_SUBSTATE_WAIT_FIND_LEN_FIELD_LEN:
nxf24591c1cbeab2018-02-21 17:32:26 +05301100 return "RW_T2T_SUBSTATE_WAIT_FIND_LEN_FIELD_LEN";
nxpandroidc7611652015-09-23 16:42:05 +05301101 case RW_T2T_SUBSTATE_WAIT_READ_TLV_LEN0:
nxf24591c1cbeab2018-02-21 17:32:26 +05301102 return "RW_T2T_SUBSTATE_WAIT_READ_TLV_LEN0";
nxpandroidc7611652015-09-23 16:42:05 +05301103 case RW_T2T_SUBSTATE_WAIT_READ_TLV_LEN1:
nxf24591c1cbeab2018-02-21 17:32:26 +05301104 return "RW_T2T_SUBSTATE_WAIT_READ_TLV_LEN1";
nxpandroidc7611652015-09-23 16:42:05 +05301105 case RW_T2T_SUBSTATE_WAIT_READ_TLV_VALUE:
nxf24591c1cbeab2018-02-21 17:32:26 +05301106 return "RW_T2T_SUBSTATE_WAIT_READ_TLV_VALUE";
nxpandroidc7611652015-09-23 16:42:05 +05301107 case RW_T2T_SUBSTATE_WAIT_READ_LOCKS:
nxf24591c1cbeab2018-02-21 17:32:26 +05301108 return "RW_T2T_SUBSTATE_WAIT_READ_LOCKS";
nxpandroidc7611652015-09-23 16:42:05 +05301109 case RW_T2T_SUBSTATE_WAIT_READ_NDEF_FIRST_BLOCK:
nxf24591c1cbeab2018-02-21 17:32:26 +05301110 return "RW_T2T_SUBSTATE_WAIT_READ_NDEF_FIRST_BLOCK";
nxpandroidc7611652015-09-23 16:42:05 +05301111 case RW_T2T_SUBSTATE_WAIT_READ_NDEF_LAST_BLOCK:
nxf24591c1cbeab2018-02-21 17:32:26 +05301112 return "RW_T2T_SUBSTATE_WAIT_READ_NDEF_LAST_BLOCK";
nxpandroidc7611652015-09-23 16:42:05 +05301113 case RW_T2T_SUBSTATE_WAIT_READ_TERM_TLV_BLOCK:
nxf24591c1cbeab2018-02-21 17:32:26 +05301114 return "RW_T2T_SUBSTATE_WAIT_READ_TERM_TLV_BLOCK";
nxpandroidc7611652015-09-23 16:42:05 +05301115 case RW_T2T_SUBSTATE_WAIT_READ_NDEF_NEXT_BLOCK:
nxf24591c1cbeab2018-02-21 17:32:26 +05301116 return "RW_T2T_SUBSTATE_WAIT_READ_NDEF_NEXT_BLOCK";
nxpandroidc7611652015-09-23 16:42:05 +05301117 case RW_T2T_SUBSTATE_WAIT_WRITE_NDEF_NEXT_BLOCK:
nxf24591c1cbeab2018-02-21 17:32:26 +05301118 return "RW_T2T_SUBSTATE_WAIT_WRITE_NDEF_NEXT_BLOCK";
nxpandroidc7611652015-09-23 16:42:05 +05301119 case RW_T2T_SUBSTATE_WAIT_WRITE_NDEF_LAST_BLOCK:
nxf24591c1cbeab2018-02-21 17:32:26 +05301120 return "RW_T2T_SUBSTATE_WAIT_WRITE_NDEF_LAST_BLOCK";
nxpandroidc7611652015-09-23 16:42:05 +05301121 case RW_T2T_SUBSTATE_WAIT_READ_NDEF_LEN_BLOCK:
nxf24591c1cbeab2018-02-21 17:32:26 +05301122 return "RW_T2T_SUBSTATE_WAIT_READ_NDEF_LEN_BLOCK";
nxpandroidc7611652015-09-23 16:42:05 +05301123 case RW_T2T_SUBSTATE_WAIT_WRITE_NDEF_LEN_BLOCK:
nxf24591c1cbeab2018-02-21 17:32:26 +05301124 return "RW_T2T_SUBSTATE_WAIT_WRITE_NDEF_LEN_BLOCK";
nxpandroidc7611652015-09-23 16:42:05 +05301125 case RW_T2T_SUBSTATE_WAIT_WRITE_NDEF_LEN_NEXT_BLOCK:
nxf24591c1cbeab2018-02-21 17:32:26 +05301126 return "RW_T2T_SUBSTATE_WAIT_WRITE_NDEF_LEN_NEXT_BLOCK";
nxpandroidc7611652015-09-23 16:42:05 +05301127 case RW_T2T_SUBSTATE_WAIT_WRITE_TERM_TLV_CMPLT:
nxf24591c1cbeab2018-02-21 17:32:26 +05301128 return "RW_T2T_SUBSTATE_WAIT_WRITE_TERM_TLV_CMPLT";
nxpandroidc7611652015-09-23 16:42:05 +05301129 default:
nxf24591c1cbeab2018-02-21 17:32:26 +05301130 return "???? UNKNOWN SUBSTATE";
nxpandroid8f6d0532017-07-12 18:25:30 +05301131 }
nxpandroidc7611652015-09-23 16:42:05 +05301132}