blob: fa8ea7c14629a8484bba9eb1a0a6f277e2d0d833 [file] [log] [blame]
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001/******************************************************************************
2 *
Evan Chu85b7e842013-01-18 11:02:50 -05003 * Copyright (C) 2011-2013 Broadcom Corporation
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08004 *
5 * Licensed under the Apache License, Version 2.0 (the "License");
6 * you may not use this file except in compliance with the License.
7 * You may obtain a copy of the License at:
8 *
9 * http://www.apache.org/licenses/LICENSE-2.0
10 *
11 * Unless required by applicable law or agreed to in writing, software
12 * distributed under the License is distributed on an "AS IS" BASIS,
13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 * See the License for the specific language governing permissions and
15 * limitations under the License.
16 *
17 ******************************************************************************/
18
19/******************************************************************************
20 *
21 * This file contains the implementation for ISO 15693 in Reader/Writer
22 * mode.
23 *
24 ******************************************************************************/
25#include <string.h>
26#include "nfc_target.h"
27#include "bt_types.h"
28#include "trace_api.h"
29
30#if (NFC_INCLUDED == TRUE)
31
32#include "nfc_api.h"
33#include "nfc_int.h"
34#include "rw_api.h"
35#include "rw_int.h"
36
37#define RW_I93_TOUT_RESP 1000 /* Response timeout */
38#define RW_I93_TOUT_STAY_QUIET 200 /* stay quiet timeout */
39#define RW_I93_READ_MULTI_BLOCK_SIZE 128 /* max reading data if read multi block is supported */
40#define RW_I93_FORMAT_DATA_LEN 8 /* CC, zero length NDEF, Terminator TLV */
Evan Chu85b7e842013-01-18 11:02:50 -050041#define RW_I93_GET_MULTI_BLOCK_SEC_SIZE 512 /* max getting lock status if get multi block sec is supported */
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -080042
43/* main state */
44enum
45{
46 RW_I93_STATE_NOT_ACTIVATED, /* ISO15693 is not activated */
47 RW_I93_STATE_IDLE, /* waiting for upper layer API */
48 RW_I93_STATE_BUSY, /* waiting for response from tag */
49
50 RW_I93_STATE_DETECT_NDEF, /* performing NDEF detection precedure */
51 RW_I93_STATE_READ_NDEF, /* performing read NDEF procedure */
52 RW_I93_STATE_UPDATE_NDEF, /* performing update NDEF procedure */
53 RW_I93_STATE_FORMAT, /* performing format procedure */
54 RW_I93_STATE_SET_READ_ONLY, /* performing set read-only procedure */
55
56 RW_I93_STATE_PRESENCE_CHECK /* checking presence of tag */
57};
58
59/* sub state */
60enum
61{
62 RW_I93_SUBSTATE_WAIT_UID, /* waiting for response of inventory */
63 RW_I93_SUBSTATE_WAIT_SYS_INFO, /* waiting for response of get sys info */
64 RW_I93_SUBSTATE_WAIT_CC, /* waiting for reading CC */
65 RW_I93_SUBSTATE_SEARCH_NDEF_TLV, /* searching NDEF TLV */
66 RW_I93_SUBSTATE_CHECK_LOCK_STATUS, /* check if any NDEF TLV is locked */
67
68 RW_I93_SUBSTATE_RESET_LEN, /* set length to 0 to update NDEF TLV */
69 RW_I93_SUBSTATE_WRITE_NDEF, /* writing NDEF and Terminator TLV */
70 RW_I93_SUBSTATE_UPDATE_LEN, /* set length into NDEF TLV */
71
72 RW_I93_SUBSTATE_WAIT_RESET_DSFID_AFI, /* reset DSFID and AFI */
73 RW_I93_SUBSTATE_CHECK_READ_ONLY, /* check if any block is locked */
74 RW_I93_SUBSTATE_WRITE_CC_NDEF_TLV, /* write CC and empty NDEF/Terminator TLV */
75
76 RW_I93_SUBSTATE_WAIT_UPDATE_CC, /* updating CC as read-only */
77 RW_I93_SUBSTATE_LOCK_NDEF_TLV, /* lock blocks of NDEF TLV */
78 RW_I93_SUBSTATE_WAIT_LOCK_CC /* lock block of CC */
79};
80
81#if (BT_TRACE_VERBOSE == TRUE)
82static char *rw_i93_get_state_name (UINT8 state);
83static char *rw_i93_get_sub_state_name (UINT8 sub_state);
Evan Chu85b7e842013-01-18 11:02:50 -050084static char *rw_i93_get_tag_name (UINT8 product_version);
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -080085#endif
86
87static void rw_i93_data_cback (UINT8 conn_id, tNFC_CONN_EVT event, tNFC_CONN *p_data);
88void rw_i93_handle_error (tNFC_STATUS status);
Evan Chu85b7e842013-01-18 11:02:50 -050089tNFC_STATUS rw_i93_send_cmd_get_sys_info (UINT8 *p_uid, UINT8 extra_flag);
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -080090
91/*******************************************************************************
92**
93** Function rw_i93_get_product_version
94**
95** Description Get product version from UID
96**
97** Returns void
98**
99*******************************************************************************/
100void rw_i93_get_product_version (UINT8 *p_uid)
101{
102 tRW_I93_CB *p_i93 = &rw_cb.tcb.i93;
103
104 if (!memcmp (p_i93->uid, p_uid, I93_UID_BYTE_LEN))
105 {
106 return;
107 }
108
109 RW_TRACE_DEBUG0 ("rw_i93_get_product_version ()");
110
111 memcpy (p_i93->uid, p_uid, I93_UID_BYTE_LEN);
112
113 if (p_uid[1] == I93_UID_IC_MFG_CODE_NXP)
114 {
115 if (p_uid[2] == I93_UID_ICODE_SLI)
116 p_i93->product_version = RW_I93_ICODE_SLI;
117 else if (p_uid[2] == I93_UID_ICODE_SLI_S)
118 p_i93->product_version = RW_I93_ICODE_SLI_S;
119 else if (p_uid[2] == I93_UID_ICODE_SLI_L)
120 p_i93->product_version = RW_I93_ICODE_SLI_L;
121 else
122 p_i93->product_version = RW_I93_UNKNOWN_PRODUCT;
123 }
124 else if (p_uid[1] == I93_UID_IC_MFG_CODE_TI)
125 {
126 if ((p_uid[2] & I93_UID_TAG_IT_HF_I_PRODUCT_ID_MASK) == I93_UID_TAG_IT_HF_I_PLUS_INLAY)
127 p_i93->product_version = RW_I93_TAG_IT_HF_I_PLUS_INLAY;
128 else if ((p_uid[2] & I93_UID_TAG_IT_HF_I_PRODUCT_ID_MASK) == I93_UID_TAG_IT_HF_I_PLUS_CHIP)
129 p_i93->product_version = RW_I93_TAG_IT_HF_I_PLUS_CHIP;
130 else if ((p_uid[2] & I93_UID_TAG_IT_HF_I_PRODUCT_ID_MASK) == I93_UID_TAG_IT_HF_I_STD_CHIP_INLAY)
131 p_i93->product_version = RW_I93_TAG_IT_HF_I_STD_CHIP_INLAY;
132 else if ((p_uid[2] & I93_UID_TAG_IT_HF_I_PRODUCT_ID_MASK) == I93_UID_TAG_IT_HF_I_PRO_CHIP_INLAY)
133 p_i93->product_version = RW_I93_TAG_IT_HF_I_PRO_CHIP_INLAY;
134 else
135 p_i93->product_version = RW_I93_UNKNOWN_PRODUCT;
136 }
Evan Chu85b7e842013-01-18 11:02:50 -0500137 else if ( (p_uid[1] == I93_UID_IC_MFG_CODE_STM)
138 &&(p_i93->info_flags & I93_INFO_FLAG_IC_REF) )
139 {
140 if (p_i93->ic_reference == I93_IC_REF_STM_M24LR04E_R)
141 p_i93->product_version = RW_I93_STM_M24LR04E_R;
142 else if (p_i93->ic_reference == I93_IC_REF_STM_M24LR16E_R)
143 p_i93->product_version = RW_I93_STM_M24LR16E_R;
144 else if (p_i93->ic_reference == I93_IC_REF_STM_M24LR64E_R)
145 p_i93->product_version = RW_I93_STM_M24LR64E_R;
146 else
147 {
148 switch (p_i93->ic_reference & I93_IC_REF_STM_MASK)
149 {
150 case I93_IC_REF_STM_LRI1K:
151 p_i93->product_version = RW_I93_STM_LRI1K;
152 break;
153 case I93_IC_REF_STM_LRI2K:
154 p_i93->product_version = RW_I93_STM_LRI2K;
155 break;
156 case I93_IC_REF_STM_LRIS2K:
157 p_i93->product_version = RW_I93_STM_LRIS2K;
158 break;
159 case I93_IC_REF_STM_LRIS64K:
160 p_i93->product_version = RW_I93_STM_LRIS64K;
161 break;
162 case I93_IC_REF_STM_M24LR64_R:
163 p_i93->product_version = RW_I93_STM_M24LR64_R;
164 break;
165 default:
166 p_i93->product_version = RW_I93_UNKNOWN_PRODUCT;
167 break;
168 }
169 }
170 }
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800171 else
172 {
173 p_i93->product_version = RW_I93_UNKNOWN_PRODUCT;
174 }
175
Evan Chu85b7e842013-01-18 11:02:50 -0500176#if (BT_TRACE_VERBOSE == TRUE)
177 RW_TRACE_DEBUG1 ("product_version = <%s>", rw_i93_get_tag_name(p_i93->product_version));
178#else
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800179 RW_TRACE_DEBUG1 ("product_version = %d", p_i93->product_version);
Evan Chu85b7e842013-01-18 11:02:50 -0500180#endif
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800181
182 switch (p_i93->product_version)
183 {
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800184 case RW_I93_TAG_IT_HF_I_STD_CHIP_INLAY:
185 case RW_I93_TAG_IT_HF_I_PRO_CHIP_INLAY:
186 /* these don't support Get System Information Command */
187 /* these support only Inventory, Stay Quiet, Read Single Block, Write Single Block, Lock Block */
188 p_i93->block_size = I93_TAG_IT_HF_I_STD_PRO_CHIP_INLAY_BLK_SIZE;
189 p_i93->num_block = I93_TAG_IT_HF_I_STD_PRO_CHIP_INLAY_NUM_USER_BLK;
190 break;
Evan Chu85b7e842013-01-18 11:02:50 -0500191 default:
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800192 break;
193 }
194}
195
196/*******************************************************************************
197**
Evan Chu85b7e842013-01-18 11:02:50 -0500198** Function rw_i93_process_sys_info
199**
200** Description Store system information of tag
201**
202** Returns FALSE if retrying with protocol extension flag
203**
204*******************************************************************************/
205BOOLEAN rw_i93_process_sys_info (UINT8* p_data)
206{
207 UINT8 *p = p_data;
208 tRW_I93_CB *p_i93 = &rw_cb.tcb.i93;
209 UINT8 uid[I93_UID_BYTE_LEN], *p_uid;
210
211 RW_TRACE_DEBUG0 ("rw_i93_process_sys_info ()");
212
213 STREAM_TO_UINT8 (p_i93->info_flags, p);
214
215 p_uid = uid;
216 STREAM_TO_ARRAY8 (p_uid, p);
217
218 if (p_i93->info_flags & I93_INFO_FLAG_DSFID)
219 {
220 STREAM_TO_UINT8 (p_i93->dsfid, p);
221 }
222 if (p_i93->info_flags & I93_INFO_FLAG_AFI)
223 {
224 STREAM_TO_UINT8 (p_i93->afi, p);
225 }
226 if (p_i93->info_flags & I93_INFO_FLAG_MEM_SIZE)
227 {
228 if (p_i93->intl_flags & RW_I93_FLAG_16BIT_NUM_BLOCK)
229 {
230 STREAM_TO_UINT16 (p_i93->num_block, p);
231 }
232 else
233 {
234 STREAM_TO_UINT8 (p_i93->num_block, p);
235 }
236 /* it is one less than actual number of bytes */
237 p_i93->num_block += 1;
238
239 STREAM_TO_UINT8 (p_i93->block_size, p);
240 /* it is one less than actual number of blocks */
241 p_i93->block_size = (p_i93->block_size & 0x1F) + 1;
242 }
243 if (p_i93->info_flags & I93_INFO_FLAG_IC_REF)
244 {
245 STREAM_TO_UINT8 (p_i93->ic_reference, p);
246
247 /* clear existing UID to set product version */
248 p_i93->uid[0] = 0x00;
249
250 /* store UID and get product version */
251 rw_i93_get_product_version (p_uid);
252
253 if (p_i93->uid[0] == I93_UID_FIRST_BYTE)
254 {
255 if ( (p_i93->uid[1] == I93_UID_IC_MFG_CODE_NXP)
256 &&(p_i93->ic_reference == I93_IC_REF_ICODE_SLI_L) )
257 {
258 p_i93->num_block = 8;
259 p_i93->block_size = 4;
260 }
261 else if (p_i93->uid[1] == I93_UID_IC_MFG_CODE_STM)
262 {
263 /*
264 ** LRI1K: 010000xx(b), blockSize: 4, numberBlocks: 0x20
265 ** LRI2K: 001000xx(b), blockSize: 4, numberBlocks: 0x40
266 ** LRIS2K: 001010xx(b), blockSize: 4, numberBlocks: 0x40
267 ** LRIS64K: 010001xx(b), blockSize: 4, numberBlocks: 0x800
268 ** M24LR64-R: 001011xx(b), blockSize: 4, numberBlocks: 0x800
269 ** M24LR04E-R: 01011010(b), blockSize: 4, numberBlocks: 0x80
270 ** M24LR16E-R: 01001110(b), blockSize: 4, numberBlocks: 0x200
271 ** M24LR64E-R: 01011110(b), blockSize: 4, numberBlocks: 0x800
272 */
273 if ( (p_i93->product_version == RW_I93_STM_M24LR16E_R)
274 ||(p_i93->product_version == RW_I93_STM_M24LR64E_R) )
275 {
276 /*
277 ** M24LR16E-R or M24LR64E-R returns system information without memory size,
278 ** if option flag is not set.
279 ** LRIS64K and M24LR64-R return error if option flag is not set.
280 */
281 if (!(p_i93->intl_flags & RW_I93_FLAG_16BIT_NUM_BLOCK))
282 {
283 /* get memory size with protocol extension flag */
284 if (rw_i93_send_cmd_get_sys_info (NULL, I93_FLAG_PROT_EXT_YES) == NFC_STATUS_OK)
285 {
286 /* STM supports more than 2040 bytes */
287 p_i93->intl_flags |= RW_I93_FLAG_16BIT_NUM_BLOCK;
288
289 return FALSE;
290 }
291 }
292 return TRUE;
293 }
294 else if ( (p_i93->product_version == RW_I93_STM_LRI2K)
295 &&(p_i93->ic_reference == 0x21) )
296 {
297 /* workaround of byte order in memory size information */
298 p_i93->num_block = 64;
299 p_i93->block_size = 4;
300 }
301 }
302 }
303 }
304
305 return TRUE;
306}
307
308/*******************************************************************************
309**
310** Function rw_i93_check_sys_info_prot_ext
311**
312** Description Check if need to set protocol extension flag to get system info
313**
314** Returns TRUE if sent Get System Info with protocol extension flag
315**
316*******************************************************************************/
317BOOLEAN rw_i93_check_sys_info_prot_ext (UINT8 error_code)
318{
319 tRW_I93_CB *p_i93 = &rw_cb.tcb.i93;
320
321 RW_TRACE_DEBUG0 ("rw_i93_check_sys_info_prot_ext ()");
322
323 if ( (p_i93->uid[1] == I93_UID_IC_MFG_CODE_STM)
324 &&(p_i93->sent_cmd == I93_CMD_GET_SYS_INFO)
325 &&(error_code == I93_ERROR_CODE_OPTION_NOT_SUPPORTED)
326 &&(rw_i93_send_cmd_get_sys_info (NULL, I93_FLAG_PROT_EXT_YES) == NFC_STATUS_OK) )
327 {
328 return TRUE;
329 }
330 else
331 {
332 return FALSE;
333 }
334}
335
336/*******************************************************************************
337**
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800338** Function rw_i93_send_to_upper
339**
340** Description Send response to upper layer
341**
342** Returns void
343**
344*******************************************************************************/
345void rw_i93_send_to_upper (BT_HDR *p_resp)
346{
347 UINT8 *p = (UINT8 *) (p_resp + 1) + p_resp->offset, *p_uid;
348 UINT16 length = p_resp->len;
349 tRW_I93_CB *p_i93 = &rw_cb.tcb.i93;
350 tRW_DATA rw_data;
351 UINT8 event = RW_I93_MAX_EVT;
352 UINT8 flags;
353 BT_HDR *p_buff;
354
355 RW_TRACE_DEBUG0 ("rw_i93_send_to_upper ()");
356
357 STREAM_TO_UINT8 (flags, p);
358 length--;
359
360 if (flags & I93_FLAG_ERROR_DETECTED)
361 {
Evan Chu85b7e842013-01-18 11:02:50 -0500362 if ((length) && (rw_i93_check_sys_info_prot_ext(*p)))
363 {
364 /* getting system info with protocol extension flag */
365 /* This STM tag supports more than 2040 bytes */
366 p_i93->intl_flags |= RW_I93_FLAG_16BIT_NUM_BLOCK;
367 p_i93->state = RW_I93_STATE_BUSY;
368 }
369 else
370 {
371 /* notify error to upper layer */
372 rw_data.i93_cmd_cmpl.status = NFC_STATUS_FAILED;
373 rw_data.i93_cmd_cmpl.command = p_i93->sent_cmd;
374 STREAM_TO_UINT8 (rw_data.i93_cmd_cmpl.error_code, p);
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800375
Evan Chu85b7e842013-01-18 11:02:50 -0500376 rw_cb.tcb.i93.sent_cmd = 0;
377 (*(rw_cb.p_cback)) (RW_I93_CMD_CMPL_EVT, &rw_data);
378 }
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800379 return;
380 }
381
382 switch (p_i93->sent_cmd)
383 {
384 case I93_CMD_INVENTORY:
385
386 /* forward inventory response */
387 rw_data.i93_inventory.status = NFC_STATUS_OK;
388 STREAM_TO_UINT8 (rw_data.i93_inventory.dsfid, p);
389
390 p_uid = rw_data.i93_inventory.uid;
391 STREAM_TO_ARRAY8 (p_uid, p);
392
393 /* store UID and get product version */
394 rw_i93_get_product_version (p_uid);
395
396 event = RW_I93_INVENTORY_EVT;
397 break;
398
399 case I93_CMD_READ_SINGLE_BLOCK:
400 case I93_CMD_READ_MULTI_BLOCK:
401 case I93_CMD_GET_MULTI_BLK_SEC:
402
403 /* forward tag data or security status */
404 p_buff = (BT_HDR*) GKI_getbuf ((UINT16) (length + BT_HDR_SIZE));
405
406 if (p_buff)
407 {
408 p_buff->offset = 0;
409 p_buff->len = length;
410
411 memcpy ((p_buff + 1), p, length);
412
413 rw_data.i93_data.status = NFC_STATUS_OK;
414 rw_data.i93_data.command = p_i93->sent_cmd;
415 rw_data.i93_data.p_data = p_buff;
416
417 event = RW_I93_DATA_EVT;
418 }
419 else
420 {
421 rw_data.i93_cmd_cmpl.status = NFC_STATUS_NO_BUFFERS;
422 rw_data.i93_cmd_cmpl.command = p_i93->sent_cmd;
423 rw_data.i93_cmd_cmpl.error_code = 0;
424
425 event = RW_I93_CMD_CMPL_EVT;
426 }
427 break;
428
429 case I93_CMD_WRITE_SINGLE_BLOCK:
430 case I93_CMD_LOCK_BLOCK:
431 case I93_CMD_WRITE_MULTI_BLOCK:
432 case I93_CMD_SELECT:
433 case I93_CMD_RESET_TO_READY:
434 case I93_CMD_WRITE_AFI:
435 case I93_CMD_LOCK_AFI:
436 case I93_CMD_WRITE_DSFID:
437 case I93_CMD_LOCK_DSFID:
438
439 /* notify the complete of command */
440 rw_data.i93_cmd_cmpl.status = NFC_STATUS_OK;
441 rw_data.i93_cmd_cmpl.command = p_i93->sent_cmd;
442 rw_data.i93_cmd_cmpl.error_code = 0;
443
444 event = RW_I93_CMD_CMPL_EVT;
445 break;
446
447 case I93_CMD_GET_SYS_INFO:
448
Evan Chu85b7e842013-01-18 11:02:50 -0500449 if (rw_i93_process_sys_info (p))
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800450 {
Evan Chu85b7e842013-01-18 11:02:50 -0500451 rw_data.i93_sys_info.status = NFC_STATUS_OK;
452 rw_data.i93_sys_info.info_flags = p_i93->info_flags;
453 rw_data.i93_sys_info.dsfid = p_i93->dsfid;
454 rw_data.i93_sys_info.afi = p_i93->afi;
455 rw_data.i93_sys_info.num_block = p_i93->num_block;
456 rw_data.i93_sys_info.block_size = p_i93->block_size;
457 rw_data.i93_sys_info.IC_reference = p_i93->ic_reference;
458
459 memcpy (rw_data.i93_sys_info.uid, p_i93->uid, I93_UID_BYTE_LEN);
460
461 event = RW_I93_SYS_INFO_EVT;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800462 }
Evan Chu85b7e842013-01-18 11:02:50 -0500463 else
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800464 {
Evan Chu85b7e842013-01-18 11:02:50 -0500465 /* retrying with protocol extension flag */
466 p_i93->state = RW_I93_STATE_BUSY;
467 return;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800468 }
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800469 break;
470
471 default:
472 break;
473 }
474
475 rw_cb.tcb.i93.sent_cmd = 0;
476 if (event != RW_I93_MAX_EVT)
477 {
478 (*(rw_cb.p_cback)) (event, &rw_data);
479 }
480 else
481 {
482 RW_TRACE_ERROR0 ("rw_i93_send_to_upper (): Invalid response");
483 }
484}
485
486/*******************************************************************************
487**
488** Function rw_i93_send_to_lower
489**
490** Description Send Request frame to lower layer
491**
492** Returns TRUE if success
493**
494*******************************************************************************/
495BOOLEAN rw_i93_send_to_lower (BT_HDR *p_msg)
496{
497#if (BT_TRACE_PROTOCOL == TRUE)
498 DispRWI93Tag (p_msg, FALSE, 0x00);
499#endif
500
Evan Chu85b7e842013-01-18 11:02:50 -0500501 /* store command for retransmitting */
502 if (rw_cb.tcb.i93.p_retry_cmd)
503 {
504 GKI_freebuf (rw_cb.tcb.i93.p_retry_cmd);
505 rw_cb.tcb.i93.p_retry_cmd = NULL;
506 }
507
508 rw_cb.tcb.i93.p_retry_cmd = (BT_HDR *) GKI_getpoolbuf (NFC_RW_POOL_ID);
509
510 if (rw_cb.tcb.i93.p_retry_cmd)
511 {
512 memcpy (rw_cb.tcb.i93.p_retry_cmd, p_msg, sizeof (BT_HDR) + p_msg->offset + p_msg->len);
513 }
514
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800515 if (NFC_SendData (NFC_RF_CONN_ID, p_msg) != NFC_STATUS_OK)
516 {
517 RW_TRACE_ERROR0 ("rw_i93_send_to_lower (): NFC_SendData () failed");
518 return FALSE;
519 }
520
521 nfc_start_quick_timer (&rw_cb.tcb.i93.timer, NFC_TTYPE_RW_I93_RESPONSE,
522 (RW_I93_TOUT_RESP*QUICK_TIMER_TICKS_PER_SEC)/1000);
523
524 return TRUE;
525}
526
527/*******************************************************************************
528**
529** Function rw_i93_send_cmd_inventory
530**
531** Description Send Inventory Request to VICC
532**
533** Returns tNFC_STATUS
534**
535*******************************************************************************/
536tNFC_STATUS rw_i93_send_cmd_inventory (UINT8 *p_uid, UINT8 afi)
537{
538 BT_HDR *p_cmd;
539 UINT8 *p;
540
541 RW_TRACE_DEBUG1 ("rw_i93_send_cmd_inventory () AFI:0x%02X", afi);
542
543 p_cmd = (BT_HDR *) GKI_getpoolbuf (NFC_RW_POOL_ID);
544
545 if (!p_cmd)
546 {
547 RW_TRACE_ERROR0 ("rw_i93_send_cmd_inventory (): Cannot allocate buffer");
548 return NFC_STATUS_NO_BUFFERS;
549 }
550
551 p_cmd->offset = NCI_MSG_OFFSET_SIZE + NCI_DATA_HDR_SIZE;
552 p_cmd->len = 4;
553 p = (UINT8 *) (p_cmd + 1) + p_cmd->offset;
554
555 /* Flags */
556 UINT8_TO_STREAM (p, (I93_FLAG_SLOT_ONE | I93_FLAG_INVENTORY_SET | I93_FLAG_AFI_PRESENT | RW_I93_FLAG_SUB_CARRIER | RW_I93_FLAG_DATA_RATE));
557
558 /* Command Code */
559 UINT8_TO_STREAM (p, I93_CMD_INVENTORY);
560
561 /* Parameters */
562 UINT8_TO_STREAM (p, afi); /* Optional AFI */
563
564 if (p_uid)
565 {
566 UINT8_TO_STREAM (p, I93_UID_BYTE_LEN*8); /* Mask Length */
567 ARRAY8_TO_STREAM (p, p_uid); /* UID */
568 p_cmd->len += I93_UID_BYTE_LEN;
569 }
570 else
571 {
572 UINT8_TO_STREAM (p, 0x00); /* Mask Length */
573 }
574
575 if (rw_i93_send_to_lower (p_cmd))
576 {
577 rw_cb.tcb.i93.sent_cmd = I93_CMD_INVENTORY;
578 return NFC_STATUS_OK;
579 }
580 else
581 {
582 return NFC_STATUS_FAILED;
583 }
584}
585
586/*******************************************************************************
587**
588** Function rw_i93_send_cmd_stay_quiet
589**
590** Description Send Stay Quiet Request to VICC
591**
592** Returns tNFC_STATUS
593**
594*******************************************************************************/
595tNFC_STATUS rw_i93_send_cmd_stay_quiet (void)
596{
597 BT_HDR *p_cmd;
598 UINT8 *p;
599
600 RW_TRACE_DEBUG0 ("rw_i93_send_cmd_stay_quiet ()");
601
602 p_cmd = (BT_HDR *) GKI_getpoolbuf (NFC_RW_POOL_ID);
603
604 if (!p_cmd)
605 {
606 RW_TRACE_ERROR0 ("rw_i93_send_cmd_stay_quiet (): Cannot allocate buffer");
607 return NFC_STATUS_NO_BUFFERS;
608 }
609
610 p_cmd->offset = NCI_MSG_OFFSET_SIZE + NCI_DATA_HDR_SIZE;
611 p_cmd->len = 10;
612 p = (UINT8 *) (p_cmd + 1) + p_cmd->offset;
613
614 /* Flags */
615 UINT8_TO_STREAM (p, (I93_FLAG_ADDRESS_SET | RW_I93_FLAG_SUB_CARRIER | RW_I93_FLAG_DATA_RATE));
616
617 /* Command Code */
618 UINT8_TO_STREAM (p, I93_CMD_STAY_QUIET);
619
620 /* Parameters */
621 ARRAY8_TO_STREAM (p, rw_cb.tcb.i93.uid); /* UID */
622
623 if (rw_i93_send_to_lower (p_cmd))
624 {
625 rw_cb.tcb.i93.sent_cmd = I93_CMD_STAY_QUIET;
626
627 /* restart timer for stay quiet */
628 nfc_start_quick_timer (&rw_cb.tcb.i93.timer, NFC_TTYPE_RW_I93_RESPONSE,
629 (RW_I93_TOUT_STAY_QUIET * QUICK_TIMER_TICKS_PER_SEC) / 1000);
630 return NFC_STATUS_OK;
631 }
632 else
633 {
634 return NFC_STATUS_FAILED;
635 }
636}
637
638/*******************************************************************************
639**
640** Function rw_i93_send_cmd_read_single_block
641**
642** Description Send Read Single Block Request to VICC
643**
644** Returns tNFC_STATUS
645**
646*******************************************************************************/
Evan Chu85b7e842013-01-18 11:02:50 -0500647tNFC_STATUS rw_i93_send_cmd_read_single_block (UINT16 block_number, BOOLEAN read_security)
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800648{
649 BT_HDR *p_cmd;
Evan Chu85b7e842013-01-18 11:02:50 -0500650 UINT8 *p, flags;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800651
652 RW_TRACE_DEBUG0 ("rw_i93_send_cmd_read_single_block ()");
653
654 p_cmd = (BT_HDR *) GKI_getpoolbuf (NFC_RW_POOL_ID);
655
656 if (!p_cmd)
657 {
658 RW_TRACE_ERROR0 ("rw_i93_send_cmd_read_single_block (): Cannot allocate buffer");
659 return NFC_STATUS_NO_BUFFERS;
660 }
661
662 p_cmd->offset = NCI_MSG_OFFSET_SIZE + NCI_DATA_HDR_SIZE;
663 p_cmd->len = 11;
664 p = (UINT8 *) (p_cmd + 1) + p_cmd->offset;
665
666 /* Flags */
Evan Chu85b7e842013-01-18 11:02:50 -0500667 flags = (I93_FLAG_ADDRESS_SET | RW_I93_FLAG_SUB_CARRIER | RW_I93_FLAG_DATA_RATE);
668
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800669 if (read_security)
Evan Chu85b7e842013-01-18 11:02:50 -0500670 flags |= I93_FLAG_OPTION_SET;
671
672 if (rw_cb.tcb.i93.intl_flags & RW_I93_FLAG_16BIT_NUM_BLOCK)
673 flags |= I93_FLAG_PROT_EXT_YES;
674
675 UINT8_TO_STREAM (p, flags);
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800676
677 /* Command Code */
678 UINT8_TO_STREAM (p, I93_CMD_READ_SINGLE_BLOCK);
679
680 /* Parameters */
681 ARRAY8_TO_STREAM (p, rw_cb.tcb.i93.uid); /* UID */
Evan Chu85b7e842013-01-18 11:02:50 -0500682
683 if (rw_cb.tcb.i93.intl_flags & RW_I93_FLAG_16BIT_NUM_BLOCK)
684 {
685 UINT16_TO_STREAM (p, block_number); /* Block number */
686 p_cmd->len++;
687 }
688 else
689 {
690 UINT8_TO_STREAM (p, block_number); /* Block number */
691 }
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800692
693 if (rw_i93_send_to_lower (p_cmd))
694 {
695 rw_cb.tcb.i93.sent_cmd = I93_CMD_READ_SINGLE_BLOCK;
696 return NFC_STATUS_OK;
697 }
698 else
699 {
700 return NFC_STATUS_FAILED;
701 }
702}
703
704/*******************************************************************************
705**
706** Function rw_i93_send_cmd_write_single_block
707**
708** Description Send Write Single Block Request to VICC
709**
710** Returns tNFC_STATUS
711**
712*******************************************************************************/
Evan Chu85b7e842013-01-18 11:02:50 -0500713tNFC_STATUS rw_i93_send_cmd_write_single_block (UINT16 block_number, UINT8 *p_data)
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800714{
715 BT_HDR *p_cmd;
Evan Chu85b7e842013-01-18 11:02:50 -0500716 UINT8 *p, flags;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800717
718 RW_TRACE_DEBUG0 ("rw_i93_send_cmd_write_single_block ()");
719
720 p_cmd = (BT_HDR *) GKI_getpoolbuf (NFC_RW_POOL_ID);
721
722 if (!p_cmd)
723 {
724 RW_TRACE_ERROR0 ("rw_i93_send_cmd_write_single_block (): Cannot allocate buffer");
725 return NFC_STATUS_NO_BUFFERS;
726 }
727
728 p_cmd->offset = NCI_MSG_OFFSET_SIZE + NCI_DATA_HDR_SIZE;
729 p_cmd->len = 11 + rw_cb.tcb.i93.block_size;
730 p = (UINT8 *) (p_cmd + 1) + p_cmd->offset;
731
732 /* Flags */
733 if ( (rw_cb.tcb.i93.product_version == RW_I93_TAG_IT_HF_I_PLUS_INLAY)
734 ||(rw_cb.tcb.i93.product_version == RW_I93_TAG_IT_HF_I_PLUS_CHIP)
735 ||(rw_cb.tcb.i93.product_version == RW_I93_TAG_IT_HF_I_STD_CHIP_INLAY)
736 ||(rw_cb.tcb.i93.product_version == RW_I93_TAG_IT_HF_I_PRO_CHIP_INLAY) )
737 {
738 /* Option must be set for TI tag */
Evan Chu85b7e842013-01-18 11:02:50 -0500739 flags = (I93_FLAG_ADDRESS_SET | I93_FLAG_OPTION_SET | RW_I93_FLAG_SUB_CARRIER | RW_I93_FLAG_DATA_RATE);
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800740 }
741 else
742 {
Evan Chu85b7e842013-01-18 11:02:50 -0500743 flags = (I93_FLAG_ADDRESS_SET | RW_I93_FLAG_SUB_CARRIER | RW_I93_FLAG_DATA_RATE);
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800744 }
745
Evan Chu85b7e842013-01-18 11:02:50 -0500746 if (rw_cb.tcb.i93.intl_flags & RW_I93_FLAG_16BIT_NUM_BLOCK)
747 flags |= I93_FLAG_PROT_EXT_YES;
748
749 UINT8_TO_STREAM (p, flags);
750
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800751 /* Command Code */
752 UINT8_TO_STREAM (p, I93_CMD_WRITE_SINGLE_BLOCK);
753
754 /* Parameters */
755 ARRAY8_TO_STREAM (p, rw_cb.tcb.i93.uid); /* UID */
Evan Chu85b7e842013-01-18 11:02:50 -0500756
757 if (rw_cb.tcb.i93.intl_flags & RW_I93_FLAG_16BIT_NUM_BLOCK)
758 {
759 UINT16_TO_STREAM (p, block_number); /* Block number */
760 p_cmd->len++;
761 }
762 else
763 {
764 UINT8_TO_STREAM (p, block_number); /* Block number */
765 }
766
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800767
768 /* Data */
769 ARRAY_TO_STREAM (p, p_data, rw_cb.tcb.i93.block_size);
770
771 if (rw_i93_send_to_lower (p_cmd))
772 {
773 rw_cb.tcb.i93.sent_cmd = I93_CMD_WRITE_SINGLE_BLOCK;
774 return NFC_STATUS_OK;
775 }
776 else
777 {
778 return NFC_STATUS_FAILED;
779 }
780}
781
782/*******************************************************************************
783**
784** Function rw_i93_send_cmd_lock_block
785**
786** Description Send Lock Block Request to VICC
787**
Evan Chu85b7e842013-01-18 11:02:50 -0500788** STM LRIS64K, M24LR64-R, M24LR04E-R, M24LR16E-R, M24LR64E-R
789** do not support.
790**
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800791** Returns tNFC_STATUS
792**
793*******************************************************************************/
794tNFC_STATUS rw_i93_send_cmd_lock_block (UINT8 block_number)
795{
796 BT_HDR *p_cmd;
797 UINT8 *p;
798
799 RW_TRACE_DEBUG0 ("rw_i93_send_cmd_lock_block ()");
800
801 p_cmd = (BT_HDR *) GKI_getpoolbuf (NFC_RW_POOL_ID);
802
803 if (!p_cmd)
804 {
805 RW_TRACE_ERROR0 ("rw_i93_send_cmd_lock_block (): Cannot allocate buffer");
806 return NFC_STATUS_NO_BUFFERS;
807 }
808
809 p_cmd->offset = NCI_MSG_OFFSET_SIZE + NCI_DATA_HDR_SIZE;
810 p_cmd->len = 11;
811 p = (UINT8 *) (p_cmd + 1) + p_cmd->offset;
812
813 /* Flags */
814 if ( (rw_cb.tcb.i93.product_version == RW_I93_TAG_IT_HF_I_PLUS_INLAY)
815 ||(rw_cb.tcb.i93.product_version == RW_I93_TAG_IT_HF_I_PLUS_CHIP)
816 ||(rw_cb.tcb.i93.product_version == RW_I93_TAG_IT_HF_I_STD_CHIP_INLAY)
817 ||(rw_cb.tcb.i93.product_version == RW_I93_TAG_IT_HF_I_PRO_CHIP_INLAY) )
818 {
819 /* Option must be set for TI tag */
820 UINT8_TO_STREAM (p, (I93_FLAG_ADDRESS_SET | I93_FLAG_OPTION_SET | RW_I93_FLAG_SUB_CARRIER | RW_I93_FLAG_DATA_RATE));
821 }
822 else
823 {
824 UINT8_TO_STREAM (p, (I93_FLAG_ADDRESS_SET | RW_I93_FLAG_SUB_CARRIER | RW_I93_FLAG_DATA_RATE));
825 }
826
827 /* Command Code */
828 UINT8_TO_STREAM (p, I93_CMD_LOCK_BLOCK);
829
830 /* Parameters */
831 ARRAY8_TO_STREAM (p, rw_cb.tcb.i93.uid); /* UID */
832 UINT8_TO_STREAM (p, block_number); /* Block number */
833
834 if (rw_i93_send_to_lower (p_cmd))
835 {
836 rw_cb.tcb.i93.sent_cmd = I93_CMD_LOCK_BLOCK;
837 return NFC_STATUS_OK;
838 }
839 else
840 {
841 return NFC_STATUS_FAILED;
842 }
843}
844
845/*******************************************************************************
846**
847** Function rw_i93_send_cmd_read_multi_blocks
848**
849** Description Send Read Multiple Blocks Request to VICC
850**
851** Returns tNFC_STATUS
852**
853*******************************************************************************/
Evan Chu85b7e842013-01-18 11:02:50 -0500854tNFC_STATUS rw_i93_send_cmd_read_multi_blocks (UINT16 first_block_number, UINT16 number_blocks)
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800855{
856 BT_HDR *p_cmd;
Evan Chu85b7e842013-01-18 11:02:50 -0500857 UINT8 *p, flags;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800858
859 RW_TRACE_DEBUG0 ("rw_i93_send_cmd_read_multi_blocks ()");
860
861 p_cmd = (BT_HDR *) GKI_getpoolbuf (NFC_RW_POOL_ID);
862
863 if (!p_cmd)
864 {
865 RW_TRACE_ERROR0 ("rw_i93_send_cmd_read_multi_blocks (): Cannot allocate buffer");
866 return NFC_STATUS_NO_BUFFERS;
867 }
868
869 p_cmd->offset = NCI_MSG_OFFSET_SIZE + NCI_DATA_HDR_SIZE;
870 p_cmd->len = 12;
871 p = (UINT8 *) (p_cmd + 1) + p_cmd->offset;
872
873 /* Flags */
Evan Chu85b7e842013-01-18 11:02:50 -0500874 flags = (I93_FLAG_ADDRESS_SET | RW_I93_FLAG_SUB_CARRIER | RW_I93_FLAG_DATA_RATE);
875
876 if (rw_cb.tcb.i93.intl_flags & RW_I93_FLAG_16BIT_NUM_BLOCK)
877 flags |= I93_FLAG_PROT_EXT_YES;
878
879 UINT8_TO_STREAM (p, flags);
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800880
881 /* Command Code */
882 UINT8_TO_STREAM (p, I93_CMD_READ_MULTI_BLOCK);
883
884 /* Parameters */
885 ARRAY8_TO_STREAM (p, rw_cb.tcb.i93.uid); /* UID */
Evan Chu85b7e842013-01-18 11:02:50 -0500886
887 if (rw_cb.tcb.i93.intl_flags & RW_I93_FLAG_16BIT_NUM_BLOCK)
888 {
889 UINT16_TO_STREAM (p, first_block_number); /* First block number */
890 p_cmd->len++;
891 }
892 else
893 {
894 UINT8_TO_STREAM (p, first_block_number); /* First block number */
895 }
896
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800897 UINT8_TO_STREAM (p, number_blocks - 1); /* Number of blocks, 0x00 to read one block */
898
899 if (rw_i93_send_to_lower (p_cmd))
900 {
901 rw_cb.tcb.i93.sent_cmd = I93_CMD_READ_MULTI_BLOCK;
902 return NFC_STATUS_OK;
903 }
904 else
905 {
906 return NFC_STATUS_FAILED;
907 }
908}
909
910/*******************************************************************************
911**
912** Function rw_i93_send_cmd_write_multi_blocks
913**
914** Description Send Write Multiple Blocks Request to VICC
915**
916** Returns tNFC_STATUS
917**
918*******************************************************************************/
919tNFC_STATUS rw_i93_send_cmd_write_multi_blocks (UINT8 first_block_number,
920 UINT16 number_blocks,
921 UINT8 *p_data)
922{
923 BT_HDR *p_cmd;
924 UINT8 *p;
925
926 RW_TRACE_DEBUG0 ("rw_i93_send_cmd_write_multi_blocks ()");
927
928 p_cmd = (BT_HDR *) GKI_getpoolbuf (NFC_RW_POOL_ID);
929
930 if (!p_cmd)
931 {
932 RW_TRACE_ERROR0 ("rw_i93_send_cmd_write_multi_blocks (): Cannot allocate buffer");
933 return NFC_STATUS_NO_BUFFERS;
934 }
935
936 p_cmd->offset = NCI_MSG_OFFSET_SIZE + NCI_DATA_HDR_SIZE;
937 p_cmd->len = 12 + number_blocks * rw_cb.tcb.i93.block_size;
938 p = (UINT8 *) (p_cmd + 1) + p_cmd->offset;
939
940 /* Flags */
941 UINT8_TO_STREAM (p, (I93_FLAG_ADDRESS_SET | RW_I93_FLAG_SUB_CARRIER | RW_I93_FLAG_DATA_RATE));
942
943 /* Command Code */
944 UINT8_TO_STREAM (p, I93_CMD_WRITE_MULTI_BLOCK);
945
946 /* Parameters */
947 ARRAY8_TO_STREAM (p, rw_cb.tcb.i93.uid); /* UID */
948 UINT8_TO_STREAM (p, first_block_number); /* First block number */
949 UINT8_TO_STREAM (p, number_blocks - 1); /* Number of blocks, 0x00 to read one block */
950
951 /* Data */
952 ARRAY_TO_STREAM (p, p_data, number_blocks * rw_cb.tcb.i93.block_size);
953
954 if (rw_i93_send_to_lower (p_cmd))
955 {
956 rw_cb.tcb.i93.sent_cmd = I93_CMD_WRITE_MULTI_BLOCK;
957 return NFC_STATUS_OK;
958 }
959 else
960 {
961 return NFC_STATUS_FAILED;
962 }
963}
964
965/*******************************************************************************
966**
967** Function rw_i93_send_cmd_select
968**
969** Description Send Select Request to VICC
970**
971** Returns tNFC_STATUS
972**
973*******************************************************************************/
974tNFC_STATUS rw_i93_send_cmd_select (UINT8 *p_uid)
975{
976 BT_HDR *p_cmd;
977 UINT8 *p;
978
979 RW_TRACE_DEBUG0 ("rw_i93_send_cmd_select ()");
980
981 p_cmd = (BT_HDR *) GKI_getpoolbuf (NFC_RW_POOL_ID);
982
983 if (!p_cmd)
984 {
985 RW_TRACE_ERROR0 ("rw_i93_send_cmd_select (): Cannot allocate buffer");
986 return NFC_STATUS_NO_BUFFERS;
987 }
988
989 p_cmd->offset = NCI_MSG_OFFSET_SIZE + NCI_DATA_HDR_SIZE;
990 p_cmd->len = 10 ;
991 p = (UINT8 *) (p_cmd + 1) + p_cmd->offset;
992
993 /* Flags */
994 UINT8_TO_STREAM (p, (I93_FLAG_ADDRESS_SET | RW_I93_FLAG_SUB_CARRIER | RW_I93_FLAG_DATA_RATE));
995
996 /* Command Code */
997 UINT8_TO_STREAM (p, I93_CMD_SELECT);
998
999 /* Parameters */
1000 ARRAY8_TO_STREAM (p, p_uid); /* UID */
1001
1002 if (rw_i93_send_to_lower (p_cmd))
1003 {
1004 rw_cb.tcb.i93.sent_cmd = I93_CMD_SELECT;
1005 return NFC_STATUS_OK;
1006 }
1007 else
1008 {
1009 return NFC_STATUS_FAILED;
1010 }
1011}
1012
1013/*******************************************************************************
1014**
1015** Function rw_i93_send_cmd_reset_to_ready
1016**
1017** Description Send Reset to Ready Request to VICC
1018**
1019** Returns tNFC_STATUS
1020**
1021*******************************************************************************/
1022tNFC_STATUS rw_i93_send_cmd_reset_to_ready (void)
1023{
1024 BT_HDR *p_cmd;
1025 UINT8 *p;
1026
1027 RW_TRACE_DEBUG0 ("rw_i93_send_cmd_reset_to_ready ()");
1028
1029 p_cmd = (BT_HDR *) GKI_getpoolbuf (NFC_RW_POOL_ID);
1030
1031 if (!p_cmd)
1032 {
1033 RW_TRACE_ERROR0 ("rw_i93_send_cmd_reset_to_ready (): Cannot allocate buffer");
1034 return NFC_STATUS_NO_BUFFERS;
1035 }
1036
1037 p_cmd->offset = NCI_MSG_OFFSET_SIZE + NCI_DATA_HDR_SIZE;
1038 p_cmd->len = 10 ;
1039 p = (UINT8 *) (p_cmd + 1) + p_cmd->offset;
1040
1041 /* Flags */
1042 UINT8_TO_STREAM (p, (I93_FLAG_ADDRESS_SET | RW_I93_FLAG_SUB_CARRIER | RW_I93_FLAG_DATA_RATE));
1043
1044 /* Command Code */
1045 UINT8_TO_STREAM (p, I93_CMD_RESET_TO_READY);
1046
1047 /* Parameters */
1048 ARRAY8_TO_STREAM (p, rw_cb.tcb.i93.uid); /* UID */
1049
1050 if (rw_i93_send_to_lower (p_cmd))
1051 {
1052 rw_cb.tcb.i93.sent_cmd = I93_CMD_RESET_TO_READY;
1053 return NFC_STATUS_OK;
1054 }
1055 else
1056 {
1057 return NFC_STATUS_FAILED;
1058 }
1059}
1060
1061/*******************************************************************************
1062**
1063** Function rw_i93_send_cmd_write_afi
1064**
1065** Description Send Write AFI Request to VICC
1066**
1067** Returns tNFC_STATUS
1068**
1069*******************************************************************************/
1070tNFC_STATUS rw_i93_send_cmd_write_afi (UINT8 afi)
1071{
1072 BT_HDR *p_cmd;
1073 UINT8 *p;
1074
1075 RW_TRACE_DEBUG0 ("rw_i93_send_cmd_write_afi ()");
1076
1077 p_cmd = (BT_HDR *) GKI_getpoolbuf (NFC_RW_POOL_ID);
1078
1079 if (!p_cmd)
1080 {
1081 RW_TRACE_ERROR0 ("rw_i93_send_cmd_write_afi (): Cannot allocate buffer");
1082 return NFC_STATUS_NO_BUFFERS;
1083 }
1084
1085 p_cmd->offset = NCI_MSG_OFFSET_SIZE + NCI_DATA_HDR_SIZE;
1086 p_cmd->len = 11;
1087 p = (UINT8 *) (p_cmd + 1) + p_cmd->offset;
1088
1089 /* Flags */
1090 UINT8_TO_STREAM (p, (I93_FLAG_ADDRESS_SET | RW_I93_FLAG_SUB_CARRIER | RW_I93_FLAG_DATA_RATE));
1091
1092 /* Command Code */
1093 UINT8_TO_STREAM (p, I93_CMD_WRITE_AFI);
1094
1095 /* Parameters */
1096 ARRAY8_TO_STREAM (p, rw_cb.tcb.i93.uid); /* UID */
1097 UINT8_TO_STREAM (p, afi); /* AFI */
1098
1099 if (rw_i93_send_to_lower (p_cmd))
1100 {
1101 rw_cb.tcb.i93.sent_cmd = I93_CMD_WRITE_AFI;
1102 return NFC_STATUS_OK;
1103 }
1104 else
1105 {
1106 return NFC_STATUS_FAILED;
1107 }
1108}
1109
1110/*******************************************************************************
1111**
1112** Function rw_i93_send_cmd_lock_afi
1113**
1114** Description Send Lock AFI Request to VICC
1115**
1116** Returns tNFC_STATUS
1117**
1118*******************************************************************************/
1119tNFC_STATUS rw_i93_send_cmd_lock_afi (void)
1120{
1121 BT_HDR *p_cmd;
1122 UINT8 *p;
1123
1124 RW_TRACE_DEBUG0 ("rw_i93_send_cmd_lock_afi ()");
1125
1126 p_cmd = (BT_HDR *) GKI_getpoolbuf (NFC_RW_POOL_ID);
1127
1128 if (!p_cmd)
1129 {
1130 RW_TRACE_ERROR0 ("rw_i93_send_cmd_lock_afi (): Cannot allocate buffer");
1131 return NFC_STATUS_NO_BUFFERS;
1132 }
1133
1134 p_cmd->offset = NCI_MSG_OFFSET_SIZE + NCI_DATA_HDR_SIZE;
1135 p_cmd->len = 10;
1136 p = (UINT8 *) (p_cmd + 1) + p_cmd->offset;
1137
1138 /* Flags */
1139 UINT8_TO_STREAM (p, (I93_FLAG_ADDRESS_SET | RW_I93_FLAG_SUB_CARRIER | RW_I93_FLAG_DATA_RATE));
1140
1141 /* Command Code */
1142 UINT8_TO_STREAM (p, I93_CMD_LOCK_AFI);
1143
1144 /* Parameters */
1145 ARRAY8_TO_STREAM (p, rw_cb.tcb.i93.uid); /* UID */
1146
1147 if (rw_i93_send_to_lower (p_cmd))
1148 {
1149 rw_cb.tcb.i93.sent_cmd = I93_CMD_LOCK_AFI;
1150 return NFC_STATUS_OK;
1151 }
1152 else
1153 {
1154 return NFC_STATUS_FAILED;
1155 }
1156}
1157
1158/*******************************************************************************
1159**
1160** Function rw_i93_send_cmd_write_dsfid
1161**
1162** Description Send Write DSFID Request to VICC
1163**
1164** Returns tNFC_STATUS
1165**
1166*******************************************************************************/
1167tNFC_STATUS rw_i93_send_cmd_write_dsfid (UINT8 dsfid)
1168{
1169 BT_HDR *p_cmd;
1170 UINT8 *p;
1171
1172 RW_TRACE_DEBUG0 ("rw_i93_send_cmd_write_dsfid ()");
1173
1174 p_cmd = (BT_HDR *) GKI_getpoolbuf (NFC_RW_POOL_ID);
1175
1176 if (!p_cmd)
1177 {
1178 RW_TRACE_ERROR0 ("rw_i93_send_cmd_write_dsfid (): Cannot allocate buffer");
1179 return NFC_STATUS_NO_BUFFERS;
1180 }
1181
1182 p_cmd->offset = NCI_MSG_OFFSET_SIZE + NCI_DATA_HDR_SIZE;
1183 p_cmd->len = 11;
1184 p = (UINT8 *) (p_cmd + 1) + p_cmd->offset;
1185
1186 /* Flags */
1187 UINT8_TO_STREAM (p, (I93_FLAG_ADDRESS_SET | RW_I93_FLAG_SUB_CARRIER | RW_I93_FLAG_DATA_RATE));
1188
1189 /* Command Code */
1190 UINT8_TO_STREAM (p, I93_CMD_WRITE_DSFID);
1191
1192 /* Parameters */
1193 ARRAY8_TO_STREAM (p, rw_cb.tcb.i93.uid); /* UID */
1194 UINT8_TO_STREAM (p, dsfid); /* DSFID */
1195
1196 if (rw_i93_send_to_lower (p_cmd))
1197 {
1198 rw_cb.tcb.i93.sent_cmd = I93_CMD_WRITE_DSFID;
1199 return NFC_STATUS_OK;
1200 }
1201 else
1202 {
1203 return NFC_STATUS_FAILED;
1204 }
1205}
1206
1207/*******************************************************************************
1208**
1209** Function rw_i93_send_cmd_lock_dsfid
1210**
1211** Description Send Lock DSFID Request to VICC
1212**
1213** Returns tNFC_STATUS
1214**
1215*******************************************************************************/
1216tNFC_STATUS rw_i93_send_cmd_lock_dsfid (void)
1217{
1218 BT_HDR *p_cmd;
1219 UINT8 *p;
1220
1221 RW_TRACE_DEBUG0 ("rw_i93_send_cmd_lock_dsfid ()");
1222
1223 p_cmd = (BT_HDR *) GKI_getpoolbuf (NFC_RW_POOL_ID);
1224
1225 if (!p_cmd)
1226 {
1227 RW_TRACE_ERROR0 ("rw_i93_send_cmd_lock_dsfid (): Cannot allocate buffer");
1228 return NFC_STATUS_NO_BUFFERS;
1229 }
1230
1231 p_cmd->offset = NCI_MSG_OFFSET_SIZE + NCI_DATA_HDR_SIZE;
1232 p_cmd->len = 10;
1233 p = (UINT8 *) (p_cmd + 1) + p_cmd->offset;
1234
1235 /* Flags */
1236 UINT8_TO_STREAM (p, (I93_FLAG_ADDRESS_SET | RW_I93_FLAG_SUB_CARRIER | RW_I93_FLAG_DATA_RATE));
1237
1238 /* Command Code */
1239 UINT8_TO_STREAM (p, I93_CMD_LOCK_DSFID);
1240
1241 /* Parameters */
1242 ARRAY8_TO_STREAM (p, rw_cb.tcb.i93.uid); /* UID */
1243
1244 if (rw_i93_send_to_lower (p_cmd))
1245 {
1246 rw_cb.tcb.i93.sent_cmd = I93_CMD_LOCK_DSFID;
1247 return NFC_STATUS_OK;
1248 }
1249 else
1250 {
1251 return NFC_STATUS_FAILED;
1252 }
1253}
1254
1255/*******************************************************************************
1256**
1257** Function rw_i93_send_cmd_get_sys_info
1258**
1259** Description Send Get System Information Request to VICC
1260**
1261** Returns tNFC_STATUS
1262**
1263*******************************************************************************/
Evan Chu85b7e842013-01-18 11:02:50 -05001264tNFC_STATUS rw_i93_send_cmd_get_sys_info (UINT8 *p_uid, UINT8 extra_flags)
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001265{
1266 BT_HDR *p_cmd;
1267 UINT8 *p;
1268
1269 RW_TRACE_DEBUG0 ("rw_i93_send_cmd_get_sys_info ()");
1270
1271 p_cmd = (BT_HDR *) GKI_getpoolbuf (NFC_RW_POOL_ID);
1272
1273 if (!p_cmd)
1274 {
1275 RW_TRACE_ERROR0 ("rw_i93_send_cmd_get_sys_info (): Cannot allocate buffer");
1276 return NFC_STATUS_NO_BUFFERS;
1277 }
1278
1279 p_cmd->offset = NCI_MSG_OFFSET_SIZE + NCI_DATA_HDR_SIZE;
1280 p_cmd->len = 10;
1281 p = (UINT8 *) (p_cmd + 1) + p_cmd->offset;
1282
1283 /* Flags */
Evan Chu85b7e842013-01-18 11:02:50 -05001284 UINT8_TO_STREAM (p, (I93_FLAG_ADDRESS_SET | RW_I93_FLAG_SUB_CARRIER | RW_I93_FLAG_DATA_RATE | extra_flags));
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001285
1286 /* Command Code */
1287 UINT8_TO_STREAM (p, I93_CMD_GET_SYS_INFO);
1288
1289 /* Parameters */
1290 if (p_uid)
1291 {
1292 ARRAY8_TO_STREAM (p, p_uid); /* UID */
1293 }
1294 else
1295 {
1296 ARRAY8_TO_STREAM (p, rw_cb.tcb.i93.uid); /* UID */
1297 }
1298
1299 if (rw_i93_send_to_lower (p_cmd))
1300 {
1301 rw_cb.tcb.i93.sent_cmd = I93_CMD_GET_SYS_INFO;
1302 return NFC_STATUS_OK;
1303 }
1304 else
1305 {
1306 return NFC_STATUS_FAILED;
1307 }
1308}
1309
1310/*******************************************************************************
1311**
1312** Function rw_i93_send_cmd_get_multi_block_sec
1313**
1314** Description Send Get Multiple Block Security Status Request to VICC
1315**
1316** Returns tNFC_STATUS
1317**
1318*******************************************************************************/
Evan Chu85b7e842013-01-18 11:02:50 -05001319tNFC_STATUS rw_i93_send_cmd_get_multi_block_sec (UINT16 first_block_number,
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001320 UINT16 number_blocks)
1321{
1322 BT_HDR *p_cmd;
Evan Chu85b7e842013-01-18 11:02:50 -05001323 UINT8 *p, flags;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001324
1325 RW_TRACE_DEBUG0 ("rw_i93_send_cmd_get_multi_block_sec ()");
1326
1327 p_cmd = (BT_HDR *) GKI_getpoolbuf (NFC_RW_POOL_ID);
1328
1329 if (!p_cmd)
1330 {
1331 RW_TRACE_ERROR0 ("rw_i93_send_cmd_get_multi_block_sec (): Cannot allocate buffer");
1332 return NFC_STATUS_NO_BUFFERS;
1333 }
1334
1335 p_cmd->offset = NCI_MSG_OFFSET_SIZE + NCI_DATA_HDR_SIZE;
1336 p_cmd->len = 12;
1337 p = (UINT8 *) (p_cmd + 1) + p_cmd->offset;
1338
1339 /* Flags */
Evan Chu85b7e842013-01-18 11:02:50 -05001340 flags = (I93_FLAG_ADDRESS_SET | RW_I93_FLAG_SUB_CARRIER | RW_I93_FLAG_DATA_RATE);
1341
1342 if (rw_cb.tcb.i93.intl_flags & RW_I93_FLAG_16BIT_NUM_BLOCK)
1343 flags |= I93_FLAG_PROT_EXT_YES;
1344
1345 UINT8_TO_STREAM (p, flags);
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001346
1347 /* Command Code */
1348 UINT8_TO_STREAM (p, I93_CMD_GET_MULTI_BLK_SEC);
1349
1350 /* Parameters */
1351 ARRAY8_TO_STREAM (p, rw_cb.tcb.i93.uid); /* UID */
Evan Chu85b7e842013-01-18 11:02:50 -05001352
1353 if (rw_cb.tcb.i93.intl_flags & RW_I93_FLAG_16BIT_NUM_BLOCK)
1354 {
1355 UINT16_TO_STREAM (p, first_block_number); /* First block number */
1356 UINT16_TO_STREAM (p, number_blocks - 1); /* Number of blocks, 0x00 to read one block */
1357 p_cmd->len += 2;
1358 }
1359 else
1360 {
1361 UINT8_TO_STREAM (p, first_block_number); /* First block number */
1362 UINT8_TO_STREAM (p, number_blocks - 1); /* Number of blocks, 0x00 to read one block */
1363 }
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001364
1365 if (rw_i93_send_to_lower (p_cmd))
1366 {
1367 rw_cb.tcb.i93.sent_cmd = I93_CMD_GET_MULTI_BLK_SEC;
1368 return NFC_STATUS_OK;
1369 }
1370 else
1371 {
1372 return NFC_STATUS_FAILED;
1373 }
1374}
1375
1376/*******************************************************************************
1377**
1378** Function rw_i93_get_next_blocks
1379**
1380** Description Read as many blocks as possible (up to RW_I93_READ_MULTI_BLOCK_SIZE)
1381**
1382** Returns tNFC_STATUS
1383**
1384*******************************************************************************/
1385tNFC_STATUS rw_i93_get_next_blocks (UINT16 offset)
1386{
1387 tRW_I93_CB *p_i93 = &rw_cb.tcb.i93;
Evan Chu85b7e842013-01-18 11:02:50 -05001388 UINT16 first_block;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001389 UINT16 num_block;
1390
Evan Chu85b7e842013-01-18 11:02:50 -05001391 RW_TRACE_DEBUG0 ("rw_i93_get_next_blocks ()");
1392
1393 first_block = offset / p_i93->block_size;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001394
1395 /* more blocks, more efficent but more error rate */
1396
1397 if (p_i93->intl_flags & RW_I93_FLAG_READ_MULTI_BLOCK)
1398 {
1399 num_block = RW_I93_READ_MULTI_BLOCK_SIZE / p_i93->block_size;
1400
1401 if (num_block + first_block > p_i93->num_block)
1402 num_block = p_i93->num_block - first_block;
1403
Evan Chu85b7e842013-01-18 11:02:50 -05001404 if (p_i93->uid[1] == I93_UID_IC_MFG_CODE_STM)
1405 {
1406 /* LRIS64K, M24LR64-R, M24LR04E-R, M24LR16E-R, M24LR64E-R requires
1407 ** The max number of blocks is 32 and they are all located in the same sector.
1408 ** The sector is 32 blocks of 4 bytes.
1409 */
1410 if ( (p_i93->product_version == RW_I93_STM_LRIS64K)
1411 ||(p_i93->product_version == RW_I93_STM_M24LR64_R)
1412 ||(p_i93->product_version == RW_I93_STM_M24LR04E_R)
1413 ||(p_i93->product_version == RW_I93_STM_M24LR16E_R)
1414 ||(p_i93->product_version == RW_I93_STM_M24LR64E_R) )
1415 {
1416 if (num_block > I93_STM_MAX_BLOCKS_PER_READ)
1417 num_block = I93_STM_MAX_BLOCKS_PER_READ;
1418
1419 if ((first_block / I93_STM_BLOCKS_PER_SECTOR)
1420 != ((first_block + num_block - 1) / I93_STM_BLOCKS_PER_SECTOR))
1421 {
1422 num_block = I93_STM_BLOCKS_PER_SECTOR - (first_block % I93_STM_BLOCKS_PER_SECTOR);
1423 }
1424 }
1425 }
1426
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001427 return rw_i93_send_cmd_read_multi_blocks (first_block, num_block);
1428 }
1429 else
1430 {
1431 return rw_i93_send_cmd_read_single_block (first_block, FALSE);
1432 }
1433}
1434
1435/*******************************************************************************
1436**
Evan Chu85b7e842013-01-18 11:02:50 -05001437** Function rw_i93_get_next_block_sec
1438**
1439** Description Get as many security of blocks as possible from p_i93->rw_offset
1440** (up to RW_I93_GET_MULTI_BLOCK_SEC_SIZE)
1441**
1442** Returns tNFC_STATUS
1443**
1444*******************************************************************************/
1445tNFC_STATUS rw_i93_get_next_block_sec (void)
1446{
1447 tRW_I93_CB *p_i93 = &rw_cb.tcb.i93;
1448 UINT16 num_blocks;
1449
1450 RW_TRACE_DEBUG0 ("rw_i93_get_next_block_sec ()");
1451
1452 if (p_i93->num_block <= p_i93->rw_offset)
1453 {
1454 RW_TRACE_ERROR2 ("rw_offset(0x%x) must be less than num_block(0x%x)",
1455 p_i93->rw_offset, p_i93->num_block);
1456 return NFC_STATUS_FAILED;
1457 }
1458
1459 num_blocks = p_i93->num_block - p_i93->rw_offset;
1460
1461 if (num_blocks > RW_I93_GET_MULTI_BLOCK_SEC_SIZE)
1462 num_blocks = RW_I93_GET_MULTI_BLOCK_SEC_SIZE;
1463
1464 return rw_i93_send_cmd_get_multi_block_sec (p_i93->rw_offset, num_blocks);
1465}
1466
1467/*******************************************************************************
1468**
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001469** Function rw_i93_sm_detect_ndef
1470**
1471** Description Process NDEF detection procedure
1472**
1473** 1. Get UID if not having yet
1474** 2. Get System Info if not having yet
1475** 3. Read first block for CC
1476** 4. Search NDEF Type and length
1477** 5. Get block status to get max NDEF size and read-only status
1478**
1479** Returns void
1480**
1481*******************************************************************************/
1482void rw_i93_sm_detect_ndef (BT_HDR *p_resp)
1483{
1484 UINT8 *p = (UINT8 *) (p_resp + 1) + p_resp->offset, *p_uid;
Evan Chu85b7e842013-01-18 11:02:50 -05001485 UINT8 flags, u8 = 0, cc[4];
1486 UINT16 length = p_resp->len, xx, block, first_block, last_block, num_blocks;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001487 tRW_I93_CB *p_i93 = &rw_cb.tcb.i93;
1488 tRW_DATA rw_data;
1489 tNFC_STATUS status = NFC_STATUS_FAILED;
1490
1491#if (BT_TRACE_VERBOSE == TRUE)
1492 RW_TRACE_DEBUG2 ("rw_i93_sm_detect_ndef () sub_state:%s (0x%x)",
1493 rw_i93_get_sub_state_name (p_i93->sub_state), p_i93->sub_state);
1494#else
1495 RW_TRACE_DEBUG1 ("rw_i93_sm_detect_ndef () sub_state:0x%x", p_i93->sub_state);
1496#endif
1497
1498 STREAM_TO_UINT8 (flags, p);
1499 length--;
1500
1501 if (flags & I93_FLAG_ERROR_DETECTED)
1502 {
Evan Chu85b7e842013-01-18 11:02:50 -05001503 if ((length) && (rw_i93_check_sys_info_prot_ext(*p)))
1504 {
1505 /* getting system info with protocol extension flag */
1506 /* This STM tag supports more than 2040 bytes */
1507 p_i93->intl_flags |= RW_I93_FLAG_16BIT_NUM_BLOCK;
1508 }
1509 else
1510 {
1511 RW_TRACE_DEBUG1 ("Got error flags (0x%02x)", flags);
1512 rw_i93_handle_error (NFC_STATUS_FAILED);
1513 }
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001514 return;
1515 }
1516
1517 switch (p_i93->sub_state)
1518 {
1519 case RW_I93_SUBSTATE_WAIT_UID:
1520
1521 STREAM_TO_UINT8 (u8, p); /* DSFID */
1522 p_uid = p_i93->uid;
1523 STREAM_TO_ARRAY8 (p_uid, p);
1524
1525 if (u8 != I93_DFS_UNSUPPORTED)
1526 {
1527 /* if Data Storage Format is unknown */
1528 RW_TRACE_DEBUG1 ("Got unknown DSFID (0x%02x)", u8);
1529 rw_i93_handle_error (NFC_STATUS_FAILED);
1530 }
1531 else
1532 {
1533 /* get system information to get memory size */
Evan Chu85b7e842013-01-18 11:02:50 -05001534 if (rw_i93_send_cmd_get_sys_info (NULL, I93_FLAG_PROT_EXT_NO) == NFC_STATUS_OK)
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001535 {
1536 p_i93->sub_state = RW_I93_SUBSTATE_WAIT_SYS_INFO;
1537 }
1538 else
1539 {
1540 rw_i93_handle_error (NFC_STATUS_FAILED);
1541 }
1542 }
1543 break;
1544
1545 case RW_I93_SUBSTATE_WAIT_SYS_INFO:
1546
Evan Chu85b7e842013-01-18 11:02:50 -05001547 p_i93->block_size = 0;
1548 p_i93->num_block = 0;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001549
Evan Chu85b7e842013-01-18 11:02:50 -05001550 if (!rw_i93_process_sys_info (p))
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001551 {
Evan Chu85b7e842013-01-18 11:02:50 -05001552 /* retrying with protocol extension flag */
1553 break;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001554 }
1555
Evan Chu85b7e842013-01-18 11:02:50 -05001556 if ((p_i93->block_size == 0)||(p_i93->num_block == 0))
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001557 {
1558 RW_TRACE_DEBUG0 ("Unable to get tag memory size");
1559 rw_i93_handle_error (status);
1560 }
1561 else
1562 {
1563 /* read CC in the first block */
Evan Chu85b7e842013-01-18 11:02:50 -05001564 if (rw_i93_send_cmd_read_single_block (0x0000, FALSE) == NFC_STATUS_OK)
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001565 {
1566 p_i93->sub_state = RW_I93_SUBSTATE_WAIT_CC;
1567 }
1568 else
1569 {
1570 rw_i93_handle_error (NFC_STATUS_FAILED);
1571 }
1572 }
1573 break;
1574
1575 case RW_I93_SUBSTATE_WAIT_CC:
1576
1577 /* assume block size is more than 4 */
1578 STREAM_TO_ARRAY (cc, p, 4);
1579
1580 status = NFC_STATUS_FAILED;
1581
1582 /*
1583 ** Capability Container (CC)
1584 **
1585 ** CC[0] : magic number (0xE1)
1586 ** CC[1] : Bit 7-6:Major version number
1587 ** : Bit 5-4:Minor version number
1588 ** : Bit 3-2:Read access condition (00b: read access granted without any security)
1589 ** : Bit 1-0:Write access condition (00b: write access granted without any security)
Evan Chu85b7e842013-01-18 11:02:50 -05001590 ** CC[2] : Memory size in 8 bytes (Ex. 0x04 is 32 bytes) [STM, set to 0xFF if more than 2040bytes]
1591 ** CC[3] : Bit 0:Read multiple blocks is supported [NXP, STM]
1592 ** : Bit 1:Inventory page read is supported [NXP]
1593 ** : Bit 2:More than 2040 bytes are supported [STM]
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001594 */
1595
1596 RW_TRACE_DEBUG4 ("rw_i93_sm_detect_ndef (): cc: 0x%02X 0x%02X 0x%02X 0x%02X", cc[0], cc[1], cc[2], cc[3]);
1597 RW_TRACE_DEBUG2 ("rw_i93_sm_detect_ndef (): Total blocks:0x%04X, Block size:0x%02X", p_i93->num_block, p_i93->block_size );
1598
1599 if ( (cc[0] == I93_ICODE_CC_MAGIC_NUMER)
Evan Chu85b7e842013-01-18 11:02:50 -05001600 &&( (cc[3] & I93_STM_CC_OVERFLOW_MASK)
1601 ||(cc[2] * 8) == (p_i93->num_block * p_i93->block_size) ) )
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001602 {
1603 if ((cc[1] & I93_ICODE_CC_READ_ACCESS_MASK) == I93_ICODE_CC_READ_ACCESS_GRANTED)
1604 {
1605 if ((cc[1] & I93_ICODE_CC_WRITE_ACCESS_MASK) != I93_ICODE_CC_WRITE_ACCESS_GRANTED)
1606 {
1607 /* read-only or password required to write */
1608 p_i93->intl_flags |= RW_I93_FLAG_READ_ONLY;
1609 }
1610 if (cc[3] & I93_ICODE_CC_MBREAD_MASK)
1611 {
1612 /* tag supports read multi blocks command */
1613 p_i93->intl_flags |= RW_I93_FLAG_READ_MULTI_BLOCK;
1614 }
1615 status = NFC_STATUS_OK;
1616 }
1617 }
1618
1619 if (status == NFC_STATUS_OK)
1620 {
1621 /* seach NDEF TLV from offset 4 */
1622 p_i93->rw_offset = 4;
1623
1624 if (rw_i93_get_next_blocks (p_i93->rw_offset) == NFC_STATUS_OK)
1625 {
1626 p_i93->sub_state = RW_I93_SUBSTATE_SEARCH_NDEF_TLV;
1627 p_i93->tlv_detect_state = RW_I93_TLV_DETECT_STATE_TYPE;
1628 }
1629 else
1630 {
1631 rw_i93_handle_error (NFC_STATUS_FAILED);
1632 }
1633 }
1634 else
1635 {
1636 rw_i93_handle_error (NFC_STATUS_FAILED);
1637 }
1638 break;
1639
1640 case RW_I93_SUBSTATE_SEARCH_NDEF_TLV:
1641
1642 /* search TLV within read blocks */
Evan Chu85b7e842013-01-18 11:02:50 -05001643 for (xx = 0; xx < length; xx++)
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001644 {
1645 /* if looking for type */
1646 if (p_i93->tlv_detect_state == RW_I93_TLV_DETECT_STATE_TYPE)
1647 {
Evan Chu85b7e842013-01-18 11:02:50 -05001648 if (*(p + xx) == I93_ICODE_TLV_TYPE_NULL)
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001649 {
1650 continue;
1651 }
Evan Chu85b7e842013-01-18 11:02:50 -05001652 else if ( (*(p + xx) == I93_ICODE_TLV_TYPE_NDEF)
1653 ||(*(p + xx) == I93_ICODE_TLV_TYPE_PROP) )
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001654 {
1655 /* store found type and get length field */
Evan Chu85b7e842013-01-18 11:02:50 -05001656 p_i93->tlv_type = *(p + xx);
1657 p_i93->ndef_tlv_start_offset = p_i93->rw_offset + xx;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001658
1659 p_i93->tlv_detect_state = RW_I93_TLV_DETECT_STATE_LENGTH_1;
1660 }
Evan Chu85b7e842013-01-18 11:02:50 -05001661 else if (*(p + xx) == I93_ICODE_TLV_TYPE_TERM)
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001662 {
1663 /* no NDEF TLV found */
1664 p_i93->tlv_type = I93_ICODE_TLV_TYPE_TERM;
1665 break;
1666 }
1667 else
1668 {
Evan Chu85b7e842013-01-18 11:02:50 -05001669 RW_TRACE_DEBUG1 ("Invalid type: 0x%02x", *(p + xx));
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001670 rw_i93_handle_error (NFC_STATUS_FAILED);
1671 return;
1672 }
1673 }
1674 else if (p_i93->tlv_detect_state == RW_I93_TLV_DETECT_STATE_LENGTH_1)
1675 {
1676 /* if 3 bytes length field */
Evan Chu85b7e842013-01-18 11:02:50 -05001677 if (*(p + xx) == 0xFF)
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001678 {
1679 /* need 2 more bytes for length field */
1680 p_i93->tlv_detect_state = RW_I93_TLV_DETECT_STATE_LENGTH_2;
1681 }
1682 else
1683 {
Evan Chu85b7e842013-01-18 11:02:50 -05001684 p_i93->tlv_length = *(p + xx);
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001685 p_i93->tlv_detect_state = RW_I93_TLV_DETECT_STATE_VALUE;
1686
1687 if (p_i93->tlv_type == I93_ICODE_TLV_TYPE_NDEF)
1688 {
1689 p_i93->ndef_tlv_last_offset = p_i93->ndef_tlv_start_offset + 1 + p_i93->tlv_length;
1690 break;
1691 }
1692 }
1693 }
1694 else if (p_i93->tlv_detect_state == RW_I93_TLV_DETECT_STATE_LENGTH_2)
1695 {
1696 /* the second byte of 3 bytes length field */
Evan Chu85b7e842013-01-18 11:02:50 -05001697 p_i93->tlv_length = *(p + xx);
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001698 p_i93->tlv_detect_state = RW_I93_TLV_DETECT_STATE_LENGTH_3;
1699 }
1700 else if (p_i93->tlv_detect_state == RW_I93_TLV_DETECT_STATE_LENGTH_3)
1701 {
1702 /* the last byte of 3 bytes length field */
Evan Chu85b7e842013-01-18 11:02:50 -05001703 p_i93->tlv_length = (p_i93->tlv_length << 8) + *(p + xx);
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001704 p_i93->tlv_detect_state = RW_I93_TLV_DETECT_STATE_VALUE;
1705
1706 if (p_i93->tlv_type == I93_ICODE_TLV_TYPE_NDEF)
1707 {
1708 p_i93->ndef_tlv_last_offset = p_i93->ndef_tlv_start_offset + 3 + p_i93->tlv_length;
1709 break;
1710 }
1711 }
1712 else if (p_i93->tlv_detect_state == RW_I93_TLV_DETECT_STATE_VALUE)
1713 {
1714 /* this is other than NDEF TLV */
Evan Chu85b7e842013-01-18 11:02:50 -05001715 if (p_i93->tlv_length <= length - xx)
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001716 {
1717 /* skip value field */
Evan Chu85b7e842013-01-18 11:02:50 -05001718 xx += (UINT8)p_i93->tlv_length;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001719 p_i93->tlv_detect_state = RW_I93_TLV_DETECT_STATE_TYPE;
1720 }
1721 else
1722 {
1723 /* read more data */
Evan Chu85b7e842013-01-18 11:02:50 -05001724 p_i93->tlv_length -= (length - xx);
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001725 break;
1726 }
1727 }
1728 }
1729
1730 /* found NDEF TLV and read length field */
1731 if ( (p_i93->tlv_type == I93_ICODE_TLV_TYPE_NDEF)
1732 &&(p_i93->tlv_detect_state == RW_I93_TLV_DETECT_STATE_VALUE) )
1733 {
1734 p_i93->ndef_length = p_i93->tlv_length;
1735
1736 /* get lock status to see if read-only */
1737 if ( (p_i93->product_version == RW_I93_TAG_IT_HF_I_STD_CHIP_INLAY)
1738 ||(p_i93->product_version == RW_I93_TAG_IT_HF_I_PRO_CHIP_INLAY)
1739 ||((p_i93->uid[1] == I93_UID_IC_MFG_CODE_NXP) && (p_i93->ic_reference & I93_ICODE_IC_REF_MBREAD_MASK)) )
1740 {
1741 /* these doesn't support GetMultiBlockSecurityStatus */
1742
1743 p_i93->rw_offset = p_i93->ndef_tlv_start_offset;
Evan Chu85b7e842013-01-18 11:02:50 -05001744 first_block = p_i93->ndef_tlv_start_offset / p_i93->block_size;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001745
1746 /* read block to get lock status */
1747 rw_i93_send_cmd_read_single_block (first_block, TRUE);
1748 p_i93->sub_state = RW_I93_SUBSTATE_CHECK_LOCK_STATUS;
1749 }
1750 else
1751 {
Evan Chu85b7e842013-01-18 11:02:50 -05001752 /* block offset for read-only check */
1753 p_i93->rw_offset = 0;
1754
1755 if (rw_i93_get_next_block_sec () == NFC_STATUS_OK)
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001756 {
1757 p_i93->sub_state = RW_I93_SUBSTATE_CHECK_LOCK_STATUS;
1758 }
1759 else
1760 {
1761 rw_i93_handle_error (NFC_STATUS_FAILED);
1762 }
1763 }
1764 }
1765 else
1766 {
1767 /* read more data */
1768 p_i93->rw_offset += length;
1769
1770 if (p_i93->rw_offset >= p_i93->block_size * p_i93->num_block)
1771 {
1772 rw_i93_handle_error (NFC_STATUS_FAILED);
1773 }
1774 else if (rw_i93_get_next_blocks (p_i93->rw_offset) == NFC_STATUS_OK)
1775 {
1776 p_i93->sub_state = RW_I93_SUBSTATE_SEARCH_NDEF_TLV;
1777 }
1778 else
1779 {
1780 rw_i93_handle_error (NFC_STATUS_FAILED);
1781 }
1782 }
1783 break;
1784
1785 case RW_I93_SUBSTATE_CHECK_LOCK_STATUS:
1786
1787 if ( (p_i93->product_version == RW_I93_TAG_IT_HF_I_STD_CHIP_INLAY)
1788 ||(p_i93->product_version == RW_I93_TAG_IT_HF_I_PRO_CHIP_INLAY)
1789 ||((p_i93->uid[1] == I93_UID_IC_MFG_CODE_NXP) && (p_i93->ic_reference & I93_ICODE_IC_REF_MBREAD_MASK)) )
1790 {
1791 /* these doesn't support GetMultiBlockSecurityStatus */
1792
Evan Chu85b7e842013-01-18 11:02:50 -05001793 block = (p_i93->rw_offset / p_i93->block_size);
1794 last_block = (p_i93->ndef_tlv_last_offset / p_i93->block_size);
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001795
1796 if ((*p) & I93_BLOCK_LOCKED)
1797 {
Evan Chu85b7e842013-01-18 11:02:50 -05001798 if (block <= last_block)
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001799 {
1800 p_i93->intl_flags |= RW_I93_FLAG_READ_ONLY;
1801 }
1802 }
1803 else
1804 {
1805 /* if we need to check more user blocks */
Evan Chu85b7e842013-01-18 11:02:50 -05001806 if (block + 1 < p_i93->num_block)
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001807 {
1808 p_i93->rw_offset += p_i93->block_size;
1809
1810 /* read block to get lock status */
Evan Chu85b7e842013-01-18 11:02:50 -05001811 rw_i93_send_cmd_read_single_block ((UINT16)(p_i93->rw_offset / p_i93->block_size), TRUE);
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001812 break;
1813 }
1814 }
1815
1816 p_i93->max_ndef_length = p_i93->ndef_length
1817 /* add available bytes including the last block of NDEF TLV */
Evan Chu85b7e842013-01-18 11:02:50 -05001818 + (p_i93->block_size * (block - last_block) + 1)
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001819 - (p_i93->ndef_tlv_last_offset % p_i93->block_size)
1820 - 1;
1821 }
1822 else
1823 {
Evan Chu85b7e842013-01-18 11:02:50 -05001824 if (p_i93->rw_offset == 0)
1825 {
1826 p_i93->max_ndef_length = p_i93->ndef_length
1827 /* add available bytes in the last block of NDEF TLV */
1828 + p_i93->block_size
1829 - (p_i93->ndef_tlv_last_offset % p_i93->block_size)
1830 - 1;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001831
Evan Chu85b7e842013-01-18 11:02:50 -05001832 first_block = (p_i93->ndef_tlv_start_offset / p_i93->block_size);
1833 }
1834 else
1835 {
1836 first_block = 0;
1837 }
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001838
Evan Chu85b7e842013-01-18 11:02:50 -05001839 last_block = (p_i93->ndef_tlv_last_offset / p_i93->block_size);
1840 num_blocks = length;
1841
1842 for (block = first_block; block < num_blocks; block++)
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001843 {
1844 /* if any block of NDEF TLV is locked */
Evan Chu85b7e842013-01-18 11:02:50 -05001845 if ((block + p_i93->rw_offset) <= last_block)
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001846 {
Evan Chu85b7e842013-01-18 11:02:50 -05001847 if (*(p + block) & I93_BLOCK_LOCKED)
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001848 {
1849 p_i93->intl_flags |= RW_I93_FLAG_READ_ONLY;
1850 break;
1851 }
1852 }
1853 else
1854 {
Evan Chu85b7e842013-01-18 11:02:50 -05001855 if (*(p + block) & I93_BLOCK_LOCKED)
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001856 {
1857 /* no more consecutive unlocked block */
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001858 break;
1859 }
1860 else
1861 {
1862 /* add block size if not locked */
1863 p_i93->max_ndef_length += p_i93->block_size;
1864 }
1865 }
1866 }
Evan Chu85b7e842013-01-18 11:02:50 -05001867
1868 /* update next security of block to check */
1869 p_i93->rw_offset += num_blocks;
1870
1871 /* if need to check more */
1872 if (p_i93->num_block > p_i93->rw_offset)
1873 {
1874 if (rw_i93_get_next_block_sec () != NFC_STATUS_OK)
1875 {
1876 rw_i93_handle_error (NFC_STATUS_FAILED);
1877 }
1878 break;
1879 }
1880 }
1881
1882 /* check if need to adjust max NDEF length */
1883 if ( (p_i93->ndef_length < 0xFF)
1884 &&(p_i93->max_ndef_length >= 0xFF) )
1885 {
1886 /* 3 bytes length field must be used */
1887 p_i93->max_ndef_length -= 2;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001888 }
1889
1890 rw_data.ndef.status = NFC_STATUS_OK;
1891 rw_data.ndef.protocol = NFC_PROTOCOL_15693;
1892 rw_data.ndef.flags = 0;
1893 rw_data.ndef.flags |= RW_NDEF_FL_SUPPORTED;
1894 rw_data.ndef.flags |= RW_NDEF_FL_FORMATED;
1895 rw_data.ndef.flags |= RW_NDEF_FL_FORMATABLE;
1896 rw_data.ndef.cur_size = p_i93->ndef_length;
1897
1898 if (p_i93->intl_flags & RW_I93_FLAG_READ_ONLY)
1899 {
1900 rw_data.ndef.flags |= RW_NDEF_FL_READ_ONLY;
1901 rw_data.ndef.max_size = p_i93->ndef_length;
1902 }
1903 else
1904 {
1905 rw_data.ndef.flags |= RW_NDEF_FL_HARD_LOCKABLE;
1906 rw_data.ndef.max_size = p_i93->max_ndef_length;
1907 }
1908
1909 p_i93->state = RW_I93_STATE_IDLE;
1910 p_i93->sent_cmd = 0;
1911
1912 RW_TRACE_DEBUG3 ("NDEF cur_size(%d),max_size (%d), flags (0x%x)",
1913 rw_data.ndef.cur_size,
1914 rw_data.ndef.max_size,
1915 rw_data.ndef.flags);
1916
1917 (*(rw_cb.p_cback)) (RW_I93_NDEF_DETECT_EVT, &rw_data);
1918 break;
1919
1920 default:
1921 break;
1922 }
1923}
1924
1925/*******************************************************************************
1926**
1927** Function rw_i93_sm_read_ndef
1928**
1929** Description Process NDEF read procedure
1930**
1931** Returns void
1932**
1933*******************************************************************************/
1934void rw_i93_sm_read_ndef (BT_HDR *p_resp)
1935{
1936 UINT8 *p = (UINT8 *) (p_resp + 1) + p_resp->offset;
1937 UINT8 flags;
1938 UINT16 offset, length = p_resp->len;
1939 tRW_I93_CB *p_i93 = &rw_cb.tcb.i93;
1940 tRW_DATA rw_data;
1941
1942 RW_TRACE_DEBUG0 ("rw_i93_sm_read_ndef ()");
1943
1944 STREAM_TO_UINT8 (flags, p);
1945 length--;
1946
1947 if (flags & I93_FLAG_ERROR_DETECTED)
1948 {
1949 RW_TRACE_DEBUG1 ("Got error flags (0x%02x)", flags);
1950 rw_i93_handle_error (NFC_STATUS_FAILED);
1951 return;
1952 }
1953
1954 /* if this is the first block */
1955 if (p_i93->rw_length == 0)
1956 {
1957 /* get start of NDEF in the first block */
1958 offset = p_i93->ndef_tlv_start_offset % p_i93->block_size;
1959
1960 if (p_i93->ndef_length < 0xFF)
1961 {
1962 offset += 2;
1963 }
1964 else
1965 {
1966 offset += 4;
1967 }
1968
1969 /* adjust offset if read more blocks because the first block doesn't have NDEF */
1970 offset -= (p_i93->rw_offset - p_i93->ndef_tlv_start_offset);
1971 }
1972 else
1973 {
1974 offset = 0;
1975 }
1976
1977 /* if read enough data to skip type and length field for the beginning */
1978 if (offset < length)
1979 {
1980 offset++; /* flags */
1981 p_resp->offset += offset;
1982 p_resp->len -= offset;
1983
1984 rw_data.data.status = NFC_STATUS_OK;
1985 rw_data.data.p_data = p_resp;
1986
1987 p_i93->rw_length += p_resp->len;
1988 }
1989
1990 /* if read all of NDEF data */
1991 if (p_i93->rw_length >= p_i93->ndef_length)
1992 {
1993 /* remove extra btyes in the last block */
1994 p_resp->len -= (p_i93->rw_length - p_i93->ndef_length);
1995
1996 p_i93->state = RW_I93_STATE_IDLE;
1997 p_i93->sent_cmd = 0;
1998
1999 RW_TRACE_DEBUG2 ("NDEF read complete read (%d)/total (%d)",
2000 p_resp->len,
2001 p_i93->ndef_length);
2002
2003 (*(rw_cb.p_cback)) (RW_I93_NDEF_READ_CPLT_EVT, &rw_data);
2004 }
2005 else
2006 {
2007 RW_TRACE_DEBUG2 ("NDEF read segment read (%d)/total (%d)",
2008 p_resp->len,
2009 p_i93->ndef_length);
2010
2011 (*(rw_cb.p_cback)) (RW_I93_NDEF_READ_EVT, &rw_data);
2012
2013 /* this will make read data from next block */
2014 p_i93->rw_offset += length;
2015
2016 if (rw_i93_get_next_blocks (p_i93->rw_offset) != NFC_STATUS_OK)
2017 {
2018 rw_i93_handle_error (NFC_STATUS_FAILED);
2019 }
2020 }
2021}
2022
2023/*******************************************************************************
2024**
2025** Function rw_i93_sm_update_ndef
2026**
2027** Description Process NDEF update procedure
2028**
2029** 1. Set length field to zero
2030** 2. Write NDEF and Terminator TLV
2031** 3. Set length field to NDEF length
2032**
2033** Returns void
2034**
2035*******************************************************************************/
2036void rw_i93_sm_update_ndef (BT_HDR *p_resp)
2037{
2038 UINT8 *p = (UINT8 *) (p_resp + 1) + p_resp->offset;
Evan Chu85b7e842013-01-18 11:02:50 -05002039 UINT8 flags, xx, length_offset, buff[I93_MAX_BLOCK_LENGH];
2040 UINT16 length = p_resp->len, block_number;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002041 tRW_I93_CB *p_i93 = &rw_cb.tcb.i93;
2042 tRW_DATA rw_data;
2043
2044#if (BT_TRACE_VERBOSE == TRUE)
2045 RW_TRACE_DEBUG2 ("rw_i93_sm_update_ndef () sub_state:%s (0x%x)",
2046 rw_i93_get_sub_state_name (p_i93->sub_state), p_i93->sub_state);
2047#else
2048 RW_TRACE_DEBUG1 ("rw_i93_sm_update_ndef () sub_state:0x%x", p_i93->sub_state);
2049#endif
2050
2051 STREAM_TO_UINT8 (flags, p);
2052 length--;
2053
2054 if (flags & I93_FLAG_ERROR_DETECTED)
2055 {
2056 if ( ( (p_i93->product_version == RW_I93_TAG_IT_HF_I_PLUS_INLAY)
2057 ||(p_i93->product_version == RW_I93_TAG_IT_HF_I_PLUS_CHIP)
2058 ||(p_i93->product_version == RW_I93_TAG_IT_HF_I_STD_CHIP_INLAY)
2059 ||(p_i93->product_version == RW_I93_TAG_IT_HF_I_PRO_CHIP_INLAY) )
2060 &&
2061 (*p == I93_ERROR_CODE_BLOCK_FAIL_TO_WRITE) )
2062 {
2063 /* ignore error */
2064 }
2065 else
2066 {
2067 RW_TRACE_DEBUG1 ("Got error flags (0x%02x)", flags);
2068 rw_i93_handle_error (NFC_STATUS_FAILED);
2069 return;
2070 }
2071 }
2072
2073 switch (p_i93->sub_state)
2074 {
2075 case RW_I93_SUBSTATE_RESET_LEN:
2076
2077 /* get offset of length field */
2078 length_offset = (p_i93->ndef_tlv_start_offset + 1) % p_i93->block_size;
2079
2080 /* set length to zero */
2081 *(p + length_offset) = 0x00;
2082
2083 if (p_i93->ndef_length > 0)
2084 {
2085 /* if 3 bytes length field is needed */
2086 if (p_i93->ndef_length >= 0xFF)
2087 {
2088 xx = length_offset + 3;
2089 }
2090 else
2091 {
2092 xx = length_offset + 1;
2093 }
2094
2095 /* write the first part of NDEF in the same block */
2096 for ( ; xx < p_i93->block_size; xx++)
2097 {
2098 if (p_i93->rw_length < p_i93->ndef_length)
2099 {
2100 *(p + xx) = *(p_i93->p_update_data + p_i93->rw_length++);
2101 }
2102 else
2103 {
2104 *(p + xx) = I93_ICODE_TLV_TYPE_NULL;
2105 }
2106 }
2107 }
2108
Evan Chu85b7e842013-01-18 11:02:50 -05002109 block_number = (p_i93->ndef_tlv_start_offset + 1) / p_i93->block_size;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002110
2111 if (rw_i93_send_cmd_write_single_block (block_number, p) == NFC_STATUS_OK)
2112 {
2113 /* update next writing offset */
2114 p_i93->rw_offset = (block_number + 1) * p_i93->block_size;
2115 p_i93->sub_state = RW_I93_SUBSTATE_WRITE_NDEF;
2116 }
2117 else
2118 {
2119 rw_i93_handle_error (NFC_STATUS_FAILED);
2120 }
2121 break;
2122
2123 case RW_I93_SUBSTATE_WRITE_NDEF:
2124
2125 /* if it's not the end of tag memory */
2126 if (p_i93->rw_offset < p_i93->block_size * p_i93->num_block)
2127 {
Evan Chu85b7e842013-01-18 11:02:50 -05002128 block_number = p_i93->rw_offset / p_i93->block_size;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002129
2130 /* if we have more data to write */
2131 if (p_i93->rw_length < p_i93->ndef_length)
2132 {
2133 p = p_i93->p_update_data + p_i93->rw_length;
2134
2135 p_i93->rw_offset += p_i93->block_size;
2136 p_i93->rw_length += p_i93->block_size;
2137
2138 /* if this is the last block of NDEF TLV */
2139 if (p_i93->rw_length > p_i93->ndef_length)
2140 {
2141 /* length of NDEF TLV in the block */
2142 xx = (UINT8) (p_i93->block_size - (p_i93->rw_length - p_i93->ndef_length));
2143
2144 /* set NULL TLV in the unused part of block */
2145 memset (buff, I93_ICODE_TLV_TYPE_NULL, p_i93->block_size);
2146 memcpy (buff, p, xx);
2147 p = buff;
2148
2149 /* if it's the end of tag memory */
2150 if ( (p_i93->rw_offset >= p_i93->block_size * p_i93->num_block)
2151 &&(xx < p_i93->block_size) )
2152 {
2153 buff[xx] = I93_ICODE_TLV_TYPE_TERM;
2154 }
2155
2156 p_i93->ndef_tlv_last_offset = p_i93->rw_offset - p_i93->block_size + xx - 1;
2157 }
2158
2159 if (rw_i93_send_cmd_write_single_block (block_number, p) != NFC_STATUS_OK)
2160 {
2161 rw_i93_handle_error (NFC_STATUS_FAILED);
2162 }
2163 }
2164 else
2165 {
2166 /* if this is the very next block of NDEF TLV */
2167 if (block_number == (p_i93->ndef_tlv_last_offset / p_i93->block_size) + 1)
2168 {
2169 p_i93->rw_offset += p_i93->block_size;
2170
2171 /* write Terminator TLV and NULL TLV */
2172 memset (buff, I93_ICODE_TLV_TYPE_NULL, p_i93->block_size);
2173 buff[0] = I93_ICODE_TLV_TYPE_TERM;
2174 p = buff;
2175
2176 if (rw_i93_send_cmd_write_single_block (block_number, p) != NFC_STATUS_OK)
2177 {
2178 rw_i93_handle_error (NFC_STATUS_FAILED);
2179 }
2180 }
2181 else
2182 {
2183 /* finished writing NDEF and Terminator TLV */
2184 /* read length field to update length */
Evan Chu85b7e842013-01-18 11:02:50 -05002185 block_number = (p_i93->ndef_tlv_start_offset + 1) / p_i93->block_size;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002186
2187 if (rw_i93_send_cmd_read_single_block (block_number, FALSE) == NFC_STATUS_OK)
2188 {
2189 /* set offset to length field */
2190 p_i93->rw_offset = p_i93->ndef_tlv_start_offset + 1;
2191
2192 /* get size of length field */
2193 if (p_i93->ndef_length >= 0xFF)
2194 {
2195 p_i93->rw_length = 3;
2196 }
2197 else if (p_i93->ndef_length > 0)
2198 {
2199 p_i93->rw_length = 1;
2200 }
2201 else
2202 {
2203 p_i93->rw_length = 0;
2204 }
2205
2206 p_i93->sub_state = RW_I93_SUBSTATE_UPDATE_LEN;
2207 }
2208 else
2209 {
2210 rw_i93_handle_error (NFC_STATUS_FAILED);
2211 }
2212 }
2213 }
2214 }
2215 else
2216 {
2217 /* if we have no more data to write */
2218 if (p_i93->rw_length >= p_i93->ndef_length)
2219 {
2220 /* finished writing NDEF and Terminator TLV */
2221 /* read length field to update length */
Evan Chu85b7e842013-01-18 11:02:50 -05002222 block_number = (p_i93->ndef_tlv_start_offset + 1) / p_i93->block_size;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002223
2224 if (rw_i93_send_cmd_read_single_block (block_number, FALSE) == NFC_STATUS_OK)
2225 {
2226 /* set offset to length field */
2227 p_i93->rw_offset = p_i93->ndef_tlv_start_offset + 1;
2228
2229 /* get size of length field */
2230 if (p_i93->ndef_length >= 0xFF)
2231 {
2232 p_i93->rw_length = 3;
2233 }
2234 else if (p_i93->ndef_length > 0)
2235 {
2236 p_i93->rw_length = 1;
2237 }
2238 else
2239 {
2240 p_i93->rw_length = 0;
2241 }
2242
2243 p_i93->sub_state = RW_I93_SUBSTATE_UPDATE_LEN;
2244 break;
2245 }
2246 }
2247 rw_i93_handle_error (NFC_STATUS_FAILED);
2248 }
2249 break;
2250
2251 case RW_I93_SUBSTATE_UPDATE_LEN:
2252
2253 /* if we have more length field to write */
2254 if (p_i93->rw_length > 0)
2255 {
2256 /* if we got ack for writing, read next block to update rest of length field */
2257 if (length == 0)
2258 {
Evan Chu85b7e842013-01-18 11:02:50 -05002259 block_number = p_i93->rw_offset / p_i93->block_size;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002260
2261 if (rw_i93_send_cmd_read_single_block (block_number, FALSE) != NFC_STATUS_OK)
2262 {
2263 rw_i93_handle_error (NFC_STATUS_FAILED);
2264 }
2265 }
2266 else
2267 {
2268 length_offset = p_i93->rw_offset % p_i93->block_size;
2269
2270 /* update length field within the read block */
2271 for (xx = length_offset; xx < p_i93->block_size; xx++)
2272 {
2273 if (p_i93->rw_length == 3)
2274 *(p + xx) = 0xFF;
2275 else if (p_i93->rw_length == 2)
2276 *(p + xx) = (UINT8) ((p_i93->ndef_length >> 8) & 0xFF);
2277 else if (p_i93->rw_length == 1)
2278 *(p + xx) = (UINT8) (p_i93->ndef_length & 0xFF);
2279
2280 p_i93->rw_length--;
2281 if (p_i93->rw_length == 0)
2282 break;
2283 }
2284
Evan Chu85b7e842013-01-18 11:02:50 -05002285 block_number = (p_i93->rw_offset / p_i93->block_size);
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002286
2287 if (rw_i93_send_cmd_write_single_block (block_number, p) == NFC_STATUS_OK)
2288 {
2289 /* set offset to the beginning of next block */
2290 p_i93->rw_offset += p_i93->block_size - (p_i93->rw_offset % p_i93->block_size);
2291 }
2292 else
2293 {
2294 rw_i93_handle_error (NFC_STATUS_FAILED);
2295 }
2296 }
2297 }
2298 else
2299 {
2300 RW_TRACE_DEBUG3 ("NDEF update complete, %d bytes, (%d-%d)",
2301 p_i93->ndef_length,
2302 p_i93->ndef_tlv_start_offset,
2303 p_i93->ndef_tlv_last_offset);
2304
2305 p_i93->state = RW_I93_STATE_IDLE;
2306 p_i93->sent_cmd = 0;
2307 p_i93->p_update_data = NULL;
2308
2309 rw_data.status = NFC_STATUS_OK;
2310 (*(rw_cb.p_cback)) (RW_I93_NDEF_UPDATE_CPLT_EVT, &rw_data);
2311 }
2312 break;
2313
2314 default:
2315 break;
2316 }
2317}
2318
2319/*******************************************************************************
2320**
2321** Function rw_i93_sm_format
2322**
2323** Description Process format procedure
2324**
2325** 1. Get UID
2326** 2. Get sys info for memory size (reset AFI/DSFID)
2327** 3. Get block status to get read-only status
2328** 4. Write CC and empty NDEF
2329**
2330** Returns void
2331**
2332*******************************************************************************/
2333void rw_i93_sm_format (BT_HDR *p_resp)
2334{
2335 UINT8 *p = (UINT8 *) (p_resp + 1) + p_resp->offset, *p_uid;
Evan Chu85b7e842013-01-18 11:02:50 -05002336 UINT8 flags;
2337 UINT16 length = p_resp->len, xx, block_number;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002338 tRW_I93_CB *p_i93 = &rw_cb.tcb.i93;
2339 tRW_DATA rw_data;
2340 tNFC_STATUS status = NFC_STATUS_FAILED;
2341
2342#if (BT_TRACE_VERBOSE == TRUE)
2343 RW_TRACE_DEBUG2 ("rw_i93_sm_format () sub_state:%s (0x%x)",
2344 rw_i93_get_sub_state_name (p_i93->sub_state), p_i93->sub_state);
2345#else
2346 RW_TRACE_DEBUG1 ("rw_i93_sm_format () sub_state:0x%x", p_i93->sub_state);
2347#endif
2348
2349 STREAM_TO_UINT8 (flags, p);
2350 length--;
2351
2352 if (flags & I93_FLAG_ERROR_DETECTED)
2353 {
2354 if ( ( (p_i93->product_version == RW_I93_TAG_IT_HF_I_PLUS_INLAY)
2355 ||(p_i93->product_version == RW_I93_TAG_IT_HF_I_PLUS_CHIP)
2356 ||(p_i93->product_version == RW_I93_TAG_IT_HF_I_STD_CHIP_INLAY)
2357 ||(p_i93->product_version == RW_I93_TAG_IT_HF_I_PRO_CHIP_INLAY) )
2358 &&
2359 (*p == I93_ERROR_CODE_BLOCK_FAIL_TO_WRITE) )
2360 {
2361 /* ignore error */
2362 }
Evan Chu85b7e842013-01-18 11:02:50 -05002363 else if ((length) && (rw_i93_check_sys_info_prot_ext(*p)))
2364 {
2365 /* getting system info with protocol extension flag */
2366 /* This STM tag supports more than 2040 bytes */
2367 p_i93->intl_flags |= RW_I93_FLAG_16BIT_NUM_BLOCK;
2368 return;
2369 }
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002370 else
2371 {
2372 RW_TRACE_DEBUG1 ("Got error flags (0x%02x)", flags);
2373 rw_i93_handle_error (NFC_STATUS_FAILED);
2374 return;
2375 }
2376 }
2377
2378 switch (p_i93->sub_state)
2379 {
2380 case RW_I93_SUBSTATE_WAIT_UID:
2381
2382 p++; /* skip DSFID */
2383 p_uid = p_i93->uid;
2384 STREAM_TO_ARRAY8 (p_uid, p); /* store UID */
2385
2386 /* get system information to get memory size */
Evan Chu85b7e842013-01-18 11:02:50 -05002387 if (rw_i93_send_cmd_get_sys_info (NULL, I93_FLAG_PROT_EXT_NO) == NFC_STATUS_OK)
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002388 {
2389 p_i93->sub_state = RW_I93_SUBSTATE_WAIT_SYS_INFO;
2390 }
2391 else
2392 {
2393 rw_i93_handle_error (NFC_STATUS_FAILED);
2394 }
2395 break;
2396
2397 case RW_I93_SUBSTATE_WAIT_SYS_INFO:
2398
Evan Chu85b7e842013-01-18 11:02:50 -05002399 p_i93->block_size = 0;
2400 p_i93->num_block = 0;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002401
Evan Chu85b7e842013-01-18 11:02:50 -05002402 if (!rw_i93_process_sys_info (p))
2403 {
2404 /* retrying with protocol extension flag */
2405 break;
2406 }
2407
2408 if (p_i93->info_flags & I93_INFO_FLAG_DSFID)
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002409 {
2410 /* DSFID, if any DSFID then reset */
Evan Chu85b7e842013-01-18 11:02:50 -05002411 if (p_i93->dsfid != I93_DFS_UNSUPPORTED)
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002412 {
2413 p_i93->intl_flags |= RW_I93_FLAG_RESET_DSFID;
2414 }
2415 }
Evan Chu85b7e842013-01-18 11:02:50 -05002416 if (p_i93->info_flags & I93_INFO_FLAG_AFI)
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002417 {
2418 /* AFI, reset to 0 */
Evan Chu85b7e842013-01-18 11:02:50 -05002419 if (p_i93->afi != 0x00)
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002420 {
2421 p_i93->intl_flags |= RW_I93_FLAG_RESET_AFI;
2422 }
2423 }
Evan Chu85b7e842013-01-18 11:02:50 -05002424
2425 if ((p_i93->block_size == 0)||(p_i93->num_block == 0))
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002426 {
Evan Chu85b7e842013-01-18 11:02:50 -05002427 RW_TRACE_DEBUG0 ("Unable to get tag memory size");
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002428 rw_i93_handle_error (status);
2429 }
2430 else if (p_i93->intl_flags & RW_I93_FLAG_RESET_DSFID)
2431 {
2432 if (rw_i93_send_cmd_write_dsfid (I93_DFS_UNSUPPORTED) == NFC_STATUS_OK)
2433 {
2434 p_i93->sub_state = RW_I93_SUBSTATE_WAIT_RESET_DSFID_AFI;
2435 }
2436 else
2437 {
2438 rw_i93_handle_error (NFC_STATUS_FAILED);
2439 }
2440 }
2441 else if (p_i93->intl_flags & RW_I93_FLAG_RESET_AFI)
2442 {
2443 if (rw_i93_send_cmd_write_afi (0x00) == NFC_STATUS_OK)
2444 {
2445 p_i93->sub_state = RW_I93_SUBSTATE_WAIT_RESET_DSFID_AFI;
2446 }
2447 else
2448 {
2449 rw_i93_handle_error (NFC_STATUS_FAILED);
2450 }
2451 }
2452 else
2453 {
2454 /* get lock status to see if read-only */
2455 if ((p_i93->uid[1] == I93_UID_IC_MFG_CODE_NXP) && (p_i93->ic_reference & I93_ICODE_IC_REF_MBREAD_MASK))
2456 {
2457 /* these doesn't support GetMultiBlockSecurityStatus */
2458
2459 rw_cb.tcb.i93.rw_offset = 0;
2460
2461 /* read blocks with option flag to get block security status */
Evan Chu85b7e842013-01-18 11:02:50 -05002462 if (rw_i93_send_cmd_read_single_block (0x0000, TRUE) == NFC_STATUS_OK)
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002463 {
2464 p_i93->sub_state = RW_I93_SUBSTATE_CHECK_READ_ONLY;
2465 }
2466 else
2467 {
2468 rw_i93_handle_error (NFC_STATUS_FAILED);
2469 }
2470 }
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002471 else
2472 {
Evan Chu85b7e842013-01-18 11:02:50 -05002473 /* block offset for read-only check */
2474 p_i93->rw_offset = 0;
2475
2476 if (rw_i93_get_next_block_sec () == NFC_STATUS_OK)
2477 {
2478 p_i93->sub_state = RW_I93_SUBSTATE_CHECK_READ_ONLY;
2479 }
2480 else
2481 {
2482 rw_i93_handle_error (NFC_STATUS_FAILED);
2483 }
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002484 }
2485 }
2486
2487 break;
2488
2489 case RW_I93_SUBSTATE_WAIT_RESET_DSFID_AFI:
2490
2491 if (p_i93->sent_cmd == I93_CMD_WRITE_DSFID)
2492 {
2493 p_i93->intl_flags &= ~RW_I93_FLAG_RESET_DSFID;
2494 }
2495 else if (p_i93->sent_cmd == I93_CMD_WRITE_AFI)
2496 {
2497 p_i93->intl_flags &= ~RW_I93_FLAG_RESET_AFI;
2498 }
2499
2500 if (p_i93->intl_flags & RW_I93_FLAG_RESET_DSFID)
2501 {
2502 if (rw_i93_send_cmd_write_dsfid (I93_DFS_UNSUPPORTED) == NFC_STATUS_OK)
2503 {
2504 p_i93->sub_state = RW_I93_SUBSTATE_WAIT_RESET_DSFID_AFI;
2505 }
2506 else
2507 {
2508 rw_i93_handle_error (NFC_STATUS_FAILED);
2509 }
2510 }
2511 else if (p_i93->intl_flags & RW_I93_FLAG_RESET_AFI)
2512 {
2513 if (rw_i93_send_cmd_write_afi (0x00) == NFC_STATUS_OK)
2514 {
2515 p_i93->sub_state = RW_I93_SUBSTATE_WAIT_RESET_DSFID_AFI;
2516 }
2517 else
2518 {
2519 rw_i93_handle_error (NFC_STATUS_FAILED);
2520 }
2521 }
2522 else
2523 {
2524 /* get lock status to see if read-only */
2525 if ((p_i93->uid[1] == I93_UID_IC_MFG_CODE_NXP) && (p_i93->ic_reference & I93_ICODE_IC_REF_MBREAD_MASK))
2526 {
2527 /* these doesn't support GetMultiBlockSecurityStatus */
2528
2529 rw_cb.tcb.i93.rw_offset = 0;
2530
2531 /* read blocks with option flag to get block security status */
Evan Chu85b7e842013-01-18 11:02:50 -05002532 if (rw_i93_send_cmd_read_single_block (0x0000, TRUE) == NFC_STATUS_OK)
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002533 {
2534 p_i93->sub_state = RW_I93_SUBSTATE_CHECK_READ_ONLY;
2535 }
2536 else
2537 {
2538 rw_i93_handle_error (NFC_STATUS_FAILED);
2539 }
2540 }
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002541 else
2542 {
Evan Chu85b7e842013-01-18 11:02:50 -05002543 /* block offset for read-only check */
2544 p_i93->rw_offset = 0;
2545
2546 if (rw_i93_get_next_block_sec () == NFC_STATUS_OK)
2547 {
2548 p_i93->sub_state = RW_I93_SUBSTATE_CHECK_READ_ONLY;
2549 }
2550 else
2551 {
2552 rw_i93_handle_error (NFC_STATUS_FAILED);
2553 }
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002554 }
2555 }
2556 break;
2557
2558 case RW_I93_SUBSTATE_CHECK_READ_ONLY:
2559
2560 if ( (p_i93->product_version == RW_I93_TAG_IT_HF_I_STD_CHIP_INLAY)
2561 ||(p_i93->product_version == RW_I93_TAG_IT_HF_I_PRO_CHIP_INLAY)
2562 ||((p_i93->uid[1] == I93_UID_IC_MFG_CODE_NXP) && (p_i93->ic_reference & I93_ICODE_IC_REF_MBREAD_MASK)) )
2563 {
2564 if ((*p) & I93_BLOCK_LOCKED)
2565 {
2566 rw_i93_handle_error (NFC_STATUS_FAILED);
2567 break;
2568 }
2569
2570 /* if we checked all of user blocks */
2571 if ((p_i93->rw_offset / p_i93->block_size) + 1 == p_i93->num_block)
2572 {
2573 if ( (p_i93->product_version == RW_I93_TAG_IT_HF_I_STD_CHIP_INLAY)
2574 ||(p_i93->product_version == RW_I93_TAG_IT_HF_I_PRO_CHIP_INLAY) )
2575 {
2576 /* read the block which has AFI */
2577 p_i93->rw_offset = I93_TAG_IT_HF_I_STD_PRO_CHIP_INLAY_AFI_LOCATION;
Evan Chu85b7e842013-01-18 11:02:50 -05002578 rw_i93_send_cmd_read_single_block ((UINT16)(p_i93->rw_offset/p_i93->block_size), TRUE);
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002579 break;
2580 }
2581 }
2582 else if (p_i93->rw_offset == I93_TAG_IT_HF_I_STD_PRO_CHIP_INLAY_AFI_LOCATION)
2583 {
2584 /* no block is locked */
2585 }
2586 else
2587 {
2588 p_i93->rw_offset += p_i93->block_size;
Evan Chu85b7e842013-01-18 11:02:50 -05002589 rw_i93_send_cmd_read_single_block ((UINT16)(p_i93->rw_offset/p_i93->block_size), TRUE);
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002590 break;
2591 }
2592 }
2593 else
2594 {
2595 /* if any block is locked, we cannot format it */
Evan Chu85b7e842013-01-18 11:02:50 -05002596 for (xx = 0; xx < length; xx++)
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002597 {
Evan Chu85b7e842013-01-18 11:02:50 -05002598 if (*(p + xx) & I93_BLOCK_LOCKED)
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002599 {
2600 rw_i93_handle_error (NFC_STATUS_FAILED);
2601 break;
2602 }
2603 }
Evan Chu85b7e842013-01-18 11:02:50 -05002604
2605 /* update block offset for read-only check */
2606 p_i93->rw_offset += length;
2607
2608 /* if need to get more lock status of blocks */
2609 if (p_i93->num_block > p_i93->rw_offset)
2610 {
2611 if (rw_i93_get_next_block_sec () != NFC_STATUS_OK)
2612 {
2613 rw_i93_handle_error (NFC_STATUS_FAILED);
2614 }
2615 break;
2616 }
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002617 }
2618
2619 /* get buffer to store CC, zero length NDEF TLV and Terminator TLV */
2620 p_i93->p_update_data = (UINT8*) GKI_getbuf (RW_I93_FORMAT_DATA_LEN);
2621
2622 if (!p_i93->p_update_data)
2623 {
2624 RW_TRACE_ERROR0 ("rw_i93_sm_format (): Cannot allocate buffer");
2625 rw_i93_handle_error (NFC_STATUS_FAILED);
2626 break;
2627 }
2628
2629 p = p_i93->p_update_data;
2630
2631 /* Capability Container */
2632 *(p++) = I93_ICODE_CC_MAGIC_NUMER; /* magic number */
2633 *(p++) = 0x40; /* version 1.0, read/write */
Evan Chu85b7e842013-01-18 11:02:50 -05002634
2635 /* if memory size is less than 2048 bytes */
2636 if (((p_i93->num_block * p_i93->block_size) / 8) < 0x100)
2637 *(p++) = (UINT8) ((p_i93->num_block * p_i93->block_size) / 8); /* memory size */
2638 else
2639 *(p++) = 0xFF;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002640
2641 if ( (p_i93->product_version == RW_I93_ICODE_SLI)
2642 ||(p_i93->product_version == RW_I93_ICODE_SLI_S)
2643 ||(p_i93->product_version == RW_I93_ICODE_SLI_L) )
2644 {
2645 if (p_i93->ic_reference & I93_ICODE_IC_REF_MBREAD_MASK)
2646 *(p++) = I93_ICODE_CC_IPREAD_MASK; /* IPREAD */
2647 else
2648 *(p++) = I93_ICODE_CC_MBREAD_MASK; /* MBREAD, read multi block command supported */
2649 }
2650 else if ( (p_i93->product_version == RW_I93_TAG_IT_HF_I_PLUS_INLAY)
2651 ||(p_i93->product_version == RW_I93_TAG_IT_HF_I_PLUS_CHIP) )
2652 {
2653 *(p++) = I93_ICODE_CC_MBREAD_MASK; /* MBREAD, read multi block command supported */
2654 }
2655 else if ( (p_i93->product_version == RW_I93_TAG_IT_HF_I_STD_CHIP_INLAY)
2656 ||(p_i93->product_version == RW_I93_TAG_IT_HF_I_PRO_CHIP_INLAY) )
2657 {
2658 *(p++) = 0;
2659 }
2660 else
2661 {
Evan Chu85b7e842013-01-18 11:02:50 -05002662 /* STM except LRIS2K, Broadcom supports read multi block command */
2663
2664 /* if memory size is more than 2040 bytes (which is not LRIS2K) */
2665 if (((p_i93->num_block * p_i93->block_size) / 8) > 0xFF)
2666 *(p++) = (I93_ICODE_CC_MBREAD_MASK | I93_STM_CC_OVERFLOW_MASK);
2667 else if (p_i93->product_version == RW_I93_STM_LRIS2K)
2668 *(p++) = 0x00;
2669 else
2670 *(p++) = I93_ICODE_CC_MBREAD_MASK;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002671 }
2672
2673 /* zero length NDEF and Terminator TLV */
2674 *(p++) = I93_ICODE_TLV_TYPE_NDEF;
2675 *(p++) = 0x00;
2676 *(p++) = I93_ICODE_TLV_TYPE_TERM;
2677 *(p++) = I93_ICODE_TLV_TYPE_NULL;
2678
2679 /* start from block 0 */
2680 p_i93->rw_offset = 0;
2681
2682 if (rw_i93_send_cmd_write_single_block (0, p_i93->p_update_data) == NFC_STATUS_OK)
2683 {
2684 p_i93->sub_state = RW_I93_SUBSTATE_WRITE_CC_NDEF_TLV;
2685 p_i93->rw_offset += p_i93->block_size;
2686 }
2687 else
2688 {
2689 rw_i93_handle_error (NFC_STATUS_FAILED);
2690 }
2691 break;
2692
2693 case RW_I93_SUBSTATE_WRITE_CC_NDEF_TLV:
2694
2695 /* if we have more data to write */
2696 if (p_i93->rw_offset < RW_I93_FORMAT_DATA_LEN)
2697 {
Evan Chu85b7e842013-01-18 11:02:50 -05002698 block_number = (p_i93->rw_offset / p_i93->block_size);
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002699 p = p_i93->p_update_data + p_i93->rw_offset;
2700
2701 if (rw_i93_send_cmd_write_single_block (block_number, p) == NFC_STATUS_OK)
2702 {
2703 p_i93->sub_state = RW_I93_SUBSTATE_WRITE_CC_NDEF_TLV;
2704 p_i93->rw_offset += p_i93->block_size;
2705 }
2706 else
2707 {
2708 rw_i93_handle_error (NFC_STATUS_FAILED);
2709 }
2710 }
2711 else
2712 {
2713 GKI_freebuf (p_i93->p_update_data);
2714 p_i93->p_update_data = NULL;
2715
2716 p_i93->state = RW_I93_STATE_IDLE;
2717 p_i93->sent_cmd = 0;
2718
2719 rw_data.status = NFC_STATUS_OK;
2720 (*(rw_cb.p_cback)) (RW_I93_FORMAT_CPLT_EVT, &rw_data);
2721 }
2722 break;
2723
2724 default:
2725 break;
2726 }
2727}
2728
2729/*******************************************************************************
2730**
2731** Function rw_i93_sm_set_read_only
2732**
2733** Description Process read-only procedure
2734**
2735** 1. Update CC as read-only
2736** 2. Lock all block of NDEF TLV
2737** 3. Lock block of CC
2738**
2739** Returns void
2740**
2741*******************************************************************************/
2742void rw_i93_sm_set_read_only (BT_HDR *p_resp)
2743{
2744 UINT8 *p = (UINT8 *) (p_resp + 1) + p_resp->offset;
2745 UINT8 flags, block_number;
2746 UINT16 length = p_resp->len;
2747 tRW_I93_CB *p_i93 = &rw_cb.tcb.i93;
2748 tRW_DATA rw_data;
2749
2750#if (BT_TRACE_VERBOSE == TRUE)
2751 RW_TRACE_DEBUG2 ("rw_i93_sm_set_read_only () sub_state:%s (0x%x)",
2752 rw_i93_get_sub_state_name (p_i93->sub_state), p_i93->sub_state);
2753#else
2754 RW_TRACE_DEBUG1 ("rw_i93_sm_set_read_only () sub_state:0x%x", p_i93->sub_state);
2755#endif
2756
2757 STREAM_TO_UINT8 (flags, p);
2758 length--;
2759
2760 if (flags & I93_FLAG_ERROR_DETECTED)
2761 {
2762 if ( ( (p_i93->product_version == RW_I93_TAG_IT_HF_I_PLUS_INLAY)
2763 ||(p_i93->product_version == RW_I93_TAG_IT_HF_I_PLUS_CHIP)
2764 ||(p_i93->product_version == RW_I93_TAG_IT_HF_I_STD_CHIP_INLAY)
2765 ||(p_i93->product_version == RW_I93_TAG_IT_HF_I_PRO_CHIP_INLAY) )
2766 &&
2767 (*p == I93_ERROR_CODE_BLOCK_FAIL_TO_WRITE) )
2768 {
2769 /* ignore error */
2770 }
2771 else
2772 {
2773 RW_TRACE_DEBUG1 ("Got error flags (0x%02x)", flags);
2774 rw_i93_handle_error (NFC_STATUS_FAILED);
2775 return;
2776 }
2777 }
2778
2779 switch (p_i93->sub_state)
2780 {
2781 case RW_I93_SUBSTATE_WAIT_CC:
2782
2783 /* mark CC as read-only */
2784 *(p+1) |= I93_ICODE_CC_READ_ONLY;
2785
2786 if (rw_i93_send_cmd_write_single_block (0, p) == NFC_STATUS_OK)
2787 {
2788 p_i93->sub_state = RW_I93_SUBSTATE_WAIT_UPDATE_CC;
2789 }
2790 else
2791 {
2792 rw_i93_handle_error (NFC_STATUS_FAILED);
2793 }
2794 break;
2795
2796 case RW_I93_SUBSTATE_WAIT_UPDATE_CC:
2797
2798 /* successfully write CC then lock all blocks of NDEF TLV */
2799 p_i93->rw_offset = p_i93->ndef_tlv_start_offset;
2800 block_number = (UINT8) (p_i93->rw_offset / p_i93->block_size);
2801
2802 if (rw_i93_send_cmd_lock_block (block_number) == NFC_STATUS_OK)
2803 {
2804 p_i93->rw_offset += p_i93->block_size;
2805 p_i93->sub_state = RW_I93_SUBSTATE_LOCK_NDEF_TLV;
2806 }
2807 else
2808 {
2809 rw_i93_handle_error (NFC_STATUS_FAILED);
2810 }
2811 break;
2812
2813 case RW_I93_SUBSTATE_LOCK_NDEF_TLV:
2814
2815 /* if we need to lock more blocks */
2816 if (p_i93->rw_offset < p_i93->ndef_tlv_last_offset)
2817 {
2818 /* get the next block of NDEF TLV */
2819 block_number = (UINT8) (p_i93->rw_offset / p_i93->block_size);
2820
2821 if (rw_i93_send_cmd_lock_block (block_number) == NFC_STATUS_OK)
2822 {
2823 p_i93->rw_offset += p_i93->block_size;
2824 }
2825 else
2826 {
2827 rw_i93_handle_error (NFC_STATUS_FAILED);
2828 }
2829 }
2830 /* if the first block of NDEF TLV is different from block of CC */
2831 else if (p_i93->ndef_tlv_start_offset / p_i93->block_size != 0)
2832 {
2833 /* lock block of CC */
2834 if (rw_i93_send_cmd_lock_block (0) == NFC_STATUS_OK)
2835 {
2836 p_i93->sub_state = RW_I93_SUBSTATE_WAIT_LOCK_CC;
2837 }
2838 else
2839 {
2840 rw_i93_handle_error (NFC_STATUS_FAILED);
2841 }
2842 }
2843 else
2844 {
2845 p_i93->intl_flags |= RW_I93_FLAG_READ_ONLY;
2846 p_i93->state = RW_I93_STATE_IDLE;
2847 p_i93->sent_cmd = 0;
2848
2849 rw_data.status = NFC_STATUS_OK;
2850 (*(rw_cb.p_cback)) (RW_I93_SET_TAG_RO_EVT, &rw_data);
2851 }
2852 break;
2853
2854 case RW_I93_SUBSTATE_WAIT_LOCK_CC:
2855
2856 p_i93->intl_flags |= RW_I93_FLAG_READ_ONLY;
2857 p_i93->state = RW_I93_STATE_IDLE;
2858 p_i93->sent_cmd = 0;
2859
2860 rw_data.status = NFC_STATUS_OK;
2861 (*(rw_cb.p_cback)) (RW_I93_SET_TAG_RO_EVT, &rw_data);
2862 break;
2863
2864 default:
2865 break;
2866 }
2867}
2868
2869/*******************************************************************************
2870**
2871** Function rw_i93_handle_error
2872**
2873** Description notify error to application and clean up
2874**
2875** Returns none
2876**
2877*******************************************************************************/
2878void rw_i93_handle_error (tNFC_STATUS status)
2879{
2880 tRW_I93_CB *p_i93 = &rw_cb.tcb.i93;
2881 tRW_DATA rw_data;
2882 tRW_EVENT event;
2883
2884 RW_TRACE_DEBUG2 ("rw_i93_handle_error (): status:0x%02X, state:0x%X",
2885 status, p_i93->state);
2886
2887 nfc_stop_quick_timer (&p_i93->timer);
2888
2889 if (rw_cb.p_cback)
2890 {
2891 rw_data.status = status;
2892
2893 switch (p_i93->state)
2894 {
2895 case RW_I93_STATE_IDLE: /* in case of RawFrame */
2896 event = RW_I93_INTF_ERROR_EVT;
2897 break;
2898
2899 case RW_I93_STATE_BUSY:
2900 if (p_i93->sent_cmd == I93_CMD_STAY_QUIET)
2901 {
2902 /* There is no response to Stay Quiet command */
2903 rw_data.i93_cmd_cmpl.status = NFC_STATUS_OK;
2904 rw_data.i93_cmd_cmpl.command = I93_CMD_STAY_QUIET;
2905 rw_data.i93_cmd_cmpl.error_code = 0;
2906 event = RW_I93_CMD_CMPL_EVT;
2907 }
2908 else
2909 {
2910 event = RW_I93_INTF_ERROR_EVT;
2911 }
2912 break;
2913
2914 case RW_I93_STATE_DETECT_NDEF:
2915 rw_data.ndef.protocol = NFC_PROTOCOL_15693;
2916 rw_data.ndef.cur_size = 0;
2917 rw_data.ndef.max_size = 0;
2918 rw_data.ndef.flags = 0;
2919 rw_data.ndef.flags |= RW_NDEF_FL_FORMATABLE;
2920 rw_data.ndef.flags |= RW_NDEF_FL_UNKNOWN;
2921 event = RW_I93_NDEF_DETECT_EVT;
2922 break;
2923
2924 case RW_I93_STATE_READ_NDEF:
2925 event = RW_I93_NDEF_READ_FAIL_EVT;
2926 break;
2927
2928 case RW_I93_STATE_UPDATE_NDEF:
2929 p_i93->p_update_data = NULL;
2930 event = RW_I93_NDEF_UPDATE_FAIL_EVT;
2931 break;
2932
2933 case RW_I93_STATE_FORMAT:
2934 if (p_i93->p_update_data)
2935 {
2936 GKI_freebuf (p_i93->p_update_data);
2937 p_i93->p_update_data = NULL;
2938 }
2939 event = RW_I93_FORMAT_CPLT_EVT;
2940 break;
2941
2942 case RW_I93_STATE_SET_READ_ONLY:
2943 event = RW_I93_SET_TAG_RO_EVT;
2944 break;
2945
2946 case RW_I93_STATE_PRESENCE_CHECK:
2947 event = RW_I93_PRESENCE_CHECK_EVT;
2948 break;
2949
2950 default:
2951 event = RW_I93_MAX_EVT;
2952 break;
2953 }
2954
2955 p_i93->state = RW_I93_STATE_IDLE;
2956 p_i93->sent_cmd = 0;
2957
2958 if (event != RW_I93_MAX_EVT)
2959 {
2960 (*(rw_cb.p_cback)) (event, &rw_data);
2961 }
2962 }
2963 else
2964 {
2965 p_i93->state = RW_I93_STATE_IDLE;
2966 }
2967}
2968
2969/*******************************************************************************
2970**
2971** Function rw_i93_process_timeout
2972**
2973** Description process timeout event
2974**
2975** Returns none
2976**
2977*******************************************************************************/
2978void rw_i93_process_timeout (TIMER_LIST_ENT *p_tle)
2979{
Evan Chu85b7e842013-01-18 11:02:50 -05002980 BT_HDR *p_buf;
2981
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002982 RW_TRACE_DEBUG1 ("rw_i93_process_timeout () event=%d", p_tle->event);
2983
2984 if (p_tle->event == NFC_TTYPE_RW_I93_RESPONSE)
2985 {
Evan Chu85b7e842013-01-18 11:02:50 -05002986 if ( (rw_cb.tcb.i93.retry_count < RW_MAX_RETRIES)
2987 &&(rw_cb.tcb.i93.p_retry_cmd)
2988 &&(rw_cb.tcb.i93.sent_cmd != I93_CMD_STAY_QUIET))
2989 {
2990 rw_cb.tcb.i93.retry_count++;
2991 RW_TRACE_ERROR1 ("rw_i93_process_timeout (): retry_count = %d", rw_cb.tcb.i93.retry_count);
2992
2993 p_buf = rw_cb.tcb.i93.p_retry_cmd;
2994 rw_cb.tcb.i93.p_retry_cmd = NULL;
2995 rw_i93_send_to_lower (p_buf);
2996 }
2997 else
2998 {
2999 if (rw_cb.tcb.i93.p_retry_cmd)
3000 {
3001 GKI_freebuf (rw_cb.tcb.i93.p_retry_cmd);
3002 rw_cb.tcb.i93.p_retry_cmd = NULL;
3003 rw_cb.tcb.i93.retry_count = 0;
3004 }
3005 rw_i93_handle_error (NFC_STATUS_TIMEOUT);
3006 }
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08003007 }
3008 else
3009 {
3010 RW_TRACE_ERROR1 ("rw_i93_process_timeout () unknown event=%d", p_tle->event);
3011 }
3012}
3013
3014/*******************************************************************************
3015**
3016** Function rw_i93_data_cback
3017**
3018** Description This callback function receives the data from NFCC.
3019**
3020** Returns none
3021**
3022*******************************************************************************/
3023static void rw_i93_data_cback (UINT8 conn_id, tNFC_CONN_EVT event, tNFC_CONN *p_data)
3024{
3025 tRW_I93_CB *p_i93 = &rw_cb.tcb.i93;
3026 BT_HDR *p_resp = (BT_HDR *) p_data->data.p_data;
3027 tRW_DATA rw_data;
3028
3029#if (BT_TRACE_VERBOSE == TRUE)
3030 UINT8 begin_state = p_i93->state;
3031#endif
3032
3033 RW_TRACE_DEBUG1 ("rw_i93_data_cback () event = 0x%X", event);
3034
3035 if ( (event == NFC_DEACTIVATE_CEVT)
3036 ||(event == NFC_ERROR_CEVT) )
3037 {
3038 nfc_stop_quick_timer (&p_i93->timer);
3039
3040 if (event == NFC_ERROR_CEVT)
3041 {
Evan Chu85b7e842013-01-18 11:02:50 -05003042 if ( (p_i93->retry_count < RW_MAX_RETRIES)
3043 &&(p_i93->p_retry_cmd) )
3044 {
3045 p_i93->retry_count++;
3046
3047 RW_TRACE_ERROR1 ("rw_i93_data_cback (): retry_count = %d", p_i93->retry_count);
3048
3049 p_resp = p_i93->p_retry_cmd;
3050 p_i93->p_retry_cmd = NULL;
3051 rw_i93_send_to_lower (p_resp);
3052 }
3053 else
3054 {
3055 if (p_i93->p_retry_cmd)
3056 {
3057 GKI_freebuf (p_i93->p_retry_cmd);
3058 p_i93->p_retry_cmd = NULL;
3059 p_i93->retry_count = 0;
3060 }
3061
3062 rw_i93_handle_error ((tNFC_STATUS) (*(UINT8*) p_data));
3063 }
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08003064 }
3065 else
3066 {
3067 NFC_SetStaticRfCback (NULL);
3068 p_i93->state = RW_I93_STATE_NOT_ACTIVATED;
3069 }
3070 return;
3071 }
3072
3073 if (event != NFC_DATA_CEVT)
3074 {
3075 return;
3076 }
3077
3078 nfc_stop_quick_timer (&p_i93->timer);
3079
Evan Chu85b7e842013-01-18 11:02:50 -05003080 /* free retry buffer */
3081 if (p_i93->p_retry_cmd)
3082 {
3083 GKI_freebuf (p_i93->p_retry_cmd);
3084 p_i93->p_retry_cmd = NULL;
3085 p_i93->retry_count = 0;
3086 }
3087
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08003088#if (BT_TRACE_PROTOCOL == TRUE)
3089 DispRWI93Tag (p_resp, TRUE, p_i93->sent_cmd);
3090#endif
3091
3092#if (BT_TRACE_VERBOSE == TRUE)
3093 RW_TRACE_DEBUG2 ("RW I93 state: <%s (%d)>",
3094 rw_i93_get_state_name (p_i93->state), p_i93->state);
3095#else
3096 RW_TRACE_DEBUG1 ("RW I93 state: %d", p_i93->state);
3097#endif
3098
3099 switch (p_i93->state)
3100 {
3101 case RW_I93_STATE_IDLE:
3102 /* Unexpected Response from VICC, it should be raw frame response */
3103 /* forward to upper layer without parsing */
3104 p_i93->sent_cmd = 0;
3105 if (rw_cb.p_cback)
3106 {
3107 rw_data.raw_frame.status = NFC_STATUS_OK;
3108 rw_data.raw_frame.p_data = p_resp;
3109 (*(rw_cb.p_cback)) (RW_I93_RAW_FRAME_EVT, &rw_data);
3110 p_resp = NULL;
3111 }
3112 else
3113 {
3114 GKI_freebuf (p_resp);
3115 }
3116 break;
3117 case RW_I93_STATE_BUSY:
3118 p_i93->state = RW_I93_STATE_IDLE;
3119 rw_i93_send_to_upper (p_resp);
3120 GKI_freebuf (p_resp);
3121 break;
3122
3123 case RW_I93_STATE_DETECT_NDEF:
3124 rw_i93_sm_detect_ndef (p_resp);
3125 GKI_freebuf (p_resp);
3126 break;
3127
3128 case RW_I93_STATE_READ_NDEF:
3129 rw_i93_sm_read_ndef (p_resp);
3130 /* p_resp may send upper lyaer */
3131 break;
3132
3133 case RW_I93_STATE_UPDATE_NDEF:
3134 rw_i93_sm_update_ndef (p_resp);
3135 GKI_freebuf (p_resp);
3136 break;
3137
3138 case RW_I93_STATE_FORMAT:
3139 rw_i93_sm_format (p_resp);
3140 GKI_freebuf (p_resp);
3141 break;
3142
3143 case RW_I93_STATE_SET_READ_ONLY:
3144 rw_i93_sm_set_read_only (p_resp);
3145 GKI_freebuf (p_resp);
3146 break;
3147
3148 case RW_I93_STATE_PRESENCE_CHECK:
3149 p_i93->state = RW_I93_STATE_IDLE;
3150 p_i93->sent_cmd = 0;
3151
3152 /* if any response, send presence check with ok */
3153 rw_data.status = NFC_STATUS_OK;
3154 (*(rw_cb.p_cback)) (RW_I93_PRESENCE_CHECK_EVT, &rw_data);
3155 GKI_freebuf (p_resp);
3156 break;
3157
3158 default:
3159 RW_TRACE_ERROR1 ("rw_i93_data_cback (): invalid state=%d", p_i93->state);
3160 GKI_freebuf (p_resp);
3161 break;
3162 }
3163
3164#if (BT_TRACE_VERBOSE == TRUE)
3165 if (begin_state != p_i93->state)
3166 {
3167 RW_TRACE_DEBUG2 ("RW I93 state changed:<%s> -> <%s>",
3168 rw_i93_get_state_name (begin_state),
3169 rw_i93_get_state_name (p_i93->state));
3170 }
3171#endif
3172}
3173
3174/*******************************************************************************
3175**
3176** Function rw_i93_select
3177**
3178** Description Initialise ISO 15693 RW
3179**
3180** Returns NFC_STATUS_OK if success
3181**
3182*******************************************************************************/
Evan Chu85b7e842013-01-18 11:02:50 -05003183tNFC_STATUS rw_i93_select (UINT8 *p_uid)
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08003184{
3185 tRW_I93_CB *p_i93 = &rw_cb.tcb.i93;
Evan Chu85b7e842013-01-18 11:02:50 -05003186 UINT8 uid[I93_UID_BYTE_LEN], *p;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08003187
3188 RW_TRACE_DEBUG0 ("rw_i93_select ()");
3189
3190 NFC_SetStaticRfCback (rw_i93_data_cback);
3191
3192 p_i93->state = RW_I93_STATE_IDLE;
3193
Evan Chu85b7e842013-01-18 11:02:50 -05003194 /* convert UID to big endian format - MSB(0xE0) in first byte */
3195 p = uid;
3196 STREAM_TO_ARRAY8 (p, p_uid);
3197
3198 rw_i93_get_product_version (uid);
3199
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08003200 return NFC_STATUS_OK;
3201}
3202
3203/*******************************************************************************
3204**
3205** Function RW_I93Inventory
3206**
3207** Description This function send Inventory command
3208** If UID is provided then set UID[0]:MSB, ... UID[7]:LSB
3209**
3210** RW_I93_RESPONSE_EVT will be returned
3211**
3212** Returns NFC_STATUS_OK if success
3213** NFC_STATUS_NO_BUFFERS if out of buffer
3214** NFC_STATUS_BUSY if busy
3215** NFC_STATUS_FAILED if other error
3216**
3217*******************************************************************************/
3218tNFC_STATUS RW_I93Inventory (UINT8 afi, UINT8 *p_uid)
3219{
3220 tNFC_STATUS status;
3221
3222 RW_TRACE_API1 ("RW_I93Inventory (), AFI:0x%02X", afi);
3223
3224 if (rw_cb.tcb.i93.state != RW_I93_STATE_IDLE)
3225 {
3226 RW_TRACE_ERROR1 ("RW_I93Inventory ():Unable to start command at state (0x%X)",
3227 rw_cb.tcb.i93.state);
3228 return NFC_STATUS_BUSY;
3229 }
3230
3231 if (p_uid)
3232 {
3233 status = rw_i93_send_cmd_inventory (p_uid, afi);
3234 }
3235 else
3236 {
3237 status = rw_i93_send_cmd_inventory (NULL, afi);
3238 }
3239
3240 if (status == NFC_STATUS_OK)
3241 {
3242 rw_cb.tcb.i93.state = RW_I93_STATE_BUSY;
3243 }
3244
3245 return (status);
3246}
3247
3248/*******************************************************************************
3249**
3250** Function RW_I93StayQuiet
3251**
3252** Description This function send Inventory command
3253**
3254** RW_I93_CMD_CMPL_EVT will be returned
3255**
3256** Returns NFC_STATUS_OK if success
3257** NFC_STATUS_NO_BUFFERS if out of buffer
3258** NFC_STATUS_BUSY if busy
3259** NFC_STATUS_FAILED if other error
3260**
3261*******************************************************************************/
3262tNFC_STATUS RW_I93StayQuiet (void)
3263{
3264 tNFC_STATUS status;
3265
3266 RW_TRACE_API0 ("RW_I93StayQuiet ()");
3267
3268 if (rw_cb.tcb.i93.state != RW_I93_STATE_IDLE)
3269 {
3270 RW_TRACE_ERROR1 ("RW_I93StayQuiet ():Unable to start command at state (0x%X)",
3271 rw_cb.tcb.i93.state);
3272 return NFC_STATUS_BUSY;
3273 }
3274
3275 status = rw_i93_send_cmd_stay_quiet ();
3276 if (status == NFC_STATUS_OK)
3277 {
3278 rw_cb.tcb.i93.state = RW_I93_STATE_BUSY;
3279 }
3280
3281 return status;
3282}
3283
3284/*******************************************************************************
3285**
3286** Function RW_I93ReadSingleBlock
3287**
3288** Description This function send Read Single Block command
3289**
3290** RW_I93_RESPONSE_EVT will be returned
3291**
3292** Returns NFC_STATUS_OK if success
3293** NFC_STATUS_NO_BUFFERS if out of buffer
3294** NFC_STATUS_BUSY if busy
3295** NFC_STATUS_FAILED if other error
3296**
3297*******************************************************************************/
Evan Chu85b7e842013-01-18 11:02:50 -05003298tNFC_STATUS RW_I93ReadSingleBlock (UINT16 block_number)
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08003299{
3300 tNFC_STATUS status;
3301
3302 RW_TRACE_API1 ("RW_I93ReadSingleBlock () block_number:0x%02X", block_number);
3303
3304 if (rw_cb.tcb.i93.state != RW_I93_STATE_IDLE)
3305 {
3306 RW_TRACE_ERROR1 ("RW_I93ReadSingleBlock ():Unable to start command at state (0x%X)",
3307 rw_cb.tcb.i93.state);
3308 return NFC_STATUS_BUSY;
3309 }
3310
3311 status = rw_i93_send_cmd_read_single_block (block_number, FALSE);
3312 if (status == NFC_STATUS_OK)
3313 {
3314 rw_cb.tcb.i93.state = RW_I93_STATE_BUSY;
3315 }
3316
3317 return status;
3318}
3319
3320/*******************************************************************************
3321**
3322** Function RW_I93WriteSingleBlock
3323**
3324** Description This function send Write Single Block command
3325** Application must get block size first by calling RW_I93GetSysInfo().
3326**
3327** RW_I93_CMD_CMPL_EVT will be returned
3328**
3329** Returns NFC_STATUS_OK if success
3330** NFC_STATUS_NO_BUFFERS if out of buffer
3331** NFC_STATUS_BUSY if busy
3332** NFC_STATUS_FAILED if other error
3333**
3334*******************************************************************************/
Evan Chu85b7e842013-01-18 11:02:50 -05003335tNFC_STATUS RW_I93WriteSingleBlock (UINT16 block_number,
3336 UINT8 *p_data)
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08003337{
3338 tNFC_STATUS status;
3339
3340 RW_TRACE_API0 ("RW_I93WriteSingleBlock ()");
3341
3342 if (rw_cb.tcb.i93.state != RW_I93_STATE_IDLE)
3343 {
3344 RW_TRACE_ERROR1 ("RW_I93WriteSingleBlock ():Unable to start command at state (0x%X)",
3345 rw_cb.tcb.i93.state);
3346 return NFC_STATUS_BUSY;
3347 }
3348
3349 if (rw_cb.tcb.i93.block_size == 0)
3350 {
3351 RW_TRACE_ERROR0 ("RW_I93WriteSingleBlock ():Block size is unknown");
3352 return NFC_STATUS_FAILED;
3353 }
3354
3355 status = rw_i93_send_cmd_write_single_block (block_number, p_data);
3356 if (status == NFC_STATUS_OK)
3357 {
3358 rw_cb.tcb.i93.state = RW_I93_STATE_BUSY;
3359 }
3360
3361 return status;
3362}
3363
3364/*******************************************************************************
3365**
3366** Function RW_I93LockBlock
3367**
3368** Description This function send Lock Block command
3369**
3370** RW_I93_CMD_CMPL_EVT will be returned
3371**
3372** Returns NFC_STATUS_OK if success
3373** NFC_STATUS_NO_BUFFERS if out of buffer
3374** NFC_STATUS_BUSY if busy
3375** NFC_STATUS_FAILED if other error
3376**
3377*******************************************************************************/
3378tNFC_STATUS RW_I93LockBlock (UINT8 block_number)
3379{
3380 tNFC_STATUS status;
3381
3382 RW_TRACE_API0 ("RW_I93LockBlock ()");
3383
3384 if (rw_cb.tcb.i93.state != RW_I93_STATE_IDLE)
3385 {
3386 RW_TRACE_ERROR1 ("RW_I93LockBlock ():Unable to start command at state (0x%X)",
3387 rw_cb.tcb.i93.state);
3388 return NFC_STATUS_BUSY;
3389 }
3390
3391 status = rw_i93_send_cmd_lock_block (block_number);
3392 if (status == NFC_STATUS_OK)
3393 {
3394 rw_cb.tcb.i93.state = RW_I93_STATE_BUSY;
3395 }
3396
3397 return status;
3398}
3399
3400/*******************************************************************************
3401**
3402** Function RW_I93ReadMultipleBlocks
3403**
3404** Description This function send Read Multiple Blocks command
3405**
3406** RW_I93_RESPONSE_EVT will be returned
3407**
3408** Returns NFC_STATUS_OK if success
3409** NFC_STATUS_NO_BUFFERS if out of buffer
3410** NFC_STATUS_BUSY if busy
3411** NFC_STATUS_FAILED if other error
3412**
3413*******************************************************************************/
Evan Chu85b7e842013-01-18 11:02:50 -05003414tNFC_STATUS RW_I93ReadMultipleBlocks (UINT16 first_block_number,
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08003415 UINT16 number_blocks)
3416{
3417 tNFC_STATUS status;
3418
3419 RW_TRACE_API0 ("RW_I93ReadMultipleBlocks ()");
3420
3421 if (rw_cb.tcb.i93.state != RW_I93_STATE_IDLE)
3422 {
3423 RW_TRACE_ERROR1 ("RW_I93ReadMultipleBlocks ():Unable to start command at state (0x%X)",
3424 rw_cb.tcb.i93.state);
3425 return NFC_STATUS_BUSY;
3426 }
3427
3428 status = rw_i93_send_cmd_read_multi_blocks (first_block_number, number_blocks);
3429 if (status == NFC_STATUS_OK)
3430 {
3431 rw_cb.tcb.i93.state = RW_I93_STATE_BUSY;
3432 }
3433
3434 return status;
3435}
3436
3437/*******************************************************************************
3438**
3439** Function RW_I93WriteMultipleBlocks
3440**
3441** Description This function send Write Multiple Blocks command
3442**
3443** RW_I93_CMD_CMPL_EVT will be returned
3444**
3445** Returns NFC_STATUS_OK if success
3446** NFC_STATUS_NO_BUFFERS if out of buffer
3447** NFC_STATUS_BUSY if busy
3448** NFC_STATUS_FAILED if other error
3449**
3450*******************************************************************************/
3451tNFC_STATUS RW_I93WriteMultipleBlocks (UINT8 first_block_number,
3452 UINT16 number_blocks,
3453 UINT8 *p_data)
3454{
3455 tNFC_STATUS status;
3456
3457 RW_TRACE_API0 ("RW_I93WriteMultipleBlocks ()");
3458
3459 if (rw_cb.tcb.i93.state != RW_I93_STATE_IDLE)
3460 {
3461 RW_TRACE_ERROR1 ("RW_I93WriteMultipleBlocks ():Unable to start command at state (0x%X)",
3462 rw_cb.tcb.i93.state);
3463 return NFC_STATUS_BUSY;
3464 }
3465
3466 if (rw_cb.tcb.i93.block_size == 0)
3467 {
3468 RW_TRACE_ERROR0 ("RW_I93WriteSingleBlock ():Block size is unknown");
3469 return NFC_STATUS_FAILED;
3470 }
3471
3472 status = rw_i93_send_cmd_write_multi_blocks (first_block_number, number_blocks, p_data);
3473 if (status == NFC_STATUS_OK)
3474 {
3475 rw_cb.tcb.i93.state = RW_I93_STATE_BUSY;
3476 }
3477
3478 return status;
3479}
3480
3481/*******************************************************************************
3482**
3483** Function RW_I93Select
3484**
3485** Description This function send Select command
3486**
3487** UID[0]: 0xE0, MSB
3488** UID[1]: IC Mfg Code
3489** ...
3490** UID[7]: LSB
3491**
3492** RW_I93_CMD_CMPL_EVT will be returned
3493**
3494** Returns NFC_STATUS_OK if success
3495** NFC_STATUS_NO_BUFFERS if out of buffer
3496** NFC_STATUS_BUSY if busy
3497** NFC_STATUS_FAILED if other error
3498**
3499*******************************************************************************/
3500tNFC_STATUS RW_I93Select (UINT8 *p_uid)
3501{
3502 tNFC_STATUS status;
3503
3504 RW_TRACE_API0 ("RW_I93Select ()");
3505
3506 if (rw_cb.tcb.i93.state != RW_I93_STATE_IDLE)
3507 {
3508 RW_TRACE_ERROR1 ("RW_I93Select ():Unable to start command at state (0x%X)",
3509 rw_cb.tcb.i93.state);
3510 return NFC_STATUS_BUSY;
3511 }
3512
3513 if (p_uid)
3514 {
3515 status = rw_i93_send_cmd_select (p_uid);
3516 if (status == NFC_STATUS_OK)
3517 {
3518 rw_cb.tcb.i93.state = RW_I93_STATE_BUSY;
3519 }
3520 }
3521 else
3522 {
3523 RW_TRACE_ERROR0 ("RW_I93Select ():UID shall be provided");
3524 status = NFC_STATUS_FAILED;
3525 }
3526
3527 return status;
3528}
3529
3530/*******************************************************************************
3531**
3532** Function RW_I93ResetToReady
3533**
3534** Description This function send Reset To Ready command
3535**
3536** RW_I93_CMD_CMPL_EVT will be returned
3537**
3538** Returns NFC_STATUS_OK if success
3539** NFC_STATUS_NO_BUFFERS if out of buffer
3540** NFC_STATUS_BUSY if busy
3541** NFC_STATUS_FAILED if other error
3542**
3543*******************************************************************************/
3544tNFC_STATUS RW_I93ResetToReady (void)
3545{
3546 tNFC_STATUS status;
3547
3548 RW_TRACE_API0 ("RW_I93ResetToReady ()");
3549
3550 if (rw_cb.tcb.i93.state != RW_I93_STATE_IDLE)
3551 {
3552 RW_TRACE_ERROR1 ("RW_I93ResetToReady ():Unable to start command at state (0x%X)",
3553 rw_cb.tcb.i93.state);
3554 return NFC_STATUS_BUSY;
3555 }
3556
3557 status = rw_i93_send_cmd_reset_to_ready ();
3558 if (status == NFC_STATUS_OK)
3559 {
3560 rw_cb.tcb.i93.state = RW_I93_STATE_BUSY;
3561 }
3562
3563 return status;
3564}
3565
3566/*******************************************************************************
3567**
3568** Function RW_I93WriteAFI
3569**
3570** Description This function send Write AFI command
3571**
3572** RW_I93_CMD_CMPL_EVT will be returned
3573**
3574** Returns NFC_STATUS_OK if success
3575** NFC_STATUS_NO_BUFFERS if out of buffer
3576** NFC_STATUS_BUSY if busy
3577** NFC_STATUS_FAILED if other error
3578**
3579*******************************************************************************/
3580tNFC_STATUS RW_I93WriteAFI (UINT8 afi)
3581{
3582 tNFC_STATUS status;
3583
3584 RW_TRACE_API0 ("RW_I93WriteAFI ()");
3585
3586 if (rw_cb.tcb.i93.state != RW_I93_STATE_IDLE)
3587 {
3588 RW_TRACE_ERROR1 ("RW_I93WriteAFI ():Unable to start command at state (0x%X)",
3589 rw_cb.tcb.i93.state);
3590 return NFC_STATUS_BUSY;
3591 }
3592
3593 status = rw_i93_send_cmd_write_afi (afi);
3594 if (status == NFC_STATUS_OK)
3595 {
3596 rw_cb.tcb.i93.state = RW_I93_STATE_BUSY;
3597 }
3598
3599 return status;
3600}
3601
3602/*******************************************************************************
3603**
3604** Function RW_I93LockAFI
3605**
3606** Description This function send Lock AFI command
3607**
3608** RW_I93_CMD_CMPL_EVT will be returned
3609**
3610** Returns NFC_STATUS_OK if success
3611** NFC_STATUS_NO_BUFFERS if out of buffer
3612** NFC_STATUS_BUSY if busy
3613** NFC_STATUS_FAILED if other error
3614**
3615*******************************************************************************/
3616tNFC_STATUS RW_I93LockAFI (void)
3617{
3618 tNFC_STATUS status;
3619
3620 RW_TRACE_API0 ("RW_I93LockAFI ()");
3621
3622 if (rw_cb.tcb.i93.state != RW_I93_STATE_IDLE)
3623 {
3624 RW_TRACE_ERROR1 ("RW_I93LockAFI ():Unable to start command at state (0x%X)",
3625 rw_cb.tcb.i93.state);
3626 return NFC_STATUS_BUSY;
3627 }
3628
3629 status = rw_i93_send_cmd_lock_afi ();
3630 if (status == NFC_STATUS_OK)
3631 {
3632 rw_cb.tcb.i93.state = RW_I93_STATE_BUSY;
3633 }
3634
3635 return status;
3636}
3637
3638/*******************************************************************************
3639**
3640** Function RW_I93WriteDSFID
3641**
3642** Description This function send Write DSFID command
3643**
3644** RW_I93_CMD_CMPL_EVT will be returned
3645**
3646** Returns NFC_STATUS_OK if success
3647** NFC_STATUS_NO_BUFFERS if out of buffer
3648** NFC_STATUS_BUSY if busy
3649** NFC_STATUS_FAILED if other error
3650**
3651*******************************************************************************/
3652tNFC_STATUS RW_I93WriteDSFID (UINT8 dsfid)
3653{
3654 tNFC_STATUS status;
3655
3656 RW_TRACE_API0 ("RW_I93WriteDSFID ()");
3657
3658 if (rw_cb.tcb.i93.state != RW_I93_STATE_IDLE)
3659 {
3660 RW_TRACE_ERROR1 ("RW_I93WriteDSFID ():Unable to start command at state (0x%X)",
3661 rw_cb.tcb.i93.state);
3662 return NFC_STATUS_BUSY;
3663 }
3664
3665 status = rw_i93_send_cmd_write_dsfid (dsfid);
3666 if (status == NFC_STATUS_OK)
3667 {
3668 rw_cb.tcb.i93.state = RW_I93_STATE_BUSY;
3669 }
3670
3671 return status;
3672}
3673
3674/*******************************************************************************
3675**
3676** Function RW_I93LockDSFID
3677**
3678** Description This function send Lock DSFID command
3679**
3680** RW_I93_CMD_CMPL_EVT will be returned
3681**
3682** Returns NFC_STATUS_OK if success
3683** NFC_STATUS_NO_BUFFERS if out of buffer
3684** NFC_STATUS_BUSY if busy
3685** NFC_STATUS_FAILED if other error
3686**
3687*******************************************************************************/
3688tNFC_STATUS RW_I93LockDSFID (void)
3689{
3690 tNFC_STATUS status;
3691
3692 RW_TRACE_API0 ("RW_I93LockDSFID ()");
3693
3694 if (rw_cb.tcb.i93.state != RW_I93_STATE_IDLE)
3695 {
3696 RW_TRACE_ERROR1 ("RW_I93LockDSFID ():Unable to start command at state (0x%X)",
3697 rw_cb.tcb.i93.state);
3698 return NFC_STATUS_BUSY;
3699 }
3700
3701 status = rw_i93_send_cmd_lock_dsfid ();
3702 if (status == NFC_STATUS_OK)
3703 {
3704 rw_cb.tcb.i93.state = RW_I93_STATE_BUSY;
3705 }
3706
3707 return status;
3708}
3709
3710/*******************************************************************************
3711**
3712** Function RW_I93GetSysInfo
3713**
3714** Description This function send Get System Information command
3715**
3716** RW_I93_RESPONSE_EVT will be returned
3717**
3718** Returns NFC_STATUS_OK if success
3719** NFC_STATUS_NO_BUFFERS if out of buffer
3720** NFC_STATUS_BUSY if busy
3721** NFC_STATUS_FAILED if other error
3722**
3723*******************************************************************************/
3724tNFC_STATUS RW_I93GetSysInfo (UINT8 *p_uid)
3725{
3726 tNFC_STATUS status;
3727
3728 RW_TRACE_API0 ("RW_I93GetSysInfo ()");
3729
3730 if (rw_cb.tcb.i93.state != RW_I93_STATE_IDLE)
3731 {
3732 RW_TRACE_ERROR1 ("RW_I93GetSysInfo ():Unable to start command at state (0x%X)",
3733 rw_cb.tcb.i93.state);
3734 return NFC_STATUS_BUSY;
3735 }
3736
3737 if (p_uid)
3738 {
Evan Chu85b7e842013-01-18 11:02:50 -05003739 status = rw_i93_send_cmd_get_sys_info (p_uid, I93_FLAG_PROT_EXT_NO);
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08003740 }
3741 else
3742 {
Evan Chu85b7e842013-01-18 11:02:50 -05003743 status = rw_i93_send_cmd_get_sys_info (NULL, I93_FLAG_PROT_EXT_NO);
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08003744 }
3745
3746 if (status == NFC_STATUS_OK)
3747 {
3748 rw_cb.tcb.i93.state = RW_I93_STATE_BUSY;
3749 }
3750
3751 return status;
3752}
3753
3754/*******************************************************************************
3755**
3756** Function RW_I93GetMultiBlockSecurityStatus
3757**
3758** Description This function send Get Multiple Block Security Status command
3759**
3760** RW_I93_RESPONSE_EVT will be returned
3761**
3762** Returns NFC_STATUS_OK if success
3763** NFC_STATUS_NO_BUFFERS if out of buffer
3764** NFC_STATUS_BUSY if busy
3765** NFC_STATUS_FAILED if other error
3766**
3767*******************************************************************************/
Evan Chu85b7e842013-01-18 11:02:50 -05003768tNFC_STATUS RW_I93GetMultiBlockSecurityStatus (UINT16 first_block_number,
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08003769 UINT16 number_blocks)
3770{
3771 tNFC_STATUS status;
3772
3773 RW_TRACE_API0 ("RW_I93GetMultiBlockSecurityStatus ()");
3774
3775 if (rw_cb.tcb.i93.state != RW_I93_STATE_IDLE)
3776 {
3777 RW_TRACE_ERROR1 ("RW_I93GetMultiBlockSecurityStatus ():Unable to start command at state (0x%X)",
3778 rw_cb.tcb.i93.state);
3779 return NFC_STATUS_BUSY;
3780 }
3781
3782 status = rw_i93_send_cmd_get_multi_block_sec (first_block_number, number_blocks);
3783 if (status == NFC_STATUS_OK)
3784 {
3785 rw_cb.tcb.i93.state = RW_I93_STATE_BUSY;
3786 }
3787
3788 return status;
3789}
3790
3791/*******************************************************************************
3792**
3793** Function RW_I93DetectNDef
3794**
3795** Description This function performs NDEF detection procedure
3796**
3797** RW_I93_NDEF_DETECT_EVT will be returned
3798**
3799** Returns NFC_STATUS_OK if success
3800** NFC_STATUS_FAILED if busy or other error
3801**
3802*******************************************************************************/
3803tNFC_STATUS RW_I93DetectNDef (void)
3804{
3805 tNFC_STATUS status;
3806 tRW_I93_RW_SUBSTATE sub_state;
3807
3808 RW_TRACE_API0 ("RW_I93DetectNDef ()");
3809
3810 if (rw_cb.tcb.i93.state != RW_I93_STATE_IDLE)
3811 {
3812 RW_TRACE_ERROR1 ("RW_I93DetectNDef ():Unable to start command at state (0x%X)",
3813 rw_cb.tcb.i93.state);
3814 return NFC_STATUS_FAILED;
3815 }
3816
3817 if (rw_cb.tcb.i93.uid[0] != I93_UID_FIRST_BYTE)
3818 {
3819 status = rw_i93_send_cmd_inventory (NULL, 0x00);
3820 sub_state = RW_I93_SUBSTATE_WAIT_UID;
3821 }
3822 else if ( (rw_cb.tcb.i93.num_block == 0)
3823 ||(rw_cb.tcb.i93.block_size == 0) )
3824 {
Evan Chu85b7e842013-01-18 11:02:50 -05003825 status = rw_i93_send_cmd_get_sys_info (rw_cb.tcb.i93.uid, I93_FLAG_PROT_EXT_NO);
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08003826 sub_state = RW_I93_SUBSTATE_WAIT_SYS_INFO;
Evan Chu85b7e842013-01-18 11:02:50 -05003827
3828 /* clear all flags */
3829 rw_cb.tcb.i93.intl_flags = 0;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08003830 }
3831 else
3832 {
3833 /* read CC in the first block */
Evan Chu85b7e842013-01-18 11:02:50 -05003834 status = rw_i93_send_cmd_read_single_block (0x0000, FALSE);
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08003835 sub_state = RW_I93_SUBSTATE_WAIT_CC;
3836 }
3837
3838 if (status == NFC_STATUS_OK)
3839 {
3840 rw_cb.tcb.i93.state = RW_I93_STATE_DETECT_NDEF;
3841 rw_cb.tcb.i93.sub_state = sub_state;
Evan Chu85b7e842013-01-18 11:02:50 -05003842
3843 /* clear flags except flag for 2 bytes of number of blocks */
3844 rw_cb.tcb.i93.intl_flags &= RW_I93_FLAG_16BIT_NUM_BLOCK;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08003845 }
3846
3847 return (status);
3848}
3849
3850/*******************************************************************************
3851**
3852** Function RW_I93ReadNDef
3853**
3854** Description This function performs NDEF read procedure
3855** Note: RW_I93DetectNDef () must be called before using this
3856**
3857** The following event will be returned
3858** RW_I93_NDEF_READ_EVT for each segmented NDEF message
3859** RW_I93_NDEF_READ_CPLT_EVT for the last segment or complete NDEF
3860** RW_I93_NDEF_READ_FAIL_EVT for failure
3861**
3862** Returns NFC_STATUS_OK if success
3863** NFC_STATUS_FAILED if I93 is busy or other error
3864**
3865*******************************************************************************/
3866tNFC_STATUS RW_I93ReadNDef (void)
3867{
3868 RW_TRACE_API0 ("RW_I93ReadNDef ()");
3869
3870 if (rw_cb.tcb.i93.state != RW_I93_STATE_IDLE)
3871 {
3872 RW_TRACE_ERROR1 ("RW_I93ReadNDef ():Unable to start command at state (0x%X)",
3873 rw_cb.tcb.i93.state);
3874 return NFC_STATUS_FAILED;
3875 }
3876
3877 if ( (rw_cb.tcb.i93.tlv_type == I93_ICODE_TLV_TYPE_NDEF)
3878 &&(rw_cb.tcb.i93.ndef_length > 0) )
3879 {
3880 rw_cb.tcb.i93.rw_offset = rw_cb.tcb.i93.ndef_tlv_start_offset;
3881 rw_cb.tcb.i93.rw_length = 0;
3882
3883 if (rw_i93_get_next_blocks (rw_cb.tcb.i93.rw_offset) == NFC_STATUS_OK)
3884 {
3885 rw_cb.tcb.i93.state = RW_I93_STATE_READ_NDEF;
3886 }
3887 else
3888 {
3889 return NFC_STATUS_FAILED;
3890 }
3891 }
3892 else
3893 {
3894 RW_TRACE_ERROR0 ("RW_I93ReadNDef ():No NDEF detected");
3895 return NFC_STATUS_FAILED;
3896 }
3897
3898 return NFC_STATUS_OK;
3899}
3900
3901/*******************************************************************************
3902**
3903** Function RW_I93UpdateNDef
3904**
3905** Description This function performs NDEF update procedure
3906** Note: RW_I93DetectNDef () must be called before using this
3907** Updating data must not be removed until returning event
3908**
3909** The following event will be returned
3910** RW_I93_NDEF_UPDATE_CPLT_EVT for complete
3911** RW_I93_NDEF_UPDATE_FAIL_EVT for failure
3912**
3913** Returns NFC_STATUS_OK if success
3914** NFC_STATUS_FAILED if I93 is busy or other error
3915**
3916*******************************************************************************/
3917tNFC_STATUS RW_I93UpdateNDef (UINT16 length, UINT8 *p_data)
3918{
Evan Chu85b7e842013-01-18 11:02:50 -05003919 UINT16 block_number;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08003920
3921 RW_TRACE_API1 ("RW_I93UpdateNDef () length:%d", length);
3922
3923 if (rw_cb.tcb.i93.state != RW_I93_STATE_IDLE)
3924 {
3925 RW_TRACE_ERROR1 ("RW_I93UpdateNDef ():Unable to start command at state (0x%X)",
3926 rw_cb.tcb.i93.state);
3927 return NFC_STATUS_FAILED;
3928 }
3929
3930 if (rw_cb.tcb.i93.tlv_type == I93_ICODE_TLV_TYPE_NDEF)
3931 {
3932 if (rw_cb.tcb.i93.intl_flags & RW_I93_FLAG_READ_ONLY)
3933 {
3934 RW_TRACE_ERROR0 ("RW_I93UpdateNDef ():NDEF is read-only");
3935 return NFC_STATUS_FAILED;
3936 }
3937 if (rw_cb.tcb.i93.max_ndef_length < length)
3938 {
3939 RW_TRACE_ERROR2 ("RW_I93UpdateNDef ():data (%d bytes) is more than max NDEF length (%d)",
3940 length, rw_cb.tcb.i93.max_ndef_length);
3941 return NFC_STATUS_FAILED;
3942 }
3943
3944 rw_cb.tcb.i93.ndef_length = length;
3945 rw_cb.tcb.i93.p_update_data = p_data;
3946
3947 /* read length field */
3948 rw_cb.tcb.i93.rw_offset = rw_cb.tcb.i93.ndef_tlv_start_offset + 1;
3949 rw_cb.tcb.i93.rw_length = 0;
3950
Evan Chu85b7e842013-01-18 11:02:50 -05003951 block_number = rw_cb.tcb.i93.rw_offset / rw_cb.tcb.i93.block_size;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08003952
3953 if (rw_i93_send_cmd_read_single_block (block_number, FALSE) == NFC_STATUS_OK)
3954 {
3955 rw_cb.tcb.i93.state = RW_I93_STATE_UPDATE_NDEF;
3956 rw_cb.tcb.i93.sub_state = RW_I93_SUBSTATE_RESET_LEN;
3957 }
3958 else
3959 {
3960 return NFC_STATUS_FAILED;
3961 }
3962 }
3963 else
3964 {
3965 RW_TRACE_ERROR0 ("RW_I93ReadNDef ():No NDEF detected");
3966 return NFC_STATUS_FAILED;
3967 }
3968
3969 return NFC_STATUS_OK;
3970}
3971
3972/*******************************************************************************
3973**
3974** Function RW_I93FormatNDef
3975**
3976** Description This function performs formatting procedure
3977**
3978** RW_I93_FORMAT_CPLT_EVT will be returned
3979**
3980** Returns NFC_STATUS_OK if success
3981** NFC_STATUS_FAILED if busy or other error
3982**
3983*******************************************************************************/
3984tNFC_STATUS RW_I93FormatNDef (void)
3985{
3986 tNFC_STATUS status;
3987 tRW_I93_RW_SUBSTATE sub_state;
3988
3989 RW_TRACE_API0 ("RW_I93FormatNDef ()");
3990
3991 if (rw_cb.tcb.i93.state != RW_I93_STATE_IDLE)
3992 {
3993 RW_TRACE_ERROR1 ("RW_I93FormatNDef ():Unable to start command at state (0x%X)",
3994 rw_cb.tcb.i93.state);
3995 return NFC_STATUS_FAILED;
3996 }
3997
3998 if ( (rw_cb.tcb.i93.product_version == RW_I93_TAG_IT_HF_I_STD_CHIP_INLAY)
3999 ||(rw_cb.tcb.i93.product_version == RW_I93_TAG_IT_HF_I_PRO_CHIP_INLAY) )
4000 {
4001 /* These don't support GetSystemInformation and GetMultiBlockSecurityStatus */
4002 rw_cb.tcb.i93.rw_offset = 0;
4003
4004 /* read blocks with option flag to get block security status */
Evan Chu85b7e842013-01-18 11:02:50 -05004005 status = rw_i93_send_cmd_read_single_block (0x0000, TRUE);
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08004006 sub_state = RW_I93_SUBSTATE_CHECK_READ_ONLY;
4007 }
4008 else
4009 {
4010 status = rw_i93_send_cmd_inventory (rw_cb.tcb.i93.uid, 0x00);
4011 sub_state = RW_I93_SUBSTATE_WAIT_UID;
4012 }
4013
4014 if (status == NFC_STATUS_OK)
4015 {
4016 rw_cb.tcb.i93.state = RW_I93_STATE_FORMAT;
4017 rw_cb.tcb.i93.sub_state = sub_state;
4018 rw_cb.tcb.i93.intl_flags = 0;
4019 }
4020
4021 return (status);
4022}
4023
4024/*******************************************************************************
4025**
4026** Function RW_I93SetTagReadOnly
4027**
4028** Description This function performs NDEF read-only procedure
4029** Note: RW_I93DetectNDef () must be called before using this
4030** Updating data must not be removed until returning event
4031**
4032** The RW_I93_SET_TAG_RO_EVT event will be returned.
4033**
4034** Returns NFC_STATUS_OK if success
4035** NFC_STATUS_FAILED if I93 is busy or other error
4036**
4037*******************************************************************************/
4038tNFC_STATUS RW_I93SetTagReadOnly (void)
4039{
4040 RW_TRACE_API0 ("RW_I93SetTagReadOnly ()");
4041
4042 if (rw_cb.tcb.i93.state != RW_I93_STATE_IDLE)
4043 {
4044 RW_TRACE_ERROR1 ("RW_I93SetTagReadOnly ():Unable to start command at state (0x%X)",
4045 rw_cb.tcb.i93.state);
4046 return NFC_STATUS_FAILED;
4047 }
4048
4049 if (rw_cb.tcb.i93.tlv_type == I93_ICODE_TLV_TYPE_NDEF)
4050 {
4051 if (rw_cb.tcb.i93.intl_flags & RW_I93_FLAG_READ_ONLY)
4052 {
4053 RW_TRACE_ERROR0 ("RW_I93SetTagReadOnly ():NDEF is already read-only");
4054 return NFC_STATUS_FAILED;
4055 }
4056
4057 /* get CC in the first block */
4058 if (rw_i93_send_cmd_read_single_block (0, FALSE) == NFC_STATUS_OK)
4059 {
4060 rw_cb.tcb.i93.state = RW_I93_STATE_SET_READ_ONLY;
4061 rw_cb.tcb.i93.sub_state = RW_I93_SUBSTATE_WAIT_CC;
4062 }
4063 else
4064 {
4065 return NFC_STATUS_FAILED;
4066 }
4067 }
4068 else
4069 {
4070 RW_TRACE_ERROR0 ("RW_I93SetTagReadOnly ():No NDEF detected");
4071 return NFC_STATUS_FAILED;
4072 }
4073
4074 return NFC_STATUS_OK;
4075}
4076
4077/*****************************************************************************
4078**
4079** Function RW_I93PresenceCheck
4080**
4081** Description Check if the tag is still in the field.
4082**
4083** The RW_I93_PRESENCE_CHECK_EVT w/ status is used to indicate
4084** presence or non-presence.
4085**
4086** Returns NFC_STATUS_OK, if raw data frame sent
4087** NFC_STATUS_NO_BUFFERS: unable to allocate a buffer for this operation
4088** NFC_STATUS_FAILED: other error
4089**
4090*****************************************************************************/
4091tNFC_STATUS RW_I93PresenceCheck (void)
4092{
4093
4094 tNFC_STATUS status;
4095 tRW_DATA evt_data;
4096
4097 RW_TRACE_API0 ("RW_I93PresenceCheck ()");
4098
4099 if (!rw_cb.p_cback)
4100 {
4101 return NFC_STATUS_FAILED;
4102 }
4103 else if (rw_cb.tcb.i93.state == RW_I93_STATE_NOT_ACTIVATED)
4104 {
4105 evt_data.status = NFC_STATUS_FAILED;
4106 (*rw_cb.p_cback) (RW_T4T_PRESENCE_CHECK_EVT, &evt_data);
4107
4108 return NFC_STATUS_OK;
4109 }
4110 else if (rw_cb.tcb.i93.state != RW_I93_STATE_IDLE)
4111 {
4112 return NFC_STATUS_BUSY;
4113 }
4114 else
4115 {
4116 status = rw_i93_send_cmd_inventory (rw_cb.tcb.i93.uid, 0x00);
4117
4118 if (status == NFC_STATUS_OK)
4119 {
Evan Chu85b7e842013-01-18 11:02:50 -05004120 /* do not retry during presence check */
4121 rw_cb.tcb.i93.retry_count = RW_MAX_RETRIES;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08004122 rw_cb.tcb.i93.state = RW_I93_STATE_PRESENCE_CHECK;
4123 }
4124 }
4125
4126 return (status);
4127}
4128
4129#if (BT_TRACE_VERBOSE == TRUE)
4130/*******************************************************************************
4131**
4132** Function rw_i93_get_state_name
4133**
4134** Description This function returns the state name.
4135**
4136** NOTE conditionally compiled to save memory.
4137**
4138** Returns pointer to the name
4139**
4140*******************************************************************************/
4141static char *rw_i93_get_state_name (UINT8 state)
4142{
4143 switch (state)
4144 {
4145 case RW_I93_STATE_NOT_ACTIVATED:
4146 return ("NOT_ACTIVATED");
4147 case RW_I93_STATE_IDLE:
4148 return ("IDLE");
4149 case RW_I93_STATE_BUSY:
4150 return ("BUSY");
4151
4152 case RW_I93_STATE_DETECT_NDEF:
4153 return ("NDEF_DETECTION");
4154 case RW_I93_STATE_READ_NDEF:
4155 return ("READ_NDEF");
4156 case RW_I93_STATE_UPDATE_NDEF:
4157 return ("UPDATE_NDEF");
4158 case RW_I93_STATE_FORMAT:
4159 return ("FORMAT");
4160 case RW_I93_STATE_SET_READ_ONLY:
4161 return ("SET_READ_ONLY");
4162
4163 case RW_I93_STATE_PRESENCE_CHECK:
4164 return ("PRESENCE_CHECK");
4165 default:
4166 return ("???? UNKNOWN STATE");
4167 }
4168}
4169
4170/*******************************************************************************
4171**
4172** Function rw_i93_get_sub_state_name
4173**
4174** Description This function returns the sub_state name.
4175**
4176** NOTE conditionally compiled to save memory.
4177**
4178** Returns pointer to the name
4179**
4180*******************************************************************************/
4181static char *rw_i93_get_sub_state_name (UINT8 sub_state)
4182{
4183 switch (sub_state)
4184 {
4185 case RW_I93_SUBSTATE_WAIT_UID:
4186 return ("WAIT_UID");
4187 case RW_I93_SUBSTATE_WAIT_SYS_INFO:
4188 return ("WAIT_SYS_INFO");
4189 case RW_I93_SUBSTATE_WAIT_CC:
4190 return ("WAIT_CC");
4191 case RW_I93_SUBSTATE_SEARCH_NDEF_TLV:
4192 return ("SEARCH_NDEF_TLV");
4193 case RW_I93_SUBSTATE_CHECK_LOCK_STATUS:
4194 return ("CHECK_LOCK_STATUS");
4195 case RW_I93_SUBSTATE_RESET_LEN:
4196 return ("RESET_LEN");
4197 case RW_I93_SUBSTATE_WRITE_NDEF:
4198 return ("WRITE_NDEF");
4199 case RW_I93_SUBSTATE_UPDATE_LEN:
4200 return ("UPDATE_LEN");
4201 case RW_I93_SUBSTATE_WAIT_RESET_DSFID_AFI:
4202 return ("WAIT_RESET_DSFID_AFI");
4203 case RW_I93_SUBSTATE_CHECK_READ_ONLY:
4204 return ("CHECK_READ_ONLY");
4205 case RW_I93_SUBSTATE_WRITE_CC_NDEF_TLV:
4206 return ("WRITE_CC_NDEF_TLV");
4207 case RW_I93_SUBSTATE_WAIT_UPDATE_CC:
4208 return ("WAIT_UPDATE_CC");
4209 case RW_I93_SUBSTATE_LOCK_NDEF_TLV:
4210 return ("LOCK_NDEF_TLV");
4211 case RW_I93_SUBSTATE_WAIT_LOCK_CC:
4212 return ("WAIT_LOCK_CC");
4213 default:
4214 return ("???? UNKNOWN SUBSTATE");
4215 }
4216}
Evan Chu85b7e842013-01-18 11:02:50 -05004217
4218/*******************************************************************************
4219**
4220** Function rw_i93_get_tag_name
4221**
4222** Description This function returns the tag name.
4223**
4224** NOTE conditionally compiled to save memory.
4225**
4226** Returns pointer to the name
4227**
4228*******************************************************************************/
4229static char *rw_i93_get_tag_name (UINT8 product_version)
4230{
4231 switch (product_version)
4232 {
4233 case RW_I93_ICODE_SLI:
4234 return ("SLI/SLIX");
4235 case RW_I93_ICODE_SLI_S:
4236 return ("SLI-S/SLIX-S");
4237 case RW_I93_ICODE_SLI_L:
4238 return ("SLI-L/SLIX-L");
4239 case RW_I93_TAG_IT_HF_I_PLUS_INLAY:
4240 return ("Tag-it HF-I Plus Inlay");
4241 case RW_I93_TAG_IT_HF_I_PLUS_CHIP:
4242 return ("Tag-it HF-I Plus Chip");
4243 case RW_I93_TAG_IT_HF_I_STD_CHIP_INLAY:
4244 return ("Tag-it HF-I Standard Chip/Inlyas");
4245 case RW_I93_TAG_IT_HF_I_PRO_CHIP_INLAY:
4246 return ("Tag-it HF-I Pro Chip/Inlays");
4247 case RW_I93_STM_LRI1K:
4248 return ("LRi1K");
4249 case RW_I93_STM_LRI2K:
4250 return ("LRi2K");
4251 case RW_I93_STM_LRIS2K:
4252 return ("LRiS2K");
4253 case RW_I93_STM_LRIS64K:
4254 return ("LRiS64K");
4255 case RW_I93_STM_M24LR64_R:
4256 return ("M24LR64");
4257 case RW_I93_STM_M24LR04E_R:
4258 return ("M24LR04E");
4259 case RW_I93_STM_M24LR16E_R:
4260 return ("M24LR16E");
4261 case RW_I93_STM_M24LR64E_R:
4262 return ("M24LR64E");
4263 case RW_I93_UNKNOWN_PRODUCT:
4264 default:
4265 return ("UNKNOWN");
4266 }
4267}
4268
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08004269#endif
4270
4271#endif /* (NFC_INCLUDED == TRUE) */