blob: ea88fc948df13bb800136a7d87e9f6816e69aa88 [file] [log] [blame]
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001/******************************************************************************
2 *
Evan Chue9629ba2014-01-31 11:18:47 -05003 * Copyright (C) 2010-2014 Broadcom Corporation
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08004 *
5 * Licensed under the Apache License, Version 2.0 (the "License");
6 * you may not use this file except in compliance with the License.
7 * You may obtain a copy of the License at:
8 *
9 * http://www.apache.org/licenses/LICENSE-2.0
10 *
11 * Unless required by applicable law or agreed to in writing, software
12 * distributed under the License is distributed on an "AS IS" BASIS,
13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 * See the License for the specific language governing permissions and
15 * limitations under the License.
16 *
17 ******************************************************************************/
18
19/******************************************************************************
20 *
21 * This file contains the implementation for Type 3 tag in Reader/Writer
22 * mode.
23 *
24 ******************************************************************************/
25#include <string.h>
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -080026
Andre Eisenbach8a4edf62017-11-20 14:51:11 -080027#include <android-base/stringprintf.h>
28#include <base/logging.h>
Ruchi Kandoi32592772019-01-07 17:36:52 -080029#include <log/log.h>
Andre Eisenbach8a4edf62017-11-20 14:51:11 -080030
31#include "nfc_target.h"
32
33#include "bt_types.h"
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -080034#include "nci_hmsgs.h"
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -080035#include "nfc_api.h"
36#include "nfc_int.h"
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -080037#include "rw_api.h"
38#include "rw_int.h"
Andre Eisenbach8a4edf62017-11-20 14:51:11 -080039#include "trace_api.h"
40
41using android::base::StringPrintf;
42
43extern bool nfc_debug_enabled;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -080044
45/* Definitions for constructing t3t command messages */
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -080046#define RW_T3T_FL_PADDING 0x01 /* Padding needed for last NDEF block */
47/* Maximum number of NDEF blocks updates that can fit into one command (when all
48 * block-numbers are < 256) */
Ruchi Kandoi46e6e282017-01-30 14:26:10 -080049#define RW_T3T_MAX_NDEF_BLOCKS_PER_UPDATE_1_BYTE_FORMAT (13)
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -080050/* Maximum number of NDEF blocks updates that can fit into one command (when all
51 * block-numbers are >= 256) */
Ruchi Kandoi46e6e282017-01-30 14:26:10 -080052#define RW_T3T_MAX_NDEF_BLOCKS_PER_UPDATE_2_BYTE_FORMAT (12)
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -080053
54/* Definitions for SENSF_RES */
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -080055/* Offset of RD in SENSF_RES from NCI_POLL NTF (includes 1 byte SENSF_RES
56 * length) */
Ruchi Kandoi46e6e282017-01-30 14:26:10 -080057#define RW_T3T_SENSF_RES_RD_OFFSET 17
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -080058#define RW_T3T_SENSF_RES_RD_LEN 2 /* Size of RD in SENSF_RES */
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -080059
60/* Timeout definitions for commands */
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -080061#define RW_T3T_POLL_CMD_TIMEOUT_TICKS \
62 ((RW_T3T_TOUT_RESP * 2 * QUICK_TIMER_TICKS_PER_SEC) / 1000)
63#define RW_T3T_DEFAULT_CMD_TIMEOUT_TICKS \
64 ((RW_T3T_TOUT_RESP * QUICK_TIMER_TICKS_PER_SEC) / 1000)
65#define RW_T3T_RAW_FRAME_CMD_TIMEOUT_TICKS \
66 (RW_T3T_DEFAULT_CMD_TIMEOUT_TICKS * 4)
67#define RW_T3T_MIN_TIMEOUT_TICKS 10
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -080068
69/* Macro to extract major version from NDEF version byte */
Chih-Hung Hsieh7ac6a7c2017-08-01 14:26:16 -070070#define T3T_GET_MAJOR_VERSION(ver) ((ver) >> 4)
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -080071
72/* Enumeration of API commands */
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -080073enum {
74 RW_T3T_CMD_DETECT_NDEF,
75 RW_T3T_CMD_CHECK_NDEF,
76 RW_T3T_CMD_UPDATE_NDEF,
77 RW_T3T_CMD_CHECK,
78 RW_T3T_CMD_UPDATE,
79 RW_T3T_CMD_SEND_RAW_FRAME,
80 RW_T3T_CMD_GET_SYSTEM_CODES,
81 RW_T3T_CMD_FORMAT,
82 RW_T3T_CMD_SET_READ_ONLY_SOFT,
83 RW_T3T_CMD_SET_READ_ONLY_HARD,
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -080084
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -080085 RW_T3T_CMD_MAX
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -080086};
87
88/* RW_CBACK events corresponding to API comands */
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -080089const uint8_t rw_t3t_api_res_evt[RW_T3T_CMD_MAX] = {
90 RW_T3T_NDEF_DETECT_EVT, /* RW_T3T_CMD_DETECT_NDEF */
91 RW_T3T_CHECK_CPLT_EVT, /* RW_T3T_CMD_CHECK_NDEF */
92 RW_T3T_UPDATE_CPLT_EVT, /* RW_T3T_CMD_UPDATE_NDEF */
93 RW_T3T_CHECK_CPLT_EVT, /* RW_T3T_CMD_CHECK */
94 RW_T3T_UPDATE_CPLT_EVT, /* RW_T3T_CMD_UPDATE */
95 RW_T3T_RAW_FRAME_EVT, /* RW_T3T_CMD_SEND_RAW_FRAME */
96 RW_T3T_GET_SYSTEM_CODES_EVT, /* RW_T3T_CMD_GET_SYSTEM_CODES */
97 RW_T3T_FORMAT_CPLT_EVT, /* RW_T3T_CMD_FORMAT */
98 RW_T3T_SET_READ_ONLY_CPLT_EVT /* RW_T3T_CMD_SET_READ_ONLY */
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -080099};
100
101/* States */
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800102enum {
103 RW_T3T_STATE_NOT_ACTIVATED,
104 RW_T3T_STATE_IDLE,
105 RW_T3T_STATE_COMMAND_PENDING
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800106};
107
108/* Sub-states */
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800109enum {
110 /* Sub states for formatting Felica-Lite */
111 RW_T3T_FMT_SST_POLL_FELICA_LITE, /* Waiting for POLL Felica-Lite response (for
112 formatting) */
113 RW_T3T_FMT_SST_CHECK_MC_BLK, /* Waiting for Felica-Lite MC (MemoryControl)
114 block-read to complete */
115 RW_T3T_FMT_SST_UPDATE_MC_BLK, /* Waiting for Felica-Lite MC (MemoryControl)
116 block-write to complete */
117 RW_T3T_FMT_SST_UPDATE_NDEF_ATTRIB, /* Waiting for NDEF attribute block-write
118 to complete */
Martijn Coenen5c65c3a2013-03-27 13:23:36 -0700119
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800120 /* Sub states for setting Felica-Lite read only */
121 RW_T3T_SRO_SST_POLL_FELICA_LITE, /* Waiting for POLL Felica-Lite response (for
122 setting read only) */
123 RW_T3T_SRO_SST_UPDATE_NDEF_ATTRIB, /* Waiting for NDEF attribute block-write
124 to complete */
125 RW_T3T_SRO_SST_CHECK_MC_BLK, /* Waiting for Felica-Lite MC (MemoryControl)
126 block-read to complete */
127 RW_T3T_SRO_SST_UPDATE_MC_BLK /* Waiting for Felica-Lite MC (MemoryControl)
128 block-write to complete */
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800129};
130
Ruchi Kandoi7dab0e52017-08-03 13:09:49 -0700131static std::string rw_t3t_cmd_str(uint8_t cmd_id);
132static std::string rw_t3t_state_str(uint8_t state_id);
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800133
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800134/* Local static functions */
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800135static void rw_t3t_update_ndef_flag(uint8_t* p_flag);
Ruchi Kandoi9ba6d242017-10-13 16:07:01 -0700136static tNFC_STATUS rw_t3t_unselect();
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800137static NFC_HDR* rw_t3t_get_cmd_buf(void);
138static tNFC_STATUS rw_t3t_send_to_lower(NFC_HDR* p_msg);
139static void rw_t3t_handle_get_system_codes_cplt(void);
140static void rw_t3t_handle_get_sc_poll_rsp(tRW_T3T_CB* p_cb, uint8_t nci_status,
141 uint8_t num_responses,
142 uint8_t sensf_res_buf_size,
143 uint8_t* p_sensf_res_buf);
144static void rw_t3t_handle_ndef_detect_poll_rsp(tRW_T3T_CB* p_cb,
145 uint8_t nci_status,
Ruchi Kandoi9ba6d242017-10-13 16:07:01 -0700146 uint8_t num_responses);
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800147static void rw_t3t_handle_fmt_poll_rsp(tRW_T3T_CB* p_cb, uint8_t nci_status,
Ruchi Kandoi9ba6d242017-10-13 16:07:01 -0700148 uint8_t num_responses);
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800149static void rw_t3t_handle_sro_poll_rsp(tRW_T3T_CB* p_cb, uint8_t nci_status,
Ruchi Kandoi9ba6d242017-10-13 16:07:01 -0700150 uint8_t num_responses);
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800151
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800152/* Default NDEF attribute information block (used when formatting Felica-Lite
153 * tags) */
Ruchi Kandoi46e6e282017-01-30 14:26:10 -0800154/* NBr (max block reads per cmd)*/
155#define RW_T3T_DEFAULT_FELICALITE_NBR 4
156/* NBw (max block write per cmd)*/
157#define RW_T3T_DEFAULT_FELICALITE_NBW 1
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800158#define RW_T3T_DEFAULT_FELICALITE_NMAXB (T3T_FELICALITE_NMAXB)
159#define RW_T3T_DEFAULT_FELICALITE_ATTRIB_INFO_CHECKSUM \
160 ((T3T_MSG_NDEF_VERSION + RW_T3T_DEFAULT_FELICALITE_NBR + \
161 RW_T3T_DEFAULT_FELICALITE_NBW + (RW_T3T_DEFAULT_FELICALITE_NMAXB >> 8) + \
162 (RW_T3T_DEFAULT_FELICALITE_NMAXB & 0xFF) + T3T_MSG_NDEF_WRITEF_OFF + \
163 T3T_MSG_NDEF_RWFLAG_RW) & \
164 0xFFFF)
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800165
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800166const uint8_t rw_t3t_default_attrib_info[T3T_MSG_BLOCKSIZE] = {
167 T3T_MSG_NDEF_VERSION, /* Ver */
168 RW_T3T_DEFAULT_FELICALITE_NBR, /* NBr (max block reads per cmd)*/
169 RW_T3T_DEFAULT_FELICALITE_NBW, /* NBw (max block write per cmd)*/
170 (RW_T3T_DEFAULT_FELICALITE_NMAXB >> 8), /* Nmaxb (max size in blocks) */
171 (RW_T3T_DEFAULT_FELICALITE_NMAXB & 0xFF), /* Nmaxb (max size in blocks) */
Love Khannac76c21d2017-02-27 18:20:08 +0530172 0, 0, 0, 0, /* Unused */
173 T3T_MSG_NDEF_WRITEF_OFF, /* WriteF */
174 T3T_MSG_NDEF_RWFLAG_RW, /* RW Flag */
175 0, 0, 0, /* Ln (current size in bytes) */
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800176
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800177 (RW_T3T_DEFAULT_FELICALITE_ATTRIB_INFO_CHECKSUM >>
178 8), /* checksum (high-byte) */
179 (RW_T3T_DEFAULT_FELICALITE_ATTRIB_INFO_CHECKSUM &
180 0xFF) /* checksum (low-byte) */
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800181
182};
183
Sherry Smith818b56e2014-05-14 16:46:32 -0700184/* This is (T/t3t * 4^E) , E is the index of the array. The unit is .0001 ms */
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800185static const uint32_t rw_t3t_mrti_base[] = {302, 1208, 4832, 19328};
Sherry Smith818b56e2014-05-14 16:46:32 -0700186
187/*******************************************************************************
188**
189** Function rw_t3t_check_timeout
190**
191** Description The timeout value is a + b * number_blocks)
192**
193** Returns timeout value in ticks
194**
195*******************************************************************************/
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800196static uint32_t rw_t3t_check_timeout(uint16_t num_blocks) {
197 tRW_T3T_CB* p_cb = &rw_cb.tcb.t3t;
198 uint32_t timeout;
199 uint32_t extra;
Sherry Smith67fe6102014-06-02 11:01:54 -0700200
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800201 timeout = (p_cb->check_tout_a + num_blocks * p_cb->check_tout_b) *
202 QUICK_TIMER_TICKS_PER_SEC / 1000000;
203 /* allow some extra time for driver */
204 extra = (timeout / 10) + RW_T3T_MIN_TIMEOUT_TICKS;
205 timeout += extra;
Sherry Smith67fe6102014-06-02 11:01:54 -0700206
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800207 return timeout;
Sherry Smith818b56e2014-05-14 16:46:32 -0700208}
209
210/*******************************************************************************
211**
212** Function rw_t3t_update_timeout
213**
214** Description The timeout value is a + b * number_blocks)
215**
216** Returns timeout value in ticks
217**
218*******************************************************************************/
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800219static uint32_t rw_t3t_update_timeout(uint16_t num_blocks) {
220 tRW_T3T_CB* p_cb = &rw_cb.tcb.t3t;
221 uint32_t timeout;
222 uint32_t extra;
Sherry Smith67fe6102014-06-02 11:01:54 -0700223
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800224 timeout = (p_cb->update_tout_a + num_blocks * p_cb->update_tout_b) *
225 QUICK_TIMER_TICKS_PER_SEC / 1000000;
226 /* allow some extra time for driver */
227 extra = (timeout / 10) + RW_T3T_MIN_TIMEOUT_TICKS;
228 timeout += extra;
Sherry Smith67fe6102014-06-02 11:01:54 -0700229
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800230 return timeout;
Sherry Smith818b56e2014-05-14 16:46:32 -0700231}
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800232/*******************************************************************************
233**
234** Function rw_t3t_process_error
235**
236** Description Process error (timeout or CRC error)
237**
238** Returns none
239**
240*******************************************************************************/
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800241void rw_t3t_process_error(tNFC_STATUS status) {
242 tRW_T3T_CB* p_cb = &rw_cb.tcb.t3t;
243 uint8_t evt;
244 tRW_DATA evt_data;
245 NFC_HDR* p_cmd_buf;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800246
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800247 if (p_cb->rw_state == RW_T3T_STATE_COMMAND_PENDING) {
248 if (p_cb->cur_cmd == RW_T3T_CMD_GET_SYSTEM_CODES) {
249 /* For GetSystemCode: tag did not respond to requested POLL */
250 rw_t3t_handle_get_system_codes_cplt();
251 return;
252 }
253 /* Retry sending command if retry-count < max */
254 else if (rw_cb.cur_retry < RW_MAX_RETRIES) {
255 /* retry sending the command */
256 rw_cb.cur_retry++;
257
Ruchi Kandoi6767aec2017-09-26 09:46:26 -0700258 DLOG_IF(INFO, nfc_debug_enabled)
259 << StringPrintf("T3T retransmission attempt %i of %i",
260 rw_cb.cur_retry, RW_MAX_RETRIES);
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800261
262 /* allocate a new buffer for message */
Ruchi Kandoi0c515ae2017-01-30 17:48:41 -0800263 p_cmd_buf = rw_t3t_get_cmd_buf();
264 if (p_cmd_buf != NULL) {
Ruchi Kandoi7dab0e52017-08-03 13:09:49 -0700265 memcpy(p_cmd_buf, p_cb->p_cur_cmd_buf, sizeof(NFC_HDR) +
266 p_cb->p_cur_cmd_buf->offset +
267 p_cb->p_cur_cmd_buf->len);
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800268
269 if (rw_t3t_send_to_lower(p_cmd_buf) == NFC_STATUS_OK) {
270 /* Start timer for waiting for response */
271 nfc_start_quick_timer(&p_cb->timer, NFC_TTYPE_RW_T3T_RESPONSE,
272 p_cb->cur_tout);
273 return;
274 } else {
275 /* failure - could not send buffer */
276 GKI_freebuf(p_cmd_buf);
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800277 }
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800278 }
279 } else {
Ruchi Kandoi6767aec2017-09-26 09:46:26 -0700280 DLOG_IF(INFO, nfc_debug_enabled) << StringPrintf(
281 "T3T maximum retransmission attempts reached (%i)", RW_MAX_RETRIES);
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800282 }
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800283
Ruchi Kandoi303fec12016-12-14 13:22:38 -0800284#if (RW_STATS_INCLUDED == TRUE)
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800285 /* update failure count */
286 rw_main_update_fail_stats();
287#endif /* RW_STATS_INCLUDED */
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800288
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800289 p_cb->rw_state = RW_T3T_STATE_IDLE;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800290
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800291 /* Notify app of result (if there was a pending command) */
292 if (p_cb->cur_cmd < RW_T3T_CMD_MAX) {
293 /* If doing presence check, use status=NFC_STATUS_FAILED, otherwise
294 * NFC_STATUS_TIMEOUT */
295 evt_data.status = status;
296 evt = rw_t3t_api_res_evt[p_cb->cur_cmd];
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800297
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800298 /* Set additional flags for RW_T3T_NDEF_DETECT_EVT */
299 if (evt == RW_T3T_NDEF_DETECT_EVT) {
300 evt_data.ndef.flags = RW_NDEF_FL_UNKNOWN;
301 rw_t3t_update_ndef_flag(&evt_data.ndef.flags);
302 }
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800303
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800304 (*(rw_cb.p_cback))(evt, &evt_data);
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800305 }
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800306 } else {
307 evt_data.status = status;
308 (*(rw_cb.p_cback))(RW_T3T_INTF_ERROR_EVT, &evt_data);
309 }
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800310}
311
312/*******************************************************************************
313**
314** Function rw_t3t_start_poll_timer
315**
316** Description Start the timer for T3T POLL Command
317**
318** Returns none
319**
320*******************************************************************************/
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800321void rw_t3t_start_poll_timer(tRW_T3T_CB* p_cb) {
322 nfc_start_quick_timer(&p_cb->poll_timer, NFC_TTYPE_RW_T3T_RESPONSE,
323 RW_T3T_POLL_CMD_TIMEOUT_TICKS);
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800324}
325
326/*******************************************************************************
327**
328** Function rw_t3t_handle_nci_poll_ntf
329**
330** Description Handle NCI_T3T_POLLING_NTF
331**
332** Returns none
333**
334*******************************************************************************/
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800335void rw_t3t_handle_nci_poll_ntf(uint8_t nci_status, uint8_t num_responses,
336 uint8_t sensf_res_buf_size,
337 uint8_t* p_sensf_res_buf) {
338 tRW_DATA evt_data;
339 tRW_T3T_CB* p_cb = &rw_cb.tcb.t3t;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800340
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800341 /* stop timer for poll response */
342 nfc_stop_quick_timer(&p_cb->poll_timer);
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800343
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800344 /* Stop t3t timer (if started) */
345 if (p_cb->flags & RW_T3T_FL_W4_PRESENCE_CHECK_POLL_RSP) {
346 p_cb->flags &= ~RW_T3T_FL_W4_PRESENCE_CHECK_POLL_RSP;
347 evt_data.status = nci_status;
348 p_cb->rw_state = RW_T3T_STATE_IDLE;
Myles Watson1361d522017-09-26 13:39:54 -0700349 (*(rw_cb.p_cback))(RW_T3T_PRESENCE_CHECK_EVT, &evt_data);
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800350 } else if (p_cb->flags & RW_T3T_FL_W4_GET_SC_POLL_RSP) {
351 /* Handle POLL ntf in response to get system codes */
352 p_cb->flags &= ~RW_T3T_FL_W4_GET_SC_POLL_RSP;
353 rw_t3t_handle_get_sc_poll_rsp(p_cb, nci_status, num_responses,
354 sensf_res_buf_size, p_sensf_res_buf);
355 } else if (p_cb->flags & RW_T3T_FL_W4_FMT_FELICA_LITE_POLL_RSP) {
356 /* Handle POLL ntf in response to get system codes */
357 p_cb->flags &= ~RW_T3T_FL_W4_FMT_FELICA_LITE_POLL_RSP;
Ruchi Kandoi9ba6d242017-10-13 16:07:01 -0700358 rw_t3t_handle_fmt_poll_rsp(p_cb, nci_status, num_responses);
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800359 } else if (p_cb->flags & RW_T3T_FL_W4_SRO_FELICA_LITE_POLL_RSP) {
360 /* Handle POLL ntf in response to get system codes */
361 p_cb->flags &= ~RW_T3T_FL_W4_SRO_FELICA_LITE_POLL_RSP;
Ruchi Kandoi9ba6d242017-10-13 16:07:01 -0700362 rw_t3t_handle_sro_poll_rsp(p_cb, nci_status, num_responses);
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800363 } else if (p_cb->flags & RW_T3T_FL_W4_NDEF_DETECT_POLL_RSP) {
364 /* Handle POLL ntf in response to ndef detection */
365 p_cb->flags &= ~RW_T3T_FL_W4_NDEF_DETECT_POLL_RSP;
Ruchi Kandoi9ba6d242017-10-13 16:07:01 -0700366 rw_t3t_handle_ndef_detect_poll_rsp(p_cb, nci_status, num_responses);
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800367 } else {
368 /* Handle POLL ntf in response to RW_T3tPoll */
Ruchi Kandoi0c515ae2017-01-30 17:48:41 -0800369 evt_data.t3t_poll.status = nci_status;
370 if (evt_data.t3t_poll.status == NCI_STATUS_OK) {
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800371 evt_data.t3t_poll.rc = p_cb->cur_poll_rc;
372 evt_data.t3t_poll.response_num = num_responses;
373 evt_data.t3t_poll.response_bufsize = sensf_res_buf_size;
374 evt_data.t3t_poll.response_buf = p_sensf_res_buf;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800375 }
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800376
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800377 p_cb->rw_state = RW_T3T_STATE_IDLE;
378 (*(rw_cb.p_cback))(RW_T3T_POLL_EVT, &evt_data);
379 }
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800380}
381
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800382/*******************************************************************************
383**
384** Function rw_t3t_handle_get_system_codes_cplt
385**
386** Description Notify upper layer of system codes
387**
388** Returns none
389**
390*******************************************************************************/
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800391void rw_t3t_handle_get_system_codes_cplt(void) {
392 tRW_T3T_CB* p_cb = &rw_cb.tcb.t3t;
393 tRW_DATA evt_data;
394 uint8_t i;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800395
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800396 evt_data.t3t_sc.status = NFC_STATUS_OK;
397 evt_data.t3t_sc.num_system_codes = p_cb->num_system_codes;
398 evt_data.t3t_sc.p_system_codes = p_cb->system_codes;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800399
Ruchi Kandoi6767aec2017-09-26 09:46:26 -0700400 DLOG_IF(INFO, nfc_debug_enabled) << StringPrintf(
401 "number of systems: %i", evt_data.t3t_sc.num_system_codes);
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800402 for (i = 0; i < evt_data.t3t_sc.num_system_codes; i++) {
Ruchi Kandoi6767aec2017-09-26 09:46:26 -0700403 DLOG_IF(INFO, nfc_debug_enabled) << StringPrintf(
404 "system %i: %04X", i, evt_data.t3t_sc.p_system_codes[i]);
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800405 }
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800406
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800407 p_cb->rw_state = RW_T3T_STATE_IDLE;
408 (*(rw_cb.p_cback))(RW_T3T_GET_SYSTEM_CODES_EVT, &evt_data);
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800409}
410
411/*******************************************************************************
412**
413** Function rw_t3t_format_cplt
414**
415** Description Notify upper layer of format complete
416**
417** Returns none
418**
419*******************************************************************************/
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800420void rw_t3t_format_cplt(tNFC_STATUS status) {
421 tRW_T3T_CB* p_cb = &rw_cb.tcb.t3t;
422 tRW_DATA evt_data;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800423
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800424 p_cb->rw_state = RW_T3T_STATE_IDLE;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800425
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800426 /* Update ndef info */
427 p_cb->ndef_attrib.status = status;
428 if (status == NFC_STATUS_OK) {
429 p_cb->ndef_attrib.version = T3T_MSG_NDEF_VERSION;
430 p_cb->ndef_attrib.nbr = RW_T3T_DEFAULT_FELICALITE_NBR;
431 p_cb->ndef_attrib.nbw = RW_T3T_DEFAULT_FELICALITE_NBW;
432 p_cb->ndef_attrib.nmaxb = RW_T3T_DEFAULT_FELICALITE_NMAXB;
433 p_cb->ndef_attrib.writef = T3T_MSG_NDEF_WRITEF_OFF;
434 p_cb->ndef_attrib.rwflag = T3T_MSG_NDEF_RWFLAG_RW;
435 p_cb->ndef_attrib.ln = 0;
436 }
Martijn Coenen5c65c3a2013-03-27 13:23:36 -0700437
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800438 /* Notify upper layer of format complete */
439 evt_data.status = status;
440 (*(rw_cb.p_cback))(RW_T3T_FORMAT_CPLT_EVT, &evt_data);
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800441}
442
443/*******************************************************************************
444**
Martijn Coenen5c65c3a2013-03-27 13:23:36 -0700445** Function rw_t3t_set_readonly_cplt
446**
447** Description Notify upper layer of set read only complete
448**
449** Returns none
450**
451*******************************************************************************/
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800452void rw_t3t_set_readonly_cplt(tNFC_STATUS status) {
453 tRW_T3T_CB* p_cb = &rw_cb.tcb.t3t;
454 tRW_DATA evt_data;
Martijn Coenen5c65c3a2013-03-27 13:23:36 -0700455
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800456 p_cb->rw_state = RW_T3T_STATE_IDLE;
Martijn Coenen5c65c3a2013-03-27 13:23:36 -0700457
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800458 /* Notify upper layer of format complete */
459 evt_data.status = status;
460 (*(rw_cb.p_cback))(RW_T3T_SET_READ_ONLY_CPLT_EVT, &evt_data);
Martijn Coenen5c65c3a2013-03-27 13:23:36 -0700461}
462
463/*******************************************************************************
464**
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800465** Function rw_t3t_process_timeout
466**
467** Description Process timeout
468**
469** Returns none
470**
471*******************************************************************************/
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800472void rw_t3t_process_timeout(TIMER_LIST_ENT* p_tle) {
473 tRW_T3T_CB* p_cb = &rw_cb.tcb.t3t;
474 tRW_DATA evt_data;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800475
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800476 /* Check which timer timed out */
477 if (p_tle == &p_cb->timer) {
478/* UPDATE/CHECK response timeout */
Ruchi Kandoi6767aec2017-09-26 09:46:26 -0700479LOG(ERROR) << StringPrintf("T3T timeout. state=%s cur_cmd=0x%02X (%s)",
480 rw_t3t_state_str(rw_cb.tcb.t3t.rw_state).c_str(),
481 rw_cb.tcb.t3t.cur_cmd,
482 rw_t3t_cmd_str(rw_cb.tcb.t3t.cur_cmd).c_str());
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800483
Ruchi Kandoi6767aec2017-09-26 09:46:26 -0700484rw_t3t_process_error(NFC_STATUS_TIMEOUT);
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800485 } else {
Ruchi Kandoi6767aec2017-09-26 09:46:26 -0700486 LOG(ERROR) << StringPrintf("T3T POLL timeout.");
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800487
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800488 /* POLL response timeout */
489 if (p_cb->flags & RW_T3T_FL_W4_PRESENCE_CHECK_POLL_RSP) {
490 /* POLL timeout for presence check */
491 p_cb->flags &= ~RW_T3T_FL_W4_PRESENCE_CHECK_POLL_RSP;
492 evt_data.status = NFC_STATUS_FAILED;
493 p_cb->rw_state = RW_T3T_STATE_IDLE;
Myles Watson1361d522017-09-26 13:39:54 -0700494 (*(rw_cb.p_cback))(RW_T3T_PRESENCE_CHECK_EVT, &evt_data);
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800495 } else if (p_cb->flags & RW_T3T_FL_W4_GET_SC_POLL_RSP) {
496 /* POLL timeout for getting system codes */
497 p_cb->flags &= ~RW_T3T_FL_W4_GET_SC_POLL_RSP;
498 rw_t3t_handle_get_system_codes_cplt();
499 } else if (p_cb->flags & RW_T3T_FL_W4_FMT_FELICA_LITE_POLL_RSP) {
500 /* POLL timeout for formatting Felica Lite */
501 p_cb->flags &= ~RW_T3T_FL_W4_FMT_FELICA_LITE_POLL_RSP;
Ruchi Kandoi6767aec2017-09-26 09:46:26 -0700502 LOG(ERROR) << StringPrintf("Felica-Lite tag not detected");
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800503 rw_t3t_format_cplt(NFC_STATUS_FAILED);
504 } else if (p_cb->flags & RW_T3T_FL_W4_SRO_FELICA_LITE_POLL_RSP) {
505 /* POLL timeout for configuring Felica Lite read only */
506 p_cb->flags &= ~RW_T3T_FL_W4_SRO_FELICA_LITE_POLL_RSP;
Ruchi Kandoi6767aec2017-09-26 09:46:26 -0700507 LOG(ERROR) << StringPrintf("Felica-Lite tag not detected");
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800508 rw_t3t_set_readonly_cplt(NFC_STATUS_FAILED);
509 } else if (p_cb->flags & RW_T3T_FL_W4_NDEF_DETECT_POLL_RSP) {
510 /* POLL timeout for ndef detection */
511 p_cb->flags &= ~RW_T3T_FL_W4_NDEF_DETECT_POLL_RSP;
Ruchi Kandoi9ba6d242017-10-13 16:07:01 -0700512 rw_t3t_handle_ndef_detect_poll_rsp(p_cb, NFC_STATUS_TIMEOUT, 0);
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800513 } else {
514 /* Timeout waiting for response for RW_T3tPoll */
515 evt_data.t3t_poll.status = NFC_STATUS_FAILED;
516 p_cb->rw_state = RW_T3T_STATE_IDLE;
Myles Watson1361d522017-09-26 13:39:54 -0700517 (*(rw_cb.p_cback))(RW_T3T_POLL_EVT, &evt_data);
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800518 }
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800519 }
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800520}
521
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800522/*******************************************************************************
523**
524** Function rw_t3t_process_frame_error
525**
526** Description Process frame crc error
527**
528** Returns none
529**
530*******************************************************************************/
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800531void rw_t3t_process_frame_error(void) {
Ruchi Kandoi6767aec2017-09-26 09:46:26 -0700532 LOG(ERROR) << StringPrintf("T3T frame error. state=%s cur_cmd=0x%02X (%s)",
533 rw_t3t_state_str(rw_cb.tcb.t3t.rw_state).c_str(),
534 rw_cb.tcb.t3t.cur_cmd,
535 rw_t3t_cmd_str(rw_cb.tcb.t3t.cur_cmd).c_str());
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800536
Ruchi Kandoi303fec12016-12-14 13:22:38 -0800537#if (RW_STATS_INCLUDED == TRUE)
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800538 /* Update stats */
539 rw_main_update_crc_error_stats();
540#endif /* RW_STATS_INCLUDED */
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800541
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800542 /* Process the error */
543 rw_t3t_process_error(NFC_STATUS_MSG_CORRUPTED);
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800544}
545
546/*******************************************************************************
547**
548** Function rw_t3t_send_to_lower
549**
550** Description Send command to lower layer
551**
552** Returns status of the send
553**
554*******************************************************************************/
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800555tNFC_STATUS rw_t3t_send_to_lower(NFC_HDR* p_msg) {
556 uint8_t* p;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800557
Ruchi Kandoi303fec12016-12-14 13:22:38 -0800558#if (RW_STATS_INCLUDED == TRUE)
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800559 bool is_retry;
560 /* Update stats */
561 rw_main_update_tx_stats(p_msg->len, ((rw_cb.cur_retry == 0) ? false : true));
562#endif /* RW_STATS_INCLUDED */
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800563
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800564 /* Set NFC-F SoD field (payload len + 1) */
565 p_msg->offset -= 1; /* Point to SoD field */
566 p = (uint8_t*)(p_msg + 1) + p_msg->offset;
567 UINT8_TO_STREAM(p, (p_msg->len + 1));
568 p_msg->len += 1; /* Increment len to include SoD */
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800569
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800570 return (NFC_SendData(NFC_RF_CONN_ID, p_msg));
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800571}
572
573/*****************************************************************************
574**
575** Function rw_t3t_get_cmd_buf
576**
577** Description Get a buffer for sending T3T messages
578**
Ruchi Kandoi0a736882017-01-09 15:43:14 -0800579** Returns NFC_HDR *
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800580**
581*****************************************************************************/
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800582NFC_HDR* rw_t3t_get_cmd_buf(void) {
583 NFC_HDR* p_cmd_buf;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800584
Ruchi Kandoi0c515ae2017-01-30 17:48:41 -0800585 p_cmd_buf = (NFC_HDR*)GKI_getpoolbuf(NFC_RW_POOL_ID);
586 if (p_cmd_buf != NULL) {
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800587 /* Reserve offset for NCI_DATA_HDR and NFC-F Sod (LEN) field */
588 p_cmd_buf->offset = NCI_MSG_OFFSET_SIZE + NCI_DATA_HDR_SIZE + 1;
589 p_cmd_buf->len = 0;
590 }
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800591
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800592 return (p_cmd_buf);
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800593}
594
595/*****************************************************************************
596**
597** Function rw_t3t_send_cmd
598**
599** Description Send command to tag, and start timer for response
600**
601** Returns tNFC_STATUS
602**
603*****************************************************************************/
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800604tNFC_STATUS rw_t3t_send_cmd(tRW_T3T_CB* p_cb, uint8_t rw_t3t_cmd,
605 NFC_HDR* p_cmd_buf, uint32_t timeout_ticks) {
606 tNFC_STATUS retval;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800607
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800608 /* Indicate first attempt to send command, back up cmd buffer in case needed
609 * for retransmission */
610 rw_cb.cur_retry = 0;
611 memcpy(p_cb->p_cur_cmd_buf, p_cmd_buf,
612 sizeof(NFC_HDR) + p_cmd_buf->offset + p_cmd_buf->len);
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800613
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800614 p_cb->cur_cmd = rw_t3t_cmd;
615 p_cb->cur_tout = timeout_ticks;
616 p_cb->rw_state = RW_T3T_STATE_COMMAND_PENDING;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800617
Ruchi Kandoi0c515ae2017-01-30 17:48:41 -0800618 retval = rw_t3t_send_to_lower(p_cmd_buf);
619 if (retval == NFC_STATUS_OK) {
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800620 /* Start timer for waiting for response */
621 nfc_start_quick_timer(&p_cb->timer, NFC_TTYPE_RW_T3T_RESPONSE,
622 timeout_ticks);
623 } else {
624 /* Error sending */
625 p_cb->rw_state = RW_T3T_STATE_IDLE;
626 }
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800627
Ruchi Kandoi6767aec2017-09-26 09:46:26 -0700628 DLOG_IF(INFO, nfc_debug_enabled)
629 << StringPrintf("cur_tout: %d, timeout_ticks: %d ret:%d", p_cb->cur_tout,
630 timeout_ticks, retval);
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800631 return (retval);
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800632}
633
634/*****************************************************************************
635**
636** Function rw_t3t_send_update_ndef_attribute_cmd
637**
638** Description Send UPDATE command for Attribute Information
639**
640** Returns tNFC_STATUS
641**
642*****************************************************************************/
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800643tNFC_STATUS rw_t3t_send_update_ndef_attribute_cmd(tRW_T3T_CB* p_cb,
644 bool write_in_progress) {
645 tNFC_STATUS retval = NFC_STATUS_OK;
646 NFC_HDR* p_cmd_buf;
647 uint8_t *p_cmd_start, *p;
648 uint16_t checksum, i;
649 uint8_t write_f;
650 uint32_t ln;
651 uint8_t* p_ndef_attr_info_start;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800652
Ruchi Kandoi0c515ae2017-01-30 17:48:41 -0800653 p_cmd_buf = rw_t3t_get_cmd_buf();
654 if (p_cmd_buf != NULL) {
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800655 /* Construct T3T message */
656 p = p_cmd_start = (uint8_t*)(p_cmd_buf + 1) + p_cmd_buf->offset;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800657
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800658 /* Add UPDATE opcode to message */
659 UINT8_TO_STREAM(p, T3T_MSG_OPC_UPDATE_CMD);
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800660
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800661 /* Add IDm to message */
662 ARRAY_TO_STREAM(p, p_cb->peer_nfcid2, NCI_NFCID2_LEN);
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800663
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800664 /* Add Service code list */
665 UINT8_TO_STREAM(p, 1); /* Number of services (only 1 service: NDEF) */
666 UINT16_TO_STREAM(
667 p, T3T_MSG_NDEF_SC_RW); /* Service code (little-endian format) */
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800668
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800669 /* Add number of blocks in this UPDATE command */
670 UINT8_TO_STREAM(p, 1); /* Number of blocks to write in this command */
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800671
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800672 /* Block List element: the NDEF attribute information block (block 0) */
673 UINT8_TO_STREAM(p, T3T_MSG_MASK_TWO_BYTE_BLOCK_DESC_FORMAT);
674 UINT8_TO_STREAM(p, 0);
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800675
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800676 /* Add payload (Attribute information block) */
677 p_ndef_attr_info_start =
678 p; /* Save start of a NDEF attribute info block for checksum */
679 UINT8_TO_STREAM(p, T3T_MSG_NDEF_VERSION);
680 UINT8_TO_STREAM(p, p_cb->ndef_attrib.nbr);
681 UINT8_TO_STREAM(p, p_cb->ndef_attrib.nbw);
682 UINT16_TO_BE_STREAM(p, p_cb->ndef_attrib.nmaxb);
683 UINT32_TO_STREAM(p, 0);
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800684
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800685 /* If starting NDEF write: set WriteF=ON, and ln=current ndef length */
686 if (write_in_progress) {
687 write_f = T3T_MSG_NDEF_WRITEF_ON;
688 ln = p_cb->ndef_attrib.ln;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800689 }
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800690 /* If finishing NDEF write: set WriteF=OFF, and ln=new ndef len */
691 else {
692 write_f = T3T_MSG_NDEF_WRITEF_OFF;
693 ln = p_cb->ndef_msg_len;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800694 }
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800695 UINT8_TO_STREAM(p, write_f);
696 UINT8_TO_STREAM(p, p_cb->ndef_attrib.rwflag);
697 UINT8_TO_STREAM(p, (ln >> 16) & 0xFF); /* High byte (of 3) of Ln */
698 UINT8_TO_STREAM(p, (ln >> 8) & 0xFF); /* Middle byte (of 3) of Ln */
699 UINT8_TO_STREAM(p, (ln)&0xFF); /* Low byte (of 3) of Ln */
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800700
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800701 /* Calculate and append Checksum */
702 checksum = 0;
703 for (i = 0; i < T3T_MSG_NDEF_ATTR_INFO_SIZE; i++) {
704 checksum += p_ndef_attr_info_start[i];
705 }
706 UINT16_TO_BE_STREAM(p, checksum);
707
708 /* Calculate length of message */
709 p_cmd_buf->len = (uint16_t)(p - p_cmd_start);
710
711 /* Send the T3T message */
712 retval = rw_t3t_send_cmd(p_cb, RW_T3T_CMD_UPDATE_NDEF, p_cmd_buf,
713 rw_t3t_update_timeout(1));
714 } else {
715 retval = NFC_STATUS_NO_BUFFERS;
716 }
717
718 return (retval);
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800719}
720
721/*****************************************************************************
722**
723** Function rw_t3t_send_next_ndef_update_cmd
724**
725** Description Send next segment of NDEF message to update
726**
727** Returns tNFC_STATUS
728**
729*****************************************************************************/
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800730tNFC_STATUS rw_t3t_send_next_ndef_update_cmd(tRW_T3T_CB* p_cb) {
731 tNFC_STATUS retval = NFC_STATUS_OK;
732 uint16_t block_id;
733 uint16_t first_block_to_write;
734 uint16_t ndef_blocks_to_write, ndef_blocks_remaining;
735 uint32_t ndef_bytes_remaining, ndef_padding = 0;
736 uint8_t flags = 0;
737 uint8_t* p_cur_ndef_src_offset;
738 NFC_HDR* p_cmd_buf;
739 uint8_t *p_cmd_start, *p;
740 uint8_t blocks_per_update;
741 uint32_t timeout;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800742
Ruchi Kandoi0c515ae2017-01-30 17:48:41 -0800743 p_cmd_buf = rw_t3t_get_cmd_buf();
744 if (p_cmd_buf != NULL) {
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800745 /* Construct T3T message */
746 p = p_cmd_start = (uint8_t*)(p_cmd_buf + 1) + p_cmd_buf->offset;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800747
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800748 /* Calculate number of ndef bytes remaining to write */
749 ndef_bytes_remaining = p_cb->ndef_msg_len - p_cb->ndef_msg_bytes_sent;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800750
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800751 /* Calculate number of blocks remaining to write */
752 ndef_blocks_remaining =
753 (uint16_t)((ndef_bytes_remaining + 15) >>
754 4); /* ndef blocks remaining (rounded upward) */
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800755
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800756 /* Calculate first NDEF block ID for this UPDATE command */
757 first_block_to_write = (uint16_t)((p_cb->ndef_msg_bytes_sent >> 4) + 1);
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800758
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800759 /* Calculate max number of blocks per write. */
760 if ((first_block_to_write +
761 RW_T3T_MAX_NDEF_BLOCKS_PER_UPDATE_1_BYTE_FORMAT) < 0x100) {
762 /* All block-numbers are < 0x100 (i.e. can be specified using one-byte
763 * format) */
764 blocks_per_update = RW_T3T_MAX_NDEF_BLOCKS_PER_UPDATE_1_BYTE_FORMAT;
765 } else {
766 /* Block-numbers are >= 0x100 (i.e. need to be specified using two-byte
767 * format) */
768 blocks_per_update = RW_T3T_MAX_NDEF_BLOCKS_PER_UPDATE_2_BYTE_FORMAT;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800769 }
770
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800771 /* Check if blocks_per_update is bigger than what peer allows */
772 if (blocks_per_update > p_cb->ndef_attrib.nbw)
773 blocks_per_update = p_cb->ndef_attrib.nbw;
774
775 /* Check if remaining blocks can fit into one UPDATE command */
776 if (ndef_blocks_remaining <= blocks_per_update) {
777 /* remaining blocks can fit into one UPDATE command */
778 ndef_blocks_to_write = ndef_blocks_remaining;
779 } else {
780 /* Remaining blocks cannot fit into one UPDATE command */
781 ndef_blocks_to_write = blocks_per_update;
782 }
783
784 /* Write to command header for UPDATE */
785
786 /* Add UPDATE opcode to message */
787 UINT8_TO_STREAM(p, T3T_MSG_OPC_UPDATE_CMD);
788
789 /* Add IDm to message */
790 ARRAY_TO_STREAM(p, p_cb->peer_nfcid2, NCI_NFCID2_LEN);
791
792 /* Add Service code list */
793 UINT8_TO_STREAM(p, 1); /* Number of services (only 1 service: NDEF) */
794 UINT16_TO_STREAM(
795 p, T3T_MSG_NDEF_SC_RW); /* Service code (little-endian format) */
796
797 /* Add number of blocks in this UPDATE command */
798 UINT8_TO_STREAM(
799 p,
800 ndef_blocks_to_write); /* Number of blocks to write in this command */
801 timeout = rw_t3t_update_timeout(ndef_blocks_to_write);
802
803 for (block_id = first_block_to_write;
804 block_id < (first_block_to_write + ndef_blocks_to_write); block_id++) {
805 if (block_id < 256) {
806 /* Block IDs 0-255 can be specified in '2-byte' format: byte0=0,
807 * byte1=blocknumber */
808 UINT8_TO_STREAM(
809 p, T3T_MSG_MASK_TWO_BYTE_BLOCK_DESC_FORMAT); /* byte0: len=1;
810 access-mode=0;
811 service code list
812 order=0 */
813 UINT8_TO_STREAM(p, block_id); /* byte1: block number */
814 } else {
815 /* Block IDs 256+ must be specified in '3-byte' format: byte0=80h,
816 * followed by blocknumber */
817 UINT8_TO_STREAM(
818 p,
819 0x00); /* byte0: len=0; access-mode=0; service code list order=0 */
820 UINT16_TO_STREAM(
821 p, block_id); /* byte1-2: block number in little-endian format */
822 }
823 }
824
825 /* Add NDEF payload */
826
827 /* If this sending last block of NDEF, check if padding is needed to make
828 * payload a multiple of 16 bytes */
829 if (ndef_blocks_to_write == ndef_blocks_remaining) {
830 ndef_padding = (16 - (ndef_bytes_remaining & 0x0F)) & 0x0F;
831 if (ndef_padding) {
832 flags |= RW_T3T_FL_PADDING;
833 ndef_blocks_to_write--; /* handle the last block separately if it needs
834 padding */
835 }
836 }
837
838 /* Add NDEF payload to the message */
839 p_cur_ndef_src_offset = &p_cb->ndef_msg[p_cb->ndef_msg_bytes_sent];
840
841 ARRAY_TO_STREAM(p, p_cur_ndef_src_offset, (ndef_blocks_to_write * 16));
842 p_cb->ndef_msg_bytes_sent += ((uint32_t)ndef_blocks_to_write * 16);
843
844 if (flags & RW_T3T_FL_PADDING) {
845 /* Add last of the NDEF message */
846 p_cur_ndef_src_offset = &p_cb->ndef_msg[p_cb->ndef_msg_bytes_sent];
847 ARRAY_TO_STREAM(p, p_cur_ndef_src_offset, (int)(16 - ndef_padding));
848 p_cb->ndef_msg_bytes_sent += (16 - ndef_padding);
849
850 /* Add padding */
851 memset(p, 0, ndef_padding);
852 p += ndef_padding;
853 }
854
855 /* Calculate length of message */
856 p_cmd_buf->len = (uint16_t)(p - p_cmd_start);
857
858 /* Send the T3T message */
859 retval = rw_t3t_send_cmd(p_cb, RW_T3T_CMD_UPDATE_NDEF, p_cmd_buf, timeout);
860 } else {
861 retval = NFC_STATUS_NO_BUFFERS;
862 }
863
864 return (retval);
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800865}
866
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800867/*****************************************************************************
868**
869** Function rw_t3t_send_next_ndef_check_cmd
870**
871** Description Send command for reading next segment of NDEF message
872**
873** Returns tNFC_STATUS
874**
875*****************************************************************************/
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800876tNFC_STATUS rw_t3t_send_next_ndef_check_cmd(tRW_T3T_CB* p_cb) {
877 tNFC_STATUS retval = NFC_STATUS_OK;
878 uint16_t block_id;
879 uint16_t ndef_blocks_remaining, first_block_to_read, cur_blocks_to_read;
880 uint32_t ndef_bytes_remaining;
881 NFC_HDR* p_cmd_buf;
882 uint8_t *p_cmd_start, *p;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800883
Ruchi Kandoi0c515ae2017-01-30 17:48:41 -0800884 p_cmd_buf = rw_t3t_get_cmd_buf();
885 if (p_cmd_buf != NULL) {
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800886 /* Construct T3T message */
887 p = p_cmd_start = (uint8_t*)(p_cmd_buf + 1) + p_cmd_buf->offset;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800888
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800889 /* Calculate number of ndef bytes remaining to read */
890 ndef_bytes_remaining = p_cb->ndef_attrib.ln - p_cb->ndef_rx_offset;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800891
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800892 /* Calculate number of blocks remaining to read */
893 ndef_blocks_remaining =
894 (uint16_t)((ndef_bytes_remaining + 15) >>
895 4); /* ndef blocks remaining (rounded upward) */
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800896
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800897 /* Calculate first NDEF block ID */
898 first_block_to_read = (uint16_t)((p_cb->ndef_rx_offset >> 4) + 1);
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800899
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800900 /* Check if remaining blocks can fit into one CHECK command */
901 if (ndef_blocks_remaining <= p_cb->ndef_attrib.nbr) {
902 /* remaining blocks can fit into one CHECK command */
903 cur_blocks_to_read = ndef_blocks_remaining;
904 p_cb->ndef_rx_readlen = ndef_bytes_remaining;
905 p_cb->flags |= RW_T3T_FL_IS_FINAL_NDEF_SEGMENT;
906 } else {
907 /* Remaining blocks cannot fit into one CHECK command */
908 cur_blocks_to_read =
909 p_cb->ndef_attrib
910 .nbr; /* Read maximum number of blocks allowed by the peer */
911 p_cb->ndef_rx_readlen = ((uint32_t)p_cb->ndef_attrib.nbr * 16);
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800912 }
913
Ruchi Kandoi6767aec2017-09-26 09:46:26 -0700914 DLOG_IF(INFO, nfc_debug_enabled) << StringPrintf(
915 "bytes_remaining: %i, cur_blocks_to_read: %i, is_final: %i",
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800916 ndef_bytes_remaining, cur_blocks_to_read,
917 (p_cb->flags & RW_T3T_FL_IS_FINAL_NDEF_SEGMENT));
918
919 /* Add CHECK opcode to message */
920 UINT8_TO_STREAM(p, T3T_MSG_OPC_CHECK_CMD);
921
922 /* Add IDm to message */
923 ARRAY_TO_STREAM(p, p_cb->peer_nfcid2, NCI_NFCID2_LEN);
924
925 /* Add Service code list */
926 UINT8_TO_STREAM(p, 1); /* Number of services (only 1 service: NDEF) */
927
928 /* Service code (little-endian format) . If NDEF is read-only, then use
929 * T3T_MSG_NDEF_SC_RO, otherwise use T3T_MSG_NDEF_SC_RW */
930 if (p_cb->ndef_attrib.rwflag == T3T_MSG_NDEF_RWFLAG_RO) {
931 UINT16_TO_STREAM(p, T3T_MSG_NDEF_SC_RO);
932 } else {
933 UINT16_TO_STREAM(p, T3T_MSG_NDEF_SC_RW);
934 }
935
936 /* Add number of blocks in this CHECK command */
937 UINT8_TO_STREAM(
938 p, cur_blocks_to_read); /* Number of blocks to check in this command */
939
940 for (block_id = first_block_to_read;
941 block_id < (first_block_to_read + cur_blocks_to_read); block_id++) {
942 if (block_id < 256) {
943 /* Block IDs 0-255 can be specified in '2-byte' format: byte0=0,
944 * byte1=blocknumber */
945 UINT8_TO_STREAM(
946 p, T3T_MSG_MASK_TWO_BYTE_BLOCK_DESC_FORMAT); /* byte1: len=0;
947 access-mode=0;
948 service code list
949 order=0 */
950 UINT8_TO_STREAM(p, block_id); /* byte1: block number */
951 } else {
952 /* Block IDs 256+ must be specified in '3-byte' format: byte0=80h,
953 * followed by blocknumber */
954 UINT8_TO_STREAM(
955 p,
956 0x00); /* byte0: len=1; access-mode=0; service code list order=0 */
957 UINT16_TO_STREAM(
958 p, block_id); /* byte1-2: block number in little-endian format */
959 }
960 }
961
962 /* Calculate length of message */
963 p_cmd_buf->len = (uint16_t)(p - p_cmd_start);
964
965 /* Send the T3T message */
966 retval = rw_t3t_send_cmd(p_cb, RW_T3T_CMD_CHECK_NDEF, p_cmd_buf,
967 rw_t3t_check_timeout(cur_blocks_to_read));
968 } else {
969 retval = NFC_STATUS_NO_BUFFERS;
970 }
971
972 return (retval);
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800973}
974
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800975/*****************************************************************************
976**
977** Function rw_t3t_message_set_block_list
978**
979** Description Add block list to T3T message
980**
981** Returns Number of bytes added to message
982**
983*****************************************************************************/
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800984void rw_t3t_message_set_block_list(tRW_T3T_CB* p_cb, uint8_t** p,
985 uint8_t num_blocks,
986 tT3T_BLOCK_DESC* p_t3t_blocks) {
987 uint16_t i, cur_service_code;
988 uint8_t service_code_idx, num_services = 0;
989 uint8_t* p_msg_num_services;
990 uint16_t service_list[T3T_MSG_SERVICE_LIST_MAX];
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800991
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800992 /* Add CHECK or UPDATE opcode to message */
993 UINT8_TO_STREAM(
994 (*p), ((p_cb->cur_cmd == RW_T3T_CMD_CHECK) ? T3T_MSG_OPC_CHECK_CMD
995 : T3T_MSG_OPC_UPDATE_CMD));
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800996
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800997 /* Add IDm to message */
998 ARRAY_TO_STREAM((*p), p_cb->peer_nfcid2, NCI_NFCID2_LEN);
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800999
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001000 /* Skip over Number of Services field */
1001 p_msg_num_services = (*p); /* pointer to Number of Services offset */
1002 (*p)++;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001003
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001004 /* Count number of different services are specified in the list, and add
1005 * services to Service Code list */
1006 for (i = 0; i < num_blocks; i++) {
1007 cur_service_code = p_t3t_blocks[i].service_code;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001008
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001009 /* Check if current service_code is already in the service_list */
1010 for (service_code_idx = 0; service_code_idx < num_services;
1011 service_code_idx++) {
1012 if (service_list[service_code_idx] == cur_service_code) break;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001013 }
1014
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001015 if (service_code_idx == num_services) {
1016 /* Service not in the list yet. Add it. */
1017 service_list[service_code_idx] = cur_service_code;
1018 num_services++;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001019
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001020 /* Add service code to T3T message */
1021 UINT16_TO_STREAM((*p), cur_service_code);
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001022 }
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001023 }
1024
1025 /* Add 'Number of Sservices' to the message */
1026 *p_msg_num_services = num_services;
1027
1028 /* Add 'number of blocks' to the message */
1029 UINT8_TO_STREAM((*p), num_blocks);
1030
1031 /* Add block descriptors */
1032 for (i = 0; i < num_blocks; i++) {
1033 cur_service_code = p_t3t_blocks[i].service_code;
1034
1035 /* Check if current service_code is already in the service_list */
1036 for (service_code_idx = 0; service_code_idx < num_services;
1037 service_code_idx++) {
1038 if (service_list[service_code_idx] == cur_service_code) break;
1039 }
1040
1041 /* Add decriptor to T3T message */
1042 if (p_t3t_blocks[i].block_number > 0xFF) {
1043 UINT8_TO_STREAM((*p), service_code_idx);
1044 UINT16_TO_STREAM((*p), p_t3t_blocks[i].block_number);
1045 } else {
1046 service_code_idx |= T3T_MSG_MASK_TWO_BYTE_BLOCK_DESC_FORMAT;
1047 UINT8_TO_STREAM((*p), service_code_idx);
1048 UINT8_TO_STREAM((*p), p_t3t_blocks[i].block_number);
1049 }
1050 }
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001051}
1052
1053/*****************************************************************************
1054**
1055** Function rw_t3t_send_check_cmd
1056**
1057** Description Send CHECK command
1058**
1059** Returns tNFC_STATUS
1060**
1061*****************************************************************************/
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001062tNFC_STATUS rw_t3t_send_check_cmd(tRW_T3T_CB* p_cb, uint8_t num_blocks,
1063 tT3T_BLOCK_DESC* p_t3t_blocks) {
1064 NFC_HDR* p_cmd_buf;
1065 uint8_t *p, *p_cmd_start;
1066 tNFC_STATUS retval = NFC_STATUS_OK;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001067
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001068 p_cb->cur_cmd = RW_T3T_CMD_CHECK;
Ruchi Kandoi0c515ae2017-01-30 17:48:41 -08001069 p_cmd_buf = rw_t3t_get_cmd_buf();
1070 if (p_cmd_buf != NULL) {
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001071 /* Construct T3T message */
1072 p = p_cmd_start = (uint8_t*)(p_cmd_buf + 1) + p_cmd_buf->offset;
1073 rw_t3t_message_set_block_list(p_cb, &p, num_blocks, p_t3t_blocks);
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001074
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001075 /* Calculate length of message */
1076 p_cmd_buf->len = (uint16_t)(p - p_cmd_start);
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001077
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001078 /* Send the T3T message */
1079 retval = rw_t3t_send_cmd(p_cb, RW_T3T_CMD_CHECK, p_cmd_buf,
1080 rw_t3t_check_timeout(num_blocks));
1081 } else {
1082 retval = NFC_STATUS_NO_BUFFERS;
1083 }
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001084
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001085 return (retval);
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001086}
1087
1088/*****************************************************************************
1089**
1090** Function rw_t3t_send_update_cmd
1091**
1092** Description Send UPDATE command
1093**
1094** Returns tNFC_STATUS
1095**
1096*****************************************************************************/
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001097tNFC_STATUS rw_t3t_send_update_cmd(tRW_T3T_CB* p_cb, uint8_t num_blocks,
1098 tT3T_BLOCK_DESC* p_t3t_blocks,
1099 uint8_t* p_data) {
1100 NFC_HDR* p_cmd_buf;
1101 uint8_t *p, *p_cmd_start;
1102 tNFC_STATUS retval = NFC_STATUS_OK;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001103
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001104 p_cb->cur_cmd = RW_T3T_CMD_UPDATE;
Ruchi Kandoi0c515ae2017-01-30 17:48:41 -08001105 p_cmd_buf = rw_t3t_get_cmd_buf();
1106 if (p_cmd_buf != NULL) {
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001107 /* Construct T3T message */
1108 p = p_cmd_start = (uint8_t*)(p_cmd_buf + 1) + p_cmd_buf->offset;
1109 rw_t3t_message_set_block_list(p_cb, &p, num_blocks, p_t3t_blocks);
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001110
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001111 /* Add data blocks to the message */
1112 ARRAY_TO_STREAM(p, p_data, num_blocks * 16);
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001113
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001114 /* Calculate length of message */
1115 p_cmd_buf->len = (uint16_t)(p - p_cmd_start);
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001116
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001117 /* Send the T3T message */
1118 retval = rw_t3t_send_cmd(p_cb, RW_T3T_CMD_UPDATE, p_cmd_buf,
1119 rw_t3t_update_timeout(num_blocks));
1120 } else {
1121 retval = NFC_STATUS_NO_BUFFERS;
1122 }
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001123
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001124 return (retval);
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001125}
1126
1127/*****************************************************************************
1128**
Martijn Coenen5c65c3a2013-03-27 13:23:36 -07001129** Function rw_t3t_check_mc_block
1130**
1131** Description Send command to check Memory Configuration Block
1132**
1133** Returns tNFC_STATUS
1134**
1135*****************************************************************************/
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001136tNFC_STATUS rw_t3t_check_mc_block(tRW_T3T_CB* p_cb) {
1137 NFC_HDR* p_cmd_buf;
1138 uint8_t *p, *p_cmd_start;
Martijn Coenen5c65c3a2013-03-27 13:23:36 -07001139
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001140 /* Read Memory Configuration block */
Ruchi Kandoi0c515ae2017-01-30 17:48:41 -08001141 p_cmd_buf = rw_t3t_get_cmd_buf();
1142 if (p_cmd_buf != NULL) {
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001143 /* Construct T3T message */
1144 p = p_cmd_start = (uint8_t*)(p_cmd_buf + 1) + p_cmd_buf->offset;
Martijn Coenen5c65c3a2013-03-27 13:23:36 -07001145
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001146 /* Add CHECK opcode to message */
1147 UINT8_TO_STREAM(p, T3T_MSG_OPC_CHECK_CMD);
Martijn Coenen5c65c3a2013-03-27 13:23:36 -07001148
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001149 /* Add IDm to message */
1150 ARRAY_TO_STREAM(p, p_cb->peer_nfcid2, NCI_NFCID2_LEN);
Martijn Coenen5c65c3a2013-03-27 13:23:36 -07001151
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001152 /* Add Service code list */
1153 UINT8_TO_STREAM(p, 1); /* Number of services (only 1 service: NDEF) */
1154 UINT16_TO_STREAM(
1155 p, T3T_MSG_NDEF_SC_RO); /* Service code (little-endian format) */
Martijn Coenen5c65c3a2013-03-27 13:23:36 -07001156
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001157 /* Number of blocks */
1158 UINT8_TO_STREAM(p, 1); /* Number of blocks (only 1 block: Memory
1159 Configuration Information ) */
Martijn Coenen5c65c3a2013-03-27 13:23:36 -07001160
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001161 /* Block List element: the Memory Configuration block (block 0x88) */
1162 UINT8_TO_STREAM(p, T3T_MSG_MASK_TWO_BYTE_BLOCK_DESC_FORMAT);
1163 UINT8_TO_STREAM(p, T3T_MSG_FELICALITE_BLOCK_ID_MC);
Martijn Coenen5c65c3a2013-03-27 13:23:36 -07001164
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001165 /* Calculate length of message */
1166 p_cmd_buf->len = (uint16_t)(p - p_cmd_start);
Martijn Coenen5c65c3a2013-03-27 13:23:36 -07001167
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001168 /* Send the T3T message */
1169 return rw_t3t_send_cmd(p_cb, p_cb->cur_cmd, p_cmd_buf,
1170 rw_t3t_check_timeout(1));
1171 } else {
Ruchi Kandoi6767aec2017-09-26 09:46:26 -07001172 LOG(ERROR) << StringPrintf("Unable to allocate buffer to read MC block");
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001173 return (NFC_STATUS_NO_BUFFERS);
1174 }
Martijn Coenen5c65c3a2013-03-27 13:23:36 -07001175}
1176
1177/*****************************************************************************
1178**
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001179** Function rw_t3t_send_raw_frame
1180**
1181** Description Send raw frame
1182**
1183** Returns tNFC_STATUS
1184**
1185*****************************************************************************/
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001186tNFC_STATUS rw_t3t_send_raw_frame(tRW_T3T_CB* p_cb, uint16_t len,
1187 uint8_t* p_data) {
1188 NFC_HDR* p_cmd_buf;
1189 uint8_t* p;
1190 tNFC_STATUS retval = NFC_STATUS_OK;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001191
Ruchi Kandoi0c515ae2017-01-30 17:48:41 -08001192 p_cmd_buf = rw_t3t_get_cmd_buf();
1193 if (p_cmd_buf != NULL) {
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001194 /* Construct T3T message */
1195 p = (uint8_t*)(p_cmd_buf + 1) + p_cmd_buf->offset;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001196
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001197 /* Add data blocks to the message */
1198 ARRAY_TO_STREAM(p, p_data, len);
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001199
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001200 /* Calculate length of message */
1201 p_cmd_buf->len = len;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001202
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001203 /* Send the T3T message */
1204 retval = rw_t3t_send_cmd(p_cb, RW_T3T_CMD_SEND_RAW_FRAME, p_cmd_buf,
1205 RW_T3T_RAW_FRAME_CMD_TIMEOUT_TICKS);
1206 } else {
1207 retval = NFC_STATUS_NO_BUFFERS;
1208 }
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001209
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001210 return (retval);
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001211}
1212
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001213/*****************************************************************************
1214** TAG RESPONSE HANDLERS
1215*****************************************************************************/
1216
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001217/*****************************************************************************
1218**
1219** Function rw_t3t_act_handle_ndef_detect_rsp
1220**
1221** Description Handle response to NDEF detection
1222**
1223** Returns Nothing
1224**
1225*****************************************************************************/
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001226void rw_t3t_act_handle_ndef_detect_rsp(tRW_T3T_CB* p_cb, NFC_HDR* p_msg_rsp) {
1227 uint8_t* p;
1228 uint32_t temp;
1229 uint8_t i;
1230 uint16_t checksum_calc, checksum_rx;
1231 tRW_DETECT_NDEF_DATA evt_data;
1232 uint8_t* p_t3t_rsp = (uint8_t*)(p_msg_rsp + 1) + p_msg_rsp->offset;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001233
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001234 evt_data.status = NFC_STATUS_FAILED;
1235 evt_data.flags = RW_NDEF_FL_UNKNOWN;
1236
1237 /* Check if response code is CHECK resp (for reading NDEF attribute block) */
1238 if (p_t3t_rsp[T3T_MSG_RSP_OFFSET_RSPCODE] != T3T_MSG_OPC_CHECK_RSP) {
Ruchi Kandoi6767aec2017-09-26 09:46:26 -07001239 LOG(ERROR) << StringPrintf(
1240 "Response error: expecting rsp_code %02X, but got %02X",
1241 T3T_MSG_OPC_CHECK_RSP, p_t3t_rsp[T3T_MSG_RSP_OFFSET_RSPCODE]);
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001242 evt_data.status = NFC_STATUS_FAILED;
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001243 }
1244 /* Validate status code and NFCID2 response from tag */
1245 else if ((p_t3t_rsp[T3T_MSG_RSP_OFFSET_STATUS1] !=
1246 T3T_MSG_RSP_STATUS_OK) /* verify response status code */
1247 || (memcmp(p_cb->peer_nfcid2, &p_t3t_rsp[T3T_MSG_RSP_OFFSET_IDM],
1248 NCI_NFCID2_LEN) != 0)) /* verify response IDm */
1249 {
1250 evt_data.status = NFC_STATUS_FAILED;
Jack Yu71dd18c2019-01-08 21:20:15 +08001251 } else if (p_msg_rsp->len <
1252 (T3T_MSG_RSP_OFFSET_CHECK_DATA + T3T_MSG_BLOCKSIZE)) {
1253 evt_data.status = NFC_STATUS_FAILED;
1254 android_errorWriteLog(0x534e4554, "120428041");
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001255 } else {
1256 /* Get checksum from received ndef attribute msg */
1257 p = &p_t3t_rsp[T3T_MSG_RSP_OFFSET_CHECK_DATA + T3T_MSG_NDEF_ATTR_INFO_SIZE];
1258 BE_STREAM_TO_UINT16(checksum_rx, p);
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001259
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001260 /* Calculate checksum - move check for checsum to beginning */
1261 checksum_calc = 0;
1262 p = &p_t3t_rsp[T3T_MSG_RSP_OFFSET_CHECK_DATA];
1263 for (i = 0; i < T3T_MSG_NDEF_ATTR_INFO_SIZE; i++) {
1264 checksum_calc += p[i];
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001265 }
1266
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001267 /* Validate checksum */
1268 if (checksum_calc != checksum_rx) {
1269 p_cb->ndef_attrib.status =
1270 NFC_STATUS_FAILED; /* only ok or failed passed to the app. can be
1271 boolean*/
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001272
Ruchi Kandoi6767aec2017-09-26 09:46:26 -07001273 LOG(ERROR) << StringPrintf("RW_T3tDetectNDEF checksum failed");
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001274 } else {
1275 p_cb->ndef_attrib.status = NFC_STATUS_OK;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001276
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001277 /* Validate version number */
1278 STREAM_TO_UINT8(p_cb->ndef_attrib.version, p);
1279
1280 if (T3T_GET_MAJOR_VERSION(T3T_MSG_NDEF_VERSION) <
1281 T3T_GET_MAJOR_VERSION(p_cb->ndef_attrib.version)) {
1282 /* Remote tag's MajorVer is newer than our's. Reject NDEF as per T3TOP
1283 * RQ_T3T_NDA_024 */
Ruchi Kandoi6767aec2017-09-26 09:46:26 -07001284 LOG(ERROR) << StringPrintf(
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001285 "RW_T3tDetectNDEF: incompatible NDEF version. Local=0x%02x, "
1286 "Remote=0x%02x",
1287 T3T_MSG_NDEF_VERSION, p_cb->ndef_attrib.version);
1288 p_cb->ndef_attrib.status = NFC_STATUS_FAILED;
1289 evt_data.status = NFC_STATUS_BAD_RESP;
1290 } else {
1291 /* Remote tag's MajorVer is equal or older than our's. NDEF is
1292 * compatible with our version. */
1293
1294 /* Update NDEF info */
1295 STREAM_TO_UINT8(
1296 p_cb->ndef_attrib.nbr,
1297 p); /* NBr: number of blocks that can be read using one Check
1298 command */
1299 STREAM_TO_UINT8(p_cb->ndef_attrib.nbw,
1300 p); /* Nbw: number of blocks that can be written using
1301 one Update command */
1302 BE_STREAM_TO_UINT16(
1303 p_cb->ndef_attrib.nmaxb,
1304 p); /* Nmaxb: maximum number of blocks available for NDEF data */
1305 BE_STREAM_TO_UINT32(temp, p);
1306 STREAM_TO_UINT8(p_cb->ndef_attrib.writef,
1307 p); /* WriteFlag: 00h if writing data finished; 0Fh if
1308 writing data in progress */
1309 STREAM_TO_UINT8(
1310 p_cb->ndef_attrib.rwflag,
1311 p); /* RWFlag: 00h NDEF is read-only; 01h if read/write available */
1312
1313 /* Get length (3-byte, big-endian) */
1314 STREAM_TO_UINT8(temp, p); /* Ln: high-byte */
1315 BE_STREAM_TO_UINT16(p_cb->ndef_attrib.ln, p); /* Ln: lo-word */
1316 p_cb->ndef_attrib.ln += (temp << 16);
1317
Ruchi Kandoi6767aec2017-09-26 09:46:26 -07001318 DLOG_IF(INFO, nfc_debug_enabled) << StringPrintf(
1319 "Detected NDEF Ver: 0x%02x", p_cb->ndef_attrib.version);
1320 DLOG_IF(INFO, nfc_debug_enabled) << StringPrintf(
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001321 "Detected NDEF Attributes: Nbr=%i, Nbw=%i, Nmaxb=%i, WriteF=%i, "
1322 "RWFlag=%i, Ln=%i",
1323 p_cb->ndef_attrib.nbr, p_cb->ndef_attrib.nbw,
1324 p_cb->ndef_attrib.nmaxb, p_cb->ndef_attrib.writef,
1325 p_cb->ndef_attrib.rwflag, p_cb->ndef_attrib.ln);
1326
1327 /* Set data for RW_T3T_NDEF_DETECT_EVT */
1328 evt_data.status = p_cb->ndef_attrib.status;
1329 evt_data.cur_size = p_cb->ndef_attrib.ln;
1330 evt_data.max_size = (uint32_t)p_cb->ndef_attrib.nmaxb * 16;
1331 evt_data.protocol = NFC_PROTOCOL_T3T;
1332 evt_data.flags = (RW_NDEF_FL_SUPPORTED | RW_NDEF_FL_FORMATED);
1333 if (p_cb->ndef_attrib.rwflag == T3T_MSG_NDEF_RWFLAG_RO)
1334 evt_data.flags |= RW_NDEF_FL_READ_ONLY;
1335 }
1336 }
1337 }
1338
Ruchi Kandoi6767aec2017-09-26 09:46:26 -07001339 DLOG_IF(INFO, nfc_debug_enabled)
1340 << StringPrintf("RW_T3tDetectNDEF response: %i", evt_data.status);
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001341
1342 p_cb->rw_state = RW_T3T_STATE_IDLE;
1343 rw_t3t_update_ndef_flag(&evt_data.flags);
1344 /* Notify app of NDEF detection result */
Myles Watson1361d522017-09-26 13:39:54 -07001345 tRW_DATA rw_data;
1346 rw_data.ndef = evt_data;
1347 (*(rw_cb.p_cback))(RW_T3T_NDEF_DETECT_EVT, &rw_data);
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001348
1349 GKI_freebuf(p_msg_rsp);
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001350}
1351
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001352/*****************************************************************************
1353**
1354** Function rw_t3t_act_handle_check_rsp
1355**
1356** Description Handle response to CHECK command
1357**
1358** Returns Nothing
1359**
1360*****************************************************************************/
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001361void rw_t3t_act_handle_check_rsp(tRW_T3T_CB* p_cb, NFC_HDR* p_msg_rsp) {
1362 uint8_t* p_t3t_rsp = (uint8_t*)(p_msg_rsp + 1) + p_msg_rsp->offset;
1363 tRW_READ_DATA evt_data;
1364 tNFC_STATUS nfc_status = NFC_STATUS_OK;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001365
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001366 /* Validate response from tag */
1367 if ((p_t3t_rsp[T3T_MSG_RSP_OFFSET_STATUS1] !=
1368 T3T_MSG_RSP_STATUS_OK) /* verify response status code */
1369 || (memcmp(p_cb->peer_nfcid2, &p_t3t_rsp[T3T_MSG_RSP_OFFSET_IDM],
1370 NCI_NFCID2_LEN) != 0)) /* verify response IDm */
1371 {
1372 nfc_status = NFC_STATUS_FAILED;
1373 GKI_freebuf(p_msg_rsp);
1374 } else if (p_t3t_rsp[T3T_MSG_RSP_OFFSET_RSPCODE] != T3T_MSG_OPC_CHECK_RSP) {
Ruchi Kandoi6767aec2017-09-26 09:46:26 -07001375 LOG(ERROR) << StringPrintf(
1376 "Response error: expecting rsp_code %02X, but got %02X",
1377 T3T_MSG_OPC_CHECK_RSP, p_t3t_rsp[T3T_MSG_RSP_OFFSET_RSPCODE]);
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001378 nfc_status = NFC_STATUS_FAILED;
1379 GKI_freebuf(p_msg_rsp);
Ruchi Kandoi8beb9a92019-01-07 17:36:52 -08001380 } else if (p_msg_rsp->len >= T3T_MSG_RSP_OFFSET_CHECK_DATA) {
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001381 /* Copy incoming data into buffer */
1382 p_msg_rsp->offset +=
1383 T3T_MSG_RSP_OFFSET_CHECK_DATA; /* Skip over t3t header */
1384 p_msg_rsp->len -= T3T_MSG_RSP_OFFSET_CHECK_DATA;
1385 evt_data.status = NFC_STATUS_OK;
1386 evt_data.p_data = p_msg_rsp;
Myles Watson1361d522017-09-26 13:39:54 -07001387 tRW_DATA rw_data;
1388 rw_data.data = evt_data;
1389 (*(rw_cb.p_cback))(RW_T3T_CHECK_EVT, &rw_data);
Ruchi Kandoi8beb9a92019-01-07 17:36:52 -08001390 } else {
1391 android_errorWriteLog(0x534e4554, "120503926");
1392 nfc_status = NFC_STATUS_FAILED;
1393 GKI_freebuf(p_msg_rsp);
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001394 }
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001395
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001396 p_cb->rw_state = RW_T3T_STATE_IDLE;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001397
Myles Watson1361d522017-09-26 13:39:54 -07001398 tRW_DATA rw_data;
1399 rw_data.status = nfc_status;
1400 (*(rw_cb.p_cback))(RW_T3T_CHECK_CPLT_EVT, &rw_data);
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001401}
1402
1403/*****************************************************************************
1404**
1405** Function rw_t3t_act_handle_update_rsp
1406**
1407** Description Handle response to UPDATE command
1408**
1409** Returns Nothing
1410**
1411*****************************************************************************/
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001412void rw_t3t_act_handle_update_rsp(tRW_T3T_CB* p_cb, NFC_HDR* p_msg_rsp) {
1413 uint8_t* p_t3t_rsp = (uint8_t*)(p_msg_rsp + 1) + p_msg_rsp->offset;
1414 tRW_READ_DATA evt_data;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001415
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001416 /* Validate response from tag */
1417 if ((p_t3t_rsp[T3T_MSG_RSP_OFFSET_STATUS1] !=
1418 T3T_MSG_RSP_STATUS_OK) /* verify response status code */
1419 || (memcmp(p_cb->peer_nfcid2, &p_t3t_rsp[T3T_MSG_RSP_OFFSET_IDM],
1420 NCI_NFCID2_LEN) != 0)) /* verify response IDm */
1421 {
1422 evt_data.status = NFC_STATUS_FAILED;
1423 } else if (p_t3t_rsp[T3T_MSG_RSP_OFFSET_RSPCODE] != T3T_MSG_OPC_UPDATE_RSP) {
Ruchi Kandoi6767aec2017-09-26 09:46:26 -07001424 LOG(ERROR) << StringPrintf(
1425 "Response error: expecting rsp_code %02X, but got %02X",
1426 T3T_MSG_OPC_UPDATE_RSP, p_t3t_rsp[T3T_MSG_RSP_OFFSET_RSPCODE]);
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001427 evt_data.status = NFC_STATUS_FAILED;
1428 } else {
1429 /* Copy incoming data into buffer */
1430 evt_data.status = NFC_STATUS_OK;
1431 }
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001432
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001433 p_cb->rw_state = RW_T3T_STATE_IDLE;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001434
Myles Watson1361d522017-09-26 13:39:54 -07001435 tRW_DATA rw_data;
1436 rw_data.data = evt_data;
1437 (*(rw_cb.p_cback))(RW_T3T_UPDATE_CPLT_EVT, &rw_data);
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001438
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001439 GKI_freebuf(p_msg_rsp);
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001440}
1441
1442/*****************************************************************************
1443**
1444** Function rw_t3t_act_handle_raw_senddata_rsp
1445**
1446** Description Handle response to NDEF detection
1447**
1448** Returns Nothing
1449**
1450*****************************************************************************/
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001451void rw_t3t_act_handle_raw_senddata_rsp(tRW_T3T_CB* p_cb,
1452 tNFC_DATA_CEVT* p_data) {
1453 tRW_READ_DATA evt_data;
1454 NFC_HDR* p_pkt = p_data->p_data;
Evan Chua24be4f2013-11-13 15:30:16 -05001455
Ruchi Kandoi6767aec2017-09-26 09:46:26 -07001456 DLOG_IF(INFO, nfc_debug_enabled)
1457 << StringPrintf("RW T3T Raw Frame: Len [0x%X] Status [%s]", p_pkt->len,
1458 NFC_GetStatusName(p_data->status).c_str());
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001459
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001460 /* Copy incoming data into buffer */
1461 evt_data.status = p_data->status;
1462 evt_data.p_data = p_pkt;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001463
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001464 p_cb->rw_state = RW_T3T_STATE_IDLE;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001465
Myles Watson1361d522017-09-26 13:39:54 -07001466 tRW_DATA rw_data;
1467 rw_data.data = evt_data;
1468 (*(rw_cb.p_cback))(RW_T3T_RAW_FRAME_EVT, &rw_data);
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001469}
1470
1471/*****************************************************************************
1472**
1473** Function rw_t3t_act_handle_check_ndef_rsp
1474**
1475** Description Handle response to NDEF read segment
1476**
1477** Returns Nothing
1478**
1479*****************************************************************************/
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001480void rw_t3t_act_handle_check_ndef_rsp(tRW_T3T_CB* p_cb, NFC_HDR* p_msg_rsp) {
1481 bool check_complete = true;
1482 tNFC_STATUS nfc_status = NFC_STATUS_OK;
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001483 uint8_t* p_t3t_rsp = (uint8_t*)(p_msg_rsp + 1) + p_msg_rsp->offset;
1484 uint8_t rsp_num_bytes_rx;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001485
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001486 /* Validate response from tag */
1487 if ((p_t3t_rsp[T3T_MSG_RSP_OFFSET_STATUS1] !=
1488 T3T_MSG_RSP_STATUS_OK) /* verify response status code */
1489 || (memcmp(p_cb->peer_nfcid2, &p_t3t_rsp[T3T_MSG_RSP_OFFSET_IDM],
1490 NCI_NFCID2_LEN) != 0) /* verify response IDm */
1491 || (p_t3t_rsp[T3T_MSG_RSP_OFFSET_NUMBLOCKS] !=
1492 ((p_cb->ndef_rx_readlen + 15) >> 4))) /* verify length of response */
1493 {
Ruchi Kandoi6767aec2017-09-26 09:46:26 -07001494 LOG(ERROR) << StringPrintf(
1495 "Response error: bad status, nfcid2, or invalid len: %i %i",
1496 p_t3t_rsp[T3T_MSG_RSP_OFFSET_NUMBLOCKS],
1497 ((p_cb->ndef_rx_readlen + 15) >> 4));
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001498 nfc_status = NFC_STATUS_FAILED;
1499 GKI_freebuf(p_msg_rsp);
1500 } else if (p_t3t_rsp[T3T_MSG_RSP_OFFSET_RSPCODE] != T3T_MSG_OPC_CHECK_RSP) {
Ruchi Kandoi6767aec2017-09-26 09:46:26 -07001501 LOG(ERROR) << StringPrintf(
1502 "Response error: expecting rsp_code %02X, but got %02X",
1503 T3T_MSG_OPC_CHECK_RSP, p_t3t_rsp[T3T_MSG_RSP_OFFSET_RSPCODE]);
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001504 nfc_status = NFC_STATUS_FAILED;
1505 GKI_freebuf(p_msg_rsp);
George Chang4a115a72019-01-08 17:27:27 +08001506 } else if (p_msg_rsp->len >= T3T_MSG_RSP_OFFSET_CHECK_DATA &&
1507 p_t3t_rsp[T3T_MSG_RSP_OFFSET_NUMBLOCKS] > 0) {
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001508 /* Notify app of NDEF segment received */
George Chang4a115a72019-01-08 17:27:27 +08001509 /* Number of bytes received, according to header */
1510 rsp_num_bytes_rx = p_t3t_rsp[T3T_MSG_RSP_OFFSET_NUMBLOCKS] * 16;
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001511 p_cb->ndef_rx_offset += p_cb->ndef_rx_readlen;
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001512 p_msg_rsp->offset +=
1513 T3T_MSG_RSP_OFFSET_CHECK_DATA; /* Skip over t3t header (point to block
1514 data) */
1515 p_msg_rsp->len -= T3T_MSG_RSP_OFFSET_CHECK_DATA;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001516
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001517 /* Verify that the bytes received is really the amount indicated in the
1518 * check-response header */
1519 if (rsp_num_bytes_rx > p_msg_rsp->len) {
Ruchi Kandoi6767aec2017-09-26 09:46:26 -07001520 LOG(ERROR) << StringPrintf(
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001521 "Response error: CHECK rsp header indicates %i bytes, but only "
1522 "received %i bytes",
1523 rsp_num_bytes_rx, p_msg_rsp->len);
1524 nfc_status = NFC_STATUS_FAILED;
1525 GKI_freebuf(p_msg_rsp);
1526 } else {
1527 /* If this is the the final block, then set len to reflect only valid
1528 * bytes (do not include padding to 16-byte boundary) */
1529 if ((p_cb->flags & RW_T3T_FL_IS_FINAL_NDEF_SEGMENT) &&
1530 (p_cb->ndef_attrib.ln & 0x000F)) {
1531 rsp_num_bytes_rx -= (16 - (p_cb->ndef_attrib.ln & 0x000F));
1532 }
1533
1534 p_msg_rsp->len = rsp_num_bytes_rx;
Myles Watson1361d522017-09-26 13:39:54 -07001535 tRW_DATA rw_data;
1536 rw_data.data.status = NFC_STATUS_OK;
1537 rw_data.data.p_data = p_msg_rsp;
1538 (*(rw_cb.p_cback))(RW_T3T_CHECK_EVT, &rw_data);
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001539
1540 /* Send CHECK cmd for next NDEF segment, if needed */
1541 if (!(p_cb->flags & RW_T3T_FL_IS_FINAL_NDEF_SEGMENT)) {
Ruchi Kandoi0c515ae2017-01-30 17:48:41 -08001542 nfc_status = rw_t3t_send_next_ndef_check_cmd(p_cb);
1543 if (nfc_status == NFC_STATUS_OK) {
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001544 /* Still getting more segments. Don't send RW_T3T_CHECK_CPLT_EVT yet
1545 */
1546 check_complete = false;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001547 }
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001548 }
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001549 }
George Chang4a115a72019-01-08 17:27:27 +08001550 } else {
1551 android_errorWriteLog(0x534e4554, "120502559");
1552 GKI_freebuf(p_msg_rsp);
1553 nfc_status = NFC_STATUS_FAILED;
1554 LOG(ERROR) << StringPrintf("Underflow in p_msg_rsp->len!");
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001555 }
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001556
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001557 /* Notify app of RW_T3T_CHECK_CPLT_EVT if entire NDEF has been read, or if
1558 * failure */
1559 if (check_complete) {
1560 p_cb->rw_state = RW_T3T_STATE_IDLE;
Myles Watson1361d522017-09-26 13:39:54 -07001561 tRW_DATA evt_data;
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001562 evt_data.status = nfc_status;
Myles Watson1361d522017-09-26 13:39:54 -07001563 (*(rw_cb.p_cback))(RW_T3T_CHECK_CPLT_EVT, &evt_data);
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001564 }
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001565}
1566
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001567/*****************************************************************************
1568**
1569** Function rw_t3t_act_handle_update_ndef_rsp
1570**
1571** Description Handle response to NDEF write segment
1572**
1573** Returns Nothing
1574**
1575*****************************************************************************/
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001576void rw_t3t_act_handle_update_ndef_rsp(tRW_T3T_CB* p_cb, NFC_HDR* p_msg_rsp) {
1577 bool update_complete = true;
1578 tNFC_STATUS nfc_status = NFC_STATUS_OK;
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001579 uint8_t* p_t3t_rsp = (uint8_t*)(p_msg_rsp + 1) + p_msg_rsp->offset;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001580
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001581 /* Check nfcid2 and status of response */
1582 if ((p_t3t_rsp[T3T_MSG_RSP_OFFSET_STATUS1] !=
1583 T3T_MSG_RSP_STATUS_OK) /* verify response status code */
1584 || (memcmp(p_cb->peer_nfcid2, &p_t3t_rsp[T3T_MSG_RSP_OFFSET_IDM],
1585 NCI_NFCID2_LEN) != 0)) /* verify response IDm */
1586 {
1587 nfc_status = NFC_STATUS_FAILED;
1588 }
1589 /* Validate response opcode */
1590 else if (p_t3t_rsp[T3T_MSG_RSP_OFFSET_RSPCODE] != T3T_MSG_OPC_UPDATE_RSP) {
Ruchi Kandoi6767aec2017-09-26 09:46:26 -07001591 LOG(ERROR) << StringPrintf(
1592 "Response error: expecting rsp_code %02X, but got %02X",
1593 T3T_MSG_OPC_UPDATE_RSP, p_t3t_rsp[T3T_MSG_RSP_OFFSET_RSPCODE]);
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001594 nfc_status = NFC_STATUS_FAILED;
1595 }
1596 /* If this is response to final UPDATE, then update NDEF local size */
1597 else if (p_cb->flags & RW_T3T_FL_IS_FINAL_NDEF_SEGMENT) {
1598 /* If successful, update current NDEF size */
1599 p_cb->ndef_attrib.ln = p_cb->ndef_msg_len;
1600 }
1601 /* If any more NDEF bytes to update, then send next UPDATE command */
1602 else if (p_cb->ndef_msg_bytes_sent < p_cb->ndef_msg_len) {
1603 /* Send UPDATE command for next segment of NDEF */
Ruchi Kandoi0c515ae2017-01-30 17:48:41 -08001604 nfc_status = rw_t3t_send_next_ndef_update_cmd(p_cb);
1605 if (nfc_status == NFC_STATUS_OK) {
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001606 /* Wait for update response */
1607 update_complete = false;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001608 }
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001609 }
1610 /* Otherwise, no more NDEF bytes. Send final UPDATE for Attribute Information
1611 block */
1612 else {
1613 p_cb->flags |= RW_T3T_FL_IS_FINAL_NDEF_SEGMENT;
Ruchi Kandoi0c515ae2017-01-30 17:48:41 -08001614 nfc_status = rw_t3t_send_update_ndef_attribute_cmd(p_cb, false);
1615 if (nfc_status == NFC_STATUS_OK) {
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001616 /* Wait for update response */
1617 update_complete = false;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001618 }
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001619 }
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001620
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001621 /* If update is completed, then notify app */
1622 if (update_complete) {
1623 p_cb->rw_state = RW_T3T_STATE_IDLE;
Myles Watson1361d522017-09-26 13:39:54 -07001624 tRW_DATA evt_data;
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001625 evt_data.status = nfc_status;
Myles Watson1361d522017-09-26 13:39:54 -07001626 (*(rw_cb.p_cback))(RW_T3T_UPDATE_CPLT_EVT, &evt_data);
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001627 }
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001628
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001629 GKI_freebuf(p_msg_rsp);
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001630
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001631 return;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001632}
1633
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001634/*****************************************************************************
1635**
1636** Function rw_t3t_handle_get_sc_poll_rsp
1637**
1638** Description Handle POLL response for getting system codes
1639**
1640** Returns Nothing
1641**
1642*****************************************************************************/
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001643static void rw_t3t_handle_get_sc_poll_rsp(tRW_T3T_CB* p_cb, uint8_t nci_status,
1644 uint8_t num_responses,
1645 uint8_t sensf_res_buf_size,
1646 uint8_t* p_sensf_res_buf) {
1647 uint8_t* p;
1648 uint16_t sc;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001649
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001650 /* Get the system code from the response */
1651 if ((nci_status == NCI_STATUS_OK) && (num_responses > 0) &&
1652 (sensf_res_buf_size >=
1653 (RW_T3T_SENSF_RES_RD_OFFSET + RW_T3T_SENSF_RES_RD_LEN))) {
1654 p = &p_sensf_res_buf[RW_T3T_SENSF_RES_RD_OFFSET];
1655 BE_STREAM_TO_UINT16(sc, p);
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001656
Ruchi Kandoi6767aec2017-09-26 09:46:26 -07001657 DLOG_IF(INFO, nfc_debug_enabled)
1658 << StringPrintf("FeliCa detected (RD, system code %04X)", sc);
George Chang7729db62019-01-08 15:20:51 +08001659 if (p_cb->num_system_codes < T3T_MAX_SYSTEM_CODES) {
1660 p_cb->system_codes[p_cb->num_system_codes++] = sc;
1661 } else {
1662 LOG(ERROR) << StringPrintf("Exceed T3T_MAX_SYSTEM_CODES!");
1663 android_errorWriteLog(0x534e4554, "120499324");
1664 }
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001665 }
Yoshinobu Ito721b3ab2016-08-02 14:41:33 +09001666
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001667 rw_t3t_handle_get_system_codes_cplt();
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001668}
1669
1670/*****************************************************************************
1671**
1672** Function rw_t3t_handle_ndef_detect_poll_rsp
1673**
1674** Description Handle POLL response for getting system codes
1675**
1676** Returns Nothing
1677**
1678*****************************************************************************/
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001679static void rw_t3t_handle_ndef_detect_poll_rsp(tRW_T3T_CB* p_cb,
1680 uint8_t nci_status,
Ruchi Kandoi9ba6d242017-10-13 16:07:01 -07001681 uint8_t num_responses) {
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001682 NFC_HDR* p_cmd_buf;
1683 uint8_t *p, *p_cmd_start;
1684 tRW_DATA evt_data;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001685
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001686 /* Validate response for NDEF poll */
1687 if ((nci_status == NCI_STATUS_OK) && (num_responses > 0)) {
1688 /* Tag responded for NDEF poll */
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001689
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001690 /* Read NDEF attribute block */
Ruchi Kandoi0c515ae2017-01-30 17:48:41 -08001691 p_cmd_buf = rw_t3t_get_cmd_buf();
1692 if (p_cmd_buf != NULL) {
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001693 /* Construct T3T message */
1694 p = p_cmd_start = (uint8_t*)(p_cmd_buf + 1) + p_cmd_buf->offset;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001695
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001696 /* Add CHECK opcode to message */
1697 UINT8_TO_STREAM(p, T3T_MSG_OPC_CHECK_CMD);
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001698
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001699 /* Add IDm to message */
1700 ARRAY_TO_STREAM(p, p_cb->peer_nfcid2, NCI_NFCID2_LEN);
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001701
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001702 /* Add Service code list */
1703 UINT8_TO_STREAM(p, 1); /* Number of services (only 1 service: NDEF) */
1704 UINT16_TO_STREAM(
1705 p, T3T_MSG_NDEF_SC_RO); /* Service code (little-endian format) */
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001706
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001707 /* Number of blocks */
1708 UINT8_TO_STREAM(
1709 p,
1710 1); /* Number of blocks (only 1 block: NDEF Attribute Information ) */
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001711
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001712 /* Block List element: the NDEF attribute information block (block 0) */
1713 UINT8_TO_STREAM(p, T3T_MSG_MASK_TWO_BYTE_BLOCK_DESC_FORMAT);
1714 UINT8_TO_STREAM(p, 0);
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001715
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001716 /* Calculate length of message */
1717 p_cmd_buf->len = (uint16_t)(p - p_cmd_start);
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001718
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001719 /* Send the T3T message */
Ruchi Kandoi0c515ae2017-01-30 17:48:41 -08001720 evt_data.status = rw_t3t_send_cmd(p_cb, RW_T3T_CMD_DETECT_NDEF, p_cmd_buf,
1721 rw_t3t_check_timeout(1));
1722 if (evt_data.status == NFC_STATUS_OK) {
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001723 /* CHECK command sent. Wait for response */
1724 return;
1725 }
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001726 }
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001727 nci_status = NFC_STATUS_FAILED;
1728 }
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001729
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001730 /* NDEF detection failed */
1731 p_cb->rw_state = RW_T3T_STATE_IDLE;
1732 evt_data.ndef.status = nci_status;
1733 evt_data.ndef.flags = RW_NDEF_FL_UNKNOWN;
1734 rw_t3t_update_ndef_flag(&evt_data.ndef.flags);
1735 (*(rw_cb.p_cback))(RW_T3T_NDEF_DETECT_EVT, &evt_data);
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001736}
1737
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001738/*****************************************************************************
1739**
1740** Function rw_t3t_update_block
1741**
Martijn Coenen5c65c3a2013-03-27 13:23:36 -07001742** Description Send UPDATE command for single block
1743** (for formatting/configuring read only)
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001744**
1745** Returns tNFC_STATUS
1746**
1747*****************************************************************************/
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001748tNFC_STATUS rw_t3t_update_block(tRW_T3T_CB* p_cb, uint8_t block_id,
1749 uint8_t* p_block_data) {
1750 uint8_t *p_dst, *p_cmd_start;
1751 NFC_HDR* p_cmd_buf;
1752 tNFC_STATUS status;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001753
Ruchi Kandoi0c515ae2017-01-30 17:48:41 -08001754 p_cmd_buf = rw_t3t_get_cmd_buf();
1755 if (p_cmd_buf != NULL) {
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001756 p_dst = p_cmd_start = (uint8_t*)(p_cmd_buf + 1) + p_cmd_buf->offset;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001757
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001758 /* Add UPDATE opcode to message */
1759 UINT8_TO_STREAM(p_dst, T3T_MSG_OPC_UPDATE_CMD);
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001760
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001761 /* Add IDm to message */
1762 ARRAY_TO_STREAM(p_dst, p_cb->peer_nfcid2, NCI_NFCID2_LEN);
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001763
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001764 /* Add Service code list */
1765 UINT8_TO_STREAM(p_dst, 1); /* Number of services (only 1 service: NDEF) */
1766 UINT16_TO_STREAM(
1767 p_dst, T3T_MSG_NDEF_SC_RW); /* Service code (little-endian format) */
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001768
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001769 /* Number of blocks */
1770 UINT8_TO_STREAM(p_dst, 1);
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001771
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001772 /* Add Block list element for MC */
1773 UINT8_TO_STREAM(p_dst, T3T_MSG_MASK_TWO_BYTE_BLOCK_DESC_FORMAT);
1774 UINT8_TO_STREAM(p_dst, block_id);
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001775
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001776 /* Copy MC data to UPDATE message */
1777 ARRAY_TO_STREAM(p_dst, p_block_data, T3T_MSG_BLOCKSIZE);
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001778
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001779 /* Calculate length of message */
1780 p_cmd_buf->len = (uint16_t)(p_dst - p_cmd_start);
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001781
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001782 /* Send the T3T message */
1783 status = rw_t3t_send_cmd(p_cb, p_cb->cur_cmd, p_cmd_buf,
1784 rw_t3t_update_timeout(1));
1785 } else {
1786 /* Unable to send UPDATE command */
1787 status = NFC_STATUS_NO_BUFFERS;
1788 }
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001789
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001790 return (status);
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001791}
1792
1793/*****************************************************************************
1794**
1795** Function rw_t3t_handle_fmt_poll_rsp
1796**
1797** Description Handle POLL response for formatting felica-lite
1798**
1799** Returns Nothing
1800**
1801*****************************************************************************/
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001802static void rw_t3t_handle_fmt_poll_rsp(tRW_T3T_CB* p_cb, uint8_t nci_status,
Ruchi Kandoi9ba6d242017-10-13 16:07:01 -07001803 uint8_t num_responses) {
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001804 tRW_DATA evt_data;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001805
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001806 evt_data.status = NFC_STATUS_OK;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001807
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001808 /* Validate response for poll response */
1809 if ((nci_status == NCI_STATUS_OK) && (num_responses > 0)) {
1810 /* Tag responded for Felica-Lite poll */
1811 /* Get MemoryControl block */
Ruchi Kandoi6767aec2017-09-26 09:46:26 -07001812 DLOG_IF(INFO, nfc_debug_enabled) << StringPrintf(
1813 "Felica-Lite tag detected...getting Memory Control block.");
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001814
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001815 p_cb->rw_substate = RW_T3T_FMT_SST_CHECK_MC_BLK;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001816
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001817 /* Send command to check Memory Configuration block */
1818 evt_data.status = rw_t3t_check_mc_block(p_cb);
1819 } else {
Ruchi Kandoi6767aec2017-09-26 09:46:26 -07001820 LOG(ERROR) << StringPrintf("Felica-Lite tag not detected");
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001821 evt_data.status = NFC_STATUS_FAILED;
1822 }
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001823
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001824 /* If error, notify upper layer */
1825 if (evt_data.status != NFC_STATUS_OK) {
1826 rw_t3t_format_cplt(evt_data.status);
1827 }
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001828}
1829
1830/*****************************************************************************
1831**
1832** Function rw_t3t_act_handle_fmt_rsp
1833**
1834** Description Handle response for formatting codes
1835**
1836** Returns Nothing
1837**
1838*****************************************************************************/
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001839void rw_t3t_act_handle_fmt_rsp(tRW_T3T_CB* p_cb, NFC_HDR* p_msg_rsp) {
1840 uint8_t* p_t3t_rsp = (uint8_t*)(p_msg_rsp + 1) + p_msg_rsp->offset;
1841 uint8_t* p_mc;
1842 tRW_DATA evt_data;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001843
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001844 evt_data.status = NFC_STATUS_OK;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001845
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001846 /* Check tags's response for reading MemoryControl block */
1847 if (p_cb->rw_substate == RW_T3T_FMT_SST_CHECK_MC_BLK) {
1848 /* Validate response opcode */
1849 if (p_t3t_rsp[T3T_MSG_RSP_OFFSET_RSPCODE] != T3T_MSG_OPC_CHECK_RSP) {
Ruchi Kandoi6767aec2017-09-26 09:46:26 -07001850 LOG(ERROR) << StringPrintf(
1851 "Response error: expecting rsp_code %02X, but got %02X",
1852 T3T_MSG_OPC_CHECK_RSP, p_t3t_rsp[T3T_MSG_RSP_OFFSET_RSPCODE]);
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001853 evt_data.status = NFC_STATUS_FAILED;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001854 }
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001855 /* Validate status code and NFCID2 response from tag */
1856 else if ((p_t3t_rsp[T3T_MSG_RSP_OFFSET_STATUS1] !=
1857 T3T_MSG_RSP_STATUS_OK) /* verify response status code */
1858 || (memcmp(p_cb->peer_nfcid2, &p_t3t_rsp[T3T_MSG_RSP_OFFSET_IDM],
1859 NCI_NFCID2_LEN) != 0)) /* verify response IDm */
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001860 {
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001861 evt_data.status = NFC_STATUS_FAILED;
Ruchi Kandoi32592772019-01-07 17:36:52 -08001862 } else if (p_msg_rsp->len <
1863 (T3T_MSG_RSP_OFFSET_CHECK_DATA + T3T_MSG_BLOCKSIZE)) {
1864 evt_data.status = NFC_STATUS_FAILED;
1865 android_errorWriteLog(0x534e4554, "120506143");
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001866 } else {
1867 /* Check if memory configuration (MC) block to see if SYS_OP=1 (NDEF
1868 * enabled) */
1869 p_mc = &p_t3t_rsp[T3T_MSG_RSP_OFFSET_CHECK_DATA]; /* Point to MC data of
1870 CHECK response */
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001871
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001872 if (p_mc[T3T_MSG_FELICALITE_MC_OFFSET_SYS_OP] != 0x01) {
1873 /* Tag is not currently enabled for NDEF. Indicate that we need to
1874 * update the MC block */
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001875
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001876 /* Set SYS_OP field to 0x01 (enable NDEF) */
1877 p_mc[T3T_MSG_FELICALITE_MC_OFFSET_SYS_OP] = 0x01;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001878
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001879 /* Set RF_PRM field to 0x07 (procedure of issuance) */
1880 p_mc[T3T_MSG_FELICALITE_MC_OFFSET_RF_PRM] = 0x07;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001881
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001882 /* Construct and send UPDATE message to write MC block */
1883 p_cb->rw_substate = RW_T3T_FMT_SST_UPDATE_MC_BLK;
1884 evt_data.status =
1885 rw_t3t_update_block(p_cb, T3T_MSG_FELICALITE_BLOCK_ID_MC, p_mc);
1886 } else {
1887 /* SYS_OP=1: ndef already enabled. Just need to update attribute
1888 * information block */
1889 p_cb->rw_substate = RW_T3T_FMT_SST_UPDATE_NDEF_ATTRIB;
1890 evt_data.status =
1891 rw_t3t_update_block(p_cb, 0, (uint8_t*)rw_t3t_default_attrib_info);
1892 }
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001893 }
1894
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001895 /* If error, notify upper layer */
1896 if (evt_data.status != NFC_STATUS_OK) {
1897 rw_t3t_format_cplt(evt_data.status);
1898 }
1899 } else if (p_cb->rw_substate == RW_T3T_FMT_SST_UPDATE_MC_BLK) {
1900 /* Validate response opcode */
1901 if ((p_t3t_rsp[T3T_MSG_RSP_OFFSET_RSPCODE] != T3T_MSG_OPC_UPDATE_RSP) ||
1902 (p_t3t_rsp[T3T_MSG_RSP_OFFSET_STATUS1] != T3T_MSG_RSP_STATUS_OK))
1903
1904 {
Ruchi Kandoi6767aec2017-09-26 09:46:26 -07001905 LOG(ERROR) << StringPrintf("Response error: rsp_code=%02X, status=%02X",
1906 p_t3t_rsp[T3T_MSG_RSP_OFFSET_RSPCODE],
1907 p_t3t_rsp[T3T_MSG_RSP_OFFSET_STATUS1]);
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001908 evt_data.status = NFC_STATUS_FAILED;
1909 } else {
1910 /* SYS_OP=1: ndef already enabled. Just need to update attribute
1911 * information block */
1912 p_cb->rw_substate = RW_T3T_FMT_SST_UPDATE_NDEF_ATTRIB;
1913 evt_data.status =
1914 rw_t3t_update_block(p_cb, 0, (uint8_t*)rw_t3t_default_attrib_info);
1915 }
1916
1917 /* If error, notify upper layer */
1918 if (evt_data.status != NFC_STATUS_OK) {
1919 rw_t3t_format_cplt(evt_data.status);
1920 }
1921 } else if (p_cb->rw_substate == RW_T3T_FMT_SST_UPDATE_NDEF_ATTRIB) {
1922 /* Validate response opcode */
1923 if ((p_t3t_rsp[T3T_MSG_RSP_OFFSET_RSPCODE] != T3T_MSG_OPC_UPDATE_RSP) ||
1924 (p_t3t_rsp[T3T_MSG_RSP_OFFSET_STATUS1] != T3T_MSG_RSP_STATUS_OK))
1925
1926 {
Ruchi Kandoi6767aec2017-09-26 09:46:26 -07001927 LOG(ERROR) << StringPrintf("Response error: rsp_code=%02X, status=%02X",
1928 p_t3t_rsp[T3T_MSG_RSP_OFFSET_RSPCODE],
1929 p_t3t_rsp[T3T_MSG_RSP_OFFSET_STATUS1]);
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001930 evt_data.status = NFC_STATUS_FAILED;
1931 }
1932
1933 rw_t3t_format_cplt(evt_data.status);
1934 }
1935
1936 GKI_freebuf(p_msg_rsp);
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001937}
1938
Martijn Coenen5c65c3a2013-03-27 13:23:36 -07001939/*****************************************************************************
1940**
1941** Function rw_t3t_handle_sro_poll_rsp
1942**
1943** Description Handle POLL response for configuring felica-lite read only
1944**
1945** Returns Nothing
1946**
1947*****************************************************************************/
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001948static void rw_t3t_handle_sro_poll_rsp(tRW_T3T_CB* p_cb, uint8_t nci_status,
Ruchi Kandoi9ba6d242017-10-13 16:07:01 -07001949 uint8_t num_responses) {
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001950 tRW_DATA evt_data;
1951 uint8_t rw_t3t_ndef_attrib_info[T3T_MSG_BLOCKSIZE];
1952 uint8_t* p;
1953 uint8_t tempU8;
1954 uint16_t checksum, i;
1955 uint32_t tempU32 = 0;
Martijn Coenen5c65c3a2013-03-27 13:23:36 -07001956
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001957 evt_data.status = NFC_STATUS_OK;
Martijn Coenen5c65c3a2013-03-27 13:23:36 -07001958
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001959 /* Validate response for poll response */
1960 if ((nci_status == NCI_STATUS_OK) && (num_responses > 0)) {
1961 /* Tag responded for Felica-Lite poll */
1962 if (p_cb->ndef_attrib.rwflag != T3T_MSG_NDEF_RWFLAG_RO) {
1963 /* First update attribute information block */
Ruchi Kandoi6767aec2017-09-26 09:46:26 -07001964 DLOG_IF(INFO, nfc_debug_enabled) << StringPrintf(
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001965 "Felica-Lite tag detected...update NDef attribution block.");
Martijn Coenen5c65c3a2013-03-27 13:23:36 -07001966
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001967 p_cb->rw_substate = RW_T3T_SRO_SST_UPDATE_NDEF_ATTRIB;
Martijn Coenen5c65c3a2013-03-27 13:23:36 -07001968
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001969 p = rw_t3t_ndef_attrib_info;
Martijn Coenen5c65c3a2013-03-27 13:23:36 -07001970
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001971 UINT8_TO_STREAM(p, p_cb->ndef_attrib.version);
Martijn Coenen5c65c3a2013-03-27 13:23:36 -07001972
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001973 /* Update NDEF info */
1974 UINT8_TO_STREAM(
1975 p, p_cb->ndef_attrib.nbr); /* NBr: number of blocks that can be read
1976 using one Check command */
1977 UINT8_TO_STREAM(p, p_cb->ndef_attrib.nbw); /* Nbw: number of blocks that
1978 can be written using one
1979 Update command */
1980 UINT16_TO_BE_STREAM(
1981 p, p_cb->ndef_attrib.nmaxb); /* Nmaxb: maximum number of blocks
1982 available for NDEF data */
1983 UINT32_TO_BE_STREAM(p, tempU32);
1984 UINT8_TO_STREAM(p,
1985 p_cb->ndef_attrib.writef); /* WriteFlag: 00h if writing
1986 data finished; 0Fh if
1987 writing data in progress */
1988 UINT8_TO_STREAM(p, 0x00); /* RWFlag: 00h NDEF is read-only */
Martijn Coenen5c65c3a2013-03-27 13:23:36 -07001989
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001990 tempU8 = (uint8_t)(p_cb->ndef_attrib.ln >> 16);
1991 /* Get length (3-byte, big-endian) */
1992 UINT8_TO_STREAM(p, tempU8); /* Ln: high-byte */
1993 UINT16_TO_BE_STREAM(p, p_cb->ndef_attrib.ln); /* Ln: lo-word */
Martijn Coenen5c65c3a2013-03-27 13:23:36 -07001994
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001995 /* Calculate and append Checksum */
1996 checksum = 0;
1997 for (i = 0; i < T3T_MSG_NDEF_ATTR_INFO_SIZE; i++) {
1998 checksum += rw_t3t_ndef_attrib_info[i];
1999 }
2000 UINT16_TO_BE_STREAM(p, checksum);
Martijn Coenen5c65c3a2013-03-27 13:23:36 -07002001
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002002 evt_data.status =
2003 rw_t3t_update_block(p_cb, 0, (uint8_t*)rw_t3t_ndef_attrib_info);
2004 } else if (p_cb->cur_cmd == RW_T3T_CMD_SET_READ_ONLY_HARD) {
2005 /* NDEF is already read only, Read and update MemoryControl block */
Ruchi Kandoi6767aec2017-09-26 09:46:26 -07002006 DLOG_IF(INFO, nfc_debug_enabled) << StringPrintf(
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002007 "Felica-Lite tag detected...getting Memory Control block.");
2008 p_cb->rw_substate = RW_T3T_SRO_SST_CHECK_MC_BLK;
Martijn Coenen5c65c3a2013-03-27 13:23:36 -07002009
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002010 /* Send command to check Memory Configuration block */
2011 evt_data.status = rw_t3t_check_mc_block(p_cb);
Martijn Coenen5c65c3a2013-03-27 13:23:36 -07002012 }
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002013 } else {
Ruchi Kandoi6767aec2017-09-26 09:46:26 -07002014 LOG(ERROR) << StringPrintf("Felica-Lite tag not detected");
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002015 evt_data.status = NFC_STATUS_FAILED;
2016 }
Martijn Coenen5c65c3a2013-03-27 13:23:36 -07002017
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002018 /* If error, notify upper layer */
2019 if (evt_data.status != NFC_STATUS_OK) {
2020 rw_t3t_set_readonly_cplt(evt_data.status);
2021 }
Martijn Coenen5c65c3a2013-03-27 13:23:36 -07002022}
2023
2024/*****************************************************************************
2025**
2026** Function rw_t3t_act_handle_sro_rsp
2027**
2028** Description Handle response for setting read only codes
2029**
2030** Returns Nothing
2031**
2032*****************************************************************************/
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002033void rw_t3t_act_handle_sro_rsp(tRW_T3T_CB* p_cb, NFC_HDR* p_msg_rsp) {
2034 uint8_t* p_t3t_rsp = (uint8_t*)(p_msg_rsp + 1) + p_msg_rsp->offset;
2035 uint8_t* p_mc;
2036 tRW_DATA evt_data;
Martijn Coenen5c65c3a2013-03-27 13:23:36 -07002037
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002038 evt_data.status = NFC_STATUS_OK;
Martijn Coenen5c65c3a2013-03-27 13:23:36 -07002039
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002040 if (p_cb->rw_substate == RW_T3T_SRO_SST_UPDATE_NDEF_ATTRIB) {
2041 /* Validate response opcode */
2042 if ((p_t3t_rsp[T3T_MSG_RSP_OFFSET_RSPCODE] != T3T_MSG_OPC_UPDATE_RSP) ||
2043 (p_t3t_rsp[T3T_MSG_RSP_OFFSET_STATUS1] != T3T_MSG_RSP_STATUS_OK))
2044
Martijn Coenen5c65c3a2013-03-27 13:23:36 -07002045 {
Ruchi Kandoi6767aec2017-09-26 09:46:26 -07002046 LOG(ERROR) << StringPrintf("Response error: rsp_code=%02X, status=%02X",
2047 p_t3t_rsp[T3T_MSG_RSP_OFFSET_RSPCODE],
2048 p_t3t_rsp[T3T_MSG_RSP_OFFSET_STATUS1]);
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002049 evt_data.status = NFC_STATUS_FAILED;
2050 } else {
2051 p_cb->ndef_attrib.rwflag = T3T_MSG_NDEF_RWFLAG_RO;
2052 if (p_cb->cur_cmd == RW_T3T_CMD_SET_READ_ONLY_HARD) {
2053 p_cb->rw_substate = RW_T3T_SRO_SST_CHECK_MC_BLK;
Martijn Coenen5c65c3a2013-03-27 13:23:36 -07002054
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002055 /* Send command to check Memory Configuration block */
2056 evt_data.status = rw_t3t_check_mc_block(p_cb);
2057 } else {
2058 rw_t3t_set_readonly_cplt(evt_data.status);
2059 }
Martijn Coenen5c65c3a2013-03-27 13:23:36 -07002060 }
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002061 } else if (p_cb->rw_substate == RW_T3T_SRO_SST_CHECK_MC_BLK) {
2062 /* Check tags's response for reading MemoryControl block, Validate response
2063 * opcode */
2064 if (p_t3t_rsp[T3T_MSG_RSP_OFFSET_RSPCODE] != T3T_MSG_OPC_CHECK_RSP) {
Ruchi Kandoi6767aec2017-09-26 09:46:26 -07002065 LOG(ERROR) << StringPrintf(
2066 "Response error: expecting rsp_code %02X, but got %02X",
2067 T3T_MSG_OPC_CHECK_RSP, p_t3t_rsp[T3T_MSG_RSP_OFFSET_RSPCODE]);
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002068 evt_data.status = NFC_STATUS_FAILED;
2069 }
2070 /* Validate status code and NFCID2 response from tag */
2071 else if ((p_t3t_rsp[T3T_MSG_RSP_OFFSET_STATUS1] !=
2072 T3T_MSG_RSP_STATUS_OK) /* verify response status code */
2073 || (memcmp(p_cb->peer_nfcid2, &p_t3t_rsp[T3T_MSG_RSP_OFFSET_IDM],
2074 NCI_NFCID2_LEN) != 0)) /* verify response IDm */
Martijn Coenen5c65c3a2013-03-27 13:23:36 -07002075 {
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002076 evt_data.status = NFC_STATUS_FAILED;
Ruchi Kandoi32592772019-01-07 17:36:52 -08002077 } else if (p_msg_rsp->len <
2078 (T3T_MSG_RSP_OFFSET_CHECK_DATA + T3T_MSG_BLOCKSIZE)) {
2079 evt_data.status = NFC_STATUS_FAILED;
2080 android_errorWriteLog(0x534e4554, "120506143");
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002081 } else {
2082 /* Check if memory configuration (MC) block to see if SYS_OP=1 (NDEF
2083 * enabled) */
2084 p_mc = &p_t3t_rsp[T3T_MSG_RSP_OFFSET_CHECK_DATA]; /* Point to MC data of
2085 CHECK response */
Martijn Coenen5c65c3a2013-03-27 13:23:36 -07002086
Ruchi Kandoi32592772019-01-07 17:36:52 -08002087 evt_data.status = NFC_STATUS_FAILED;
2088 if (p_mc[T3T_MSG_FELICALITE_MC_OFFSET_SYS_OP] == 0x01) {
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002089 /* Set MC_SP field with MC[0] = 0x00 & MC[1] = 0xC0 (Hardlock) to change
2090 * access permission from RW to RO */
2091 p_mc[T3T_MSG_FELICALITE_MC_OFFSET_MC_SP] = 0x00;
2092 /* Not changing the access permission of Subtraction Register and
2093 * MC[0:1] */
2094 p_mc[T3T_MSG_FELICALITE_MC_OFFSET_MC_SP + 1] = 0xC0;
Martijn Coenen5c65c3a2013-03-27 13:23:36 -07002095
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002096 /* Set RF_PRM field to 0x07 (procedure of issuance) */
2097 p_mc[T3T_MSG_FELICALITE_MC_OFFSET_RF_PRM] = 0x07;
Martijn Coenen5c65c3a2013-03-27 13:23:36 -07002098
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002099 /* Construct and send UPDATE message to write MC block */
2100 p_cb->rw_substate = RW_T3T_SRO_SST_UPDATE_MC_BLK;
2101 evt_data.status =
2102 rw_t3t_update_block(p_cb, T3T_MSG_FELICALITE_BLOCK_ID_MC, p_mc);
2103 }
Martijn Coenen5c65c3a2013-03-27 13:23:36 -07002104 }
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002105 } else if (p_cb->rw_substate == RW_T3T_SRO_SST_UPDATE_MC_BLK) {
2106 /* Validate response opcode */
2107 if ((p_t3t_rsp[T3T_MSG_RSP_OFFSET_RSPCODE] != T3T_MSG_OPC_UPDATE_RSP) ||
2108 (p_t3t_rsp[T3T_MSG_RSP_OFFSET_STATUS1] != T3T_MSG_RSP_STATUS_OK))
2109
Martijn Coenen5c65c3a2013-03-27 13:23:36 -07002110 {
Ruchi Kandoi6767aec2017-09-26 09:46:26 -07002111 LOG(ERROR) << StringPrintf("Response error: rsp_code=%02X, status=%02X",
2112 p_t3t_rsp[T3T_MSG_RSP_OFFSET_RSPCODE],
2113 p_t3t_rsp[T3T_MSG_RSP_OFFSET_STATUS1]);
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002114 evt_data.status = NFC_STATUS_FAILED;
2115 } else {
2116 rw_t3t_set_readonly_cplt(evt_data.status);
Martijn Coenen5c65c3a2013-03-27 13:23:36 -07002117 }
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002118 }
Martijn Coenen5c65c3a2013-03-27 13:23:36 -07002119
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002120 /* If error, notify upper layer */
2121 if (evt_data.status != NFC_STATUS_OK) {
2122 rw_t3t_set_readonly_cplt(evt_data.status);
2123 }
Martijn Coenen5c65c3a2013-03-27 13:23:36 -07002124
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002125 GKI_freebuf(p_msg_rsp);
Martijn Coenen5c65c3a2013-03-27 13:23:36 -07002126}
2127
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002128/*******************************************************************************
2129**
2130** Function rw_t3t_data_cback
2131**
2132** Description This callback function receives the data from NFCC.
2133**
2134** Returns none
2135**
2136*******************************************************************************/
Ruchi Kandoi9ba6d242017-10-13 16:07:01 -07002137void rw_t3t_data_cback(__attribute__((unused)) uint8_t conn_id,
2138 tNFC_DATA_CEVT* p_data) {
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002139 tRW_T3T_CB* p_cb = &rw_cb.tcb.t3t;
2140 NFC_HDR* p_msg = p_data->p_data;
2141 bool free_msg = false; /* if TRUE, free msg buffer before returning */
2142 uint8_t *p, sod;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002143
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002144 /* Stop rsponse timer */
2145 nfc_stop_quick_timer(&p_cb->timer);
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002146
Ruchi Kandoi303fec12016-12-14 13:22:38 -08002147#if (RW_STATS_INCLUDED == TRUE)
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002148 /* Update rx stats */
2149 rw_main_update_rx_stats(p_msg->len);
2150#endif /* RW_STATS_INCLUDED */
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002151
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002152 /* Check if we are expecting a response */
2153 if (p_cb->rw_state != RW_T3T_STATE_COMMAND_PENDING) {
2154 /*
2155 ** This must be raw frame response
2156 ** send raw frame to app with SoD
2157 */
2158 rw_t3t_act_handle_raw_senddata_rsp(p_cb, p_data);
2159 }
2160 /* Sanity check: verify msg len is big enough to contain t3t header */
2161 else if (p_msg->len < T3T_MSG_RSP_COMMON_HDR_LEN) {
Ruchi Kandoi6767aec2017-09-26 09:46:26 -07002162 LOG(ERROR) << StringPrintf(
2163 "T3T: invalid Type3 Tag Message (invalid len: %i)", p_msg->len);
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002164 free_msg = true;
2165
2166 rw_t3t_process_frame_error();
2167 } else {
2168 /* Check for RF frame error */
2169 p = (uint8_t*)(p_msg + 1) + p_msg->offset;
2170 sod = p[0];
2171 if (p[sod] != NCI_STATUS_OK) {
Ruchi Kandoi6767aec2017-09-26 09:46:26 -07002172 LOG(ERROR) << StringPrintf("T3T: rf frame error (crc status=%i)", p[sod]);
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002173 GKI_freebuf(p_msg);
2174
2175 rw_t3t_process_frame_error();
2176 return;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002177 }
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002178
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002179 /* Skip over SoD */
2180 p_msg->offset++;
2181 p_msg->len--;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002182
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002183 /* Get response code */
2184 switch (p_cb->cur_cmd) {
2185 case RW_T3T_CMD_DETECT_NDEF:
2186 rw_t3t_act_handle_ndef_detect_rsp(p_cb, p_msg);
2187 break;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002188
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002189 case RW_T3T_CMD_CHECK_NDEF:
2190 rw_t3t_act_handle_check_ndef_rsp(p_cb, p_msg);
2191 break;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002192
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002193 case RW_T3T_CMD_UPDATE_NDEF:
2194 rw_t3t_act_handle_update_ndef_rsp(p_cb, p_msg);
2195 break;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002196
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002197 case RW_T3T_CMD_CHECK:
2198 rw_t3t_act_handle_check_rsp(p_cb, p_msg);
2199 break;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002200
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002201 case RW_T3T_CMD_UPDATE:
2202 rw_t3t_act_handle_update_rsp(p_cb, p_msg);
2203 break;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002204
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002205 case RW_T3T_CMD_SEND_RAW_FRAME:
2206 rw_t3t_act_handle_raw_senddata_rsp(p_cb, p_data);
2207 break;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002208
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002209 case RW_T3T_CMD_FORMAT:
2210 rw_t3t_act_handle_fmt_rsp(p_cb, p_msg);
2211 break;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002212
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002213 case RW_T3T_CMD_SET_READ_ONLY_SOFT:
2214 case RW_T3T_CMD_SET_READ_ONLY_HARD:
2215 rw_t3t_act_handle_sro_rsp(p_cb, p_msg);
2216 break;
Martijn Coenen5c65c3a2013-03-27 13:23:36 -07002217
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002218 default:
2219 GKI_freebuf(p_msg);
2220 break;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002221 }
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002222 }
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002223
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002224 if (free_msg) {
2225 GKI_freebuf(p_msg);
2226 }
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002227}
2228
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002229/*******************************************************************************
2230**
2231** Function rw_t3t_conn_cback
2232**
2233** Description This callback function receives the events/data from NFCC.
2234**
2235** Returns none
2236**
2237*******************************************************************************/
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002238void rw_t3t_conn_cback(uint8_t conn_id, tNFC_CONN_EVT event,
2239 tNFC_CONN* p_data) {
2240 tRW_T3T_CB* p_cb = &rw_cb.tcb.t3t;
Ruchi Kandoi6767aec2017-09-26 09:46:26 -07002241 DLOG_IF(INFO, nfc_debug_enabled) << StringPrintf(
2242 "rw_t3t_conn_cback: conn_id=%i, evt=0x%02x", conn_id, event);
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002243
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002244 /* Only handle NFC_RF_CONN_ID conn_id */
2245 if (conn_id != NFC_RF_CONN_ID) {
2246 return;
2247 }
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002248
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002249 switch (event) {
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002250 case NFC_DEACTIVATE_CEVT:
Ruchi Kandoi9ba6d242017-10-13 16:07:01 -07002251 rw_t3t_unselect();
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002252 break;
2253
2254 case NFC_DATA_CEVT: /* check for status in tNFC_CONN */
2255 if ((p_data != NULL) && ((p_data->data.status == NFC_STATUS_OK) ||
2256 (p_data->data.status == NFC_STATUS_CONTINUE))) {
2257 rw_t3t_data_cback(conn_id, &(p_data->data));
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002258 break;
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002259 } else if (p_data->data.p_data != NULL) {
2260 /* Free the response buffer in case of error response */
2261 GKI_freebuf((NFC_HDR*)(p_data->data.p_data));
2262 p_data->data.p_data = NULL;
2263 }
2264 /* Data event with error status...fall through to NFC_ERROR_CEVT case */
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002265
2266 case NFC_ERROR_CEVT:
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002267 nfc_stop_quick_timer(&p_cb->timer);
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002268
Ruchi Kandoi303fec12016-12-14 13:22:38 -08002269#if (RW_STATS_INCLUDED == TRUE)
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002270 rw_main_update_trans_error_stats();
2271#endif /* RW_STATS_INCLUDED */
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002272
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002273 if (event == NFC_ERROR_CEVT)
2274 rw_t3t_process_error(NFC_STATUS_TIMEOUT);
2275 else if (p_data)
2276 rw_t3t_process_error(p_data->status);
2277 break;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002278
2279 default:
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002280 break;
2281 }
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002282}
2283
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002284/*******************************************************************************
2285**
Sherry Smith818b56e2014-05-14 16:46:32 -07002286** Function rw_t3t_mrti_to_a_b
2287**
2288** Description Converts the given MRTI (Maximum Response Time Information)
2289** to the base to calculate timeout value.
2290** (The timeout value is a + b * number_blocks)
2291**
2292** Returns NFC_STATUS_OK
2293**
2294*******************************************************************************/
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002295static void rw_t3t_mrti_to_a_b(uint8_t mrti, uint32_t* p_a, uint32_t* p_b) {
2296 uint8_t a, b, e;
Sherry Smith818b56e2014-05-14 16:46:32 -07002297
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002298 a = (mrti & 0x7) + 1; /* A is bit 0 ~ bit 2 */
2299 mrti >>= 3;
2300 b = (mrti & 0x7) + 1; /* B is bit 3 ~ bit 5 */
2301 mrti >>= 3;
2302 e = mrti & 0x3; /* E is bit 6 ~ bit 7 */
2303 *p_a = rw_t3t_mrti_base[e] * a; /* (A+1) * base (i.e T/t3t * 4^E) */
2304 *p_b = rw_t3t_mrti_base[e] * b; /* (B+1) * base (i.e T/t3t * 4^E) */
Sherry Smith818b56e2014-05-14 16:46:32 -07002305}
2306
Sherry Smith818b56e2014-05-14 16:46:32 -07002307/*******************************************************************************
2308**
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002309** Function rw_t3t_select
2310**
2311** Description Called by NFC manager when a Type3 tag has been activated
2312**
2313** Returns NFC_STATUS_OK
2314**
2315*******************************************************************************/
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002316tNFC_STATUS rw_t3t_select(uint8_t peer_nfcid2[NCI_RF_F_UID_LEN],
2317 uint8_t mrti_check, uint8_t mrti_update) {
2318 tRW_T3T_CB* p_cb = &rw_cb.tcb.t3t;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002319
Ruchi Kandoi6767aec2017-09-26 09:46:26 -07002320 DLOG_IF(INFO, nfc_debug_enabled) << __func__;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002321
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002322 memcpy(p_cb->peer_nfcid2, peer_nfcid2,
2323 NCI_NFCID2_LEN); /* Store tag's NFCID2 */
2324 p_cb->ndef_attrib.status =
2325 NFC_STATUS_NOT_INITIALIZED; /* Indicate that NDEF detection has not been
2326 performed yet */
2327 p_cb->rw_state = RW_T3T_STATE_IDLE;
2328 p_cb->flags = 0;
2329 rw_t3t_mrti_to_a_b(mrti_check, &p_cb->check_tout_a, &p_cb->check_tout_b);
2330 rw_t3t_mrti_to_a_b(mrti_update, &p_cb->update_tout_a, &p_cb->update_tout_b);
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002331
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002332 /* Alloc cmd buf for retransmissions */
2333 if (p_cb->p_cur_cmd_buf == NULL) {
Ruchi Kandoi0c515ae2017-01-30 17:48:41 -08002334 p_cb->p_cur_cmd_buf = (NFC_HDR*)GKI_getpoolbuf(NFC_RW_POOL_ID);
2335 if (p_cb->p_cur_cmd_buf == NULL) {
Ruchi Kandoi6767aec2017-09-26 09:46:26 -07002336 LOG(ERROR) << StringPrintf(
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002337 "rw_t3t_select: unable to allocate buffer for retransmission");
2338 p_cb->rw_state = RW_T3T_STATE_NOT_ACTIVATED;
2339 return (NFC_STATUS_FAILED);
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002340 }
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002341 }
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002342
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002343 NFC_SetStaticRfCback(rw_t3t_conn_cback);
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002344
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002345 return NFC_STATUS_OK;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002346}
2347
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002348/*******************************************************************************
2349**
2350** Function rw_t3t_unselect
2351**
2352** Description Called by NFC manager when a Type3 tag has been de-activated
2353**
2354** Returns NFC_STATUS_OK
2355**
2356*******************************************************************************/
Ruchi Kandoi9ba6d242017-10-13 16:07:01 -07002357static tNFC_STATUS rw_t3t_unselect() {
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002358 tRW_T3T_CB* p_cb = &rw_cb.tcb.t3t;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002359
Ruchi Kandoi303fec12016-12-14 13:22:38 -08002360#if (RW_STATS_INCLUDED == TRUE)
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002361 /* Display stats */
2362 rw_main_log_stats();
2363#endif /* RW_STATS_INCLUDED */
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002364
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002365 /* Stop t3t timer (if started) */
2366 nfc_stop_quick_timer(&p_cb->timer);
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002367
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002368 /* Free cmd buf for retransmissions */
2369 if (p_cb->p_cur_cmd_buf) {
2370 GKI_freebuf(p_cb->p_cur_cmd_buf);
2371 p_cb->p_cur_cmd_buf = NULL;
2372 }
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002373
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002374 p_cb->rw_state = RW_T3T_STATE_NOT_ACTIVATED;
2375 NFC_SetStaticRfCback(NULL);
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002376
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002377 return NFC_STATUS_OK;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002378}
2379
Evan Chua24be4f2013-11-13 15:30:16 -05002380/*******************************************************************************
2381**
2382** Function rw_t3t_update_ndef_flag
2383**
2384** Description set additional NDEF Flags for felica lite tag
2385**
2386** Returns updated NDEF Flag value
2387**
2388*******************************************************************************/
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002389static void rw_t3t_update_ndef_flag(uint8_t* p_flag) {
2390 tRW_T3T_CB* p_cb = &rw_cb.tcb.t3t;
2391 uint8_t xx;
Evan Chua24be4f2013-11-13 15:30:16 -05002392
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002393 for (xx = 0; xx < p_cb->num_system_codes; xx++) {
2394 if (p_cb->system_codes[xx] == T3T_SYSTEM_CODE_FELICA_LITE) {
2395 *p_flag &= ~RW_NDEF_FL_UNKNOWN;
2396 *p_flag |= (RW_NDEF_FL_SUPPORTED | RW_NDEF_FL_FORMATABLE);
2397 break;
Evan Chua24be4f2013-11-13 15:30:16 -05002398 }
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002399 }
Evan Chua24be4f2013-11-13 15:30:16 -05002400}
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002401
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002402/*******************************************************************************
2403**
2404** Function rw_t3t_cmd_str
2405**
2406** Description Converts cmd_id to command string for logging
2407**
2408** Returns command string
2409**
2410*******************************************************************************/
Ruchi Kandoi7dab0e52017-08-03 13:09:49 -07002411static std::string rw_t3t_cmd_str(uint8_t cmd_id) {
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002412 switch (cmd_id) {
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002413 case RW_T3T_CMD_DETECT_NDEF:
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002414 return "RW_T3T_CMD_DETECT_NDEF";
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002415 case RW_T3T_CMD_CHECK_NDEF:
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002416 return "RW_T3T_CMD_CHECK_NDEF";
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002417 case RW_T3T_CMD_UPDATE_NDEF:
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002418 return "RW_T3T_CMD_UPDATE_NDEF";
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002419 case RW_T3T_CMD_CHECK:
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002420 return "RW_T3T_CMD_CHECK";
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002421 case RW_T3T_CMD_UPDATE:
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002422 return "RW_T3T_CMD_UPDATE";
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002423 case RW_T3T_CMD_SEND_RAW_FRAME:
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002424 return "RW_T3T_CMD_SEND_RAW_FRAME";
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002425 case RW_T3T_CMD_GET_SYSTEM_CODES:
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002426 return "RW_T3T_CMD_GET_SYSTEM_CODES";
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002427 default:
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002428 return "Unknown";
2429 }
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002430}
2431
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002432/*******************************************************************************
2433**
2434** Function rw_t3t_state_str
2435**
2436** Description Converts state_id to command string for logging
2437**
2438** Returns command string
2439**
2440*******************************************************************************/
Ruchi Kandoi7dab0e52017-08-03 13:09:49 -07002441static std::string rw_t3t_state_str(uint8_t state_id) {
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002442 switch (state_id) {
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002443 case RW_T3T_STATE_NOT_ACTIVATED:
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002444 return "RW_T3T_STATE_NOT_ACTIVATED";
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002445 case RW_T3T_STATE_IDLE:
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002446 return "RW_T3T_STATE_IDLE";
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002447 case RW_T3T_STATE_COMMAND_PENDING:
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002448 return "RW_T3T_STATE_COMMAND_PENDING";
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002449 default:
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002450 return "Unknown";
2451 }
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002452}
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002453
2454/*****************************************************************************
2455** Type3 Tag API Functions
2456*****************************************************************************/
2457
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002458/*****************************************************************************
2459**
2460** Function RW_T3tDetectNDef
2461**
2462** Description
2463** This function is used to perform NDEF detection on a Type 3 tag, and
2464** retrieve the tag's NDEF attribute information (block 0).
2465**
2466** Before using this API, the application must call RW_SelectTagType to
2467** indicate that a Type 3 tag has been activated, and to provide the
2468** tag's Manufacture ID (IDm) .
2469**
2470** Returns
2471** NFC_STATUS_OK: ndef detection procedure started
2472** NFC_STATUS_NO_BUFFERS: unable to allocate a buffer for this operation
2473** NFC_STATUS_FAILED: other error
2474**
2475*****************************************************************************/
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002476tNFC_STATUS RW_T3tDetectNDef(void) {
2477 tRW_T3T_CB* p_cb = &rw_cb.tcb.t3t;
2478 tNFC_STATUS retval = NFC_STATUS_OK;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002479
Ruchi Kandoi6767aec2017-09-26 09:46:26 -07002480 DLOG_IF(INFO, nfc_debug_enabled) << __func__;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002481
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002482 /* Check if we are in valid state to handle this API */
2483 if (p_cb->rw_state != RW_T3T_STATE_IDLE) {
Ruchi Kandoi6767aec2017-09-26 09:46:26 -07002484 LOG(ERROR) << StringPrintf("Error: invalid state to handle API (0x%x)",
2485 p_cb->rw_state);
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002486 return (NFC_STATUS_FAILED);
2487 }
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002488
Ruchi Kandoi0c515ae2017-01-30 17:48:41 -08002489 retval = (tNFC_STATUS)nci_snd_t3t_polling(T3T_SYSTEM_CODE_NDEF, 0, 0);
2490 if (retval == NCI_STATUS_OK) {
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002491 p_cb->cur_cmd = RW_T3T_CMD_DETECT_NDEF;
2492 p_cb->cur_tout = RW_T3T_DEFAULT_CMD_TIMEOUT_TICKS;
2493 p_cb->cur_poll_rc = 0;
2494 p_cb->rw_state = RW_T3T_STATE_COMMAND_PENDING;
2495 p_cb->flags |= RW_T3T_FL_W4_NDEF_DETECT_POLL_RSP;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002496
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002497 /* start timer for waiting for responses */
2498 rw_t3t_start_poll_timer(p_cb);
2499 }
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002500
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002501 return (retval);
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002502}
2503
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002504/*****************************************************************************
2505**
2506** Function RW_T3tCheckNDef
2507**
2508** Description
2509** Retrieve NDEF contents from a Type3 tag.
2510**
2511** The RW_T3T_CHECK_EVT event is used to notify the application for each
Ruchi Kandoi552f2b72017-01-28 16:22:55 -08002512** segment of NDEF data received. The RW_T3T_CHECK_CPLT_EVT event is used
2513** to notify the application all segments have been received.
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002514**
2515** Before using this API, the RW_T3tDetectNDef function must be called to
2516** verify that the tag contains NDEF data, and to retrieve the NDEF
2517** attributes.
2518**
2519** Internally, this command will be separated into multiple Tag 3 Check
2520** commands (if necessary) - depending on the tag's Nbr (max number of
2521** blocks per read) attribute.
2522**
2523** Returns
2524** NFC_STATUS_OK: check command started
2525** NFC_STATUS_NO_BUFFERS: unable to allocate a buffer for this operation
2526** NFC_STATUS_FAILED: other error
2527**
2528*****************************************************************************/
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002529tNFC_STATUS RW_T3tCheckNDef(void) {
2530 tNFC_STATUS retval = NFC_STATUS_OK;
2531 tRW_T3T_CB* p_cb = &rw_cb.tcb.t3t;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002532
Ruchi Kandoi6767aec2017-09-26 09:46:26 -07002533 DLOG_IF(INFO, nfc_debug_enabled) << __func__;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002534
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002535 /* Check if we are in valid state to handle this API */
2536 if (p_cb->rw_state != RW_T3T_STATE_IDLE) {
Ruchi Kandoi6767aec2017-09-26 09:46:26 -07002537 LOG(ERROR) << StringPrintf("Error: invalid state to handle API (0x%x)",
2538 p_cb->rw_state);
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002539 return (NFC_STATUS_FAILED);
2540 } else if (p_cb->ndef_attrib.status !=
2541 NFC_STATUS_OK) /* NDEF detection not performed yet? */
2542 {
Ruchi Kandoi6767aec2017-09-26 09:46:26 -07002543 LOG(ERROR) << StringPrintf("Error: NDEF detection not performed yet");
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002544 return (NFC_STATUS_NOT_INITIALIZED);
2545 } else if (p_cb->ndef_attrib.ln == 0) {
Ruchi Kandoi6767aec2017-09-26 09:46:26 -07002546 LOG(ERROR) << StringPrintf("Type 3 tag contains empty NDEF message");
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002547 return (NFC_STATUS_FAILED);
2548 }
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002549
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002550 /* Check number of blocks needed for this update */
2551 p_cb->flags &= ~RW_T3T_FL_IS_FINAL_NDEF_SEGMENT;
2552 p_cb->ndef_rx_offset = 0;
2553 retval = rw_t3t_send_next_ndef_check_cmd(p_cb);
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002554
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002555 return (retval);
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002556}
2557
2558/*****************************************************************************
2559**
2560** Function RW_T3tUpdateNDef
2561**
2562** Description
2563** Write NDEF contents to a Type3 tag.
2564**
2565** The RW_T3T_UPDATE_CPLT_EVT callback event will be used to notify the
2566** application of the response.
2567**
2568** Before using this API, the RW_T3tDetectNDef function must be called to
2569** verify that the tag contains NDEF data, and to retrieve the NDEF
2570** attributes.
2571**
2572** Internally, this command will be separated into multiple Tag 3 Update
2573** commands (if necessary) - depending on the tag's Nbw (max number of
2574** blocks per write) attribute.
2575**
2576** Returns
2577** NFC_STATUS_OK: check command started
2578** NFC_STATUS_NO_BUFFERS: unable to allocate a buffer for this operation
2579** NFC_STATUS_REFUSED: tag is read-only
2580** NFC_STATUS_BUFFER_FULL: len exceeds tag's maximum size
2581** NFC_STATUS_FAILED: other error
2582**
2583*****************************************************************************/
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002584tNFC_STATUS RW_T3tUpdateNDef(uint32_t len, uint8_t* p_data) {
2585 tNFC_STATUS retval = NFC_STATUS_OK;
2586 tRW_T3T_CB* p_cb = &rw_cb.tcb.t3t;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002587
Ruchi Kandoi6767aec2017-09-26 09:46:26 -07002588 DLOG_IF(INFO, nfc_debug_enabled)
2589 << StringPrintf("RW_T3tUpdateNDef (len=%i)", len);
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002590
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002591 /* Check if we are in valid state to handle this API */
2592 if (p_cb->rw_state != RW_T3T_STATE_IDLE) {
Ruchi Kandoi6767aec2017-09-26 09:46:26 -07002593 LOG(ERROR) << StringPrintf("Error: invalid state to handle API (0x%x)",
2594 p_cb->rw_state);
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002595 return (NFC_STATUS_FAILED);
2596 } else if (p_cb->ndef_attrib.status !=
2597 NFC_STATUS_OK) /* NDEF detection not performed yet? */
2598 {
Ruchi Kandoi6767aec2017-09-26 09:46:26 -07002599 LOG(ERROR) << StringPrintf("Error: NDEF detection not performed yet");
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002600 return (NFC_STATUS_NOT_INITIALIZED);
2601 } else if (len > (((uint32_t)p_cb->ndef_attrib.nmaxb) *
2602 16)) /* Len exceed's tag's NDEF memory? */
2603 {
2604 return (NFC_STATUS_BUFFER_FULL);
2605 } else if (p_cb->ndef_attrib.rwflag ==
2606 T3T_MSG_NDEF_RWFLAG_RO) /* Tag's NDEF memory is read-only? */
2607 {
2608 return (NFC_STATUS_REFUSED);
2609 }
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002610
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002611 /* Check number of blocks needed for this update */
2612 p_cb->flags &= ~RW_T3T_FL_IS_FINAL_NDEF_SEGMENT;
2613 p_cb->ndef_msg_bytes_sent = 0;
2614 p_cb->ndef_msg_len = len;
2615 p_cb->ndef_msg = p_data;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002616
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002617 /* Send initial UPDATE command for NDEF Attribute Info */
2618 retval = rw_t3t_send_update_ndef_attribute_cmd(p_cb, true);
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002619
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002620 return (retval);
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002621}
2622
2623/*****************************************************************************
2624**
2625** Function RW_T3tCheck
2626**
2627** Description
2628** Read (non-NDEF) contents from a Type3 tag.
2629**
2630** The RW_READ_EVT event is used to notify the application for each
2631** segment of NDEF data received. The RW_READ_CPLT_EVT event is used to
2632** notify the application all segments have been received.
2633**
2634** Before using this API, the application must call RW_SelectTagType to
2635** indicate that a Type 3 tag has been activated, and to provide the
2636** tag's Manufacture ID (IDm) .
2637**
2638** Returns
2639** NFC_STATUS_OK: check command started
2640** NFC_STATUS_NO_BUFFERS: unable to allocate a buffer for this operation
2641** NFC_STATUS_FAILED: other error
2642**
2643*****************************************************************************/
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002644tNFC_STATUS RW_T3tCheck(uint8_t num_blocks, tT3T_BLOCK_DESC* t3t_blocks) {
2645 tNFC_STATUS retval = NFC_STATUS_OK;
2646 tRW_T3T_CB* p_cb = &rw_cb.tcb.t3t;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002647
Ruchi Kandoi6767aec2017-09-26 09:46:26 -07002648 DLOG_IF(INFO, nfc_debug_enabled)
2649 << StringPrintf("RW_T3tCheck (num_blocks = %i)", num_blocks);
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002650
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002651 /* Check if we are in valid state to handle this API */
2652 if (p_cb->rw_state != RW_T3T_STATE_IDLE) {
Ruchi Kandoi6767aec2017-09-26 09:46:26 -07002653 LOG(ERROR) << StringPrintf("Error: invalid state to handle API (0x%x)",
2654 p_cb->rw_state);
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002655 return (NFC_STATUS_FAILED);
2656 }
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002657
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002658 /* Send the CHECK command */
2659 retval = rw_t3t_send_check_cmd(p_cb, num_blocks, t3t_blocks);
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002660
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002661 return (retval);
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002662}
2663
2664/*****************************************************************************
2665**
2666** Function RW_T3tUpdate
2667**
2668** Description
2669** Write (non-NDEF) contents to a Type3 tag.
2670**
2671** The RW_WRITE_CPLT_EVT event is used to notify the application all
2672** segments have been received.
2673**
2674** Before using this API, the application must call RW_SelectTagType to
2675** indicate that a Type 3 tag has been activated, and to provide the tag's
2676** Manufacture ID (IDm) .
2677**
2678** Returns
2679** NFC_STATUS_OK: check command started
2680** NFC_STATUS_NO_BUFFERS: unable to allocate a buffer for this operation
2681** NFC_STATUS_FAILED: other error
2682**
2683*****************************************************************************/
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002684tNFC_STATUS RW_T3tUpdate(uint8_t num_blocks, tT3T_BLOCK_DESC* t3t_blocks,
2685 uint8_t* p_data) {
2686 tNFC_STATUS retval = NFC_STATUS_OK;
2687 tRW_T3T_CB* p_cb = &rw_cb.tcb.t3t;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002688
Ruchi Kandoi6767aec2017-09-26 09:46:26 -07002689 DLOG_IF(INFO, nfc_debug_enabled)
2690 << StringPrintf("RW_T3tUpdate (num_blocks = %i)", num_blocks);
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002691
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002692 /* Check if we are in valid state to handle this API */
2693 if (p_cb->rw_state != RW_T3T_STATE_IDLE) {
Ruchi Kandoi6767aec2017-09-26 09:46:26 -07002694 LOG(ERROR) << StringPrintf("Error: invalid state to handle API (0x%x)",
2695 p_cb->rw_state);
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002696 return (NFC_STATUS_FAILED);
2697 }
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002698
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002699 /* Send the UPDATE command */
2700 retval = rw_t3t_send_update_cmd(p_cb, num_blocks, t3t_blocks, p_data);
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002701
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002702 return (retval);
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002703}
2704
2705/*****************************************************************************
2706**
2707** Function RW_T3tPresenceCheck
2708**
2709** Description
2710** Check if the tag is still in the field.
2711**
2712** The RW_T3T_PRESENCE_CHECK_EVT w/ status is used to indicate presence
2713** or non-presence.
2714**
2715** Returns
2716** NFC_STATUS_OK, if raw data frame sent
2717** NFC_STATUS_NO_BUFFERS: unable to allocate a buffer for this operation
2718** NFC_STATUS_FAILED: other error
2719**
2720*****************************************************************************/
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002721tNFC_STATUS RW_T3tPresenceCheck(void) {
2722 tNFC_STATUS retval = NFC_STATUS_OK;
2723 tRW_DATA evt_data;
2724 tRW_CB* p_rw_cb = &rw_cb;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002725
Ruchi Kandoi6767aec2017-09-26 09:46:26 -07002726 DLOG_IF(INFO, nfc_debug_enabled) << __func__;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002727
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002728 /* If RW_SelectTagType was not called (no conn_callback) return failure */
2729 if (!(p_rw_cb->p_cback)) {
2730 retval = NFC_STATUS_FAILED;
2731 }
2732 /* If we are not activated, then RW_T3T_PRESENCE_CHECK_EVT status=FAIL */
2733 else if (p_rw_cb->tcb.t3t.rw_state == RW_T3T_STATE_NOT_ACTIVATED) {
2734 evt_data.status = NFC_STATUS_FAILED;
2735 (*p_rw_cb->p_cback)(RW_T3T_PRESENCE_CHECK_EVT, &evt_data);
2736 }
2737 /* If command is pending */
2738 else if (p_rw_cb->tcb.t3t.rw_state == RW_T3T_STATE_COMMAND_PENDING) {
2739 /* If already performing presence check, return error */
2740 if (p_rw_cb->tcb.t3t.flags & RW_T3T_FL_W4_PRESENCE_CHECK_POLL_RSP) {
Ruchi Kandoi6767aec2017-09-26 09:46:26 -07002741 DLOG_IF(INFO, nfc_debug_enabled)
2742 << StringPrintf("RW_T3tPresenceCheck already in progress");
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002743 retval = NFC_STATUS_FAILED;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002744 }
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002745 /* If busy with any other command, assume that the tag is present */
2746 else {
2747 evt_data.status = NFC_STATUS_OK;
2748 (*p_rw_cb->p_cback)(RW_T3T_PRESENCE_CHECK_EVT, &evt_data);
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002749 }
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002750 } else {
2751 /* IDLE state: send POLL command */
Ruchi Kandoi0c515ae2017-01-30 17:48:41 -08002752 retval = (tNFC_STATUS)nci_snd_t3t_polling(0xFFFF, T3T_POLL_RC_SC, 0);
2753 if (retval == NCI_STATUS_OK) {
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002754 p_rw_cb->tcb.t3t.flags |= RW_T3T_FL_W4_PRESENCE_CHECK_POLL_RSP;
2755 p_rw_cb->tcb.t3t.rw_state = RW_T3T_STATE_COMMAND_PENDING;
2756 p_rw_cb->tcb.t3t.cur_poll_rc = 0;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002757
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002758 /* start timer for waiting for responses */
2759 rw_t3t_start_poll_timer(&p_rw_cb->tcb.t3t);
2760 } else {
Ruchi Kandoi6767aec2017-09-26 09:46:26 -07002761 DLOG_IF(INFO, nfc_debug_enabled) << StringPrintf(
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002762 "RW_T3tPresenceCheck error sending NCI_RF_T3T_POLLING cmd (status = "
2763 "0x%0x)",
2764 retval);
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002765 }
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002766 }
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002767
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002768 return (retval);
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002769}
2770
2771/*****************************************************************************
2772**
2773** Function RW_T3tPoll
2774**
2775** Description
2776** Send POLL command
2777**
2778** Returns
2779** NFC_STATUS_OK, if raw data frame sent
2780** NFC_STATUS_NO_BUFFERS: unable to allocate a buffer for this operation
2781** NFC_STATUS_FAILED: other error
2782**
2783*****************************************************************************/
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002784tNFC_STATUS RW_T3tPoll(uint16_t system_code, tT3T_POLL_RC rc, uint8_t tsn) {
2785 tNFC_STATUS retval = NFC_STATUS_OK;
2786 tRW_T3T_CB* p_cb = &rw_cb.tcb.t3t;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002787
Ruchi Kandoi6767aec2017-09-26 09:46:26 -07002788 DLOG_IF(INFO, nfc_debug_enabled) << __func__;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002789
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002790 /* Check if we are in valid state to handle this API */
2791 if (p_cb->rw_state != RW_T3T_STATE_IDLE) {
Ruchi Kandoi6767aec2017-09-26 09:46:26 -07002792 LOG(ERROR) << StringPrintf("Error: invalid state to handle API (0x%x)",
2793 p_cb->rw_state);
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002794 return (NFC_STATUS_FAILED);
2795 }
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002796
Ruchi Kandoi0c515ae2017-01-30 17:48:41 -08002797 retval = (tNFC_STATUS)nci_snd_t3t_polling(system_code, (uint8_t)rc, tsn);
2798 if (retval == NCI_STATUS_OK) {
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002799 /* start timer for waiting for responses */
2800 p_cb->cur_poll_rc = rc;
2801 p_cb->rw_state = RW_T3T_STATE_COMMAND_PENDING;
2802 rw_t3t_start_poll_timer(p_cb);
2803 }
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002804
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002805 return (retval);
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002806}
2807
2808/*****************************************************************************
2809**
2810** Function RW_T3tSendRawFrame
2811**
2812** Description
2813** This function is called to send a raw data frame to the peer device.
2814** When type 3 tag receives response from peer, the callback function
2815** will be called with a RW_T3T_RAW_FRAME_EVT [Table 6].
2816**
2817** Before using this API, the application must call RW_SelectTagType to
2818** indicate that a Type 3 tag has been activated.
2819**
2820** The raw frame should be a properly formatted Type 3 tag message.
2821**
2822** Returns
2823** NFC_STATUS_OK, if raw data frame sent
2824** NFC_STATUS_NO_BUFFERS: unable to allocate a buffer for this operation
2825** NFC_STATUS_FAILED: other error
2826**
2827*****************************************************************************/
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002828tNFC_STATUS RW_T3tSendRawFrame(uint16_t len, uint8_t* p_data) {
2829 tNFC_STATUS retval = NFC_STATUS_OK;
2830 tRW_T3T_CB* p_cb = &rw_cb.tcb.t3t;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002831
Ruchi Kandoi6767aec2017-09-26 09:46:26 -07002832 DLOG_IF(INFO, nfc_debug_enabled)
2833 << StringPrintf("RW_T3tSendRawFrame (len = %i)", len);
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002834
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002835 /* Check if we are in valid state to handle this API */
2836 if (p_cb->rw_state != RW_T3T_STATE_IDLE) {
Ruchi Kandoi6767aec2017-09-26 09:46:26 -07002837 LOG(ERROR) << StringPrintf("Error: invalid state to handle API (0x%x)",
2838 p_cb->rw_state);
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002839 return (NFC_STATUS_FAILED);
2840 }
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002841
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002842 /* Send the UPDATE command */
2843 retval = rw_t3t_send_raw_frame(p_cb, len, p_data);
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002844
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002845 return (retval);
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002846}
2847
2848/*****************************************************************************
2849**
2850** Function RW_T3tGetSystemCodes
2851**
2852** Description
2853** Get systems codes supported by the activated tag:
Yoshinobu Ito721b3ab2016-08-02 14:41:33 +09002854** Poll for wildcard (FFFF, RC=1):
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002855**
2856** Before using this API, the application must call RW_SelectTagType to
2857** indicate that a Type 3 tag has been activated.
2858**
2859** Returns
2860** NFC_STATUS_OK, if raw data frame sent
2861** NFC_STATUS_NO_BUFFERS: unable to allocate a buffer for this operation
2862** NFC_STATUS_FAILED: other error
2863**
2864*****************************************************************************/
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002865tNFC_STATUS RW_T3tGetSystemCodes(void) {
2866 tNFC_STATUS retval = NFC_STATUS_OK;
2867 tRW_T3T_CB* p_cb = &rw_cb.tcb.t3t;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002868
Ruchi Kandoi6767aec2017-09-26 09:46:26 -07002869 DLOG_IF(INFO, nfc_debug_enabled) << __func__;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002870
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002871 /* Check if we are in valid state to handle this API */
2872 if (p_cb->rw_state != RW_T3T_STATE_IDLE) {
Ruchi Kandoi6767aec2017-09-26 09:46:26 -07002873 LOG(ERROR) << StringPrintf("Error: invalid state to handle API (0x%x)",
2874 p_cb->rw_state);
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002875 return (NFC_STATUS_FAILED);
2876 } else {
Ruchi Kandoi0c515ae2017-01-30 17:48:41 -08002877 retval = (tNFC_STATUS)nci_snd_t3t_polling(0xFFFF, T3T_POLL_RC_SC, 0);
2878 if (retval == NCI_STATUS_OK) {
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002879 p_cb->cur_cmd = RW_T3T_CMD_GET_SYSTEM_CODES;
2880 p_cb->cur_tout = RW_T3T_DEFAULT_CMD_TIMEOUT_TICKS;
2881 p_cb->cur_poll_rc = T3T_POLL_RC_SC;
2882 p_cb->rw_state = RW_T3T_STATE_COMMAND_PENDING;
2883 p_cb->flags |= RW_T3T_FL_W4_GET_SC_POLL_RSP;
2884 p_cb->num_system_codes = 0;
2885
2886 /* start timer for waiting for responses */
2887 rw_t3t_start_poll_timer(p_cb);
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002888 }
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002889 }
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002890
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002891 return (retval);
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002892}
2893
2894/*****************************************************************************
2895**
2896** Function RW_T3tFormatNDef
2897**
2898** Description
2899** Format a type-3 tag for NDEF.
2900**
2901** Only Felica-Lite tags are supported by this API. The
2902** RW_T3T_FORMAT_CPLT_EVT is used to notify the status of the operation.
2903**
2904** Returns
2905** NFC_STATUS_OK: ndef detection procedure started
2906** NFC_STATUS_NO_BUFFERS: unable to allocate a buffer for this operation
2907** NFC_STATUS_FAILED: other error
2908**
2909*****************************************************************************/
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002910tNFC_STATUS RW_T3tFormatNDef(void) {
2911 tNFC_STATUS retval = NFC_STATUS_OK;
2912 tRW_T3T_CB* p_cb = &rw_cb.tcb.t3t;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002913
Ruchi Kandoi6767aec2017-09-26 09:46:26 -07002914 DLOG_IF(INFO, nfc_debug_enabled) << __func__;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002915
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002916 /* Check if we are in valid state to handle this API */
2917 if (p_cb->rw_state != RW_T3T_STATE_IDLE) {
Ruchi Kandoi6767aec2017-09-26 09:46:26 -07002918 LOG(ERROR) << StringPrintf("Error: invalid state to handle API (0x%x)",
2919 p_cb->rw_state);
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002920 return (NFC_STATUS_FAILED);
2921 } else {
2922 /* Poll tag, to see if Felica-Lite system is supported */
Ruchi Kandoi0c515ae2017-01-30 17:48:41 -08002923 retval = (tNFC_STATUS)nci_snd_t3t_polling(T3T_SYSTEM_CODE_FELICA_LITE,
2924 T3T_POLL_RC_SC, 0);
2925 if (retval == NCI_STATUS_OK) {
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002926 p_cb->cur_cmd = RW_T3T_CMD_FORMAT;
2927 p_cb->cur_tout = RW_T3T_DEFAULT_CMD_TIMEOUT_TICKS;
2928 p_cb->cur_poll_rc = T3T_POLL_RC_SC;
2929 p_cb->rw_state = RW_T3T_STATE_COMMAND_PENDING;
2930 p_cb->rw_substate = RW_T3T_FMT_SST_POLL_FELICA_LITE;
2931 p_cb->flags |= RW_T3T_FL_W4_FMT_FELICA_LITE_POLL_RSP;
2932
2933 /* start timer for waiting for responses */
2934 rw_t3t_start_poll_timer(p_cb);
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002935 }
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002936 }
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002937
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002938 return (retval);
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002939}
Martijn Coenen5c65c3a2013-03-27 13:23:36 -07002940
2941/*****************************************************************************
2942**
2943** Function RW_T3tSetReadOnly
2944**
2945** Description This function performs NDEF read-only procedure
2946** Note: Only Felica-Lite tags are supported by this API.
2947** RW_T3tDetectNDef() must be called before using this
2948**
2949** The RW_T3T_SET_READ_ONLY_CPLT_EVT event will be returned.
2950**
2951** Returns NFC_STATUS_OK if success
2952** NFC_STATUS_FAILED if T3T is busy or other error
2953**
2954*****************************************************************************/
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002955tNFC_STATUS RW_T3tSetReadOnly(bool b_hard_lock) {
2956 tNFC_STATUS retval = NFC_STATUS_OK;
2957 tRW_T3T_CB* p_cb = &rw_cb.tcb.t3t;
2958 tRW_DATA evt_data;
Martijn Coenen5c65c3a2013-03-27 13:23:36 -07002959
Ruchi Kandoi6767aec2017-09-26 09:46:26 -07002960 DLOG_IF(INFO, nfc_debug_enabled)
2961 << StringPrintf("b_hard_lock=%d", b_hard_lock);
Martijn Coenen5c65c3a2013-03-27 13:23:36 -07002962
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002963 /* Check if we are in valid state to handle this API */
2964 if (p_cb->rw_state != RW_T3T_STATE_IDLE) {
Ruchi Kandoi6767aec2017-09-26 09:46:26 -07002965 LOG(ERROR) << StringPrintf("Error: invalid state to handle API (0x%x)",
2966 p_cb->rw_state);
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002967 return (NFC_STATUS_FAILED);
2968 }
Martijn Coenen5c65c3a2013-03-27 13:23:36 -07002969
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002970 if (p_cb->ndef_attrib.status !=
2971 NFC_STATUS_OK) /* NDEF detection not performed yet? */
2972 {
Ruchi Kandoi6767aec2017-09-26 09:46:26 -07002973 LOG(ERROR) << StringPrintf("Error: NDEF detection not performed yet");
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002974 return (NFC_STATUS_NOT_INITIALIZED);
2975 }
Martijn Coenen5c65c3a2013-03-27 13:23:36 -07002976
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002977 if ((!b_hard_lock) &&
2978 (p_cb->ndef_attrib.rwflag ==
2979 T3T_MSG_NDEF_RWFLAG_RO)) /* Tag's NDEF memory is read-only already */
2980 {
2981 evt_data.status = NFC_STATUS_OK;
2982 (*(rw_cb.p_cback))(RW_T3T_SET_READ_ONLY_CPLT_EVT, &evt_data);
Martijn Coenen5c65c3a2013-03-27 13:23:36 -07002983 return (retval);
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002984 } else {
2985 /* Poll tag, to see if Felica-Lite system is supported */
Ruchi Kandoi0c515ae2017-01-30 17:48:41 -08002986 retval = (tNFC_STATUS)nci_snd_t3t_polling(T3T_SYSTEM_CODE_FELICA_LITE,
2987 T3T_POLL_RC_SC, 0);
2988 if (retval == NCI_STATUS_OK) {
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002989 if (b_hard_lock)
2990 p_cb->cur_cmd = RW_T3T_CMD_SET_READ_ONLY_HARD;
2991 else
2992 p_cb->cur_cmd = RW_T3T_CMD_SET_READ_ONLY_SOFT;
2993 p_cb->cur_tout = RW_T3T_DEFAULT_CMD_TIMEOUT_TICKS;
2994 p_cb->cur_poll_rc = T3T_POLL_RC_SC;
2995 p_cb->rw_state = RW_T3T_STATE_COMMAND_PENDING;
2996 p_cb->rw_substate = RW_T3T_SRO_SST_POLL_FELICA_LITE;
2997 p_cb->flags |= RW_T3T_FL_W4_SRO_FELICA_LITE_POLL_RSP;
2998
2999 /* start timer for waiting for responses */
3000 rw_t3t_start_poll_timer(p_cb);
3001 }
3002 }
3003 return (retval);
Martijn Coenen5c65c3a2013-03-27 13:23:36 -07003004}