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