blob: 7db0fac1cd2183aa4da871b76ba64c8e474a3d6b [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 */
75const UINT8 rw_t3t_api_res_evt[RW_T3T_CMD_MAX] =
76{
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)
118static char *rw_t3t_cmd_str (UINT8 cmd_id);
119static char *rw_t3t_state_str (UINT8 state_id);
120#endif
121
122
123/* Local static functions */
Evan Chua24be4f2013-11-13 15:30:16 -0500124static void rw_t3t_update_ndef_flag (UINT8 *p_flag);
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800125static tNFC_STATUS rw_t3t_unselect (UINT8 peer_nfcid2[]);
126static 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);
129static void rw_t3t_handle_get_sc_poll_rsp (tRW_T3T_CB *p_cb, UINT8 nci_status, UINT8 num_responses, UINT8 sensf_res_buf_size, UINT8 *p_sensf_res_buf);
130static void rw_t3t_handle_ndef_detect_poll_rsp (tRW_T3T_CB *p_cb, UINT8 nci_status, UINT8 num_responses, UINT8 sensf_res_buf_size, UINT8 *p_sensf_res_buf);
131static void rw_t3t_handle_fmt_poll_rsp (tRW_T3T_CB *p_cb, UINT8 nci_status, UINT8 num_responses, UINT8 sensf_res_buf_size, UINT8 *p_sensf_res_buf);
Martijn Coenen5c65c3a2013-03-27 13:23:36 -0700132static void rw_t3t_handle_sro_poll_rsp (tRW_T3T_CB *p_cb, UINT8 nci_status, UINT8 num_responses, UINT8 sensf_res_buf_size, UINT8 *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
147const UINT8 rw_t3t_default_attrib_info[T3T_MSG_BLOCKSIZE] =
148{
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 */
165static const UINT32 rw_t3t_mrti_base [] =
166{
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*******************************************************************************/
183static UINT32 rw_t3t_check_timeout (UINT16 num_blocks)
184{
185 tRW_T3T_CB *p_cb = &rw_cb.tcb.t3t;
186 UINT32 timeout;
Sherry Smith67fe6102014-06-02 11:01:54 -0700187 UINT32 extra;
188
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*******************************************************************************/
206static UINT32 rw_t3t_update_timeout (UINT16 num_blocks)
207{
208 tRW_T3T_CB *p_cb = &rw_cb.tcb.t3t;
209 UINT32 timeout;
Sherry Smith67fe6102014-06-02 11:01:54 -0700210 UINT32 extra;
211
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;
231 UINT8 evt;
232 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
274#if (defined (RW_STATS_INCLUDED) && (RW_STATS_INCLUDED == TRUE))
275 /* 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*******************************************************************************/
328void rw_t3t_handle_nci_poll_ntf (UINT8 nci_status, UINT8 num_responses, UINT8 sensf_res_buf_size, UINT8 *p_sensf_res_buf)
329{
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;
398 UINT8 i;
399
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
564#if (defined (RW_STATS_INCLUDED) && (RW_STATS_INCLUDED == TRUE))
565 /* 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{
584 UINT8 *p;
585
586#if (defined (RW_STATS_INCLUDED) && (RW_STATS_INCLUDED == TRUE))
587 BOOLEAN is_retry;
588 /* Update stats */
589 rw_main_update_tx_stats (p_msg->len, ((rw_cb.cur_retry==0) ? FALSE : TRUE));
590#endif /* RW_STATS_INCLUDED */
591
592 /* Set NFC-F SoD field (payload len + 1) */
593 p_msg->offset -= 1; /* Point to SoD field */
594 p = (UINT8 *) (p_msg+1) + p_msg->offset;
595 UINT8_TO_STREAM (p, (p_msg->len+1));
596 p_msg->len += 1; /* Increment len to include SoD */
597
598#if (BT_TRACE_PROTOCOL == TRUE)
599 DispT3TagMessage (p_msg, FALSE);
600#endif
601
602 return (NFC_SendData (NFC_RF_CONN_ID, p_msg));
603}
604
605/*****************************************************************************
606**
607** Function rw_t3t_get_cmd_buf
608**
609** Description Get a buffer for sending T3T messages
610**
611** Returns BT_HDR *
612**
613*****************************************************************************/
614BT_HDR *rw_t3t_get_cmd_buf (void)
615{
616 BT_HDR *p_cmd_buf;
617
618 if ((p_cmd_buf = (BT_HDR *) GKI_getpoolbuf (NFC_RW_POOL_ID)) != NULL)
619 {
620 /* Reserve offset for NCI_DATA_HDR and NFC-F Sod (LEN) field */
621 p_cmd_buf->offset = NCI_MSG_OFFSET_SIZE + NCI_DATA_HDR_SIZE + 1;
622 p_cmd_buf->len = 0;
623 }
624
625 return (p_cmd_buf);
626}
627
628/*****************************************************************************
629**
630** Function rw_t3t_send_cmd
631**
632** Description Send command to tag, and start timer for response
633**
634** Returns tNFC_STATUS
635**
636*****************************************************************************/
Sherry Smith818b56e2014-05-14 16:46:32 -0700637tNFC_STATUS rw_t3t_send_cmd (tRW_T3T_CB *p_cb, UINT8 rw_t3t_cmd, BT_HDR *p_cmd_buf, UINT32 timeout_ticks)
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800638{
639 tNFC_STATUS retval;
640
641 /* Indicate first attempt to send command, back up cmd buffer in case needed for retransmission */
642 rw_cb.cur_retry = 0;
643 memcpy (p_cb->p_cur_cmd_buf, p_cmd_buf, sizeof (BT_HDR) + p_cmd_buf->offset + p_cmd_buf->len);
644
645 p_cb->cur_cmd = rw_t3t_cmd;
Sherry Smith818b56e2014-05-14 16:46:32 -0700646 p_cb->cur_tout = timeout_ticks;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800647 p_cb->rw_state = RW_T3T_STATE_COMMAND_PENDING;
648
649 if ((retval = rw_t3t_send_to_lower (p_cmd_buf)) == NFC_STATUS_OK)
650 {
651 /* Start timer for waiting for response */
Sherry Smith818b56e2014-05-14 16:46:32 -0700652 nfc_start_quick_timer (&p_cb->timer, NFC_TTYPE_RW_T3T_RESPONSE, timeout_ticks);
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800653 }
654 else
655 {
656 /* Error sending */
657 p_cb->rw_state = RW_T3T_STATE_IDLE;
658 }
659
Sherry Smith818b56e2014-05-14 16:46:32 -0700660 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 -0800661 return (retval);
662}
663
664/*****************************************************************************
665**
666** Function rw_t3t_send_update_ndef_attribute_cmd
667**
668** Description Send UPDATE command for Attribute Information
669**
670** Returns tNFC_STATUS
671**
672*****************************************************************************/
673tNFC_STATUS rw_t3t_send_update_ndef_attribute_cmd (tRW_T3T_CB *p_cb, BOOLEAN write_in_progress)
674{
675 tNFC_STATUS retval = NFC_STATUS_OK;
676 BT_HDR *p_cmd_buf;
677 UINT8 *p_cmd_start, *p;
678 UINT16 checksum, i;
679 UINT8 write_f;
680 UINT32 ln;
681 UINT8 *p_ndef_attr_info_start;
682
683 if ((p_cmd_buf = rw_t3t_get_cmd_buf ()) != NULL)
684 {
685 /* Construct T3T message */
686 p = p_cmd_start = (UINT8 *) (p_cmd_buf+1) + p_cmd_buf->offset;
687
688 /* Add UPDATE opcode to message */
689 UINT8_TO_STREAM (p, T3T_MSG_OPC_UPDATE_CMD);
690
691 /* Add IDm to message */
692 ARRAY_TO_STREAM (p, p_cb->peer_nfcid2, NCI_NFCID2_LEN);
693
694 /* Add Service code list */
695 UINT8_TO_STREAM (p, 1); /* Number of services (only 1 service: NDEF) */
696 UINT16_TO_STREAM (p, T3T_MSG_NDEF_SC_RW); /* Service code (little-endian format) */
697
698 /* Add number of blocks in this UPDATE command */
699 UINT8_TO_STREAM (p, 1); /* Number of blocks to write in this command */
700
701 /* Block List element: the NDEF attribute information block (block 0) */
702 UINT8_TO_STREAM (p, T3T_MSG_MASK_TWO_BYTE_BLOCK_DESC_FORMAT);
703 UINT8_TO_STREAM (p, 0);
704
705 /* Add payload (Attribute information block) */
706 p_ndef_attr_info_start = p; /* Save start of a NDEF attribute info block for checksum */
707 UINT8_TO_STREAM (p, T3T_MSG_NDEF_VERSION);
708 UINT8_TO_STREAM (p, p_cb->ndef_attrib.nbr);
709 UINT8_TO_STREAM (p, p_cb->ndef_attrib.nbw);
710 UINT16_TO_BE_STREAM (p, p_cb->ndef_attrib.nmaxb);
711 UINT32_TO_STREAM (p, 0);
712
713 /* If starting NDEF write: set WriteF=ON, and ln=current ndef length */
714 if (write_in_progress)
715 {
716 write_f = T3T_MSG_NDEF_WRITEF_ON;
717 ln = p_cb->ndef_attrib.ln;
718 }
719 /* If finishing NDEF write: set WriteF=OFF, and ln=new ndef len */
720 else
721 {
722 write_f = T3T_MSG_NDEF_WRITEF_OFF;
723 ln = p_cb->ndef_msg_len;
724 }
725 UINT8_TO_STREAM (p, write_f);
726 UINT8_TO_STREAM (p, p_cb->ndef_attrib.rwflag);
727 UINT8_TO_STREAM (p, (ln>>16) & 0xFF); /* High byte (of 3) of Ln */
728 UINT8_TO_STREAM (p, (ln>>8) & 0xFF); /* Middle byte (of 3) of Ln */
729 UINT8_TO_STREAM (p, (ln) & 0xFF); /* Low byte (of 3) of Ln */
730
731 /* Calculate and append Checksum */
732 checksum = 0;
733 for (i = 0; i < T3T_MSG_NDEF_ATTR_INFO_SIZE; i++)
734 {
735 checksum+=p_ndef_attr_info_start[i];
736 }
737 UINT16_TO_BE_STREAM (p, checksum);
738
739
740 /* Calculate length of message */
741 p_cmd_buf->len = (UINT16) (p - p_cmd_start);
742
743 /* Send the T3T message */
Sherry Smith818b56e2014-05-14 16:46:32 -0700744 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 -0800745 }
746 else
747 {
748 retval = NFC_STATUS_NO_BUFFERS;
749 }
750
751 return (retval);
752}
753
754/*****************************************************************************
755**
756** Function rw_t3t_send_next_ndef_update_cmd
757**
758** Description Send next segment of NDEF message to update
759**
760** Returns tNFC_STATUS
761**
762*****************************************************************************/
763tNFC_STATUS rw_t3t_send_next_ndef_update_cmd (tRW_T3T_CB *p_cb)
764{
765 tNFC_STATUS retval = NFC_STATUS_OK;
766 UINT16 block_id;
767 UINT16 first_block_to_write;
768 UINT16 ndef_blocks_to_write, ndef_blocks_remaining;
769 UINT32 ndef_bytes_remaining, ndef_padding = 0;
770 UINT8 flags = 0;
771 UINT8 *p_cur_ndef_src_offset;
772 BT_HDR *p_cmd_buf;
773 UINT8 *p_cmd_start, *p;
774 UINT8 blocks_per_update;
775 UINT32 timeout;
776
777 if ((p_cmd_buf = rw_t3t_get_cmd_buf ()) != NULL)
778 {
779 /* Construct T3T message */
780 p = p_cmd_start = (UINT8 *) (p_cmd_buf + 1) + p_cmd_buf->offset;
781
782 /* Calculate number of ndef bytes remaining to write */
783 ndef_bytes_remaining = p_cb->ndef_msg_len - p_cb->ndef_msg_bytes_sent;
784
785 /* Calculate number of blocks remaining to write */
786 ndef_blocks_remaining = (UINT16) ((ndef_bytes_remaining+15) >> 4); /* ndef blocks remaining (rounded upward) */
787
788 /* Calculate first NDEF block ID for this UPDATE command */
789 first_block_to_write = (UINT16) ((p_cb->ndef_msg_bytes_sent >> 4) + 1);
790
791 /* Calculate max number of blocks per write. */
792 if ((first_block_to_write + RW_T3T_MAX_NDEF_BLOCKS_PER_UPDATE_1_BYTE_FORMAT) < 0x100)
793 {
794 /* All block-numbers are < 0x100 (i.e. can be specified using one-byte format) */
795 blocks_per_update = RW_T3T_MAX_NDEF_BLOCKS_PER_UPDATE_1_BYTE_FORMAT;
796 }
797 else
798 {
799 /* Block-numbers are >= 0x100 (i.e. need to be specified using two-byte format) */
800 blocks_per_update = RW_T3T_MAX_NDEF_BLOCKS_PER_UPDATE_2_BYTE_FORMAT;
801 }
802
803 /* Check if blocks_per_update is bigger than what peer allows */
804 if (blocks_per_update > p_cb->ndef_attrib.nbw)
805 blocks_per_update = p_cb->ndef_attrib.nbw;
806
807 /* Check if remaining blocks can fit into one UPDATE command */
808 if (ndef_blocks_remaining <= blocks_per_update)
809 {
810 /* remaining blocks can fit into one UPDATE command */
811 ndef_blocks_to_write = ndef_blocks_remaining;
812 }
813 else
814 {
815 /* Remaining blocks cannot fit into one UPDATE command */
816 ndef_blocks_to_write = blocks_per_update;
817 }
818
819
820 /* Write to command header for UPDATE */
821
822 /* Add UPDATE opcode to message */
823 UINT8_TO_STREAM (p, T3T_MSG_OPC_UPDATE_CMD);
824
825 /* Add IDm to message */
826 ARRAY_TO_STREAM (p, p_cb->peer_nfcid2, NCI_NFCID2_LEN);
827
828 /* Add Service code list */
829 UINT8_TO_STREAM (p, 1); /* Number of services (only 1 service: NDEF) */
830 UINT16_TO_STREAM (p, T3T_MSG_NDEF_SC_RW); /* Service code (little-endian format) */
831
832
833 /* Add number of blocks in this UPDATE command */
834 UINT8_TO_STREAM (p, ndef_blocks_to_write); /* Number of blocks to write in this command */
Sherry Smith818b56e2014-05-14 16:46:32 -0700835 timeout = rw_t3t_update_timeout(ndef_blocks_to_write);
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800836
837 for (block_id = first_block_to_write; block_id < (first_block_to_write + ndef_blocks_to_write); block_id++)
838 {
839 if (block_id<256)
840 {
841 /* Block IDs 0-255 can be specified in '2-byte' format: byte0=0, byte1=blocknumber */
842 UINT8_TO_STREAM (p, T3T_MSG_MASK_TWO_BYTE_BLOCK_DESC_FORMAT); /* byte0: len=1; access-mode=0; service code list order=0 */
843 UINT8_TO_STREAM (p, block_id); /* byte1: block number */
844 }
845 else
846 {
847 /* Block IDs 256+ must be specified in '3-byte' format: byte0=80h, followed by blocknumber */
848 UINT8_TO_STREAM (p, 0x00); /* byte0: len=0; access-mode=0; service code list order=0 */
849 UINT16_TO_STREAM (p, block_id); /* byte1-2: block number in little-endian format */
850 }
851
852 }
853
854 /* Add NDEF payload */
855
856 /* If this sending last block of NDEF, check if padding is needed to make payload a multiple of 16 bytes */
857 if (ndef_blocks_to_write == ndef_blocks_remaining)
858 {
859 ndef_padding = (16 - (ndef_bytes_remaining & 0x0F)) & 0x0F;
860 if (ndef_padding)
861 {
862 flags |= RW_T3T_FL_PADDING;
863 ndef_blocks_to_write--; /* handle the last block separately if it needs padding */
864 }
865 }
866
867 /* Add NDEF payload to the message */
868 p_cur_ndef_src_offset = &p_cb->ndef_msg[p_cb->ndef_msg_bytes_sent];
869
870
871 ARRAY_TO_STREAM (p, p_cur_ndef_src_offset, (ndef_blocks_to_write * 16));
872 p_cb->ndef_msg_bytes_sent += ((UINT32) ndef_blocks_to_write * 16);
873
874 if (flags & RW_T3T_FL_PADDING)
875 {
876 /* Add last of the NDEF message */
877 p_cur_ndef_src_offset = &p_cb->ndef_msg[p_cb->ndef_msg_bytes_sent];
878 ARRAY_TO_STREAM (p, p_cur_ndef_src_offset, (int) (16-ndef_padding));
879 p_cb->ndef_msg_bytes_sent += (16-ndef_padding);
880
881 /* Add padding */
882 memset (p, 0, ndef_padding);
883 p+=ndef_padding;
884 }
885
886 /* Calculate length of message */
887 p_cmd_buf->len = (UINT16) (p - p_cmd_start);
888
889 /* Send the T3T message */
890 retval = rw_t3t_send_cmd (p_cb, RW_T3T_CMD_UPDATE_NDEF, p_cmd_buf, timeout);
891 }
892 else
893 {
894 retval = NFC_STATUS_NO_BUFFERS;
895 }
896
897 return (retval);
898}
899
900
901
902/*****************************************************************************
903**
904** Function rw_t3t_send_next_ndef_check_cmd
905**
906** Description Send command for reading next segment of NDEF message
907**
908** Returns tNFC_STATUS
909**
910*****************************************************************************/
911tNFC_STATUS rw_t3t_send_next_ndef_check_cmd (tRW_T3T_CB *p_cb)
912{
913 tNFC_STATUS retval = NFC_STATUS_OK;
914 UINT16 block_id;
915 UINT16 ndef_blocks_remaining, first_block_to_read, cur_blocks_to_read;
916 UINT32 ndef_bytes_remaining;
917 BT_HDR *p_cmd_buf;
918 UINT8 *p_cmd_start, *p;
919
920 if ((p_cmd_buf = rw_t3t_get_cmd_buf ()) != NULL)
921 {
922 /* Construct T3T message */
923 p = p_cmd_start = (UINT8 *) (p_cmd_buf+1) + p_cmd_buf->offset;
924
925 /* Calculate number of ndef bytes remaining to read */
926 ndef_bytes_remaining = p_cb->ndef_attrib.ln - p_cb->ndef_rx_offset;
927
928 /* Calculate number of blocks remaining to read */
929 ndef_blocks_remaining = (UINT16) ((ndef_bytes_remaining+15) >> 4); /* ndef blocks remaining (rounded upward) */
930
931 /* Calculate first NDEF block ID */
932 first_block_to_read = (UINT16) ((p_cb->ndef_rx_offset >> 4) + 1);
933
934 /* Check if remaining blocks can fit into one CHECK command */
935 if (ndef_blocks_remaining <= p_cb->ndef_attrib.nbr)
936 {
937 /* remaining blocks can fit into one CHECK command */
938 cur_blocks_to_read = ndef_blocks_remaining;
939 p_cb->ndef_rx_readlen = ndef_bytes_remaining;
940 p_cb->flags |= RW_T3T_FL_IS_FINAL_NDEF_SEGMENT;
941 }
942 else
943 {
944 /* Remaining blocks cannot fit into one CHECK command */
945 cur_blocks_to_read = p_cb->ndef_attrib.nbr; /* Read maximum number of blocks allowed by the peer */
946 p_cb->ndef_rx_readlen = ((UINT32) p_cb->ndef_attrib.nbr * 16);
947 }
948
949 RW_TRACE_DEBUG3 ("rw_t3t_send_next_ndef_check_cmd: bytes_remaining: %i, cur_blocks_to_read: %i, is_final: %i",
950 ndef_bytes_remaining, cur_blocks_to_read, (p_cb->flags & RW_T3T_FL_IS_FINAL_NDEF_SEGMENT));
951
Sherry Smith818b56e2014-05-14 16:46:32 -0700952 /* Add CHECK opcode to message */
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800953 UINT8_TO_STREAM (p, T3T_MSG_OPC_CHECK_CMD);
954
955 /* Add IDm to message */
956 ARRAY_TO_STREAM (p, p_cb->peer_nfcid2, NCI_NFCID2_LEN);
957
958 /* Add Service code list */
959 UINT8_TO_STREAM (p, 1); /* Number of services (only 1 service: NDEF) */
960
961 /* Service code (little-endian format) . If NDEF is read-only, then use T3T_MSG_NDEF_SC_RO, otherwise use T3T_MSG_NDEF_SC_RW */
962 if (p_cb->ndef_attrib.rwflag == T3T_MSG_NDEF_RWFLAG_RO)
963 {
964 UINT16_TO_STREAM (p, T3T_MSG_NDEF_SC_RO);
965 }
966 else
967 {
968 UINT16_TO_STREAM (p, T3T_MSG_NDEF_SC_RW);
969 }
970
Sherry Smith818b56e2014-05-14 16:46:32 -0700971 /* Add number of blocks in this CHECK command */
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800972 UINT8_TO_STREAM (p, cur_blocks_to_read); /* Number of blocks to check in this command */
973
974 for (block_id = first_block_to_read; block_id < (first_block_to_read + cur_blocks_to_read); block_id++)
975 {
976 if (block_id<256)
977 {
978 /* Block IDs 0-255 can be specified in '2-byte' format: byte0=0, byte1=blocknumber */
979 UINT8_TO_STREAM (p, T3T_MSG_MASK_TWO_BYTE_BLOCK_DESC_FORMAT); /* byte1: len=0; access-mode=0; service code list order=0 */
980 UINT8_TO_STREAM (p, block_id); /* byte1: block number */
981 }
982 else
983 {
984 /* Block IDs 256+ must be specified in '3-byte' format: byte0=80h, followed by blocknumber */
985 UINT8_TO_STREAM (p, 0x00); /* byte0: len=1; access-mode=0; service code list order=0 */
986 UINT16_TO_STREAM (p, block_id); /* byte1-2: block number in little-endian format */
987 }
988
989 }
990
991 /* Calculate length of message */
992 p_cmd_buf->len = (UINT16) (p - p_cmd_start);
993
994 /* Send the T3T message */
Sherry Smith818b56e2014-05-14 16:46:32 -0700995 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 -0800996 }
997 else
998 {
999 retval = NFC_STATUS_NO_BUFFERS;
1000 }
1001
1002 return(retval);
1003}
1004
1005
1006/*****************************************************************************
1007**
1008** Function rw_t3t_message_set_block_list
1009**
1010** Description Add block list to T3T message
1011**
1012** Returns Number of bytes added to message
1013**
1014*****************************************************************************/
1015void rw_t3t_message_set_block_list (tRW_T3T_CB *p_cb, UINT8 **p, UINT8 num_blocks, tT3T_BLOCK_DESC *p_t3t_blocks)
1016{
1017 UINT16 i, cur_service_code;
1018 UINT8 service_code_idx, num_services = 0;
1019 UINT8 *p_msg_num_services;
1020 UINT16 service_list[T3T_MSG_SERVICE_LIST_MAX];
1021
1022 /* Add CHECK or UPDATE opcode to message */
1023 UINT8_TO_STREAM ((*p), ((p_cb->cur_cmd == RW_T3T_CMD_CHECK) ? T3T_MSG_OPC_CHECK_CMD:T3T_MSG_OPC_UPDATE_CMD));
1024
1025 /* Add IDm to message */
1026 ARRAY_TO_STREAM ((*p), p_cb->peer_nfcid2, NCI_NFCID2_LEN);
1027
1028 /* Skip over Number of Services field */
1029 p_msg_num_services = (*p); /* pointer to Number of Services offset */
1030 (*p)++;
1031
1032 /* Count number of different services are specified in the list, and add services to Service Code list */
1033 for (i = 0; i < num_blocks; i++)
1034 {
1035 cur_service_code = p_t3t_blocks[i].service_code;
1036
1037 /* Check if current service_code is already in the service_list */
1038 for (service_code_idx=0; service_code_idx<num_services; service_code_idx++)
1039 {
1040 if (service_list[service_code_idx] == cur_service_code)
1041 break;
1042 }
1043
1044 if (service_code_idx == num_services)
1045 {
1046 /* Service not in the list yet. Add it. */
1047 service_list[service_code_idx] = cur_service_code;
1048 num_services++;
1049
1050 /* Add service code to T3T message */
1051 UINT16_TO_STREAM ((*p), cur_service_code);
1052 }
1053 }
1054
1055 /* Add 'Number of Sservices' to the message */
1056 *p_msg_num_services = num_services;
1057
1058 /* Add 'number of blocks' to the message */
1059 UINT8_TO_STREAM ((*p), num_blocks);
1060
1061 /* Add block descriptors */
1062 for (i = 0; i < num_blocks; i++)
1063 {
1064 cur_service_code = p_t3t_blocks[i].service_code;
1065
1066 /* Check if current service_code is already in the service_list */
1067 for (service_code_idx=0; service_code_idx<num_services; service_code_idx++)
1068 {
1069 if (service_list[service_code_idx] == cur_service_code)
1070 break;
1071 }
1072
1073 /* Add decriptor to T3T message */
1074 if (p_t3t_blocks[i].block_number > 0xFF)
1075 {
1076 UINT8_TO_STREAM ((*p), service_code_idx);
1077 UINT16_TO_STREAM ((*p), p_t3t_blocks[i].block_number);
1078 }
1079 else
1080 {
1081 service_code_idx |= T3T_MSG_MASK_TWO_BYTE_BLOCK_DESC_FORMAT;
1082 UINT8_TO_STREAM ((*p), service_code_idx);
1083 UINT8_TO_STREAM ((*p), p_t3t_blocks[i].block_number);
1084 }
1085 }
1086}
1087
1088/*****************************************************************************
1089**
1090** Function rw_t3t_send_check_cmd
1091**
1092** Description Send CHECK command
1093**
1094** Returns tNFC_STATUS
1095**
1096*****************************************************************************/
1097tNFC_STATUS rw_t3t_send_check_cmd (tRW_T3T_CB *p_cb, UINT8 num_blocks, tT3T_BLOCK_DESC *p_t3t_blocks)
1098{
1099 BT_HDR *p_cmd_buf;
1100 UINT8 *p, *p_cmd_start;
1101 tNFC_STATUS retval = NFC_STATUS_OK;
1102
1103 p_cb->cur_cmd = RW_T3T_CMD_CHECK;
1104 if ((p_cmd_buf = rw_t3t_get_cmd_buf ()) != NULL)
1105 {
1106 /* Construct T3T message */
1107 p = p_cmd_start = (UINT8 *) (p_cmd_buf+1) + p_cmd_buf->offset;
1108 rw_t3t_message_set_block_list (p_cb, &p, num_blocks, p_t3t_blocks);
1109
1110 /* Calculate length of message */
1111 p_cmd_buf->len = (UINT16) (p - p_cmd_start);
1112
1113 /* Send the T3T message */
Sherry Smith818b56e2014-05-14 16:46:32 -07001114 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 -08001115 }
1116 else
1117 {
1118 retval = NFC_STATUS_NO_BUFFERS;
1119 }
1120
1121 return(retval);
1122}
1123
1124/*****************************************************************************
1125**
1126** Function rw_t3t_send_update_cmd
1127**
1128** Description Send UPDATE command
1129**
1130** Returns tNFC_STATUS
1131**
1132*****************************************************************************/
1133tNFC_STATUS rw_t3t_send_update_cmd (tRW_T3T_CB *p_cb, UINT8 num_blocks, tT3T_BLOCK_DESC *p_t3t_blocks, UINT8 *p_data)
1134{
1135 BT_HDR *p_cmd_buf;
1136 UINT8 *p, *p_cmd_start;
1137 tNFC_STATUS retval = NFC_STATUS_OK;
1138
1139 p_cb->cur_cmd = RW_T3T_CMD_UPDATE;
1140 if ((p_cmd_buf = rw_t3t_get_cmd_buf ()) != NULL)
1141 {
1142 /* Construct T3T message */
1143 p = p_cmd_start = (UINT8 *) (p_cmd_buf+1) + p_cmd_buf->offset;
1144 rw_t3t_message_set_block_list (p_cb, &p, num_blocks, p_t3t_blocks);
1145
1146 /* Add data blocks to the message */
1147 ARRAY_TO_STREAM (p, p_data, num_blocks*16);
1148
1149 /* Calculate length of message */
1150 p_cmd_buf->len = (UINT16) (p - p_cmd_start);
1151
1152 /* Send the T3T message */
Sherry Smith818b56e2014-05-14 16:46:32 -07001153 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 -08001154 }
1155 else
1156 {
1157 retval = NFC_STATUS_NO_BUFFERS;
1158 }
1159
1160 return(retval);
1161}
1162
1163/*****************************************************************************
1164**
Martijn Coenen5c65c3a2013-03-27 13:23:36 -07001165** Function rw_t3t_check_mc_block
1166**
1167** Description Send command to check Memory Configuration Block
1168**
1169** Returns tNFC_STATUS
1170**
1171*****************************************************************************/
1172tNFC_STATUS rw_t3t_check_mc_block (tRW_T3T_CB *p_cb)
1173{
1174 BT_HDR *p_cmd_buf;
1175 UINT8 *p, *p_cmd_start;
1176
1177 /* Read Memory Configuration block */
1178 if ((p_cmd_buf = rw_t3t_get_cmd_buf ()) != NULL)
1179 {
1180 /* Construct T3T message */
1181 p = p_cmd_start = (UINT8 *) (p_cmd_buf+1) + p_cmd_buf->offset;
1182
1183 /* Add CHECK opcode to message */
1184 UINT8_TO_STREAM (p, T3T_MSG_OPC_CHECK_CMD);
1185
1186 /* Add IDm to message */
1187 ARRAY_TO_STREAM (p, p_cb->peer_nfcid2, NCI_NFCID2_LEN);
1188
1189 /* Add Service code list */
1190 UINT8_TO_STREAM (p, 1); /* Number of services (only 1 service: NDEF) */
1191 UINT16_TO_STREAM (p, T3T_MSG_NDEF_SC_RO); /* Service code (little-endian format) */
1192
1193 /* Number of blocks */
1194 UINT8_TO_STREAM (p, 1); /* Number of blocks (only 1 block: Memory Configuration Information ) */
1195
1196 /* Block List element: the Memory Configuration block (block 0x88) */
1197 UINT8_TO_STREAM (p, T3T_MSG_MASK_TWO_BYTE_BLOCK_DESC_FORMAT);
1198 UINT8_TO_STREAM (p, T3T_MSG_FELICALITE_BLOCK_ID_MC);
1199
1200 /* Calculate length of message */
1201 p_cmd_buf->len = (UINT16) (p - p_cmd_start);
1202
1203 /* Send the T3T message */
Sherry Smith818b56e2014-05-14 16:46:32 -07001204 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 -07001205 }
1206 else
1207 {
1208 RW_TRACE_ERROR0 ("Unable to allocate buffer to read MC block");
1209 return (NFC_STATUS_NO_BUFFERS);
1210 }
1211}
1212
1213/*****************************************************************************
1214**
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001215** Function rw_t3t_send_raw_frame
1216**
1217** Description Send raw frame
1218**
1219** Returns tNFC_STATUS
1220**
1221*****************************************************************************/
1222tNFC_STATUS rw_t3t_send_raw_frame (tRW_T3T_CB *p_cb, UINT16 len, UINT8 *p_data)
1223{
1224 BT_HDR *p_cmd_buf;
1225 UINT8 *p;
1226 tNFC_STATUS retval = NFC_STATUS_OK;
1227
1228 if ((p_cmd_buf = rw_t3t_get_cmd_buf ()) != NULL)
1229 {
1230 /* Construct T3T message */
1231 p = (UINT8 *) (p_cmd_buf+1) + p_cmd_buf->offset;
1232
1233 /* Add data blocks to the message */
1234 ARRAY_TO_STREAM (p, p_data, len);
1235
1236 /* Calculate length of message */
1237 p_cmd_buf->len = len;
1238
1239 /* Send the T3T message */
1240 retval = rw_t3t_send_cmd (p_cb, RW_T3T_CMD_SEND_RAW_FRAME, p_cmd_buf, RW_T3T_RAW_FRAME_CMD_TIMEOUT_TICKS);
1241 }
1242 else
1243 {
1244 retval = NFC_STATUS_NO_BUFFERS;
1245 }
1246
1247 return (retval);
1248}
1249
1250
1251/*****************************************************************************
1252** TAG RESPONSE HANDLERS
1253*****************************************************************************/
1254
1255
1256/*****************************************************************************
1257**
1258** Function rw_t3t_act_handle_ndef_detect_rsp
1259**
1260** Description Handle response to NDEF detection
1261**
1262** Returns Nothing
1263**
1264*****************************************************************************/
1265void rw_t3t_act_handle_ndef_detect_rsp (tRW_T3T_CB *p_cb, BT_HDR *p_msg_rsp)
1266{
1267 UINT8 *p;
1268 UINT32 temp;
1269 UINT8 i;
1270 UINT16 checksum_calc, checksum_rx;
1271 tRW_DETECT_NDEF_DATA evt_data;
1272 UINT8 *p_t3t_rsp = (UINT8 *) (p_msg_rsp+1) + p_msg_rsp->offset;
1273
1274 evt_data.status = NFC_STATUS_FAILED;
1275 evt_data.flags = RW_NDEF_FL_UNKNOWN;
1276
1277 /* Check if response code is CHECK resp (for reading NDEF attribute block) */
1278 if (p_t3t_rsp[T3T_MSG_RSP_OFFSET_RSPCODE] != T3T_MSG_OPC_CHECK_RSP)
1279 {
1280 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]);
1281 evt_data.status = NFC_STATUS_FAILED;
1282 }
1283 /* Validate status code and NFCID2 response from tag */
1284 else if ( (p_t3t_rsp[T3T_MSG_RSP_OFFSET_STATUS1] != T3T_MSG_RSP_STATUS_OK) /* verify response status code */
1285 ||(memcmp (p_cb->peer_nfcid2, &p_t3t_rsp[T3T_MSG_RSP_OFFSET_IDM], NCI_NFCID2_LEN) != 0) ) /* verify response IDm */
1286 {
1287 evt_data.status = NFC_STATUS_FAILED;
1288 }
1289 else
1290 {
1291 /* Get checksum from received ndef attribute msg */
1292 p = &p_t3t_rsp[T3T_MSG_RSP_OFFSET_CHECK_DATA+T3T_MSG_NDEF_ATTR_INFO_SIZE];
1293 BE_STREAM_TO_UINT16 (checksum_rx, p);
1294
1295 /* Calculate checksum - move check for checsum to beginning */
1296 checksum_calc = 0;
1297 p = &p_t3t_rsp[T3T_MSG_RSP_OFFSET_CHECK_DATA];
1298 for (i = 0; i < T3T_MSG_NDEF_ATTR_INFO_SIZE; i++)
1299 {
1300 checksum_calc+=p[i];
1301 }
1302
1303 /* Validate checksum */
1304 if (checksum_calc != checksum_rx)
1305 {
1306 p_cb->ndef_attrib.status = NFC_STATUS_FAILED; /* only ok or failed passed to the app. can be boolean*/
1307
1308 RW_TRACE_ERROR0 ("RW_T3tDetectNDEF checksum failed");
1309 }
1310 else
1311 {
1312 p_cb->ndef_attrib.status = NFC_STATUS_OK;
1313
1314 /* Validate version number */
1315 STREAM_TO_UINT8 (p_cb->ndef_attrib.version, p);
1316
1317 if (T3T_GET_MAJOR_VERSION (T3T_MSG_NDEF_VERSION) < T3T_GET_MAJOR_VERSION (p_cb->ndef_attrib.version))
1318 {
1319 /* Remote tag's MajorVer is newer than our's. Reject NDEF as per T3TOP RQ_T3T_NDA_024 */
1320 RW_TRACE_ERROR2 ("RW_T3tDetectNDEF: incompatible NDEF version. Local=0x%02x, Remote=0x%02x", T3T_MSG_NDEF_VERSION, p_cb->ndef_attrib.version);
1321 p_cb->ndef_attrib.status = NFC_STATUS_FAILED;
1322 evt_data.status = NFC_STATUS_BAD_RESP;
1323 }
1324 else
1325 {
1326 /* Remote tag's MajorVer is equal or older than our's. NDEF is compatible with our version. */
1327
1328 /* Update NDEF info */
1329 STREAM_TO_UINT8 (p_cb->ndef_attrib.nbr, p); /* NBr: number of blocks that can be read using one Check command */
1330 STREAM_TO_UINT8 (p_cb->ndef_attrib.nbw, p); /* Nbw: number of blocks that can be written using one Update command */
1331 BE_STREAM_TO_UINT16 (p_cb->ndef_attrib.nmaxb, p); /* Nmaxb: maximum number of blocks available for NDEF data */
1332 BE_STREAM_TO_UINT32 (temp, p);
1333 STREAM_TO_UINT8 (p_cb->ndef_attrib.writef, p); /* WriteFlag: 00h if writing data finished; 0Fh if writing data in progress */
1334 STREAM_TO_UINT8 (p_cb->ndef_attrib.rwflag, p); /* RWFlag: 00h NDEF is read-only; 01h if read/write available */
1335
1336 /* Get length (3-byte, big-endian) */
1337 STREAM_TO_UINT8 (temp, p); /* Ln: high-byte */
1338 BE_STREAM_TO_UINT16 (p_cb->ndef_attrib.ln, p); /* Ln: lo-word */
1339 p_cb->ndef_attrib.ln += (temp << 16);
1340
1341
1342 RW_TRACE_DEBUG1 ("Detected NDEF Ver: 0x%02x", p_cb->ndef_attrib.version);
1343 RW_TRACE_DEBUG6 ("Detected NDEF Attributes: Nbr=%i, Nbw=%i, Nmaxb=%i, WriteF=%i, RWFlag=%i, Ln=%i",
1344 p_cb->ndef_attrib.nbr,
1345 p_cb->ndef_attrib.nbw,
1346 p_cb->ndef_attrib.nmaxb,
1347 p_cb->ndef_attrib.writef,
1348 p_cb->ndef_attrib.rwflag,
1349 p_cb->ndef_attrib.ln);
1350
1351 /* Set data for RW_T3T_NDEF_DETECT_EVT */
1352 evt_data.status = p_cb->ndef_attrib.status;
1353 evt_data.cur_size = p_cb->ndef_attrib.ln;
1354 evt_data.max_size = (UINT32) p_cb->ndef_attrib.nmaxb * 16;
1355 evt_data.protocol = NFC_PROTOCOL_T3T;
1356 evt_data.flags = (RW_NDEF_FL_SUPPORTED | RW_NDEF_FL_FORMATED);
1357 if (p_cb->ndef_attrib.rwflag == T3T_MSG_NDEF_RWFLAG_RO)
1358 evt_data.flags |= RW_NDEF_FL_READ_ONLY;
1359 }
1360 }
1361 }
1362
1363 RW_TRACE_DEBUG1 ("RW_T3tDetectNDEF response: %i", evt_data.status);
1364
1365 p_cb->rw_state = RW_T3T_STATE_IDLE;
Evan Chua24be4f2013-11-13 15:30:16 -05001366 rw_t3t_update_ndef_flag (&evt_data.flags);
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001367 /* Notify app of NDEF detection result */
1368 (*(rw_cb.p_cback)) (RW_T3T_NDEF_DETECT_EVT, (tRW_DATA *) &evt_data);
1369
1370 GKI_freebuf (p_msg_rsp);
1371}
1372
1373
1374/*****************************************************************************
1375**
1376** Function rw_t3t_act_handle_check_rsp
1377**
1378** Description Handle response to CHECK command
1379**
1380** Returns Nothing
1381**
1382*****************************************************************************/
1383void rw_t3t_act_handle_check_rsp (tRW_T3T_CB *p_cb, BT_HDR *p_msg_rsp)
1384{
1385 UINT8 *p_t3t_rsp = (UINT8 *) (p_msg_rsp+1) + p_msg_rsp->offset;
1386 tRW_READ_DATA evt_data;
1387 tNFC_STATUS nfc_status = NFC_STATUS_OK;
1388
1389 /* Validate response from tag */
1390 if ( (p_t3t_rsp[T3T_MSG_RSP_OFFSET_STATUS1] != T3T_MSG_RSP_STATUS_OK) /* verify response status code */
1391 ||(memcmp (p_cb->peer_nfcid2, &p_t3t_rsp[T3T_MSG_RSP_OFFSET_IDM], NCI_NFCID2_LEN) != 0) ) /* verify response IDm */
1392 {
1393 nfc_status = NFC_STATUS_FAILED;
1394 GKI_freebuf (p_msg_rsp);
1395 }
1396 else if (p_t3t_rsp[T3T_MSG_RSP_OFFSET_RSPCODE] != T3T_MSG_OPC_CHECK_RSP)
1397 {
1398 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]);
1399 nfc_status = NFC_STATUS_FAILED;
1400 GKI_freebuf (p_msg_rsp);
1401 }
1402 else
1403 {
1404 /* Copy incoming data into buffer */
1405 p_msg_rsp->offset += T3T_MSG_RSP_OFFSET_CHECK_DATA; /* Skip over t3t header */
1406 p_msg_rsp->len -= T3T_MSG_RSP_OFFSET_CHECK_DATA;
1407 evt_data.status = NFC_STATUS_OK;
1408 evt_data.p_data = p_msg_rsp;
1409 (*(rw_cb.p_cback)) (RW_T3T_CHECK_EVT, (tRW_DATA *) &evt_data);
1410 }
1411
1412
1413 p_cb->rw_state = RW_T3T_STATE_IDLE;
1414
1415 (*(rw_cb.p_cback)) (RW_T3T_CHECK_CPLT_EVT, (tRW_DATA *) &nfc_status);
1416}
1417
1418/*****************************************************************************
1419**
1420** Function rw_t3t_act_handle_update_rsp
1421**
1422** Description Handle response to UPDATE command
1423**
1424** Returns Nothing
1425**
1426*****************************************************************************/
1427void rw_t3t_act_handle_update_rsp (tRW_T3T_CB *p_cb, BT_HDR *p_msg_rsp)
1428{
1429 UINT8 *p_t3t_rsp = (UINT8 *) (p_msg_rsp+1) + p_msg_rsp->offset;
1430 tRW_READ_DATA evt_data;
1431
1432 /* Validate response from tag */
1433 if ( (p_t3t_rsp[T3T_MSG_RSP_OFFSET_STATUS1] != T3T_MSG_RSP_STATUS_OK) /* verify response status code */
1434 ||(memcmp (p_cb->peer_nfcid2, &p_t3t_rsp[T3T_MSG_RSP_OFFSET_IDM], NCI_NFCID2_LEN) != 0) ) /* verify response IDm */
1435 {
1436 evt_data.status = NFC_STATUS_FAILED;
1437 }
1438 else if (p_t3t_rsp[T3T_MSG_RSP_OFFSET_RSPCODE] != T3T_MSG_OPC_UPDATE_RSP)
1439 {
1440 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]);
1441 evt_data.status = NFC_STATUS_FAILED;
1442 }
1443 else
1444 {
1445 /* Copy incoming data into buffer */
1446 evt_data.status = NFC_STATUS_OK;
1447 }
1448
1449 p_cb->rw_state = RW_T3T_STATE_IDLE;
1450
1451 (*(rw_cb.p_cback)) (RW_T3T_UPDATE_CPLT_EVT, (tRW_DATA *)&evt_data);
1452
1453 GKI_freebuf (p_msg_rsp);
1454}
1455
1456/*****************************************************************************
1457**
1458** Function rw_t3t_act_handle_raw_senddata_rsp
1459**
1460** Description Handle response to NDEF detection
1461**
1462** Returns Nothing
1463**
1464*****************************************************************************/
Evan Chua24be4f2013-11-13 15:30:16 -05001465void 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 -08001466{
1467 tRW_READ_DATA evt_data;
Evan Chua24be4f2013-11-13 15:30:16 -05001468 BT_HDR *p_pkt = p_data->p_data;
1469
1470#if (BT_TRACE_VERBOSE == TRUE)
1471 RW_TRACE_DEBUG2 ("RW T3T Raw Frame: Len [0x%X] Status [%s]", p_pkt->len, NFC_GetStatusName (p_data->status));
1472#else
1473 RW_TRACE_DEBUG2 ("RW T3T Raw Frame: Len [0x%X] Status [0x%X]", p_pkt->len, p_data->status);
1474#endif
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001475
1476 /* Copy incoming data into buffer */
Evan Chua24be4f2013-11-13 15:30:16 -05001477 evt_data.status = p_data->status;
1478 evt_data.p_data = p_pkt;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001479
1480 p_cb->rw_state = RW_T3T_STATE_IDLE;
1481
1482 (*(rw_cb.p_cback)) (RW_T3T_RAW_FRAME_EVT, (tRW_DATA *) &evt_data);
1483}
1484
1485/*****************************************************************************
1486**
1487** Function rw_t3t_act_handle_check_ndef_rsp
1488**
1489** Description Handle response to NDEF read segment
1490**
1491** Returns Nothing
1492**
1493*****************************************************************************/
1494void rw_t3t_act_handle_check_ndef_rsp (tRW_T3T_CB *p_cb, BT_HDR *p_msg_rsp)
1495{
1496 BOOLEAN check_complete = TRUE;
1497 tNFC_STATUS nfc_status = NFC_STATUS_OK;
1498 tRW_READ_DATA read_data;
1499 tRW_DATA evt_data;
1500 UINT8 *p_t3t_rsp = (UINT8 *) (p_msg_rsp+1) + p_msg_rsp->offset;
1501 UINT8 rsp_num_bytes_rx;
1502
1503 /* Validate response from tag */
1504 if ( (p_t3t_rsp[T3T_MSG_RSP_OFFSET_STATUS1] != T3T_MSG_RSP_STATUS_OK) /* verify response status code */
1505 ||(memcmp (p_cb->peer_nfcid2, &p_t3t_rsp[T3T_MSG_RSP_OFFSET_IDM], NCI_NFCID2_LEN) != 0) /* verify response IDm */
1506 ||(p_t3t_rsp[T3T_MSG_RSP_OFFSET_NUMBLOCKS] != ((p_cb->ndef_rx_readlen+15) >> 4)) ) /* verify length of response */
1507 {
1508 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));
1509 nfc_status = NFC_STATUS_FAILED;
1510 GKI_freebuf (p_msg_rsp);
1511 }
1512 else if (p_t3t_rsp[T3T_MSG_RSP_OFFSET_RSPCODE] != T3T_MSG_OPC_CHECK_RSP)
1513 {
1514 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]);
1515 nfc_status = NFC_STATUS_FAILED;
1516 GKI_freebuf (p_msg_rsp);
1517 }
1518 else
1519 {
1520 /* Notify app of NDEF segment received */
1521 rsp_num_bytes_rx = p_t3t_rsp[T3T_MSG_RSP_OFFSET_NUMBLOCKS] * 16; /* Number of bytes received, according to header */
1522 p_cb->ndef_rx_offset += p_cb->ndef_rx_readlen;
1523 read_data.status = NFC_STATUS_OK;
1524 p_msg_rsp->offset += T3T_MSG_RSP_OFFSET_CHECK_DATA; /* Skip over t3t header (point to block data) */
1525 p_msg_rsp->len -= T3T_MSG_RSP_OFFSET_CHECK_DATA;
1526
1527 /* Verify that the bytes received is really the amount indicated in the check-response header */
1528 if (rsp_num_bytes_rx > p_msg_rsp->len)
1529 {
1530 RW_TRACE_ERROR2 ("Response error: CHECK rsp header indicates %i bytes, but only received %i bytes", rsp_num_bytes_rx, p_msg_rsp->len);
1531 nfc_status = NFC_STATUS_FAILED;
1532 GKI_freebuf (p_msg_rsp);
1533 }
1534 else
1535 {
1536 /* If this is the the final block, then set len to reflect only valid bytes (do not include padding to 16-byte boundary) */
1537 if ((p_cb->flags & RW_T3T_FL_IS_FINAL_NDEF_SEGMENT) && (p_cb->ndef_attrib.ln & 0x000F))
1538 {
1539 rsp_num_bytes_rx -= (16 - (p_cb->ndef_attrib.ln & 0x000F));
1540 }
1541
1542 p_msg_rsp->len = rsp_num_bytes_rx;
1543 read_data.p_data = p_msg_rsp;
1544 (*(rw_cb.p_cback)) (RW_T3T_CHECK_EVT, (tRW_DATA *) &read_data);
1545
1546 /* Send CHECK cmd for next NDEF segment, if needed */
1547 if (!(p_cb->flags & RW_T3T_FL_IS_FINAL_NDEF_SEGMENT))
1548 {
1549 if ((nfc_status = rw_t3t_send_next_ndef_check_cmd (p_cb)) == NFC_STATUS_OK)
1550 {
1551 /* Still getting more segments. Don't send RW_T3T_CHECK_CPLT_EVT yet */
1552 check_complete = FALSE;
1553 }
1554 }
1555 }
1556 }
1557
1558 /* Notify app of RW_T3T_CHECK_CPLT_EVT if entire NDEF has been read, or if failure */
1559 if (check_complete)
1560 {
1561 p_cb->rw_state = RW_T3T_STATE_IDLE;
1562 evt_data.status = nfc_status;
1563 (*(rw_cb.p_cback)) (RW_T3T_CHECK_CPLT_EVT, (tRW_DATA *) &evt_data);
1564 }
1565}
1566
1567
1568/*****************************************************************************
1569**
1570** Function rw_t3t_act_handle_update_ndef_rsp
1571**
1572** Description Handle response to NDEF write segment
1573**
1574** Returns Nothing
1575**
1576*****************************************************************************/
1577void rw_t3t_act_handle_update_ndef_rsp (tRW_T3T_CB *p_cb, BT_HDR *p_msg_rsp)
1578{
1579 BOOLEAN update_complete = TRUE;
1580 tNFC_STATUS nfc_status = NFC_STATUS_OK;
1581 tRW_DATA evt_data;
1582 UINT8 *p_t3t_rsp = (UINT8 *) (p_msg_rsp+1) + p_msg_rsp->offset;
1583
1584 /* Check nfcid2 and status of response */
1585 if ( (p_t3t_rsp[T3T_MSG_RSP_OFFSET_STATUS1] != T3T_MSG_RSP_STATUS_OK) /* verify response status code */
1586 ||(memcmp (p_cb->peer_nfcid2, &p_t3t_rsp[T3T_MSG_RSP_OFFSET_IDM], NCI_NFCID2_LEN) != 0) ) /* verify response IDm */
1587 {
1588 nfc_status = NFC_STATUS_FAILED;
1589 }
1590 /* Validate response opcode */
1591 else if (p_t3t_rsp[T3T_MSG_RSP_OFFSET_RSPCODE] != T3T_MSG_OPC_UPDATE_RSP)
1592 {
1593 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]);
1594 nfc_status = NFC_STATUS_FAILED;
1595 }
1596 /* If this is response to final UPDATE, then update NDEF local size */
1597 else if (p_cb->flags & RW_T3T_FL_IS_FINAL_NDEF_SEGMENT)
1598 {
1599 /* If successful, update current NDEF size */
1600 p_cb->ndef_attrib.ln = p_cb->ndef_msg_len;
1601 }
1602 /* If any more NDEF bytes to update, then send next UPDATE command */
1603 else if (p_cb->ndef_msg_bytes_sent < p_cb->ndef_msg_len)
1604 {
1605 /* Send UPDATE command for next segment of NDEF */
1606 if ((nfc_status = rw_t3t_send_next_ndef_update_cmd (p_cb)) == NFC_STATUS_OK)
1607 {
1608 /* Wait for update response */
1609 update_complete = FALSE;
1610 }
1611 }
1612 /* Otherwise, no more NDEF bytes. Send final UPDATE for Attribute Information block */
1613 else
1614 {
1615 p_cb->flags |= RW_T3T_FL_IS_FINAL_NDEF_SEGMENT;
1616 if ((nfc_status = rw_t3t_send_update_ndef_attribute_cmd (p_cb, FALSE)) == NFC_STATUS_OK)
1617 {
1618 /* Wait for update response */
1619 update_complete = FALSE;
1620 }
1621 }
1622
1623 /* If update is completed, then notify app */
1624 if (update_complete)
1625 {
1626 p_cb->rw_state = RW_T3T_STATE_IDLE;
1627 evt_data.status = nfc_status;
1628 (*(rw_cb.p_cback)) (RW_T3T_UPDATE_CPLT_EVT, (tRW_DATA *) &evt_data);
1629 }
1630
1631
1632 GKI_freebuf (p_msg_rsp);
1633
1634 return;
1635}
1636
1637
1638/*****************************************************************************
1639**
1640** Function rw_t3t_handle_get_sc_poll_rsp
1641**
1642** Description Handle POLL response for getting system codes
1643**
1644** Returns Nothing
1645**
1646*****************************************************************************/
1647static void rw_t3t_handle_get_sc_poll_rsp (tRW_T3T_CB *p_cb, UINT8 nci_status, UINT8 num_responses, UINT8 sensf_res_buf_size, UINT8 *p_sensf_res_buf)
1648{
1649 BT_HDR *p_cmd_buf;
1650 UINT8 *p, *p_cmd_start;
1651 UINT16 sc;
1652 tNFC_STATUS status = NFC_STATUS_FAILED;
1653
1654 /* If waiting for wildcard POLL */
1655 if (p_cb->rw_substate == RW_T3T_GET_SC_SST_POLL_WILDCARD)
1656 {
1657 /* Get the system code from the response */
1658 if ( (nci_status == NCI_STATUS_OK)
1659 &&(num_responses > 0)
1660 &&(sensf_res_buf_size >= (RW_T3T_SENSF_RES_RD_OFFSET + RW_T3T_SENSF_RES_RD_LEN)) )
1661 {
1662 p = &p_sensf_res_buf[RW_T3T_SENSF_RES_RD_OFFSET];
1663 BE_STREAM_TO_UINT16 (sc, p);
1664
1665 /* Handle felica lite */
1666 if (sc == T3T_SYSTEM_CODE_FELICA_LITE)
1667 {
1668 RW_TRACE_DEBUG1 ("FeliCa Lite tag detected (system code %04X)", sc);
1669 /* Store system code */
1670 p_cb->system_codes[p_cb->num_system_codes++] = sc;
1671
1672 /* Poll for NDEF system code */
The Android Open Source Project808ebf82012-12-13 15:18:55 -08001673 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 -08001674 {
1675 p_cb->rw_substate = RW_T3T_GET_SC_SST_POLL_NDEF;
1676 p_cb->cur_poll_rc = 0;
1677 p_cb->flags |= RW_T3T_FL_W4_GET_SC_POLL_RSP;
1678
1679 /* start timer for waiting for responses */
1680 rw_t3t_start_poll_timer (p_cb);
1681 }
1682 }
1683 else
1684 {
1685 /* All other types, send REQUEST_SYSTEM_CODE command */
1686 if ((p_cmd_buf = rw_t3t_get_cmd_buf ()) != NULL)
1687 {
1688 p_cb->rw_substate = RW_T3T_GET_SC_SST_REQUEST_SC;
1689
1690 /* Construct T3T message */
1691 p_cmd_start = p = (UINT8 *) (p_cmd_buf+1) + p_cmd_buf->offset;
1692 UINT8_TO_STREAM (p, T3T_MSG_OPC_REQ_SYSTEMCODE_CMD);
1693 ARRAY_TO_STREAM (p, p_cb->peer_nfcid2, NCI_NFCID2_LEN);
1694
1695 /* Fill in length field */
1696 p_cmd_buf->len = (UINT16) (p - p_cmd_start);
1697
1698 /* Send the T3T message */
1699 status = rw_t3t_send_cmd (p_cb, RW_T3T_CMD_GET_SYSTEM_CODES, p_cmd_buf, RW_T3T_DEFAULT_CMD_TIMEOUT_TICKS);
1700 }
1701 }
1702 }
1703
1704 /* Error proceeding. Notify upper layer of system codes found so far */
1705 if (status != NFC_STATUS_OK)
1706 {
1707 rw_t3t_handle_get_system_codes_cplt ();
1708 }
1709 }
1710 /* If waiting for NDEF POLL */
1711 else if (p_cb->rw_substate == RW_T3T_GET_SC_SST_POLL_NDEF)
1712 {
1713 /* Validate response for NDEF poll */
1714 if ((nci_status == NCI_STATUS_OK) && (num_responses > 0))
1715 {
1716 /* Tag responded for NDEF poll */
1717 p_cb->system_codes[p_cb->num_system_codes++] = T3T_SYSTEM_CODE_NDEF;
1718 }
1719 rw_t3t_handle_get_system_codes_cplt ();
1720 }
1721}
1722
1723/*****************************************************************************
1724**
1725** Function rw_t3t_handle_ndef_detect_poll_rsp
1726**
1727** Description Handle POLL response for getting system codes
1728**
1729** Returns Nothing
1730**
1731*****************************************************************************/
1732static void rw_t3t_handle_ndef_detect_poll_rsp (tRW_T3T_CB *p_cb, UINT8 nci_status, UINT8 num_responses, UINT8 sensf_res_buf_size, UINT8 *p_sensf_res_buf)
1733{
1734 BT_HDR *p_cmd_buf;
1735 UINT8 *p, *p_cmd_start;
1736 tRW_DATA evt_data;
1737
1738 /* Validate response for NDEF poll */
1739 if ((nci_status == NCI_STATUS_OK) && (num_responses > 0))
1740 {
1741 /* Tag responded for NDEF poll */
1742
1743 /* Read NDEF attribute block */
1744 if ((p_cmd_buf = rw_t3t_get_cmd_buf ()) != NULL)
1745 {
1746 /* Construct T3T message */
1747 p = p_cmd_start = (UINT8 *) (p_cmd_buf+1) + p_cmd_buf->offset;
1748
1749 /* Add CHECK opcode to message */
1750 UINT8_TO_STREAM (p, T3T_MSG_OPC_CHECK_CMD);
1751
1752 /* Add IDm to message */
1753 ARRAY_TO_STREAM (p, p_cb->peer_nfcid2, NCI_NFCID2_LEN);
1754
1755 /* Add Service code list */
1756 UINT8_TO_STREAM (p, 1); /* Number of services (only 1 service: NDEF) */
1757 UINT16_TO_STREAM (p, T3T_MSG_NDEF_SC_RO); /* Service code (little-endian format) */
1758
1759 /* Number of blocks */
1760 UINT8_TO_STREAM (p, 1); /* Number of blocks (only 1 block: NDEF Attribute Information ) */
1761
1762 /* Block List element: the NDEF attribute information block (block 0) */
1763 UINT8_TO_STREAM (p, T3T_MSG_MASK_TWO_BYTE_BLOCK_DESC_FORMAT);
1764 UINT8_TO_STREAM (p, 0);
1765
1766 /* Calculate length of message */
1767 p_cmd_buf->len = (UINT16) (p - p_cmd_start);
1768
1769 /* Send the T3T message */
Sherry Smith818b56e2014-05-14 16:46:32 -07001770 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 -08001771 {
1772 /* CHECK command sent. Wait for response */
1773 return;
1774 }
1775 }
1776 nci_status = NFC_STATUS_FAILED;
1777 }
1778
1779 /* NDEF detection failed */
1780 p_cb->rw_state = RW_T3T_STATE_IDLE;
1781 evt_data.ndef.status = nci_status;
1782 evt_data.ndef.flags = RW_NDEF_FL_UNKNOWN;
Evan Chua24be4f2013-11-13 15:30:16 -05001783 rw_t3t_update_ndef_flag (&evt_data.ndef.flags);
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001784 (*(rw_cb.p_cback)) (RW_T3T_NDEF_DETECT_EVT, &evt_data);
1785}
1786
1787
1788/*****************************************************************************
1789**
1790** Function rw_t3t_act_handle_get_sc_rsp
1791**
1792** Description Handle response for getting system codes
1793**
1794** Returns Nothing
1795**
1796*****************************************************************************/
1797void rw_t3t_act_handle_get_sc_rsp (tRW_T3T_CB *p_cb, BT_HDR *p_msg_rsp)
1798{
1799 UINT8 *p_t3t_rsp = (UINT8 *) (p_msg_rsp+1) + p_msg_rsp->offset;
1800 UINT8 *p;
1801 UINT16 sc;
1802 UINT8 num_sc, i;
1803
1804 /* Validate response opcode */
1805 if (p_t3t_rsp[T3T_MSG_RSP_OFFSET_RSPCODE] != T3T_MSG_OPC_REQ_SYSTEMCODE_RSP)
1806 {
1807 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]);
1808 }
1809 else
1810 {
1811 /* Point to number of systems parameter */
1812 p = &p_t3t_rsp[T3T_MSG_RSP_OFFSET_NUMSYS];
1813 STREAM_TO_UINT8 (num_sc, p);
1814
1815 /* Validate maximum */
1816 if (num_sc>T3T_MAX_SYSTEM_CODES)
1817 {
1818 RW_TRACE_DEBUG2 ("Tag's number of systems (%i) exceeds NFA max (%i)", num_sc, T3T_MAX_SYSTEM_CODES);
1819 num_sc = T3T_MAX_SYSTEM_CODES;
1820 }
1821
1822 for (i = 0; i < num_sc; i++)
1823 {
1824 BE_STREAM_TO_UINT16 (sc, p);
1825 p_cb->system_codes[p_cb->num_system_codes++] = sc;
1826 }
1827 }
1828 rw_t3t_handle_get_system_codes_cplt ();
1829
1830 GKI_freebuf (p_msg_rsp);
1831}
1832
1833/*****************************************************************************
1834**
1835** Function rw_t3t_update_block
1836**
Martijn Coenen5c65c3a2013-03-27 13:23:36 -07001837** Description Send UPDATE command for single block
1838** (for formatting/configuring read only)
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001839**
1840** Returns tNFC_STATUS
1841**
1842*****************************************************************************/
1843tNFC_STATUS rw_t3t_update_block (tRW_T3T_CB *p_cb, UINT8 block_id, UINT8 *p_block_data)
1844{
1845 UINT8 *p_dst, *p_cmd_start;
1846 BT_HDR *p_cmd_buf;
1847 tNFC_STATUS status;
1848
1849 if ((p_cmd_buf = rw_t3t_get_cmd_buf ()) != NULL)
1850 {
1851 p_dst = p_cmd_start = (UINT8 *) (p_cmd_buf+1) + p_cmd_buf->offset;
1852
1853 /* Add UPDATE opcode to message */
1854 UINT8_TO_STREAM (p_dst, T3T_MSG_OPC_UPDATE_CMD);
1855
1856 /* Add IDm to message */
1857 ARRAY_TO_STREAM (p_dst, p_cb->peer_nfcid2, NCI_NFCID2_LEN);
1858
1859 /* Add Service code list */
1860 UINT8_TO_STREAM (p_dst, 1); /* Number of services (only 1 service: NDEF) */
1861 UINT16_TO_STREAM (p_dst, T3T_MSG_NDEF_SC_RW); /* Service code (little-endian format) */
1862
1863 /* Number of blocks */
1864 UINT8_TO_STREAM (p_dst, 1);
1865
1866 /* Add Block list element for MC */
1867 UINT8_TO_STREAM (p_dst, T3T_MSG_MASK_TWO_BYTE_BLOCK_DESC_FORMAT);
1868 UINT8_TO_STREAM (p_dst, block_id);
1869
1870 /* Copy MC data to UPDATE message */
1871 ARRAY_TO_STREAM (p_dst, p_block_data, T3T_MSG_BLOCKSIZE);
1872
1873 /* Calculate length of message */
1874 p_cmd_buf->len = (UINT16) (p_dst - p_cmd_start);
1875
1876 /* Send the T3T message */
Sherry Smith818b56e2014-05-14 16:46:32 -07001877 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 -08001878 }
1879 else
1880 {
1881 /* Unable to send UPDATE command */
1882 status = NFC_STATUS_NO_BUFFERS;
1883 }
1884
1885 return (status);
1886}
1887
1888/*****************************************************************************
1889**
1890** Function rw_t3t_handle_fmt_poll_rsp
1891**
1892** Description Handle POLL response for formatting felica-lite
1893**
1894** Returns Nothing
1895**
1896*****************************************************************************/
1897static void rw_t3t_handle_fmt_poll_rsp (tRW_T3T_CB *p_cb, UINT8 nci_status, UINT8 num_responses, UINT8 sensf_res_buf_size, UINT8 *p_sensf_res_buf)
1898{
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001899 tRW_DATA evt_data;
1900
1901 evt_data.status = NFC_STATUS_OK;
1902
1903 /* Validate response for poll response */
1904 if ((nci_status == NCI_STATUS_OK) && (num_responses > 0))
1905 {
1906 /* Tag responded for Felica-Lite poll */
1907 /* Get MemoryControl block */
1908 RW_TRACE_DEBUG0 ("Felica-Lite tag detected...getting Memory Control block.");
1909
Martijn Coenen5c65c3a2013-03-27 13:23:36 -07001910 p_cb->rw_substate = RW_T3T_FMT_SST_CHECK_MC_BLK;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001911
Martijn Coenen5c65c3a2013-03-27 13:23:36 -07001912 /* Send command to check Memory Configuration block */
1913 evt_data.status = rw_t3t_check_mc_block (p_cb);
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001914 }
1915 else
1916 {
1917 RW_TRACE_ERROR0 ("Felica-Lite tag not detected");
1918 evt_data.status = NFC_STATUS_FAILED;
1919 }
1920
1921 /* If error, notify upper layer */
1922 if (evt_data.status != NFC_STATUS_OK)
1923 {
1924 rw_t3t_format_cplt (evt_data.status);
1925 }
1926}
1927
1928/*****************************************************************************
1929**
1930** Function rw_t3t_act_handle_fmt_rsp
1931**
1932** Description Handle response for formatting codes
1933**
1934** Returns Nothing
1935**
1936*****************************************************************************/
1937void rw_t3t_act_handle_fmt_rsp (tRW_T3T_CB *p_cb, BT_HDR *p_msg_rsp)
1938{
1939 UINT8 *p_t3t_rsp = (UINT8 *) (p_msg_rsp+1) + p_msg_rsp->offset;
1940 UINT8 *p_mc;
1941 tRW_DATA evt_data;
1942
1943 evt_data.status = NFC_STATUS_OK;
1944
1945 /* Check tags's response for reading MemoryControl block */
1946 if (p_cb->rw_substate == RW_T3T_FMT_SST_CHECK_MC_BLK)
1947 {
1948 /* Validate response opcode */
1949 if (p_t3t_rsp[T3T_MSG_RSP_OFFSET_RSPCODE] != T3T_MSG_OPC_CHECK_RSP)
1950 {
1951 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]);
1952 evt_data.status = NFC_STATUS_FAILED;
1953 }
1954 /* Validate status code and NFCID2 response from tag */
1955 else if ( (p_t3t_rsp[T3T_MSG_RSP_OFFSET_STATUS1] != T3T_MSG_RSP_STATUS_OK) /* verify response status code */
1956 ||(memcmp (p_cb->peer_nfcid2, &p_t3t_rsp[T3T_MSG_RSP_OFFSET_IDM], NCI_NFCID2_LEN) != 0) ) /* verify response IDm */
1957 {
1958 evt_data.status = NFC_STATUS_FAILED;
1959 }
1960 else
1961 {
1962 /* Check if memory configuration (MC) block to see if SYS_OP=1 (NDEF enabled) */
1963 p_mc = &p_t3t_rsp[T3T_MSG_RSP_OFFSET_CHECK_DATA]; /* Point to MC data of CHECK response */
1964
1965 if (p_mc[T3T_MSG_FELICALITE_MC_OFFSET_SYS_OP] != 0x01)
1966 {
1967 /* Tag is not currently enabled for NDEF. Indicate that we need to update the MC block */
1968
1969 /* Set SYS_OP field to 0x01 (enable NDEF) */
1970 p_mc[T3T_MSG_FELICALITE_MC_OFFSET_SYS_OP] = 0x01;
1971
Martijn Coenen5c65c3a2013-03-27 13:23:36 -07001972 /* Set RF_PRM field to 0x07 (procedure of issuance) */
1973 p_mc[T3T_MSG_FELICALITE_MC_OFFSET_RF_PRM] = 0x07;
1974
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001975 /* Construct and send UPDATE message to write MC block */
1976 p_cb->rw_substate = RW_T3T_FMT_SST_UPDATE_MC_BLK;
1977 evt_data.status = rw_t3t_update_block (p_cb, T3T_MSG_FELICALITE_BLOCK_ID_MC, p_mc);
1978 }
1979 else
1980 {
1981 /* SYS_OP=1: ndef already enabled. Just need to update attribute information block */
1982 p_cb->rw_substate = RW_T3T_FMT_SST_UPDATE_NDEF_ATTRIB;
1983 evt_data.status = rw_t3t_update_block (p_cb, 0, (UINT8 *) rw_t3t_default_attrib_info);
1984 }
1985 }
1986
1987 /* If error, notify upper layer */
1988 if (evt_data.status != NFC_STATUS_OK)
1989 {
1990 rw_t3t_format_cplt (evt_data.status);
1991 }
1992 }
1993 else if (p_cb->rw_substate == RW_T3T_FMT_SST_UPDATE_MC_BLK)
1994 {
1995 /* Validate response opcode */
1996 if ( (p_t3t_rsp[T3T_MSG_RSP_OFFSET_RSPCODE] != T3T_MSG_OPC_UPDATE_RSP)
1997 ||(p_t3t_rsp[T3T_MSG_RSP_OFFSET_STATUS1] != T3T_MSG_RSP_STATUS_OK) )
1998
1999 {
2000 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]);
2001 evt_data.status = NFC_STATUS_FAILED;
2002 }
2003 else
2004 {
2005 /* SYS_OP=1: ndef already enabled. Just need to update attribute information block */
2006 p_cb->rw_substate = RW_T3T_FMT_SST_UPDATE_NDEF_ATTRIB;
2007 evt_data.status = rw_t3t_update_block (p_cb, 0, (UINT8 *) rw_t3t_default_attrib_info);
2008 }
2009
2010 /* If error, notify upper layer */
2011 if (evt_data.status != NFC_STATUS_OK)
2012 {
2013 rw_t3t_format_cplt (evt_data.status);
2014 }
2015 }
2016 else if (p_cb->rw_substate == RW_T3T_FMT_SST_UPDATE_NDEF_ATTRIB)
2017 {
2018 /* Validate response opcode */
2019 if ( (p_t3t_rsp[T3T_MSG_RSP_OFFSET_RSPCODE] != T3T_MSG_OPC_UPDATE_RSP)
2020 ||(p_t3t_rsp[T3T_MSG_RSP_OFFSET_STATUS1] != T3T_MSG_RSP_STATUS_OK) )
2021
2022 {
2023 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]);
2024 evt_data.status = NFC_STATUS_FAILED;
2025 }
2026
2027
2028 rw_t3t_format_cplt (evt_data.status);
2029 }
2030
2031 GKI_freebuf (p_msg_rsp);
2032}
2033
Martijn Coenen5c65c3a2013-03-27 13:23:36 -07002034/*****************************************************************************
2035**
2036** Function rw_t3t_handle_sro_poll_rsp
2037**
2038** Description Handle POLL response for configuring felica-lite read only
2039**
2040** Returns Nothing
2041**
2042*****************************************************************************/
2043static void rw_t3t_handle_sro_poll_rsp (tRW_T3T_CB *p_cb, UINT8 nci_status, UINT8 num_responses, UINT8 sensf_res_buf_size, UINT8 *p_sensf_res_buf)
2044{
2045 tRW_DATA evt_data;
2046 UINT8 rw_t3t_ndef_attrib_info[T3T_MSG_BLOCKSIZE];
2047 UINT8 *p;
2048 UINT8 tempU8;
2049 UINT16 checksum, i;
2050 UINT32 tempU32 = 0;
2051
2052 evt_data.status = NFC_STATUS_OK;
2053
2054 /* Validate response for poll response */
2055 if ((nci_status == NCI_STATUS_OK) && (num_responses > 0))
2056 {
2057 /* Tag responded for Felica-Lite poll */
2058 if (p_cb->ndef_attrib.rwflag != T3T_MSG_NDEF_RWFLAG_RO)
2059 {
2060 /* First update attribute information block */
2061 RW_TRACE_DEBUG0 ("Felica-Lite tag detected...update NDef attribution block.");
2062
2063 p_cb->rw_substate = RW_T3T_SRO_SST_UPDATE_NDEF_ATTRIB;
2064
2065 p = rw_t3t_ndef_attrib_info;
2066
2067 UINT8_TO_STREAM (p, p_cb->ndef_attrib.version);
2068
2069 /* Update NDEF info */
2070 UINT8_TO_STREAM (p, p_cb->ndef_attrib.nbr); /* NBr: number of blocks that can be read using one Check command */
2071 UINT8_TO_STREAM (p, p_cb->ndef_attrib.nbw); /* Nbw: number of blocks that can be written using one Update command */
2072 UINT16_TO_BE_STREAM (p, p_cb->ndef_attrib.nmaxb); /* Nmaxb: maximum number of blocks available for NDEF data */
2073 UINT32_TO_BE_STREAM (p, tempU32);
2074 UINT8_TO_STREAM (p, p_cb->ndef_attrib.writef); /* WriteFlag: 00h if writing data finished; 0Fh if writing data in progress */
2075 UINT8_TO_STREAM (p, 0x00); /* RWFlag: 00h NDEF is read-only */
2076
2077 tempU8 = (UINT8) (p_cb->ndef_attrib.ln >> 16);
2078 /* Get length (3-byte, big-endian) */
2079 UINT8_TO_STREAM (p, tempU8); /* Ln: high-byte */
2080 UINT16_TO_BE_STREAM (p, p_cb->ndef_attrib.ln); /* Ln: lo-word */
2081
2082 /* Calculate and append Checksum */
2083 checksum = 0;
2084 for (i = 0; i < T3T_MSG_NDEF_ATTR_INFO_SIZE; i++)
2085 {
2086 checksum+=rw_t3t_ndef_attrib_info[i];
2087 }
2088 UINT16_TO_BE_STREAM (p, checksum);
2089
2090 evt_data.status = rw_t3t_update_block (p_cb, 0, (UINT8 *) rw_t3t_ndef_attrib_info);
2091 }
2092 else if (p_cb->cur_cmd == RW_T3T_CMD_SET_READ_ONLY_HARD)
2093 {
2094 /* NDEF is already read only, Read and update MemoryControl block */
2095 RW_TRACE_DEBUG0 ("Felica-Lite tag detected...getting Memory Control block.");
2096 p_cb->rw_substate = RW_T3T_SRO_SST_CHECK_MC_BLK;
2097
2098 /* Send command to check Memory Configuration block */
2099 evt_data.status = rw_t3t_check_mc_block (p_cb);
2100 }
2101 }
2102 else
2103 {
2104 RW_TRACE_ERROR0 ("Felica-Lite tag not detected");
2105 evt_data.status = NFC_STATUS_FAILED;
2106 }
2107
2108 /* If error, notify upper layer */
2109 if (evt_data.status != NFC_STATUS_OK)
2110 {
2111 rw_t3t_set_readonly_cplt (evt_data.status);
2112 }
2113}
2114
2115/*****************************************************************************
2116**
2117** Function rw_t3t_act_handle_sro_rsp
2118**
2119** Description Handle response for setting read only codes
2120**
2121** Returns Nothing
2122**
2123*****************************************************************************/
2124void rw_t3t_act_handle_sro_rsp (tRW_T3T_CB *p_cb, BT_HDR *p_msg_rsp)
2125{
2126 UINT8 *p_t3t_rsp = (UINT8 *) (p_msg_rsp+1) + p_msg_rsp->offset;
2127 UINT8 *p_mc;
2128 tRW_DATA evt_data;
2129
2130 evt_data.status = NFC_STATUS_OK;
2131
2132 if (p_cb->rw_substate == RW_T3T_SRO_SST_UPDATE_NDEF_ATTRIB)
2133 {
2134 /* Validate response opcode */
2135 if ( (p_t3t_rsp[T3T_MSG_RSP_OFFSET_RSPCODE] != T3T_MSG_OPC_UPDATE_RSP)
2136 ||(p_t3t_rsp[T3T_MSG_RSP_OFFSET_STATUS1] != T3T_MSG_RSP_STATUS_OK) )
2137
2138 {
2139 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]);
2140 evt_data.status = NFC_STATUS_FAILED;
2141 }
2142 else
2143 {
2144 p_cb->ndef_attrib.rwflag = T3T_MSG_NDEF_RWFLAG_RO;
2145 if (p_cb->cur_cmd == RW_T3T_CMD_SET_READ_ONLY_HARD)
2146 {
2147 p_cb->rw_substate = RW_T3T_SRO_SST_CHECK_MC_BLK;
2148
2149 /* Send command to check Memory Configuration block */
2150 evt_data.status = rw_t3t_check_mc_block (p_cb);
2151 }
2152 else
2153 {
2154 rw_t3t_set_readonly_cplt (evt_data.status);
2155 }
2156 }
2157 }
2158 else if (p_cb->rw_substate == RW_T3T_SRO_SST_CHECK_MC_BLK)
2159 {
2160 /* Check tags's response for reading MemoryControl block, Validate response opcode */
2161 if (p_t3t_rsp[T3T_MSG_RSP_OFFSET_RSPCODE] != T3T_MSG_OPC_CHECK_RSP)
2162 {
2163 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]);
2164 evt_data.status = NFC_STATUS_FAILED;
2165 }
2166 /* Validate status code and NFCID2 response from tag */
2167 else if ( (p_t3t_rsp[T3T_MSG_RSP_OFFSET_STATUS1] != T3T_MSG_RSP_STATUS_OK) /* verify response status code */
2168 ||(memcmp (p_cb->peer_nfcid2, &p_t3t_rsp[T3T_MSG_RSP_OFFSET_IDM], NCI_NFCID2_LEN) != 0) ) /* verify response IDm */
2169 {
2170 evt_data.status = NFC_STATUS_FAILED;
2171 }
2172 else
2173 {
2174 /* Check if memory configuration (MC) block to see if SYS_OP=1 (NDEF enabled) */
2175 p_mc = &p_t3t_rsp[T3T_MSG_RSP_OFFSET_CHECK_DATA]; /* Point to MC data of CHECK response */
2176
2177 if (p_mc[T3T_MSG_FELICALITE_MC_OFFSET_SYS_OP] != 0x01)
2178 {
2179 /* Tag is not currently enabled for NDEF */
2180 evt_data.status = NFC_STATUS_FAILED;
2181 }
2182 else
2183 {
2184 /* Set MC_SP field with MC[0] = 0x00 & MC[1] = 0xC0 (Hardlock) to change access permission from RW to RO */
2185 p_mc[T3T_MSG_FELICALITE_MC_OFFSET_MC_SP] = 0x00;
2186 /* Not changing the access permission of Subtraction Register and MC[0:1] */
2187 p_mc[T3T_MSG_FELICALITE_MC_OFFSET_MC_SP + 1] = 0xC0;
2188
2189 /* Set RF_PRM field to 0x07 (procedure of issuance) */
2190 p_mc[T3T_MSG_FELICALITE_MC_OFFSET_RF_PRM] = 0x07;
2191
2192 /* Construct and send UPDATE message to write MC block */
2193 p_cb->rw_substate = RW_T3T_SRO_SST_UPDATE_MC_BLK;
2194 evt_data.status = rw_t3t_update_block (p_cb, T3T_MSG_FELICALITE_BLOCK_ID_MC, p_mc);
2195 }
2196 }
2197 }
2198 else if (p_cb->rw_substate == RW_T3T_SRO_SST_UPDATE_MC_BLK)
2199 {
2200 /* Validate response opcode */
2201 if ( (p_t3t_rsp[T3T_MSG_RSP_OFFSET_RSPCODE] != T3T_MSG_OPC_UPDATE_RSP)
2202 ||(p_t3t_rsp[T3T_MSG_RSP_OFFSET_STATUS1] != T3T_MSG_RSP_STATUS_OK) )
2203
2204 {
2205 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]);
2206 evt_data.status = NFC_STATUS_FAILED;
2207 }
2208 else
2209 {
2210 rw_t3t_set_readonly_cplt (evt_data.status);
2211 }
2212 }
2213
2214 /* If error, notify upper layer */
2215 if (evt_data.status != NFC_STATUS_OK)
2216 {
2217 rw_t3t_set_readonly_cplt (evt_data.status);
2218 }
2219
2220 GKI_freebuf (p_msg_rsp);
2221}
2222
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002223/*******************************************************************************
2224**
2225** Function rw_t3t_data_cback
2226**
2227** Description This callback function receives the data from NFCC.
2228**
2229** Returns none
2230**
2231*******************************************************************************/
Evan Chua24be4f2013-11-13 15:30:16 -05002232void rw_t3t_data_cback (UINT8 conn_id, tNFC_DATA_CEVT *p_data)
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002233{
Evan Chua24be4f2013-11-13 15:30:16 -05002234 tRW_T3T_CB *p_cb = &rw_cb.tcb.t3t;
2235 BT_HDR *p_msg = p_data->p_data;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002236 BOOLEAN free_msg = FALSE; /* if TRUE, free msg buffer before returning */
2237 UINT8 *p, sod;
2238
2239 /* Stop rsponse timer */
2240 nfc_stop_quick_timer (&p_cb->timer);
2241
2242#if (defined (RW_STATS_INCLUDED) && (RW_STATS_INCLUDED == TRUE))
2243 /* Update rx stats */
2244 rw_main_update_rx_stats (p_msg->len);
2245#endif /* RW_STATS_INCLUDED */
2246
2247 /* Check if we are expecting a response */
2248 if (p_cb->rw_state != RW_T3T_STATE_COMMAND_PENDING)
2249 {
2250 /*
2251 ** This must be raw frame response
2252 ** send raw frame to app with SoD
2253 */
Evan Chua24be4f2013-11-13 15:30:16 -05002254 rw_t3t_act_handle_raw_senddata_rsp (p_cb, p_data);
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002255 }
2256 /* Sanity check: verify msg len is big enough to contain t3t header */
2257 else if (p_msg->len < T3T_MSG_RSP_COMMON_HDR_LEN)
2258 {
2259 RW_TRACE_ERROR1 ("T3T: invalid Type3 Tag Message (invalid len: %i)", p_msg->len);
2260 free_msg = TRUE;
2261
2262 rw_t3t_process_frame_error ();
2263 }
2264 else
2265 {
2266 /* Check for RF frame error */
2267 p = (UINT8 *) (p_msg+1) + p_msg->offset;
2268 sod = p[0];
2269 if (p[sod] != NCI_STATUS_OK)
2270 {
2271 RW_TRACE_ERROR1 ("T3T: rf frame error (crc status=%i)", p[sod]);
2272 GKI_freebuf (p_msg);
2273
2274 rw_t3t_process_frame_error ();
2275 return;
2276 }
2277
2278#if (BT_TRACE_PROTOCOL == TRUE)
2279 DispT3TagMessage (p_msg, TRUE);
2280#endif
2281
2282 /* Skip over SoD */
2283 p_msg->offset++;
2284 p_msg->len--;
2285
2286 /* Get response code */
2287 switch (p_cb->cur_cmd)
2288 {
2289 case RW_T3T_CMD_DETECT_NDEF:
2290 rw_t3t_act_handle_ndef_detect_rsp (p_cb, p_msg);
2291 break;
2292
2293 case RW_T3T_CMD_CHECK_NDEF:
2294 rw_t3t_act_handle_check_ndef_rsp (p_cb, p_msg);
2295 break;
2296
2297 case RW_T3T_CMD_UPDATE_NDEF:
2298 rw_t3t_act_handle_update_ndef_rsp (p_cb, p_msg);
2299 break;
2300
2301 case RW_T3T_CMD_CHECK:
2302 rw_t3t_act_handle_check_rsp (p_cb, p_msg);
2303 break;
2304
2305 case RW_T3T_CMD_UPDATE:
2306 rw_t3t_act_handle_update_rsp (p_cb, p_msg);
2307 break;
2308
2309 case RW_T3T_CMD_SEND_RAW_FRAME:
Evan Chua24be4f2013-11-13 15:30:16 -05002310 rw_t3t_act_handle_raw_senddata_rsp (p_cb, p_data);
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002311 break;
2312
2313 case RW_T3T_CMD_GET_SYSTEM_CODES:
2314 rw_t3t_act_handle_get_sc_rsp (p_cb, p_msg);
2315 break;
2316
2317 case RW_T3T_CMD_FORMAT:
2318 rw_t3t_act_handle_fmt_rsp (p_cb, p_msg);
2319 break;
2320
Martijn Coenen5c65c3a2013-03-27 13:23:36 -07002321 case RW_T3T_CMD_SET_READ_ONLY_SOFT:
2322 case RW_T3T_CMD_SET_READ_ONLY_HARD:
2323 rw_t3t_act_handle_sro_rsp (p_cb, p_msg);
2324 break;
2325
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002326 default:
2327 GKI_freebuf (p_msg);
2328 break;
2329 }
2330 }
2331
2332 if (free_msg)
2333 {
2334 GKI_freebuf (p_msg);
2335 }
2336}
2337
2338
2339/*******************************************************************************
2340**
2341** Function rw_t3t_conn_cback
2342**
2343** Description This callback function receives the events/data from NFCC.
2344**
2345** Returns none
2346**
2347*******************************************************************************/
2348void rw_t3t_conn_cback (UINT8 conn_id, tNFC_CONN_EVT event, tNFC_CONN *p_data)
2349{
2350 tRW_T3T_CB *p_cb = &rw_cb.tcb.t3t;
2351 RW_TRACE_DEBUG2 ("rw_t3t_conn_cback: conn_id=%i, evt=0x%02x", conn_id, event);
2352
2353 /* Only handle NFC_RF_CONN_ID conn_id */
2354 if (conn_id != NFC_RF_CONN_ID)
2355 {
2356 return;
2357 }
2358
2359 switch (event)
2360 {
2361 case NFC_DEACTIVATE_CEVT:
2362 rw_t3t_unselect (NULL);
2363 break;
2364
2365 case NFC_DATA_CEVT: /* check for status in tNFC_CONN */
Evan Chua24be4f2013-11-13 15:30:16 -05002366 if ( (p_data->data.status == NFC_STATUS_OK)
2367 ||(p_data->data.status == NFC_STATUS_CONTINUE) )
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002368 {
Evan Chua24be4f2013-11-13 15:30:16 -05002369 rw_t3t_data_cback (conn_id, &(p_data->data));
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002370 break;
2371 }
2372 /* Data event with error status...fall through to NFC_ERROR_CEVT case */
2373
2374
2375 case NFC_ERROR_CEVT:
2376 nfc_stop_quick_timer (&p_cb->timer);
2377
2378#if (defined (RW_STATS_INCLUDED) && (RW_STATS_INCLUDED == TRUE))
2379 rw_main_update_trans_error_stats ();
2380#endif /* RW_STATS_INCLUDED */
2381
2382 if (event == NFC_ERROR_CEVT)
2383 rw_t3t_process_error (NFC_STATUS_TIMEOUT);
2384 else
2385 rw_t3t_process_error (p_data->status);
2386 break;
2387
2388 default:
2389 break;
2390
2391 }
2392}
2393
2394
2395/*******************************************************************************
2396**
Sherry Smith818b56e2014-05-14 16:46:32 -07002397** Function rw_t3t_mrti_to_a_b
2398**
2399** Description Converts the given MRTI (Maximum Response Time Information)
2400** to the base to calculate timeout value.
2401** (The timeout value is a + b * number_blocks)
2402**
2403** Returns NFC_STATUS_OK
2404**
2405*******************************************************************************/
2406static void rw_t3t_mrti_to_a_b (UINT8 mrti, UINT32 *p_a, UINT32 *p_b)
2407{
2408 UINT8 a, b, e;
2409
2410 a = (mrti & 0x7) + 1; /* A is bit 0 ~ bit 2 */
2411 mrti >>=3;
2412 b = (mrti & 0x7) + 1; /* B is bit 3 ~ bit 5 */
2413 mrti >>=3;
2414 e = mrti & 0x3; /* E is bit 6 ~ bit 7 */
2415 *p_a = rw_t3t_mrti_base[e] * a; /* (A+1) * base (i.e T/t3t * 4^E) */
2416 *p_b = rw_t3t_mrti_base[e] * b; /* (B+1) * base (i.e T/t3t * 4^E) */
2417}
2418
2419
2420/*******************************************************************************
2421**
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002422** Function rw_t3t_select
2423**
2424** Description Called by NFC manager when a Type3 tag has been activated
2425**
2426** Returns NFC_STATUS_OK
2427**
2428*******************************************************************************/
2429tNFC_STATUS rw_t3t_select (UINT8 peer_nfcid2[NCI_RF_F_UID_LEN], UINT8 mrti_check, UINT8 mrti_update)
2430{
2431 tRW_T3T_CB *p_cb = &rw_cb.tcb.t3t;
2432
2433 RW_TRACE_API0 ("rw_t3t_select");
2434
2435 memcpy (p_cb->peer_nfcid2, peer_nfcid2, NCI_NFCID2_LEN); /* Store tag's NFCID2 */
2436 p_cb->ndef_attrib.status = NFC_STATUS_NOT_INITIALIZED; /* Indicate that NDEF detection has not been performed yet */
2437 p_cb->rw_state = RW_T3T_STATE_IDLE;
2438 p_cb->flags = 0;
Sherry Smith818b56e2014-05-14 16:46:32 -07002439 rw_t3t_mrti_to_a_b (mrti_check, &p_cb->check_tout_a, &p_cb->check_tout_b);
2440 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 -08002441
2442 /* Alloc cmd buf for retransmissions */
2443 if (p_cb->p_cur_cmd_buf == NULL)
2444 {
2445 if ((p_cb->p_cur_cmd_buf = (BT_HDR *) GKI_getpoolbuf (NFC_RW_POOL_ID)) == NULL)
2446 {
2447 RW_TRACE_ERROR0 ("rw_t3t_select: unable to allocate buffer for retransmission");
2448 p_cb->rw_state = RW_T3T_STATE_NOT_ACTIVATED;
2449 return (NFC_STATUS_FAILED);
2450 }
2451 }
2452
2453
2454 NFC_SetStaticRfCback (rw_t3t_conn_cback);
2455
2456 return NFC_STATUS_OK;
2457}
2458
2459
2460/*******************************************************************************
2461**
2462** Function rw_t3t_unselect
2463**
2464** Description Called by NFC manager when a Type3 tag has been de-activated
2465**
2466** Returns NFC_STATUS_OK
2467**
2468*******************************************************************************/
2469static tNFC_STATUS rw_t3t_unselect (UINT8 peer_nfcid2[])
2470{
2471 tRW_T3T_CB *p_cb = &rw_cb.tcb.t3t;
2472
2473#if (defined (RW_STATS_INCLUDED) && (RW_STATS_INCLUDED == TRUE))
2474 /* Display stats */
2475 rw_main_log_stats ();
2476#endif /* RW_STATS_INCLUDED */
2477
2478 /* Stop t3t timer (if started) */
2479 nfc_stop_quick_timer (&p_cb->timer);
2480
2481 /* Free cmd buf for retransmissions */
2482 if (p_cb->p_cur_cmd_buf)
2483 {
2484 GKI_freebuf (p_cb->p_cur_cmd_buf);
2485 p_cb->p_cur_cmd_buf = NULL;
2486 }
2487
2488 p_cb->rw_state = RW_T3T_STATE_NOT_ACTIVATED;
2489 NFC_SetStaticRfCback (NULL);
2490
2491 return NFC_STATUS_OK;
2492}
2493
Evan Chua24be4f2013-11-13 15:30:16 -05002494/*******************************************************************************
2495**
2496** Function rw_t3t_update_ndef_flag
2497**
2498** Description set additional NDEF Flags for felica lite tag
2499**
2500** Returns updated NDEF Flag value
2501**
2502*******************************************************************************/
2503static void rw_t3t_update_ndef_flag (UINT8 *p_flag)
2504{
2505 tRW_T3T_CB *p_cb = &rw_cb.tcb.t3t;
2506 UINT8 xx;
2507
2508 for (xx = 0; xx < p_cb->num_system_codes; xx++)
2509 {
2510 if (p_cb->system_codes[xx] == T3T_SYSTEM_CODE_FELICA_LITE)
2511 {
2512 *p_flag &= ~RW_NDEF_FL_UNKNOWN;
2513 *p_flag |= (RW_NDEF_FL_SUPPORTED | RW_NDEF_FL_FORMATABLE);
2514 break;
2515 }
2516 }
2517}
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002518
2519#if (BT_TRACE_VERBOSE == TRUE)
2520/*******************************************************************************
2521**
2522** Function rw_t3t_cmd_str
2523**
2524** Description Converts cmd_id to command string for logging
2525**
2526** Returns command string
2527**
2528*******************************************************************************/
2529static char *rw_t3t_cmd_str (UINT8 cmd_id)
2530{
2531 switch (cmd_id)
2532 {
2533 case RW_T3T_CMD_DETECT_NDEF:
2534 return "RW_T3T_CMD_DETECT_NDEF";
2535
2536 case RW_T3T_CMD_CHECK_NDEF:
2537 return "RW_T3T_CMD_CHECK_NDEF";
2538
2539 case RW_T3T_CMD_UPDATE_NDEF:
2540 return "RW_T3T_CMD_UPDATE_NDEF";
2541
2542 case RW_T3T_CMD_CHECK:
2543 return "RW_T3T_CMD_CHECK";
2544
2545 case RW_T3T_CMD_UPDATE:
2546 return "RW_T3T_CMD_UPDATE";
2547
2548 case RW_T3T_CMD_SEND_RAW_FRAME:
2549 return "RW_T3T_CMD_SEND_RAW_FRAME";
2550
2551 case RW_T3T_CMD_GET_SYSTEM_CODES:
2552 return "RW_T3T_CMD_GET_SYSTEM_CODES";
2553
2554 default:
2555 return "Unknown";
2556 }
2557}
2558
2559
2560/*******************************************************************************
2561**
2562** Function rw_t3t_state_str
2563**
2564** Description Converts state_id to command string for logging
2565**
2566** Returns command string
2567**
2568*******************************************************************************/
2569static char *rw_t3t_state_str (UINT8 state_id)
2570{
2571 switch (state_id)
2572 {
2573 case RW_T3T_STATE_NOT_ACTIVATED:
2574 return "RW_T3T_STATE_NOT_ACTIVATED";
2575
2576 case RW_T3T_STATE_IDLE:
2577 return "RW_T3T_STATE_IDLE";
2578
2579 case RW_T3T_STATE_COMMAND_PENDING:
2580 return "RW_T3T_STATE_COMMAND_PENDING";
2581
2582 default:
2583 return "Unknown";
2584 }
2585}
2586#endif
2587
2588/*****************************************************************************
2589** Type3 Tag API Functions
2590*****************************************************************************/
2591
2592
2593/*****************************************************************************
2594**
2595** Function RW_T3tDetectNDef
2596**
2597** Description
2598** This function is used to perform NDEF detection on a Type 3 tag, and
2599** retrieve the tag's NDEF attribute information (block 0).
2600**
2601** Before using this API, the application must call RW_SelectTagType to
2602** indicate that a Type 3 tag has been activated, and to provide the
2603** tag's Manufacture ID (IDm) .
2604**
2605** Returns
2606** NFC_STATUS_OK: ndef detection procedure started
2607** NFC_STATUS_NO_BUFFERS: unable to allocate a buffer for this operation
2608** NFC_STATUS_FAILED: other error
2609**
2610*****************************************************************************/
2611tNFC_STATUS RW_T3tDetectNDef (void)
2612{
2613 tRW_T3T_CB *p_cb = &rw_cb.tcb.t3t;
2614 tNFC_STATUS retval = NFC_STATUS_OK;
2615
2616 RW_TRACE_API0 ("RW_T3tDetectNDef");
2617
2618 /* Check if we are in valid state to handle this API */
2619 if (p_cb->rw_state != RW_T3T_STATE_IDLE)
2620 {
2621 RW_TRACE_ERROR1 ("Error: invalid state to handle API (0x%x)", p_cb->rw_state);
2622 return (NFC_STATUS_FAILED);
2623 }
2624
The Android Open Source Project808ebf82012-12-13 15:18:55 -08002625 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 -08002626 {
2627 p_cb->cur_cmd = RW_T3T_CMD_DETECT_NDEF;
2628 p_cb->cur_tout = RW_T3T_DEFAULT_CMD_TIMEOUT_TICKS;
2629 p_cb->cur_poll_rc = 0;
2630 p_cb->rw_state = RW_T3T_STATE_COMMAND_PENDING;
2631 p_cb->flags |= RW_T3T_FL_W4_NDEF_DETECT_POLL_RSP;
2632
2633 /* start timer for waiting for responses */
2634 rw_t3t_start_poll_timer (p_cb);
2635 }
2636
2637 return (retval);
2638}
2639
2640
2641/*****************************************************************************
2642**
2643** Function RW_T3tCheckNDef
2644**
2645** Description
2646** Retrieve NDEF contents from a Type3 tag.
2647**
2648** The RW_T3T_CHECK_EVT event is used to notify the application for each
2649** segment of NDEF data received. The RW_T3T_CHECK_CPLT_EVT event is used to
2650** notify the application all segments have been received.
2651**
2652** Before using this API, the RW_T3tDetectNDef function must be called to
2653** verify that the tag contains NDEF data, and to retrieve the NDEF
2654** attributes.
2655**
2656** Internally, this command will be separated into multiple Tag 3 Check
2657** commands (if necessary) - depending on the tag's Nbr (max number of
2658** blocks per read) attribute.
2659**
2660** Returns
2661** NFC_STATUS_OK: check command started
2662** NFC_STATUS_NO_BUFFERS: unable to allocate a buffer for this operation
2663** NFC_STATUS_FAILED: other error
2664**
2665*****************************************************************************/
2666tNFC_STATUS RW_T3tCheckNDef (void)
2667{
2668 tNFC_STATUS retval = NFC_STATUS_OK;
2669 tRW_T3T_CB *p_cb = &rw_cb.tcb.t3t;
2670
2671 RW_TRACE_API0 ("RW_T3tCheckNDef");
2672
2673 /* Check if we are in valid state to handle this API */
2674 if (p_cb->rw_state != RW_T3T_STATE_IDLE)
2675 {
2676 RW_TRACE_ERROR1 ("Error: invalid state to handle API (0x%x)", p_cb->rw_state);
2677 return (NFC_STATUS_FAILED);
2678 }
2679 else if (p_cb->ndef_attrib.status != NFC_STATUS_OK) /* NDEF detection not performed yet? */
2680 {
2681 RW_TRACE_ERROR0 ("Error: NDEF detection not performed yet");
2682 return (NFC_STATUS_NOT_INITIALIZED);
2683 }
2684 else if (p_cb->ndef_attrib.ln == 0)
2685 {
2686 RW_TRACE_ERROR0 ("Type 3 tag contains empty NDEF message");
2687 return (NFC_STATUS_FAILED);
2688 }
2689
2690 /* Check number of blocks needed for this update */
2691 p_cb->flags &= ~RW_T3T_FL_IS_FINAL_NDEF_SEGMENT;
2692 p_cb->ndef_rx_offset = 0;
2693 retval = rw_t3t_send_next_ndef_check_cmd (p_cb);
2694
2695 return (retval);
2696}
2697
2698/*****************************************************************************
2699**
2700** Function RW_T3tUpdateNDef
2701**
2702** Description
2703** Write NDEF contents to a Type3 tag.
2704**
2705** The RW_T3T_UPDATE_CPLT_EVT callback event will be used to notify the
2706** application of the response.
2707**
2708** Before using this API, the RW_T3tDetectNDef function must be called to
2709** verify that the tag contains NDEF data, and to retrieve the NDEF
2710** attributes.
2711**
2712** Internally, this command will be separated into multiple Tag 3 Update
2713** commands (if necessary) - depending on the tag's Nbw (max number of
2714** blocks per write) attribute.
2715**
2716** Returns
2717** NFC_STATUS_OK: check command started
2718** NFC_STATUS_NO_BUFFERS: unable to allocate a buffer for this operation
2719** NFC_STATUS_REFUSED: tag is read-only
2720** NFC_STATUS_BUFFER_FULL: len exceeds tag's maximum size
2721** NFC_STATUS_FAILED: other error
2722**
2723*****************************************************************************/
2724tNFC_STATUS RW_T3tUpdateNDef (UINT32 len, UINT8 *p_data)
2725{
2726 tNFC_STATUS retval = NFC_STATUS_OK;
2727 tRW_T3T_CB *p_cb = &rw_cb.tcb.t3t;
2728
2729 RW_TRACE_API1 ("RW_T3tUpdateNDef (len=%i)", len);
2730
2731 /* Check if we are in valid state to handle this API */
2732 if (p_cb->rw_state != RW_T3T_STATE_IDLE)
2733 {
2734 RW_TRACE_ERROR1 ("Error: invalid state to handle API (0x%x)", p_cb->rw_state);
2735 return (NFC_STATUS_FAILED);
2736 }
2737 else if (p_cb->ndef_attrib.status != NFC_STATUS_OK) /* NDEF detection not performed yet? */
2738 {
2739 RW_TRACE_ERROR0 ("Error: NDEF detection not performed yet");
2740 return (NFC_STATUS_NOT_INITIALIZED);
2741 }
2742 else if (len > (((UINT32)p_cb->ndef_attrib.nmaxb) * 16)) /* Len exceed's tag's NDEF memory? */
2743 {
2744 return (NFC_STATUS_BUFFER_FULL);
2745 }
2746 else if (p_cb->ndef_attrib.rwflag == T3T_MSG_NDEF_RWFLAG_RO)/* Tag's NDEF memory is read-only? */
2747 {
2748 return (NFC_STATUS_REFUSED);
2749 }
2750
2751 /* Check number of blocks needed for this update */
2752 p_cb->flags &= ~RW_T3T_FL_IS_FINAL_NDEF_SEGMENT;
2753 p_cb->ndef_msg_bytes_sent = 0;
2754 p_cb->ndef_msg_len = len;
2755 p_cb->ndef_msg = p_data;
2756
2757 /* Send initial UPDATE command for NDEF Attribute Info */
2758 retval = rw_t3t_send_update_ndef_attribute_cmd (p_cb, TRUE);
2759
2760 return (retval);
2761}
2762
2763/*****************************************************************************
2764**
2765** Function RW_T3tCheck
2766**
2767** Description
2768** Read (non-NDEF) contents from a Type3 tag.
2769**
2770** The RW_READ_EVT event is used to notify the application for each
2771** segment of NDEF data received. The RW_READ_CPLT_EVT event is used to
2772** notify the application all segments have been received.
2773**
2774** Before using this API, the application must call RW_SelectTagType to
2775** indicate that a Type 3 tag has been activated, and to provide the
2776** tag's Manufacture ID (IDm) .
2777**
2778** Returns
2779** NFC_STATUS_OK: check command started
2780** NFC_STATUS_NO_BUFFERS: unable to allocate a buffer for this operation
2781** NFC_STATUS_FAILED: other error
2782**
2783*****************************************************************************/
2784tNFC_STATUS RW_T3tCheck (UINT8 num_blocks, tT3T_BLOCK_DESC *t3t_blocks)
2785{
2786 tNFC_STATUS retval = NFC_STATUS_OK;
2787 tRW_T3T_CB *p_cb = &rw_cb.tcb.t3t;
2788
2789 RW_TRACE_API1 ("RW_T3tCheck (num_blocks = %i)", num_blocks);
2790
2791 /* Check if we are in valid state to handle this API */
2792 if (p_cb->rw_state != RW_T3T_STATE_IDLE)
2793 {
2794 RW_TRACE_ERROR1 ("Error: invalid state to handle API (0x%x)", p_cb->rw_state);
2795 return (NFC_STATUS_FAILED);
2796 }
2797
2798 /* Send the CHECK command */
2799 retval = rw_t3t_send_check_cmd (p_cb, num_blocks, t3t_blocks);
2800
2801 return (retval);
2802}
2803
2804/*****************************************************************************
2805**
2806** Function RW_T3tUpdate
2807**
2808** Description
2809** Write (non-NDEF) contents to a Type3 tag.
2810**
2811** The RW_WRITE_CPLT_EVT event is used to notify the application all
2812** segments have been received.
2813**
2814** Before using this API, the application must call RW_SelectTagType to
2815** indicate that a Type 3 tag has been activated, and to provide the tag's
2816** Manufacture ID (IDm) .
2817**
2818** Returns
2819** NFC_STATUS_OK: check command started
2820** NFC_STATUS_NO_BUFFERS: unable to allocate a buffer for this operation
2821** NFC_STATUS_FAILED: other error
2822**
2823*****************************************************************************/
2824tNFC_STATUS RW_T3tUpdate (UINT8 num_blocks, tT3T_BLOCK_DESC *t3t_blocks, UINT8 *p_data)
2825{
2826 tNFC_STATUS retval = NFC_STATUS_OK;
2827 tRW_T3T_CB *p_cb = &rw_cb.tcb.t3t;
2828
2829 RW_TRACE_API1 ("RW_T3tUpdate (num_blocks = %i)", num_blocks);
2830
2831 /* Check if we are in valid state to handle this API */
2832 if (p_cb->rw_state != RW_T3T_STATE_IDLE)
2833 {
2834 RW_TRACE_ERROR1 ("Error: invalid state to handle API (0x%x)", p_cb->rw_state);
2835 return (NFC_STATUS_FAILED);
2836 }
2837
2838 /* Send the UPDATE command */
2839 retval = rw_t3t_send_update_cmd (p_cb, num_blocks, t3t_blocks, p_data);
2840
2841 return (retval);
2842}
2843
2844/*****************************************************************************
2845**
2846** Function RW_T3tPresenceCheck
2847**
2848** Description
2849** Check if the tag is still in the field.
2850**
2851** The RW_T3T_PRESENCE_CHECK_EVT w/ status is used to indicate presence
2852** or non-presence.
2853**
2854** Returns
2855** NFC_STATUS_OK, if raw data frame sent
2856** NFC_STATUS_NO_BUFFERS: unable to allocate a buffer for this operation
2857** NFC_STATUS_FAILED: other error
2858**
2859*****************************************************************************/
2860tNFC_STATUS RW_T3tPresenceCheck (void)
2861{
2862 tNFC_STATUS retval = NFC_STATUS_OK;
2863 tRW_DATA evt_data;
2864 tRW_CB *p_rw_cb = &rw_cb;
2865
2866 RW_TRACE_API0 ("RW_T3tPresenceCheck");
2867
2868 /* If RW_SelectTagType was not called (no conn_callback) return failure */
2869 if (!(p_rw_cb->p_cback))
2870 {
2871 retval = NFC_STATUS_FAILED;
2872 }
2873 /* If we are not activated, then RW_T3T_PRESENCE_CHECK_EVT status=FAIL */
2874 else if (p_rw_cb->tcb.t3t.rw_state == RW_T3T_STATE_NOT_ACTIVATED)
2875 {
2876 evt_data.status = NFC_STATUS_FAILED;
2877 (*p_rw_cb->p_cback) (RW_T3T_PRESENCE_CHECK_EVT, &evt_data);
2878 }
2879 /* If command is pending */
2880 else if (p_rw_cb->tcb.t3t.rw_state == RW_T3T_STATE_COMMAND_PENDING)
2881 {
2882 /* If already performing presence check, return error */
2883 if (p_rw_cb->tcb.t3t.flags & RW_T3T_FL_W4_PRESENCE_CHECK_POLL_RSP)
2884 {
2885 RW_TRACE_DEBUG0 ("RW_T3tPresenceCheck already in progress");
2886 retval = NFC_STATUS_FAILED;
2887 }
2888 /* If busy with any other command, assume that the tag is present */
2889 else
2890 {
2891 evt_data.status = NFC_STATUS_OK;
2892 (*p_rw_cb->p_cback) (RW_T3T_PRESENCE_CHECK_EVT, &evt_data);
2893 }
2894 }
2895 else
2896 {
2897 /* IDLE state: send POLL command */
2898 if ((retval = (tNFC_STATUS) nci_snd_t3t_polling (0xFFFF, T3T_POLL_RC_SC, 0)) == NCI_STATUS_OK)
2899 {
2900 p_rw_cb->tcb.t3t.flags |= RW_T3T_FL_W4_PRESENCE_CHECK_POLL_RSP;
2901 p_rw_cb->tcb.t3t.rw_state = RW_T3T_STATE_COMMAND_PENDING;
2902 p_rw_cb->tcb.t3t.cur_poll_rc = 0;
2903
2904 /* start timer for waiting for responses */
2905 rw_t3t_start_poll_timer (&p_rw_cb->tcb.t3t);
2906 }
2907 else
2908 {
2909 RW_TRACE_DEBUG1 ("RW_T3tPresenceCheck error sending NCI_RF_T3T_POLLING cmd (status = 0x%0x)", retval);
2910 }
2911 }
2912
2913 return (retval);
2914}
2915
2916/*****************************************************************************
2917**
2918** Function RW_T3tPoll
2919**
2920** Description
2921** Send POLL command
2922**
2923** Returns
2924** NFC_STATUS_OK, if raw data frame sent
2925** NFC_STATUS_NO_BUFFERS: unable to allocate a buffer for this operation
2926** NFC_STATUS_FAILED: other error
2927**
2928*****************************************************************************/
2929tNFC_STATUS RW_T3tPoll (UINT16 system_code, tT3T_POLL_RC rc, UINT8 tsn)
2930{
2931 tNFC_STATUS retval = NFC_STATUS_OK;
2932 tRW_T3T_CB *p_cb = &rw_cb.tcb.t3t;
2933
2934 RW_TRACE_API0 ("RW_T3tPoll");
2935
2936 /* Check if we are in valid state to handle this API */
2937 if (p_cb->rw_state != RW_T3T_STATE_IDLE)
2938 {
2939 RW_TRACE_ERROR1 ("Error: invalid state to handle API (0x%x)", p_cb->rw_state);
2940 return (NFC_STATUS_FAILED);
2941 }
2942
2943 if ((retval = (tNFC_STATUS) nci_snd_t3t_polling (system_code, (UINT8) rc, tsn)) == NCI_STATUS_OK)
2944 {
2945 /* start timer for waiting for responses */
2946 p_cb->cur_poll_rc = rc;
2947 p_cb->rw_state = RW_T3T_STATE_COMMAND_PENDING;
2948 rw_t3t_start_poll_timer (p_cb);
2949 }
2950
2951
2952 return (retval);
2953}
2954
2955/*****************************************************************************
2956**
2957** Function RW_T3tSendRawFrame
2958**
2959** Description
2960** This function is called to send a raw data frame to the peer device.
2961** When type 3 tag receives response from peer, the callback function
2962** will be called with a RW_T3T_RAW_FRAME_EVT [Table 6].
2963**
2964** Before using this API, the application must call RW_SelectTagType to
2965** indicate that a Type 3 tag has been activated.
2966**
2967** The raw frame should be a properly formatted Type 3 tag message.
2968**
2969** Returns
2970** NFC_STATUS_OK, if raw data frame sent
2971** NFC_STATUS_NO_BUFFERS: unable to allocate a buffer for this operation
2972** NFC_STATUS_FAILED: other error
2973**
2974*****************************************************************************/
2975tNFC_STATUS RW_T3tSendRawFrame (UINT16 len, UINT8 *p_data)
2976{
2977 tNFC_STATUS retval = NFC_STATUS_OK;
2978 tRW_T3T_CB *p_cb = &rw_cb.tcb.t3t;
2979
2980 RW_TRACE_API1 ("RW_T3tSendRawFrame (len = %i)", len);
2981
2982 /* Check if we are in valid state to handle this API */
2983 if (p_cb->rw_state != RW_T3T_STATE_IDLE)
2984 {
2985 RW_TRACE_ERROR1 ("Error: invalid state to handle API (0x%x)", p_cb->rw_state);
2986 return (NFC_STATUS_FAILED);
2987 }
2988
2989 /* Send the UPDATE command */
2990 retval = rw_t3t_send_raw_frame (p_cb, len ,p_data);
2991
2992 return (retval);
2993}
2994
2995/*****************************************************************************
2996**
2997** Function RW_T3tGetSystemCodes
2998**
2999** Description
3000** Get systems codes supported by the activated tag:
3001** Poll for wildcard (FFFF):
3002** - If felica-lite code then poll for ndef (12fc)
3003** - Otherwise send RequestSystmCode command to get
3004** system codes.
3005**
3006** Before using this API, the application must call RW_SelectTagType to
3007** indicate that a Type 3 tag has been activated.
3008**
3009** Returns
3010** NFC_STATUS_OK, if raw data frame sent
3011** NFC_STATUS_NO_BUFFERS: unable to allocate a buffer for this operation
3012** NFC_STATUS_FAILED: other error
3013**
3014*****************************************************************************/
3015tNFC_STATUS RW_T3tGetSystemCodes (void)
3016{
3017 tNFC_STATUS retval = NFC_STATUS_OK;
3018 tRW_T3T_CB *p_cb = &rw_cb.tcb.t3t;
3019
3020 RW_TRACE_API0 ("RW_T3tGetSystemCodes");
3021
3022 /* Check if we are in valid state to handle this API */
3023 if (p_cb->rw_state != RW_T3T_STATE_IDLE)
3024 {
3025 RW_TRACE_ERROR1 ("Error: invalid state to handle API (0x%x)", p_cb->rw_state);
3026 return (NFC_STATUS_FAILED);
3027 }
3028 else
3029 {
3030 if ((retval = (tNFC_STATUS) nci_snd_t3t_polling (0xFFFF, T3T_POLL_RC_SC, 0)) == NCI_STATUS_OK)
3031 {
3032 p_cb->cur_cmd = RW_T3T_CMD_GET_SYSTEM_CODES;
3033 p_cb->cur_tout = RW_T3T_DEFAULT_CMD_TIMEOUT_TICKS;
3034 p_cb->cur_poll_rc = T3T_POLL_RC_SC;
3035 p_cb->rw_state = RW_T3T_STATE_COMMAND_PENDING;
3036 p_cb->rw_substate = RW_T3T_GET_SC_SST_POLL_WILDCARD;
3037 p_cb->flags |= RW_T3T_FL_W4_GET_SC_POLL_RSP;
3038 p_cb->num_system_codes = 0;
3039
3040 /* start timer for waiting for responses */
3041 rw_t3t_start_poll_timer (p_cb);
3042 }
3043 }
3044
3045
3046
3047 return (retval);
3048}
3049
3050/*****************************************************************************
3051**
3052** Function RW_T3tFormatNDef
3053**
3054** Description
3055** Format a type-3 tag for NDEF.
3056**
3057** Only Felica-Lite tags are supported by this API. The
3058** RW_T3T_FORMAT_CPLT_EVT is used to notify the status of the operation.
3059**
3060** Returns
3061** NFC_STATUS_OK: ndef detection procedure started
3062** NFC_STATUS_NO_BUFFERS: unable to allocate a buffer for this operation
3063** NFC_STATUS_FAILED: other error
3064**
3065*****************************************************************************/
3066tNFC_STATUS RW_T3tFormatNDef (void)
3067{
3068 tNFC_STATUS retval = NFC_STATUS_OK;
3069 tRW_T3T_CB *p_cb = &rw_cb.tcb.t3t;
3070
3071 RW_TRACE_API0 ("RW_T3tFormatNDef");
3072
3073 /* Check if we are in valid state to handle this API */
3074 if (p_cb->rw_state != RW_T3T_STATE_IDLE)
3075 {
3076 RW_TRACE_ERROR1 ("Error: invalid state to handle API (0x%x)", p_cb->rw_state);
3077 return (NFC_STATUS_FAILED);
3078 }
3079 else
3080 {
3081 /* Poll tag, to see if Felica-Lite system is supported */
3082 if ((retval = (tNFC_STATUS) nci_snd_t3t_polling (T3T_SYSTEM_CODE_FELICA_LITE, T3T_POLL_RC_SC, 0)) == NCI_STATUS_OK)
3083 {
3084 p_cb->cur_cmd = RW_T3T_CMD_FORMAT;
3085 p_cb->cur_tout = RW_T3T_DEFAULT_CMD_TIMEOUT_TICKS;
3086 p_cb->cur_poll_rc = T3T_POLL_RC_SC;
3087 p_cb->rw_state = RW_T3T_STATE_COMMAND_PENDING;
3088 p_cb->rw_substate = RW_T3T_FMT_SST_POLL_FELICA_LITE;
3089 p_cb->flags |= RW_T3T_FL_W4_FMT_FELICA_LITE_POLL_RSP;
3090
3091 /* start timer for waiting for responses */
3092 rw_t3t_start_poll_timer (p_cb);
3093 }
3094 }
3095
3096
3097
3098 return (retval);
3099}
Martijn Coenen5c65c3a2013-03-27 13:23:36 -07003100
3101/*****************************************************************************
3102**
3103** Function RW_T3tSetReadOnly
3104**
3105** Description This function performs NDEF read-only procedure
3106** Note: Only Felica-Lite tags are supported by this API.
3107** RW_T3tDetectNDef() must be called before using this
3108**
3109** The RW_T3T_SET_READ_ONLY_CPLT_EVT event will be returned.
3110**
3111** Returns NFC_STATUS_OK if success
3112** NFC_STATUS_FAILED if T3T is busy or other error
3113**
3114*****************************************************************************/
3115tNFC_STATUS RW_T3tSetReadOnly (BOOLEAN b_hard_lock)
3116{
3117 tNFC_STATUS retval = NFC_STATUS_OK;
3118 tRW_T3T_CB *p_cb = &rw_cb.tcb.t3t;
3119 tRW_DATA evt_data;
3120
Evan Chu7c69b272013-05-14 12:48:36 -04003121 RW_TRACE_API1 ("RW_T3tSetReadOnly (): b_hard_lock=%d", b_hard_lock);
Martijn Coenen5c65c3a2013-03-27 13:23:36 -07003122
3123 /* Check if we are in valid state to handle this API */
3124 if (p_cb->rw_state != RW_T3T_STATE_IDLE)
3125 {
3126 RW_TRACE_ERROR1 ("Error: invalid state to handle API (0x%x)", p_cb->rw_state);
3127 return (NFC_STATUS_FAILED);
3128 }
3129
3130 if (p_cb->ndef_attrib.status != NFC_STATUS_OK) /* NDEF detection not performed yet? */
3131 {
3132 RW_TRACE_ERROR0 ("Error: NDEF detection not performed yet");
3133 return (NFC_STATUS_NOT_INITIALIZED);
3134 }
3135
3136 if ((!b_hard_lock) && (p_cb->ndef_attrib.rwflag == T3T_MSG_NDEF_RWFLAG_RO))/* Tag's NDEF memory is read-only already */
3137 {
3138 evt_data.status = NFC_STATUS_OK;
Evan Chu7c69b272013-05-14 12:48:36 -04003139 (*(rw_cb.p_cback)) (RW_T3T_SET_READ_ONLY_CPLT_EVT, &evt_data);
Martijn Coenen5c65c3a2013-03-27 13:23:36 -07003140 return (retval);
3141 }
3142 else
3143 {
3144 /* Poll tag, to see if Felica-Lite system is supported */
3145 if ((retval = (tNFC_STATUS) nci_snd_t3t_polling (T3T_SYSTEM_CODE_FELICA_LITE, T3T_POLL_RC_SC, 0)) == NCI_STATUS_OK)
3146 {
3147 if (b_hard_lock)
3148 p_cb->cur_cmd = RW_T3T_CMD_SET_READ_ONLY_HARD;
3149 else
3150 p_cb->cur_cmd = RW_T3T_CMD_SET_READ_ONLY_SOFT;
3151 p_cb->cur_tout = RW_T3T_DEFAULT_CMD_TIMEOUT_TICKS;
3152 p_cb->cur_poll_rc = T3T_POLL_RC_SC;
3153 p_cb->rw_state = RW_T3T_STATE_COMMAND_PENDING;
3154 p_cb->rw_substate = RW_T3T_SRO_SST_POLL_FELICA_LITE;
3155 p_cb->flags |= RW_T3T_FL_W4_SRO_FELICA_LITE_POLL_RSP;
3156
3157 /* start timer for waiting for responses */
3158 rw_t3t_start_poll_timer (p_cb);
3159 }
3160 }
3161 return (retval);
3162}