blob: 45321e503ef5db960f6e46306c061a6e9a68bad7 [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;
1251 } else {
1252 /* Get checksum from received ndef attribute msg */
1253 p = &p_t3t_rsp[T3T_MSG_RSP_OFFSET_CHECK_DATA + T3T_MSG_NDEF_ATTR_INFO_SIZE];
1254 BE_STREAM_TO_UINT16(checksum_rx, p);
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001255
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001256 /* Calculate checksum - move check for checsum to beginning */
1257 checksum_calc = 0;
1258 p = &p_t3t_rsp[T3T_MSG_RSP_OFFSET_CHECK_DATA];
1259 for (i = 0; i < T3T_MSG_NDEF_ATTR_INFO_SIZE; i++) {
1260 checksum_calc += p[i];
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001261 }
1262
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001263 /* Validate checksum */
1264 if (checksum_calc != checksum_rx) {
1265 p_cb->ndef_attrib.status =
1266 NFC_STATUS_FAILED; /* only ok or failed passed to the app. can be
1267 boolean*/
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001268
Ruchi Kandoi6767aec2017-09-26 09:46:26 -07001269 LOG(ERROR) << StringPrintf("RW_T3tDetectNDEF checksum failed");
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001270 } else {
1271 p_cb->ndef_attrib.status = NFC_STATUS_OK;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001272
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001273 /* Validate version number */
1274 STREAM_TO_UINT8(p_cb->ndef_attrib.version, p);
1275
1276 if (T3T_GET_MAJOR_VERSION(T3T_MSG_NDEF_VERSION) <
1277 T3T_GET_MAJOR_VERSION(p_cb->ndef_attrib.version)) {
1278 /* Remote tag's MajorVer is newer than our's. Reject NDEF as per T3TOP
1279 * RQ_T3T_NDA_024 */
Ruchi Kandoi6767aec2017-09-26 09:46:26 -07001280 LOG(ERROR) << StringPrintf(
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001281 "RW_T3tDetectNDEF: incompatible NDEF version. Local=0x%02x, "
1282 "Remote=0x%02x",
1283 T3T_MSG_NDEF_VERSION, p_cb->ndef_attrib.version);
1284 p_cb->ndef_attrib.status = NFC_STATUS_FAILED;
1285 evt_data.status = NFC_STATUS_BAD_RESP;
1286 } else {
1287 /* Remote tag's MajorVer is equal or older than our's. NDEF is
1288 * compatible with our version. */
1289
1290 /* Update NDEF info */
1291 STREAM_TO_UINT8(
1292 p_cb->ndef_attrib.nbr,
1293 p); /* NBr: number of blocks that can be read using one Check
1294 command */
1295 STREAM_TO_UINT8(p_cb->ndef_attrib.nbw,
1296 p); /* Nbw: number of blocks that can be written using
1297 one Update command */
1298 BE_STREAM_TO_UINT16(
1299 p_cb->ndef_attrib.nmaxb,
1300 p); /* Nmaxb: maximum number of blocks available for NDEF data */
1301 BE_STREAM_TO_UINT32(temp, p);
1302 STREAM_TO_UINT8(p_cb->ndef_attrib.writef,
1303 p); /* WriteFlag: 00h if writing data finished; 0Fh if
1304 writing data in progress */
1305 STREAM_TO_UINT8(
1306 p_cb->ndef_attrib.rwflag,
1307 p); /* RWFlag: 00h NDEF is read-only; 01h if read/write available */
1308
1309 /* Get length (3-byte, big-endian) */
1310 STREAM_TO_UINT8(temp, p); /* Ln: high-byte */
1311 BE_STREAM_TO_UINT16(p_cb->ndef_attrib.ln, p); /* Ln: lo-word */
1312 p_cb->ndef_attrib.ln += (temp << 16);
1313
Ruchi Kandoi6767aec2017-09-26 09:46:26 -07001314 DLOG_IF(INFO, nfc_debug_enabled) << StringPrintf(
1315 "Detected NDEF Ver: 0x%02x", p_cb->ndef_attrib.version);
1316 DLOG_IF(INFO, nfc_debug_enabled) << StringPrintf(
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001317 "Detected NDEF Attributes: Nbr=%i, Nbw=%i, Nmaxb=%i, WriteF=%i, "
1318 "RWFlag=%i, Ln=%i",
1319 p_cb->ndef_attrib.nbr, p_cb->ndef_attrib.nbw,
1320 p_cb->ndef_attrib.nmaxb, p_cb->ndef_attrib.writef,
1321 p_cb->ndef_attrib.rwflag, p_cb->ndef_attrib.ln);
1322
1323 /* Set data for RW_T3T_NDEF_DETECT_EVT */
1324 evt_data.status = p_cb->ndef_attrib.status;
1325 evt_data.cur_size = p_cb->ndef_attrib.ln;
1326 evt_data.max_size = (uint32_t)p_cb->ndef_attrib.nmaxb * 16;
1327 evt_data.protocol = NFC_PROTOCOL_T3T;
1328 evt_data.flags = (RW_NDEF_FL_SUPPORTED | RW_NDEF_FL_FORMATED);
1329 if (p_cb->ndef_attrib.rwflag == T3T_MSG_NDEF_RWFLAG_RO)
1330 evt_data.flags |= RW_NDEF_FL_READ_ONLY;
1331 }
1332 }
1333 }
1334
Ruchi Kandoi6767aec2017-09-26 09:46:26 -07001335 DLOG_IF(INFO, nfc_debug_enabled)
1336 << StringPrintf("RW_T3tDetectNDEF response: %i", evt_data.status);
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001337
1338 p_cb->rw_state = RW_T3T_STATE_IDLE;
1339 rw_t3t_update_ndef_flag(&evt_data.flags);
1340 /* Notify app of NDEF detection result */
Myles Watson1361d522017-09-26 13:39:54 -07001341 tRW_DATA rw_data;
1342 rw_data.ndef = evt_data;
1343 (*(rw_cb.p_cback))(RW_T3T_NDEF_DETECT_EVT, &rw_data);
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001344
1345 GKI_freebuf(p_msg_rsp);
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001346}
1347
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001348/*****************************************************************************
1349**
1350** Function rw_t3t_act_handle_check_rsp
1351**
1352** Description Handle response to CHECK command
1353**
1354** Returns Nothing
1355**
1356*****************************************************************************/
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001357void rw_t3t_act_handle_check_rsp(tRW_T3T_CB* p_cb, NFC_HDR* p_msg_rsp) {
1358 uint8_t* p_t3t_rsp = (uint8_t*)(p_msg_rsp + 1) + p_msg_rsp->offset;
1359 tRW_READ_DATA evt_data;
1360 tNFC_STATUS nfc_status = NFC_STATUS_OK;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001361
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001362 /* Validate response from tag */
1363 if ((p_t3t_rsp[T3T_MSG_RSP_OFFSET_STATUS1] !=
1364 T3T_MSG_RSP_STATUS_OK) /* verify response status code */
1365 || (memcmp(p_cb->peer_nfcid2, &p_t3t_rsp[T3T_MSG_RSP_OFFSET_IDM],
1366 NCI_NFCID2_LEN) != 0)) /* verify response IDm */
1367 {
1368 nfc_status = NFC_STATUS_FAILED;
1369 GKI_freebuf(p_msg_rsp);
1370 } else if (p_t3t_rsp[T3T_MSG_RSP_OFFSET_RSPCODE] != T3T_MSG_OPC_CHECK_RSP) {
Ruchi Kandoi6767aec2017-09-26 09:46:26 -07001371 LOG(ERROR) << StringPrintf(
1372 "Response error: expecting rsp_code %02X, but got %02X",
1373 T3T_MSG_OPC_CHECK_RSP, p_t3t_rsp[T3T_MSG_RSP_OFFSET_RSPCODE]);
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001374 nfc_status = NFC_STATUS_FAILED;
1375 GKI_freebuf(p_msg_rsp);
1376 } else {
1377 /* Copy incoming data into buffer */
1378 p_msg_rsp->offset +=
1379 T3T_MSG_RSP_OFFSET_CHECK_DATA; /* Skip over t3t header */
1380 p_msg_rsp->len -= T3T_MSG_RSP_OFFSET_CHECK_DATA;
1381 evt_data.status = NFC_STATUS_OK;
1382 evt_data.p_data = p_msg_rsp;
Myles Watson1361d522017-09-26 13:39:54 -07001383 tRW_DATA rw_data;
1384 rw_data.data = evt_data;
1385 (*(rw_cb.p_cback))(RW_T3T_CHECK_EVT, &rw_data);
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001386 }
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001387
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001388 p_cb->rw_state = RW_T3T_STATE_IDLE;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001389
Myles Watson1361d522017-09-26 13:39:54 -07001390 tRW_DATA rw_data;
1391 rw_data.status = nfc_status;
1392 (*(rw_cb.p_cback))(RW_T3T_CHECK_CPLT_EVT, &rw_data);
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001393}
1394
1395/*****************************************************************************
1396**
1397** Function rw_t3t_act_handle_update_rsp
1398**
1399** Description Handle response to UPDATE command
1400**
1401** Returns Nothing
1402**
1403*****************************************************************************/
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001404void rw_t3t_act_handle_update_rsp(tRW_T3T_CB* p_cb, NFC_HDR* p_msg_rsp) {
1405 uint8_t* p_t3t_rsp = (uint8_t*)(p_msg_rsp + 1) + p_msg_rsp->offset;
1406 tRW_READ_DATA evt_data;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001407
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001408 /* Validate response from tag */
1409 if ((p_t3t_rsp[T3T_MSG_RSP_OFFSET_STATUS1] !=
1410 T3T_MSG_RSP_STATUS_OK) /* verify response status code */
1411 || (memcmp(p_cb->peer_nfcid2, &p_t3t_rsp[T3T_MSG_RSP_OFFSET_IDM],
1412 NCI_NFCID2_LEN) != 0)) /* verify response IDm */
1413 {
1414 evt_data.status = NFC_STATUS_FAILED;
1415 } else if (p_t3t_rsp[T3T_MSG_RSP_OFFSET_RSPCODE] != T3T_MSG_OPC_UPDATE_RSP) {
Ruchi Kandoi6767aec2017-09-26 09:46:26 -07001416 LOG(ERROR) << StringPrintf(
1417 "Response error: expecting rsp_code %02X, but got %02X",
1418 T3T_MSG_OPC_UPDATE_RSP, p_t3t_rsp[T3T_MSG_RSP_OFFSET_RSPCODE]);
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001419 evt_data.status = NFC_STATUS_FAILED;
1420 } else {
1421 /* Copy incoming data into buffer */
1422 evt_data.status = NFC_STATUS_OK;
1423 }
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001424
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001425 p_cb->rw_state = RW_T3T_STATE_IDLE;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001426
Myles Watson1361d522017-09-26 13:39:54 -07001427 tRW_DATA rw_data;
1428 rw_data.data = evt_data;
1429 (*(rw_cb.p_cback))(RW_T3T_UPDATE_CPLT_EVT, &rw_data);
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001430
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001431 GKI_freebuf(p_msg_rsp);
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001432}
1433
1434/*****************************************************************************
1435**
1436** Function rw_t3t_act_handle_raw_senddata_rsp
1437**
1438** Description Handle response to NDEF detection
1439**
1440** Returns Nothing
1441**
1442*****************************************************************************/
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001443void rw_t3t_act_handle_raw_senddata_rsp(tRW_T3T_CB* p_cb,
1444 tNFC_DATA_CEVT* p_data) {
1445 tRW_READ_DATA evt_data;
1446 NFC_HDR* p_pkt = p_data->p_data;
Evan Chua24be4f2013-11-13 15:30:16 -05001447
Ruchi Kandoi6767aec2017-09-26 09:46:26 -07001448 DLOG_IF(INFO, nfc_debug_enabled)
1449 << StringPrintf("RW T3T Raw Frame: Len [0x%X] Status [%s]", p_pkt->len,
1450 NFC_GetStatusName(p_data->status).c_str());
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001451
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001452 /* Copy incoming data into buffer */
1453 evt_data.status = p_data->status;
1454 evt_data.p_data = p_pkt;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001455
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001456 p_cb->rw_state = RW_T3T_STATE_IDLE;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001457
Myles Watson1361d522017-09-26 13:39:54 -07001458 tRW_DATA rw_data;
1459 rw_data.data = evt_data;
1460 (*(rw_cb.p_cback))(RW_T3T_RAW_FRAME_EVT, &rw_data);
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001461}
1462
1463/*****************************************************************************
1464**
1465** Function rw_t3t_act_handle_check_ndef_rsp
1466**
1467** Description Handle response to NDEF read segment
1468**
1469** Returns Nothing
1470**
1471*****************************************************************************/
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001472void rw_t3t_act_handle_check_ndef_rsp(tRW_T3T_CB* p_cb, NFC_HDR* p_msg_rsp) {
1473 bool check_complete = true;
1474 tNFC_STATUS nfc_status = NFC_STATUS_OK;
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001475 uint8_t* p_t3t_rsp = (uint8_t*)(p_msg_rsp + 1) + p_msg_rsp->offset;
1476 uint8_t rsp_num_bytes_rx;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001477
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001478 /* Validate response from tag */
1479 if ((p_t3t_rsp[T3T_MSG_RSP_OFFSET_STATUS1] !=
1480 T3T_MSG_RSP_STATUS_OK) /* verify response status code */
1481 || (memcmp(p_cb->peer_nfcid2, &p_t3t_rsp[T3T_MSG_RSP_OFFSET_IDM],
1482 NCI_NFCID2_LEN) != 0) /* verify response IDm */
1483 || (p_t3t_rsp[T3T_MSG_RSP_OFFSET_NUMBLOCKS] !=
1484 ((p_cb->ndef_rx_readlen + 15) >> 4))) /* verify length of response */
1485 {
Ruchi Kandoi6767aec2017-09-26 09:46:26 -07001486 LOG(ERROR) << StringPrintf(
1487 "Response error: bad status, nfcid2, or invalid len: %i %i",
1488 p_t3t_rsp[T3T_MSG_RSP_OFFSET_NUMBLOCKS],
1489 ((p_cb->ndef_rx_readlen + 15) >> 4));
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001490 nfc_status = NFC_STATUS_FAILED;
1491 GKI_freebuf(p_msg_rsp);
1492 } else if (p_t3t_rsp[T3T_MSG_RSP_OFFSET_RSPCODE] != T3T_MSG_OPC_CHECK_RSP) {
Ruchi Kandoi6767aec2017-09-26 09:46:26 -07001493 LOG(ERROR) << StringPrintf(
1494 "Response error: expecting rsp_code %02X, but got %02X",
1495 T3T_MSG_OPC_CHECK_RSP, p_t3t_rsp[T3T_MSG_RSP_OFFSET_RSPCODE]);
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001496 nfc_status = NFC_STATUS_FAILED;
1497 GKI_freebuf(p_msg_rsp);
1498 } else {
1499 /* Notify app of NDEF segment received */
1500 rsp_num_bytes_rx = p_t3t_rsp[T3T_MSG_RSP_OFFSET_NUMBLOCKS] *
1501 16; /* Number of bytes received, according to header */
1502 p_cb->ndef_rx_offset += p_cb->ndef_rx_readlen;
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001503 p_msg_rsp->offset +=
1504 T3T_MSG_RSP_OFFSET_CHECK_DATA; /* Skip over t3t header (point to block
1505 data) */
1506 p_msg_rsp->len -= T3T_MSG_RSP_OFFSET_CHECK_DATA;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001507
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001508 /* Verify that the bytes received is really the amount indicated in the
1509 * check-response header */
1510 if (rsp_num_bytes_rx > p_msg_rsp->len) {
Ruchi Kandoi6767aec2017-09-26 09:46:26 -07001511 LOG(ERROR) << StringPrintf(
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001512 "Response error: CHECK rsp header indicates %i bytes, but only "
1513 "received %i bytes",
1514 rsp_num_bytes_rx, p_msg_rsp->len);
1515 nfc_status = NFC_STATUS_FAILED;
1516 GKI_freebuf(p_msg_rsp);
1517 } else {
1518 /* If this is the the final block, then set len to reflect only valid
1519 * bytes (do not include padding to 16-byte boundary) */
1520 if ((p_cb->flags & RW_T3T_FL_IS_FINAL_NDEF_SEGMENT) &&
1521 (p_cb->ndef_attrib.ln & 0x000F)) {
1522 rsp_num_bytes_rx -= (16 - (p_cb->ndef_attrib.ln & 0x000F));
1523 }
1524
1525 p_msg_rsp->len = rsp_num_bytes_rx;
Myles Watson1361d522017-09-26 13:39:54 -07001526 tRW_DATA rw_data;
1527 rw_data.data.status = NFC_STATUS_OK;
1528 rw_data.data.p_data = p_msg_rsp;
1529 (*(rw_cb.p_cback))(RW_T3T_CHECK_EVT, &rw_data);
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001530
1531 /* Send CHECK cmd for next NDEF segment, if needed */
1532 if (!(p_cb->flags & RW_T3T_FL_IS_FINAL_NDEF_SEGMENT)) {
Ruchi Kandoi0c515ae2017-01-30 17:48:41 -08001533 nfc_status = rw_t3t_send_next_ndef_check_cmd(p_cb);
1534 if (nfc_status == NFC_STATUS_OK) {
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001535 /* Still getting more segments. Don't send RW_T3T_CHECK_CPLT_EVT yet
1536 */
1537 check_complete = false;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001538 }
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001539 }
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001540 }
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001541 }
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001542
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001543 /* Notify app of RW_T3T_CHECK_CPLT_EVT if entire NDEF has been read, or if
1544 * failure */
1545 if (check_complete) {
1546 p_cb->rw_state = RW_T3T_STATE_IDLE;
Myles Watson1361d522017-09-26 13:39:54 -07001547 tRW_DATA evt_data;
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001548 evt_data.status = nfc_status;
Myles Watson1361d522017-09-26 13:39:54 -07001549 (*(rw_cb.p_cback))(RW_T3T_CHECK_CPLT_EVT, &evt_data);
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001550 }
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001551}
1552
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001553/*****************************************************************************
1554**
1555** Function rw_t3t_act_handle_update_ndef_rsp
1556**
1557** Description Handle response to NDEF write segment
1558**
1559** Returns Nothing
1560**
1561*****************************************************************************/
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001562void rw_t3t_act_handle_update_ndef_rsp(tRW_T3T_CB* p_cb, NFC_HDR* p_msg_rsp) {
1563 bool update_complete = true;
1564 tNFC_STATUS nfc_status = NFC_STATUS_OK;
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001565 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 -08001566
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001567 /* Check nfcid2 and status of response */
1568 if ((p_t3t_rsp[T3T_MSG_RSP_OFFSET_STATUS1] !=
1569 T3T_MSG_RSP_STATUS_OK) /* verify response status code */
1570 || (memcmp(p_cb->peer_nfcid2, &p_t3t_rsp[T3T_MSG_RSP_OFFSET_IDM],
1571 NCI_NFCID2_LEN) != 0)) /* verify response IDm */
1572 {
1573 nfc_status = NFC_STATUS_FAILED;
1574 }
1575 /* Validate response opcode */
1576 else if (p_t3t_rsp[T3T_MSG_RSP_OFFSET_RSPCODE] != T3T_MSG_OPC_UPDATE_RSP) {
Ruchi Kandoi6767aec2017-09-26 09:46:26 -07001577 LOG(ERROR) << StringPrintf(
1578 "Response error: expecting rsp_code %02X, but got %02X",
1579 T3T_MSG_OPC_UPDATE_RSP, p_t3t_rsp[T3T_MSG_RSP_OFFSET_RSPCODE]);
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001580 nfc_status = NFC_STATUS_FAILED;
1581 }
1582 /* If this is response to final UPDATE, then update NDEF local size */
1583 else if (p_cb->flags & RW_T3T_FL_IS_FINAL_NDEF_SEGMENT) {
1584 /* If successful, update current NDEF size */
1585 p_cb->ndef_attrib.ln = p_cb->ndef_msg_len;
1586 }
1587 /* If any more NDEF bytes to update, then send next UPDATE command */
1588 else if (p_cb->ndef_msg_bytes_sent < p_cb->ndef_msg_len) {
1589 /* Send UPDATE command for next segment of NDEF */
Ruchi Kandoi0c515ae2017-01-30 17:48:41 -08001590 nfc_status = rw_t3t_send_next_ndef_update_cmd(p_cb);
1591 if (nfc_status == NFC_STATUS_OK) {
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001592 /* Wait for update response */
1593 update_complete = false;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001594 }
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001595 }
1596 /* Otherwise, no more NDEF bytes. Send final UPDATE for Attribute Information
1597 block */
1598 else {
1599 p_cb->flags |= RW_T3T_FL_IS_FINAL_NDEF_SEGMENT;
Ruchi Kandoi0c515ae2017-01-30 17:48:41 -08001600 nfc_status = rw_t3t_send_update_ndef_attribute_cmd(p_cb, false);
1601 if (nfc_status == NFC_STATUS_OK) {
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001602 /* Wait for update response */
1603 update_complete = false;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001604 }
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001605 }
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001606
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001607 /* If update is completed, then notify app */
1608 if (update_complete) {
1609 p_cb->rw_state = RW_T3T_STATE_IDLE;
Myles Watson1361d522017-09-26 13:39:54 -07001610 tRW_DATA evt_data;
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001611 evt_data.status = nfc_status;
Myles Watson1361d522017-09-26 13:39:54 -07001612 (*(rw_cb.p_cback))(RW_T3T_UPDATE_CPLT_EVT, &evt_data);
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001613 }
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001614
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001615 GKI_freebuf(p_msg_rsp);
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001616
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001617 return;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001618}
1619
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001620/*****************************************************************************
1621**
1622** Function rw_t3t_handle_get_sc_poll_rsp
1623**
1624** Description Handle POLL response for getting system codes
1625**
1626** Returns Nothing
1627**
1628*****************************************************************************/
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001629static void rw_t3t_handle_get_sc_poll_rsp(tRW_T3T_CB* p_cb, uint8_t nci_status,
1630 uint8_t num_responses,
1631 uint8_t sensf_res_buf_size,
1632 uint8_t* p_sensf_res_buf) {
1633 uint8_t* p;
1634 uint16_t sc;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001635
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001636 /* Get the system code from the response */
1637 if ((nci_status == NCI_STATUS_OK) && (num_responses > 0) &&
1638 (sensf_res_buf_size >=
1639 (RW_T3T_SENSF_RES_RD_OFFSET + RW_T3T_SENSF_RES_RD_LEN))) {
1640 p = &p_sensf_res_buf[RW_T3T_SENSF_RES_RD_OFFSET];
1641 BE_STREAM_TO_UINT16(sc, p);
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001642
Ruchi Kandoi6767aec2017-09-26 09:46:26 -07001643 DLOG_IF(INFO, nfc_debug_enabled)
1644 << StringPrintf("FeliCa detected (RD, system code %04X)", sc);
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001645 p_cb->system_codes[p_cb->num_system_codes++] = sc;
1646 }
Yoshinobu Ito721b3ab2016-08-02 14:41:33 +09001647
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001648 rw_t3t_handle_get_system_codes_cplt();
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001649}
1650
1651/*****************************************************************************
1652**
1653** Function rw_t3t_handle_ndef_detect_poll_rsp
1654**
1655** Description Handle POLL response for getting system codes
1656**
1657** Returns Nothing
1658**
1659*****************************************************************************/
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001660static void rw_t3t_handle_ndef_detect_poll_rsp(tRW_T3T_CB* p_cb,
1661 uint8_t nci_status,
Ruchi Kandoi9ba6d242017-10-13 16:07:01 -07001662 uint8_t num_responses) {
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001663 NFC_HDR* p_cmd_buf;
1664 uint8_t *p, *p_cmd_start;
1665 tRW_DATA evt_data;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001666
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001667 /* Validate response for NDEF poll */
1668 if ((nci_status == NCI_STATUS_OK) && (num_responses > 0)) {
1669 /* Tag responded for NDEF poll */
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001670
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001671 /* Read NDEF attribute block */
Ruchi Kandoi0c515ae2017-01-30 17:48:41 -08001672 p_cmd_buf = rw_t3t_get_cmd_buf();
1673 if (p_cmd_buf != NULL) {
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001674 /* Construct T3T message */
1675 p = p_cmd_start = (uint8_t*)(p_cmd_buf + 1) + p_cmd_buf->offset;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001676
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001677 /* Add CHECK opcode to message */
1678 UINT8_TO_STREAM(p, T3T_MSG_OPC_CHECK_CMD);
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001679
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001680 /* Add IDm to message */
1681 ARRAY_TO_STREAM(p, p_cb->peer_nfcid2, NCI_NFCID2_LEN);
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001682
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001683 /* Add Service code list */
1684 UINT8_TO_STREAM(p, 1); /* Number of services (only 1 service: NDEF) */
1685 UINT16_TO_STREAM(
1686 p, T3T_MSG_NDEF_SC_RO); /* Service code (little-endian format) */
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001687
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001688 /* Number of blocks */
1689 UINT8_TO_STREAM(
1690 p,
1691 1); /* Number of blocks (only 1 block: NDEF Attribute Information ) */
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001692
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001693 /* Block List element: the NDEF attribute information block (block 0) */
1694 UINT8_TO_STREAM(p, T3T_MSG_MASK_TWO_BYTE_BLOCK_DESC_FORMAT);
1695 UINT8_TO_STREAM(p, 0);
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001696
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001697 /* Calculate length of message */
1698 p_cmd_buf->len = (uint16_t)(p - p_cmd_start);
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001699
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001700 /* Send the T3T message */
Ruchi Kandoi0c515ae2017-01-30 17:48:41 -08001701 evt_data.status = rw_t3t_send_cmd(p_cb, RW_T3T_CMD_DETECT_NDEF, p_cmd_buf,
1702 rw_t3t_check_timeout(1));
1703 if (evt_data.status == NFC_STATUS_OK) {
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001704 /* CHECK command sent. Wait for response */
1705 return;
1706 }
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001707 }
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001708 nci_status = NFC_STATUS_FAILED;
1709 }
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001710
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001711 /* NDEF detection failed */
1712 p_cb->rw_state = RW_T3T_STATE_IDLE;
1713 evt_data.ndef.status = nci_status;
1714 evt_data.ndef.flags = RW_NDEF_FL_UNKNOWN;
1715 rw_t3t_update_ndef_flag(&evt_data.ndef.flags);
1716 (*(rw_cb.p_cback))(RW_T3T_NDEF_DETECT_EVT, &evt_data);
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001717}
1718
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001719/*****************************************************************************
1720**
1721** Function rw_t3t_update_block
1722**
Martijn Coenen5c65c3a2013-03-27 13:23:36 -07001723** Description Send UPDATE command for single block
1724** (for formatting/configuring read only)
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001725**
1726** Returns tNFC_STATUS
1727**
1728*****************************************************************************/
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001729tNFC_STATUS rw_t3t_update_block(tRW_T3T_CB* p_cb, uint8_t block_id,
1730 uint8_t* p_block_data) {
1731 uint8_t *p_dst, *p_cmd_start;
1732 NFC_HDR* p_cmd_buf;
1733 tNFC_STATUS status;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001734
Ruchi Kandoi0c515ae2017-01-30 17:48:41 -08001735 p_cmd_buf = rw_t3t_get_cmd_buf();
1736 if (p_cmd_buf != NULL) {
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001737 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 -08001738
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001739 /* Add UPDATE opcode to message */
1740 UINT8_TO_STREAM(p_dst, T3T_MSG_OPC_UPDATE_CMD);
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001741
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001742 /* Add IDm to message */
1743 ARRAY_TO_STREAM(p_dst, p_cb->peer_nfcid2, NCI_NFCID2_LEN);
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001744
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001745 /* Add Service code list */
1746 UINT8_TO_STREAM(p_dst, 1); /* Number of services (only 1 service: NDEF) */
1747 UINT16_TO_STREAM(
1748 p_dst, T3T_MSG_NDEF_SC_RW); /* Service code (little-endian format) */
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001749
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001750 /* Number of blocks */
1751 UINT8_TO_STREAM(p_dst, 1);
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001752
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001753 /* Add Block list element for MC */
1754 UINT8_TO_STREAM(p_dst, T3T_MSG_MASK_TWO_BYTE_BLOCK_DESC_FORMAT);
1755 UINT8_TO_STREAM(p_dst, block_id);
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001756
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001757 /* Copy MC data to UPDATE message */
1758 ARRAY_TO_STREAM(p_dst, p_block_data, T3T_MSG_BLOCKSIZE);
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001759
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001760 /* Calculate length of message */
1761 p_cmd_buf->len = (uint16_t)(p_dst - p_cmd_start);
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001762
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001763 /* Send the T3T message */
1764 status = rw_t3t_send_cmd(p_cb, p_cb->cur_cmd, p_cmd_buf,
1765 rw_t3t_update_timeout(1));
1766 } else {
1767 /* Unable to send UPDATE command */
1768 status = NFC_STATUS_NO_BUFFERS;
1769 }
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001770
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001771 return (status);
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001772}
1773
1774/*****************************************************************************
1775**
1776** Function rw_t3t_handle_fmt_poll_rsp
1777**
1778** Description Handle POLL response for formatting felica-lite
1779**
1780** Returns Nothing
1781**
1782*****************************************************************************/
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001783static void rw_t3t_handle_fmt_poll_rsp(tRW_T3T_CB* p_cb, uint8_t nci_status,
Ruchi Kandoi9ba6d242017-10-13 16:07:01 -07001784 uint8_t num_responses) {
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001785 tRW_DATA evt_data;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001786
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001787 evt_data.status = NFC_STATUS_OK;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001788
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001789 /* Validate response for poll response */
1790 if ((nci_status == NCI_STATUS_OK) && (num_responses > 0)) {
1791 /* Tag responded for Felica-Lite poll */
1792 /* Get MemoryControl block */
Ruchi Kandoi6767aec2017-09-26 09:46:26 -07001793 DLOG_IF(INFO, nfc_debug_enabled) << StringPrintf(
1794 "Felica-Lite tag detected...getting Memory Control block.");
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001795
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001796 p_cb->rw_substate = RW_T3T_FMT_SST_CHECK_MC_BLK;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001797
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001798 /* Send command to check Memory Configuration block */
1799 evt_data.status = rw_t3t_check_mc_block(p_cb);
1800 } else {
Ruchi Kandoi6767aec2017-09-26 09:46:26 -07001801 LOG(ERROR) << StringPrintf("Felica-Lite tag not detected");
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001802 evt_data.status = NFC_STATUS_FAILED;
1803 }
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001804
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001805 /* If error, notify upper layer */
1806 if (evt_data.status != NFC_STATUS_OK) {
1807 rw_t3t_format_cplt(evt_data.status);
1808 }
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001809}
1810
1811/*****************************************************************************
1812**
1813** Function rw_t3t_act_handle_fmt_rsp
1814**
1815** Description Handle response for formatting codes
1816**
1817** Returns Nothing
1818**
1819*****************************************************************************/
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001820void rw_t3t_act_handle_fmt_rsp(tRW_T3T_CB* p_cb, NFC_HDR* p_msg_rsp) {
1821 uint8_t* p_t3t_rsp = (uint8_t*)(p_msg_rsp + 1) + p_msg_rsp->offset;
1822 uint8_t* p_mc;
1823 tRW_DATA evt_data;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001824
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001825 evt_data.status = NFC_STATUS_OK;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001826
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001827 /* Check tags's response for reading MemoryControl block */
1828 if (p_cb->rw_substate == RW_T3T_FMT_SST_CHECK_MC_BLK) {
1829 /* Validate response opcode */
1830 if (p_t3t_rsp[T3T_MSG_RSP_OFFSET_RSPCODE] != T3T_MSG_OPC_CHECK_RSP) {
Ruchi Kandoi6767aec2017-09-26 09:46:26 -07001831 LOG(ERROR) << StringPrintf(
1832 "Response error: expecting rsp_code %02X, but got %02X",
1833 T3T_MSG_OPC_CHECK_RSP, p_t3t_rsp[T3T_MSG_RSP_OFFSET_RSPCODE]);
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001834 evt_data.status = NFC_STATUS_FAILED;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001835 }
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001836 /* Validate status code and NFCID2 response from tag */
1837 else if ((p_t3t_rsp[T3T_MSG_RSP_OFFSET_STATUS1] !=
1838 T3T_MSG_RSP_STATUS_OK) /* verify response status code */
1839 || (memcmp(p_cb->peer_nfcid2, &p_t3t_rsp[T3T_MSG_RSP_OFFSET_IDM],
1840 NCI_NFCID2_LEN) != 0)) /* verify response IDm */
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001841 {
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001842 evt_data.status = NFC_STATUS_FAILED;
Ruchi Kandoi32592772019-01-07 17:36:52 -08001843 } else if (p_msg_rsp->len <
1844 (T3T_MSG_RSP_OFFSET_CHECK_DATA + T3T_MSG_BLOCKSIZE)) {
1845 evt_data.status = NFC_STATUS_FAILED;
1846 android_errorWriteLog(0x534e4554, "120506143");
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001847 } else {
1848 /* Check if memory configuration (MC) block to see if SYS_OP=1 (NDEF
1849 * enabled) */
1850 p_mc = &p_t3t_rsp[T3T_MSG_RSP_OFFSET_CHECK_DATA]; /* Point to MC data of
1851 CHECK response */
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001852
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001853 if (p_mc[T3T_MSG_FELICALITE_MC_OFFSET_SYS_OP] != 0x01) {
1854 /* Tag is not currently enabled for NDEF. Indicate that we need to
1855 * update the MC block */
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001856
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001857 /* Set SYS_OP field to 0x01 (enable NDEF) */
1858 p_mc[T3T_MSG_FELICALITE_MC_OFFSET_SYS_OP] = 0x01;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001859
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001860 /* Set RF_PRM field to 0x07 (procedure of issuance) */
1861 p_mc[T3T_MSG_FELICALITE_MC_OFFSET_RF_PRM] = 0x07;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001862
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001863 /* Construct and send UPDATE message to write MC block */
1864 p_cb->rw_substate = RW_T3T_FMT_SST_UPDATE_MC_BLK;
1865 evt_data.status =
1866 rw_t3t_update_block(p_cb, T3T_MSG_FELICALITE_BLOCK_ID_MC, p_mc);
1867 } else {
1868 /* SYS_OP=1: ndef already enabled. Just need to update attribute
1869 * information block */
1870 p_cb->rw_substate = RW_T3T_FMT_SST_UPDATE_NDEF_ATTRIB;
1871 evt_data.status =
1872 rw_t3t_update_block(p_cb, 0, (uint8_t*)rw_t3t_default_attrib_info);
1873 }
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001874 }
1875
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001876 /* If error, notify upper layer */
1877 if (evt_data.status != NFC_STATUS_OK) {
1878 rw_t3t_format_cplt(evt_data.status);
1879 }
1880 } else if (p_cb->rw_substate == RW_T3T_FMT_SST_UPDATE_MC_BLK) {
1881 /* Validate response opcode */
1882 if ((p_t3t_rsp[T3T_MSG_RSP_OFFSET_RSPCODE] != T3T_MSG_OPC_UPDATE_RSP) ||
1883 (p_t3t_rsp[T3T_MSG_RSP_OFFSET_STATUS1] != T3T_MSG_RSP_STATUS_OK))
1884
1885 {
Ruchi Kandoi6767aec2017-09-26 09:46:26 -07001886 LOG(ERROR) << StringPrintf("Response error: rsp_code=%02X, status=%02X",
1887 p_t3t_rsp[T3T_MSG_RSP_OFFSET_RSPCODE],
1888 p_t3t_rsp[T3T_MSG_RSP_OFFSET_STATUS1]);
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001889 evt_data.status = NFC_STATUS_FAILED;
1890 } else {
1891 /* SYS_OP=1: ndef already enabled. Just need to update attribute
1892 * information block */
1893 p_cb->rw_substate = RW_T3T_FMT_SST_UPDATE_NDEF_ATTRIB;
1894 evt_data.status =
1895 rw_t3t_update_block(p_cb, 0, (uint8_t*)rw_t3t_default_attrib_info);
1896 }
1897
1898 /* If error, notify upper layer */
1899 if (evt_data.status != NFC_STATUS_OK) {
1900 rw_t3t_format_cplt(evt_data.status);
1901 }
1902 } else if (p_cb->rw_substate == RW_T3T_FMT_SST_UPDATE_NDEF_ATTRIB) {
1903 /* Validate response opcode */
1904 if ((p_t3t_rsp[T3T_MSG_RSP_OFFSET_RSPCODE] != T3T_MSG_OPC_UPDATE_RSP) ||
1905 (p_t3t_rsp[T3T_MSG_RSP_OFFSET_STATUS1] != T3T_MSG_RSP_STATUS_OK))
1906
1907 {
Ruchi Kandoi6767aec2017-09-26 09:46:26 -07001908 LOG(ERROR) << StringPrintf("Response error: rsp_code=%02X, status=%02X",
1909 p_t3t_rsp[T3T_MSG_RSP_OFFSET_RSPCODE],
1910 p_t3t_rsp[T3T_MSG_RSP_OFFSET_STATUS1]);
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001911 evt_data.status = NFC_STATUS_FAILED;
1912 }
1913
1914 rw_t3t_format_cplt(evt_data.status);
1915 }
1916
1917 GKI_freebuf(p_msg_rsp);
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001918}
1919
Martijn Coenen5c65c3a2013-03-27 13:23:36 -07001920/*****************************************************************************
1921**
1922** Function rw_t3t_handle_sro_poll_rsp
1923**
1924** Description Handle POLL response for configuring felica-lite read only
1925**
1926** Returns Nothing
1927**
1928*****************************************************************************/
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001929static void rw_t3t_handle_sro_poll_rsp(tRW_T3T_CB* p_cb, uint8_t nci_status,
Ruchi Kandoi9ba6d242017-10-13 16:07:01 -07001930 uint8_t num_responses) {
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001931 tRW_DATA evt_data;
1932 uint8_t rw_t3t_ndef_attrib_info[T3T_MSG_BLOCKSIZE];
1933 uint8_t* p;
1934 uint8_t tempU8;
1935 uint16_t checksum, i;
1936 uint32_t tempU32 = 0;
Martijn Coenen5c65c3a2013-03-27 13:23:36 -07001937
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001938 evt_data.status = NFC_STATUS_OK;
Martijn Coenen5c65c3a2013-03-27 13:23:36 -07001939
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001940 /* Validate response for poll response */
1941 if ((nci_status == NCI_STATUS_OK) && (num_responses > 0)) {
1942 /* Tag responded for Felica-Lite poll */
1943 if (p_cb->ndef_attrib.rwflag != T3T_MSG_NDEF_RWFLAG_RO) {
1944 /* First update attribute information block */
Ruchi Kandoi6767aec2017-09-26 09:46:26 -07001945 DLOG_IF(INFO, nfc_debug_enabled) << StringPrintf(
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001946 "Felica-Lite tag detected...update NDef attribution block.");
Martijn Coenen5c65c3a2013-03-27 13:23:36 -07001947
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001948 p_cb->rw_substate = RW_T3T_SRO_SST_UPDATE_NDEF_ATTRIB;
Martijn Coenen5c65c3a2013-03-27 13:23:36 -07001949
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001950 p = rw_t3t_ndef_attrib_info;
Martijn Coenen5c65c3a2013-03-27 13:23:36 -07001951
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001952 UINT8_TO_STREAM(p, p_cb->ndef_attrib.version);
Martijn Coenen5c65c3a2013-03-27 13:23:36 -07001953
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001954 /* Update NDEF info */
1955 UINT8_TO_STREAM(
1956 p, p_cb->ndef_attrib.nbr); /* NBr: number of blocks that can be read
1957 using one Check command */
1958 UINT8_TO_STREAM(p, p_cb->ndef_attrib.nbw); /* Nbw: number of blocks that
1959 can be written using one
1960 Update command */
1961 UINT16_TO_BE_STREAM(
1962 p, p_cb->ndef_attrib.nmaxb); /* Nmaxb: maximum number of blocks
1963 available for NDEF data */
1964 UINT32_TO_BE_STREAM(p, tempU32);
1965 UINT8_TO_STREAM(p,
1966 p_cb->ndef_attrib.writef); /* WriteFlag: 00h if writing
1967 data finished; 0Fh if
1968 writing data in progress */
1969 UINT8_TO_STREAM(p, 0x00); /* RWFlag: 00h NDEF is read-only */
Martijn Coenen5c65c3a2013-03-27 13:23:36 -07001970
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001971 tempU8 = (uint8_t)(p_cb->ndef_attrib.ln >> 16);
1972 /* Get length (3-byte, big-endian) */
1973 UINT8_TO_STREAM(p, tempU8); /* Ln: high-byte */
1974 UINT16_TO_BE_STREAM(p, p_cb->ndef_attrib.ln); /* Ln: lo-word */
Martijn Coenen5c65c3a2013-03-27 13:23:36 -07001975
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001976 /* Calculate and append Checksum */
1977 checksum = 0;
1978 for (i = 0; i < T3T_MSG_NDEF_ATTR_INFO_SIZE; i++) {
1979 checksum += rw_t3t_ndef_attrib_info[i];
1980 }
1981 UINT16_TO_BE_STREAM(p, checksum);
Martijn Coenen5c65c3a2013-03-27 13:23:36 -07001982
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001983 evt_data.status =
1984 rw_t3t_update_block(p_cb, 0, (uint8_t*)rw_t3t_ndef_attrib_info);
1985 } else if (p_cb->cur_cmd == RW_T3T_CMD_SET_READ_ONLY_HARD) {
1986 /* NDEF is already read only, Read and update MemoryControl block */
Ruchi Kandoi6767aec2017-09-26 09:46:26 -07001987 DLOG_IF(INFO, nfc_debug_enabled) << StringPrintf(
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001988 "Felica-Lite tag detected...getting Memory Control block.");
1989 p_cb->rw_substate = RW_T3T_SRO_SST_CHECK_MC_BLK;
Martijn Coenen5c65c3a2013-03-27 13:23:36 -07001990
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001991 /* Send command to check Memory Configuration block */
1992 evt_data.status = rw_t3t_check_mc_block(p_cb);
Martijn Coenen5c65c3a2013-03-27 13:23:36 -07001993 }
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001994 } else {
Ruchi Kandoi6767aec2017-09-26 09:46:26 -07001995 LOG(ERROR) << StringPrintf("Felica-Lite tag not detected");
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001996 evt_data.status = NFC_STATUS_FAILED;
1997 }
Martijn Coenen5c65c3a2013-03-27 13:23:36 -07001998
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001999 /* If error, notify upper layer */
2000 if (evt_data.status != NFC_STATUS_OK) {
2001 rw_t3t_set_readonly_cplt(evt_data.status);
2002 }
Martijn Coenen5c65c3a2013-03-27 13:23:36 -07002003}
2004
2005/*****************************************************************************
2006**
2007** Function rw_t3t_act_handle_sro_rsp
2008**
2009** Description Handle response for setting read only codes
2010**
2011** Returns Nothing
2012**
2013*****************************************************************************/
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002014void rw_t3t_act_handle_sro_rsp(tRW_T3T_CB* p_cb, NFC_HDR* p_msg_rsp) {
2015 uint8_t* p_t3t_rsp = (uint8_t*)(p_msg_rsp + 1) + p_msg_rsp->offset;
2016 uint8_t* p_mc;
2017 tRW_DATA evt_data;
Martijn Coenen5c65c3a2013-03-27 13:23:36 -07002018
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002019 evt_data.status = NFC_STATUS_OK;
Martijn Coenen5c65c3a2013-03-27 13:23:36 -07002020
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002021 if (p_cb->rw_substate == RW_T3T_SRO_SST_UPDATE_NDEF_ATTRIB) {
2022 /* Validate response opcode */
2023 if ((p_t3t_rsp[T3T_MSG_RSP_OFFSET_RSPCODE] != T3T_MSG_OPC_UPDATE_RSP) ||
2024 (p_t3t_rsp[T3T_MSG_RSP_OFFSET_STATUS1] != T3T_MSG_RSP_STATUS_OK))
2025
Martijn Coenen5c65c3a2013-03-27 13:23:36 -07002026 {
Ruchi Kandoi6767aec2017-09-26 09:46:26 -07002027 LOG(ERROR) << StringPrintf("Response error: rsp_code=%02X, status=%02X",
2028 p_t3t_rsp[T3T_MSG_RSP_OFFSET_RSPCODE],
2029 p_t3t_rsp[T3T_MSG_RSP_OFFSET_STATUS1]);
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002030 evt_data.status = NFC_STATUS_FAILED;
2031 } else {
2032 p_cb->ndef_attrib.rwflag = T3T_MSG_NDEF_RWFLAG_RO;
2033 if (p_cb->cur_cmd == RW_T3T_CMD_SET_READ_ONLY_HARD) {
2034 p_cb->rw_substate = RW_T3T_SRO_SST_CHECK_MC_BLK;
Martijn Coenen5c65c3a2013-03-27 13:23:36 -07002035
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002036 /* Send command to check Memory Configuration block */
2037 evt_data.status = rw_t3t_check_mc_block(p_cb);
2038 } else {
2039 rw_t3t_set_readonly_cplt(evt_data.status);
2040 }
Martijn Coenen5c65c3a2013-03-27 13:23:36 -07002041 }
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002042 } else if (p_cb->rw_substate == RW_T3T_SRO_SST_CHECK_MC_BLK) {
2043 /* Check tags's response for reading MemoryControl block, Validate response
2044 * opcode */
2045 if (p_t3t_rsp[T3T_MSG_RSP_OFFSET_RSPCODE] != T3T_MSG_OPC_CHECK_RSP) {
Ruchi Kandoi6767aec2017-09-26 09:46:26 -07002046 LOG(ERROR) << StringPrintf(
2047 "Response error: expecting rsp_code %02X, but got %02X",
2048 T3T_MSG_OPC_CHECK_RSP, p_t3t_rsp[T3T_MSG_RSP_OFFSET_RSPCODE]);
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002049 evt_data.status = NFC_STATUS_FAILED;
2050 }
2051 /* Validate status code and NFCID2 response from tag */
2052 else if ((p_t3t_rsp[T3T_MSG_RSP_OFFSET_STATUS1] !=
2053 T3T_MSG_RSP_STATUS_OK) /* verify response status code */
2054 || (memcmp(p_cb->peer_nfcid2, &p_t3t_rsp[T3T_MSG_RSP_OFFSET_IDM],
2055 NCI_NFCID2_LEN) != 0)) /* verify response IDm */
Martijn Coenen5c65c3a2013-03-27 13:23:36 -07002056 {
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002057 evt_data.status = NFC_STATUS_FAILED;
Ruchi Kandoi32592772019-01-07 17:36:52 -08002058 } else if (p_msg_rsp->len <
2059 (T3T_MSG_RSP_OFFSET_CHECK_DATA + T3T_MSG_BLOCKSIZE)) {
2060 evt_data.status = NFC_STATUS_FAILED;
2061 android_errorWriteLog(0x534e4554, "120506143");
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002062 } else {
2063 /* Check if memory configuration (MC) block to see if SYS_OP=1 (NDEF
2064 * enabled) */
2065 p_mc = &p_t3t_rsp[T3T_MSG_RSP_OFFSET_CHECK_DATA]; /* Point to MC data of
2066 CHECK response */
Martijn Coenen5c65c3a2013-03-27 13:23:36 -07002067
Ruchi Kandoi32592772019-01-07 17:36:52 -08002068 evt_data.status = NFC_STATUS_FAILED;
2069 if (p_mc[T3T_MSG_FELICALITE_MC_OFFSET_SYS_OP] == 0x01) {
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002070 /* Set MC_SP field with MC[0] = 0x00 & MC[1] = 0xC0 (Hardlock) to change
2071 * access permission from RW to RO */
2072 p_mc[T3T_MSG_FELICALITE_MC_OFFSET_MC_SP] = 0x00;
2073 /* Not changing the access permission of Subtraction Register and
2074 * MC[0:1] */
2075 p_mc[T3T_MSG_FELICALITE_MC_OFFSET_MC_SP + 1] = 0xC0;
Martijn Coenen5c65c3a2013-03-27 13:23:36 -07002076
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002077 /* Set RF_PRM field to 0x07 (procedure of issuance) */
2078 p_mc[T3T_MSG_FELICALITE_MC_OFFSET_RF_PRM] = 0x07;
Martijn Coenen5c65c3a2013-03-27 13:23:36 -07002079
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002080 /* Construct and send UPDATE message to write MC block */
2081 p_cb->rw_substate = RW_T3T_SRO_SST_UPDATE_MC_BLK;
2082 evt_data.status =
2083 rw_t3t_update_block(p_cb, T3T_MSG_FELICALITE_BLOCK_ID_MC, p_mc);
2084 }
Martijn Coenen5c65c3a2013-03-27 13:23:36 -07002085 }
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002086 } else if (p_cb->rw_substate == RW_T3T_SRO_SST_UPDATE_MC_BLK) {
2087 /* Validate response opcode */
2088 if ((p_t3t_rsp[T3T_MSG_RSP_OFFSET_RSPCODE] != T3T_MSG_OPC_UPDATE_RSP) ||
2089 (p_t3t_rsp[T3T_MSG_RSP_OFFSET_STATUS1] != T3T_MSG_RSP_STATUS_OK))
2090
Martijn Coenen5c65c3a2013-03-27 13:23:36 -07002091 {
Ruchi Kandoi6767aec2017-09-26 09:46:26 -07002092 LOG(ERROR) << StringPrintf("Response error: rsp_code=%02X, status=%02X",
2093 p_t3t_rsp[T3T_MSG_RSP_OFFSET_RSPCODE],
2094 p_t3t_rsp[T3T_MSG_RSP_OFFSET_STATUS1]);
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002095 evt_data.status = NFC_STATUS_FAILED;
2096 } else {
2097 rw_t3t_set_readonly_cplt(evt_data.status);
Martijn Coenen5c65c3a2013-03-27 13:23:36 -07002098 }
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002099 }
Martijn Coenen5c65c3a2013-03-27 13:23:36 -07002100
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002101 /* If error, notify upper layer */
2102 if (evt_data.status != NFC_STATUS_OK) {
2103 rw_t3t_set_readonly_cplt(evt_data.status);
2104 }
Martijn Coenen5c65c3a2013-03-27 13:23:36 -07002105
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002106 GKI_freebuf(p_msg_rsp);
Martijn Coenen5c65c3a2013-03-27 13:23:36 -07002107}
2108
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002109/*******************************************************************************
2110**
2111** Function rw_t3t_data_cback
2112**
2113** Description This callback function receives the data from NFCC.
2114**
2115** Returns none
2116**
2117*******************************************************************************/
Ruchi Kandoi9ba6d242017-10-13 16:07:01 -07002118void rw_t3t_data_cback(__attribute__((unused)) uint8_t conn_id,
2119 tNFC_DATA_CEVT* p_data) {
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002120 tRW_T3T_CB* p_cb = &rw_cb.tcb.t3t;
2121 NFC_HDR* p_msg = p_data->p_data;
2122 bool free_msg = false; /* if TRUE, free msg buffer before returning */
2123 uint8_t *p, sod;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002124
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002125 /* Stop rsponse timer */
2126 nfc_stop_quick_timer(&p_cb->timer);
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002127
Ruchi Kandoi303fec12016-12-14 13:22:38 -08002128#if (RW_STATS_INCLUDED == TRUE)
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002129 /* Update rx stats */
2130 rw_main_update_rx_stats(p_msg->len);
2131#endif /* RW_STATS_INCLUDED */
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002132
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002133 /* Check if we are expecting a response */
2134 if (p_cb->rw_state != RW_T3T_STATE_COMMAND_PENDING) {
2135 /*
2136 ** This must be raw frame response
2137 ** send raw frame to app with SoD
2138 */
2139 rw_t3t_act_handle_raw_senddata_rsp(p_cb, p_data);
2140 }
2141 /* Sanity check: verify msg len is big enough to contain t3t header */
2142 else if (p_msg->len < T3T_MSG_RSP_COMMON_HDR_LEN) {
Ruchi Kandoi6767aec2017-09-26 09:46:26 -07002143 LOG(ERROR) << StringPrintf(
2144 "T3T: invalid Type3 Tag Message (invalid len: %i)", p_msg->len);
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002145 free_msg = true;
2146
2147 rw_t3t_process_frame_error();
2148 } else {
2149 /* Check for RF frame error */
2150 p = (uint8_t*)(p_msg + 1) + p_msg->offset;
2151 sod = p[0];
2152 if (p[sod] != NCI_STATUS_OK) {
Ruchi Kandoi6767aec2017-09-26 09:46:26 -07002153 LOG(ERROR) << StringPrintf("T3T: rf frame error (crc status=%i)", p[sod]);
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002154 GKI_freebuf(p_msg);
2155
2156 rw_t3t_process_frame_error();
2157 return;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002158 }
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002159
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002160 /* Skip over SoD */
2161 p_msg->offset++;
2162 p_msg->len--;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002163
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002164 /* Get response code */
2165 switch (p_cb->cur_cmd) {
2166 case RW_T3T_CMD_DETECT_NDEF:
2167 rw_t3t_act_handle_ndef_detect_rsp(p_cb, p_msg);
2168 break;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002169
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002170 case RW_T3T_CMD_CHECK_NDEF:
2171 rw_t3t_act_handle_check_ndef_rsp(p_cb, p_msg);
2172 break;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002173
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002174 case RW_T3T_CMD_UPDATE_NDEF:
2175 rw_t3t_act_handle_update_ndef_rsp(p_cb, p_msg);
2176 break;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002177
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002178 case RW_T3T_CMD_CHECK:
2179 rw_t3t_act_handle_check_rsp(p_cb, p_msg);
2180 break;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002181
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002182 case RW_T3T_CMD_UPDATE:
2183 rw_t3t_act_handle_update_rsp(p_cb, p_msg);
2184 break;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002185
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002186 case RW_T3T_CMD_SEND_RAW_FRAME:
2187 rw_t3t_act_handle_raw_senddata_rsp(p_cb, p_data);
2188 break;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002189
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002190 case RW_T3T_CMD_FORMAT:
2191 rw_t3t_act_handle_fmt_rsp(p_cb, p_msg);
2192 break;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002193
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002194 case RW_T3T_CMD_SET_READ_ONLY_SOFT:
2195 case RW_T3T_CMD_SET_READ_ONLY_HARD:
2196 rw_t3t_act_handle_sro_rsp(p_cb, p_msg);
2197 break;
Martijn Coenen5c65c3a2013-03-27 13:23:36 -07002198
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002199 default:
2200 GKI_freebuf(p_msg);
2201 break;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002202 }
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002203 }
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002204
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002205 if (free_msg) {
2206 GKI_freebuf(p_msg);
2207 }
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002208}
2209
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002210/*******************************************************************************
2211**
2212** Function rw_t3t_conn_cback
2213**
2214** Description This callback function receives the events/data from NFCC.
2215**
2216** Returns none
2217**
2218*******************************************************************************/
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002219void rw_t3t_conn_cback(uint8_t conn_id, tNFC_CONN_EVT event,
2220 tNFC_CONN* p_data) {
2221 tRW_T3T_CB* p_cb = &rw_cb.tcb.t3t;
Ruchi Kandoi6767aec2017-09-26 09:46:26 -07002222 DLOG_IF(INFO, nfc_debug_enabled) << StringPrintf(
2223 "rw_t3t_conn_cback: conn_id=%i, evt=0x%02x", conn_id, event);
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002224
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002225 /* Only handle NFC_RF_CONN_ID conn_id */
2226 if (conn_id != NFC_RF_CONN_ID) {
2227 return;
2228 }
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002229
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002230 switch (event) {
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002231 case NFC_DEACTIVATE_CEVT:
Ruchi Kandoi9ba6d242017-10-13 16:07:01 -07002232 rw_t3t_unselect();
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002233 break;
2234
2235 case NFC_DATA_CEVT: /* check for status in tNFC_CONN */
2236 if ((p_data != NULL) && ((p_data->data.status == NFC_STATUS_OK) ||
2237 (p_data->data.status == NFC_STATUS_CONTINUE))) {
2238 rw_t3t_data_cback(conn_id, &(p_data->data));
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002239 break;
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002240 } else if (p_data->data.p_data != NULL) {
2241 /* Free the response buffer in case of error response */
2242 GKI_freebuf((NFC_HDR*)(p_data->data.p_data));
2243 p_data->data.p_data = NULL;
2244 }
2245 /* Data event with error status...fall through to NFC_ERROR_CEVT case */
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002246
2247 case NFC_ERROR_CEVT:
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002248 nfc_stop_quick_timer(&p_cb->timer);
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002249
Ruchi Kandoi303fec12016-12-14 13:22:38 -08002250#if (RW_STATS_INCLUDED == TRUE)
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002251 rw_main_update_trans_error_stats();
2252#endif /* RW_STATS_INCLUDED */
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002253
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002254 if (event == NFC_ERROR_CEVT)
2255 rw_t3t_process_error(NFC_STATUS_TIMEOUT);
2256 else if (p_data)
2257 rw_t3t_process_error(p_data->status);
2258 break;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002259
2260 default:
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002261 break;
2262 }
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002263}
2264
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002265/*******************************************************************************
2266**
Sherry Smith818b56e2014-05-14 16:46:32 -07002267** Function rw_t3t_mrti_to_a_b
2268**
2269** Description Converts the given MRTI (Maximum Response Time Information)
2270** to the base to calculate timeout value.
2271** (The timeout value is a + b * number_blocks)
2272**
2273** Returns NFC_STATUS_OK
2274**
2275*******************************************************************************/
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002276static void rw_t3t_mrti_to_a_b(uint8_t mrti, uint32_t* p_a, uint32_t* p_b) {
2277 uint8_t a, b, e;
Sherry Smith818b56e2014-05-14 16:46:32 -07002278
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002279 a = (mrti & 0x7) + 1; /* A is bit 0 ~ bit 2 */
2280 mrti >>= 3;
2281 b = (mrti & 0x7) + 1; /* B is bit 3 ~ bit 5 */
2282 mrti >>= 3;
2283 e = mrti & 0x3; /* E is bit 6 ~ bit 7 */
2284 *p_a = rw_t3t_mrti_base[e] * a; /* (A+1) * base (i.e T/t3t * 4^E) */
2285 *p_b = rw_t3t_mrti_base[e] * b; /* (B+1) * base (i.e T/t3t * 4^E) */
Sherry Smith818b56e2014-05-14 16:46:32 -07002286}
2287
Sherry Smith818b56e2014-05-14 16:46:32 -07002288/*******************************************************************************
2289**
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002290** Function rw_t3t_select
2291**
2292** Description Called by NFC manager when a Type3 tag has been activated
2293**
2294** Returns NFC_STATUS_OK
2295**
2296*******************************************************************************/
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002297tNFC_STATUS rw_t3t_select(uint8_t peer_nfcid2[NCI_RF_F_UID_LEN],
2298 uint8_t mrti_check, uint8_t mrti_update) {
2299 tRW_T3T_CB* p_cb = &rw_cb.tcb.t3t;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002300
Ruchi Kandoi6767aec2017-09-26 09:46:26 -07002301 DLOG_IF(INFO, nfc_debug_enabled) << __func__;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002302
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002303 memcpy(p_cb->peer_nfcid2, peer_nfcid2,
2304 NCI_NFCID2_LEN); /* Store tag's NFCID2 */
2305 p_cb->ndef_attrib.status =
2306 NFC_STATUS_NOT_INITIALIZED; /* Indicate that NDEF detection has not been
2307 performed yet */
2308 p_cb->rw_state = RW_T3T_STATE_IDLE;
2309 p_cb->flags = 0;
2310 rw_t3t_mrti_to_a_b(mrti_check, &p_cb->check_tout_a, &p_cb->check_tout_b);
2311 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 -08002312
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002313 /* Alloc cmd buf for retransmissions */
2314 if (p_cb->p_cur_cmd_buf == NULL) {
Ruchi Kandoi0c515ae2017-01-30 17:48:41 -08002315 p_cb->p_cur_cmd_buf = (NFC_HDR*)GKI_getpoolbuf(NFC_RW_POOL_ID);
2316 if (p_cb->p_cur_cmd_buf == NULL) {
Ruchi Kandoi6767aec2017-09-26 09:46:26 -07002317 LOG(ERROR) << StringPrintf(
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002318 "rw_t3t_select: unable to allocate buffer for retransmission");
2319 p_cb->rw_state = RW_T3T_STATE_NOT_ACTIVATED;
2320 return (NFC_STATUS_FAILED);
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002321 }
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002322 }
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002323
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002324 NFC_SetStaticRfCback(rw_t3t_conn_cback);
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002325
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002326 return NFC_STATUS_OK;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002327}
2328
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002329/*******************************************************************************
2330**
2331** Function rw_t3t_unselect
2332**
2333** Description Called by NFC manager when a Type3 tag has been de-activated
2334**
2335** Returns NFC_STATUS_OK
2336**
2337*******************************************************************************/
Ruchi Kandoi9ba6d242017-10-13 16:07:01 -07002338static tNFC_STATUS rw_t3t_unselect() {
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002339 tRW_T3T_CB* p_cb = &rw_cb.tcb.t3t;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002340
Ruchi Kandoi303fec12016-12-14 13:22:38 -08002341#if (RW_STATS_INCLUDED == TRUE)
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002342 /* Display stats */
2343 rw_main_log_stats();
2344#endif /* RW_STATS_INCLUDED */
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002345
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002346 /* Stop t3t timer (if started) */
2347 nfc_stop_quick_timer(&p_cb->timer);
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002348
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002349 /* Free cmd buf for retransmissions */
2350 if (p_cb->p_cur_cmd_buf) {
2351 GKI_freebuf(p_cb->p_cur_cmd_buf);
2352 p_cb->p_cur_cmd_buf = NULL;
2353 }
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002354
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002355 p_cb->rw_state = RW_T3T_STATE_NOT_ACTIVATED;
2356 NFC_SetStaticRfCback(NULL);
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002357
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002358 return NFC_STATUS_OK;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002359}
2360
Evan Chua24be4f2013-11-13 15:30:16 -05002361/*******************************************************************************
2362**
2363** Function rw_t3t_update_ndef_flag
2364**
2365** Description set additional NDEF Flags for felica lite tag
2366**
2367** Returns updated NDEF Flag value
2368**
2369*******************************************************************************/
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002370static void rw_t3t_update_ndef_flag(uint8_t* p_flag) {
2371 tRW_T3T_CB* p_cb = &rw_cb.tcb.t3t;
2372 uint8_t xx;
Evan Chua24be4f2013-11-13 15:30:16 -05002373
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002374 for (xx = 0; xx < p_cb->num_system_codes; xx++) {
2375 if (p_cb->system_codes[xx] == T3T_SYSTEM_CODE_FELICA_LITE) {
2376 *p_flag &= ~RW_NDEF_FL_UNKNOWN;
2377 *p_flag |= (RW_NDEF_FL_SUPPORTED | RW_NDEF_FL_FORMATABLE);
2378 break;
Evan Chua24be4f2013-11-13 15:30:16 -05002379 }
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002380 }
Evan Chua24be4f2013-11-13 15:30:16 -05002381}
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002382
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002383/*******************************************************************************
2384**
2385** Function rw_t3t_cmd_str
2386**
2387** Description Converts cmd_id to command string for logging
2388**
2389** Returns command string
2390**
2391*******************************************************************************/
Ruchi Kandoi7dab0e52017-08-03 13:09:49 -07002392static std::string rw_t3t_cmd_str(uint8_t cmd_id) {
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002393 switch (cmd_id) {
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002394 case RW_T3T_CMD_DETECT_NDEF:
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002395 return "RW_T3T_CMD_DETECT_NDEF";
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002396 case RW_T3T_CMD_CHECK_NDEF:
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002397 return "RW_T3T_CMD_CHECK_NDEF";
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002398 case RW_T3T_CMD_UPDATE_NDEF:
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002399 return "RW_T3T_CMD_UPDATE_NDEF";
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002400 case RW_T3T_CMD_CHECK:
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002401 return "RW_T3T_CMD_CHECK";
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002402 case RW_T3T_CMD_UPDATE:
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002403 return "RW_T3T_CMD_UPDATE";
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002404 case RW_T3T_CMD_SEND_RAW_FRAME:
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002405 return "RW_T3T_CMD_SEND_RAW_FRAME";
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002406 case RW_T3T_CMD_GET_SYSTEM_CODES:
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002407 return "RW_T3T_CMD_GET_SYSTEM_CODES";
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002408 default:
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002409 return "Unknown";
2410 }
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002411}
2412
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002413/*******************************************************************************
2414**
2415** Function rw_t3t_state_str
2416**
2417** Description Converts state_id to command string for logging
2418**
2419** Returns command string
2420**
2421*******************************************************************************/
Ruchi Kandoi7dab0e52017-08-03 13:09:49 -07002422static std::string rw_t3t_state_str(uint8_t state_id) {
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002423 switch (state_id) {
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002424 case RW_T3T_STATE_NOT_ACTIVATED:
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002425 return "RW_T3T_STATE_NOT_ACTIVATED";
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002426 case RW_T3T_STATE_IDLE:
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002427 return "RW_T3T_STATE_IDLE";
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002428 case RW_T3T_STATE_COMMAND_PENDING:
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002429 return "RW_T3T_STATE_COMMAND_PENDING";
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002430 default:
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002431 return "Unknown";
2432 }
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002433}
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002434
2435/*****************************************************************************
2436** Type3 Tag API Functions
2437*****************************************************************************/
2438
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002439/*****************************************************************************
2440**
2441** Function RW_T3tDetectNDef
2442**
2443** Description
2444** This function is used to perform NDEF detection on a Type 3 tag, and
2445** retrieve the tag's NDEF attribute information (block 0).
2446**
2447** Before using this API, the application must call RW_SelectTagType to
2448** indicate that a Type 3 tag has been activated, and to provide the
2449** tag's Manufacture ID (IDm) .
2450**
2451** Returns
2452** NFC_STATUS_OK: ndef detection procedure started
2453** NFC_STATUS_NO_BUFFERS: unable to allocate a buffer for this operation
2454** NFC_STATUS_FAILED: other error
2455**
2456*****************************************************************************/
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002457tNFC_STATUS RW_T3tDetectNDef(void) {
2458 tRW_T3T_CB* p_cb = &rw_cb.tcb.t3t;
2459 tNFC_STATUS retval = NFC_STATUS_OK;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002460
Ruchi Kandoi6767aec2017-09-26 09:46:26 -07002461 DLOG_IF(INFO, nfc_debug_enabled) << __func__;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002462
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002463 /* Check if we are in valid state to handle this API */
2464 if (p_cb->rw_state != RW_T3T_STATE_IDLE) {
Ruchi Kandoi6767aec2017-09-26 09:46:26 -07002465 LOG(ERROR) << StringPrintf("Error: invalid state to handle API (0x%x)",
2466 p_cb->rw_state);
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002467 return (NFC_STATUS_FAILED);
2468 }
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002469
Ruchi Kandoi0c515ae2017-01-30 17:48:41 -08002470 retval = (tNFC_STATUS)nci_snd_t3t_polling(T3T_SYSTEM_CODE_NDEF, 0, 0);
2471 if (retval == NCI_STATUS_OK) {
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002472 p_cb->cur_cmd = RW_T3T_CMD_DETECT_NDEF;
2473 p_cb->cur_tout = RW_T3T_DEFAULT_CMD_TIMEOUT_TICKS;
2474 p_cb->cur_poll_rc = 0;
2475 p_cb->rw_state = RW_T3T_STATE_COMMAND_PENDING;
2476 p_cb->flags |= RW_T3T_FL_W4_NDEF_DETECT_POLL_RSP;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002477
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002478 /* start timer for waiting for responses */
2479 rw_t3t_start_poll_timer(p_cb);
2480 }
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002481
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002482 return (retval);
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002483}
2484
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002485/*****************************************************************************
2486**
2487** Function RW_T3tCheckNDef
2488**
2489** Description
2490** Retrieve NDEF contents from a Type3 tag.
2491**
2492** The RW_T3T_CHECK_EVT event is used to notify the application for each
Ruchi Kandoi552f2b72017-01-28 16:22:55 -08002493** segment of NDEF data received. The RW_T3T_CHECK_CPLT_EVT event is used
2494** to notify the application all segments have been received.
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002495**
2496** Before using this API, the RW_T3tDetectNDef function must be called to
2497** verify that the tag contains NDEF data, and to retrieve the NDEF
2498** attributes.
2499**
2500** Internally, this command will be separated into multiple Tag 3 Check
2501** commands (if necessary) - depending on the tag's Nbr (max number of
2502** blocks per read) attribute.
2503**
2504** Returns
2505** NFC_STATUS_OK: check command started
2506** NFC_STATUS_NO_BUFFERS: unable to allocate a buffer for this operation
2507** NFC_STATUS_FAILED: other error
2508**
2509*****************************************************************************/
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002510tNFC_STATUS RW_T3tCheckNDef(void) {
2511 tNFC_STATUS retval = NFC_STATUS_OK;
2512 tRW_T3T_CB* p_cb = &rw_cb.tcb.t3t;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002513
Ruchi Kandoi6767aec2017-09-26 09:46:26 -07002514 DLOG_IF(INFO, nfc_debug_enabled) << __func__;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002515
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002516 /* Check if we are in valid state to handle this API */
2517 if (p_cb->rw_state != RW_T3T_STATE_IDLE) {
Ruchi Kandoi6767aec2017-09-26 09:46:26 -07002518 LOG(ERROR) << StringPrintf("Error: invalid state to handle API (0x%x)",
2519 p_cb->rw_state);
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002520 return (NFC_STATUS_FAILED);
2521 } else if (p_cb->ndef_attrib.status !=
2522 NFC_STATUS_OK) /* NDEF detection not performed yet? */
2523 {
Ruchi Kandoi6767aec2017-09-26 09:46:26 -07002524 LOG(ERROR) << StringPrintf("Error: NDEF detection not performed yet");
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002525 return (NFC_STATUS_NOT_INITIALIZED);
2526 } else if (p_cb->ndef_attrib.ln == 0) {
Ruchi Kandoi6767aec2017-09-26 09:46:26 -07002527 LOG(ERROR) << StringPrintf("Type 3 tag contains empty NDEF message");
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002528 return (NFC_STATUS_FAILED);
2529 }
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002530
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002531 /* Check number of blocks needed for this update */
2532 p_cb->flags &= ~RW_T3T_FL_IS_FINAL_NDEF_SEGMENT;
2533 p_cb->ndef_rx_offset = 0;
2534 retval = rw_t3t_send_next_ndef_check_cmd(p_cb);
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002535
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002536 return (retval);
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002537}
2538
2539/*****************************************************************************
2540**
2541** Function RW_T3tUpdateNDef
2542**
2543** Description
2544** Write NDEF contents to a Type3 tag.
2545**
2546** The RW_T3T_UPDATE_CPLT_EVT callback event will be used to notify the
2547** application of the response.
2548**
2549** Before using this API, the RW_T3tDetectNDef function must be called to
2550** verify that the tag contains NDEF data, and to retrieve the NDEF
2551** attributes.
2552**
2553** Internally, this command will be separated into multiple Tag 3 Update
2554** commands (if necessary) - depending on the tag's Nbw (max number of
2555** blocks per write) attribute.
2556**
2557** Returns
2558** NFC_STATUS_OK: check command started
2559** NFC_STATUS_NO_BUFFERS: unable to allocate a buffer for this operation
2560** NFC_STATUS_REFUSED: tag is read-only
2561** NFC_STATUS_BUFFER_FULL: len exceeds tag's maximum size
2562** NFC_STATUS_FAILED: other error
2563**
2564*****************************************************************************/
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002565tNFC_STATUS RW_T3tUpdateNDef(uint32_t len, uint8_t* p_data) {
2566 tNFC_STATUS retval = NFC_STATUS_OK;
2567 tRW_T3T_CB* p_cb = &rw_cb.tcb.t3t;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002568
Ruchi Kandoi6767aec2017-09-26 09:46:26 -07002569 DLOG_IF(INFO, nfc_debug_enabled)
2570 << StringPrintf("RW_T3tUpdateNDef (len=%i)", len);
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002571
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002572 /* Check if we are in valid state to handle this API */
2573 if (p_cb->rw_state != RW_T3T_STATE_IDLE) {
Ruchi Kandoi6767aec2017-09-26 09:46:26 -07002574 LOG(ERROR) << StringPrintf("Error: invalid state to handle API (0x%x)",
2575 p_cb->rw_state);
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002576 return (NFC_STATUS_FAILED);
2577 } else if (p_cb->ndef_attrib.status !=
2578 NFC_STATUS_OK) /* NDEF detection not performed yet? */
2579 {
Ruchi Kandoi6767aec2017-09-26 09:46:26 -07002580 LOG(ERROR) << StringPrintf("Error: NDEF detection not performed yet");
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002581 return (NFC_STATUS_NOT_INITIALIZED);
2582 } else if (len > (((uint32_t)p_cb->ndef_attrib.nmaxb) *
2583 16)) /* Len exceed's tag's NDEF memory? */
2584 {
2585 return (NFC_STATUS_BUFFER_FULL);
2586 } else if (p_cb->ndef_attrib.rwflag ==
2587 T3T_MSG_NDEF_RWFLAG_RO) /* Tag's NDEF memory is read-only? */
2588 {
2589 return (NFC_STATUS_REFUSED);
2590 }
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002591
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002592 /* Check number of blocks needed for this update */
2593 p_cb->flags &= ~RW_T3T_FL_IS_FINAL_NDEF_SEGMENT;
2594 p_cb->ndef_msg_bytes_sent = 0;
2595 p_cb->ndef_msg_len = len;
2596 p_cb->ndef_msg = p_data;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002597
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002598 /* Send initial UPDATE command for NDEF Attribute Info */
2599 retval = rw_t3t_send_update_ndef_attribute_cmd(p_cb, true);
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002600
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002601 return (retval);
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002602}
2603
2604/*****************************************************************************
2605**
2606** Function RW_T3tCheck
2607**
2608** Description
2609** Read (non-NDEF) contents from a Type3 tag.
2610**
2611** The RW_READ_EVT event is used to notify the application for each
2612** segment of NDEF data received. The RW_READ_CPLT_EVT event is used to
2613** notify the application all segments have been received.
2614**
2615** Before using this API, the application must call RW_SelectTagType to
2616** indicate that a Type 3 tag has been activated, and to provide the
2617** tag's Manufacture ID (IDm) .
2618**
2619** Returns
2620** NFC_STATUS_OK: check command started
2621** NFC_STATUS_NO_BUFFERS: unable to allocate a buffer for this operation
2622** NFC_STATUS_FAILED: other error
2623**
2624*****************************************************************************/
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002625tNFC_STATUS RW_T3tCheck(uint8_t num_blocks, tT3T_BLOCK_DESC* t3t_blocks) {
2626 tNFC_STATUS retval = NFC_STATUS_OK;
2627 tRW_T3T_CB* p_cb = &rw_cb.tcb.t3t;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002628
Ruchi Kandoi6767aec2017-09-26 09:46:26 -07002629 DLOG_IF(INFO, nfc_debug_enabled)
2630 << StringPrintf("RW_T3tCheck (num_blocks = %i)", num_blocks);
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002631
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002632 /* Check if we are in valid state to handle this API */
2633 if (p_cb->rw_state != RW_T3T_STATE_IDLE) {
Ruchi Kandoi6767aec2017-09-26 09:46:26 -07002634 LOG(ERROR) << StringPrintf("Error: invalid state to handle API (0x%x)",
2635 p_cb->rw_state);
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002636 return (NFC_STATUS_FAILED);
2637 }
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002638
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002639 /* Send the CHECK command */
2640 retval = rw_t3t_send_check_cmd(p_cb, num_blocks, t3t_blocks);
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002641
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002642 return (retval);
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002643}
2644
2645/*****************************************************************************
2646**
2647** Function RW_T3tUpdate
2648**
2649** Description
2650** Write (non-NDEF) contents to a Type3 tag.
2651**
2652** The RW_WRITE_CPLT_EVT event is used to notify the application all
2653** segments have been received.
2654**
2655** Before using this API, the application must call RW_SelectTagType to
2656** indicate that a Type 3 tag has been activated, and to provide the tag's
2657** Manufacture ID (IDm) .
2658**
2659** Returns
2660** NFC_STATUS_OK: check command started
2661** NFC_STATUS_NO_BUFFERS: unable to allocate a buffer for this operation
2662** NFC_STATUS_FAILED: other error
2663**
2664*****************************************************************************/
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002665tNFC_STATUS RW_T3tUpdate(uint8_t num_blocks, tT3T_BLOCK_DESC* t3t_blocks,
2666 uint8_t* p_data) {
2667 tNFC_STATUS retval = NFC_STATUS_OK;
2668 tRW_T3T_CB* p_cb = &rw_cb.tcb.t3t;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002669
Ruchi Kandoi6767aec2017-09-26 09:46:26 -07002670 DLOG_IF(INFO, nfc_debug_enabled)
2671 << StringPrintf("RW_T3tUpdate (num_blocks = %i)", num_blocks);
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002672
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002673 /* Check if we are in valid state to handle this API */
2674 if (p_cb->rw_state != RW_T3T_STATE_IDLE) {
Ruchi Kandoi6767aec2017-09-26 09:46:26 -07002675 LOG(ERROR) << StringPrintf("Error: invalid state to handle API (0x%x)",
2676 p_cb->rw_state);
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002677 return (NFC_STATUS_FAILED);
2678 }
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002679
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002680 /* Send the UPDATE command */
2681 retval = rw_t3t_send_update_cmd(p_cb, num_blocks, t3t_blocks, p_data);
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002682
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002683 return (retval);
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002684}
2685
2686/*****************************************************************************
2687**
2688** Function RW_T3tPresenceCheck
2689**
2690** Description
2691** Check if the tag is still in the field.
2692**
2693** The RW_T3T_PRESENCE_CHECK_EVT w/ status is used to indicate presence
2694** or non-presence.
2695**
2696** Returns
2697** NFC_STATUS_OK, if raw data frame sent
2698** NFC_STATUS_NO_BUFFERS: unable to allocate a buffer for this operation
2699** NFC_STATUS_FAILED: other error
2700**
2701*****************************************************************************/
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002702tNFC_STATUS RW_T3tPresenceCheck(void) {
2703 tNFC_STATUS retval = NFC_STATUS_OK;
2704 tRW_DATA evt_data;
2705 tRW_CB* p_rw_cb = &rw_cb;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002706
Ruchi Kandoi6767aec2017-09-26 09:46:26 -07002707 DLOG_IF(INFO, nfc_debug_enabled) << __func__;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002708
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002709 /* If RW_SelectTagType was not called (no conn_callback) return failure */
2710 if (!(p_rw_cb->p_cback)) {
2711 retval = NFC_STATUS_FAILED;
2712 }
2713 /* If we are not activated, then RW_T3T_PRESENCE_CHECK_EVT status=FAIL */
2714 else if (p_rw_cb->tcb.t3t.rw_state == RW_T3T_STATE_NOT_ACTIVATED) {
2715 evt_data.status = NFC_STATUS_FAILED;
2716 (*p_rw_cb->p_cback)(RW_T3T_PRESENCE_CHECK_EVT, &evt_data);
2717 }
2718 /* If command is pending */
2719 else if (p_rw_cb->tcb.t3t.rw_state == RW_T3T_STATE_COMMAND_PENDING) {
2720 /* If already performing presence check, return error */
2721 if (p_rw_cb->tcb.t3t.flags & RW_T3T_FL_W4_PRESENCE_CHECK_POLL_RSP) {
Ruchi Kandoi6767aec2017-09-26 09:46:26 -07002722 DLOG_IF(INFO, nfc_debug_enabled)
2723 << StringPrintf("RW_T3tPresenceCheck already in progress");
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002724 retval = NFC_STATUS_FAILED;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002725 }
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002726 /* If busy with any other command, assume that the tag is present */
2727 else {
2728 evt_data.status = NFC_STATUS_OK;
2729 (*p_rw_cb->p_cback)(RW_T3T_PRESENCE_CHECK_EVT, &evt_data);
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002730 }
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002731 } else {
2732 /* IDLE state: send POLL command */
Ruchi Kandoi0c515ae2017-01-30 17:48:41 -08002733 retval = (tNFC_STATUS)nci_snd_t3t_polling(0xFFFF, T3T_POLL_RC_SC, 0);
2734 if (retval == NCI_STATUS_OK) {
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002735 p_rw_cb->tcb.t3t.flags |= RW_T3T_FL_W4_PRESENCE_CHECK_POLL_RSP;
2736 p_rw_cb->tcb.t3t.rw_state = RW_T3T_STATE_COMMAND_PENDING;
2737 p_rw_cb->tcb.t3t.cur_poll_rc = 0;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002738
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002739 /* start timer for waiting for responses */
2740 rw_t3t_start_poll_timer(&p_rw_cb->tcb.t3t);
2741 } else {
Ruchi Kandoi6767aec2017-09-26 09:46:26 -07002742 DLOG_IF(INFO, nfc_debug_enabled) << StringPrintf(
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002743 "RW_T3tPresenceCheck error sending NCI_RF_T3T_POLLING cmd (status = "
2744 "0x%0x)",
2745 retval);
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002746 }
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002747 }
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002748
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002749 return (retval);
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002750}
2751
2752/*****************************************************************************
2753**
2754** Function RW_T3tPoll
2755**
2756** Description
2757** Send POLL command
2758**
2759** Returns
2760** NFC_STATUS_OK, if raw data frame sent
2761** NFC_STATUS_NO_BUFFERS: unable to allocate a buffer for this operation
2762** NFC_STATUS_FAILED: other error
2763**
2764*****************************************************************************/
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002765tNFC_STATUS RW_T3tPoll(uint16_t system_code, tT3T_POLL_RC rc, uint8_t tsn) {
2766 tNFC_STATUS retval = NFC_STATUS_OK;
2767 tRW_T3T_CB* p_cb = &rw_cb.tcb.t3t;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002768
Ruchi Kandoi6767aec2017-09-26 09:46:26 -07002769 DLOG_IF(INFO, nfc_debug_enabled) << __func__;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002770
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002771 /* Check if we are in valid state to handle this API */
2772 if (p_cb->rw_state != RW_T3T_STATE_IDLE) {
Ruchi Kandoi6767aec2017-09-26 09:46:26 -07002773 LOG(ERROR) << StringPrintf("Error: invalid state to handle API (0x%x)",
2774 p_cb->rw_state);
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002775 return (NFC_STATUS_FAILED);
2776 }
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002777
Ruchi Kandoi0c515ae2017-01-30 17:48:41 -08002778 retval = (tNFC_STATUS)nci_snd_t3t_polling(system_code, (uint8_t)rc, tsn);
2779 if (retval == NCI_STATUS_OK) {
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002780 /* start timer for waiting for responses */
2781 p_cb->cur_poll_rc = rc;
2782 p_cb->rw_state = RW_T3T_STATE_COMMAND_PENDING;
2783 rw_t3t_start_poll_timer(p_cb);
2784 }
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002785
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002786 return (retval);
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002787}
2788
2789/*****************************************************************************
2790**
2791** Function RW_T3tSendRawFrame
2792**
2793** Description
2794** This function is called to send a raw data frame to the peer device.
2795** When type 3 tag receives response from peer, the callback function
2796** will be called with a RW_T3T_RAW_FRAME_EVT [Table 6].
2797**
2798** Before using this API, the application must call RW_SelectTagType to
2799** indicate that a Type 3 tag has been activated.
2800**
2801** The raw frame should be a properly formatted Type 3 tag message.
2802**
2803** Returns
2804** NFC_STATUS_OK, if raw data frame sent
2805** NFC_STATUS_NO_BUFFERS: unable to allocate a buffer for this operation
2806** NFC_STATUS_FAILED: other error
2807**
2808*****************************************************************************/
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002809tNFC_STATUS RW_T3tSendRawFrame(uint16_t len, uint8_t* p_data) {
2810 tNFC_STATUS retval = NFC_STATUS_OK;
2811 tRW_T3T_CB* p_cb = &rw_cb.tcb.t3t;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002812
Ruchi Kandoi6767aec2017-09-26 09:46:26 -07002813 DLOG_IF(INFO, nfc_debug_enabled)
2814 << StringPrintf("RW_T3tSendRawFrame (len = %i)", len);
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002815
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002816 /* Check if we are in valid state to handle this API */
2817 if (p_cb->rw_state != RW_T3T_STATE_IDLE) {
Ruchi Kandoi6767aec2017-09-26 09:46:26 -07002818 LOG(ERROR) << StringPrintf("Error: invalid state to handle API (0x%x)",
2819 p_cb->rw_state);
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002820 return (NFC_STATUS_FAILED);
2821 }
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002822
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002823 /* Send the UPDATE command */
2824 retval = rw_t3t_send_raw_frame(p_cb, len, p_data);
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002825
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002826 return (retval);
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002827}
2828
2829/*****************************************************************************
2830**
2831** Function RW_T3tGetSystemCodes
2832**
2833** Description
2834** Get systems codes supported by the activated tag:
Yoshinobu Ito721b3ab2016-08-02 14:41:33 +09002835** Poll for wildcard (FFFF, RC=1):
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002836**
2837** Before using this API, the application must call RW_SelectTagType to
2838** indicate that a Type 3 tag has been activated.
2839**
2840** Returns
2841** NFC_STATUS_OK, if raw data frame sent
2842** NFC_STATUS_NO_BUFFERS: unable to allocate a buffer for this operation
2843** NFC_STATUS_FAILED: other error
2844**
2845*****************************************************************************/
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002846tNFC_STATUS RW_T3tGetSystemCodes(void) {
2847 tNFC_STATUS retval = NFC_STATUS_OK;
2848 tRW_T3T_CB* p_cb = &rw_cb.tcb.t3t;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002849
Ruchi Kandoi6767aec2017-09-26 09:46:26 -07002850 DLOG_IF(INFO, nfc_debug_enabled) << __func__;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002851
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002852 /* Check if we are in valid state to handle this API */
2853 if (p_cb->rw_state != RW_T3T_STATE_IDLE) {
Ruchi Kandoi6767aec2017-09-26 09:46:26 -07002854 LOG(ERROR) << StringPrintf("Error: invalid state to handle API (0x%x)",
2855 p_cb->rw_state);
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002856 return (NFC_STATUS_FAILED);
2857 } else {
Ruchi Kandoi0c515ae2017-01-30 17:48:41 -08002858 retval = (tNFC_STATUS)nci_snd_t3t_polling(0xFFFF, T3T_POLL_RC_SC, 0);
2859 if (retval == NCI_STATUS_OK) {
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002860 p_cb->cur_cmd = RW_T3T_CMD_GET_SYSTEM_CODES;
2861 p_cb->cur_tout = RW_T3T_DEFAULT_CMD_TIMEOUT_TICKS;
2862 p_cb->cur_poll_rc = T3T_POLL_RC_SC;
2863 p_cb->rw_state = RW_T3T_STATE_COMMAND_PENDING;
2864 p_cb->flags |= RW_T3T_FL_W4_GET_SC_POLL_RSP;
2865 p_cb->num_system_codes = 0;
2866
2867 /* start timer for waiting for responses */
2868 rw_t3t_start_poll_timer(p_cb);
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002869 }
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002870 }
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002871
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002872 return (retval);
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002873}
2874
2875/*****************************************************************************
2876**
2877** Function RW_T3tFormatNDef
2878**
2879** Description
2880** Format a type-3 tag for NDEF.
2881**
2882** Only Felica-Lite tags are supported by this API. The
2883** RW_T3T_FORMAT_CPLT_EVT is used to notify the status of the operation.
2884**
2885** Returns
2886** NFC_STATUS_OK: ndef detection procedure started
2887** NFC_STATUS_NO_BUFFERS: unable to allocate a buffer for this operation
2888** NFC_STATUS_FAILED: other error
2889**
2890*****************************************************************************/
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002891tNFC_STATUS RW_T3tFormatNDef(void) {
2892 tNFC_STATUS retval = NFC_STATUS_OK;
2893 tRW_T3T_CB* p_cb = &rw_cb.tcb.t3t;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002894
Ruchi Kandoi6767aec2017-09-26 09:46:26 -07002895 DLOG_IF(INFO, nfc_debug_enabled) << __func__;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002896
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002897 /* Check if we are in valid state to handle this API */
2898 if (p_cb->rw_state != RW_T3T_STATE_IDLE) {
Ruchi Kandoi6767aec2017-09-26 09:46:26 -07002899 LOG(ERROR) << StringPrintf("Error: invalid state to handle API (0x%x)",
2900 p_cb->rw_state);
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002901 return (NFC_STATUS_FAILED);
2902 } else {
2903 /* Poll tag, to see if Felica-Lite system is supported */
Ruchi Kandoi0c515ae2017-01-30 17:48:41 -08002904 retval = (tNFC_STATUS)nci_snd_t3t_polling(T3T_SYSTEM_CODE_FELICA_LITE,
2905 T3T_POLL_RC_SC, 0);
2906 if (retval == NCI_STATUS_OK) {
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002907 p_cb->cur_cmd = RW_T3T_CMD_FORMAT;
2908 p_cb->cur_tout = RW_T3T_DEFAULT_CMD_TIMEOUT_TICKS;
2909 p_cb->cur_poll_rc = T3T_POLL_RC_SC;
2910 p_cb->rw_state = RW_T3T_STATE_COMMAND_PENDING;
2911 p_cb->rw_substate = RW_T3T_FMT_SST_POLL_FELICA_LITE;
2912 p_cb->flags |= RW_T3T_FL_W4_FMT_FELICA_LITE_POLL_RSP;
2913
2914 /* start timer for waiting for responses */
2915 rw_t3t_start_poll_timer(p_cb);
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002916 }
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002917 }
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002918
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002919 return (retval);
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002920}
Martijn Coenen5c65c3a2013-03-27 13:23:36 -07002921
2922/*****************************************************************************
2923**
2924** Function RW_T3tSetReadOnly
2925**
2926** Description This function performs NDEF read-only procedure
2927** Note: Only Felica-Lite tags are supported by this API.
2928** RW_T3tDetectNDef() must be called before using this
2929**
2930** The RW_T3T_SET_READ_ONLY_CPLT_EVT event will be returned.
2931**
2932** Returns NFC_STATUS_OK if success
2933** NFC_STATUS_FAILED if T3T is busy or other error
2934**
2935*****************************************************************************/
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002936tNFC_STATUS RW_T3tSetReadOnly(bool b_hard_lock) {
2937 tNFC_STATUS retval = NFC_STATUS_OK;
2938 tRW_T3T_CB* p_cb = &rw_cb.tcb.t3t;
2939 tRW_DATA evt_data;
Martijn Coenen5c65c3a2013-03-27 13:23:36 -07002940
Ruchi Kandoi6767aec2017-09-26 09:46:26 -07002941 DLOG_IF(INFO, nfc_debug_enabled)
2942 << StringPrintf("b_hard_lock=%d", b_hard_lock);
Martijn Coenen5c65c3a2013-03-27 13:23:36 -07002943
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002944 /* Check if we are in valid state to handle this API */
2945 if (p_cb->rw_state != RW_T3T_STATE_IDLE) {
Ruchi Kandoi6767aec2017-09-26 09:46:26 -07002946 LOG(ERROR) << StringPrintf("Error: invalid state to handle API (0x%x)",
2947 p_cb->rw_state);
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002948 return (NFC_STATUS_FAILED);
2949 }
Martijn Coenen5c65c3a2013-03-27 13:23:36 -07002950
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002951 if (p_cb->ndef_attrib.status !=
2952 NFC_STATUS_OK) /* NDEF detection not performed yet? */
2953 {
Ruchi Kandoi6767aec2017-09-26 09:46:26 -07002954 LOG(ERROR) << StringPrintf("Error: NDEF detection not performed yet");
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002955 return (NFC_STATUS_NOT_INITIALIZED);
2956 }
Martijn Coenen5c65c3a2013-03-27 13:23:36 -07002957
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002958 if ((!b_hard_lock) &&
2959 (p_cb->ndef_attrib.rwflag ==
2960 T3T_MSG_NDEF_RWFLAG_RO)) /* Tag's NDEF memory is read-only already */
2961 {
2962 evt_data.status = NFC_STATUS_OK;
2963 (*(rw_cb.p_cback))(RW_T3T_SET_READ_ONLY_CPLT_EVT, &evt_data);
Martijn Coenen5c65c3a2013-03-27 13:23:36 -07002964 return (retval);
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002965 } else {
2966 /* Poll tag, to see if Felica-Lite system is supported */
Ruchi Kandoi0c515ae2017-01-30 17:48:41 -08002967 retval = (tNFC_STATUS)nci_snd_t3t_polling(T3T_SYSTEM_CODE_FELICA_LITE,
2968 T3T_POLL_RC_SC, 0);
2969 if (retval == NCI_STATUS_OK) {
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002970 if (b_hard_lock)
2971 p_cb->cur_cmd = RW_T3T_CMD_SET_READ_ONLY_HARD;
2972 else
2973 p_cb->cur_cmd = RW_T3T_CMD_SET_READ_ONLY_SOFT;
2974 p_cb->cur_tout = RW_T3T_DEFAULT_CMD_TIMEOUT_TICKS;
2975 p_cb->cur_poll_rc = T3T_POLL_RC_SC;
2976 p_cb->rw_state = RW_T3T_STATE_COMMAND_PENDING;
2977 p_cb->rw_substate = RW_T3T_SRO_SST_POLL_FELICA_LITE;
2978 p_cb->flags |= RW_T3T_FL_W4_SRO_FELICA_LITE_POLL_RSP;
2979
2980 /* start timer for waiting for responses */
2981 rw_t3t_start_poll_timer(p_cb);
2982 }
2983 }
2984 return (retval);
Martijn Coenen5c65c3a2013-03-27 13:23:36 -07002985}