blob: 3fa2af14c11228c0bed651b3dce1d5a549135d8d [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{
99 /* Sub states for getting system codes */
100 RW_T3T_GET_SC_SST_POLL_WILDCARD, /* Waiting for wilcard poll response */
101 RW_T3T_GET_SC_SST_POLL_NDEF, /* Waiting for NDEF poll response */
102 RW_T3T_GET_SC_SST_REQUEST_SC, /* Waiting for REQUEST_SYSTEM_CODE response */
103
104 /* Sub states for formatting Felica-Lite */
105 RW_T3T_FMT_SST_POLL_FELICA_LITE, /* Waiting for POLL Felica-Lite response (for formatting) */
106 RW_T3T_FMT_SST_CHECK_MC_BLK, /* Waiting for Felica-Lite MC (MemoryControl) block-read to complete */
107 RW_T3T_FMT_SST_UPDATE_MC_BLK, /* Waiting for Felica-Lite MC (MemoryControl) block-write to complete */
Martijn Coenen5c65c3a2013-03-27 13:23:36 -0700108 RW_T3T_FMT_SST_UPDATE_NDEF_ATTRIB, /* Waiting for NDEF attribute block-write to complete */
109
110 /* Sub states for setting Felica-Lite read only */
111 RW_T3T_SRO_SST_POLL_FELICA_LITE, /* Waiting for POLL Felica-Lite response (for setting read only) */
112 RW_T3T_SRO_SST_UPDATE_NDEF_ATTRIB, /* Waiting for NDEF attribute block-write to complete */
113 RW_T3T_SRO_SST_CHECK_MC_BLK, /* Waiting for Felica-Lite MC (MemoryControl) block-read to complete */
114 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 -0800115};
116
117#if (BT_TRACE_VERBOSE == TRUE)
Ruchi Kandoi512ee632017-01-03 13:59:10 -0800118static char *rw_t3t_cmd_str (uint8_t cmd_id);
119static char *rw_t3t_state_str (uint8_t state_id);
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800120#endif
121
122
123/* Local static functions */
Ruchi Kandoi512ee632017-01-03 13:59:10 -0800124static void rw_t3t_update_ndef_flag (uint8_t *p_flag);
125static tNFC_STATUS rw_t3t_unselect (uint8_t peer_nfcid2[]);
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800126static BT_HDR *rw_t3t_get_cmd_buf (void);
127static tNFC_STATUS rw_t3t_send_to_lower (BT_HDR *p_msg);
128static void rw_t3t_handle_get_system_codes_cplt (void);
Ruchi Kandoi512ee632017-01-03 13:59:10 -0800129static 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);
130static 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);
131static 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);
132static 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 -0800133
134
135/* Default NDEF attribute information block (used when formatting Felica-Lite tags) */
136#define RW_T3T_DEFAULT_FELICALITE_NBR 4 /* NBr (max block reads per cmd)*/
137#define RW_T3T_DEFAULT_FELICALITE_NBW 1 /* NBw (max block write per cmd)*/
Martijn Coenen5c65c3a2013-03-27 13:23:36 -0700138#define RW_T3T_DEFAULT_FELICALITE_NMAXB (T3T_FELICALITE_NMAXB)
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800139#define RW_T3T_DEFAULT_FELICALITE_ATTRIB_INFO_CHECKSUM ((T3T_MSG_NDEF_VERSION + \
140 RW_T3T_DEFAULT_FELICALITE_NBR + \
141 RW_T3T_DEFAULT_FELICALITE_NBW + \
142 (RW_T3T_DEFAULT_FELICALITE_NMAXB>>8) + \
143 (RW_T3T_DEFAULT_FELICALITE_NMAXB&0xFF) +\
144 T3T_MSG_NDEF_WRITEF_OFF + \
145 T3T_MSG_NDEF_RWFLAG_RW) & 0xFFFF)
146
Ruchi Kandoi512ee632017-01-03 13:59:10 -0800147const uint8_t rw_t3t_default_attrib_info[T3T_MSG_BLOCKSIZE] =
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800148{
149 T3T_MSG_NDEF_VERSION, /* Ver */
150 RW_T3T_DEFAULT_FELICALITE_NBR, /* NBr (max block reads per cmd)*/
151 RW_T3T_DEFAULT_FELICALITE_NBW, /* NBw (max block write per cmd)*/
152 (RW_T3T_DEFAULT_FELICALITE_NMAXB>>8), /* Nmaxb (max size in blocks) */
153 (RW_T3T_DEFAULT_FELICALITE_NMAXB&0xFF), /* Nmaxb (max size in blocks) */
154 0, 0, 0, 0, /* Unused */
155 T3T_MSG_NDEF_WRITEF_OFF, /* WriteF */
156 T3T_MSG_NDEF_RWFLAG_RW, /* RW Flag */
157 0, 0, 0, /* Ln (current size in bytes) */
158
159 (RW_T3T_DEFAULT_FELICALITE_ATTRIB_INFO_CHECKSUM >> 8), /* checksum (high-byte) */
160 (RW_T3T_DEFAULT_FELICALITE_ATTRIB_INFO_CHECKSUM & 0xFF) /* checksum (low-byte) */
161
162};
163
Sherry Smith818b56e2014-05-14 16:46:32 -0700164/* 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 -0800165static const uint32_t rw_t3t_mrti_base [] =
Sherry Smith818b56e2014-05-14 16:46:32 -0700166{
167 302,
168 1208,
169 4832,
170 19328
171};
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800172
Sherry Smith818b56e2014-05-14 16:46:32 -0700173
174/*******************************************************************************
175**
176** Function rw_t3t_check_timeout
177**
178** Description The timeout value is a + b * number_blocks)
179**
180** Returns timeout value in ticks
181**
182*******************************************************************************/
Ruchi Kandoi512ee632017-01-03 13:59:10 -0800183static uint32_t rw_t3t_check_timeout (uint16_t num_blocks)
Sherry Smith818b56e2014-05-14 16:46:32 -0700184{
185 tRW_T3T_CB *p_cb = &rw_cb.tcb.t3t;
Ruchi Kandoi512ee632017-01-03 13:59:10 -0800186 uint32_t timeout;
187 uint32_t extra;
Sherry Smith67fe6102014-06-02 11:01:54 -0700188
Sherry Smith818b56e2014-05-14 16:46:32 -0700189 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 -0700190 /* allow some extra time for driver */
191 extra = (timeout / 10) + RW_T3T_MIN_TIMEOUT_TICKS;
192 timeout += extra;
193
Sherry Smith818b56e2014-05-14 16:46:32 -0700194 return timeout;
195}
196
197/*******************************************************************************
198**
199** Function rw_t3t_update_timeout
200**
201** Description The timeout value is a + b * number_blocks)
202**
203** Returns timeout value in ticks
204**
205*******************************************************************************/
Ruchi Kandoi512ee632017-01-03 13:59:10 -0800206static uint32_t rw_t3t_update_timeout (uint16_t num_blocks)
Sherry Smith818b56e2014-05-14 16:46:32 -0700207{
208 tRW_T3T_CB *p_cb = &rw_cb.tcb.t3t;
Ruchi Kandoi512ee632017-01-03 13:59:10 -0800209 uint32_t timeout;
210 uint32_t extra;
Sherry Smith67fe6102014-06-02 11:01:54 -0700211
Sherry Smith818b56e2014-05-14 16:46:32 -0700212 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 -0700213 /* allow some extra time for driver */
214 extra = (timeout / 10) + RW_T3T_MIN_TIMEOUT_TICKS;
215 timeout += extra;
216
Sherry Smith818b56e2014-05-14 16:46:32 -0700217 return timeout;
218}
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800219/*******************************************************************************
220**
221** Function rw_t3t_process_error
222**
223** Description Process error (timeout or CRC error)
224**
225** Returns none
226**
227*******************************************************************************/
228void rw_t3t_process_error (tNFC_STATUS status)
229{
230 tRW_T3T_CB *p_cb = &rw_cb.tcb.t3t;
Ruchi Kandoi512ee632017-01-03 13:59:10 -0800231 uint8_t evt;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800232 tRW_DATA evt_data;
233 BT_HDR *p_cmd_buf;
234
235 if (p_cb->rw_state == RW_T3T_STATE_COMMAND_PENDING)
236 {
237 if (p_cb->cur_cmd == RW_T3T_CMD_GET_SYSTEM_CODES)
238 {
239 /* For GetSystemCode: either tag did not respond to requested POLL, or REQUEST_SYSTEM_CODE command */
240 rw_t3t_handle_get_system_codes_cplt ();
241 return;
242 }
243 /* Retry sending command if retry-count < max */
244 else if (rw_cb.cur_retry < RW_MAX_RETRIES)
245 {
246 /* retry sending the command */
247 rw_cb.cur_retry++;
248
249 RW_TRACE_DEBUG2 ("T3T retransmission attempt %i of %i", rw_cb.cur_retry, RW_MAX_RETRIES);
250
251 /* allocate a new buffer for message */
252 if ((p_cmd_buf = rw_t3t_get_cmd_buf ()) != NULL)
253 {
254 memcpy (p_cmd_buf, p_cb->p_cur_cmd_buf, sizeof (BT_HDR) + p_cb->p_cur_cmd_buf->offset + p_cb->p_cur_cmd_buf->len);
255
256 if (rw_t3t_send_to_lower (p_cmd_buf) == NFC_STATUS_OK)
257 {
258 /* Start timer for waiting for response */
259 nfc_start_quick_timer (&p_cb->timer, NFC_TTYPE_RW_T3T_RESPONSE, p_cb->cur_tout);
260 return;
261 }
262 else
263 {
264 /* failure - could not send buffer */
265 GKI_freebuf (p_cmd_buf);
266 }
267 }
268 }
269 else
270 {
271 RW_TRACE_DEBUG1 ("T3T maximum retransmission attempts reached (%i)", RW_MAX_RETRIES);
272 }
273
Ruchi Kandoi303fec12016-12-14 13:22:38 -0800274#if (RW_STATS_INCLUDED == TRUE)
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800275 /* update failure count */
276 rw_main_update_fail_stats ();
277#endif /* RW_STATS_INCLUDED */
278
279 p_cb->rw_state = RW_T3T_STATE_IDLE;
280
281 /* Notify app of result (if there was a pending command) */
282 if (p_cb->cur_cmd < RW_T3T_CMD_MAX)
283 {
284 /* If doing presence check, use status=NFC_STATUS_FAILED, otherwise NFC_STATUS_TIMEOUT */
285 evt_data.status = status;
286 evt = rw_t3t_api_res_evt[p_cb->cur_cmd];
287
288 /* Set additional flags for RW_T3T_NDEF_DETECT_EVT */
289 if (evt == RW_T3T_NDEF_DETECT_EVT)
290 {
291 evt_data.ndef.flags = RW_NDEF_FL_UNKNOWN;
Evan Chua24be4f2013-11-13 15:30:16 -0500292 rw_t3t_update_ndef_flag (&evt_data.ndef.flags);
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800293 }
294
295 (*(rw_cb.p_cback)) (evt, &evt_data);
296 }
297 }
298 else
299 {
300 evt_data.status = status;
301 (*(rw_cb.p_cback)) (RW_T3T_INTF_ERROR_EVT, &evt_data);
302 }
303}
304
305/*******************************************************************************
306**
307** Function rw_t3t_start_poll_timer
308**
309** Description Start the timer for T3T POLL Command
310**
311** Returns none
312**
313*******************************************************************************/
314void rw_t3t_start_poll_timer (tRW_T3T_CB *p_cb)
315{
316 nfc_start_quick_timer (&p_cb->poll_timer, NFC_TTYPE_RW_T3T_RESPONSE, RW_T3T_POLL_CMD_TIMEOUT_TICKS);
317}
318
319/*******************************************************************************
320**
321** Function rw_t3t_handle_nci_poll_ntf
322**
323** Description Handle NCI_T3T_POLLING_NTF
324**
325** Returns none
326**
327*******************************************************************************/
Ruchi Kandoi512ee632017-01-03 13:59:10 -0800328void 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 -0800329{
330 tRW_DATA evt_data;
331 tRW_T3T_CB *p_cb = &rw_cb.tcb.t3t;
332
333 /* stop timer for poll response */
334 nfc_stop_quick_timer (&p_cb->poll_timer);
335
336 /* Stop t3t timer (if started) */
337 if (p_cb->flags & RW_T3T_FL_W4_PRESENCE_CHECK_POLL_RSP)
338 {
339 p_cb->flags &= ~RW_T3T_FL_W4_PRESENCE_CHECK_POLL_RSP;
340 evt_data.status = nci_status;
341 p_cb->rw_state = RW_T3T_STATE_IDLE;
342 (*(rw_cb.p_cback)) (RW_T3T_PRESENCE_CHECK_EVT, (tRW_DATA *) &evt_data);
343 }
344 else if (p_cb->flags & RW_T3T_FL_W4_GET_SC_POLL_RSP)
345 {
346 /* Handle POLL ntf in response to get system codes */
347 p_cb->flags &= ~RW_T3T_FL_W4_GET_SC_POLL_RSP;
348 rw_t3t_handle_get_sc_poll_rsp (p_cb, nci_status, num_responses, sensf_res_buf_size, p_sensf_res_buf);
349 }
350 else if (p_cb->flags & RW_T3T_FL_W4_FMT_FELICA_LITE_POLL_RSP)
351 {
352 /* Handle POLL ntf in response to get system codes */
353 p_cb->flags &= ~RW_T3T_FL_W4_FMT_FELICA_LITE_POLL_RSP;
354 rw_t3t_handle_fmt_poll_rsp (p_cb, nci_status, num_responses, sensf_res_buf_size, p_sensf_res_buf);
355 }
Martijn Coenen5c65c3a2013-03-27 13:23:36 -0700356 else if (p_cb->flags & RW_T3T_FL_W4_SRO_FELICA_LITE_POLL_RSP)
357 {
358 /* Handle POLL ntf in response to get system codes */
359 p_cb->flags &= ~RW_T3T_FL_W4_SRO_FELICA_LITE_POLL_RSP;
360 rw_t3t_handle_sro_poll_rsp (p_cb, nci_status, num_responses, sensf_res_buf_size, p_sensf_res_buf);
361 }
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800362 else if (p_cb->flags & RW_T3T_FL_W4_NDEF_DETECT_POLL_RSP)
363 {
364 /* Handle POLL ntf in response to ndef detection */
365 p_cb->flags &= ~RW_T3T_FL_W4_NDEF_DETECT_POLL_RSP;
366 rw_t3t_handle_ndef_detect_poll_rsp (p_cb, nci_status, num_responses, sensf_res_buf_size, p_sensf_res_buf);
367 }
368 else
369 {
370 /* Handle POLL ntf in response to RW_T3tPoll */
371 if ((evt_data.t3t_poll.status = nci_status) == NCI_STATUS_OK)
372 {
373 evt_data.t3t_poll.rc = p_cb->cur_poll_rc;
374 evt_data.t3t_poll.response_num = num_responses;
375 evt_data.t3t_poll.response_bufsize = sensf_res_buf_size;
376 evt_data.t3t_poll.response_buf = p_sensf_res_buf;
377 }
378
379 p_cb->rw_state = RW_T3T_STATE_IDLE;
380 (*(rw_cb.p_cback)) (RW_T3T_POLL_EVT, &evt_data);
381 }
382}
383
384
385/*******************************************************************************
386**
387** Function rw_t3t_handle_get_system_codes_cplt
388**
389** Description Notify upper layer of system codes
390**
391** Returns none
392**
393*******************************************************************************/
394void rw_t3t_handle_get_system_codes_cplt (void)
395{
396 tRW_T3T_CB *p_cb = &rw_cb.tcb.t3t;
397 tRW_DATA evt_data;
Ruchi Kandoi512ee632017-01-03 13:59:10 -0800398 uint8_t i;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800399
400 evt_data.t3t_sc.status = NFC_STATUS_OK;
401 evt_data.t3t_sc.num_system_codes = p_cb->num_system_codes;
402 evt_data.t3t_sc.p_system_codes = p_cb->system_codes;
403
404 RW_TRACE_DEBUG1 ("rw_t3t_handle_get_system_codes_cplt, number of systems: %i", evt_data.t3t_sc.num_system_codes);
405 for (i = 0; i < evt_data.t3t_sc.num_system_codes; i++)
406 {
407 RW_TRACE_DEBUG2 (" system %i: %04X", i, evt_data.t3t_sc.p_system_codes[i]);
408 }
409
410 p_cb->rw_state = RW_T3T_STATE_IDLE;
411 (*(rw_cb.p_cback)) (RW_T3T_GET_SYSTEM_CODES_EVT, &evt_data);
412
413
414}
415
416/*******************************************************************************
417**
418** Function rw_t3t_format_cplt
419**
420** Description Notify upper layer of format complete
421**
422** Returns none
423**
424*******************************************************************************/
425void rw_t3t_format_cplt (tNFC_STATUS status)
426{
427 tRW_T3T_CB *p_cb = &rw_cb.tcb.t3t;
428 tRW_DATA evt_data;
429
430 p_cb->rw_state = RW_T3T_STATE_IDLE;
431
Martijn Coenen5c65c3a2013-03-27 13:23:36 -0700432 /* Update ndef info */
433 p_cb->ndef_attrib.status = status;
434 if (status == NFC_STATUS_OK)
435 {
436 p_cb->ndef_attrib.version = T3T_MSG_NDEF_VERSION;
437 p_cb->ndef_attrib.nbr = RW_T3T_DEFAULT_FELICALITE_NBR;
438 p_cb->ndef_attrib.nbw = RW_T3T_DEFAULT_FELICALITE_NBW;
439 p_cb->ndef_attrib.nmaxb = RW_T3T_DEFAULT_FELICALITE_NMAXB;
440 p_cb->ndef_attrib.writef = T3T_MSG_NDEF_WRITEF_OFF;
441 p_cb->ndef_attrib.rwflag = T3T_MSG_NDEF_RWFLAG_RW;
442 p_cb->ndef_attrib.ln = 0;
443 }
444
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800445 /* Notify upper layer of format complete */
446 evt_data.status = status;
447 (*(rw_cb.p_cback)) (RW_T3T_FORMAT_CPLT_EVT, &evt_data);
448}
449
450/*******************************************************************************
451**
Martijn Coenen5c65c3a2013-03-27 13:23:36 -0700452** Function rw_t3t_set_readonly_cplt
453**
454** Description Notify upper layer of set read only complete
455**
456** Returns none
457**
458*******************************************************************************/
459void rw_t3t_set_readonly_cplt (tNFC_STATUS status)
460{
461 tRW_T3T_CB *p_cb = &rw_cb.tcb.t3t;
462 tRW_DATA evt_data;
463
464 p_cb->rw_state = RW_T3T_STATE_IDLE;
465
466 /* Notify upper layer of format complete */
467 evt_data.status = status;
468 (*(rw_cb.p_cback)) (RW_T3T_SET_READ_ONLY_CPLT_EVT, &evt_data);
469}
470
471/*******************************************************************************
472**
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800473** Function rw_t3t_process_timeout
474**
475** Description Process timeout
476**
477** Returns none
478**
479*******************************************************************************/
480void rw_t3t_process_timeout (TIMER_LIST_ENT *p_tle)
481{
482 tRW_T3T_CB *p_cb = &rw_cb.tcb.t3t;
483 tRW_DATA evt_data;
484
485 /* Check which timer timed out */
486 if (p_tle == &p_cb->timer)
487 {
488 /* UPDATE/CHECK response timeout */
489#if (BT_TRACE_VERBOSE == TRUE)
490 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));
491#else
492 RW_TRACE_ERROR2 ("T3T timeout. state=0x%02X cur_cmd=0x%02X", rw_cb.tcb.t3t.rw_state, rw_cb.tcb.t3t.cur_cmd);
493#endif
494
495 rw_t3t_process_error (NFC_STATUS_TIMEOUT);
496 }
497 else
498 {
499 RW_TRACE_ERROR0 ("T3T POLL timeout.");
500
501 /* POLL response timeout */
502 if (p_cb->flags & RW_T3T_FL_W4_PRESENCE_CHECK_POLL_RSP)
503 {
504 /* POLL timeout for presence check */
505 p_cb->flags &= ~RW_T3T_FL_W4_PRESENCE_CHECK_POLL_RSP;
506 evt_data.status = NFC_STATUS_FAILED;
507 p_cb->rw_state = RW_T3T_STATE_IDLE;
508 (*(rw_cb.p_cback)) (RW_T3T_PRESENCE_CHECK_EVT, (tRW_DATA *) &evt_data);
509 }
510 else if (p_cb->flags & RW_T3T_FL_W4_GET_SC_POLL_RSP)
511 {
512 /* POLL timeout for getting system codes */
513 p_cb->flags &= ~RW_T3T_FL_W4_GET_SC_POLL_RSP;
514 rw_t3t_handle_get_system_codes_cplt ();
515 }
516 else if (p_cb->flags & RW_T3T_FL_W4_FMT_FELICA_LITE_POLL_RSP)
517 {
518 /* POLL timeout for formatting Felica Lite */
519 p_cb->flags &= ~RW_T3T_FL_W4_FMT_FELICA_LITE_POLL_RSP;
520 RW_TRACE_ERROR0 ("Felica-Lite tag not detected");
521 rw_t3t_format_cplt (NFC_STATUS_FAILED);
522 }
Martijn Coenen5c65c3a2013-03-27 13:23:36 -0700523 else if (p_cb->flags & RW_T3T_FL_W4_SRO_FELICA_LITE_POLL_RSP)
524 {
525 /* POLL timeout for configuring Felica Lite read only */
526 p_cb->flags &= ~RW_T3T_FL_W4_SRO_FELICA_LITE_POLL_RSP;
527 RW_TRACE_ERROR0 ("Felica-Lite tag not detected");
528 rw_t3t_set_readonly_cplt (NFC_STATUS_FAILED);
529 }
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800530 else if (p_cb->flags & RW_T3T_FL_W4_NDEF_DETECT_POLL_RSP)
531 {
532 /* POLL timeout for ndef detection */
533 p_cb->flags &= ~RW_T3T_FL_W4_NDEF_DETECT_POLL_RSP;
534 rw_t3t_handle_ndef_detect_poll_rsp (p_cb, NFC_STATUS_TIMEOUT, 0, 0, NULL);
535 }
536 else
537 {
538 /* Timeout waiting for response for RW_T3tPoll */
539 evt_data.t3t_poll.status = NFC_STATUS_FAILED;
540 p_cb->rw_state = RW_T3T_STATE_IDLE;
541 (*(rw_cb.p_cback)) (RW_T3T_POLL_EVT, (tRW_DATA *) &evt_data);
542 }
543 }
544}
545
546
547/*******************************************************************************
548**
549** Function rw_t3t_process_frame_error
550**
551** Description Process frame crc error
552**
553** Returns none
554**
555*******************************************************************************/
556void rw_t3t_process_frame_error (void)
557{
558#if (BT_TRACE_VERBOSE == TRUE)
559 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));
560#else
561 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);
562#endif
563
Ruchi Kandoi303fec12016-12-14 13:22:38 -0800564#if (RW_STATS_INCLUDED == TRUE)
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800565 /* Update stats */
566 rw_main_update_crc_error_stats ();
567#endif /* RW_STATS_INCLUDED */
568
569 /* Process the error */
570 rw_t3t_process_error (NFC_STATUS_MSG_CORRUPTED);
571}
572
573/*******************************************************************************
574**
575** Function rw_t3t_send_to_lower
576**
577** Description Send command to lower layer
578**
579** Returns status of the send
580**
581*******************************************************************************/
582tNFC_STATUS rw_t3t_send_to_lower (BT_HDR *p_msg)
583{
Ruchi Kandoi512ee632017-01-03 13:59:10 -0800584 uint8_t *p;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800585
Ruchi Kandoi303fec12016-12-14 13:22:38 -0800586#if (RW_STATS_INCLUDED == TRUE)
Ruchi Kandoi512ee632017-01-03 13:59:10 -0800587 bool is_retry;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800588 /* Update stats */
Ruchi Kandoi4a179642017-01-04 10:04:48 -0800589 rw_main_update_tx_stats (p_msg->len,
590 ((rw_cb.cur_retry == 0) ? false : true));
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800591#endif /* RW_STATS_INCLUDED */
592
593 /* Set NFC-F SoD field (payload len + 1) */
594 p_msg->offset -= 1; /* Point to SoD field */
Ruchi Kandoi512ee632017-01-03 13:59:10 -0800595 p = (uint8_t *) (p_msg+1) + p_msg->offset;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800596 UINT8_TO_STREAM (p, (p_msg->len+1));
597 p_msg->len += 1; /* Increment len to include SoD */
598
599#if (BT_TRACE_PROTOCOL == TRUE)
Ruchi Kandoi4a179642017-01-04 10:04:48 -0800600 DispT3TagMessage (p_msg, false);
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800601#endif
602
603 return (NFC_SendData (NFC_RF_CONN_ID, p_msg));
604}
605
606/*****************************************************************************
607**
608** Function rw_t3t_get_cmd_buf
609**
610** Description Get a buffer for sending T3T messages
611**
612** Returns BT_HDR *
613**
614*****************************************************************************/
615BT_HDR *rw_t3t_get_cmd_buf (void)
616{
617 BT_HDR *p_cmd_buf;
618
619 if ((p_cmd_buf = (BT_HDR *) GKI_getpoolbuf (NFC_RW_POOL_ID)) != NULL)
620 {
621 /* Reserve offset for NCI_DATA_HDR and NFC-F Sod (LEN) field */
622 p_cmd_buf->offset = NCI_MSG_OFFSET_SIZE + NCI_DATA_HDR_SIZE + 1;
623 p_cmd_buf->len = 0;
624 }
625
626 return (p_cmd_buf);
627}
628
629/*****************************************************************************
630**
631** Function rw_t3t_send_cmd
632**
633** Description Send command to tag, and start timer for response
634**
635** Returns tNFC_STATUS
636**
637*****************************************************************************/
Ruchi Kandoi512ee632017-01-03 13:59:10 -0800638tNFC_STATUS rw_t3t_send_cmd (tRW_T3T_CB *p_cb, uint8_t rw_t3t_cmd, BT_HDR *p_cmd_buf, uint32_t timeout_ticks)
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800639{
640 tNFC_STATUS retval;
641
642 /* Indicate first attempt to send command, back up cmd buffer in case needed for retransmission */
643 rw_cb.cur_retry = 0;
644 memcpy (p_cb->p_cur_cmd_buf, p_cmd_buf, sizeof (BT_HDR) + p_cmd_buf->offset + p_cmd_buf->len);
645
646 p_cb->cur_cmd = rw_t3t_cmd;
Sherry Smith818b56e2014-05-14 16:46:32 -0700647 p_cb->cur_tout = timeout_ticks;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800648 p_cb->rw_state = RW_T3T_STATE_COMMAND_PENDING;
649
650 if ((retval = rw_t3t_send_to_lower (p_cmd_buf)) == NFC_STATUS_OK)
651 {
652 /* Start timer for waiting for response */
Sherry Smith818b56e2014-05-14 16:46:32 -0700653 nfc_start_quick_timer (&p_cb->timer, NFC_TTYPE_RW_T3T_RESPONSE, timeout_ticks);
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800654 }
655 else
656 {
657 /* Error sending */
658 p_cb->rw_state = RW_T3T_STATE_IDLE;
659 }
660
Sherry Smith818b56e2014-05-14 16:46:32 -0700661 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 -0800662 return (retval);
663}
664
665/*****************************************************************************
666**
667** Function rw_t3t_send_update_ndef_attribute_cmd
668**
669** Description Send UPDATE command for Attribute Information
670**
671** Returns tNFC_STATUS
672**
673*****************************************************************************/
Ruchi Kandoi512ee632017-01-03 13:59:10 -0800674tNFC_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 -0800675{
676 tNFC_STATUS retval = NFC_STATUS_OK;
677 BT_HDR *p_cmd_buf;
Ruchi Kandoi512ee632017-01-03 13:59:10 -0800678 uint8_t *p_cmd_start, *p;
679 uint16_t checksum, i;
680 uint8_t write_f;
681 uint32_t ln;
682 uint8_t *p_ndef_attr_info_start;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800683
684 if ((p_cmd_buf = rw_t3t_get_cmd_buf ()) != NULL)
685 {
686 /* Construct T3T message */
Ruchi Kandoi512ee632017-01-03 13:59:10 -0800687 p = p_cmd_start = (uint8_t *) (p_cmd_buf+1) + p_cmd_buf->offset;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800688
689 /* Add UPDATE opcode to message */
690 UINT8_TO_STREAM (p, T3T_MSG_OPC_UPDATE_CMD);
691
692 /* Add IDm to message */
693 ARRAY_TO_STREAM (p, p_cb->peer_nfcid2, NCI_NFCID2_LEN);
694
695 /* Add Service code list */
696 UINT8_TO_STREAM (p, 1); /* Number of services (only 1 service: NDEF) */
697 UINT16_TO_STREAM (p, T3T_MSG_NDEF_SC_RW); /* Service code (little-endian format) */
698
699 /* Add number of blocks in this UPDATE command */
700 UINT8_TO_STREAM (p, 1); /* Number of blocks to write in this command */
701
702 /* Block List element: the NDEF attribute information block (block 0) */
703 UINT8_TO_STREAM (p, T3T_MSG_MASK_TWO_BYTE_BLOCK_DESC_FORMAT);
704 UINT8_TO_STREAM (p, 0);
705
706 /* Add payload (Attribute information block) */
707 p_ndef_attr_info_start = p; /* Save start of a NDEF attribute info block for checksum */
708 UINT8_TO_STREAM (p, T3T_MSG_NDEF_VERSION);
709 UINT8_TO_STREAM (p, p_cb->ndef_attrib.nbr);
710 UINT8_TO_STREAM (p, p_cb->ndef_attrib.nbw);
711 UINT16_TO_BE_STREAM (p, p_cb->ndef_attrib.nmaxb);
712 UINT32_TO_STREAM (p, 0);
713
714 /* If starting NDEF write: set WriteF=ON, and ln=current ndef length */
715 if (write_in_progress)
716 {
717 write_f = T3T_MSG_NDEF_WRITEF_ON;
718 ln = p_cb->ndef_attrib.ln;
719 }
720 /* If finishing NDEF write: set WriteF=OFF, and ln=new ndef len */
721 else
722 {
723 write_f = T3T_MSG_NDEF_WRITEF_OFF;
724 ln = p_cb->ndef_msg_len;
725 }
726 UINT8_TO_STREAM (p, write_f);
727 UINT8_TO_STREAM (p, p_cb->ndef_attrib.rwflag);
728 UINT8_TO_STREAM (p, (ln>>16) & 0xFF); /* High byte (of 3) of Ln */
729 UINT8_TO_STREAM (p, (ln>>8) & 0xFF); /* Middle byte (of 3) of Ln */
730 UINT8_TO_STREAM (p, (ln) & 0xFF); /* Low byte (of 3) of Ln */
731
732 /* Calculate and append Checksum */
733 checksum = 0;
734 for (i = 0; i < T3T_MSG_NDEF_ATTR_INFO_SIZE; i++)
735 {
736 checksum+=p_ndef_attr_info_start[i];
737 }
738 UINT16_TO_BE_STREAM (p, checksum);
739
740
741 /* Calculate length of message */
Ruchi Kandoi512ee632017-01-03 13:59:10 -0800742 p_cmd_buf->len = (uint16_t) (p - p_cmd_start);
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800743
744 /* Send the T3T message */
Sherry Smith818b56e2014-05-14 16:46:32 -0700745 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 -0800746 }
747 else
748 {
749 retval = NFC_STATUS_NO_BUFFERS;
750 }
751
752 return (retval);
753}
754
755/*****************************************************************************
756**
757** Function rw_t3t_send_next_ndef_update_cmd
758**
759** Description Send next segment of NDEF message to update
760**
761** Returns tNFC_STATUS
762**
763*****************************************************************************/
764tNFC_STATUS rw_t3t_send_next_ndef_update_cmd (tRW_T3T_CB *p_cb)
765{
766 tNFC_STATUS retval = NFC_STATUS_OK;
Ruchi Kandoi512ee632017-01-03 13:59:10 -0800767 uint16_t block_id;
768 uint16_t first_block_to_write;
769 uint16_t ndef_blocks_to_write, ndef_blocks_remaining;
770 uint32_t ndef_bytes_remaining, ndef_padding = 0;
771 uint8_t flags = 0;
772 uint8_t *p_cur_ndef_src_offset;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800773 BT_HDR *p_cmd_buf;
Ruchi Kandoi512ee632017-01-03 13:59:10 -0800774 uint8_t *p_cmd_start, *p;
775 uint8_t blocks_per_update;
776 uint32_t timeout;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800777
778 if ((p_cmd_buf = rw_t3t_get_cmd_buf ()) != NULL)
779 {
780 /* Construct T3T message */
Ruchi Kandoi512ee632017-01-03 13:59:10 -0800781 p = p_cmd_start = (uint8_t *) (p_cmd_buf + 1) + p_cmd_buf->offset;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800782
783 /* Calculate number of ndef bytes remaining to write */
784 ndef_bytes_remaining = p_cb->ndef_msg_len - p_cb->ndef_msg_bytes_sent;
785
786 /* Calculate number of blocks remaining to write */
Ruchi Kandoi512ee632017-01-03 13:59:10 -0800787 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 -0800788
789 /* Calculate first NDEF block ID for this UPDATE command */
Ruchi Kandoi512ee632017-01-03 13:59:10 -0800790 first_block_to_write = (uint16_t) ((p_cb->ndef_msg_bytes_sent >> 4) + 1);
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800791
792 /* Calculate max number of blocks per write. */
793 if ((first_block_to_write + RW_T3T_MAX_NDEF_BLOCKS_PER_UPDATE_1_BYTE_FORMAT) < 0x100)
794 {
795 /* All block-numbers are < 0x100 (i.e. can be specified using one-byte format) */
796 blocks_per_update = RW_T3T_MAX_NDEF_BLOCKS_PER_UPDATE_1_BYTE_FORMAT;
797 }
798 else
799 {
800 /* Block-numbers are >= 0x100 (i.e. need to be specified using two-byte format) */
801 blocks_per_update = RW_T3T_MAX_NDEF_BLOCKS_PER_UPDATE_2_BYTE_FORMAT;
802 }
803
804 /* Check if blocks_per_update is bigger than what peer allows */
805 if (blocks_per_update > p_cb->ndef_attrib.nbw)
806 blocks_per_update = p_cb->ndef_attrib.nbw;
807
808 /* Check if remaining blocks can fit into one UPDATE command */
809 if (ndef_blocks_remaining <= blocks_per_update)
810 {
811 /* remaining blocks can fit into one UPDATE command */
812 ndef_blocks_to_write = ndef_blocks_remaining;
813 }
814 else
815 {
816 /* Remaining blocks cannot fit into one UPDATE command */
817 ndef_blocks_to_write = blocks_per_update;
818 }
819
820
821 /* Write to command header for UPDATE */
822
823 /* Add UPDATE opcode to message */
824 UINT8_TO_STREAM (p, T3T_MSG_OPC_UPDATE_CMD);
825
826 /* Add IDm to message */
827 ARRAY_TO_STREAM (p, p_cb->peer_nfcid2, NCI_NFCID2_LEN);
828
829 /* Add Service code list */
830 UINT8_TO_STREAM (p, 1); /* Number of services (only 1 service: NDEF) */
831 UINT16_TO_STREAM (p, T3T_MSG_NDEF_SC_RW); /* Service code (little-endian format) */
832
833
834 /* Add number of blocks in this UPDATE command */
835 UINT8_TO_STREAM (p, ndef_blocks_to_write); /* Number of blocks to write in this command */
Sherry Smith818b56e2014-05-14 16:46:32 -0700836 timeout = rw_t3t_update_timeout(ndef_blocks_to_write);
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800837
838 for (block_id = first_block_to_write; block_id < (first_block_to_write + ndef_blocks_to_write); block_id++)
839 {
840 if (block_id<256)
841 {
842 /* Block IDs 0-255 can be specified in '2-byte' format: byte0=0, byte1=blocknumber */
843 UINT8_TO_STREAM (p, T3T_MSG_MASK_TWO_BYTE_BLOCK_DESC_FORMAT); /* byte0: len=1; access-mode=0; service code list order=0 */
844 UINT8_TO_STREAM (p, block_id); /* byte1: block number */
845 }
846 else
847 {
848 /* Block IDs 256+ must be specified in '3-byte' format: byte0=80h, followed by blocknumber */
849 UINT8_TO_STREAM (p, 0x00); /* byte0: len=0; access-mode=0; service code list order=0 */
850 UINT16_TO_STREAM (p, block_id); /* byte1-2: block number in little-endian format */
851 }
852
853 }
854
855 /* Add NDEF payload */
856
857 /* If this sending last block of NDEF, check if padding is needed to make payload a multiple of 16 bytes */
858 if (ndef_blocks_to_write == ndef_blocks_remaining)
859 {
860 ndef_padding = (16 - (ndef_bytes_remaining & 0x0F)) & 0x0F;
861 if (ndef_padding)
862 {
863 flags |= RW_T3T_FL_PADDING;
864 ndef_blocks_to_write--; /* handle the last block separately if it needs padding */
865 }
866 }
867
868 /* Add NDEF payload to the message */
869 p_cur_ndef_src_offset = &p_cb->ndef_msg[p_cb->ndef_msg_bytes_sent];
870
871
872 ARRAY_TO_STREAM (p, p_cur_ndef_src_offset, (ndef_blocks_to_write * 16));
Ruchi Kandoi512ee632017-01-03 13:59:10 -0800873 p_cb->ndef_msg_bytes_sent += ((uint32_t) ndef_blocks_to_write * 16);
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800874
875 if (flags & RW_T3T_FL_PADDING)
876 {
877 /* Add last of the NDEF message */
878 p_cur_ndef_src_offset = &p_cb->ndef_msg[p_cb->ndef_msg_bytes_sent];
879 ARRAY_TO_STREAM (p, p_cur_ndef_src_offset, (int) (16-ndef_padding));
880 p_cb->ndef_msg_bytes_sent += (16-ndef_padding);
881
882 /* Add padding */
883 memset (p, 0, ndef_padding);
884 p+=ndef_padding;
885 }
886
887 /* Calculate length of message */
Ruchi Kandoi512ee632017-01-03 13:59:10 -0800888 p_cmd_buf->len = (uint16_t) (p - p_cmd_start);
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800889
890 /* Send the T3T message */
891 retval = rw_t3t_send_cmd (p_cb, RW_T3T_CMD_UPDATE_NDEF, p_cmd_buf, timeout);
892 }
893 else
894 {
895 retval = NFC_STATUS_NO_BUFFERS;
896 }
897
898 return (retval);
899}
900
901
902
903/*****************************************************************************
904**
905** Function rw_t3t_send_next_ndef_check_cmd
906**
907** Description Send command for reading next segment of NDEF message
908**
909** Returns tNFC_STATUS
910**
911*****************************************************************************/
912tNFC_STATUS rw_t3t_send_next_ndef_check_cmd (tRW_T3T_CB *p_cb)
913{
914 tNFC_STATUS retval = NFC_STATUS_OK;
Ruchi Kandoi512ee632017-01-03 13:59:10 -0800915 uint16_t block_id;
916 uint16_t ndef_blocks_remaining, first_block_to_read, cur_blocks_to_read;
917 uint32_t ndef_bytes_remaining;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800918 BT_HDR *p_cmd_buf;
Ruchi Kandoi512ee632017-01-03 13:59:10 -0800919 uint8_t *p_cmd_start, *p;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800920
921 if ((p_cmd_buf = rw_t3t_get_cmd_buf ()) != NULL)
922 {
923 /* Construct T3T message */
Ruchi Kandoi512ee632017-01-03 13:59:10 -0800924 p = p_cmd_start = (uint8_t *) (p_cmd_buf+1) + p_cmd_buf->offset;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800925
926 /* Calculate number of ndef bytes remaining to read */
927 ndef_bytes_remaining = p_cb->ndef_attrib.ln - p_cb->ndef_rx_offset;
928
929 /* Calculate number of blocks remaining to read */
Ruchi Kandoi512ee632017-01-03 13:59:10 -0800930 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 -0800931
932 /* Calculate first NDEF block ID */
Ruchi Kandoi512ee632017-01-03 13:59:10 -0800933 first_block_to_read = (uint16_t) ((p_cb->ndef_rx_offset >> 4) + 1);
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800934
935 /* Check if remaining blocks can fit into one CHECK command */
936 if (ndef_blocks_remaining <= p_cb->ndef_attrib.nbr)
937 {
938 /* remaining blocks can fit into one CHECK command */
939 cur_blocks_to_read = ndef_blocks_remaining;
940 p_cb->ndef_rx_readlen = ndef_bytes_remaining;
941 p_cb->flags |= RW_T3T_FL_IS_FINAL_NDEF_SEGMENT;
942 }
943 else
944 {
945 /* Remaining blocks cannot fit into one CHECK command */
946 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 -0800947 p_cb->ndef_rx_readlen = ((uint32_t) p_cb->ndef_attrib.nbr * 16);
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800948 }
949
950 RW_TRACE_DEBUG3 ("rw_t3t_send_next_ndef_check_cmd: bytes_remaining: %i, cur_blocks_to_read: %i, is_final: %i",
951 ndef_bytes_remaining, cur_blocks_to_read, (p_cb->flags & RW_T3T_FL_IS_FINAL_NDEF_SEGMENT));
952
Sherry Smith818b56e2014-05-14 16:46:32 -0700953 /* Add CHECK opcode to message */
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800954 UINT8_TO_STREAM (p, T3T_MSG_OPC_CHECK_CMD);
955
956 /* Add IDm to message */
957 ARRAY_TO_STREAM (p, p_cb->peer_nfcid2, NCI_NFCID2_LEN);
958
959 /* Add Service code list */
960 UINT8_TO_STREAM (p, 1); /* Number of services (only 1 service: NDEF) */
961
962 /* Service code (little-endian format) . If NDEF is read-only, then use T3T_MSG_NDEF_SC_RO, otherwise use T3T_MSG_NDEF_SC_RW */
963 if (p_cb->ndef_attrib.rwflag == T3T_MSG_NDEF_RWFLAG_RO)
964 {
965 UINT16_TO_STREAM (p, T3T_MSG_NDEF_SC_RO);
966 }
967 else
968 {
969 UINT16_TO_STREAM (p, T3T_MSG_NDEF_SC_RW);
970 }
971
Sherry Smith818b56e2014-05-14 16:46:32 -0700972 /* Add number of blocks in this CHECK command */
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800973 UINT8_TO_STREAM (p, cur_blocks_to_read); /* Number of blocks to check in this command */
974
975 for (block_id = first_block_to_read; block_id < (first_block_to_read + cur_blocks_to_read); block_id++)
976 {
977 if (block_id<256)
978 {
979 /* Block IDs 0-255 can be specified in '2-byte' format: byte0=0, byte1=blocknumber */
980 UINT8_TO_STREAM (p, T3T_MSG_MASK_TWO_BYTE_BLOCK_DESC_FORMAT); /* byte1: len=0; access-mode=0; service code list order=0 */
981 UINT8_TO_STREAM (p, block_id); /* byte1: block number */
982 }
983 else
984 {
985 /* Block IDs 256+ must be specified in '3-byte' format: byte0=80h, followed by blocknumber */
986 UINT8_TO_STREAM (p, 0x00); /* byte0: len=1; access-mode=0; service code list order=0 */
987 UINT16_TO_STREAM (p, block_id); /* byte1-2: block number in little-endian format */
988 }
989
990 }
991
992 /* Calculate length of message */
Ruchi Kandoi512ee632017-01-03 13:59:10 -0800993 p_cmd_buf->len = (uint16_t) (p - p_cmd_start);
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800994
995 /* Send the T3T message */
Sherry Smith818b56e2014-05-14 16:46:32 -0700996 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 -0800997 }
998 else
999 {
1000 retval = NFC_STATUS_NO_BUFFERS;
1001 }
1002
1003 return(retval);
1004}
1005
1006
1007/*****************************************************************************
1008**
1009** Function rw_t3t_message_set_block_list
1010**
1011** Description Add block list to T3T message
1012**
1013** Returns Number of bytes added to message
1014**
1015*****************************************************************************/
Ruchi Kandoi512ee632017-01-03 13:59:10 -08001016void 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 -08001017{
Ruchi Kandoi512ee632017-01-03 13:59:10 -08001018 uint16_t i, cur_service_code;
1019 uint8_t service_code_idx, num_services = 0;
1020 uint8_t *p_msg_num_services;
1021 uint16_t service_list[T3T_MSG_SERVICE_LIST_MAX];
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001022
1023 /* Add CHECK or UPDATE opcode to message */
1024 UINT8_TO_STREAM ((*p), ((p_cb->cur_cmd == RW_T3T_CMD_CHECK) ? T3T_MSG_OPC_CHECK_CMD:T3T_MSG_OPC_UPDATE_CMD));
1025
1026 /* Add IDm to message */
1027 ARRAY_TO_STREAM ((*p), p_cb->peer_nfcid2, NCI_NFCID2_LEN);
1028
1029 /* Skip over Number of Services field */
1030 p_msg_num_services = (*p); /* pointer to Number of Services offset */
1031 (*p)++;
1032
1033 /* Count number of different services are specified in the list, and add services to Service Code list */
1034 for (i = 0; i < num_blocks; i++)
1035 {
1036 cur_service_code = p_t3t_blocks[i].service_code;
1037
1038 /* Check if current service_code is already in the service_list */
1039 for (service_code_idx=0; service_code_idx<num_services; service_code_idx++)
1040 {
1041 if (service_list[service_code_idx] == cur_service_code)
1042 break;
1043 }
1044
1045 if (service_code_idx == num_services)
1046 {
1047 /* Service not in the list yet. Add it. */
1048 service_list[service_code_idx] = cur_service_code;
1049 num_services++;
1050
1051 /* Add service code to T3T message */
1052 UINT16_TO_STREAM ((*p), cur_service_code);
1053 }
1054 }
1055
1056 /* Add 'Number of Sservices' to the message */
1057 *p_msg_num_services = num_services;
1058
1059 /* Add 'number of blocks' to the message */
1060 UINT8_TO_STREAM ((*p), num_blocks);
1061
1062 /* Add block descriptors */
1063 for (i = 0; i < num_blocks; i++)
1064 {
1065 cur_service_code = p_t3t_blocks[i].service_code;
1066
1067 /* Check if current service_code is already in the service_list */
1068 for (service_code_idx=0; service_code_idx<num_services; service_code_idx++)
1069 {
1070 if (service_list[service_code_idx] == cur_service_code)
1071 break;
1072 }
1073
1074 /* Add decriptor to T3T message */
1075 if (p_t3t_blocks[i].block_number > 0xFF)
1076 {
1077 UINT8_TO_STREAM ((*p), service_code_idx);
1078 UINT16_TO_STREAM ((*p), p_t3t_blocks[i].block_number);
1079 }
1080 else
1081 {
1082 service_code_idx |= T3T_MSG_MASK_TWO_BYTE_BLOCK_DESC_FORMAT;
1083 UINT8_TO_STREAM ((*p), service_code_idx);
1084 UINT8_TO_STREAM ((*p), p_t3t_blocks[i].block_number);
1085 }
1086 }
1087}
1088
1089/*****************************************************************************
1090**
1091** Function rw_t3t_send_check_cmd
1092**
1093** Description Send CHECK command
1094**
1095** Returns tNFC_STATUS
1096**
1097*****************************************************************************/
Ruchi Kandoi512ee632017-01-03 13:59:10 -08001098tNFC_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 -08001099{
1100 BT_HDR *p_cmd_buf;
Ruchi Kandoi512ee632017-01-03 13:59:10 -08001101 uint8_t *p, *p_cmd_start;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001102 tNFC_STATUS retval = NFC_STATUS_OK;
1103
1104 p_cb->cur_cmd = RW_T3T_CMD_CHECK;
1105 if ((p_cmd_buf = rw_t3t_get_cmd_buf ()) != NULL)
1106 {
1107 /* Construct T3T message */
Ruchi Kandoi512ee632017-01-03 13:59:10 -08001108 p = p_cmd_start = (uint8_t *) (p_cmd_buf+1) + p_cmd_buf->offset;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001109 rw_t3t_message_set_block_list (p_cb, &p, num_blocks, p_t3t_blocks);
1110
1111 /* Calculate length of message */
Ruchi Kandoi512ee632017-01-03 13:59:10 -08001112 p_cmd_buf->len = (uint16_t) (p - p_cmd_start);
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001113
1114 /* Send the T3T message */
Sherry Smith818b56e2014-05-14 16:46:32 -07001115 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 -08001116 }
1117 else
1118 {
1119 retval = NFC_STATUS_NO_BUFFERS;
1120 }
1121
1122 return(retval);
1123}
1124
1125/*****************************************************************************
1126**
1127** Function rw_t3t_send_update_cmd
1128**
1129** Description Send UPDATE command
1130**
1131** Returns tNFC_STATUS
1132**
1133*****************************************************************************/
Ruchi Kandoi512ee632017-01-03 13:59:10 -08001134tNFC_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 -08001135{
1136 BT_HDR *p_cmd_buf;
Ruchi Kandoi512ee632017-01-03 13:59:10 -08001137 uint8_t *p, *p_cmd_start;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001138 tNFC_STATUS retval = NFC_STATUS_OK;
1139
1140 p_cb->cur_cmd = RW_T3T_CMD_UPDATE;
1141 if ((p_cmd_buf = rw_t3t_get_cmd_buf ()) != NULL)
1142 {
1143 /* Construct T3T message */
Ruchi Kandoi512ee632017-01-03 13:59:10 -08001144 p = p_cmd_start = (uint8_t *) (p_cmd_buf+1) + p_cmd_buf->offset;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001145 rw_t3t_message_set_block_list (p_cb, &p, num_blocks, p_t3t_blocks);
1146
1147 /* Add data blocks to the message */
1148 ARRAY_TO_STREAM (p, p_data, num_blocks*16);
1149
1150 /* Calculate length of message */
Ruchi Kandoi512ee632017-01-03 13:59:10 -08001151 p_cmd_buf->len = (uint16_t) (p - p_cmd_start);
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001152
1153 /* Send the T3T message */
Sherry Smith818b56e2014-05-14 16:46:32 -07001154 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 -08001155 }
1156 else
1157 {
1158 retval = NFC_STATUS_NO_BUFFERS;
1159 }
1160
1161 return(retval);
1162}
1163
1164/*****************************************************************************
1165**
Martijn Coenen5c65c3a2013-03-27 13:23:36 -07001166** Function rw_t3t_check_mc_block
1167**
1168** Description Send command to check Memory Configuration Block
1169**
1170** Returns tNFC_STATUS
1171**
1172*****************************************************************************/
1173tNFC_STATUS rw_t3t_check_mc_block (tRW_T3T_CB *p_cb)
1174{
1175 BT_HDR *p_cmd_buf;
Ruchi Kandoi512ee632017-01-03 13:59:10 -08001176 uint8_t *p, *p_cmd_start;
Martijn Coenen5c65c3a2013-03-27 13:23:36 -07001177
1178 /* Read Memory Configuration block */
1179 if ((p_cmd_buf = rw_t3t_get_cmd_buf ()) != NULL)
1180 {
1181 /* Construct T3T message */
Ruchi Kandoi512ee632017-01-03 13:59:10 -08001182 p = p_cmd_start = (uint8_t *) (p_cmd_buf+1) + p_cmd_buf->offset;
Martijn Coenen5c65c3a2013-03-27 13:23:36 -07001183
1184 /* Add CHECK opcode to message */
1185 UINT8_TO_STREAM (p, T3T_MSG_OPC_CHECK_CMD);
1186
1187 /* Add IDm to message */
1188 ARRAY_TO_STREAM (p, p_cb->peer_nfcid2, NCI_NFCID2_LEN);
1189
1190 /* Add Service code list */
1191 UINT8_TO_STREAM (p, 1); /* Number of services (only 1 service: NDEF) */
1192 UINT16_TO_STREAM (p, T3T_MSG_NDEF_SC_RO); /* Service code (little-endian format) */
1193
1194 /* Number of blocks */
1195 UINT8_TO_STREAM (p, 1); /* Number of blocks (only 1 block: Memory Configuration Information ) */
1196
1197 /* Block List element: the Memory Configuration block (block 0x88) */
1198 UINT8_TO_STREAM (p, T3T_MSG_MASK_TWO_BYTE_BLOCK_DESC_FORMAT);
1199 UINT8_TO_STREAM (p, T3T_MSG_FELICALITE_BLOCK_ID_MC);
1200
1201 /* Calculate length of message */
Ruchi Kandoi512ee632017-01-03 13:59:10 -08001202 p_cmd_buf->len = (uint16_t) (p - p_cmd_start);
Martijn Coenen5c65c3a2013-03-27 13:23:36 -07001203
1204 /* Send the T3T message */
Sherry Smith818b56e2014-05-14 16:46:32 -07001205 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 -07001206 }
1207 else
1208 {
1209 RW_TRACE_ERROR0 ("Unable to allocate buffer to read MC block");
1210 return (NFC_STATUS_NO_BUFFERS);
1211 }
1212}
1213
1214/*****************************************************************************
1215**
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001216** Function rw_t3t_send_raw_frame
1217**
1218** Description Send raw frame
1219**
1220** Returns tNFC_STATUS
1221**
1222*****************************************************************************/
Ruchi Kandoi512ee632017-01-03 13:59:10 -08001223tNFC_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 -08001224{
1225 BT_HDR *p_cmd_buf;
Ruchi Kandoi512ee632017-01-03 13:59:10 -08001226 uint8_t *p;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001227 tNFC_STATUS retval = NFC_STATUS_OK;
1228
1229 if ((p_cmd_buf = rw_t3t_get_cmd_buf ()) != NULL)
1230 {
1231 /* Construct T3T message */
Ruchi Kandoi512ee632017-01-03 13:59:10 -08001232 p = (uint8_t *) (p_cmd_buf+1) + p_cmd_buf->offset;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001233
1234 /* Add data blocks to the message */
1235 ARRAY_TO_STREAM (p, p_data, len);
1236
1237 /* Calculate length of message */
1238 p_cmd_buf->len = len;
1239
1240 /* Send the T3T message */
1241 retval = rw_t3t_send_cmd (p_cb, RW_T3T_CMD_SEND_RAW_FRAME, p_cmd_buf, RW_T3T_RAW_FRAME_CMD_TIMEOUT_TICKS);
1242 }
1243 else
1244 {
1245 retval = NFC_STATUS_NO_BUFFERS;
1246 }
1247
1248 return (retval);
1249}
1250
1251
1252/*****************************************************************************
1253** TAG RESPONSE HANDLERS
1254*****************************************************************************/
1255
1256
1257/*****************************************************************************
1258**
1259** Function rw_t3t_act_handle_ndef_detect_rsp
1260**
1261** Description Handle response to NDEF detection
1262**
1263** Returns Nothing
1264**
1265*****************************************************************************/
1266void rw_t3t_act_handle_ndef_detect_rsp (tRW_T3T_CB *p_cb, BT_HDR *p_msg_rsp)
1267{
Ruchi Kandoi512ee632017-01-03 13:59:10 -08001268 uint8_t *p;
1269 uint32_t temp;
1270 uint8_t i;
1271 uint16_t checksum_calc, checksum_rx;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001272 tRW_DETECT_NDEF_DATA evt_data;
Ruchi Kandoi512ee632017-01-03 13:59:10 -08001273 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 -08001274
1275 evt_data.status = NFC_STATUS_FAILED;
1276 evt_data.flags = RW_NDEF_FL_UNKNOWN;
1277
1278 /* Check if response code is CHECK resp (for reading NDEF attribute block) */
1279 if (p_t3t_rsp[T3T_MSG_RSP_OFFSET_RSPCODE] != T3T_MSG_OPC_CHECK_RSP)
1280 {
1281 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]);
1282 evt_data.status = NFC_STATUS_FAILED;
1283 }
1284 /* Validate status code and NFCID2 response from tag */
1285 else if ( (p_t3t_rsp[T3T_MSG_RSP_OFFSET_STATUS1] != T3T_MSG_RSP_STATUS_OK) /* verify response status code */
1286 ||(memcmp (p_cb->peer_nfcid2, &p_t3t_rsp[T3T_MSG_RSP_OFFSET_IDM], NCI_NFCID2_LEN) != 0) ) /* verify response IDm */
1287 {
1288 evt_data.status = NFC_STATUS_FAILED;
1289 }
1290 else
1291 {
1292 /* Get checksum from received ndef attribute msg */
1293 p = &p_t3t_rsp[T3T_MSG_RSP_OFFSET_CHECK_DATA+T3T_MSG_NDEF_ATTR_INFO_SIZE];
1294 BE_STREAM_TO_UINT16 (checksum_rx, p);
1295
1296 /* Calculate checksum - move check for checsum to beginning */
1297 checksum_calc = 0;
1298 p = &p_t3t_rsp[T3T_MSG_RSP_OFFSET_CHECK_DATA];
1299 for (i = 0; i < T3T_MSG_NDEF_ATTR_INFO_SIZE; i++)
1300 {
1301 checksum_calc+=p[i];
1302 }
1303
1304 /* Validate checksum */
1305 if (checksum_calc != checksum_rx)
1306 {
1307 p_cb->ndef_attrib.status = NFC_STATUS_FAILED; /* only ok or failed passed to the app. can be boolean*/
1308
1309 RW_TRACE_ERROR0 ("RW_T3tDetectNDEF checksum failed");
1310 }
1311 else
1312 {
1313 p_cb->ndef_attrib.status = NFC_STATUS_OK;
1314
1315 /* Validate version number */
1316 STREAM_TO_UINT8 (p_cb->ndef_attrib.version, p);
1317
1318 if (T3T_GET_MAJOR_VERSION (T3T_MSG_NDEF_VERSION) < T3T_GET_MAJOR_VERSION (p_cb->ndef_attrib.version))
1319 {
1320 /* Remote tag's MajorVer is newer than our's. Reject NDEF as per T3TOP RQ_T3T_NDA_024 */
1321 RW_TRACE_ERROR2 ("RW_T3tDetectNDEF: incompatible NDEF version. Local=0x%02x, Remote=0x%02x", T3T_MSG_NDEF_VERSION, p_cb->ndef_attrib.version);
1322 p_cb->ndef_attrib.status = NFC_STATUS_FAILED;
1323 evt_data.status = NFC_STATUS_BAD_RESP;
1324 }
1325 else
1326 {
1327 /* Remote tag's MajorVer is equal or older than our's. NDEF is compatible with our version. */
1328
1329 /* Update NDEF info */
1330 STREAM_TO_UINT8 (p_cb->ndef_attrib.nbr, p); /* NBr: number of blocks that can be read using one Check command */
1331 STREAM_TO_UINT8 (p_cb->ndef_attrib.nbw, p); /* Nbw: number of blocks that can be written using one Update command */
1332 BE_STREAM_TO_UINT16 (p_cb->ndef_attrib.nmaxb, p); /* Nmaxb: maximum number of blocks available for NDEF data */
1333 BE_STREAM_TO_UINT32 (temp, p);
1334 STREAM_TO_UINT8 (p_cb->ndef_attrib.writef, p); /* WriteFlag: 00h if writing data finished; 0Fh if writing data in progress */
1335 STREAM_TO_UINT8 (p_cb->ndef_attrib.rwflag, p); /* RWFlag: 00h NDEF is read-only; 01h if read/write available */
1336
1337 /* Get length (3-byte, big-endian) */
1338 STREAM_TO_UINT8 (temp, p); /* Ln: high-byte */
1339 BE_STREAM_TO_UINT16 (p_cb->ndef_attrib.ln, p); /* Ln: lo-word */
1340 p_cb->ndef_attrib.ln += (temp << 16);
1341
1342
1343 RW_TRACE_DEBUG1 ("Detected NDEF Ver: 0x%02x", p_cb->ndef_attrib.version);
1344 RW_TRACE_DEBUG6 ("Detected NDEF Attributes: Nbr=%i, Nbw=%i, Nmaxb=%i, WriteF=%i, RWFlag=%i, Ln=%i",
1345 p_cb->ndef_attrib.nbr,
1346 p_cb->ndef_attrib.nbw,
1347 p_cb->ndef_attrib.nmaxb,
1348 p_cb->ndef_attrib.writef,
1349 p_cb->ndef_attrib.rwflag,
1350 p_cb->ndef_attrib.ln);
1351
1352 /* Set data for RW_T3T_NDEF_DETECT_EVT */
1353 evt_data.status = p_cb->ndef_attrib.status;
1354 evt_data.cur_size = p_cb->ndef_attrib.ln;
Ruchi Kandoi512ee632017-01-03 13:59:10 -08001355 evt_data.max_size = (uint32_t) p_cb->ndef_attrib.nmaxb * 16;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001356 evt_data.protocol = NFC_PROTOCOL_T3T;
1357 evt_data.flags = (RW_NDEF_FL_SUPPORTED | RW_NDEF_FL_FORMATED);
1358 if (p_cb->ndef_attrib.rwflag == T3T_MSG_NDEF_RWFLAG_RO)
1359 evt_data.flags |= RW_NDEF_FL_READ_ONLY;
1360 }
1361 }
1362 }
1363
1364 RW_TRACE_DEBUG1 ("RW_T3tDetectNDEF response: %i", evt_data.status);
1365
1366 p_cb->rw_state = RW_T3T_STATE_IDLE;
Evan Chua24be4f2013-11-13 15:30:16 -05001367 rw_t3t_update_ndef_flag (&evt_data.flags);
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001368 /* Notify app of NDEF detection result */
1369 (*(rw_cb.p_cback)) (RW_T3T_NDEF_DETECT_EVT, (tRW_DATA *) &evt_data);
1370
1371 GKI_freebuf (p_msg_rsp);
1372}
1373
1374
1375/*****************************************************************************
1376**
1377** Function rw_t3t_act_handle_check_rsp
1378**
1379** Description Handle response to CHECK command
1380**
1381** Returns Nothing
1382**
1383*****************************************************************************/
1384void rw_t3t_act_handle_check_rsp (tRW_T3T_CB *p_cb, BT_HDR *p_msg_rsp)
1385{
Ruchi Kandoi512ee632017-01-03 13:59:10 -08001386 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 -08001387 tRW_READ_DATA evt_data;
1388 tNFC_STATUS nfc_status = NFC_STATUS_OK;
1389
1390 /* Validate response from tag */
1391 if ( (p_t3t_rsp[T3T_MSG_RSP_OFFSET_STATUS1] != T3T_MSG_RSP_STATUS_OK) /* verify response status code */
1392 ||(memcmp (p_cb->peer_nfcid2, &p_t3t_rsp[T3T_MSG_RSP_OFFSET_IDM], NCI_NFCID2_LEN) != 0) ) /* verify response IDm */
1393 {
1394 nfc_status = NFC_STATUS_FAILED;
1395 GKI_freebuf (p_msg_rsp);
1396 }
1397 else if (p_t3t_rsp[T3T_MSG_RSP_OFFSET_RSPCODE] != T3T_MSG_OPC_CHECK_RSP)
1398 {
1399 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]);
1400 nfc_status = NFC_STATUS_FAILED;
1401 GKI_freebuf (p_msg_rsp);
1402 }
1403 else
1404 {
1405 /* Copy incoming data into buffer */
1406 p_msg_rsp->offset += T3T_MSG_RSP_OFFSET_CHECK_DATA; /* Skip over t3t header */
1407 p_msg_rsp->len -= T3T_MSG_RSP_OFFSET_CHECK_DATA;
1408 evt_data.status = NFC_STATUS_OK;
1409 evt_data.p_data = p_msg_rsp;
1410 (*(rw_cb.p_cback)) (RW_T3T_CHECK_EVT, (tRW_DATA *) &evt_data);
1411 }
1412
1413
1414 p_cb->rw_state = RW_T3T_STATE_IDLE;
1415
1416 (*(rw_cb.p_cback)) (RW_T3T_CHECK_CPLT_EVT, (tRW_DATA *) &nfc_status);
1417}
1418
1419/*****************************************************************************
1420**
1421** Function rw_t3t_act_handle_update_rsp
1422**
1423** Description Handle response to UPDATE command
1424**
1425** Returns Nothing
1426**
1427*****************************************************************************/
1428void rw_t3t_act_handle_update_rsp (tRW_T3T_CB *p_cb, BT_HDR *p_msg_rsp)
1429{
Ruchi Kandoi512ee632017-01-03 13:59:10 -08001430 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 -08001431 tRW_READ_DATA evt_data;
1432
1433 /* Validate response from tag */
1434 if ( (p_t3t_rsp[T3T_MSG_RSP_OFFSET_STATUS1] != T3T_MSG_RSP_STATUS_OK) /* verify response status code */
1435 ||(memcmp (p_cb->peer_nfcid2, &p_t3t_rsp[T3T_MSG_RSP_OFFSET_IDM], NCI_NFCID2_LEN) != 0) ) /* verify response IDm */
1436 {
1437 evt_data.status = NFC_STATUS_FAILED;
1438 }
1439 else if (p_t3t_rsp[T3T_MSG_RSP_OFFSET_RSPCODE] != T3T_MSG_OPC_UPDATE_RSP)
1440 {
1441 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]);
1442 evt_data.status = NFC_STATUS_FAILED;
1443 }
1444 else
1445 {
1446 /* Copy incoming data into buffer */
1447 evt_data.status = NFC_STATUS_OK;
1448 }
1449
1450 p_cb->rw_state = RW_T3T_STATE_IDLE;
1451
1452 (*(rw_cb.p_cback)) (RW_T3T_UPDATE_CPLT_EVT, (tRW_DATA *)&evt_data);
1453
1454 GKI_freebuf (p_msg_rsp);
1455}
1456
1457/*****************************************************************************
1458**
1459** Function rw_t3t_act_handle_raw_senddata_rsp
1460**
1461** Description Handle response to NDEF detection
1462**
1463** Returns Nothing
1464**
1465*****************************************************************************/
Evan Chua24be4f2013-11-13 15:30:16 -05001466void 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 -08001467{
1468 tRW_READ_DATA evt_data;
Evan Chua24be4f2013-11-13 15:30:16 -05001469 BT_HDR *p_pkt = p_data->p_data;
1470
1471#if (BT_TRACE_VERBOSE == TRUE)
1472 RW_TRACE_DEBUG2 ("RW T3T Raw Frame: Len [0x%X] Status [%s]", p_pkt->len, NFC_GetStatusName (p_data->status));
1473#else
1474 RW_TRACE_DEBUG2 ("RW T3T Raw Frame: Len [0x%X] Status [0x%X]", p_pkt->len, p_data->status);
1475#endif
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001476
1477 /* Copy incoming data into buffer */
Evan Chua24be4f2013-11-13 15:30:16 -05001478 evt_data.status = p_data->status;
1479 evt_data.p_data = p_pkt;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001480
1481 p_cb->rw_state = RW_T3T_STATE_IDLE;
1482
1483 (*(rw_cb.p_cback)) (RW_T3T_RAW_FRAME_EVT, (tRW_DATA *) &evt_data);
1484}
1485
1486/*****************************************************************************
1487**
1488** Function rw_t3t_act_handle_check_ndef_rsp
1489**
1490** Description Handle response to NDEF read segment
1491**
1492** Returns Nothing
1493**
1494*****************************************************************************/
1495void rw_t3t_act_handle_check_ndef_rsp (tRW_T3T_CB *p_cb, BT_HDR *p_msg_rsp)
1496{
Ruchi Kandoi4a179642017-01-04 10:04:48 -08001497 bool check_complete = true;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001498 tNFC_STATUS nfc_status = NFC_STATUS_OK;
1499 tRW_READ_DATA read_data;
1500 tRW_DATA evt_data;
Ruchi Kandoi512ee632017-01-03 13:59:10 -08001501 uint8_t *p_t3t_rsp = (uint8_t *) (p_msg_rsp+1) + p_msg_rsp->offset;
1502 uint8_t rsp_num_bytes_rx;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001503
1504 /* Validate response from tag */
1505 if ( (p_t3t_rsp[T3T_MSG_RSP_OFFSET_STATUS1] != T3T_MSG_RSP_STATUS_OK) /* verify response status code */
1506 ||(memcmp (p_cb->peer_nfcid2, &p_t3t_rsp[T3T_MSG_RSP_OFFSET_IDM], NCI_NFCID2_LEN) != 0) /* verify response IDm */
1507 ||(p_t3t_rsp[T3T_MSG_RSP_OFFSET_NUMBLOCKS] != ((p_cb->ndef_rx_readlen+15) >> 4)) ) /* verify length of response */
1508 {
1509 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));
1510 nfc_status = NFC_STATUS_FAILED;
1511 GKI_freebuf (p_msg_rsp);
1512 }
1513 else if (p_t3t_rsp[T3T_MSG_RSP_OFFSET_RSPCODE] != T3T_MSG_OPC_CHECK_RSP)
1514 {
1515 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]);
1516 nfc_status = NFC_STATUS_FAILED;
1517 GKI_freebuf (p_msg_rsp);
1518 }
1519 else
1520 {
1521 /* Notify app of NDEF segment received */
1522 rsp_num_bytes_rx = p_t3t_rsp[T3T_MSG_RSP_OFFSET_NUMBLOCKS] * 16; /* Number of bytes received, according to header */
1523 p_cb->ndef_rx_offset += p_cb->ndef_rx_readlen;
1524 read_data.status = NFC_STATUS_OK;
1525 p_msg_rsp->offset += T3T_MSG_RSP_OFFSET_CHECK_DATA; /* Skip over t3t header (point to block data) */
1526 p_msg_rsp->len -= T3T_MSG_RSP_OFFSET_CHECK_DATA;
1527
1528 /* Verify that the bytes received is really the amount indicated in the check-response header */
1529 if (rsp_num_bytes_rx > p_msg_rsp->len)
1530 {
1531 RW_TRACE_ERROR2 ("Response error: CHECK rsp header indicates %i bytes, but only received %i bytes", rsp_num_bytes_rx, p_msg_rsp->len);
1532 nfc_status = NFC_STATUS_FAILED;
1533 GKI_freebuf (p_msg_rsp);
1534 }
1535 else
1536 {
1537 /* If this is the the final block, then set len to reflect only valid bytes (do not include padding to 16-byte boundary) */
1538 if ((p_cb->flags & RW_T3T_FL_IS_FINAL_NDEF_SEGMENT) && (p_cb->ndef_attrib.ln & 0x000F))
1539 {
1540 rsp_num_bytes_rx -= (16 - (p_cb->ndef_attrib.ln & 0x000F));
1541 }
1542
1543 p_msg_rsp->len = rsp_num_bytes_rx;
1544 read_data.p_data = p_msg_rsp;
1545 (*(rw_cb.p_cback)) (RW_T3T_CHECK_EVT, (tRW_DATA *) &read_data);
1546
1547 /* Send CHECK cmd for next NDEF segment, if needed */
1548 if (!(p_cb->flags & RW_T3T_FL_IS_FINAL_NDEF_SEGMENT))
1549 {
1550 if ((nfc_status = rw_t3t_send_next_ndef_check_cmd (p_cb)) == NFC_STATUS_OK)
1551 {
1552 /* Still getting more segments. Don't send RW_T3T_CHECK_CPLT_EVT yet */
Ruchi Kandoi4a179642017-01-04 10:04:48 -08001553 check_complete = false;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001554 }
1555 }
1556 }
1557 }
1558
1559 /* Notify app of RW_T3T_CHECK_CPLT_EVT if entire NDEF has been read, or if failure */
1560 if (check_complete)
1561 {
1562 p_cb->rw_state = RW_T3T_STATE_IDLE;
1563 evt_data.status = nfc_status;
1564 (*(rw_cb.p_cback)) (RW_T3T_CHECK_CPLT_EVT, (tRW_DATA *) &evt_data);
1565 }
1566}
1567
1568
1569/*****************************************************************************
1570**
1571** Function rw_t3t_act_handle_update_ndef_rsp
1572**
1573** Description Handle response to NDEF write segment
1574**
1575** Returns Nothing
1576**
1577*****************************************************************************/
1578void rw_t3t_act_handle_update_ndef_rsp (tRW_T3T_CB *p_cb, BT_HDR *p_msg_rsp)
1579{
Ruchi Kandoi4a179642017-01-04 10:04:48 -08001580 bool update_complete = true;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001581 tNFC_STATUS nfc_status = NFC_STATUS_OK;
1582 tRW_DATA evt_data;
Ruchi Kandoi512ee632017-01-03 13:59:10 -08001583 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 -08001584
1585 /* Check nfcid2 and status of response */
1586 if ( (p_t3t_rsp[T3T_MSG_RSP_OFFSET_STATUS1] != T3T_MSG_RSP_STATUS_OK) /* verify response status code */
1587 ||(memcmp (p_cb->peer_nfcid2, &p_t3t_rsp[T3T_MSG_RSP_OFFSET_IDM], NCI_NFCID2_LEN) != 0) ) /* verify response IDm */
1588 {
1589 nfc_status = NFC_STATUS_FAILED;
1590 }
1591 /* Validate response opcode */
1592 else if (p_t3t_rsp[T3T_MSG_RSP_OFFSET_RSPCODE] != T3T_MSG_OPC_UPDATE_RSP)
1593 {
1594 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]);
1595 nfc_status = NFC_STATUS_FAILED;
1596 }
1597 /* If this is response to final UPDATE, then update NDEF local size */
1598 else if (p_cb->flags & RW_T3T_FL_IS_FINAL_NDEF_SEGMENT)
1599 {
1600 /* If successful, update current NDEF size */
1601 p_cb->ndef_attrib.ln = p_cb->ndef_msg_len;
1602 }
1603 /* If any more NDEF bytes to update, then send next UPDATE command */
1604 else if (p_cb->ndef_msg_bytes_sent < p_cb->ndef_msg_len)
1605 {
1606 /* Send UPDATE command for next segment of NDEF */
1607 if ((nfc_status = rw_t3t_send_next_ndef_update_cmd (p_cb)) == NFC_STATUS_OK)
1608 {
1609 /* Wait for update response */
Ruchi Kandoi4a179642017-01-04 10:04:48 -08001610 update_complete = false;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001611 }
1612 }
1613 /* Otherwise, no more NDEF bytes. Send final UPDATE for Attribute Information block */
1614 else
1615 {
1616 p_cb->flags |= RW_T3T_FL_IS_FINAL_NDEF_SEGMENT;
Ruchi Kandoi4a179642017-01-04 10:04:48 -08001617 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 -08001618 {
1619 /* Wait for update response */
Ruchi Kandoi4a179642017-01-04 10:04:48 -08001620 update_complete = false;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001621 }
1622 }
1623
1624 /* If update is completed, then notify app */
1625 if (update_complete)
1626 {
1627 p_cb->rw_state = RW_T3T_STATE_IDLE;
1628 evt_data.status = nfc_status;
1629 (*(rw_cb.p_cback)) (RW_T3T_UPDATE_CPLT_EVT, (tRW_DATA *) &evt_data);
1630 }
1631
1632
1633 GKI_freebuf (p_msg_rsp);
1634
1635 return;
1636}
1637
1638
1639/*****************************************************************************
1640**
1641** Function rw_t3t_handle_get_sc_poll_rsp
1642**
1643** Description Handle POLL response for getting system codes
1644**
1645** Returns Nothing
1646**
1647*****************************************************************************/
Ruchi Kandoi512ee632017-01-03 13:59:10 -08001648static 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 -08001649{
1650 BT_HDR *p_cmd_buf;
Ruchi Kandoi512ee632017-01-03 13:59:10 -08001651 uint8_t *p, *p_cmd_start;
1652 uint16_t sc;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001653 tNFC_STATUS status = NFC_STATUS_FAILED;
1654
1655 /* If waiting for wildcard POLL */
1656 if (p_cb->rw_substate == RW_T3T_GET_SC_SST_POLL_WILDCARD)
1657 {
1658 /* Get the system code from the response */
1659 if ( (nci_status == NCI_STATUS_OK)
1660 &&(num_responses > 0)
1661 &&(sensf_res_buf_size >= (RW_T3T_SENSF_RES_RD_OFFSET + RW_T3T_SENSF_RES_RD_LEN)) )
1662 {
1663 p = &p_sensf_res_buf[RW_T3T_SENSF_RES_RD_OFFSET];
1664 BE_STREAM_TO_UINT16 (sc, p);
1665
1666 /* Handle felica lite */
1667 if (sc == T3T_SYSTEM_CODE_FELICA_LITE)
1668 {
1669 RW_TRACE_DEBUG1 ("FeliCa Lite tag detected (system code %04X)", sc);
1670 /* Store system code */
1671 p_cb->system_codes[p_cb->num_system_codes++] = sc;
1672
1673 /* Poll for NDEF system code */
The Android Open Source Project808ebf82012-12-13 15:18:55 -08001674 if ((status = (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 -08001675 {
1676 p_cb->rw_substate = RW_T3T_GET_SC_SST_POLL_NDEF;
1677 p_cb->cur_poll_rc = 0;
1678 p_cb->flags |= RW_T3T_FL_W4_GET_SC_POLL_RSP;
1679
1680 /* start timer for waiting for responses */
1681 rw_t3t_start_poll_timer (p_cb);
1682 }
1683 }
1684 else
1685 {
1686 /* All other types, send REQUEST_SYSTEM_CODE command */
1687 if ((p_cmd_buf = rw_t3t_get_cmd_buf ()) != NULL)
1688 {
1689 p_cb->rw_substate = RW_T3T_GET_SC_SST_REQUEST_SC;
1690
1691 /* Construct T3T message */
Ruchi Kandoi512ee632017-01-03 13:59:10 -08001692 p_cmd_start = p = (uint8_t *) (p_cmd_buf+1) + p_cmd_buf->offset;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001693 UINT8_TO_STREAM (p, T3T_MSG_OPC_REQ_SYSTEMCODE_CMD);
1694 ARRAY_TO_STREAM (p, p_cb->peer_nfcid2, NCI_NFCID2_LEN);
1695
1696 /* Fill in length field */
Ruchi Kandoi512ee632017-01-03 13:59:10 -08001697 p_cmd_buf->len = (uint16_t) (p - p_cmd_start);
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001698
1699 /* Send the T3T message */
1700 status = rw_t3t_send_cmd (p_cb, RW_T3T_CMD_GET_SYSTEM_CODES, p_cmd_buf, RW_T3T_DEFAULT_CMD_TIMEOUT_TICKS);
1701 }
1702 }
1703 }
1704
1705 /* Error proceeding. Notify upper layer of system codes found so far */
1706 if (status != NFC_STATUS_OK)
1707 {
1708 rw_t3t_handle_get_system_codes_cplt ();
1709 }
1710 }
1711 /* If waiting for NDEF POLL */
1712 else if (p_cb->rw_substate == RW_T3T_GET_SC_SST_POLL_NDEF)
1713 {
1714 /* Validate response for NDEF poll */
1715 if ((nci_status == NCI_STATUS_OK) && (num_responses > 0))
1716 {
1717 /* Tag responded for NDEF poll */
1718 p_cb->system_codes[p_cb->num_system_codes++] = T3T_SYSTEM_CODE_NDEF;
1719 }
1720 rw_t3t_handle_get_system_codes_cplt ();
1721 }
1722}
1723
1724/*****************************************************************************
1725**
1726** Function rw_t3t_handle_ndef_detect_poll_rsp
1727**
1728** Description Handle POLL response for getting system codes
1729**
1730** Returns Nothing
1731**
1732*****************************************************************************/
Ruchi Kandoi512ee632017-01-03 13:59:10 -08001733static 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 -08001734{
1735 BT_HDR *p_cmd_buf;
Ruchi Kandoi512ee632017-01-03 13:59:10 -08001736 uint8_t *p, *p_cmd_start;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001737 tRW_DATA evt_data;
1738
1739 /* Validate response for NDEF poll */
1740 if ((nci_status == NCI_STATUS_OK) && (num_responses > 0))
1741 {
1742 /* Tag responded for NDEF poll */
1743
1744 /* Read NDEF attribute block */
1745 if ((p_cmd_buf = rw_t3t_get_cmd_buf ()) != NULL)
1746 {
1747 /* Construct T3T message */
Ruchi Kandoi512ee632017-01-03 13:59:10 -08001748 p = p_cmd_start = (uint8_t *) (p_cmd_buf+1) + p_cmd_buf->offset;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001749
1750 /* Add CHECK opcode to message */
1751 UINT8_TO_STREAM (p, T3T_MSG_OPC_CHECK_CMD);
1752
1753 /* Add IDm to message */
1754 ARRAY_TO_STREAM (p, p_cb->peer_nfcid2, NCI_NFCID2_LEN);
1755
1756 /* Add Service code list */
1757 UINT8_TO_STREAM (p, 1); /* Number of services (only 1 service: NDEF) */
1758 UINT16_TO_STREAM (p, T3T_MSG_NDEF_SC_RO); /* Service code (little-endian format) */
1759
1760 /* Number of blocks */
1761 UINT8_TO_STREAM (p, 1); /* Number of blocks (only 1 block: NDEF Attribute Information ) */
1762
1763 /* Block List element: the NDEF attribute information block (block 0) */
1764 UINT8_TO_STREAM (p, T3T_MSG_MASK_TWO_BYTE_BLOCK_DESC_FORMAT);
1765 UINT8_TO_STREAM (p, 0);
1766
1767 /* Calculate length of message */
Ruchi Kandoi512ee632017-01-03 13:59:10 -08001768 p_cmd_buf->len = (uint16_t) (p - 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 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 -08001772 {
1773 /* CHECK command sent. Wait for response */
1774 return;
1775 }
1776 }
1777 nci_status = NFC_STATUS_FAILED;
1778 }
1779
1780 /* NDEF detection failed */
1781 p_cb->rw_state = RW_T3T_STATE_IDLE;
1782 evt_data.ndef.status = nci_status;
1783 evt_data.ndef.flags = RW_NDEF_FL_UNKNOWN;
Evan Chua24be4f2013-11-13 15:30:16 -05001784 rw_t3t_update_ndef_flag (&evt_data.ndef.flags);
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001785 (*(rw_cb.p_cback)) (RW_T3T_NDEF_DETECT_EVT, &evt_data);
1786}
1787
1788
1789/*****************************************************************************
1790**
1791** Function rw_t3t_act_handle_get_sc_rsp
1792**
1793** Description Handle response for getting system codes
1794**
1795** Returns Nothing
1796**
1797*****************************************************************************/
1798void rw_t3t_act_handle_get_sc_rsp (tRW_T3T_CB *p_cb, BT_HDR *p_msg_rsp)
1799{
Ruchi Kandoi512ee632017-01-03 13:59:10 -08001800 uint8_t *p_t3t_rsp = (uint8_t *) (p_msg_rsp+1) + p_msg_rsp->offset;
1801 uint8_t *p;
1802 uint16_t sc;
1803 uint8_t num_sc, i;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001804
1805 /* Validate response opcode */
1806 if (p_t3t_rsp[T3T_MSG_RSP_OFFSET_RSPCODE] != T3T_MSG_OPC_REQ_SYSTEMCODE_RSP)
1807 {
1808 RW_TRACE_ERROR2 ("Response error: expecting rsp_code %02X, but got %02X", T3T_MSG_OPC_REQ_SYSTEMCODE_RSP, p_t3t_rsp[T3T_MSG_RSP_OFFSET_RSPCODE]);
1809 }
1810 else
1811 {
1812 /* Point to number of systems parameter */
1813 p = &p_t3t_rsp[T3T_MSG_RSP_OFFSET_NUMSYS];
1814 STREAM_TO_UINT8 (num_sc, p);
1815
1816 /* Validate maximum */
1817 if (num_sc>T3T_MAX_SYSTEM_CODES)
1818 {
1819 RW_TRACE_DEBUG2 ("Tag's number of systems (%i) exceeds NFA max (%i)", num_sc, T3T_MAX_SYSTEM_CODES);
1820 num_sc = T3T_MAX_SYSTEM_CODES;
1821 }
1822
1823 for (i = 0; i < num_sc; i++)
1824 {
1825 BE_STREAM_TO_UINT16 (sc, p);
1826 p_cb->system_codes[p_cb->num_system_codes++] = sc;
1827 }
1828 }
1829 rw_t3t_handle_get_system_codes_cplt ();
1830
1831 GKI_freebuf (p_msg_rsp);
1832}
1833
1834/*****************************************************************************
1835**
1836** Function rw_t3t_update_block
1837**
Martijn Coenen5c65c3a2013-03-27 13:23:36 -07001838** Description Send UPDATE command for single block
1839** (for formatting/configuring read only)
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001840**
1841** Returns tNFC_STATUS
1842**
1843*****************************************************************************/
Ruchi Kandoi512ee632017-01-03 13:59:10 -08001844tNFC_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 -08001845{
Ruchi Kandoi512ee632017-01-03 13:59:10 -08001846 uint8_t *p_dst, *p_cmd_start;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001847 BT_HDR *p_cmd_buf;
1848 tNFC_STATUS status;
1849
1850 if ((p_cmd_buf = rw_t3t_get_cmd_buf ()) != NULL)
1851 {
Ruchi Kandoi512ee632017-01-03 13:59:10 -08001852 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 -08001853
1854 /* Add UPDATE opcode to message */
1855 UINT8_TO_STREAM (p_dst, T3T_MSG_OPC_UPDATE_CMD);
1856
1857 /* Add IDm to message */
1858 ARRAY_TO_STREAM (p_dst, p_cb->peer_nfcid2, NCI_NFCID2_LEN);
1859
1860 /* Add Service code list */
1861 UINT8_TO_STREAM (p_dst, 1); /* Number of services (only 1 service: NDEF) */
1862 UINT16_TO_STREAM (p_dst, T3T_MSG_NDEF_SC_RW); /* Service code (little-endian format) */
1863
1864 /* Number of blocks */
1865 UINT8_TO_STREAM (p_dst, 1);
1866
1867 /* Add Block list element for MC */
1868 UINT8_TO_STREAM (p_dst, T3T_MSG_MASK_TWO_BYTE_BLOCK_DESC_FORMAT);
1869 UINT8_TO_STREAM (p_dst, block_id);
1870
1871 /* Copy MC data to UPDATE message */
1872 ARRAY_TO_STREAM (p_dst, p_block_data, T3T_MSG_BLOCKSIZE);
1873
1874 /* Calculate length of message */
Ruchi Kandoi512ee632017-01-03 13:59:10 -08001875 p_cmd_buf->len = (uint16_t) (p_dst - p_cmd_start);
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001876
1877 /* Send the T3T message */
Sherry Smith818b56e2014-05-14 16:46:32 -07001878 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 -08001879 }
1880 else
1881 {
1882 /* Unable to send UPDATE command */
1883 status = NFC_STATUS_NO_BUFFERS;
1884 }
1885
1886 return (status);
1887}
1888
1889/*****************************************************************************
1890**
1891** Function rw_t3t_handle_fmt_poll_rsp
1892**
1893** Description Handle POLL response for formatting felica-lite
1894**
1895** Returns Nothing
1896**
1897*****************************************************************************/
Ruchi Kandoi512ee632017-01-03 13:59:10 -08001898static 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 -08001899{
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001900 tRW_DATA evt_data;
1901
1902 evt_data.status = NFC_STATUS_OK;
1903
1904 /* Validate response for poll response */
1905 if ((nci_status == NCI_STATUS_OK) && (num_responses > 0))
1906 {
1907 /* Tag responded for Felica-Lite poll */
1908 /* Get MemoryControl block */
1909 RW_TRACE_DEBUG0 ("Felica-Lite tag detected...getting Memory Control block.");
1910
Martijn Coenen5c65c3a2013-03-27 13:23:36 -07001911 p_cb->rw_substate = RW_T3T_FMT_SST_CHECK_MC_BLK;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001912
Martijn Coenen5c65c3a2013-03-27 13:23:36 -07001913 /* Send command to check Memory Configuration block */
1914 evt_data.status = rw_t3t_check_mc_block (p_cb);
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001915 }
1916 else
1917 {
1918 RW_TRACE_ERROR0 ("Felica-Lite tag not detected");
1919 evt_data.status = NFC_STATUS_FAILED;
1920 }
1921
1922 /* If error, notify upper layer */
1923 if (evt_data.status != NFC_STATUS_OK)
1924 {
1925 rw_t3t_format_cplt (evt_data.status);
1926 }
1927}
1928
1929/*****************************************************************************
1930**
1931** Function rw_t3t_act_handle_fmt_rsp
1932**
1933** Description Handle response for formatting codes
1934**
1935** Returns Nothing
1936**
1937*****************************************************************************/
1938void rw_t3t_act_handle_fmt_rsp (tRW_T3T_CB *p_cb, BT_HDR *p_msg_rsp)
1939{
Ruchi Kandoi512ee632017-01-03 13:59:10 -08001940 uint8_t *p_t3t_rsp = (uint8_t *) (p_msg_rsp+1) + p_msg_rsp->offset;
1941 uint8_t *p_mc;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001942 tRW_DATA evt_data;
1943
1944 evt_data.status = NFC_STATUS_OK;
1945
1946 /* Check tags's response for reading MemoryControl block */
1947 if (p_cb->rw_substate == RW_T3T_FMT_SST_CHECK_MC_BLK)
1948 {
1949 /* Validate response opcode */
1950 if (p_t3t_rsp[T3T_MSG_RSP_OFFSET_RSPCODE] != T3T_MSG_OPC_CHECK_RSP)
1951 {
1952 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]);
1953 evt_data.status = NFC_STATUS_FAILED;
1954 }
1955 /* Validate status code and NFCID2 response from tag */
1956 else if ( (p_t3t_rsp[T3T_MSG_RSP_OFFSET_STATUS1] != T3T_MSG_RSP_STATUS_OK) /* verify response status code */
1957 ||(memcmp (p_cb->peer_nfcid2, &p_t3t_rsp[T3T_MSG_RSP_OFFSET_IDM], NCI_NFCID2_LEN) != 0) ) /* verify response IDm */
1958 {
1959 evt_data.status = NFC_STATUS_FAILED;
1960 }
1961 else
1962 {
1963 /* Check if memory configuration (MC) block to see if SYS_OP=1 (NDEF enabled) */
1964 p_mc = &p_t3t_rsp[T3T_MSG_RSP_OFFSET_CHECK_DATA]; /* Point to MC data of CHECK response */
1965
1966 if (p_mc[T3T_MSG_FELICALITE_MC_OFFSET_SYS_OP] != 0x01)
1967 {
1968 /* Tag is not currently enabled for NDEF. Indicate that we need to update the MC block */
1969
1970 /* Set SYS_OP field to 0x01 (enable NDEF) */
1971 p_mc[T3T_MSG_FELICALITE_MC_OFFSET_SYS_OP] = 0x01;
1972
Martijn Coenen5c65c3a2013-03-27 13:23:36 -07001973 /* Set RF_PRM field to 0x07 (procedure of issuance) */
1974 p_mc[T3T_MSG_FELICALITE_MC_OFFSET_RF_PRM] = 0x07;
1975
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001976 /* Construct and send UPDATE message to write MC block */
1977 p_cb->rw_substate = RW_T3T_FMT_SST_UPDATE_MC_BLK;
1978 evt_data.status = rw_t3t_update_block (p_cb, T3T_MSG_FELICALITE_BLOCK_ID_MC, p_mc);
1979 }
1980 else
1981 {
1982 /* SYS_OP=1: ndef already enabled. Just need to update attribute information block */
1983 p_cb->rw_substate = RW_T3T_FMT_SST_UPDATE_NDEF_ATTRIB;
Ruchi Kandoi512ee632017-01-03 13:59:10 -08001984 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 -08001985 }
1986 }
1987
1988 /* If error, notify upper layer */
1989 if (evt_data.status != NFC_STATUS_OK)
1990 {
1991 rw_t3t_format_cplt (evt_data.status);
1992 }
1993 }
1994 else if (p_cb->rw_substate == RW_T3T_FMT_SST_UPDATE_MC_BLK)
1995 {
1996 /* Validate response opcode */
1997 if ( (p_t3t_rsp[T3T_MSG_RSP_OFFSET_RSPCODE] != T3T_MSG_OPC_UPDATE_RSP)
1998 ||(p_t3t_rsp[T3T_MSG_RSP_OFFSET_STATUS1] != T3T_MSG_RSP_STATUS_OK) )
1999
2000 {
2001 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]);
2002 evt_data.status = NFC_STATUS_FAILED;
2003 }
2004 else
2005 {
2006 /* SYS_OP=1: ndef already enabled. Just need to update attribute information block */
2007 p_cb->rw_substate = RW_T3T_FMT_SST_UPDATE_NDEF_ATTRIB;
Ruchi Kandoi512ee632017-01-03 13:59:10 -08002008 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 -08002009 }
2010
2011 /* If error, notify upper layer */
2012 if (evt_data.status != NFC_STATUS_OK)
2013 {
2014 rw_t3t_format_cplt (evt_data.status);
2015 }
2016 }
2017 else if (p_cb->rw_substate == RW_T3T_FMT_SST_UPDATE_NDEF_ATTRIB)
2018 {
2019 /* Validate response opcode */
2020 if ( (p_t3t_rsp[T3T_MSG_RSP_OFFSET_RSPCODE] != T3T_MSG_OPC_UPDATE_RSP)
2021 ||(p_t3t_rsp[T3T_MSG_RSP_OFFSET_STATUS1] != T3T_MSG_RSP_STATUS_OK) )
2022
2023 {
2024 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]);
2025 evt_data.status = NFC_STATUS_FAILED;
2026 }
2027
2028
2029 rw_t3t_format_cplt (evt_data.status);
2030 }
2031
2032 GKI_freebuf (p_msg_rsp);
2033}
2034
Martijn Coenen5c65c3a2013-03-27 13:23:36 -07002035/*****************************************************************************
2036**
2037** Function rw_t3t_handle_sro_poll_rsp
2038**
2039** Description Handle POLL response for configuring felica-lite read only
2040**
2041** Returns Nothing
2042**
2043*****************************************************************************/
Ruchi Kandoi512ee632017-01-03 13:59:10 -08002044static 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 -07002045{
2046 tRW_DATA evt_data;
Ruchi Kandoi512ee632017-01-03 13:59:10 -08002047 uint8_t rw_t3t_ndef_attrib_info[T3T_MSG_BLOCKSIZE];
2048 uint8_t *p;
2049 uint8_t tempU8;
2050 uint16_t checksum, i;
2051 uint32_t tempU32 = 0;
Martijn Coenen5c65c3a2013-03-27 13:23:36 -07002052
2053 evt_data.status = NFC_STATUS_OK;
2054
2055 /* Validate response for poll response */
2056 if ((nci_status == NCI_STATUS_OK) && (num_responses > 0))
2057 {
2058 /* Tag responded for Felica-Lite poll */
2059 if (p_cb->ndef_attrib.rwflag != T3T_MSG_NDEF_RWFLAG_RO)
2060 {
2061 /* First update attribute information block */
2062 RW_TRACE_DEBUG0 ("Felica-Lite tag detected...update NDef attribution block.");
2063
2064 p_cb->rw_substate = RW_T3T_SRO_SST_UPDATE_NDEF_ATTRIB;
2065
2066 p = rw_t3t_ndef_attrib_info;
2067
2068 UINT8_TO_STREAM (p, p_cb->ndef_attrib.version);
2069
2070 /* Update NDEF info */
2071 UINT8_TO_STREAM (p, p_cb->ndef_attrib.nbr); /* NBr: number of blocks that can be read using one Check command */
2072 UINT8_TO_STREAM (p, p_cb->ndef_attrib.nbw); /* Nbw: number of blocks that can be written using one Update command */
2073 UINT16_TO_BE_STREAM (p, p_cb->ndef_attrib.nmaxb); /* Nmaxb: maximum number of blocks available for NDEF data */
2074 UINT32_TO_BE_STREAM (p, tempU32);
2075 UINT8_TO_STREAM (p, p_cb->ndef_attrib.writef); /* WriteFlag: 00h if writing data finished; 0Fh if writing data in progress */
2076 UINT8_TO_STREAM (p, 0x00); /* RWFlag: 00h NDEF is read-only */
2077
Ruchi Kandoi512ee632017-01-03 13:59:10 -08002078 tempU8 = (uint8_t) (p_cb->ndef_attrib.ln >> 16);
Martijn Coenen5c65c3a2013-03-27 13:23:36 -07002079 /* Get length (3-byte, big-endian) */
2080 UINT8_TO_STREAM (p, tempU8); /* Ln: high-byte */
2081 UINT16_TO_BE_STREAM (p, p_cb->ndef_attrib.ln); /* Ln: lo-word */
2082
2083 /* Calculate and append Checksum */
2084 checksum = 0;
2085 for (i = 0; i < T3T_MSG_NDEF_ATTR_INFO_SIZE; i++)
2086 {
2087 checksum+=rw_t3t_ndef_attrib_info[i];
2088 }
2089 UINT16_TO_BE_STREAM (p, checksum);
2090
Ruchi Kandoi512ee632017-01-03 13:59:10 -08002091 evt_data.status = rw_t3t_update_block (p_cb, 0, (uint8_t *) rw_t3t_ndef_attrib_info);
Martijn Coenen5c65c3a2013-03-27 13:23:36 -07002092 }
2093 else if (p_cb->cur_cmd == RW_T3T_CMD_SET_READ_ONLY_HARD)
2094 {
2095 /* NDEF is already read only, Read and update MemoryControl block */
2096 RW_TRACE_DEBUG0 ("Felica-Lite tag detected...getting Memory Control block.");
2097 p_cb->rw_substate = RW_T3T_SRO_SST_CHECK_MC_BLK;
2098
2099 /* Send command to check Memory Configuration block */
2100 evt_data.status = rw_t3t_check_mc_block (p_cb);
2101 }
2102 }
2103 else
2104 {
2105 RW_TRACE_ERROR0 ("Felica-Lite tag not detected");
2106 evt_data.status = NFC_STATUS_FAILED;
2107 }
2108
2109 /* If error, notify upper layer */
2110 if (evt_data.status != NFC_STATUS_OK)
2111 {
2112 rw_t3t_set_readonly_cplt (evt_data.status);
2113 }
2114}
2115
2116/*****************************************************************************
2117**
2118** Function rw_t3t_act_handle_sro_rsp
2119**
2120** Description Handle response for setting read only codes
2121**
2122** Returns Nothing
2123**
2124*****************************************************************************/
2125void rw_t3t_act_handle_sro_rsp (tRW_T3T_CB *p_cb, BT_HDR *p_msg_rsp)
2126{
Ruchi Kandoi512ee632017-01-03 13:59:10 -08002127 uint8_t *p_t3t_rsp = (uint8_t *) (p_msg_rsp+1) + p_msg_rsp->offset;
2128 uint8_t *p_mc;
Martijn Coenen5c65c3a2013-03-27 13:23:36 -07002129 tRW_DATA evt_data;
2130
2131 evt_data.status = NFC_STATUS_OK;
2132
2133 if (p_cb->rw_substate == RW_T3T_SRO_SST_UPDATE_NDEF_ATTRIB)
2134 {
2135 /* Validate response opcode */
2136 if ( (p_t3t_rsp[T3T_MSG_RSP_OFFSET_RSPCODE] != T3T_MSG_OPC_UPDATE_RSP)
2137 ||(p_t3t_rsp[T3T_MSG_RSP_OFFSET_STATUS1] != T3T_MSG_RSP_STATUS_OK) )
2138
2139 {
2140 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]);
2141 evt_data.status = NFC_STATUS_FAILED;
2142 }
2143 else
2144 {
2145 p_cb->ndef_attrib.rwflag = T3T_MSG_NDEF_RWFLAG_RO;
2146 if (p_cb->cur_cmd == RW_T3T_CMD_SET_READ_ONLY_HARD)
2147 {
2148 p_cb->rw_substate = RW_T3T_SRO_SST_CHECK_MC_BLK;
2149
2150 /* Send command to check Memory Configuration block */
2151 evt_data.status = rw_t3t_check_mc_block (p_cb);
2152 }
2153 else
2154 {
2155 rw_t3t_set_readonly_cplt (evt_data.status);
2156 }
2157 }
2158 }
2159 else if (p_cb->rw_substate == RW_T3T_SRO_SST_CHECK_MC_BLK)
2160 {
2161 /* Check tags's response for reading MemoryControl block, Validate response opcode */
2162 if (p_t3t_rsp[T3T_MSG_RSP_OFFSET_RSPCODE] != T3T_MSG_OPC_CHECK_RSP)
2163 {
2164 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]);
2165 evt_data.status = NFC_STATUS_FAILED;
2166 }
2167 /* Validate status code and NFCID2 response from tag */
2168 else if ( (p_t3t_rsp[T3T_MSG_RSP_OFFSET_STATUS1] != T3T_MSG_RSP_STATUS_OK) /* verify response status code */
2169 ||(memcmp (p_cb->peer_nfcid2, &p_t3t_rsp[T3T_MSG_RSP_OFFSET_IDM], NCI_NFCID2_LEN) != 0) ) /* verify response IDm */
2170 {
2171 evt_data.status = NFC_STATUS_FAILED;
2172 }
2173 else
2174 {
2175 /* Check if memory configuration (MC) block to see if SYS_OP=1 (NDEF enabled) */
2176 p_mc = &p_t3t_rsp[T3T_MSG_RSP_OFFSET_CHECK_DATA]; /* Point to MC data of CHECK response */
2177
2178 if (p_mc[T3T_MSG_FELICALITE_MC_OFFSET_SYS_OP] != 0x01)
2179 {
2180 /* Tag is not currently enabled for NDEF */
2181 evt_data.status = NFC_STATUS_FAILED;
2182 }
2183 else
2184 {
2185 /* Set MC_SP field with MC[0] = 0x00 & MC[1] = 0xC0 (Hardlock) to change access permission from RW to RO */
2186 p_mc[T3T_MSG_FELICALITE_MC_OFFSET_MC_SP] = 0x00;
2187 /* Not changing the access permission of Subtraction Register and MC[0:1] */
2188 p_mc[T3T_MSG_FELICALITE_MC_OFFSET_MC_SP + 1] = 0xC0;
2189
2190 /* Set RF_PRM field to 0x07 (procedure of issuance) */
2191 p_mc[T3T_MSG_FELICALITE_MC_OFFSET_RF_PRM] = 0x07;
2192
2193 /* Construct and send UPDATE message to write MC block */
2194 p_cb->rw_substate = RW_T3T_SRO_SST_UPDATE_MC_BLK;
2195 evt_data.status = rw_t3t_update_block (p_cb, T3T_MSG_FELICALITE_BLOCK_ID_MC, p_mc);
2196 }
2197 }
2198 }
2199 else if (p_cb->rw_substate == RW_T3T_SRO_SST_UPDATE_MC_BLK)
2200 {
2201 /* Validate response opcode */
2202 if ( (p_t3t_rsp[T3T_MSG_RSP_OFFSET_RSPCODE] != T3T_MSG_OPC_UPDATE_RSP)
2203 ||(p_t3t_rsp[T3T_MSG_RSP_OFFSET_STATUS1] != T3T_MSG_RSP_STATUS_OK) )
2204
2205 {
2206 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]);
2207 evt_data.status = NFC_STATUS_FAILED;
2208 }
2209 else
2210 {
2211 rw_t3t_set_readonly_cplt (evt_data.status);
2212 }
2213 }
2214
2215 /* If error, notify upper layer */
2216 if (evt_data.status != NFC_STATUS_OK)
2217 {
2218 rw_t3t_set_readonly_cplt (evt_data.status);
2219 }
2220
2221 GKI_freebuf (p_msg_rsp);
2222}
2223
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002224/*******************************************************************************
2225**
2226** Function rw_t3t_data_cback
2227**
2228** Description This callback function receives the data from NFCC.
2229**
2230** Returns none
2231**
2232*******************************************************************************/
Ruchi Kandoi512ee632017-01-03 13:59:10 -08002233void rw_t3t_data_cback (uint8_t conn_id, tNFC_DATA_CEVT *p_data)
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002234{
Evan Chua24be4f2013-11-13 15:30:16 -05002235 tRW_T3T_CB *p_cb = &rw_cb.tcb.t3t;
2236 BT_HDR *p_msg = p_data->p_data;
Ruchi Kandoi4a179642017-01-04 10:04:48 -08002237 bool free_msg = false; /* if TRUE, free msg buffer before returning */
Ruchi Kandoi512ee632017-01-03 13:59:10 -08002238 uint8_t *p, sod;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002239
2240 /* Stop rsponse timer */
2241 nfc_stop_quick_timer (&p_cb->timer);
2242
Ruchi Kandoi303fec12016-12-14 13:22:38 -08002243#if (RW_STATS_INCLUDED == TRUE)
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002244 /* Update rx stats */
2245 rw_main_update_rx_stats (p_msg->len);
2246#endif /* RW_STATS_INCLUDED */
2247
2248 /* Check if we are expecting a response */
2249 if (p_cb->rw_state != RW_T3T_STATE_COMMAND_PENDING)
2250 {
2251 /*
2252 ** This must be raw frame response
2253 ** send raw frame to app with SoD
2254 */
Evan Chua24be4f2013-11-13 15:30:16 -05002255 rw_t3t_act_handle_raw_senddata_rsp (p_cb, p_data);
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002256 }
2257 /* Sanity check: verify msg len is big enough to contain t3t header */
2258 else if (p_msg->len < T3T_MSG_RSP_COMMON_HDR_LEN)
2259 {
2260 RW_TRACE_ERROR1 ("T3T: invalid Type3 Tag Message (invalid len: %i)", p_msg->len);
Ruchi Kandoi4a179642017-01-04 10:04:48 -08002261 free_msg = true;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002262
2263 rw_t3t_process_frame_error ();
2264 }
2265 else
2266 {
2267 /* Check for RF frame error */
Ruchi Kandoi512ee632017-01-03 13:59:10 -08002268 p = (uint8_t *) (p_msg+1) + p_msg->offset;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002269 sod = p[0];
2270 if (p[sod] != NCI_STATUS_OK)
2271 {
2272 RW_TRACE_ERROR1 ("T3T: rf frame error (crc status=%i)", p[sod]);
2273 GKI_freebuf (p_msg);
2274
2275 rw_t3t_process_frame_error ();
2276 return;
2277 }
2278
2279#if (BT_TRACE_PROTOCOL == TRUE)
Ruchi Kandoi4a179642017-01-04 10:04:48 -08002280 DispT3TagMessage (p_msg, true);
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002281#endif
2282
2283 /* Skip over SoD */
2284 p_msg->offset++;
2285 p_msg->len--;
2286
2287 /* Get response code */
2288 switch (p_cb->cur_cmd)
2289 {
2290 case RW_T3T_CMD_DETECT_NDEF:
2291 rw_t3t_act_handle_ndef_detect_rsp (p_cb, p_msg);
2292 break;
2293
2294 case RW_T3T_CMD_CHECK_NDEF:
2295 rw_t3t_act_handle_check_ndef_rsp (p_cb, p_msg);
2296 break;
2297
2298 case RW_T3T_CMD_UPDATE_NDEF:
2299 rw_t3t_act_handle_update_ndef_rsp (p_cb, p_msg);
2300 break;
2301
2302 case RW_T3T_CMD_CHECK:
2303 rw_t3t_act_handle_check_rsp (p_cb, p_msg);
2304 break;
2305
2306 case RW_T3T_CMD_UPDATE:
2307 rw_t3t_act_handle_update_rsp (p_cb, p_msg);
2308 break;
2309
2310 case RW_T3T_CMD_SEND_RAW_FRAME:
Evan Chua24be4f2013-11-13 15:30:16 -05002311 rw_t3t_act_handle_raw_senddata_rsp (p_cb, p_data);
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002312 break;
2313
2314 case RW_T3T_CMD_GET_SYSTEM_CODES:
2315 rw_t3t_act_handle_get_sc_rsp (p_cb, p_msg);
2316 break;
2317
2318 case RW_T3T_CMD_FORMAT:
2319 rw_t3t_act_handle_fmt_rsp (p_cb, p_msg);
2320 break;
2321
Martijn Coenen5c65c3a2013-03-27 13:23:36 -07002322 case RW_T3T_CMD_SET_READ_ONLY_SOFT:
2323 case RW_T3T_CMD_SET_READ_ONLY_HARD:
2324 rw_t3t_act_handle_sro_rsp (p_cb, p_msg);
2325 break;
2326
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002327 default:
2328 GKI_freebuf (p_msg);
2329 break;
2330 }
2331 }
2332
2333 if (free_msg)
2334 {
2335 GKI_freebuf (p_msg);
2336 }
2337}
2338
2339
2340/*******************************************************************************
2341**
2342** Function rw_t3t_conn_cback
2343**
2344** Description This callback function receives the events/data from NFCC.
2345**
2346** Returns none
2347**
2348*******************************************************************************/
Ruchi Kandoi512ee632017-01-03 13:59:10 -08002349void 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 -08002350{
2351 tRW_T3T_CB *p_cb = &rw_cb.tcb.t3t;
2352 RW_TRACE_DEBUG2 ("rw_t3t_conn_cback: conn_id=%i, evt=0x%02x", conn_id, event);
2353
2354 /* Only handle NFC_RF_CONN_ID conn_id */
2355 if (conn_id != NFC_RF_CONN_ID)
2356 {
2357 return;
2358 }
2359
2360 switch (event)
2361 {
2362 case NFC_DEACTIVATE_CEVT:
2363 rw_t3t_unselect (NULL);
2364 break;
2365
2366 case NFC_DATA_CEVT: /* check for status in tNFC_CONN */
Ken Wahidd8c0f582015-05-18 14:43:25 +02002367 if ( (p_data != NULL)
2368 &&( (p_data->data.status == NFC_STATUS_OK)
2369 ||(p_data->data.status == NFC_STATUS_CONTINUE) ) )
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002370 {
Evan Chua24be4f2013-11-13 15:30:16 -05002371 rw_t3t_data_cback (conn_id, &(p_data->data));
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002372 break;
2373 }
Jizhou Liaof1877412016-03-22 12:08:11 -07002374 else if (p_data->data.p_data != NULL)
2375 {
2376 /* Free the response buffer in case of error response */
2377 GKI_freebuf ((BT_HDR *) (p_data->data.p_data));
2378 p_data->data.p_data = NULL;
2379 }
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002380 /* Data event with error status...fall through to NFC_ERROR_CEVT case */
2381
2382
2383 case NFC_ERROR_CEVT:
2384 nfc_stop_quick_timer (&p_cb->timer);
2385
Ruchi Kandoi303fec12016-12-14 13:22:38 -08002386#if (RW_STATS_INCLUDED == TRUE)
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002387 rw_main_update_trans_error_stats ();
2388#endif /* RW_STATS_INCLUDED */
2389
2390 if (event == NFC_ERROR_CEVT)
2391 rw_t3t_process_error (NFC_STATUS_TIMEOUT);
Ken Wahidd8c0f582015-05-18 14:43:25 +02002392 else if (p_data)
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002393 rw_t3t_process_error (p_data->status);
2394 break;
2395
2396 default:
2397 break;
2398
2399 }
2400}
2401
2402
2403/*******************************************************************************
2404**
Sherry Smith818b56e2014-05-14 16:46:32 -07002405** Function rw_t3t_mrti_to_a_b
2406**
2407** Description Converts the given MRTI (Maximum Response Time Information)
2408** to the base to calculate timeout value.
2409** (The timeout value is a + b * number_blocks)
2410**
2411** Returns NFC_STATUS_OK
2412**
2413*******************************************************************************/
Ruchi Kandoi512ee632017-01-03 13:59:10 -08002414static 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 -07002415{
Ruchi Kandoi512ee632017-01-03 13:59:10 -08002416 uint8_t a, b, e;
Sherry Smith818b56e2014-05-14 16:46:32 -07002417
2418 a = (mrti & 0x7) + 1; /* A is bit 0 ~ bit 2 */
2419 mrti >>=3;
2420 b = (mrti & 0x7) + 1; /* B is bit 3 ~ bit 5 */
2421 mrti >>=3;
2422 e = mrti & 0x3; /* E is bit 6 ~ bit 7 */
2423 *p_a = rw_t3t_mrti_base[e] * a; /* (A+1) * base (i.e T/t3t * 4^E) */
2424 *p_b = rw_t3t_mrti_base[e] * b; /* (B+1) * base (i.e T/t3t * 4^E) */
2425}
2426
2427
2428/*******************************************************************************
2429**
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002430** Function rw_t3t_select
2431**
2432** Description Called by NFC manager when a Type3 tag has been activated
2433**
2434** Returns NFC_STATUS_OK
2435**
2436*******************************************************************************/
Ruchi Kandoi512ee632017-01-03 13:59:10 -08002437tNFC_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 -08002438{
2439 tRW_T3T_CB *p_cb = &rw_cb.tcb.t3t;
2440
2441 RW_TRACE_API0 ("rw_t3t_select");
2442
2443 memcpy (p_cb->peer_nfcid2, peer_nfcid2, NCI_NFCID2_LEN); /* Store tag's NFCID2 */
2444 p_cb->ndef_attrib.status = NFC_STATUS_NOT_INITIALIZED; /* Indicate that NDEF detection has not been performed yet */
2445 p_cb->rw_state = RW_T3T_STATE_IDLE;
2446 p_cb->flags = 0;
Sherry Smith818b56e2014-05-14 16:46:32 -07002447 rw_t3t_mrti_to_a_b (mrti_check, &p_cb->check_tout_a, &p_cb->check_tout_b);
2448 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 -08002449
2450 /* Alloc cmd buf for retransmissions */
2451 if (p_cb->p_cur_cmd_buf == NULL)
2452 {
2453 if ((p_cb->p_cur_cmd_buf = (BT_HDR *) GKI_getpoolbuf (NFC_RW_POOL_ID)) == NULL)
2454 {
2455 RW_TRACE_ERROR0 ("rw_t3t_select: unable to allocate buffer for retransmission");
2456 p_cb->rw_state = RW_T3T_STATE_NOT_ACTIVATED;
2457 return (NFC_STATUS_FAILED);
2458 }
2459 }
2460
2461
2462 NFC_SetStaticRfCback (rw_t3t_conn_cback);
2463
2464 return NFC_STATUS_OK;
2465}
2466
2467
2468/*******************************************************************************
2469**
2470** Function rw_t3t_unselect
2471**
2472** Description Called by NFC manager when a Type3 tag has been de-activated
2473**
2474** Returns NFC_STATUS_OK
2475**
2476*******************************************************************************/
Ruchi Kandoi512ee632017-01-03 13:59:10 -08002477static tNFC_STATUS rw_t3t_unselect (uint8_t peer_nfcid2[])
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002478{
2479 tRW_T3T_CB *p_cb = &rw_cb.tcb.t3t;
2480
Ruchi Kandoi303fec12016-12-14 13:22:38 -08002481#if (RW_STATS_INCLUDED == TRUE)
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002482 /* Display stats */
2483 rw_main_log_stats ();
2484#endif /* RW_STATS_INCLUDED */
2485
2486 /* Stop t3t timer (if started) */
2487 nfc_stop_quick_timer (&p_cb->timer);
2488
2489 /* Free cmd buf for retransmissions */
2490 if (p_cb->p_cur_cmd_buf)
2491 {
2492 GKI_freebuf (p_cb->p_cur_cmd_buf);
2493 p_cb->p_cur_cmd_buf = NULL;
2494 }
2495
2496 p_cb->rw_state = RW_T3T_STATE_NOT_ACTIVATED;
2497 NFC_SetStaticRfCback (NULL);
2498
2499 return NFC_STATUS_OK;
2500}
2501
Evan Chua24be4f2013-11-13 15:30:16 -05002502/*******************************************************************************
2503**
2504** Function rw_t3t_update_ndef_flag
2505**
2506** Description set additional NDEF Flags for felica lite tag
2507**
2508** Returns updated NDEF Flag value
2509**
2510*******************************************************************************/
Ruchi Kandoi512ee632017-01-03 13:59:10 -08002511static void rw_t3t_update_ndef_flag (uint8_t *p_flag)
Evan Chua24be4f2013-11-13 15:30:16 -05002512{
2513 tRW_T3T_CB *p_cb = &rw_cb.tcb.t3t;
Ruchi Kandoi512ee632017-01-03 13:59:10 -08002514 uint8_t xx;
Evan Chua24be4f2013-11-13 15:30:16 -05002515
2516 for (xx = 0; xx < p_cb->num_system_codes; xx++)
2517 {
2518 if (p_cb->system_codes[xx] == T3T_SYSTEM_CODE_FELICA_LITE)
2519 {
2520 *p_flag &= ~RW_NDEF_FL_UNKNOWN;
2521 *p_flag |= (RW_NDEF_FL_SUPPORTED | RW_NDEF_FL_FORMATABLE);
2522 break;
2523 }
2524 }
2525}
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002526
2527#if (BT_TRACE_VERBOSE == TRUE)
2528/*******************************************************************************
2529**
2530** Function rw_t3t_cmd_str
2531**
2532** Description Converts cmd_id to command string for logging
2533**
2534** Returns command string
2535**
2536*******************************************************************************/
Ruchi Kandoi512ee632017-01-03 13:59:10 -08002537static char *rw_t3t_cmd_str (uint8_t cmd_id)
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002538{
2539 switch (cmd_id)
2540 {
2541 case RW_T3T_CMD_DETECT_NDEF:
2542 return "RW_T3T_CMD_DETECT_NDEF";
2543
2544 case RW_T3T_CMD_CHECK_NDEF:
2545 return "RW_T3T_CMD_CHECK_NDEF";
2546
2547 case RW_T3T_CMD_UPDATE_NDEF:
2548 return "RW_T3T_CMD_UPDATE_NDEF";
2549
2550 case RW_T3T_CMD_CHECK:
2551 return "RW_T3T_CMD_CHECK";
2552
2553 case RW_T3T_CMD_UPDATE:
2554 return "RW_T3T_CMD_UPDATE";
2555
2556 case RW_T3T_CMD_SEND_RAW_FRAME:
2557 return "RW_T3T_CMD_SEND_RAW_FRAME";
2558
2559 case RW_T3T_CMD_GET_SYSTEM_CODES:
2560 return "RW_T3T_CMD_GET_SYSTEM_CODES";
2561
2562 default:
2563 return "Unknown";
2564 }
2565}
2566
2567
2568/*******************************************************************************
2569**
2570** Function rw_t3t_state_str
2571**
2572** Description Converts state_id to command string for logging
2573**
2574** Returns command string
2575**
2576*******************************************************************************/
Ruchi Kandoi512ee632017-01-03 13:59:10 -08002577static char *rw_t3t_state_str (uint8_t state_id)
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002578{
2579 switch (state_id)
2580 {
2581 case RW_T3T_STATE_NOT_ACTIVATED:
2582 return "RW_T3T_STATE_NOT_ACTIVATED";
2583
2584 case RW_T3T_STATE_IDLE:
2585 return "RW_T3T_STATE_IDLE";
2586
2587 case RW_T3T_STATE_COMMAND_PENDING:
2588 return "RW_T3T_STATE_COMMAND_PENDING";
2589
2590 default:
2591 return "Unknown";
2592 }
2593}
2594#endif
2595
2596/*****************************************************************************
2597** Type3 Tag API Functions
2598*****************************************************************************/
2599
2600
2601/*****************************************************************************
2602**
2603** Function RW_T3tDetectNDef
2604**
2605** Description
2606** This function is used to perform NDEF detection on a Type 3 tag, and
2607** retrieve the tag's NDEF attribute information (block 0).
2608**
2609** Before using this API, the application must call RW_SelectTagType to
2610** indicate that a Type 3 tag has been activated, and to provide the
2611** tag's Manufacture ID (IDm) .
2612**
2613** Returns
2614** NFC_STATUS_OK: ndef detection procedure started
2615** NFC_STATUS_NO_BUFFERS: unable to allocate a buffer for this operation
2616** NFC_STATUS_FAILED: other error
2617**
2618*****************************************************************************/
2619tNFC_STATUS RW_T3tDetectNDef (void)
2620{
2621 tRW_T3T_CB *p_cb = &rw_cb.tcb.t3t;
2622 tNFC_STATUS retval = NFC_STATUS_OK;
2623
2624 RW_TRACE_API0 ("RW_T3tDetectNDef");
2625
2626 /* Check if we are in valid state to handle this API */
2627 if (p_cb->rw_state != RW_T3T_STATE_IDLE)
2628 {
2629 RW_TRACE_ERROR1 ("Error: invalid state to handle API (0x%x)", p_cb->rw_state);
2630 return (NFC_STATUS_FAILED);
2631 }
2632
The Android Open Source Project808ebf82012-12-13 15:18:55 -08002633 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 -08002634 {
2635 p_cb->cur_cmd = RW_T3T_CMD_DETECT_NDEF;
2636 p_cb->cur_tout = RW_T3T_DEFAULT_CMD_TIMEOUT_TICKS;
2637 p_cb->cur_poll_rc = 0;
2638 p_cb->rw_state = RW_T3T_STATE_COMMAND_PENDING;
2639 p_cb->flags |= RW_T3T_FL_W4_NDEF_DETECT_POLL_RSP;
2640
2641 /* start timer for waiting for responses */
2642 rw_t3t_start_poll_timer (p_cb);
2643 }
2644
2645 return (retval);
2646}
2647
2648
2649/*****************************************************************************
2650**
2651** Function RW_T3tCheckNDef
2652**
2653** Description
2654** Retrieve NDEF contents from a Type3 tag.
2655**
2656** The RW_T3T_CHECK_EVT event is used to notify the application for each
2657** segment of NDEF data received. The RW_T3T_CHECK_CPLT_EVT event is used to
2658** notify the application all segments have been received.
2659**
2660** Before using this API, the RW_T3tDetectNDef function must be called to
2661** verify that the tag contains NDEF data, and to retrieve the NDEF
2662** attributes.
2663**
2664** Internally, this command will be separated into multiple Tag 3 Check
2665** commands (if necessary) - depending on the tag's Nbr (max number of
2666** blocks per read) attribute.
2667**
2668** Returns
2669** NFC_STATUS_OK: check command started
2670** NFC_STATUS_NO_BUFFERS: unable to allocate a buffer for this operation
2671** NFC_STATUS_FAILED: other error
2672**
2673*****************************************************************************/
2674tNFC_STATUS RW_T3tCheckNDef (void)
2675{
2676 tNFC_STATUS retval = NFC_STATUS_OK;
2677 tRW_T3T_CB *p_cb = &rw_cb.tcb.t3t;
2678
2679 RW_TRACE_API0 ("RW_T3tCheckNDef");
2680
2681 /* Check if we are in valid state to handle this API */
2682 if (p_cb->rw_state != RW_T3T_STATE_IDLE)
2683 {
2684 RW_TRACE_ERROR1 ("Error: invalid state to handle API (0x%x)", p_cb->rw_state);
2685 return (NFC_STATUS_FAILED);
2686 }
2687 else if (p_cb->ndef_attrib.status != NFC_STATUS_OK) /* NDEF detection not performed yet? */
2688 {
2689 RW_TRACE_ERROR0 ("Error: NDEF detection not performed yet");
2690 return (NFC_STATUS_NOT_INITIALIZED);
2691 }
2692 else if (p_cb->ndef_attrib.ln == 0)
2693 {
2694 RW_TRACE_ERROR0 ("Type 3 tag contains empty NDEF message");
2695 return (NFC_STATUS_FAILED);
2696 }
2697
2698 /* Check number of blocks needed for this update */
2699 p_cb->flags &= ~RW_T3T_FL_IS_FINAL_NDEF_SEGMENT;
2700 p_cb->ndef_rx_offset = 0;
2701 retval = rw_t3t_send_next_ndef_check_cmd (p_cb);
2702
2703 return (retval);
2704}
2705
2706/*****************************************************************************
2707**
2708** Function RW_T3tUpdateNDef
2709**
2710** Description
2711** Write NDEF contents to a Type3 tag.
2712**
2713** The RW_T3T_UPDATE_CPLT_EVT callback event will be used to notify the
2714** application of the response.
2715**
2716** Before using this API, the RW_T3tDetectNDef function must be called to
2717** verify that the tag contains NDEF data, and to retrieve the NDEF
2718** attributes.
2719**
2720** Internally, this command will be separated into multiple Tag 3 Update
2721** commands (if necessary) - depending on the tag's Nbw (max number of
2722** blocks per write) attribute.
2723**
2724** Returns
2725** NFC_STATUS_OK: check command started
2726** NFC_STATUS_NO_BUFFERS: unable to allocate a buffer for this operation
2727** NFC_STATUS_REFUSED: tag is read-only
2728** NFC_STATUS_BUFFER_FULL: len exceeds tag's maximum size
2729** NFC_STATUS_FAILED: other error
2730**
2731*****************************************************************************/
Ruchi Kandoi512ee632017-01-03 13:59:10 -08002732tNFC_STATUS RW_T3tUpdateNDef (uint32_t len, uint8_t *p_data)
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002733{
2734 tNFC_STATUS retval = NFC_STATUS_OK;
2735 tRW_T3T_CB *p_cb = &rw_cb.tcb.t3t;
2736
2737 RW_TRACE_API1 ("RW_T3tUpdateNDef (len=%i)", len);
2738
2739 /* Check if we are in valid state to handle this API */
2740 if (p_cb->rw_state != RW_T3T_STATE_IDLE)
2741 {
2742 RW_TRACE_ERROR1 ("Error: invalid state to handle API (0x%x)", p_cb->rw_state);
2743 return (NFC_STATUS_FAILED);
2744 }
2745 else if (p_cb->ndef_attrib.status != NFC_STATUS_OK) /* NDEF detection not performed yet? */
2746 {
2747 RW_TRACE_ERROR0 ("Error: NDEF detection not performed yet");
2748 return (NFC_STATUS_NOT_INITIALIZED);
2749 }
Ruchi Kandoi512ee632017-01-03 13:59:10 -08002750 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 -08002751 {
2752 return (NFC_STATUS_BUFFER_FULL);
2753 }
2754 else if (p_cb->ndef_attrib.rwflag == T3T_MSG_NDEF_RWFLAG_RO)/* Tag's NDEF memory is read-only? */
2755 {
2756 return (NFC_STATUS_REFUSED);
2757 }
2758
2759 /* Check number of blocks needed for this update */
2760 p_cb->flags &= ~RW_T3T_FL_IS_FINAL_NDEF_SEGMENT;
2761 p_cb->ndef_msg_bytes_sent = 0;
2762 p_cb->ndef_msg_len = len;
2763 p_cb->ndef_msg = p_data;
2764
2765 /* Send initial UPDATE command for NDEF Attribute Info */
Ruchi Kandoi4a179642017-01-04 10:04:48 -08002766 retval = rw_t3t_send_update_ndef_attribute_cmd (p_cb, true);
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002767
2768 return (retval);
2769}
2770
2771/*****************************************************************************
2772**
2773** Function RW_T3tCheck
2774**
2775** Description
2776** Read (non-NDEF) contents from a Type3 tag.
2777**
2778** The RW_READ_EVT event is used to notify the application for each
2779** segment of NDEF data received. The RW_READ_CPLT_EVT event is used to
2780** notify the application all segments have been received.
2781**
2782** Before using this API, the application must call RW_SelectTagType to
2783** indicate that a Type 3 tag has been activated, and to provide the
2784** tag's Manufacture ID (IDm) .
2785**
2786** Returns
2787** NFC_STATUS_OK: check command started
2788** NFC_STATUS_NO_BUFFERS: unable to allocate a buffer for this operation
2789** NFC_STATUS_FAILED: other error
2790**
2791*****************************************************************************/
Ruchi Kandoi512ee632017-01-03 13:59:10 -08002792tNFC_STATUS RW_T3tCheck (uint8_t num_blocks, tT3T_BLOCK_DESC *t3t_blocks)
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002793{
2794 tNFC_STATUS retval = NFC_STATUS_OK;
2795 tRW_T3T_CB *p_cb = &rw_cb.tcb.t3t;
2796
2797 RW_TRACE_API1 ("RW_T3tCheck (num_blocks = %i)", num_blocks);
2798
2799 /* Check if we are in valid state to handle this API */
2800 if (p_cb->rw_state != RW_T3T_STATE_IDLE)
2801 {
2802 RW_TRACE_ERROR1 ("Error: invalid state to handle API (0x%x)", p_cb->rw_state);
2803 return (NFC_STATUS_FAILED);
2804 }
2805
2806 /* Send the CHECK command */
2807 retval = rw_t3t_send_check_cmd (p_cb, num_blocks, t3t_blocks);
2808
2809 return (retval);
2810}
2811
2812/*****************************************************************************
2813**
2814** Function RW_T3tUpdate
2815**
2816** Description
2817** Write (non-NDEF) contents to a Type3 tag.
2818**
2819** The RW_WRITE_CPLT_EVT event is used to notify the application all
2820** segments have been received.
2821**
2822** Before using this API, the application must call RW_SelectTagType to
2823** indicate that a Type 3 tag has been activated, and to provide the tag's
2824** Manufacture ID (IDm) .
2825**
2826** Returns
2827** NFC_STATUS_OK: check command started
2828** NFC_STATUS_NO_BUFFERS: unable to allocate a buffer for this operation
2829** NFC_STATUS_FAILED: other error
2830**
2831*****************************************************************************/
Ruchi Kandoi512ee632017-01-03 13:59:10 -08002832tNFC_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 -08002833{
2834 tNFC_STATUS retval = NFC_STATUS_OK;
2835 tRW_T3T_CB *p_cb = &rw_cb.tcb.t3t;
2836
2837 RW_TRACE_API1 ("RW_T3tUpdate (num_blocks = %i)", num_blocks);
2838
2839 /* Check if we are in valid state to handle this API */
2840 if (p_cb->rw_state != RW_T3T_STATE_IDLE)
2841 {
2842 RW_TRACE_ERROR1 ("Error: invalid state to handle API (0x%x)", p_cb->rw_state);
2843 return (NFC_STATUS_FAILED);
2844 }
2845
2846 /* Send the UPDATE command */
2847 retval = rw_t3t_send_update_cmd (p_cb, num_blocks, t3t_blocks, p_data);
2848
2849 return (retval);
2850}
2851
2852/*****************************************************************************
2853**
2854** Function RW_T3tPresenceCheck
2855**
2856** Description
2857** Check if the tag is still in the field.
2858**
2859** The RW_T3T_PRESENCE_CHECK_EVT w/ status is used to indicate presence
2860** or non-presence.
2861**
2862** Returns
2863** NFC_STATUS_OK, if raw data frame sent
2864** NFC_STATUS_NO_BUFFERS: unable to allocate a buffer for this operation
2865** NFC_STATUS_FAILED: other error
2866**
2867*****************************************************************************/
2868tNFC_STATUS RW_T3tPresenceCheck (void)
2869{
2870 tNFC_STATUS retval = NFC_STATUS_OK;
2871 tRW_DATA evt_data;
2872 tRW_CB *p_rw_cb = &rw_cb;
2873
2874 RW_TRACE_API0 ("RW_T3tPresenceCheck");
2875
2876 /* If RW_SelectTagType was not called (no conn_callback) return failure */
2877 if (!(p_rw_cb->p_cback))
2878 {
2879 retval = NFC_STATUS_FAILED;
2880 }
2881 /* If we are not activated, then RW_T3T_PRESENCE_CHECK_EVT status=FAIL */
2882 else if (p_rw_cb->tcb.t3t.rw_state == RW_T3T_STATE_NOT_ACTIVATED)
2883 {
2884 evt_data.status = NFC_STATUS_FAILED;
2885 (*p_rw_cb->p_cback) (RW_T3T_PRESENCE_CHECK_EVT, &evt_data);
2886 }
2887 /* If command is pending */
2888 else if (p_rw_cb->tcb.t3t.rw_state == RW_T3T_STATE_COMMAND_PENDING)
2889 {
2890 /* If already performing presence check, return error */
2891 if (p_rw_cb->tcb.t3t.flags & RW_T3T_FL_W4_PRESENCE_CHECK_POLL_RSP)
2892 {
2893 RW_TRACE_DEBUG0 ("RW_T3tPresenceCheck already in progress");
2894 retval = NFC_STATUS_FAILED;
2895 }
2896 /* If busy with any other command, assume that the tag is present */
2897 else
2898 {
2899 evt_data.status = NFC_STATUS_OK;
2900 (*p_rw_cb->p_cback) (RW_T3T_PRESENCE_CHECK_EVT, &evt_data);
2901 }
2902 }
2903 else
2904 {
2905 /* IDLE state: send POLL command */
2906 if ((retval = (tNFC_STATUS) nci_snd_t3t_polling (0xFFFF, T3T_POLL_RC_SC, 0)) == NCI_STATUS_OK)
2907 {
2908 p_rw_cb->tcb.t3t.flags |= RW_T3T_FL_W4_PRESENCE_CHECK_POLL_RSP;
2909 p_rw_cb->tcb.t3t.rw_state = RW_T3T_STATE_COMMAND_PENDING;
2910 p_rw_cb->tcb.t3t.cur_poll_rc = 0;
2911
2912 /* start timer for waiting for responses */
2913 rw_t3t_start_poll_timer (&p_rw_cb->tcb.t3t);
2914 }
2915 else
2916 {
2917 RW_TRACE_DEBUG1 ("RW_T3tPresenceCheck error sending NCI_RF_T3T_POLLING cmd (status = 0x%0x)", retval);
2918 }
2919 }
2920
2921 return (retval);
2922}
2923
2924/*****************************************************************************
2925**
2926** Function RW_T3tPoll
2927**
2928** Description
2929** Send POLL command
2930**
2931** Returns
2932** NFC_STATUS_OK, if raw data frame sent
2933** NFC_STATUS_NO_BUFFERS: unable to allocate a buffer for this operation
2934** NFC_STATUS_FAILED: other error
2935**
2936*****************************************************************************/
Ruchi Kandoi512ee632017-01-03 13:59:10 -08002937tNFC_STATUS RW_T3tPoll (uint16_t system_code, tT3T_POLL_RC rc, uint8_t tsn)
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002938{
2939 tNFC_STATUS retval = NFC_STATUS_OK;
2940 tRW_T3T_CB *p_cb = &rw_cb.tcb.t3t;
2941
2942 RW_TRACE_API0 ("RW_T3tPoll");
2943
2944 /* Check if we are in valid state to handle this API */
2945 if (p_cb->rw_state != RW_T3T_STATE_IDLE)
2946 {
2947 RW_TRACE_ERROR1 ("Error: invalid state to handle API (0x%x)", p_cb->rw_state);
2948 return (NFC_STATUS_FAILED);
2949 }
2950
Ruchi Kandoi512ee632017-01-03 13:59:10 -08002951 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 -08002952 {
2953 /* start timer for waiting for responses */
2954 p_cb->cur_poll_rc = rc;
2955 p_cb->rw_state = RW_T3T_STATE_COMMAND_PENDING;
2956 rw_t3t_start_poll_timer (p_cb);
2957 }
2958
2959
2960 return (retval);
2961}
2962
2963/*****************************************************************************
2964**
2965** Function RW_T3tSendRawFrame
2966**
2967** Description
2968** This function is called to send a raw data frame to the peer device.
2969** When type 3 tag receives response from peer, the callback function
2970** will be called with a RW_T3T_RAW_FRAME_EVT [Table 6].
2971**
2972** Before using this API, the application must call RW_SelectTagType to
2973** indicate that a Type 3 tag has been activated.
2974**
2975** The raw frame should be a properly formatted Type 3 tag message.
2976**
2977** Returns
2978** NFC_STATUS_OK, if raw data frame sent
2979** NFC_STATUS_NO_BUFFERS: unable to allocate a buffer for this operation
2980** NFC_STATUS_FAILED: other error
2981**
2982*****************************************************************************/
Ruchi Kandoi512ee632017-01-03 13:59:10 -08002983tNFC_STATUS RW_T3tSendRawFrame (uint16_t len, uint8_t *p_data)
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002984{
2985 tNFC_STATUS retval = NFC_STATUS_OK;
2986 tRW_T3T_CB *p_cb = &rw_cb.tcb.t3t;
2987
2988 RW_TRACE_API1 ("RW_T3tSendRawFrame (len = %i)", len);
2989
2990 /* Check if we are in valid state to handle this API */
2991 if (p_cb->rw_state != RW_T3T_STATE_IDLE)
2992 {
2993 RW_TRACE_ERROR1 ("Error: invalid state to handle API (0x%x)", p_cb->rw_state);
2994 return (NFC_STATUS_FAILED);
2995 }
2996
2997 /* Send the UPDATE command */
2998 retval = rw_t3t_send_raw_frame (p_cb, len ,p_data);
2999
3000 return (retval);
3001}
3002
3003/*****************************************************************************
3004**
3005** Function RW_T3tGetSystemCodes
3006**
3007** Description
3008** Get systems codes supported by the activated tag:
3009** Poll for wildcard (FFFF):
3010** - If felica-lite code then poll for ndef (12fc)
3011** - Otherwise send RequestSystmCode command to get
3012** system codes.
3013**
3014** Before using this API, the application must call RW_SelectTagType to
3015** indicate that a Type 3 tag has been activated.
3016**
3017** Returns
3018** NFC_STATUS_OK, if raw data frame sent
3019** NFC_STATUS_NO_BUFFERS: unable to allocate a buffer for this operation
3020** NFC_STATUS_FAILED: other error
3021**
3022*****************************************************************************/
3023tNFC_STATUS RW_T3tGetSystemCodes (void)
3024{
3025 tNFC_STATUS retval = NFC_STATUS_OK;
3026 tRW_T3T_CB *p_cb = &rw_cb.tcb.t3t;
3027
3028 RW_TRACE_API0 ("RW_T3tGetSystemCodes");
3029
3030 /* Check if we are in valid state to handle this API */
3031 if (p_cb->rw_state != RW_T3T_STATE_IDLE)
3032 {
3033 RW_TRACE_ERROR1 ("Error: invalid state to handle API (0x%x)", p_cb->rw_state);
3034 return (NFC_STATUS_FAILED);
3035 }
3036 else
3037 {
3038 if ((retval = (tNFC_STATUS) nci_snd_t3t_polling (0xFFFF, T3T_POLL_RC_SC, 0)) == NCI_STATUS_OK)
3039 {
3040 p_cb->cur_cmd = RW_T3T_CMD_GET_SYSTEM_CODES;
3041 p_cb->cur_tout = RW_T3T_DEFAULT_CMD_TIMEOUT_TICKS;
3042 p_cb->cur_poll_rc = T3T_POLL_RC_SC;
3043 p_cb->rw_state = RW_T3T_STATE_COMMAND_PENDING;
3044 p_cb->rw_substate = RW_T3T_GET_SC_SST_POLL_WILDCARD;
3045 p_cb->flags |= RW_T3T_FL_W4_GET_SC_POLL_RSP;
3046 p_cb->num_system_codes = 0;
3047
3048 /* start timer for waiting for responses */
3049 rw_t3t_start_poll_timer (p_cb);
3050 }
3051 }
3052
3053
3054
3055 return (retval);
3056}
3057
3058/*****************************************************************************
3059**
3060** Function RW_T3tFormatNDef
3061**
3062** Description
3063** Format a type-3 tag for NDEF.
3064**
3065** Only Felica-Lite tags are supported by this API. The
3066** RW_T3T_FORMAT_CPLT_EVT is used to notify the status of the operation.
3067**
3068** Returns
3069** NFC_STATUS_OK: ndef detection procedure started
3070** NFC_STATUS_NO_BUFFERS: unable to allocate a buffer for this operation
3071** NFC_STATUS_FAILED: other error
3072**
3073*****************************************************************************/
3074tNFC_STATUS RW_T3tFormatNDef (void)
3075{
3076 tNFC_STATUS retval = NFC_STATUS_OK;
3077 tRW_T3T_CB *p_cb = &rw_cb.tcb.t3t;
3078
3079 RW_TRACE_API0 ("RW_T3tFormatNDef");
3080
3081 /* Check if we are in valid state to handle this API */
3082 if (p_cb->rw_state != RW_T3T_STATE_IDLE)
3083 {
3084 RW_TRACE_ERROR1 ("Error: invalid state to handle API (0x%x)", p_cb->rw_state);
3085 return (NFC_STATUS_FAILED);
3086 }
3087 else
3088 {
3089 /* Poll tag, to see if Felica-Lite system is supported */
3090 if ((retval = (tNFC_STATUS) nci_snd_t3t_polling (T3T_SYSTEM_CODE_FELICA_LITE, T3T_POLL_RC_SC, 0)) == NCI_STATUS_OK)
3091 {
3092 p_cb->cur_cmd = RW_T3T_CMD_FORMAT;
3093 p_cb->cur_tout = RW_T3T_DEFAULT_CMD_TIMEOUT_TICKS;
3094 p_cb->cur_poll_rc = T3T_POLL_RC_SC;
3095 p_cb->rw_state = RW_T3T_STATE_COMMAND_PENDING;
3096 p_cb->rw_substate = RW_T3T_FMT_SST_POLL_FELICA_LITE;
3097 p_cb->flags |= RW_T3T_FL_W4_FMT_FELICA_LITE_POLL_RSP;
3098
3099 /* start timer for waiting for responses */
3100 rw_t3t_start_poll_timer (p_cb);
3101 }
3102 }
3103
3104
3105
3106 return (retval);
3107}
Martijn Coenen5c65c3a2013-03-27 13:23:36 -07003108
3109/*****************************************************************************
3110**
3111** Function RW_T3tSetReadOnly
3112**
3113** Description This function performs NDEF read-only procedure
3114** Note: Only Felica-Lite tags are supported by this API.
3115** RW_T3tDetectNDef() must be called before using this
3116**
3117** The RW_T3T_SET_READ_ONLY_CPLT_EVT event will be returned.
3118**
3119** Returns NFC_STATUS_OK if success
3120** NFC_STATUS_FAILED if T3T is busy or other error
3121**
3122*****************************************************************************/
Ruchi Kandoi512ee632017-01-03 13:59:10 -08003123tNFC_STATUS RW_T3tSetReadOnly (bool b_hard_lock)
Martijn Coenen5c65c3a2013-03-27 13:23:36 -07003124{
3125 tNFC_STATUS retval = NFC_STATUS_OK;
3126 tRW_T3T_CB *p_cb = &rw_cb.tcb.t3t;
3127 tRW_DATA evt_data;
3128
Evan Chu7c69b272013-05-14 12:48:36 -04003129 RW_TRACE_API1 ("RW_T3tSetReadOnly (): b_hard_lock=%d", b_hard_lock);
Martijn Coenen5c65c3a2013-03-27 13:23:36 -07003130
3131 /* Check if we are in valid state to handle this API */
3132 if (p_cb->rw_state != RW_T3T_STATE_IDLE)
3133 {
3134 RW_TRACE_ERROR1 ("Error: invalid state to handle API (0x%x)", p_cb->rw_state);
3135 return (NFC_STATUS_FAILED);
3136 }
3137
3138 if (p_cb->ndef_attrib.status != NFC_STATUS_OK) /* NDEF detection not performed yet? */
3139 {
3140 RW_TRACE_ERROR0 ("Error: NDEF detection not performed yet");
3141 return (NFC_STATUS_NOT_INITIALIZED);
3142 }
3143
3144 if ((!b_hard_lock) && (p_cb->ndef_attrib.rwflag == T3T_MSG_NDEF_RWFLAG_RO))/* Tag's NDEF memory is read-only already */
3145 {
3146 evt_data.status = NFC_STATUS_OK;
Evan Chu7c69b272013-05-14 12:48:36 -04003147 (*(rw_cb.p_cback)) (RW_T3T_SET_READ_ONLY_CPLT_EVT, &evt_data);
Martijn Coenen5c65c3a2013-03-27 13:23:36 -07003148 return (retval);
3149 }
3150 else
3151 {
3152 /* Poll tag, to see if Felica-Lite system is supported */
3153 if ((retval = (tNFC_STATUS) nci_snd_t3t_polling (T3T_SYSTEM_CODE_FELICA_LITE, T3T_POLL_RC_SC, 0)) == NCI_STATUS_OK)
3154 {
3155 if (b_hard_lock)
3156 p_cb->cur_cmd = RW_T3T_CMD_SET_READ_ONLY_HARD;
3157 else
3158 p_cb->cur_cmd = RW_T3T_CMD_SET_READ_ONLY_SOFT;
3159 p_cb->cur_tout = RW_T3T_DEFAULT_CMD_TIMEOUT_TICKS;
3160 p_cb->cur_poll_rc = T3T_POLL_RC_SC;
3161 p_cb->rw_state = RW_T3T_STATE_COMMAND_PENDING;
3162 p_cb->rw_substate = RW_T3T_SRO_SST_POLL_FELICA_LITE;
3163 p_cb->flags |= RW_T3T_FL_W4_SRO_FELICA_LITE_POLL_RSP;
3164
3165 /* start timer for waiting for responses */
3166 rw_t3t_start_poll_timer (p_cb);
3167 }
3168 }
3169 return (retval);
3170}