blob: 817901d8f7802e1e6df507d3a47c9775ec36f5c8 [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#include "bt_types.h"
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -080027#include "nfc_target.h"
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -080028#include "trace_api.h"
29
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -080030#include "gki.h"
31#include "nci_hmsgs.h"
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -080032#include "nfc_api.h"
33#include "nfc_int.h"
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -080034#include "rw_api.h"
35#include "rw_int.h"
36#include "tags_int.h"
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -080037
38/* Definitions for constructing t3t command messages */
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -080039#define RW_T3T_FL_PADDING 0x01 /* Padding needed for last NDEF block */
40/* Maximum number of NDEF blocks updates that can fit into one command (when all
41 * block-numbers are < 256) */
Ruchi Kandoi46e6e282017-01-30 14:26:10 -080042#define RW_T3T_MAX_NDEF_BLOCKS_PER_UPDATE_1_BYTE_FORMAT (13)
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -080043/* Maximum number of NDEF blocks updates that can fit into one command (when all
44 * block-numbers are >= 256) */
Ruchi Kandoi46e6e282017-01-30 14:26:10 -080045#define RW_T3T_MAX_NDEF_BLOCKS_PER_UPDATE_2_BYTE_FORMAT (12)
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -080046
47/* Definitions for SENSF_RES */
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -080048/* Offset of RD in SENSF_RES from NCI_POLL NTF (includes 1 byte SENSF_RES
49 * length) */
Ruchi Kandoi46e6e282017-01-30 14:26:10 -080050#define RW_T3T_SENSF_RES_RD_OFFSET 17
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -080051#define RW_T3T_SENSF_RES_RD_LEN 2 /* Size of RD in SENSF_RES */
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -080052
53/* Timeout definitions for commands */
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -080054#define RW_T3T_POLL_CMD_TIMEOUT_TICKS \
55 ((RW_T3T_TOUT_RESP * 2 * QUICK_TIMER_TICKS_PER_SEC) / 1000)
56#define RW_T3T_DEFAULT_CMD_TIMEOUT_TICKS \
57 ((RW_T3T_TOUT_RESP * QUICK_TIMER_TICKS_PER_SEC) / 1000)
58#define RW_T3T_RAW_FRAME_CMD_TIMEOUT_TICKS \
59 (RW_T3T_DEFAULT_CMD_TIMEOUT_TICKS * 4)
60#define RW_T3T_MIN_TIMEOUT_TICKS 10
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -080061
62/* Macro to extract major version from NDEF version byte */
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -080063#define T3T_GET_MAJOR_VERSION(ver) (ver >> 4)
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -080064
65/* Enumeration of API commands */
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -080066enum {
67 RW_T3T_CMD_DETECT_NDEF,
68 RW_T3T_CMD_CHECK_NDEF,
69 RW_T3T_CMD_UPDATE_NDEF,
70 RW_T3T_CMD_CHECK,
71 RW_T3T_CMD_UPDATE,
72 RW_T3T_CMD_SEND_RAW_FRAME,
73 RW_T3T_CMD_GET_SYSTEM_CODES,
74 RW_T3T_CMD_FORMAT,
75 RW_T3T_CMD_SET_READ_ONLY_SOFT,
76 RW_T3T_CMD_SET_READ_ONLY_HARD,
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -080077
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -080078 RW_T3T_CMD_MAX
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -080079};
80
81/* RW_CBACK events corresponding to API comands */
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -080082const uint8_t rw_t3t_api_res_evt[RW_T3T_CMD_MAX] = {
83 RW_T3T_NDEF_DETECT_EVT, /* RW_T3T_CMD_DETECT_NDEF */
84 RW_T3T_CHECK_CPLT_EVT, /* RW_T3T_CMD_CHECK_NDEF */
85 RW_T3T_UPDATE_CPLT_EVT, /* RW_T3T_CMD_UPDATE_NDEF */
86 RW_T3T_CHECK_CPLT_EVT, /* RW_T3T_CMD_CHECK */
87 RW_T3T_UPDATE_CPLT_EVT, /* RW_T3T_CMD_UPDATE */
88 RW_T3T_RAW_FRAME_EVT, /* RW_T3T_CMD_SEND_RAW_FRAME */
89 RW_T3T_GET_SYSTEM_CODES_EVT, /* RW_T3T_CMD_GET_SYSTEM_CODES */
90 RW_T3T_FORMAT_CPLT_EVT, /* RW_T3T_CMD_FORMAT */
91 RW_T3T_SET_READ_ONLY_CPLT_EVT /* RW_T3T_CMD_SET_READ_ONLY */
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -080092};
93
94/* States */
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -080095enum {
96 RW_T3T_STATE_NOT_ACTIVATED,
97 RW_T3T_STATE_IDLE,
98 RW_T3T_STATE_COMMAND_PENDING
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -080099};
100
101/* Sub-states */
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800102enum {
103 /* Sub states for formatting Felica-Lite */
104 RW_T3T_FMT_SST_POLL_FELICA_LITE, /* Waiting for POLL Felica-Lite response (for
105 formatting) */
106 RW_T3T_FMT_SST_CHECK_MC_BLK, /* Waiting for Felica-Lite MC (MemoryControl)
107 block-read to complete */
108 RW_T3T_FMT_SST_UPDATE_MC_BLK, /* Waiting for Felica-Lite MC (MemoryControl)
109 block-write to complete */
110 RW_T3T_FMT_SST_UPDATE_NDEF_ATTRIB, /* Waiting for NDEF attribute block-write
111 to complete */
Martijn Coenen5c65c3a2013-03-27 13:23:36 -0700112
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800113 /* Sub states for setting Felica-Lite read only */
114 RW_T3T_SRO_SST_POLL_FELICA_LITE, /* Waiting for POLL Felica-Lite response (for
115 setting read only) */
116 RW_T3T_SRO_SST_UPDATE_NDEF_ATTRIB, /* Waiting for NDEF attribute block-write
117 to complete */
118 RW_T3T_SRO_SST_CHECK_MC_BLK, /* Waiting for Felica-Lite MC (MemoryControl)
119 block-read to complete */
120 RW_T3T_SRO_SST_UPDATE_MC_BLK /* Waiting for Felica-Lite MC (MemoryControl)
121 block-write to complete */
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800122};
123
124#if (BT_TRACE_VERBOSE == TRUE)
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800125static char* rw_t3t_cmd_str(uint8_t cmd_id);
126static char* rw_t3t_state_str(uint8_t state_id);
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800127#endif
128
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800129/* Local static functions */
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800130static void rw_t3t_update_ndef_flag(uint8_t* p_flag);
131static tNFC_STATUS rw_t3t_unselect(uint8_t peer_nfcid2[]);
132static NFC_HDR* rw_t3t_get_cmd_buf(void);
133static tNFC_STATUS rw_t3t_send_to_lower(NFC_HDR* p_msg);
134static void rw_t3t_handle_get_system_codes_cplt(void);
135static void rw_t3t_handle_get_sc_poll_rsp(tRW_T3T_CB* p_cb, uint8_t nci_status,
136 uint8_t num_responses,
137 uint8_t sensf_res_buf_size,
138 uint8_t* p_sensf_res_buf);
139static void rw_t3t_handle_ndef_detect_poll_rsp(tRW_T3T_CB* p_cb,
140 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_fmt_poll_rsp(tRW_T3T_CB* p_cb, uint8_t nci_status,
145 uint8_t num_responses,
146 uint8_t sensf_res_buf_size,
147 uint8_t* p_sensf_res_buf);
148static void rw_t3t_handle_sro_poll_rsp(tRW_T3T_CB* p_cb, uint8_t nci_status,
149 uint8_t num_responses,
150 uint8_t sensf_res_buf_size,
151 uint8_t* p_sensf_res_buf);
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800152
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800153/* Default NDEF attribute information block (used when formatting Felica-Lite
154 * tags) */
Ruchi Kandoi46e6e282017-01-30 14:26:10 -0800155/* NBr (max block reads per cmd)*/
156#define RW_T3T_DEFAULT_FELICALITE_NBR 4
157/* NBw (max block write per cmd)*/
158#define RW_T3T_DEFAULT_FELICALITE_NBW 1
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800159#define RW_T3T_DEFAULT_FELICALITE_NMAXB (T3T_FELICALITE_NMAXB)
160#define RW_T3T_DEFAULT_FELICALITE_ATTRIB_INFO_CHECKSUM \
161 ((T3T_MSG_NDEF_VERSION + RW_T3T_DEFAULT_FELICALITE_NBR + \
162 RW_T3T_DEFAULT_FELICALITE_NBW + (RW_T3T_DEFAULT_FELICALITE_NMAXB >> 8) + \
163 (RW_T3T_DEFAULT_FELICALITE_NMAXB & 0xFF) + T3T_MSG_NDEF_WRITEF_OFF + \
164 T3T_MSG_NDEF_RWFLAG_RW) & \
165 0xFFFF)
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800166
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800167const uint8_t rw_t3t_default_attrib_info[T3T_MSG_BLOCKSIZE] = {
168 T3T_MSG_NDEF_VERSION, /* Ver */
169 RW_T3T_DEFAULT_FELICALITE_NBR, /* NBr (max block reads per cmd)*/
170 RW_T3T_DEFAULT_FELICALITE_NBW, /* NBw (max block write per cmd)*/
171 (RW_T3T_DEFAULT_FELICALITE_NMAXB >> 8), /* Nmaxb (max size in blocks) */
172 (RW_T3T_DEFAULT_FELICALITE_NMAXB & 0xFF), /* Nmaxb (max size in blocks) */
Love Khannac76c21d2017-02-27 18:20:08 +0530173 0, 0, 0, 0, /* Unused */
174 T3T_MSG_NDEF_WRITEF_OFF, /* WriteF */
175 T3T_MSG_NDEF_RWFLAG_RW, /* RW Flag */
176 0, 0, 0, /* Ln (current size in bytes) */
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800177
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800178 (RW_T3T_DEFAULT_FELICALITE_ATTRIB_INFO_CHECKSUM >>
179 8), /* checksum (high-byte) */
180 (RW_T3T_DEFAULT_FELICALITE_ATTRIB_INFO_CHECKSUM &
181 0xFF) /* checksum (low-byte) */
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800182
183};
184
Sherry Smith818b56e2014-05-14 16:46:32 -0700185/* 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 -0800186static const uint32_t rw_t3t_mrti_base[] = {302, 1208, 4832, 19328};
Sherry Smith818b56e2014-05-14 16:46:32 -0700187
188/*******************************************************************************
189**
190** Function rw_t3t_check_timeout
191**
192** Description The timeout value is a + b * number_blocks)
193**
194** Returns timeout value in ticks
195**
196*******************************************************************************/
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800197static uint32_t rw_t3t_check_timeout(uint16_t num_blocks) {
198 tRW_T3T_CB* p_cb = &rw_cb.tcb.t3t;
199 uint32_t timeout;
200 uint32_t extra;
Sherry Smith67fe6102014-06-02 11:01:54 -0700201
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800202 timeout = (p_cb->check_tout_a + num_blocks * p_cb->check_tout_b) *
203 QUICK_TIMER_TICKS_PER_SEC / 1000000;
204 /* allow some extra time for driver */
205 extra = (timeout / 10) + RW_T3T_MIN_TIMEOUT_TICKS;
206 timeout += extra;
Sherry Smith67fe6102014-06-02 11:01:54 -0700207
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800208 return timeout;
Sherry Smith818b56e2014-05-14 16:46:32 -0700209}
210
211/*******************************************************************************
212**
213** Function rw_t3t_update_timeout
214**
215** Description The timeout value is a + b * number_blocks)
216**
217** Returns timeout value in ticks
218**
219*******************************************************************************/
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800220static uint32_t rw_t3t_update_timeout(uint16_t num_blocks) {
221 tRW_T3T_CB* p_cb = &rw_cb.tcb.t3t;
222 uint32_t timeout;
223 uint32_t extra;
Sherry Smith67fe6102014-06-02 11:01:54 -0700224
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800225 timeout = (p_cb->update_tout_a + num_blocks * p_cb->update_tout_b) *
226 QUICK_TIMER_TICKS_PER_SEC / 1000000;
227 /* allow some extra time for driver */
228 extra = (timeout / 10) + RW_T3T_MIN_TIMEOUT_TICKS;
229 timeout += extra;
Sherry Smith67fe6102014-06-02 11:01:54 -0700230
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800231 return timeout;
Sherry Smith818b56e2014-05-14 16:46:32 -0700232}
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800233/*******************************************************************************
234**
235** Function rw_t3t_process_error
236**
237** Description Process error (timeout or CRC error)
238**
239** Returns none
240**
241*******************************************************************************/
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800242void rw_t3t_process_error(tNFC_STATUS status) {
243 tRW_T3T_CB* p_cb = &rw_cb.tcb.t3t;
244 uint8_t evt;
245 tRW_DATA evt_data;
246 NFC_HDR* p_cmd_buf;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800247
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800248 if (p_cb->rw_state == RW_T3T_STATE_COMMAND_PENDING) {
249 if (p_cb->cur_cmd == RW_T3T_CMD_GET_SYSTEM_CODES) {
250 /* For GetSystemCode: tag did not respond to requested POLL */
251 rw_t3t_handle_get_system_codes_cplt();
252 return;
253 }
254 /* Retry sending command if retry-count < max */
255 else if (rw_cb.cur_retry < RW_MAX_RETRIES) {
256 /* retry sending the command */
257 rw_cb.cur_retry++;
258
259 RW_TRACE_DEBUG2("T3T retransmission attempt %i of %i", rw_cb.cur_retry,
260 RW_MAX_RETRIES);
261
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 Kandoi6fca02d2017-01-30 14:28:16 -0800265 memcpy(p_cmd_buf, p_cb->p_cur_cmd_buf,
266 sizeof(NFC_HDR) + p_cb->p_cur_cmd_buf->offset +
267 p_cb->p_cur_cmd_buf->len);
268
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 {
280 RW_TRACE_DEBUG1("T3T maximum retransmission attempts reached (%i)",
281 RW_MAX_RETRIES);
282 }
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;
349 (*(rw_cb.p_cback))(RW_T3T_PRESENCE_CHECK_EVT, (tRW_DATA*)&evt_data);
350 } 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;
358 rw_t3t_handle_fmt_poll_rsp(p_cb, nci_status, num_responses,
359 sensf_res_buf_size, p_sensf_res_buf);
360 } else if (p_cb->flags & RW_T3T_FL_W4_SRO_FELICA_LITE_POLL_RSP) {
361 /* Handle POLL ntf in response to get system codes */
362 p_cb->flags &= ~RW_T3T_FL_W4_SRO_FELICA_LITE_POLL_RSP;
363 rw_t3t_handle_sro_poll_rsp(p_cb, nci_status, num_responses,
364 sensf_res_buf_size, p_sensf_res_buf);
365 } else if (p_cb->flags & RW_T3T_FL_W4_NDEF_DETECT_POLL_RSP) {
366 /* Handle POLL ntf in response to ndef detection */
367 p_cb->flags &= ~RW_T3T_FL_W4_NDEF_DETECT_POLL_RSP;
368 rw_t3t_handle_ndef_detect_poll_rsp(p_cb, nci_status, num_responses,
369 sensf_res_buf_size, p_sensf_res_buf);
370 } else {
371 /* Handle POLL ntf in response to RW_T3tPoll */
Ruchi Kandoi0c515ae2017-01-30 17:48:41 -0800372 evt_data.t3t_poll.status = nci_status;
373 if (evt_data.t3t_poll.status == NCI_STATUS_OK) {
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800374 evt_data.t3t_poll.rc = p_cb->cur_poll_rc;
375 evt_data.t3t_poll.response_num = num_responses;
376 evt_data.t3t_poll.response_bufsize = sensf_res_buf_size;
377 evt_data.t3t_poll.response_buf = p_sensf_res_buf;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800378 }
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800379
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800380 p_cb->rw_state = RW_T3T_STATE_IDLE;
381 (*(rw_cb.p_cback))(RW_T3T_POLL_EVT, &evt_data);
382 }
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800383}
384
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800385/*******************************************************************************
386**
387** Function rw_t3t_handle_get_system_codes_cplt
388**
389** Description Notify upper layer of system codes
390**
391** Returns none
392**
393*******************************************************************************/
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800394void rw_t3t_handle_get_system_codes_cplt(void) {
395 tRW_T3T_CB* p_cb = &rw_cb.tcb.t3t;
396 tRW_DATA evt_data;
397 uint8_t i;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800398
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800399 evt_data.t3t_sc.status = NFC_STATUS_OK;
400 evt_data.t3t_sc.num_system_codes = p_cb->num_system_codes;
401 evt_data.t3t_sc.p_system_codes = p_cb->system_codes;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800402
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800403 RW_TRACE_DEBUG1("rw_t3t_handle_get_system_codes_cplt, number of systems: %i",
404 evt_data.t3t_sc.num_system_codes);
405 for (i = 0; i < evt_data.t3t_sc.num_system_codes; i++) {
406 RW_TRACE_DEBUG2(" system %i: %04X", i, evt_data.t3t_sc.p_system_codes[i]);
407 }
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800408
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800409 p_cb->rw_state = RW_T3T_STATE_IDLE;
410 (*(rw_cb.p_cback))(RW_T3T_GET_SYSTEM_CODES_EVT, &evt_data);
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800411}
412
413/*******************************************************************************
414**
415** Function rw_t3t_format_cplt
416**
417** Description Notify upper layer of format complete
418**
419** Returns none
420**
421*******************************************************************************/
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800422void rw_t3t_format_cplt(tNFC_STATUS status) {
423 tRW_T3T_CB* p_cb = &rw_cb.tcb.t3t;
424 tRW_DATA evt_data;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800425
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800426 p_cb->rw_state = RW_T3T_STATE_IDLE;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800427
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800428 /* Update ndef info */
429 p_cb->ndef_attrib.status = status;
430 if (status == NFC_STATUS_OK) {
431 p_cb->ndef_attrib.version = T3T_MSG_NDEF_VERSION;
432 p_cb->ndef_attrib.nbr = RW_T3T_DEFAULT_FELICALITE_NBR;
433 p_cb->ndef_attrib.nbw = RW_T3T_DEFAULT_FELICALITE_NBW;
434 p_cb->ndef_attrib.nmaxb = RW_T3T_DEFAULT_FELICALITE_NMAXB;
435 p_cb->ndef_attrib.writef = T3T_MSG_NDEF_WRITEF_OFF;
436 p_cb->ndef_attrib.rwflag = T3T_MSG_NDEF_RWFLAG_RW;
437 p_cb->ndef_attrib.ln = 0;
438 }
Martijn Coenen5c65c3a2013-03-27 13:23:36 -0700439
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800440 /* Notify upper layer of format complete */
441 evt_data.status = status;
442 (*(rw_cb.p_cback))(RW_T3T_FORMAT_CPLT_EVT, &evt_data);
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800443}
444
445/*******************************************************************************
446**
Martijn Coenen5c65c3a2013-03-27 13:23:36 -0700447** Function rw_t3t_set_readonly_cplt
448**
449** Description Notify upper layer of set read only complete
450**
451** Returns none
452**
453*******************************************************************************/
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800454void rw_t3t_set_readonly_cplt(tNFC_STATUS status) {
455 tRW_T3T_CB* p_cb = &rw_cb.tcb.t3t;
456 tRW_DATA evt_data;
Martijn Coenen5c65c3a2013-03-27 13:23:36 -0700457
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800458 p_cb->rw_state = RW_T3T_STATE_IDLE;
Martijn Coenen5c65c3a2013-03-27 13:23:36 -0700459
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800460 /* Notify upper layer of format complete */
461 evt_data.status = status;
462 (*(rw_cb.p_cback))(RW_T3T_SET_READ_ONLY_CPLT_EVT, &evt_data);
Martijn Coenen5c65c3a2013-03-27 13:23:36 -0700463}
464
465/*******************************************************************************
466**
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800467** Function rw_t3t_process_timeout
468**
469** Description Process timeout
470**
471** Returns none
472**
473*******************************************************************************/
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800474void rw_t3t_process_timeout(TIMER_LIST_ENT* p_tle) {
475 tRW_T3T_CB* p_cb = &rw_cb.tcb.t3t;
476 tRW_DATA evt_data;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800477
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800478 /* Check which timer timed out */
479 if (p_tle == &p_cb->timer) {
480/* UPDATE/CHECK response timeout */
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800481#if (BT_TRACE_VERBOSE == TRUE)
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800482 RW_TRACE_ERROR3("T3T timeout. state=%s cur_cmd=0x%02X (%s)",
483 rw_t3t_state_str(rw_cb.tcb.t3t.rw_state),
484 rw_cb.tcb.t3t.cur_cmd,
485 rw_t3t_cmd_str(rw_cb.tcb.t3t.cur_cmd));
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800486#else
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800487 RW_TRACE_ERROR2("T3T timeout. state=0x%02X cur_cmd=0x%02X",
488 rw_cb.tcb.t3t.rw_state, rw_cb.tcb.t3t.cur_cmd);
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800489#endif
490
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800491 rw_t3t_process_error(NFC_STATUS_TIMEOUT);
492 } else {
493 RW_TRACE_ERROR0("T3T POLL timeout.");
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800494
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800495 /* POLL response timeout */
496 if (p_cb->flags & RW_T3T_FL_W4_PRESENCE_CHECK_POLL_RSP) {
497 /* POLL timeout for presence check */
498 p_cb->flags &= ~RW_T3T_FL_W4_PRESENCE_CHECK_POLL_RSP;
499 evt_data.status = NFC_STATUS_FAILED;
500 p_cb->rw_state = RW_T3T_STATE_IDLE;
501 (*(rw_cb.p_cback))(RW_T3T_PRESENCE_CHECK_EVT, (tRW_DATA*)&evt_data);
502 } else if (p_cb->flags & RW_T3T_FL_W4_GET_SC_POLL_RSP) {
503 /* POLL timeout for getting system codes */
504 p_cb->flags &= ~RW_T3T_FL_W4_GET_SC_POLL_RSP;
505 rw_t3t_handle_get_system_codes_cplt();
506 } else if (p_cb->flags & RW_T3T_FL_W4_FMT_FELICA_LITE_POLL_RSP) {
507 /* POLL timeout for formatting Felica Lite */
508 p_cb->flags &= ~RW_T3T_FL_W4_FMT_FELICA_LITE_POLL_RSP;
509 RW_TRACE_ERROR0("Felica-Lite tag not detected");
510 rw_t3t_format_cplt(NFC_STATUS_FAILED);
511 } else if (p_cb->flags & RW_T3T_FL_W4_SRO_FELICA_LITE_POLL_RSP) {
512 /* POLL timeout for configuring Felica Lite read only */
513 p_cb->flags &= ~RW_T3T_FL_W4_SRO_FELICA_LITE_POLL_RSP;
514 RW_TRACE_ERROR0("Felica-Lite tag not detected");
515 rw_t3t_set_readonly_cplt(NFC_STATUS_FAILED);
516 } else if (p_cb->flags & RW_T3T_FL_W4_NDEF_DETECT_POLL_RSP) {
517 /* POLL timeout for ndef detection */
518 p_cb->flags &= ~RW_T3T_FL_W4_NDEF_DETECT_POLL_RSP;
519 rw_t3t_handle_ndef_detect_poll_rsp(p_cb, NFC_STATUS_TIMEOUT, 0, 0, NULL);
520 } else {
521 /* Timeout waiting for response for RW_T3tPoll */
522 evt_data.t3t_poll.status = NFC_STATUS_FAILED;
523 p_cb->rw_state = RW_T3T_STATE_IDLE;
524 (*(rw_cb.p_cback))(RW_T3T_POLL_EVT, (tRW_DATA*)&evt_data);
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800525 }
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800526 }
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800527}
528
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800529/*******************************************************************************
530**
531** Function rw_t3t_process_frame_error
532**
533** Description Process frame crc error
534**
535** Returns none
536**
537*******************************************************************************/
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800538void rw_t3t_process_frame_error(void) {
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800539#if (BT_TRACE_VERBOSE == TRUE)
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800540 RW_TRACE_ERROR3("T3T frame error. state=%s cur_cmd=0x%02X (%s)",
541 rw_t3t_state_str(rw_cb.tcb.t3t.rw_state),
542 rw_cb.tcb.t3t.cur_cmd, rw_t3t_cmd_str(rw_cb.tcb.t3t.cur_cmd));
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800543#else
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800544 RW_TRACE_ERROR2("T3T frame error. state=0x%02X cur_cmd=0x%02X",
545 rw_cb.tcb.t3t.rw_state, rw_cb.tcb.t3t.cur_cmd);
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800546#endif
547
Ruchi Kandoi303fec12016-12-14 13:22:38 -0800548#if (RW_STATS_INCLUDED == TRUE)
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800549 /* Update stats */
550 rw_main_update_crc_error_stats();
551#endif /* RW_STATS_INCLUDED */
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800552
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800553 /* Process the error */
554 rw_t3t_process_error(NFC_STATUS_MSG_CORRUPTED);
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800555}
556
557/*******************************************************************************
558**
559** Function rw_t3t_send_to_lower
560**
561** Description Send command to lower layer
562**
563** Returns status of the send
564**
565*******************************************************************************/
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800566tNFC_STATUS rw_t3t_send_to_lower(NFC_HDR* p_msg) {
567 uint8_t* p;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800568
Ruchi Kandoi303fec12016-12-14 13:22:38 -0800569#if (RW_STATS_INCLUDED == TRUE)
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800570 bool is_retry;
571 /* Update stats */
572 rw_main_update_tx_stats(p_msg->len, ((rw_cb.cur_retry == 0) ? false : true));
573#endif /* RW_STATS_INCLUDED */
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800574
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800575 /* Set NFC-F SoD field (payload len + 1) */
576 p_msg->offset -= 1; /* Point to SoD field */
577 p = (uint8_t*)(p_msg + 1) + p_msg->offset;
578 UINT8_TO_STREAM(p, (p_msg->len + 1));
579 p_msg->len += 1; /* Increment len to include SoD */
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800580
581#if (BT_TRACE_PROTOCOL == TRUE)
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800582 DispT3TagMessage(p_msg, false);
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800583#endif
584
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800585 return (NFC_SendData(NFC_RF_CONN_ID, p_msg));
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800586}
587
588/*****************************************************************************
589**
590** Function rw_t3t_get_cmd_buf
591**
592** Description Get a buffer for sending T3T messages
593**
Ruchi Kandoi0a736882017-01-09 15:43:14 -0800594** Returns NFC_HDR *
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800595**
596*****************************************************************************/
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800597NFC_HDR* rw_t3t_get_cmd_buf(void) {
598 NFC_HDR* p_cmd_buf;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800599
Ruchi Kandoi0c515ae2017-01-30 17:48:41 -0800600 p_cmd_buf = (NFC_HDR*)GKI_getpoolbuf(NFC_RW_POOL_ID);
601 if (p_cmd_buf != NULL) {
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800602 /* Reserve offset for NCI_DATA_HDR and NFC-F Sod (LEN) field */
603 p_cmd_buf->offset = NCI_MSG_OFFSET_SIZE + NCI_DATA_HDR_SIZE + 1;
604 p_cmd_buf->len = 0;
605 }
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800606
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800607 return (p_cmd_buf);
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800608}
609
610/*****************************************************************************
611**
612** Function rw_t3t_send_cmd
613**
614** Description Send command to tag, and start timer for response
615**
616** Returns tNFC_STATUS
617**
618*****************************************************************************/
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800619tNFC_STATUS rw_t3t_send_cmd(tRW_T3T_CB* p_cb, uint8_t rw_t3t_cmd,
620 NFC_HDR* p_cmd_buf, uint32_t timeout_ticks) {
621 tNFC_STATUS retval;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800622
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800623 /* Indicate first attempt to send command, back up cmd buffer in case needed
624 * for retransmission */
625 rw_cb.cur_retry = 0;
626 memcpy(p_cb->p_cur_cmd_buf, p_cmd_buf,
627 sizeof(NFC_HDR) + p_cmd_buf->offset + p_cmd_buf->len);
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800628
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800629 p_cb->cur_cmd = rw_t3t_cmd;
630 p_cb->cur_tout = timeout_ticks;
631 p_cb->rw_state = RW_T3T_STATE_COMMAND_PENDING;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800632
Ruchi Kandoi0c515ae2017-01-30 17:48:41 -0800633 retval = rw_t3t_send_to_lower(p_cmd_buf);
634 if (retval == NFC_STATUS_OK) {
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800635 /* Start timer for waiting for response */
636 nfc_start_quick_timer(&p_cb->timer, NFC_TTYPE_RW_T3T_RESPONSE,
637 timeout_ticks);
638 } else {
639 /* Error sending */
640 p_cb->rw_state = RW_T3T_STATE_IDLE;
641 }
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800642
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800643 RW_TRACE_DEBUG3("rw_t3t_send_cmd: cur_tout: %d, timeout_ticks: %d ret:%d",
644 p_cb->cur_tout, timeout_ticks, retval);
645 return (retval);
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800646}
647
648/*****************************************************************************
649**
650** Function rw_t3t_send_update_ndef_attribute_cmd
651**
652** Description Send UPDATE command for Attribute Information
653**
654** Returns tNFC_STATUS
655**
656*****************************************************************************/
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800657tNFC_STATUS rw_t3t_send_update_ndef_attribute_cmd(tRW_T3T_CB* p_cb,
658 bool write_in_progress) {
659 tNFC_STATUS retval = NFC_STATUS_OK;
660 NFC_HDR* p_cmd_buf;
661 uint8_t *p_cmd_start, *p;
662 uint16_t checksum, i;
663 uint8_t write_f;
664 uint32_t ln;
665 uint8_t* p_ndef_attr_info_start;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800666
Ruchi Kandoi0c515ae2017-01-30 17:48:41 -0800667 p_cmd_buf = rw_t3t_get_cmd_buf();
668 if (p_cmd_buf != NULL) {
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800669 /* Construct T3T message */
670 p = p_cmd_start = (uint8_t*)(p_cmd_buf + 1) + p_cmd_buf->offset;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800671
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800672 /* Add UPDATE opcode to message */
673 UINT8_TO_STREAM(p, T3T_MSG_OPC_UPDATE_CMD);
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800674
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800675 /* Add IDm to message */
676 ARRAY_TO_STREAM(p, p_cb->peer_nfcid2, NCI_NFCID2_LEN);
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800677
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800678 /* Add Service code list */
679 UINT8_TO_STREAM(p, 1); /* Number of services (only 1 service: NDEF) */
680 UINT16_TO_STREAM(
681 p, T3T_MSG_NDEF_SC_RW); /* Service code (little-endian format) */
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800682
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800683 /* Add number of blocks in this UPDATE command */
684 UINT8_TO_STREAM(p, 1); /* Number of blocks to write in this command */
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800685
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800686 /* Block List element: the NDEF attribute information block (block 0) */
687 UINT8_TO_STREAM(p, T3T_MSG_MASK_TWO_BYTE_BLOCK_DESC_FORMAT);
688 UINT8_TO_STREAM(p, 0);
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800689
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800690 /* Add payload (Attribute information block) */
691 p_ndef_attr_info_start =
692 p; /* Save start of a NDEF attribute info block for checksum */
693 UINT8_TO_STREAM(p, T3T_MSG_NDEF_VERSION);
694 UINT8_TO_STREAM(p, p_cb->ndef_attrib.nbr);
695 UINT8_TO_STREAM(p, p_cb->ndef_attrib.nbw);
696 UINT16_TO_BE_STREAM(p, p_cb->ndef_attrib.nmaxb);
697 UINT32_TO_STREAM(p, 0);
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800698
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800699 /* If starting NDEF write: set WriteF=ON, and ln=current ndef length */
700 if (write_in_progress) {
701 write_f = T3T_MSG_NDEF_WRITEF_ON;
702 ln = p_cb->ndef_attrib.ln;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800703 }
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800704 /* If finishing NDEF write: set WriteF=OFF, and ln=new ndef len */
705 else {
706 write_f = T3T_MSG_NDEF_WRITEF_OFF;
707 ln = p_cb->ndef_msg_len;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800708 }
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800709 UINT8_TO_STREAM(p, write_f);
710 UINT8_TO_STREAM(p, p_cb->ndef_attrib.rwflag);
711 UINT8_TO_STREAM(p, (ln >> 16) & 0xFF); /* High byte (of 3) of Ln */
712 UINT8_TO_STREAM(p, (ln >> 8) & 0xFF); /* Middle byte (of 3) of Ln */
713 UINT8_TO_STREAM(p, (ln)&0xFF); /* Low byte (of 3) of Ln */
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800714
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800715 /* Calculate and append Checksum */
716 checksum = 0;
717 for (i = 0; i < T3T_MSG_NDEF_ATTR_INFO_SIZE; i++) {
718 checksum += p_ndef_attr_info_start[i];
719 }
720 UINT16_TO_BE_STREAM(p, checksum);
721
722 /* Calculate length of message */
723 p_cmd_buf->len = (uint16_t)(p - p_cmd_start);
724
725 /* Send the T3T message */
726 retval = rw_t3t_send_cmd(p_cb, RW_T3T_CMD_UPDATE_NDEF, p_cmd_buf,
727 rw_t3t_update_timeout(1));
728 } else {
729 retval = NFC_STATUS_NO_BUFFERS;
730 }
731
732 return (retval);
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800733}
734
735/*****************************************************************************
736**
737** Function rw_t3t_send_next_ndef_update_cmd
738**
739** Description Send next segment of NDEF message to update
740**
741** Returns tNFC_STATUS
742**
743*****************************************************************************/
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800744tNFC_STATUS rw_t3t_send_next_ndef_update_cmd(tRW_T3T_CB* p_cb) {
745 tNFC_STATUS retval = NFC_STATUS_OK;
746 uint16_t block_id;
747 uint16_t first_block_to_write;
748 uint16_t ndef_blocks_to_write, ndef_blocks_remaining;
749 uint32_t ndef_bytes_remaining, ndef_padding = 0;
750 uint8_t flags = 0;
751 uint8_t* p_cur_ndef_src_offset;
752 NFC_HDR* p_cmd_buf;
753 uint8_t *p_cmd_start, *p;
754 uint8_t blocks_per_update;
755 uint32_t timeout;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800756
Ruchi Kandoi0c515ae2017-01-30 17:48:41 -0800757 p_cmd_buf = rw_t3t_get_cmd_buf();
758 if (p_cmd_buf != NULL) {
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800759 /* Construct T3T message */
760 p = p_cmd_start = (uint8_t*)(p_cmd_buf + 1) + p_cmd_buf->offset;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800761
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800762 /* Calculate number of ndef bytes remaining to write */
763 ndef_bytes_remaining = p_cb->ndef_msg_len - p_cb->ndef_msg_bytes_sent;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800764
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800765 /* Calculate number of blocks remaining to write */
766 ndef_blocks_remaining =
767 (uint16_t)((ndef_bytes_remaining + 15) >>
768 4); /* ndef blocks remaining (rounded upward) */
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800769
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800770 /* Calculate first NDEF block ID for this UPDATE command */
771 first_block_to_write = (uint16_t)((p_cb->ndef_msg_bytes_sent >> 4) + 1);
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800772
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800773 /* Calculate max number of blocks per write. */
774 if ((first_block_to_write +
775 RW_T3T_MAX_NDEF_BLOCKS_PER_UPDATE_1_BYTE_FORMAT) < 0x100) {
776 /* All block-numbers are < 0x100 (i.e. can be specified using one-byte
777 * format) */
778 blocks_per_update = RW_T3T_MAX_NDEF_BLOCKS_PER_UPDATE_1_BYTE_FORMAT;
779 } else {
780 /* Block-numbers are >= 0x100 (i.e. need to be specified using two-byte
781 * format) */
782 blocks_per_update = RW_T3T_MAX_NDEF_BLOCKS_PER_UPDATE_2_BYTE_FORMAT;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800783 }
784
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800785 /* Check if blocks_per_update is bigger than what peer allows */
786 if (blocks_per_update > p_cb->ndef_attrib.nbw)
787 blocks_per_update = p_cb->ndef_attrib.nbw;
788
789 /* Check if remaining blocks can fit into one UPDATE command */
790 if (ndef_blocks_remaining <= blocks_per_update) {
791 /* remaining blocks can fit into one UPDATE command */
792 ndef_blocks_to_write = ndef_blocks_remaining;
793 } else {
794 /* Remaining blocks cannot fit into one UPDATE command */
795 ndef_blocks_to_write = blocks_per_update;
796 }
797
798 /* Write to command header for UPDATE */
799
800 /* Add UPDATE opcode to message */
801 UINT8_TO_STREAM(p, T3T_MSG_OPC_UPDATE_CMD);
802
803 /* Add IDm to message */
804 ARRAY_TO_STREAM(p, p_cb->peer_nfcid2, NCI_NFCID2_LEN);
805
806 /* Add Service code list */
807 UINT8_TO_STREAM(p, 1); /* Number of services (only 1 service: NDEF) */
808 UINT16_TO_STREAM(
809 p, T3T_MSG_NDEF_SC_RW); /* Service code (little-endian format) */
810
811 /* Add number of blocks in this UPDATE command */
812 UINT8_TO_STREAM(
813 p,
814 ndef_blocks_to_write); /* Number of blocks to write in this command */
815 timeout = rw_t3t_update_timeout(ndef_blocks_to_write);
816
817 for (block_id = first_block_to_write;
818 block_id < (first_block_to_write + ndef_blocks_to_write); block_id++) {
819 if (block_id < 256) {
820 /* Block IDs 0-255 can be specified in '2-byte' format: byte0=0,
821 * byte1=blocknumber */
822 UINT8_TO_STREAM(
823 p, T3T_MSG_MASK_TWO_BYTE_BLOCK_DESC_FORMAT); /* byte0: len=1;
824 access-mode=0;
825 service code list
826 order=0 */
827 UINT8_TO_STREAM(p, block_id); /* byte1: block number */
828 } else {
829 /* Block IDs 256+ must be specified in '3-byte' format: byte0=80h,
830 * followed by blocknumber */
831 UINT8_TO_STREAM(
832 p,
833 0x00); /* byte0: len=0; access-mode=0; service code list order=0 */
834 UINT16_TO_STREAM(
835 p, block_id); /* byte1-2: block number in little-endian format */
836 }
837 }
838
839 /* Add NDEF payload */
840
841 /* If this sending last block of NDEF, check if padding is needed to make
842 * payload a multiple of 16 bytes */
843 if (ndef_blocks_to_write == ndef_blocks_remaining) {
844 ndef_padding = (16 - (ndef_bytes_remaining & 0x0F)) & 0x0F;
845 if (ndef_padding) {
846 flags |= RW_T3T_FL_PADDING;
847 ndef_blocks_to_write--; /* handle the last block separately if it needs
848 padding */
849 }
850 }
851
852 /* Add NDEF payload to the message */
853 p_cur_ndef_src_offset = &p_cb->ndef_msg[p_cb->ndef_msg_bytes_sent];
854
855 ARRAY_TO_STREAM(p, p_cur_ndef_src_offset, (ndef_blocks_to_write * 16));
856 p_cb->ndef_msg_bytes_sent += ((uint32_t)ndef_blocks_to_write * 16);
857
858 if (flags & RW_T3T_FL_PADDING) {
859 /* Add last of the NDEF message */
860 p_cur_ndef_src_offset = &p_cb->ndef_msg[p_cb->ndef_msg_bytes_sent];
861 ARRAY_TO_STREAM(p, p_cur_ndef_src_offset, (int)(16 - ndef_padding));
862 p_cb->ndef_msg_bytes_sent += (16 - ndef_padding);
863
864 /* Add padding */
865 memset(p, 0, ndef_padding);
866 p += ndef_padding;
867 }
868
869 /* Calculate length of message */
870 p_cmd_buf->len = (uint16_t)(p - p_cmd_start);
871
872 /* Send the T3T message */
873 retval = rw_t3t_send_cmd(p_cb, RW_T3T_CMD_UPDATE_NDEF, p_cmd_buf, timeout);
874 } else {
875 retval = NFC_STATUS_NO_BUFFERS;
876 }
877
878 return (retval);
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800879}
880
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800881/*****************************************************************************
882**
883** Function rw_t3t_send_next_ndef_check_cmd
884**
885** Description Send command for reading next segment of NDEF message
886**
887** Returns tNFC_STATUS
888**
889*****************************************************************************/
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800890tNFC_STATUS rw_t3t_send_next_ndef_check_cmd(tRW_T3T_CB* p_cb) {
891 tNFC_STATUS retval = NFC_STATUS_OK;
892 uint16_t block_id;
893 uint16_t ndef_blocks_remaining, first_block_to_read, cur_blocks_to_read;
894 uint32_t ndef_bytes_remaining;
895 NFC_HDR* p_cmd_buf;
896 uint8_t *p_cmd_start, *p;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800897
Ruchi Kandoi0c515ae2017-01-30 17:48:41 -0800898 p_cmd_buf = rw_t3t_get_cmd_buf();
899 if (p_cmd_buf != NULL) {
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800900 /* Construct T3T message */
901 p = p_cmd_start = (uint8_t*)(p_cmd_buf + 1) + p_cmd_buf->offset;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800902
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800903 /* Calculate number of ndef bytes remaining to read */
904 ndef_bytes_remaining = p_cb->ndef_attrib.ln - p_cb->ndef_rx_offset;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800905
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800906 /* Calculate number of blocks remaining to read */
907 ndef_blocks_remaining =
908 (uint16_t)((ndef_bytes_remaining + 15) >>
909 4); /* ndef blocks remaining (rounded upward) */
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800910
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800911 /* Calculate first NDEF block ID */
912 first_block_to_read = (uint16_t)((p_cb->ndef_rx_offset >> 4) + 1);
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800913
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800914 /* Check if remaining blocks can fit into one CHECK command */
915 if (ndef_blocks_remaining <= p_cb->ndef_attrib.nbr) {
916 /* remaining blocks can fit into one CHECK command */
917 cur_blocks_to_read = ndef_blocks_remaining;
918 p_cb->ndef_rx_readlen = ndef_bytes_remaining;
919 p_cb->flags |= RW_T3T_FL_IS_FINAL_NDEF_SEGMENT;
920 } else {
921 /* Remaining blocks cannot fit into one CHECK command */
922 cur_blocks_to_read =
923 p_cb->ndef_attrib
924 .nbr; /* Read maximum number of blocks allowed by the peer */
925 p_cb->ndef_rx_readlen = ((uint32_t)p_cb->ndef_attrib.nbr * 16);
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800926 }
927
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800928 RW_TRACE_DEBUG3(
929 "rw_t3t_send_next_ndef_check_cmd: bytes_remaining: %i, "
930 "cur_blocks_to_read: %i, is_final: %i",
931 ndef_bytes_remaining, cur_blocks_to_read,
932 (p_cb->flags & RW_T3T_FL_IS_FINAL_NDEF_SEGMENT));
933
934 /* Add CHECK opcode to message */
935 UINT8_TO_STREAM(p, T3T_MSG_OPC_CHECK_CMD);
936
937 /* Add IDm to message */
938 ARRAY_TO_STREAM(p, p_cb->peer_nfcid2, NCI_NFCID2_LEN);
939
940 /* Add Service code list */
941 UINT8_TO_STREAM(p, 1); /* Number of services (only 1 service: NDEF) */
942
943 /* Service code (little-endian format) . If NDEF is read-only, then use
944 * T3T_MSG_NDEF_SC_RO, otherwise use T3T_MSG_NDEF_SC_RW */
945 if (p_cb->ndef_attrib.rwflag == T3T_MSG_NDEF_RWFLAG_RO) {
946 UINT16_TO_STREAM(p, T3T_MSG_NDEF_SC_RO);
947 } else {
948 UINT16_TO_STREAM(p, T3T_MSG_NDEF_SC_RW);
949 }
950
951 /* Add number of blocks in this CHECK command */
952 UINT8_TO_STREAM(
953 p, cur_blocks_to_read); /* Number of blocks to check in this command */
954
955 for (block_id = first_block_to_read;
956 block_id < (first_block_to_read + cur_blocks_to_read); block_id++) {
957 if (block_id < 256) {
958 /* Block IDs 0-255 can be specified in '2-byte' format: byte0=0,
959 * byte1=blocknumber */
960 UINT8_TO_STREAM(
961 p, T3T_MSG_MASK_TWO_BYTE_BLOCK_DESC_FORMAT); /* byte1: len=0;
962 access-mode=0;
963 service code list
964 order=0 */
965 UINT8_TO_STREAM(p, block_id); /* byte1: block number */
966 } else {
967 /* Block IDs 256+ must be specified in '3-byte' format: byte0=80h,
968 * followed by blocknumber */
969 UINT8_TO_STREAM(
970 p,
971 0x00); /* byte0: len=1; access-mode=0; service code list order=0 */
972 UINT16_TO_STREAM(
973 p, block_id); /* byte1-2: block number in little-endian format */
974 }
975 }
976
977 /* Calculate length of message */
978 p_cmd_buf->len = (uint16_t)(p - p_cmd_start);
979
980 /* Send the T3T message */
981 retval = rw_t3t_send_cmd(p_cb, RW_T3T_CMD_CHECK_NDEF, p_cmd_buf,
982 rw_t3t_check_timeout(cur_blocks_to_read));
983 } else {
984 retval = NFC_STATUS_NO_BUFFERS;
985 }
986
987 return (retval);
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800988}
989
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800990/*****************************************************************************
991**
992** Function rw_t3t_message_set_block_list
993**
994** Description Add block list to T3T message
995**
996** Returns Number of bytes added to message
997**
998*****************************************************************************/
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800999void rw_t3t_message_set_block_list(tRW_T3T_CB* p_cb, uint8_t** p,
1000 uint8_t num_blocks,
1001 tT3T_BLOCK_DESC* p_t3t_blocks) {
1002 uint16_t i, cur_service_code;
1003 uint8_t service_code_idx, num_services = 0;
1004 uint8_t* p_msg_num_services;
1005 uint16_t service_list[T3T_MSG_SERVICE_LIST_MAX];
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001006
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001007 /* Add CHECK or UPDATE opcode to message */
1008 UINT8_TO_STREAM(
1009 (*p), ((p_cb->cur_cmd == RW_T3T_CMD_CHECK) ? T3T_MSG_OPC_CHECK_CMD
1010 : T3T_MSG_OPC_UPDATE_CMD));
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001011
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001012 /* Add IDm to message */
1013 ARRAY_TO_STREAM((*p), p_cb->peer_nfcid2, NCI_NFCID2_LEN);
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001014
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001015 /* Skip over Number of Services field */
1016 p_msg_num_services = (*p); /* pointer to Number of Services offset */
1017 (*p)++;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001018
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001019 /* Count number of different services are specified in the list, and add
1020 * services to Service Code list */
1021 for (i = 0; i < num_blocks; i++) {
1022 cur_service_code = p_t3t_blocks[i].service_code;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001023
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001024 /* Check if current service_code is already in the service_list */
1025 for (service_code_idx = 0; service_code_idx < num_services;
1026 service_code_idx++) {
1027 if (service_list[service_code_idx] == cur_service_code) break;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001028 }
1029
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001030 if (service_code_idx == num_services) {
1031 /* Service not in the list yet. Add it. */
1032 service_list[service_code_idx] = cur_service_code;
1033 num_services++;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001034
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001035 /* Add service code to T3T message */
1036 UINT16_TO_STREAM((*p), cur_service_code);
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001037 }
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001038 }
1039
1040 /* Add 'Number of Sservices' to the message */
1041 *p_msg_num_services = num_services;
1042
1043 /* Add 'number of blocks' to the message */
1044 UINT8_TO_STREAM((*p), num_blocks);
1045
1046 /* Add block descriptors */
1047 for (i = 0; i < num_blocks; i++) {
1048 cur_service_code = p_t3t_blocks[i].service_code;
1049
1050 /* Check if current service_code is already in the service_list */
1051 for (service_code_idx = 0; service_code_idx < num_services;
1052 service_code_idx++) {
1053 if (service_list[service_code_idx] == cur_service_code) break;
1054 }
1055
1056 /* Add decriptor to T3T message */
1057 if (p_t3t_blocks[i].block_number > 0xFF) {
1058 UINT8_TO_STREAM((*p), service_code_idx);
1059 UINT16_TO_STREAM((*p), p_t3t_blocks[i].block_number);
1060 } else {
1061 service_code_idx |= T3T_MSG_MASK_TWO_BYTE_BLOCK_DESC_FORMAT;
1062 UINT8_TO_STREAM((*p), service_code_idx);
1063 UINT8_TO_STREAM((*p), p_t3t_blocks[i].block_number);
1064 }
1065 }
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001066}
1067
1068/*****************************************************************************
1069**
1070** Function rw_t3t_send_check_cmd
1071**
1072** Description Send CHECK command
1073**
1074** Returns tNFC_STATUS
1075**
1076*****************************************************************************/
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001077tNFC_STATUS rw_t3t_send_check_cmd(tRW_T3T_CB* p_cb, uint8_t num_blocks,
1078 tT3T_BLOCK_DESC* p_t3t_blocks) {
1079 NFC_HDR* p_cmd_buf;
1080 uint8_t *p, *p_cmd_start;
1081 tNFC_STATUS retval = NFC_STATUS_OK;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001082
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001083 p_cb->cur_cmd = RW_T3T_CMD_CHECK;
Ruchi Kandoi0c515ae2017-01-30 17:48:41 -08001084 p_cmd_buf = rw_t3t_get_cmd_buf();
1085 if (p_cmd_buf != NULL) {
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001086 /* Construct T3T message */
1087 p = p_cmd_start = (uint8_t*)(p_cmd_buf + 1) + p_cmd_buf->offset;
1088 rw_t3t_message_set_block_list(p_cb, &p, num_blocks, p_t3t_blocks);
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001089
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001090 /* Calculate length of message */
1091 p_cmd_buf->len = (uint16_t)(p - p_cmd_start);
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001092
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001093 /* Send the T3T message */
1094 retval = rw_t3t_send_cmd(p_cb, RW_T3T_CMD_CHECK, p_cmd_buf,
1095 rw_t3t_check_timeout(num_blocks));
1096 } else {
1097 retval = NFC_STATUS_NO_BUFFERS;
1098 }
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001099
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001100 return (retval);
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001101}
1102
1103/*****************************************************************************
1104**
1105** Function rw_t3t_send_update_cmd
1106**
1107** Description Send UPDATE command
1108**
1109** Returns tNFC_STATUS
1110**
1111*****************************************************************************/
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001112tNFC_STATUS rw_t3t_send_update_cmd(tRW_T3T_CB* p_cb, uint8_t num_blocks,
1113 tT3T_BLOCK_DESC* p_t3t_blocks,
1114 uint8_t* p_data) {
1115 NFC_HDR* p_cmd_buf;
1116 uint8_t *p, *p_cmd_start;
1117 tNFC_STATUS retval = NFC_STATUS_OK;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001118
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001119 p_cb->cur_cmd = RW_T3T_CMD_UPDATE;
Ruchi Kandoi0c515ae2017-01-30 17:48:41 -08001120 p_cmd_buf = rw_t3t_get_cmd_buf();
1121 if (p_cmd_buf != NULL) {
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001122 /* Construct T3T message */
1123 p = p_cmd_start = (uint8_t*)(p_cmd_buf + 1) + p_cmd_buf->offset;
1124 rw_t3t_message_set_block_list(p_cb, &p, num_blocks, p_t3t_blocks);
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001125
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001126 /* Add data blocks to the message */
1127 ARRAY_TO_STREAM(p, p_data, num_blocks * 16);
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001128
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001129 /* Calculate length of message */
1130 p_cmd_buf->len = (uint16_t)(p - p_cmd_start);
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001131
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001132 /* Send the T3T message */
1133 retval = rw_t3t_send_cmd(p_cb, RW_T3T_CMD_UPDATE, p_cmd_buf,
1134 rw_t3t_update_timeout(num_blocks));
1135 } else {
1136 retval = NFC_STATUS_NO_BUFFERS;
1137 }
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001138
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001139 return (retval);
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001140}
1141
1142/*****************************************************************************
1143**
Martijn Coenen5c65c3a2013-03-27 13:23:36 -07001144** Function rw_t3t_check_mc_block
1145**
1146** Description Send command to check Memory Configuration Block
1147**
1148** Returns tNFC_STATUS
1149**
1150*****************************************************************************/
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001151tNFC_STATUS rw_t3t_check_mc_block(tRW_T3T_CB* p_cb) {
1152 NFC_HDR* p_cmd_buf;
1153 uint8_t *p, *p_cmd_start;
Martijn Coenen5c65c3a2013-03-27 13:23:36 -07001154
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001155 /* Read Memory Configuration block */
Ruchi Kandoi0c515ae2017-01-30 17:48:41 -08001156 p_cmd_buf = rw_t3t_get_cmd_buf();
1157 if (p_cmd_buf != NULL) {
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001158 /* Construct T3T message */
1159 p = p_cmd_start = (uint8_t*)(p_cmd_buf + 1) + p_cmd_buf->offset;
Martijn Coenen5c65c3a2013-03-27 13:23:36 -07001160
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001161 /* Add CHECK opcode to message */
1162 UINT8_TO_STREAM(p, T3T_MSG_OPC_CHECK_CMD);
Martijn Coenen5c65c3a2013-03-27 13:23:36 -07001163
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001164 /* Add IDm to message */
1165 ARRAY_TO_STREAM(p, p_cb->peer_nfcid2, NCI_NFCID2_LEN);
Martijn Coenen5c65c3a2013-03-27 13:23:36 -07001166
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001167 /* Add Service code list */
1168 UINT8_TO_STREAM(p, 1); /* Number of services (only 1 service: NDEF) */
1169 UINT16_TO_STREAM(
1170 p, T3T_MSG_NDEF_SC_RO); /* Service code (little-endian format) */
Martijn Coenen5c65c3a2013-03-27 13:23:36 -07001171
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001172 /* Number of blocks */
1173 UINT8_TO_STREAM(p, 1); /* Number of blocks (only 1 block: Memory
1174 Configuration Information ) */
Martijn Coenen5c65c3a2013-03-27 13:23:36 -07001175
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001176 /* Block List element: the Memory Configuration block (block 0x88) */
1177 UINT8_TO_STREAM(p, T3T_MSG_MASK_TWO_BYTE_BLOCK_DESC_FORMAT);
1178 UINT8_TO_STREAM(p, T3T_MSG_FELICALITE_BLOCK_ID_MC);
Martijn Coenen5c65c3a2013-03-27 13:23:36 -07001179
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001180 /* Calculate length of message */
1181 p_cmd_buf->len = (uint16_t)(p - p_cmd_start);
Martijn Coenen5c65c3a2013-03-27 13:23:36 -07001182
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001183 /* Send the T3T message */
1184 return rw_t3t_send_cmd(p_cb, p_cb->cur_cmd, p_cmd_buf,
1185 rw_t3t_check_timeout(1));
1186 } else {
1187 RW_TRACE_ERROR0("Unable to allocate buffer to read MC block");
1188 return (NFC_STATUS_NO_BUFFERS);
1189 }
Martijn Coenen5c65c3a2013-03-27 13:23:36 -07001190}
1191
1192/*****************************************************************************
1193**
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001194** Function rw_t3t_send_raw_frame
1195**
1196** Description Send raw frame
1197**
1198** Returns tNFC_STATUS
1199**
1200*****************************************************************************/
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001201tNFC_STATUS rw_t3t_send_raw_frame(tRW_T3T_CB* p_cb, uint16_t len,
1202 uint8_t* p_data) {
1203 NFC_HDR* p_cmd_buf;
1204 uint8_t* p;
1205 tNFC_STATUS retval = NFC_STATUS_OK;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001206
Ruchi Kandoi0c515ae2017-01-30 17:48:41 -08001207 p_cmd_buf = rw_t3t_get_cmd_buf();
1208 if (p_cmd_buf != NULL) {
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001209 /* Construct T3T message */
1210 p = (uint8_t*)(p_cmd_buf + 1) + p_cmd_buf->offset;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001211
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001212 /* Add data blocks to the message */
1213 ARRAY_TO_STREAM(p, p_data, len);
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001214
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001215 /* Calculate length of message */
1216 p_cmd_buf->len = len;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001217
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001218 /* Send the T3T message */
1219 retval = rw_t3t_send_cmd(p_cb, RW_T3T_CMD_SEND_RAW_FRAME, p_cmd_buf,
1220 RW_T3T_RAW_FRAME_CMD_TIMEOUT_TICKS);
1221 } else {
1222 retval = NFC_STATUS_NO_BUFFERS;
1223 }
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001224
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001225 return (retval);
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001226}
1227
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001228/*****************************************************************************
1229** TAG RESPONSE HANDLERS
1230*****************************************************************************/
1231
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001232/*****************************************************************************
1233**
1234** Function rw_t3t_act_handle_ndef_detect_rsp
1235**
1236** Description Handle response to NDEF detection
1237**
1238** Returns Nothing
1239**
1240*****************************************************************************/
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001241void rw_t3t_act_handle_ndef_detect_rsp(tRW_T3T_CB* p_cb, NFC_HDR* p_msg_rsp) {
1242 uint8_t* p;
1243 uint32_t temp;
1244 uint8_t i;
1245 uint16_t checksum_calc, checksum_rx;
1246 tRW_DETECT_NDEF_DATA evt_data;
1247 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 -08001248
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001249 evt_data.status = NFC_STATUS_FAILED;
1250 evt_data.flags = RW_NDEF_FL_UNKNOWN;
1251
1252 /* Check if response code is CHECK resp (for reading NDEF attribute block) */
1253 if (p_t3t_rsp[T3T_MSG_RSP_OFFSET_RSPCODE] != T3T_MSG_OPC_CHECK_RSP) {
1254 RW_TRACE_ERROR2("Response error: expecting rsp_code %02X, but got %02X",
1255 T3T_MSG_OPC_CHECK_RSP,
1256 p_t3t_rsp[T3T_MSG_RSP_OFFSET_RSPCODE]);
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001257 evt_data.status = NFC_STATUS_FAILED;
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001258 }
1259 /* Validate status code and NFCID2 response from tag */
1260 else if ((p_t3t_rsp[T3T_MSG_RSP_OFFSET_STATUS1] !=
1261 T3T_MSG_RSP_STATUS_OK) /* verify response status code */
1262 || (memcmp(p_cb->peer_nfcid2, &p_t3t_rsp[T3T_MSG_RSP_OFFSET_IDM],
1263 NCI_NFCID2_LEN) != 0)) /* verify response IDm */
1264 {
1265 evt_data.status = NFC_STATUS_FAILED;
1266 } else {
1267 /* Get checksum from received ndef attribute msg */
1268 p = &p_t3t_rsp[T3T_MSG_RSP_OFFSET_CHECK_DATA + T3T_MSG_NDEF_ATTR_INFO_SIZE];
1269 BE_STREAM_TO_UINT16(checksum_rx, p);
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001270
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001271 /* Calculate checksum - move check for checsum to beginning */
1272 checksum_calc = 0;
1273 p = &p_t3t_rsp[T3T_MSG_RSP_OFFSET_CHECK_DATA];
1274 for (i = 0; i < T3T_MSG_NDEF_ATTR_INFO_SIZE; i++) {
1275 checksum_calc += p[i];
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001276 }
1277
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001278 /* Validate checksum */
1279 if (checksum_calc != checksum_rx) {
1280 p_cb->ndef_attrib.status =
1281 NFC_STATUS_FAILED; /* only ok or failed passed to the app. can be
1282 boolean*/
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001283
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001284 RW_TRACE_ERROR0("RW_T3tDetectNDEF checksum failed");
1285 } else {
1286 p_cb->ndef_attrib.status = NFC_STATUS_OK;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001287
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001288 /* Validate version number */
1289 STREAM_TO_UINT8(p_cb->ndef_attrib.version, p);
1290
1291 if (T3T_GET_MAJOR_VERSION(T3T_MSG_NDEF_VERSION) <
1292 T3T_GET_MAJOR_VERSION(p_cb->ndef_attrib.version)) {
1293 /* Remote tag's MajorVer is newer than our's. Reject NDEF as per T3TOP
1294 * RQ_T3T_NDA_024 */
1295 RW_TRACE_ERROR2(
1296 "RW_T3tDetectNDEF: incompatible NDEF version. Local=0x%02x, "
1297 "Remote=0x%02x",
1298 T3T_MSG_NDEF_VERSION, p_cb->ndef_attrib.version);
1299 p_cb->ndef_attrib.status = NFC_STATUS_FAILED;
1300 evt_data.status = NFC_STATUS_BAD_RESP;
1301 } else {
1302 /* Remote tag's MajorVer is equal or older than our's. NDEF is
1303 * compatible with our version. */
1304
1305 /* Update NDEF info */
1306 STREAM_TO_UINT8(
1307 p_cb->ndef_attrib.nbr,
1308 p); /* NBr: number of blocks that can be read using one Check
1309 command */
1310 STREAM_TO_UINT8(p_cb->ndef_attrib.nbw,
1311 p); /* Nbw: number of blocks that can be written using
1312 one Update command */
1313 BE_STREAM_TO_UINT16(
1314 p_cb->ndef_attrib.nmaxb,
1315 p); /* Nmaxb: maximum number of blocks available for NDEF data */
1316 BE_STREAM_TO_UINT32(temp, p);
1317 STREAM_TO_UINT8(p_cb->ndef_attrib.writef,
1318 p); /* WriteFlag: 00h if writing data finished; 0Fh if
1319 writing data in progress */
1320 STREAM_TO_UINT8(
1321 p_cb->ndef_attrib.rwflag,
1322 p); /* RWFlag: 00h NDEF is read-only; 01h if read/write available */
1323
1324 /* Get length (3-byte, big-endian) */
1325 STREAM_TO_UINT8(temp, p); /* Ln: high-byte */
1326 BE_STREAM_TO_UINT16(p_cb->ndef_attrib.ln, p); /* Ln: lo-word */
1327 p_cb->ndef_attrib.ln += (temp << 16);
1328
1329 RW_TRACE_DEBUG1("Detected NDEF Ver: 0x%02x", p_cb->ndef_attrib.version);
1330 RW_TRACE_DEBUG6(
1331 "Detected NDEF Attributes: Nbr=%i, Nbw=%i, Nmaxb=%i, WriteF=%i, "
1332 "RWFlag=%i, Ln=%i",
1333 p_cb->ndef_attrib.nbr, p_cb->ndef_attrib.nbw,
1334 p_cb->ndef_attrib.nmaxb, p_cb->ndef_attrib.writef,
1335 p_cb->ndef_attrib.rwflag, p_cb->ndef_attrib.ln);
1336
1337 /* Set data for RW_T3T_NDEF_DETECT_EVT */
1338 evt_data.status = p_cb->ndef_attrib.status;
1339 evt_data.cur_size = p_cb->ndef_attrib.ln;
1340 evt_data.max_size = (uint32_t)p_cb->ndef_attrib.nmaxb * 16;
1341 evt_data.protocol = NFC_PROTOCOL_T3T;
1342 evt_data.flags = (RW_NDEF_FL_SUPPORTED | RW_NDEF_FL_FORMATED);
1343 if (p_cb->ndef_attrib.rwflag == T3T_MSG_NDEF_RWFLAG_RO)
1344 evt_data.flags |= RW_NDEF_FL_READ_ONLY;
1345 }
1346 }
1347 }
1348
1349 RW_TRACE_DEBUG1("RW_T3tDetectNDEF response: %i", evt_data.status);
1350
1351 p_cb->rw_state = RW_T3T_STATE_IDLE;
1352 rw_t3t_update_ndef_flag(&evt_data.flags);
1353 /* Notify app of NDEF detection result */
1354 (*(rw_cb.p_cback))(RW_T3T_NDEF_DETECT_EVT, (tRW_DATA*)&evt_data);
1355
1356 GKI_freebuf(p_msg_rsp);
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001357}
1358
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001359/*****************************************************************************
1360**
1361** Function rw_t3t_act_handle_check_rsp
1362**
1363** Description Handle response to CHECK command
1364**
1365** Returns Nothing
1366**
1367*****************************************************************************/
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001368void rw_t3t_act_handle_check_rsp(tRW_T3T_CB* p_cb, NFC_HDR* p_msg_rsp) {
1369 uint8_t* p_t3t_rsp = (uint8_t*)(p_msg_rsp + 1) + p_msg_rsp->offset;
1370 tRW_READ_DATA evt_data;
1371 tNFC_STATUS nfc_status = NFC_STATUS_OK;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001372
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001373 /* Validate response from tag */
1374 if ((p_t3t_rsp[T3T_MSG_RSP_OFFSET_STATUS1] !=
1375 T3T_MSG_RSP_STATUS_OK) /* verify response status code */
1376 || (memcmp(p_cb->peer_nfcid2, &p_t3t_rsp[T3T_MSG_RSP_OFFSET_IDM],
1377 NCI_NFCID2_LEN) != 0)) /* verify response IDm */
1378 {
1379 nfc_status = NFC_STATUS_FAILED;
1380 GKI_freebuf(p_msg_rsp);
1381 } else if (p_t3t_rsp[T3T_MSG_RSP_OFFSET_RSPCODE] != T3T_MSG_OPC_CHECK_RSP) {
1382 RW_TRACE_ERROR2("Response error: expecting rsp_code %02X, but got %02X",
1383 T3T_MSG_OPC_CHECK_RSP,
1384 p_t3t_rsp[T3T_MSG_RSP_OFFSET_RSPCODE]);
1385 nfc_status = NFC_STATUS_FAILED;
1386 GKI_freebuf(p_msg_rsp);
1387 } else {
1388 /* Copy incoming data into buffer */
1389 p_msg_rsp->offset +=
1390 T3T_MSG_RSP_OFFSET_CHECK_DATA; /* Skip over t3t header */
1391 p_msg_rsp->len -= T3T_MSG_RSP_OFFSET_CHECK_DATA;
1392 evt_data.status = NFC_STATUS_OK;
1393 evt_data.p_data = p_msg_rsp;
1394 (*(rw_cb.p_cback))(RW_T3T_CHECK_EVT, (tRW_DATA*)&evt_data);
1395 }
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001396
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001397 p_cb->rw_state = RW_T3T_STATE_IDLE;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001398
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001399 (*(rw_cb.p_cback))(RW_T3T_CHECK_CPLT_EVT, (tRW_DATA*)&nfc_status);
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001400}
1401
1402/*****************************************************************************
1403**
1404** Function rw_t3t_act_handle_update_rsp
1405**
1406** Description Handle response to UPDATE command
1407**
1408** Returns Nothing
1409**
1410*****************************************************************************/
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001411void rw_t3t_act_handle_update_rsp(tRW_T3T_CB* p_cb, NFC_HDR* p_msg_rsp) {
1412 uint8_t* p_t3t_rsp = (uint8_t*)(p_msg_rsp + 1) + p_msg_rsp->offset;
1413 tRW_READ_DATA evt_data;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001414
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001415 /* Validate response from tag */
1416 if ((p_t3t_rsp[T3T_MSG_RSP_OFFSET_STATUS1] !=
1417 T3T_MSG_RSP_STATUS_OK) /* verify response status code */
1418 || (memcmp(p_cb->peer_nfcid2, &p_t3t_rsp[T3T_MSG_RSP_OFFSET_IDM],
1419 NCI_NFCID2_LEN) != 0)) /* verify response IDm */
1420 {
1421 evt_data.status = NFC_STATUS_FAILED;
1422 } else if (p_t3t_rsp[T3T_MSG_RSP_OFFSET_RSPCODE] != T3T_MSG_OPC_UPDATE_RSP) {
1423 RW_TRACE_ERROR2("Response error: expecting rsp_code %02X, but got %02X",
1424 T3T_MSG_OPC_UPDATE_RSP,
1425 p_t3t_rsp[T3T_MSG_RSP_OFFSET_RSPCODE]);
1426 evt_data.status = NFC_STATUS_FAILED;
1427 } else {
1428 /* Copy incoming data into buffer */
1429 evt_data.status = NFC_STATUS_OK;
1430 }
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001431
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001432 p_cb->rw_state = RW_T3T_STATE_IDLE;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001433
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001434 (*(rw_cb.p_cback))(RW_T3T_UPDATE_CPLT_EVT, (tRW_DATA*)&evt_data);
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001435
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001436 GKI_freebuf(p_msg_rsp);
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001437}
1438
1439/*****************************************************************************
1440**
1441** Function rw_t3t_act_handle_raw_senddata_rsp
1442**
1443** Description Handle response to NDEF detection
1444**
1445** Returns Nothing
1446**
1447*****************************************************************************/
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001448void rw_t3t_act_handle_raw_senddata_rsp(tRW_T3T_CB* p_cb,
1449 tNFC_DATA_CEVT* p_data) {
1450 tRW_READ_DATA evt_data;
1451 NFC_HDR* p_pkt = p_data->p_data;
Evan Chua24be4f2013-11-13 15:30:16 -05001452
1453#if (BT_TRACE_VERBOSE == TRUE)
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001454 RW_TRACE_DEBUG2("RW T3T Raw Frame: Len [0x%X] Status [%s]", p_pkt->len,
1455 NFC_GetStatusName(p_data->status));
Evan Chua24be4f2013-11-13 15:30:16 -05001456#else
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001457 RW_TRACE_DEBUG2("RW T3T Raw Frame: Len [0x%X] Status [0x%X]", p_pkt->len,
1458 p_data->status);
Evan Chua24be4f2013-11-13 15:30:16 -05001459#endif
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001460
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001461 /* Copy incoming data into buffer */
1462 evt_data.status = p_data->status;
1463 evt_data.p_data = p_pkt;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001464
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001465 p_cb->rw_state = RW_T3T_STATE_IDLE;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001466
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001467 (*(rw_cb.p_cback))(RW_T3T_RAW_FRAME_EVT, (tRW_DATA*)&evt_data);
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001468}
1469
1470/*****************************************************************************
1471**
1472** Function rw_t3t_act_handle_check_ndef_rsp
1473**
1474** Description Handle response to NDEF read segment
1475**
1476** Returns Nothing
1477**
1478*****************************************************************************/
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001479void rw_t3t_act_handle_check_ndef_rsp(tRW_T3T_CB* p_cb, NFC_HDR* p_msg_rsp) {
1480 bool check_complete = true;
1481 tNFC_STATUS nfc_status = NFC_STATUS_OK;
1482 tRW_READ_DATA read_data;
1483 tRW_DATA evt_data;
1484 uint8_t* p_t3t_rsp = (uint8_t*)(p_msg_rsp + 1) + p_msg_rsp->offset;
1485 uint8_t rsp_num_bytes_rx;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001486
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001487 /* Validate response from tag */
1488 if ((p_t3t_rsp[T3T_MSG_RSP_OFFSET_STATUS1] !=
1489 T3T_MSG_RSP_STATUS_OK) /* verify response status code */
1490 || (memcmp(p_cb->peer_nfcid2, &p_t3t_rsp[T3T_MSG_RSP_OFFSET_IDM],
1491 NCI_NFCID2_LEN) != 0) /* verify response IDm */
1492 || (p_t3t_rsp[T3T_MSG_RSP_OFFSET_NUMBLOCKS] !=
1493 ((p_cb->ndef_rx_readlen + 15) >> 4))) /* verify length of response */
1494 {
1495 RW_TRACE_ERROR2("Response error: bad status, nfcid2, or invalid len: %i %i",
1496 p_t3t_rsp[T3T_MSG_RSP_OFFSET_NUMBLOCKS],
1497 ((p_cb->ndef_rx_readlen + 15) >> 4));
1498 nfc_status = NFC_STATUS_FAILED;
1499 GKI_freebuf(p_msg_rsp);
1500 } else if (p_t3t_rsp[T3T_MSG_RSP_OFFSET_RSPCODE] != T3T_MSG_OPC_CHECK_RSP) {
1501 RW_TRACE_ERROR2("Response error: expecting rsp_code %02X, but got %02X",
1502 T3T_MSG_OPC_CHECK_RSP,
1503 p_t3t_rsp[T3T_MSG_RSP_OFFSET_RSPCODE]);
1504 nfc_status = NFC_STATUS_FAILED;
1505 GKI_freebuf(p_msg_rsp);
1506 } else {
1507 /* Notify app of NDEF segment received */
1508 rsp_num_bytes_rx = p_t3t_rsp[T3T_MSG_RSP_OFFSET_NUMBLOCKS] *
1509 16; /* Number of bytes received, according to header */
1510 p_cb->ndef_rx_offset += p_cb->ndef_rx_readlen;
1511 read_data.status = NFC_STATUS_OK;
1512 p_msg_rsp->offset +=
1513 T3T_MSG_RSP_OFFSET_CHECK_DATA; /* Skip over t3t header (point to block
1514 data) */
1515 p_msg_rsp->len -= T3T_MSG_RSP_OFFSET_CHECK_DATA;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001516
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001517 /* Verify that the bytes received is really the amount indicated in the
1518 * check-response header */
1519 if (rsp_num_bytes_rx > p_msg_rsp->len) {
1520 RW_TRACE_ERROR2(
1521 "Response error: CHECK rsp header indicates %i bytes, but only "
1522 "received %i bytes",
1523 rsp_num_bytes_rx, p_msg_rsp->len);
1524 nfc_status = NFC_STATUS_FAILED;
1525 GKI_freebuf(p_msg_rsp);
1526 } else {
1527 /* If this is the the final block, then set len to reflect only valid
1528 * bytes (do not include padding to 16-byte boundary) */
1529 if ((p_cb->flags & RW_T3T_FL_IS_FINAL_NDEF_SEGMENT) &&
1530 (p_cb->ndef_attrib.ln & 0x000F)) {
1531 rsp_num_bytes_rx -= (16 - (p_cb->ndef_attrib.ln & 0x000F));
1532 }
1533
1534 p_msg_rsp->len = rsp_num_bytes_rx;
1535 read_data.p_data = p_msg_rsp;
1536 (*(rw_cb.p_cback))(RW_T3T_CHECK_EVT, (tRW_DATA*)&read_data);
1537
1538 /* Send CHECK cmd for next NDEF segment, if needed */
1539 if (!(p_cb->flags & RW_T3T_FL_IS_FINAL_NDEF_SEGMENT)) {
Ruchi Kandoi0c515ae2017-01-30 17:48:41 -08001540 nfc_status = rw_t3t_send_next_ndef_check_cmd(p_cb);
1541 if (nfc_status == NFC_STATUS_OK) {
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001542 /* Still getting more segments. Don't send RW_T3T_CHECK_CPLT_EVT yet
1543 */
1544 check_complete = false;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001545 }
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001546 }
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001547 }
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001548 }
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001549
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001550 /* Notify app of RW_T3T_CHECK_CPLT_EVT if entire NDEF has been read, or if
1551 * failure */
1552 if (check_complete) {
1553 p_cb->rw_state = RW_T3T_STATE_IDLE;
1554 evt_data.status = nfc_status;
1555 (*(rw_cb.p_cback))(RW_T3T_CHECK_CPLT_EVT, (tRW_DATA*)&evt_data);
1556 }
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001557}
1558
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001559/*****************************************************************************
1560**
1561** Function rw_t3t_act_handle_update_ndef_rsp
1562**
1563** Description Handle response to NDEF write segment
1564**
1565** Returns Nothing
1566**
1567*****************************************************************************/
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001568void rw_t3t_act_handle_update_ndef_rsp(tRW_T3T_CB* p_cb, NFC_HDR* p_msg_rsp) {
1569 bool update_complete = true;
1570 tNFC_STATUS nfc_status = NFC_STATUS_OK;
1571 tRW_DATA evt_data;
1572 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 -08001573
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001574 /* Check nfcid2 and status of response */
1575 if ((p_t3t_rsp[T3T_MSG_RSP_OFFSET_STATUS1] !=
1576 T3T_MSG_RSP_STATUS_OK) /* verify response status code */
1577 || (memcmp(p_cb->peer_nfcid2, &p_t3t_rsp[T3T_MSG_RSP_OFFSET_IDM],
1578 NCI_NFCID2_LEN) != 0)) /* verify response IDm */
1579 {
1580 nfc_status = NFC_STATUS_FAILED;
1581 }
1582 /* Validate response opcode */
1583 else if (p_t3t_rsp[T3T_MSG_RSP_OFFSET_RSPCODE] != T3T_MSG_OPC_UPDATE_RSP) {
1584 RW_TRACE_ERROR2("Response error: expecting rsp_code %02X, but got %02X",
1585 T3T_MSG_OPC_UPDATE_RSP,
1586 p_t3t_rsp[T3T_MSG_RSP_OFFSET_RSPCODE]);
1587 nfc_status = NFC_STATUS_FAILED;
1588 }
1589 /* If this is response to final UPDATE, then update NDEF local size */
1590 else if (p_cb->flags & RW_T3T_FL_IS_FINAL_NDEF_SEGMENT) {
1591 /* If successful, update current NDEF size */
1592 p_cb->ndef_attrib.ln = p_cb->ndef_msg_len;
1593 }
1594 /* If any more NDEF bytes to update, then send next UPDATE command */
1595 else if (p_cb->ndef_msg_bytes_sent < p_cb->ndef_msg_len) {
1596 /* Send UPDATE command for next segment of NDEF */
Ruchi Kandoi0c515ae2017-01-30 17:48:41 -08001597 nfc_status = rw_t3t_send_next_ndef_update_cmd(p_cb);
1598 if (nfc_status == NFC_STATUS_OK) {
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001599 /* Wait for update response */
1600 update_complete = false;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001601 }
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001602 }
1603 /* Otherwise, no more NDEF bytes. Send final UPDATE for Attribute Information
1604 block */
1605 else {
1606 p_cb->flags |= RW_T3T_FL_IS_FINAL_NDEF_SEGMENT;
Ruchi Kandoi0c515ae2017-01-30 17:48:41 -08001607 nfc_status = rw_t3t_send_update_ndef_attribute_cmd(p_cb, false);
1608 if (nfc_status == NFC_STATUS_OK) {
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001609 /* Wait for update response */
1610 update_complete = false;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001611 }
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001612 }
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001613
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001614 /* If update is completed, then notify app */
1615 if (update_complete) {
1616 p_cb->rw_state = RW_T3T_STATE_IDLE;
1617 evt_data.status = nfc_status;
1618 (*(rw_cb.p_cback))(RW_T3T_UPDATE_CPLT_EVT, (tRW_DATA*)&evt_data);
1619 }
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001620
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001621 GKI_freebuf(p_msg_rsp);
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001622
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001623 return;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001624}
1625
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001626/*****************************************************************************
1627**
1628** Function rw_t3t_handle_get_sc_poll_rsp
1629**
1630** Description Handle POLL response for getting system codes
1631**
1632** Returns Nothing
1633**
1634*****************************************************************************/
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001635static void rw_t3t_handle_get_sc_poll_rsp(tRW_T3T_CB* p_cb, uint8_t nci_status,
1636 uint8_t num_responses,
1637 uint8_t sensf_res_buf_size,
1638 uint8_t* p_sensf_res_buf) {
1639 uint8_t* p;
1640 uint16_t sc;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001641
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001642 /* Get the system code from the response */
1643 if ((nci_status == NCI_STATUS_OK) && (num_responses > 0) &&
1644 (sensf_res_buf_size >=
1645 (RW_T3T_SENSF_RES_RD_OFFSET + RW_T3T_SENSF_RES_RD_LEN))) {
1646 p = &p_sensf_res_buf[RW_T3T_SENSF_RES_RD_OFFSET];
1647 BE_STREAM_TO_UINT16(sc, p);
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001648
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001649 RW_TRACE_DEBUG1("FeliCa detected (RD, system code %04X)", sc);
1650 p_cb->system_codes[p_cb->num_system_codes++] = sc;
1651 }
Yoshinobu Ito721b3ab2016-08-02 14:41:33 +09001652
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001653 rw_t3t_handle_get_system_codes_cplt();
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001654}
1655
1656/*****************************************************************************
1657**
1658** Function rw_t3t_handle_ndef_detect_poll_rsp
1659**
1660** Description Handle POLL response for getting system codes
1661**
1662** Returns Nothing
1663**
1664*****************************************************************************/
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001665static void rw_t3t_handle_ndef_detect_poll_rsp(tRW_T3T_CB* p_cb,
1666 uint8_t nci_status,
1667 uint8_t num_responses,
1668 uint8_t sensf_res_buf_size,
1669 uint8_t* p_sensf_res_buf) {
1670 NFC_HDR* p_cmd_buf;
1671 uint8_t *p, *p_cmd_start;
1672 tRW_DATA evt_data;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001673
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001674 /* Validate response for NDEF poll */
1675 if ((nci_status == NCI_STATUS_OK) && (num_responses > 0)) {
1676 /* Tag responded for NDEF poll */
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001677
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001678 /* Read NDEF attribute block */
Ruchi Kandoi0c515ae2017-01-30 17:48:41 -08001679 p_cmd_buf = rw_t3t_get_cmd_buf();
1680 if (p_cmd_buf != NULL) {
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001681 /* Construct T3T message */
1682 p = p_cmd_start = (uint8_t*)(p_cmd_buf + 1) + p_cmd_buf->offset;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001683
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001684 /* Add CHECK opcode to message */
1685 UINT8_TO_STREAM(p, T3T_MSG_OPC_CHECK_CMD);
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001686
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001687 /* Add IDm to message */
1688 ARRAY_TO_STREAM(p, p_cb->peer_nfcid2, NCI_NFCID2_LEN);
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001689
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001690 /* Add Service code list */
1691 UINT8_TO_STREAM(p, 1); /* Number of services (only 1 service: NDEF) */
1692 UINT16_TO_STREAM(
1693 p, T3T_MSG_NDEF_SC_RO); /* Service code (little-endian format) */
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001694
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001695 /* Number of blocks */
1696 UINT8_TO_STREAM(
1697 p,
1698 1); /* Number of blocks (only 1 block: NDEF Attribute Information ) */
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001699
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001700 /* Block List element: the NDEF attribute information block (block 0) */
1701 UINT8_TO_STREAM(p, T3T_MSG_MASK_TWO_BYTE_BLOCK_DESC_FORMAT);
1702 UINT8_TO_STREAM(p, 0);
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001703
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001704 /* Calculate length of message */
1705 p_cmd_buf->len = (uint16_t)(p - p_cmd_start);
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001706
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001707 /* Send the T3T message */
Ruchi Kandoi0c515ae2017-01-30 17:48:41 -08001708 evt_data.status = rw_t3t_send_cmd(p_cb, RW_T3T_CMD_DETECT_NDEF, p_cmd_buf,
1709 rw_t3t_check_timeout(1));
1710 if (evt_data.status == NFC_STATUS_OK) {
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001711 /* CHECK command sent. Wait for response */
1712 return;
1713 }
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001714 }
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001715 nci_status = NFC_STATUS_FAILED;
1716 }
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001717
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001718 /* NDEF detection failed */
1719 p_cb->rw_state = RW_T3T_STATE_IDLE;
1720 evt_data.ndef.status = nci_status;
1721 evt_data.ndef.flags = RW_NDEF_FL_UNKNOWN;
1722 rw_t3t_update_ndef_flag(&evt_data.ndef.flags);
1723 (*(rw_cb.p_cback))(RW_T3T_NDEF_DETECT_EVT, &evt_data);
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001724}
1725
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001726/*****************************************************************************
1727**
1728** Function rw_t3t_update_block
1729**
Martijn Coenen5c65c3a2013-03-27 13:23:36 -07001730** Description Send UPDATE command for single block
1731** (for formatting/configuring read only)
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001732**
1733** Returns tNFC_STATUS
1734**
1735*****************************************************************************/
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001736tNFC_STATUS rw_t3t_update_block(tRW_T3T_CB* p_cb, uint8_t block_id,
1737 uint8_t* p_block_data) {
1738 uint8_t *p_dst, *p_cmd_start;
1739 NFC_HDR* p_cmd_buf;
1740 tNFC_STATUS status;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001741
Ruchi Kandoi0c515ae2017-01-30 17:48:41 -08001742 p_cmd_buf = rw_t3t_get_cmd_buf();
1743 if (p_cmd_buf != NULL) {
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001744 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 -08001745
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001746 /* Add UPDATE opcode to message */
1747 UINT8_TO_STREAM(p_dst, T3T_MSG_OPC_UPDATE_CMD);
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001748
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001749 /* Add IDm to message */
1750 ARRAY_TO_STREAM(p_dst, p_cb->peer_nfcid2, NCI_NFCID2_LEN);
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001751
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001752 /* Add Service code list */
1753 UINT8_TO_STREAM(p_dst, 1); /* Number of services (only 1 service: NDEF) */
1754 UINT16_TO_STREAM(
1755 p_dst, T3T_MSG_NDEF_SC_RW); /* Service code (little-endian format) */
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001756
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001757 /* Number of blocks */
1758 UINT8_TO_STREAM(p_dst, 1);
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001759
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001760 /* Add Block list element for MC */
1761 UINT8_TO_STREAM(p_dst, T3T_MSG_MASK_TWO_BYTE_BLOCK_DESC_FORMAT);
1762 UINT8_TO_STREAM(p_dst, block_id);
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001763
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001764 /* Copy MC data to UPDATE message */
1765 ARRAY_TO_STREAM(p_dst, p_block_data, T3T_MSG_BLOCKSIZE);
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001766
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001767 /* Calculate length of message */
1768 p_cmd_buf->len = (uint16_t)(p_dst - p_cmd_start);
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001769
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001770 /* Send the T3T message */
1771 status = rw_t3t_send_cmd(p_cb, p_cb->cur_cmd, p_cmd_buf,
1772 rw_t3t_update_timeout(1));
1773 } else {
1774 /* Unable to send UPDATE command */
1775 status = NFC_STATUS_NO_BUFFERS;
1776 }
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001777
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001778 return (status);
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001779}
1780
1781/*****************************************************************************
1782**
1783** Function rw_t3t_handle_fmt_poll_rsp
1784**
1785** Description Handle POLL response for formatting felica-lite
1786**
1787** Returns Nothing
1788**
1789*****************************************************************************/
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001790static void rw_t3t_handle_fmt_poll_rsp(tRW_T3T_CB* p_cb, uint8_t nci_status,
1791 uint8_t num_responses,
1792 uint8_t sensf_res_buf_size,
1793 uint8_t* p_sensf_res_buf) {
1794 tRW_DATA evt_data;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001795
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001796 evt_data.status = NFC_STATUS_OK;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001797
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001798 /* Validate response for poll response */
1799 if ((nci_status == NCI_STATUS_OK) && (num_responses > 0)) {
1800 /* Tag responded for Felica-Lite poll */
1801 /* Get MemoryControl block */
1802 RW_TRACE_DEBUG0("Felica-Lite tag detected...getting Memory Control block.");
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001803
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001804 p_cb->rw_substate = RW_T3T_FMT_SST_CHECK_MC_BLK;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001805
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001806 /* Send command to check Memory Configuration block */
1807 evt_data.status = rw_t3t_check_mc_block(p_cb);
1808 } else {
1809 RW_TRACE_ERROR0("Felica-Lite tag not detected");
1810 evt_data.status = NFC_STATUS_FAILED;
1811 }
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001812
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001813 /* If error, notify upper layer */
1814 if (evt_data.status != NFC_STATUS_OK) {
1815 rw_t3t_format_cplt(evt_data.status);
1816 }
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001817}
1818
1819/*****************************************************************************
1820**
1821** Function rw_t3t_act_handle_fmt_rsp
1822**
1823** Description Handle response for formatting codes
1824**
1825** Returns Nothing
1826**
1827*****************************************************************************/
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001828void rw_t3t_act_handle_fmt_rsp(tRW_T3T_CB* p_cb, NFC_HDR* p_msg_rsp) {
1829 uint8_t* p_t3t_rsp = (uint8_t*)(p_msg_rsp + 1) + p_msg_rsp->offset;
1830 uint8_t* p_mc;
1831 tRW_DATA evt_data;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001832
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001833 evt_data.status = NFC_STATUS_OK;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001834
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001835 /* Check tags's response for reading MemoryControl block */
1836 if (p_cb->rw_substate == RW_T3T_FMT_SST_CHECK_MC_BLK) {
1837 /* Validate response opcode */
1838 if (p_t3t_rsp[T3T_MSG_RSP_OFFSET_RSPCODE] != T3T_MSG_OPC_CHECK_RSP) {
1839 RW_TRACE_ERROR2("Response error: expecting rsp_code %02X, but got %02X",
1840 T3T_MSG_OPC_CHECK_RSP,
1841 p_t3t_rsp[T3T_MSG_RSP_OFFSET_RSPCODE]);
1842 evt_data.status = NFC_STATUS_FAILED;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001843 }
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001844 /* Validate status code and NFCID2 response from tag */
1845 else if ((p_t3t_rsp[T3T_MSG_RSP_OFFSET_STATUS1] !=
1846 T3T_MSG_RSP_STATUS_OK) /* verify response status code */
1847 || (memcmp(p_cb->peer_nfcid2, &p_t3t_rsp[T3T_MSG_RSP_OFFSET_IDM],
1848 NCI_NFCID2_LEN) != 0)) /* verify response IDm */
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001849 {
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001850 evt_data.status = NFC_STATUS_FAILED;
1851 } 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 {
1890 RW_TRACE_ERROR2("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]);
1893 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 {
1912 RW_TRACE_ERROR2("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]);
1915 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,
1934 uint8_t num_responses,
1935 uint8_t sensf_res_buf_size,
1936 uint8_t* p_sensf_res_buf) {
1937 tRW_DATA evt_data;
1938 uint8_t rw_t3t_ndef_attrib_info[T3T_MSG_BLOCKSIZE];
1939 uint8_t* p;
1940 uint8_t tempU8;
1941 uint16_t checksum, i;
1942 uint32_t tempU32 = 0;
Martijn Coenen5c65c3a2013-03-27 13:23:36 -07001943
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001944 evt_data.status = NFC_STATUS_OK;
Martijn Coenen5c65c3a2013-03-27 13:23:36 -07001945
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001946 /* Validate response for poll response */
1947 if ((nci_status == NCI_STATUS_OK) && (num_responses > 0)) {
1948 /* Tag responded for Felica-Lite poll */
1949 if (p_cb->ndef_attrib.rwflag != T3T_MSG_NDEF_RWFLAG_RO) {
1950 /* First update attribute information block */
1951 RW_TRACE_DEBUG0(
1952 "Felica-Lite tag detected...update NDef attribution block.");
Martijn Coenen5c65c3a2013-03-27 13:23:36 -07001953
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001954 p_cb->rw_substate = RW_T3T_SRO_SST_UPDATE_NDEF_ATTRIB;
Martijn Coenen5c65c3a2013-03-27 13:23:36 -07001955
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001956 p = rw_t3t_ndef_attrib_info;
Martijn Coenen5c65c3a2013-03-27 13:23:36 -07001957
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001958 UINT8_TO_STREAM(p, p_cb->ndef_attrib.version);
Martijn Coenen5c65c3a2013-03-27 13:23:36 -07001959
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001960 /* Update NDEF info */
1961 UINT8_TO_STREAM(
1962 p, p_cb->ndef_attrib.nbr); /* NBr: number of blocks that can be read
1963 using one Check command */
1964 UINT8_TO_STREAM(p, p_cb->ndef_attrib.nbw); /* Nbw: number of blocks that
1965 can be written using one
1966 Update command */
1967 UINT16_TO_BE_STREAM(
1968 p, p_cb->ndef_attrib.nmaxb); /* Nmaxb: maximum number of blocks
1969 available for NDEF data */
1970 UINT32_TO_BE_STREAM(p, tempU32);
1971 UINT8_TO_STREAM(p,
1972 p_cb->ndef_attrib.writef); /* WriteFlag: 00h if writing
1973 data finished; 0Fh if
1974 writing data in progress */
1975 UINT8_TO_STREAM(p, 0x00); /* RWFlag: 00h NDEF is read-only */
Martijn Coenen5c65c3a2013-03-27 13:23:36 -07001976
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001977 tempU8 = (uint8_t)(p_cb->ndef_attrib.ln >> 16);
1978 /* Get length (3-byte, big-endian) */
1979 UINT8_TO_STREAM(p, tempU8); /* Ln: high-byte */
1980 UINT16_TO_BE_STREAM(p, p_cb->ndef_attrib.ln); /* Ln: lo-word */
Martijn Coenen5c65c3a2013-03-27 13:23:36 -07001981
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001982 /* Calculate and append Checksum */
1983 checksum = 0;
1984 for (i = 0; i < T3T_MSG_NDEF_ATTR_INFO_SIZE; i++) {
1985 checksum += rw_t3t_ndef_attrib_info[i];
1986 }
1987 UINT16_TO_BE_STREAM(p, checksum);
Martijn Coenen5c65c3a2013-03-27 13:23:36 -07001988
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001989 evt_data.status =
1990 rw_t3t_update_block(p_cb, 0, (uint8_t*)rw_t3t_ndef_attrib_info);
1991 } else if (p_cb->cur_cmd == RW_T3T_CMD_SET_READ_ONLY_HARD) {
1992 /* NDEF is already read only, Read and update MemoryControl block */
1993 RW_TRACE_DEBUG0(
1994 "Felica-Lite tag detected...getting Memory Control block.");
1995 p_cb->rw_substate = RW_T3T_SRO_SST_CHECK_MC_BLK;
Martijn Coenen5c65c3a2013-03-27 13:23:36 -07001996
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001997 /* Send command to check Memory Configuration block */
1998 evt_data.status = rw_t3t_check_mc_block(p_cb);
Martijn Coenen5c65c3a2013-03-27 13:23:36 -07001999 }
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002000 } else {
2001 RW_TRACE_ERROR0("Felica-Lite tag not detected");
2002 evt_data.status = NFC_STATUS_FAILED;
2003 }
Martijn Coenen5c65c3a2013-03-27 13:23:36 -07002004
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002005 /* If error, notify upper layer */
2006 if (evt_data.status != NFC_STATUS_OK) {
2007 rw_t3t_set_readonly_cplt(evt_data.status);
2008 }
Martijn Coenen5c65c3a2013-03-27 13:23:36 -07002009}
2010
2011/*****************************************************************************
2012**
2013** Function rw_t3t_act_handle_sro_rsp
2014**
2015** Description Handle response for setting read only codes
2016**
2017** Returns Nothing
2018**
2019*****************************************************************************/
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002020void rw_t3t_act_handle_sro_rsp(tRW_T3T_CB* p_cb, NFC_HDR* p_msg_rsp) {
2021 uint8_t* p_t3t_rsp = (uint8_t*)(p_msg_rsp + 1) + p_msg_rsp->offset;
2022 uint8_t* p_mc;
2023 tRW_DATA evt_data;
Martijn Coenen5c65c3a2013-03-27 13:23:36 -07002024
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002025 evt_data.status = NFC_STATUS_OK;
Martijn Coenen5c65c3a2013-03-27 13:23:36 -07002026
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002027 if (p_cb->rw_substate == RW_T3T_SRO_SST_UPDATE_NDEF_ATTRIB) {
2028 /* Validate response opcode */
2029 if ((p_t3t_rsp[T3T_MSG_RSP_OFFSET_RSPCODE] != T3T_MSG_OPC_UPDATE_RSP) ||
2030 (p_t3t_rsp[T3T_MSG_RSP_OFFSET_STATUS1] != T3T_MSG_RSP_STATUS_OK))
2031
Martijn Coenen5c65c3a2013-03-27 13:23:36 -07002032 {
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002033 RW_TRACE_ERROR2("Response error: rsp_code=%02X, status=%02X",
2034 p_t3t_rsp[T3T_MSG_RSP_OFFSET_RSPCODE],
2035 p_t3t_rsp[T3T_MSG_RSP_OFFSET_STATUS1]);
2036 evt_data.status = NFC_STATUS_FAILED;
2037 } else {
2038 p_cb->ndef_attrib.rwflag = T3T_MSG_NDEF_RWFLAG_RO;
2039 if (p_cb->cur_cmd == RW_T3T_CMD_SET_READ_ONLY_HARD) {
2040 p_cb->rw_substate = RW_T3T_SRO_SST_CHECK_MC_BLK;
Martijn Coenen5c65c3a2013-03-27 13:23:36 -07002041
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002042 /* Send command to check Memory Configuration block */
2043 evt_data.status = rw_t3t_check_mc_block(p_cb);
2044 } else {
2045 rw_t3t_set_readonly_cplt(evt_data.status);
2046 }
Martijn Coenen5c65c3a2013-03-27 13:23:36 -07002047 }
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002048 } else if (p_cb->rw_substate == RW_T3T_SRO_SST_CHECK_MC_BLK) {
2049 /* Check tags's response for reading MemoryControl block, Validate response
2050 * opcode */
2051 if (p_t3t_rsp[T3T_MSG_RSP_OFFSET_RSPCODE] != T3T_MSG_OPC_CHECK_RSP) {
2052 RW_TRACE_ERROR2("Response error: expecting rsp_code %02X, but got %02X",
2053 T3T_MSG_OPC_CHECK_RSP,
2054 p_t3t_rsp[T3T_MSG_RSP_OFFSET_RSPCODE]);
2055 evt_data.status = NFC_STATUS_FAILED;
2056 }
2057 /* Validate status code and NFCID2 response from tag */
2058 else if ((p_t3t_rsp[T3T_MSG_RSP_OFFSET_STATUS1] !=
2059 T3T_MSG_RSP_STATUS_OK) /* verify response status code */
2060 || (memcmp(p_cb->peer_nfcid2, &p_t3t_rsp[T3T_MSG_RSP_OFFSET_IDM],
2061 NCI_NFCID2_LEN) != 0)) /* verify response IDm */
Martijn Coenen5c65c3a2013-03-27 13:23:36 -07002062 {
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002063 evt_data.status = NFC_STATUS_FAILED;
2064 } else {
2065 /* Check if memory configuration (MC) block to see if SYS_OP=1 (NDEF
2066 * enabled) */
2067 p_mc = &p_t3t_rsp[T3T_MSG_RSP_OFFSET_CHECK_DATA]; /* Point to MC data of
2068 CHECK response */
Martijn Coenen5c65c3a2013-03-27 13:23:36 -07002069
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002070 if (p_mc[T3T_MSG_FELICALITE_MC_OFFSET_SYS_OP] != 0x01) {
2071 /* Tag is not currently enabled for NDEF */
2072 evt_data.status = NFC_STATUS_FAILED;
2073 } else {
2074 /* 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 Kandoi6fca02d2017-01-30 14:28:16 -08002096 RW_TRACE_ERROR2("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]);
2099 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 Kandoi6fca02d2017-01-30 14:28:16 -08002122void rw_t3t_data_cback(uint8_t conn_id, tNFC_DATA_CEVT* p_data) {
2123 tRW_T3T_CB* p_cb = &rw_cb.tcb.t3t;
2124 NFC_HDR* p_msg = p_data->p_data;
2125 bool free_msg = false; /* if TRUE, free msg buffer before returning */
2126 uint8_t *p, sod;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002127
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002128 /* Stop rsponse timer */
2129 nfc_stop_quick_timer(&p_cb->timer);
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002130
Ruchi Kandoi303fec12016-12-14 13:22:38 -08002131#if (RW_STATS_INCLUDED == TRUE)
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002132 /* Update rx stats */
2133 rw_main_update_rx_stats(p_msg->len);
2134#endif /* RW_STATS_INCLUDED */
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002135
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002136 /* Check if we are expecting a response */
2137 if (p_cb->rw_state != RW_T3T_STATE_COMMAND_PENDING) {
2138 /*
2139 ** This must be raw frame response
2140 ** send raw frame to app with SoD
2141 */
2142 rw_t3t_act_handle_raw_senddata_rsp(p_cb, p_data);
2143 }
2144 /* Sanity check: verify msg len is big enough to contain t3t header */
2145 else if (p_msg->len < T3T_MSG_RSP_COMMON_HDR_LEN) {
2146 RW_TRACE_ERROR1("T3T: invalid Type3 Tag Message (invalid len: %i)",
2147 p_msg->len);
2148 free_msg = true;
2149
2150 rw_t3t_process_frame_error();
2151 } else {
2152 /* Check for RF frame error */
2153 p = (uint8_t*)(p_msg + 1) + p_msg->offset;
2154 sod = p[0];
2155 if (p[sod] != NCI_STATUS_OK) {
2156 RW_TRACE_ERROR1("T3T: rf frame error (crc status=%i)", p[sod]);
2157 GKI_freebuf(p_msg);
2158
2159 rw_t3t_process_frame_error();
2160 return;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002161 }
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002162
2163#if (BT_TRACE_PROTOCOL == TRUE)
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002164 DispT3TagMessage(p_msg, true);
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002165#endif
2166
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002167 /* Skip over SoD */
2168 p_msg->offset++;
2169 p_msg->len--;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002170
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002171 /* Get response code */
2172 switch (p_cb->cur_cmd) {
2173 case RW_T3T_CMD_DETECT_NDEF:
2174 rw_t3t_act_handle_ndef_detect_rsp(p_cb, p_msg);
2175 break;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002176
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002177 case RW_T3T_CMD_CHECK_NDEF:
2178 rw_t3t_act_handle_check_ndef_rsp(p_cb, p_msg);
2179 break;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002180
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002181 case RW_T3T_CMD_UPDATE_NDEF:
2182 rw_t3t_act_handle_update_ndef_rsp(p_cb, p_msg);
2183 break;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002184
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002185 case RW_T3T_CMD_CHECK:
2186 rw_t3t_act_handle_check_rsp(p_cb, p_msg);
2187 break;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002188
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002189 case RW_T3T_CMD_UPDATE:
2190 rw_t3t_act_handle_update_rsp(p_cb, p_msg);
2191 break;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002192
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002193 case RW_T3T_CMD_SEND_RAW_FRAME:
2194 rw_t3t_act_handle_raw_senddata_rsp(p_cb, p_data);
2195 break;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002196
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002197 case RW_T3T_CMD_FORMAT:
2198 rw_t3t_act_handle_fmt_rsp(p_cb, p_msg);
2199 break;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002200
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002201 case RW_T3T_CMD_SET_READ_ONLY_SOFT:
2202 case RW_T3T_CMD_SET_READ_ONLY_HARD:
2203 rw_t3t_act_handle_sro_rsp(p_cb, p_msg);
2204 break;
Martijn Coenen5c65c3a2013-03-27 13:23:36 -07002205
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002206 default:
2207 GKI_freebuf(p_msg);
2208 break;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002209 }
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002210 }
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002211
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002212 if (free_msg) {
2213 GKI_freebuf(p_msg);
2214 }
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002215}
2216
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002217/*******************************************************************************
2218**
2219** Function rw_t3t_conn_cback
2220**
2221** Description This callback function receives the events/data from NFCC.
2222**
2223** Returns none
2224**
2225*******************************************************************************/
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002226void rw_t3t_conn_cback(uint8_t conn_id, tNFC_CONN_EVT event,
2227 tNFC_CONN* p_data) {
2228 tRW_T3T_CB* p_cb = &rw_cb.tcb.t3t;
2229 RW_TRACE_DEBUG2("rw_t3t_conn_cback: conn_id=%i, evt=0x%02x", conn_id, event);
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002230
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002231 /* Only handle NFC_RF_CONN_ID conn_id */
2232 if (conn_id != NFC_RF_CONN_ID) {
2233 return;
2234 }
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002235
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002236 switch (event) {
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002237 case NFC_DEACTIVATE_CEVT:
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002238 rw_t3t_unselect(NULL);
2239 break;
2240
2241 case NFC_DATA_CEVT: /* check for status in tNFC_CONN */
2242 if ((p_data != NULL) && ((p_data->data.status == NFC_STATUS_OK) ||
2243 (p_data->data.status == NFC_STATUS_CONTINUE))) {
2244 rw_t3t_data_cback(conn_id, &(p_data->data));
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002245 break;
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002246 } else if (p_data->data.p_data != NULL) {
2247 /* Free the response buffer in case of error response */
2248 GKI_freebuf((NFC_HDR*)(p_data->data.p_data));
2249 p_data->data.p_data = NULL;
2250 }
2251 /* Data event with error status...fall through to NFC_ERROR_CEVT case */
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002252
2253 case NFC_ERROR_CEVT:
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002254 nfc_stop_quick_timer(&p_cb->timer);
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002255
Ruchi Kandoi303fec12016-12-14 13:22:38 -08002256#if (RW_STATS_INCLUDED == TRUE)
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002257 rw_main_update_trans_error_stats();
2258#endif /* RW_STATS_INCLUDED */
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002259
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002260 if (event == NFC_ERROR_CEVT)
2261 rw_t3t_process_error(NFC_STATUS_TIMEOUT);
2262 else if (p_data)
2263 rw_t3t_process_error(p_data->status);
2264 break;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002265
2266 default:
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002267 break;
2268 }
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002269}
2270
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002271/*******************************************************************************
2272**
Sherry Smith818b56e2014-05-14 16:46:32 -07002273** Function rw_t3t_mrti_to_a_b
2274**
2275** Description Converts the given MRTI (Maximum Response Time Information)
2276** to the base to calculate timeout value.
2277** (The timeout value is a + b * number_blocks)
2278**
2279** Returns NFC_STATUS_OK
2280**
2281*******************************************************************************/
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002282static void rw_t3t_mrti_to_a_b(uint8_t mrti, uint32_t* p_a, uint32_t* p_b) {
2283 uint8_t a, b, e;
Sherry Smith818b56e2014-05-14 16:46:32 -07002284
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002285 a = (mrti & 0x7) + 1; /* A is bit 0 ~ bit 2 */
2286 mrti >>= 3;
2287 b = (mrti & 0x7) + 1; /* B is bit 3 ~ bit 5 */
2288 mrti >>= 3;
2289 e = mrti & 0x3; /* E is bit 6 ~ bit 7 */
2290 *p_a = rw_t3t_mrti_base[e] * a; /* (A+1) * base (i.e T/t3t * 4^E) */
2291 *p_b = rw_t3t_mrti_base[e] * b; /* (B+1) * base (i.e T/t3t * 4^E) */
Sherry Smith818b56e2014-05-14 16:46:32 -07002292}
2293
Sherry Smith818b56e2014-05-14 16:46:32 -07002294/*******************************************************************************
2295**
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002296** Function rw_t3t_select
2297**
2298** Description Called by NFC manager when a Type3 tag has been activated
2299**
2300** Returns NFC_STATUS_OK
2301**
2302*******************************************************************************/
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002303tNFC_STATUS rw_t3t_select(uint8_t peer_nfcid2[NCI_RF_F_UID_LEN],
2304 uint8_t mrti_check, uint8_t mrti_update) {
2305 tRW_T3T_CB* p_cb = &rw_cb.tcb.t3t;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002306
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002307 RW_TRACE_API0("rw_t3t_select");
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002308
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002309 memcpy(p_cb->peer_nfcid2, peer_nfcid2,
2310 NCI_NFCID2_LEN); /* Store tag's NFCID2 */
2311 p_cb->ndef_attrib.status =
2312 NFC_STATUS_NOT_INITIALIZED; /* Indicate that NDEF detection has not been
2313 performed yet */
2314 p_cb->rw_state = RW_T3T_STATE_IDLE;
2315 p_cb->flags = 0;
2316 rw_t3t_mrti_to_a_b(mrti_check, &p_cb->check_tout_a, &p_cb->check_tout_b);
2317 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 -08002318
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002319 /* Alloc cmd buf for retransmissions */
2320 if (p_cb->p_cur_cmd_buf == NULL) {
Ruchi Kandoi0c515ae2017-01-30 17:48:41 -08002321 p_cb->p_cur_cmd_buf = (NFC_HDR*)GKI_getpoolbuf(NFC_RW_POOL_ID);
2322 if (p_cb->p_cur_cmd_buf == NULL) {
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002323 RW_TRACE_ERROR0(
2324 "rw_t3t_select: unable to allocate buffer for retransmission");
2325 p_cb->rw_state = RW_T3T_STATE_NOT_ACTIVATED;
2326 return (NFC_STATUS_FAILED);
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002327 }
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002328 }
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002329
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002330 NFC_SetStaticRfCback(rw_t3t_conn_cback);
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002331
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002332 return NFC_STATUS_OK;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002333}
2334
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002335/*******************************************************************************
2336**
2337** Function rw_t3t_unselect
2338**
2339** Description Called by NFC manager when a Type3 tag has been de-activated
2340**
2341** Returns NFC_STATUS_OK
2342**
2343*******************************************************************************/
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002344static tNFC_STATUS rw_t3t_unselect(uint8_t peer_nfcid2[]) {
2345 tRW_T3T_CB* p_cb = &rw_cb.tcb.t3t;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002346
Ruchi Kandoi303fec12016-12-14 13:22:38 -08002347#if (RW_STATS_INCLUDED == TRUE)
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002348 /* Display stats */
2349 rw_main_log_stats();
2350#endif /* RW_STATS_INCLUDED */
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002351
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002352 /* Stop t3t timer (if started) */
2353 nfc_stop_quick_timer(&p_cb->timer);
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002354
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002355 /* Free cmd buf for retransmissions */
2356 if (p_cb->p_cur_cmd_buf) {
2357 GKI_freebuf(p_cb->p_cur_cmd_buf);
2358 p_cb->p_cur_cmd_buf = NULL;
2359 }
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002360
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002361 p_cb->rw_state = RW_T3T_STATE_NOT_ACTIVATED;
2362 NFC_SetStaticRfCback(NULL);
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002363
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002364 return NFC_STATUS_OK;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002365}
2366
Evan Chua24be4f2013-11-13 15:30:16 -05002367/*******************************************************************************
2368**
2369** Function rw_t3t_update_ndef_flag
2370**
2371** Description set additional NDEF Flags for felica lite tag
2372**
2373** Returns updated NDEF Flag value
2374**
2375*******************************************************************************/
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002376static void rw_t3t_update_ndef_flag(uint8_t* p_flag) {
2377 tRW_T3T_CB* p_cb = &rw_cb.tcb.t3t;
2378 uint8_t xx;
Evan Chua24be4f2013-11-13 15:30:16 -05002379
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002380 for (xx = 0; xx < p_cb->num_system_codes; xx++) {
2381 if (p_cb->system_codes[xx] == T3T_SYSTEM_CODE_FELICA_LITE) {
2382 *p_flag &= ~RW_NDEF_FL_UNKNOWN;
2383 *p_flag |= (RW_NDEF_FL_SUPPORTED | RW_NDEF_FL_FORMATABLE);
2384 break;
Evan Chua24be4f2013-11-13 15:30:16 -05002385 }
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002386 }
Evan Chua24be4f2013-11-13 15:30:16 -05002387}
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002388
2389#if (BT_TRACE_VERBOSE == TRUE)
2390/*******************************************************************************
2391**
2392** Function rw_t3t_cmd_str
2393**
2394** Description Converts cmd_id to command string for logging
2395**
2396** Returns command string
2397**
2398*******************************************************************************/
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002399static char* rw_t3t_cmd_str(uint8_t cmd_id) {
2400 switch (cmd_id) {
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002401 case RW_T3T_CMD_DETECT_NDEF:
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002402 return "RW_T3T_CMD_DETECT_NDEF";
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002403
2404 case RW_T3T_CMD_CHECK_NDEF:
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002405 return "RW_T3T_CMD_CHECK_NDEF";
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002406
2407 case RW_T3T_CMD_UPDATE_NDEF:
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002408 return "RW_T3T_CMD_UPDATE_NDEF";
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002409
2410 case RW_T3T_CMD_CHECK:
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002411 return "RW_T3T_CMD_CHECK";
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002412
2413 case RW_T3T_CMD_UPDATE:
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002414 return "RW_T3T_CMD_UPDATE";
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002415
2416 case RW_T3T_CMD_SEND_RAW_FRAME:
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002417 return "RW_T3T_CMD_SEND_RAW_FRAME";
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002418
2419 case RW_T3T_CMD_GET_SYSTEM_CODES:
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002420 return "RW_T3T_CMD_GET_SYSTEM_CODES";
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002421
2422 default:
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002423 return "Unknown";
2424 }
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002425}
2426
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002427/*******************************************************************************
2428**
2429** Function rw_t3t_state_str
2430**
2431** Description Converts state_id to command string for logging
2432**
2433** Returns command string
2434**
2435*******************************************************************************/
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002436static char* rw_t3t_state_str(uint8_t state_id) {
2437 switch (state_id) {
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002438 case RW_T3T_STATE_NOT_ACTIVATED:
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002439 return "RW_T3T_STATE_NOT_ACTIVATED";
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002440
2441 case RW_T3T_STATE_IDLE:
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002442 return "RW_T3T_STATE_IDLE";
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002443
2444 case RW_T3T_STATE_COMMAND_PENDING:
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002445 return "RW_T3T_STATE_COMMAND_PENDING";
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002446
2447 default:
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002448 return "Unknown";
2449 }
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002450}
2451#endif
2452
2453/*****************************************************************************
2454** Type3 Tag API Functions
2455*****************************************************************************/
2456
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002457/*****************************************************************************
2458**
2459** Function RW_T3tDetectNDef
2460**
2461** Description
2462** This function is used to perform NDEF detection on a Type 3 tag, and
2463** retrieve the tag's NDEF attribute information (block 0).
2464**
2465** Before using this API, the application must call RW_SelectTagType to
2466** indicate that a Type 3 tag has been activated, and to provide the
2467** tag's Manufacture ID (IDm) .
2468**
2469** Returns
2470** NFC_STATUS_OK: ndef detection procedure started
2471** NFC_STATUS_NO_BUFFERS: unable to allocate a buffer for this operation
2472** NFC_STATUS_FAILED: other error
2473**
2474*****************************************************************************/
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002475tNFC_STATUS RW_T3tDetectNDef(void) {
2476 tRW_T3T_CB* p_cb = &rw_cb.tcb.t3t;
2477 tNFC_STATUS retval = NFC_STATUS_OK;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002478
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002479 RW_TRACE_API0("RW_T3tDetectNDef");
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002480
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002481 /* Check if we are in valid state to handle this API */
2482 if (p_cb->rw_state != RW_T3T_STATE_IDLE) {
2483 RW_TRACE_ERROR1("Error: invalid state to handle API (0x%x)",
2484 p_cb->rw_state);
2485 return (NFC_STATUS_FAILED);
2486 }
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002487
Ruchi Kandoi0c515ae2017-01-30 17:48:41 -08002488 retval = (tNFC_STATUS)nci_snd_t3t_polling(T3T_SYSTEM_CODE_NDEF, 0, 0);
2489 if (retval == NCI_STATUS_OK) {
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002490 p_cb->cur_cmd = RW_T3T_CMD_DETECT_NDEF;
2491 p_cb->cur_tout = RW_T3T_DEFAULT_CMD_TIMEOUT_TICKS;
2492 p_cb->cur_poll_rc = 0;
2493 p_cb->rw_state = RW_T3T_STATE_COMMAND_PENDING;
2494 p_cb->flags |= RW_T3T_FL_W4_NDEF_DETECT_POLL_RSP;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002495
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002496 /* start timer for waiting for responses */
2497 rw_t3t_start_poll_timer(p_cb);
2498 }
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002499
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002500 return (retval);
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002501}
2502
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002503/*****************************************************************************
2504**
2505** Function RW_T3tCheckNDef
2506**
2507** Description
2508** Retrieve NDEF contents from a Type3 tag.
2509**
2510** The RW_T3T_CHECK_EVT event is used to notify the application for each
Ruchi Kandoi552f2b72017-01-28 16:22:55 -08002511** segment of NDEF data received. The RW_T3T_CHECK_CPLT_EVT event is used
2512** to notify the application all segments have been received.
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002513**
2514** Before using this API, the RW_T3tDetectNDef function must be called to
2515** verify that the tag contains NDEF data, and to retrieve the NDEF
2516** attributes.
2517**
2518** Internally, this command will be separated into multiple Tag 3 Check
2519** commands (if necessary) - depending on the tag's Nbr (max number of
2520** blocks per read) attribute.
2521**
2522** Returns
2523** NFC_STATUS_OK: check command started
2524** NFC_STATUS_NO_BUFFERS: unable to allocate a buffer for this operation
2525** NFC_STATUS_FAILED: other error
2526**
2527*****************************************************************************/
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002528tNFC_STATUS RW_T3tCheckNDef(void) {
2529 tNFC_STATUS retval = NFC_STATUS_OK;
2530 tRW_T3T_CB* p_cb = &rw_cb.tcb.t3t;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002531
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002532 RW_TRACE_API0("RW_T3tCheckNDef");
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002533
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002534 /* Check if we are in valid state to handle this API */
2535 if (p_cb->rw_state != RW_T3T_STATE_IDLE) {
2536 RW_TRACE_ERROR1("Error: invalid state to handle API (0x%x)",
2537 p_cb->rw_state);
2538 return (NFC_STATUS_FAILED);
2539 } else if (p_cb->ndef_attrib.status !=
2540 NFC_STATUS_OK) /* NDEF detection not performed yet? */
2541 {
2542 RW_TRACE_ERROR0("Error: NDEF detection not performed yet");
2543 return (NFC_STATUS_NOT_INITIALIZED);
2544 } else if (p_cb->ndef_attrib.ln == 0) {
2545 RW_TRACE_ERROR0("Type 3 tag contains empty NDEF message");
2546 return (NFC_STATUS_FAILED);
2547 }
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002548
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002549 /* Check number of blocks needed for this update */
2550 p_cb->flags &= ~RW_T3T_FL_IS_FINAL_NDEF_SEGMENT;
2551 p_cb->ndef_rx_offset = 0;
2552 retval = rw_t3t_send_next_ndef_check_cmd(p_cb);
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002553
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002554 return (retval);
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002555}
2556
2557/*****************************************************************************
2558**
2559** Function RW_T3tUpdateNDef
2560**
2561** Description
2562** Write NDEF contents to a Type3 tag.
2563**
2564** The RW_T3T_UPDATE_CPLT_EVT callback event will be used to notify the
2565** application of the response.
2566**
2567** Before using this API, the RW_T3tDetectNDef function must be called to
2568** verify that the tag contains NDEF data, and to retrieve the NDEF
2569** attributes.
2570**
2571** Internally, this command will be separated into multiple Tag 3 Update
2572** commands (if necessary) - depending on the tag's Nbw (max number of
2573** blocks per write) attribute.
2574**
2575** Returns
2576** NFC_STATUS_OK: check command started
2577** NFC_STATUS_NO_BUFFERS: unable to allocate a buffer for this operation
2578** NFC_STATUS_REFUSED: tag is read-only
2579** NFC_STATUS_BUFFER_FULL: len exceeds tag's maximum size
2580** NFC_STATUS_FAILED: other error
2581**
2582*****************************************************************************/
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002583tNFC_STATUS RW_T3tUpdateNDef(uint32_t len, uint8_t* p_data) {
2584 tNFC_STATUS retval = NFC_STATUS_OK;
2585 tRW_T3T_CB* p_cb = &rw_cb.tcb.t3t;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002586
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002587 RW_TRACE_API1("RW_T3tUpdateNDef (len=%i)", len);
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002588
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002589 /* Check if we are in valid state to handle this API */
2590 if (p_cb->rw_state != RW_T3T_STATE_IDLE) {
2591 RW_TRACE_ERROR1("Error: invalid state to handle API (0x%x)",
2592 p_cb->rw_state);
2593 return (NFC_STATUS_FAILED);
2594 } else if (p_cb->ndef_attrib.status !=
2595 NFC_STATUS_OK) /* NDEF detection not performed yet? */
2596 {
2597 RW_TRACE_ERROR0("Error: NDEF detection not performed yet");
2598 return (NFC_STATUS_NOT_INITIALIZED);
2599 } else if (len > (((uint32_t)p_cb->ndef_attrib.nmaxb) *
2600 16)) /* Len exceed's tag's NDEF memory? */
2601 {
2602 return (NFC_STATUS_BUFFER_FULL);
2603 } else if (p_cb->ndef_attrib.rwflag ==
2604 T3T_MSG_NDEF_RWFLAG_RO) /* Tag's NDEF memory is read-only? */
2605 {
2606 return (NFC_STATUS_REFUSED);
2607 }
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002608
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002609 /* Check number of blocks needed for this update */
2610 p_cb->flags &= ~RW_T3T_FL_IS_FINAL_NDEF_SEGMENT;
2611 p_cb->ndef_msg_bytes_sent = 0;
2612 p_cb->ndef_msg_len = len;
2613 p_cb->ndef_msg = p_data;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002614
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002615 /* Send initial UPDATE command for NDEF Attribute Info */
2616 retval = rw_t3t_send_update_ndef_attribute_cmd(p_cb, true);
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002617
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002618 return (retval);
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002619}
2620
2621/*****************************************************************************
2622**
2623** Function RW_T3tCheck
2624**
2625** Description
2626** Read (non-NDEF) contents from a Type3 tag.
2627**
2628** The RW_READ_EVT event is used to notify the application for each
2629** segment of NDEF data received. The RW_READ_CPLT_EVT event is used to
2630** notify the application all segments have been received.
2631**
2632** Before using this API, the application must call RW_SelectTagType to
2633** indicate that a Type 3 tag has been activated, and to provide the
2634** tag's Manufacture ID (IDm) .
2635**
2636** Returns
2637** NFC_STATUS_OK: check command started
2638** NFC_STATUS_NO_BUFFERS: unable to allocate a buffer for this operation
2639** NFC_STATUS_FAILED: other error
2640**
2641*****************************************************************************/
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002642tNFC_STATUS RW_T3tCheck(uint8_t num_blocks, tT3T_BLOCK_DESC* t3t_blocks) {
2643 tNFC_STATUS retval = NFC_STATUS_OK;
2644 tRW_T3T_CB* p_cb = &rw_cb.tcb.t3t;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002645
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002646 RW_TRACE_API1("RW_T3tCheck (num_blocks = %i)", num_blocks);
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002647
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002648 /* Check if we are in valid state to handle this API */
2649 if (p_cb->rw_state != RW_T3T_STATE_IDLE) {
2650 RW_TRACE_ERROR1("Error: invalid state to handle API (0x%x)",
2651 p_cb->rw_state);
2652 return (NFC_STATUS_FAILED);
2653 }
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002654
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002655 /* Send the CHECK command */
2656 retval = rw_t3t_send_check_cmd(p_cb, num_blocks, t3t_blocks);
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002657
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002658 return (retval);
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002659}
2660
2661/*****************************************************************************
2662**
2663** Function RW_T3tUpdate
2664**
2665** Description
2666** Write (non-NDEF) contents to a Type3 tag.
2667**
2668** The RW_WRITE_CPLT_EVT event is used to notify the application all
2669** segments have been received.
2670**
2671** Before using this API, the application must call RW_SelectTagType to
2672** indicate that a Type 3 tag has been activated, and to provide the tag's
2673** Manufacture ID (IDm) .
2674**
2675** Returns
2676** NFC_STATUS_OK: check command started
2677** NFC_STATUS_NO_BUFFERS: unable to allocate a buffer for this operation
2678** NFC_STATUS_FAILED: other error
2679**
2680*****************************************************************************/
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002681tNFC_STATUS RW_T3tUpdate(uint8_t num_blocks, tT3T_BLOCK_DESC* t3t_blocks,
2682 uint8_t* p_data) {
2683 tNFC_STATUS retval = NFC_STATUS_OK;
2684 tRW_T3T_CB* p_cb = &rw_cb.tcb.t3t;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002685
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002686 RW_TRACE_API1("RW_T3tUpdate (num_blocks = %i)", num_blocks);
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002687
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002688 /* Check if we are in valid state to handle this API */
2689 if (p_cb->rw_state != RW_T3T_STATE_IDLE) {
2690 RW_TRACE_ERROR1("Error: invalid state to handle API (0x%x)",
2691 p_cb->rw_state);
2692 return (NFC_STATUS_FAILED);
2693 }
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002694
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002695 /* Send the UPDATE command */
2696 retval = rw_t3t_send_update_cmd(p_cb, num_blocks, t3t_blocks, p_data);
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002697
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002698 return (retval);
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002699}
2700
2701/*****************************************************************************
2702**
2703** Function RW_T3tPresenceCheck
2704**
2705** Description
2706** Check if the tag is still in the field.
2707**
2708** The RW_T3T_PRESENCE_CHECK_EVT w/ status is used to indicate presence
2709** or non-presence.
2710**
2711** Returns
2712** NFC_STATUS_OK, if raw data frame sent
2713** NFC_STATUS_NO_BUFFERS: unable to allocate a buffer for this operation
2714** NFC_STATUS_FAILED: other error
2715**
2716*****************************************************************************/
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002717tNFC_STATUS RW_T3tPresenceCheck(void) {
2718 tNFC_STATUS retval = NFC_STATUS_OK;
2719 tRW_DATA evt_data;
2720 tRW_CB* p_rw_cb = &rw_cb;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002721
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002722 RW_TRACE_API0("RW_T3tPresenceCheck");
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002723
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002724 /* If RW_SelectTagType was not called (no conn_callback) return failure */
2725 if (!(p_rw_cb->p_cback)) {
2726 retval = NFC_STATUS_FAILED;
2727 }
2728 /* If we are not activated, then RW_T3T_PRESENCE_CHECK_EVT status=FAIL */
2729 else if (p_rw_cb->tcb.t3t.rw_state == RW_T3T_STATE_NOT_ACTIVATED) {
2730 evt_data.status = NFC_STATUS_FAILED;
2731 (*p_rw_cb->p_cback)(RW_T3T_PRESENCE_CHECK_EVT, &evt_data);
2732 }
2733 /* If command is pending */
2734 else if (p_rw_cb->tcb.t3t.rw_state == RW_T3T_STATE_COMMAND_PENDING) {
2735 /* If already performing presence check, return error */
2736 if (p_rw_cb->tcb.t3t.flags & RW_T3T_FL_W4_PRESENCE_CHECK_POLL_RSP) {
2737 RW_TRACE_DEBUG0("RW_T3tPresenceCheck already in progress");
2738 retval = NFC_STATUS_FAILED;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002739 }
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002740 /* If busy with any other command, assume that the tag is present */
2741 else {
2742 evt_data.status = NFC_STATUS_OK;
2743 (*p_rw_cb->p_cback)(RW_T3T_PRESENCE_CHECK_EVT, &evt_data);
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002744 }
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002745 } else {
2746 /* IDLE state: send POLL command */
Ruchi Kandoi0c515ae2017-01-30 17:48:41 -08002747 retval = (tNFC_STATUS)nci_snd_t3t_polling(0xFFFF, T3T_POLL_RC_SC, 0);
2748 if (retval == NCI_STATUS_OK) {
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002749 p_rw_cb->tcb.t3t.flags |= RW_T3T_FL_W4_PRESENCE_CHECK_POLL_RSP;
2750 p_rw_cb->tcb.t3t.rw_state = RW_T3T_STATE_COMMAND_PENDING;
2751 p_rw_cb->tcb.t3t.cur_poll_rc = 0;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002752
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002753 /* start timer for waiting for responses */
2754 rw_t3t_start_poll_timer(&p_rw_cb->tcb.t3t);
2755 } else {
2756 RW_TRACE_DEBUG1(
2757 "RW_T3tPresenceCheck error sending NCI_RF_T3T_POLLING cmd (status = "
2758 "0x%0x)",
2759 retval);
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002760 }
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002761 }
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002762
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002763 return (retval);
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002764}
2765
2766/*****************************************************************************
2767**
2768** Function RW_T3tPoll
2769**
2770** Description
2771** Send POLL command
2772**
2773** Returns
2774** NFC_STATUS_OK, if raw data frame sent
2775** NFC_STATUS_NO_BUFFERS: unable to allocate a buffer for this operation
2776** NFC_STATUS_FAILED: other error
2777**
2778*****************************************************************************/
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002779tNFC_STATUS RW_T3tPoll(uint16_t system_code, tT3T_POLL_RC rc, uint8_t tsn) {
2780 tNFC_STATUS retval = NFC_STATUS_OK;
2781 tRW_T3T_CB* p_cb = &rw_cb.tcb.t3t;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002782
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002783 RW_TRACE_API0("RW_T3tPoll");
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002784
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002785 /* Check if we are in valid state to handle this API */
2786 if (p_cb->rw_state != RW_T3T_STATE_IDLE) {
2787 RW_TRACE_ERROR1("Error: invalid state to handle API (0x%x)",
2788 p_cb->rw_state);
2789 return (NFC_STATUS_FAILED);
2790 }
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002791
Ruchi Kandoi0c515ae2017-01-30 17:48:41 -08002792 retval = (tNFC_STATUS)nci_snd_t3t_polling(system_code, (uint8_t)rc, tsn);
2793 if (retval == NCI_STATUS_OK) {
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002794 /* start timer for waiting for responses */
2795 p_cb->cur_poll_rc = rc;
2796 p_cb->rw_state = RW_T3T_STATE_COMMAND_PENDING;
2797 rw_t3t_start_poll_timer(p_cb);
2798 }
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002799
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002800 return (retval);
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002801}
2802
2803/*****************************************************************************
2804**
2805** Function RW_T3tSendRawFrame
2806**
2807** Description
2808** This function is called to send a raw data frame to the peer device.
2809** When type 3 tag receives response from peer, the callback function
2810** will be called with a RW_T3T_RAW_FRAME_EVT [Table 6].
2811**
2812** Before using this API, the application must call RW_SelectTagType to
2813** indicate that a Type 3 tag has been activated.
2814**
2815** The raw frame should be a properly formatted Type 3 tag message.
2816**
2817** Returns
2818** NFC_STATUS_OK, if raw data frame sent
2819** NFC_STATUS_NO_BUFFERS: unable to allocate a buffer for this operation
2820** NFC_STATUS_FAILED: other error
2821**
2822*****************************************************************************/
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002823tNFC_STATUS RW_T3tSendRawFrame(uint16_t len, uint8_t* p_data) {
2824 tNFC_STATUS retval = NFC_STATUS_OK;
2825 tRW_T3T_CB* p_cb = &rw_cb.tcb.t3t;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002826
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002827 RW_TRACE_API1("RW_T3tSendRawFrame (len = %i)", len);
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002828
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002829 /* Check if we are in valid state to handle this API */
2830 if (p_cb->rw_state != RW_T3T_STATE_IDLE) {
2831 RW_TRACE_ERROR1("Error: invalid state to handle API (0x%x)",
2832 p_cb->rw_state);
2833 return (NFC_STATUS_FAILED);
2834 }
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002835
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002836 /* Send the UPDATE command */
2837 retval = rw_t3t_send_raw_frame(p_cb, len, p_data);
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002838
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002839 return (retval);
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002840}
2841
2842/*****************************************************************************
2843**
2844** Function RW_T3tGetSystemCodes
2845**
2846** Description
2847** Get systems codes supported by the activated tag:
Yoshinobu Ito721b3ab2016-08-02 14:41:33 +09002848** Poll for wildcard (FFFF, RC=1):
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002849**
2850** Before using this API, the application must call RW_SelectTagType to
2851** indicate that a Type 3 tag has been activated.
2852**
2853** Returns
2854** NFC_STATUS_OK, if raw data frame sent
2855** NFC_STATUS_NO_BUFFERS: unable to allocate a buffer for this operation
2856** NFC_STATUS_FAILED: other error
2857**
2858*****************************************************************************/
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002859tNFC_STATUS RW_T3tGetSystemCodes(void) {
2860 tNFC_STATUS retval = NFC_STATUS_OK;
2861 tRW_T3T_CB* p_cb = &rw_cb.tcb.t3t;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002862
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002863 RW_TRACE_API0("RW_T3tGetSystemCodes");
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002864
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002865 /* Check if we are in valid state to handle this API */
2866 if (p_cb->rw_state != RW_T3T_STATE_IDLE) {
2867 RW_TRACE_ERROR1("Error: invalid state to handle API (0x%x)",
2868 p_cb->rw_state);
2869 return (NFC_STATUS_FAILED);
2870 } else {
Ruchi Kandoi0c515ae2017-01-30 17:48:41 -08002871 retval = (tNFC_STATUS)nci_snd_t3t_polling(0xFFFF, T3T_POLL_RC_SC, 0);
2872 if (retval == NCI_STATUS_OK) {
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002873 p_cb->cur_cmd = RW_T3T_CMD_GET_SYSTEM_CODES;
2874 p_cb->cur_tout = RW_T3T_DEFAULT_CMD_TIMEOUT_TICKS;
2875 p_cb->cur_poll_rc = T3T_POLL_RC_SC;
2876 p_cb->rw_state = RW_T3T_STATE_COMMAND_PENDING;
2877 p_cb->flags |= RW_T3T_FL_W4_GET_SC_POLL_RSP;
2878 p_cb->num_system_codes = 0;
2879
2880 /* start timer for waiting for responses */
2881 rw_t3t_start_poll_timer(p_cb);
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002882 }
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002883 }
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002884
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002885 return (retval);
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002886}
2887
2888/*****************************************************************************
2889**
2890** Function RW_T3tFormatNDef
2891**
2892** Description
2893** Format a type-3 tag for NDEF.
2894**
2895** Only Felica-Lite tags are supported by this API. The
2896** RW_T3T_FORMAT_CPLT_EVT is used to notify the status of the operation.
2897**
2898** Returns
2899** NFC_STATUS_OK: ndef detection procedure started
2900** NFC_STATUS_NO_BUFFERS: unable to allocate a buffer for this operation
2901** NFC_STATUS_FAILED: other error
2902**
2903*****************************************************************************/
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002904tNFC_STATUS RW_T3tFormatNDef(void) {
2905 tNFC_STATUS retval = NFC_STATUS_OK;
2906 tRW_T3T_CB* p_cb = &rw_cb.tcb.t3t;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002907
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002908 RW_TRACE_API0("RW_T3tFormatNDef");
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002909
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002910 /* Check if we are in valid state to handle this API */
2911 if (p_cb->rw_state != RW_T3T_STATE_IDLE) {
2912 RW_TRACE_ERROR1("Error: invalid state to handle API (0x%x)",
2913 p_cb->rw_state);
2914 return (NFC_STATUS_FAILED);
2915 } else {
2916 /* Poll tag, to see if Felica-Lite system is supported */
Ruchi Kandoi0c515ae2017-01-30 17:48:41 -08002917 retval = (tNFC_STATUS)nci_snd_t3t_polling(T3T_SYSTEM_CODE_FELICA_LITE,
2918 T3T_POLL_RC_SC, 0);
2919 if (retval == NCI_STATUS_OK) {
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002920 p_cb->cur_cmd = RW_T3T_CMD_FORMAT;
2921 p_cb->cur_tout = RW_T3T_DEFAULT_CMD_TIMEOUT_TICKS;
2922 p_cb->cur_poll_rc = T3T_POLL_RC_SC;
2923 p_cb->rw_state = RW_T3T_STATE_COMMAND_PENDING;
2924 p_cb->rw_substate = RW_T3T_FMT_SST_POLL_FELICA_LITE;
2925 p_cb->flags |= RW_T3T_FL_W4_FMT_FELICA_LITE_POLL_RSP;
2926
2927 /* start timer for waiting for responses */
2928 rw_t3t_start_poll_timer(p_cb);
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002929 }
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002930 }
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002931
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002932 return (retval);
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002933}
Martijn Coenen5c65c3a2013-03-27 13:23:36 -07002934
2935/*****************************************************************************
2936**
2937** Function RW_T3tSetReadOnly
2938**
2939** Description This function performs NDEF read-only procedure
2940** Note: Only Felica-Lite tags are supported by this API.
2941** RW_T3tDetectNDef() must be called before using this
2942**
2943** The RW_T3T_SET_READ_ONLY_CPLT_EVT event will be returned.
2944**
2945** Returns NFC_STATUS_OK if success
2946** NFC_STATUS_FAILED if T3T is busy or other error
2947**
2948*****************************************************************************/
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002949tNFC_STATUS RW_T3tSetReadOnly(bool b_hard_lock) {
2950 tNFC_STATUS retval = NFC_STATUS_OK;
2951 tRW_T3T_CB* p_cb = &rw_cb.tcb.t3t;
2952 tRW_DATA evt_data;
Martijn Coenen5c65c3a2013-03-27 13:23:36 -07002953
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002954 RW_TRACE_API1("RW_T3tSetReadOnly (): b_hard_lock=%d", b_hard_lock);
Martijn Coenen5c65c3a2013-03-27 13:23:36 -07002955
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002956 /* Check if we are in valid state to handle this API */
2957 if (p_cb->rw_state != RW_T3T_STATE_IDLE) {
2958 RW_TRACE_ERROR1("Error: invalid state to handle API (0x%x)",
2959 p_cb->rw_state);
2960 return (NFC_STATUS_FAILED);
2961 }
Martijn Coenen5c65c3a2013-03-27 13:23:36 -07002962
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002963 if (p_cb->ndef_attrib.status !=
2964 NFC_STATUS_OK) /* NDEF detection not performed yet? */
2965 {
2966 RW_TRACE_ERROR0("Error: NDEF detection not performed yet");
2967 return (NFC_STATUS_NOT_INITIALIZED);
2968 }
Martijn Coenen5c65c3a2013-03-27 13:23:36 -07002969
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002970 if ((!b_hard_lock) &&
2971 (p_cb->ndef_attrib.rwflag ==
2972 T3T_MSG_NDEF_RWFLAG_RO)) /* Tag's NDEF memory is read-only already */
2973 {
2974 evt_data.status = NFC_STATUS_OK;
2975 (*(rw_cb.p_cback))(RW_T3T_SET_READ_ONLY_CPLT_EVT, &evt_data);
Martijn Coenen5c65c3a2013-03-27 13:23:36 -07002976 return (retval);
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002977 } else {
2978 /* Poll tag, to see if Felica-Lite system is supported */
Ruchi Kandoi0c515ae2017-01-30 17:48:41 -08002979 retval = (tNFC_STATUS)nci_snd_t3t_polling(T3T_SYSTEM_CODE_FELICA_LITE,
2980 T3T_POLL_RC_SC, 0);
2981 if (retval == NCI_STATUS_OK) {
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002982 if (b_hard_lock)
2983 p_cb->cur_cmd = RW_T3T_CMD_SET_READ_ONLY_HARD;
2984 else
2985 p_cb->cur_cmd = RW_T3T_CMD_SET_READ_ONLY_SOFT;
2986 p_cb->cur_tout = RW_T3T_DEFAULT_CMD_TIMEOUT_TICKS;
2987 p_cb->cur_poll_rc = T3T_POLL_RC_SC;
2988 p_cb->rw_state = RW_T3T_STATE_COMMAND_PENDING;
2989 p_cb->rw_substate = RW_T3T_SRO_SST_POLL_FELICA_LITE;
2990 p_cb->flags |= RW_T3T_FL_W4_SRO_FELICA_LITE_POLL_RSP;
2991
2992 /* start timer for waiting for responses */
2993 rw_t3t_start_poll_timer(p_cb);
2994 }
2995 }
2996 return (retval);
Martijn Coenen5c65c3a2013-03-27 13:23:36 -07002997}