blob: efc9dbd8093769b70756889422bb91dd3d0b97fb [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
Martijn Coenen5c65c3a2013-03-27 13:23:36 -070019
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -080020/******************************************************************************
21 *
22 * This file contains the implementation for Type 3 tag in Reader/Writer
23 * mode.
24 *
25 ******************************************************************************/
26#include <string.h>
27#include "nfc_target.h"
28#include "bt_types.h"
29#include "trace_api.h"
30
31#include "nfc_api.h"
32#include "nfc_int.h"
33#include "nci_hmsgs.h"
34#include "rw_api.h"
35#include "rw_int.h"
36#include "tags_int.h"
37#include "gki.h"
38
39/* Definitions for constructing t3t command messages */
40#define RW_T3T_FL_PADDING 0x01 /* Padding needed for last NDEF block */
41#define RW_T3T_MAX_NDEF_BLOCKS_PER_UPDATE_1_BYTE_FORMAT (13) /* Maximum number of NDEF blocks updates that can fit into one command (when all block-numbers are < 256) */
42#define RW_T3T_MAX_NDEF_BLOCKS_PER_UPDATE_2_BYTE_FORMAT (12) /* Maximum number of NDEF blocks updates that can fit into one command (when all block-numbers are >= 256) */
43
44/* Definitions for SENSF_RES */
45#define RW_T3T_SENSF_RES_RD_OFFSET 17 /* Offset of RD in SENSF_RES from NCI_POLL NTF (includes 1 byte SENSF_RES length) */
46#define RW_T3T_SENSF_RES_RD_LEN 2 /* Size of RD in SENSF_RES */
47
48/* Timeout definitions for commands */
49#define RW_T3T_POLL_CMD_TIMEOUT_TICKS ((RW_T3T_TOUT_RESP*2*QUICK_TIMER_TICKS_PER_SEC) / 1000)
50#define RW_T3T_DEFAULT_CMD_TIMEOUT_TICKS ((RW_T3T_TOUT_RESP*QUICK_TIMER_TICKS_PER_SEC) / 1000)
51#define RW_T3T_RAW_FRAME_CMD_TIMEOUT_TICKS (RW_T3T_DEFAULT_CMD_TIMEOUT_TICKS * 4)
Sherry Smith67fe6102014-06-02 11:01:54 -070052#define RW_T3T_MIN_TIMEOUT_TICKS 10
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -080053
54/* Macro to extract major version from NDEF version byte */
55#define T3T_GET_MAJOR_VERSION(ver) (ver>>4)
56
57/* Enumeration of API commands */
58enum
59{
60 RW_T3T_CMD_DETECT_NDEF,
61 RW_T3T_CMD_CHECK_NDEF,
62 RW_T3T_CMD_UPDATE_NDEF,
63 RW_T3T_CMD_CHECK,
64 RW_T3T_CMD_UPDATE,
65 RW_T3T_CMD_SEND_RAW_FRAME,
66 RW_T3T_CMD_GET_SYSTEM_CODES,
67 RW_T3T_CMD_FORMAT,
Martijn Coenen5c65c3a2013-03-27 13:23:36 -070068 RW_T3T_CMD_SET_READ_ONLY_SOFT,
69 RW_T3T_CMD_SET_READ_ONLY_HARD,
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -080070
71 RW_T3T_CMD_MAX
72};
73
74/* RW_CBACK events corresponding to API comands */
Ruchi Kandoi512ee632017-01-03 13:59:10 -080075const uint8_t rw_t3t_api_res_evt[RW_T3T_CMD_MAX] =
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -080076{
77 RW_T3T_NDEF_DETECT_EVT, /* RW_T3T_CMD_DETECT_NDEF */
78 RW_T3T_CHECK_CPLT_EVT, /* RW_T3T_CMD_CHECK_NDEF */
79 RW_T3T_UPDATE_CPLT_EVT, /* RW_T3T_CMD_UPDATE_NDEF */
80 RW_T3T_CHECK_CPLT_EVT, /* RW_T3T_CMD_CHECK */
81 RW_T3T_UPDATE_CPLT_EVT, /* RW_T3T_CMD_UPDATE */
82 RW_T3T_RAW_FRAME_EVT, /* RW_T3T_CMD_SEND_RAW_FRAME */
83 RW_T3T_GET_SYSTEM_CODES_EVT, /* RW_T3T_CMD_GET_SYSTEM_CODES */
Martijn Coenen5c65c3a2013-03-27 13:23:36 -070084 RW_T3T_FORMAT_CPLT_EVT, /* RW_T3T_CMD_FORMAT */
85 RW_T3T_SET_READ_ONLY_CPLT_EVT /* RW_T3T_CMD_SET_READ_ONLY */
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -080086};
87
88/* States */
89enum
90{
91 RW_T3T_STATE_NOT_ACTIVATED,
92 RW_T3T_STATE_IDLE,
93 RW_T3T_STATE_COMMAND_PENDING
94};
95
96/* Sub-states */
97enum
98{
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -080099 /* Sub states for formatting Felica-Lite */
100 RW_T3T_FMT_SST_POLL_FELICA_LITE, /* Waiting for POLL Felica-Lite response (for formatting) */
101 RW_T3T_FMT_SST_CHECK_MC_BLK, /* Waiting for Felica-Lite MC (MemoryControl) block-read to complete */
102 RW_T3T_FMT_SST_UPDATE_MC_BLK, /* Waiting for Felica-Lite MC (MemoryControl) block-write to complete */
Martijn Coenen5c65c3a2013-03-27 13:23:36 -0700103 RW_T3T_FMT_SST_UPDATE_NDEF_ATTRIB, /* Waiting for NDEF attribute block-write to complete */
104
105 /* Sub states for setting Felica-Lite read only */
106 RW_T3T_SRO_SST_POLL_FELICA_LITE, /* Waiting for POLL Felica-Lite response (for setting read only) */
107 RW_T3T_SRO_SST_UPDATE_NDEF_ATTRIB, /* Waiting for NDEF attribute block-write to complete */
108 RW_T3T_SRO_SST_CHECK_MC_BLK, /* Waiting for Felica-Lite MC (MemoryControl) block-read to complete */
109 RW_T3T_SRO_SST_UPDATE_MC_BLK /* Waiting for Felica-Lite MC (MemoryControl) block-write to complete */
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800110};
111
112#if (BT_TRACE_VERBOSE == TRUE)
Ruchi Kandoi512ee632017-01-03 13:59:10 -0800113static char *rw_t3t_cmd_str (uint8_t cmd_id);
114static char *rw_t3t_state_str (uint8_t state_id);
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800115#endif
116
117
118/* Local static functions */
Ruchi Kandoi512ee632017-01-03 13:59:10 -0800119static void rw_t3t_update_ndef_flag (uint8_t *p_flag);
120static tNFC_STATUS rw_t3t_unselect (uint8_t peer_nfcid2[]);
Ruchi Kandoi0a736882017-01-09 15:43:14 -0800121static NFC_HDR *rw_t3t_get_cmd_buf (void);
122static tNFC_STATUS rw_t3t_send_to_lower (NFC_HDR *p_msg);
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800123static void rw_t3t_handle_get_system_codes_cplt (void);
Ruchi Kandoi512ee632017-01-03 13:59:10 -0800124static void rw_t3t_handle_get_sc_poll_rsp (tRW_T3T_CB *p_cb, uint8_t nci_status, uint8_t num_responses, uint8_t sensf_res_buf_size, uint8_t *p_sensf_res_buf);
125static void rw_t3t_handle_ndef_detect_poll_rsp (tRW_T3T_CB *p_cb, uint8_t nci_status, uint8_t num_responses, uint8_t sensf_res_buf_size, uint8_t *p_sensf_res_buf);
126static void rw_t3t_handle_fmt_poll_rsp (tRW_T3T_CB *p_cb, uint8_t nci_status, uint8_t num_responses, uint8_t sensf_res_buf_size, uint8_t *p_sensf_res_buf);
127static void rw_t3t_handle_sro_poll_rsp (tRW_T3T_CB *p_cb, uint8_t nci_status, uint8_t num_responses, uint8_t sensf_res_buf_size, uint8_t *p_sensf_res_buf);
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800128
129
130/* Default NDEF attribute information block (used when formatting Felica-Lite tags) */
131#define RW_T3T_DEFAULT_FELICALITE_NBR 4 /* NBr (max block reads per cmd)*/
132#define RW_T3T_DEFAULT_FELICALITE_NBW 1 /* NBw (max block write per cmd)*/
Martijn Coenen5c65c3a2013-03-27 13:23:36 -0700133#define RW_T3T_DEFAULT_FELICALITE_NMAXB (T3T_FELICALITE_NMAXB)
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800134#define RW_T3T_DEFAULT_FELICALITE_ATTRIB_INFO_CHECKSUM ((T3T_MSG_NDEF_VERSION + \
135 RW_T3T_DEFAULT_FELICALITE_NBR + \
136 RW_T3T_DEFAULT_FELICALITE_NBW + \
137 (RW_T3T_DEFAULT_FELICALITE_NMAXB>>8) + \
138 (RW_T3T_DEFAULT_FELICALITE_NMAXB&0xFF) +\
139 T3T_MSG_NDEF_WRITEF_OFF + \
140 T3T_MSG_NDEF_RWFLAG_RW) & 0xFFFF)
141
Ruchi Kandoi512ee632017-01-03 13:59:10 -0800142const uint8_t rw_t3t_default_attrib_info[T3T_MSG_BLOCKSIZE] =
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800143{
144 T3T_MSG_NDEF_VERSION, /* Ver */
145 RW_T3T_DEFAULT_FELICALITE_NBR, /* NBr (max block reads per cmd)*/
146 RW_T3T_DEFAULT_FELICALITE_NBW, /* NBw (max block write per cmd)*/
147 (RW_T3T_DEFAULT_FELICALITE_NMAXB>>8), /* Nmaxb (max size in blocks) */
148 (RW_T3T_DEFAULT_FELICALITE_NMAXB&0xFF), /* Nmaxb (max size in blocks) */
149 0, 0, 0, 0, /* Unused */
150 T3T_MSG_NDEF_WRITEF_OFF, /* WriteF */
151 T3T_MSG_NDEF_RWFLAG_RW, /* RW Flag */
152 0, 0, 0, /* Ln (current size in bytes) */
153
154 (RW_T3T_DEFAULT_FELICALITE_ATTRIB_INFO_CHECKSUM >> 8), /* checksum (high-byte) */
155 (RW_T3T_DEFAULT_FELICALITE_ATTRIB_INFO_CHECKSUM & 0xFF) /* checksum (low-byte) */
156
157};
158
Sherry Smith818b56e2014-05-14 16:46:32 -0700159/* This is (T/t3t * 4^E) , E is the index of the array. The unit is .0001 ms */
Ruchi Kandoi512ee632017-01-03 13:59:10 -0800160static const uint32_t rw_t3t_mrti_base [] =
Sherry Smith818b56e2014-05-14 16:46:32 -0700161{
162 302,
163 1208,
164 4832,
165 19328
166};
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800167
Sherry Smith818b56e2014-05-14 16:46:32 -0700168
169/*******************************************************************************
170**
171** Function rw_t3t_check_timeout
172**
173** Description The timeout value is a + b * number_blocks)
174**
175** Returns timeout value in ticks
176**
177*******************************************************************************/
Ruchi Kandoi512ee632017-01-03 13:59:10 -0800178static uint32_t rw_t3t_check_timeout (uint16_t num_blocks)
Sherry Smith818b56e2014-05-14 16:46:32 -0700179{
180 tRW_T3T_CB *p_cb = &rw_cb.tcb.t3t;
Ruchi Kandoi512ee632017-01-03 13:59:10 -0800181 uint32_t timeout;
182 uint32_t extra;
Sherry Smith67fe6102014-06-02 11:01:54 -0700183
Sherry Smith818b56e2014-05-14 16:46:32 -0700184 timeout = (p_cb->check_tout_a + num_blocks * p_cb->check_tout_b)*QUICK_TIMER_TICKS_PER_SEC/1000000;
Sherry Smith67fe6102014-06-02 11:01:54 -0700185 /* allow some extra time for driver */
186 extra = (timeout / 10) + RW_T3T_MIN_TIMEOUT_TICKS;
187 timeout += extra;
188
Sherry Smith818b56e2014-05-14 16:46:32 -0700189 return timeout;
190}
191
192/*******************************************************************************
193**
194** Function rw_t3t_update_timeout
195**
196** Description The timeout value is a + b * number_blocks)
197**
198** Returns timeout value in ticks
199**
200*******************************************************************************/
Ruchi Kandoi512ee632017-01-03 13:59:10 -0800201static uint32_t rw_t3t_update_timeout (uint16_t num_blocks)
Sherry Smith818b56e2014-05-14 16:46:32 -0700202{
203 tRW_T3T_CB *p_cb = &rw_cb.tcb.t3t;
Ruchi Kandoi512ee632017-01-03 13:59:10 -0800204 uint32_t timeout;
205 uint32_t extra;
Sherry Smith67fe6102014-06-02 11:01:54 -0700206
Sherry Smith818b56e2014-05-14 16:46:32 -0700207 timeout = (p_cb->update_tout_a + num_blocks * p_cb->update_tout_b)*QUICK_TIMER_TICKS_PER_SEC/1000000;
Sherry Smith67fe6102014-06-02 11:01:54 -0700208 /* allow some extra time for driver */
209 extra = (timeout / 10) + RW_T3T_MIN_TIMEOUT_TICKS;
210 timeout += extra;
211
Sherry Smith818b56e2014-05-14 16:46:32 -0700212 return timeout;
213}
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800214/*******************************************************************************
215**
216** Function rw_t3t_process_error
217**
218** Description Process error (timeout or CRC error)
219**
220** Returns none
221**
222*******************************************************************************/
223void rw_t3t_process_error (tNFC_STATUS status)
224{
225 tRW_T3T_CB *p_cb = &rw_cb.tcb.t3t;
Ruchi Kandoi512ee632017-01-03 13:59:10 -0800226 uint8_t evt;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800227 tRW_DATA evt_data;
Ruchi Kandoi0a736882017-01-09 15:43:14 -0800228 NFC_HDR *p_cmd_buf;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800229
230 if (p_cb->rw_state == RW_T3T_STATE_COMMAND_PENDING)
231 {
232 if (p_cb->cur_cmd == RW_T3T_CMD_GET_SYSTEM_CODES)
233 {
Yoshinobu Ito721b3ab2016-08-02 14:41:33 +0900234 /* For GetSystemCode: tag did not respond to requested POLL */
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800235 rw_t3t_handle_get_system_codes_cplt ();
236 return;
237 }
238 /* Retry sending command if retry-count < max */
239 else if (rw_cb.cur_retry < RW_MAX_RETRIES)
240 {
241 /* retry sending the command */
242 rw_cb.cur_retry++;
243
244 RW_TRACE_DEBUG2 ("T3T retransmission attempt %i of %i", rw_cb.cur_retry, RW_MAX_RETRIES);
245
246 /* allocate a new buffer for message */
247 if ((p_cmd_buf = rw_t3t_get_cmd_buf ()) != NULL)
248 {
Ruchi Kandoi0a736882017-01-09 15:43:14 -0800249 memcpy (p_cmd_buf, p_cb->p_cur_cmd_buf, sizeof (NFC_HDR) + p_cb->p_cur_cmd_buf->offset + p_cb->p_cur_cmd_buf->len);
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800250
251 if (rw_t3t_send_to_lower (p_cmd_buf) == NFC_STATUS_OK)
252 {
253 /* Start timer for waiting for response */
254 nfc_start_quick_timer (&p_cb->timer, NFC_TTYPE_RW_T3T_RESPONSE, p_cb->cur_tout);
255 return;
256 }
257 else
258 {
259 /* failure - could not send buffer */
260 GKI_freebuf (p_cmd_buf);
261 }
262 }
263 }
264 else
265 {
266 RW_TRACE_DEBUG1 ("T3T maximum retransmission attempts reached (%i)", RW_MAX_RETRIES);
267 }
268
Ruchi Kandoi303fec12016-12-14 13:22:38 -0800269#if (RW_STATS_INCLUDED == TRUE)
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800270 /* update failure count */
271 rw_main_update_fail_stats ();
272#endif /* RW_STATS_INCLUDED */
273
274 p_cb->rw_state = RW_T3T_STATE_IDLE;
275
276 /* Notify app of result (if there was a pending command) */
277 if (p_cb->cur_cmd < RW_T3T_CMD_MAX)
278 {
279 /* If doing presence check, use status=NFC_STATUS_FAILED, otherwise NFC_STATUS_TIMEOUT */
280 evt_data.status = status;
281 evt = rw_t3t_api_res_evt[p_cb->cur_cmd];
282
283 /* Set additional flags for RW_T3T_NDEF_DETECT_EVT */
284 if (evt == RW_T3T_NDEF_DETECT_EVT)
285 {
286 evt_data.ndef.flags = RW_NDEF_FL_UNKNOWN;
Evan Chua24be4f2013-11-13 15:30:16 -0500287 rw_t3t_update_ndef_flag (&evt_data.ndef.flags);
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800288 }
289
290 (*(rw_cb.p_cback)) (evt, &evt_data);
291 }
292 }
293 else
294 {
295 evt_data.status = status;
296 (*(rw_cb.p_cback)) (RW_T3T_INTF_ERROR_EVT, &evt_data);
297 }
298}
299
300/*******************************************************************************
301**
302** Function rw_t3t_start_poll_timer
303**
304** Description Start the timer for T3T POLL Command
305**
306** Returns none
307**
308*******************************************************************************/
309void rw_t3t_start_poll_timer (tRW_T3T_CB *p_cb)
310{
311 nfc_start_quick_timer (&p_cb->poll_timer, NFC_TTYPE_RW_T3T_RESPONSE, RW_T3T_POLL_CMD_TIMEOUT_TICKS);
312}
313
314/*******************************************************************************
315**
316** Function rw_t3t_handle_nci_poll_ntf
317**
318** Description Handle NCI_T3T_POLLING_NTF
319**
320** Returns none
321**
322*******************************************************************************/
Ruchi Kandoi512ee632017-01-03 13:59:10 -0800323void rw_t3t_handle_nci_poll_ntf (uint8_t nci_status, uint8_t num_responses, uint8_t sensf_res_buf_size, uint8_t *p_sensf_res_buf)
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800324{
325 tRW_DATA evt_data;
326 tRW_T3T_CB *p_cb = &rw_cb.tcb.t3t;
327
328 /* stop timer for poll response */
329 nfc_stop_quick_timer (&p_cb->poll_timer);
330
331 /* Stop t3t timer (if started) */
332 if (p_cb->flags & RW_T3T_FL_W4_PRESENCE_CHECK_POLL_RSP)
333 {
334 p_cb->flags &= ~RW_T3T_FL_W4_PRESENCE_CHECK_POLL_RSP;
335 evt_data.status = nci_status;
336 p_cb->rw_state = RW_T3T_STATE_IDLE;
337 (*(rw_cb.p_cback)) (RW_T3T_PRESENCE_CHECK_EVT, (tRW_DATA *) &evt_data);
338 }
339 else if (p_cb->flags & RW_T3T_FL_W4_GET_SC_POLL_RSP)
340 {
341 /* Handle POLL ntf in response to get system codes */
342 p_cb->flags &= ~RW_T3T_FL_W4_GET_SC_POLL_RSP;
343 rw_t3t_handle_get_sc_poll_rsp (p_cb, nci_status, num_responses, sensf_res_buf_size, p_sensf_res_buf);
344 }
345 else if (p_cb->flags & RW_T3T_FL_W4_FMT_FELICA_LITE_POLL_RSP)
346 {
347 /* Handle POLL ntf in response to get system codes */
348 p_cb->flags &= ~RW_T3T_FL_W4_FMT_FELICA_LITE_POLL_RSP;
349 rw_t3t_handle_fmt_poll_rsp (p_cb, nci_status, num_responses, sensf_res_buf_size, p_sensf_res_buf);
350 }
Martijn Coenen5c65c3a2013-03-27 13:23:36 -0700351 else if (p_cb->flags & RW_T3T_FL_W4_SRO_FELICA_LITE_POLL_RSP)
352 {
353 /* Handle POLL ntf in response to get system codes */
354 p_cb->flags &= ~RW_T3T_FL_W4_SRO_FELICA_LITE_POLL_RSP;
355 rw_t3t_handle_sro_poll_rsp (p_cb, nci_status, num_responses, sensf_res_buf_size, p_sensf_res_buf);
356 }
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800357 else if (p_cb->flags & RW_T3T_FL_W4_NDEF_DETECT_POLL_RSP)
358 {
359 /* Handle POLL ntf in response to ndef detection */
360 p_cb->flags &= ~RW_T3T_FL_W4_NDEF_DETECT_POLL_RSP;
361 rw_t3t_handle_ndef_detect_poll_rsp (p_cb, nci_status, num_responses, sensf_res_buf_size, p_sensf_res_buf);
362 }
363 else
364 {
365 /* Handle POLL ntf in response to RW_T3tPoll */
366 if ((evt_data.t3t_poll.status = nci_status) == NCI_STATUS_OK)
367 {
368 evt_data.t3t_poll.rc = p_cb->cur_poll_rc;
369 evt_data.t3t_poll.response_num = num_responses;
370 evt_data.t3t_poll.response_bufsize = sensf_res_buf_size;
371 evt_data.t3t_poll.response_buf = p_sensf_res_buf;
372 }
373
374 p_cb->rw_state = RW_T3T_STATE_IDLE;
375 (*(rw_cb.p_cback)) (RW_T3T_POLL_EVT, &evt_data);
376 }
377}
378
379
380/*******************************************************************************
381**
382** Function rw_t3t_handle_get_system_codes_cplt
383**
384** Description Notify upper layer of system codes
385**
386** Returns none
387**
388*******************************************************************************/
389void rw_t3t_handle_get_system_codes_cplt (void)
390{
391 tRW_T3T_CB *p_cb = &rw_cb.tcb.t3t;
392 tRW_DATA evt_data;
Ruchi Kandoi512ee632017-01-03 13:59:10 -0800393 uint8_t i;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800394
395 evt_data.t3t_sc.status = NFC_STATUS_OK;
396 evt_data.t3t_sc.num_system_codes = p_cb->num_system_codes;
397 evt_data.t3t_sc.p_system_codes = p_cb->system_codes;
398
399 RW_TRACE_DEBUG1 ("rw_t3t_handle_get_system_codes_cplt, number of systems: %i", evt_data.t3t_sc.num_system_codes);
400 for (i = 0; i < evt_data.t3t_sc.num_system_codes; i++)
401 {
402 RW_TRACE_DEBUG2 (" system %i: %04X", i, evt_data.t3t_sc.p_system_codes[i]);
403 }
404
405 p_cb->rw_state = RW_T3T_STATE_IDLE;
406 (*(rw_cb.p_cback)) (RW_T3T_GET_SYSTEM_CODES_EVT, &evt_data);
407
408
409}
410
411/*******************************************************************************
412**
413** Function rw_t3t_format_cplt
414**
415** Description Notify upper layer of format complete
416**
417** Returns none
418**
419*******************************************************************************/
420void rw_t3t_format_cplt (tNFC_STATUS status)
421{
422 tRW_T3T_CB *p_cb = &rw_cb.tcb.t3t;
423 tRW_DATA evt_data;
424
425 p_cb->rw_state = RW_T3T_STATE_IDLE;
426
Martijn Coenen5c65c3a2013-03-27 13:23:36 -0700427 /* Update ndef info */
428 p_cb->ndef_attrib.status = status;
429 if (status == NFC_STATUS_OK)
430 {
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 }
439
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800440 /* Notify upper layer of format complete */
441 evt_data.status = status;
442 (*(rw_cb.p_cback)) (RW_T3T_FORMAT_CPLT_EVT, &evt_data);
443}
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*******************************************************************************/
454void rw_t3t_set_readonly_cplt (tNFC_STATUS status)
455{
456 tRW_T3T_CB *p_cb = &rw_cb.tcb.t3t;
457 tRW_DATA evt_data;
458
459 p_cb->rw_state = RW_T3T_STATE_IDLE;
460
461 /* Notify upper layer of format complete */
462 evt_data.status = status;
463 (*(rw_cb.p_cback)) (RW_T3T_SET_READ_ONLY_CPLT_EVT, &evt_data);
464}
465
466/*******************************************************************************
467**
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800468** Function rw_t3t_process_timeout
469**
470** Description Process timeout
471**
472** Returns none
473**
474*******************************************************************************/
475void rw_t3t_process_timeout (TIMER_LIST_ENT *p_tle)
476{
477 tRW_T3T_CB *p_cb = &rw_cb.tcb.t3t;
478 tRW_DATA evt_data;
479
480 /* Check which timer timed out */
481 if (p_tle == &p_cb->timer)
482 {
483 /* UPDATE/CHECK response timeout */
484#if (BT_TRACE_VERBOSE == TRUE)
485 RW_TRACE_ERROR3 ("T3T timeout. state=%s cur_cmd=0x%02X (%s)", rw_t3t_state_str (rw_cb.tcb.t3t.rw_state), rw_cb.tcb.t3t.cur_cmd, rw_t3t_cmd_str (rw_cb.tcb.t3t.cur_cmd));
486#else
487 RW_TRACE_ERROR2 ("T3T timeout. state=0x%02X cur_cmd=0x%02X", rw_cb.tcb.t3t.rw_state, rw_cb.tcb.t3t.cur_cmd);
488#endif
489
490 rw_t3t_process_error (NFC_STATUS_TIMEOUT);
491 }
492 else
493 {
494 RW_TRACE_ERROR0 ("T3T POLL timeout.");
495
496 /* POLL response timeout */
497 if (p_cb->flags & RW_T3T_FL_W4_PRESENCE_CHECK_POLL_RSP)
498 {
499 /* POLL timeout for presence check */
500 p_cb->flags &= ~RW_T3T_FL_W4_PRESENCE_CHECK_POLL_RSP;
501 evt_data.status = NFC_STATUS_FAILED;
502 p_cb->rw_state = RW_T3T_STATE_IDLE;
503 (*(rw_cb.p_cback)) (RW_T3T_PRESENCE_CHECK_EVT, (tRW_DATA *) &evt_data);
504 }
505 else if (p_cb->flags & RW_T3T_FL_W4_GET_SC_POLL_RSP)
506 {
507 /* POLL timeout for getting system codes */
508 p_cb->flags &= ~RW_T3T_FL_W4_GET_SC_POLL_RSP;
509 rw_t3t_handle_get_system_codes_cplt ();
510 }
511 else if (p_cb->flags & RW_T3T_FL_W4_FMT_FELICA_LITE_POLL_RSP)
512 {
513 /* POLL timeout for formatting Felica Lite */
514 p_cb->flags &= ~RW_T3T_FL_W4_FMT_FELICA_LITE_POLL_RSP;
515 RW_TRACE_ERROR0 ("Felica-Lite tag not detected");
516 rw_t3t_format_cplt (NFC_STATUS_FAILED);
517 }
Martijn Coenen5c65c3a2013-03-27 13:23:36 -0700518 else if (p_cb->flags & RW_T3T_FL_W4_SRO_FELICA_LITE_POLL_RSP)
519 {
520 /* POLL timeout for configuring Felica Lite read only */
521 p_cb->flags &= ~RW_T3T_FL_W4_SRO_FELICA_LITE_POLL_RSP;
522 RW_TRACE_ERROR0 ("Felica-Lite tag not detected");
523 rw_t3t_set_readonly_cplt (NFC_STATUS_FAILED);
524 }
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800525 else if (p_cb->flags & RW_T3T_FL_W4_NDEF_DETECT_POLL_RSP)
526 {
527 /* POLL timeout for ndef detection */
528 p_cb->flags &= ~RW_T3T_FL_W4_NDEF_DETECT_POLL_RSP;
529 rw_t3t_handle_ndef_detect_poll_rsp (p_cb, NFC_STATUS_TIMEOUT, 0, 0, NULL);
530 }
531 else
532 {
533 /* Timeout waiting for response for RW_T3tPoll */
534 evt_data.t3t_poll.status = NFC_STATUS_FAILED;
535 p_cb->rw_state = RW_T3T_STATE_IDLE;
536 (*(rw_cb.p_cback)) (RW_T3T_POLL_EVT, (tRW_DATA *) &evt_data);
537 }
538 }
539}
540
541
542/*******************************************************************************
543**
544** Function rw_t3t_process_frame_error
545**
546** Description Process frame crc error
547**
548** Returns none
549**
550*******************************************************************************/
551void rw_t3t_process_frame_error (void)
552{
553#if (BT_TRACE_VERBOSE == TRUE)
554 RW_TRACE_ERROR3 ("T3T frame error. state=%s cur_cmd=0x%02X (%s)", rw_t3t_state_str (rw_cb.tcb.t3t.rw_state), rw_cb.tcb.t3t.cur_cmd, rw_t3t_cmd_str (rw_cb.tcb.t3t.cur_cmd));
555#else
556 RW_TRACE_ERROR2 ("T3T frame error. state=0x%02X cur_cmd=0x%02X", rw_cb.tcb.t3t.rw_state, rw_cb.tcb.t3t.cur_cmd);
557#endif
558
Ruchi Kandoi303fec12016-12-14 13:22:38 -0800559#if (RW_STATS_INCLUDED == TRUE)
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800560 /* Update stats */
561 rw_main_update_crc_error_stats ();
562#endif /* RW_STATS_INCLUDED */
563
564 /* Process the error */
565 rw_t3t_process_error (NFC_STATUS_MSG_CORRUPTED);
566}
567
568/*******************************************************************************
569**
570** Function rw_t3t_send_to_lower
571**
572** Description Send command to lower layer
573**
574** Returns status of the send
575**
576*******************************************************************************/
Ruchi Kandoi0a736882017-01-09 15:43:14 -0800577tNFC_STATUS rw_t3t_send_to_lower (NFC_HDR *p_msg)
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800578{
Ruchi Kandoi512ee632017-01-03 13:59:10 -0800579 uint8_t *p;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800580
Ruchi Kandoi303fec12016-12-14 13:22:38 -0800581#if (RW_STATS_INCLUDED == TRUE)
Ruchi Kandoi512ee632017-01-03 13:59:10 -0800582 bool is_retry;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800583 /* Update stats */
Ruchi Kandoi4a179642017-01-04 10:04:48 -0800584 rw_main_update_tx_stats (p_msg->len,
585 ((rw_cb.cur_retry == 0) ? false : true));
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800586#endif /* RW_STATS_INCLUDED */
587
588 /* Set NFC-F SoD field (payload len + 1) */
589 p_msg->offset -= 1; /* Point to SoD field */
Ruchi Kandoi512ee632017-01-03 13:59:10 -0800590 p = (uint8_t *) (p_msg+1) + p_msg->offset;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800591 UINT8_TO_STREAM (p, (p_msg->len+1));
592 p_msg->len += 1; /* Increment len to include SoD */
593
594#if (BT_TRACE_PROTOCOL == TRUE)
Ruchi Kandoi4a179642017-01-04 10:04:48 -0800595 DispT3TagMessage (p_msg, false);
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800596#endif
597
598 return (NFC_SendData (NFC_RF_CONN_ID, p_msg));
599}
600
601/*****************************************************************************
602**
603** Function rw_t3t_get_cmd_buf
604**
605** Description Get a buffer for sending T3T messages
606**
Ruchi Kandoi0a736882017-01-09 15:43:14 -0800607** Returns NFC_HDR *
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800608**
609*****************************************************************************/
Ruchi Kandoi0a736882017-01-09 15:43:14 -0800610NFC_HDR *rw_t3t_get_cmd_buf (void)
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800611{
Ruchi Kandoi0a736882017-01-09 15:43:14 -0800612 NFC_HDR *p_cmd_buf;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800613
Ruchi Kandoi0a736882017-01-09 15:43:14 -0800614 if ((p_cmd_buf = (NFC_HDR *) GKI_getpoolbuf (NFC_RW_POOL_ID)) != NULL)
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800615 {
616 /* Reserve offset for NCI_DATA_HDR and NFC-F Sod (LEN) field */
617 p_cmd_buf->offset = NCI_MSG_OFFSET_SIZE + NCI_DATA_HDR_SIZE + 1;
618 p_cmd_buf->len = 0;
619 }
620
621 return (p_cmd_buf);
622}
623
624/*****************************************************************************
625**
626** Function rw_t3t_send_cmd
627**
628** Description Send command to tag, and start timer for response
629**
630** Returns tNFC_STATUS
631**
632*****************************************************************************/
Ruchi Kandoi0a736882017-01-09 15:43:14 -0800633tNFC_STATUS rw_t3t_send_cmd (tRW_T3T_CB *p_cb, uint8_t rw_t3t_cmd, NFC_HDR *p_cmd_buf, uint32_t timeout_ticks)
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800634{
635 tNFC_STATUS retval;
636
637 /* Indicate first attempt to send command, back up cmd buffer in case needed for retransmission */
638 rw_cb.cur_retry = 0;
Ruchi Kandoi0a736882017-01-09 15:43:14 -0800639 memcpy (p_cb->p_cur_cmd_buf, p_cmd_buf, sizeof (NFC_HDR) + p_cmd_buf->offset + p_cmd_buf->len);
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800640
641 p_cb->cur_cmd = rw_t3t_cmd;
Sherry Smith818b56e2014-05-14 16:46:32 -0700642 p_cb->cur_tout = timeout_ticks;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800643 p_cb->rw_state = RW_T3T_STATE_COMMAND_PENDING;
644
645 if ((retval = rw_t3t_send_to_lower (p_cmd_buf)) == NFC_STATUS_OK)
646 {
647 /* Start timer for waiting for response */
Sherry Smith818b56e2014-05-14 16:46:32 -0700648 nfc_start_quick_timer (&p_cb->timer, NFC_TTYPE_RW_T3T_RESPONSE, timeout_ticks);
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800649 }
650 else
651 {
652 /* Error sending */
653 p_cb->rw_state = RW_T3T_STATE_IDLE;
654 }
655
Sherry Smith818b56e2014-05-14 16:46:32 -0700656 RW_TRACE_DEBUG3 ("rw_t3t_send_cmd: cur_tout: %d, timeout_ticks: %d ret:%d",p_cb->cur_tout, timeout_ticks, retval);
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800657 return (retval);
658}
659
660/*****************************************************************************
661**
662** Function rw_t3t_send_update_ndef_attribute_cmd
663**
664** Description Send UPDATE command for Attribute Information
665**
666** Returns tNFC_STATUS
667**
668*****************************************************************************/
Ruchi Kandoi512ee632017-01-03 13:59:10 -0800669tNFC_STATUS rw_t3t_send_update_ndef_attribute_cmd (tRW_T3T_CB *p_cb, bool write_in_progress)
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800670{
671 tNFC_STATUS retval = NFC_STATUS_OK;
Ruchi Kandoi0a736882017-01-09 15:43:14 -0800672 NFC_HDR *p_cmd_buf;
Ruchi Kandoi512ee632017-01-03 13:59:10 -0800673 uint8_t *p_cmd_start, *p;
674 uint16_t checksum, i;
675 uint8_t write_f;
676 uint32_t ln;
677 uint8_t *p_ndef_attr_info_start;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800678
679 if ((p_cmd_buf = rw_t3t_get_cmd_buf ()) != NULL)
680 {
681 /* Construct T3T message */
Ruchi Kandoi512ee632017-01-03 13:59:10 -0800682 p = p_cmd_start = (uint8_t *) (p_cmd_buf+1) + p_cmd_buf->offset;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800683
684 /* Add UPDATE opcode to message */
685 UINT8_TO_STREAM (p, T3T_MSG_OPC_UPDATE_CMD);
686
687 /* Add IDm to message */
688 ARRAY_TO_STREAM (p, p_cb->peer_nfcid2, NCI_NFCID2_LEN);
689
690 /* Add Service code list */
691 UINT8_TO_STREAM (p, 1); /* Number of services (only 1 service: NDEF) */
692 UINT16_TO_STREAM (p, T3T_MSG_NDEF_SC_RW); /* Service code (little-endian format) */
693
694 /* Add number of blocks in this UPDATE command */
695 UINT8_TO_STREAM (p, 1); /* Number of blocks to write in this command */
696
697 /* Block List element: the NDEF attribute information block (block 0) */
698 UINT8_TO_STREAM (p, T3T_MSG_MASK_TWO_BYTE_BLOCK_DESC_FORMAT);
699 UINT8_TO_STREAM (p, 0);
700
701 /* Add payload (Attribute information block) */
702 p_ndef_attr_info_start = p; /* Save start of a NDEF attribute info block for checksum */
703 UINT8_TO_STREAM (p, T3T_MSG_NDEF_VERSION);
704 UINT8_TO_STREAM (p, p_cb->ndef_attrib.nbr);
705 UINT8_TO_STREAM (p, p_cb->ndef_attrib.nbw);
706 UINT16_TO_BE_STREAM (p, p_cb->ndef_attrib.nmaxb);
707 UINT32_TO_STREAM (p, 0);
708
709 /* If starting NDEF write: set WriteF=ON, and ln=current ndef length */
710 if (write_in_progress)
711 {
712 write_f = T3T_MSG_NDEF_WRITEF_ON;
713 ln = p_cb->ndef_attrib.ln;
714 }
715 /* If finishing NDEF write: set WriteF=OFF, and ln=new ndef len */
716 else
717 {
718 write_f = T3T_MSG_NDEF_WRITEF_OFF;
719 ln = p_cb->ndef_msg_len;
720 }
721 UINT8_TO_STREAM (p, write_f);
722 UINT8_TO_STREAM (p, p_cb->ndef_attrib.rwflag);
723 UINT8_TO_STREAM (p, (ln>>16) & 0xFF); /* High byte (of 3) of Ln */
724 UINT8_TO_STREAM (p, (ln>>8) & 0xFF); /* Middle byte (of 3) of Ln */
725 UINT8_TO_STREAM (p, (ln) & 0xFF); /* Low byte (of 3) of Ln */
726
727 /* Calculate and append Checksum */
728 checksum = 0;
729 for (i = 0; i < T3T_MSG_NDEF_ATTR_INFO_SIZE; i++)
730 {
731 checksum+=p_ndef_attr_info_start[i];
732 }
733 UINT16_TO_BE_STREAM (p, checksum);
734
735
736 /* Calculate length of message */
Ruchi Kandoi512ee632017-01-03 13:59:10 -0800737 p_cmd_buf->len = (uint16_t) (p - p_cmd_start);
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800738
739 /* Send the T3T message */
Sherry Smith818b56e2014-05-14 16:46:32 -0700740 retval = rw_t3t_send_cmd (p_cb, RW_T3T_CMD_UPDATE_NDEF, p_cmd_buf, rw_t3t_update_timeout(1));
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800741 }
742 else
743 {
744 retval = NFC_STATUS_NO_BUFFERS;
745 }
746
747 return (retval);
748}
749
750/*****************************************************************************
751**
752** Function rw_t3t_send_next_ndef_update_cmd
753**
754** Description Send next segment of NDEF message to update
755**
756** Returns tNFC_STATUS
757**
758*****************************************************************************/
759tNFC_STATUS rw_t3t_send_next_ndef_update_cmd (tRW_T3T_CB *p_cb)
760{
761 tNFC_STATUS retval = NFC_STATUS_OK;
Ruchi Kandoi512ee632017-01-03 13:59:10 -0800762 uint16_t block_id;
763 uint16_t first_block_to_write;
764 uint16_t ndef_blocks_to_write, ndef_blocks_remaining;
765 uint32_t ndef_bytes_remaining, ndef_padding = 0;
766 uint8_t flags = 0;
767 uint8_t *p_cur_ndef_src_offset;
Ruchi Kandoi0a736882017-01-09 15:43:14 -0800768 NFC_HDR *p_cmd_buf;
Ruchi Kandoi512ee632017-01-03 13:59:10 -0800769 uint8_t *p_cmd_start, *p;
770 uint8_t blocks_per_update;
771 uint32_t timeout;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800772
773 if ((p_cmd_buf = rw_t3t_get_cmd_buf ()) != NULL)
774 {
775 /* Construct T3T message */
Ruchi Kandoi512ee632017-01-03 13:59:10 -0800776 p = p_cmd_start = (uint8_t *) (p_cmd_buf + 1) + p_cmd_buf->offset;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800777
778 /* Calculate number of ndef bytes remaining to write */
779 ndef_bytes_remaining = p_cb->ndef_msg_len - p_cb->ndef_msg_bytes_sent;
780
781 /* Calculate number of blocks remaining to write */
Ruchi Kandoi512ee632017-01-03 13:59:10 -0800782 ndef_blocks_remaining = (uint16_t) ((ndef_bytes_remaining+15) >> 4); /* ndef blocks remaining (rounded upward) */
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800783
784 /* Calculate first NDEF block ID for this UPDATE command */
Ruchi Kandoi512ee632017-01-03 13:59:10 -0800785 first_block_to_write = (uint16_t) ((p_cb->ndef_msg_bytes_sent >> 4) + 1);
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800786
787 /* Calculate max number of blocks per write. */
788 if ((first_block_to_write + RW_T3T_MAX_NDEF_BLOCKS_PER_UPDATE_1_BYTE_FORMAT) < 0x100)
789 {
790 /* All block-numbers are < 0x100 (i.e. can be specified using one-byte format) */
791 blocks_per_update = RW_T3T_MAX_NDEF_BLOCKS_PER_UPDATE_1_BYTE_FORMAT;
792 }
793 else
794 {
795 /* Block-numbers are >= 0x100 (i.e. need to be specified using two-byte format) */
796 blocks_per_update = RW_T3T_MAX_NDEF_BLOCKS_PER_UPDATE_2_BYTE_FORMAT;
797 }
798
799 /* Check if blocks_per_update is bigger than what peer allows */
800 if (blocks_per_update > p_cb->ndef_attrib.nbw)
801 blocks_per_update = p_cb->ndef_attrib.nbw;
802
803 /* Check if remaining blocks can fit into one UPDATE command */
804 if (ndef_blocks_remaining <= blocks_per_update)
805 {
806 /* remaining blocks can fit into one UPDATE command */
807 ndef_blocks_to_write = ndef_blocks_remaining;
808 }
809 else
810 {
811 /* Remaining blocks cannot fit into one UPDATE command */
812 ndef_blocks_to_write = blocks_per_update;
813 }
814
815
816 /* Write to command header for UPDATE */
817
818 /* Add UPDATE opcode to message */
819 UINT8_TO_STREAM (p, T3T_MSG_OPC_UPDATE_CMD);
820
821 /* Add IDm to message */
822 ARRAY_TO_STREAM (p, p_cb->peer_nfcid2, NCI_NFCID2_LEN);
823
824 /* Add Service code list */
825 UINT8_TO_STREAM (p, 1); /* Number of services (only 1 service: NDEF) */
826 UINT16_TO_STREAM (p, T3T_MSG_NDEF_SC_RW); /* Service code (little-endian format) */
827
828
829 /* Add number of blocks in this UPDATE command */
830 UINT8_TO_STREAM (p, ndef_blocks_to_write); /* Number of blocks to write in this command */
Sherry Smith818b56e2014-05-14 16:46:32 -0700831 timeout = rw_t3t_update_timeout(ndef_blocks_to_write);
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800832
833 for (block_id = first_block_to_write; block_id < (first_block_to_write + ndef_blocks_to_write); block_id++)
834 {
835 if (block_id<256)
836 {
837 /* Block IDs 0-255 can be specified in '2-byte' format: byte0=0, byte1=blocknumber */
838 UINT8_TO_STREAM (p, T3T_MSG_MASK_TWO_BYTE_BLOCK_DESC_FORMAT); /* byte0: len=1; access-mode=0; service code list order=0 */
839 UINT8_TO_STREAM (p, block_id); /* byte1: block number */
840 }
841 else
842 {
843 /* Block IDs 256+ must be specified in '3-byte' format: byte0=80h, followed by blocknumber */
844 UINT8_TO_STREAM (p, 0x00); /* byte0: len=0; access-mode=0; service code list order=0 */
845 UINT16_TO_STREAM (p, block_id); /* byte1-2: block number in little-endian format */
846 }
847
848 }
849
850 /* Add NDEF payload */
851
852 /* If this sending last block of NDEF, check if padding is needed to make payload a multiple of 16 bytes */
853 if (ndef_blocks_to_write == ndef_blocks_remaining)
854 {
855 ndef_padding = (16 - (ndef_bytes_remaining & 0x0F)) & 0x0F;
856 if (ndef_padding)
857 {
858 flags |= RW_T3T_FL_PADDING;
859 ndef_blocks_to_write--; /* handle the last block separately if it needs padding */
860 }
861 }
862
863 /* Add NDEF payload to the message */
864 p_cur_ndef_src_offset = &p_cb->ndef_msg[p_cb->ndef_msg_bytes_sent];
865
866
867 ARRAY_TO_STREAM (p, p_cur_ndef_src_offset, (ndef_blocks_to_write * 16));
Ruchi Kandoi512ee632017-01-03 13:59:10 -0800868 p_cb->ndef_msg_bytes_sent += ((uint32_t) ndef_blocks_to_write * 16);
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800869
870 if (flags & RW_T3T_FL_PADDING)
871 {
872 /* Add last of the NDEF message */
873 p_cur_ndef_src_offset = &p_cb->ndef_msg[p_cb->ndef_msg_bytes_sent];
874 ARRAY_TO_STREAM (p, p_cur_ndef_src_offset, (int) (16-ndef_padding));
875 p_cb->ndef_msg_bytes_sent += (16-ndef_padding);
876
877 /* Add padding */
878 memset (p, 0, ndef_padding);
879 p+=ndef_padding;
880 }
881
882 /* Calculate length of message */
Ruchi Kandoi512ee632017-01-03 13:59:10 -0800883 p_cmd_buf->len = (uint16_t) (p - p_cmd_start);
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800884
885 /* Send the T3T message */
886 retval = rw_t3t_send_cmd (p_cb, RW_T3T_CMD_UPDATE_NDEF, p_cmd_buf, timeout);
887 }
888 else
889 {
890 retval = NFC_STATUS_NO_BUFFERS;
891 }
892
893 return (retval);
894}
895
896
897
898/*****************************************************************************
899**
900** Function rw_t3t_send_next_ndef_check_cmd
901**
902** Description Send command for reading next segment of NDEF message
903**
904** Returns tNFC_STATUS
905**
906*****************************************************************************/
907tNFC_STATUS rw_t3t_send_next_ndef_check_cmd (tRW_T3T_CB *p_cb)
908{
909 tNFC_STATUS retval = NFC_STATUS_OK;
Ruchi Kandoi512ee632017-01-03 13:59:10 -0800910 uint16_t block_id;
911 uint16_t ndef_blocks_remaining, first_block_to_read, cur_blocks_to_read;
912 uint32_t ndef_bytes_remaining;
Ruchi Kandoi0a736882017-01-09 15:43:14 -0800913 NFC_HDR *p_cmd_buf;
Ruchi Kandoi512ee632017-01-03 13:59:10 -0800914 uint8_t *p_cmd_start, *p;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800915
916 if ((p_cmd_buf = rw_t3t_get_cmd_buf ()) != NULL)
917 {
918 /* Construct T3T message */
Ruchi Kandoi512ee632017-01-03 13:59:10 -0800919 p = p_cmd_start = (uint8_t *) (p_cmd_buf+1) + p_cmd_buf->offset;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800920
921 /* Calculate number of ndef bytes remaining to read */
922 ndef_bytes_remaining = p_cb->ndef_attrib.ln - p_cb->ndef_rx_offset;
923
924 /* Calculate number of blocks remaining to read */
Ruchi Kandoi512ee632017-01-03 13:59:10 -0800925 ndef_blocks_remaining = (uint16_t) ((ndef_bytes_remaining+15) >> 4); /* ndef blocks remaining (rounded upward) */
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800926
927 /* Calculate first NDEF block ID */
Ruchi Kandoi512ee632017-01-03 13:59:10 -0800928 first_block_to_read = (uint16_t) ((p_cb->ndef_rx_offset >> 4) + 1);
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800929
930 /* Check if remaining blocks can fit into one CHECK command */
931 if (ndef_blocks_remaining <= p_cb->ndef_attrib.nbr)
932 {
933 /* remaining blocks can fit into one CHECK command */
934 cur_blocks_to_read = ndef_blocks_remaining;
935 p_cb->ndef_rx_readlen = ndef_bytes_remaining;
936 p_cb->flags |= RW_T3T_FL_IS_FINAL_NDEF_SEGMENT;
937 }
938 else
939 {
940 /* Remaining blocks cannot fit into one CHECK command */
941 cur_blocks_to_read = p_cb->ndef_attrib.nbr; /* Read maximum number of blocks allowed by the peer */
Ruchi Kandoi512ee632017-01-03 13:59:10 -0800942 p_cb->ndef_rx_readlen = ((uint32_t) p_cb->ndef_attrib.nbr * 16);
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800943 }
944
945 RW_TRACE_DEBUG3 ("rw_t3t_send_next_ndef_check_cmd: bytes_remaining: %i, cur_blocks_to_read: %i, is_final: %i",
946 ndef_bytes_remaining, cur_blocks_to_read, (p_cb->flags & RW_T3T_FL_IS_FINAL_NDEF_SEGMENT));
947
Sherry Smith818b56e2014-05-14 16:46:32 -0700948 /* Add CHECK opcode to message */
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800949 UINT8_TO_STREAM (p, T3T_MSG_OPC_CHECK_CMD);
950
951 /* Add IDm to message */
952 ARRAY_TO_STREAM (p, p_cb->peer_nfcid2, NCI_NFCID2_LEN);
953
954 /* Add Service code list */
955 UINT8_TO_STREAM (p, 1); /* Number of services (only 1 service: NDEF) */
956
957 /* Service code (little-endian format) . If NDEF is read-only, then use T3T_MSG_NDEF_SC_RO, otherwise use T3T_MSG_NDEF_SC_RW */
958 if (p_cb->ndef_attrib.rwflag == T3T_MSG_NDEF_RWFLAG_RO)
959 {
960 UINT16_TO_STREAM (p, T3T_MSG_NDEF_SC_RO);
961 }
962 else
963 {
964 UINT16_TO_STREAM (p, T3T_MSG_NDEF_SC_RW);
965 }
966
Sherry Smith818b56e2014-05-14 16:46:32 -0700967 /* Add number of blocks in this CHECK command */
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800968 UINT8_TO_STREAM (p, cur_blocks_to_read); /* Number of blocks to check in this command */
969
970 for (block_id = first_block_to_read; block_id < (first_block_to_read + cur_blocks_to_read); block_id++)
971 {
972 if (block_id<256)
973 {
974 /* Block IDs 0-255 can be specified in '2-byte' format: byte0=0, byte1=blocknumber */
975 UINT8_TO_STREAM (p, T3T_MSG_MASK_TWO_BYTE_BLOCK_DESC_FORMAT); /* byte1: len=0; access-mode=0; service code list order=0 */
976 UINT8_TO_STREAM (p, block_id); /* byte1: block number */
977 }
978 else
979 {
980 /* Block IDs 256+ must be specified in '3-byte' format: byte0=80h, followed by blocknumber */
981 UINT8_TO_STREAM (p, 0x00); /* byte0: len=1; access-mode=0; service code list order=0 */
982 UINT16_TO_STREAM (p, block_id); /* byte1-2: block number in little-endian format */
983 }
984
985 }
986
987 /* Calculate length of message */
Ruchi Kandoi512ee632017-01-03 13:59:10 -0800988 p_cmd_buf->len = (uint16_t) (p - p_cmd_start);
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800989
990 /* Send the T3T message */
Sherry Smith818b56e2014-05-14 16:46:32 -0700991 retval = rw_t3t_send_cmd (p_cb, RW_T3T_CMD_CHECK_NDEF, p_cmd_buf, rw_t3t_check_timeout (cur_blocks_to_read));
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800992 }
993 else
994 {
995 retval = NFC_STATUS_NO_BUFFERS;
996 }
997
998 return(retval);
999}
1000
1001
1002/*****************************************************************************
1003**
1004** Function rw_t3t_message_set_block_list
1005**
1006** Description Add block list to T3T message
1007**
1008** Returns Number of bytes added to message
1009**
1010*****************************************************************************/
Ruchi Kandoi512ee632017-01-03 13:59:10 -08001011void rw_t3t_message_set_block_list (tRW_T3T_CB *p_cb, uint8_t **p, uint8_t num_blocks, tT3T_BLOCK_DESC *p_t3t_blocks)
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001012{
Ruchi Kandoi512ee632017-01-03 13:59:10 -08001013 uint16_t i, cur_service_code;
1014 uint8_t service_code_idx, num_services = 0;
1015 uint8_t *p_msg_num_services;
1016 uint16_t service_list[T3T_MSG_SERVICE_LIST_MAX];
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001017
1018 /* Add CHECK or UPDATE opcode to message */
1019 UINT8_TO_STREAM ((*p), ((p_cb->cur_cmd == RW_T3T_CMD_CHECK) ? T3T_MSG_OPC_CHECK_CMD:T3T_MSG_OPC_UPDATE_CMD));
1020
1021 /* Add IDm to message */
1022 ARRAY_TO_STREAM ((*p), p_cb->peer_nfcid2, NCI_NFCID2_LEN);
1023
1024 /* Skip over Number of Services field */
1025 p_msg_num_services = (*p); /* pointer to Number of Services offset */
1026 (*p)++;
1027
1028 /* Count number of different services are specified in the list, and add services to Service Code list */
1029 for (i = 0; i < num_blocks; i++)
1030 {
1031 cur_service_code = p_t3t_blocks[i].service_code;
1032
1033 /* Check if current service_code is already in the service_list */
1034 for (service_code_idx=0; service_code_idx<num_services; service_code_idx++)
1035 {
1036 if (service_list[service_code_idx] == cur_service_code)
1037 break;
1038 }
1039
1040 if (service_code_idx == num_services)
1041 {
1042 /* Service not in the list yet. Add it. */
1043 service_list[service_code_idx] = cur_service_code;
1044 num_services++;
1045
1046 /* Add service code to T3T message */
1047 UINT16_TO_STREAM ((*p), cur_service_code);
1048 }
1049 }
1050
1051 /* Add 'Number of Sservices' to the message */
1052 *p_msg_num_services = num_services;
1053
1054 /* Add 'number of blocks' to the message */
1055 UINT8_TO_STREAM ((*p), num_blocks);
1056
1057 /* Add block descriptors */
1058 for (i = 0; i < num_blocks; i++)
1059 {
1060 cur_service_code = p_t3t_blocks[i].service_code;
1061
1062 /* Check if current service_code is already in the service_list */
1063 for (service_code_idx=0; service_code_idx<num_services; service_code_idx++)
1064 {
1065 if (service_list[service_code_idx] == cur_service_code)
1066 break;
1067 }
1068
1069 /* Add decriptor to T3T message */
1070 if (p_t3t_blocks[i].block_number > 0xFF)
1071 {
1072 UINT8_TO_STREAM ((*p), service_code_idx);
1073 UINT16_TO_STREAM ((*p), p_t3t_blocks[i].block_number);
1074 }
1075 else
1076 {
1077 service_code_idx |= T3T_MSG_MASK_TWO_BYTE_BLOCK_DESC_FORMAT;
1078 UINT8_TO_STREAM ((*p), service_code_idx);
1079 UINT8_TO_STREAM ((*p), p_t3t_blocks[i].block_number);
1080 }
1081 }
1082}
1083
1084/*****************************************************************************
1085**
1086** Function rw_t3t_send_check_cmd
1087**
1088** Description Send CHECK command
1089**
1090** Returns tNFC_STATUS
1091**
1092*****************************************************************************/
Ruchi Kandoi512ee632017-01-03 13:59:10 -08001093tNFC_STATUS rw_t3t_send_check_cmd (tRW_T3T_CB *p_cb, uint8_t num_blocks, tT3T_BLOCK_DESC *p_t3t_blocks)
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001094{
Ruchi Kandoi0a736882017-01-09 15:43:14 -08001095 NFC_HDR *p_cmd_buf;
Ruchi Kandoi512ee632017-01-03 13:59:10 -08001096 uint8_t *p, *p_cmd_start;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001097 tNFC_STATUS retval = NFC_STATUS_OK;
1098
1099 p_cb->cur_cmd = RW_T3T_CMD_CHECK;
1100 if ((p_cmd_buf = rw_t3t_get_cmd_buf ()) != NULL)
1101 {
1102 /* Construct T3T message */
Ruchi Kandoi512ee632017-01-03 13:59:10 -08001103 p = p_cmd_start = (uint8_t *) (p_cmd_buf+1) + p_cmd_buf->offset;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001104 rw_t3t_message_set_block_list (p_cb, &p, num_blocks, p_t3t_blocks);
1105
1106 /* Calculate length of message */
Ruchi Kandoi512ee632017-01-03 13:59:10 -08001107 p_cmd_buf->len = (uint16_t) (p - p_cmd_start);
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001108
1109 /* Send the T3T message */
Sherry Smith818b56e2014-05-14 16:46:32 -07001110 retval = rw_t3t_send_cmd (p_cb, RW_T3T_CMD_CHECK, p_cmd_buf, rw_t3t_check_timeout(num_blocks));
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001111 }
1112 else
1113 {
1114 retval = NFC_STATUS_NO_BUFFERS;
1115 }
1116
1117 return(retval);
1118}
1119
1120/*****************************************************************************
1121**
1122** Function rw_t3t_send_update_cmd
1123**
1124** Description Send UPDATE command
1125**
1126** Returns tNFC_STATUS
1127**
1128*****************************************************************************/
Ruchi Kandoi512ee632017-01-03 13:59:10 -08001129tNFC_STATUS rw_t3t_send_update_cmd (tRW_T3T_CB *p_cb, uint8_t num_blocks, tT3T_BLOCK_DESC *p_t3t_blocks, uint8_t *p_data)
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001130{
Ruchi Kandoi0a736882017-01-09 15:43:14 -08001131 NFC_HDR *p_cmd_buf;
Ruchi Kandoi512ee632017-01-03 13:59:10 -08001132 uint8_t *p, *p_cmd_start;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001133 tNFC_STATUS retval = NFC_STATUS_OK;
1134
1135 p_cb->cur_cmd = RW_T3T_CMD_UPDATE;
1136 if ((p_cmd_buf = rw_t3t_get_cmd_buf ()) != NULL)
1137 {
1138 /* Construct T3T message */
Ruchi Kandoi512ee632017-01-03 13:59:10 -08001139 p = p_cmd_start = (uint8_t *) (p_cmd_buf+1) + p_cmd_buf->offset;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001140 rw_t3t_message_set_block_list (p_cb, &p, num_blocks, p_t3t_blocks);
1141
1142 /* Add data blocks to the message */
1143 ARRAY_TO_STREAM (p, p_data, num_blocks*16);
1144
1145 /* Calculate length of message */
Ruchi Kandoi512ee632017-01-03 13:59:10 -08001146 p_cmd_buf->len = (uint16_t) (p - p_cmd_start);
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001147
1148 /* Send the T3T message */
Sherry Smith818b56e2014-05-14 16:46:32 -07001149 retval = rw_t3t_send_cmd (p_cb, RW_T3T_CMD_UPDATE, p_cmd_buf, rw_t3t_update_timeout(num_blocks));
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001150 }
1151 else
1152 {
1153 retval = NFC_STATUS_NO_BUFFERS;
1154 }
1155
1156 return(retval);
1157}
1158
1159/*****************************************************************************
1160**
Martijn Coenen5c65c3a2013-03-27 13:23:36 -07001161** Function rw_t3t_check_mc_block
1162**
1163** Description Send command to check Memory Configuration Block
1164**
1165** Returns tNFC_STATUS
1166**
1167*****************************************************************************/
1168tNFC_STATUS rw_t3t_check_mc_block (tRW_T3T_CB *p_cb)
1169{
Ruchi Kandoi0a736882017-01-09 15:43:14 -08001170 NFC_HDR *p_cmd_buf;
Ruchi Kandoi512ee632017-01-03 13:59:10 -08001171 uint8_t *p, *p_cmd_start;
Martijn Coenen5c65c3a2013-03-27 13:23:36 -07001172
1173 /* Read Memory Configuration block */
1174 if ((p_cmd_buf = rw_t3t_get_cmd_buf ()) != NULL)
1175 {
1176 /* Construct T3T message */
Ruchi Kandoi512ee632017-01-03 13:59:10 -08001177 p = p_cmd_start = (uint8_t *) (p_cmd_buf+1) + p_cmd_buf->offset;
Martijn Coenen5c65c3a2013-03-27 13:23:36 -07001178
1179 /* Add CHECK opcode to message */
1180 UINT8_TO_STREAM (p, T3T_MSG_OPC_CHECK_CMD);
1181
1182 /* Add IDm to message */
1183 ARRAY_TO_STREAM (p, p_cb->peer_nfcid2, NCI_NFCID2_LEN);
1184
1185 /* Add Service code list */
1186 UINT8_TO_STREAM (p, 1); /* Number of services (only 1 service: NDEF) */
1187 UINT16_TO_STREAM (p, T3T_MSG_NDEF_SC_RO); /* Service code (little-endian format) */
1188
1189 /* Number of blocks */
1190 UINT8_TO_STREAM (p, 1); /* Number of blocks (only 1 block: Memory Configuration Information ) */
1191
1192 /* Block List element: the Memory Configuration block (block 0x88) */
1193 UINT8_TO_STREAM (p, T3T_MSG_MASK_TWO_BYTE_BLOCK_DESC_FORMAT);
1194 UINT8_TO_STREAM (p, T3T_MSG_FELICALITE_BLOCK_ID_MC);
1195
1196 /* Calculate length of message */
Ruchi Kandoi512ee632017-01-03 13:59:10 -08001197 p_cmd_buf->len = (uint16_t) (p - p_cmd_start);
Martijn Coenen5c65c3a2013-03-27 13:23:36 -07001198
1199 /* Send the T3T message */
Sherry Smith818b56e2014-05-14 16:46:32 -07001200 return rw_t3t_send_cmd (p_cb, p_cb->cur_cmd, p_cmd_buf, rw_t3t_check_timeout(1));
Martijn Coenen5c65c3a2013-03-27 13:23:36 -07001201 }
1202 else
1203 {
1204 RW_TRACE_ERROR0 ("Unable to allocate buffer to read MC block");
1205 return (NFC_STATUS_NO_BUFFERS);
1206 }
1207}
1208
1209/*****************************************************************************
1210**
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001211** Function rw_t3t_send_raw_frame
1212**
1213** Description Send raw frame
1214**
1215** Returns tNFC_STATUS
1216**
1217*****************************************************************************/
Ruchi Kandoi512ee632017-01-03 13:59:10 -08001218tNFC_STATUS rw_t3t_send_raw_frame (tRW_T3T_CB *p_cb, uint16_t len, uint8_t *p_data)
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001219{
Ruchi Kandoi0a736882017-01-09 15:43:14 -08001220 NFC_HDR *p_cmd_buf;
Ruchi Kandoi512ee632017-01-03 13:59:10 -08001221 uint8_t *p;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001222 tNFC_STATUS retval = NFC_STATUS_OK;
1223
1224 if ((p_cmd_buf = rw_t3t_get_cmd_buf ()) != NULL)
1225 {
1226 /* Construct T3T message */
Ruchi Kandoi512ee632017-01-03 13:59:10 -08001227 p = (uint8_t *) (p_cmd_buf+1) + p_cmd_buf->offset;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001228
1229 /* Add data blocks to the message */
1230 ARRAY_TO_STREAM (p, p_data, len);
1231
1232 /* Calculate length of message */
1233 p_cmd_buf->len = len;
1234
1235 /* Send the T3T message */
1236 retval = rw_t3t_send_cmd (p_cb, RW_T3T_CMD_SEND_RAW_FRAME, p_cmd_buf, RW_T3T_RAW_FRAME_CMD_TIMEOUT_TICKS);
1237 }
1238 else
1239 {
1240 retval = NFC_STATUS_NO_BUFFERS;
1241 }
1242
1243 return (retval);
1244}
1245
1246
1247/*****************************************************************************
1248** TAG RESPONSE HANDLERS
1249*****************************************************************************/
1250
1251
1252/*****************************************************************************
1253**
1254** Function rw_t3t_act_handle_ndef_detect_rsp
1255**
1256** Description Handle response to NDEF detection
1257**
1258** Returns Nothing
1259**
1260*****************************************************************************/
Ruchi Kandoi0a736882017-01-09 15:43:14 -08001261void rw_t3t_act_handle_ndef_detect_rsp (tRW_T3T_CB *p_cb, NFC_HDR *p_msg_rsp)
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001262{
Ruchi Kandoi512ee632017-01-03 13:59:10 -08001263 uint8_t *p;
1264 uint32_t temp;
1265 uint8_t i;
1266 uint16_t checksum_calc, checksum_rx;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001267 tRW_DETECT_NDEF_DATA evt_data;
Ruchi Kandoi512ee632017-01-03 13:59:10 -08001268 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 -08001269
1270 evt_data.status = NFC_STATUS_FAILED;
1271 evt_data.flags = RW_NDEF_FL_UNKNOWN;
1272
1273 /* Check if response code is CHECK resp (for reading NDEF attribute block) */
1274 if (p_t3t_rsp[T3T_MSG_RSP_OFFSET_RSPCODE] != T3T_MSG_OPC_CHECK_RSP)
1275 {
1276 RW_TRACE_ERROR2 ("Response error: expecting rsp_code %02X, but got %02X", T3T_MSG_OPC_CHECK_RSP, p_t3t_rsp[T3T_MSG_RSP_OFFSET_RSPCODE]);
1277 evt_data.status = NFC_STATUS_FAILED;
1278 }
1279 /* Validate status code and NFCID2 response from tag */
1280 else if ( (p_t3t_rsp[T3T_MSG_RSP_OFFSET_STATUS1] != T3T_MSG_RSP_STATUS_OK) /* verify response status code */
1281 ||(memcmp (p_cb->peer_nfcid2, &p_t3t_rsp[T3T_MSG_RSP_OFFSET_IDM], NCI_NFCID2_LEN) != 0) ) /* verify response IDm */
1282 {
1283 evt_data.status = NFC_STATUS_FAILED;
1284 }
1285 else
1286 {
1287 /* Get checksum from received ndef attribute msg */
1288 p = &p_t3t_rsp[T3T_MSG_RSP_OFFSET_CHECK_DATA+T3T_MSG_NDEF_ATTR_INFO_SIZE];
1289 BE_STREAM_TO_UINT16 (checksum_rx, p);
1290
1291 /* Calculate checksum - move check for checsum to beginning */
1292 checksum_calc = 0;
1293 p = &p_t3t_rsp[T3T_MSG_RSP_OFFSET_CHECK_DATA];
1294 for (i = 0; i < T3T_MSG_NDEF_ATTR_INFO_SIZE; i++)
1295 {
1296 checksum_calc+=p[i];
1297 }
1298
1299 /* Validate checksum */
1300 if (checksum_calc != checksum_rx)
1301 {
1302 p_cb->ndef_attrib.status = NFC_STATUS_FAILED; /* only ok or failed passed to the app. can be boolean*/
1303
1304 RW_TRACE_ERROR0 ("RW_T3tDetectNDEF checksum failed");
1305 }
1306 else
1307 {
1308 p_cb->ndef_attrib.status = NFC_STATUS_OK;
1309
1310 /* Validate version number */
1311 STREAM_TO_UINT8 (p_cb->ndef_attrib.version, p);
1312
1313 if (T3T_GET_MAJOR_VERSION (T3T_MSG_NDEF_VERSION) < T3T_GET_MAJOR_VERSION (p_cb->ndef_attrib.version))
1314 {
1315 /* Remote tag's MajorVer is newer than our's. Reject NDEF as per T3TOP RQ_T3T_NDA_024 */
1316 RW_TRACE_ERROR2 ("RW_T3tDetectNDEF: incompatible NDEF version. Local=0x%02x, Remote=0x%02x", T3T_MSG_NDEF_VERSION, p_cb->ndef_attrib.version);
1317 p_cb->ndef_attrib.status = NFC_STATUS_FAILED;
1318 evt_data.status = NFC_STATUS_BAD_RESP;
1319 }
1320 else
1321 {
1322 /* Remote tag's MajorVer is equal or older than our's. NDEF is compatible with our version. */
1323
1324 /* Update NDEF info */
1325 STREAM_TO_UINT8 (p_cb->ndef_attrib.nbr, p); /* NBr: number of blocks that can be read using one Check command */
1326 STREAM_TO_UINT8 (p_cb->ndef_attrib.nbw, p); /* Nbw: number of blocks that can be written using one Update command */
1327 BE_STREAM_TO_UINT16 (p_cb->ndef_attrib.nmaxb, p); /* Nmaxb: maximum number of blocks available for NDEF data */
1328 BE_STREAM_TO_UINT32 (temp, p);
1329 STREAM_TO_UINT8 (p_cb->ndef_attrib.writef, p); /* WriteFlag: 00h if writing data finished; 0Fh if writing data in progress */
1330 STREAM_TO_UINT8 (p_cb->ndef_attrib.rwflag, p); /* RWFlag: 00h NDEF is read-only; 01h if read/write available */
1331
1332 /* Get length (3-byte, big-endian) */
1333 STREAM_TO_UINT8 (temp, p); /* Ln: high-byte */
1334 BE_STREAM_TO_UINT16 (p_cb->ndef_attrib.ln, p); /* Ln: lo-word */
1335 p_cb->ndef_attrib.ln += (temp << 16);
1336
1337
1338 RW_TRACE_DEBUG1 ("Detected NDEF Ver: 0x%02x", p_cb->ndef_attrib.version);
1339 RW_TRACE_DEBUG6 ("Detected NDEF Attributes: Nbr=%i, Nbw=%i, Nmaxb=%i, WriteF=%i, RWFlag=%i, Ln=%i",
1340 p_cb->ndef_attrib.nbr,
1341 p_cb->ndef_attrib.nbw,
1342 p_cb->ndef_attrib.nmaxb,
1343 p_cb->ndef_attrib.writef,
1344 p_cb->ndef_attrib.rwflag,
1345 p_cb->ndef_attrib.ln);
1346
1347 /* Set data for RW_T3T_NDEF_DETECT_EVT */
1348 evt_data.status = p_cb->ndef_attrib.status;
1349 evt_data.cur_size = p_cb->ndef_attrib.ln;
Ruchi Kandoi512ee632017-01-03 13:59:10 -08001350 evt_data.max_size = (uint32_t) p_cb->ndef_attrib.nmaxb * 16;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001351 evt_data.protocol = NFC_PROTOCOL_T3T;
1352 evt_data.flags = (RW_NDEF_FL_SUPPORTED | RW_NDEF_FL_FORMATED);
1353 if (p_cb->ndef_attrib.rwflag == T3T_MSG_NDEF_RWFLAG_RO)
1354 evt_data.flags |= RW_NDEF_FL_READ_ONLY;
1355 }
1356 }
1357 }
1358
1359 RW_TRACE_DEBUG1 ("RW_T3tDetectNDEF response: %i", evt_data.status);
1360
1361 p_cb->rw_state = RW_T3T_STATE_IDLE;
Evan Chua24be4f2013-11-13 15:30:16 -05001362 rw_t3t_update_ndef_flag (&evt_data.flags);
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001363 /* Notify app of NDEF detection result */
1364 (*(rw_cb.p_cback)) (RW_T3T_NDEF_DETECT_EVT, (tRW_DATA *) &evt_data);
1365
1366 GKI_freebuf (p_msg_rsp);
1367}
1368
1369
1370/*****************************************************************************
1371**
1372** Function rw_t3t_act_handle_check_rsp
1373**
1374** Description Handle response to CHECK command
1375**
1376** Returns Nothing
1377**
1378*****************************************************************************/
Ruchi Kandoi0a736882017-01-09 15:43:14 -08001379void rw_t3t_act_handle_check_rsp (tRW_T3T_CB *p_cb, NFC_HDR *p_msg_rsp)
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001380{
Ruchi Kandoi512ee632017-01-03 13:59:10 -08001381 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 -08001382 tRW_READ_DATA evt_data;
1383 tNFC_STATUS nfc_status = NFC_STATUS_OK;
1384
1385 /* Validate response from tag */
1386 if ( (p_t3t_rsp[T3T_MSG_RSP_OFFSET_STATUS1] != T3T_MSG_RSP_STATUS_OK) /* verify response status code */
1387 ||(memcmp (p_cb->peer_nfcid2, &p_t3t_rsp[T3T_MSG_RSP_OFFSET_IDM], NCI_NFCID2_LEN) != 0) ) /* verify response IDm */
1388 {
1389 nfc_status = NFC_STATUS_FAILED;
1390 GKI_freebuf (p_msg_rsp);
1391 }
1392 else if (p_t3t_rsp[T3T_MSG_RSP_OFFSET_RSPCODE] != T3T_MSG_OPC_CHECK_RSP)
1393 {
1394 RW_TRACE_ERROR2 ("Response error: expecting rsp_code %02X, but got %02X", T3T_MSG_OPC_CHECK_RSP, p_t3t_rsp[T3T_MSG_RSP_OFFSET_RSPCODE]);
1395 nfc_status = NFC_STATUS_FAILED;
1396 GKI_freebuf (p_msg_rsp);
1397 }
1398 else
1399 {
1400 /* Copy incoming data into buffer */
1401 p_msg_rsp->offset += T3T_MSG_RSP_OFFSET_CHECK_DATA; /* Skip over t3t header */
1402 p_msg_rsp->len -= T3T_MSG_RSP_OFFSET_CHECK_DATA;
1403 evt_data.status = NFC_STATUS_OK;
1404 evt_data.p_data = p_msg_rsp;
1405 (*(rw_cb.p_cback)) (RW_T3T_CHECK_EVT, (tRW_DATA *) &evt_data);
1406 }
1407
1408
1409 p_cb->rw_state = RW_T3T_STATE_IDLE;
1410
1411 (*(rw_cb.p_cback)) (RW_T3T_CHECK_CPLT_EVT, (tRW_DATA *) &nfc_status);
1412}
1413
1414/*****************************************************************************
1415**
1416** Function rw_t3t_act_handle_update_rsp
1417**
1418** Description Handle response to UPDATE command
1419**
1420** Returns Nothing
1421**
1422*****************************************************************************/
Ruchi Kandoi0a736882017-01-09 15:43:14 -08001423void rw_t3t_act_handle_update_rsp (tRW_T3T_CB *p_cb, NFC_HDR *p_msg_rsp)
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001424{
Ruchi Kandoi512ee632017-01-03 13:59:10 -08001425 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 -08001426 tRW_READ_DATA evt_data;
1427
1428 /* Validate response from tag */
1429 if ( (p_t3t_rsp[T3T_MSG_RSP_OFFSET_STATUS1] != T3T_MSG_RSP_STATUS_OK) /* verify response status code */
1430 ||(memcmp (p_cb->peer_nfcid2, &p_t3t_rsp[T3T_MSG_RSP_OFFSET_IDM], NCI_NFCID2_LEN) != 0) ) /* verify response IDm */
1431 {
1432 evt_data.status = NFC_STATUS_FAILED;
1433 }
1434 else if (p_t3t_rsp[T3T_MSG_RSP_OFFSET_RSPCODE] != T3T_MSG_OPC_UPDATE_RSP)
1435 {
1436 RW_TRACE_ERROR2 ("Response error: expecting rsp_code %02X, but got %02X", T3T_MSG_OPC_UPDATE_RSP, p_t3t_rsp[T3T_MSG_RSP_OFFSET_RSPCODE]);
1437 evt_data.status = NFC_STATUS_FAILED;
1438 }
1439 else
1440 {
1441 /* Copy incoming data into buffer */
1442 evt_data.status = NFC_STATUS_OK;
1443 }
1444
1445 p_cb->rw_state = RW_T3T_STATE_IDLE;
1446
1447 (*(rw_cb.p_cback)) (RW_T3T_UPDATE_CPLT_EVT, (tRW_DATA *)&evt_data);
1448
1449 GKI_freebuf (p_msg_rsp);
1450}
1451
1452/*****************************************************************************
1453**
1454** Function rw_t3t_act_handle_raw_senddata_rsp
1455**
1456** Description Handle response to NDEF detection
1457**
1458** Returns Nothing
1459**
1460*****************************************************************************/
Evan Chua24be4f2013-11-13 15:30:16 -05001461void rw_t3t_act_handle_raw_senddata_rsp (tRW_T3T_CB *p_cb, tNFC_DATA_CEVT *p_data)
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001462{
1463 tRW_READ_DATA evt_data;
Ruchi Kandoi0a736882017-01-09 15:43:14 -08001464 NFC_HDR *p_pkt = p_data->p_data;
Evan Chua24be4f2013-11-13 15:30:16 -05001465
1466#if (BT_TRACE_VERBOSE == TRUE)
1467 RW_TRACE_DEBUG2 ("RW T3T Raw Frame: Len [0x%X] Status [%s]", p_pkt->len, NFC_GetStatusName (p_data->status));
1468#else
1469 RW_TRACE_DEBUG2 ("RW T3T Raw Frame: Len [0x%X] Status [0x%X]", p_pkt->len, p_data->status);
1470#endif
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001471
1472 /* Copy incoming data into buffer */
Evan Chua24be4f2013-11-13 15:30:16 -05001473 evt_data.status = p_data->status;
1474 evt_data.p_data = p_pkt;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001475
1476 p_cb->rw_state = RW_T3T_STATE_IDLE;
1477
1478 (*(rw_cb.p_cback)) (RW_T3T_RAW_FRAME_EVT, (tRW_DATA *) &evt_data);
1479}
1480
1481/*****************************************************************************
1482**
1483** Function rw_t3t_act_handle_check_ndef_rsp
1484**
1485** Description Handle response to NDEF read segment
1486**
1487** Returns Nothing
1488**
1489*****************************************************************************/
Ruchi Kandoi0a736882017-01-09 15:43:14 -08001490void rw_t3t_act_handle_check_ndef_rsp (tRW_T3T_CB *p_cb, NFC_HDR *p_msg_rsp)
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001491{
Ruchi Kandoi4a179642017-01-04 10:04:48 -08001492 bool check_complete = true;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001493 tNFC_STATUS nfc_status = NFC_STATUS_OK;
1494 tRW_READ_DATA read_data;
1495 tRW_DATA evt_data;
Ruchi Kandoi512ee632017-01-03 13:59:10 -08001496 uint8_t *p_t3t_rsp = (uint8_t *) (p_msg_rsp+1) + p_msg_rsp->offset;
1497 uint8_t rsp_num_bytes_rx;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001498
1499 /* Validate response from tag */
1500 if ( (p_t3t_rsp[T3T_MSG_RSP_OFFSET_STATUS1] != T3T_MSG_RSP_STATUS_OK) /* verify response status code */
1501 ||(memcmp (p_cb->peer_nfcid2, &p_t3t_rsp[T3T_MSG_RSP_OFFSET_IDM], NCI_NFCID2_LEN) != 0) /* verify response IDm */
1502 ||(p_t3t_rsp[T3T_MSG_RSP_OFFSET_NUMBLOCKS] != ((p_cb->ndef_rx_readlen+15) >> 4)) ) /* verify length of response */
1503 {
1504 RW_TRACE_ERROR2 ("Response error: bad status, nfcid2, or invalid len: %i %i", p_t3t_rsp[T3T_MSG_RSP_OFFSET_NUMBLOCKS], ((p_cb->ndef_rx_readlen+15)>>4));
1505 nfc_status = NFC_STATUS_FAILED;
1506 GKI_freebuf (p_msg_rsp);
1507 }
1508 else if (p_t3t_rsp[T3T_MSG_RSP_OFFSET_RSPCODE] != T3T_MSG_OPC_CHECK_RSP)
1509 {
1510 RW_TRACE_ERROR2 ("Response error: expecting rsp_code %02X, but got %02X", T3T_MSG_OPC_CHECK_RSP, p_t3t_rsp[T3T_MSG_RSP_OFFSET_RSPCODE]);
1511 nfc_status = NFC_STATUS_FAILED;
1512 GKI_freebuf (p_msg_rsp);
1513 }
1514 else
1515 {
1516 /* Notify app of NDEF segment received */
1517 rsp_num_bytes_rx = p_t3t_rsp[T3T_MSG_RSP_OFFSET_NUMBLOCKS] * 16; /* Number of bytes received, according to header */
1518 p_cb->ndef_rx_offset += p_cb->ndef_rx_readlen;
1519 read_data.status = NFC_STATUS_OK;
1520 p_msg_rsp->offset += T3T_MSG_RSP_OFFSET_CHECK_DATA; /* Skip over t3t header (point to block data) */
1521 p_msg_rsp->len -= T3T_MSG_RSP_OFFSET_CHECK_DATA;
1522
1523 /* Verify that the bytes received is really the amount indicated in the check-response header */
1524 if (rsp_num_bytes_rx > p_msg_rsp->len)
1525 {
1526 RW_TRACE_ERROR2 ("Response error: CHECK rsp header indicates %i bytes, but only received %i bytes", rsp_num_bytes_rx, p_msg_rsp->len);
1527 nfc_status = NFC_STATUS_FAILED;
1528 GKI_freebuf (p_msg_rsp);
1529 }
1530 else
1531 {
1532 /* If this is the the final block, then set len to reflect only valid bytes (do not include padding to 16-byte boundary) */
1533 if ((p_cb->flags & RW_T3T_FL_IS_FINAL_NDEF_SEGMENT) && (p_cb->ndef_attrib.ln & 0x000F))
1534 {
1535 rsp_num_bytes_rx -= (16 - (p_cb->ndef_attrib.ln & 0x000F));
1536 }
1537
1538 p_msg_rsp->len = rsp_num_bytes_rx;
1539 read_data.p_data = p_msg_rsp;
1540 (*(rw_cb.p_cback)) (RW_T3T_CHECK_EVT, (tRW_DATA *) &read_data);
1541
1542 /* Send CHECK cmd for next NDEF segment, if needed */
1543 if (!(p_cb->flags & RW_T3T_FL_IS_FINAL_NDEF_SEGMENT))
1544 {
1545 if ((nfc_status = rw_t3t_send_next_ndef_check_cmd (p_cb)) == NFC_STATUS_OK)
1546 {
1547 /* Still getting more segments. Don't send RW_T3T_CHECK_CPLT_EVT yet */
Ruchi Kandoi4a179642017-01-04 10:04:48 -08001548 check_complete = false;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001549 }
1550 }
1551 }
1552 }
1553
1554 /* Notify app of RW_T3T_CHECK_CPLT_EVT if entire NDEF has been read, or if failure */
1555 if (check_complete)
1556 {
1557 p_cb->rw_state = RW_T3T_STATE_IDLE;
1558 evt_data.status = nfc_status;
1559 (*(rw_cb.p_cback)) (RW_T3T_CHECK_CPLT_EVT, (tRW_DATA *) &evt_data);
1560 }
1561}
1562
1563
1564/*****************************************************************************
1565**
1566** Function rw_t3t_act_handle_update_ndef_rsp
1567**
1568** Description Handle response to NDEF write segment
1569**
1570** Returns Nothing
1571**
1572*****************************************************************************/
Ruchi Kandoi0a736882017-01-09 15:43:14 -08001573void rw_t3t_act_handle_update_ndef_rsp (tRW_T3T_CB *p_cb, NFC_HDR *p_msg_rsp)
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001574{
Ruchi Kandoi4a179642017-01-04 10:04:48 -08001575 bool update_complete = true;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001576 tNFC_STATUS nfc_status = NFC_STATUS_OK;
1577 tRW_DATA evt_data;
Ruchi Kandoi512ee632017-01-03 13:59:10 -08001578 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 -08001579
1580 /* Check nfcid2 and status of response */
1581 if ( (p_t3t_rsp[T3T_MSG_RSP_OFFSET_STATUS1] != T3T_MSG_RSP_STATUS_OK) /* verify response status code */
1582 ||(memcmp (p_cb->peer_nfcid2, &p_t3t_rsp[T3T_MSG_RSP_OFFSET_IDM], NCI_NFCID2_LEN) != 0) ) /* verify response IDm */
1583 {
1584 nfc_status = NFC_STATUS_FAILED;
1585 }
1586 /* Validate response opcode */
1587 else if (p_t3t_rsp[T3T_MSG_RSP_OFFSET_RSPCODE] != T3T_MSG_OPC_UPDATE_RSP)
1588 {
1589 RW_TRACE_ERROR2 ("Response error: expecting rsp_code %02X, but got %02X", T3T_MSG_OPC_UPDATE_RSP, p_t3t_rsp[T3T_MSG_RSP_OFFSET_RSPCODE]);
1590 nfc_status = NFC_STATUS_FAILED;
1591 }
1592 /* If this is response to final UPDATE, then update NDEF local size */
1593 else if (p_cb->flags & RW_T3T_FL_IS_FINAL_NDEF_SEGMENT)
1594 {
1595 /* If successful, update current NDEF size */
1596 p_cb->ndef_attrib.ln = p_cb->ndef_msg_len;
1597 }
1598 /* If any more NDEF bytes to update, then send next UPDATE command */
1599 else if (p_cb->ndef_msg_bytes_sent < p_cb->ndef_msg_len)
1600 {
1601 /* Send UPDATE command for next segment of NDEF */
1602 if ((nfc_status = rw_t3t_send_next_ndef_update_cmd (p_cb)) == NFC_STATUS_OK)
1603 {
1604 /* Wait for update response */
Ruchi Kandoi4a179642017-01-04 10:04:48 -08001605 update_complete = false;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001606 }
1607 }
1608 /* Otherwise, no more NDEF bytes. Send final UPDATE for Attribute Information block */
1609 else
1610 {
1611 p_cb->flags |= RW_T3T_FL_IS_FINAL_NDEF_SEGMENT;
Ruchi Kandoi4a179642017-01-04 10:04:48 -08001612 if ((nfc_status = rw_t3t_send_update_ndef_attribute_cmd (p_cb, false)) == NFC_STATUS_OK)
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001613 {
1614 /* Wait for update response */
Ruchi Kandoi4a179642017-01-04 10:04:48 -08001615 update_complete = false;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001616 }
1617 }
1618
1619 /* If update is completed, then notify app */
1620 if (update_complete)
1621 {
1622 p_cb->rw_state = RW_T3T_STATE_IDLE;
1623 evt_data.status = nfc_status;
1624 (*(rw_cb.p_cback)) (RW_T3T_UPDATE_CPLT_EVT, (tRW_DATA *) &evt_data);
1625 }
1626
1627
1628 GKI_freebuf (p_msg_rsp);
1629
1630 return;
1631}
1632
1633
1634/*****************************************************************************
1635**
1636** Function rw_t3t_handle_get_sc_poll_rsp
1637**
1638** Description Handle POLL response for getting system codes
1639**
1640** Returns Nothing
1641**
1642*****************************************************************************/
Ruchi Kandoi512ee632017-01-03 13:59:10 -08001643static void rw_t3t_handle_get_sc_poll_rsp (tRW_T3T_CB *p_cb, uint8_t nci_status, uint8_t num_responses, uint8_t sensf_res_buf_size, uint8_t *p_sensf_res_buf)
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001644{
Yoshinobu Ito721b3ab2016-08-02 14:41:33 +09001645 uint8_t *p;
Ruchi Kandoi512ee632017-01-03 13:59:10 -08001646 uint16_t sc;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001647
Yoshinobu Ito721b3ab2016-08-02 14:41:33 +09001648 /* Get the system code from the response */
1649 if ( (nci_status == NCI_STATUS_OK)
1650 &&(num_responses > 0)
1651 &&(sensf_res_buf_size >= (RW_T3T_SENSF_RES_RD_OFFSET + RW_T3T_SENSF_RES_RD_LEN)) )
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001652 {
Yoshinobu Ito721b3ab2016-08-02 14:41:33 +09001653 p = &p_sensf_res_buf[RW_T3T_SENSF_RES_RD_OFFSET];
1654 BE_STREAM_TO_UINT16 (sc, p);
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001655
Yoshinobu Ito721b3ab2016-08-02 14:41:33 +09001656 RW_TRACE_DEBUG1 ("FeliCa detected (RD, system code %04X)", sc);
1657 p_cb->system_codes[p_cb->num_system_codes++] = sc;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001658 }
Yoshinobu Ito721b3ab2016-08-02 14:41:33 +09001659
1660 rw_t3t_handle_get_system_codes_cplt ();
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001661}
1662
1663/*****************************************************************************
1664**
1665** Function rw_t3t_handle_ndef_detect_poll_rsp
1666**
1667** Description Handle POLL response for getting system codes
1668**
1669** Returns Nothing
1670**
1671*****************************************************************************/
Ruchi Kandoi512ee632017-01-03 13:59:10 -08001672static void rw_t3t_handle_ndef_detect_poll_rsp (tRW_T3T_CB *p_cb, uint8_t nci_status, uint8_t num_responses, uint8_t sensf_res_buf_size, uint8_t *p_sensf_res_buf)
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001673{
Ruchi Kandoi0a736882017-01-09 15:43:14 -08001674 NFC_HDR *p_cmd_buf;
Ruchi Kandoi512ee632017-01-03 13:59:10 -08001675 uint8_t *p, *p_cmd_start;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001676 tRW_DATA evt_data;
1677
1678 /* Validate response for NDEF poll */
1679 if ((nci_status == NCI_STATUS_OK) && (num_responses > 0))
1680 {
1681 /* Tag responded for NDEF poll */
1682
1683 /* Read NDEF attribute block */
1684 if ((p_cmd_buf = rw_t3t_get_cmd_buf ()) != NULL)
1685 {
1686 /* Construct T3T message */
Ruchi Kandoi512ee632017-01-03 13:59:10 -08001687 p = p_cmd_start = (uint8_t *) (p_cmd_buf+1) + p_cmd_buf->offset;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001688
1689 /* Add CHECK opcode to message */
1690 UINT8_TO_STREAM (p, T3T_MSG_OPC_CHECK_CMD);
1691
1692 /* Add IDm to message */
1693 ARRAY_TO_STREAM (p, p_cb->peer_nfcid2, NCI_NFCID2_LEN);
1694
1695 /* Add Service code list */
1696 UINT8_TO_STREAM (p, 1); /* Number of services (only 1 service: NDEF) */
1697 UINT16_TO_STREAM (p, T3T_MSG_NDEF_SC_RO); /* Service code (little-endian format) */
1698
1699 /* Number of blocks */
1700 UINT8_TO_STREAM (p, 1); /* Number of blocks (only 1 block: NDEF Attribute Information ) */
1701
1702 /* Block List element: the NDEF attribute information block (block 0) */
1703 UINT8_TO_STREAM (p, T3T_MSG_MASK_TWO_BYTE_BLOCK_DESC_FORMAT);
1704 UINT8_TO_STREAM (p, 0);
1705
1706 /* Calculate length of message */
Ruchi Kandoi512ee632017-01-03 13:59:10 -08001707 p_cmd_buf->len = (uint16_t) (p - p_cmd_start);
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001708
1709 /* Send the T3T message */
Sherry Smith818b56e2014-05-14 16:46:32 -07001710 if ((evt_data.status = rw_t3t_send_cmd (p_cb, RW_T3T_CMD_DETECT_NDEF, p_cmd_buf, rw_t3t_check_timeout(1))) == NFC_STATUS_OK)
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001711 {
1712 /* CHECK command sent. Wait for response */
1713 return;
1714 }
1715 }
1716 nci_status = NFC_STATUS_FAILED;
1717 }
1718
1719 /* NDEF detection failed */
1720 p_cb->rw_state = RW_T3T_STATE_IDLE;
1721 evt_data.ndef.status = nci_status;
1722 evt_data.ndef.flags = RW_NDEF_FL_UNKNOWN;
Evan Chua24be4f2013-11-13 15:30:16 -05001723 rw_t3t_update_ndef_flag (&evt_data.ndef.flags);
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001724 (*(rw_cb.p_cback)) (RW_T3T_NDEF_DETECT_EVT, &evt_data);
1725}
1726
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001727/*****************************************************************************
1728**
1729** Function rw_t3t_update_block
1730**
Martijn Coenen5c65c3a2013-03-27 13:23:36 -07001731** Description Send UPDATE command for single block
1732** (for formatting/configuring read only)
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001733**
1734** Returns tNFC_STATUS
1735**
1736*****************************************************************************/
Ruchi Kandoi512ee632017-01-03 13:59:10 -08001737tNFC_STATUS rw_t3t_update_block (tRW_T3T_CB *p_cb, uint8_t block_id, uint8_t *p_block_data)
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001738{
Ruchi Kandoi512ee632017-01-03 13:59:10 -08001739 uint8_t *p_dst, *p_cmd_start;
Ruchi Kandoi0a736882017-01-09 15:43:14 -08001740 NFC_HDR *p_cmd_buf;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001741 tNFC_STATUS status;
1742
1743 if ((p_cmd_buf = rw_t3t_get_cmd_buf ()) != NULL)
1744 {
Ruchi Kandoi512ee632017-01-03 13:59:10 -08001745 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 -08001746
1747 /* Add UPDATE opcode to message */
1748 UINT8_TO_STREAM (p_dst, T3T_MSG_OPC_UPDATE_CMD);
1749
1750 /* Add IDm to message */
1751 ARRAY_TO_STREAM (p_dst, p_cb->peer_nfcid2, NCI_NFCID2_LEN);
1752
1753 /* Add Service code list */
1754 UINT8_TO_STREAM (p_dst, 1); /* Number of services (only 1 service: NDEF) */
1755 UINT16_TO_STREAM (p_dst, T3T_MSG_NDEF_SC_RW); /* Service code (little-endian format) */
1756
1757 /* Number of blocks */
1758 UINT8_TO_STREAM (p_dst, 1);
1759
1760 /* 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);
1763
1764 /* Copy MC data to UPDATE message */
1765 ARRAY_TO_STREAM (p_dst, p_block_data, T3T_MSG_BLOCKSIZE);
1766
1767 /* Calculate length of message */
Ruchi Kandoi512ee632017-01-03 13:59:10 -08001768 p_cmd_buf->len = (uint16_t) (p_dst - p_cmd_start);
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001769
1770 /* Send the T3T message */
Sherry Smith818b56e2014-05-14 16:46:32 -07001771 status = rw_t3t_send_cmd (p_cb, p_cb->cur_cmd, p_cmd_buf, rw_t3t_update_timeout(1));
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001772 }
1773 else
1774 {
1775 /* Unable to send UPDATE command */
1776 status = NFC_STATUS_NO_BUFFERS;
1777 }
1778
1779 return (status);
1780}
1781
1782/*****************************************************************************
1783**
1784** Function rw_t3t_handle_fmt_poll_rsp
1785**
1786** Description Handle POLL response for formatting felica-lite
1787**
1788** Returns Nothing
1789**
1790*****************************************************************************/
Ruchi Kandoi512ee632017-01-03 13:59:10 -08001791static void rw_t3t_handle_fmt_poll_rsp (tRW_T3T_CB *p_cb, uint8_t nci_status, uint8_t num_responses, uint8_t sensf_res_buf_size, uint8_t *p_sensf_res_buf)
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001792{
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001793 tRW_DATA evt_data;
1794
1795 evt_data.status = NFC_STATUS_OK;
1796
1797 /* Validate response for poll response */
1798 if ((nci_status == NCI_STATUS_OK) && (num_responses > 0))
1799 {
1800 /* Tag responded for Felica-Lite poll */
1801 /* Get MemoryControl block */
1802 RW_TRACE_DEBUG0 ("Felica-Lite tag detected...getting Memory Control block.");
1803
Martijn Coenen5c65c3a2013-03-27 13:23:36 -07001804 p_cb->rw_substate = RW_T3T_FMT_SST_CHECK_MC_BLK;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001805
Martijn Coenen5c65c3a2013-03-27 13:23:36 -07001806 /* Send command to check Memory Configuration block */
1807 evt_data.status = rw_t3t_check_mc_block (p_cb);
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001808 }
1809 else
1810 {
1811 RW_TRACE_ERROR0 ("Felica-Lite tag not detected");
1812 evt_data.status = NFC_STATUS_FAILED;
1813 }
1814
1815 /* If error, notify upper layer */
1816 if (evt_data.status != NFC_STATUS_OK)
1817 {
1818 rw_t3t_format_cplt (evt_data.status);
1819 }
1820}
1821
1822/*****************************************************************************
1823**
1824** Function rw_t3t_act_handle_fmt_rsp
1825**
1826** Description Handle response for formatting codes
1827**
1828** Returns Nothing
1829**
1830*****************************************************************************/
Ruchi Kandoi0a736882017-01-09 15:43:14 -08001831void rw_t3t_act_handle_fmt_rsp (tRW_T3T_CB *p_cb, NFC_HDR *p_msg_rsp)
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001832{
Ruchi Kandoi512ee632017-01-03 13:59:10 -08001833 uint8_t *p_t3t_rsp = (uint8_t *) (p_msg_rsp+1) + p_msg_rsp->offset;
1834 uint8_t *p_mc;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001835 tRW_DATA evt_data;
1836
1837 evt_data.status = NFC_STATUS_OK;
1838
1839 /* Check tags's response for reading MemoryControl block */
1840 if (p_cb->rw_substate == RW_T3T_FMT_SST_CHECK_MC_BLK)
1841 {
1842 /* Validate response opcode */
1843 if (p_t3t_rsp[T3T_MSG_RSP_OFFSET_RSPCODE] != T3T_MSG_OPC_CHECK_RSP)
1844 {
1845 RW_TRACE_ERROR2 ("Response error: expecting rsp_code %02X, but got %02X", T3T_MSG_OPC_CHECK_RSP, p_t3t_rsp[T3T_MSG_RSP_OFFSET_RSPCODE]);
1846 evt_data.status = NFC_STATUS_FAILED;
1847 }
1848 /* Validate status code and NFCID2 response from tag */
1849 else if ( (p_t3t_rsp[T3T_MSG_RSP_OFFSET_STATUS1] != T3T_MSG_RSP_STATUS_OK) /* verify response status code */
1850 ||(memcmp (p_cb->peer_nfcid2, &p_t3t_rsp[T3T_MSG_RSP_OFFSET_IDM], NCI_NFCID2_LEN) != 0) ) /* verify response IDm */
1851 {
1852 evt_data.status = NFC_STATUS_FAILED;
1853 }
1854 else
1855 {
1856 /* Check if memory configuration (MC) block to see if SYS_OP=1 (NDEF enabled) */
1857 p_mc = &p_t3t_rsp[T3T_MSG_RSP_OFFSET_CHECK_DATA]; /* Point to MC data of CHECK response */
1858
1859 if (p_mc[T3T_MSG_FELICALITE_MC_OFFSET_SYS_OP] != 0x01)
1860 {
1861 /* Tag is not currently enabled for NDEF. Indicate that we need to update the MC block */
1862
1863 /* Set SYS_OP field to 0x01 (enable NDEF) */
1864 p_mc[T3T_MSG_FELICALITE_MC_OFFSET_SYS_OP] = 0x01;
1865
Martijn Coenen5c65c3a2013-03-27 13:23:36 -07001866 /* Set RF_PRM field to 0x07 (procedure of issuance) */
1867 p_mc[T3T_MSG_FELICALITE_MC_OFFSET_RF_PRM] = 0x07;
1868
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001869 /* Construct and send UPDATE message to write MC block */
1870 p_cb->rw_substate = RW_T3T_FMT_SST_UPDATE_MC_BLK;
1871 evt_data.status = rw_t3t_update_block (p_cb, T3T_MSG_FELICALITE_BLOCK_ID_MC, p_mc);
1872 }
1873 else
1874 {
1875 /* SYS_OP=1: ndef already enabled. Just need to update attribute information block */
1876 p_cb->rw_substate = RW_T3T_FMT_SST_UPDATE_NDEF_ATTRIB;
Ruchi Kandoi512ee632017-01-03 13:59:10 -08001877 evt_data.status = rw_t3t_update_block (p_cb, 0, (uint8_t *) rw_t3t_default_attrib_info);
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001878 }
1879 }
1880
1881 /* If error, notify upper layer */
1882 if (evt_data.status != NFC_STATUS_OK)
1883 {
1884 rw_t3t_format_cplt (evt_data.status);
1885 }
1886 }
1887 else if (p_cb->rw_substate == RW_T3T_FMT_SST_UPDATE_MC_BLK)
1888 {
1889 /* Validate response opcode */
1890 if ( (p_t3t_rsp[T3T_MSG_RSP_OFFSET_RSPCODE] != T3T_MSG_OPC_UPDATE_RSP)
1891 ||(p_t3t_rsp[T3T_MSG_RSP_OFFSET_STATUS1] != T3T_MSG_RSP_STATUS_OK) )
1892
1893 {
1894 RW_TRACE_ERROR2 ("Response error: rsp_code=%02X, status=%02X", p_t3t_rsp[T3T_MSG_RSP_OFFSET_RSPCODE], p_t3t_rsp[T3T_MSG_RSP_OFFSET_STATUS1]);
1895 evt_data.status = NFC_STATUS_FAILED;
1896 }
1897 else
1898 {
1899 /* SYS_OP=1: ndef already enabled. Just need to update attribute information block */
1900 p_cb->rw_substate = RW_T3T_FMT_SST_UPDATE_NDEF_ATTRIB;
Ruchi Kandoi512ee632017-01-03 13:59:10 -08001901 evt_data.status = rw_t3t_update_block (p_cb, 0, (uint8_t *) rw_t3t_default_attrib_info);
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001902 }
1903
1904 /* If error, notify upper layer */
1905 if (evt_data.status != NFC_STATUS_OK)
1906 {
1907 rw_t3t_format_cplt (evt_data.status);
1908 }
1909 }
1910 else if (p_cb->rw_substate == RW_T3T_FMT_SST_UPDATE_NDEF_ATTRIB)
1911 {
1912 /* Validate response opcode */
1913 if ( (p_t3t_rsp[T3T_MSG_RSP_OFFSET_RSPCODE] != T3T_MSG_OPC_UPDATE_RSP)
1914 ||(p_t3t_rsp[T3T_MSG_RSP_OFFSET_STATUS1] != T3T_MSG_RSP_STATUS_OK) )
1915
1916 {
1917 RW_TRACE_ERROR2 ("Response error: rsp_code=%02X, status=%02X", p_t3t_rsp[T3T_MSG_RSP_OFFSET_RSPCODE], p_t3t_rsp[T3T_MSG_RSP_OFFSET_STATUS1]);
1918 evt_data.status = NFC_STATUS_FAILED;
1919 }
1920
1921
1922 rw_t3t_format_cplt (evt_data.status);
1923 }
1924
1925 GKI_freebuf (p_msg_rsp);
1926}
1927
Martijn Coenen5c65c3a2013-03-27 13:23:36 -07001928/*****************************************************************************
1929**
1930** Function rw_t3t_handle_sro_poll_rsp
1931**
1932** Description Handle POLL response for configuring felica-lite read only
1933**
1934** Returns Nothing
1935**
1936*****************************************************************************/
Ruchi Kandoi512ee632017-01-03 13:59:10 -08001937static void rw_t3t_handle_sro_poll_rsp (tRW_T3T_CB *p_cb, uint8_t nci_status, uint8_t num_responses, uint8_t sensf_res_buf_size, uint8_t *p_sensf_res_buf)
Martijn Coenen5c65c3a2013-03-27 13:23:36 -07001938{
1939 tRW_DATA evt_data;
Ruchi Kandoi512ee632017-01-03 13:59:10 -08001940 uint8_t rw_t3t_ndef_attrib_info[T3T_MSG_BLOCKSIZE];
1941 uint8_t *p;
1942 uint8_t tempU8;
1943 uint16_t checksum, i;
1944 uint32_t tempU32 = 0;
Martijn Coenen5c65c3a2013-03-27 13:23:36 -07001945
1946 evt_data.status = NFC_STATUS_OK;
1947
1948 /* Validate response for poll response */
1949 if ((nci_status == NCI_STATUS_OK) && (num_responses > 0))
1950 {
1951 /* Tag responded for Felica-Lite poll */
1952 if (p_cb->ndef_attrib.rwflag != T3T_MSG_NDEF_RWFLAG_RO)
1953 {
1954 /* First update attribute information block */
1955 RW_TRACE_DEBUG0 ("Felica-Lite tag detected...update NDef attribution block.");
1956
1957 p_cb->rw_substate = RW_T3T_SRO_SST_UPDATE_NDEF_ATTRIB;
1958
1959 p = rw_t3t_ndef_attrib_info;
1960
1961 UINT8_TO_STREAM (p, p_cb->ndef_attrib.version);
1962
1963 /* Update NDEF info */
1964 UINT8_TO_STREAM (p, p_cb->ndef_attrib.nbr); /* NBr: number of blocks that can be read using one Check command */
1965 UINT8_TO_STREAM (p, p_cb->ndef_attrib.nbw); /* Nbw: number of blocks that can be written using one Update command */
1966 UINT16_TO_BE_STREAM (p, p_cb->ndef_attrib.nmaxb); /* Nmaxb: maximum number of blocks available for NDEF data */
1967 UINT32_TO_BE_STREAM (p, tempU32);
1968 UINT8_TO_STREAM (p, p_cb->ndef_attrib.writef); /* WriteFlag: 00h if writing data finished; 0Fh if writing data in progress */
1969 UINT8_TO_STREAM (p, 0x00); /* RWFlag: 00h NDEF is read-only */
1970
Ruchi Kandoi512ee632017-01-03 13:59:10 -08001971 tempU8 = (uint8_t) (p_cb->ndef_attrib.ln >> 16);
Martijn Coenen5c65c3a2013-03-27 13:23:36 -07001972 /* Get length (3-byte, big-endian) */
1973 UINT8_TO_STREAM (p, tempU8); /* Ln: high-byte */
1974 UINT16_TO_BE_STREAM (p, p_cb->ndef_attrib.ln); /* Ln: lo-word */
1975
1976 /* Calculate and append Checksum */
1977 checksum = 0;
1978 for (i = 0; i < T3T_MSG_NDEF_ATTR_INFO_SIZE; i++)
1979 {
1980 checksum+=rw_t3t_ndef_attrib_info[i];
1981 }
1982 UINT16_TO_BE_STREAM (p, checksum);
1983
Ruchi Kandoi512ee632017-01-03 13:59:10 -08001984 evt_data.status = rw_t3t_update_block (p_cb, 0, (uint8_t *) rw_t3t_ndef_attrib_info);
Martijn Coenen5c65c3a2013-03-27 13:23:36 -07001985 }
1986 else if (p_cb->cur_cmd == RW_T3T_CMD_SET_READ_ONLY_HARD)
1987 {
1988 /* NDEF is already read only, Read and update MemoryControl block */
1989 RW_TRACE_DEBUG0 ("Felica-Lite tag detected...getting Memory Control block.");
1990 p_cb->rw_substate = RW_T3T_SRO_SST_CHECK_MC_BLK;
1991
1992 /* Send command to check Memory Configuration block */
1993 evt_data.status = rw_t3t_check_mc_block (p_cb);
1994 }
1995 }
1996 else
1997 {
1998 RW_TRACE_ERROR0 ("Felica-Lite tag not detected");
1999 evt_data.status = NFC_STATUS_FAILED;
2000 }
2001
2002 /* If error, notify upper layer */
2003 if (evt_data.status != NFC_STATUS_OK)
2004 {
2005 rw_t3t_set_readonly_cplt (evt_data.status);
2006 }
2007}
2008
2009/*****************************************************************************
2010**
2011** Function rw_t3t_act_handle_sro_rsp
2012**
2013** Description Handle response for setting read only codes
2014**
2015** Returns Nothing
2016**
2017*****************************************************************************/
Ruchi Kandoi0a736882017-01-09 15:43:14 -08002018void rw_t3t_act_handle_sro_rsp (tRW_T3T_CB *p_cb, NFC_HDR *p_msg_rsp)
Martijn Coenen5c65c3a2013-03-27 13:23:36 -07002019{
Ruchi Kandoi512ee632017-01-03 13:59:10 -08002020 uint8_t *p_t3t_rsp = (uint8_t *) (p_msg_rsp+1) + p_msg_rsp->offset;
2021 uint8_t *p_mc;
Martijn Coenen5c65c3a2013-03-27 13:23:36 -07002022 tRW_DATA evt_data;
2023
2024 evt_data.status = NFC_STATUS_OK;
2025
2026 if (p_cb->rw_substate == RW_T3T_SRO_SST_UPDATE_NDEF_ATTRIB)
2027 {
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
2032 {
2033 RW_TRACE_ERROR2 ("Response error: rsp_code=%02X, status=%02X", p_t3t_rsp[T3T_MSG_RSP_OFFSET_RSPCODE], p_t3t_rsp[T3T_MSG_RSP_OFFSET_STATUS1]);
2034 evt_data.status = NFC_STATUS_FAILED;
2035 }
2036 else
2037 {
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 {
2041 p_cb->rw_substate = RW_T3T_SRO_SST_CHECK_MC_BLK;
2042
2043 /* Send command to check Memory Configuration block */
2044 evt_data.status = rw_t3t_check_mc_block (p_cb);
2045 }
2046 else
2047 {
2048 rw_t3t_set_readonly_cplt (evt_data.status);
2049 }
2050 }
2051 }
2052 else if (p_cb->rw_substate == RW_T3T_SRO_SST_CHECK_MC_BLK)
2053 {
2054 /* Check tags's response for reading MemoryControl block, Validate response opcode */
2055 if (p_t3t_rsp[T3T_MSG_RSP_OFFSET_RSPCODE] != T3T_MSG_OPC_CHECK_RSP)
2056 {
2057 RW_TRACE_ERROR2 ("Response error: expecting rsp_code %02X, but got %02X", T3T_MSG_OPC_CHECK_RSP, p_t3t_rsp[T3T_MSG_RSP_OFFSET_RSPCODE]);
2058 evt_data.status = NFC_STATUS_FAILED;
2059 }
2060 /* Validate status code and NFCID2 response from tag */
2061 else if ( (p_t3t_rsp[T3T_MSG_RSP_OFFSET_STATUS1] != T3T_MSG_RSP_STATUS_OK) /* verify response status code */
2062 ||(memcmp (p_cb->peer_nfcid2, &p_t3t_rsp[T3T_MSG_RSP_OFFSET_IDM], NCI_NFCID2_LEN) != 0) ) /* verify response IDm */
2063 {
2064 evt_data.status = NFC_STATUS_FAILED;
2065 }
2066 else
2067 {
2068 /* Check if memory configuration (MC) block to see if SYS_OP=1 (NDEF enabled) */
2069 p_mc = &p_t3t_rsp[T3T_MSG_RSP_OFFSET_CHECK_DATA]; /* Point to MC data of CHECK response */
2070
2071 if (p_mc[T3T_MSG_FELICALITE_MC_OFFSET_SYS_OP] != 0x01)
2072 {
2073 /* Tag is not currently enabled for NDEF */
2074 evt_data.status = NFC_STATUS_FAILED;
2075 }
2076 else
2077 {
2078 /* Set MC_SP field with MC[0] = 0x00 & MC[1] = 0xC0 (Hardlock) to change access permission from RW to RO */
2079 p_mc[T3T_MSG_FELICALITE_MC_OFFSET_MC_SP] = 0x00;
2080 /* Not changing the access permission of Subtraction Register and MC[0:1] */
2081 p_mc[T3T_MSG_FELICALITE_MC_OFFSET_MC_SP + 1] = 0xC0;
2082
2083 /* Set RF_PRM field to 0x07 (procedure of issuance) */
2084 p_mc[T3T_MSG_FELICALITE_MC_OFFSET_RF_PRM] = 0x07;
2085
2086 /* Construct and send UPDATE message to write MC block */
2087 p_cb->rw_substate = RW_T3T_SRO_SST_UPDATE_MC_BLK;
2088 evt_data.status = rw_t3t_update_block (p_cb, T3T_MSG_FELICALITE_BLOCK_ID_MC, p_mc);
2089 }
2090 }
2091 }
2092 else if (p_cb->rw_substate == RW_T3T_SRO_SST_UPDATE_MC_BLK)
2093 {
2094 /* Validate response opcode */
2095 if ( (p_t3t_rsp[T3T_MSG_RSP_OFFSET_RSPCODE] != T3T_MSG_OPC_UPDATE_RSP)
2096 ||(p_t3t_rsp[T3T_MSG_RSP_OFFSET_STATUS1] != T3T_MSG_RSP_STATUS_OK) )
2097
2098 {
2099 RW_TRACE_ERROR2 ("Response error: rsp_code=%02X, status=%02X", p_t3t_rsp[T3T_MSG_RSP_OFFSET_RSPCODE], p_t3t_rsp[T3T_MSG_RSP_OFFSET_STATUS1]);
2100 evt_data.status = NFC_STATUS_FAILED;
2101 }
2102 else
2103 {
2104 rw_t3t_set_readonly_cplt (evt_data.status);
2105 }
2106 }
2107
2108 /* If error, notify upper layer */
2109 if (evt_data.status != NFC_STATUS_OK)
2110 {
2111 rw_t3t_set_readonly_cplt (evt_data.status);
2112 }
2113
2114 GKI_freebuf (p_msg_rsp);
2115}
2116
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002117/*******************************************************************************
2118**
2119** Function rw_t3t_data_cback
2120**
2121** Description This callback function receives the data from NFCC.
2122**
2123** Returns none
2124**
2125*******************************************************************************/
Ruchi Kandoi512ee632017-01-03 13:59:10 -08002126void rw_t3t_data_cback (uint8_t conn_id, tNFC_DATA_CEVT *p_data)
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002127{
Evan Chua24be4f2013-11-13 15:30:16 -05002128 tRW_T3T_CB *p_cb = &rw_cb.tcb.t3t;
Ruchi Kandoi0a736882017-01-09 15:43:14 -08002129 NFC_HDR *p_msg = p_data->p_data;
Ruchi Kandoi4a179642017-01-04 10:04:48 -08002130 bool free_msg = false; /* if TRUE, free msg buffer before returning */
Ruchi Kandoi512ee632017-01-03 13:59:10 -08002131 uint8_t *p, sod;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002132
2133 /* Stop rsponse timer */
2134 nfc_stop_quick_timer (&p_cb->timer);
2135
Ruchi Kandoi303fec12016-12-14 13:22:38 -08002136#if (RW_STATS_INCLUDED == TRUE)
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002137 /* Update rx stats */
2138 rw_main_update_rx_stats (p_msg->len);
2139#endif /* RW_STATS_INCLUDED */
2140
2141 /* Check if we are expecting a response */
2142 if (p_cb->rw_state != RW_T3T_STATE_COMMAND_PENDING)
2143 {
2144 /*
2145 ** This must be raw frame response
2146 ** send raw frame to app with SoD
2147 */
Evan Chua24be4f2013-11-13 15:30:16 -05002148 rw_t3t_act_handle_raw_senddata_rsp (p_cb, p_data);
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002149 }
2150 /* Sanity check: verify msg len is big enough to contain t3t header */
2151 else if (p_msg->len < T3T_MSG_RSP_COMMON_HDR_LEN)
2152 {
2153 RW_TRACE_ERROR1 ("T3T: invalid Type3 Tag Message (invalid len: %i)", p_msg->len);
Ruchi Kandoi4a179642017-01-04 10:04:48 -08002154 free_msg = true;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002155
2156 rw_t3t_process_frame_error ();
2157 }
2158 else
2159 {
2160 /* Check for RF frame error */
Ruchi Kandoi512ee632017-01-03 13:59:10 -08002161 p = (uint8_t *) (p_msg+1) + p_msg->offset;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002162 sod = p[0];
2163 if (p[sod] != NCI_STATUS_OK)
2164 {
2165 RW_TRACE_ERROR1 ("T3T: rf frame error (crc status=%i)", p[sod]);
2166 GKI_freebuf (p_msg);
2167
2168 rw_t3t_process_frame_error ();
2169 return;
2170 }
2171
2172#if (BT_TRACE_PROTOCOL == TRUE)
Ruchi Kandoi4a179642017-01-04 10:04:48 -08002173 DispT3TagMessage (p_msg, true);
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002174#endif
2175
2176 /* Skip over SoD */
2177 p_msg->offset++;
2178 p_msg->len--;
2179
2180 /* Get response code */
2181 switch (p_cb->cur_cmd)
2182 {
2183 case RW_T3T_CMD_DETECT_NDEF:
2184 rw_t3t_act_handle_ndef_detect_rsp (p_cb, p_msg);
2185 break;
2186
2187 case RW_T3T_CMD_CHECK_NDEF:
2188 rw_t3t_act_handle_check_ndef_rsp (p_cb, p_msg);
2189 break;
2190
2191 case RW_T3T_CMD_UPDATE_NDEF:
2192 rw_t3t_act_handle_update_ndef_rsp (p_cb, p_msg);
2193 break;
2194
2195 case RW_T3T_CMD_CHECK:
2196 rw_t3t_act_handle_check_rsp (p_cb, p_msg);
2197 break;
2198
2199 case RW_T3T_CMD_UPDATE:
2200 rw_t3t_act_handle_update_rsp (p_cb, p_msg);
2201 break;
2202
2203 case RW_T3T_CMD_SEND_RAW_FRAME:
Evan Chua24be4f2013-11-13 15:30:16 -05002204 rw_t3t_act_handle_raw_senddata_rsp (p_cb, p_data);
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002205 break;
2206
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002207 case RW_T3T_CMD_FORMAT:
2208 rw_t3t_act_handle_fmt_rsp (p_cb, p_msg);
2209 break;
2210
Martijn Coenen5c65c3a2013-03-27 13:23:36 -07002211 case RW_T3T_CMD_SET_READ_ONLY_SOFT:
2212 case RW_T3T_CMD_SET_READ_ONLY_HARD:
2213 rw_t3t_act_handle_sro_rsp (p_cb, p_msg);
2214 break;
2215
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002216 default:
2217 GKI_freebuf (p_msg);
2218 break;
2219 }
2220 }
2221
2222 if (free_msg)
2223 {
2224 GKI_freebuf (p_msg);
2225 }
2226}
2227
2228
2229/*******************************************************************************
2230**
2231** Function rw_t3t_conn_cback
2232**
2233** Description This callback function receives the events/data from NFCC.
2234**
2235** Returns none
2236**
2237*******************************************************************************/
Ruchi Kandoi512ee632017-01-03 13:59:10 -08002238void rw_t3t_conn_cback (uint8_t conn_id, tNFC_CONN_EVT event, tNFC_CONN *p_data)
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002239{
2240 tRW_T3T_CB *p_cb = &rw_cb.tcb.t3t;
2241 RW_TRACE_DEBUG2 ("rw_t3t_conn_cback: conn_id=%i, evt=0x%02x", conn_id, event);
2242
2243 /* Only handle NFC_RF_CONN_ID conn_id */
2244 if (conn_id != NFC_RF_CONN_ID)
2245 {
2246 return;
2247 }
2248
2249 switch (event)
2250 {
2251 case NFC_DEACTIVATE_CEVT:
2252 rw_t3t_unselect (NULL);
2253 break;
2254
2255 case NFC_DATA_CEVT: /* check for status in tNFC_CONN */
Ken Wahidd8c0f582015-05-18 14:43:25 +02002256 if ( (p_data != NULL)
2257 &&( (p_data->data.status == NFC_STATUS_OK)
2258 ||(p_data->data.status == NFC_STATUS_CONTINUE) ) )
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002259 {
Evan Chua24be4f2013-11-13 15:30:16 -05002260 rw_t3t_data_cback (conn_id, &(p_data->data));
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002261 break;
2262 }
Jizhou Liaof1877412016-03-22 12:08:11 -07002263 else if (p_data->data.p_data != NULL)
2264 {
2265 /* Free the response buffer in case of error response */
Ruchi Kandoi0a736882017-01-09 15:43:14 -08002266 GKI_freebuf ((NFC_HDR *) (p_data->data.p_data));
Jizhou Liaof1877412016-03-22 12:08:11 -07002267 p_data->data.p_data = NULL;
2268 }
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002269 /* Data event with error status...fall through to NFC_ERROR_CEVT case */
2270
2271
2272 case NFC_ERROR_CEVT:
2273 nfc_stop_quick_timer (&p_cb->timer);
2274
Ruchi Kandoi303fec12016-12-14 13:22:38 -08002275#if (RW_STATS_INCLUDED == TRUE)
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002276 rw_main_update_trans_error_stats ();
2277#endif /* RW_STATS_INCLUDED */
2278
2279 if (event == NFC_ERROR_CEVT)
2280 rw_t3t_process_error (NFC_STATUS_TIMEOUT);
Ken Wahidd8c0f582015-05-18 14:43:25 +02002281 else if (p_data)
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002282 rw_t3t_process_error (p_data->status);
2283 break;
2284
2285 default:
2286 break;
2287
2288 }
2289}
2290
2291
2292/*******************************************************************************
2293**
Sherry Smith818b56e2014-05-14 16:46:32 -07002294** Function rw_t3t_mrti_to_a_b
2295**
2296** Description Converts the given MRTI (Maximum Response Time Information)
2297** to the base to calculate timeout value.
2298** (The timeout value is a + b * number_blocks)
2299**
2300** Returns NFC_STATUS_OK
2301**
2302*******************************************************************************/
Ruchi Kandoi512ee632017-01-03 13:59:10 -08002303static void rw_t3t_mrti_to_a_b (uint8_t mrti, uint32_t *p_a, uint32_t *p_b)
Sherry Smith818b56e2014-05-14 16:46:32 -07002304{
Ruchi Kandoi512ee632017-01-03 13:59:10 -08002305 uint8_t a, b, e;
Sherry Smith818b56e2014-05-14 16:46:32 -07002306
2307 a = (mrti & 0x7) + 1; /* A is bit 0 ~ bit 2 */
2308 mrti >>=3;
2309 b = (mrti & 0x7) + 1; /* B is bit 3 ~ bit 5 */
2310 mrti >>=3;
2311 e = mrti & 0x3; /* E is bit 6 ~ bit 7 */
2312 *p_a = rw_t3t_mrti_base[e] * a; /* (A+1) * base (i.e T/t3t * 4^E) */
2313 *p_b = rw_t3t_mrti_base[e] * b; /* (B+1) * base (i.e T/t3t * 4^E) */
2314}
2315
2316
2317/*******************************************************************************
2318**
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002319** Function rw_t3t_select
2320**
2321** Description Called by NFC manager when a Type3 tag has been activated
2322**
2323** Returns NFC_STATUS_OK
2324**
2325*******************************************************************************/
Ruchi Kandoi512ee632017-01-03 13:59:10 -08002326tNFC_STATUS rw_t3t_select (uint8_t peer_nfcid2[NCI_RF_F_UID_LEN], uint8_t mrti_check, uint8_t mrti_update)
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002327{
2328 tRW_T3T_CB *p_cb = &rw_cb.tcb.t3t;
2329
2330 RW_TRACE_API0 ("rw_t3t_select");
2331
2332 memcpy (p_cb->peer_nfcid2, peer_nfcid2, NCI_NFCID2_LEN); /* Store tag's NFCID2 */
2333 p_cb->ndef_attrib.status = NFC_STATUS_NOT_INITIALIZED; /* Indicate that NDEF detection has not been performed yet */
2334 p_cb->rw_state = RW_T3T_STATE_IDLE;
2335 p_cb->flags = 0;
Sherry Smith818b56e2014-05-14 16:46:32 -07002336 rw_t3t_mrti_to_a_b (mrti_check, &p_cb->check_tout_a, &p_cb->check_tout_b);
2337 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 -08002338
2339 /* Alloc cmd buf for retransmissions */
2340 if (p_cb->p_cur_cmd_buf == NULL)
2341 {
Ruchi Kandoi0a736882017-01-09 15:43:14 -08002342 if ((p_cb->p_cur_cmd_buf = (NFC_HDR *) GKI_getpoolbuf (NFC_RW_POOL_ID)) == NULL)
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002343 {
2344 RW_TRACE_ERROR0 ("rw_t3t_select: unable to allocate buffer for retransmission");
2345 p_cb->rw_state = RW_T3T_STATE_NOT_ACTIVATED;
2346 return (NFC_STATUS_FAILED);
2347 }
2348 }
2349
2350
2351 NFC_SetStaticRfCback (rw_t3t_conn_cback);
2352
2353 return NFC_STATUS_OK;
2354}
2355
2356
2357/*******************************************************************************
2358**
2359** Function rw_t3t_unselect
2360**
2361** Description Called by NFC manager when a Type3 tag has been de-activated
2362**
2363** Returns NFC_STATUS_OK
2364**
2365*******************************************************************************/
Ruchi Kandoi512ee632017-01-03 13:59:10 -08002366static tNFC_STATUS rw_t3t_unselect (uint8_t peer_nfcid2[])
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002367{
2368 tRW_T3T_CB *p_cb = &rw_cb.tcb.t3t;
2369
Ruchi Kandoi303fec12016-12-14 13:22:38 -08002370#if (RW_STATS_INCLUDED == TRUE)
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002371 /* Display stats */
2372 rw_main_log_stats ();
2373#endif /* RW_STATS_INCLUDED */
2374
2375 /* Stop t3t timer (if started) */
2376 nfc_stop_quick_timer (&p_cb->timer);
2377
2378 /* Free cmd buf for retransmissions */
2379 if (p_cb->p_cur_cmd_buf)
2380 {
2381 GKI_freebuf (p_cb->p_cur_cmd_buf);
2382 p_cb->p_cur_cmd_buf = NULL;
2383 }
2384
2385 p_cb->rw_state = RW_T3T_STATE_NOT_ACTIVATED;
2386 NFC_SetStaticRfCback (NULL);
2387
2388 return NFC_STATUS_OK;
2389}
2390
Evan Chua24be4f2013-11-13 15:30:16 -05002391/*******************************************************************************
2392**
2393** Function rw_t3t_update_ndef_flag
2394**
2395** Description set additional NDEF Flags for felica lite tag
2396**
2397** Returns updated NDEF Flag value
2398**
2399*******************************************************************************/
Ruchi Kandoi512ee632017-01-03 13:59:10 -08002400static void rw_t3t_update_ndef_flag (uint8_t *p_flag)
Evan Chua24be4f2013-11-13 15:30:16 -05002401{
2402 tRW_T3T_CB *p_cb = &rw_cb.tcb.t3t;
Ruchi Kandoi512ee632017-01-03 13:59:10 -08002403 uint8_t xx;
Evan Chua24be4f2013-11-13 15:30:16 -05002404
2405 for (xx = 0; xx < p_cb->num_system_codes; xx++)
2406 {
2407 if (p_cb->system_codes[xx] == T3T_SYSTEM_CODE_FELICA_LITE)
2408 {
2409 *p_flag &= ~RW_NDEF_FL_UNKNOWN;
2410 *p_flag |= (RW_NDEF_FL_SUPPORTED | RW_NDEF_FL_FORMATABLE);
2411 break;
2412 }
2413 }
2414}
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002415
2416#if (BT_TRACE_VERBOSE == TRUE)
2417/*******************************************************************************
2418**
2419** Function rw_t3t_cmd_str
2420**
2421** Description Converts cmd_id to command string for logging
2422**
2423** Returns command string
2424**
2425*******************************************************************************/
Ruchi Kandoi512ee632017-01-03 13:59:10 -08002426static char *rw_t3t_cmd_str (uint8_t cmd_id)
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002427{
2428 switch (cmd_id)
2429 {
2430 case RW_T3T_CMD_DETECT_NDEF:
2431 return "RW_T3T_CMD_DETECT_NDEF";
2432
2433 case RW_T3T_CMD_CHECK_NDEF:
2434 return "RW_T3T_CMD_CHECK_NDEF";
2435
2436 case RW_T3T_CMD_UPDATE_NDEF:
2437 return "RW_T3T_CMD_UPDATE_NDEF";
2438
2439 case RW_T3T_CMD_CHECK:
2440 return "RW_T3T_CMD_CHECK";
2441
2442 case RW_T3T_CMD_UPDATE:
2443 return "RW_T3T_CMD_UPDATE";
2444
2445 case RW_T3T_CMD_SEND_RAW_FRAME:
2446 return "RW_T3T_CMD_SEND_RAW_FRAME";
2447
2448 case RW_T3T_CMD_GET_SYSTEM_CODES:
2449 return "RW_T3T_CMD_GET_SYSTEM_CODES";
2450
2451 default:
2452 return "Unknown";
2453 }
2454}
2455
2456
2457/*******************************************************************************
2458**
2459** Function rw_t3t_state_str
2460**
2461** Description Converts state_id to command string for logging
2462**
2463** Returns command string
2464**
2465*******************************************************************************/
Ruchi Kandoi512ee632017-01-03 13:59:10 -08002466static char *rw_t3t_state_str (uint8_t state_id)
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002467{
2468 switch (state_id)
2469 {
2470 case RW_T3T_STATE_NOT_ACTIVATED:
2471 return "RW_T3T_STATE_NOT_ACTIVATED";
2472
2473 case RW_T3T_STATE_IDLE:
2474 return "RW_T3T_STATE_IDLE";
2475
2476 case RW_T3T_STATE_COMMAND_PENDING:
2477 return "RW_T3T_STATE_COMMAND_PENDING";
2478
2479 default:
2480 return "Unknown";
2481 }
2482}
2483#endif
2484
2485/*****************************************************************************
2486** Type3 Tag API Functions
2487*****************************************************************************/
2488
2489
2490/*****************************************************************************
2491**
2492** Function RW_T3tDetectNDef
2493**
2494** Description
2495** This function is used to perform NDEF detection on a Type 3 tag, and
2496** retrieve the tag's NDEF attribute information (block 0).
2497**
2498** Before using this API, the application must call RW_SelectTagType to
2499** indicate that a Type 3 tag has been activated, and to provide the
2500** tag's Manufacture ID (IDm) .
2501**
2502** Returns
2503** NFC_STATUS_OK: ndef detection procedure started
2504** NFC_STATUS_NO_BUFFERS: unable to allocate a buffer for this operation
2505** NFC_STATUS_FAILED: other error
2506**
2507*****************************************************************************/
2508tNFC_STATUS RW_T3tDetectNDef (void)
2509{
2510 tRW_T3T_CB *p_cb = &rw_cb.tcb.t3t;
2511 tNFC_STATUS retval = NFC_STATUS_OK;
2512
2513 RW_TRACE_API0 ("RW_T3tDetectNDef");
2514
2515 /* Check if we are in valid state to handle this API */
2516 if (p_cb->rw_state != RW_T3T_STATE_IDLE)
2517 {
2518 RW_TRACE_ERROR1 ("Error: invalid state to handle API (0x%x)", p_cb->rw_state);
2519 return (NFC_STATUS_FAILED);
2520 }
2521
The Android Open Source Project808ebf82012-12-13 15:18:55 -08002522 if ((retval = (tNFC_STATUS) nci_snd_t3t_polling (T3T_SYSTEM_CODE_NDEF, 0, 0)) == NCI_STATUS_OK)
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002523 {
2524 p_cb->cur_cmd = RW_T3T_CMD_DETECT_NDEF;
2525 p_cb->cur_tout = RW_T3T_DEFAULT_CMD_TIMEOUT_TICKS;
2526 p_cb->cur_poll_rc = 0;
2527 p_cb->rw_state = RW_T3T_STATE_COMMAND_PENDING;
2528 p_cb->flags |= RW_T3T_FL_W4_NDEF_DETECT_POLL_RSP;
2529
2530 /* start timer for waiting for responses */
2531 rw_t3t_start_poll_timer (p_cb);
2532 }
2533
2534 return (retval);
2535}
2536
2537
2538/*****************************************************************************
2539**
2540** Function RW_T3tCheckNDef
2541**
2542** Description
2543** Retrieve NDEF contents from a Type3 tag.
2544**
2545** The RW_T3T_CHECK_EVT event is used to notify the application for each
Ruchi Kandoi552f2b72017-01-28 16:22:55 -08002546** segment of NDEF data received. The RW_T3T_CHECK_CPLT_EVT event is used
2547** to notify the application all segments have been received.
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002548**
2549** Before using this API, the RW_T3tDetectNDef function must be called to
2550** verify that the tag contains NDEF data, and to retrieve the NDEF
2551** attributes.
2552**
2553** Internally, this command will be separated into multiple Tag 3 Check
2554** commands (if necessary) - depending on the tag's Nbr (max number of
2555** blocks per read) attribute.
2556**
2557** Returns
2558** NFC_STATUS_OK: check command started
2559** NFC_STATUS_NO_BUFFERS: unable to allocate a buffer for this operation
2560** NFC_STATUS_FAILED: other error
2561**
2562*****************************************************************************/
2563tNFC_STATUS RW_T3tCheckNDef (void)
2564{
2565 tNFC_STATUS retval = NFC_STATUS_OK;
2566 tRW_T3T_CB *p_cb = &rw_cb.tcb.t3t;
2567
2568 RW_TRACE_API0 ("RW_T3tCheckNDef");
2569
2570 /* Check if we are in valid state to handle this API */
2571 if (p_cb->rw_state != RW_T3T_STATE_IDLE)
2572 {
2573 RW_TRACE_ERROR1 ("Error: invalid state to handle API (0x%x)", p_cb->rw_state);
2574 return (NFC_STATUS_FAILED);
2575 }
2576 else if (p_cb->ndef_attrib.status != NFC_STATUS_OK) /* NDEF detection not performed yet? */
2577 {
2578 RW_TRACE_ERROR0 ("Error: NDEF detection not performed yet");
2579 return (NFC_STATUS_NOT_INITIALIZED);
2580 }
2581 else if (p_cb->ndef_attrib.ln == 0)
2582 {
2583 RW_TRACE_ERROR0 ("Type 3 tag contains empty NDEF message");
2584 return (NFC_STATUS_FAILED);
2585 }
2586
2587 /* Check number of blocks needed for this update */
2588 p_cb->flags &= ~RW_T3T_FL_IS_FINAL_NDEF_SEGMENT;
2589 p_cb->ndef_rx_offset = 0;
2590 retval = rw_t3t_send_next_ndef_check_cmd (p_cb);
2591
2592 return (retval);
2593}
2594
2595/*****************************************************************************
2596**
2597** Function RW_T3tUpdateNDef
2598**
2599** Description
2600** Write NDEF contents to a Type3 tag.
2601**
2602** The RW_T3T_UPDATE_CPLT_EVT callback event will be used to notify the
2603** application of the response.
2604**
2605** Before using this API, the RW_T3tDetectNDef function must be called to
2606** verify that the tag contains NDEF data, and to retrieve the NDEF
2607** attributes.
2608**
2609** Internally, this command will be separated into multiple Tag 3 Update
2610** commands (if necessary) - depending on the tag's Nbw (max number of
2611** blocks per write) attribute.
2612**
2613** Returns
2614** NFC_STATUS_OK: check command started
2615** NFC_STATUS_NO_BUFFERS: unable to allocate a buffer for this operation
2616** NFC_STATUS_REFUSED: tag is read-only
2617** NFC_STATUS_BUFFER_FULL: len exceeds tag's maximum size
2618** NFC_STATUS_FAILED: other error
2619**
2620*****************************************************************************/
Ruchi Kandoi512ee632017-01-03 13:59:10 -08002621tNFC_STATUS RW_T3tUpdateNDef (uint32_t len, uint8_t *p_data)
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002622{
2623 tNFC_STATUS retval = NFC_STATUS_OK;
2624 tRW_T3T_CB *p_cb = &rw_cb.tcb.t3t;
2625
2626 RW_TRACE_API1 ("RW_T3tUpdateNDef (len=%i)", len);
2627
2628 /* Check if we are in valid state to handle this API */
2629 if (p_cb->rw_state != RW_T3T_STATE_IDLE)
2630 {
2631 RW_TRACE_ERROR1 ("Error: invalid state to handle API (0x%x)", p_cb->rw_state);
2632 return (NFC_STATUS_FAILED);
2633 }
2634 else if (p_cb->ndef_attrib.status != NFC_STATUS_OK) /* NDEF detection not performed yet? */
2635 {
2636 RW_TRACE_ERROR0 ("Error: NDEF detection not performed yet");
2637 return (NFC_STATUS_NOT_INITIALIZED);
2638 }
Ruchi Kandoi512ee632017-01-03 13:59:10 -08002639 else if (len > (((uint32_t)p_cb->ndef_attrib.nmaxb) * 16)) /* Len exceed's tag's NDEF memory? */
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002640 {
2641 return (NFC_STATUS_BUFFER_FULL);
2642 }
2643 else if (p_cb->ndef_attrib.rwflag == T3T_MSG_NDEF_RWFLAG_RO)/* Tag's NDEF memory is read-only? */
2644 {
2645 return (NFC_STATUS_REFUSED);
2646 }
2647
2648 /* Check number of blocks needed for this update */
2649 p_cb->flags &= ~RW_T3T_FL_IS_FINAL_NDEF_SEGMENT;
2650 p_cb->ndef_msg_bytes_sent = 0;
2651 p_cb->ndef_msg_len = len;
2652 p_cb->ndef_msg = p_data;
2653
2654 /* Send initial UPDATE command for NDEF Attribute Info */
Ruchi Kandoi4a179642017-01-04 10:04:48 -08002655 retval = rw_t3t_send_update_ndef_attribute_cmd (p_cb, true);
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002656
2657 return (retval);
2658}
2659
2660/*****************************************************************************
2661**
2662** Function RW_T3tCheck
2663**
2664** Description
2665** Read (non-NDEF) contents from a Type3 tag.
2666**
2667** The RW_READ_EVT event is used to notify the application for each
2668** segment of NDEF data received. The RW_READ_CPLT_EVT event is used to
2669** notify the application all 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
2673** tag's 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 Kandoi512ee632017-01-03 13:59:10 -08002681tNFC_STATUS RW_T3tCheck (uint8_t num_blocks, tT3T_BLOCK_DESC *t3t_blocks)
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002682{
2683 tNFC_STATUS retval = NFC_STATUS_OK;
2684 tRW_T3T_CB *p_cb = &rw_cb.tcb.t3t;
2685
2686 RW_TRACE_API1 ("RW_T3tCheck (num_blocks = %i)", num_blocks);
2687
2688 /* Check if we are in valid state to handle this API */
2689 if (p_cb->rw_state != RW_T3T_STATE_IDLE)
2690 {
2691 RW_TRACE_ERROR1 ("Error: invalid state to handle API (0x%x)", p_cb->rw_state);
2692 return (NFC_STATUS_FAILED);
2693 }
2694
2695 /* Send the CHECK command */
2696 retval = rw_t3t_send_check_cmd (p_cb, num_blocks, t3t_blocks);
2697
2698 return (retval);
2699}
2700
2701/*****************************************************************************
2702**
2703** Function RW_T3tUpdate
2704**
2705** Description
2706** Write (non-NDEF) contents to a Type3 tag.
2707**
2708** The RW_WRITE_CPLT_EVT event is used to notify the application all
2709** segments have been received.
2710**
2711** Before using this API, the application must call RW_SelectTagType to
2712** indicate that a Type 3 tag has been activated, and to provide the tag's
2713** Manufacture ID (IDm) .
2714**
2715** Returns
2716** NFC_STATUS_OK: check command started
2717** NFC_STATUS_NO_BUFFERS: unable to allocate a buffer for this operation
2718** NFC_STATUS_FAILED: other error
2719**
2720*****************************************************************************/
Ruchi Kandoi512ee632017-01-03 13:59:10 -08002721tNFC_STATUS RW_T3tUpdate (uint8_t num_blocks, tT3T_BLOCK_DESC *t3t_blocks, uint8_t *p_data)
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002722{
2723 tNFC_STATUS retval = NFC_STATUS_OK;
2724 tRW_T3T_CB *p_cb = &rw_cb.tcb.t3t;
2725
2726 RW_TRACE_API1 ("RW_T3tUpdate (num_blocks = %i)", num_blocks);
2727
2728 /* Check if we are in valid state to handle this API */
2729 if (p_cb->rw_state != RW_T3T_STATE_IDLE)
2730 {
2731 RW_TRACE_ERROR1 ("Error: invalid state to handle API (0x%x)", p_cb->rw_state);
2732 return (NFC_STATUS_FAILED);
2733 }
2734
2735 /* Send the UPDATE command */
2736 retval = rw_t3t_send_update_cmd (p_cb, num_blocks, t3t_blocks, p_data);
2737
2738 return (retval);
2739}
2740
2741/*****************************************************************************
2742**
2743** Function RW_T3tPresenceCheck
2744**
2745** Description
2746** Check if the tag is still in the field.
2747**
2748** The RW_T3T_PRESENCE_CHECK_EVT w/ status is used to indicate presence
2749** or non-presence.
2750**
2751** Returns
2752** NFC_STATUS_OK, if raw data frame sent
2753** NFC_STATUS_NO_BUFFERS: unable to allocate a buffer for this operation
2754** NFC_STATUS_FAILED: other error
2755**
2756*****************************************************************************/
2757tNFC_STATUS RW_T3tPresenceCheck (void)
2758{
2759 tNFC_STATUS retval = NFC_STATUS_OK;
2760 tRW_DATA evt_data;
2761 tRW_CB *p_rw_cb = &rw_cb;
2762
2763 RW_TRACE_API0 ("RW_T3tPresenceCheck");
2764
2765 /* If RW_SelectTagType was not called (no conn_callback) return failure */
2766 if (!(p_rw_cb->p_cback))
2767 {
2768 retval = NFC_STATUS_FAILED;
2769 }
2770 /* If we are not activated, then RW_T3T_PRESENCE_CHECK_EVT status=FAIL */
2771 else if (p_rw_cb->tcb.t3t.rw_state == RW_T3T_STATE_NOT_ACTIVATED)
2772 {
2773 evt_data.status = NFC_STATUS_FAILED;
2774 (*p_rw_cb->p_cback) (RW_T3T_PRESENCE_CHECK_EVT, &evt_data);
2775 }
2776 /* If command is pending */
2777 else if (p_rw_cb->tcb.t3t.rw_state == RW_T3T_STATE_COMMAND_PENDING)
2778 {
2779 /* If already performing presence check, return error */
2780 if (p_rw_cb->tcb.t3t.flags & RW_T3T_FL_W4_PRESENCE_CHECK_POLL_RSP)
2781 {
2782 RW_TRACE_DEBUG0 ("RW_T3tPresenceCheck already in progress");
2783 retval = NFC_STATUS_FAILED;
2784 }
2785 /* If busy with any other command, assume that the tag is present */
2786 else
2787 {
2788 evt_data.status = NFC_STATUS_OK;
2789 (*p_rw_cb->p_cback) (RW_T3T_PRESENCE_CHECK_EVT, &evt_data);
2790 }
2791 }
2792 else
2793 {
2794 /* IDLE state: send POLL command */
2795 if ((retval = (tNFC_STATUS) nci_snd_t3t_polling (0xFFFF, T3T_POLL_RC_SC, 0)) == NCI_STATUS_OK)
2796 {
2797 p_rw_cb->tcb.t3t.flags |= RW_T3T_FL_W4_PRESENCE_CHECK_POLL_RSP;
2798 p_rw_cb->tcb.t3t.rw_state = RW_T3T_STATE_COMMAND_PENDING;
2799 p_rw_cb->tcb.t3t.cur_poll_rc = 0;
2800
2801 /* start timer for waiting for responses */
2802 rw_t3t_start_poll_timer (&p_rw_cb->tcb.t3t);
2803 }
2804 else
2805 {
2806 RW_TRACE_DEBUG1 ("RW_T3tPresenceCheck error sending NCI_RF_T3T_POLLING cmd (status = 0x%0x)", retval);
2807 }
2808 }
2809
2810 return (retval);
2811}
2812
2813/*****************************************************************************
2814**
2815** Function RW_T3tPoll
2816**
2817** Description
2818** Send POLL command
2819**
2820** Returns
2821** NFC_STATUS_OK, if raw data frame sent
2822** NFC_STATUS_NO_BUFFERS: unable to allocate a buffer for this operation
2823** NFC_STATUS_FAILED: other error
2824**
2825*****************************************************************************/
Ruchi Kandoi512ee632017-01-03 13:59:10 -08002826tNFC_STATUS RW_T3tPoll (uint16_t system_code, tT3T_POLL_RC rc, uint8_t tsn)
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002827{
2828 tNFC_STATUS retval = NFC_STATUS_OK;
2829 tRW_T3T_CB *p_cb = &rw_cb.tcb.t3t;
2830
2831 RW_TRACE_API0 ("RW_T3tPoll");
2832
2833 /* Check if we are in valid state to handle this API */
2834 if (p_cb->rw_state != RW_T3T_STATE_IDLE)
2835 {
2836 RW_TRACE_ERROR1 ("Error: invalid state to handle API (0x%x)", p_cb->rw_state);
2837 return (NFC_STATUS_FAILED);
2838 }
2839
Ruchi Kandoi512ee632017-01-03 13:59:10 -08002840 if ((retval = (tNFC_STATUS) nci_snd_t3t_polling (system_code, (uint8_t) rc, tsn)) == NCI_STATUS_OK)
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002841 {
2842 /* start timer for waiting for responses */
2843 p_cb->cur_poll_rc = rc;
2844 p_cb->rw_state = RW_T3T_STATE_COMMAND_PENDING;
2845 rw_t3t_start_poll_timer (p_cb);
2846 }
2847
2848
2849 return (retval);
2850}
2851
2852/*****************************************************************************
2853**
2854** Function RW_T3tSendRawFrame
2855**
2856** Description
2857** This function is called to send a raw data frame to the peer device.
2858** When type 3 tag receives response from peer, the callback function
2859** will be called with a RW_T3T_RAW_FRAME_EVT [Table 6].
2860**
2861** Before using this API, the application must call RW_SelectTagType to
2862** indicate that a Type 3 tag has been activated.
2863**
2864** The raw frame should be a properly formatted Type 3 tag message.
2865**
2866** Returns
2867** NFC_STATUS_OK, if raw data frame sent
2868** NFC_STATUS_NO_BUFFERS: unable to allocate a buffer for this operation
2869** NFC_STATUS_FAILED: other error
2870**
2871*****************************************************************************/
Ruchi Kandoi512ee632017-01-03 13:59:10 -08002872tNFC_STATUS RW_T3tSendRawFrame (uint16_t len, uint8_t *p_data)
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002873{
2874 tNFC_STATUS retval = NFC_STATUS_OK;
2875 tRW_T3T_CB *p_cb = &rw_cb.tcb.t3t;
2876
2877 RW_TRACE_API1 ("RW_T3tSendRawFrame (len = %i)", len);
2878
2879 /* Check if we are in valid state to handle this API */
2880 if (p_cb->rw_state != RW_T3T_STATE_IDLE)
2881 {
2882 RW_TRACE_ERROR1 ("Error: invalid state to handle API (0x%x)", p_cb->rw_state);
2883 return (NFC_STATUS_FAILED);
2884 }
2885
2886 /* Send the UPDATE command */
2887 retval = rw_t3t_send_raw_frame (p_cb, len ,p_data);
2888
2889 return (retval);
2890}
2891
2892/*****************************************************************************
2893**
2894** Function RW_T3tGetSystemCodes
2895**
2896** Description
2897** Get systems codes supported by the activated tag:
Yoshinobu Ito721b3ab2016-08-02 14:41:33 +09002898** Poll for wildcard (FFFF, RC=1):
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002899**
2900** Before using this API, the application must call RW_SelectTagType to
2901** indicate that a Type 3 tag has been activated.
2902**
2903** Returns
2904** NFC_STATUS_OK, if raw data frame sent
2905** NFC_STATUS_NO_BUFFERS: unable to allocate a buffer for this operation
2906** NFC_STATUS_FAILED: other error
2907**
2908*****************************************************************************/
2909tNFC_STATUS RW_T3tGetSystemCodes (void)
2910{
2911 tNFC_STATUS retval = NFC_STATUS_OK;
2912 tRW_T3T_CB *p_cb = &rw_cb.tcb.t3t;
2913
2914 RW_TRACE_API0 ("RW_T3tGetSystemCodes");
2915
2916 /* Check if we are in valid state to handle this API */
2917 if (p_cb->rw_state != RW_T3T_STATE_IDLE)
2918 {
2919 RW_TRACE_ERROR1 ("Error: invalid state to handle API (0x%x)", p_cb->rw_state);
2920 return (NFC_STATUS_FAILED);
2921 }
2922 else
2923 {
2924 if ((retval = (tNFC_STATUS) nci_snd_t3t_polling (0xFFFF, T3T_POLL_RC_SC, 0)) == NCI_STATUS_OK)
2925 {
2926 p_cb->cur_cmd = RW_T3T_CMD_GET_SYSTEM_CODES;
2927 p_cb->cur_tout = RW_T3T_DEFAULT_CMD_TIMEOUT_TICKS;
2928 p_cb->cur_poll_rc = T3T_POLL_RC_SC;
2929 p_cb->rw_state = RW_T3T_STATE_COMMAND_PENDING;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002930 p_cb->flags |= RW_T3T_FL_W4_GET_SC_POLL_RSP;
2931 p_cb->num_system_codes = 0;
2932
2933 /* start timer for waiting for responses */
2934 rw_t3t_start_poll_timer (p_cb);
2935 }
2936 }
2937
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002938 return (retval);
2939}
2940
2941/*****************************************************************************
2942**
2943** Function RW_T3tFormatNDef
2944**
2945** Description
2946** Format a type-3 tag for NDEF.
2947**
2948** Only Felica-Lite tags are supported by this API. The
2949** RW_T3T_FORMAT_CPLT_EVT is used to notify the status of the operation.
2950**
2951** Returns
2952** NFC_STATUS_OK: ndef detection procedure started
2953** NFC_STATUS_NO_BUFFERS: unable to allocate a buffer for this operation
2954** NFC_STATUS_FAILED: other error
2955**
2956*****************************************************************************/
2957tNFC_STATUS RW_T3tFormatNDef (void)
2958{
2959 tNFC_STATUS retval = NFC_STATUS_OK;
2960 tRW_T3T_CB *p_cb = &rw_cb.tcb.t3t;
2961
2962 RW_TRACE_API0 ("RW_T3tFormatNDef");
2963
2964 /* Check if we are in valid state to handle this API */
2965 if (p_cb->rw_state != RW_T3T_STATE_IDLE)
2966 {
2967 RW_TRACE_ERROR1 ("Error: invalid state to handle API (0x%x)", p_cb->rw_state);
2968 return (NFC_STATUS_FAILED);
2969 }
2970 else
2971 {
2972 /* Poll tag, to see if Felica-Lite system is supported */
2973 if ((retval = (tNFC_STATUS) nci_snd_t3t_polling (T3T_SYSTEM_CODE_FELICA_LITE, T3T_POLL_RC_SC, 0)) == NCI_STATUS_OK)
2974 {
2975 p_cb->cur_cmd = RW_T3T_CMD_FORMAT;
2976 p_cb->cur_tout = RW_T3T_DEFAULT_CMD_TIMEOUT_TICKS;
2977 p_cb->cur_poll_rc = T3T_POLL_RC_SC;
2978 p_cb->rw_state = RW_T3T_STATE_COMMAND_PENDING;
2979 p_cb->rw_substate = RW_T3T_FMT_SST_POLL_FELICA_LITE;
2980 p_cb->flags |= RW_T3T_FL_W4_FMT_FELICA_LITE_POLL_RSP;
2981
2982 /* start timer for waiting for responses */
2983 rw_t3t_start_poll_timer (p_cb);
2984 }
2985 }
2986
2987
2988
2989 return (retval);
2990}
Martijn Coenen5c65c3a2013-03-27 13:23:36 -07002991
2992/*****************************************************************************
2993**
2994** Function RW_T3tSetReadOnly
2995**
2996** Description This function performs NDEF read-only procedure
2997** Note: Only Felica-Lite tags are supported by this API.
2998** RW_T3tDetectNDef() must be called before using this
2999**
3000** The RW_T3T_SET_READ_ONLY_CPLT_EVT event will be returned.
3001**
3002** Returns NFC_STATUS_OK if success
3003** NFC_STATUS_FAILED if T3T is busy or other error
3004**
3005*****************************************************************************/
Ruchi Kandoi512ee632017-01-03 13:59:10 -08003006tNFC_STATUS RW_T3tSetReadOnly (bool b_hard_lock)
Martijn Coenen5c65c3a2013-03-27 13:23:36 -07003007{
3008 tNFC_STATUS retval = NFC_STATUS_OK;
3009 tRW_T3T_CB *p_cb = &rw_cb.tcb.t3t;
3010 tRW_DATA evt_data;
3011
Evan Chu7c69b272013-05-14 12:48:36 -04003012 RW_TRACE_API1 ("RW_T3tSetReadOnly (): b_hard_lock=%d", b_hard_lock);
Martijn Coenen5c65c3a2013-03-27 13:23:36 -07003013
3014 /* Check if we are in valid state to handle this API */
3015 if (p_cb->rw_state != RW_T3T_STATE_IDLE)
3016 {
3017 RW_TRACE_ERROR1 ("Error: invalid state to handle API (0x%x)", p_cb->rw_state);
3018 return (NFC_STATUS_FAILED);
3019 }
3020
3021 if (p_cb->ndef_attrib.status != NFC_STATUS_OK) /* NDEF detection not performed yet? */
3022 {
3023 RW_TRACE_ERROR0 ("Error: NDEF detection not performed yet");
3024 return (NFC_STATUS_NOT_INITIALIZED);
3025 }
3026
3027 if ((!b_hard_lock) && (p_cb->ndef_attrib.rwflag == T3T_MSG_NDEF_RWFLAG_RO))/* Tag's NDEF memory is read-only already */
3028 {
3029 evt_data.status = NFC_STATUS_OK;
Evan Chu7c69b272013-05-14 12:48:36 -04003030 (*(rw_cb.p_cback)) (RW_T3T_SET_READ_ONLY_CPLT_EVT, &evt_data);
Martijn Coenen5c65c3a2013-03-27 13:23:36 -07003031 return (retval);
3032 }
3033 else
3034 {
3035 /* Poll tag, to see if Felica-Lite system is supported */
3036 if ((retval = (tNFC_STATUS) nci_snd_t3t_polling (T3T_SYSTEM_CODE_FELICA_LITE, T3T_POLL_RC_SC, 0)) == NCI_STATUS_OK)
3037 {
3038 if (b_hard_lock)
3039 p_cb->cur_cmd = RW_T3T_CMD_SET_READ_ONLY_HARD;
3040 else
3041 p_cb->cur_cmd = RW_T3T_CMD_SET_READ_ONLY_SOFT;
3042 p_cb->cur_tout = RW_T3T_DEFAULT_CMD_TIMEOUT_TICKS;
3043 p_cb->cur_poll_rc = T3T_POLL_RC_SC;
3044 p_cb->rw_state = RW_T3T_STATE_COMMAND_PENDING;
3045 p_cb->rw_substate = RW_T3T_SRO_SST_POLL_FELICA_LITE;
3046 p_cb->flags |= RW_T3T_FL_W4_SRO_FELICA_LITE_POLL_RSP;
3047
3048 /* start timer for waiting for responses */
3049 rw_t3t_start_poll_timer (p_cb);
3050 }
3051 }
3052 return (retval);
3053}