blob: e27890030eba273a44e28f029678c389b2ae4754 [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 ******************************************************************************/
nxpandroidc7611652015-09-23 16:42:05 +053018
nxpandroidc7611652015-09-23 16:42:05 +053019/******************************************************************************
20 *
21 * This file contains the implementation for Type 3 tag in Reader/Writer
22 * mode.
23 *
24 ******************************************************************************/
25#include <string.h>
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 "nci_hmsgs.h"
nxpandroidc7611652015-09-23 16:42:05 +053034#include "nfc_api.h"
35#include "nfc_int.h"
nxpandroidc7611652015-09-23 16:42:05 +053036#include "rw_api.h"
37#include "rw_int.h"
nxf24591c1cbeab2018-02-21 17:32:26 +053038#include "trace_api.h"
39
40using android::base::StringPrintf;
41
42extern bool nfc_debug_enabled;
nxpandroidc7611652015-09-23 16:42:05 +053043
44/* Definitions for constructing t3t command messages */
nxpandroid8f6d0532017-07-12 18:25:30 +053045#define RW_T3T_FL_PADDING 0x01 /* Padding needed for last NDEF block */
46/* Maximum number of NDEF blocks updates that can fit into one command (when all
47 * block-numbers are < 256) */
48#define RW_T3T_MAX_NDEF_BLOCKS_PER_UPDATE_1_BYTE_FORMAT (13)
49/* Maximum number of NDEF blocks updates that can fit into one command (when all
50 * block-numbers are >= 256) */
51#define RW_T3T_MAX_NDEF_BLOCKS_PER_UPDATE_2_BYTE_FORMAT (12)
nxpandroidc7611652015-09-23 16:42:05 +053052
53/* Definitions for SENSF_RES */
nxpandroid8f6d0532017-07-12 18:25:30 +053054/* Offset of RD in SENSF_RES from NCI_POLL NTF (includes 1 byte SENSF_RES
55 * length) */
56#define RW_T3T_SENSF_RES_RD_OFFSET 17
57#define RW_T3T_SENSF_RES_RD_LEN 2 /* Size of RD in SENSF_RES */
nxpandroidc7611652015-09-23 16:42:05 +053058
59/* Timeout definitions for commands */
nxpandroid8f6d0532017-07-12 18:25:30 +053060#define RW_T3T_POLL_CMD_TIMEOUT_TICKS \
61 ((RW_T3T_TOUT_RESP * 2 * QUICK_TIMER_TICKS_PER_SEC) / 1000)
62#define RW_T3T_DEFAULT_CMD_TIMEOUT_TICKS \
63 ((RW_T3T_TOUT_RESP * QUICK_TIMER_TICKS_PER_SEC) / 1000)
64#define RW_T3T_RAW_FRAME_CMD_TIMEOUT_TICKS \
65 (RW_T3T_DEFAULT_CMD_TIMEOUT_TICKS * 4)
66#define RW_T3T_MIN_TIMEOUT_TICKS 10
nxpandroidc7611652015-09-23 16:42:05 +053067
68/* Macro to extract major version from NDEF version byte */
nxf24591c1cbeab2018-02-21 17:32:26 +053069#define T3T_GET_MAJOR_VERSION(ver) ((ver) >> 4)
nxpandroidc7611652015-09-23 16:42:05 +053070
71/* Enumeration of API commands */
nxpandroid8f6d0532017-07-12 18:25:30 +053072enum {
73 RW_T3T_CMD_DETECT_NDEF,
74 RW_T3T_CMD_CHECK_NDEF,
75 RW_T3T_CMD_UPDATE_NDEF,
76 RW_T3T_CMD_CHECK,
77 RW_T3T_CMD_UPDATE,
78 RW_T3T_CMD_SEND_RAW_FRAME,
79 RW_T3T_CMD_GET_SYSTEM_CODES,
80 RW_T3T_CMD_FORMAT,
81 RW_T3T_CMD_SET_READ_ONLY_SOFT,
82 RW_T3T_CMD_SET_READ_ONLY_HARD,
nxpandroidc7611652015-09-23 16:42:05 +053083
nxpandroid8f6d0532017-07-12 18:25:30 +053084 RW_T3T_CMD_MAX
nxpandroidc7611652015-09-23 16:42:05 +053085};
86
87/* RW_CBACK events corresponding to API comands */
nxpandroid8f6d0532017-07-12 18:25:30 +053088const uint8_t rw_t3t_api_res_evt[RW_T3T_CMD_MAX] = {
89 RW_T3T_NDEF_DETECT_EVT, /* RW_T3T_CMD_DETECT_NDEF */
90 RW_T3T_CHECK_CPLT_EVT, /* RW_T3T_CMD_CHECK_NDEF */
91 RW_T3T_UPDATE_CPLT_EVT, /* RW_T3T_CMD_UPDATE_NDEF */
92 RW_T3T_CHECK_CPLT_EVT, /* RW_T3T_CMD_CHECK */
93 RW_T3T_UPDATE_CPLT_EVT, /* RW_T3T_CMD_UPDATE */
94 RW_T3T_RAW_FRAME_EVT, /* RW_T3T_CMD_SEND_RAW_FRAME */
95 RW_T3T_GET_SYSTEM_CODES_EVT, /* RW_T3T_CMD_GET_SYSTEM_CODES */
96 RW_T3T_FORMAT_CPLT_EVT, /* RW_T3T_CMD_FORMAT */
97 RW_T3T_SET_READ_ONLY_CPLT_EVT /* RW_T3T_CMD_SET_READ_ONLY */
nxpandroidc7611652015-09-23 16:42:05 +053098};
99
100/* States */
nxpandroid8f6d0532017-07-12 18:25:30 +0530101enum {
102 RW_T3T_STATE_NOT_ACTIVATED,
103 RW_T3T_STATE_IDLE,
104 RW_T3T_STATE_COMMAND_PENDING
nxpandroidc7611652015-09-23 16:42:05 +0530105};
106
107/* Sub-states */
nxpandroid8f6d0532017-07-12 18:25:30 +0530108enum {
109 /* Sub states for formatting Felica-Lite */
110 RW_T3T_FMT_SST_POLL_FELICA_LITE, /* Waiting for POLL Felica-Lite response (for
111 formatting) */
112 RW_T3T_FMT_SST_CHECK_MC_BLK, /* Waiting for Felica-Lite MC (MemoryControl)
113 block-read to complete */
114 RW_T3T_FMT_SST_UPDATE_MC_BLK, /* Waiting for Felica-Lite MC (MemoryControl)
115 block-write to complete */
116 RW_T3T_FMT_SST_UPDATE_NDEF_ATTRIB, /* Waiting for NDEF attribute block-write
117 to complete */
nxpandroidc7611652015-09-23 16:42:05 +0530118
nxpandroid8f6d0532017-07-12 18:25:30 +0530119 /* Sub states for setting Felica-Lite read only */
120 RW_T3T_SRO_SST_POLL_FELICA_LITE, /* Waiting for POLL Felica-Lite response (for
121 setting read only) */
122 RW_T3T_SRO_SST_UPDATE_NDEF_ATTRIB, /* Waiting for NDEF attribute block-write
123 to complete */
124 RW_T3T_SRO_SST_CHECK_MC_BLK, /* Waiting for Felica-Lite MC (MemoryControl)
125 block-read to complete */
126 RW_T3T_SRO_SST_UPDATE_MC_BLK /* Waiting for Felica-Lite MC (MemoryControl)
127 block-write to complete */
nxpandroidc7611652015-09-23 16:42:05 +0530128};
129
nxf24591c1cbeab2018-02-21 17:32:26 +0530130static std::string rw_t3t_cmd_str(uint8_t cmd_id);
131static std::string rw_t3t_state_str(uint8_t state_id);
nxpandroidc7611652015-09-23 16:42:05 +0530132
nxpandroidc7611652015-09-23 16:42:05 +0530133/* Local static functions */
nxpandroid8f6d0532017-07-12 18:25:30 +0530134static void rw_t3t_update_ndef_flag(uint8_t* p_flag);
nxf24591c1cbeab2018-02-21 17:32:26 +0530135static tNFC_STATUS rw_t3t_unselect();
nxpandroid8f6d0532017-07-12 18:25:30 +0530136static NFC_HDR* rw_t3t_get_cmd_buf(void);
137static tNFC_STATUS rw_t3t_send_to_lower(NFC_HDR* p_msg);
138static void rw_t3t_handle_get_system_codes_cplt(void);
139static void rw_t3t_handle_get_sc_poll_rsp(tRW_T3T_CB* p_cb, uint8_t nci_status,
140 uint8_t num_responses,
141 uint8_t sensf_res_buf_size,
142 uint8_t* p_sensf_res_buf);
143static void rw_t3t_handle_ndef_detect_poll_rsp(tRW_T3T_CB* p_cb,
144 uint8_t nci_status,
nxf24591c1cbeab2018-02-21 17:32:26 +0530145 uint8_t num_responses);
nxpandroid8f6d0532017-07-12 18:25:30 +0530146static void rw_t3t_handle_fmt_poll_rsp(tRW_T3T_CB* p_cb, uint8_t nci_status,
nxf24591c1cbeab2018-02-21 17:32:26 +0530147 uint8_t num_responses);
nxpandroid8f6d0532017-07-12 18:25:30 +0530148static void rw_t3t_handle_sro_poll_rsp(tRW_T3T_CB* p_cb, uint8_t nci_status,
nxf24591c1cbeab2018-02-21 17:32:26 +0530149 uint8_t num_responses);
nxpandroidc7611652015-09-23 16:42:05 +0530150
nxpandroid8f6d0532017-07-12 18:25:30 +0530151/* Default NDEF attribute information block (used when formatting Felica-Lite
152 * tags) */
153/* NBr (max block reads per cmd)*/
154#define RW_T3T_DEFAULT_FELICALITE_NBR 4
155/* NBw (max block write per cmd)*/
156#define RW_T3T_DEFAULT_FELICALITE_NBW 1
157#define RW_T3T_DEFAULT_FELICALITE_NMAXB (T3T_FELICALITE_NMAXB)
158#define RW_T3T_DEFAULT_FELICALITE_ATTRIB_INFO_CHECKSUM \
159 ((T3T_MSG_NDEF_VERSION + RW_T3T_DEFAULT_FELICALITE_NBR + \
160 RW_T3T_DEFAULT_FELICALITE_NBW + (RW_T3T_DEFAULT_FELICALITE_NMAXB >> 8) + \
161 (RW_T3T_DEFAULT_FELICALITE_NMAXB & 0xFF) + T3T_MSG_NDEF_WRITEF_OFF + \
162 T3T_MSG_NDEF_RWFLAG_RW) & \
163 0xFFFF)
nxpandroidc7611652015-09-23 16:42:05 +0530164
nxpandroid8f6d0532017-07-12 18:25:30 +0530165const uint8_t rw_t3t_default_attrib_info[T3T_MSG_BLOCKSIZE] = {
166 T3T_MSG_NDEF_VERSION, /* Ver */
167 RW_T3T_DEFAULT_FELICALITE_NBR, /* NBr (max block reads per cmd)*/
168 RW_T3T_DEFAULT_FELICALITE_NBW, /* NBw (max block write per cmd)*/
169 (RW_T3T_DEFAULT_FELICALITE_NMAXB >> 8), /* Nmaxb (max size in blocks) */
170 (RW_T3T_DEFAULT_FELICALITE_NMAXB & 0xFF), /* Nmaxb (max size in blocks) */
171 0, 0, 0, 0, /* Unused */
172 T3T_MSG_NDEF_WRITEF_OFF, /* WriteF */
173 T3T_MSG_NDEF_RWFLAG_RW, /* RW Flag */
174 0, 0, 0, /* Ln (current size in bytes) */
nxpandroidc7611652015-09-23 16:42:05 +0530175
nxpandroid8f6d0532017-07-12 18:25:30 +0530176 (RW_T3T_DEFAULT_FELICALITE_ATTRIB_INFO_CHECKSUM >>
177 8), /* checksum (high-byte) */
178 (RW_T3T_DEFAULT_FELICALITE_ATTRIB_INFO_CHECKSUM &
179 0xFF) /* checksum (low-byte) */
nxpandroidc7611652015-09-23 16:42:05 +0530180
181};
182
183/* This is (T/t3t * 4^E) , E is the index of the array. The unit is .0001 ms */
nxpandroid8f6d0532017-07-12 18:25:30 +0530184static const uint32_t rw_t3t_mrti_base[] = {302, 1208, 4832, 19328};
nxpandroidc7611652015-09-23 16:42:05 +0530185
186/*******************************************************************************
187**
188** Function rw_t3t_check_timeout
189**
190** Description The timeout value is a + b * number_blocks)
191**
192** Returns timeout value in ticks
193**
194*******************************************************************************/
nxpandroid8f6d0532017-07-12 18:25:30 +0530195static uint32_t rw_t3t_check_timeout(uint16_t num_blocks) {
196 tRW_T3T_CB* p_cb = &rw_cb.tcb.t3t;
197 uint32_t timeout;
198 uint32_t extra;
nxpandroidc7611652015-09-23 16:42:05 +0530199
nxpandroid8f6d0532017-07-12 18:25:30 +0530200 timeout = (p_cb->check_tout_a + num_blocks * p_cb->check_tout_b) *
201 QUICK_TIMER_TICKS_PER_SEC / 1000000;
202 /* allow some extra time for driver */
203 extra = (timeout / 10) + RW_T3T_MIN_TIMEOUT_TICKS;
204 timeout += extra;
nxpandroidc7611652015-09-23 16:42:05 +0530205
nxpandroid8f6d0532017-07-12 18:25:30 +0530206 return timeout;
nxpandroidc7611652015-09-23 16:42:05 +0530207}
208
209/*******************************************************************************
210**
211** Function rw_t3t_update_timeout
212**
213** Description The timeout value is a + b * number_blocks)
214**
215** Returns timeout value in ticks
216**
217*******************************************************************************/
nxpandroid8f6d0532017-07-12 18:25:30 +0530218static uint32_t rw_t3t_update_timeout(uint16_t num_blocks) {
219 tRW_T3T_CB* p_cb = &rw_cb.tcb.t3t;
220 uint32_t timeout;
221 uint32_t extra;
nxpandroidc7611652015-09-23 16:42:05 +0530222
nxpandroid8f6d0532017-07-12 18:25:30 +0530223 timeout = (p_cb->update_tout_a + num_blocks * p_cb->update_tout_b) *
224 QUICK_TIMER_TICKS_PER_SEC / 1000000;
225 /* allow some extra time for driver */
226 extra = (timeout / 10) + RW_T3T_MIN_TIMEOUT_TICKS;
227 timeout += extra;
nxpandroidc7611652015-09-23 16:42:05 +0530228
nxpandroid8f6d0532017-07-12 18:25:30 +0530229 return timeout;
nxpandroidc7611652015-09-23 16:42:05 +0530230}
231/*******************************************************************************
232**
233** Function rw_t3t_process_error
234**
235** Description Process error (timeout or CRC error)
236**
237** Returns none
238**
239*******************************************************************************/
nxpandroid8f6d0532017-07-12 18:25:30 +0530240void rw_t3t_process_error(tNFC_STATUS status) {
241 tRW_T3T_CB* p_cb = &rw_cb.tcb.t3t;
242 uint8_t evt;
243 tRW_DATA evt_data;
244 NFC_HDR* p_cmd_buf;
nxpandroidc7611652015-09-23 16:42:05 +0530245
nxpandroid8f6d0532017-07-12 18:25:30 +0530246 if (p_cb->rw_state == RW_T3T_STATE_COMMAND_PENDING) {
247 if (p_cb->cur_cmd == RW_T3T_CMD_GET_SYSTEM_CODES) {
248 /* For GetSystemCode: tag did not respond to requested POLL */
249 rw_t3t_handle_get_system_codes_cplt();
250 return;
nxpandroidc7611652015-09-23 16:42:05 +0530251 }
nxpandroid8f6d0532017-07-12 18:25:30 +0530252 /* Retry sending command if retry-count < max */
253 else if (rw_cb.cur_retry < RW_MAX_RETRIES) {
254 /* retry sending the command */
255 rw_cb.cur_retry++;
256
nxf24591c1cbeab2018-02-21 17:32:26 +0530257 DLOG_IF(INFO, nfc_debug_enabled)
258 << StringPrintf("T3T retransmission attempt %i of %i",
259 rw_cb.cur_retry, RW_MAX_RETRIES);
nxpandroid8f6d0532017-07-12 18:25:30 +0530260
261 /* allocate a new buffer for message */
262 p_cmd_buf = rw_t3t_get_cmd_buf();
263 if (p_cmd_buf != NULL) {
264 memcpy(p_cmd_buf, p_cb->p_cur_cmd_buf, sizeof(NFC_HDR) +
265 p_cb->p_cur_cmd_buf->offset +
266 p_cb->p_cur_cmd_buf->len);
267
268 if (rw_t3t_send_to_lower(p_cmd_buf) == NFC_STATUS_OK) {
269 /* Start timer for waiting for response */
270 nfc_start_quick_timer(&p_cb->timer, NFC_TTYPE_RW_T3T_RESPONSE,
271 p_cb->cur_tout);
272 return;
273 } else {
274 /* failure - could not send buffer */
275 GKI_freebuf(p_cmd_buf);
276 }
277 }
278 } else {
nxf24591c1cbeab2018-02-21 17:32:26 +0530279 DLOG_IF(INFO, nfc_debug_enabled) << StringPrintf(
280 "T3T maximum retransmission attempts reached (%i)", RW_MAX_RETRIES);
nxpandroidc7611652015-09-23 16:42:05 +0530281 }
nxpandroid8f6d0532017-07-12 18:25:30 +0530282
nxf24591c1cbeab2018-02-21 17:32:26 +0530283#if (RW_STATS_INCLUDED == TRUE)
nxpandroid8f6d0532017-07-12 18:25:30 +0530284 /* update failure count */
285 rw_main_update_fail_stats();
286#endif /* RW_STATS_INCLUDED */
287
288 p_cb->rw_state = RW_T3T_STATE_IDLE;
289
290 /* Notify app of result (if there was a pending command) */
291 if (p_cb->cur_cmd < RW_T3T_CMD_MAX) {
292 /* If doing presence check, use status=NFC_STATUS_FAILED, otherwise
293 * NFC_STATUS_TIMEOUT */
294 evt_data.status = status;
295 evt = rw_t3t_api_res_evt[p_cb->cur_cmd];
296
297 /* Set additional flags for RW_T3T_NDEF_DETECT_EVT */
298 if (evt == RW_T3T_NDEF_DETECT_EVT) {
299 evt_data.ndef.flags = RW_NDEF_FL_UNKNOWN;
300 rw_t3t_update_ndef_flag(&evt_data.ndef.flags);
301 }
302
303 (*(rw_cb.p_cback))(evt, &evt_data);
304 }
305 } else {
306 evt_data.status = status;
307 (*(rw_cb.p_cback))(RW_T3T_INTF_ERROR_EVT, &evt_data);
308 }
nxpandroidc7611652015-09-23 16:42:05 +0530309}
310
311/*******************************************************************************
312**
313** Function rw_t3t_start_poll_timer
314**
315** Description Start the timer for T3T POLL Command
316**
317** Returns none
318**
319*******************************************************************************/
nxpandroid8f6d0532017-07-12 18:25:30 +0530320void rw_t3t_start_poll_timer(tRW_T3T_CB* p_cb) {
321 nfc_start_quick_timer(&p_cb->poll_timer, NFC_TTYPE_RW_T3T_RESPONSE,
322 RW_T3T_POLL_CMD_TIMEOUT_TICKS);
nxpandroidc7611652015-09-23 16:42:05 +0530323}
nxpandroid8f6d0532017-07-12 18:25:30 +0530324
nxpandroidc7611652015-09-23 16:42:05 +0530325/*******************************************************************************
326**
327** Function rw_t3t_handle_nci_poll_ntf
328**
329** Description Handle NCI_T3T_POLLING_NTF
330**
331** Returns none
332**
333*******************************************************************************/
nxpandroid8f6d0532017-07-12 18:25:30 +0530334void rw_t3t_handle_nci_poll_ntf(uint8_t nci_status, uint8_t num_responses,
335 uint8_t sensf_res_buf_size,
336 uint8_t* p_sensf_res_buf) {
337 tRW_DATA evt_data;
338 tRW_T3T_CB* p_cb = &rw_cb.tcb.t3t;
nxpandroidc7611652015-09-23 16:42:05 +0530339
nxpandroid8f6d0532017-07-12 18:25:30 +0530340 /* stop timer for poll response */
nxf24591c1cbeab2018-02-21 17:32:26 +0530341 nfc_stop_quick_timer(&p_cb->poll_timer);
nxpandroidc7611652015-09-23 16:42:05 +0530342
nxpandroid8f6d0532017-07-12 18:25:30 +0530343 /* Stop t3t timer (if started) */
344 if (p_cb->flags & RW_T3T_FL_W4_PRESENCE_CHECK_POLL_RSP) {
345 p_cb->flags &= ~RW_T3T_FL_W4_PRESENCE_CHECK_POLL_RSP;
346 evt_data.status = nci_status;
347 p_cb->rw_state = RW_T3T_STATE_IDLE;
nxf24591c1cbeab2018-02-21 17:32:26 +0530348 (*(rw_cb.p_cback))(RW_T3T_PRESENCE_CHECK_EVT, &evt_data);
nxpandroid8f6d0532017-07-12 18:25:30 +0530349 } else if (p_cb->flags & RW_T3T_FL_W4_GET_SC_POLL_RSP) {
350 /* Handle POLL ntf in response to get system codes */
351 p_cb->flags &= ~RW_T3T_FL_W4_GET_SC_POLL_RSP;
352 rw_t3t_handle_get_sc_poll_rsp(p_cb, nci_status, num_responses,
353 sensf_res_buf_size, p_sensf_res_buf);
354 } else if (p_cb->flags & RW_T3T_FL_W4_FMT_FELICA_LITE_POLL_RSP) {
355 /* Handle POLL ntf in response to get system codes */
356 p_cb->flags &= ~RW_T3T_FL_W4_FMT_FELICA_LITE_POLL_RSP;
nxf24591c1cbeab2018-02-21 17:32:26 +0530357 rw_t3t_handle_fmt_poll_rsp(p_cb, nci_status, num_responses);
nxpandroid8f6d0532017-07-12 18:25:30 +0530358 } else if (p_cb->flags & RW_T3T_FL_W4_SRO_FELICA_LITE_POLL_RSP) {
359 /* Handle POLL ntf in response to get system codes */
360 p_cb->flags &= ~RW_T3T_FL_W4_SRO_FELICA_LITE_POLL_RSP;
nxf24591c1cbeab2018-02-21 17:32:26 +0530361 rw_t3t_handle_sro_poll_rsp(p_cb, nci_status, num_responses);
nxpandroid8f6d0532017-07-12 18:25:30 +0530362 } else if (p_cb->flags & RW_T3T_FL_W4_NDEF_DETECT_POLL_RSP) {
363 /* Handle POLL ntf in response to ndef detection */
364 p_cb->flags &= ~RW_T3T_FL_W4_NDEF_DETECT_POLL_RSP;
nxf24591c1cbeab2018-02-21 17:32:26 +0530365 rw_t3t_handle_ndef_detect_poll_rsp(p_cb, nci_status, num_responses);
nxpandroid8f6d0532017-07-12 18:25:30 +0530366 } else {
367 /* Handle POLL ntf in response to RW_T3tPoll */
368 evt_data.t3t_poll.status = nci_status;
369 if (evt_data.t3t_poll.status == NCI_STATUS_OK) {
370 evt_data.t3t_poll.rc = p_cb->cur_poll_rc;
371 evt_data.t3t_poll.response_num = num_responses;
372 evt_data.t3t_poll.response_bufsize = sensf_res_buf_size;
373 evt_data.t3t_poll.response_buf = p_sensf_res_buf;
nxpandroidc7611652015-09-23 16:42:05 +0530374 }
nxpandroidc7611652015-09-23 16:42:05 +0530375
nxpandroid8f6d0532017-07-12 18:25:30 +0530376 p_cb->rw_state = RW_T3T_STATE_IDLE;
377 (*(rw_cb.p_cback))(RW_T3T_POLL_EVT, &evt_data);
378 }
nxpandroidc7611652015-09-23 16:42:05 +0530379}
380
nxpandroidc7611652015-09-23 16:42:05 +0530381/*******************************************************************************
382**
383** Function rw_t3t_handle_get_system_codes_cplt
384**
385** Description Notify upper layer of system codes
386**
387** Returns none
388**
389*******************************************************************************/
nxpandroid8f6d0532017-07-12 18:25:30 +0530390void rw_t3t_handle_get_system_codes_cplt(void) {
391 tRW_T3T_CB* p_cb = &rw_cb.tcb.t3t;
392 tRW_DATA evt_data;
393 uint8_t i;
nxpandroidc7611652015-09-23 16:42:05 +0530394
nxpandroid8f6d0532017-07-12 18:25:30 +0530395 evt_data.t3t_sc.status = NFC_STATUS_OK;
396 evt_data.t3t_sc.num_system_codes = p_cb->num_system_codes;
397 evt_data.t3t_sc.p_system_codes = p_cb->system_codes;
nxpandroidc7611652015-09-23 16:42:05 +0530398
nxf24591c1cbeab2018-02-21 17:32:26 +0530399 DLOG_IF(INFO, nfc_debug_enabled) << StringPrintf(
400 "number of systems: %i", evt_data.t3t_sc.num_system_codes);
nxpandroid8f6d0532017-07-12 18:25:30 +0530401 for (i = 0; i < evt_data.t3t_sc.num_system_codes; i++) {
nxf24591c1cbeab2018-02-21 17:32:26 +0530402 DLOG_IF(INFO, nfc_debug_enabled) << StringPrintf(
403 "system %i: %04X", i, evt_data.t3t_sc.p_system_codes[i]);
nxpandroid8f6d0532017-07-12 18:25:30 +0530404 }
nxpandroidc7611652015-09-23 16:42:05 +0530405
nxpandroid8f6d0532017-07-12 18:25:30 +0530406 p_cb->rw_state = RW_T3T_STATE_IDLE;
407 (*(rw_cb.p_cback))(RW_T3T_GET_SYSTEM_CODES_EVT, &evt_data);
nxpandroidc7611652015-09-23 16:42:05 +0530408}
409
410/*******************************************************************************
411**
412** Function rw_t3t_format_cplt
413**
414** Description Notify upper layer of format complete
415**
416** Returns none
417**
418*******************************************************************************/
nxpandroid8f6d0532017-07-12 18:25:30 +0530419void rw_t3t_format_cplt(tNFC_STATUS status) {
420 tRW_T3T_CB* p_cb = &rw_cb.tcb.t3t;
421 tRW_DATA evt_data;
nxpandroidc7611652015-09-23 16:42:05 +0530422
nxpandroid8f6d0532017-07-12 18:25:30 +0530423 p_cb->rw_state = RW_T3T_STATE_IDLE;
nxpandroidc7611652015-09-23 16:42:05 +0530424
nxpandroid8f6d0532017-07-12 18:25:30 +0530425 /* Update ndef info */
426 p_cb->ndef_attrib.status = status;
427 if (status == NFC_STATUS_OK) {
428 p_cb->ndef_attrib.version = T3T_MSG_NDEF_VERSION;
429 p_cb->ndef_attrib.nbr = RW_T3T_DEFAULT_FELICALITE_NBR;
430 p_cb->ndef_attrib.nbw = RW_T3T_DEFAULT_FELICALITE_NBW;
431 p_cb->ndef_attrib.nmaxb = RW_T3T_DEFAULT_FELICALITE_NMAXB;
432 p_cb->ndef_attrib.writef = T3T_MSG_NDEF_WRITEF_OFF;
433 p_cb->ndef_attrib.rwflag = T3T_MSG_NDEF_RWFLAG_RW;
434 p_cb->ndef_attrib.ln = 0;
435 }
nxpandroidc7611652015-09-23 16:42:05 +0530436
nxpandroid8f6d0532017-07-12 18:25:30 +0530437 /* Notify upper layer of format complete */
438 evt_data.status = status;
439 (*(rw_cb.p_cback))(RW_T3T_FORMAT_CPLT_EVT, &evt_data);
nxpandroidc7611652015-09-23 16:42:05 +0530440}
441
442/*******************************************************************************
443**
444** Function rw_t3t_set_readonly_cplt
445**
446** Description Notify upper layer of set read only complete
447**
448** Returns none
449**
450*******************************************************************************/
nxpandroid8f6d0532017-07-12 18:25:30 +0530451void rw_t3t_set_readonly_cplt(tNFC_STATUS status) {
452 tRW_T3T_CB* p_cb = &rw_cb.tcb.t3t;
453 tRW_DATA evt_data;
nxpandroidc7611652015-09-23 16:42:05 +0530454
nxpandroid8f6d0532017-07-12 18:25:30 +0530455 p_cb->rw_state = RW_T3T_STATE_IDLE;
nxpandroidc7611652015-09-23 16:42:05 +0530456
nxpandroid8f6d0532017-07-12 18:25:30 +0530457 /* Notify upper layer of format complete */
458 evt_data.status = status;
459 (*(rw_cb.p_cback))(RW_T3T_SET_READ_ONLY_CPLT_EVT, &evt_data);
nxpandroidc7611652015-09-23 16:42:05 +0530460}
461
462/*******************************************************************************
463**
464** Function rw_t3t_process_timeout
465**
466** Description Process timeout
467**
468** Returns none
469**
470*******************************************************************************/
nxpandroid8f6d0532017-07-12 18:25:30 +0530471void rw_t3t_process_timeout(TIMER_LIST_ENT* p_tle) {
472 tRW_T3T_CB* p_cb = &rw_cb.tcb.t3t;
473 tRW_DATA evt_data;
nxpandroidc7611652015-09-23 16:42:05 +0530474
nxpandroid8f6d0532017-07-12 18:25:30 +0530475 /* Check which timer timed out */
476 if (p_tle == &p_cb->timer) {
477/* UPDATE/CHECK response timeout */
nxf24591c1cbeab2018-02-21 17:32:26 +0530478LOG(ERROR) << StringPrintf("T3T timeout. state=%s cur_cmd=0x%02X (%s)",
479 rw_t3t_state_str(rw_cb.tcb.t3t.rw_state).c_str(),
480 rw_cb.tcb.t3t.cur_cmd,
481 rw_t3t_cmd_str(rw_cb.tcb.t3t.cur_cmd).c_str());
nxpandroidc7611652015-09-23 16:42:05 +0530482
nxf24591c1cbeab2018-02-21 17:32:26 +0530483rw_t3t_process_error(NFC_STATUS_TIMEOUT);
nxpandroid8f6d0532017-07-12 18:25:30 +0530484 } else {
nxf24591c1cbeab2018-02-21 17:32:26 +0530485 LOG(ERROR) << StringPrintf("T3T POLL timeout.");
nxpandroidc7611652015-09-23 16:42:05 +0530486
nxpandroid8f6d0532017-07-12 18:25:30 +0530487 /* POLL response timeout */
488 if (p_cb->flags & RW_T3T_FL_W4_PRESENCE_CHECK_POLL_RSP) {
489 /* POLL timeout for presence check */
490 p_cb->flags &= ~RW_T3T_FL_W4_PRESENCE_CHECK_POLL_RSP;
491 evt_data.status = NFC_STATUS_FAILED;
492 p_cb->rw_state = RW_T3T_STATE_IDLE;
nxf24591c1cbeab2018-02-21 17:32:26 +0530493 (*(rw_cb.p_cback))(RW_T3T_PRESENCE_CHECK_EVT, &evt_data);
nxpandroid8f6d0532017-07-12 18:25:30 +0530494 } else if (p_cb->flags & RW_T3T_FL_W4_GET_SC_POLL_RSP) {
495 /* POLL timeout for getting system codes */
496 p_cb->flags &= ~RW_T3T_FL_W4_GET_SC_POLL_RSP;
497 rw_t3t_handle_get_system_codes_cplt();
498 } else if (p_cb->flags & RW_T3T_FL_W4_FMT_FELICA_LITE_POLL_RSP) {
499 /* POLL timeout for formatting Felica Lite */
500 p_cb->flags &= ~RW_T3T_FL_W4_FMT_FELICA_LITE_POLL_RSP;
nxf24591c1cbeab2018-02-21 17:32:26 +0530501 LOG(ERROR) << StringPrintf("Felica-Lite tag not detected");
nxpandroid8f6d0532017-07-12 18:25:30 +0530502 rw_t3t_format_cplt(NFC_STATUS_FAILED);
503 } else if (p_cb->flags & RW_T3T_FL_W4_SRO_FELICA_LITE_POLL_RSP) {
504 /* POLL timeout for configuring Felica Lite read only */
505 p_cb->flags &= ~RW_T3T_FL_W4_SRO_FELICA_LITE_POLL_RSP;
nxf24591c1cbeab2018-02-21 17:32:26 +0530506 LOG(ERROR) << StringPrintf("Felica-Lite tag not detected");
nxpandroid8f6d0532017-07-12 18:25:30 +0530507 rw_t3t_set_readonly_cplt(NFC_STATUS_FAILED);
508 } else if (p_cb->flags & RW_T3T_FL_W4_NDEF_DETECT_POLL_RSP) {
509 /* POLL timeout for ndef detection */
510 p_cb->flags &= ~RW_T3T_FL_W4_NDEF_DETECT_POLL_RSP;
nxf24591c1cbeab2018-02-21 17:32:26 +0530511 rw_t3t_handle_ndef_detect_poll_rsp(p_cb, NFC_STATUS_TIMEOUT, 0);
nxpandroid8f6d0532017-07-12 18:25:30 +0530512 } else {
513 /* Timeout waiting for response for RW_T3tPoll */
514 evt_data.t3t_poll.status = NFC_STATUS_FAILED;
515 p_cb->rw_state = RW_T3T_STATE_IDLE;
nxf24591c1cbeab2018-02-21 17:32:26 +0530516 (*(rw_cb.p_cback))(RW_T3T_POLL_EVT, &evt_data);
nxpandroidc7611652015-09-23 16:42:05 +0530517 }
nxpandroid8f6d0532017-07-12 18:25:30 +0530518 }
nxpandroidc7611652015-09-23 16:42:05 +0530519}
520
nxpandroidc7611652015-09-23 16:42:05 +0530521/*******************************************************************************
522**
523** Function rw_t3t_process_frame_error
524**
525** Description Process frame crc error
526**
527** Returns none
528**
529*******************************************************************************/
nxpandroid8f6d0532017-07-12 18:25:30 +0530530void rw_t3t_process_frame_error(void) {
nxf24591c1cbeab2018-02-21 17:32:26 +0530531 LOG(ERROR) << StringPrintf("T3T frame error. state=%s cur_cmd=0x%02X (%s)",
532 rw_t3t_state_str(rw_cb.tcb.t3t.rw_state).c_str(),
533 rw_cb.tcb.t3t.cur_cmd,
534 rw_t3t_cmd_str(rw_cb.tcb.t3t.cur_cmd).c_str());
nxpandroidc7611652015-09-23 16:42:05 +0530535
nxf24591c1cbeab2018-02-21 17:32:26 +0530536#if (RW_STATS_INCLUDED == TRUE)
nxpandroid8f6d0532017-07-12 18:25:30 +0530537 /* Update stats */
538 rw_main_update_crc_error_stats();
539#endif /* RW_STATS_INCLUDED */
nxpandroidc7611652015-09-23 16:42:05 +0530540
nxpandroid8f6d0532017-07-12 18:25:30 +0530541 /* Process the error */
542 rw_t3t_process_error(NFC_STATUS_MSG_CORRUPTED);
nxpandroidc7611652015-09-23 16:42:05 +0530543}
544
545/*******************************************************************************
546**
547** Function rw_t3t_send_to_lower
548**
549** Description Send command to lower layer
550**
551** Returns status of the send
552**
553*******************************************************************************/
nxpandroid8f6d0532017-07-12 18:25:30 +0530554tNFC_STATUS rw_t3t_send_to_lower(NFC_HDR* p_msg) {
555 uint8_t* p;
nxpandroidc7611652015-09-23 16:42:05 +0530556
nxf24591c1cbeab2018-02-21 17:32:26 +0530557#if (RW_STATS_INCLUDED == TRUE)
nxpandroid8f6d0532017-07-12 18:25:30 +0530558 bool is_retry;
559 /* Update stats */
560 rw_main_update_tx_stats(p_msg->len, ((rw_cb.cur_retry == 0) ? false : true));
561#endif /* RW_STATS_INCLUDED */
nxpandroidc7611652015-09-23 16:42:05 +0530562
nxpandroid8f6d0532017-07-12 18:25:30 +0530563 /* Set NFC-F SoD field (payload len + 1) */
564 p_msg->offset -= 1; /* Point to SoD field */
565 p = (uint8_t*)(p_msg + 1) + p_msg->offset;
566 UINT8_TO_STREAM(p, (p_msg->len + 1));
567 p_msg->len += 1; /* Increment len to include SoD */
nxpandroidc7611652015-09-23 16:42:05 +0530568
nxpandroid8f6d0532017-07-12 18:25:30 +0530569 return (NFC_SendData(NFC_RF_CONN_ID, p_msg));
nxpandroidc7611652015-09-23 16:42:05 +0530570}
571
572/*****************************************************************************
573**
574** Function rw_t3t_get_cmd_buf
575**
576** Description Get a buffer for sending T3T messages
577**
nxpandroid8f6d0532017-07-12 18:25:30 +0530578** Returns NFC_HDR *
nxpandroidc7611652015-09-23 16:42:05 +0530579**
580*****************************************************************************/
nxpandroid8f6d0532017-07-12 18:25:30 +0530581NFC_HDR* rw_t3t_get_cmd_buf(void) {
582 NFC_HDR* p_cmd_buf;
nxpandroidc7611652015-09-23 16:42:05 +0530583
nxpandroid8f6d0532017-07-12 18:25:30 +0530584 p_cmd_buf = (NFC_HDR*)GKI_getpoolbuf(NFC_RW_POOL_ID);
585 if (p_cmd_buf != NULL) {
586 /* Reserve offset for NCI_DATA_HDR and NFC-F Sod (LEN) field */
587 p_cmd_buf->offset = NCI_MSG_OFFSET_SIZE + NCI_DATA_HDR_SIZE + 1;
588 p_cmd_buf->len = 0;
589 }
nxpandroidc7611652015-09-23 16:42:05 +0530590
nxpandroid8f6d0532017-07-12 18:25:30 +0530591 return (p_cmd_buf);
nxpandroidc7611652015-09-23 16:42:05 +0530592}
593
594/*****************************************************************************
595**
596** Function rw_t3t_send_cmd
597**
598** Description Send command to tag, and start timer for response
599**
600** Returns tNFC_STATUS
601**
602*****************************************************************************/
nxpandroid8f6d0532017-07-12 18:25:30 +0530603tNFC_STATUS rw_t3t_send_cmd(tRW_T3T_CB* p_cb, uint8_t rw_t3t_cmd,
604 NFC_HDR* p_cmd_buf, uint32_t timeout_ticks) {
605 tNFC_STATUS retval;
nxpandroidc7611652015-09-23 16:42:05 +0530606
nxpandroid8f6d0532017-07-12 18:25:30 +0530607 /* Indicate first attempt to send command, back up cmd buffer in case needed
608 * for retransmission */
609 rw_cb.cur_retry = 0;
610 memcpy(p_cb->p_cur_cmd_buf, p_cmd_buf,
611 sizeof(NFC_HDR) + p_cmd_buf->offset + p_cmd_buf->len);
nxpandroidc7611652015-09-23 16:42:05 +0530612
nxpandroid8f6d0532017-07-12 18:25:30 +0530613 p_cb->cur_cmd = rw_t3t_cmd;
614 p_cb->cur_tout = timeout_ticks;
615 p_cb->rw_state = RW_T3T_STATE_COMMAND_PENDING;
nxpandroidc7611652015-09-23 16:42:05 +0530616
nxpandroid8f6d0532017-07-12 18:25:30 +0530617 retval = rw_t3t_send_to_lower(p_cmd_buf);
618 if (retval == NFC_STATUS_OK) {
619 /* Start timer for waiting for response */
620 nfc_start_quick_timer(&p_cb->timer, NFC_TTYPE_RW_T3T_RESPONSE,
621 timeout_ticks);
622 } else {
623 /* Error sending */
624 p_cb->rw_state = RW_T3T_STATE_IDLE;
625 }
nxpandroidc7611652015-09-23 16:42:05 +0530626
nxf24591c1cbeab2018-02-21 17:32:26 +0530627 DLOG_IF(INFO, nfc_debug_enabled)
628 << StringPrintf("cur_tout: %d, timeout_ticks: %d ret:%d", p_cb->cur_tout,
629 timeout_ticks, retval);
nxpandroid8f6d0532017-07-12 18:25:30 +0530630 return (retval);
nxpandroidc7611652015-09-23 16:42:05 +0530631}
632
633/*****************************************************************************
634**
635** Function rw_t3t_send_update_ndef_attribute_cmd
636**
637** Description Send UPDATE command for Attribute Information
638**
639** Returns tNFC_STATUS
640**
641*****************************************************************************/
nxpandroid8f6d0532017-07-12 18:25:30 +0530642tNFC_STATUS rw_t3t_send_update_ndef_attribute_cmd(tRW_T3T_CB* p_cb,
643 bool write_in_progress) {
644 tNFC_STATUS retval = NFC_STATUS_OK;
645 NFC_HDR* p_cmd_buf;
nxf24591c1cbeab2018-02-21 17:32:26 +0530646 uint8_t *p_cmd_start, *p;
nxpandroid8f6d0532017-07-12 18:25:30 +0530647 uint16_t checksum, i;
648 uint8_t write_f;
649 uint32_t ln;
650 uint8_t* p_ndef_attr_info_start;
nxpandroidc7611652015-09-23 16:42:05 +0530651
nxpandroid8f6d0532017-07-12 18:25:30 +0530652 p_cmd_buf = rw_t3t_get_cmd_buf();
653 if (p_cmd_buf != NULL) {
654 /* Construct T3T message */
655 p = p_cmd_start = (uint8_t*)(p_cmd_buf + 1) + p_cmd_buf->offset;
nxpandroidc7611652015-09-23 16:42:05 +0530656
nxpandroid8f6d0532017-07-12 18:25:30 +0530657 /* Add UPDATE opcode to message */
658 UINT8_TO_STREAM(p, T3T_MSG_OPC_UPDATE_CMD);
nxpandroidc7611652015-09-23 16:42:05 +0530659
nxpandroid8f6d0532017-07-12 18:25:30 +0530660 /* Add IDm to message */
661 ARRAY_TO_STREAM(p, p_cb->peer_nfcid2, NCI_NFCID2_LEN);
nxpandroidc7611652015-09-23 16:42:05 +0530662
nxpandroid8f6d0532017-07-12 18:25:30 +0530663 /* Add Service code list */
664 UINT8_TO_STREAM(p, 1); /* Number of services (only 1 service: NDEF) */
665 UINT16_TO_STREAM(
666 p, T3T_MSG_NDEF_SC_RW); /* Service code (little-endian format) */
nxpandroidc7611652015-09-23 16:42:05 +0530667
nxpandroid8f6d0532017-07-12 18:25:30 +0530668 /* Add number of blocks in this UPDATE command */
669 UINT8_TO_STREAM(p, 1); /* Number of blocks to write in this command */
nxpandroidc7611652015-09-23 16:42:05 +0530670
nxpandroid8f6d0532017-07-12 18:25:30 +0530671 /* Block List element: the NDEF attribute information block (block 0) */
672 UINT8_TO_STREAM(p, T3T_MSG_MASK_TWO_BYTE_BLOCK_DESC_FORMAT);
673 UINT8_TO_STREAM(p, 0);
nxpandroidc7611652015-09-23 16:42:05 +0530674
nxpandroid8f6d0532017-07-12 18:25:30 +0530675 /* Add payload (Attribute information block) */
676 p_ndef_attr_info_start =
677 p; /* Save start of a NDEF attribute info block for checksum */
678 UINT8_TO_STREAM(p, T3T_MSG_NDEF_VERSION);
679 UINT8_TO_STREAM(p, p_cb->ndef_attrib.nbr);
680 UINT8_TO_STREAM(p, p_cb->ndef_attrib.nbw);
681 UINT16_TO_BE_STREAM(p, p_cb->ndef_attrib.nmaxb);
682 UINT32_TO_STREAM(p, 0);
nxpandroidc7611652015-09-23 16:42:05 +0530683
nxpandroid8f6d0532017-07-12 18:25:30 +0530684 /* If starting NDEF write: set WriteF=ON, and ln=current ndef length */
685 if (write_in_progress) {
686 write_f = T3T_MSG_NDEF_WRITEF_ON;
687 ln = p_cb->ndef_attrib.ln;
nxpandroidc7611652015-09-23 16:42:05 +0530688 }
nxpandroid8f6d0532017-07-12 18:25:30 +0530689 /* If finishing NDEF write: set WriteF=OFF, and ln=new ndef len */
690 else {
691 write_f = T3T_MSG_NDEF_WRITEF_OFF;
692 ln = p_cb->ndef_msg_len;
nxpandroidc7611652015-09-23 16:42:05 +0530693 }
nxpandroid8f6d0532017-07-12 18:25:30 +0530694 UINT8_TO_STREAM(p, write_f);
695 UINT8_TO_STREAM(p, p_cb->ndef_attrib.rwflag);
696 UINT8_TO_STREAM(p, (ln >> 16) & 0xFF); /* High byte (of 3) of Ln */
697 UINT8_TO_STREAM(p, (ln >> 8) & 0xFF); /* Middle byte (of 3) of Ln */
698 UINT8_TO_STREAM(p, (ln)&0xFF); /* Low byte (of 3) of Ln */
nxpandroidc7611652015-09-23 16:42:05 +0530699
nxpandroid8f6d0532017-07-12 18:25:30 +0530700 /* Calculate and append Checksum */
701 checksum = 0;
702 for (i = 0; i < T3T_MSG_NDEF_ATTR_INFO_SIZE; i++) {
703 checksum += p_ndef_attr_info_start[i];
704 }
705 UINT16_TO_BE_STREAM(p, checksum);
706
707 /* Calculate length of message */
708 p_cmd_buf->len = (uint16_t)(p - p_cmd_start);
709
710 /* Send the T3T message */
711 retval = rw_t3t_send_cmd(p_cb, RW_T3T_CMD_UPDATE_NDEF, p_cmd_buf,
712 rw_t3t_update_timeout(1));
713 } else {
714 retval = NFC_STATUS_NO_BUFFERS;
715 }
716
717 return (retval);
nxpandroidc7611652015-09-23 16:42:05 +0530718}
719
720/*****************************************************************************
721**
722** Function rw_t3t_send_next_ndef_update_cmd
723**
724** Description Send next segment of NDEF message to update
725**
726** Returns tNFC_STATUS
727**
728*****************************************************************************/
nxpandroid8f6d0532017-07-12 18:25:30 +0530729tNFC_STATUS rw_t3t_send_next_ndef_update_cmd(tRW_T3T_CB* p_cb) {
730 tNFC_STATUS retval = NFC_STATUS_OK;
731 uint16_t block_id;
732 uint16_t first_block_to_write;
733 uint16_t ndef_blocks_to_write, ndef_blocks_remaining;
734 uint32_t ndef_bytes_remaining, ndef_padding = 0;
735 uint8_t flags = 0;
736 uint8_t* p_cur_ndef_src_offset;
737 NFC_HDR* p_cmd_buf;
nxf24591c1cbeab2018-02-21 17:32:26 +0530738 uint8_t *p_cmd_start, *p;
nxpandroid8f6d0532017-07-12 18:25:30 +0530739 uint8_t blocks_per_update;
740 uint32_t timeout;
nxpandroidc7611652015-09-23 16:42:05 +0530741
nxpandroid8f6d0532017-07-12 18:25:30 +0530742 p_cmd_buf = rw_t3t_get_cmd_buf();
743 if (p_cmd_buf != NULL) {
744 /* Construct T3T message */
745 p = p_cmd_start = (uint8_t*)(p_cmd_buf + 1) + p_cmd_buf->offset;
nxpandroidc7611652015-09-23 16:42:05 +0530746
nxpandroid8f6d0532017-07-12 18:25:30 +0530747 /* Calculate number of ndef bytes remaining to write */
748 ndef_bytes_remaining = p_cb->ndef_msg_len - p_cb->ndef_msg_bytes_sent;
nxpandroidc7611652015-09-23 16:42:05 +0530749
nxpandroid8f6d0532017-07-12 18:25:30 +0530750 /* Calculate number of blocks remaining to write */
751 ndef_blocks_remaining =
752 (uint16_t)((ndef_bytes_remaining + 15) >>
753 4); /* ndef blocks remaining (rounded upward) */
nxpandroidc7611652015-09-23 16:42:05 +0530754
nxpandroid8f6d0532017-07-12 18:25:30 +0530755 /* Calculate first NDEF block ID for this UPDATE command */
756 first_block_to_write = (uint16_t)((p_cb->ndef_msg_bytes_sent >> 4) + 1);
nxpandroidc7611652015-09-23 16:42:05 +0530757
nxpandroid8f6d0532017-07-12 18:25:30 +0530758 /* Calculate max number of blocks per write. */
759 if ((first_block_to_write +
760 RW_T3T_MAX_NDEF_BLOCKS_PER_UPDATE_1_BYTE_FORMAT) < 0x100) {
761 /* All block-numbers are < 0x100 (i.e. can be specified using one-byte
762 * format) */
763 blocks_per_update = RW_T3T_MAX_NDEF_BLOCKS_PER_UPDATE_1_BYTE_FORMAT;
764 } else {
765 /* Block-numbers are >= 0x100 (i.e. need to be specified using two-byte
766 * format) */
767 blocks_per_update = RW_T3T_MAX_NDEF_BLOCKS_PER_UPDATE_2_BYTE_FORMAT;
nxpandroidc7611652015-09-23 16:42:05 +0530768 }
769
nxpandroid8f6d0532017-07-12 18:25:30 +0530770 /* Check if blocks_per_update is bigger than what peer allows */
771 if (blocks_per_update > p_cb->ndef_attrib.nbw)
772 blocks_per_update = p_cb->ndef_attrib.nbw;
773
774 /* Check if remaining blocks can fit into one UPDATE command */
775 if (ndef_blocks_remaining <= blocks_per_update) {
776 /* remaining blocks can fit into one UPDATE command */
777 ndef_blocks_to_write = ndef_blocks_remaining;
778 } else {
779 /* Remaining blocks cannot fit into one UPDATE command */
780 ndef_blocks_to_write = blocks_per_update;
781 }
782
783 /* Write to command header for UPDATE */
784
785 /* Add UPDATE opcode to message */
786 UINT8_TO_STREAM(p, T3T_MSG_OPC_UPDATE_CMD);
787
788 /* Add IDm to message */
789 ARRAY_TO_STREAM(p, p_cb->peer_nfcid2, NCI_NFCID2_LEN);
790
791 /* Add Service code list */
792 UINT8_TO_STREAM(p, 1); /* Number of services (only 1 service: NDEF) */
793 UINT16_TO_STREAM(
794 p, T3T_MSG_NDEF_SC_RW); /* Service code (little-endian format) */
795
796 /* Add number of blocks in this UPDATE command */
797 UINT8_TO_STREAM(
798 p,
799 ndef_blocks_to_write); /* Number of blocks to write in this command */
800 timeout = rw_t3t_update_timeout(ndef_blocks_to_write);
801
802 for (block_id = first_block_to_write;
803 block_id < (first_block_to_write + ndef_blocks_to_write); block_id++) {
804 if (block_id < 256) {
805 /* Block IDs 0-255 can be specified in '2-byte' format: byte0=0,
806 * byte1=blocknumber */
807 UINT8_TO_STREAM(
808 p, T3T_MSG_MASK_TWO_BYTE_BLOCK_DESC_FORMAT); /* byte0: len=1;
809 access-mode=0;
810 service code list
811 order=0 */
812 UINT8_TO_STREAM(p, block_id); /* byte1: block number */
813 } else {
814 /* Block IDs 256+ must be specified in '3-byte' format: byte0=80h,
815 * followed by blocknumber */
816 UINT8_TO_STREAM(
817 p,
818 0x00); /* byte0: len=0; access-mode=0; service code list order=0 */
819 UINT16_TO_STREAM(
820 p, block_id); /* byte1-2: block number in little-endian format */
821 }
822 }
823
824 /* Add NDEF payload */
825
826 /* If this sending last block of NDEF, check if padding is needed to make
827 * payload a multiple of 16 bytes */
828 if (ndef_blocks_to_write == ndef_blocks_remaining) {
829 ndef_padding = (16 - (ndef_bytes_remaining & 0x0F)) & 0x0F;
830 if (ndef_padding) {
831 flags |= RW_T3T_FL_PADDING;
832 ndef_blocks_to_write--; /* handle the last block separately if it needs
833 padding */
834 }
835 }
836
837 /* Add NDEF payload to the message */
838 p_cur_ndef_src_offset = &p_cb->ndef_msg[p_cb->ndef_msg_bytes_sent];
839
840 ARRAY_TO_STREAM(p, p_cur_ndef_src_offset, (ndef_blocks_to_write * 16));
841 p_cb->ndef_msg_bytes_sent += ((uint32_t)ndef_blocks_to_write * 16);
842
843 if (flags & RW_T3T_FL_PADDING) {
844 /* Add last of the NDEF message */
845 p_cur_ndef_src_offset = &p_cb->ndef_msg[p_cb->ndef_msg_bytes_sent];
846 ARRAY_TO_STREAM(p, p_cur_ndef_src_offset, (int)(16 - ndef_padding));
847 p_cb->ndef_msg_bytes_sent += (16 - ndef_padding);
848
849 /* Add padding */
850 memset(p, 0, ndef_padding);
851 p += ndef_padding;
852 }
853
854 /* Calculate length of message */
855 p_cmd_buf->len = (uint16_t)(p - p_cmd_start);
856
857 /* Send the T3T message */
858 retval = rw_t3t_send_cmd(p_cb, RW_T3T_CMD_UPDATE_NDEF, p_cmd_buf, timeout);
859 } else {
860 retval = NFC_STATUS_NO_BUFFERS;
861 }
862
863 return (retval);
nxpandroidc7611652015-09-23 16:42:05 +0530864}
865
nxpandroidc7611652015-09-23 16:42:05 +0530866/*****************************************************************************
867**
868** Function rw_t3t_send_next_ndef_check_cmd
869**
870** Description Send command for reading next segment of NDEF message
871**
872** Returns tNFC_STATUS
873**
874*****************************************************************************/
nxpandroid8f6d0532017-07-12 18:25:30 +0530875tNFC_STATUS rw_t3t_send_next_ndef_check_cmd(tRW_T3T_CB* p_cb) {
876 tNFC_STATUS retval = NFC_STATUS_OK;
877 uint16_t block_id;
878 uint16_t ndef_blocks_remaining, first_block_to_read, cur_blocks_to_read;
879 uint32_t ndef_bytes_remaining;
880 NFC_HDR* p_cmd_buf;
nxf24591c1cbeab2018-02-21 17:32:26 +0530881 uint8_t *p_cmd_start, *p;
nxpandroidc7611652015-09-23 16:42:05 +0530882
nxpandroid8f6d0532017-07-12 18:25:30 +0530883 p_cmd_buf = rw_t3t_get_cmd_buf();
884 if (p_cmd_buf != NULL) {
885 /* Construct T3T message */
886 p = p_cmd_start = (uint8_t*)(p_cmd_buf + 1) + p_cmd_buf->offset;
nxpandroidc7611652015-09-23 16:42:05 +0530887
nxpandroid8f6d0532017-07-12 18:25:30 +0530888 /* Calculate number of ndef bytes remaining to read */
889 ndef_bytes_remaining = p_cb->ndef_attrib.ln - p_cb->ndef_rx_offset;
nxpandroidc7611652015-09-23 16:42:05 +0530890
nxpandroid8f6d0532017-07-12 18:25:30 +0530891 /* Calculate number of blocks remaining to read */
892 ndef_blocks_remaining =
893 (uint16_t)((ndef_bytes_remaining + 15) >>
894 4); /* ndef blocks remaining (rounded upward) */
nxpandroidc7611652015-09-23 16:42:05 +0530895
nxpandroid8f6d0532017-07-12 18:25:30 +0530896 /* Calculate first NDEF block ID */
897 first_block_to_read = (uint16_t)((p_cb->ndef_rx_offset >> 4) + 1);
nxpandroidc7611652015-09-23 16:42:05 +0530898
nxpandroid8f6d0532017-07-12 18:25:30 +0530899 /* Check if remaining blocks can fit into one CHECK command */
900 if (ndef_blocks_remaining <= p_cb->ndef_attrib.nbr) {
901 /* remaining blocks can fit into one CHECK command */
902 cur_blocks_to_read = ndef_blocks_remaining;
903 p_cb->ndef_rx_readlen = ndef_bytes_remaining;
904 p_cb->flags |= RW_T3T_FL_IS_FINAL_NDEF_SEGMENT;
905 } else {
906 /* Remaining blocks cannot fit into one CHECK command */
907 cur_blocks_to_read =
908 p_cb->ndef_attrib
909 .nbr; /* Read maximum number of blocks allowed by the peer */
910 p_cb->ndef_rx_readlen = ((uint32_t)p_cb->ndef_attrib.nbr * 16);
nxpandroidc7611652015-09-23 16:42:05 +0530911 }
912
nxf24591c1cbeab2018-02-21 17:32:26 +0530913 DLOG_IF(INFO, nfc_debug_enabled) << StringPrintf(
914 "bytes_remaining: %i, cur_blocks_to_read: %i, is_final: %i",
nxpandroid8f6d0532017-07-12 18:25:30 +0530915 ndef_bytes_remaining, cur_blocks_to_read,
916 (p_cb->flags & RW_T3T_FL_IS_FINAL_NDEF_SEGMENT));
917
918 /* Add CHECK opcode to message */
919 UINT8_TO_STREAM(p, T3T_MSG_OPC_CHECK_CMD);
920
921 /* Add IDm to message */
922 ARRAY_TO_STREAM(p, p_cb->peer_nfcid2, NCI_NFCID2_LEN);
923
924 /* Add Service code list */
925 UINT8_TO_STREAM(p, 1); /* Number of services (only 1 service: NDEF) */
926
927 /* Service code (little-endian format) . If NDEF is read-only, then use
928 * T3T_MSG_NDEF_SC_RO, otherwise use T3T_MSG_NDEF_SC_RW */
929 if (p_cb->ndef_attrib.rwflag == T3T_MSG_NDEF_RWFLAG_RO) {
930 UINT16_TO_STREAM(p, T3T_MSG_NDEF_SC_RO);
931 } else {
932 UINT16_TO_STREAM(p, T3T_MSG_NDEF_SC_RW);
933 }
934
935 /* Add number of blocks in this CHECK command */
936 UINT8_TO_STREAM(
937 p, cur_blocks_to_read); /* Number of blocks to check in this command */
938
939 for (block_id = first_block_to_read;
940 block_id < (first_block_to_read + cur_blocks_to_read); block_id++) {
941 if (block_id < 256) {
942 /* Block IDs 0-255 can be specified in '2-byte' format: byte0=0,
943 * byte1=blocknumber */
944 UINT8_TO_STREAM(
945 p, T3T_MSG_MASK_TWO_BYTE_BLOCK_DESC_FORMAT); /* byte1: len=0;
946 access-mode=0;
947 service code list
948 order=0 */
949 UINT8_TO_STREAM(p, block_id); /* byte1: block number */
950 } else {
951 /* Block IDs 256+ must be specified in '3-byte' format: byte0=80h,
952 * followed by blocknumber */
953 UINT8_TO_STREAM(
954 p,
955 0x00); /* byte0: len=1; access-mode=0; service code list order=0 */
956 UINT16_TO_STREAM(
957 p, block_id); /* byte1-2: block number in little-endian format */
958 }
959 }
960
961 /* Calculate length of message */
962 p_cmd_buf->len = (uint16_t)(p - p_cmd_start);
963
964 /* Send the T3T message */
965 retval = rw_t3t_send_cmd(p_cb, RW_T3T_CMD_CHECK_NDEF, p_cmd_buf,
966 rw_t3t_check_timeout(cur_blocks_to_read));
967 } else {
968 retval = NFC_STATUS_NO_BUFFERS;
969 }
970
971 return (retval);
nxpandroidc7611652015-09-23 16:42:05 +0530972}
973
nxpandroidc7611652015-09-23 16:42:05 +0530974/*****************************************************************************
975**
976** Function rw_t3t_message_set_block_list
977**
978** Description Add block list to T3T message
979**
980** Returns Number of bytes added to message
981**
982*****************************************************************************/
nxpandroid8f6d0532017-07-12 18:25:30 +0530983void rw_t3t_message_set_block_list(tRW_T3T_CB* p_cb, uint8_t** p,
984 uint8_t num_blocks,
985 tT3T_BLOCK_DESC* p_t3t_blocks) {
986 uint16_t i, cur_service_code;
987 uint8_t service_code_idx, num_services = 0;
988 uint8_t* p_msg_num_services;
989 uint16_t service_list[T3T_MSG_SERVICE_LIST_MAX];
nxpandroidc7611652015-09-23 16:42:05 +0530990
nxpandroid8f6d0532017-07-12 18:25:30 +0530991 /* Add CHECK or UPDATE opcode to message */
992 UINT8_TO_STREAM(
993 (*p), ((p_cb->cur_cmd == RW_T3T_CMD_CHECK) ? T3T_MSG_OPC_CHECK_CMD
994 : T3T_MSG_OPC_UPDATE_CMD));
nxpandroidc7611652015-09-23 16:42:05 +0530995
nxpandroid8f6d0532017-07-12 18:25:30 +0530996 /* Add IDm to message */
997 ARRAY_TO_STREAM((*p), p_cb->peer_nfcid2, NCI_NFCID2_LEN);
nxpandroidc7611652015-09-23 16:42:05 +0530998
nxpandroid8f6d0532017-07-12 18:25:30 +0530999 /* Skip over Number of Services field */
1000 p_msg_num_services = (*p); /* pointer to Number of Services offset */
1001 (*p)++;
nxpandroidc7611652015-09-23 16:42:05 +05301002
nxpandroid8f6d0532017-07-12 18:25:30 +05301003 /* Count number of different services are specified in the list, and add
1004 * services to Service Code list */
1005 for (i = 0; i < num_blocks; i++) {
1006 cur_service_code = p_t3t_blocks[i].service_code;
nxpandroidc7611652015-09-23 16:42:05 +05301007
nxpandroid8f6d0532017-07-12 18:25:30 +05301008 /* Check if current service_code is already in the service_list */
1009 for (service_code_idx = 0; service_code_idx < num_services;
1010 service_code_idx++) {
1011 if (service_list[service_code_idx] == cur_service_code) break;
nxpandroidc7611652015-09-23 16:42:05 +05301012 }
1013
nxpandroid8f6d0532017-07-12 18:25:30 +05301014 if (service_code_idx == num_services) {
1015 /* Service not in the list yet. Add it. */
1016 service_list[service_code_idx] = cur_service_code;
1017 num_services++;
nxpandroidc7611652015-09-23 16:42:05 +05301018
nxpandroid8f6d0532017-07-12 18:25:30 +05301019 /* Add service code to T3T message */
1020 UINT16_TO_STREAM((*p), cur_service_code);
nxpandroidc7611652015-09-23 16:42:05 +05301021 }
nxpandroid8f6d0532017-07-12 18:25:30 +05301022 }
1023
1024 /* Add 'Number of Sservices' to the message */
1025 *p_msg_num_services = num_services;
1026
1027 /* Add 'number of blocks' to the message */
1028 UINT8_TO_STREAM((*p), num_blocks);
1029
1030 /* Add block descriptors */
1031 for (i = 0; i < num_blocks; i++) {
1032 cur_service_code = p_t3t_blocks[i].service_code;
1033
1034 /* Check if current service_code is already in the service_list */
1035 for (service_code_idx = 0; service_code_idx < num_services;
1036 service_code_idx++) {
1037 if (service_list[service_code_idx] == cur_service_code) break;
1038 }
1039
1040 /* Add decriptor to T3T message */
1041 if (p_t3t_blocks[i].block_number > 0xFF) {
1042 UINT8_TO_STREAM((*p), service_code_idx);
1043 UINT16_TO_STREAM((*p), p_t3t_blocks[i].block_number);
1044 } else {
1045 service_code_idx |= T3T_MSG_MASK_TWO_BYTE_BLOCK_DESC_FORMAT;
1046 UINT8_TO_STREAM((*p), service_code_idx);
1047 UINT8_TO_STREAM((*p), p_t3t_blocks[i].block_number);
1048 }
1049 }
nxpandroidc7611652015-09-23 16:42:05 +05301050}
1051
1052/*****************************************************************************
1053**
1054** Function rw_t3t_send_check_cmd
1055**
1056** Description Send CHECK command
1057**
1058** Returns tNFC_STATUS
1059**
1060*****************************************************************************/
nxpandroid8f6d0532017-07-12 18:25:30 +05301061tNFC_STATUS rw_t3t_send_check_cmd(tRW_T3T_CB* p_cb, uint8_t num_blocks,
1062 tT3T_BLOCK_DESC* p_t3t_blocks) {
1063 NFC_HDR* p_cmd_buf;
nxf24591c1cbeab2018-02-21 17:32:26 +05301064 uint8_t *p, *p_cmd_start;
nxpandroid8f6d0532017-07-12 18:25:30 +05301065 tNFC_STATUS retval = NFC_STATUS_OK;
nxpandroidc7611652015-09-23 16:42:05 +05301066
nxpandroid8f6d0532017-07-12 18:25:30 +05301067 p_cb->cur_cmd = RW_T3T_CMD_CHECK;
1068 p_cmd_buf = rw_t3t_get_cmd_buf();
1069 if (p_cmd_buf != NULL) {
1070 /* Construct T3T message */
1071 p = p_cmd_start = (uint8_t*)(p_cmd_buf + 1) + p_cmd_buf->offset;
1072 rw_t3t_message_set_block_list(p_cb, &p, num_blocks, p_t3t_blocks);
nxpandroidc7611652015-09-23 16:42:05 +05301073
nxpandroid8f6d0532017-07-12 18:25:30 +05301074 /* Calculate length of message */
1075 p_cmd_buf->len = (uint16_t)(p - p_cmd_start);
nxpandroidc7611652015-09-23 16:42:05 +05301076
nxpandroid8f6d0532017-07-12 18:25:30 +05301077 /* Send the T3T message */
1078 retval = rw_t3t_send_cmd(p_cb, RW_T3T_CMD_CHECK, p_cmd_buf,
1079 rw_t3t_check_timeout(num_blocks));
1080 } else {
1081 retval = NFC_STATUS_NO_BUFFERS;
1082 }
nxpandroidc7611652015-09-23 16:42:05 +05301083
nxpandroid8f6d0532017-07-12 18:25:30 +05301084 return (retval);
nxpandroidc7611652015-09-23 16:42:05 +05301085}
1086
1087/*****************************************************************************
1088**
1089** Function rw_t3t_send_update_cmd
1090**
1091** Description Send UPDATE command
1092**
1093** Returns tNFC_STATUS
1094**
1095*****************************************************************************/
nxpandroid8f6d0532017-07-12 18:25:30 +05301096tNFC_STATUS rw_t3t_send_update_cmd(tRW_T3T_CB* p_cb, uint8_t num_blocks,
1097 tT3T_BLOCK_DESC* p_t3t_blocks,
1098 uint8_t* p_data) {
1099 NFC_HDR* p_cmd_buf;
nxf24591c1cbeab2018-02-21 17:32:26 +05301100 uint8_t *p, *p_cmd_start;
nxpandroid8f6d0532017-07-12 18:25:30 +05301101 tNFC_STATUS retval = NFC_STATUS_OK;
nxpandroidc7611652015-09-23 16:42:05 +05301102
nxpandroid8f6d0532017-07-12 18:25:30 +05301103 p_cb->cur_cmd = RW_T3T_CMD_UPDATE;
1104 p_cmd_buf = rw_t3t_get_cmd_buf();
1105 if (p_cmd_buf != NULL) {
1106 /* Construct T3T message */
1107 p = p_cmd_start = (uint8_t*)(p_cmd_buf + 1) + p_cmd_buf->offset;
1108 rw_t3t_message_set_block_list(p_cb, &p, num_blocks, p_t3t_blocks);
nxpandroidc7611652015-09-23 16:42:05 +05301109
nxpandroid8f6d0532017-07-12 18:25:30 +05301110 /* Add data blocks to the message */
1111 ARRAY_TO_STREAM(p, p_data, num_blocks * 16);
nxpandroidc7611652015-09-23 16:42:05 +05301112
nxpandroid8f6d0532017-07-12 18:25:30 +05301113 /* Calculate length of message */
1114 p_cmd_buf->len = (uint16_t)(p - p_cmd_start);
nxpandroidc7611652015-09-23 16:42:05 +05301115
nxpandroid8f6d0532017-07-12 18:25:30 +05301116 /* Send the T3T message */
1117 retval = rw_t3t_send_cmd(p_cb, RW_T3T_CMD_UPDATE, p_cmd_buf,
1118 rw_t3t_update_timeout(num_blocks));
1119 } else {
1120 retval = NFC_STATUS_NO_BUFFERS;
1121 }
nxpandroidc7611652015-09-23 16:42:05 +05301122
nxpandroid8f6d0532017-07-12 18:25:30 +05301123 return (retval);
nxpandroidc7611652015-09-23 16:42:05 +05301124}
1125
1126/*****************************************************************************
1127**
1128** Function rw_t3t_check_mc_block
1129**
1130** Description Send command to check Memory Configuration Block
1131**
1132** Returns tNFC_STATUS
1133**
1134*****************************************************************************/
nxpandroid8f6d0532017-07-12 18:25:30 +05301135tNFC_STATUS rw_t3t_check_mc_block(tRW_T3T_CB* p_cb) {
1136 NFC_HDR* p_cmd_buf;
nxf24591c1cbeab2018-02-21 17:32:26 +05301137 uint8_t *p, *p_cmd_start;
nxpandroidc7611652015-09-23 16:42:05 +05301138
nxpandroid8f6d0532017-07-12 18:25:30 +05301139 /* Read Memory Configuration block */
1140 p_cmd_buf = rw_t3t_get_cmd_buf();
1141 if (p_cmd_buf != NULL) {
1142 /* Construct T3T message */
1143 p = p_cmd_start = (uint8_t*)(p_cmd_buf + 1) + p_cmd_buf->offset;
nxpandroidc7611652015-09-23 16:42:05 +05301144
nxpandroid8f6d0532017-07-12 18:25:30 +05301145 /* Add CHECK opcode to message */
1146 UINT8_TO_STREAM(p, T3T_MSG_OPC_CHECK_CMD);
nxpandroidc7611652015-09-23 16:42:05 +05301147
nxpandroid8f6d0532017-07-12 18:25:30 +05301148 /* Add IDm to message */
1149 ARRAY_TO_STREAM(p, p_cb->peer_nfcid2, NCI_NFCID2_LEN);
nxpandroidc7611652015-09-23 16:42:05 +05301150
nxpandroid8f6d0532017-07-12 18:25:30 +05301151 /* Add Service code list */
1152 UINT8_TO_STREAM(p, 1); /* Number of services (only 1 service: NDEF) */
1153 UINT16_TO_STREAM(
1154 p, T3T_MSG_NDEF_SC_RO); /* Service code (little-endian format) */
nxpandroidc7611652015-09-23 16:42:05 +05301155
nxpandroid8f6d0532017-07-12 18:25:30 +05301156 /* Number of blocks */
1157 UINT8_TO_STREAM(p, 1); /* Number of blocks (only 1 block: Memory
1158 Configuration Information ) */
nxpandroidc7611652015-09-23 16:42:05 +05301159
nxpandroid8f6d0532017-07-12 18:25:30 +05301160 /* Block List element: the Memory Configuration block (block 0x88) */
1161 UINT8_TO_STREAM(p, T3T_MSG_MASK_TWO_BYTE_BLOCK_DESC_FORMAT);
1162 UINT8_TO_STREAM(p, T3T_MSG_FELICALITE_BLOCK_ID_MC);
nxpandroidc7611652015-09-23 16:42:05 +05301163
nxpandroid8f6d0532017-07-12 18:25:30 +05301164 /* Calculate length of message */
1165 p_cmd_buf->len = (uint16_t)(p - p_cmd_start);
nxpandroidc7611652015-09-23 16:42:05 +05301166
nxpandroid8f6d0532017-07-12 18:25:30 +05301167 /* Send the T3T message */
1168 return rw_t3t_send_cmd(p_cb, p_cb->cur_cmd, p_cmd_buf,
1169 rw_t3t_check_timeout(1));
1170 } else {
nxf24591c1cbeab2018-02-21 17:32:26 +05301171 LOG(ERROR) << StringPrintf("Unable to allocate buffer to read MC block");
nxpandroid8f6d0532017-07-12 18:25:30 +05301172 return (NFC_STATUS_NO_BUFFERS);
1173 }
nxpandroidc7611652015-09-23 16:42:05 +05301174}
1175
1176/*****************************************************************************
1177**
1178** Function rw_t3t_send_raw_frame
1179**
1180** Description Send raw frame
1181**
1182** Returns tNFC_STATUS
1183**
1184*****************************************************************************/
nxpandroid8f6d0532017-07-12 18:25:30 +05301185tNFC_STATUS rw_t3t_send_raw_frame(tRW_T3T_CB* p_cb, uint16_t len,
1186 uint8_t* p_data) {
1187 NFC_HDR* p_cmd_buf;
1188 uint8_t* p;
1189 tNFC_STATUS retval = NFC_STATUS_OK;
nxpandroidc7611652015-09-23 16:42:05 +05301190
nxpandroid8f6d0532017-07-12 18:25:30 +05301191 p_cmd_buf = rw_t3t_get_cmd_buf();
1192 if (p_cmd_buf != NULL) {
1193 /* Construct T3T message */
1194 p = (uint8_t*)(p_cmd_buf + 1) + p_cmd_buf->offset;
nxpandroidc7611652015-09-23 16:42:05 +05301195
nxpandroid8f6d0532017-07-12 18:25:30 +05301196 /* Add data blocks to the message */
1197 ARRAY_TO_STREAM(p, p_data, len);
nxpandroidc7611652015-09-23 16:42:05 +05301198
nxpandroid8f6d0532017-07-12 18:25:30 +05301199 /* Calculate length of message */
1200 p_cmd_buf->len = len;
nxpandroidc7611652015-09-23 16:42:05 +05301201
nxpandroid8f6d0532017-07-12 18:25:30 +05301202 /* Send the T3T message */
1203 retval = rw_t3t_send_cmd(p_cb, RW_T3T_CMD_SEND_RAW_FRAME, p_cmd_buf,
1204 RW_T3T_RAW_FRAME_CMD_TIMEOUT_TICKS);
1205 } else {
1206 retval = NFC_STATUS_NO_BUFFERS;
1207 }
nxpandroidc7611652015-09-23 16:42:05 +05301208
nxpandroid8f6d0532017-07-12 18:25:30 +05301209 return (retval);
nxpandroidc7611652015-09-23 16:42:05 +05301210}
1211
nxpandroidc7611652015-09-23 16:42:05 +05301212/*****************************************************************************
1213** TAG RESPONSE HANDLERS
1214*****************************************************************************/
1215
nxpandroidc7611652015-09-23 16:42:05 +05301216/*****************************************************************************
1217**
1218** Function rw_t3t_act_handle_ndef_detect_rsp
1219**
1220** Description Handle response to NDEF detection
1221**
1222** Returns Nothing
1223**
1224*****************************************************************************/
nxpandroid8f6d0532017-07-12 18:25:30 +05301225void rw_t3t_act_handle_ndef_detect_rsp(tRW_T3T_CB* p_cb, NFC_HDR* p_msg_rsp) {
1226 uint8_t* p;
1227 uint32_t temp;
1228 uint8_t i;
1229 uint16_t checksum_calc, checksum_rx;
1230 tRW_DETECT_NDEF_DATA evt_data;
1231 uint8_t* p_t3t_rsp = (uint8_t*)(p_msg_rsp + 1) + p_msg_rsp->offset;
nxpandroidc7611652015-09-23 16:42:05 +05301232
nxpandroid8f6d0532017-07-12 18:25:30 +05301233 evt_data.status = NFC_STATUS_FAILED;
1234 evt_data.flags = RW_NDEF_FL_UNKNOWN;
1235
1236 /* Check if response code is CHECK resp (for reading NDEF attribute block) */
1237 if (p_t3t_rsp[T3T_MSG_RSP_OFFSET_RSPCODE] != T3T_MSG_OPC_CHECK_RSP) {
nxf24591c1cbeab2018-02-21 17:32:26 +05301238 LOG(ERROR) << StringPrintf(
1239 "Response error: expecting rsp_code %02X, but got %02X",
1240 T3T_MSG_OPC_CHECK_RSP, p_t3t_rsp[T3T_MSG_RSP_OFFSET_RSPCODE]);
nxpandroidc7611652015-09-23 16:42:05 +05301241 evt_data.status = NFC_STATUS_FAILED;
nxpandroid8f6d0532017-07-12 18:25:30 +05301242 }
1243 /* Validate status code and NFCID2 response from tag */
1244 else if ((p_t3t_rsp[T3T_MSG_RSP_OFFSET_STATUS1] !=
1245 T3T_MSG_RSP_STATUS_OK) /* verify response status code */
nxf24591c1cbeab2018-02-21 17:32:26 +05301246 || (memcmp(p_cb->peer_nfcid2, &p_t3t_rsp[T3T_MSG_RSP_OFFSET_IDM],
1247 NCI_NFCID2_LEN) != 0)) /* verify response IDm */
nxpandroid8f6d0532017-07-12 18:25:30 +05301248 {
1249 evt_data.status = NFC_STATUS_FAILED;
1250 } else {
1251 /* Get checksum from received ndef attribute msg */
1252 p = &p_t3t_rsp[T3T_MSG_RSP_OFFSET_CHECK_DATA + T3T_MSG_NDEF_ATTR_INFO_SIZE];
1253 BE_STREAM_TO_UINT16(checksum_rx, p);
nxpandroidc7611652015-09-23 16:42:05 +05301254
nxpandroid8f6d0532017-07-12 18:25:30 +05301255 /* Calculate checksum - move check for checsum to beginning */
1256 checksum_calc = 0;
1257 p = &p_t3t_rsp[T3T_MSG_RSP_OFFSET_CHECK_DATA];
1258 for (i = 0; i < T3T_MSG_NDEF_ATTR_INFO_SIZE; i++) {
1259 checksum_calc += p[i];
nxpandroidc7611652015-09-23 16:42:05 +05301260 }
1261
nxpandroid8f6d0532017-07-12 18:25:30 +05301262 /* Validate checksum */
1263 if (checksum_calc != checksum_rx) {
1264 p_cb->ndef_attrib.status =
1265 NFC_STATUS_FAILED; /* only ok or failed passed to the app. can be
1266 boolean*/
nxpandroidc7611652015-09-23 16:42:05 +05301267
nxf24591c1cbeab2018-02-21 17:32:26 +05301268 LOG(ERROR) << StringPrintf("RW_T3tDetectNDEF checksum failed");
nxpandroid8f6d0532017-07-12 18:25:30 +05301269 } else {
1270 p_cb->ndef_attrib.status = NFC_STATUS_OK;
nxpandroidc7611652015-09-23 16:42:05 +05301271
nxpandroid8f6d0532017-07-12 18:25:30 +05301272 /* Validate version number */
1273 STREAM_TO_UINT8(p_cb->ndef_attrib.version, p);
1274
1275 if (T3T_GET_MAJOR_VERSION(T3T_MSG_NDEF_VERSION) <
1276 T3T_GET_MAJOR_VERSION(p_cb->ndef_attrib.version)) {
1277 /* Remote tag's MajorVer is newer than our's. Reject NDEF as per T3TOP
1278 * RQ_T3T_NDA_024 */
nxf24591c1cbeab2018-02-21 17:32:26 +05301279 LOG(ERROR) << StringPrintf(
nxpandroid8f6d0532017-07-12 18:25:30 +05301280 "RW_T3tDetectNDEF: incompatible NDEF version. Local=0x%02x, "
1281 "Remote=0x%02x",
1282 T3T_MSG_NDEF_VERSION, p_cb->ndef_attrib.version);
1283 p_cb->ndef_attrib.status = NFC_STATUS_FAILED;
1284 evt_data.status = NFC_STATUS_BAD_RESP;
1285 } else {
1286 /* Remote tag's MajorVer is equal or older than our's. NDEF is
1287 * compatible with our version. */
1288
1289 /* Update NDEF info */
1290 STREAM_TO_UINT8(
1291 p_cb->ndef_attrib.nbr,
1292 p); /* NBr: number of blocks that can be read using one Check
1293 command */
1294 STREAM_TO_UINT8(p_cb->ndef_attrib.nbw,
1295 p); /* Nbw: number of blocks that can be written using
1296 one Update command */
1297 BE_STREAM_TO_UINT16(
1298 p_cb->ndef_attrib.nmaxb,
1299 p); /* Nmaxb: maximum number of blocks available for NDEF data */
1300 BE_STREAM_TO_UINT32(temp, p);
1301 STREAM_TO_UINT8(p_cb->ndef_attrib.writef,
1302 p); /* WriteFlag: 00h if writing data finished; 0Fh if
1303 writing data in progress */
1304 STREAM_TO_UINT8(
1305 p_cb->ndef_attrib.rwflag,
1306 p); /* RWFlag: 00h NDEF is read-only; 01h if read/write available */
1307
1308 /* Get length (3-byte, big-endian) */
1309 STREAM_TO_UINT8(temp, p); /* Ln: high-byte */
1310 BE_STREAM_TO_UINT16(p_cb->ndef_attrib.ln, p); /* Ln: lo-word */
1311 p_cb->ndef_attrib.ln += (temp << 16);
1312
nxf24591c1cbeab2018-02-21 17:32:26 +05301313 DLOG_IF(INFO, nfc_debug_enabled) << StringPrintf(
1314 "Detected NDEF Ver: 0x%02x", p_cb->ndef_attrib.version);
1315 DLOG_IF(INFO, nfc_debug_enabled) << StringPrintf(
nxpandroid8f6d0532017-07-12 18:25:30 +05301316 "Detected NDEF Attributes: Nbr=%i, Nbw=%i, Nmaxb=%i, WriteF=%i, "
1317 "RWFlag=%i, Ln=%i",
1318 p_cb->ndef_attrib.nbr, p_cb->ndef_attrib.nbw,
1319 p_cb->ndef_attrib.nmaxb, p_cb->ndef_attrib.writef,
1320 p_cb->ndef_attrib.rwflag, p_cb->ndef_attrib.ln);
1321
1322 /* Set data for RW_T3T_NDEF_DETECT_EVT */
1323 evt_data.status = p_cb->ndef_attrib.status;
1324 evt_data.cur_size = p_cb->ndef_attrib.ln;
1325 evt_data.max_size = (uint32_t)p_cb->ndef_attrib.nmaxb * 16;
1326 evt_data.protocol = NFC_PROTOCOL_T3T;
1327 evt_data.flags = (RW_NDEF_FL_SUPPORTED | RW_NDEF_FL_FORMATED);
1328 if (p_cb->ndef_attrib.rwflag == T3T_MSG_NDEF_RWFLAG_RO)
1329 evt_data.flags |= RW_NDEF_FL_READ_ONLY;
1330 }
1331 }
1332 }
1333
nxf24591c1cbeab2018-02-21 17:32:26 +05301334 DLOG_IF(INFO, nfc_debug_enabled)
1335 << StringPrintf("RW_T3tDetectNDEF response: %i", evt_data.status);
nxpandroid8f6d0532017-07-12 18:25:30 +05301336
1337 p_cb->rw_state = RW_T3T_STATE_IDLE;
1338 rw_t3t_update_ndef_flag(&evt_data.flags);
1339 /* Notify app of NDEF detection result */
nxf24591c1cbeab2018-02-21 17:32:26 +05301340 tRW_DATA rw_data;
1341 rw_data.ndef = evt_data;
1342 (*(rw_cb.p_cback))(RW_T3T_NDEF_DETECT_EVT, &rw_data);
nxpandroid8f6d0532017-07-12 18:25:30 +05301343
1344 GKI_freebuf(p_msg_rsp);
nxpandroidc7611652015-09-23 16:42:05 +05301345}
1346
nxpandroidc7611652015-09-23 16:42:05 +05301347/*****************************************************************************
1348**
1349** Function rw_t3t_act_handle_check_rsp
1350**
1351** Description Handle response to CHECK command
1352**
1353** Returns Nothing
1354**
1355*****************************************************************************/
nxpandroid8f6d0532017-07-12 18:25:30 +05301356void rw_t3t_act_handle_check_rsp(tRW_T3T_CB* p_cb, NFC_HDR* p_msg_rsp) {
1357 uint8_t* p_t3t_rsp = (uint8_t*)(p_msg_rsp + 1) + p_msg_rsp->offset;
1358 tRW_READ_DATA evt_data;
1359 tNFC_STATUS nfc_status = NFC_STATUS_OK;
nxpandroidc7611652015-09-23 16:42:05 +05301360
nxpandroid8f6d0532017-07-12 18:25:30 +05301361 /* Validate response from tag */
1362 if ((p_t3t_rsp[T3T_MSG_RSP_OFFSET_STATUS1] !=
1363 T3T_MSG_RSP_STATUS_OK) /* verify response status code */
nxf24591c1cbeab2018-02-21 17:32:26 +05301364 || (memcmp(p_cb->peer_nfcid2, &p_t3t_rsp[T3T_MSG_RSP_OFFSET_IDM],
1365 NCI_NFCID2_LEN) != 0)) /* verify response IDm */
nxpandroid8f6d0532017-07-12 18:25:30 +05301366 {
1367 nfc_status = NFC_STATUS_FAILED;
1368 GKI_freebuf(p_msg_rsp);
1369 } else if (p_t3t_rsp[T3T_MSG_RSP_OFFSET_RSPCODE] != T3T_MSG_OPC_CHECK_RSP) {
nxf24591c1cbeab2018-02-21 17:32:26 +05301370 LOG(ERROR) << StringPrintf(
1371 "Response error: expecting rsp_code %02X, but got %02X",
1372 T3T_MSG_OPC_CHECK_RSP, p_t3t_rsp[T3T_MSG_RSP_OFFSET_RSPCODE]);
nxpandroid8f6d0532017-07-12 18:25:30 +05301373 nfc_status = NFC_STATUS_FAILED;
1374 GKI_freebuf(p_msg_rsp);
1375 } else {
1376 /* Copy incoming data into buffer */
1377 p_msg_rsp->offset +=
1378 T3T_MSG_RSP_OFFSET_CHECK_DATA; /* Skip over t3t header */
1379 p_msg_rsp->len -= T3T_MSG_RSP_OFFSET_CHECK_DATA;
1380 evt_data.status = NFC_STATUS_OK;
1381 evt_data.p_data = p_msg_rsp;
nxf24591c1cbeab2018-02-21 17:32:26 +05301382 tRW_DATA rw_data;
1383 rw_data.data = evt_data;
1384 (*(rw_cb.p_cback))(RW_T3T_CHECK_EVT, &rw_data);
nxpandroid8f6d0532017-07-12 18:25:30 +05301385 }
nxpandroidc7611652015-09-23 16:42:05 +05301386
nxpandroid8f6d0532017-07-12 18:25:30 +05301387 p_cb->rw_state = RW_T3T_STATE_IDLE;
nxpandroidc7611652015-09-23 16:42:05 +05301388
nxf24591c1cbeab2018-02-21 17:32:26 +05301389 tRW_DATA rw_data;
1390 rw_data.status = nfc_status;
1391 (*(rw_cb.p_cback))(RW_T3T_CHECK_CPLT_EVT, &rw_data);
nxpandroidc7611652015-09-23 16:42:05 +05301392}
1393
1394/*****************************************************************************
1395**
1396** Function rw_t3t_act_handle_update_rsp
1397**
1398** Description Handle response to UPDATE command
1399**
1400** Returns Nothing
1401**
1402*****************************************************************************/
nxpandroid8f6d0532017-07-12 18:25:30 +05301403void rw_t3t_act_handle_update_rsp(tRW_T3T_CB* p_cb, NFC_HDR* p_msg_rsp) {
1404 uint8_t* p_t3t_rsp = (uint8_t*)(p_msg_rsp + 1) + p_msg_rsp->offset;
1405 tRW_READ_DATA evt_data;
nxpandroidc7611652015-09-23 16:42:05 +05301406
nxpandroid8f6d0532017-07-12 18:25:30 +05301407 /* Validate response from tag */
1408 if ((p_t3t_rsp[T3T_MSG_RSP_OFFSET_STATUS1] !=
1409 T3T_MSG_RSP_STATUS_OK) /* verify response status code */
nxf24591c1cbeab2018-02-21 17:32:26 +05301410 || (memcmp(p_cb->peer_nfcid2, &p_t3t_rsp[T3T_MSG_RSP_OFFSET_IDM],
1411 NCI_NFCID2_LEN) != 0)) /* verify response IDm */
nxpandroid8f6d0532017-07-12 18:25:30 +05301412 {
1413 evt_data.status = NFC_STATUS_FAILED;
1414 } else if (p_t3t_rsp[T3T_MSG_RSP_OFFSET_RSPCODE] != T3T_MSG_OPC_UPDATE_RSP) {
nxf24591c1cbeab2018-02-21 17:32:26 +05301415 LOG(ERROR) << StringPrintf(
1416 "Response error: expecting rsp_code %02X, but got %02X",
1417 T3T_MSG_OPC_UPDATE_RSP, p_t3t_rsp[T3T_MSG_RSP_OFFSET_RSPCODE]);
nxpandroid8f6d0532017-07-12 18:25:30 +05301418 evt_data.status = NFC_STATUS_FAILED;
1419 } else {
1420 /* Copy incoming data into buffer */
1421 evt_data.status = NFC_STATUS_OK;
1422 }
nxpandroidc7611652015-09-23 16:42:05 +05301423
nxpandroid8f6d0532017-07-12 18:25:30 +05301424 p_cb->rw_state = RW_T3T_STATE_IDLE;
nxpandroidc7611652015-09-23 16:42:05 +05301425
nxf24591c1cbeab2018-02-21 17:32:26 +05301426 tRW_DATA rw_data;
1427 rw_data.data = evt_data;
1428 (*(rw_cb.p_cback))(RW_T3T_UPDATE_CPLT_EVT, &rw_data);
nxpandroidc7611652015-09-23 16:42:05 +05301429
nxpandroid8f6d0532017-07-12 18:25:30 +05301430 GKI_freebuf(p_msg_rsp);
nxpandroidc7611652015-09-23 16:42:05 +05301431}
1432
1433/*****************************************************************************
1434**
1435** Function rw_t3t_act_handle_raw_senddata_rsp
1436**
1437** Description Handle response to NDEF detection
1438**
1439** Returns Nothing
1440**
1441*****************************************************************************/
nxpandroid8f6d0532017-07-12 18:25:30 +05301442void rw_t3t_act_handle_raw_senddata_rsp(tRW_T3T_CB* p_cb,
1443 tNFC_DATA_CEVT* p_data) {
1444 tRW_READ_DATA evt_data;
1445 NFC_HDR* p_pkt = p_data->p_data;
nxpandroidc7611652015-09-23 16:42:05 +05301446
nxf24591c1cbeab2018-02-21 17:32:26 +05301447 DLOG_IF(INFO, nfc_debug_enabled)
1448 << StringPrintf("RW T3T Raw Frame: Len [0x%X] Status [%s]", p_pkt->len,
1449 NFC_GetStatusName(p_data->status).c_str());
nxpandroidc7611652015-09-23 16:42:05 +05301450
nxpandroid8f6d0532017-07-12 18:25:30 +05301451 /* Copy incoming data into buffer */
1452 evt_data.status = p_data->status;
1453 evt_data.p_data = p_pkt;
nxpandroidc7611652015-09-23 16:42:05 +05301454
nxpandroid8f6d0532017-07-12 18:25:30 +05301455 p_cb->rw_state = RW_T3T_STATE_IDLE;
nxpandroidc7611652015-09-23 16:42:05 +05301456
nxf24591c1cbeab2018-02-21 17:32:26 +05301457 tRW_DATA rw_data;
1458 rw_data.data = evt_data;
1459 (*(rw_cb.p_cback))(RW_T3T_RAW_FRAME_EVT, &rw_data);
nxpandroidc7611652015-09-23 16:42:05 +05301460}
1461
1462/*****************************************************************************
1463**
1464** Function rw_t3t_act_handle_check_ndef_rsp
1465**
1466** Description Handle response to NDEF read segment
1467**
1468** Returns Nothing
1469**
1470*****************************************************************************/
nxpandroid8f6d0532017-07-12 18:25:30 +05301471void rw_t3t_act_handle_check_ndef_rsp(tRW_T3T_CB* p_cb, NFC_HDR* p_msg_rsp) {
1472 bool check_complete = true;
1473 tNFC_STATUS nfc_status = NFC_STATUS_OK;
nxpandroid8f6d0532017-07-12 18:25:30 +05301474 uint8_t* p_t3t_rsp = (uint8_t*)(p_msg_rsp + 1) + p_msg_rsp->offset;
1475 uint8_t rsp_num_bytes_rx;
nxpandroidc7611652015-09-23 16:42:05 +05301476
nxpandroid8f6d0532017-07-12 18:25:30 +05301477 /* Validate response from tag */
1478 if ((p_t3t_rsp[T3T_MSG_RSP_OFFSET_STATUS1] !=
1479 T3T_MSG_RSP_STATUS_OK) /* verify response status code */
nxf24591c1cbeab2018-02-21 17:32:26 +05301480 || (memcmp(p_cb->peer_nfcid2, &p_t3t_rsp[T3T_MSG_RSP_OFFSET_IDM],
1481 NCI_NFCID2_LEN) != 0) /* verify response IDm */
1482 || (p_t3t_rsp[T3T_MSG_RSP_OFFSET_NUMBLOCKS] !=
1483 ((p_cb->ndef_rx_readlen + 15) >> 4))) /* verify length of response */
nxpandroid8f6d0532017-07-12 18:25:30 +05301484 {
nxf24591c1cbeab2018-02-21 17:32:26 +05301485 LOG(ERROR) << StringPrintf(
1486 "Response error: bad status, nfcid2, or invalid len: %i %i",
1487 p_t3t_rsp[T3T_MSG_RSP_OFFSET_NUMBLOCKS],
1488 ((p_cb->ndef_rx_readlen + 15) >> 4));
nxpandroid8f6d0532017-07-12 18:25:30 +05301489 nfc_status = NFC_STATUS_FAILED;
1490 GKI_freebuf(p_msg_rsp);
1491 } else if (p_t3t_rsp[T3T_MSG_RSP_OFFSET_RSPCODE] != T3T_MSG_OPC_CHECK_RSP) {
nxf24591c1cbeab2018-02-21 17:32:26 +05301492 LOG(ERROR) << StringPrintf(
1493 "Response error: expecting rsp_code %02X, but got %02X",
1494 T3T_MSG_OPC_CHECK_RSP, p_t3t_rsp[T3T_MSG_RSP_OFFSET_RSPCODE]);
nxpandroid8f6d0532017-07-12 18:25:30 +05301495 nfc_status = NFC_STATUS_FAILED;
1496 GKI_freebuf(p_msg_rsp);
1497 } else {
1498 /* Notify app of NDEF segment received */
1499 rsp_num_bytes_rx = p_t3t_rsp[T3T_MSG_RSP_OFFSET_NUMBLOCKS] *
1500 16; /* Number of bytes received, according to header */
1501 p_cb->ndef_rx_offset += p_cb->ndef_rx_readlen;
nxpandroid8f6d0532017-07-12 18:25:30 +05301502 p_msg_rsp->offset +=
1503 T3T_MSG_RSP_OFFSET_CHECK_DATA; /* Skip over t3t header (point to block
1504 data) */
1505 p_msg_rsp->len -= T3T_MSG_RSP_OFFSET_CHECK_DATA;
nxpandroidc7611652015-09-23 16:42:05 +05301506
nxpandroid8f6d0532017-07-12 18:25:30 +05301507 /* Verify that the bytes received is really the amount indicated in the
1508 * check-response header */
1509 if (rsp_num_bytes_rx > p_msg_rsp->len) {
nxf24591c1cbeab2018-02-21 17:32:26 +05301510 LOG(ERROR) << StringPrintf(
nxpandroid8f6d0532017-07-12 18:25:30 +05301511 "Response error: CHECK rsp header indicates %i bytes, but only "
1512 "received %i bytes",
1513 rsp_num_bytes_rx, p_msg_rsp->len);
1514 nfc_status = NFC_STATUS_FAILED;
1515 GKI_freebuf(p_msg_rsp);
1516 } else {
1517 /* If this is the the final block, then set len to reflect only valid
1518 * bytes (do not include padding to 16-byte boundary) */
1519 if ((p_cb->flags & RW_T3T_FL_IS_FINAL_NDEF_SEGMENT) &&
1520 (p_cb->ndef_attrib.ln & 0x000F)) {
1521 rsp_num_bytes_rx -= (16 - (p_cb->ndef_attrib.ln & 0x000F));
1522 }
1523
1524 p_msg_rsp->len = rsp_num_bytes_rx;
nxf24591c1cbeab2018-02-21 17:32:26 +05301525 tRW_DATA rw_data;
1526 rw_data.data.status = NFC_STATUS_OK;
1527 rw_data.data.p_data = p_msg_rsp;
1528 (*(rw_cb.p_cback))(RW_T3T_CHECK_EVT, &rw_data);
nxpandroid8f6d0532017-07-12 18:25:30 +05301529
1530 /* Send CHECK cmd for next NDEF segment, if needed */
1531 if (!(p_cb->flags & RW_T3T_FL_IS_FINAL_NDEF_SEGMENT)) {
1532 nfc_status = rw_t3t_send_next_ndef_check_cmd(p_cb);
1533 if (nfc_status == NFC_STATUS_OK) {
1534 /* Still getting more segments. Don't send RW_T3T_CHECK_CPLT_EVT yet
1535 */
1536 check_complete = false;
nxpandroidc7611652015-09-23 16:42:05 +05301537 }
nxpandroid8f6d0532017-07-12 18:25:30 +05301538 }
nxpandroidc7611652015-09-23 16:42:05 +05301539 }
nxpandroid8f6d0532017-07-12 18:25:30 +05301540 }
nxpandroidc7611652015-09-23 16:42:05 +05301541
nxpandroid8f6d0532017-07-12 18:25:30 +05301542 /* Notify app of RW_T3T_CHECK_CPLT_EVT if entire NDEF has been read, or if
1543 * failure */
1544 if (check_complete) {
1545 p_cb->rw_state = RW_T3T_STATE_IDLE;
nxf24591c1cbeab2018-02-21 17:32:26 +05301546 tRW_DATA evt_data;
nxpandroid8f6d0532017-07-12 18:25:30 +05301547 evt_data.status = nfc_status;
nxf24591c1cbeab2018-02-21 17:32:26 +05301548 (*(rw_cb.p_cback))(RW_T3T_CHECK_CPLT_EVT, &evt_data);
nxpandroid8f6d0532017-07-12 18:25:30 +05301549 }
nxpandroidc7611652015-09-23 16:42:05 +05301550}
1551
nxpandroidc7611652015-09-23 16:42:05 +05301552/*****************************************************************************
1553**
1554** Function rw_t3t_act_handle_update_ndef_rsp
1555**
1556** Description Handle response to NDEF write segment
1557**
1558** Returns Nothing
1559**
1560*****************************************************************************/
nxpandroid8f6d0532017-07-12 18:25:30 +05301561void rw_t3t_act_handle_update_ndef_rsp(tRW_T3T_CB* p_cb, NFC_HDR* p_msg_rsp) {
1562 bool update_complete = true;
1563 tNFC_STATUS nfc_status = NFC_STATUS_OK;
nxpandroid8f6d0532017-07-12 18:25:30 +05301564 uint8_t* p_t3t_rsp = (uint8_t*)(p_msg_rsp + 1) + p_msg_rsp->offset;
nxpandroidc7611652015-09-23 16:42:05 +05301565
nxpandroid8f6d0532017-07-12 18:25:30 +05301566 /* Check nfcid2 and status of response */
1567 if ((p_t3t_rsp[T3T_MSG_RSP_OFFSET_STATUS1] !=
1568 T3T_MSG_RSP_STATUS_OK) /* verify response status code */
nxf24591c1cbeab2018-02-21 17:32:26 +05301569 || (memcmp(p_cb->peer_nfcid2, &p_t3t_rsp[T3T_MSG_RSP_OFFSET_IDM],
1570 NCI_NFCID2_LEN) != 0)) /* verify response IDm */
nxpandroid8f6d0532017-07-12 18:25:30 +05301571 {
1572 nfc_status = NFC_STATUS_FAILED;
1573 }
1574 /* Validate response opcode */
1575 else if (p_t3t_rsp[T3T_MSG_RSP_OFFSET_RSPCODE] != T3T_MSG_OPC_UPDATE_RSP) {
nxf24591c1cbeab2018-02-21 17:32:26 +05301576 LOG(ERROR) << StringPrintf(
1577 "Response error: expecting rsp_code %02X, but got %02X",
1578 T3T_MSG_OPC_UPDATE_RSP, p_t3t_rsp[T3T_MSG_RSP_OFFSET_RSPCODE]);
nxpandroid8f6d0532017-07-12 18:25:30 +05301579 nfc_status = NFC_STATUS_FAILED;
1580 }
1581 /* If this is response to final UPDATE, then update NDEF local size */
1582 else if (p_cb->flags & RW_T3T_FL_IS_FINAL_NDEF_SEGMENT) {
1583 /* If successful, update current NDEF size */
1584 p_cb->ndef_attrib.ln = p_cb->ndef_msg_len;
1585 }
1586 /* If any more NDEF bytes to update, then send next UPDATE command */
1587 else if (p_cb->ndef_msg_bytes_sent < p_cb->ndef_msg_len) {
1588 /* Send UPDATE command for next segment of NDEF */
1589 nfc_status = rw_t3t_send_next_ndef_update_cmd(p_cb);
1590 if (nfc_status == NFC_STATUS_OK) {
1591 /* Wait for update response */
1592 update_complete = false;
nxpandroidc7611652015-09-23 16:42:05 +05301593 }
nxpandroid8f6d0532017-07-12 18:25:30 +05301594 }
1595 /* Otherwise, no more NDEF bytes. Send final UPDATE for Attribute Information
1596 block */
1597 else {
1598 p_cb->flags |= RW_T3T_FL_IS_FINAL_NDEF_SEGMENT;
1599 nfc_status = rw_t3t_send_update_ndef_attribute_cmd(p_cb, false);
1600 if (nfc_status == NFC_STATUS_OK) {
1601 /* Wait for update response */
1602 update_complete = false;
nxpandroidc7611652015-09-23 16:42:05 +05301603 }
nxpandroid8f6d0532017-07-12 18:25:30 +05301604 }
nxpandroidc7611652015-09-23 16:42:05 +05301605
nxpandroid8f6d0532017-07-12 18:25:30 +05301606 /* If update is completed, then notify app */
1607 if (update_complete) {
1608 p_cb->rw_state = RW_T3T_STATE_IDLE;
nxf24591c1cbeab2018-02-21 17:32:26 +05301609 tRW_DATA evt_data;
nxpandroid8f6d0532017-07-12 18:25:30 +05301610 evt_data.status = nfc_status;
nxf24591c1cbeab2018-02-21 17:32:26 +05301611 (*(rw_cb.p_cback))(RW_T3T_UPDATE_CPLT_EVT, &evt_data);
nxpandroid8f6d0532017-07-12 18:25:30 +05301612 }
nxpandroidc7611652015-09-23 16:42:05 +05301613
nxpandroid8f6d0532017-07-12 18:25:30 +05301614 GKI_freebuf(p_msg_rsp);
nxpandroidc7611652015-09-23 16:42:05 +05301615
nxpandroid8f6d0532017-07-12 18:25:30 +05301616 return;
nxpandroidc7611652015-09-23 16:42:05 +05301617}
1618
nxpandroidc7611652015-09-23 16:42:05 +05301619/*****************************************************************************
1620**
1621** Function rw_t3t_handle_get_sc_poll_rsp
1622**
1623** Description Handle POLL response for getting system codes
1624**
1625** Returns Nothing
1626**
1627*****************************************************************************/
nxpandroid8f6d0532017-07-12 18:25:30 +05301628static void rw_t3t_handle_get_sc_poll_rsp(tRW_T3T_CB* p_cb, uint8_t nci_status,
1629 uint8_t num_responses,
1630 uint8_t sensf_res_buf_size,
1631 uint8_t* p_sensf_res_buf) {
1632 uint8_t* p;
1633 uint16_t sc;
nxpandroidc7611652015-09-23 16:42:05 +05301634
nxpandroid8f6d0532017-07-12 18:25:30 +05301635 /* Get the system code from the response */
1636 if ((nci_status == NCI_STATUS_OK) && (num_responses > 0) &&
1637 (sensf_res_buf_size >=
1638 (RW_T3T_SENSF_RES_RD_OFFSET + RW_T3T_SENSF_RES_RD_LEN))) {
1639 p = &p_sensf_res_buf[RW_T3T_SENSF_RES_RD_OFFSET];
1640 BE_STREAM_TO_UINT16(sc, p);
nxpandroidc7611652015-09-23 16:42:05 +05301641
nxf24591c1cbeab2018-02-21 17:32:26 +05301642 DLOG_IF(INFO, nfc_debug_enabled)
1643 << StringPrintf("FeliCa detected (RD, system code %04X)", sc);
nxpandroid8f6d0532017-07-12 18:25:30 +05301644 p_cb->system_codes[p_cb->num_system_codes++] = sc;
1645 }
nxpandroidc7611652015-09-23 16:42:05 +05301646
nxpandroid8f6d0532017-07-12 18:25:30 +05301647 rw_t3t_handle_get_system_codes_cplt();
nxpandroidc7611652015-09-23 16:42:05 +05301648}
1649
1650/*****************************************************************************
1651**
1652** Function rw_t3t_handle_ndef_detect_poll_rsp
1653**
1654** Description Handle POLL response for getting system codes
1655**
1656** Returns Nothing
1657**
1658*****************************************************************************/
nxpandroid8f6d0532017-07-12 18:25:30 +05301659static void rw_t3t_handle_ndef_detect_poll_rsp(tRW_T3T_CB* p_cb,
1660 uint8_t nci_status,
nxf24591c1cbeab2018-02-21 17:32:26 +05301661 uint8_t num_responses) {
nxpandroid8f6d0532017-07-12 18:25:30 +05301662 NFC_HDR* p_cmd_buf;
nxf24591c1cbeab2018-02-21 17:32:26 +05301663 uint8_t *p, *p_cmd_start;
nxpandroid8f6d0532017-07-12 18:25:30 +05301664 tRW_DATA evt_data;
nxpandroidc7611652015-09-23 16:42:05 +05301665
nxpandroid8f6d0532017-07-12 18:25:30 +05301666 /* Validate response for NDEF poll */
1667 if ((nci_status == NCI_STATUS_OK) && (num_responses > 0)) {
1668 /* Tag responded for NDEF poll */
nxpandroidc7611652015-09-23 16:42:05 +05301669
nxpandroid8f6d0532017-07-12 18:25:30 +05301670 /* Read NDEF attribute block */
1671 p_cmd_buf = rw_t3t_get_cmd_buf();
1672 if (p_cmd_buf != NULL) {
1673 /* Construct T3T message */
1674 p = p_cmd_start = (uint8_t*)(p_cmd_buf + 1) + p_cmd_buf->offset;
nxpandroidc7611652015-09-23 16:42:05 +05301675
nxpandroid8f6d0532017-07-12 18:25:30 +05301676 /* Add CHECK opcode to message */
1677 UINT8_TO_STREAM(p, T3T_MSG_OPC_CHECK_CMD);
nxpandroidc7611652015-09-23 16:42:05 +05301678
nxpandroid8f6d0532017-07-12 18:25:30 +05301679 /* Add IDm to message */
1680 ARRAY_TO_STREAM(p, p_cb->peer_nfcid2, NCI_NFCID2_LEN);
nxpandroidc7611652015-09-23 16:42:05 +05301681
nxpandroid8f6d0532017-07-12 18:25:30 +05301682 /* Add Service code list */
1683 UINT8_TO_STREAM(p, 1); /* Number of services (only 1 service: NDEF) */
1684 UINT16_TO_STREAM(
1685 p, T3T_MSG_NDEF_SC_RO); /* Service code (little-endian format) */
nxpandroidc7611652015-09-23 16:42:05 +05301686
nxpandroid8f6d0532017-07-12 18:25:30 +05301687 /* Number of blocks */
1688 UINT8_TO_STREAM(
1689 p,
1690 1); /* Number of blocks (only 1 block: NDEF Attribute Information ) */
nxpandroidc7611652015-09-23 16:42:05 +05301691
nxpandroid8f6d0532017-07-12 18:25:30 +05301692 /* Block List element: the NDEF attribute information block (block 0) */
1693 UINT8_TO_STREAM(p, T3T_MSG_MASK_TWO_BYTE_BLOCK_DESC_FORMAT);
1694 UINT8_TO_STREAM(p, 0);
nxpandroidc7611652015-09-23 16:42:05 +05301695
nxpandroid8f6d0532017-07-12 18:25:30 +05301696 /* Calculate length of message */
1697 p_cmd_buf->len = (uint16_t)(p - p_cmd_start);
nxpandroidc7611652015-09-23 16:42:05 +05301698
nxpandroid8f6d0532017-07-12 18:25:30 +05301699 /* Send the T3T message */
1700 evt_data.status = rw_t3t_send_cmd(p_cb, RW_T3T_CMD_DETECT_NDEF, p_cmd_buf,
1701 rw_t3t_check_timeout(1));
1702 if (evt_data.status == NFC_STATUS_OK) {
1703 /* CHECK command sent. Wait for response */
1704 return;
1705 }
nxpandroidc7611652015-09-23 16:42:05 +05301706 }
nxpandroid8f6d0532017-07-12 18:25:30 +05301707 nci_status = NFC_STATUS_FAILED;
1708 }
nxpandroidc7611652015-09-23 16:42:05 +05301709
nxpandroid8f6d0532017-07-12 18:25:30 +05301710 /* NDEF detection failed */
1711 p_cb->rw_state = RW_T3T_STATE_IDLE;
1712 evt_data.ndef.status = nci_status;
1713 evt_data.ndef.flags = RW_NDEF_FL_UNKNOWN;
1714 rw_t3t_update_ndef_flag(&evt_data.ndef.flags);
1715 (*(rw_cb.p_cback))(RW_T3T_NDEF_DETECT_EVT, &evt_data);
nxpandroidc7611652015-09-23 16:42:05 +05301716}
1717
1718/*****************************************************************************
1719**
1720** Function rw_t3t_update_block
1721**
1722** Description Send UPDATE command for single block
1723** (for formatting/configuring read only)
1724**
1725** Returns tNFC_STATUS
1726**
1727*****************************************************************************/
nxpandroid8f6d0532017-07-12 18:25:30 +05301728tNFC_STATUS rw_t3t_update_block(tRW_T3T_CB* p_cb, uint8_t block_id,
1729 uint8_t* p_block_data) {
nxf24591c1cbeab2018-02-21 17:32:26 +05301730 uint8_t *p_dst, *p_cmd_start;
nxpandroid8f6d0532017-07-12 18:25:30 +05301731 NFC_HDR* p_cmd_buf;
1732 tNFC_STATUS status;
nxpandroidc7611652015-09-23 16:42:05 +05301733
nxpandroid8f6d0532017-07-12 18:25:30 +05301734 p_cmd_buf = rw_t3t_get_cmd_buf();
1735 if (p_cmd_buf != NULL) {
1736 p_dst = p_cmd_start = (uint8_t*)(p_cmd_buf + 1) + p_cmd_buf->offset;
nxpandroidc7611652015-09-23 16:42:05 +05301737
nxpandroid8f6d0532017-07-12 18:25:30 +05301738 /* Add UPDATE opcode to message */
1739 UINT8_TO_STREAM(p_dst, T3T_MSG_OPC_UPDATE_CMD);
nxpandroidc7611652015-09-23 16:42:05 +05301740
nxpandroid8f6d0532017-07-12 18:25:30 +05301741 /* Add IDm to message */
1742 ARRAY_TO_STREAM(p_dst, p_cb->peer_nfcid2, NCI_NFCID2_LEN);
nxpandroidc7611652015-09-23 16:42:05 +05301743
nxpandroid8f6d0532017-07-12 18:25:30 +05301744 /* Add Service code list */
1745 UINT8_TO_STREAM(p_dst, 1); /* Number of services (only 1 service: NDEF) */
1746 UINT16_TO_STREAM(
1747 p_dst, T3T_MSG_NDEF_SC_RW); /* Service code (little-endian format) */
nxpandroidc7611652015-09-23 16:42:05 +05301748
nxpandroid8f6d0532017-07-12 18:25:30 +05301749 /* Number of blocks */
1750 UINT8_TO_STREAM(p_dst, 1);
nxpandroidc7611652015-09-23 16:42:05 +05301751
nxpandroid8f6d0532017-07-12 18:25:30 +05301752 /* Add Block list element for MC */
1753 UINT8_TO_STREAM(p_dst, T3T_MSG_MASK_TWO_BYTE_BLOCK_DESC_FORMAT);
1754 UINT8_TO_STREAM(p_dst, block_id);
nxpandroidc7611652015-09-23 16:42:05 +05301755
nxpandroid8f6d0532017-07-12 18:25:30 +05301756 /* Copy MC data to UPDATE message */
1757 ARRAY_TO_STREAM(p_dst, p_block_data, T3T_MSG_BLOCKSIZE);
nxpandroidc7611652015-09-23 16:42:05 +05301758
nxpandroid8f6d0532017-07-12 18:25:30 +05301759 /* Calculate length of message */
1760 p_cmd_buf->len = (uint16_t)(p_dst - p_cmd_start);
nxpandroidc7611652015-09-23 16:42:05 +05301761
nxpandroid8f6d0532017-07-12 18:25:30 +05301762 /* Send the T3T message */
1763 status = rw_t3t_send_cmd(p_cb, p_cb->cur_cmd, p_cmd_buf,
1764 rw_t3t_update_timeout(1));
1765 } else {
1766 /* Unable to send UPDATE command */
1767 status = NFC_STATUS_NO_BUFFERS;
1768 }
nxpandroidc7611652015-09-23 16:42:05 +05301769
nxpandroid8f6d0532017-07-12 18:25:30 +05301770 return (status);
nxpandroidc7611652015-09-23 16:42:05 +05301771}
1772
1773/*****************************************************************************
1774**
1775** Function rw_t3t_handle_fmt_poll_rsp
1776**
1777** Description Handle POLL response for formatting felica-lite
1778**
1779** Returns Nothing
1780**
1781*****************************************************************************/
nxpandroid8f6d0532017-07-12 18:25:30 +05301782static void rw_t3t_handle_fmt_poll_rsp(tRW_T3T_CB* p_cb, uint8_t nci_status,
nxf24591c1cbeab2018-02-21 17:32:26 +05301783 uint8_t num_responses) {
nxpandroid8f6d0532017-07-12 18:25:30 +05301784 tRW_DATA evt_data;
nxpandroidc7611652015-09-23 16:42:05 +05301785
nxpandroid8f6d0532017-07-12 18:25:30 +05301786 evt_data.status = NFC_STATUS_OK;
nxpandroidc7611652015-09-23 16:42:05 +05301787
nxpandroid8f6d0532017-07-12 18:25:30 +05301788 /* Validate response for poll response */
1789 if ((nci_status == NCI_STATUS_OK) && (num_responses > 0)) {
1790 /* Tag responded for Felica-Lite poll */
1791 /* Get MemoryControl block */
nxf24591c1cbeab2018-02-21 17:32:26 +05301792 DLOG_IF(INFO, nfc_debug_enabled) << StringPrintf(
1793 "Felica-Lite tag detected...getting Memory Control block.");
nxpandroidc7611652015-09-23 16:42:05 +05301794
nxpandroid8f6d0532017-07-12 18:25:30 +05301795 p_cb->rw_substate = RW_T3T_FMT_SST_CHECK_MC_BLK;
nxpandroidc7611652015-09-23 16:42:05 +05301796
nxpandroid8f6d0532017-07-12 18:25:30 +05301797 /* Send command to check Memory Configuration block */
1798 evt_data.status = rw_t3t_check_mc_block(p_cb);
1799 } else {
nxf24591c1cbeab2018-02-21 17:32:26 +05301800 LOG(ERROR) << StringPrintf("Felica-Lite tag not detected");
nxpandroid8f6d0532017-07-12 18:25:30 +05301801 evt_data.status = NFC_STATUS_FAILED;
1802 }
nxpandroidc7611652015-09-23 16:42:05 +05301803
nxpandroid8f6d0532017-07-12 18:25:30 +05301804 /* If error, notify upper layer */
1805 if (evt_data.status != NFC_STATUS_OK) {
1806 rw_t3t_format_cplt(evt_data.status);
1807 }
nxpandroidc7611652015-09-23 16:42:05 +05301808}
1809
1810/*****************************************************************************
1811**
1812** Function rw_t3t_act_handle_fmt_rsp
1813**
1814** Description Handle response for formatting codes
1815**
1816** Returns Nothing
1817**
1818*****************************************************************************/
nxpandroid8f6d0532017-07-12 18:25:30 +05301819void rw_t3t_act_handle_fmt_rsp(tRW_T3T_CB* p_cb, NFC_HDR* p_msg_rsp) {
1820 uint8_t* p_t3t_rsp = (uint8_t*)(p_msg_rsp + 1) + p_msg_rsp->offset;
1821 uint8_t* p_mc;
1822 tRW_DATA evt_data;
nxpandroidc7611652015-09-23 16:42:05 +05301823
nxpandroid8f6d0532017-07-12 18:25:30 +05301824 evt_data.status = NFC_STATUS_OK;
nxpandroidc7611652015-09-23 16:42:05 +05301825
nxpandroid8f6d0532017-07-12 18:25:30 +05301826 /* Check tags's response for reading MemoryControl block */
1827 if (p_cb->rw_substate == RW_T3T_FMT_SST_CHECK_MC_BLK) {
1828 /* Validate response opcode */
1829 if (p_t3t_rsp[T3T_MSG_RSP_OFFSET_RSPCODE] != T3T_MSG_OPC_CHECK_RSP) {
nxf24591c1cbeab2018-02-21 17:32:26 +05301830 LOG(ERROR) << StringPrintf(
1831 "Response error: expecting rsp_code %02X, but got %02X",
1832 T3T_MSG_OPC_CHECK_RSP, p_t3t_rsp[T3T_MSG_RSP_OFFSET_RSPCODE]);
nxpandroid8f6d0532017-07-12 18:25:30 +05301833 evt_data.status = NFC_STATUS_FAILED;
nxpandroidc7611652015-09-23 16:42:05 +05301834 }
nxpandroid8f6d0532017-07-12 18:25:30 +05301835 /* Validate status code and NFCID2 response from tag */
1836 else if ((p_t3t_rsp[T3T_MSG_RSP_OFFSET_STATUS1] !=
1837 T3T_MSG_RSP_STATUS_OK) /* verify response status code */
nxf24591c1cbeab2018-02-21 17:32:26 +05301838 || (memcmp(p_cb->peer_nfcid2, &p_t3t_rsp[T3T_MSG_RSP_OFFSET_IDM],
1839 NCI_NFCID2_LEN) != 0)) /* verify response IDm */
nxpandroidc7611652015-09-23 16:42:05 +05301840 {
nxpandroid8f6d0532017-07-12 18:25:30 +05301841 evt_data.status = NFC_STATUS_FAILED;
1842 } else {
1843 /* Check if memory configuration (MC) block to see if SYS_OP=1 (NDEF
1844 * enabled) */
1845 p_mc = &p_t3t_rsp[T3T_MSG_RSP_OFFSET_CHECK_DATA]; /* Point to MC data of
1846 CHECK response */
nxpandroidc7611652015-09-23 16:42:05 +05301847
nxpandroid8f6d0532017-07-12 18:25:30 +05301848 if (p_mc[T3T_MSG_FELICALITE_MC_OFFSET_SYS_OP] != 0x01) {
1849 /* Tag is not currently enabled for NDEF. Indicate that we need to
1850 * update the MC block */
nxpandroidc7611652015-09-23 16:42:05 +05301851
nxpandroid8f6d0532017-07-12 18:25:30 +05301852 /* Set SYS_OP field to 0x01 (enable NDEF) */
1853 p_mc[T3T_MSG_FELICALITE_MC_OFFSET_SYS_OP] = 0x01;
nxpandroidc7611652015-09-23 16:42:05 +05301854
nxpandroid8f6d0532017-07-12 18:25:30 +05301855 /* Set RF_PRM field to 0x07 (procedure of issuance) */
1856 p_mc[T3T_MSG_FELICALITE_MC_OFFSET_RF_PRM] = 0x07;
nxpandroidc7611652015-09-23 16:42:05 +05301857
nxpandroid8f6d0532017-07-12 18:25:30 +05301858 /* Construct and send UPDATE message to write MC block */
1859 p_cb->rw_substate = RW_T3T_FMT_SST_UPDATE_MC_BLK;
1860 evt_data.status =
1861 rw_t3t_update_block(p_cb, T3T_MSG_FELICALITE_BLOCK_ID_MC, p_mc);
1862 } else {
1863 /* SYS_OP=1: ndef already enabled. Just need to update attribute
1864 * information block */
1865 p_cb->rw_substate = RW_T3T_FMT_SST_UPDATE_NDEF_ATTRIB;
1866 evt_data.status =
1867 rw_t3t_update_block(p_cb, 0, (uint8_t*)rw_t3t_default_attrib_info);
1868 }
nxpandroidc7611652015-09-23 16:42:05 +05301869 }
1870
nxpandroid8f6d0532017-07-12 18:25:30 +05301871 /* If error, notify upper layer */
1872 if (evt_data.status != NFC_STATUS_OK) {
1873 rw_t3t_format_cplt(evt_data.status);
1874 }
1875 } else if (p_cb->rw_substate == RW_T3T_FMT_SST_UPDATE_MC_BLK) {
1876 /* Validate response opcode */
1877 if ((p_t3t_rsp[T3T_MSG_RSP_OFFSET_RSPCODE] != T3T_MSG_OPC_UPDATE_RSP) ||
1878 (p_t3t_rsp[T3T_MSG_RSP_OFFSET_STATUS1] != T3T_MSG_RSP_STATUS_OK))
1879
1880 {
nxf24591c1cbeab2018-02-21 17:32:26 +05301881 LOG(ERROR) << StringPrintf("Response error: rsp_code=%02X, status=%02X",
1882 p_t3t_rsp[T3T_MSG_RSP_OFFSET_RSPCODE],
1883 p_t3t_rsp[T3T_MSG_RSP_OFFSET_STATUS1]);
nxpandroid8f6d0532017-07-12 18:25:30 +05301884 evt_data.status = NFC_STATUS_FAILED;
1885 } else {
1886 /* SYS_OP=1: ndef already enabled. Just need to update attribute
1887 * information block */
1888 p_cb->rw_substate = RW_T3T_FMT_SST_UPDATE_NDEF_ATTRIB;
1889 evt_data.status =
1890 rw_t3t_update_block(p_cb, 0, (uint8_t*)rw_t3t_default_attrib_info);
1891 }
1892
1893 /* If error, notify upper layer */
1894 if (evt_data.status != NFC_STATUS_OK) {
1895 rw_t3t_format_cplt(evt_data.status);
1896 }
1897 } else if (p_cb->rw_substate == RW_T3T_FMT_SST_UPDATE_NDEF_ATTRIB) {
1898 /* Validate response opcode */
1899 if ((p_t3t_rsp[T3T_MSG_RSP_OFFSET_RSPCODE] != T3T_MSG_OPC_UPDATE_RSP) ||
1900 (p_t3t_rsp[T3T_MSG_RSP_OFFSET_STATUS1] != T3T_MSG_RSP_STATUS_OK))
1901
1902 {
nxf24591c1cbeab2018-02-21 17:32:26 +05301903 LOG(ERROR) << StringPrintf("Response error: rsp_code=%02X, status=%02X",
1904 p_t3t_rsp[T3T_MSG_RSP_OFFSET_RSPCODE],
1905 p_t3t_rsp[T3T_MSG_RSP_OFFSET_STATUS1]);
nxpandroid8f6d0532017-07-12 18:25:30 +05301906 evt_data.status = NFC_STATUS_FAILED;
1907 }
1908
1909 rw_t3t_format_cplt(evt_data.status);
1910 }
1911
1912 GKI_freebuf(p_msg_rsp);
nxpandroidc7611652015-09-23 16:42:05 +05301913}
1914
1915/*****************************************************************************
1916**
1917** Function rw_t3t_handle_sro_poll_rsp
1918**
1919** Description Handle POLL response for configuring felica-lite read only
1920**
1921** Returns Nothing
1922**
1923*****************************************************************************/
nxpandroid8f6d0532017-07-12 18:25:30 +05301924static void rw_t3t_handle_sro_poll_rsp(tRW_T3T_CB* p_cb, uint8_t nci_status,
nxf24591c1cbeab2018-02-21 17:32:26 +05301925 uint8_t num_responses) {
nxpandroid8f6d0532017-07-12 18:25:30 +05301926 tRW_DATA evt_data;
1927 uint8_t rw_t3t_ndef_attrib_info[T3T_MSG_BLOCKSIZE];
1928 uint8_t* p;
1929 uint8_t tempU8;
1930 uint16_t checksum, i;
1931 uint32_t tempU32 = 0;
nxpandroidc7611652015-09-23 16:42:05 +05301932
nxpandroid8f6d0532017-07-12 18:25:30 +05301933 evt_data.status = NFC_STATUS_OK;
nxpandroidc7611652015-09-23 16:42:05 +05301934
nxpandroid8f6d0532017-07-12 18:25:30 +05301935 /* Validate response for poll response */
1936 if ((nci_status == NCI_STATUS_OK) && (num_responses > 0)) {
1937 /* Tag responded for Felica-Lite poll */
1938 if (p_cb->ndef_attrib.rwflag != T3T_MSG_NDEF_RWFLAG_RO) {
1939 /* First update attribute information block */
nxf24591c1cbeab2018-02-21 17:32:26 +05301940 DLOG_IF(INFO, nfc_debug_enabled) << StringPrintf(
nxpandroid8f6d0532017-07-12 18:25:30 +05301941 "Felica-Lite tag detected...update NDef attribution block.");
nxpandroidc7611652015-09-23 16:42:05 +05301942
nxpandroid8f6d0532017-07-12 18:25:30 +05301943 p_cb->rw_substate = RW_T3T_SRO_SST_UPDATE_NDEF_ATTRIB;
nxpandroidc7611652015-09-23 16:42:05 +05301944
nxpandroid8f6d0532017-07-12 18:25:30 +05301945 p = rw_t3t_ndef_attrib_info;
nxpandroidc7611652015-09-23 16:42:05 +05301946
nxpandroid8f6d0532017-07-12 18:25:30 +05301947 UINT8_TO_STREAM(p, p_cb->ndef_attrib.version);
nxpandroidc7611652015-09-23 16:42:05 +05301948
nxpandroid8f6d0532017-07-12 18:25:30 +05301949 /* Update NDEF info */
1950 UINT8_TO_STREAM(
1951 p, p_cb->ndef_attrib.nbr); /* NBr: number of blocks that can be read
1952 using one Check command */
1953 UINT8_TO_STREAM(p, p_cb->ndef_attrib.nbw); /* Nbw: number of blocks that
1954 can be written using one
1955 Update command */
1956 UINT16_TO_BE_STREAM(
1957 p, p_cb->ndef_attrib.nmaxb); /* Nmaxb: maximum number of blocks
1958 available for NDEF data */
1959 UINT32_TO_BE_STREAM(p, tempU32);
1960 UINT8_TO_STREAM(p,
1961 p_cb->ndef_attrib.writef); /* WriteFlag: 00h if writing
1962 data finished; 0Fh if
1963 writing data in progress */
1964 UINT8_TO_STREAM(p, 0x00); /* RWFlag: 00h NDEF is read-only */
nxpandroidc7611652015-09-23 16:42:05 +05301965
nxpandroid8f6d0532017-07-12 18:25:30 +05301966 tempU8 = (uint8_t)(p_cb->ndef_attrib.ln >> 16);
1967 /* Get length (3-byte, big-endian) */
1968 UINT8_TO_STREAM(p, tempU8); /* Ln: high-byte */
1969 UINT16_TO_BE_STREAM(p, p_cb->ndef_attrib.ln); /* Ln: lo-word */
nxpandroidc7611652015-09-23 16:42:05 +05301970
nxpandroid8f6d0532017-07-12 18:25:30 +05301971 /* Calculate and append Checksum */
1972 checksum = 0;
1973 for (i = 0; i < T3T_MSG_NDEF_ATTR_INFO_SIZE; i++) {
1974 checksum += rw_t3t_ndef_attrib_info[i];
1975 }
1976 UINT16_TO_BE_STREAM(p, checksum);
nxpandroidc7611652015-09-23 16:42:05 +05301977
nxpandroid8f6d0532017-07-12 18:25:30 +05301978 evt_data.status =
1979 rw_t3t_update_block(p_cb, 0, (uint8_t*)rw_t3t_ndef_attrib_info);
1980 } else if (p_cb->cur_cmd == RW_T3T_CMD_SET_READ_ONLY_HARD) {
1981 /* NDEF is already read only, Read and update MemoryControl block */
nxf24591c1cbeab2018-02-21 17:32:26 +05301982 DLOG_IF(INFO, nfc_debug_enabled) << StringPrintf(
nxpandroid8f6d0532017-07-12 18:25:30 +05301983 "Felica-Lite tag detected...getting Memory Control block.");
1984 p_cb->rw_substate = RW_T3T_SRO_SST_CHECK_MC_BLK;
nxpandroidc7611652015-09-23 16:42:05 +05301985
nxpandroid8f6d0532017-07-12 18:25:30 +05301986 /* Send command to check Memory Configuration block */
1987 evt_data.status = rw_t3t_check_mc_block(p_cb);
nxpandroidc7611652015-09-23 16:42:05 +05301988 }
nxpandroid8f6d0532017-07-12 18:25:30 +05301989 } else {
nxf24591c1cbeab2018-02-21 17:32:26 +05301990 LOG(ERROR) << StringPrintf("Felica-Lite tag not detected");
nxpandroid8f6d0532017-07-12 18:25:30 +05301991 evt_data.status = NFC_STATUS_FAILED;
1992 }
nxpandroidc7611652015-09-23 16:42:05 +05301993
nxpandroid8f6d0532017-07-12 18:25:30 +05301994 /* If error, notify upper layer */
1995 if (evt_data.status != NFC_STATUS_OK) {
1996 rw_t3t_set_readonly_cplt(evt_data.status);
1997 }
nxpandroidc7611652015-09-23 16:42:05 +05301998}
1999
2000/*****************************************************************************
2001**
2002** Function rw_t3t_act_handle_sro_rsp
2003**
2004** Description Handle response for setting read only codes
2005**
2006** Returns Nothing
2007**
2008*****************************************************************************/
nxpandroid8f6d0532017-07-12 18:25:30 +05302009void rw_t3t_act_handle_sro_rsp(tRW_T3T_CB* p_cb, NFC_HDR* p_msg_rsp) {
2010 uint8_t* p_t3t_rsp = (uint8_t*)(p_msg_rsp + 1) + p_msg_rsp->offset;
2011 uint8_t* p_mc;
2012 tRW_DATA evt_data;
nxpandroidc7611652015-09-23 16:42:05 +05302013
nxpandroid8f6d0532017-07-12 18:25:30 +05302014 evt_data.status = NFC_STATUS_OK;
nxpandroidc7611652015-09-23 16:42:05 +05302015
nxpandroid8f6d0532017-07-12 18:25:30 +05302016 if (p_cb->rw_substate == RW_T3T_SRO_SST_UPDATE_NDEF_ATTRIB) {
2017 /* Validate response opcode */
2018 if ((p_t3t_rsp[T3T_MSG_RSP_OFFSET_RSPCODE] != T3T_MSG_OPC_UPDATE_RSP) ||
2019 (p_t3t_rsp[T3T_MSG_RSP_OFFSET_STATUS1] != T3T_MSG_RSP_STATUS_OK))
2020
nxpandroidc7611652015-09-23 16:42:05 +05302021 {
nxf24591c1cbeab2018-02-21 17:32:26 +05302022 LOG(ERROR) << StringPrintf("Response error: rsp_code=%02X, status=%02X",
2023 p_t3t_rsp[T3T_MSG_RSP_OFFSET_RSPCODE],
2024 p_t3t_rsp[T3T_MSG_RSP_OFFSET_STATUS1]);
nxpandroid8f6d0532017-07-12 18:25:30 +05302025 evt_data.status = NFC_STATUS_FAILED;
2026 } else {
2027 p_cb->ndef_attrib.rwflag = T3T_MSG_NDEF_RWFLAG_RO;
2028 if (p_cb->cur_cmd == RW_T3T_CMD_SET_READ_ONLY_HARD) {
2029 p_cb->rw_substate = RW_T3T_SRO_SST_CHECK_MC_BLK;
nxpandroidc7611652015-09-23 16:42:05 +05302030
nxpandroid8f6d0532017-07-12 18:25:30 +05302031 /* Send command to check Memory Configuration block */
2032 evt_data.status = rw_t3t_check_mc_block(p_cb);
2033 } else {
2034 rw_t3t_set_readonly_cplt(evt_data.status);
2035 }
nxpandroidc7611652015-09-23 16:42:05 +05302036 }
nxpandroid8f6d0532017-07-12 18:25:30 +05302037 } else if (p_cb->rw_substate == RW_T3T_SRO_SST_CHECK_MC_BLK) {
2038 /* Check tags's response for reading MemoryControl block, Validate response
2039 * opcode */
2040 if (p_t3t_rsp[T3T_MSG_RSP_OFFSET_RSPCODE] != T3T_MSG_OPC_CHECK_RSP) {
nxf24591c1cbeab2018-02-21 17:32:26 +05302041 LOG(ERROR) << StringPrintf(
2042 "Response error: expecting rsp_code %02X, but got %02X",
2043 T3T_MSG_OPC_CHECK_RSP, p_t3t_rsp[T3T_MSG_RSP_OFFSET_RSPCODE]);
nxpandroid8f6d0532017-07-12 18:25:30 +05302044 evt_data.status = NFC_STATUS_FAILED;
2045 }
2046 /* Validate status code and NFCID2 response from tag */
2047 else if ((p_t3t_rsp[T3T_MSG_RSP_OFFSET_STATUS1] !=
2048 T3T_MSG_RSP_STATUS_OK) /* verify response status code */
nxf24591c1cbeab2018-02-21 17:32:26 +05302049 || (memcmp(p_cb->peer_nfcid2, &p_t3t_rsp[T3T_MSG_RSP_OFFSET_IDM],
2050 NCI_NFCID2_LEN) != 0)) /* verify response IDm */
nxpandroidc7611652015-09-23 16:42:05 +05302051 {
nxpandroid8f6d0532017-07-12 18:25:30 +05302052 evt_data.status = NFC_STATUS_FAILED;
2053 } else {
2054 /* Check if memory configuration (MC) block to see if SYS_OP=1 (NDEF
2055 * enabled) */
2056 p_mc = &p_t3t_rsp[T3T_MSG_RSP_OFFSET_CHECK_DATA]; /* Point to MC data of
2057 CHECK response */
nxpandroidc7611652015-09-23 16:42:05 +05302058
nxpandroid8f6d0532017-07-12 18:25:30 +05302059 if (p_mc[T3T_MSG_FELICALITE_MC_OFFSET_SYS_OP] != 0x01) {
2060 /* Tag is not currently enabled for NDEF */
2061 evt_data.status = NFC_STATUS_FAILED;
2062 } else {
2063 /* Set MC_SP field with MC[0] = 0x00 & MC[1] = 0xC0 (Hardlock) to change
2064 * access permission from RW to RO */
2065 p_mc[T3T_MSG_FELICALITE_MC_OFFSET_MC_SP] = 0x00;
2066 /* Not changing the access permission of Subtraction Register and
2067 * MC[0:1] */
2068 p_mc[T3T_MSG_FELICALITE_MC_OFFSET_MC_SP + 1] = 0xC0;
nxpandroidc7611652015-09-23 16:42:05 +05302069
nxpandroid8f6d0532017-07-12 18:25:30 +05302070 /* Set RF_PRM field to 0x07 (procedure of issuance) */
2071 p_mc[T3T_MSG_FELICALITE_MC_OFFSET_RF_PRM] = 0x07;
nxpandroidc7611652015-09-23 16:42:05 +05302072
nxpandroid8f6d0532017-07-12 18:25:30 +05302073 /* Construct and send UPDATE message to write MC block */
2074 p_cb->rw_substate = RW_T3T_SRO_SST_UPDATE_MC_BLK;
2075 evt_data.status =
2076 rw_t3t_update_block(p_cb, T3T_MSG_FELICALITE_BLOCK_ID_MC, p_mc);
2077 }
nxpandroidc7611652015-09-23 16:42:05 +05302078 }
nxpandroid8f6d0532017-07-12 18:25:30 +05302079 } else if (p_cb->rw_substate == RW_T3T_SRO_SST_UPDATE_MC_BLK) {
2080 /* Validate response opcode */
2081 if ((p_t3t_rsp[T3T_MSG_RSP_OFFSET_RSPCODE] != T3T_MSG_OPC_UPDATE_RSP) ||
2082 (p_t3t_rsp[T3T_MSG_RSP_OFFSET_STATUS1] != T3T_MSG_RSP_STATUS_OK))
2083
nxpandroidc7611652015-09-23 16:42:05 +05302084 {
nxf24591c1cbeab2018-02-21 17:32:26 +05302085 LOG(ERROR) << StringPrintf("Response error: rsp_code=%02X, status=%02X",
2086 p_t3t_rsp[T3T_MSG_RSP_OFFSET_RSPCODE],
2087 p_t3t_rsp[T3T_MSG_RSP_OFFSET_STATUS1]);
nxpandroid8f6d0532017-07-12 18:25:30 +05302088 evt_data.status = NFC_STATUS_FAILED;
2089 } else {
2090 rw_t3t_set_readonly_cplt(evt_data.status);
nxpandroidc7611652015-09-23 16:42:05 +05302091 }
nxpandroid8f6d0532017-07-12 18:25:30 +05302092 }
nxpandroidc7611652015-09-23 16:42:05 +05302093
nxpandroid8f6d0532017-07-12 18:25:30 +05302094 /* If error, notify upper layer */
2095 if (evt_data.status != NFC_STATUS_OK) {
2096 rw_t3t_set_readonly_cplt(evt_data.status);
2097 }
nxpandroidc7611652015-09-23 16:42:05 +05302098
nxpandroid8f6d0532017-07-12 18:25:30 +05302099 GKI_freebuf(p_msg_rsp);
nxpandroidc7611652015-09-23 16:42:05 +05302100}
2101
2102/*******************************************************************************
2103**
2104** Function rw_t3t_data_cback
2105**
2106** Description This callback function receives the data from NFCC.
2107**
2108** Returns none
2109**
2110*******************************************************************************/
nxf24591c1cbeab2018-02-21 17:32:26 +05302111void rw_t3t_data_cback(__attribute__((unused)) uint8_t conn_id,
2112 tNFC_DATA_CEVT* p_data) {
nxpandroid8f6d0532017-07-12 18:25:30 +05302113 tRW_T3T_CB* p_cb = &rw_cb.tcb.t3t;
2114 NFC_HDR* p_msg = p_data->p_data;
nxf24591c1cbeab2018-02-21 17:32:26 +05302115 bool free_msg = false; /* if TRUE, free msg buffer before returning */
2116 uint8_t *p, sod;
nxpandroidc7611652015-09-23 16:42:05 +05302117
nxpandroid8f6d0532017-07-12 18:25:30 +05302118 /* Stop rsponse timer */
2119 nfc_stop_quick_timer(&p_cb->timer);
nxpandroidc7611652015-09-23 16:42:05 +05302120
nxf24591c1cbeab2018-02-21 17:32:26 +05302121#if (RW_STATS_INCLUDED == TRUE)
nxpandroid8f6d0532017-07-12 18:25:30 +05302122 /* Update rx stats */
2123 rw_main_update_rx_stats(p_msg->len);
2124#endif /* RW_STATS_INCLUDED */
nxpandroidc7611652015-09-23 16:42:05 +05302125
nxpandroid8f6d0532017-07-12 18:25:30 +05302126 /* Check if we are expecting a response */
2127 if (p_cb->rw_state != RW_T3T_STATE_COMMAND_PENDING) {
2128 /*
2129 ** This must be raw frame response
2130 ** send raw frame to app with SoD
2131 */
2132 rw_t3t_act_handle_raw_senddata_rsp(p_cb, p_data);
2133 }
2134 /* Sanity check: verify msg len is big enough to contain t3t header */
2135 else if (p_msg->len < T3T_MSG_RSP_COMMON_HDR_LEN) {
nxf24591c1cbeab2018-02-21 17:32:26 +05302136 LOG(ERROR) << StringPrintf(
2137 "T3T: invalid Type3 Tag Message (invalid len: %i)", p_msg->len);
nxpandroid8f6d0532017-07-12 18:25:30 +05302138 free_msg = true;
2139
2140 rw_t3t_process_frame_error();
2141 } else {
2142 /* Check for RF frame error */
2143 p = (uint8_t*)(p_msg + 1) + p_msg->offset;
2144 sod = p[0];
2145 if (p[sod] != NCI_STATUS_OK) {
nxf24591c1cbeab2018-02-21 17:32:26 +05302146 LOG(ERROR) << StringPrintf("T3T: rf frame error (crc status=%i)", p[sod]);
nxpandroid8f6d0532017-07-12 18:25:30 +05302147 GKI_freebuf(p_msg);
2148
2149 rw_t3t_process_frame_error();
2150 return;
nxpandroidc7611652015-09-23 16:42:05 +05302151 }
nxpandroidc7611652015-09-23 16:42:05 +05302152
nxpandroid8f6d0532017-07-12 18:25:30 +05302153 /* Skip over SoD */
2154 p_msg->offset++;
2155 p_msg->len--;
nxpandroidc7611652015-09-23 16:42:05 +05302156
nxpandroid8f6d0532017-07-12 18:25:30 +05302157 /* Get response code */
2158 switch (p_cb->cur_cmd) {
2159 case RW_T3T_CMD_DETECT_NDEF:
2160 rw_t3t_act_handle_ndef_detect_rsp(p_cb, p_msg);
2161 break;
nxpandroidc7611652015-09-23 16:42:05 +05302162
nxpandroid8f6d0532017-07-12 18:25:30 +05302163 case RW_T3T_CMD_CHECK_NDEF:
2164 rw_t3t_act_handle_check_ndef_rsp(p_cb, p_msg);
2165 break;
nxpandroidc7611652015-09-23 16:42:05 +05302166
nxpandroid8f6d0532017-07-12 18:25:30 +05302167 case RW_T3T_CMD_UPDATE_NDEF:
2168 rw_t3t_act_handle_update_ndef_rsp(p_cb, p_msg);
2169 break;
nxpandroidc7611652015-09-23 16:42:05 +05302170
nxpandroid8f6d0532017-07-12 18:25:30 +05302171 case RW_T3T_CMD_CHECK:
2172 rw_t3t_act_handle_check_rsp(p_cb, p_msg);
2173 break;
nxpandroidc7611652015-09-23 16:42:05 +05302174
nxpandroid8f6d0532017-07-12 18:25:30 +05302175 case RW_T3T_CMD_UPDATE:
2176 rw_t3t_act_handle_update_rsp(p_cb, p_msg);
2177 break;
nxpandroidc7611652015-09-23 16:42:05 +05302178
nxpandroid8f6d0532017-07-12 18:25:30 +05302179 case RW_T3T_CMD_SEND_RAW_FRAME:
2180 rw_t3t_act_handle_raw_senddata_rsp(p_cb, p_data);
2181 break;
nxpandroidc7611652015-09-23 16:42:05 +05302182
nxpandroid8f6d0532017-07-12 18:25:30 +05302183 case RW_T3T_CMD_FORMAT:
2184 rw_t3t_act_handle_fmt_rsp(p_cb, p_msg);
2185 break;
nxpandroidc7611652015-09-23 16:42:05 +05302186
nxpandroid8f6d0532017-07-12 18:25:30 +05302187 case RW_T3T_CMD_SET_READ_ONLY_SOFT:
2188 case RW_T3T_CMD_SET_READ_ONLY_HARD:
2189 rw_t3t_act_handle_sro_rsp(p_cb, p_msg);
2190 break;
nxpandroidc7611652015-09-23 16:42:05 +05302191
nxpandroid8f6d0532017-07-12 18:25:30 +05302192 default:
2193 GKI_freebuf(p_msg);
2194 break;
nxpandroidc7611652015-09-23 16:42:05 +05302195 }
nxpandroid8f6d0532017-07-12 18:25:30 +05302196 }
nxpandroidc7611652015-09-23 16:42:05 +05302197
nxpandroid8f6d0532017-07-12 18:25:30 +05302198 if (free_msg) {
2199 GKI_freebuf(p_msg);
2200 }
nxpandroidc7611652015-09-23 16:42:05 +05302201}
2202
nxpandroidc7611652015-09-23 16:42:05 +05302203/*******************************************************************************
2204**
2205** Function rw_t3t_conn_cback
2206**
2207** Description This callback function receives the events/data from NFCC.
2208**
2209** Returns none
2210**
2211*******************************************************************************/
nxpandroid8f6d0532017-07-12 18:25:30 +05302212void rw_t3t_conn_cback(uint8_t conn_id, tNFC_CONN_EVT event,
2213 tNFC_CONN* p_data) {
2214 tRW_T3T_CB* p_cb = &rw_cb.tcb.t3t;
nxf24591c1cbeab2018-02-21 17:32:26 +05302215 DLOG_IF(INFO, nfc_debug_enabled) << StringPrintf(
2216 "rw_t3t_conn_cback: conn_id=%i, evt=0x%02x", conn_id, event);
nxpandroidc7611652015-09-23 16:42:05 +05302217
nxpandroid8f6d0532017-07-12 18:25:30 +05302218 /* Only handle NFC_RF_CONN_ID conn_id */
2219 if (conn_id != NFC_RF_CONN_ID) {
2220 return;
2221 }
nxpandroidc7611652015-09-23 16:42:05 +05302222
nxpandroid8f6d0532017-07-12 18:25:30 +05302223 switch (event) {
nxpandroidc7611652015-09-23 16:42:05 +05302224 case NFC_DEACTIVATE_CEVT:
nxf24591c1cbeab2018-02-21 17:32:26 +05302225 rw_t3t_unselect();
nxpandroid8f6d0532017-07-12 18:25:30 +05302226 break;
2227
2228 case NFC_DATA_CEVT: /* check for status in tNFC_CONN */
2229 if ((p_data != NULL) && ((p_data->data.status == NFC_STATUS_OK) ||
2230 (p_data->data.status == NFC_STATUS_CONTINUE))) {
2231 rw_t3t_data_cback(conn_id, &(p_data->data));
nxpandroidc7611652015-09-23 16:42:05 +05302232 break;
nxpandroid8f6d0532017-07-12 18:25:30 +05302233 } else if (p_data->data.p_data != NULL) {
2234 /* Free the response buffer in case of error response */
2235 GKI_freebuf((NFC_HDR*)(p_data->data.p_data));
2236 p_data->data.p_data = NULL;
2237 }
2238 /* Data event with error status...fall through to NFC_ERROR_CEVT case */
nxpandroidc7611652015-09-23 16:42:05 +05302239
2240 case NFC_ERROR_CEVT:
nxpandroid8f6d0532017-07-12 18:25:30 +05302241 nfc_stop_quick_timer(&p_cb->timer);
nxpandroidc7611652015-09-23 16:42:05 +05302242
nxf24591c1cbeab2018-02-21 17:32:26 +05302243#if (RW_STATS_INCLUDED == TRUE)
nxpandroid8f6d0532017-07-12 18:25:30 +05302244 rw_main_update_trans_error_stats();
2245#endif /* RW_STATS_INCLUDED */
nxpandroidc7611652015-09-23 16:42:05 +05302246
nxpandroid8f6d0532017-07-12 18:25:30 +05302247 if (event == NFC_ERROR_CEVT)
2248 rw_t3t_process_error(NFC_STATUS_TIMEOUT);
2249 else if (p_data)
2250 rw_t3t_process_error(p_data->status);
nxpandroid8f6d0532017-07-12 18:25:30 +05302251 break;
nxpandroidc7611652015-09-23 16:42:05 +05302252
2253 default:
nxpandroid8f6d0532017-07-12 18:25:30 +05302254 break;
2255 }
nxpandroidc7611652015-09-23 16:42:05 +05302256}
2257
nxpandroidc7611652015-09-23 16:42:05 +05302258/*******************************************************************************
2259**
2260** Function rw_t3t_mrti_to_a_b
2261**
2262** Description Converts the given MRTI (Maximum Response Time Information)
2263** to the base to calculate timeout value.
2264** (The timeout value is a + b * number_blocks)
2265**
2266** Returns NFC_STATUS_OK
2267**
2268*******************************************************************************/
nxpandroid8f6d0532017-07-12 18:25:30 +05302269static void rw_t3t_mrti_to_a_b(uint8_t mrti, uint32_t* p_a, uint32_t* p_b) {
2270 uint8_t a, b, e;
nxpandroidc7611652015-09-23 16:42:05 +05302271
nxpandroid8f6d0532017-07-12 18:25:30 +05302272 a = (mrti & 0x7) + 1; /* A is bit 0 ~ bit 2 */
2273 mrti >>= 3;
2274 b = (mrti & 0x7) + 1; /* B is bit 3 ~ bit 5 */
2275 mrti >>= 3;
2276 e = mrti & 0x3; /* E is bit 6 ~ bit 7 */
2277 *p_a = rw_t3t_mrti_base[e] * a; /* (A+1) * base (i.e T/t3t * 4^E) */
2278 *p_b = rw_t3t_mrti_base[e] * b; /* (B+1) * base (i.e T/t3t * 4^E) */
nxpandroidc7611652015-09-23 16:42:05 +05302279}
2280
nxpandroidc7611652015-09-23 16:42:05 +05302281/*******************************************************************************
2282**
2283** Function rw_t3t_select
2284**
2285** Description Called by NFC manager when a Type3 tag has been activated
2286**
2287** Returns NFC_STATUS_OK
2288**
2289*******************************************************************************/
nxpandroid8f6d0532017-07-12 18:25:30 +05302290tNFC_STATUS rw_t3t_select(uint8_t peer_nfcid2[NCI_RF_F_UID_LEN],
2291 uint8_t mrti_check, uint8_t mrti_update) {
2292 tRW_T3T_CB* p_cb = &rw_cb.tcb.t3t;
nxpandroidc7611652015-09-23 16:42:05 +05302293
nxf24591c1cbeab2018-02-21 17:32:26 +05302294 DLOG_IF(INFO, nfc_debug_enabled) << __func__;
nxpandroidc7611652015-09-23 16:42:05 +05302295
nxpandroid8f6d0532017-07-12 18:25:30 +05302296 memcpy(p_cb->peer_nfcid2, peer_nfcid2,
2297 NCI_NFCID2_LEN); /* Store tag's NFCID2 */
2298 p_cb->ndef_attrib.status =
2299 NFC_STATUS_NOT_INITIALIZED; /* Indicate that NDEF detection has not been
2300 performed yet */
2301 p_cb->rw_state = RW_T3T_STATE_IDLE;
2302 p_cb->flags = 0;
2303 rw_t3t_mrti_to_a_b(mrti_check, &p_cb->check_tout_a, &p_cb->check_tout_b);
2304 rw_t3t_mrti_to_a_b(mrti_update, &p_cb->update_tout_a, &p_cb->update_tout_b);
nxpandroidc7611652015-09-23 16:42:05 +05302305
nxpandroid8f6d0532017-07-12 18:25:30 +05302306 /* Alloc cmd buf for retransmissions */
2307 if (p_cb->p_cur_cmd_buf == NULL) {
2308 p_cb->p_cur_cmd_buf = (NFC_HDR*)GKI_getpoolbuf(NFC_RW_POOL_ID);
2309 if (p_cb->p_cur_cmd_buf == NULL) {
nxf24591c1cbeab2018-02-21 17:32:26 +05302310 LOG(ERROR) << StringPrintf(
nxpandroid8f6d0532017-07-12 18:25:30 +05302311 "rw_t3t_select: unable to allocate buffer for retransmission");
2312 p_cb->rw_state = RW_T3T_STATE_NOT_ACTIVATED;
2313 return (NFC_STATUS_FAILED);
nxpandroidc7611652015-09-23 16:42:05 +05302314 }
nxpandroid8f6d0532017-07-12 18:25:30 +05302315 }
nxpandroidc7611652015-09-23 16:42:05 +05302316
nxpandroid8f6d0532017-07-12 18:25:30 +05302317 NFC_SetStaticRfCback(rw_t3t_conn_cback);
nxpandroidc7611652015-09-23 16:42:05 +05302318
nxpandroid8f6d0532017-07-12 18:25:30 +05302319 return NFC_STATUS_OK;
nxpandroidc7611652015-09-23 16:42:05 +05302320}
2321
nxpandroidc7611652015-09-23 16:42:05 +05302322/*******************************************************************************
2323**
2324** Function rw_t3t_unselect
2325**
2326** Description Called by NFC manager when a Type3 tag has been de-activated
2327**
2328** Returns NFC_STATUS_OK
2329**
2330*******************************************************************************/
nxf24591c1cbeab2018-02-21 17:32:26 +05302331static tNFC_STATUS rw_t3t_unselect() {
nxpandroid8f6d0532017-07-12 18:25:30 +05302332 tRW_T3T_CB* p_cb = &rw_cb.tcb.t3t;
nxpandroidc7611652015-09-23 16:42:05 +05302333
nxf24591c1cbeab2018-02-21 17:32:26 +05302334#if (RW_STATS_INCLUDED == TRUE)
nxpandroid8f6d0532017-07-12 18:25:30 +05302335 /* Display stats */
2336 rw_main_log_stats();
2337#endif /* RW_STATS_INCLUDED */
nxpandroidc7611652015-09-23 16:42:05 +05302338
nxpandroid8f6d0532017-07-12 18:25:30 +05302339 /* Stop t3t timer (if started) */
2340 nfc_stop_quick_timer(&p_cb->timer);
nxpandroidc7611652015-09-23 16:42:05 +05302341
nxpandroid8f6d0532017-07-12 18:25:30 +05302342 /* Free cmd buf for retransmissions */
2343 if (p_cb->p_cur_cmd_buf) {
2344 GKI_freebuf(p_cb->p_cur_cmd_buf);
2345 p_cb->p_cur_cmd_buf = NULL;
2346 }
nxpandroidc7611652015-09-23 16:42:05 +05302347
nxpandroid8f6d0532017-07-12 18:25:30 +05302348 p_cb->rw_state = RW_T3T_STATE_NOT_ACTIVATED;
2349 NFC_SetStaticRfCback(NULL);
nxpandroidc7611652015-09-23 16:42:05 +05302350
nxpandroid8f6d0532017-07-12 18:25:30 +05302351 return NFC_STATUS_OK;
nxpandroidc7611652015-09-23 16:42:05 +05302352}
2353
2354/*******************************************************************************
2355**
2356** Function rw_t3t_update_ndef_flag
2357**
2358** Description set additional NDEF Flags for felica lite tag
2359**
2360** Returns updated NDEF Flag value
2361**
2362*******************************************************************************/
nxpandroid8f6d0532017-07-12 18:25:30 +05302363static void rw_t3t_update_ndef_flag(uint8_t* p_flag) {
2364 tRW_T3T_CB* p_cb = &rw_cb.tcb.t3t;
2365 uint8_t xx;
nxpandroidc7611652015-09-23 16:42:05 +05302366
nxpandroid8f6d0532017-07-12 18:25:30 +05302367 for (xx = 0; xx < p_cb->num_system_codes; xx++) {
2368 if (p_cb->system_codes[xx] == T3T_SYSTEM_CODE_FELICA_LITE) {
2369 *p_flag &= ~RW_NDEF_FL_UNKNOWN;
2370 *p_flag |= (RW_NDEF_FL_SUPPORTED | RW_NDEF_FL_FORMATABLE);
2371 break;
nxpandroidc7611652015-09-23 16:42:05 +05302372 }
nxpandroid8f6d0532017-07-12 18:25:30 +05302373 }
nxpandroidc7611652015-09-23 16:42:05 +05302374}
2375
nxpandroidc7611652015-09-23 16:42:05 +05302376/*******************************************************************************
2377**
2378** Function rw_t3t_cmd_str
2379**
2380** Description Converts cmd_id to command string for logging
2381**
2382** Returns command string
2383**
2384*******************************************************************************/
nxf24591c1cbeab2018-02-21 17:32:26 +05302385static std::string rw_t3t_cmd_str(uint8_t cmd_id) {
nxpandroid8f6d0532017-07-12 18:25:30 +05302386 switch (cmd_id) {
nxpandroidc7611652015-09-23 16:42:05 +05302387 case RW_T3T_CMD_DETECT_NDEF:
nxpandroid8f6d0532017-07-12 18:25:30 +05302388 return "RW_T3T_CMD_DETECT_NDEF";
nxpandroidc7611652015-09-23 16:42:05 +05302389 case RW_T3T_CMD_CHECK_NDEF:
nxpandroid8f6d0532017-07-12 18:25:30 +05302390 return "RW_T3T_CMD_CHECK_NDEF";
nxpandroidc7611652015-09-23 16:42:05 +05302391 case RW_T3T_CMD_UPDATE_NDEF:
nxpandroid8f6d0532017-07-12 18:25:30 +05302392 return "RW_T3T_CMD_UPDATE_NDEF";
nxpandroidc7611652015-09-23 16:42:05 +05302393 case RW_T3T_CMD_CHECK:
nxpandroid8f6d0532017-07-12 18:25:30 +05302394 return "RW_T3T_CMD_CHECK";
nxpandroidc7611652015-09-23 16:42:05 +05302395 case RW_T3T_CMD_UPDATE:
nxpandroid8f6d0532017-07-12 18:25:30 +05302396 return "RW_T3T_CMD_UPDATE";
nxpandroidc7611652015-09-23 16:42:05 +05302397 case RW_T3T_CMD_SEND_RAW_FRAME:
nxpandroid8f6d0532017-07-12 18:25:30 +05302398 return "RW_T3T_CMD_SEND_RAW_FRAME";
nxpandroidc7611652015-09-23 16:42:05 +05302399 case RW_T3T_CMD_GET_SYSTEM_CODES:
nxpandroid8f6d0532017-07-12 18:25:30 +05302400 return "RW_T3T_CMD_GET_SYSTEM_CODES";
nxpandroidc7611652015-09-23 16:42:05 +05302401 default:
nxpandroid8f6d0532017-07-12 18:25:30 +05302402 return "Unknown";
2403 }
nxpandroidc7611652015-09-23 16:42:05 +05302404}
2405
nxpandroidc7611652015-09-23 16:42:05 +05302406/*******************************************************************************
2407**
2408** Function rw_t3t_state_str
2409**
2410** Description Converts state_id to command string for logging
2411**
2412** Returns command string
2413**
2414*******************************************************************************/
nxf24591c1cbeab2018-02-21 17:32:26 +05302415static std::string rw_t3t_state_str(uint8_t state_id) {
nxpandroid8f6d0532017-07-12 18:25:30 +05302416 switch (state_id) {
nxpandroidc7611652015-09-23 16:42:05 +05302417 case RW_T3T_STATE_NOT_ACTIVATED:
nxpandroid8f6d0532017-07-12 18:25:30 +05302418 return "RW_T3T_STATE_NOT_ACTIVATED";
nxpandroidc7611652015-09-23 16:42:05 +05302419 case RW_T3T_STATE_IDLE:
nxpandroid8f6d0532017-07-12 18:25:30 +05302420 return "RW_T3T_STATE_IDLE";
nxpandroidc7611652015-09-23 16:42:05 +05302421 case RW_T3T_STATE_COMMAND_PENDING:
nxpandroid8f6d0532017-07-12 18:25:30 +05302422 return "RW_T3T_STATE_COMMAND_PENDING";
nxpandroidc7611652015-09-23 16:42:05 +05302423 default:
nxpandroid8f6d0532017-07-12 18:25:30 +05302424 return "Unknown";
2425 }
nxpandroidc7611652015-09-23 16:42:05 +05302426}
nxpandroidc7611652015-09-23 16:42:05 +05302427
2428/*****************************************************************************
2429** Type3 Tag API Functions
2430*****************************************************************************/
2431
nxpandroidc7611652015-09-23 16:42:05 +05302432/*****************************************************************************
2433**
2434** Function RW_T3tDetectNDef
2435**
2436** Description
2437** This function is used to perform NDEF detection on a Type 3 tag, and
2438** retrieve the tag's NDEF attribute information (block 0).
2439**
2440** Before using this API, the application must call RW_SelectTagType to
2441** indicate that a Type 3 tag has been activated, and to provide the
2442** tag's Manufacture ID (IDm) .
2443**
2444** Returns
2445** NFC_STATUS_OK: ndef detection procedure started
2446** NFC_STATUS_NO_BUFFERS: unable to allocate a buffer for this operation
2447** NFC_STATUS_FAILED: other error
2448**
2449*****************************************************************************/
nxpandroid8f6d0532017-07-12 18:25:30 +05302450tNFC_STATUS RW_T3tDetectNDef(void) {
2451 tRW_T3T_CB* p_cb = &rw_cb.tcb.t3t;
2452 tNFC_STATUS retval = NFC_STATUS_OK;
nxpandroidc7611652015-09-23 16:42:05 +05302453
nxf24591c1cbeab2018-02-21 17:32:26 +05302454 DLOG_IF(INFO, nfc_debug_enabled) << __func__;
nxpandroidc7611652015-09-23 16:42:05 +05302455
nxpandroid8f6d0532017-07-12 18:25:30 +05302456 /* Check if we are in valid state to handle this API */
2457 if (p_cb->rw_state != RW_T3T_STATE_IDLE) {
nxf24591c1cbeab2018-02-21 17:32:26 +05302458 LOG(ERROR) << StringPrintf("Error: invalid state to handle API (0x%x)",
2459 p_cb->rw_state);
nxpandroid8f6d0532017-07-12 18:25:30 +05302460 return (NFC_STATUS_FAILED);
2461 }
nxpandroidc7611652015-09-23 16:42:05 +05302462
nxpandroid8f6d0532017-07-12 18:25:30 +05302463 retval = (tNFC_STATUS)nci_snd_t3t_polling(T3T_SYSTEM_CODE_NDEF, 0, 0);
2464 if (retval == NCI_STATUS_OK) {
2465 p_cb->cur_cmd = RW_T3T_CMD_DETECT_NDEF;
2466 p_cb->cur_tout = RW_T3T_DEFAULT_CMD_TIMEOUT_TICKS;
2467 p_cb->cur_poll_rc = 0;
2468 p_cb->rw_state = RW_T3T_STATE_COMMAND_PENDING;
2469 p_cb->flags |= RW_T3T_FL_W4_NDEF_DETECT_POLL_RSP;
nxpandroidc7611652015-09-23 16:42:05 +05302470
nxpandroid8f6d0532017-07-12 18:25:30 +05302471 /* start timer for waiting for responses */
2472 rw_t3t_start_poll_timer(p_cb);
2473 }
nxpandroidc7611652015-09-23 16:42:05 +05302474
nxpandroid8f6d0532017-07-12 18:25:30 +05302475 return (retval);
nxpandroidc7611652015-09-23 16:42:05 +05302476}
2477
nxpandroidc7611652015-09-23 16:42:05 +05302478/*****************************************************************************
2479**
2480** Function RW_T3tCheckNDef
2481**
2482** Description
2483** Retrieve NDEF contents from a Type3 tag.
2484**
2485** The RW_T3T_CHECK_EVT event is used to notify the application for each
nxpandroid8f6d0532017-07-12 18:25:30 +05302486** segment of NDEF data received. The RW_T3T_CHECK_CPLT_EVT event is used
2487** to notify the application all segments have been received.
nxpandroidc7611652015-09-23 16:42:05 +05302488**
2489** Before using this API, the RW_T3tDetectNDef function must be called to
2490** verify that the tag contains NDEF data, and to retrieve the NDEF
2491** attributes.
2492**
2493** Internally, this command will be separated into multiple Tag 3 Check
2494** commands (if necessary) - depending on the tag's Nbr (max number of
2495** blocks per read) attribute.
2496**
2497** Returns
2498** NFC_STATUS_OK: check command started
2499** NFC_STATUS_NO_BUFFERS: unable to allocate a buffer for this operation
2500** NFC_STATUS_FAILED: other error
2501**
2502*****************************************************************************/
nxpandroid8f6d0532017-07-12 18:25:30 +05302503tNFC_STATUS RW_T3tCheckNDef(void) {
2504 tNFC_STATUS retval = NFC_STATUS_OK;
2505 tRW_T3T_CB* p_cb = &rw_cb.tcb.t3t;
nxpandroidc7611652015-09-23 16:42:05 +05302506
nxf24591c1cbeab2018-02-21 17:32:26 +05302507 DLOG_IF(INFO, nfc_debug_enabled) << __func__;
nxpandroidc7611652015-09-23 16:42:05 +05302508
nxpandroid8f6d0532017-07-12 18:25:30 +05302509 /* Check if we are in valid state to handle this API */
2510 if (p_cb->rw_state != RW_T3T_STATE_IDLE) {
nxf24591c1cbeab2018-02-21 17:32:26 +05302511 LOG(ERROR) << StringPrintf("Error: invalid state to handle API (0x%x)",
2512 p_cb->rw_state);
nxpandroid8f6d0532017-07-12 18:25:30 +05302513 return (NFC_STATUS_FAILED);
2514 } else if (p_cb->ndef_attrib.status !=
2515 NFC_STATUS_OK) /* NDEF detection not performed yet? */
2516 {
nxf24591c1cbeab2018-02-21 17:32:26 +05302517 LOG(ERROR) << StringPrintf("Error: NDEF detection not performed yet");
nxpandroid8f6d0532017-07-12 18:25:30 +05302518 return (NFC_STATUS_NOT_INITIALIZED);
2519 } else if (p_cb->ndef_attrib.ln == 0) {
nxf24591c1cbeab2018-02-21 17:32:26 +05302520 LOG(ERROR) << StringPrintf("Type 3 tag contains empty NDEF message");
nxpandroid8f6d0532017-07-12 18:25:30 +05302521 return (NFC_STATUS_FAILED);
2522 }
nxpandroidc7611652015-09-23 16:42:05 +05302523
nxpandroid8f6d0532017-07-12 18:25:30 +05302524 /* Check number of blocks needed for this update */
2525 p_cb->flags &= ~RW_T3T_FL_IS_FINAL_NDEF_SEGMENT;
2526 p_cb->ndef_rx_offset = 0;
2527 retval = rw_t3t_send_next_ndef_check_cmd(p_cb);
nxpandroidc7611652015-09-23 16:42:05 +05302528
nxpandroid8f6d0532017-07-12 18:25:30 +05302529 return (retval);
nxpandroidc7611652015-09-23 16:42:05 +05302530}
2531
2532/*****************************************************************************
2533**
2534** Function RW_T3tUpdateNDef
2535**
2536** Description
2537** Write NDEF contents to a Type3 tag.
2538**
2539** The RW_T3T_UPDATE_CPLT_EVT callback event will be used to notify the
2540** application of the response.
2541**
2542** Before using this API, the RW_T3tDetectNDef function must be called to
2543** verify that the tag contains NDEF data, and to retrieve the NDEF
2544** attributes.
2545**
2546** Internally, this command will be separated into multiple Tag 3 Update
2547** commands (if necessary) - depending on the tag's Nbw (max number of
2548** blocks per write) attribute.
2549**
2550** Returns
2551** NFC_STATUS_OK: check command started
2552** NFC_STATUS_NO_BUFFERS: unable to allocate a buffer for this operation
2553** NFC_STATUS_REFUSED: tag is read-only
2554** NFC_STATUS_BUFFER_FULL: len exceeds tag's maximum size
2555** NFC_STATUS_FAILED: other error
2556**
2557*****************************************************************************/
nxpandroid8f6d0532017-07-12 18:25:30 +05302558tNFC_STATUS RW_T3tUpdateNDef(uint32_t len, uint8_t* p_data) {
2559 tNFC_STATUS retval = NFC_STATUS_OK;
2560 tRW_T3T_CB* p_cb = &rw_cb.tcb.t3t;
nxpandroidc7611652015-09-23 16:42:05 +05302561
nxf24591c1cbeab2018-02-21 17:32:26 +05302562 DLOG_IF(INFO, nfc_debug_enabled)
2563 << StringPrintf("RW_T3tUpdateNDef (len=%i)", len);
nxpandroidc7611652015-09-23 16:42:05 +05302564
nxpandroid8f6d0532017-07-12 18:25:30 +05302565 /* Check if we are in valid state to handle this API */
2566 if (p_cb->rw_state != RW_T3T_STATE_IDLE) {
nxf24591c1cbeab2018-02-21 17:32:26 +05302567 LOG(ERROR) << StringPrintf("Error: invalid state to handle API (0x%x)",
2568 p_cb->rw_state);
nxpandroid8f6d0532017-07-12 18:25:30 +05302569 return (NFC_STATUS_FAILED);
2570 } else if (p_cb->ndef_attrib.status !=
2571 NFC_STATUS_OK) /* NDEF detection not performed yet? */
2572 {
nxf24591c1cbeab2018-02-21 17:32:26 +05302573 LOG(ERROR) << StringPrintf("Error: NDEF detection not performed yet");
nxpandroid8f6d0532017-07-12 18:25:30 +05302574 return (NFC_STATUS_NOT_INITIALIZED);
2575 } else if (len > (((uint32_t)p_cb->ndef_attrib.nmaxb) *
2576 16)) /* Len exceed's tag's NDEF memory? */
2577 {
2578 return (NFC_STATUS_BUFFER_FULL);
2579 } else if (p_cb->ndef_attrib.rwflag ==
2580 T3T_MSG_NDEF_RWFLAG_RO) /* Tag's NDEF memory is read-only? */
2581 {
2582 return (NFC_STATUS_REFUSED);
2583 }
nxpandroidc7611652015-09-23 16:42:05 +05302584
nxpandroid8f6d0532017-07-12 18:25:30 +05302585 /* Check number of blocks needed for this update */
2586 p_cb->flags &= ~RW_T3T_FL_IS_FINAL_NDEF_SEGMENT;
2587 p_cb->ndef_msg_bytes_sent = 0;
2588 p_cb->ndef_msg_len = len;
2589 p_cb->ndef_msg = p_data;
nxpandroidc7611652015-09-23 16:42:05 +05302590
nxpandroid8f6d0532017-07-12 18:25:30 +05302591 /* Send initial UPDATE command for NDEF Attribute Info */
2592 retval = rw_t3t_send_update_ndef_attribute_cmd(p_cb, true);
nxpandroidc7611652015-09-23 16:42:05 +05302593
nxpandroid8f6d0532017-07-12 18:25:30 +05302594 return (retval);
nxpandroidc7611652015-09-23 16:42:05 +05302595}
2596
2597/*****************************************************************************
2598**
2599** Function RW_T3tCheck
2600**
2601** Description
2602** Read (non-NDEF) contents from a Type3 tag.
2603**
2604** The RW_READ_EVT event is used to notify the application for each
2605** segment of NDEF data received. The RW_READ_CPLT_EVT event is used to
2606** notify the application all segments have been received.
2607**
2608** Before using this API, the application must call RW_SelectTagType to
2609** indicate that a Type 3 tag has been activated, and to provide the
2610** tag's Manufacture ID (IDm) .
2611**
2612** Returns
2613** NFC_STATUS_OK: check command started
2614** NFC_STATUS_NO_BUFFERS: unable to allocate a buffer for this operation
2615** NFC_STATUS_FAILED: other error
2616**
2617*****************************************************************************/
nxpandroid8f6d0532017-07-12 18:25:30 +05302618tNFC_STATUS RW_T3tCheck(uint8_t num_blocks, tT3T_BLOCK_DESC* t3t_blocks) {
2619 tNFC_STATUS retval = NFC_STATUS_OK;
2620 tRW_T3T_CB* p_cb = &rw_cb.tcb.t3t;
nxpandroidc7611652015-09-23 16:42:05 +05302621
nxf24591c1cbeab2018-02-21 17:32:26 +05302622 DLOG_IF(INFO, nfc_debug_enabled)
2623 << StringPrintf("RW_T3tCheck (num_blocks = %i)", num_blocks);
nxpandroidc7611652015-09-23 16:42:05 +05302624
nxpandroid8f6d0532017-07-12 18:25:30 +05302625 /* Check if we are in valid state to handle this API */
2626 if (p_cb->rw_state != RW_T3T_STATE_IDLE) {
nxf24591c1cbeab2018-02-21 17:32:26 +05302627 LOG(ERROR) << StringPrintf("Error: invalid state to handle API (0x%x)",
2628 p_cb->rw_state);
nxpandroid8f6d0532017-07-12 18:25:30 +05302629 return (NFC_STATUS_FAILED);
2630 }
nxpandroidc7611652015-09-23 16:42:05 +05302631
nxpandroid8f6d0532017-07-12 18:25:30 +05302632 /* Send the CHECK command */
2633 retval = rw_t3t_send_check_cmd(p_cb, num_blocks, t3t_blocks);
nxpandroidc7611652015-09-23 16:42:05 +05302634
nxpandroid8f6d0532017-07-12 18:25:30 +05302635 return (retval);
nxpandroidc7611652015-09-23 16:42:05 +05302636}
2637
2638/*****************************************************************************
2639**
2640** Function RW_T3tUpdate
2641**
2642** Description
2643** Write (non-NDEF) contents to a Type3 tag.
2644**
2645** The RW_WRITE_CPLT_EVT event is used to notify the application all
2646** segments have been received.
2647**
2648** Before using this API, the application must call RW_SelectTagType to
2649** indicate that a Type 3 tag has been activated, and to provide the tag's
2650** Manufacture ID (IDm) .
2651**
2652** Returns
2653** NFC_STATUS_OK: check command started
2654** NFC_STATUS_NO_BUFFERS: unable to allocate a buffer for this operation
2655** NFC_STATUS_FAILED: other error
2656**
2657*****************************************************************************/
nxpandroid8f6d0532017-07-12 18:25:30 +05302658tNFC_STATUS RW_T3tUpdate(uint8_t num_blocks, tT3T_BLOCK_DESC* t3t_blocks,
2659 uint8_t* p_data) {
2660 tNFC_STATUS retval = NFC_STATUS_OK;
2661 tRW_T3T_CB* p_cb = &rw_cb.tcb.t3t;
nxpandroidc7611652015-09-23 16:42:05 +05302662
nxf24591c1cbeab2018-02-21 17:32:26 +05302663 DLOG_IF(INFO, nfc_debug_enabled)
2664 << StringPrintf("RW_T3tUpdate (num_blocks = %i)", num_blocks);
nxpandroidc7611652015-09-23 16:42:05 +05302665
nxpandroid8f6d0532017-07-12 18:25:30 +05302666 /* Check if we are in valid state to handle this API */
2667 if (p_cb->rw_state != RW_T3T_STATE_IDLE) {
nxf24591c1cbeab2018-02-21 17:32:26 +05302668 LOG(ERROR) << StringPrintf("Error: invalid state to handle API (0x%x)",
2669 p_cb->rw_state);
nxpandroid8f6d0532017-07-12 18:25:30 +05302670 return (NFC_STATUS_FAILED);
2671 }
nxpandroidc7611652015-09-23 16:42:05 +05302672
nxpandroid8f6d0532017-07-12 18:25:30 +05302673 /* Send the UPDATE command */
2674 retval = rw_t3t_send_update_cmd(p_cb, num_blocks, t3t_blocks, p_data);
nxpandroidc7611652015-09-23 16:42:05 +05302675
nxpandroid8f6d0532017-07-12 18:25:30 +05302676 return (retval);
nxpandroidc7611652015-09-23 16:42:05 +05302677}
2678
2679/*****************************************************************************
2680**
2681** Function RW_T3tPresenceCheck
2682**
2683** Description
2684** Check if the tag is still in the field.
2685**
2686** The RW_T3T_PRESENCE_CHECK_EVT w/ status is used to indicate presence
2687** or non-presence.
2688**
2689** Returns
2690** NFC_STATUS_OK, if raw data frame sent
2691** NFC_STATUS_NO_BUFFERS: unable to allocate a buffer for this operation
2692** NFC_STATUS_FAILED: other error
2693**
2694*****************************************************************************/
nxpandroid8f6d0532017-07-12 18:25:30 +05302695tNFC_STATUS RW_T3tPresenceCheck(void) {
2696 tNFC_STATUS retval = NFC_STATUS_OK;
2697 tRW_DATA evt_data;
2698 tRW_CB* p_rw_cb = &rw_cb;
nxpandroidc7611652015-09-23 16:42:05 +05302699
nxf24591c1cbeab2018-02-21 17:32:26 +05302700 DLOG_IF(INFO, nfc_debug_enabled) << __func__;
nxpandroidc7611652015-09-23 16:42:05 +05302701
nxpandroid8f6d0532017-07-12 18:25:30 +05302702 /* If RW_SelectTagType was not called (no conn_callback) return failure */
2703 if (!(p_rw_cb->p_cback)) {
2704 retval = NFC_STATUS_FAILED;
2705 }
2706 /* If we are not activated, then RW_T3T_PRESENCE_CHECK_EVT status=FAIL */
2707 else if (p_rw_cb->tcb.t3t.rw_state == RW_T3T_STATE_NOT_ACTIVATED) {
2708 evt_data.status = NFC_STATUS_FAILED;
2709 (*p_rw_cb->p_cback)(RW_T3T_PRESENCE_CHECK_EVT, &evt_data);
2710 }
2711 /* If command is pending */
2712 else if (p_rw_cb->tcb.t3t.rw_state == RW_T3T_STATE_COMMAND_PENDING) {
2713 /* If already performing presence check, return error */
2714 if (p_rw_cb->tcb.t3t.flags & RW_T3T_FL_W4_PRESENCE_CHECK_POLL_RSP) {
nxf24591c1cbeab2018-02-21 17:32:26 +05302715 DLOG_IF(INFO, nfc_debug_enabled)
2716 << StringPrintf("RW_T3tPresenceCheck already in progress");
nxpandroid8f6d0532017-07-12 18:25:30 +05302717 retval = NFC_STATUS_FAILED;
nxpandroidc7611652015-09-23 16:42:05 +05302718 }
nxpandroid8f6d0532017-07-12 18:25:30 +05302719 /* If busy with any other command, assume that the tag is present */
2720 else {
2721 evt_data.status = NFC_STATUS_OK;
2722 (*p_rw_cb->p_cback)(RW_T3T_PRESENCE_CHECK_EVT, &evt_data);
nxpandroidc7611652015-09-23 16:42:05 +05302723 }
nxpandroid8f6d0532017-07-12 18:25:30 +05302724 } else {
2725 /* IDLE state: send POLL command */
2726 retval = (tNFC_STATUS)nci_snd_t3t_polling(0xFFFF, T3T_POLL_RC_SC, 0);
2727 if (retval == NCI_STATUS_OK) {
2728 p_rw_cb->tcb.t3t.flags |= RW_T3T_FL_W4_PRESENCE_CHECK_POLL_RSP;
2729 p_rw_cb->tcb.t3t.rw_state = RW_T3T_STATE_COMMAND_PENDING;
2730 p_rw_cb->tcb.t3t.cur_poll_rc = 0;
nxpandroidc7611652015-09-23 16:42:05 +05302731
nxpandroid8f6d0532017-07-12 18:25:30 +05302732 /* start timer for waiting for responses */
2733 rw_t3t_start_poll_timer(&p_rw_cb->tcb.t3t);
2734 } else {
nxf24591c1cbeab2018-02-21 17:32:26 +05302735 DLOG_IF(INFO, nfc_debug_enabled) << StringPrintf(
nxpandroid8f6d0532017-07-12 18:25:30 +05302736 "RW_T3tPresenceCheck error sending NCI_RF_T3T_POLLING cmd (status = "
2737 "0x%0x)",
2738 retval);
nxpandroidc7611652015-09-23 16:42:05 +05302739 }
nxpandroid8f6d0532017-07-12 18:25:30 +05302740 }
nxpandroidc7611652015-09-23 16:42:05 +05302741
nxpandroid8f6d0532017-07-12 18:25:30 +05302742 return (retval);
nxpandroidc7611652015-09-23 16:42:05 +05302743}
2744
2745/*****************************************************************************
2746**
2747** Function RW_T3tPoll
2748**
2749** Description
2750** Send POLL command
2751**
2752** Returns
2753** NFC_STATUS_OK, if raw data frame sent
2754** NFC_STATUS_NO_BUFFERS: unable to allocate a buffer for this operation
2755** NFC_STATUS_FAILED: other error
2756**
2757*****************************************************************************/
nxpandroid8f6d0532017-07-12 18:25:30 +05302758tNFC_STATUS RW_T3tPoll(uint16_t system_code, tT3T_POLL_RC rc, uint8_t tsn) {
2759 tNFC_STATUS retval = NFC_STATUS_OK;
2760 tRW_T3T_CB* p_cb = &rw_cb.tcb.t3t;
nxpandroidc7611652015-09-23 16:42:05 +05302761
nxf24591c1cbeab2018-02-21 17:32:26 +05302762 DLOG_IF(INFO, nfc_debug_enabled) << __func__;
nxpandroidc7611652015-09-23 16:42:05 +05302763
nxpandroid8f6d0532017-07-12 18:25:30 +05302764 /* Check if we are in valid state to handle this API */
2765 if (p_cb->rw_state != RW_T3T_STATE_IDLE) {
nxf24591c1cbeab2018-02-21 17:32:26 +05302766 LOG(ERROR) << StringPrintf("Error: invalid state to handle API (0x%x)",
2767 p_cb->rw_state);
nxpandroid8f6d0532017-07-12 18:25:30 +05302768 return (NFC_STATUS_FAILED);
2769 }
nxpandroidc7611652015-09-23 16:42:05 +05302770
nxpandroid8f6d0532017-07-12 18:25:30 +05302771 retval = (tNFC_STATUS)nci_snd_t3t_polling(system_code, (uint8_t)rc, tsn);
2772 if (retval == NCI_STATUS_OK) {
2773 /* start timer for waiting for responses */
2774 p_cb->cur_poll_rc = rc;
2775 p_cb->rw_state = RW_T3T_STATE_COMMAND_PENDING;
2776 rw_t3t_start_poll_timer(p_cb);
2777 }
nxpandroidc7611652015-09-23 16:42:05 +05302778
nxpandroid8f6d0532017-07-12 18:25:30 +05302779 return (retval);
nxpandroidc7611652015-09-23 16:42:05 +05302780}
2781
2782/*****************************************************************************
2783**
2784** Function RW_T3tSendRawFrame
2785**
2786** Description
2787** This function is called to send a raw data frame to the peer device.
2788** When type 3 tag receives response from peer, the callback function
2789** will be called with a RW_T3T_RAW_FRAME_EVT [Table 6].
2790**
2791** Before using this API, the application must call RW_SelectTagType to
2792** indicate that a Type 3 tag has been activated.
2793**
2794** The raw frame should be a properly formatted Type 3 tag message.
2795**
2796** Returns
2797** NFC_STATUS_OK, if raw data frame sent
2798** NFC_STATUS_NO_BUFFERS: unable to allocate a buffer for this operation
2799** NFC_STATUS_FAILED: other error
2800**
2801*****************************************************************************/
nxpandroid8f6d0532017-07-12 18:25:30 +05302802tNFC_STATUS RW_T3tSendRawFrame(uint16_t len, uint8_t* p_data) {
2803 tNFC_STATUS retval = NFC_STATUS_OK;
2804 tRW_T3T_CB* p_cb = &rw_cb.tcb.t3t;
nxpandroidc7611652015-09-23 16:42:05 +05302805
nxf24591c1cbeab2018-02-21 17:32:26 +05302806 DLOG_IF(INFO, nfc_debug_enabled)
2807 << StringPrintf("RW_T3tSendRawFrame (len = %i)", len);
nxpandroidc7611652015-09-23 16:42:05 +05302808
nxpandroid8f6d0532017-07-12 18:25:30 +05302809 /* Check if we are in valid state to handle this API */
2810 if (p_cb->rw_state != RW_T3T_STATE_IDLE) {
nxf24591c1cbeab2018-02-21 17:32:26 +05302811 LOG(ERROR) << StringPrintf("Error: invalid state to handle API (0x%x)",
2812 p_cb->rw_state);
nxpandroid8f6d0532017-07-12 18:25:30 +05302813 return (NFC_STATUS_FAILED);
2814 }
nxpandroidc7611652015-09-23 16:42:05 +05302815
nxpandroid8f6d0532017-07-12 18:25:30 +05302816 /* Send the UPDATE command */
2817 retval = rw_t3t_send_raw_frame(p_cb, len, p_data);
nxpandroidc7611652015-09-23 16:42:05 +05302818
nxpandroid8f6d0532017-07-12 18:25:30 +05302819 return (retval);
nxpandroidc7611652015-09-23 16:42:05 +05302820}
2821
2822/*****************************************************************************
2823**
2824** Function RW_T3tGetSystemCodes
2825**
2826** Description
2827** Get systems codes supported by the activated tag:
nxpandroid8f6d0532017-07-12 18:25:30 +05302828** Poll for wildcard (FFFF, RC=1):
nxpandroidc7611652015-09-23 16:42:05 +05302829**
2830** Before using this API, the application must call RW_SelectTagType to
2831** indicate that a Type 3 tag has been activated.
2832**
2833** Returns
2834** NFC_STATUS_OK, if raw data frame sent
2835** NFC_STATUS_NO_BUFFERS: unable to allocate a buffer for this operation
2836** NFC_STATUS_FAILED: other error
2837**
2838*****************************************************************************/
nxpandroid8f6d0532017-07-12 18:25:30 +05302839tNFC_STATUS RW_T3tGetSystemCodes(void) {
2840 tNFC_STATUS retval = NFC_STATUS_OK;
2841 tRW_T3T_CB* p_cb = &rw_cb.tcb.t3t;
nxpandroidc7611652015-09-23 16:42:05 +05302842
nxf24591c1cbeab2018-02-21 17:32:26 +05302843 DLOG_IF(INFO, nfc_debug_enabled) << __func__;
nxpandroidc7611652015-09-23 16:42:05 +05302844
nxpandroid8f6d0532017-07-12 18:25:30 +05302845 /* Check if we are in valid state to handle this API */
2846 if (p_cb->rw_state != RW_T3T_STATE_IDLE) {
nxf24591c1cbeab2018-02-21 17:32:26 +05302847 LOG(ERROR) << StringPrintf("Error: invalid state to handle API (0x%x)",
2848 p_cb->rw_state);
nxpandroid8f6d0532017-07-12 18:25:30 +05302849 return (NFC_STATUS_FAILED);
2850 } else {
2851 retval = (tNFC_STATUS)nci_snd_t3t_polling(0xFFFF, T3T_POLL_RC_SC, 0);
2852 if (retval == NCI_STATUS_OK) {
2853 p_cb->cur_cmd = RW_T3T_CMD_GET_SYSTEM_CODES;
2854 p_cb->cur_tout = RW_T3T_DEFAULT_CMD_TIMEOUT_TICKS;
2855 p_cb->cur_poll_rc = T3T_POLL_RC_SC;
2856 p_cb->rw_state = RW_T3T_STATE_COMMAND_PENDING;
2857 p_cb->flags |= RW_T3T_FL_W4_GET_SC_POLL_RSP;
2858 p_cb->num_system_codes = 0;
2859
2860 /* start timer for waiting for responses */
2861 rw_t3t_start_poll_timer(p_cb);
nxpandroidc7611652015-09-23 16:42:05 +05302862 }
nxpandroid8f6d0532017-07-12 18:25:30 +05302863 }
nxpandroidc7611652015-09-23 16:42:05 +05302864
nxpandroid8f6d0532017-07-12 18:25:30 +05302865 return (retval);
nxpandroidc7611652015-09-23 16:42:05 +05302866}
2867
2868/*****************************************************************************
2869**
2870** Function RW_T3tFormatNDef
2871**
2872** Description
2873** Format a type-3 tag for NDEF.
2874**
2875** Only Felica-Lite tags are supported by this API. The
2876** RW_T3T_FORMAT_CPLT_EVT is used to notify the status of the operation.
2877**
2878** Returns
2879** NFC_STATUS_OK: ndef detection procedure started
2880** NFC_STATUS_NO_BUFFERS: unable to allocate a buffer for this operation
2881** NFC_STATUS_FAILED: other error
2882**
2883*****************************************************************************/
nxpandroid8f6d0532017-07-12 18:25:30 +05302884tNFC_STATUS RW_T3tFormatNDef(void) {
2885 tNFC_STATUS retval = NFC_STATUS_OK;
2886 tRW_T3T_CB* p_cb = &rw_cb.tcb.t3t;
nxpandroidc7611652015-09-23 16:42:05 +05302887
nxf24591c1cbeab2018-02-21 17:32:26 +05302888 DLOG_IF(INFO, nfc_debug_enabled) << __func__;
nxpandroidc7611652015-09-23 16:42:05 +05302889
nxpandroid8f6d0532017-07-12 18:25:30 +05302890 /* Check if we are in valid state to handle this API */
2891 if (p_cb->rw_state != RW_T3T_STATE_IDLE) {
nxf24591c1cbeab2018-02-21 17:32:26 +05302892 LOG(ERROR) << StringPrintf("Error: invalid state to handle API (0x%x)",
2893 p_cb->rw_state);
nxpandroid8f6d0532017-07-12 18:25:30 +05302894 return (NFC_STATUS_FAILED);
2895 } else {
2896 /* Poll tag, to see if Felica-Lite system is supported */
2897 retval = (tNFC_STATUS)nci_snd_t3t_polling(T3T_SYSTEM_CODE_FELICA_LITE,
2898 T3T_POLL_RC_SC, 0);
2899 if (retval == NCI_STATUS_OK) {
2900 p_cb->cur_cmd = RW_T3T_CMD_FORMAT;
2901 p_cb->cur_tout = RW_T3T_DEFAULT_CMD_TIMEOUT_TICKS;
2902 p_cb->cur_poll_rc = T3T_POLL_RC_SC;
2903 p_cb->rw_state = RW_T3T_STATE_COMMAND_PENDING;
2904 p_cb->rw_substate = RW_T3T_FMT_SST_POLL_FELICA_LITE;
2905 p_cb->flags |= RW_T3T_FL_W4_FMT_FELICA_LITE_POLL_RSP;
2906
2907 /* start timer for waiting for responses */
2908 rw_t3t_start_poll_timer(p_cb);
nxpandroidc7611652015-09-23 16:42:05 +05302909 }
nxpandroid8f6d0532017-07-12 18:25:30 +05302910 }
nxpandroidc7611652015-09-23 16:42:05 +05302911
nxpandroid8f6d0532017-07-12 18:25:30 +05302912 return (retval);
nxpandroidc7611652015-09-23 16:42:05 +05302913}
2914
2915/*****************************************************************************
2916**
2917** Function RW_T3tSetReadOnly
2918**
2919** Description This function performs NDEF read-only procedure
2920** Note: Only Felica-Lite tags are supported by this API.
2921** RW_T3tDetectNDef() must be called before using this
2922**
2923** The RW_T3T_SET_READ_ONLY_CPLT_EVT event will be returned.
2924**
2925** Returns NFC_STATUS_OK if success
2926** NFC_STATUS_FAILED if T3T is busy or other error
2927**
2928*****************************************************************************/
nxpandroid8f6d0532017-07-12 18:25:30 +05302929tNFC_STATUS RW_T3tSetReadOnly(bool b_hard_lock) {
2930 tNFC_STATUS retval = NFC_STATUS_OK;
2931 tRW_T3T_CB* p_cb = &rw_cb.tcb.t3t;
2932 tRW_DATA evt_data;
nxpandroidc7611652015-09-23 16:42:05 +05302933
nxf24591c1cbeab2018-02-21 17:32:26 +05302934 DLOG_IF(INFO, nfc_debug_enabled)
2935 << StringPrintf("b_hard_lock=%d", b_hard_lock);
nxpandroidc7611652015-09-23 16:42:05 +05302936
nxpandroid8f6d0532017-07-12 18:25:30 +05302937 /* Check if we are in valid state to handle this API */
2938 if (p_cb->rw_state != RW_T3T_STATE_IDLE) {
nxf24591c1cbeab2018-02-21 17:32:26 +05302939 LOG(ERROR) << StringPrintf("Error: invalid state to handle API (0x%x)",
2940 p_cb->rw_state);
nxpandroid8f6d0532017-07-12 18:25:30 +05302941 return (NFC_STATUS_FAILED);
2942 }
nxpandroidc7611652015-09-23 16:42:05 +05302943
nxpandroid8f6d0532017-07-12 18:25:30 +05302944 if (p_cb->ndef_attrib.status !=
2945 NFC_STATUS_OK) /* NDEF detection not performed yet? */
2946 {
nxf24591c1cbeab2018-02-21 17:32:26 +05302947 LOG(ERROR) << StringPrintf("Error: NDEF detection not performed yet");
nxpandroid8f6d0532017-07-12 18:25:30 +05302948 return (NFC_STATUS_NOT_INITIALIZED);
2949 }
nxpandroidc7611652015-09-23 16:42:05 +05302950
nxpandroid8f6d0532017-07-12 18:25:30 +05302951 if ((!b_hard_lock) &&
2952 (p_cb->ndef_attrib.rwflag ==
2953 T3T_MSG_NDEF_RWFLAG_RO)) /* Tag's NDEF memory is read-only already */
2954 {
2955 evt_data.status = NFC_STATUS_OK;
2956 (*(rw_cb.p_cback))(RW_T3T_SET_READ_ONLY_CPLT_EVT, &evt_data);
nxpandroidc7611652015-09-23 16:42:05 +05302957 return (retval);
nxpandroid8f6d0532017-07-12 18:25:30 +05302958 } else {
2959 /* Poll tag, to see if Felica-Lite system is supported */
2960 retval = (tNFC_STATUS)nci_snd_t3t_polling(T3T_SYSTEM_CODE_FELICA_LITE,
2961 T3T_POLL_RC_SC, 0);
2962 if (retval == NCI_STATUS_OK) {
2963 if (b_hard_lock)
2964 p_cb->cur_cmd = RW_T3T_CMD_SET_READ_ONLY_HARD;
2965 else
2966 p_cb->cur_cmd = RW_T3T_CMD_SET_READ_ONLY_SOFT;
2967 p_cb->cur_tout = RW_T3T_DEFAULT_CMD_TIMEOUT_TICKS;
2968 p_cb->cur_poll_rc = T3T_POLL_RC_SC;
2969 p_cb->rw_state = RW_T3T_STATE_COMMAND_PENDING;
2970 p_cb->rw_substate = RW_T3T_SRO_SST_POLL_FELICA_LITE;
2971 p_cb->flags |= RW_T3T_FL_W4_SRO_FELICA_LITE_POLL_RSP;
2972
2973 /* start timer for waiting for responses */
2974 rw_t3t_start_poll_timer(p_cb);
2975 }
2976 }
2977 return (retval);
nxpandroidc7611652015-09-23 16:42:05 +05302978}