blob: 81307303b10fd1ef0c1a9f77c6d29545b80c461c [file] [log] [blame]
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001/******************************************************************************
2 *
Evan Chue9629ba2014-01-31 11:18:47 -05003 * Copyright (C) 2010-2014 Broadcom Corporation
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08004 *
5 * Licensed under the Apache License, Version 2.0 (the "License");
6 * you may not use this file except in compliance with the License.
7 * You may obtain a copy of the License at:
8 *
9 * http://www.apache.org/licenses/LICENSE-2.0
10 *
11 * Unless required by applicable law or agreed to in writing, software
12 * distributed under the License is distributed on an "AS IS" BASIS,
13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 * See the License for the specific language governing permissions and
15 * limitations under the License.
16 *
17 ******************************************************************************/
18
19/******************************************************************************
20 *
21 * This file contains the implementation for Type 3 tag in Reader/Writer
22 * mode.
23 *
24 ******************************************************************************/
25#include <string.h>
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -080026
Andre Eisenbach8a4edf62017-11-20 14:51:11 -080027#include <android-base/stringprintf.h>
28#include <base/logging.h>
Ruchi Kandoi32592772019-01-07 17:36:52 -080029#include <log/log.h>
Andre Eisenbach8a4edf62017-11-20 14:51:11 -080030
31#include "nfc_target.h"
32
33#include "bt_types.h"
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -080034#include "nci_hmsgs.h"
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -080035#include "nfc_api.h"
36#include "nfc_int.h"
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -080037#include "rw_api.h"
38#include "rw_int.h"
Andre Eisenbach8a4edf62017-11-20 14:51:11 -080039#include "trace_api.h"
40
41using android::base::StringPrintf;
42
43extern bool nfc_debug_enabled;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -080044
45/* Definitions for constructing t3t command messages */
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -080046#define RW_T3T_FL_PADDING 0x01 /* Padding needed for last NDEF block */
47/* Maximum number of NDEF blocks updates that can fit into one command (when all
48 * block-numbers are < 256) */
Ruchi Kandoi46e6e282017-01-30 14:26:10 -080049#define RW_T3T_MAX_NDEF_BLOCKS_PER_UPDATE_1_BYTE_FORMAT (13)
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -080050/* Maximum number of NDEF blocks updates that can fit into one command (when all
51 * block-numbers are >= 256) */
Ruchi Kandoi46e6e282017-01-30 14:26:10 -080052#define RW_T3T_MAX_NDEF_BLOCKS_PER_UPDATE_2_BYTE_FORMAT (12)
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -080053
54/* Definitions for SENSF_RES */
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -080055/* Offset of RD in SENSF_RES from NCI_POLL NTF (includes 1 byte SENSF_RES
56 * length) */
Ruchi Kandoi46e6e282017-01-30 14:26:10 -080057#define RW_T3T_SENSF_RES_RD_OFFSET 17
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -080058#define RW_T3T_SENSF_RES_RD_LEN 2 /* Size of RD in SENSF_RES */
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -080059
60/* Timeout definitions for commands */
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -080061#define RW_T3T_POLL_CMD_TIMEOUT_TICKS \
62 ((RW_T3T_TOUT_RESP * 2 * QUICK_TIMER_TICKS_PER_SEC) / 1000)
63#define RW_T3T_DEFAULT_CMD_TIMEOUT_TICKS \
64 ((RW_T3T_TOUT_RESP * QUICK_TIMER_TICKS_PER_SEC) / 1000)
65#define RW_T3T_RAW_FRAME_CMD_TIMEOUT_TICKS \
66 (RW_T3T_DEFAULT_CMD_TIMEOUT_TICKS * 4)
67#define RW_T3T_MIN_TIMEOUT_TICKS 10
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -080068
69/* Macro to extract major version from NDEF version byte */
Chih-Hung Hsieh7ac6a7c2017-08-01 14:26:16 -070070#define T3T_GET_MAJOR_VERSION(ver) ((ver) >> 4)
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -080071
72/* Enumeration of API commands */
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -080073enum {
74 RW_T3T_CMD_DETECT_NDEF,
75 RW_T3T_CMD_CHECK_NDEF,
76 RW_T3T_CMD_UPDATE_NDEF,
77 RW_T3T_CMD_CHECK,
78 RW_T3T_CMD_UPDATE,
79 RW_T3T_CMD_SEND_RAW_FRAME,
80 RW_T3T_CMD_GET_SYSTEM_CODES,
81 RW_T3T_CMD_FORMAT,
82 RW_T3T_CMD_SET_READ_ONLY_SOFT,
83 RW_T3T_CMD_SET_READ_ONLY_HARD,
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -080084
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -080085 RW_T3T_CMD_MAX
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -080086};
87
88/* RW_CBACK events corresponding to API comands */
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -080089const uint8_t rw_t3t_api_res_evt[RW_T3T_CMD_MAX] = {
90 RW_T3T_NDEF_DETECT_EVT, /* RW_T3T_CMD_DETECT_NDEF */
91 RW_T3T_CHECK_CPLT_EVT, /* RW_T3T_CMD_CHECK_NDEF */
92 RW_T3T_UPDATE_CPLT_EVT, /* RW_T3T_CMD_UPDATE_NDEF */
93 RW_T3T_CHECK_CPLT_EVT, /* RW_T3T_CMD_CHECK */
94 RW_T3T_UPDATE_CPLT_EVT, /* RW_T3T_CMD_UPDATE */
95 RW_T3T_RAW_FRAME_EVT, /* RW_T3T_CMD_SEND_RAW_FRAME */
96 RW_T3T_GET_SYSTEM_CODES_EVT, /* RW_T3T_CMD_GET_SYSTEM_CODES */
97 RW_T3T_FORMAT_CPLT_EVT, /* RW_T3T_CMD_FORMAT */
98 RW_T3T_SET_READ_ONLY_CPLT_EVT /* RW_T3T_CMD_SET_READ_ONLY */
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -080099};
100
101/* States */
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800102enum {
103 RW_T3T_STATE_NOT_ACTIVATED,
104 RW_T3T_STATE_IDLE,
105 RW_T3T_STATE_COMMAND_PENDING
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800106};
107
108/* Sub-states */
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800109enum {
110 /* Sub states for formatting Felica-Lite */
111 RW_T3T_FMT_SST_POLL_FELICA_LITE, /* Waiting for POLL Felica-Lite response (for
112 formatting) */
113 RW_T3T_FMT_SST_CHECK_MC_BLK, /* Waiting for Felica-Lite MC (MemoryControl)
114 block-read to complete */
115 RW_T3T_FMT_SST_UPDATE_MC_BLK, /* Waiting for Felica-Lite MC (MemoryControl)
116 block-write to complete */
117 RW_T3T_FMT_SST_UPDATE_NDEF_ATTRIB, /* Waiting for NDEF attribute block-write
118 to complete */
Martijn Coenen5c65c3a2013-03-27 13:23:36 -0700119
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800120 /* Sub states for setting Felica-Lite read only */
121 RW_T3T_SRO_SST_POLL_FELICA_LITE, /* Waiting for POLL Felica-Lite response (for
122 setting read only) */
123 RW_T3T_SRO_SST_UPDATE_NDEF_ATTRIB, /* Waiting for NDEF attribute block-write
124 to complete */
125 RW_T3T_SRO_SST_CHECK_MC_BLK, /* Waiting for Felica-Lite MC (MemoryControl)
126 block-read to complete */
127 RW_T3T_SRO_SST_UPDATE_MC_BLK /* Waiting for Felica-Lite MC (MemoryControl)
128 block-write to complete */
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800129};
130
Ruchi Kandoi7dab0e52017-08-03 13:09:49 -0700131static std::string rw_t3t_cmd_str(uint8_t cmd_id);
132static std::string rw_t3t_state_str(uint8_t state_id);
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800133
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800134/* Local static functions */
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800135static void rw_t3t_update_ndef_flag(uint8_t* p_flag);
Ruchi Kandoi9ba6d242017-10-13 16:07:01 -0700136static tNFC_STATUS rw_t3t_unselect();
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800137static NFC_HDR* rw_t3t_get_cmd_buf(void);
138static tNFC_STATUS rw_t3t_send_to_lower(NFC_HDR* p_msg);
139static void rw_t3t_handle_get_system_codes_cplt(void);
140static void rw_t3t_handle_get_sc_poll_rsp(tRW_T3T_CB* p_cb, uint8_t nci_status,
141 uint8_t num_responses,
142 uint8_t sensf_res_buf_size,
143 uint8_t* p_sensf_res_buf);
144static void rw_t3t_handle_ndef_detect_poll_rsp(tRW_T3T_CB* p_cb,
145 uint8_t nci_status,
Ruchi Kandoi9ba6d242017-10-13 16:07:01 -0700146 uint8_t num_responses);
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800147static void rw_t3t_handle_fmt_poll_rsp(tRW_T3T_CB* p_cb, uint8_t nci_status,
Ruchi Kandoi9ba6d242017-10-13 16:07:01 -0700148 uint8_t num_responses);
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800149static void rw_t3t_handle_sro_poll_rsp(tRW_T3T_CB* p_cb, uint8_t nci_status,
Ruchi Kandoi9ba6d242017-10-13 16:07:01 -0700150 uint8_t num_responses);
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800151
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800152/* Default NDEF attribute information block (used when formatting Felica-Lite
153 * tags) */
Ruchi Kandoi46e6e282017-01-30 14:26:10 -0800154/* NBr (max block reads per cmd)*/
155#define RW_T3T_DEFAULT_FELICALITE_NBR 4
156/* NBw (max block write per cmd)*/
157#define RW_T3T_DEFAULT_FELICALITE_NBW 1
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800158#define RW_T3T_DEFAULT_FELICALITE_NMAXB (T3T_FELICALITE_NMAXB)
159#define RW_T3T_DEFAULT_FELICALITE_ATTRIB_INFO_CHECKSUM \
160 ((T3T_MSG_NDEF_VERSION + RW_T3T_DEFAULT_FELICALITE_NBR + \
161 RW_T3T_DEFAULT_FELICALITE_NBW + (RW_T3T_DEFAULT_FELICALITE_NMAXB >> 8) + \
162 (RW_T3T_DEFAULT_FELICALITE_NMAXB & 0xFF) + T3T_MSG_NDEF_WRITEF_OFF + \
163 T3T_MSG_NDEF_RWFLAG_RW) & \
164 0xFFFF)
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800165
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800166const uint8_t rw_t3t_default_attrib_info[T3T_MSG_BLOCKSIZE] = {
167 T3T_MSG_NDEF_VERSION, /* Ver */
168 RW_T3T_DEFAULT_FELICALITE_NBR, /* NBr (max block reads per cmd)*/
169 RW_T3T_DEFAULT_FELICALITE_NBW, /* NBw (max block write per cmd)*/
170 (RW_T3T_DEFAULT_FELICALITE_NMAXB >> 8), /* Nmaxb (max size in blocks) */
171 (RW_T3T_DEFAULT_FELICALITE_NMAXB & 0xFF), /* Nmaxb (max size in blocks) */
Love Khannac76c21d2017-02-27 18:20:08 +0530172 0, 0, 0, 0, /* Unused */
173 T3T_MSG_NDEF_WRITEF_OFF, /* WriteF */
174 T3T_MSG_NDEF_RWFLAG_RW, /* RW Flag */
175 0, 0, 0, /* Ln (current size in bytes) */
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800176
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800177 (RW_T3T_DEFAULT_FELICALITE_ATTRIB_INFO_CHECKSUM >>
178 8), /* checksum (high-byte) */
179 (RW_T3T_DEFAULT_FELICALITE_ATTRIB_INFO_CHECKSUM &
180 0xFF) /* checksum (low-byte) */
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800181
182};
183
Sherry Smith818b56e2014-05-14 16:46:32 -0700184/* This is (T/t3t * 4^E) , E is the index of the array. The unit is .0001 ms */
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800185static const uint32_t rw_t3t_mrti_base[] = {302, 1208, 4832, 19328};
Sherry Smith818b56e2014-05-14 16:46:32 -0700186
187/*******************************************************************************
188**
189** Function rw_t3t_check_timeout
190**
191** Description The timeout value is a + b * number_blocks)
192**
193** Returns timeout value in ticks
194**
195*******************************************************************************/
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800196static uint32_t rw_t3t_check_timeout(uint16_t num_blocks) {
197 tRW_T3T_CB* p_cb = &rw_cb.tcb.t3t;
198 uint32_t timeout;
199 uint32_t extra;
Sherry Smith67fe6102014-06-02 11:01:54 -0700200
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800201 timeout = (p_cb->check_tout_a + num_blocks * p_cb->check_tout_b) *
202 QUICK_TIMER_TICKS_PER_SEC / 1000000;
203 /* allow some extra time for driver */
204 extra = (timeout / 10) + RW_T3T_MIN_TIMEOUT_TICKS;
205 timeout += extra;
Sherry Smith67fe6102014-06-02 11:01:54 -0700206
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800207 return timeout;
Sherry Smith818b56e2014-05-14 16:46:32 -0700208}
209
210/*******************************************************************************
211**
212** Function rw_t3t_update_timeout
213**
214** Description The timeout value is a + b * number_blocks)
215**
216** Returns timeout value in ticks
217**
218*******************************************************************************/
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800219static uint32_t rw_t3t_update_timeout(uint16_t num_blocks) {
220 tRW_T3T_CB* p_cb = &rw_cb.tcb.t3t;
221 uint32_t timeout;
222 uint32_t extra;
Sherry Smith67fe6102014-06-02 11:01:54 -0700223
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800224 timeout = (p_cb->update_tout_a + num_blocks * p_cb->update_tout_b) *
225 QUICK_TIMER_TICKS_PER_SEC / 1000000;
226 /* allow some extra time for driver */
227 extra = (timeout / 10) + RW_T3T_MIN_TIMEOUT_TICKS;
228 timeout += extra;
Sherry Smith67fe6102014-06-02 11:01:54 -0700229
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800230 return timeout;
Sherry Smith818b56e2014-05-14 16:46:32 -0700231}
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800232/*******************************************************************************
233**
234** Function rw_t3t_process_error
235**
236** Description Process error (timeout or CRC error)
237**
238** Returns none
239**
240*******************************************************************************/
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800241void rw_t3t_process_error(tNFC_STATUS status) {
242 tRW_T3T_CB* p_cb = &rw_cb.tcb.t3t;
243 uint8_t evt;
244 tRW_DATA evt_data;
245 NFC_HDR* p_cmd_buf;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800246
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800247 if (p_cb->rw_state == RW_T3T_STATE_COMMAND_PENDING) {
248 if (p_cb->cur_cmd == RW_T3T_CMD_GET_SYSTEM_CODES) {
249 /* For GetSystemCode: tag did not respond to requested POLL */
250 rw_t3t_handle_get_system_codes_cplt();
251 return;
252 }
253 /* Retry sending command if retry-count < max */
254 else if (rw_cb.cur_retry < RW_MAX_RETRIES) {
255 /* retry sending the command */
256 rw_cb.cur_retry++;
257
Ruchi Kandoi6767aec2017-09-26 09:46:26 -0700258 DLOG_IF(INFO, nfc_debug_enabled)
259 << StringPrintf("T3T retransmission attempt %i of %i",
260 rw_cb.cur_retry, RW_MAX_RETRIES);
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800261
262 /* allocate a new buffer for message */
Ruchi Kandoi0c515ae2017-01-30 17:48:41 -0800263 p_cmd_buf = rw_t3t_get_cmd_buf();
264 if (p_cmd_buf != NULL) {
Ruchi Kandoi7dab0e52017-08-03 13:09:49 -0700265 memcpy(p_cmd_buf, p_cb->p_cur_cmd_buf, sizeof(NFC_HDR) +
266 p_cb->p_cur_cmd_buf->offset +
267 p_cb->p_cur_cmd_buf->len);
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800268
269 if (rw_t3t_send_to_lower(p_cmd_buf) == NFC_STATUS_OK) {
270 /* Start timer for waiting for response */
271 nfc_start_quick_timer(&p_cb->timer, NFC_TTYPE_RW_T3T_RESPONSE,
272 p_cb->cur_tout);
273 return;
274 } else {
275 /* failure - could not send buffer */
276 GKI_freebuf(p_cmd_buf);
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800277 }
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800278 }
279 } else {
Ruchi Kandoi6767aec2017-09-26 09:46:26 -0700280 DLOG_IF(INFO, nfc_debug_enabled) << StringPrintf(
281 "T3T maximum retransmission attempts reached (%i)", RW_MAX_RETRIES);
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800282 }
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800283
Ruchi Kandoi303fec12016-12-14 13:22:38 -0800284#if (RW_STATS_INCLUDED == TRUE)
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800285 /* update failure count */
286 rw_main_update_fail_stats();
287#endif /* RW_STATS_INCLUDED */
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800288
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800289 p_cb->rw_state = RW_T3T_STATE_IDLE;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800290
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800291 /* Notify app of result (if there was a pending command) */
292 if (p_cb->cur_cmd < RW_T3T_CMD_MAX) {
293 /* If doing presence check, use status=NFC_STATUS_FAILED, otherwise
294 * NFC_STATUS_TIMEOUT */
295 evt_data.status = status;
296 evt = rw_t3t_api_res_evt[p_cb->cur_cmd];
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800297
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800298 /* Set additional flags for RW_T3T_NDEF_DETECT_EVT */
299 if (evt == RW_T3T_NDEF_DETECT_EVT) {
300 evt_data.ndef.flags = RW_NDEF_FL_UNKNOWN;
301 rw_t3t_update_ndef_flag(&evt_data.ndef.flags);
302 }
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800303
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800304 (*(rw_cb.p_cback))(evt, &evt_data);
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800305 }
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800306 } else {
307 evt_data.status = status;
308 (*(rw_cb.p_cback))(RW_T3T_INTF_ERROR_EVT, &evt_data);
309 }
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800310}
311
312/*******************************************************************************
313**
314** Function rw_t3t_start_poll_timer
315**
316** Description Start the timer for T3T POLL Command
317**
318** Returns none
319**
320*******************************************************************************/
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800321void rw_t3t_start_poll_timer(tRW_T3T_CB* p_cb) {
322 nfc_start_quick_timer(&p_cb->poll_timer, NFC_TTYPE_RW_T3T_RESPONSE,
323 RW_T3T_POLL_CMD_TIMEOUT_TICKS);
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800324}
325
326/*******************************************************************************
327**
328** Function rw_t3t_handle_nci_poll_ntf
329**
330** Description Handle NCI_T3T_POLLING_NTF
331**
332** Returns none
333**
334*******************************************************************************/
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800335void rw_t3t_handle_nci_poll_ntf(uint8_t nci_status, uint8_t num_responses,
336 uint8_t sensf_res_buf_size,
337 uint8_t* p_sensf_res_buf) {
338 tRW_DATA evt_data;
339 tRW_T3T_CB* p_cb = &rw_cb.tcb.t3t;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800340
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800341 /* stop timer for poll response */
342 nfc_stop_quick_timer(&p_cb->poll_timer);
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800343
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800344 /* Stop t3t timer (if started) */
345 if (p_cb->flags & RW_T3T_FL_W4_PRESENCE_CHECK_POLL_RSP) {
346 p_cb->flags &= ~RW_T3T_FL_W4_PRESENCE_CHECK_POLL_RSP;
347 evt_data.status = nci_status;
348 p_cb->rw_state = RW_T3T_STATE_IDLE;
Myles Watson1361d522017-09-26 13:39:54 -0700349 (*(rw_cb.p_cback))(RW_T3T_PRESENCE_CHECK_EVT, &evt_data);
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800350 } else if (p_cb->flags & RW_T3T_FL_W4_GET_SC_POLL_RSP) {
351 /* Handle POLL ntf in response to get system codes */
352 p_cb->flags &= ~RW_T3T_FL_W4_GET_SC_POLL_RSP;
353 rw_t3t_handle_get_sc_poll_rsp(p_cb, nci_status, num_responses,
354 sensf_res_buf_size, p_sensf_res_buf);
355 } else if (p_cb->flags & RW_T3T_FL_W4_FMT_FELICA_LITE_POLL_RSP) {
356 /* Handle POLL ntf in response to get system codes */
357 p_cb->flags &= ~RW_T3T_FL_W4_FMT_FELICA_LITE_POLL_RSP;
Ruchi Kandoi9ba6d242017-10-13 16:07:01 -0700358 rw_t3t_handle_fmt_poll_rsp(p_cb, nci_status, num_responses);
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800359 } else if (p_cb->flags & RW_T3T_FL_W4_SRO_FELICA_LITE_POLL_RSP) {
360 /* Handle POLL ntf in response to get system codes */
361 p_cb->flags &= ~RW_T3T_FL_W4_SRO_FELICA_LITE_POLL_RSP;
Ruchi Kandoi9ba6d242017-10-13 16:07:01 -0700362 rw_t3t_handle_sro_poll_rsp(p_cb, nci_status, num_responses);
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800363 } else if (p_cb->flags & RW_T3T_FL_W4_NDEF_DETECT_POLL_RSP) {
364 /* Handle POLL ntf in response to ndef detection */
365 p_cb->flags &= ~RW_T3T_FL_W4_NDEF_DETECT_POLL_RSP;
Ruchi Kandoi9ba6d242017-10-13 16:07:01 -0700366 rw_t3t_handle_ndef_detect_poll_rsp(p_cb, nci_status, num_responses);
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800367 } else {
368 /* Handle POLL ntf in response to RW_T3tPoll */
Ruchi Kandoi0c515ae2017-01-30 17:48:41 -0800369 evt_data.t3t_poll.status = nci_status;
370 if (evt_data.t3t_poll.status == NCI_STATUS_OK) {
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800371 evt_data.t3t_poll.rc = p_cb->cur_poll_rc;
372 evt_data.t3t_poll.response_num = num_responses;
373 evt_data.t3t_poll.response_bufsize = sensf_res_buf_size;
374 evt_data.t3t_poll.response_buf = p_sensf_res_buf;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800375 }
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800376
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800377 p_cb->rw_state = RW_T3T_STATE_IDLE;
378 (*(rw_cb.p_cback))(RW_T3T_POLL_EVT, &evt_data);
379 }
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800380}
381
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800382/*******************************************************************************
383**
384** Function rw_t3t_handle_get_system_codes_cplt
385**
386** Description Notify upper layer of system codes
387**
388** Returns none
389**
390*******************************************************************************/
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800391void rw_t3t_handle_get_system_codes_cplt(void) {
392 tRW_T3T_CB* p_cb = &rw_cb.tcb.t3t;
393 tRW_DATA evt_data;
394 uint8_t i;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800395
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800396 evt_data.t3t_sc.status = NFC_STATUS_OK;
397 evt_data.t3t_sc.num_system_codes = p_cb->num_system_codes;
398 evt_data.t3t_sc.p_system_codes = p_cb->system_codes;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800399
Ruchi Kandoi6767aec2017-09-26 09:46:26 -0700400 DLOG_IF(INFO, nfc_debug_enabled) << StringPrintf(
401 "number of systems: %i", evt_data.t3t_sc.num_system_codes);
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800402 for (i = 0; i < evt_data.t3t_sc.num_system_codes; i++) {
Ruchi Kandoi6767aec2017-09-26 09:46:26 -0700403 DLOG_IF(INFO, nfc_debug_enabled) << StringPrintf(
404 "system %i: %04X", i, evt_data.t3t_sc.p_system_codes[i]);
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800405 }
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800406
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800407 p_cb->rw_state = RW_T3T_STATE_IDLE;
408 (*(rw_cb.p_cback))(RW_T3T_GET_SYSTEM_CODES_EVT, &evt_data);
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800409}
410
411/*******************************************************************************
412**
413** Function rw_t3t_format_cplt
414**
415** Description Notify upper layer of format complete
416**
417** Returns none
418**
419*******************************************************************************/
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800420void rw_t3t_format_cplt(tNFC_STATUS status) {
421 tRW_T3T_CB* p_cb = &rw_cb.tcb.t3t;
422 tRW_DATA evt_data;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800423
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800424 p_cb->rw_state = RW_T3T_STATE_IDLE;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800425
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800426 /* Update ndef info */
427 p_cb->ndef_attrib.status = status;
428 if (status == NFC_STATUS_OK) {
429 p_cb->ndef_attrib.version = T3T_MSG_NDEF_VERSION;
430 p_cb->ndef_attrib.nbr = RW_T3T_DEFAULT_FELICALITE_NBR;
431 p_cb->ndef_attrib.nbw = RW_T3T_DEFAULT_FELICALITE_NBW;
432 p_cb->ndef_attrib.nmaxb = RW_T3T_DEFAULT_FELICALITE_NMAXB;
433 p_cb->ndef_attrib.writef = T3T_MSG_NDEF_WRITEF_OFF;
434 p_cb->ndef_attrib.rwflag = T3T_MSG_NDEF_RWFLAG_RW;
435 p_cb->ndef_attrib.ln = 0;
436 }
Martijn Coenen5c65c3a2013-03-27 13:23:36 -0700437
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800438 /* Notify upper layer of format complete */
439 evt_data.status = status;
440 (*(rw_cb.p_cback))(RW_T3T_FORMAT_CPLT_EVT, &evt_data);
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800441}
442
443/*******************************************************************************
444**
Martijn Coenen5c65c3a2013-03-27 13:23:36 -0700445** Function rw_t3t_set_readonly_cplt
446**
447** Description Notify upper layer of set read only complete
448**
449** Returns none
450**
451*******************************************************************************/
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800452void rw_t3t_set_readonly_cplt(tNFC_STATUS status) {
453 tRW_T3T_CB* p_cb = &rw_cb.tcb.t3t;
454 tRW_DATA evt_data;
Martijn Coenen5c65c3a2013-03-27 13:23:36 -0700455
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800456 p_cb->rw_state = RW_T3T_STATE_IDLE;
Martijn Coenen5c65c3a2013-03-27 13:23:36 -0700457
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800458 /* Notify upper layer of format complete */
459 evt_data.status = status;
460 (*(rw_cb.p_cback))(RW_T3T_SET_READ_ONLY_CPLT_EVT, &evt_data);
Martijn Coenen5c65c3a2013-03-27 13:23:36 -0700461}
462
463/*******************************************************************************
464**
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800465** Function rw_t3t_process_timeout
466**
467** Description Process timeout
468**
469** Returns none
470**
471*******************************************************************************/
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800472void rw_t3t_process_timeout(TIMER_LIST_ENT* p_tle) {
473 tRW_T3T_CB* p_cb = &rw_cb.tcb.t3t;
474 tRW_DATA evt_data;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800475
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800476 /* Check which timer timed out */
477 if (p_tle == &p_cb->timer) {
478/* UPDATE/CHECK response timeout */
Ruchi Kandoi6767aec2017-09-26 09:46:26 -0700479LOG(ERROR) << StringPrintf("T3T timeout. state=%s cur_cmd=0x%02X (%s)",
480 rw_t3t_state_str(rw_cb.tcb.t3t.rw_state).c_str(),
481 rw_cb.tcb.t3t.cur_cmd,
482 rw_t3t_cmd_str(rw_cb.tcb.t3t.cur_cmd).c_str());
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800483
Ruchi Kandoi6767aec2017-09-26 09:46:26 -0700484rw_t3t_process_error(NFC_STATUS_TIMEOUT);
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800485 } else {
Ruchi Kandoi6767aec2017-09-26 09:46:26 -0700486 LOG(ERROR) << StringPrintf("T3T POLL timeout.");
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800487
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800488 /* POLL response timeout */
489 if (p_cb->flags & RW_T3T_FL_W4_PRESENCE_CHECK_POLL_RSP) {
490 /* POLL timeout for presence check */
491 p_cb->flags &= ~RW_T3T_FL_W4_PRESENCE_CHECK_POLL_RSP;
492 evt_data.status = NFC_STATUS_FAILED;
493 p_cb->rw_state = RW_T3T_STATE_IDLE;
Myles Watson1361d522017-09-26 13:39:54 -0700494 (*(rw_cb.p_cback))(RW_T3T_PRESENCE_CHECK_EVT, &evt_data);
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800495 } else if (p_cb->flags & RW_T3T_FL_W4_GET_SC_POLL_RSP) {
496 /* POLL timeout for getting system codes */
497 p_cb->flags &= ~RW_T3T_FL_W4_GET_SC_POLL_RSP;
498 rw_t3t_handle_get_system_codes_cplt();
499 } else if (p_cb->flags & RW_T3T_FL_W4_FMT_FELICA_LITE_POLL_RSP) {
500 /* POLL timeout for formatting Felica Lite */
501 p_cb->flags &= ~RW_T3T_FL_W4_FMT_FELICA_LITE_POLL_RSP;
Ruchi Kandoi6767aec2017-09-26 09:46:26 -0700502 LOG(ERROR) << StringPrintf("Felica-Lite tag not detected");
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800503 rw_t3t_format_cplt(NFC_STATUS_FAILED);
504 } else if (p_cb->flags & RW_T3T_FL_W4_SRO_FELICA_LITE_POLL_RSP) {
505 /* POLL timeout for configuring Felica Lite read only */
506 p_cb->flags &= ~RW_T3T_FL_W4_SRO_FELICA_LITE_POLL_RSP;
Ruchi Kandoi6767aec2017-09-26 09:46:26 -0700507 LOG(ERROR) << StringPrintf("Felica-Lite tag not detected");
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800508 rw_t3t_set_readonly_cplt(NFC_STATUS_FAILED);
509 } else if (p_cb->flags & RW_T3T_FL_W4_NDEF_DETECT_POLL_RSP) {
510 /* POLL timeout for ndef detection */
511 p_cb->flags &= ~RW_T3T_FL_W4_NDEF_DETECT_POLL_RSP;
Ruchi Kandoi9ba6d242017-10-13 16:07:01 -0700512 rw_t3t_handle_ndef_detect_poll_rsp(p_cb, NFC_STATUS_TIMEOUT, 0);
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800513 } else {
514 /* Timeout waiting for response for RW_T3tPoll */
515 evt_data.t3t_poll.status = NFC_STATUS_FAILED;
516 p_cb->rw_state = RW_T3T_STATE_IDLE;
Myles Watson1361d522017-09-26 13:39:54 -0700517 (*(rw_cb.p_cback))(RW_T3T_POLL_EVT, &evt_data);
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800518 }
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800519 }
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800520}
521
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800522/*******************************************************************************
523**
524** Function rw_t3t_process_frame_error
525**
526** Description Process frame crc error
527**
528** Returns none
529**
530*******************************************************************************/
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800531void rw_t3t_process_frame_error(void) {
Ruchi Kandoi6767aec2017-09-26 09:46:26 -0700532 LOG(ERROR) << StringPrintf("T3T frame error. state=%s cur_cmd=0x%02X (%s)",
533 rw_t3t_state_str(rw_cb.tcb.t3t.rw_state).c_str(),
534 rw_cb.tcb.t3t.cur_cmd,
535 rw_t3t_cmd_str(rw_cb.tcb.t3t.cur_cmd).c_str());
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800536
Ruchi Kandoi303fec12016-12-14 13:22:38 -0800537#if (RW_STATS_INCLUDED == TRUE)
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800538 /* Update stats */
539 rw_main_update_crc_error_stats();
540#endif /* RW_STATS_INCLUDED */
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800541
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800542 /* Process the error */
543 rw_t3t_process_error(NFC_STATUS_MSG_CORRUPTED);
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800544}
545
546/*******************************************************************************
547**
548** Function rw_t3t_send_to_lower
549**
550** Description Send command to lower layer
551**
552** Returns status of the send
553**
554*******************************************************************************/
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800555tNFC_STATUS rw_t3t_send_to_lower(NFC_HDR* p_msg) {
556 uint8_t* p;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800557
Ruchi Kandoi303fec12016-12-14 13:22:38 -0800558#if (RW_STATS_INCLUDED == TRUE)
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800559 bool is_retry;
560 /* Update stats */
561 rw_main_update_tx_stats(p_msg->len, ((rw_cb.cur_retry == 0) ? false : true));
562#endif /* RW_STATS_INCLUDED */
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800563
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800564 /* Set NFC-F SoD field (payload len + 1) */
565 p_msg->offset -= 1; /* Point to SoD field */
566 p = (uint8_t*)(p_msg + 1) + p_msg->offset;
567 UINT8_TO_STREAM(p, (p_msg->len + 1));
568 p_msg->len += 1; /* Increment len to include SoD */
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800569
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800570 return (NFC_SendData(NFC_RF_CONN_ID, p_msg));
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800571}
572
573/*****************************************************************************
574**
575** Function rw_t3t_get_cmd_buf
576**
577** Description Get a buffer for sending T3T messages
578**
Ruchi Kandoi0a736882017-01-09 15:43:14 -0800579** Returns NFC_HDR *
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800580**
581*****************************************************************************/
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800582NFC_HDR* rw_t3t_get_cmd_buf(void) {
583 NFC_HDR* p_cmd_buf;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800584
Ruchi Kandoi0c515ae2017-01-30 17:48:41 -0800585 p_cmd_buf = (NFC_HDR*)GKI_getpoolbuf(NFC_RW_POOL_ID);
586 if (p_cmd_buf != NULL) {
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800587 /* Reserve offset for NCI_DATA_HDR and NFC-F Sod (LEN) field */
588 p_cmd_buf->offset = NCI_MSG_OFFSET_SIZE + NCI_DATA_HDR_SIZE + 1;
589 p_cmd_buf->len = 0;
590 }
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800591
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800592 return (p_cmd_buf);
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800593}
594
595/*****************************************************************************
596**
597** Function rw_t3t_send_cmd
598**
599** Description Send command to tag, and start timer for response
600**
601** Returns tNFC_STATUS
602**
603*****************************************************************************/
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800604tNFC_STATUS rw_t3t_send_cmd(tRW_T3T_CB* p_cb, uint8_t rw_t3t_cmd,
605 NFC_HDR* p_cmd_buf, uint32_t timeout_ticks) {
606 tNFC_STATUS retval;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800607
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800608 /* Indicate first attempt to send command, back up cmd buffer in case needed
609 * for retransmission */
610 rw_cb.cur_retry = 0;
611 memcpy(p_cb->p_cur_cmd_buf, p_cmd_buf,
612 sizeof(NFC_HDR) + p_cmd_buf->offset + p_cmd_buf->len);
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800613
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800614 p_cb->cur_cmd = rw_t3t_cmd;
615 p_cb->cur_tout = timeout_ticks;
616 p_cb->rw_state = RW_T3T_STATE_COMMAND_PENDING;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800617
Ruchi Kandoi0c515ae2017-01-30 17:48:41 -0800618 retval = rw_t3t_send_to_lower(p_cmd_buf);
619 if (retval == NFC_STATUS_OK) {
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800620 /* Start timer for waiting for response */
621 nfc_start_quick_timer(&p_cb->timer, NFC_TTYPE_RW_T3T_RESPONSE,
622 timeout_ticks);
623 } else {
624 /* Error sending */
625 p_cb->rw_state = RW_T3T_STATE_IDLE;
626 }
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800627
Ruchi Kandoi6767aec2017-09-26 09:46:26 -0700628 DLOG_IF(INFO, nfc_debug_enabled)
629 << StringPrintf("cur_tout: %d, timeout_ticks: %d ret:%d", p_cb->cur_tout,
630 timeout_ticks, retval);
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800631 return (retval);
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800632}
633
634/*****************************************************************************
635**
636** Function rw_t3t_send_update_ndef_attribute_cmd
637**
638** Description Send UPDATE command for Attribute Information
639**
640** Returns tNFC_STATUS
641**
642*****************************************************************************/
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800643tNFC_STATUS rw_t3t_send_update_ndef_attribute_cmd(tRW_T3T_CB* p_cb,
644 bool write_in_progress) {
645 tNFC_STATUS retval = NFC_STATUS_OK;
646 NFC_HDR* p_cmd_buf;
647 uint8_t *p_cmd_start, *p;
648 uint16_t checksum, i;
649 uint8_t write_f;
650 uint32_t ln;
651 uint8_t* p_ndef_attr_info_start;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800652
Ruchi Kandoi0c515ae2017-01-30 17:48:41 -0800653 p_cmd_buf = rw_t3t_get_cmd_buf();
654 if (p_cmd_buf != NULL) {
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800655 /* Construct T3T message */
656 p = p_cmd_start = (uint8_t*)(p_cmd_buf + 1) + p_cmd_buf->offset;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800657
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800658 /* Add UPDATE opcode to message */
659 UINT8_TO_STREAM(p, T3T_MSG_OPC_UPDATE_CMD);
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800660
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800661 /* Add IDm to message */
662 ARRAY_TO_STREAM(p, p_cb->peer_nfcid2, NCI_NFCID2_LEN);
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800663
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800664 /* Add Service code list */
665 UINT8_TO_STREAM(p, 1); /* Number of services (only 1 service: NDEF) */
666 UINT16_TO_STREAM(
667 p, T3T_MSG_NDEF_SC_RW); /* Service code (little-endian format) */
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800668
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800669 /* Add number of blocks in this UPDATE command */
670 UINT8_TO_STREAM(p, 1); /* Number of blocks to write in this command */
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800671
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800672 /* Block List element: the NDEF attribute information block (block 0) */
673 UINT8_TO_STREAM(p, T3T_MSG_MASK_TWO_BYTE_BLOCK_DESC_FORMAT);
674 UINT8_TO_STREAM(p, 0);
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800675
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800676 /* Add payload (Attribute information block) */
677 p_ndef_attr_info_start =
678 p; /* Save start of a NDEF attribute info block for checksum */
679 UINT8_TO_STREAM(p, T3T_MSG_NDEF_VERSION);
680 UINT8_TO_STREAM(p, p_cb->ndef_attrib.nbr);
681 UINT8_TO_STREAM(p, p_cb->ndef_attrib.nbw);
682 UINT16_TO_BE_STREAM(p, p_cb->ndef_attrib.nmaxb);
683 UINT32_TO_STREAM(p, 0);
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800684
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800685 /* If starting NDEF write: set WriteF=ON, and ln=current ndef length */
686 if (write_in_progress) {
687 write_f = T3T_MSG_NDEF_WRITEF_ON;
688 ln = p_cb->ndef_attrib.ln;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800689 }
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800690 /* If finishing NDEF write: set WriteF=OFF, and ln=new ndef len */
691 else {
692 write_f = T3T_MSG_NDEF_WRITEF_OFF;
693 ln = p_cb->ndef_msg_len;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800694 }
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800695 UINT8_TO_STREAM(p, write_f);
696 UINT8_TO_STREAM(p, p_cb->ndef_attrib.rwflag);
697 UINT8_TO_STREAM(p, (ln >> 16) & 0xFF); /* High byte (of 3) of Ln */
698 UINT8_TO_STREAM(p, (ln >> 8) & 0xFF); /* Middle byte (of 3) of Ln */
699 UINT8_TO_STREAM(p, (ln)&0xFF); /* Low byte (of 3) of Ln */
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800700
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800701 /* Calculate and append Checksum */
702 checksum = 0;
703 for (i = 0; i < T3T_MSG_NDEF_ATTR_INFO_SIZE; i++) {
704 checksum += p_ndef_attr_info_start[i];
705 }
706 UINT16_TO_BE_STREAM(p, checksum);
707
708 /* Calculate length of message */
709 p_cmd_buf->len = (uint16_t)(p - p_cmd_start);
710
711 /* Send the T3T message */
712 retval = rw_t3t_send_cmd(p_cb, RW_T3T_CMD_UPDATE_NDEF, p_cmd_buf,
713 rw_t3t_update_timeout(1));
714 } else {
715 retval = NFC_STATUS_NO_BUFFERS;
716 }
717
718 return (retval);
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800719}
720
721/*****************************************************************************
722**
723** Function rw_t3t_send_next_ndef_update_cmd
724**
725** Description Send next segment of NDEF message to update
726**
727** Returns tNFC_STATUS
728**
729*****************************************************************************/
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800730tNFC_STATUS rw_t3t_send_next_ndef_update_cmd(tRW_T3T_CB* p_cb) {
731 tNFC_STATUS retval = NFC_STATUS_OK;
732 uint16_t block_id;
733 uint16_t first_block_to_write;
734 uint16_t ndef_blocks_to_write, ndef_blocks_remaining;
735 uint32_t ndef_bytes_remaining, ndef_padding = 0;
736 uint8_t flags = 0;
737 uint8_t* p_cur_ndef_src_offset;
738 NFC_HDR* p_cmd_buf;
739 uint8_t *p_cmd_start, *p;
740 uint8_t blocks_per_update;
741 uint32_t timeout;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800742
Ruchi Kandoi0c515ae2017-01-30 17:48:41 -0800743 p_cmd_buf = rw_t3t_get_cmd_buf();
744 if (p_cmd_buf != NULL) {
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800745 /* Construct T3T message */
746 p = p_cmd_start = (uint8_t*)(p_cmd_buf + 1) + p_cmd_buf->offset;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800747
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800748 /* Calculate number of ndef bytes remaining to write */
749 ndef_bytes_remaining = p_cb->ndef_msg_len - p_cb->ndef_msg_bytes_sent;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800750
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800751 /* Calculate number of blocks remaining to write */
752 ndef_blocks_remaining =
753 (uint16_t)((ndef_bytes_remaining + 15) >>
754 4); /* ndef blocks remaining (rounded upward) */
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800755
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800756 /* Calculate first NDEF block ID for this UPDATE command */
757 first_block_to_write = (uint16_t)((p_cb->ndef_msg_bytes_sent >> 4) + 1);
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800758
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800759 /* Calculate max number of blocks per write. */
760 if ((first_block_to_write +
761 RW_T3T_MAX_NDEF_BLOCKS_PER_UPDATE_1_BYTE_FORMAT) < 0x100) {
762 /* All block-numbers are < 0x100 (i.e. can be specified using one-byte
763 * format) */
764 blocks_per_update = RW_T3T_MAX_NDEF_BLOCKS_PER_UPDATE_1_BYTE_FORMAT;
765 } else {
766 /* Block-numbers are >= 0x100 (i.e. need to be specified using two-byte
767 * format) */
768 blocks_per_update = RW_T3T_MAX_NDEF_BLOCKS_PER_UPDATE_2_BYTE_FORMAT;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800769 }
770
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800771 /* Check if blocks_per_update is bigger than what peer allows */
772 if (blocks_per_update > p_cb->ndef_attrib.nbw)
773 blocks_per_update = p_cb->ndef_attrib.nbw;
774
775 /* Check if remaining blocks can fit into one UPDATE command */
776 if (ndef_blocks_remaining <= blocks_per_update) {
777 /* remaining blocks can fit into one UPDATE command */
778 ndef_blocks_to_write = ndef_blocks_remaining;
779 } else {
780 /* Remaining blocks cannot fit into one UPDATE command */
781 ndef_blocks_to_write = blocks_per_update;
782 }
783
784 /* Write to command header for UPDATE */
785
786 /* Add UPDATE opcode to message */
787 UINT8_TO_STREAM(p, T3T_MSG_OPC_UPDATE_CMD);
788
789 /* Add IDm to message */
790 ARRAY_TO_STREAM(p, p_cb->peer_nfcid2, NCI_NFCID2_LEN);
791
792 /* Add Service code list */
793 UINT8_TO_STREAM(p, 1); /* Number of services (only 1 service: NDEF) */
794 UINT16_TO_STREAM(
795 p, T3T_MSG_NDEF_SC_RW); /* Service code (little-endian format) */
796
797 /* Add number of blocks in this UPDATE command */
798 UINT8_TO_STREAM(
799 p,
800 ndef_blocks_to_write); /* Number of blocks to write in this command */
801 timeout = rw_t3t_update_timeout(ndef_blocks_to_write);
802
803 for (block_id = first_block_to_write;
804 block_id < (first_block_to_write + ndef_blocks_to_write); block_id++) {
805 if (block_id < 256) {
806 /* Block IDs 0-255 can be specified in '2-byte' format: byte0=0,
807 * byte1=blocknumber */
808 UINT8_TO_STREAM(
809 p, T3T_MSG_MASK_TWO_BYTE_BLOCK_DESC_FORMAT); /* byte0: len=1;
810 access-mode=0;
811 service code list
812 order=0 */
813 UINT8_TO_STREAM(p, block_id); /* byte1: block number */
814 } else {
815 /* Block IDs 256+ must be specified in '3-byte' format: byte0=80h,
816 * followed by blocknumber */
817 UINT8_TO_STREAM(
818 p,
819 0x00); /* byte0: len=0; access-mode=0; service code list order=0 */
820 UINT16_TO_STREAM(
821 p, block_id); /* byte1-2: block number in little-endian format */
822 }
823 }
824
825 /* Add NDEF payload */
826
827 /* If this sending last block of NDEF, check if padding is needed to make
828 * payload a multiple of 16 bytes */
829 if (ndef_blocks_to_write == ndef_blocks_remaining) {
830 ndef_padding = (16 - (ndef_bytes_remaining & 0x0F)) & 0x0F;
831 if (ndef_padding) {
832 flags |= RW_T3T_FL_PADDING;
833 ndef_blocks_to_write--; /* handle the last block separately if it needs
834 padding */
835 }
836 }
837
838 /* Add NDEF payload to the message */
839 p_cur_ndef_src_offset = &p_cb->ndef_msg[p_cb->ndef_msg_bytes_sent];
840
841 ARRAY_TO_STREAM(p, p_cur_ndef_src_offset, (ndef_blocks_to_write * 16));
842 p_cb->ndef_msg_bytes_sent += ((uint32_t)ndef_blocks_to_write * 16);
843
844 if (flags & RW_T3T_FL_PADDING) {
845 /* Add last of the NDEF message */
846 p_cur_ndef_src_offset = &p_cb->ndef_msg[p_cb->ndef_msg_bytes_sent];
847 ARRAY_TO_STREAM(p, p_cur_ndef_src_offset, (int)(16 - ndef_padding));
848 p_cb->ndef_msg_bytes_sent += (16 - ndef_padding);
849
850 /* Add padding */
851 memset(p, 0, ndef_padding);
852 p += ndef_padding;
853 }
854
855 /* Calculate length of message */
856 p_cmd_buf->len = (uint16_t)(p - p_cmd_start);
857
858 /* Send the T3T message */
859 retval = rw_t3t_send_cmd(p_cb, RW_T3T_CMD_UPDATE_NDEF, p_cmd_buf, timeout);
860 } else {
861 retval = NFC_STATUS_NO_BUFFERS;
862 }
863
864 return (retval);
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800865}
866
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800867/*****************************************************************************
868**
869** Function rw_t3t_send_next_ndef_check_cmd
870**
871** Description Send command for reading next segment of NDEF message
872**
873** Returns tNFC_STATUS
874**
875*****************************************************************************/
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800876tNFC_STATUS rw_t3t_send_next_ndef_check_cmd(tRW_T3T_CB* p_cb) {
877 tNFC_STATUS retval = NFC_STATUS_OK;
878 uint16_t block_id;
879 uint16_t ndef_blocks_remaining, first_block_to_read, cur_blocks_to_read;
880 uint32_t ndef_bytes_remaining;
881 NFC_HDR* p_cmd_buf;
882 uint8_t *p_cmd_start, *p;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800883
Ruchi Kandoi0c515ae2017-01-30 17:48:41 -0800884 p_cmd_buf = rw_t3t_get_cmd_buf();
885 if (p_cmd_buf != NULL) {
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800886 /* Construct T3T message */
887 p = p_cmd_start = (uint8_t*)(p_cmd_buf + 1) + p_cmd_buf->offset;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800888
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800889 /* Calculate number of ndef bytes remaining to read */
890 ndef_bytes_remaining = p_cb->ndef_attrib.ln - p_cb->ndef_rx_offset;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800891
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800892 /* Calculate number of blocks remaining to read */
893 ndef_blocks_remaining =
894 (uint16_t)((ndef_bytes_remaining + 15) >>
895 4); /* ndef blocks remaining (rounded upward) */
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800896
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800897 /* Calculate first NDEF block ID */
898 first_block_to_read = (uint16_t)((p_cb->ndef_rx_offset >> 4) + 1);
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800899
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800900 /* Check if remaining blocks can fit into one CHECK command */
901 if (ndef_blocks_remaining <= p_cb->ndef_attrib.nbr) {
902 /* remaining blocks can fit into one CHECK command */
903 cur_blocks_to_read = ndef_blocks_remaining;
904 p_cb->ndef_rx_readlen = ndef_bytes_remaining;
905 p_cb->flags |= RW_T3T_FL_IS_FINAL_NDEF_SEGMENT;
906 } else {
907 /* Remaining blocks cannot fit into one CHECK command */
908 cur_blocks_to_read =
909 p_cb->ndef_attrib
910 .nbr; /* Read maximum number of blocks allowed by the peer */
911 p_cb->ndef_rx_readlen = ((uint32_t)p_cb->ndef_attrib.nbr * 16);
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800912 }
913
Ruchi Kandoi6767aec2017-09-26 09:46:26 -0700914 DLOG_IF(INFO, nfc_debug_enabled) << StringPrintf(
915 "bytes_remaining: %i, cur_blocks_to_read: %i, is_final: %i",
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800916 ndef_bytes_remaining, cur_blocks_to_read,
917 (p_cb->flags & RW_T3T_FL_IS_FINAL_NDEF_SEGMENT));
918
919 /* Add CHECK opcode to message */
920 UINT8_TO_STREAM(p, T3T_MSG_OPC_CHECK_CMD);
921
922 /* Add IDm to message */
923 ARRAY_TO_STREAM(p, p_cb->peer_nfcid2, NCI_NFCID2_LEN);
924
925 /* Add Service code list */
926 UINT8_TO_STREAM(p, 1); /* Number of services (only 1 service: NDEF) */
927
928 /* Service code (little-endian format) . If NDEF is read-only, then use
929 * T3T_MSG_NDEF_SC_RO, otherwise use T3T_MSG_NDEF_SC_RW */
930 if (p_cb->ndef_attrib.rwflag == T3T_MSG_NDEF_RWFLAG_RO) {
931 UINT16_TO_STREAM(p, T3T_MSG_NDEF_SC_RO);
932 } else {
933 UINT16_TO_STREAM(p, T3T_MSG_NDEF_SC_RW);
934 }
935
936 /* Add number of blocks in this CHECK command */
937 UINT8_TO_STREAM(
938 p, cur_blocks_to_read); /* Number of blocks to check in this command */
939
940 for (block_id = first_block_to_read;
941 block_id < (first_block_to_read + cur_blocks_to_read); block_id++) {
942 if (block_id < 256) {
943 /* Block IDs 0-255 can be specified in '2-byte' format: byte0=0,
944 * byte1=blocknumber */
945 UINT8_TO_STREAM(
946 p, T3T_MSG_MASK_TWO_BYTE_BLOCK_DESC_FORMAT); /* byte1: len=0;
947 access-mode=0;
948 service code list
949 order=0 */
950 UINT8_TO_STREAM(p, block_id); /* byte1: block number */
951 } else {
952 /* Block IDs 256+ must be specified in '3-byte' format: byte0=80h,
953 * followed by blocknumber */
954 UINT8_TO_STREAM(
955 p,
956 0x00); /* byte0: len=1; access-mode=0; service code list order=0 */
957 UINT16_TO_STREAM(
958 p, block_id); /* byte1-2: block number in little-endian format */
959 }
960 }
961
962 /* Calculate length of message */
963 p_cmd_buf->len = (uint16_t)(p - p_cmd_start);
964
965 /* Send the T3T message */
966 retval = rw_t3t_send_cmd(p_cb, RW_T3T_CMD_CHECK_NDEF, p_cmd_buf,
967 rw_t3t_check_timeout(cur_blocks_to_read));
968 } else {
969 retval = NFC_STATUS_NO_BUFFERS;
970 }
971
972 return (retval);
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800973}
974
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800975/*****************************************************************************
976**
977** Function rw_t3t_message_set_block_list
978**
979** Description Add block list to T3T message
980**
981** Returns Number of bytes added to message
982**
983*****************************************************************************/
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800984void rw_t3t_message_set_block_list(tRW_T3T_CB* p_cb, uint8_t** p,
985 uint8_t num_blocks,
986 tT3T_BLOCK_DESC* p_t3t_blocks) {
987 uint16_t i, cur_service_code;
988 uint8_t service_code_idx, num_services = 0;
989 uint8_t* p_msg_num_services;
990 uint16_t service_list[T3T_MSG_SERVICE_LIST_MAX];
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800991
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800992 /* Add CHECK or UPDATE opcode to message */
993 UINT8_TO_STREAM(
994 (*p), ((p_cb->cur_cmd == RW_T3T_CMD_CHECK) ? T3T_MSG_OPC_CHECK_CMD
995 : T3T_MSG_OPC_UPDATE_CMD));
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800996
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800997 /* Add IDm to message */
998 ARRAY_TO_STREAM((*p), p_cb->peer_nfcid2, NCI_NFCID2_LEN);
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800999
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001000 /* Skip over Number of Services field */
1001 p_msg_num_services = (*p); /* pointer to Number of Services offset */
1002 (*p)++;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001003
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001004 /* Count number of different services are specified in the list, and add
1005 * services to Service Code list */
1006 for (i = 0; i < num_blocks; i++) {
1007 cur_service_code = p_t3t_blocks[i].service_code;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001008
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001009 /* Check if current service_code is already in the service_list */
1010 for (service_code_idx = 0; service_code_idx < num_services;
1011 service_code_idx++) {
1012 if (service_list[service_code_idx] == cur_service_code) break;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001013 }
1014
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001015 if (service_code_idx == num_services) {
1016 /* Service not in the list yet. Add it. */
1017 service_list[service_code_idx] = cur_service_code;
1018 num_services++;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001019
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001020 /* Add service code to T3T message */
1021 UINT16_TO_STREAM((*p), cur_service_code);
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001022 }
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001023 }
1024
1025 /* Add 'Number of Sservices' to the message */
1026 *p_msg_num_services = num_services;
1027
1028 /* Add 'number of blocks' to the message */
1029 UINT8_TO_STREAM((*p), num_blocks);
1030
1031 /* Add block descriptors */
1032 for (i = 0; i < num_blocks; i++) {
1033 cur_service_code = p_t3t_blocks[i].service_code;
1034
1035 /* Check if current service_code is already in the service_list */
1036 for (service_code_idx = 0; service_code_idx < num_services;
1037 service_code_idx++) {
1038 if (service_list[service_code_idx] == cur_service_code) break;
1039 }
1040
1041 /* Add decriptor to T3T message */
1042 if (p_t3t_blocks[i].block_number > 0xFF) {
1043 UINT8_TO_STREAM((*p), service_code_idx);
1044 UINT16_TO_STREAM((*p), p_t3t_blocks[i].block_number);
1045 } else {
1046 service_code_idx |= T3T_MSG_MASK_TWO_BYTE_BLOCK_DESC_FORMAT;
1047 UINT8_TO_STREAM((*p), service_code_idx);
1048 UINT8_TO_STREAM((*p), p_t3t_blocks[i].block_number);
1049 }
1050 }
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001051}
1052
1053/*****************************************************************************
1054**
1055** Function rw_t3t_send_check_cmd
1056**
1057** Description Send CHECK command
1058**
1059** Returns tNFC_STATUS
1060**
1061*****************************************************************************/
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001062tNFC_STATUS rw_t3t_send_check_cmd(tRW_T3T_CB* p_cb, uint8_t num_blocks,
1063 tT3T_BLOCK_DESC* p_t3t_blocks) {
1064 NFC_HDR* p_cmd_buf;
1065 uint8_t *p, *p_cmd_start;
1066 tNFC_STATUS retval = NFC_STATUS_OK;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001067
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001068 p_cb->cur_cmd = RW_T3T_CMD_CHECK;
Ruchi Kandoi0c515ae2017-01-30 17:48:41 -08001069 p_cmd_buf = rw_t3t_get_cmd_buf();
1070 if (p_cmd_buf != NULL) {
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001071 /* Construct T3T message */
1072 p = p_cmd_start = (uint8_t*)(p_cmd_buf + 1) + p_cmd_buf->offset;
1073 rw_t3t_message_set_block_list(p_cb, &p, num_blocks, p_t3t_blocks);
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001074
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001075 /* Calculate length of message */
1076 p_cmd_buf->len = (uint16_t)(p - p_cmd_start);
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001077
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001078 /* Send the T3T message */
1079 retval = rw_t3t_send_cmd(p_cb, RW_T3T_CMD_CHECK, p_cmd_buf,
1080 rw_t3t_check_timeout(num_blocks));
1081 } else {
1082 retval = NFC_STATUS_NO_BUFFERS;
1083 }
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001084
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001085 return (retval);
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001086}
1087
1088/*****************************************************************************
1089**
1090** Function rw_t3t_send_update_cmd
1091**
1092** Description Send UPDATE command
1093**
1094** Returns tNFC_STATUS
1095**
1096*****************************************************************************/
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001097tNFC_STATUS rw_t3t_send_update_cmd(tRW_T3T_CB* p_cb, uint8_t num_blocks,
1098 tT3T_BLOCK_DESC* p_t3t_blocks,
1099 uint8_t* p_data) {
1100 NFC_HDR* p_cmd_buf;
1101 uint8_t *p, *p_cmd_start;
1102 tNFC_STATUS retval = NFC_STATUS_OK;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001103
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001104 p_cb->cur_cmd = RW_T3T_CMD_UPDATE;
Ruchi Kandoi0c515ae2017-01-30 17:48:41 -08001105 p_cmd_buf = rw_t3t_get_cmd_buf();
1106 if (p_cmd_buf != NULL) {
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001107 /* Construct T3T message */
1108 p = p_cmd_start = (uint8_t*)(p_cmd_buf + 1) + p_cmd_buf->offset;
1109 rw_t3t_message_set_block_list(p_cb, &p, num_blocks, p_t3t_blocks);
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001110
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001111 /* Add data blocks to the message */
1112 ARRAY_TO_STREAM(p, p_data, num_blocks * 16);
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001113
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001114 /* Calculate length of message */
1115 p_cmd_buf->len = (uint16_t)(p - p_cmd_start);
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001116
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001117 /* Send the T3T message */
1118 retval = rw_t3t_send_cmd(p_cb, RW_T3T_CMD_UPDATE, p_cmd_buf,
1119 rw_t3t_update_timeout(num_blocks));
1120 } else {
1121 retval = NFC_STATUS_NO_BUFFERS;
1122 }
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001123
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001124 return (retval);
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001125}
1126
1127/*****************************************************************************
1128**
Martijn Coenen5c65c3a2013-03-27 13:23:36 -07001129** Function rw_t3t_check_mc_block
1130**
1131** Description Send command to check Memory Configuration Block
1132**
1133** Returns tNFC_STATUS
1134**
1135*****************************************************************************/
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001136tNFC_STATUS rw_t3t_check_mc_block(tRW_T3T_CB* p_cb) {
1137 NFC_HDR* p_cmd_buf;
1138 uint8_t *p, *p_cmd_start;
Martijn Coenen5c65c3a2013-03-27 13:23:36 -07001139
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001140 /* Read Memory Configuration block */
Ruchi Kandoi0c515ae2017-01-30 17:48:41 -08001141 p_cmd_buf = rw_t3t_get_cmd_buf();
1142 if (p_cmd_buf != NULL) {
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001143 /* Construct T3T message */
1144 p = p_cmd_start = (uint8_t*)(p_cmd_buf + 1) + p_cmd_buf->offset;
Martijn Coenen5c65c3a2013-03-27 13:23:36 -07001145
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001146 /* Add CHECK opcode to message */
1147 UINT8_TO_STREAM(p, T3T_MSG_OPC_CHECK_CMD);
Martijn Coenen5c65c3a2013-03-27 13:23:36 -07001148
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001149 /* Add IDm to message */
1150 ARRAY_TO_STREAM(p, p_cb->peer_nfcid2, NCI_NFCID2_LEN);
Martijn Coenen5c65c3a2013-03-27 13:23:36 -07001151
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001152 /* Add Service code list */
1153 UINT8_TO_STREAM(p, 1); /* Number of services (only 1 service: NDEF) */
1154 UINT16_TO_STREAM(
1155 p, T3T_MSG_NDEF_SC_RO); /* Service code (little-endian format) */
Martijn Coenen5c65c3a2013-03-27 13:23:36 -07001156
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001157 /* Number of blocks */
1158 UINT8_TO_STREAM(p, 1); /* Number of blocks (only 1 block: Memory
1159 Configuration Information ) */
Martijn Coenen5c65c3a2013-03-27 13:23:36 -07001160
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001161 /* Block List element: the Memory Configuration block (block 0x88) */
1162 UINT8_TO_STREAM(p, T3T_MSG_MASK_TWO_BYTE_BLOCK_DESC_FORMAT);
1163 UINT8_TO_STREAM(p, T3T_MSG_FELICALITE_BLOCK_ID_MC);
Martijn Coenen5c65c3a2013-03-27 13:23:36 -07001164
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001165 /* Calculate length of message */
1166 p_cmd_buf->len = (uint16_t)(p - p_cmd_start);
Martijn Coenen5c65c3a2013-03-27 13:23:36 -07001167
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001168 /* Send the T3T message */
1169 return rw_t3t_send_cmd(p_cb, p_cb->cur_cmd, p_cmd_buf,
1170 rw_t3t_check_timeout(1));
1171 } else {
Ruchi Kandoi6767aec2017-09-26 09:46:26 -07001172 LOG(ERROR) << StringPrintf("Unable to allocate buffer to read MC block");
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001173 return (NFC_STATUS_NO_BUFFERS);
1174 }
Martijn Coenen5c65c3a2013-03-27 13:23:36 -07001175}
1176
1177/*****************************************************************************
1178**
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001179** Function rw_t3t_send_raw_frame
1180**
1181** Description Send raw frame
1182**
1183** Returns tNFC_STATUS
1184**
1185*****************************************************************************/
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001186tNFC_STATUS rw_t3t_send_raw_frame(tRW_T3T_CB* p_cb, uint16_t len,
1187 uint8_t* p_data) {
1188 NFC_HDR* p_cmd_buf;
1189 uint8_t* p;
1190 tNFC_STATUS retval = NFC_STATUS_OK;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001191
Ruchi Kandoi0c515ae2017-01-30 17:48:41 -08001192 p_cmd_buf = rw_t3t_get_cmd_buf();
1193 if (p_cmd_buf != NULL) {
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001194 /* Construct T3T message */
1195 p = (uint8_t*)(p_cmd_buf + 1) + p_cmd_buf->offset;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001196
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001197 /* Add data blocks to the message */
1198 ARRAY_TO_STREAM(p, p_data, len);
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001199
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001200 /* Calculate length of message */
1201 p_cmd_buf->len = len;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001202
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001203 /* Send the T3T message */
1204 retval = rw_t3t_send_cmd(p_cb, RW_T3T_CMD_SEND_RAW_FRAME, p_cmd_buf,
1205 RW_T3T_RAW_FRAME_CMD_TIMEOUT_TICKS);
1206 } else {
1207 retval = NFC_STATUS_NO_BUFFERS;
1208 }
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001209
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001210 return (retval);
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001211}
1212
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001213/*****************************************************************************
1214** TAG RESPONSE HANDLERS
1215*****************************************************************************/
1216
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001217/*****************************************************************************
1218**
1219** Function rw_t3t_act_handle_ndef_detect_rsp
1220**
1221** Description Handle response to NDEF detection
1222**
1223** Returns Nothing
1224**
1225*****************************************************************************/
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001226void rw_t3t_act_handle_ndef_detect_rsp(tRW_T3T_CB* p_cb, NFC_HDR* p_msg_rsp) {
1227 uint8_t* p;
1228 uint32_t temp;
1229 uint8_t i;
1230 uint16_t checksum_calc, checksum_rx;
1231 tRW_DETECT_NDEF_DATA evt_data;
1232 uint8_t* p_t3t_rsp = (uint8_t*)(p_msg_rsp + 1) + p_msg_rsp->offset;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001233
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001234 evt_data.status = NFC_STATUS_FAILED;
1235 evt_data.flags = RW_NDEF_FL_UNKNOWN;
1236
1237 /* Check if response code is CHECK resp (for reading NDEF attribute block) */
1238 if (p_t3t_rsp[T3T_MSG_RSP_OFFSET_RSPCODE] != T3T_MSG_OPC_CHECK_RSP) {
Ruchi Kandoi6767aec2017-09-26 09:46:26 -07001239 LOG(ERROR) << StringPrintf(
1240 "Response error: expecting rsp_code %02X, but got %02X",
1241 T3T_MSG_OPC_CHECK_RSP, p_t3t_rsp[T3T_MSG_RSP_OFFSET_RSPCODE]);
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001242 evt_data.status = NFC_STATUS_FAILED;
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001243 }
1244 /* Validate status code and NFCID2 response from tag */
1245 else if ((p_t3t_rsp[T3T_MSG_RSP_OFFSET_STATUS1] !=
1246 T3T_MSG_RSP_STATUS_OK) /* verify response status code */
1247 || (memcmp(p_cb->peer_nfcid2, &p_t3t_rsp[T3T_MSG_RSP_OFFSET_IDM],
1248 NCI_NFCID2_LEN) != 0)) /* verify response IDm */
1249 {
1250 evt_data.status = NFC_STATUS_FAILED;
Jack Yu71dd18c2019-01-08 21:20:15 +08001251 } else if (p_msg_rsp->len <
1252 (T3T_MSG_RSP_OFFSET_CHECK_DATA + T3T_MSG_BLOCKSIZE)) {
1253 evt_data.status = NFC_STATUS_FAILED;
1254 android_errorWriteLog(0x534e4554, "120428041");
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001255 } else {
1256 /* Get checksum from received ndef attribute msg */
1257 p = &p_t3t_rsp[T3T_MSG_RSP_OFFSET_CHECK_DATA + T3T_MSG_NDEF_ATTR_INFO_SIZE];
1258 BE_STREAM_TO_UINT16(checksum_rx, p);
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001259
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001260 /* Calculate checksum - move check for checsum to beginning */
1261 checksum_calc = 0;
1262 p = &p_t3t_rsp[T3T_MSG_RSP_OFFSET_CHECK_DATA];
1263 for (i = 0; i < T3T_MSG_NDEF_ATTR_INFO_SIZE; i++) {
1264 checksum_calc += p[i];
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001265 }
1266
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001267 /* Validate checksum */
1268 if (checksum_calc != checksum_rx) {
1269 p_cb->ndef_attrib.status =
1270 NFC_STATUS_FAILED; /* only ok or failed passed to the app. can be
1271 boolean*/
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001272
Ruchi Kandoi6767aec2017-09-26 09:46:26 -07001273 LOG(ERROR) << StringPrintf("RW_T3tDetectNDEF checksum failed");
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001274 } else {
1275 p_cb->ndef_attrib.status = NFC_STATUS_OK;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001276
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001277 /* Validate version number */
1278 STREAM_TO_UINT8(p_cb->ndef_attrib.version, p);
1279
1280 if (T3T_GET_MAJOR_VERSION(T3T_MSG_NDEF_VERSION) <
1281 T3T_GET_MAJOR_VERSION(p_cb->ndef_attrib.version)) {
1282 /* Remote tag's MajorVer is newer than our's. Reject NDEF as per T3TOP
1283 * RQ_T3T_NDA_024 */
Ruchi Kandoi6767aec2017-09-26 09:46:26 -07001284 LOG(ERROR) << StringPrintf(
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001285 "RW_T3tDetectNDEF: incompatible NDEF version. Local=0x%02x, "
1286 "Remote=0x%02x",
1287 T3T_MSG_NDEF_VERSION, p_cb->ndef_attrib.version);
1288 p_cb->ndef_attrib.status = NFC_STATUS_FAILED;
1289 evt_data.status = NFC_STATUS_BAD_RESP;
1290 } else {
1291 /* Remote tag's MajorVer is equal or older than our's. NDEF is
1292 * compatible with our version. */
1293
1294 /* Update NDEF info */
1295 STREAM_TO_UINT8(
1296 p_cb->ndef_attrib.nbr,
1297 p); /* NBr: number of blocks that can be read using one Check
1298 command */
1299 STREAM_TO_UINT8(p_cb->ndef_attrib.nbw,
1300 p); /* Nbw: number of blocks that can be written using
1301 one Update command */
1302 BE_STREAM_TO_UINT16(
1303 p_cb->ndef_attrib.nmaxb,
1304 p); /* Nmaxb: maximum number of blocks available for NDEF data */
1305 BE_STREAM_TO_UINT32(temp, p);
1306 STREAM_TO_UINT8(p_cb->ndef_attrib.writef,
1307 p); /* WriteFlag: 00h if writing data finished; 0Fh if
1308 writing data in progress */
1309 STREAM_TO_UINT8(
1310 p_cb->ndef_attrib.rwflag,
1311 p); /* RWFlag: 00h NDEF is read-only; 01h if read/write available */
1312
1313 /* Get length (3-byte, big-endian) */
1314 STREAM_TO_UINT8(temp, p); /* Ln: high-byte */
1315 BE_STREAM_TO_UINT16(p_cb->ndef_attrib.ln, p); /* Ln: lo-word */
1316 p_cb->ndef_attrib.ln += (temp << 16);
1317
Ruchi Kandoi6767aec2017-09-26 09:46:26 -07001318 DLOG_IF(INFO, nfc_debug_enabled) << StringPrintf(
1319 "Detected NDEF Ver: 0x%02x", p_cb->ndef_attrib.version);
1320 DLOG_IF(INFO, nfc_debug_enabled) << StringPrintf(
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001321 "Detected NDEF Attributes: Nbr=%i, Nbw=%i, Nmaxb=%i, WriteF=%i, "
1322 "RWFlag=%i, Ln=%i",
1323 p_cb->ndef_attrib.nbr, p_cb->ndef_attrib.nbw,
1324 p_cb->ndef_attrib.nmaxb, p_cb->ndef_attrib.writef,
1325 p_cb->ndef_attrib.rwflag, p_cb->ndef_attrib.ln);
1326
1327 /* Set data for RW_T3T_NDEF_DETECT_EVT */
1328 evt_data.status = p_cb->ndef_attrib.status;
1329 evt_data.cur_size = p_cb->ndef_attrib.ln;
1330 evt_data.max_size = (uint32_t)p_cb->ndef_attrib.nmaxb * 16;
1331 evt_data.protocol = NFC_PROTOCOL_T3T;
1332 evt_data.flags = (RW_NDEF_FL_SUPPORTED | RW_NDEF_FL_FORMATED);
1333 if (p_cb->ndef_attrib.rwflag == T3T_MSG_NDEF_RWFLAG_RO)
1334 evt_data.flags |= RW_NDEF_FL_READ_ONLY;
1335 }
1336 }
1337 }
1338
Ruchi Kandoi6767aec2017-09-26 09:46:26 -07001339 DLOG_IF(INFO, nfc_debug_enabled)
1340 << StringPrintf("RW_T3tDetectNDEF response: %i", evt_data.status);
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001341
1342 p_cb->rw_state = RW_T3T_STATE_IDLE;
1343 rw_t3t_update_ndef_flag(&evt_data.flags);
1344 /* Notify app of NDEF detection result */
Myles Watson1361d522017-09-26 13:39:54 -07001345 tRW_DATA rw_data;
1346 rw_data.ndef = evt_data;
1347 (*(rw_cb.p_cback))(RW_T3T_NDEF_DETECT_EVT, &rw_data);
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001348
1349 GKI_freebuf(p_msg_rsp);
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001350}
1351
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001352/*****************************************************************************
1353**
1354** Function rw_t3t_act_handle_check_rsp
1355**
1356** Description Handle response to CHECK command
1357**
1358** Returns Nothing
1359**
1360*****************************************************************************/
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001361void rw_t3t_act_handle_check_rsp(tRW_T3T_CB* p_cb, NFC_HDR* p_msg_rsp) {
1362 uint8_t* p_t3t_rsp = (uint8_t*)(p_msg_rsp + 1) + p_msg_rsp->offset;
1363 tRW_READ_DATA evt_data;
1364 tNFC_STATUS nfc_status = NFC_STATUS_OK;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001365
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001366 /* Validate response from tag */
1367 if ((p_t3t_rsp[T3T_MSG_RSP_OFFSET_STATUS1] !=
1368 T3T_MSG_RSP_STATUS_OK) /* verify response status code */
1369 || (memcmp(p_cb->peer_nfcid2, &p_t3t_rsp[T3T_MSG_RSP_OFFSET_IDM],
1370 NCI_NFCID2_LEN) != 0)) /* verify response IDm */
1371 {
1372 nfc_status = NFC_STATUS_FAILED;
1373 GKI_freebuf(p_msg_rsp);
1374 } else if (p_t3t_rsp[T3T_MSG_RSP_OFFSET_RSPCODE] != T3T_MSG_OPC_CHECK_RSP) {
Ruchi Kandoi6767aec2017-09-26 09:46:26 -07001375 LOG(ERROR) << StringPrintf(
1376 "Response error: expecting rsp_code %02X, but got %02X",
1377 T3T_MSG_OPC_CHECK_RSP, p_t3t_rsp[T3T_MSG_RSP_OFFSET_RSPCODE]);
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001378 nfc_status = NFC_STATUS_FAILED;
1379 GKI_freebuf(p_msg_rsp);
1380 } else {
1381 /* Copy incoming data into buffer */
1382 p_msg_rsp->offset +=
1383 T3T_MSG_RSP_OFFSET_CHECK_DATA; /* Skip over t3t header */
1384 p_msg_rsp->len -= T3T_MSG_RSP_OFFSET_CHECK_DATA;
1385 evt_data.status = NFC_STATUS_OK;
1386 evt_data.p_data = p_msg_rsp;
Myles Watson1361d522017-09-26 13:39:54 -07001387 tRW_DATA rw_data;
1388 rw_data.data = evt_data;
1389 (*(rw_cb.p_cback))(RW_T3T_CHECK_EVT, &rw_data);
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001390 }
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001391
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001392 p_cb->rw_state = RW_T3T_STATE_IDLE;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001393
Myles Watson1361d522017-09-26 13:39:54 -07001394 tRW_DATA rw_data;
1395 rw_data.status = nfc_status;
1396 (*(rw_cb.p_cback))(RW_T3T_CHECK_CPLT_EVT, &rw_data);
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001397}
1398
1399/*****************************************************************************
1400**
1401** Function rw_t3t_act_handle_update_rsp
1402**
1403** Description Handle response to UPDATE command
1404**
1405** Returns Nothing
1406**
1407*****************************************************************************/
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001408void rw_t3t_act_handle_update_rsp(tRW_T3T_CB* p_cb, NFC_HDR* p_msg_rsp) {
1409 uint8_t* p_t3t_rsp = (uint8_t*)(p_msg_rsp + 1) + p_msg_rsp->offset;
1410 tRW_READ_DATA evt_data;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001411
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001412 /* Validate response from tag */
1413 if ((p_t3t_rsp[T3T_MSG_RSP_OFFSET_STATUS1] !=
1414 T3T_MSG_RSP_STATUS_OK) /* verify response status code */
1415 || (memcmp(p_cb->peer_nfcid2, &p_t3t_rsp[T3T_MSG_RSP_OFFSET_IDM],
1416 NCI_NFCID2_LEN) != 0)) /* verify response IDm */
1417 {
1418 evt_data.status = NFC_STATUS_FAILED;
1419 } else if (p_t3t_rsp[T3T_MSG_RSP_OFFSET_RSPCODE] != T3T_MSG_OPC_UPDATE_RSP) {
Ruchi Kandoi6767aec2017-09-26 09:46:26 -07001420 LOG(ERROR) << StringPrintf(
1421 "Response error: expecting rsp_code %02X, but got %02X",
1422 T3T_MSG_OPC_UPDATE_RSP, p_t3t_rsp[T3T_MSG_RSP_OFFSET_RSPCODE]);
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001423 evt_data.status = NFC_STATUS_FAILED;
1424 } else {
1425 /* Copy incoming data into buffer */
1426 evt_data.status = NFC_STATUS_OK;
1427 }
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001428
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001429 p_cb->rw_state = RW_T3T_STATE_IDLE;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001430
Myles Watson1361d522017-09-26 13:39:54 -07001431 tRW_DATA rw_data;
1432 rw_data.data = evt_data;
1433 (*(rw_cb.p_cback))(RW_T3T_UPDATE_CPLT_EVT, &rw_data);
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001434
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001435 GKI_freebuf(p_msg_rsp);
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001436}
1437
1438/*****************************************************************************
1439**
1440** Function rw_t3t_act_handle_raw_senddata_rsp
1441**
1442** Description Handle response to NDEF detection
1443**
1444** Returns Nothing
1445**
1446*****************************************************************************/
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001447void rw_t3t_act_handle_raw_senddata_rsp(tRW_T3T_CB* p_cb,
1448 tNFC_DATA_CEVT* p_data) {
1449 tRW_READ_DATA evt_data;
1450 NFC_HDR* p_pkt = p_data->p_data;
Evan Chua24be4f2013-11-13 15:30:16 -05001451
Ruchi Kandoi6767aec2017-09-26 09:46:26 -07001452 DLOG_IF(INFO, nfc_debug_enabled)
1453 << StringPrintf("RW T3T Raw Frame: Len [0x%X] Status [%s]", p_pkt->len,
1454 NFC_GetStatusName(p_data->status).c_str());
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001455
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001456 /* Copy incoming data into buffer */
1457 evt_data.status = p_data->status;
1458 evt_data.p_data = p_pkt;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001459
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001460 p_cb->rw_state = RW_T3T_STATE_IDLE;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001461
Myles Watson1361d522017-09-26 13:39:54 -07001462 tRW_DATA rw_data;
1463 rw_data.data = evt_data;
1464 (*(rw_cb.p_cback))(RW_T3T_RAW_FRAME_EVT, &rw_data);
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001465}
1466
1467/*****************************************************************************
1468**
1469** Function rw_t3t_act_handle_check_ndef_rsp
1470**
1471** Description Handle response to NDEF read segment
1472**
1473** Returns Nothing
1474**
1475*****************************************************************************/
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001476void rw_t3t_act_handle_check_ndef_rsp(tRW_T3T_CB* p_cb, NFC_HDR* p_msg_rsp) {
1477 bool check_complete = true;
1478 tNFC_STATUS nfc_status = NFC_STATUS_OK;
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001479 uint8_t* p_t3t_rsp = (uint8_t*)(p_msg_rsp + 1) + p_msg_rsp->offset;
1480 uint8_t rsp_num_bytes_rx;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001481
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001482 /* Validate response from tag */
1483 if ((p_t3t_rsp[T3T_MSG_RSP_OFFSET_STATUS1] !=
1484 T3T_MSG_RSP_STATUS_OK) /* verify response status code */
1485 || (memcmp(p_cb->peer_nfcid2, &p_t3t_rsp[T3T_MSG_RSP_OFFSET_IDM],
1486 NCI_NFCID2_LEN) != 0) /* verify response IDm */
1487 || (p_t3t_rsp[T3T_MSG_RSP_OFFSET_NUMBLOCKS] !=
1488 ((p_cb->ndef_rx_readlen + 15) >> 4))) /* verify length of response */
1489 {
Ruchi Kandoi6767aec2017-09-26 09:46:26 -07001490 LOG(ERROR) << StringPrintf(
1491 "Response error: bad status, nfcid2, or invalid len: %i %i",
1492 p_t3t_rsp[T3T_MSG_RSP_OFFSET_NUMBLOCKS],
1493 ((p_cb->ndef_rx_readlen + 15) >> 4));
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001494 nfc_status = NFC_STATUS_FAILED;
1495 GKI_freebuf(p_msg_rsp);
1496 } else if (p_t3t_rsp[T3T_MSG_RSP_OFFSET_RSPCODE] != T3T_MSG_OPC_CHECK_RSP) {
Ruchi Kandoi6767aec2017-09-26 09:46:26 -07001497 LOG(ERROR) << StringPrintf(
1498 "Response error: expecting rsp_code %02X, but got %02X",
1499 T3T_MSG_OPC_CHECK_RSP, p_t3t_rsp[T3T_MSG_RSP_OFFSET_RSPCODE]);
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001500 nfc_status = NFC_STATUS_FAILED;
1501 GKI_freebuf(p_msg_rsp);
1502 } else {
1503 /* Notify app of NDEF segment received */
1504 rsp_num_bytes_rx = p_t3t_rsp[T3T_MSG_RSP_OFFSET_NUMBLOCKS] *
1505 16; /* Number of bytes received, according to header */
1506 p_cb->ndef_rx_offset += p_cb->ndef_rx_readlen;
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001507 p_msg_rsp->offset +=
1508 T3T_MSG_RSP_OFFSET_CHECK_DATA; /* Skip over t3t header (point to block
1509 data) */
1510 p_msg_rsp->len -= T3T_MSG_RSP_OFFSET_CHECK_DATA;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001511
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001512 /* Verify that the bytes received is really the amount indicated in the
1513 * check-response header */
1514 if (rsp_num_bytes_rx > p_msg_rsp->len) {
Ruchi Kandoi6767aec2017-09-26 09:46:26 -07001515 LOG(ERROR) << StringPrintf(
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001516 "Response error: CHECK rsp header indicates %i bytes, but only "
1517 "received %i bytes",
1518 rsp_num_bytes_rx, p_msg_rsp->len);
1519 nfc_status = NFC_STATUS_FAILED;
1520 GKI_freebuf(p_msg_rsp);
1521 } else {
1522 /* If this is the the final block, then set len to reflect only valid
1523 * bytes (do not include padding to 16-byte boundary) */
1524 if ((p_cb->flags & RW_T3T_FL_IS_FINAL_NDEF_SEGMENT) &&
1525 (p_cb->ndef_attrib.ln & 0x000F)) {
1526 rsp_num_bytes_rx -= (16 - (p_cb->ndef_attrib.ln & 0x000F));
1527 }
1528
1529 p_msg_rsp->len = rsp_num_bytes_rx;
Myles Watson1361d522017-09-26 13:39:54 -07001530 tRW_DATA rw_data;
1531 rw_data.data.status = NFC_STATUS_OK;
1532 rw_data.data.p_data = p_msg_rsp;
1533 (*(rw_cb.p_cback))(RW_T3T_CHECK_EVT, &rw_data);
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001534
1535 /* Send CHECK cmd for next NDEF segment, if needed */
1536 if (!(p_cb->flags & RW_T3T_FL_IS_FINAL_NDEF_SEGMENT)) {
Ruchi Kandoi0c515ae2017-01-30 17:48:41 -08001537 nfc_status = rw_t3t_send_next_ndef_check_cmd(p_cb);
1538 if (nfc_status == NFC_STATUS_OK) {
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001539 /* Still getting more segments. Don't send RW_T3T_CHECK_CPLT_EVT yet
1540 */
1541 check_complete = false;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001542 }
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001543 }
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001544 }
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001545 }
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001546
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001547 /* Notify app of RW_T3T_CHECK_CPLT_EVT if entire NDEF has been read, or if
1548 * failure */
1549 if (check_complete) {
1550 p_cb->rw_state = RW_T3T_STATE_IDLE;
Myles Watson1361d522017-09-26 13:39:54 -07001551 tRW_DATA evt_data;
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001552 evt_data.status = nfc_status;
Myles Watson1361d522017-09-26 13:39:54 -07001553 (*(rw_cb.p_cback))(RW_T3T_CHECK_CPLT_EVT, &evt_data);
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001554 }
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001555}
1556
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001557/*****************************************************************************
1558**
1559** Function rw_t3t_act_handle_update_ndef_rsp
1560**
1561** Description Handle response to NDEF write segment
1562**
1563** Returns Nothing
1564**
1565*****************************************************************************/
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001566void rw_t3t_act_handle_update_ndef_rsp(tRW_T3T_CB* p_cb, NFC_HDR* p_msg_rsp) {
1567 bool update_complete = true;
1568 tNFC_STATUS nfc_status = NFC_STATUS_OK;
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001569 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 -08001570
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001571 /* Check nfcid2 and status of response */
1572 if ((p_t3t_rsp[T3T_MSG_RSP_OFFSET_STATUS1] !=
1573 T3T_MSG_RSP_STATUS_OK) /* verify response status code */
1574 || (memcmp(p_cb->peer_nfcid2, &p_t3t_rsp[T3T_MSG_RSP_OFFSET_IDM],
1575 NCI_NFCID2_LEN) != 0)) /* verify response IDm */
1576 {
1577 nfc_status = NFC_STATUS_FAILED;
1578 }
1579 /* Validate response opcode */
1580 else if (p_t3t_rsp[T3T_MSG_RSP_OFFSET_RSPCODE] != T3T_MSG_OPC_UPDATE_RSP) {
Ruchi Kandoi6767aec2017-09-26 09:46:26 -07001581 LOG(ERROR) << StringPrintf(
1582 "Response error: expecting rsp_code %02X, but got %02X",
1583 T3T_MSG_OPC_UPDATE_RSP, p_t3t_rsp[T3T_MSG_RSP_OFFSET_RSPCODE]);
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001584 nfc_status = NFC_STATUS_FAILED;
1585 }
1586 /* If this is response to final UPDATE, then update NDEF local size */
1587 else if (p_cb->flags & RW_T3T_FL_IS_FINAL_NDEF_SEGMENT) {
1588 /* If successful, update current NDEF size */
1589 p_cb->ndef_attrib.ln = p_cb->ndef_msg_len;
1590 }
1591 /* If any more NDEF bytes to update, then send next UPDATE command */
1592 else if (p_cb->ndef_msg_bytes_sent < p_cb->ndef_msg_len) {
1593 /* Send UPDATE command for next segment of NDEF */
Ruchi Kandoi0c515ae2017-01-30 17:48:41 -08001594 nfc_status = rw_t3t_send_next_ndef_update_cmd(p_cb);
1595 if (nfc_status == NFC_STATUS_OK) {
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001596 /* Wait for update response */
1597 update_complete = false;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001598 }
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001599 }
1600 /* Otherwise, no more NDEF bytes. Send final UPDATE for Attribute Information
1601 block */
1602 else {
1603 p_cb->flags |= RW_T3T_FL_IS_FINAL_NDEF_SEGMENT;
Ruchi Kandoi0c515ae2017-01-30 17:48:41 -08001604 nfc_status = rw_t3t_send_update_ndef_attribute_cmd(p_cb, false);
1605 if (nfc_status == NFC_STATUS_OK) {
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001606 /* Wait for update response */
1607 update_complete = false;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001608 }
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001609 }
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001610
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001611 /* If update is completed, then notify app */
1612 if (update_complete) {
1613 p_cb->rw_state = RW_T3T_STATE_IDLE;
Myles Watson1361d522017-09-26 13:39:54 -07001614 tRW_DATA evt_data;
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001615 evt_data.status = nfc_status;
Myles Watson1361d522017-09-26 13:39:54 -07001616 (*(rw_cb.p_cback))(RW_T3T_UPDATE_CPLT_EVT, &evt_data);
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001617 }
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001618
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001619 GKI_freebuf(p_msg_rsp);
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001620
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001621 return;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001622}
1623
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001624/*****************************************************************************
1625**
1626** Function rw_t3t_handle_get_sc_poll_rsp
1627**
1628** Description Handle POLL response for getting system codes
1629**
1630** Returns Nothing
1631**
1632*****************************************************************************/
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001633static void rw_t3t_handle_get_sc_poll_rsp(tRW_T3T_CB* p_cb, uint8_t nci_status,
1634 uint8_t num_responses,
1635 uint8_t sensf_res_buf_size,
1636 uint8_t* p_sensf_res_buf) {
1637 uint8_t* p;
1638 uint16_t sc;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001639
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001640 /* Get the system code from the response */
1641 if ((nci_status == NCI_STATUS_OK) && (num_responses > 0) &&
1642 (sensf_res_buf_size >=
1643 (RW_T3T_SENSF_RES_RD_OFFSET + RW_T3T_SENSF_RES_RD_LEN))) {
1644 p = &p_sensf_res_buf[RW_T3T_SENSF_RES_RD_OFFSET];
1645 BE_STREAM_TO_UINT16(sc, p);
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001646
Ruchi Kandoi6767aec2017-09-26 09:46:26 -07001647 DLOG_IF(INFO, nfc_debug_enabled)
1648 << StringPrintf("FeliCa detected (RD, system code %04X)", sc);
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001649 p_cb->system_codes[p_cb->num_system_codes++] = sc;
1650 }
Yoshinobu Ito721b3ab2016-08-02 14:41:33 +09001651
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001652 rw_t3t_handle_get_system_codes_cplt();
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001653}
1654
1655/*****************************************************************************
1656**
1657** Function rw_t3t_handle_ndef_detect_poll_rsp
1658**
1659** Description Handle POLL response for getting system codes
1660**
1661** Returns Nothing
1662**
1663*****************************************************************************/
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001664static void rw_t3t_handle_ndef_detect_poll_rsp(tRW_T3T_CB* p_cb,
1665 uint8_t nci_status,
Ruchi Kandoi9ba6d242017-10-13 16:07:01 -07001666 uint8_t num_responses) {
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001667 NFC_HDR* p_cmd_buf;
1668 uint8_t *p, *p_cmd_start;
1669 tRW_DATA evt_data;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001670
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001671 /* Validate response for NDEF poll */
1672 if ((nci_status == NCI_STATUS_OK) && (num_responses > 0)) {
1673 /* Tag responded for NDEF poll */
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001674
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001675 /* Read NDEF attribute block */
Ruchi Kandoi0c515ae2017-01-30 17:48:41 -08001676 p_cmd_buf = rw_t3t_get_cmd_buf();
1677 if (p_cmd_buf != NULL) {
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001678 /* Construct T3T message */
1679 p = p_cmd_start = (uint8_t*)(p_cmd_buf + 1) + p_cmd_buf->offset;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001680
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001681 /* Add CHECK opcode to message */
1682 UINT8_TO_STREAM(p, T3T_MSG_OPC_CHECK_CMD);
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001683
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001684 /* Add IDm to message */
1685 ARRAY_TO_STREAM(p, p_cb->peer_nfcid2, NCI_NFCID2_LEN);
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001686
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001687 /* Add Service code list */
1688 UINT8_TO_STREAM(p, 1); /* Number of services (only 1 service: NDEF) */
1689 UINT16_TO_STREAM(
1690 p, T3T_MSG_NDEF_SC_RO); /* Service code (little-endian format) */
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001691
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001692 /* Number of blocks */
1693 UINT8_TO_STREAM(
1694 p,
1695 1); /* Number of blocks (only 1 block: NDEF Attribute Information ) */
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001696
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001697 /* Block List element: the NDEF attribute information block (block 0) */
1698 UINT8_TO_STREAM(p, T3T_MSG_MASK_TWO_BYTE_BLOCK_DESC_FORMAT);
1699 UINT8_TO_STREAM(p, 0);
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001700
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001701 /* Calculate length of message */
1702 p_cmd_buf->len = (uint16_t)(p - p_cmd_start);
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001703
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001704 /* Send the T3T message */
Ruchi Kandoi0c515ae2017-01-30 17:48:41 -08001705 evt_data.status = rw_t3t_send_cmd(p_cb, RW_T3T_CMD_DETECT_NDEF, p_cmd_buf,
1706 rw_t3t_check_timeout(1));
1707 if (evt_data.status == NFC_STATUS_OK) {
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001708 /* CHECK command sent. Wait for response */
1709 return;
1710 }
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001711 }
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001712 nci_status = NFC_STATUS_FAILED;
1713 }
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001714
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001715 /* NDEF detection failed */
1716 p_cb->rw_state = RW_T3T_STATE_IDLE;
1717 evt_data.ndef.status = nci_status;
1718 evt_data.ndef.flags = RW_NDEF_FL_UNKNOWN;
1719 rw_t3t_update_ndef_flag(&evt_data.ndef.flags);
1720 (*(rw_cb.p_cback))(RW_T3T_NDEF_DETECT_EVT, &evt_data);
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001721}
1722
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001723/*****************************************************************************
1724**
1725** Function rw_t3t_update_block
1726**
Martijn Coenen5c65c3a2013-03-27 13:23:36 -07001727** Description Send UPDATE command for single block
1728** (for formatting/configuring read only)
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001729**
1730** Returns tNFC_STATUS
1731**
1732*****************************************************************************/
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001733tNFC_STATUS rw_t3t_update_block(tRW_T3T_CB* p_cb, uint8_t block_id,
1734 uint8_t* p_block_data) {
1735 uint8_t *p_dst, *p_cmd_start;
1736 NFC_HDR* p_cmd_buf;
1737 tNFC_STATUS status;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001738
Ruchi Kandoi0c515ae2017-01-30 17:48:41 -08001739 p_cmd_buf = rw_t3t_get_cmd_buf();
1740 if (p_cmd_buf != NULL) {
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001741 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 -08001742
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001743 /* Add UPDATE opcode to message */
1744 UINT8_TO_STREAM(p_dst, T3T_MSG_OPC_UPDATE_CMD);
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001745
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001746 /* Add IDm to message */
1747 ARRAY_TO_STREAM(p_dst, p_cb->peer_nfcid2, NCI_NFCID2_LEN);
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001748
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001749 /* Add Service code list */
1750 UINT8_TO_STREAM(p_dst, 1); /* Number of services (only 1 service: NDEF) */
1751 UINT16_TO_STREAM(
1752 p_dst, T3T_MSG_NDEF_SC_RW); /* Service code (little-endian format) */
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001753
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001754 /* Number of blocks */
1755 UINT8_TO_STREAM(p_dst, 1);
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001756
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001757 /* Add Block list element for MC */
1758 UINT8_TO_STREAM(p_dst, T3T_MSG_MASK_TWO_BYTE_BLOCK_DESC_FORMAT);
1759 UINT8_TO_STREAM(p_dst, block_id);
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001760
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001761 /* Copy MC data to UPDATE message */
1762 ARRAY_TO_STREAM(p_dst, p_block_data, T3T_MSG_BLOCKSIZE);
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001763
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001764 /* Calculate length of message */
1765 p_cmd_buf->len = (uint16_t)(p_dst - p_cmd_start);
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001766
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001767 /* Send the T3T message */
1768 status = rw_t3t_send_cmd(p_cb, p_cb->cur_cmd, p_cmd_buf,
1769 rw_t3t_update_timeout(1));
1770 } else {
1771 /* Unable to send UPDATE command */
1772 status = NFC_STATUS_NO_BUFFERS;
1773 }
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001774
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001775 return (status);
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001776}
1777
1778/*****************************************************************************
1779**
1780** Function rw_t3t_handle_fmt_poll_rsp
1781**
1782** Description Handle POLL response for formatting felica-lite
1783**
1784** Returns Nothing
1785**
1786*****************************************************************************/
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001787static void rw_t3t_handle_fmt_poll_rsp(tRW_T3T_CB* p_cb, uint8_t nci_status,
Ruchi Kandoi9ba6d242017-10-13 16:07:01 -07001788 uint8_t num_responses) {
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001789 tRW_DATA evt_data;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001790
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001791 evt_data.status = NFC_STATUS_OK;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001792
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001793 /* Validate response for poll response */
1794 if ((nci_status == NCI_STATUS_OK) && (num_responses > 0)) {
1795 /* Tag responded for Felica-Lite poll */
1796 /* Get MemoryControl block */
Ruchi Kandoi6767aec2017-09-26 09:46:26 -07001797 DLOG_IF(INFO, nfc_debug_enabled) << StringPrintf(
1798 "Felica-Lite tag detected...getting Memory Control block.");
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001799
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001800 p_cb->rw_substate = RW_T3T_FMT_SST_CHECK_MC_BLK;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001801
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001802 /* Send command to check Memory Configuration block */
1803 evt_data.status = rw_t3t_check_mc_block(p_cb);
1804 } else {
Ruchi Kandoi6767aec2017-09-26 09:46:26 -07001805 LOG(ERROR) << StringPrintf("Felica-Lite tag not detected");
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001806 evt_data.status = NFC_STATUS_FAILED;
1807 }
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001808
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001809 /* If error, notify upper layer */
1810 if (evt_data.status != NFC_STATUS_OK) {
1811 rw_t3t_format_cplt(evt_data.status);
1812 }
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001813}
1814
1815/*****************************************************************************
1816**
1817** Function rw_t3t_act_handle_fmt_rsp
1818**
1819** Description Handle response for formatting codes
1820**
1821** Returns Nothing
1822**
1823*****************************************************************************/
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001824void rw_t3t_act_handle_fmt_rsp(tRW_T3T_CB* p_cb, NFC_HDR* p_msg_rsp) {
1825 uint8_t* p_t3t_rsp = (uint8_t*)(p_msg_rsp + 1) + p_msg_rsp->offset;
1826 uint8_t* p_mc;
1827 tRW_DATA evt_data;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001828
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001829 evt_data.status = NFC_STATUS_OK;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001830
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001831 /* Check tags's response for reading MemoryControl block */
1832 if (p_cb->rw_substate == RW_T3T_FMT_SST_CHECK_MC_BLK) {
1833 /* Validate response opcode */
1834 if (p_t3t_rsp[T3T_MSG_RSP_OFFSET_RSPCODE] != T3T_MSG_OPC_CHECK_RSP) {
Ruchi Kandoi6767aec2017-09-26 09:46:26 -07001835 LOG(ERROR) << StringPrintf(
1836 "Response error: expecting rsp_code %02X, but got %02X",
1837 T3T_MSG_OPC_CHECK_RSP, p_t3t_rsp[T3T_MSG_RSP_OFFSET_RSPCODE]);
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001838 evt_data.status = NFC_STATUS_FAILED;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001839 }
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001840 /* Validate status code and NFCID2 response from tag */
1841 else if ((p_t3t_rsp[T3T_MSG_RSP_OFFSET_STATUS1] !=
1842 T3T_MSG_RSP_STATUS_OK) /* verify response status code */
1843 || (memcmp(p_cb->peer_nfcid2, &p_t3t_rsp[T3T_MSG_RSP_OFFSET_IDM],
1844 NCI_NFCID2_LEN) != 0)) /* verify response IDm */
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001845 {
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001846 evt_data.status = NFC_STATUS_FAILED;
Ruchi Kandoi32592772019-01-07 17:36:52 -08001847 } else if (p_msg_rsp->len <
1848 (T3T_MSG_RSP_OFFSET_CHECK_DATA + T3T_MSG_BLOCKSIZE)) {
1849 evt_data.status = NFC_STATUS_FAILED;
1850 android_errorWriteLog(0x534e4554, "120506143");
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001851 } else {
1852 /* Check if memory configuration (MC) block to see if SYS_OP=1 (NDEF
1853 * enabled) */
1854 p_mc = &p_t3t_rsp[T3T_MSG_RSP_OFFSET_CHECK_DATA]; /* Point to MC data of
1855 CHECK response */
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001856
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001857 if (p_mc[T3T_MSG_FELICALITE_MC_OFFSET_SYS_OP] != 0x01) {
1858 /* Tag is not currently enabled for NDEF. Indicate that we need to
1859 * update the MC block */
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001860
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001861 /* Set SYS_OP field to 0x01 (enable NDEF) */
1862 p_mc[T3T_MSG_FELICALITE_MC_OFFSET_SYS_OP] = 0x01;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001863
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001864 /* Set RF_PRM field to 0x07 (procedure of issuance) */
1865 p_mc[T3T_MSG_FELICALITE_MC_OFFSET_RF_PRM] = 0x07;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001866
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001867 /* Construct and send UPDATE message to write MC block */
1868 p_cb->rw_substate = RW_T3T_FMT_SST_UPDATE_MC_BLK;
1869 evt_data.status =
1870 rw_t3t_update_block(p_cb, T3T_MSG_FELICALITE_BLOCK_ID_MC, p_mc);
1871 } else {
1872 /* SYS_OP=1: ndef already enabled. Just need to update attribute
1873 * information block */
1874 p_cb->rw_substate = RW_T3T_FMT_SST_UPDATE_NDEF_ATTRIB;
1875 evt_data.status =
1876 rw_t3t_update_block(p_cb, 0, (uint8_t*)rw_t3t_default_attrib_info);
1877 }
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001878 }
1879
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001880 /* If error, notify upper layer */
1881 if (evt_data.status != NFC_STATUS_OK) {
1882 rw_t3t_format_cplt(evt_data.status);
1883 }
1884 } else if (p_cb->rw_substate == RW_T3T_FMT_SST_UPDATE_MC_BLK) {
1885 /* Validate response opcode */
1886 if ((p_t3t_rsp[T3T_MSG_RSP_OFFSET_RSPCODE] != T3T_MSG_OPC_UPDATE_RSP) ||
1887 (p_t3t_rsp[T3T_MSG_RSP_OFFSET_STATUS1] != T3T_MSG_RSP_STATUS_OK))
1888
1889 {
Ruchi Kandoi6767aec2017-09-26 09:46:26 -07001890 LOG(ERROR) << StringPrintf("Response error: rsp_code=%02X, status=%02X",
1891 p_t3t_rsp[T3T_MSG_RSP_OFFSET_RSPCODE],
1892 p_t3t_rsp[T3T_MSG_RSP_OFFSET_STATUS1]);
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001893 evt_data.status = NFC_STATUS_FAILED;
1894 } else {
1895 /* SYS_OP=1: ndef already enabled. Just need to update attribute
1896 * information block */
1897 p_cb->rw_substate = RW_T3T_FMT_SST_UPDATE_NDEF_ATTRIB;
1898 evt_data.status =
1899 rw_t3t_update_block(p_cb, 0, (uint8_t*)rw_t3t_default_attrib_info);
1900 }
1901
1902 /* If error, notify upper layer */
1903 if (evt_data.status != NFC_STATUS_OK) {
1904 rw_t3t_format_cplt(evt_data.status);
1905 }
1906 } else if (p_cb->rw_substate == RW_T3T_FMT_SST_UPDATE_NDEF_ATTRIB) {
1907 /* Validate response opcode */
1908 if ((p_t3t_rsp[T3T_MSG_RSP_OFFSET_RSPCODE] != T3T_MSG_OPC_UPDATE_RSP) ||
1909 (p_t3t_rsp[T3T_MSG_RSP_OFFSET_STATUS1] != T3T_MSG_RSP_STATUS_OK))
1910
1911 {
Ruchi Kandoi6767aec2017-09-26 09:46:26 -07001912 LOG(ERROR) << StringPrintf("Response error: rsp_code=%02X, status=%02X",
1913 p_t3t_rsp[T3T_MSG_RSP_OFFSET_RSPCODE],
1914 p_t3t_rsp[T3T_MSG_RSP_OFFSET_STATUS1]);
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001915 evt_data.status = NFC_STATUS_FAILED;
1916 }
1917
1918 rw_t3t_format_cplt(evt_data.status);
1919 }
1920
1921 GKI_freebuf(p_msg_rsp);
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001922}
1923
Martijn Coenen5c65c3a2013-03-27 13:23:36 -07001924/*****************************************************************************
1925**
1926** Function rw_t3t_handle_sro_poll_rsp
1927**
1928** Description Handle POLL response for configuring felica-lite read only
1929**
1930** Returns Nothing
1931**
1932*****************************************************************************/
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001933static void rw_t3t_handle_sro_poll_rsp(tRW_T3T_CB* p_cb, uint8_t nci_status,
Ruchi Kandoi9ba6d242017-10-13 16:07:01 -07001934 uint8_t num_responses) {
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001935 tRW_DATA evt_data;
1936 uint8_t rw_t3t_ndef_attrib_info[T3T_MSG_BLOCKSIZE];
1937 uint8_t* p;
1938 uint8_t tempU8;
1939 uint16_t checksum, i;
1940 uint32_t tempU32 = 0;
Martijn Coenen5c65c3a2013-03-27 13:23:36 -07001941
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001942 evt_data.status = NFC_STATUS_OK;
Martijn Coenen5c65c3a2013-03-27 13:23:36 -07001943
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001944 /* Validate response for poll response */
1945 if ((nci_status == NCI_STATUS_OK) && (num_responses > 0)) {
1946 /* Tag responded for Felica-Lite poll */
1947 if (p_cb->ndef_attrib.rwflag != T3T_MSG_NDEF_RWFLAG_RO) {
1948 /* First update attribute information block */
Ruchi Kandoi6767aec2017-09-26 09:46:26 -07001949 DLOG_IF(INFO, nfc_debug_enabled) << StringPrintf(
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001950 "Felica-Lite tag detected...update NDef attribution block.");
Martijn Coenen5c65c3a2013-03-27 13:23:36 -07001951
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001952 p_cb->rw_substate = RW_T3T_SRO_SST_UPDATE_NDEF_ATTRIB;
Martijn Coenen5c65c3a2013-03-27 13:23:36 -07001953
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001954 p = rw_t3t_ndef_attrib_info;
Martijn Coenen5c65c3a2013-03-27 13:23:36 -07001955
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001956 UINT8_TO_STREAM(p, p_cb->ndef_attrib.version);
Martijn Coenen5c65c3a2013-03-27 13:23:36 -07001957
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001958 /* Update NDEF info */
1959 UINT8_TO_STREAM(
1960 p, p_cb->ndef_attrib.nbr); /* NBr: number of blocks that can be read
1961 using one Check command */
1962 UINT8_TO_STREAM(p, p_cb->ndef_attrib.nbw); /* Nbw: number of blocks that
1963 can be written using one
1964 Update command */
1965 UINT16_TO_BE_STREAM(
1966 p, p_cb->ndef_attrib.nmaxb); /* Nmaxb: maximum number of blocks
1967 available for NDEF data */
1968 UINT32_TO_BE_STREAM(p, tempU32);
1969 UINT8_TO_STREAM(p,
1970 p_cb->ndef_attrib.writef); /* WriteFlag: 00h if writing
1971 data finished; 0Fh if
1972 writing data in progress */
1973 UINT8_TO_STREAM(p, 0x00); /* RWFlag: 00h NDEF is read-only */
Martijn Coenen5c65c3a2013-03-27 13:23:36 -07001974
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001975 tempU8 = (uint8_t)(p_cb->ndef_attrib.ln >> 16);
1976 /* Get length (3-byte, big-endian) */
1977 UINT8_TO_STREAM(p, tempU8); /* Ln: high-byte */
1978 UINT16_TO_BE_STREAM(p, p_cb->ndef_attrib.ln); /* Ln: lo-word */
Martijn Coenen5c65c3a2013-03-27 13:23:36 -07001979
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001980 /* Calculate and append Checksum */
1981 checksum = 0;
1982 for (i = 0; i < T3T_MSG_NDEF_ATTR_INFO_SIZE; i++) {
1983 checksum += rw_t3t_ndef_attrib_info[i];
1984 }
1985 UINT16_TO_BE_STREAM(p, checksum);
Martijn Coenen5c65c3a2013-03-27 13:23:36 -07001986
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001987 evt_data.status =
1988 rw_t3t_update_block(p_cb, 0, (uint8_t*)rw_t3t_ndef_attrib_info);
1989 } else if (p_cb->cur_cmd == RW_T3T_CMD_SET_READ_ONLY_HARD) {
1990 /* NDEF is already read only, Read and update MemoryControl block */
Ruchi Kandoi6767aec2017-09-26 09:46:26 -07001991 DLOG_IF(INFO, nfc_debug_enabled) << StringPrintf(
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001992 "Felica-Lite tag detected...getting Memory Control block.");
1993 p_cb->rw_substate = RW_T3T_SRO_SST_CHECK_MC_BLK;
Martijn Coenen5c65c3a2013-03-27 13:23:36 -07001994
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001995 /* Send command to check Memory Configuration block */
1996 evt_data.status = rw_t3t_check_mc_block(p_cb);
Martijn Coenen5c65c3a2013-03-27 13:23:36 -07001997 }
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001998 } else {
Ruchi Kandoi6767aec2017-09-26 09:46:26 -07001999 LOG(ERROR) << StringPrintf("Felica-Lite tag not detected");
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002000 evt_data.status = NFC_STATUS_FAILED;
2001 }
Martijn Coenen5c65c3a2013-03-27 13:23:36 -07002002
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002003 /* If error, notify upper layer */
2004 if (evt_data.status != NFC_STATUS_OK) {
2005 rw_t3t_set_readonly_cplt(evt_data.status);
2006 }
Martijn Coenen5c65c3a2013-03-27 13:23:36 -07002007}
2008
2009/*****************************************************************************
2010**
2011** Function rw_t3t_act_handle_sro_rsp
2012**
2013** Description Handle response for setting read only codes
2014**
2015** Returns Nothing
2016**
2017*****************************************************************************/
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002018void rw_t3t_act_handle_sro_rsp(tRW_T3T_CB* p_cb, NFC_HDR* p_msg_rsp) {
2019 uint8_t* p_t3t_rsp = (uint8_t*)(p_msg_rsp + 1) + p_msg_rsp->offset;
2020 uint8_t* p_mc;
2021 tRW_DATA evt_data;
Martijn Coenen5c65c3a2013-03-27 13:23:36 -07002022
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002023 evt_data.status = NFC_STATUS_OK;
Martijn Coenen5c65c3a2013-03-27 13:23:36 -07002024
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002025 if (p_cb->rw_substate == RW_T3T_SRO_SST_UPDATE_NDEF_ATTRIB) {
2026 /* Validate response opcode */
2027 if ((p_t3t_rsp[T3T_MSG_RSP_OFFSET_RSPCODE] != T3T_MSG_OPC_UPDATE_RSP) ||
2028 (p_t3t_rsp[T3T_MSG_RSP_OFFSET_STATUS1] != T3T_MSG_RSP_STATUS_OK))
2029
Martijn Coenen5c65c3a2013-03-27 13:23:36 -07002030 {
Ruchi Kandoi6767aec2017-09-26 09:46:26 -07002031 LOG(ERROR) << StringPrintf("Response error: rsp_code=%02X, status=%02X",
2032 p_t3t_rsp[T3T_MSG_RSP_OFFSET_RSPCODE],
2033 p_t3t_rsp[T3T_MSG_RSP_OFFSET_STATUS1]);
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002034 evt_data.status = NFC_STATUS_FAILED;
2035 } else {
2036 p_cb->ndef_attrib.rwflag = T3T_MSG_NDEF_RWFLAG_RO;
2037 if (p_cb->cur_cmd == RW_T3T_CMD_SET_READ_ONLY_HARD) {
2038 p_cb->rw_substate = RW_T3T_SRO_SST_CHECK_MC_BLK;
Martijn Coenen5c65c3a2013-03-27 13:23:36 -07002039
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002040 /* Send command to check Memory Configuration block */
2041 evt_data.status = rw_t3t_check_mc_block(p_cb);
2042 } else {
2043 rw_t3t_set_readonly_cplt(evt_data.status);
2044 }
Martijn Coenen5c65c3a2013-03-27 13:23:36 -07002045 }
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002046 } else if (p_cb->rw_substate == RW_T3T_SRO_SST_CHECK_MC_BLK) {
2047 /* Check tags's response for reading MemoryControl block, Validate response
2048 * opcode */
2049 if (p_t3t_rsp[T3T_MSG_RSP_OFFSET_RSPCODE] != T3T_MSG_OPC_CHECK_RSP) {
Ruchi Kandoi6767aec2017-09-26 09:46:26 -07002050 LOG(ERROR) << StringPrintf(
2051 "Response error: expecting rsp_code %02X, but got %02X",
2052 T3T_MSG_OPC_CHECK_RSP, p_t3t_rsp[T3T_MSG_RSP_OFFSET_RSPCODE]);
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002053 evt_data.status = NFC_STATUS_FAILED;
2054 }
2055 /* Validate status code and NFCID2 response from tag */
2056 else if ((p_t3t_rsp[T3T_MSG_RSP_OFFSET_STATUS1] !=
2057 T3T_MSG_RSP_STATUS_OK) /* verify response status code */
2058 || (memcmp(p_cb->peer_nfcid2, &p_t3t_rsp[T3T_MSG_RSP_OFFSET_IDM],
2059 NCI_NFCID2_LEN) != 0)) /* verify response IDm */
Martijn Coenen5c65c3a2013-03-27 13:23:36 -07002060 {
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002061 evt_data.status = NFC_STATUS_FAILED;
Ruchi Kandoi32592772019-01-07 17:36:52 -08002062 } else if (p_msg_rsp->len <
2063 (T3T_MSG_RSP_OFFSET_CHECK_DATA + T3T_MSG_BLOCKSIZE)) {
2064 evt_data.status = NFC_STATUS_FAILED;
2065 android_errorWriteLog(0x534e4554, "120506143");
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002066 } else {
2067 /* Check if memory configuration (MC) block to see if SYS_OP=1 (NDEF
2068 * enabled) */
2069 p_mc = &p_t3t_rsp[T3T_MSG_RSP_OFFSET_CHECK_DATA]; /* Point to MC data of
2070 CHECK response */
Martijn Coenen5c65c3a2013-03-27 13:23:36 -07002071
Ruchi Kandoi32592772019-01-07 17:36:52 -08002072 evt_data.status = NFC_STATUS_FAILED;
2073 if (p_mc[T3T_MSG_FELICALITE_MC_OFFSET_SYS_OP] == 0x01) {
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002074 /* Set MC_SP field with MC[0] = 0x00 & MC[1] = 0xC0 (Hardlock) to change
2075 * access permission from RW to RO */
2076 p_mc[T3T_MSG_FELICALITE_MC_OFFSET_MC_SP] = 0x00;
2077 /* Not changing the access permission of Subtraction Register and
2078 * MC[0:1] */
2079 p_mc[T3T_MSG_FELICALITE_MC_OFFSET_MC_SP + 1] = 0xC0;
Martijn Coenen5c65c3a2013-03-27 13:23:36 -07002080
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002081 /* Set RF_PRM field to 0x07 (procedure of issuance) */
2082 p_mc[T3T_MSG_FELICALITE_MC_OFFSET_RF_PRM] = 0x07;
Martijn Coenen5c65c3a2013-03-27 13:23:36 -07002083
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002084 /* Construct and send UPDATE message to write MC block */
2085 p_cb->rw_substate = RW_T3T_SRO_SST_UPDATE_MC_BLK;
2086 evt_data.status =
2087 rw_t3t_update_block(p_cb, T3T_MSG_FELICALITE_BLOCK_ID_MC, p_mc);
2088 }
Martijn Coenen5c65c3a2013-03-27 13:23:36 -07002089 }
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002090 } else if (p_cb->rw_substate == RW_T3T_SRO_SST_UPDATE_MC_BLK) {
2091 /* Validate response opcode */
2092 if ((p_t3t_rsp[T3T_MSG_RSP_OFFSET_RSPCODE] != T3T_MSG_OPC_UPDATE_RSP) ||
2093 (p_t3t_rsp[T3T_MSG_RSP_OFFSET_STATUS1] != T3T_MSG_RSP_STATUS_OK))
2094
Martijn Coenen5c65c3a2013-03-27 13:23:36 -07002095 {
Ruchi Kandoi6767aec2017-09-26 09:46:26 -07002096 LOG(ERROR) << StringPrintf("Response error: rsp_code=%02X, status=%02X",
2097 p_t3t_rsp[T3T_MSG_RSP_OFFSET_RSPCODE],
2098 p_t3t_rsp[T3T_MSG_RSP_OFFSET_STATUS1]);
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002099 evt_data.status = NFC_STATUS_FAILED;
2100 } else {
2101 rw_t3t_set_readonly_cplt(evt_data.status);
Martijn Coenen5c65c3a2013-03-27 13:23:36 -07002102 }
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002103 }
Martijn Coenen5c65c3a2013-03-27 13:23:36 -07002104
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002105 /* If error, notify upper layer */
2106 if (evt_data.status != NFC_STATUS_OK) {
2107 rw_t3t_set_readonly_cplt(evt_data.status);
2108 }
Martijn Coenen5c65c3a2013-03-27 13:23:36 -07002109
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002110 GKI_freebuf(p_msg_rsp);
Martijn Coenen5c65c3a2013-03-27 13:23:36 -07002111}
2112
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002113/*******************************************************************************
2114**
2115** Function rw_t3t_data_cback
2116**
2117** Description This callback function receives the data from NFCC.
2118**
2119** Returns none
2120**
2121*******************************************************************************/
Ruchi Kandoi9ba6d242017-10-13 16:07:01 -07002122void rw_t3t_data_cback(__attribute__((unused)) uint8_t conn_id,
2123 tNFC_DATA_CEVT* p_data) {
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002124 tRW_T3T_CB* p_cb = &rw_cb.tcb.t3t;
2125 NFC_HDR* p_msg = p_data->p_data;
2126 bool free_msg = false; /* if TRUE, free msg buffer before returning */
2127 uint8_t *p, sod;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002128
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002129 /* Stop rsponse timer */
2130 nfc_stop_quick_timer(&p_cb->timer);
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002131
Ruchi Kandoi303fec12016-12-14 13:22:38 -08002132#if (RW_STATS_INCLUDED == TRUE)
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002133 /* Update rx stats */
2134 rw_main_update_rx_stats(p_msg->len);
2135#endif /* RW_STATS_INCLUDED */
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002136
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002137 /* Check if we are expecting a response */
2138 if (p_cb->rw_state != RW_T3T_STATE_COMMAND_PENDING) {
2139 /*
2140 ** This must be raw frame response
2141 ** send raw frame to app with SoD
2142 */
2143 rw_t3t_act_handle_raw_senddata_rsp(p_cb, p_data);
2144 }
2145 /* Sanity check: verify msg len is big enough to contain t3t header */
2146 else if (p_msg->len < T3T_MSG_RSP_COMMON_HDR_LEN) {
Ruchi Kandoi6767aec2017-09-26 09:46:26 -07002147 LOG(ERROR) << StringPrintf(
2148 "T3T: invalid Type3 Tag Message (invalid len: %i)", p_msg->len);
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002149 free_msg = true;
2150
2151 rw_t3t_process_frame_error();
2152 } else {
2153 /* Check for RF frame error */
2154 p = (uint8_t*)(p_msg + 1) + p_msg->offset;
2155 sod = p[0];
2156 if (p[sod] != NCI_STATUS_OK) {
Ruchi Kandoi6767aec2017-09-26 09:46:26 -07002157 LOG(ERROR) << StringPrintf("T3T: rf frame error (crc status=%i)", p[sod]);
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002158 GKI_freebuf(p_msg);
2159
2160 rw_t3t_process_frame_error();
2161 return;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002162 }
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002163
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002164 /* Skip over SoD */
2165 p_msg->offset++;
2166 p_msg->len--;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002167
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002168 /* Get response code */
2169 switch (p_cb->cur_cmd) {
2170 case RW_T3T_CMD_DETECT_NDEF:
2171 rw_t3t_act_handle_ndef_detect_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_CHECK_NDEF:
2175 rw_t3t_act_handle_check_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_UPDATE_NDEF:
2179 rw_t3t_act_handle_update_ndef_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_CHECK:
2183 rw_t3t_act_handle_check_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_UPDATE:
2187 rw_t3t_act_handle_update_rsp(p_cb, p_msg);
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_SEND_RAW_FRAME:
2191 rw_t3t_act_handle_raw_senddata_rsp(p_cb, p_data);
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_FORMAT:
2195 rw_t3t_act_handle_fmt_rsp(p_cb, p_msg);
2196 break;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002197
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002198 case RW_T3T_CMD_SET_READ_ONLY_SOFT:
2199 case RW_T3T_CMD_SET_READ_ONLY_HARD:
2200 rw_t3t_act_handle_sro_rsp(p_cb, p_msg);
2201 break;
Martijn Coenen5c65c3a2013-03-27 13:23:36 -07002202
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002203 default:
2204 GKI_freebuf(p_msg);
2205 break;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002206 }
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002207 }
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002208
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002209 if (free_msg) {
2210 GKI_freebuf(p_msg);
2211 }
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002212}
2213
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002214/*******************************************************************************
2215**
2216** Function rw_t3t_conn_cback
2217**
2218** Description This callback function receives the events/data from NFCC.
2219**
2220** Returns none
2221**
2222*******************************************************************************/
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002223void rw_t3t_conn_cback(uint8_t conn_id, tNFC_CONN_EVT event,
2224 tNFC_CONN* p_data) {
2225 tRW_T3T_CB* p_cb = &rw_cb.tcb.t3t;
Ruchi Kandoi6767aec2017-09-26 09:46:26 -07002226 DLOG_IF(INFO, nfc_debug_enabled) << StringPrintf(
2227 "rw_t3t_conn_cback: conn_id=%i, evt=0x%02x", conn_id, event);
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002228
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002229 /* Only handle NFC_RF_CONN_ID conn_id */
2230 if (conn_id != NFC_RF_CONN_ID) {
2231 return;
2232 }
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002233
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002234 switch (event) {
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002235 case NFC_DEACTIVATE_CEVT:
Ruchi Kandoi9ba6d242017-10-13 16:07:01 -07002236 rw_t3t_unselect();
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002237 break;
2238
2239 case NFC_DATA_CEVT: /* check for status in tNFC_CONN */
2240 if ((p_data != NULL) && ((p_data->data.status == NFC_STATUS_OK) ||
2241 (p_data->data.status == NFC_STATUS_CONTINUE))) {
2242 rw_t3t_data_cback(conn_id, &(p_data->data));
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002243 break;
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002244 } else if (p_data->data.p_data != NULL) {
2245 /* Free the response buffer in case of error response */
2246 GKI_freebuf((NFC_HDR*)(p_data->data.p_data));
2247 p_data->data.p_data = NULL;
2248 }
2249 /* Data event with error status...fall through to NFC_ERROR_CEVT case */
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002250
2251 case NFC_ERROR_CEVT:
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002252 nfc_stop_quick_timer(&p_cb->timer);
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002253
Ruchi Kandoi303fec12016-12-14 13:22:38 -08002254#if (RW_STATS_INCLUDED == TRUE)
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002255 rw_main_update_trans_error_stats();
2256#endif /* RW_STATS_INCLUDED */
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002257
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002258 if (event == NFC_ERROR_CEVT)
2259 rw_t3t_process_error(NFC_STATUS_TIMEOUT);
2260 else if (p_data)
2261 rw_t3t_process_error(p_data->status);
2262 break;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002263
2264 default:
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002265 break;
2266 }
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002267}
2268
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002269/*******************************************************************************
2270**
Sherry Smith818b56e2014-05-14 16:46:32 -07002271** Function rw_t3t_mrti_to_a_b
2272**
2273** Description Converts the given MRTI (Maximum Response Time Information)
2274** to the base to calculate timeout value.
2275** (The timeout value is a + b * number_blocks)
2276**
2277** Returns NFC_STATUS_OK
2278**
2279*******************************************************************************/
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002280static void rw_t3t_mrti_to_a_b(uint8_t mrti, uint32_t* p_a, uint32_t* p_b) {
2281 uint8_t a, b, e;
Sherry Smith818b56e2014-05-14 16:46:32 -07002282
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002283 a = (mrti & 0x7) + 1; /* A is bit 0 ~ bit 2 */
2284 mrti >>= 3;
2285 b = (mrti & 0x7) + 1; /* B is bit 3 ~ bit 5 */
2286 mrti >>= 3;
2287 e = mrti & 0x3; /* E is bit 6 ~ bit 7 */
2288 *p_a = rw_t3t_mrti_base[e] * a; /* (A+1) * base (i.e T/t3t * 4^E) */
2289 *p_b = rw_t3t_mrti_base[e] * b; /* (B+1) * base (i.e T/t3t * 4^E) */
Sherry Smith818b56e2014-05-14 16:46:32 -07002290}
2291
Sherry Smith818b56e2014-05-14 16:46:32 -07002292/*******************************************************************************
2293**
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002294** Function rw_t3t_select
2295**
2296** Description Called by NFC manager when a Type3 tag has been activated
2297**
2298** Returns NFC_STATUS_OK
2299**
2300*******************************************************************************/
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002301tNFC_STATUS rw_t3t_select(uint8_t peer_nfcid2[NCI_RF_F_UID_LEN],
2302 uint8_t mrti_check, uint8_t mrti_update) {
2303 tRW_T3T_CB* p_cb = &rw_cb.tcb.t3t;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002304
Ruchi Kandoi6767aec2017-09-26 09:46:26 -07002305 DLOG_IF(INFO, nfc_debug_enabled) << __func__;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002306
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002307 memcpy(p_cb->peer_nfcid2, peer_nfcid2,
2308 NCI_NFCID2_LEN); /* Store tag's NFCID2 */
2309 p_cb->ndef_attrib.status =
2310 NFC_STATUS_NOT_INITIALIZED; /* Indicate that NDEF detection has not been
2311 performed yet */
2312 p_cb->rw_state = RW_T3T_STATE_IDLE;
2313 p_cb->flags = 0;
2314 rw_t3t_mrti_to_a_b(mrti_check, &p_cb->check_tout_a, &p_cb->check_tout_b);
2315 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 -08002316
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002317 /* Alloc cmd buf for retransmissions */
2318 if (p_cb->p_cur_cmd_buf == NULL) {
Ruchi Kandoi0c515ae2017-01-30 17:48:41 -08002319 p_cb->p_cur_cmd_buf = (NFC_HDR*)GKI_getpoolbuf(NFC_RW_POOL_ID);
2320 if (p_cb->p_cur_cmd_buf == NULL) {
Ruchi Kandoi6767aec2017-09-26 09:46:26 -07002321 LOG(ERROR) << StringPrintf(
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002322 "rw_t3t_select: unable to allocate buffer for retransmission");
2323 p_cb->rw_state = RW_T3T_STATE_NOT_ACTIVATED;
2324 return (NFC_STATUS_FAILED);
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002325 }
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002326 }
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002327
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002328 NFC_SetStaticRfCback(rw_t3t_conn_cback);
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002329
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002330 return NFC_STATUS_OK;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002331}
2332
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002333/*******************************************************************************
2334**
2335** Function rw_t3t_unselect
2336**
2337** Description Called by NFC manager when a Type3 tag has been de-activated
2338**
2339** Returns NFC_STATUS_OK
2340**
2341*******************************************************************************/
Ruchi Kandoi9ba6d242017-10-13 16:07:01 -07002342static tNFC_STATUS rw_t3t_unselect() {
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002343 tRW_T3T_CB* p_cb = &rw_cb.tcb.t3t;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002344
Ruchi Kandoi303fec12016-12-14 13:22:38 -08002345#if (RW_STATS_INCLUDED == TRUE)
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002346 /* Display stats */
2347 rw_main_log_stats();
2348#endif /* RW_STATS_INCLUDED */
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002349
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002350 /* Stop t3t timer (if started) */
2351 nfc_stop_quick_timer(&p_cb->timer);
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002352
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002353 /* Free cmd buf for retransmissions */
2354 if (p_cb->p_cur_cmd_buf) {
2355 GKI_freebuf(p_cb->p_cur_cmd_buf);
2356 p_cb->p_cur_cmd_buf = NULL;
2357 }
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002358
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002359 p_cb->rw_state = RW_T3T_STATE_NOT_ACTIVATED;
2360 NFC_SetStaticRfCback(NULL);
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002361
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002362 return NFC_STATUS_OK;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002363}
2364
Evan Chua24be4f2013-11-13 15:30:16 -05002365/*******************************************************************************
2366**
2367** Function rw_t3t_update_ndef_flag
2368**
2369** Description set additional NDEF Flags for felica lite tag
2370**
2371** Returns updated NDEF Flag value
2372**
2373*******************************************************************************/
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002374static void rw_t3t_update_ndef_flag(uint8_t* p_flag) {
2375 tRW_T3T_CB* p_cb = &rw_cb.tcb.t3t;
2376 uint8_t xx;
Evan Chua24be4f2013-11-13 15:30:16 -05002377
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002378 for (xx = 0; xx < p_cb->num_system_codes; xx++) {
2379 if (p_cb->system_codes[xx] == T3T_SYSTEM_CODE_FELICA_LITE) {
2380 *p_flag &= ~RW_NDEF_FL_UNKNOWN;
2381 *p_flag |= (RW_NDEF_FL_SUPPORTED | RW_NDEF_FL_FORMATABLE);
2382 break;
Evan Chua24be4f2013-11-13 15:30:16 -05002383 }
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002384 }
Evan Chua24be4f2013-11-13 15:30:16 -05002385}
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002386
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002387/*******************************************************************************
2388**
2389** Function rw_t3t_cmd_str
2390**
2391** Description Converts cmd_id to command string for logging
2392**
2393** Returns command string
2394**
2395*******************************************************************************/
Ruchi Kandoi7dab0e52017-08-03 13:09:49 -07002396static std::string rw_t3t_cmd_str(uint8_t cmd_id) {
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002397 switch (cmd_id) {
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002398 case RW_T3T_CMD_DETECT_NDEF:
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002399 return "RW_T3T_CMD_DETECT_NDEF";
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002400 case RW_T3T_CMD_CHECK_NDEF:
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002401 return "RW_T3T_CMD_CHECK_NDEF";
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002402 case RW_T3T_CMD_UPDATE_NDEF:
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002403 return "RW_T3T_CMD_UPDATE_NDEF";
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002404 case RW_T3T_CMD_CHECK:
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002405 return "RW_T3T_CMD_CHECK";
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002406 case RW_T3T_CMD_UPDATE:
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002407 return "RW_T3T_CMD_UPDATE";
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002408 case RW_T3T_CMD_SEND_RAW_FRAME:
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002409 return "RW_T3T_CMD_SEND_RAW_FRAME";
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002410 case RW_T3T_CMD_GET_SYSTEM_CODES:
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002411 return "RW_T3T_CMD_GET_SYSTEM_CODES";
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002412 default:
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002413 return "Unknown";
2414 }
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002415}
2416
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002417/*******************************************************************************
2418**
2419** Function rw_t3t_state_str
2420**
2421** Description Converts state_id to command string for logging
2422**
2423** Returns command string
2424**
2425*******************************************************************************/
Ruchi Kandoi7dab0e52017-08-03 13:09:49 -07002426static std::string rw_t3t_state_str(uint8_t state_id) {
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002427 switch (state_id) {
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002428 case RW_T3T_STATE_NOT_ACTIVATED:
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002429 return "RW_T3T_STATE_NOT_ACTIVATED";
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002430 case RW_T3T_STATE_IDLE:
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002431 return "RW_T3T_STATE_IDLE";
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002432 case RW_T3T_STATE_COMMAND_PENDING:
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002433 return "RW_T3T_STATE_COMMAND_PENDING";
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002434 default:
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002435 return "Unknown";
2436 }
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002437}
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002438
2439/*****************************************************************************
2440** Type3 Tag API Functions
2441*****************************************************************************/
2442
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002443/*****************************************************************************
2444**
2445** Function RW_T3tDetectNDef
2446**
2447** Description
2448** This function is used to perform NDEF detection on a Type 3 tag, and
2449** retrieve the tag's NDEF attribute information (block 0).
2450**
2451** Before using this API, the application must call RW_SelectTagType to
2452** indicate that a Type 3 tag has been activated, and to provide the
2453** tag's Manufacture ID (IDm) .
2454**
2455** Returns
2456** NFC_STATUS_OK: ndef detection procedure started
2457** NFC_STATUS_NO_BUFFERS: unable to allocate a buffer for this operation
2458** NFC_STATUS_FAILED: other error
2459**
2460*****************************************************************************/
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002461tNFC_STATUS RW_T3tDetectNDef(void) {
2462 tRW_T3T_CB* p_cb = &rw_cb.tcb.t3t;
2463 tNFC_STATUS retval = NFC_STATUS_OK;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002464
Ruchi Kandoi6767aec2017-09-26 09:46:26 -07002465 DLOG_IF(INFO, nfc_debug_enabled) << __func__;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002466
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002467 /* Check if we are in valid state to handle this API */
2468 if (p_cb->rw_state != RW_T3T_STATE_IDLE) {
Ruchi Kandoi6767aec2017-09-26 09:46:26 -07002469 LOG(ERROR) << StringPrintf("Error: invalid state to handle API (0x%x)",
2470 p_cb->rw_state);
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002471 return (NFC_STATUS_FAILED);
2472 }
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002473
Ruchi Kandoi0c515ae2017-01-30 17:48:41 -08002474 retval = (tNFC_STATUS)nci_snd_t3t_polling(T3T_SYSTEM_CODE_NDEF, 0, 0);
2475 if (retval == NCI_STATUS_OK) {
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002476 p_cb->cur_cmd = RW_T3T_CMD_DETECT_NDEF;
2477 p_cb->cur_tout = RW_T3T_DEFAULT_CMD_TIMEOUT_TICKS;
2478 p_cb->cur_poll_rc = 0;
2479 p_cb->rw_state = RW_T3T_STATE_COMMAND_PENDING;
2480 p_cb->flags |= RW_T3T_FL_W4_NDEF_DETECT_POLL_RSP;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002481
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002482 /* start timer for waiting for responses */
2483 rw_t3t_start_poll_timer(p_cb);
2484 }
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002485
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002486 return (retval);
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002487}
2488
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002489/*****************************************************************************
2490**
2491** Function RW_T3tCheckNDef
2492**
2493** Description
2494** Retrieve NDEF contents from a Type3 tag.
2495**
2496** The RW_T3T_CHECK_EVT event is used to notify the application for each
Ruchi Kandoi552f2b72017-01-28 16:22:55 -08002497** segment of NDEF data received. The RW_T3T_CHECK_CPLT_EVT event is used
2498** to notify the application all segments have been received.
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002499**
2500** Before using this API, the RW_T3tDetectNDef function must be called to
2501** verify that the tag contains NDEF data, and to retrieve the NDEF
2502** attributes.
2503**
2504** Internally, this command will be separated into multiple Tag 3 Check
2505** commands (if necessary) - depending on the tag's Nbr (max number of
2506** blocks per read) attribute.
2507**
2508** Returns
2509** NFC_STATUS_OK: check command started
2510** NFC_STATUS_NO_BUFFERS: unable to allocate a buffer for this operation
2511** NFC_STATUS_FAILED: other error
2512**
2513*****************************************************************************/
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002514tNFC_STATUS RW_T3tCheckNDef(void) {
2515 tNFC_STATUS retval = NFC_STATUS_OK;
2516 tRW_T3T_CB* p_cb = &rw_cb.tcb.t3t;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002517
Ruchi Kandoi6767aec2017-09-26 09:46:26 -07002518 DLOG_IF(INFO, nfc_debug_enabled) << __func__;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002519
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002520 /* Check if we are in valid state to handle this API */
2521 if (p_cb->rw_state != RW_T3T_STATE_IDLE) {
Ruchi Kandoi6767aec2017-09-26 09:46:26 -07002522 LOG(ERROR) << StringPrintf("Error: invalid state to handle API (0x%x)",
2523 p_cb->rw_state);
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002524 return (NFC_STATUS_FAILED);
2525 } else if (p_cb->ndef_attrib.status !=
2526 NFC_STATUS_OK) /* NDEF detection not performed yet? */
2527 {
Ruchi Kandoi6767aec2017-09-26 09:46:26 -07002528 LOG(ERROR) << StringPrintf("Error: NDEF detection not performed yet");
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002529 return (NFC_STATUS_NOT_INITIALIZED);
2530 } else if (p_cb->ndef_attrib.ln == 0) {
Ruchi Kandoi6767aec2017-09-26 09:46:26 -07002531 LOG(ERROR) << StringPrintf("Type 3 tag contains empty NDEF message");
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002532 return (NFC_STATUS_FAILED);
2533 }
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002534
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002535 /* Check number of blocks needed for this update */
2536 p_cb->flags &= ~RW_T3T_FL_IS_FINAL_NDEF_SEGMENT;
2537 p_cb->ndef_rx_offset = 0;
2538 retval = rw_t3t_send_next_ndef_check_cmd(p_cb);
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002539
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002540 return (retval);
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002541}
2542
2543/*****************************************************************************
2544**
2545** Function RW_T3tUpdateNDef
2546**
2547** Description
2548** Write NDEF contents to a Type3 tag.
2549**
2550** The RW_T3T_UPDATE_CPLT_EVT callback event will be used to notify the
2551** application of the response.
2552**
2553** Before using this API, the RW_T3tDetectNDef function must be called to
2554** verify that the tag contains NDEF data, and to retrieve the NDEF
2555** attributes.
2556**
2557** Internally, this command will be separated into multiple Tag 3 Update
2558** commands (if necessary) - depending on the tag's Nbw (max number of
2559** blocks per write) attribute.
2560**
2561** Returns
2562** NFC_STATUS_OK: check command started
2563** NFC_STATUS_NO_BUFFERS: unable to allocate a buffer for this operation
2564** NFC_STATUS_REFUSED: tag is read-only
2565** NFC_STATUS_BUFFER_FULL: len exceeds tag's maximum size
2566** NFC_STATUS_FAILED: other error
2567**
2568*****************************************************************************/
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002569tNFC_STATUS RW_T3tUpdateNDef(uint32_t len, uint8_t* p_data) {
2570 tNFC_STATUS retval = NFC_STATUS_OK;
2571 tRW_T3T_CB* p_cb = &rw_cb.tcb.t3t;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002572
Ruchi Kandoi6767aec2017-09-26 09:46:26 -07002573 DLOG_IF(INFO, nfc_debug_enabled)
2574 << StringPrintf("RW_T3tUpdateNDef (len=%i)", len);
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002575
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002576 /* Check if we are in valid state to handle this API */
2577 if (p_cb->rw_state != RW_T3T_STATE_IDLE) {
Ruchi Kandoi6767aec2017-09-26 09:46:26 -07002578 LOG(ERROR) << StringPrintf("Error: invalid state to handle API (0x%x)",
2579 p_cb->rw_state);
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002580 return (NFC_STATUS_FAILED);
2581 } else if (p_cb->ndef_attrib.status !=
2582 NFC_STATUS_OK) /* NDEF detection not performed yet? */
2583 {
Ruchi Kandoi6767aec2017-09-26 09:46:26 -07002584 LOG(ERROR) << StringPrintf("Error: NDEF detection not performed yet");
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002585 return (NFC_STATUS_NOT_INITIALIZED);
2586 } else if (len > (((uint32_t)p_cb->ndef_attrib.nmaxb) *
2587 16)) /* Len exceed's tag's NDEF memory? */
2588 {
2589 return (NFC_STATUS_BUFFER_FULL);
2590 } else if (p_cb->ndef_attrib.rwflag ==
2591 T3T_MSG_NDEF_RWFLAG_RO) /* Tag's NDEF memory is read-only? */
2592 {
2593 return (NFC_STATUS_REFUSED);
2594 }
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002595
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002596 /* Check number of blocks needed for this update */
2597 p_cb->flags &= ~RW_T3T_FL_IS_FINAL_NDEF_SEGMENT;
2598 p_cb->ndef_msg_bytes_sent = 0;
2599 p_cb->ndef_msg_len = len;
2600 p_cb->ndef_msg = p_data;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002601
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002602 /* Send initial UPDATE command for NDEF Attribute Info */
2603 retval = rw_t3t_send_update_ndef_attribute_cmd(p_cb, true);
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002604
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002605 return (retval);
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002606}
2607
2608/*****************************************************************************
2609**
2610** Function RW_T3tCheck
2611**
2612** Description
2613** Read (non-NDEF) contents from a Type3 tag.
2614**
2615** The RW_READ_EVT event is used to notify the application for each
2616** segment of NDEF data received. The RW_READ_CPLT_EVT event is used to
2617** notify the application all segments have been received.
2618**
2619** Before using this API, the application must call RW_SelectTagType to
2620** indicate that a Type 3 tag has been activated, and to provide the
2621** tag's Manufacture ID (IDm) .
2622**
2623** Returns
2624** NFC_STATUS_OK: check command started
2625** NFC_STATUS_NO_BUFFERS: unable to allocate a buffer for this operation
2626** NFC_STATUS_FAILED: other error
2627**
2628*****************************************************************************/
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002629tNFC_STATUS RW_T3tCheck(uint8_t num_blocks, tT3T_BLOCK_DESC* t3t_blocks) {
2630 tNFC_STATUS retval = NFC_STATUS_OK;
2631 tRW_T3T_CB* p_cb = &rw_cb.tcb.t3t;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002632
Ruchi Kandoi6767aec2017-09-26 09:46:26 -07002633 DLOG_IF(INFO, nfc_debug_enabled)
2634 << StringPrintf("RW_T3tCheck (num_blocks = %i)", num_blocks);
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002635
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002636 /* Check if we are in valid state to handle this API */
2637 if (p_cb->rw_state != RW_T3T_STATE_IDLE) {
Ruchi Kandoi6767aec2017-09-26 09:46:26 -07002638 LOG(ERROR) << StringPrintf("Error: invalid state to handle API (0x%x)",
2639 p_cb->rw_state);
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002640 return (NFC_STATUS_FAILED);
2641 }
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002642
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002643 /* Send the CHECK command */
2644 retval = rw_t3t_send_check_cmd(p_cb, num_blocks, t3t_blocks);
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002645
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002646 return (retval);
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002647}
2648
2649/*****************************************************************************
2650**
2651** Function RW_T3tUpdate
2652**
2653** Description
2654** Write (non-NDEF) contents to a Type3 tag.
2655**
2656** The RW_WRITE_CPLT_EVT event is used to notify the application all
2657** segments have been received.
2658**
2659** Before using this API, the application must call RW_SelectTagType to
2660** indicate that a Type 3 tag has been activated, and to provide the tag's
2661** Manufacture ID (IDm) .
2662**
2663** Returns
2664** NFC_STATUS_OK: check command started
2665** NFC_STATUS_NO_BUFFERS: unable to allocate a buffer for this operation
2666** NFC_STATUS_FAILED: other error
2667**
2668*****************************************************************************/
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002669tNFC_STATUS RW_T3tUpdate(uint8_t num_blocks, tT3T_BLOCK_DESC* t3t_blocks,
2670 uint8_t* p_data) {
2671 tNFC_STATUS retval = NFC_STATUS_OK;
2672 tRW_T3T_CB* p_cb = &rw_cb.tcb.t3t;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002673
Ruchi Kandoi6767aec2017-09-26 09:46:26 -07002674 DLOG_IF(INFO, nfc_debug_enabled)
2675 << StringPrintf("RW_T3tUpdate (num_blocks = %i)", num_blocks);
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002676
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002677 /* Check if we are in valid state to handle this API */
2678 if (p_cb->rw_state != RW_T3T_STATE_IDLE) {
Ruchi Kandoi6767aec2017-09-26 09:46:26 -07002679 LOG(ERROR) << StringPrintf("Error: invalid state to handle API (0x%x)",
2680 p_cb->rw_state);
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002681 return (NFC_STATUS_FAILED);
2682 }
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002683
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002684 /* Send the UPDATE command */
2685 retval = rw_t3t_send_update_cmd(p_cb, num_blocks, t3t_blocks, p_data);
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002686
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002687 return (retval);
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002688}
2689
2690/*****************************************************************************
2691**
2692** Function RW_T3tPresenceCheck
2693**
2694** Description
2695** Check if the tag is still in the field.
2696**
2697** The RW_T3T_PRESENCE_CHECK_EVT w/ status is used to indicate presence
2698** or non-presence.
2699**
2700** Returns
2701** NFC_STATUS_OK, if raw data frame sent
2702** NFC_STATUS_NO_BUFFERS: unable to allocate a buffer for this operation
2703** NFC_STATUS_FAILED: other error
2704**
2705*****************************************************************************/
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002706tNFC_STATUS RW_T3tPresenceCheck(void) {
2707 tNFC_STATUS retval = NFC_STATUS_OK;
2708 tRW_DATA evt_data;
2709 tRW_CB* p_rw_cb = &rw_cb;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002710
Ruchi Kandoi6767aec2017-09-26 09:46:26 -07002711 DLOG_IF(INFO, nfc_debug_enabled) << __func__;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002712
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002713 /* If RW_SelectTagType was not called (no conn_callback) return failure */
2714 if (!(p_rw_cb->p_cback)) {
2715 retval = NFC_STATUS_FAILED;
2716 }
2717 /* If we are not activated, then RW_T3T_PRESENCE_CHECK_EVT status=FAIL */
2718 else if (p_rw_cb->tcb.t3t.rw_state == RW_T3T_STATE_NOT_ACTIVATED) {
2719 evt_data.status = NFC_STATUS_FAILED;
2720 (*p_rw_cb->p_cback)(RW_T3T_PRESENCE_CHECK_EVT, &evt_data);
2721 }
2722 /* If command is pending */
2723 else if (p_rw_cb->tcb.t3t.rw_state == RW_T3T_STATE_COMMAND_PENDING) {
2724 /* If already performing presence check, return error */
2725 if (p_rw_cb->tcb.t3t.flags & RW_T3T_FL_W4_PRESENCE_CHECK_POLL_RSP) {
Ruchi Kandoi6767aec2017-09-26 09:46:26 -07002726 DLOG_IF(INFO, nfc_debug_enabled)
2727 << StringPrintf("RW_T3tPresenceCheck already in progress");
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002728 retval = NFC_STATUS_FAILED;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002729 }
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002730 /* If busy with any other command, assume that the tag is present */
2731 else {
2732 evt_data.status = NFC_STATUS_OK;
2733 (*p_rw_cb->p_cback)(RW_T3T_PRESENCE_CHECK_EVT, &evt_data);
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002734 }
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002735 } else {
2736 /* IDLE state: send POLL command */
Ruchi Kandoi0c515ae2017-01-30 17:48:41 -08002737 retval = (tNFC_STATUS)nci_snd_t3t_polling(0xFFFF, T3T_POLL_RC_SC, 0);
2738 if (retval == NCI_STATUS_OK) {
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002739 p_rw_cb->tcb.t3t.flags |= RW_T3T_FL_W4_PRESENCE_CHECK_POLL_RSP;
2740 p_rw_cb->tcb.t3t.rw_state = RW_T3T_STATE_COMMAND_PENDING;
2741 p_rw_cb->tcb.t3t.cur_poll_rc = 0;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002742
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002743 /* start timer for waiting for responses */
2744 rw_t3t_start_poll_timer(&p_rw_cb->tcb.t3t);
2745 } else {
Ruchi Kandoi6767aec2017-09-26 09:46:26 -07002746 DLOG_IF(INFO, nfc_debug_enabled) << StringPrintf(
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002747 "RW_T3tPresenceCheck error sending NCI_RF_T3T_POLLING cmd (status = "
2748 "0x%0x)",
2749 retval);
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002750 }
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002751 }
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002752
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002753 return (retval);
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002754}
2755
2756/*****************************************************************************
2757**
2758** Function RW_T3tPoll
2759**
2760** Description
2761** Send POLL command
2762**
2763** Returns
2764** NFC_STATUS_OK, if raw data frame sent
2765** NFC_STATUS_NO_BUFFERS: unable to allocate a buffer for this operation
2766** NFC_STATUS_FAILED: other error
2767**
2768*****************************************************************************/
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002769tNFC_STATUS RW_T3tPoll(uint16_t system_code, tT3T_POLL_RC rc, uint8_t tsn) {
2770 tNFC_STATUS retval = NFC_STATUS_OK;
2771 tRW_T3T_CB* p_cb = &rw_cb.tcb.t3t;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002772
Ruchi Kandoi6767aec2017-09-26 09:46:26 -07002773 DLOG_IF(INFO, nfc_debug_enabled) << __func__;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002774
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002775 /* Check if we are in valid state to handle this API */
2776 if (p_cb->rw_state != RW_T3T_STATE_IDLE) {
Ruchi Kandoi6767aec2017-09-26 09:46:26 -07002777 LOG(ERROR) << StringPrintf("Error: invalid state to handle API (0x%x)",
2778 p_cb->rw_state);
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002779 return (NFC_STATUS_FAILED);
2780 }
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002781
Ruchi Kandoi0c515ae2017-01-30 17:48:41 -08002782 retval = (tNFC_STATUS)nci_snd_t3t_polling(system_code, (uint8_t)rc, tsn);
2783 if (retval == NCI_STATUS_OK) {
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002784 /* start timer for waiting for responses */
2785 p_cb->cur_poll_rc = rc;
2786 p_cb->rw_state = RW_T3T_STATE_COMMAND_PENDING;
2787 rw_t3t_start_poll_timer(p_cb);
2788 }
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002789
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002790 return (retval);
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002791}
2792
2793/*****************************************************************************
2794**
2795** Function RW_T3tSendRawFrame
2796**
2797** Description
2798** This function is called to send a raw data frame to the peer device.
2799** When type 3 tag receives response from peer, the callback function
2800** will be called with a RW_T3T_RAW_FRAME_EVT [Table 6].
2801**
2802** Before using this API, the application must call RW_SelectTagType to
2803** indicate that a Type 3 tag has been activated.
2804**
2805** The raw frame should be a properly formatted Type 3 tag message.
2806**
2807** Returns
2808** NFC_STATUS_OK, if raw data frame sent
2809** NFC_STATUS_NO_BUFFERS: unable to allocate a buffer for this operation
2810** NFC_STATUS_FAILED: other error
2811**
2812*****************************************************************************/
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002813tNFC_STATUS RW_T3tSendRawFrame(uint16_t len, uint8_t* p_data) {
2814 tNFC_STATUS retval = NFC_STATUS_OK;
2815 tRW_T3T_CB* p_cb = &rw_cb.tcb.t3t;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002816
Ruchi Kandoi6767aec2017-09-26 09:46:26 -07002817 DLOG_IF(INFO, nfc_debug_enabled)
2818 << StringPrintf("RW_T3tSendRawFrame (len = %i)", len);
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002819
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002820 /* Check if we are in valid state to handle this API */
2821 if (p_cb->rw_state != RW_T3T_STATE_IDLE) {
Ruchi Kandoi6767aec2017-09-26 09:46:26 -07002822 LOG(ERROR) << StringPrintf("Error: invalid state to handle API (0x%x)",
2823 p_cb->rw_state);
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002824 return (NFC_STATUS_FAILED);
2825 }
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002826
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002827 /* Send the UPDATE command */
2828 retval = rw_t3t_send_raw_frame(p_cb, len, p_data);
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002829
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002830 return (retval);
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002831}
2832
2833/*****************************************************************************
2834**
2835** Function RW_T3tGetSystemCodes
2836**
2837** Description
2838** Get systems codes supported by the activated tag:
Yoshinobu Ito721b3ab2016-08-02 14:41:33 +09002839** Poll for wildcard (FFFF, RC=1):
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002840**
2841** Before using this API, the application must call RW_SelectTagType to
2842** indicate that a Type 3 tag has been activated.
2843**
2844** Returns
2845** NFC_STATUS_OK, if raw data frame sent
2846** NFC_STATUS_NO_BUFFERS: unable to allocate a buffer for this operation
2847** NFC_STATUS_FAILED: other error
2848**
2849*****************************************************************************/
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002850tNFC_STATUS RW_T3tGetSystemCodes(void) {
2851 tNFC_STATUS retval = NFC_STATUS_OK;
2852 tRW_T3T_CB* p_cb = &rw_cb.tcb.t3t;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002853
Ruchi Kandoi6767aec2017-09-26 09:46:26 -07002854 DLOG_IF(INFO, nfc_debug_enabled) << __func__;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002855
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002856 /* Check if we are in valid state to handle this API */
2857 if (p_cb->rw_state != RW_T3T_STATE_IDLE) {
Ruchi Kandoi6767aec2017-09-26 09:46:26 -07002858 LOG(ERROR) << StringPrintf("Error: invalid state to handle API (0x%x)",
2859 p_cb->rw_state);
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002860 return (NFC_STATUS_FAILED);
2861 } else {
Ruchi Kandoi0c515ae2017-01-30 17:48:41 -08002862 retval = (tNFC_STATUS)nci_snd_t3t_polling(0xFFFF, T3T_POLL_RC_SC, 0);
2863 if (retval == NCI_STATUS_OK) {
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002864 p_cb->cur_cmd = RW_T3T_CMD_GET_SYSTEM_CODES;
2865 p_cb->cur_tout = RW_T3T_DEFAULT_CMD_TIMEOUT_TICKS;
2866 p_cb->cur_poll_rc = T3T_POLL_RC_SC;
2867 p_cb->rw_state = RW_T3T_STATE_COMMAND_PENDING;
2868 p_cb->flags |= RW_T3T_FL_W4_GET_SC_POLL_RSP;
2869 p_cb->num_system_codes = 0;
2870
2871 /* start timer for waiting for responses */
2872 rw_t3t_start_poll_timer(p_cb);
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002873 }
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002874 }
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002875
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002876 return (retval);
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002877}
2878
2879/*****************************************************************************
2880**
2881** Function RW_T3tFormatNDef
2882**
2883** Description
2884** Format a type-3 tag for NDEF.
2885**
2886** Only Felica-Lite tags are supported by this API. The
2887** RW_T3T_FORMAT_CPLT_EVT is used to notify the status of the operation.
2888**
2889** Returns
2890** NFC_STATUS_OK: ndef detection procedure started
2891** NFC_STATUS_NO_BUFFERS: unable to allocate a buffer for this operation
2892** NFC_STATUS_FAILED: other error
2893**
2894*****************************************************************************/
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002895tNFC_STATUS RW_T3tFormatNDef(void) {
2896 tNFC_STATUS retval = NFC_STATUS_OK;
2897 tRW_T3T_CB* p_cb = &rw_cb.tcb.t3t;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002898
Ruchi Kandoi6767aec2017-09-26 09:46:26 -07002899 DLOG_IF(INFO, nfc_debug_enabled) << __func__;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002900
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002901 /* Check if we are in valid state to handle this API */
2902 if (p_cb->rw_state != RW_T3T_STATE_IDLE) {
Ruchi Kandoi6767aec2017-09-26 09:46:26 -07002903 LOG(ERROR) << StringPrintf("Error: invalid state to handle API (0x%x)",
2904 p_cb->rw_state);
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002905 return (NFC_STATUS_FAILED);
2906 } else {
2907 /* Poll tag, to see if Felica-Lite system is supported */
Ruchi Kandoi0c515ae2017-01-30 17:48:41 -08002908 retval = (tNFC_STATUS)nci_snd_t3t_polling(T3T_SYSTEM_CODE_FELICA_LITE,
2909 T3T_POLL_RC_SC, 0);
2910 if (retval == NCI_STATUS_OK) {
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002911 p_cb->cur_cmd = RW_T3T_CMD_FORMAT;
2912 p_cb->cur_tout = RW_T3T_DEFAULT_CMD_TIMEOUT_TICKS;
2913 p_cb->cur_poll_rc = T3T_POLL_RC_SC;
2914 p_cb->rw_state = RW_T3T_STATE_COMMAND_PENDING;
2915 p_cb->rw_substate = RW_T3T_FMT_SST_POLL_FELICA_LITE;
2916 p_cb->flags |= RW_T3T_FL_W4_FMT_FELICA_LITE_POLL_RSP;
2917
2918 /* start timer for waiting for responses */
2919 rw_t3t_start_poll_timer(p_cb);
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002920 }
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002921 }
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002922
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002923 return (retval);
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002924}
Martijn Coenen5c65c3a2013-03-27 13:23:36 -07002925
2926/*****************************************************************************
2927**
2928** Function RW_T3tSetReadOnly
2929**
2930** Description This function performs NDEF read-only procedure
2931** Note: Only Felica-Lite tags are supported by this API.
2932** RW_T3tDetectNDef() must be called before using this
2933**
2934** The RW_T3T_SET_READ_ONLY_CPLT_EVT event will be returned.
2935**
2936** Returns NFC_STATUS_OK if success
2937** NFC_STATUS_FAILED if T3T is busy or other error
2938**
2939*****************************************************************************/
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002940tNFC_STATUS RW_T3tSetReadOnly(bool b_hard_lock) {
2941 tNFC_STATUS retval = NFC_STATUS_OK;
2942 tRW_T3T_CB* p_cb = &rw_cb.tcb.t3t;
2943 tRW_DATA evt_data;
Martijn Coenen5c65c3a2013-03-27 13:23:36 -07002944
Ruchi Kandoi6767aec2017-09-26 09:46:26 -07002945 DLOG_IF(INFO, nfc_debug_enabled)
2946 << StringPrintf("b_hard_lock=%d", b_hard_lock);
Martijn Coenen5c65c3a2013-03-27 13:23:36 -07002947
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002948 /* Check if we are in valid state to handle this API */
2949 if (p_cb->rw_state != RW_T3T_STATE_IDLE) {
Ruchi Kandoi6767aec2017-09-26 09:46:26 -07002950 LOG(ERROR) << StringPrintf("Error: invalid state to handle API (0x%x)",
2951 p_cb->rw_state);
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002952 return (NFC_STATUS_FAILED);
2953 }
Martijn Coenen5c65c3a2013-03-27 13:23:36 -07002954
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002955 if (p_cb->ndef_attrib.status !=
2956 NFC_STATUS_OK) /* NDEF detection not performed yet? */
2957 {
Ruchi Kandoi6767aec2017-09-26 09:46:26 -07002958 LOG(ERROR) << StringPrintf("Error: NDEF detection not performed yet");
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002959 return (NFC_STATUS_NOT_INITIALIZED);
2960 }
Martijn Coenen5c65c3a2013-03-27 13:23:36 -07002961
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002962 if ((!b_hard_lock) &&
2963 (p_cb->ndef_attrib.rwflag ==
2964 T3T_MSG_NDEF_RWFLAG_RO)) /* Tag's NDEF memory is read-only already */
2965 {
2966 evt_data.status = NFC_STATUS_OK;
2967 (*(rw_cb.p_cback))(RW_T3T_SET_READ_ONLY_CPLT_EVT, &evt_data);
Martijn Coenen5c65c3a2013-03-27 13:23:36 -07002968 return (retval);
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002969 } else {
2970 /* Poll tag, to see if Felica-Lite system is supported */
Ruchi Kandoi0c515ae2017-01-30 17:48:41 -08002971 retval = (tNFC_STATUS)nci_snd_t3t_polling(T3T_SYSTEM_CODE_FELICA_LITE,
2972 T3T_POLL_RC_SC, 0);
2973 if (retval == NCI_STATUS_OK) {
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002974 if (b_hard_lock)
2975 p_cb->cur_cmd = RW_T3T_CMD_SET_READ_ONLY_HARD;
2976 else
2977 p_cb->cur_cmd = RW_T3T_CMD_SET_READ_ONLY_SOFT;
2978 p_cb->cur_tout = RW_T3T_DEFAULT_CMD_TIMEOUT_TICKS;
2979 p_cb->cur_poll_rc = T3T_POLL_RC_SC;
2980 p_cb->rw_state = RW_T3T_STATE_COMMAND_PENDING;
2981 p_cb->rw_substate = RW_T3T_SRO_SST_POLL_FELICA_LITE;
2982 p_cb->flags |= RW_T3T_FL_W4_SRO_FELICA_LITE_POLL_RSP;
2983
2984 /* start timer for waiting for responses */
2985 rw_t3t_start_poll_timer(p_cb);
2986 }
2987 }
2988 return (retval);
Martijn Coenen5c65c3a2013-03-27 13:23:36 -07002989}