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