blob: 320235e6895b2e1ef1d4375ec59d1a13d42ab57c [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
Martijn Coenen5c65c3a2013-03-27 13:23:36 -070019
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -080020/******************************************************************************
21 *
22 * This file contains the implementation for ISO 15693 in Reader/Writer
23 * mode.
24 *
25 ******************************************************************************/
26#include <string.h>
27#include "nfc_target.h"
28#include "bt_types.h"
29#include "trace_api.h"
30
31#if (NFC_INCLUDED == TRUE)
32
33#include "nfc_api.h"
34#include "nfc_int.h"
35#include "rw_api.h"
36#include "rw_int.h"
37
38#define RW_I93_TOUT_RESP 1000 /* Response timeout */
39#define RW_I93_TOUT_STAY_QUIET 200 /* stay quiet timeout */
40#define RW_I93_READ_MULTI_BLOCK_SIZE 128 /* max reading data if read multi block is supported */
41#define RW_I93_FORMAT_DATA_LEN 8 /* CC, zero length NDEF, Terminator TLV */
Evan Chu85b7e842013-01-18 11:02:50 -050042#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 -080043
44/* main state */
45enum
46{
47 RW_I93_STATE_NOT_ACTIVATED, /* ISO15693 is not activated */
48 RW_I93_STATE_IDLE, /* waiting for upper layer API */
49 RW_I93_STATE_BUSY, /* waiting for response from tag */
50
51 RW_I93_STATE_DETECT_NDEF, /* performing NDEF detection precedure */
52 RW_I93_STATE_READ_NDEF, /* performing read NDEF procedure */
53 RW_I93_STATE_UPDATE_NDEF, /* performing update NDEF procedure */
54 RW_I93_STATE_FORMAT, /* performing format procedure */
55 RW_I93_STATE_SET_READ_ONLY, /* performing set read-only procedure */
56
57 RW_I93_STATE_PRESENCE_CHECK /* checking presence of tag */
58};
59
60/* sub state */
61enum
62{
63 RW_I93_SUBSTATE_WAIT_UID, /* waiting for response of inventory */
64 RW_I93_SUBSTATE_WAIT_SYS_INFO, /* waiting for response of get sys info */
65 RW_I93_SUBSTATE_WAIT_CC, /* waiting for reading CC */
66 RW_I93_SUBSTATE_SEARCH_NDEF_TLV, /* searching NDEF TLV */
67 RW_I93_SUBSTATE_CHECK_LOCK_STATUS, /* check if any NDEF TLV is locked */
68
69 RW_I93_SUBSTATE_RESET_LEN, /* set length to 0 to update NDEF TLV */
70 RW_I93_SUBSTATE_WRITE_NDEF, /* writing NDEF and Terminator TLV */
71 RW_I93_SUBSTATE_UPDATE_LEN, /* set length into NDEF TLV */
72
73 RW_I93_SUBSTATE_WAIT_RESET_DSFID_AFI, /* reset DSFID and AFI */
74 RW_I93_SUBSTATE_CHECK_READ_ONLY, /* check if any block is locked */
75 RW_I93_SUBSTATE_WRITE_CC_NDEF_TLV, /* write CC and empty NDEF/Terminator TLV */
76
77 RW_I93_SUBSTATE_WAIT_UPDATE_CC, /* updating CC as read-only */
78 RW_I93_SUBSTATE_LOCK_NDEF_TLV, /* lock blocks of NDEF TLV */
79 RW_I93_SUBSTATE_WAIT_LOCK_CC /* lock block of CC */
80};
81
82#if (BT_TRACE_VERBOSE == TRUE)
83static char *rw_i93_get_state_name (UINT8 state);
84static char *rw_i93_get_sub_state_name (UINT8 sub_state);
Evan Chu85b7e842013-01-18 11:02:50 -050085static char *rw_i93_get_tag_name (UINT8 product_version);
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -080086#endif
87
88static void rw_i93_data_cback (UINT8 conn_id, tNFC_CONN_EVT event, tNFC_CONN *p_data);
89void rw_i93_handle_error (tNFC_STATUS status);
Evan Chu85b7e842013-01-18 11:02:50 -050090tNFC_STATUS rw_i93_send_cmd_get_sys_info (UINT8 *p_uid, UINT8 extra_flag);
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -080091
92/*******************************************************************************
93**
94** Function rw_i93_get_product_version
95**
96** Description Get product version from UID
97**
98** Returns void
99**
100*******************************************************************************/
101void rw_i93_get_product_version (UINT8 *p_uid)
102{
103 tRW_I93_CB *p_i93 = &rw_cb.tcb.i93;
104
105 if (!memcmp (p_i93->uid, p_uid, I93_UID_BYTE_LEN))
106 {
107 return;
108 }
109
110 RW_TRACE_DEBUG0 ("rw_i93_get_product_version ()");
111
112 memcpy (p_i93->uid, p_uid, I93_UID_BYTE_LEN);
113
114 if (p_uid[1] == I93_UID_IC_MFG_CODE_NXP)
115 {
116 if (p_uid[2] == I93_UID_ICODE_SLI)
117 p_i93->product_version = RW_I93_ICODE_SLI;
118 else if (p_uid[2] == I93_UID_ICODE_SLI_S)
119 p_i93->product_version = RW_I93_ICODE_SLI_S;
120 else if (p_uid[2] == I93_UID_ICODE_SLI_L)
121 p_i93->product_version = RW_I93_ICODE_SLI_L;
122 else
123 p_i93->product_version = RW_I93_UNKNOWN_PRODUCT;
124 }
125 else if (p_uid[1] == I93_UID_IC_MFG_CODE_TI)
126 {
127 if ((p_uid[2] & I93_UID_TAG_IT_HF_I_PRODUCT_ID_MASK) == I93_UID_TAG_IT_HF_I_PLUS_INLAY)
128 p_i93->product_version = RW_I93_TAG_IT_HF_I_PLUS_INLAY;
129 else if ((p_uid[2] & I93_UID_TAG_IT_HF_I_PRODUCT_ID_MASK) == I93_UID_TAG_IT_HF_I_PLUS_CHIP)
130 p_i93->product_version = RW_I93_TAG_IT_HF_I_PLUS_CHIP;
131 else if ((p_uid[2] & I93_UID_TAG_IT_HF_I_PRODUCT_ID_MASK) == I93_UID_TAG_IT_HF_I_STD_CHIP_INLAY)
132 p_i93->product_version = RW_I93_TAG_IT_HF_I_STD_CHIP_INLAY;
133 else if ((p_uid[2] & I93_UID_TAG_IT_HF_I_PRODUCT_ID_MASK) == I93_UID_TAG_IT_HF_I_PRO_CHIP_INLAY)
134 p_i93->product_version = RW_I93_TAG_IT_HF_I_PRO_CHIP_INLAY;
135 else
136 p_i93->product_version = RW_I93_UNKNOWN_PRODUCT;
137 }
Evan Chu85b7e842013-01-18 11:02:50 -0500138 else if ( (p_uid[1] == I93_UID_IC_MFG_CODE_STM)
139 &&(p_i93->info_flags & I93_INFO_FLAG_IC_REF) )
140 {
141 if (p_i93->ic_reference == I93_IC_REF_STM_M24LR04E_R)
142 p_i93->product_version = RW_I93_STM_M24LR04E_R;
143 else if (p_i93->ic_reference == I93_IC_REF_STM_M24LR16E_R)
144 p_i93->product_version = RW_I93_STM_M24LR16E_R;
145 else if (p_i93->ic_reference == I93_IC_REF_STM_M24LR64E_R)
146 p_i93->product_version = RW_I93_STM_M24LR64E_R;
147 else
148 {
149 switch (p_i93->ic_reference & I93_IC_REF_STM_MASK)
150 {
151 case I93_IC_REF_STM_LRI1K:
152 p_i93->product_version = RW_I93_STM_LRI1K;
153 break;
154 case I93_IC_REF_STM_LRI2K:
155 p_i93->product_version = RW_I93_STM_LRI2K;
156 break;
157 case I93_IC_REF_STM_LRIS2K:
158 p_i93->product_version = RW_I93_STM_LRIS2K;
159 break;
160 case I93_IC_REF_STM_LRIS64K:
161 p_i93->product_version = RW_I93_STM_LRIS64K;
162 break;
163 case I93_IC_REF_STM_M24LR64_R:
164 p_i93->product_version = RW_I93_STM_M24LR64_R;
165 break;
166 default:
167 p_i93->product_version = RW_I93_UNKNOWN_PRODUCT;
168 break;
169 }
170 }
171 }
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800172 else
173 {
174 p_i93->product_version = RW_I93_UNKNOWN_PRODUCT;
175 }
176
Evan Chu85b7e842013-01-18 11:02:50 -0500177#if (BT_TRACE_VERBOSE == TRUE)
178 RW_TRACE_DEBUG1 ("product_version = <%s>", rw_i93_get_tag_name(p_i93->product_version));
179#else
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800180 RW_TRACE_DEBUG1 ("product_version = %d", p_i93->product_version);
Evan Chu85b7e842013-01-18 11:02:50 -0500181#endif
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800182
183 switch (p_i93->product_version)
184 {
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800185 case RW_I93_TAG_IT_HF_I_STD_CHIP_INLAY:
186 case RW_I93_TAG_IT_HF_I_PRO_CHIP_INLAY:
187 /* these don't support Get System Information Command */
188 /* these support only Inventory, Stay Quiet, Read Single Block, Write Single Block, Lock Block */
189 p_i93->block_size = I93_TAG_IT_HF_I_STD_PRO_CHIP_INLAY_BLK_SIZE;
190 p_i93->num_block = I93_TAG_IT_HF_I_STD_PRO_CHIP_INLAY_NUM_USER_BLK;
191 break;
Evan Chu85b7e842013-01-18 11:02:50 -0500192 default:
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800193 break;
194 }
195}
196
197/*******************************************************************************
198**
Evan Chu85b7e842013-01-18 11:02:50 -0500199** Function rw_i93_process_sys_info
200**
201** Description Store system information of tag
202**
203** Returns FALSE if retrying with protocol extension flag
204**
205*******************************************************************************/
206BOOLEAN rw_i93_process_sys_info (UINT8* p_data)
207{
208 UINT8 *p = p_data;
209 tRW_I93_CB *p_i93 = &rw_cb.tcb.i93;
210 UINT8 uid[I93_UID_BYTE_LEN], *p_uid;
211
212 RW_TRACE_DEBUG0 ("rw_i93_process_sys_info ()");
213
214 STREAM_TO_UINT8 (p_i93->info_flags, p);
215
216 p_uid = uid;
217 STREAM_TO_ARRAY8 (p_uid, p);
218
219 if (p_i93->info_flags & I93_INFO_FLAG_DSFID)
220 {
221 STREAM_TO_UINT8 (p_i93->dsfid, p);
222 }
223 if (p_i93->info_flags & I93_INFO_FLAG_AFI)
224 {
225 STREAM_TO_UINT8 (p_i93->afi, p);
226 }
227 if (p_i93->info_flags & I93_INFO_FLAG_MEM_SIZE)
228 {
229 if (p_i93->intl_flags & RW_I93_FLAG_16BIT_NUM_BLOCK)
230 {
231 STREAM_TO_UINT16 (p_i93->num_block, p);
232 }
233 else
234 {
235 STREAM_TO_UINT8 (p_i93->num_block, p);
236 }
237 /* it is one less than actual number of bytes */
238 p_i93->num_block += 1;
239
240 STREAM_TO_UINT8 (p_i93->block_size, p);
241 /* it is one less than actual number of blocks */
242 p_i93->block_size = (p_i93->block_size & 0x1F) + 1;
243 }
244 if (p_i93->info_flags & I93_INFO_FLAG_IC_REF)
245 {
246 STREAM_TO_UINT8 (p_i93->ic_reference, p);
247
248 /* clear existing UID to set product version */
249 p_i93->uid[0] = 0x00;
250
251 /* store UID and get product version */
252 rw_i93_get_product_version (p_uid);
253
254 if (p_i93->uid[0] == I93_UID_FIRST_BYTE)
255 {
256 if ( (p_i93->uid[1] == I93_UID_IC_MFG_CODE_NXP)
257 &&(p_i93->ic_reference == I93_IC_REF_ICODE_SLI_L) )
258 {
259 p_i93->num_block = 8;
260 p_i93->block_size = 4;
261 }
262 else if (p_i93->uid[1] == I93_UID_IC_MFG_CODE_STM)
263 {
264 /*
265 ** LRI1K: 010000xx(b), blockSize: 4, numberBlocks: 0x20
266 ** LRI2K: 001000xx(b), blockSize: 4, numberBlocks: 0x40
267 ** LRIS2K: 001010xx(b), blockSize: 4, numberBlocks: 0x40
268 ** LRIS64K: 010001xx(b), blockSize: 4, numberBlocks: 0x800
269 ** M24LR64-R: 001011xx(b), blockSize: 4, numberBlocks: 0x800
270 ** M24LR04E-R: 01011010(b), blockSize: 4, numberBlocks: 0x80
271 ** M24LR16E-R: 01001110(b), blockSize: 4, numberBlocks: 0x200
272 ** M24LR64E-R: 01011110(b), blockSize: 4, numberBlocks: 0x800
273 */
274 if ( (p_i93->product_version == RW_I93_STM_M24LR16E_R)
275 ||(p_i93->product_version == RW_I93_STM_M24LR64E_R) )
276 {
277 /*
278 ** M24LR16E-R or M24LR64E-R returns system information without memory size,
279 ** if option flag is not set.
280 ** LRIS64K and M24LR64-R return error if option flag is not set.
281 */
282 if (!(p_i93->intl_flags & RW_I93_FLAG_16BIT_NUM_BLOCK))
283 {
284 /* get memory size with protocol extension flag */
285 if (rw_i93_send_cmd_get_sys_info (NULL, I93_FLAG_PROT_EXT_YES) == NFC_STATUS_OK)
286 {
287 /* STM supports more than 2040 bytes */
288 p_i93->intl_flags |= RW_I93_FLAG_16BIT_NUM_BLOCK;
289
290 return FALSE;
291 }
292 }
293 return TRUE;
294 }
295 else if ( (p_i93->product_version == RW_I93_STM_LRI2K)
296 &&(p_i93->ic_reference == 0x21) )
297 {
298 /* workaround of byte order in memory size information */
299 p_i93->num_block = 64;
300 p_i93->block_size = 4;
301 }
302 }
303 }
304 }
305
306 return TRUE;
307}
308
309/*******************************************************************************
310**
311** Function rw_i93_check_sys_info_prot_ext
312**
313** Description Check if need to set protocol extension flag to get system info
314**
315** Returns TRUE if sent Get System Info with protocol extension flag
316**
317*******************************************************************************/
318BOOLEAN rw_i93_check_sys_info_prot_ext (UINT8 error_code)
319{
320 tRW_I93_CB *p_i93 = &rw_cb.tcb.i93;
321
322 RW_TRACE_DEBUG0 ("rw_i93_check_sys_info_prot_ext ()");
323
324 if ( (p_i93->uid[1] == I93_UID_IC_MFG_CODE_STM)
325 &&(p_i93->sent_cmd == I93_CMD_GET_SYS_INFO)
326 &&(error_code == I93_ERROR_CODE_OPTION_NOT_SUPPORTED)
327 &&(rw_i93_send_cmd_get_sys_info (NULL, I93_FLAG_PROT_EXT_YES) == NFC_STATUS_OK) )
328 {
329 return TRUE;
330 }
331 else
332 {
333 return FALSE;
334 }
335}
336
337/*******************************************************************************
338**
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800339** Function rw_i93_send_to_upper
340**
341** Description Send response to upper layer
342**
343** Returns void
344**
345*******************************************************************************/
346void rw_i93_send_to_upper (BT_HDR *p_resp)
347{
348 UINT8 *p = (UINT8 *) (p_resp + 1) + p_resp->offset, *p_uid;
349 UINT16 length = p_resp->len;
350 tRW_I93_CB *p_i93 = &rw_cb.tcb.i93;
351 tRW_DATA rw_data;
352 UINT8 event = RW_I93_MAX_EVT;
353 UINT8 flags;
354 BT_HDR *p_buff;
355
356 RW_TRACE_DEBUG0 ("rw_i93_send_to_upper ()");
357
358 STREAM_TO_UINT8 (flags, p);
359 length--;
360
361 if (flags & I93_FLAG_ERROR_DETECTED)
362 {
Evan Chu85b7e842013-01-18 11:02:50 -0500363 if ((length) && (rw_i93_check_sys_info_prot_ext(*p)))
364 {
365 /* getting system info with protocol extension flag */
366 /* This STM tag supports more than 2040 bytes */
367 p_i93->intl_flags |= RW_I93_FLAG_16BIT_NUM_BLOCK;
368 p_i93->state = RW_I93_STATE_BUSY;
369 }
370 else
371 {
372 /* notify error to upper layer */
373 rw_data.i93_cmd_cmpl.status = NFC_STATUS_FAILED;
374 rw_data.i93_cmd_cmpl.command = p_i93->sent_cmd;
375 STREAM_TO_UINT8 (rw_data.i93_cmd_cmpl.error_code, p);
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800376
Evan Chu85b7e842013-01-18 11:02:50 -0500377 rw_cb.tcb.i93.sent_cmd = 0;
378 (*(rw_cb.p_cback)) (RW_I93_CMD_CMPL_EVT, &rw_data);
379 }
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800380 return;
381 }
382
383 switch (p_i93->sent_cmd)
384 {
385 case I93_CMD_INVENTORY:
386
387 /* forward inventory response */
388 rw_data.i93_inventory.status = NFC_STATUS_OK;
389 STREAM_TO_UINT8 (rw_data.i93_inventory.dsfid, p);
390
391 p_uid = rw_data.i93_inventory.uid;
392 STREAM_TO_ARRAY8 (p_uid, p);
393
394 /* store UID and get product version */
395 rw_i93_get_product_version (p_uid);
396
397 event = RW_I93_INVENTORY_EVT;
398 break;
399
400 case I93_CMD_READ_SINGLE_BLOCK:
401 case I93_CMD_READ_MULTI_BLOCK:
402 case I93_CMD_GET_MULTI_BLK_SEC:
403
404 /* forward tag data or security status */
405 p_buff = (BT_HDR*) GKI_getbuf ((UINT16) (length + BT_HDR_SIZE));
406
407 if (p_buff)
408 {
409 p_buff->offset = 0;
410 p_buff->len = length;
411
412 memcpy ((p_buff + 1), p, length);
413
414 rw_data.i93_data.status = NFC_STATUS_OK;
415 rw_data.i93_data.command = p_i93->sent_cmd;
416 rw_data.i93_data.p_data = p_buff;
417
418 event = RW_I93_DATA_EVT;
419 }
420 else
421 {
422 rw_data.i93_cmd_cmpl.status = NFC_STATUS_NO_BUFFERS;
423 rw_data.i93_cmd_cmpl.command = p_i93->sent_cmd;
424 rw_data.i93_cmd_cmpl.error_code = 0;
425
426 event = RW_I93_CMD_CMPL_EVT;
427 }
428 break;
429
430 case I93_CMD_WRITE_SINGLE_BLOCK:
431 case I93_CMD_LOCK_BLOCK:
432 case I93_CMD_WRITE_MULTI_BLOCK:
433 case I93_CMD_SELECT:
434 case I93_CMD_RESET_TO_READY:
435 case I93_CMD_WRITE_AFI:
436 case I93_CMD_LOCK_AFI:
437 case I93_CMD_WRITE_DSFID:
438 case I93_CMD_LOCK_DSFID:
439
440 /* notify the complete of command */
441 rw_data.i93_cmd_cmpl.status = NFC_STATUS_OK;
442 rw_data.i93_cmd_cmpl.command = p_i93->sent_cmd;
443 rw_data.i93_cmd_cmpl.error_code = 0;
444
445 event = RW_I93_CMD_CMPL_EVT;
446 break;
447
448 case I93_CMD_GET_SYS_INFO:
449
Evan Chu85b7e842013-01-18 11:02:50 -0500450 if (rw_i93_process_sys_info (p))
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800451 {
Evan Chu85b7e842013-01-18 11:02:50 -0500452 rw_data.i93_sys_info.status = NFC_STATUS_OK;
453 rw_data.i93_sys_info.info_flags = p_i93->info_flags;
454 rw_data.i93_sys_info.dsfid = p_i93->dsfid;
455 rw_data.i93_sys_info.afi = p_i93->afi;
456 rw_data.i93_sys_info.num_block = p_i93->num_block;
457 rw_data.i93_sys_info.block_size = p_i93->block_size;
458 rw_data.i93_sys_info.IC_reference = p_i93->ic_reference;
459
460 memcpy (rw_data.i93_sys_info.uid, p_i93->uid, I93_UID_BYTE_LEN);
461
462 event = RW_I93_SYS_INFO_EVT;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800463 }
Evan Chu85b7e842013-01-18 11:02:50 -0500464 else
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800465 {
Evan Chu85b7e842013-01-18 11:02:50 -0500466 /* retrying with protocol extension flag */
467 p_i93->state = RW_I93_STATE_BUSY;
468 return;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800469 }
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800470 break;
471
472 default:
473 break;
474 }
475
476 rw_cb.tcb.i93.sent_cmd = 0;
477 if (event != RW_I93_MAX_EVT)
478 {
479 (*(rw_cb.p_cback)) (event, &rw_data);
480 }
481 else
482 {
483 RW_TRACE_ERROR0 ("rw_i93_send_to_upper (): Invalid response");
484 }
485}
486
487/*******************************************************************************
488**
489** Function rw_i93_send_to_lower
490**
491** Description Send Request frame to lower layer
492**
493** Returns TRUE if success
494**
495*******************************************************************************/
496BOOLEAN rw_i93_send_to_lower (BT_HDR *p_msg)
497{
498#if (BT_TRACE_PROTOCOL == TRUE)
499 DispRWI93Tag (p_msg, FALSE, 0x00);
500#endif
501
Evan Chu85b7e842013-01-18 11:02:50 -0500502 /* store command for retransmitting */
503 if (rw_cb.tcb.i93.p_retry_cmd)
504 {
505 GKI_freebuf (rw_cb.tcb.i93.p_retry_cmd);
506 rw_cb.tcb.i93.p_retry_cmd = NULL;
507 }
508
509 rw_cb.tcb.i93.p_retry_cmd = (BT_HDR *) GKI_getpoolbuf (NFC_RW_POOL_ID);
510
511 if (rw_cb.tcb.i93.p_retry_cmd)
512 {
513 memcpy (rw_cb.tcb.i93.p_retry_cmd, p_msg, sizeof (BT_HDR) + p_msg->offset + p_msg->len);
514 }
515
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800516 if (NFC_SendData (NFC_RF_CONN_ID, p_msg) != NFC_STATUS_OK)
517 {
518 RW_TRACE_ERROR0 ("rw_i93_send_to_lower (): NFC_SendData () failed");
519 return FALSE;
520 }
521
522 nfc_start_quick_timer (&rw_cb.tcb.i93.timer, NFC_TTYPE_RW_I93_RESPONSE,
523 (RW_I93_TOUT_RESP*QUICK_TIMER_TICKS_PER_SEC)/1000);
524
525 return TRUE;
526}
527
528/*******************************************************************************
529**
530** Function rw_i93_send_cmd_inventory
531**
532** Description Send Inventory Request to VICC
533**
534** Returns tNFC_STATUS
535**
536*******************************************************************************/
Martijn Coenen5c65c3a2013-03-27 13:23:36 -0700537tNFC_STATUS rw_i93_send_cmd_inventory (UINT8 *p_uid, BOOLEAN including_afi, UINT8 afi)
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800538{
539 BT_HDR *p_cmd;
Martijn Coenen5c65c3a2013-03-27 13:23:36 -0700540 UINT8 *p, flags;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800541
Martijn Coenen5c65c3a2013-03-27 13:23:36 -0700542 RW_TRACE_DEBUG2 ("rw_i93_send_cmd_inventory () including_afi:%d, AFI:0x%02X", including_afi, afi);
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800543
544 p_cmd = (BT_HDR *) GKI_getpoolbuf (NFC_RW_POOL_ID);
545
546 if (!p_cmd)
547 {
548 RW_TRACE_ERROR0 ("rw_i93_send_cmd_inventory (): Cannot allocate buffer");
549 return NFC_STATUS_NO_BUFFERS;
550 }
551
552 p_cmd->offset = NCI_MSG_OFFSET_SIZE + NCI_DATA_HDR_SIZE;
Martijn Coenenbf6bb392013-02-04 14:17:20 -0800553 p_cmd->len = 3;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800554 p = (UINT8 *) (p_cmd + 1) + p_cmd->offset;
555
556 /* Flags */
Martijn Coenen5c65c3a2013-03-27 13:23:36 -0700557 flags = (I93_FLAG_SLOT_ONE | I93_FLAG_INVENTORY_SET | RW_I93_FLAG_SUB_CARRIER | RW_I93_FLAG_DATA_RATE);
558 if (including_afi)
559 {
560 flags |= I93_FLAG_AFI_PRESENT;
561 }
562
563 UINT8_TO_STREAM (p, flags);
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800564
565 /* Command Code */
566 UINT8_TO_STREAM (p, I93_CMD_INVENTORY);
567
Martijn Coenen5c65c3a2013-03-27 13:23:36 -0700568 if (including_afi)
569 {
570 /* Parameters */
571 UINT8_TO_STREAM (p, afi); /* Optional AFI */
572 p_cmd->len++;
573 }
574
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800575 if (p_uid)
576 {
577 UINT8_TO_STREAM (p, I93_UID_BYTE_LEN*8); /* Mask Length */
578 ARRAY8_TO_STREAM (p, p_uid); /* UID */
579 p_cmd->len += I93_UID_BYTE_LEN;
580 }
581 else
582 {
583 UINT8_TO_STREAM (p, 0x00); /* Mask Length */
584 }
585
586 if (rw_i93_send_to_lower (p_cmd))
587 {
588 rw_cb.tcb.i93.sent_cmd = I93_CMD_INVENTORY;
589 return NFC_STATUS_OK;
590 }
591 else
592 {
593 return NFC_STATUS_FAILED;
594 }
595}
596
597/*******************************************************************************
598**
599** Function rw_i93_send_cmd_stay_quiet
600**
601** Description Send Stay Quiet Request to VICC
602**
603** Returns tNFC_STATUS
604**
605*******************************************************************************/
606tNFC_STATUS rw_i93_send_cmd_stay_quiet (void)
607{
608 BT_HDR *p_cmd;
609 UINT8 *p;
610
611 RW_TRACE_DEBUG0 ("rw_i93_send_cmd_stay_quiet ()");
612
613 p_cmd = (BT_HDR *) GKI_getpoolbuf (NFC_RW_POOL_ID);
614
615 if (!p_cmd)
616 {
617 RW_TRACE_ERROR0 ("rw_i93_send_cmd_stay_quiet (): Cannot allocate buffer");
618 return NFC_STATUS_NO_BUFFERS;
619 }
620
621 p_cmd->offset = NCI_MSG_OFFSET_SIZE + NCI_DATA_HDR_SIZE;
622 p_cmd->len = 10;
623 p = (UINT8 *) (p_cmd + 1) + p_cmd->offset;
624
625 /* Flags */
626 UINT8_TO_STREAM (p, (I93_FLAG_ADDRESS_SET | RW_I93_FLAG_SUB_CARRIER | RW_I93_FLAG_DATA_RATE));
627
628 /* Command Code */
629 UINT8_TO_STREAM (p, I93_CMD_STAY_QUIET);
630
631 /* Parameters */
632 ARRAY8_TO_STREAM (p, rw_cb.tcb.i93.uid); /* UID */
633
634 if (rw_i93_send_to_lower (p_cmd))
635 {
636 rw_cb.tcb.i93.sent_cmd = I93_CMD_STAY_QUIET;
637
638 /* restart timer for stay quiet */
639 nfc_start_quick_timer (&rw_cb.tcb.i93.timer, NFC_TTYPE_RW_I93_RESPONSE,
640 (RW_I93_TOUT_STAY_QUIET * QUICK_TIMER_TICKS_PER_SEC) / 1000);
641 return NFC_STATUS_OK;
642 }
643 else
644 {
645 return NFC_STATUS_FAILED;
646 }
647}
648
649/*******************************************************************************
650**
651** Function rw_i93_send_cmd_read_single_block
652**
653** Description Send Read Single Block Request to VICC
654**
655** Returns tNFC_STATUS
656**
657*******************************************************************************/
Evan Chu85b7e842013-01-18 11:02:50 -0500658tNFC_STATUS rw_i93_send_cmd_read_single_block (UINT16 block_number, BOOLEAN read_security)
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800659{
660 BT_HDR *p_cmd;
Evan Chu85b7e842013-01-18 11:02:50 -0500661 UINT8 *p, flags;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800662
663 RW_TRACE_DEBUG0 ("rw_i93_send_cmd_read_single_block ()");
664
665 p_cmd = (BT_HDR *) GKI_getpoolbuf (NFC_RW_POOL_ID);
666
667 if (!p_cmd)
668 {
669 RW_TRACE_ERROR0 ("rw_i93_send_cmd_read_single_block (): Cannot allocate buffer");
670 return NFC_STATUS_NO_BUFFERS;
671 }
672
673 p_cmd->offset = NCI_MSG_OFFSET_SIZE + NCI_DATA_HDR_SIZE;
674 p_cmd->len = 11;
675 p = (UINT8 *) (p_cmd + 1) + p_cmd->offset;
676
677 /* Flags */
Evan Chu85b7e842013-01-18 11:02:50 -0500678 flags = (I93_FLAG_ADDRESS_SET | RW_I93_FLAG_SUB_CARRIER | RW_I93_FLAG_DATA_RATE);
679
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800680 if (read_security)
Evan Chu85b7e842013-01-18 11:02:50 -0500681 flags |= I93_FLAG_OPTION_SET;
682
683 if (rw_cb.tcb.i93.intl_flags & RW_I93_FLAG_16BIT_NUM_BLOCK)
684 flags |= I93_FLAG_PROT_EXT_YES;
685
686 UINT8_TO_STREAM (p, flags);
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800687
688 /* Command Code */
689 UINT8_TO_STREAM (p, I93_CMD_READ_SINGLE_BLOCK);
690
691 /* Parameters */
692 ARRAY8_TO_STREAM (p, rw_cb.tcb.i93.uid); /* UID */
Evan Chu85b7e842013-01-18 11:02:50 -0500693
694 if (rw_cb.tcb.i93.intl_flags & RW_I93_FLAG_16BIT_NUM_BLOCK)
695 {
696 UINT16_TO_STREAM (p, block_number); /* Block number */
697 p_cmd->len++;
698 }
699 else
700 {
701 UINT8_TO_STREAM (p, block_number); /* Block number */
702 }
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800703
704 if (rw_i93_send_to_lower (p_cmd))
705 {
706 rw_cb.tcb.i93.sent_cmd = I93_CMD_READ_SINGLE_BLOCK;
707 return NFC_STATUS_OK;
708 }
709 else
710 {
711 return NFC_STATUS_FAILED;
712 }
713}
714
715/*******************************************************************************
716**
717** Function rw_i93_send_cmd_write_single_block
718**
719** Description Send Write Single Block Request to VICC
720**
721** Returns tNFC_STATUS
722**
723*******************************************************************************/
Evan Chu85b7e842013-01-18 11:02:50 -0500724tNFC_STATUS rw_i93_send_cmd_write_single_block (UINT16 block_number, UINT8 *p_data)
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800725{
726 BT_HDR *p_cmd;
Evan Chu85b7e842013-01-18 11:02:50 -0500727 UINT8 *p, flags;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800728
729 RW_TRACE_DEBUG0 ("rw_i93_send_cmd_write_single_block ()");
730
731 p_cmd = (BT_HDR *) GKI_getpoolbuf (NFC_RW_POOL_ID);
732
733 if (!p_cmd)
734 {
735 RW_TRACE_ERROR0 ("rw_i93_send_cmd_write_single_block (): Cannot allocate buffer");
736 return NFC_STATUS_NO_BUFFERS;
737 }
738
739 p_cmd->offset = NCI_MSG_OFFSET_SIZE + NCI_DATA_HDR_SIZE;
740 p_cmd->len = 11 + rw_cb.tcb.i93.block_size;
741 p = (UINT8 *) (p_cmd + 1) + p_cmd->offset;
742
743 /* Flags */
744 if ( (rw_cb.tcb.i93.product_version == RW_I93_TAG_IT_HF_I_PLUS_INLAY)
745 ||(rw_cb.tcb.i93.product_version == RW_I93_TAG_IT_HF_I_PLUS_CHIP)
746 ||(rw_cb.tcb.i93.product_version == RW_I93_TAG_IT_HF_I_STD_CHIP_INLAY)
747 ||(rw_cb.tcb.i93.product_version == RW_I93_TAG_IT_HF_I_PRO_CHIP_INLAY) )
748 {
749 /* Option must be set for TI tag */
Evan Chu85b7e842013-01-18 11:02:50 -0500750 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 -0800751 }
752 else
753 {
Evan Chu85b7e842013-01-18 11:02:50 -0500754 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 -0800755 }
756
Evan Chu85b7e842013-01-18 11:02:50 -0500757 if (rw_cb.tcb.i93.intl_flags & RW_I93_FLAG_16BIT_NUM_BLOCK)
758 flags |= I93_FLAG_PROT_EXT_YES;
759
760 UINT8_TO_STREAM (p, flags);
761
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800762 /* Command Code */
763 UINT8_TO_STREAM (p, I93_CMD_WRITE_SINGLE_BLOCK);
764
765 /* Parameters */
766 ARRAY8_TO_STREAM (p, rw_cb.tcb.i93.uid); /* UID */
Evan Chu85b7e842013-01-18 11:02:50 -0500767
768 if (rw_cb.tcb.i93.intl_flags & RW_I93_FLAG_16BIT_NUM_BLOCK)
769 {
770 UINT16_TO_STREAM (p, block_number); /* Block number */
771 p_cmd->len++;
772 }
773 else
774 {
775 UINT8_TO_STREAM (p, block_number); /* Block number */
776 }
777
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800778
779 /* Data */
780 ARRAY_TO_STREAM (p, p_data, rw_cb.tcb.i93.block_size);
781
782 if (rw_i93_send_to_lower (p_cmd))
783 {
784 rw_cb.tcb.i93.sent_cmd = I93_CMD_WRITE_SINGLE_BLOCK;
785 return NFC_STATUS_OK;
786 }
787 else
788 {
789 return NFC_STATUS_FAILED;
790 }
791}
792
793/*******************************************************************************
794**
795** Function rw_i93_send_cmd_lock_block
796**
797** Description Send Lock Block Request to VICC
798**
Evan Chu85b7e842013-01-18 11:02:50 -0500799** STM LRIS64K, M24LR64-R, M24LR04E-R, M24LR16E-R, M24LR64E-R
800** do not support.
801**
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800802** Returns tNFC_STATUS
803**
804*******************************************************************************/
805tNFC_STATUS rw_i93_send_cmd_lock_block (UINT8 block_number)
806{
807 BT_HDR *p_cmd;
808 UINT8 *p;
809
810 RW_TRACE_DEBUG0 ("rw_i93_send_cmd_lock_block ()");
811
812 p_cmd = (BT_HDR *) GKI_getpoolbuf (NFC_RW_POOL_ID);
813
814 if (!p_cmd)
815 {
816 RW_TRACE_ERROR0 ("rw_i93_send_cmd_lock_block (): Cannot allocate buffer");
817 return NFC_STATUS_NO_BUFFERS;
818 }
819
820 p_cmd->offset = NCI_MSG_OFFSET_SIZE + NCI_DATA_HDR_SIZE;
821 p_cmd->len = 11;
822 p = (UINT8 *) (p_cmd + 1) + p_cmd->offset;
823
824 /* Flags */
825 if ( (rw_cb.tcb.i93.product_version == RW_I93_TAG_IT_HF_I_PLUS_INLAY)
826 ||(rw_cb.tcb.i93.product_version == RW_I93_TAG_IT_HF_I_PLUS_CHIP)
827 ||(rw_cb.tcb.i93.product_version == RW_I93_TAG_IT_HF_I_STD_CHIP_INLAY)
828 ||(rw_cb.tcb.i93.product_version == RW_I93_TAG_IT_HF_I_PRO_CHIP_INLAY) )
829 {
830 /* Option must be set for TI tag */
831 UINT8_TO_STREAM (p, (I93_FLAG_ADDRESS_SET | I93_FLAG_OPTION_SET | RW_I93_FLAG_SUB_CARRIER | RW_I93_FLAG_DATA_RATE));
832 }
833 else
834 {
835 UINT8_TO_STREAM (p, (I93_FLAG_ADDRESS_SET | RW_I93_FLAG_SUB_CARRIER | RW_I93_FLAG_DATA_RATE));
836 }
837
838 /* Command Code */
839 UINT8_TO_STREAM (p, I93_CMD_LOCK_BLOCK);
840
841 /* Parameters */
842 ARRAY8_TO_STREAM (p, rw_cb.tcb.i93.uid); /* UID */
843 UINT8_TO_STREAM (p, block_number); /* Block number */
844
845 if (rw_i93_send_to_lower (p_cmd))
846 {
847 rw_cb.tcb.i93.sent_cmd = I93_CMD_LOCK_BLOCK;
848 return NFC_STATUS_OK;
849 }
850 else
851 {
852 return NFC_STATUS_FAILED;
853 }
854}
855
856/*******************************************************************************
857**
858** Function rw_i93_send_cmd_read_multi_blocks
859**
860** Description Send Read Multiple Blocks Request to VICC
861**
862** Returns tNFC_STATUS
863**
864*******************************************************************************/
Evan Chu85b7e842013-01-18 11:02:50 -0500865tNFC_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 -0800866{
867 BT_HDR *p_cmd;
Evan Chu85b7e842013-01-18 11:02:50 -0500868 UINT8 *p, flags;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800869
870 RW_TRACE_DEBUG0 ("rw_i93_send_cmd_read_multi_blocks ()");
871
872 p_cmd = (BT_HDR *) GKI_getpoolbuf (NFC_RW_POOL_ID);
873
874 if (!p_cmd)
875 {
876 RW_TRACE_ERROR0 ("rw_i93_send_cmd_read_multi_blocks (): Cannot allocate buffer");
877 return NFC_STATUS_NO_BUFFERS;
878 }
879
880 p_cmd->offset = NCI_MSG_OFFSET_SIZE + NCI_DATA_HDR_SIZE;
881 p_cmd->len = 12;
882 p = (UINT8 *) (p_cmd + 1) + p_cmd->offset;
883
884 /* Flags */
Evan Chu85b7e842013-01-18 11:02:50 -0500885 flags = (I93_FLAG_ADDRESS_SET | RW_I93_FLAG_SUB_CARRIER | RW_I93_FLAG_DATA_RATE);
886
887 if (rw_cb.tcb.i93.intl_flags & RW_I93_FLAG_16BIT_NUM_BLOCK)
888 flags |= I93_FLAG_PROT_EXT_YES;
889
890 UINT8_TO_STREAM (p, flags);
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800891
892 /* Command Code */
893 UINT8_TO_STREAM (p, I93_CMD_READ_MULTI_BLOCK);
894
895 /* Parameters */
896 ARRAY8_TO_STREAM (p, rw_cb.tcb.i93.uid); /* UID */
Evan Chu85b7e842013-01-18 11:02:50 -0500897
898 if (rw_cb.tcb.i93.intl_flags & RW_I93_FLAG_16BIT_NUM_BLOCK)
899 {
900 UINT16_TO_STREAM (p, first_block_number); /* First block number */
901 p_cmd->len++;
902 }
903 else
904 {
905 UINT8_TO_STREAM (p, first_block_number); /* First block number */
906 }
907
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800908 UINT8_TO_STREAM (p, number_blocks - 1); /* Number of blocks, 0x00 to read one block */
909
910 if (rw_i93_send_to_lower (p_cmd))
911 {
912 rw_cb.tcb.i93.sent_cmd = I93_CMD_READ_MULTI_BLOCK;
913 return NFC_STATUS_OK;
914 }
915 else
916 {
917 return NFC_STATUS_FAILED;
918 }
919}
920
921/*******************************************************************************
922**
923** Function rw_i93_send_cmd_write_multi_blocks
924**
925** Description Send Write Multiple Blocks Request to VICC
926**
927** Returns tNFC_STATUS
928**
929*******************************************************************************/
930tNFC_STATUS rw_i93_send_cmd_write_multi_blocks (UINT8 first_block_number,
931 UINT16 number_blocks,
932 UINT8 *p_data)
933{
934 BT_HDR *p_cmd;
935 UINT8 *p;
936
937 RW_TRACE_DEBUG0 ("rw_i93_send_cmd_write_multi_blocks ()");
938
939 p_cmd = (BT_HDR *) GKI_getpoolbuf (NFC_RW_POOL_ID);
940
941 if (!p_cmd)
942 {
943 RW_TRACE_ERROR0 ("rw_i93_send_cmd_write_multi_blocks (): Cannot allocate buffer");
944 return NFC_STATUS_NO_BUFFERS;
945 }
946
947 p_cmd->offset = NCI_MSG_OFFSET_SIZE + NCI_DATA_HDR_SIZE;
948 p_cmd->len = 12 + number_blocks * rw_cb.tcb.i93.block_size;
949 p = (UINT8 *) (p_cmd + 1) + p_cmd->offset;
950
951 /* Flags */
952 UINT8_TO_STREAM (p, (I93_FLAG_ADDRESS_SET | RW_I93_FLAG_SUB_CARRIER | RW_I93_FLAG_DATA_RATE));
953
954 /* Command Code */
955 UINT8_TO_STREAM (p, I93_CMD_WRITE_MULTI_BLOCK);
956
957 /* Parameters */
958 ARRAY8_TO_STREAM (p, rw_cb.tcb.i93.uid); /* UID */
959 UINT8_TO_STREAM (p, first_block_number); /* First block number */
960 UINT8_TO_STREAM (p, number_blocks - 1); /* Number of blocks, 0x00 to read one block */
961
962 /* Data */
963 ARRAY_TO_STREAM (p, p_data, number_blocks * rw_cb.tcb.i93.block_size);
964
965 if (rw_i93_send_to_lower (p_cmd))
966 {
967 rw_cb.tcb.i93.sent_cmd = I93_CMD_WRITE_MULTI_BLOCK;
968 return NFC_STATUS_OK;
969 }
970 else
971 {
972 return NFC_STATUS_FAILED;
973 }
974}
975
976/*******************************************************************************
977**
978** Function rw_i93_send_cmd_select
979**
980** Description Send Select Request to VICC
981**
982** Returns tNFC_STATUS
983**
984*******************************************************************************/
985tNFC_STATUS rw_i93_send_cmd_select (UINT8 *p_uid)
986{
987 BT_HDR *p_cmd;
988 UINT8 *p;
989
990 RW_TRACE_DEBUG0 ("rw_i93_send_cmd_select ()");
991
992 p_cmd = (BT_HDR *) GKI_getpoolbuf (NFC_RW_POOL_ID);
993
994 if (!p_cmd)
995 {
996 RW_TRACE_ERROR0 ("rw_i93_send_cmd_select (): Cannot allocate buffer");
997 return NFC_STATUS_NO_BUFFERS;
998 }
999
1000 p_cmd->offset = NCI_MSG_OFFSET_SIZE + NCI_DATA_HDR_SIZE;
1001 p_cmd->len = 10 ;
1002 p = (UINT8 *) (p_cmd + 1) + p_cmd->offset;
1003
1004 /* Flags */
1005 UINT8_TO_STREAM (p, (I93_FLAG_ADDRESS_SET | RW_I93_FLAG_SUB_CARRIER | RW_I93_FLAG_DATA_RATE));
1006
1007 /* Command Code */
1008 UINT8_TO_STREAM (p, I93_CMD_SELECT);
1009
1010 /* Parameters */
1011 ARRAY8_TO_STREAM (p, p_uid); /* UID */
1012
1013 if (rw_i93_send_to_lower (p_cmd))
1014 {
1015 rw_cb.tcb.i93.sent_cmd = I93_CMD_SELECT;
1016 return NFC_STATUS_OK;
1017 }
1018 else
1019 {
1020 return NFC_STATUS_FAILED;
1021 }
1022}
1023
1024/*******************************************************************************
1025**
1026** Function rw_i93_send_cmd_reset_to_ready
1027**
1028** Description Send Reset to Ready Request to VICC
1029**
1030** Returns tNFC_STATUS
1031**
1032*******************************************************************************/
1033tNFC_STATUS rw_i93_send_cmd_reset_to_ready (void)
1034{
1035 BT_HDR *p_cmd;
1036 UINT8 *p;
1037
1038 RW_TRACE_DEBUG0 ("rw_i93_send_cmd_reset_to_ready ()");
1039
1040 p_cmd = (BT_HDR *) GKI_getpoolbuf (NFC_RW_POOL_ID);
1041
1042 if (!p_cmd)
1043 {
1044 RW_TRACE_ERROR0 ("rw_i93_send_cmd_reset_to_ready (): Cannot allocate buffer");
1045 return NFC_STATUS_NO_BUFFERS;
1046 }
1047
1048 p_cmd->offset = NCI_MSG_OFFSET_SIZE + NCI_DATA_HDR_SIZE;
1049 p_cmd->len = 10 ;
1050 p = (UINT8 *) (p_cmd + 1) + p_cmd->offset;
1051
1052 /* Flags */
1053 UINT8_TO_STREAM (p, (I93_FLAG_ADDRESS_SET | RW_I93_FLAG_SUB_CARRIER | RW_I93_FLAG_DATA_RATE));
1054
1055 /* Command Code */
1056 UINT8_TO_STREAM (p, I93_CMD_RESET_TO_READY);
1057
1058 /* Parameters */
1059 ARRAY8_TO_STREAM (p, rw_cb.tcb.i93.uid); /* UID */
1060
1061 if (rw_i93_send_to_lower (p_cmd))
1062 {
1063 rw_cb.tcb.i93.sent_cmd = I93_CMD_RESET_TO_READY;
1064 return NFC_STATUS_OK;
1065 }
1066 else
1067 {
1068 return NFC_STATUS_FAILED;
1069 }
1070}
1071
1072/*******************************************************************************
1073**
1074** Function rw_i93_send_cmd_write_afi
1075**
1076** Description Send Write AFI Request to VICC
1077**
1078** Returns tNFC_STATUS
1079**
1080*******************************************************************************/
1081tNFC_STATUS rw_i93_send_cmd_write_afi (UINT8 afi)
1082{
1083 BT_HDR *p_cmd;
1084 UINT8 *p;
1085
1086 RW_TRACE_DEBUG0 ("rw_i93_send_cmd_write_afi ()");
1087
1088 p_cmd = (BT_HDR *) GKI_getpoolbuf (NFC_RW_POOL_ID);
1089
1090 if (!p_cmd)
1091 {
1092 RW_TRACE_ERROR0 ("rw_i93_send_cmd_write_afi (): Cannot allocate buffer");
1093 return NFC_STATUS_NO_BUFFERS;
1094 }
1095
1096 p_cmd->offset = NCI_MSG_OFFSET_SIZE + NCI_DATA_HDR_SIZE;
1097 p_cmd->len = 11;
1098 p = (UINT8 *) (p_cmd + 1) + p_cmd->offset;
1099
1100 /* Flags */
1101 UINT8_TO_STREAM (p, (I93_FLAG_ADDRESS_SET | RW_I93_FLAG_SUB_CARRIER | RW_I93_FLAG_DATA_RATE));
1102
1103 /* Command Code */
1104 UINT8_TO_STREAM (p, I93_CMD_WRITE_AFI);
1105
1106 /* Parameters */
1107 ARRAY8_TO_STREAM (p, rw_cb.tcb.i93.uid); /* UID */
1108 UINT8_TO_STREAM (p, afi); /* AFI */
1109
1110 if (rw_i93_send_to_lower (p_cmd))
1111 {
1112 rw_cb.tcb.i93.sent_cmd = I93_CMD_WRITE_AFI;
1113 return NFC_STATUS_OK;
1114 }
1115 else
1116 {
1117 return NFC_STATUS_FAILED;
1118 }
1119}
1120
1121/*******************************************************************************
1122**
1123** Function rw_i93_send_cmd_lock_afi
1124**
1125** Description Send Lock AFI Request to VICC
1126**
1127** Returns tNFC_STATUS
1128**
1129*******************************************************************************/
1130tNFC_STATUS rw_i93_send_cmd_lock_afi (void)
1131{
1132 BT_HDR *p_cmd;
1133 UINT8 *p;
1134
1135 RW_TRACE_DEBUG0 ("rw_i93_send_cmd_lock_afi ()");
1136
1137 p_cmd = (BT_HDR *) GKI_getpoolbuf (NFC_RW_POOL_ID);
1138
1139 if (!p_cmd)
1140 {
1141 RW_TRACE_ERROR0 ("rw_i93_send_cmd_lock_afi (): Cannot allocate buffer");
1142 return NFC_STATUS_NO_BUFFERS;
1143 }
1144
1145 p_cmd->offset = NCI_MSG_OFFSET_SIZE + NCI_DATA_HDR_SIZE;
1146 p_cmd->len = 10;
1147 p = (UINT8 *) (p_cmd + 1) + p_cmd->offset;
1148
1149 /* Flags */
1150 UINT8_TO_STREAM (p, (I93_FLAG_ADDRESS_SET | RW_I93_FLAG_SUB_CARRIER | RW_I93_FLAG_DATA_RATE));
1151
1152 /* Command Code */
1153 UINT8_TO_STREAM (p, I93_CMD_LOCK_AFI);
1154
1155 /* Parameters */
1156 ARRAY8_TO_STREAM (p, rw_cb.tcb.i93.uid); /* UID */
1157
1158 if (rw_i93_send_to_lower (p_cmd))
1159 {
1160 rw_cb.tcb.i93.sent_cmd = I93_CMD_LOCK_AFI;
1161 return NFC_STATUS_OK;
1162 }
1163 else
1164 {
1165 return NFC_STATUS_FAILED;
1166 }
1167}
1168
1169/*******************************************************************************
1170**
1171** Function rw_i93_send_cmd_write_dsfid
1172**
1173** Description Send Write DSFID Request to VICC
1174**
1175** Returns tNFC_STATUS
1176**
1177*******************************************************************************/
1178tNFC_STATUS rw_i93_send_cmd_write_dsfid (UINT8 dsfid)
1179{
1180 BT_HDR *p_cmd;
1181 UINT8 *p;
1182
1183 RW_TRACE_DEBUG0 ("rw_i93_send_cmd_write_dsfid ()");
1184
1185 p_cmd = (BT_HDR *) GKI_getpoolbuf (NFC_RW_POOL_ID);
1186
1187 if (!p_cmd)
1188 {
1189 RW_TRACE_ERROR0 ("rw_i93_send_cmd_write_dsfid (): Cannot allocate buffer");
1190 return NFC_STATUS_NO_BUFFERS;
1191 }
1192
1193 p_cmd->offset = NCI_MSG_OFFSET_SIZE + NCI_DATA_HDR_SIZE;
1194 p_cmd->len = 11;
1195 p = (UINT8 *) (p_cmd + 1) + p_cmd->offset;
1196
1197 /* Flags */
1198 UINT8_TO_STREAM (p, (I93_FLAG_ADDRESS_SET | RW_I93_FLAG_SUB_CARRIER | RW_I93_FLAG_DATA_RATE));
1199
1200 /* Command Code */
1201 UINT8_TO_STREAM (p, I93_CMD_WRITE_DSFID);
1202
1203 /* Parameters */
1204 ARRAY8_TO_STREAM (p, rw_cb.tcb.i93.uid); /* UID */
1205 UINT8_TO_STREAM (p, dsfid); /* DSFID */
1206
1207 if (rw_i93_send_to_lower (p_cmd))
1208 {
1209 rw_cb.tcb.i93.sent_cmd = I93_CMD_WRITE_DSFID;
1210 return NFC_STATUS_OK;
1211 }
1212 else
1213 {
1214 return NFC_STATUS_FAILED;
1215 }
1216}
1217
1218/*******************************************************************************
1219**
1220** Function rw_i93_send_cmd_lock_dsfid
1221**
1222** Description Send Lock DSFID Request to VICC
1223**
1224** Returns tNFC_STATUS
1225**
1226*******************************************************************************/
1227tNFC_STATUS rw_i93_send_cmd_lock_dsfid (void)
1228{
1229 BT_HDR *p_cmd;
1230 UINT8 *p;
1231
1232 RW_TRACE_DEBUG0 ("rw_i93_send_cmd_lock_dsfid ()");
1233
1234 p_cmd = (BT_HDR *) GKI_getpoolbuf (NFC_RW_POOL_ID);
1235
1236 if (!p_cmd)
1237 {
1238 RW_TRACE_ERROR0 ("rw_i93_send_cmd_lock_dsfid (): Cannot allocate buffer");
1239 return NFC_STATUS_NO_BUFFERS;
1240 }
1241
1242 p_cmd->offset = NCI_MSG_OFFSET_SIZE + NCI_DATA_HDR_SIZE;
1243 p_cmd->len = 10;
1244 p = (UINT8 *) (p_cmd + 1) + p_cmd->offset;
1245
1246 /* Flags */
1247 UINT8_TO_STREAM (p, (I93_FLAG_ADDRESS_SET | RW_I93_FLAG_SUB_CARRIER | RW_I93_FLAG_DATA_RATE));
1248
1249 /* Command Code */
1250 UINT8_TO_STREAM (p, I93_CMD_LOCK_DSFID);
1251
1252 /* Parameters */
1253 ARRAY8_TO_STREAM (p, rw_cb.tcb.i93.uid); /* UID */
1254
1255 if (rw_i93_send_to_lower (p_cmd))
1256 {
1257 rw_cb.tcb.i93.sent_cmd = I93_CMD_LOCK_DSFID;
1258 return NFC_STATUS_OK;
1259 }
1260 else
1261 {
1262 return NFC_STATUS_FAILED;
1263 }
1264}
1265
1266/*******************************************************************************
1267**
1268** Function rw_i93_send_cmd_get_sys_info
1269**
1270** Description Send Get System Information Request to VICC
1271**
1272** Returns tNFC_STATUS
1273**
1274*******************************************************************************/
Evan Chu85b7e842013-01-18 11:02:50 -05001275tNFC_STATUS rw_i93_send_cmd_get_sys_info (UINT8 *p_uid, UINT8 extra_flags)
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001276{
1277 BT_HDR *p_cmd;
1278 UINT8 *p;
1279
1280 RW_TRACE_DEBUG0 ("rw_i93_send_cmd_get_sys_info ()");
1281
1282 p_cmd = (BT_HDR *) GKI_getpoolbuf (NFC_RW_POOL_ID);
1283
1284 if (!p_cmd)
1285 {
1286 RW_TRACE_ERROR0 ("rw_i93_send_cmd_get_sys_info (): Cannot allocate buffer");
1287 return NFC_STATUS_NO_BUFFERS;
1288 }
1289
1290 p_cmd->offset = NCI_MSG_OFFSET_SIZE + NCI_DATA_HDR_SIZE;
1291 p_cmd->len = 10;
1292 p = (UINT8 *) (p_cmd + 1) + p_cmd->offset;
1293
1294 /* Flags */
Evan Chu85b7e842013-01-18 11:02:50 -05001295 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 -08001296
1297 /* Command Code */
1298 UINT8_TO_STREAM (p, I93_CMD_GET_SYS_INFO);
1299
1300 /* Parameters */
1301 if (p_uid)
1302 {
1303 ARRAY8_TO_STREAM (p, p_uid); /* UID */
1304 }
1305 else
1306 {
1307 ARRAY8_TO_STREAM (p, rw_cb.tcb.i93.uid); /* UID */
1308 }
1309
1310 if (rw_i93_send_to_lower (p_cmd))
1311 {
1312 rw_cb.tcb.i93.sent_cmd = I93_CMD_GET_SYS_INFO;
1313 return NFC_STATUS_OK;
1314 }
1315 else
1316 {
1317 return NFC_STATUS_FAILED;
1318 }
1319}
1320
1321/*******************************************************************************
1322**
1323** Function rw_i93_send_cmd_get_multi_block_sec
1324**
1325** Description Send Get Multiple Block Security Status Request to VICC
1326**
1327** Returns tNFC_STATUS
1328**
1329*******************************************************************************/
Evan Chu85b7e842013-01-18 11:02:50 -05001330tNFC_STATUS rw_i93_send_cmd_get_multi_block_sec (UINT16 first_block_number,
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001331 UINT16 number_blocks)
1332{
1333 BT_HDR *p_cmd;
Evan Chu85b7e842013-01-18 11:02:50 -05001334 UINT8 *p, flags;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001335
1336 RW_TRACE_DEBUG0 ("rw_i93_send_cmd_get_multi_block_sec ()");
1337
1338 p_cmd = (BT_HDR *) GKI_getpoolbuf (NFC_RW_POOL_ID);
1339
1340 if (!p_cmd)
1341 {
1342 RW_TRACE_ERROR0 ("rw_i93_send_cmd_get_multi_block_sec (): Cannot allocate buffer");
1343 return NFC_STATUS_NO_BUFFERS;
1344 }
1345
1346 p_cmd->offset = NCI_MSG_OFFSET_SIZE + NCI_DATA_HDR_SIZE;
1347 p_cmd->len = 12;
1348 p = (UINT8 *) (p_cmd + 1) + p_cmd->offset;
1349
1350 /* Flags */
Evan Chu85b7e842013-01-18 11:02:50 -05001351 flags = (I93_FLAG_ADDRESS_SET | RW_I93_FLAG_SUB_CARRIER | RW_I93_FLAG_DATA_RATE);
1352
1353 if (rw_cb.tcb.i93.intl_flags & RW_I93_FLAG_16BIT_NUM_BLOCK)
1354 flags |= I93_FLAG_PROT_EXT_YES;
1355
1356 UINT8_TO_STREAM (p, flags);
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001357
1358 /* Command Code */
1359 UINT8_TO_STREAM (p, I93_CMD_GET_MULTI_BLK_SEC);
1360
1361 /* Parameters */
1362 ARRAY8_TO_STREAM (p, rw_cb.tcb.i93.uid); /* UID */
Evan Chu85b7e842013-01-18 11:02:50 -05001363
1364 if (rw_cb.tcb.i93.intl_flags & RW_I93_FLAG_16BIT_NUM_BLOCK)
1365 {
1366 UINT16_TO_STREAM (p, first_block_number); /* First block number */
1367 UINT16_TO_STREAM (p, number_blocks - 1); /* Number of blocks, 0x00 to read one block */
1368 p_cmd->len += 2;
1369 }
1370 else
1371 {
1372 UINT8_TO_STREAM (p, first_block_number); /* First block number */
1373 UINT8_TO_STREAM (p, number_blocks - 1); /* Number of blocks, 0x00 to read one block */
1374 }
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001375
1376 if (rw_i93_send_to_lower (p_cmd))
1377 {
1378 rw_cb.tcb.i93.sent_cmd = I93_CMD_GET_MULTI_BLK_SEC;
1379 return NFC_STATUS_OK;
1380 }
1381 else
1382 {
1383 return NFC_STATUS_FAILED;
1384 }
1385}
1386
1387/*******************************************************************************
1388**
1389** Function rw_i93_get_next_blocks
1390**
1391** Description Read as many blocks as possible (up to RW_I93_READ_MULTI_BLOCK_SIZE)
1392**
1393** Returns tNFC_STATUS
1394**
1395*******************************************************************************/
1396tNFC_STATUS rw_i93_get_next_blocks (UINT16 offset)
1397{
1398 tRW_I93_CB *p_i93 = &rw_cb.tcb.i93;
Evan Chu85b7e842013-01-18 11:02:50 -05001399 UINT16 first_block;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001400 UINT16 num_block;
1401
Evan Chu85b7e842013-01-18 11:02:50 -05001402 RW_TRACE_DEBUG0 ("rw_i93_get_next_blocks ()");
1403
1404 first_block = offset / p_i93->block_size;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001405
1406 /* more blocks, more efficent but more error rate */
1407
1408 if (p_i93->intl_flags & RW_I93_FLAG_READ_MULTI_BLOCK)
1409 {
1410 num_block = RW_I93_READ_MULTI_BLOCK_SIZE / p_i93->block_size;
1411
1412 if (num_block + first_block > p_i93->num_block)
1413 num_block = p_i93->num_block - first_block;
1414
Evan Chu85b7e842013-01-18 11:02:50 -05001415 if (p_i93->uid[1] == I93_UID_IC_MFG_CODE_STM)
1416 {
1417 /* LRIS64K, M24LR64-R, M24LR04E-R, M24LR16E-R, M24LR64E-R requires
1418 ** The max number of blocks is 32 and they are all located in the same sector.
1419 ** The sector is 32 blocks of 4 bytes.
1420 */
1421 if ( (p_i93->product_version == RW_I93_STM_LRIS64K)
1422 ||(p_i93->product_version == RW_I93_STM_M24LR64_R)
1423 ||(p_i93->product_version == RW_I93_STM_M24LR04E_R)
1424 ||(p_i93->product_version == RW_I93_STM_M24LR16E_R)
1425 ||(p_i93->product_version == RW_I93_STM_M24LR64E_R) )
1426 {
1427 if (num_block > I93_STM_MAX_BLOCKS_PER_READ)
1428 num_block = I93_STM_MAX_BLOCKS_PER_READ;
1429
1430 if ((first_block / I93_STM_BLOCKS_PER_SECTOR)
1431 != ((first_block + num_block - 1) / I93_STM_BLOCKS_PER_SECTOR))
1432 {
1433 num_block = I93_STM_BLOCKS_PER_SECTOR - (first_block % I93_STM_BLOCKS_PER_SECTOR);
1434 }
1435 }
1436 }
1437
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001438 return rw_i93_send_cmd_read_multi_blocks (first_block, num_block);
1439 }
1440 else
1441 {
1442 return rw_i93_send_cmd_read_single_block (first_block, FALSE);
1443 }
1444}
1445
1446/*******************************************************************************
1447**
Evan Chu85b7e842013-01-18 11:02:50 -05001448** Function rw_i93_get_next_block_sec
1449**
1450** Description Get as many security of blocks as possible from p_i93->rw_offset
1451** (up to RW_I93_GET_MULTI_BLOCK_SEC_SIZE)
1452**
1453** Returns tNFC_STATUS
1454**
1455*******************************************************************************/
1456tNFC_STATUS rw_i93_get_next_block_sec (void)
1457{
1458 tRW_I93_CB *p_i93 = &rw_cb.tcb.i93;
1459 UINT16 num_blocks;
1460
1461 RW_TRACE_DEBUG0 ("rw_i93_get_next_block_sec ()");
1462
1463 if (p_i93->num_block <= p_i93->rw_offset)
1464 {
1465 RW_TRACE_ERROR2 ("rw_offset(0x%x) must be less than num_block(0x%x)",
1466 p_i93->rw_offset, p_i93->num_block);
1467 return NFC_STATUS_FAILED;
1468 }
1469
1470 num_blocks = p_i93->num_block - p_i93->rw_offset;
1471
1472 if (num_blocks > RW_I93_GET_MULTI_BLOCK_SEC_SIZE)
1473 num_blocks = RW_I93_GET_MULTI_BLOCK_SEC_SIZE;
1474
1475 return rw_i93_send_cmd_get_multi_block_sec (p_i93->rw_offset, num_blocks);
1476}
1477
1478/*******************************************************************************
1479**
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001480** Function rw_i93_sm_detect_ndef
1481**
1482** Description Process NDEF detection procedure
1483**
1484** 1. Get UID if not having yet
1485** 2. Get System Info if not having yet
1486** 3. Read first block for CC
1487** 4. Search NDEF Type and length
1488** 5. Get block status to get max NDEF size and read-only status
1489**
1490** Returns void
1491**
1492*******************************************************************************/
1493void rw_i93_sm_detect_ndef (BT_HDR *p_resp)
1494{
1495 UINT8 *p = (UINT8 *) (p_resp + 1) + p_resp->offset, *p_uid;
Evan Chu85b7e842013-01-18 11:02:50 -05001496 UINT8 flags, u8 = 0, cc[4];
1497 UINT16 length = p_resp->len, xx, block, first_block, last_block, num_blocks;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001498 tRW_I93_CB *p_i93 = &rw_cb.tcb.i93;
1499 tRW_DATA rw_data;
1500 tNFC_STATUS status = NFC_STATUS_FAILED;
1501
1502#if (BT_TRACE_VERBOSE == TRUE)
1503 RW_TRACE_DEBUG2 ("rw_i93_sm_detect_ndef () sub_state:%s (0x%x)",
1504 rw_i93_get_sub_state_name (p_i93->sub_state), p_i93->sub_state);
1505#else
1506 RW_TRACE_DEBUG1 ("rw_i93_sm_detect_ndef () sub_state:0x%x", p_i93->sub_state);
1507#endif
1508
1509 STREAM_TO_UINT8 (flags, p);
1510 length--;
1511
1512 if (flags & I93_FLAG_ERROR_DETECTED)
1513 {
Evan Chu85b7e842013-01-18 11:02:50 -05001514 if ((length) && (rw_i93_check_sys_info_prot_ext(*p)))
1515 {
1516 /* getting system info with protocol extension flag */
1517 /* This STM tag supports more than 2040 bytes */
1518 p_i93->intl_flags |= RW_I93_FLAG_16BIT_NUM_BLOCK;
1519 }
1520 else
1521 {
1522 RW_TRACE_DEBUG1 ("Got error flags (0x%02x)", flags);
1523 rw_i93_handle_error (NFC_STATUS_FAILED);
1524 }
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001525 return;
1526 }
1527
1528 switch (p_i93->sub_state)
1529 {
1530 case RW_I93_SUBSTATE_WAIT_UID:
1531
1532 STREAM_TO_UINT8 (u8, p); /* DSFID */
1533 p_uid = p_i93->uid;
1534 STREAM_TO_ARRAY8 (p_uid, p);
1535
1536 if (u8 != I93_DFS_UNSUPPORTED)
1537 {
1538 /* if Data Storage Format is unknown */
1539 RW_TRACE_DEBUG1 ("Got unknown DSFID (0x%02x)", u8);
1540 rw_i93_handle_error (NFC_STATUS_FAILED);
1541 }
1542 else
1543 {
1544 /* get system information to get memory size */
Evan Chu85b7e842013-01-18 11:02:50 -05001545 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 -08001546 {
1547 p_i93->sub_state = RW_I93_SUBSTATE_WAIT_SYS_INFO;
1548 }
1549 else
1550 {
1551 rw_i93_handle_error (NFC_STATUS_FAILED);
1552 }
1553 }
1554 break;
1555
1556 case RW_I93_SUBSTATE_WAIT_SYS_INFO:
1557
Evan Chu85b7e842013-01-18 11:02:50 -05001558 p_i93->block_size = 0;
1559 p_i93->num_block = 0;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001560
Evan Chu85b7e842013-01-18 11:02:50 -05001561 if (!rw_i93_process_sys_info (p))
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001562 {
Evan Chu85b7e842013-01-18 11:02:50 -05001563 /* retrying with protocol extension flag */
1564 break;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001565 }
1566
Evan Chu85b7e842013-01-18 11:02:50 -05001567 if ((p_i93->block_size == 0)||(p_i93->num_block == 0))
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001568 {
1569 RW_TRACE_DEBUG0 ("Unable to get tag memory size");
1570 rw_i93_handle_error (status);
1571 }
1572 else
1573 {
1574 /* read CC in the first block */
Evan Chu85b7e842013-01-18 11:02:50 -05001575 if (rw_i93_send_cmd_read_single_block (0x0000, FALSE) == NFC_STATUS_OK)
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001576 {
1577 p_i93->sub_state = RW_I93_SUBSTATE_WAIT_CC;
1578 }
1579 else
1580 {
1581 rw_i93_handle_error (NFC_STATUS_FAILED);
1582 }
1583 }
1584 break;
1585
1586 case RW_I93_SUBSTATE_WAIT_CC:
1587
1588 /* assume block size is more than 4 */
1589 STREAM_TO_ARRAY (cc, p, 4);
1590
1591 status = NFC_STATUS_FAILED;
1592
1593 /*
1594 ** Capability Container (CC)
1595 **
1596 ** CC[0] : magic number (0xE1)
1597 ** CC[1] : Bit 7-6:Major version number
1598 ** : Bit 5-4:Minor version number
1599 ** : Bit 3-2:Read access condition (00b: read access granted without any security)
1600 ** : Bit 1-0:Write access condition (00b: write access granted without any security)
Evan Chu85b7e842013-01-18 11:02:50 -05001601 ** CC[2] : Memory size in 8 bytes (Ex. 0x04 is 32 bytes) [STM, set to 0xFF if more than 2040bytes]
1602 ** CC[3] : Bit 0:Read multiple blocks is supported [NXP, STM]
1603 ** : Bit 1:Inventory page read is supported [NXP]
1604 ** : Bit 2:More than 2040 bytes are supported [STM]
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001605 */
1606
1607 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]);
1608 RW_TRACE_DEBUG2 ("rw_i93_sm_detect_ndef (): Total blocks:0x%04X, Block size:0x%02X", p_i93->num_block, p_i93->block_size );
1609
1610 if ( (cc[0] == I93_ICODE_CC_MAGIC_NUMER)
Evan Chu85b7e842013-01-18 11:02:50 -05001611 &&( (cc[3] & I93_STM_CC_OVERFLOW_MASK)
1612 ||(cc[2] * 8) == (p_i93->num_block * p_i93->block_size) ) )
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001613 {
1614 if ((cc[1] & I93_ICODE_CC_READ_ACCESS_MASK) == I93_ICODE_CC_READ_ACCESS_GRANTED)
1615 {
1616 if ((cc[1] & I93_ICODE_CC_WRITE_ACCESS_MASK) != I93_ICODE_CC_WRITE_ACCESS_GRANTED)
1617 {
1618 /* read-only or password required to write */
1619 p_i93->intl_flags |= RW_I93_FLAG_READ_ONLY;
1620 }
1621 if (cc[3] & I93_ICODE_CC_MBREAD_MASK)
1622 {
1623 /* tag supports read multi blocks command */
1624 p_i93->intl_flags |= RW_I93_FLAG_READ_MULTI_BLOCK;
1625 }
1626 status = NFC_STATUS_OK;
1627 }
1628 }
1629
1630 if (status == NFC_STATUS_OK)
1631 {
1632 /* seach NDEF TLV from offset 4 */
1633 p_i93->rw_offset = 4;
1634
1635 if (rw_i93_get_next_blocks (p_i93->rw_offset) == NFC_STATUS_OK)
1636 {
1637 p_i93->sub_state = RW_I93_SUBSTATE_SEARCH_NDEF_TLV;
1638 p_i93->tlv_detect_state = RW_I93_TLV_DETECT_STATE_TYPE;
1639 }
1640 else
1641 {
1642 rw_i93_handle_error (NFC_STATUS_FAILED);
1643 }
1644 }
1645 else
1646 {
1647 rw_i93_handle_error (NFC_STATUS_FAILED);
1648 }
1649 break;
1650
1651 case RW_I93_SUBSTATE_SEARCH_NDEF_TLV:
1652
1653 /* search TLV within read blocks */
Evan Chu85b7e842013-01-18 11:02:50 -05001654 for (xx = 0; xx < length; xx++)
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001655 {
1656 /* if looking for type */
1657 if (p_i93->tlv_detect_state == RW_I93_TLV_DETECT_STATE_TYPE)
1658 {
Evan Chu85b7e842013-01-18 11:02:50 -05001659 if (*(p + xx) == I93_ICODE_TLV_TYPE_NULL)
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001660 {
1661 continue;
1662 }
Evan Chu85b7e842013-01-18 11:02:50 -05001663 else if ( (*(p + xx) == I93_ICODE_TLV_TYPE_NDEF)
1664 ||(*(p + xx) == I93_ICODE_TLV_TYPE_PROP) )
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001665 {
1666 /* store found type and get length field */
Evan Chu85b7e842013-01-18 11:02:50 -05001667 p_i93->tlv_type = *(p + xx);
1668 p_i93->ndef_tlv_start_offset = p_i93->rw_offset + xx;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001669
1670 p_i93->tlv_detect_state = RW_I93_TLV_DETECT_STATE_LENGTH_1;
1671 }
Evan Chu85b7e842013-01-18 11:02:50 -05001672 else if (*(p + xx) == I93_ICODE_TLV_TYPE_TERM)
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001673 {
1674 /* no NDEF TLV found */
1675 p_i93->tlv_type = I93_ICODE_TLV_TYPE_TERM;
1676 break;
1677 }
1678 else
1679 {
Evan Chu85b7e842013-01-18 11:02:50 -05001680 RW_TRACE_DEBUG1 ("Invalid type: 0x%02x", *(p + xx));
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001681 rw_i93_handle_error (NFC_STATUS_FAILED);
1682 return;
1683 }
1684 }
1685 else if (p_i93->tlv_detect_state == RW_I93_TLV_DETECT_STATE_LENGTH_1)
1686 {
1687 /* if 3 bytes length field */
Evan Chu85b7e842013-01-18 11:02:50 -05001688 if (*(p + xx) == 0xFF)
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001689 {
1690 /* need 2 more bytes for length field */
1691 p_i93->tlv_detect_state = RW_I93_TLV_DETECT_STATE_LENGTH_2;
1692 }
1693 else
1694 {
Evan Chu85b7e842013-01-18 11:02:50 -05001695 p_i93->tlv_length = *(p + xx);
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001696 p_i93->tlv_detect_state = RW_I93_TLV_DETECT_STATE_VALUE;
1697
1698 if (p_i93->tlv_type == I93_ICODE_TLV_TYPE_NDEF)
1699 {
1700 p_i93->ndef_tlv_last_offset = p_i93->ndef_tlv_start_offset + 1 + p_i93->tlv_length;
1701 break;
1702 }
1703 }
1704 }
1705 else if (p_i93->tlv_detect_state == RW_I93_TLV_DETECT_STATE_LENGTH_2)
1706 {
1707 /* the second byte of 3 bytes length field */
Evan Chu85b7e842013-01-18 11:02:50 -05001708 p_i93->tlv_length = *(p + xx);
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001709 p_i93->tlv_detect_state = RW_I93_TLV_DETECT_STATE_LENGTH_3;
1710 }
1711 else if (p_i93->tlv_detect_state == RW_I93_TLV_DETECT_STATE_LENGTH_3)
1712 {
1713 /* the last byte of 3 bytes length field */
Evan Chu85b7e842013-01-18 11:02:50 -05001714 p_i93->tlv_length = (p_i93->tlv_length << 8) + *(p + xx);
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001715 p_i93->tlv_detect_state = RW_I93_TLV_DETECT_STATE_VALUE;
1716
1717 if (p_i93->tlv_type == I93_ICODE_TLV_TYPE_NDEF)
1718 {
1719 p_i93->ndef_tlv_last_offset = p_i93->ndef_tlv_start_offset + 3 + p_i93->tlv_length;
1720 break;
1721 }
1722 }
1723 else if (p_i93->tlv_detect_state == RW_I93_TLV_DETECT_STATE_VALUE)
1724 {
1725 /* this is other than NDEF TLV */
Evan Chu85b7e842013-01-18 11:02:50 -05001726 if (p_i93->tlv_length <= length - xx)
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001727 {
1728 /* skip value field */
Evan Chu85b7e842013-01-18 11:02:50 -05001729 xx += (UINT8)p_i93->tlv_length;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001730 p_i93->tlv_detect_state = RW_I93_TLV_DETECT_STATE_TYPE;
1731 }
1732 else
1733 {
1734 /* read more data */
Evan Chu85b7e842013-01-18 11:02:50 -05001735 p_i93->tlv_length -= (length - xx);
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001736 break;
1737 }
1738 }
1739 }
1740
1741 /* found NDEF TLV and read length field */
1742 if ( (p_i93->tlv_type == I93_ICODE_TLV_TYPE_NDEF)
1743 &&(p_i93->tlv_detect_state == RW_I93_TLV_DETECT_STATE_VALUE) )
1744 {
1745 p_i93->ndef_length = p_i93->tlv_length;
1746
1747 /* get lock status to see if read-only */
1748 if ( (p_i93->product_version == RW_I93_TAG_IT_HF_I_STD_CHIP_INLAY)
1749 ||(p_i93->product_version == RW_I93_TAG_IT_HF_I_PRO_CHIP_INLAY)
1750 ||((p_i93->uid[1] == I93_UID_IC_MFG_CODE_NXP) && (p_i93->ic_reference & I93_ICODE_IC_REF_MBREAD_MASK)) )
1751 {
1752 /* these doesn't support GetMultiBlockSecurityStatus */
1753
1754 p_i93->rw_offset = p_i93->ndef_tlv_start_offset;
Evan Chu85b7e842013-01-18 11:02:50 -05001755 first_block = p_i93->ndef_tlv_start_offset / p_i93->block_size;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001756
1757 /* read block to get lock status */
1758 rw_i93_send_cmd_read_single_block (first_block, TRUE);
1759 p_i93->sub_state = RW_I93_SUBSTATE_CHECK_LOCK_STATUS;
1760 }
1761 else
1762 {
Evan Chu85b7e842013-01-18 11:02:50 -05001763 /* block offset for read-only check */
1764 p_i93->rw_offset = 0;
1765
1766 if (rw_i93_get_next_block_sec () == NFC_STATUS_OK)
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001767 {
1768 p_i93->sub_state = RW_I93_SUBSTATE_CHECK_LOCK_STATUS;
1769 }
1770 else
1771 {
1772 rw_i93_handle_error (NFC_STATUS_FAILED);
1773 }
1774 }
1775 }
1776 else
1777 {
1778 /* read more data */
1779 p_i93->rw_offset += length;
1780
1781 if (p_i93->rw_offset >= p_i93->block_size * p_i93->num_block)
1782 {
1783 rw_i93_handle_error (NFC_STATUS_FAILED);
1784 }
1785 else if (rw_i93_get_next_blocks (p_i93->rw_offset) == NFC_STATUS_OK)
1786 {
1787 p_i93->sub_state = RW_I93_SUBSTATE_SEARCH_NDEF_TLV;
1788 }
1789 else
1790 {
1791 rw_i93_handle_error (NFC_STATUS_FAILED);
1792 }
1793 }
1794 break;
1795
1796 case RW_I93_SUBSTATE_CHECK_LOCK_STATUS:
1797
1798 if ( (p_i93->product_version == RW_I93_TAG_IT_HF_I_STD_CHIP_INLAY)
1799 ||(p_i93->product_version == RW_I93_TAG_IT_HF_I_PRO_CHIP_INLAY)
1800 ||((p_i93->uid[1] == I93_UID_IC_MFG_CODE_NXP) && (p_i93->ic_reference & I93_ICODE_IC_REF_MBREAD_MASK)) )
1801 {
1802 /* these doesn't support GetMultiBlockSecurityStatus */
1803
Evan Chu85b7e842013-01-18 11:02:50 -05001804 block = (p_i93->rw_offset / p_i93->block_size);
1805 last_block = (p_i93->ndef_tlv_last_offset / p_i93->block_size);
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001806
1807 if ((*p) & I93_BLOCK_LOCKED)
1808 {
Evan Chu85b7e842013-01-18 11:02:50 -05001809 if (block <= last_block)
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001810 {
1811 p_i93->intl_flags |= RW_I93_FLAG_READ_ONLY;
1812 }
1813 }
1814 else
1815 {
1816 /* if we need to check more user blocks */
Evan Chu85b7e842013-01-18 11:02:50 -05001817 if (block + 1 < p_i93->num_block)
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001818 {
1819 p_i93->rw_offset += p_i93->block_size;
1820
1821 /* read block to get lock status */
Evan Chu85b7e842013-01-18 11:02:50 -05001822 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 -08001823 break;
1824 }
1825 }
1826
1827 p_i93->max_ndef_length = p_i93->ndef_length
1828 /* add available bytes including the last block of NDEF TLV */
Evan Chu85b7e842013-01-18 11:02:50 -05001829 + (p_i93->block_size * (block - last_block) + 1)
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001830 - (p_i93->ndef_tlv_last_offset % p_i93->block_size)
1831 - 1;
1832 }
1833 else
1834 {
Evan Chu85b7e842013-01-18 11:02:50 -05001835 if (p_i93->rw_offset == 0)
1836 {
1837 p_i93->max_ndef_length = p_i93->ndef_length
1838 /* add available bytes in the last block of NDEF TLV */
1839 + p_i93->block_size
1840 - (p_i93->ndef_tlv_last_offset % p_i93->block_size)
1841 - 1;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001842
Evan Chu85b7e842013-01-18 11:02:50 -05001843 first_block = (p_i93->ndef_tlv_start_offset / p_i93->block_size);
1844 }
1845 else
1846 {
1847 first_block = 0;
1848 }
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001849
Evan Chu85b7e842013-01-18 11:02:50 -05001850 last_block = (p_i93->ndef_tlv_last_offset / p_i93->block_size);
1851 num_blocks = length;
1852
1853 for (block = first_block; block < num_blocks; block++)
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001854 {
1855 /* if any block of NDEF TLV is locked */
Evan Chu85b7e842013-01-18 11:02:50 -05001856 if ((block + p_i93->rw_offset) <= last_block)
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001857 {
Evan Chu85b7e842013-01-18 11:02:50 -05001858 if (*(p + block) & I93_BLOCK_LOCKED)
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001859 {
1860 p_i93->intl_flags |= RW_I93_FLAG_READ_ONLY;
1861 break;
1862 }
1863 }
1864 else
1865 {
Evan Chu85b7e842013-01-18 11:02:50 -05001866 if (*(p + block) & I93_BLOCK_LOCKED)
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001867 {
1868 /* no more consecutive unlocked block */
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001869 break;
1870 }
1871 else
1872 {
1873 /* add block size if not locked */
1874 p_i93->max_ndef_length += p_i93->block_size;
1875 }
1876 }
1877 }
Evan Chu85b7e842013-01-18 11:02:50 -05001878
1879 /* update next security of block to check */
1880 p_i93->rw_offset += num_blocks;
1881
1882 /* if need to check more */
1883 if (p_i93->num_block > p_i93->rw_offset)
1884 {
1885 if (rw_i93_get_next_block_sec () != NFC_STATUS_OK)
1886 {
1887 rw_i93_handle_error (NFC_STATUS_FAILED);
1888 }
1889 break;
1890 }
1891 }
1892
1893 /* check if need to adjust max NDEF length */
1894 if ( (p_i93->ndef_length < 0xFF)
1895 &&(p_i93->max_ndef_length >= 0xFF) )
1896 {
1897 /* 3 bytes length field must be used */
1898 p_i93->max_ndef_length -= 2;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001899 }
1900
1901 rw_data.ndef.status = NFC_STATUS_OK;
1902 rw_data.ndef.protocol = NFC_PROTOCOL_15693;
1903 rw_data.ndef.flags = 0;
1904 rw_data.ndef.flags |= RW_NDEF_FL_SUPPORTED;
1905 rw_data.ndef.flags |= RW_NDEF_FL_FORMATED;
1906 rw_data.ndef.flags |= RW_NDEF_FL_FORMATABLE;
1907 rw_data.ndef.cur_size = p_i93->ndef_length;
1908
1909 if (p_i93->intl_flags & RW_I93_FLAG_READ_ONLY)
1910 {
1911 rw_data.ndef.flags |= RW_NDEF_FL_READ_ONLY;
1912 rw_data.ndef.max_size = p_i93->ndef_length;
1913 }
1914 else
1915 {
1916 rw_data.ndef.flags |= RW_NDEF_FL_HARD_LOCKABLE;
1917 rw_data.ndef.max_size = p_i93->max_ndef_length;
1918 }
1919
1920 p_i93->state = RW_I93_STATE_IDLE;
1921 p_i93->sent_cmd = 0;
1922
1923 RW_TRACE_DEBUG3 ("NDEF cur_size(%d),max_size (%d), flags (0x%x)",
1924 rw_data.ndef.cur_size,
1925 rw_data.ndef.max_size,
1926 rw_data.ndef.flags);
1927
1928 (*(rw_cb.p_cback)) (RW_I93_NDEF_DETECT_EVT, &rw_data);
1929 break;
1930
1931 default:
1932 break;
1933 }
1934}
1935
1936/*******************************************************************************
1937**
1938** Function rw_i93_sm_read_ndef
1939**
1940** Description Process NDEF read procedure
1941**
1942** Returns void
1943**
1944*******************************************************************************/
1945void rw_i93_sm_read_ndef (BT_HDR *p_resp)
1946{
1947 UINT8 *p = (UINT8 *) (p_resp + 1) + p_resp->offset;
1948 UINT8 flags;
1949 UINT16 offset, length = p_resp->len;
1950 tRW_I93_CB *p_i93 = &rw_cb.tcb.i93;
1951 tRW_DATA rw_data;
1952
1953 RW_TRACE_DEBUG0 ("rw_i93_sm_read_ndef ()");
1954
1955 STREAM_TO_UINT8 (flags, p);
1956 length--;
1957
1958 if (flags & I93_FLAG_ERROR_DETECTED)
1959 {
1960 RW_TRACE_DEBUG1 ("Got error flags (0x%02x)", flags);
1961 rw_i93_handle_error (NFC_STATUS_FAILED);
1962 return;
1963 }
1964
1965 /* if this is the first block */
1966 if (p_i93->rw_length == 0)
1967 {
1968 /* get start of NDEF in the first block */
1969 offset = p_i93->ndef_tlv_start_offset % p_i93->block_size;
1970
1971 if (p_i93->ndef_length < 0xFF)
1972 {
1973 offset += 2;
1974 }
1975 else
1976 {
1977 offset += 4;
1978 }
1979
1980 /* adjust offset if read more blocks because the first block doesn't have NDEF */
1981 offset -= (p_i93->rw_offset - p_i93->ndef_tlv_start_offset);
1982 }
1983 else
1984 {
1985 offset = 0;
1986 }
1987
1988 /* if read enough data to skip type and length field for the beginning */
1989 if (offset < length)
1990 {
1991 offset++; /* flags */
1992 p_resp->offset += offset;
1993 p_resp->len -= offset;
1994
1995 rw_data.data.status = NFC_STATUS_OK;
1996 rw_data.data.p_data = p_resp;
1997
1998 p_i93->rw_length += p_resp->len;
1999 }
2000
2001 /* if read all of NDEF data */
2002 if (p_i93->rw_length >= p_i93->ndef_length)
2003 {
2004 /* remove extra btyes in the last block */
2005 p_resp->len -= (p_i93->rw_length - p_i93->ndef_length);
2006
2007 p_i93->state = RW_I93_STATE_IDLE;
2008 p_i93->sent_cmd = 0;
2009
2010 RW_TRACE_DEBUG2 ("NDEF read complete read (%d)/total (%d)",
2011 p_resp->len,
2012 p_i93->ndef_length);
2013
2014 (*(rw_cb.p_cback)) (RW_I93_NDEF_READ_CPLT_EVT, &rw_data);
2015 }
2016 else
2017 {
2018 RW_TRACE_DEBUG2 ("NDEF read segment read (%d)/total (%d)",
2019 p_resp->len,
2020 p_i93->ndef_length);
2021
2022 (*(rw_cb.p_cback)) (RW_I93_NDEF_READ_EVT, &rw_data);
2023
2024 /* this will make read data from next block */
2025 p_i93->rw_offset += length;
2026
2027 if (rw_i93_get_next_blocks (p_i93->rw_offset) != NFC_STATUS_OK)
2028 {
2029 rw_i93_handle_error (NFC_STATUS_FAILED);
2030 }
2031 }
2032}
2033
2034/*******************************************************************************
2035**
2036** Function rw_i93_sm_update_ndef
2037**
2038** Description Process NDEF update procedure
2039**
2040** 1. Set length field to zero
2041** 2. Write NDEF and Terminator TLV
2042** 3. Set length field to NDEF length
2043**
2044** Returns void
2045**
2046*******************************************************************************/
2047void rw_i93_sm_update_ndef (BT_HDR *p_resp)
2048{
2049 UINT8 *p = (UINT8 *) (p_resp + 1) + p_resp->offset;
Evan Chu85b7e842013-01-18 11:02:50 -05002050 UINT8 flags, xx, length_offset, buff[I93_MAX_BLOCK_LENGH];
2051 UINT16 length = p_resp->len, block_number;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002052 tRW_I93_CB *p_i93 = &rw_cb.tcb.i93;
2053 tRW_DATA rw_data;
2054
2055#if (BT_TRACE_VERBOSE == TRUE)
2056 RW_TRACE_DEBUG2 ("rw_i93_sm_update_ndef () sub_state:%s (0x%x)",
2057 rw_i93_get_sub_state_name (p_i93->sub_state), p_i93->sub_state);
2058#else
2059 RW_TRACE_DEBUG1 ("rw_i93_sm_update_ndef () sub_state:0x%x", p_i93->sub_state);
2060#endif
2061
2062 STREAM_TO_UINT8 (flags, p);
2063 length--;
2064
2065 if (flags & I93_FLAG_ERROR_DETECTED)
2066 {
2067 if ( ( (p_i93->product_version == RW_I93_TAG_IT_HF_I_PLUS_INLAY)
2068 ||(p_i93->product_version == RW_I93_TAG_IT_HF_I_PLUS_CHIP)
2069 ||(p_i93->product_version == RW_I93_TAG_IT_HF_I_STD_CHIP_INLAY)
2070 ||(p_i93->product_version == RW_I93_TAG_IT_HF_I_PRO_CHIP_INLAY) )
2071 &&
2072 (*p == I93_ERROR_CODE_BLOCK_FAIL_TO_WRITE) )
2073 {
2074 /* ignore error */
2075 }
2076 else
2077 {
2078 RW_TRACE_DEBUG1 ("Got error flags (0x%02x)", flags);
2079 rw_i93_handle_error (NFC_STATUS_FAILED);
2080 return;
2081 }
2082 }
2083
2084 switch (p_i93->sub_state)
2085 {
2086 case RW_I93_SUBSTATE_RESET_LEN:
2087
2088 /* get offset of length field */
2089 length_offset = (p_i93->ndef_tlv_start_offset + 1) % p_i93->block_size;
2090
2091 /* set length to zero */
2092 *(p + length_offset) = 0x00;
2093
2094 if (p_i93->ndef_length > 0)
2095 {
2096 /* if 3 bytes length field is needed */
2097 if (p_i93->ndef_length >= 0xFF)
2098 {
2099 xx = length_offset + 3;
2100 }
2101 else
2102 {
2103 xx = length_offset + 1;
2104 }
2105
2106 /* write the first part of NDEF in the same block */
2107 for ( ; xx < p_i93->block_size; xx++)
2108 {
2109 if (p_i93->rw_length < p_i93->ndef_length)
2110 {
2111 *(p + xx) = *(p_i93->p_update_data + p_i93->rw_length++);
2112 }
2113 else
2114 {
2115 *(p + xx) = I93_ICODE_TLV_TYPE_NULL;
2116 }
2117 }
2118 }
2119
Evan Chu85b7e842013-01-18 11:02:50 -05002120 block_number = (p_i93->ndef_tlv_start_offset + 1) / p_i93->block_size;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002121
2122 if (rw_i93_send_cmd_write_single_block (block_number, p) == NFC_STATUS_OK)
2123 {
2124 /* update next writing offset */
2125 p_i93->rw_offset = (block_number + 1) * p_i93->block_size;
2126 p_i93->sub_state = RW_I93_SUBSTATE_WRITE_NDEF;
2127 }
2128 else
2129 {
2130 rw_i93_handle_error (NFC_STATUS_FAILED);
2131 }
2132 break;
2133
2134 case RW_I93_SUBSTATE_WRITE_NDEF:
2135
2136 /* if it's not the end of tag memory */
2137 if (p_i93->rw_offset < p_i93->block_size * p_i93->num_block)
2138 {
Evan Chu85b7e842013-01-18 11:02:50 -05002139 block_number = p_i93->rw_offset / p_i93->block_size;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002140
2141 /* if we have more data to write */
2142 if (p_i93->rw_length < p_i93->ndef_length)
2143 {
2144 p = p_i93->p_update_data + p_i93->rw_length;
2145
2146 p_i93->rw_offset += p_i93->block_size;
2147 p_i93->rw_length += p_i93->block_size;
2148
2149 /* if this is the last block of NDEF TLV */
2150 if (p_i93->rw_length > p_i93->ndef_length)
2151 {
2152 /* length of NDEF TLV in the block */
2153 xx = (UINT8) (p_i93->block_size - (p_i93->rw_length - p_i93->ndef_length));
2154
2155 /* set NULL TLV in the unused part of block */
2156 memset (buff, I93_ICODE_TLV_TYPE_NULL, p_i93->block_size);
2157 memcpy (buff, p, xx);
2158 p = buff;
2159
2160 /* if it's the end of tag memory */
2161 if ( (p_i93->rw_offset >= p_i93->block_size * p_i93->num_block)
2162 &&(xx < p_i93->block_size) )
2163 {
2164 buff[xx] = I93_ICODE_TLV_TYPE_TERM;
2165 }
2166
2167 p_i93->ndef_tlv_last_offset = p_i93->rw_offset - p_i93->block_size + xx - 1;
2168 }
2169
2170 if (rw_i93_send_cmd_write_single_block (block_number, p) != NFC_STATUS_OK)
2171 {
2172 rw_i93_handle_error (NFC_STATUS_FAILED);
2173 }
2174 }
2175 else
2176 {
2177 /* if this is the very next block of NDEF TLV */
2178 if (block_number == (p_i93->ndef_tlv_last_offset / p_i93->block_size) + 1)
2179 {
2180 p_i93->rw_offset += p_i93->block_size;
2181
2182 /* write Terminator TLV and NULL TLV */
2183 memset (buff, I93_ICODE_TLV_TYPE_NULL, p_i93->block_size);
2184 buff[0] = I93_ICODE_TLV_TYPE_TERM;
2185 p = buff;
2186
2187 if (rw_i93_send_cmd_write_single_block (block_number, p) != NFC_STATUS_OK)
2188 {
2189 rw_i93_handle_error (NFC_STATUS_FAILED);
2190 }
2191 }
2192 else
2193 {
2194 /* finished writing NDEF and Terminator TLV */
2195 /* read length field to update length */
Evan Chu85b7e842013-01-18 11:02:50 -05002196 block_number = (p_i93->ndef_tlv_start_offset + 1) / p_i93->block_size;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002197
2198 if (rw_i93_send_cmd_read_single_block (block_number, FALSE) == NFC_STATUS_OK)
2199 {
2200 /* set offset to length field */
2201 p_i93->rw_offset = p_i93->ndef_tlv_start_offset + 1;
2202
2203 /* get size of length field */
2204 if (p_i93->ndef_length >= 0xFF)
2205 {
2206 p_i93->rw_length = 3;
2207 }
2208 else if (p_i93->ndef_length > 0)
2209 {
2210 p_i93->rw_length = 1;
2211 }
2212 else
2213 {
2214 p_i93->rw_length = 0;
2215 }
2216
2217 p_i93->sub_state = RW_I93_SUBSTATE_UPDATE_LEN;
2218 }
2219 else
2220 {
2221 rw_i93_handle_error (NFC_STATUS_FAILED);
2222 }
2223 }
2224 }
2225 }
2226 else
2227 {
2228 /* if we have no more data to write */
2229 if (p_i93->rw_length >= p_i93->ndef_length)
2230 {
2231 /* finished writing NDEF and Terminator TLV */
2232 /* read length field to update length */
Evan Chu85b7e842013-01-18 11:02:50 -05002233 block_number = (p_i93->ndef_tlv_start_offset + 1) / p_i93->block_size;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002234
2235 if (rw_i93_send_cmd_read_single_block (block_number, FALSE) == NFC_STATUS_OK)
2236 {
2237 /* set offset to length field */
2238 p_i93->rw_offset = p_i93->ndef_tlv_start_offset + 1;
2239
2240 /* get size of length field */
2241 if (p_i93->ndef_length >= 0xFF)
2242 {
2243 p_i93->rw_length = 3;
2244 }
2245 else if (p_i93->ndef_length > 0)
2246 {
2247 p_i93->rw_length = 1;
2248 }
2249 else
2250 {
2251 p_i93->rw_length = 0;
2252 }
2253
2254 p_i93->sub_state = RW_I93_SUBSTATE_UPDATE_LEN;
2255 break;
2256 }
2257 }
2258 rw_i93_handle_error (NFC_STATUS_FAILED);
2259 }
2260 break;
2261
2262 case RW_I93_SUBSTATE_UPDATE_LEN:
2263
2264 /* if we have more length field to write */
2265 if (p_i93->rw_length > 0)
2266 {
2267 /* if we got ack for writing, read next block to update rest of length field */
2268 if (length == 0)
2269 {
Evan Chu85b7e842013-01-18 11:02:50 -05002270 block_number = p_i93->rw_offset / p_i93->block_size;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002271
2272 if (rw_i93_send_cmd_read_single_block (block_number, FALSE) != NFC_STATUS_OK)
2273 {
2274 rw_i93_handle_error (NFC_STATUS_FAILED);
2275 }
2276 }
2277 else
2278 {
2279 length_offset = p_i93->rw_offset % p_i93->block_size;
2280
2281 /* update length field within the read block */
2282 for (xx = length_offset; xx < p_i93->block_size; xx++)
2283 {
2284 if (p_i93->rw_length == 3)
2285 *(p + xx) = 0xFF;
2286 else if (p_i93->rw_length == 2)
2287 *(p + xx) = (UINT8) ((p_i93->ndef_length >> 8) & 0xFF);
2288 else if (p_i93->rw_length == 1)
2289 *(p + xx) = (UINT8) (p_i93->ndef_length & 0xFF);
2290
2291 p_i93->rw_length--;
2292 if (p_i93->rw_length == 0)
2293 break;
2294 }
2295
Evan Chu85b7e842013-01-18 11:02:50 -05002296 block_number = (p_i93->rw_offset / p_i93->block_size);
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002297
2298 if (rw_i93_send_cmd_write_single_block (block_number, p) == NFC_STATUS_OK)
2299 {
2300 /* set offset to the beginning of next block */
2301 p_i93->rw_offset += p_i93->block_size - (p_i93->rw_offset % p_i93->block_size);
2302 }
2303 else
2304 {
2305 rw_i93_handle_error (NFC_STATUS_FAILED);
2306 }
2307 }
2308 }
2309 else
2310 {
2311 RW_TRACE_DEBUG3 ("NDEF update complete, %d bytes, (%d-%d)",
2312 p_i93->ndef_length,
2313 p_i93->ndef_tlv_start_offset,
2314 p_i93->ndef_tlv_last_offset);
2315
2316 p_i93->state = RW_I93_STATE_IDLE;
2317 p_i93->sent_cmd = 0;
2318 p_i93->p_update_data = NULL;
2319
2320 rw_data.status = NFC_STATUS_OK;
2321 (*(rw_cb.p_cback)) (RW_I93_NDEF_UPDATE_CPLT_EVT, &rw_data);
2322 }
2323 break;
2324
2325 default:
2326 break;
2327 }
2328}
2329
2330/*******************************************************************************
2331**
2332** Function rw_i93_sm_format
2333**
2334** Description Process format procedure
2335**
2336** 1. Get UID
2337** 2. Get sys info for memory size (reset AFI/DSFID)
2338** 3. Get block status to get read-only status
2339** 4. Write CC and empty NDEF
2340**
2341** Returns void
2342**
2343*******************************************************************************/
2344void rw_i93_sm_format (BT_HDR *p_resp)
2345{
2346 UINT8 *p = (UINT8 *) (p_resp + 1) + p_resp->offset, *p_uid;
Evan Chu85b7e842013-01-18 11:02:50 -05002347 UINT8 flags;
2348 UINT16 length = p_resp->len, xx, block_number;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002349 tRW_I93_CB *p_i93 = &rw_cb.tcb.i93;
2350 tRW_DATA rw_data;
2351 tNFC_STATUS status = NFC_STATUS_FAILED;
2352
2353#if (BT_TRACE_VERBOSE == TRUE)
2354 RW_TRACE_DEBUG2 ("rw_i93_sm_format () sub_state:%s (0x%x)",
2355 rw_i93_get_sub_state_name (p_i93->sub_state), p_i93->sub_state);
2356#else
2357 RW_TRACE_DEBUG1 ("rw_i93_sm_format () sub_state:0x%x", p_i93->sub_state);
2358#endif
2359
2360 STREAM_TO_UINT8 (flags, p);
2361 length--;
2362
2363 if (flags & I93_FLAG_ERROR_DETECTED)
2364 {
2365 if ( ( (p_i93->product_version == RW_I93_TAG_IT_HF_I_PLUS_INLAY)
2366 ||(p_i93->product_version == RW_I93_TAG_IT_HF_I_PLUS_CHIP)
2367 ||(p_i93->product_version == RW_I93_TAG_IT_HF_I_STD_CHIP_INLAY)
2368 ||(p_i93->product_version == RW_I93_TAG_IT_HF_I_PRO_CHIP_INLAY) )
2369 &&
2370 (*p == I93_ERROR_CODE_BLOCK_FAIL_TO_WRITE) )
2371 {
2372 /* ignore error */
2373 }
Evan Chu85b7e842013-01-18 11:02:50 -05002374 else if ((length) && (rw_i93_check_sys_info_prot_ext(*p)))
2375 {
2376 /* getting system info with protocol extension flag */
2377 /* This STM tag supports more than 2040 bytes */
2378 p_i93->intl_flags |= RW_I93_FLAG_16BIT_NUM_BLOCK;
2379 return;
2380 }
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002381 else
2382 {
2383 RW_TRACE_DEBUG1 ("Got error flags (0x%02x)", flags);
2384 rw_i93_handle_error (NFC_STATUS_FAILED);
2385 return;
2386 }
2387 }
2388
2389 switch (p_i93->sub_state)
2390 {
2391 case RW_I93_SUBSTATE_WAIT_UID:
2392
2393 p++; /* skip DSFID */
2394 p_uid = p_i93->uid;
2395 STREAM_TO_ARRAY8 (p_uid, p); /* store UID */
2396
2397 /* get system information to get memory size */
Evan Chu85b7e842013-01-18 11:02:50 -05002398 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 -08002399 {
2400 p_i93->sub_state = RW_I93_SUBSTATE_WAIT_SYS_INFO;
2401 }
2402 else
2403 {
2404 rw_i93_handle_error (NFC_STATUS_FAILED);
2405 }
2406 break;
2407
2408 case RW_I93_SUBSTATE_WAIT_SYS_INFO:
2409
Evan Chu85b7e842013-01-18 11:02:50 -05002410 p_i93->block_size = 0;
2411 p_i93->num_block = 0;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002412
Evan Chu85b7e842013-01-18 11:02:50 -05002413 if (!rw_i93_process_sys_info (p))
2414 {
2415 /* retrying with protocol extension flag */
2416 break;
2417 }
2418
2419 if (p_i93->info_flags & I93_INFO_FLAG_DSFID)
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002420 {
2421 /* DSFID, if any DSFID then reset */
Evan Chu85b7e842013-01-18 11:02:50 -05002422 if (p_i93->dsfid != I93_DFS_UNSUPPORTED)
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002423 {
2424 p_i93->intl_flags |= RW_I93_FLAG_RESET_DSFID;
2425 }
2426 }
Evan Chu85b7e842013-01-18 11:02:50 -05002427 if (p_i93->info_flags & I93_INFO_FLAG_AFI)
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002428 {
2429 /* AFI, reset to 0 */
Evan Chu85b7e842013-01-18 11:02:50 -05002430 if (p_i93->afi != 0x00)
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002431 {
2432 p_i93->intl_flags |= RW_I93_FLAG_RESET_AFI;
2433 }
2434 }
Evan Chu85b7e842013-01-18 11:02:50 -05002435
2436 if ((p_i93->block_size == 0)||(p_i93->num_block == 0))
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002437 {
Evan Chu85b7e842013-01-18 11:02:50 -05002438 RW_TRACE_DEBUG0 ("Unable to get tag memory size");
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002439 rw_i93_handle_error (status);
2440 }
2441 else if (p_i93->intl_flags & RW_I93_FLAG_RESET_DSFID)
2442 {
2443 if (rw_i93_send_cmd_write_dsfid (I93_DFS_UNSUPPORTED) == 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 if (p_i93->intl_flags & RW_I93_FLAG_RESET_AFI)
2453 {
2454 if (rw_i93_send_cmd_write_afi (0x00) == NFC_STATUS_OK)
2455 {
2456 p_i93->sub_state = RW_I93_SUBSTATE_WAIT_RESET_DSFID_AFI;
2457 }
2458 else
2459 {
2460 rw_i93_handle_error (NFC_STATUS_FAILED);
2461 }
2462 }
2463 else
2464 {
2465 /* get lock status to see if read-only */
2466 if ((p_i93->uid[1] == I93_UID_IC_MFG_CODE_NXP) && (p_i93->ic_reference & I93_ICODE_IC_REF_MBREAD_MASK))
2467 {
2468 /* these doesn't support GetMultiBlockSecurityStatus */
2469
2470 rw_cb.tcb.i93.rw_offset = 0;
2471
2472 /* read blocks with option flag to get block security status */
Evan Chu85b7e842013-01-18 11:02:50 -05002473 if (rw_i93_send_cmd_read_single_block (0x0000, TRUE) == NFC_STATUS_OK)
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002474 {
2475 p_i93->sub_state = RW_I93_SUBSTATE_CHECK_READ_ONLY;
2476 }
2477 else
2478 {
2479 rw_i93_handle_error (NFC_STATUS_FAILED);
2480 }
2481 }
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002482 else
2483 {
Evan Chu85b7e842013-01-18 11:02:50 -05002484 /* block offset for read-only check */
2485 p_i93->rw_offset = 0;
2486
2487 if (rw_i93_get_next_block_sec () == NFC_STATUS_OK)
2488 {
2489 p_i93->sub_state = RW_I93_SUBSTATE_CHECK_READ_ONLY;
2490 }
2491 else
2492 {
2493 rw_i93_handle_error (NFC_STATUS_FAILED);
2494 }
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002495 }
2496 }
2497
2498 break;
2499
2500 case RW_I93_SUBSTATE_WAIT_RESET_DSFID_AFI:
2501
2502 if (p_i93->sent_cmd == I93_CMD_WRITE_DSFID)
2503 {
2504 p_i93->intl_flags &= ~RW_I93_FLAG_RESET_DSFID;
2505 }
2506 else if (p_i93->sent_cmd == I93_CMD_WRITE_AFI)
2507 {
2508 p_i93->intl_flags &= ~RW_I93_FLAG_RESET_AFI;
2509 }
2510
2511 if (p_i93->intl_flags & RW_I93_FLAG_RESET_DSFID)
2512 {
2513 if (rw_i93_send_cmd_write_dsfid (I93_DFS_UNSUPPORTED) == 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 if (p_i93->intl_flags & RW_I93_FLAG_RESET_AFI)
2523 {
2524 if (rw_i93_send_cmd_write_afi (0x00) == NFC_STATUS_OK)
2525 {
2526 p_i93->sub_state = RW_I93_SUBSTATE_WAIT_RESET_DSFID_AFI;
2527 }
2528 else
2529 {
2530 rw_i93_handle_error (NFC_STATUS_FAILED);
2531 }
2532 }
2533 else
2534 {
2535 /* get lock status to see if read-only */
2536 if ((p_i93->uid[1] == I93_UID_IC_MFG_CODE_NXP) && (p_i93->ic_reference & I93_ICODE_IC_REF_MBREAD_MASK))
2537 {
2538 /* these doesn't support GetMultiBlockSecurityStatus */
2539
2540 rw_cb.tcb.i93.rw_offset = 0;
2541
2542 /* read blocks with option flag to get block security status */
Evan Chu85b7e842013-01-18 11:02:50 -05002543 if (rw_i93_send_cmd_read_single_block (0x0000, TRUE) == NFC_STATUS_OK)
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002544 {
2545 p_i93->sub_state = RW_I93_SUBSTATE_CHECK_READ_ONLY;
2546 }
2547 else
2548 {
2549 rw_i93_handle_error (NFC_STATUS_FAILED);
2550 }
2551 }
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002552 else
2553 {
Evan Chu85b7e842013-01-18 11:02:50 -05002554 /* block offset for read-only check */
2555 p_i93->rw_offset = 0;
2556
2557 if (rw_i93_get_next_block_sec () == NFC_STATUS_OK)
2558 {
2559 p_i93->sub_state = RW_I93_SUBSTATE_CHECK_READ_ONLY;
2560 }
2561 else
2562 {
2563 rw_i93_handle_error (NFC_STATUS_FAILED);
2564 }
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002565 }
2566 }
2567 break;
2568
2569 case RW_I93_SUBSTATE_CHECK_READ_ONLY:
2570
2571 if ( (p_i93->product_version == RW_I93_TAG_IT_HF_I_STD_CHIP_INLAY)
2572 ||(p_i93->product_version == RW_I93_TAG_IT_HF_I_PRO_CHIP_INLAY)
2573 ||((p_i93->uid[1] == I93_UID_IC_MFG_CODE_NXP) && (p_i93->ic_reference & I93_ICODE_IC_REF_MBREAD_MASK)) )
2574 {
2575 if ((*p) & I93_BLOCK_LOCKED)
2576 {
2577 rw_i93_handle_error (NFC_STATUS_FAILED);
2578 break;
2579 }
2580
2581 /* if we checked all of user blocks */
2582 if ((p_i93->rw_offset / p_i93->block_size) + 1 == p_i93->num_block)
2583 {
2584 if ( (p_i93->product_version == RW_I93_TAG_IT_HF_I_STD_CHIP_INLAY)
2585 ||(p_i93->product_version == RW_I93_TAG_IT_HF_I_PRO_CHIP_INLAY) )
2586 {
2587 /* read the block which has AFI */
2588 p_i93->rw_offset = I93_TAG_IT_HF_I_STD_PRO_CHIP_INLAY_AFI_LOCATION;
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 if (p_i93->rw_offset == I93_TAG_IT_HF_I_STD_PRO_CHIP_INLAY_AFI_LOCATION)
2594 {
2595 /* no block is locked */
2596 }
2597 else
2598 {
2599 p_i93->rw_offset += p_i93->block_size;
Evan Chu85b7e842013-01-18 11:02:50 -05002600 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 -08002601 break;
2602 }
2603 }
2604 else
2605 {
2606 /* if any block is locked, we cannot format it */
Evan Chu85b7e842013-01-18 11:02:50 -05002607 for (xx = 0; xx < length; xx++)
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002608 {
Evan Chu85b7e842013-01-18 11:02:50 -05002609 if (*(p + xx) & I93_BLOCK_LOCKED)
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002610 {
2611 rw_i93_handle_error (NFC_STATUS_FAILED);
2612 break;
2613 }
2614 }
Evan Chu85b7e842013-01-18 11:02:50 -05002615
2616 /* update block offset for read-only check */
2617 p_i93->rw_offset += length;
2618
2619 /* if need to get more lock status of blocks */
2620 if (p_i93->num_block > p_i93->rw_offset)
2621 {
2622 if (rw_i93_get_next_block_sec () != NFC_STATUS_OK)
2623 {
2624 rw_i93_handle_error (NFC_STATUS_FAILED);
2625 }
2626 break;
2627 }
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002628 }
2629
2630 /* get buffer to store CC, zero length NDEF TLV and Terminator TLV */
2631 p_i93->p_update_data = (UINT8*) GKI_getbuf (RW_I93_FORMAT_DATA_LEN);
2632
2633 if (!p_i93->p_update_data)
2634 {
2635 RW_TRACE_ERROR0 ("rw_i93_sm_format (): Cannot allocate buffer");
2636 rw_i93_handle_error (NFC_STATUS_FAILED);
2637 break;
2638 }
2639
2640 p = p_i93->p_update_data;
2641
2642 /* Capability Container */
2643 *(p++) = I93_ICODE_CC_MAGIC_NUMER; /* magic number */
2644 *(p++) = 0x40; /* version 1.0, read/write */
Evan Chu85b7e842013-01-18 11:02:50 -05002645
2646 /* if memory size is less than 2048 bytes */
2647 if (((p_i93->num_block * p_i93->block_size) / 8) < 0x100)
2648 *(p++) = (UINT8) ((p_i93->num_block * p_i93->block_size) / 8); /* memory size */
2649 else
2650 *(p++) = 0xFF;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002651
2652 if ( (p_i93->product_version == RW_I93_ICODE_SLI)
2653 ||(p_i93->product_version == RW_I93_ICODE_SLI_S)
2654 ||(p_i93->product_version == RW_I93_ICODE_SLI_L) )
2655 {
2656 if (p_i93->ic_reference & I93_ICODE_IC_REF_MBREAD_MASK)
2657 *(p++) = I93_ICODE_CC_IPREAD_MASK; /* IPREAD */
2658 else
2659 *(p++) = I93_ICODE_CC_MBREAD_MASK; /* MBREAD, read multi block command supported */
2660 }
2661 else if ( (p_i93->product_version == RW_I93_TAG_IT_HF_I_PLUS_INLAY)
2662 ||(p_i93->product_version == RW_I93_TAG_IT_HF_I_PLUS_CHIP) )
2663 {
2664 *(p++) = I93_ICODE_CC_MBREAD_MASK; /* MBREAD, read multi block command supported */
2665 }
2666 else if ( (p_i93->product_version == RW_I93_TAG_IT_HF_I_STD_CHIP_INLAY)
2667 ||(p_i93->product_version == RW_I93_TAG_IT_HF_I_PRO_CHIP_INLAY) )
2668 {
2669 *(p++) = 0;
2670 }
2671 else
2672 {
Evan Chu85b7e842013-01-18 11:02:50 -05002673 /* STM except LRIS2K, Broadcom supports read multi block command */
2674
2675 /* if memory size is more than 2040 bytes (which is not LRIS2K) */
2676 if (((p_i93->num_block * p_i93->block_size) / 8) > 0xFF)
2677 *(p++) = (I93_ICODE_CC_MBREAD_MASK | I93_STM_CC_OVERFLOW_MASK);
2678 else if (p_i93->product_version == RW_I93_STM_LRIS2K)
2679 *(p++) = 0x00;
2680 else
2681 *(p++) = I93_ICODE_CC_MBREAD_MASK;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002682 }
2683
2684 /* zero length NDEF and Terminator TLV */
2685 *(p++) = I93_ICODE_TLV_TYPE_NDEF;
2686 *(p++) = 0x00;
2687 *(p++) = I93_ICODE_TLV_TYPE_TERM;
2688 *(p++) = I93_ICODE_TLV_TYPE_NULL;
2689
2690 /* start from block 0 */
2691 p_i93->rw_offset = 0;
2692
2693 if (rw_i93_send_cmd_write_single_block (0, p_i93->p_update_data) == NFC_STATUS_OK)
2694 {
2695 p_i93->sub_state = RW_I93_SUBSTATE_WRITE_CC_NDEF_TLV;
2696 p_i93->rw_offset += p_i93->block_size;
2697 }
2698 else
2699 {
2700 rw_i93_handle_error (NFC_STATUS_FAILED);
2701 }
2702 break;
2703
2704 case RW_I93_SUBSTATE_WRITE_CC_NDEF_TLV:
2705
2706 /* if we have more data to write */
2707 if (p_i93->rw_offset < RW_I93_FORMAT_DATA_LEN)
2708 {
Evan Chu85b7e842013-01-18 11:02:50 -05002709 block_number = (p_i93->rw_offset / p_i93->block_size);
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002710 p = p_i93->p_update_data + p_i93->rw_offset;
2711
2712 if (rw_i93_send_cmd_write_single_block (block_number, p) == NFC_STATUS_OK)
2713 {
2714 p_i93->sub_state = RW_I93_SUBSTATE_WRITE_CC_NDEF_TLV;
2715 p_i93->rw_offset += p_i93->block_size;
2716 }
2717 else
2718 {
2719 rw_i93_handle_error (NFC_STATUS_FAILED);
2720 }
2721 }
2722 else
2723 {
2724 GKI_freebuf (p_i93->p_update_data);
2725 p_i93->p_update_data = NULL;
2726
2727 p_i93->state = RW_I93_STATE_IDLE;
2728 p_i93->sent_cmd = 0;
2729
2730 rw_data.status = NFC_STATUS_OK;
2731 (*(rw_cb.p_cback)) (RW_I93_FORMAT_CPLT_EVT, &rw_data);
2732 }
2733 break;
2734
2735 default:
2736 break;
2737 }
2738}
2739
2740/*******************************************************************************
2741**
2742** Function rw_i93_sm_set_read_only
2743**
2744** Description Process read-only procedure
2745**
2746** 1. Update CC as read-only
2747** 2. Lock all block of NDEF TLV
2748** 3. Lock block of CC
2749**
2750** Returns void
2751**
2752*******************************************************************************/
2753void rw_i93_sm_set_read_only (BT_HDR *p_resp)
2754{
2755 UINT8 *p = (UINT8 *) (p_resp + 1) + p_resp->offset;
2756 UINT8 flags, block_number;
2757 UINT16 length = p_resp->len;
2758 tRW_I93_CB *p_i93 = &rw_cb.tcb.i93;
2759 tRW_DATA rw_data;
2760
2761#if (BT_TRACE_VERBOSE == TRUE)
2762 RW_TRACE_DEBUG2 ("rw_i93_sm_set_read_only () sub_state:%s (0x%x)",
2763 rw_i93_get_sub_state_name (p_i93->sub_state), p_i93->sub_state);
2764#else
2765 RW_TRACE_DEBUG1 ("rw_i93_sm_set_read_only () sub_state:0x%x", p_i93->sub_state);
2766#endif
2767
2768 STREAM_TO_UINT8 (flags, p);
2769 length--;
2770
2771 if (flags & I93_FLAG_ERROR_DETECTED)
2772 {
2773 if ( ( (p_i93->product_version == RW_I93_TAG_IT_HF_I_PLUS_INLAY)
2774 ||(p_i93->product_version == RW_I93_TAG_IT_HF_I_PLUS_CHIP)
2775 ||(p_i93->product_version == RW_I93_TAG_IT_HF_I_STD_CHIP_INLAY)
2776 ||(p_i93->product_version == RW_I93_TAG_IT_HF_I_PRO_CHIP_INLAY) )
2777 &&
2778 (*p == I93_ERROR_CODE_BLOCK_FAIL_TO_WRITE) )
2779 {
2780 /* ignore error */
2781 }
2782 else
2783 {
2784 RW_TRACE_DEBUG1 ("Got error flags (0x%02x)", flags);
2785 rw_i93_handle_error (NFC_STATUS_FAILED);
2786 return;
2787 }
2788 }
2789
2790 switch (p_i93->sub_state)
2791 {
2792 case RW_I93_SUBSTATE_WAIT_CC:
2793
2794 /* mark CC as read-only */
2795 *(p+1) |= I93_ICODE_CC_READ_ONLY;
2796
2797 if (rw_i93_send_cmd_write_single_block (0, p) == NFC_STATUS_OK)
2798 {
2799 p_i93->sub_state = RW_I93_SUBSTATE_WAIT_UPDATE_CC;
2800 }
2801 else
2802 {
2803 rw_i93_handle_error (NFC_STATUS_FAILED);
2804 }
2805 break;
2806
2807 case RW_I93_SUBSTATE_WAIT_UPDATE_CC:
2808
2809 /* successfully write CC then lock all blocks of NDEF TLV */
2810 p_i93->rw_offset = p_i93->ndef_tlv_start_offset;
2811 block_number = (UINT8) (p_i93->rw_offset / p_i93->block_size);
2812
2813 if (rw_i93_send_cmd_lock_block (block_number) == NFC_STATUS_OK)
2814 {
2815 p_i93->rw_offset += p_i93->block_size;
2816 p_i93->sub_state = RW_I93_SUBSTATE_LOCK_NDEF_TLV;
2817 }
2818 else
2819 {
2820 rw_i93_handle_error (NFC_STATUS_FAILED);
2821 }
2822 break;
2823
2824 case RW_I93_SUBSTATE_LOCK_NDEF_TLV:
2825
2826 /* if we need to lock more blocks */
2827 if (p_i93->rw_offset < p_i93->ndef_tlv_last_offset)
2828 {
2829 /* get the next block of NDEF TLV */
2830 block_number = (UINT8) (p_i93->rw_offset / p_i93->block_size);
2831
2832 if (rw_i93_send_cmd_lock_block (block_number) == NFC_STATUS_OK)
2833 {
2834 p_i93->rw_offset += p_i93->block_size;
2835 }
2836 else
2837 {
2838 rw_i93_handle_error (NFC_STATUS_FAILED);
2839 }
2840 }
2841 /* if the first block of NDEF TLV is different from block of CC */
2842 else if (p_i93->ndef_tlv_start_offset / p_i93->block_size != 0)
2843 {
2844 /* lock block of CC */
2845 if (rw_i93_send_cmd_lock_block (0) == NFC_STATUS_OK)
2846 {
2847 p_i93->sub_state = RW_I93_SUBSTATE_WAIT_LOCK_CC;
2848 }
2849 else
2850 {
2851 rw_i93_handle_error (NFC_STATUS_FAILED);
2852 }
2853 }
2854 else
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 }
2863 break;
2864
2865 case RW_I93_SUBSTATE_WAIT_LOCK_CC:
2866
2867 p_i93->intl_flags |= RW_I93_FLAG_READ_ONLY;
2868 p_i93->state = RW_I93_STATE_IDLE;
2869 p_i93->sent_cmd = 0;
2870
2871 rw_data.status = NFC_STATUS_OK;
2872 (*(rw_cb.p_cback)) (RW_I93_SET_TAG_RO_EVT, &rw_data);
2873 break;
2874
2875 default:
2876 break;
2877 }
2878}
2879
2880/*******************************************************************************
2881**
2882** Function rw_i93_handle_error
2883**
2884** Description notify error to application and clean up
2885**
2886** Returns none
2887**
2888*******************************************************************************/
2889void rw_i93_handle_error (tNFC_STATUS status)
2890{
2891 tRW_I93_CB *p_i93 = &rw_cb.tcb.i93;
2892 tRW_DATA rw_data;
2893 tRW_EVENT event;
2894
2895 RW_TRACE_DEBUG2 ("rw_i93_handle_error (): status:0x%02X, state:0x%X",
2896 status, p_i93->state);
2897
2898 nfc_stop_quick_timer (&p_i93->timer);
2899
2900 if (rw_cb.p_cback)
2901 {
2902 rw_data.status = status;
2903
2904 switch (p_i93->state)
2905 {
2906 case RW_I93_STATE_IDLE: /* in case of RawFrame */
2907 event = RW_I93_INTF_ERROR_EVT;
2908 break;
2909
2910 case RW_I93_STATE_BUSY:
2911 if (p_i93->sent_cmd == I93_CMD_STAY_QUIET)
2912 {
2913 /* There is no response to Stay Quiet command */
2914 rw_data.i93_cmd_cmpl.status = NFC_STATUS_OK;
2915 rw_data.i93_cmd_cmpl.command = I93_CMD_STAY_QUIET;
2916 rw_data.i93_cmd_cmpl.error_code = 0;
2917 event = RW_I93_CMD_CMPL_EVT;
2918 }
2919 else
2920 {
2921 event = RW_I93_INTF_ERROR_EVT;
2922 }
2923 break;
2924
2925 case RW_I93_STATE_DETECT_NDEF:
2926 rw_data.ndef.protocol = NFC_PROTOCOL_15693;
2927 rw_data.ndef.cur_size = 0;
2928 rw_data.ndef.max_size = 0;
2929 rw_data.ndef.flags = 0;
2930 rw_data.ndef.flags |= RW_NDEF_FL_FORMATABLE;
2931 rw_data.ndef.flags |= RW_NDEF_FL_UNKNOWN;
2932 event = RW_I93_NDEF_DETECT_EVT;
2933 break;
2934
2935 case RW_I93_STATE_READ_NDEF:
2936 event = RW_I93_NDEF_READ_FAIL_EVT;
2937 break;
2938
2939 case RW_I93_STATE_UPDATE_NDEF:
2940 p_i93->p_update_data = NULL;
2941 event = RW_I93_NDEF_UPDATE_FAIL_EVT;
2942 break;
2943
2944 case RW_I93_STATE_FORMAT:
2945 if (p_i93->p_update_data)
2946 {
2947 GKI_freebuf (p_i93->p_update_data);
2948 p_i93->p_update_data = NULL;
2949 }
2950 event = RW_I93_FORMAT_CPLT_EVT;
2951 break;
2952
2953 case RW_I93_STATE_SET_READ_ONLY:
2954 event = RW_I93_SET_TAG_RO_EVT;
2955 break;
2956
2957 case RW_I93_STATE_PRESENCE_CHECK:
2958 event = RW_I93_PRESENCE_CHECK_EVT;
2959 break;
2960
2961 default:
2962 event = RW_I93_MAX_EVT;
2963 break;
2964 }
2965
2966 p_i93->state = RW_I93_STATE_IDLE;
2967 p_i93->sent_cmd = 0;
2968
2969 if (event != RW_I93_MAX_EVT)
2970 {
2971 (*(rw_cb.p_cback)) (event, &rw_data);
2972 }
2973 }
2974 else
2975 {
2976 p_i93->state = RW_I93_STATE_IDLE;
2977 }
2978}
2979
2980/*******************************************************************************
2981**
2982** Function rw_i93_process_timeout
2983**
2984** Description process timeout event
2985**
2986** Returns none
2987**
2988*******************************************************************************/
2989void rw_i93_process_timeout (TIMER_LIST_ENT *p_tle)
2990{
Evan Chu85b7e842013-01-18 11:02:50 -05002991 BT_HDR *p_buf;
2992
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002993 RW_TRACE_DEBUG1 ("rw_i93_process_timeout () event=%d", p_tle->event);
2994
2995 if (p_tle->event == NFC_TTYPE_RW_I93_RESPONSE)
2996 {
Evan Chu85b7e842013-01-18 11:02:50 -05002997 if ( (rw_cb.tcb.i93.retry_count < RW_MAX_RETRIES)
2998 &&(rw_cb.tcb.i93.p_retry_cmd)
2999 &&(rw_cb.tcb.i93.sent_cmd != I93_CMD_STAY_QUIET))
3000 {
3001 rw_cb.tcb.i93.retry_count++;
3002 RW_TRACE_ERROR1 ("rw_i93_process_timeout (): retry_count = %d", rw_cb.tcb.i93.retry_count);
3003
3004 p_buf = rw_cb.tcb.i93.p_retry_cmd;
3005 rw_cb.tcb.i93.p_retry_cmd = NULL;
Evan Chu7c69b272013-05-14 12:48:36 -04003006
3007 if (rw_i93_send_to_lower (p_buf))
Evan Chu85b7e842013-01-18 11:02:50 -05003008 {
Evan Chu7c69b272013-05-14 12:48:36 -04003009 return;
Evan Chu85b7e842013-01-18 11:02:50 -05003010 }
Evan Chu85b7e842013-01-18 11:02:50 -05003011 }
Evan Chu7c69b272013-05-14 12:48:36 -04003012
3013 /* all retrial is done or failed to send command to lower layer */
3014 if (rw_cb.tcb.i93.p_retry_cmd)
3015 {
3016 GKI_freebuf (rw_cb.tcb.i93.p_retry_cmd);
3017 rw_cb.tcb.i93.p_retry_cmd = NULL;
3018 rw_cb.tcb.i93.retry_count = 0;
3019 }
3020 rw_i93_handle_error (NFC_STATUS_TIMEOUT);
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08003021 }
3022 else
3023 {
3024 RW_TRACE_ERROR1 ("rw_i93_process_timeout () unknown event=%d", p_tle->event);
3025 }
3026}
3027
3028/*******************************************************************************
3029**
3030** Function rw_i93_data_cback
3031**
3032** Description This callback function receives the data from NFCC.
3033**
3034** Returns none
3035**
3036*******************************************************************************/
3037static void rw_i93_data_cback (UINT8 conn_id, tNFC_CONN_EVT event, tNFC_CONN *p_data)
3038{
3039 tRW_I93_CB *p_i93 = &rw_cb.tcb.i93;
Evan Chu7c69b272013-05-14 12:48:36 -04003040 BT_HDR *p_resp;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08003041 tRW_DATA rw_data;
3042
3043#if (BT_TRACE_VERBOSE == TRUE)
3044 UINT8 begin_state = p_i93->state;
3045#endif
3046
3047 RW_TRACE_DEBUG1 ("rw_i93_data_cback () event = 0x%X", event);
3048
3049 if ( (event == NFC_DEACTIVATE_CEVT)
3050 ||(event == NFC_ERROR_CEVT) )
3051 {
3052 nfc_stop_quick_timer (&p_i93->timer);
3053
3054 if (event == NFC_ERROR_CEVT)
3055 {
Evan Chu85b7e842013-01-18 11:02:50 -05003056 if ( (p_i93->retry_count < RW_MAX_RETRIES)
3057 &&(p_i93->p_retry_cmd) )
3058 {
3059 p_i93->retry_count++;
3060
3061 RW_TRACE_ERROR1 ("rw_i93_data_cback (): retry_count = %d", p_i93->retry_count);
3062
3063 p_resp = p_i93->p_retry_cmd;
3064 p_i93->p_retry_cmd = NULL;
Evan Chu7c69b272013-05-14 12:48:36 -04003065 if (rw_i93_send_to_lower (p_resp))
Evan Chu85b7e842013-01-18 11:02:50 -05003066 {
Evan Chu7c69b272013-05-14 12:48:36 -04003067 return;
Evan Chu85b7e842013-01-18 11:02:50 -05003068 }
Evan Chu85b7e842013-01-18 11:02:50 -05003069 }
Evan Chu7c69b272013-05-14 12:48:36 -04003070
3071 /* all retrial is done or failed to send command to lower layer */
3072 if (p_i93->p_retry_cmd)
3073 {
3074 GKI_freebuf (p_i93->p_retry_cmd);
3075 p_i93->p_retry_cmd = NULL;
3076 p_i93->retry_count = 0;
3077 }
3078
3079 rw_i93_handle_error ((tNFC_STATUS) (*(UINT8*) p_data));
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08003080 }
3081 else
3082 {
3083 NFC_SetStaticRfCback (NULL);
3084 p_i93->state = RW_I93_STATE_NOT_ACTIVATED;
3085 }
3086 return;
3087 }
3088
3089 if (event != NFC_DATA_CEVT)
3090 {
3091 return;
3092 }
3093
Evan Chu7c69b272013-05-14 12:48:36 -04003094 p_resp = (BT_HDR *) p_data->data.p_data;
3095
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08003096 nfc_stop_quick_timer (&p_i93->timer);
3097
Evan Chu85b7e842013-01-18 11:02:50 -05003098 /* free retry buffer */
3099 if (p_i93->p_retry_cmd)
3100 {
3101 GKI_freebuf (p_i93->p_retry_cmd);
3102 p_i93->p_retry_cmd = NULL;
3103 p_i93->retry_count = 0;
3104 }
3105
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08003106#if (BT_TRACE_PROTOCOL == TRUE)
3107 DispRWI93Tag (p_resp, TRUE, p_i93->sent_cmd);
3108#endif
3109
3110#if (BT_TRACE_VERBOSE == TRUE)
3111 RW_TRACE_DEBUG2 ("RW I93 state: <%s (%d)>",
3112 rw_i93_get_state_name (p_i93->state), p_i93->state);
3113#else
3114 RW_TRACE_DEBUG1 ("RW I93 state: %d", p_i93->state);
3115#endif
3116
3117 switch (p_i93->state)
3118 {
3119 case RW_I93_STATE_IDLE:
3120 /* Unexpected Response from VICC, it should be raw frame response */
3121 /* forward to upper layer without parsing */
3122 p_i93->sent_cmd = 0;
3123 if (rw_cb.p_cback)
3124 {
3125 rw_data.raw_frame.status = NFC_STATUS_OK;
3126 rw_data.raw_frame.p_data = p_resp;
3127 (*(rw_cb.p_cback)) (RW_I93_RAW_FRAME_EVT, &rw_data);
3128 p_resp = NULL;
3129 }
3130 else
3131 {
3132 GKI_freebuf (p_resp);
3133 }
3134 break;
3135 case RW_I93_STATE_BUSY:
3136 p_i93->state = RW_I93_STATE_IDLE;
3137 rw_i93_send_to_upper (p_resp);
3138 GKI_freebuf (p_resp);
3139 break;
3140
3141 case RW_I93_STATE_DETECT_NDEF:
3142 rw_i93_sm_detect_ndef (p_resp);
3143 GKI_freebuf (p_resp);
3144 break;
3145
3146 case RW_I93_STATE_READ_NDEF:
3147 rw_i93_sm_read_ndef (p_resp);
3148 /* p_resp may send upper lyaer */
3149 break;
3150
3151 case RW_I93_STATE_UPDATE_NDEF:
3152 rw_i93_sm_update_ndef (p_resp);
3153 GKI_freebuf (p_resp);
3154 break;
3155
3156 case RW_I93_STATE_FORMAT:
3157 rw_i93_sm_format (p_resp);
3158 GKI_freebuf (p_resp);
3159 break;
3160
3161 case RW_I93_STATE_SET_READ_ONLY:
3162 rw_i93_sm_set_read_only (p_resp);
3163 GKI_freebuf (p_resp);
3164 break;
3165
3166 case RW_I93_STATE_PRESENCE_CHECK:
3167 p_i93->state = RW_I93_STATE_IDLE;
3168 p_i93->sent_cmd = 0;
3169
3170 /* if any response, send presence check with ok */
3171 rw_data.status = NFC_STATUS_OK;
3172 (*(rw_cb.p_cback)) (RW_I93_PRESENCE_CHECK_EVT, &rw_data);
3173 GKI_freebuf (p_resp);
3174 break;
3175
3176 default:
3177 RW_TRACE_ERROR1 ("rw_i93_data_cback (): invalid state=%d", p_i93->state);
3178 GKI_freebuf (p_resp);
3179 break;
3180 }
3181
3182#if (BT_TRACE_VERBOSE == TRUE)
3183 if (begin_state != p_i93->state)
3184 {
3185 RW_TRACE_DEBUG2 ("RW I93 state changed:<%s> -> <%s>",
3186 rw_i93_get_state_name (begin_state),
3187 rw_i93_get_state_name (p_i93->state));
3188 }
3189#endif
3190}
3191
3192/*******************************************************************************
3193**
3194** Function rw_i93_select
3195**
3196** Description Initialise ISO 15693 RW
3197**
3198** Returns NFC_STATUS_OK if success
3199**
3200*******************************************************************************/
Evan Chu85b7e842013-01-18 11:02:50 -05003201tNFC_STATUS rw_i93_select (UINT8 *p_uid)
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08003202{
3203 tRW_I93_CB *p_i93 = &rw_cb.tcb.i93;
Evan Chu85b7e842013-01-18 11:02:50 -05003204 UINT8 uid[I93_UID_BYTE_LEN], *p;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08003205
3206 RW_TRACE_DEBUG0 ("rw_i93_select ()");
3207
3208 NFC_SetStaticRfCback (rw_i93_data_cback);
3209
3210 p_i93->state = RW_I93_STATE_IDLE;
3211
Evan Chu85b7e842013-01-18 11:02:50 -05003212 /* convert UID to big endian format - MSB(0xE0) in first byte */
3213 p = uid;
3214 STREAM_TO_ARRAY8 (p, p_uid);
3215
3216 rw_i93_get_product_version (uid);
3217
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08003218 return NFC_STATUS_OK;
3219}
3220
3221/*******************************************************************************
3222**
3223** Function RW_I93Inventory
3224**
Martijn Coenen5c65c3a2013-03-27 13:23:36 -07003225** Description This function send Inventory command with/without AFI
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08003226** If UID is provided then set UID[0]:MSB, ... UID[7]:LSB
3227**
3228** RW_I93_RESPONSE_EVT will be returned
3229**
3230** Returns NFC_STATUS_OK if success
3231** NFC_STATUS_NO_BUFFERS if out of buffer
3232** NFC_STATUS_BUSY if busy
3233** NFC_STATUS_FAILED if other error
3234**
3235*******************************************************************************/
Martijn Coenen5c65c3a2013-03-27 13:23:36 -07003236tNFC_STATUS RW_I93Inventory (BOOLEAN including_afi, UINT8 afi, UINT8 *p_uid)
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08003237{
3238 tNFC_STATUS status;
3239
Martijn Coenen5c65c3a2013-03-27 13:23:36 -07003240 RW_TRACE_API2 ("RW_I93Inventory (), including_afi:%d, AFI:0x%02X", including_afi, afi);
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08003241
3242 if (rw_cb.tcb.i93.state != RW_I93_STATE_IDLE)
3243 {
3244 RW_TRACE_ERROR1 ("RW_I93Inventory ():Unable to start command at state (0x%X)",
3245 rw_cb.tcb.i93.state);
3246 return NFC_STATUS_BUSY;
3247 }
3248
Martijn Coenen5c65c3a2013-03-27 13:23:36 -07003249 status = rw_i93_send_cmd_inventory (p_uid, including_afi, afi);
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08003250
3251 if (status == NFC_STATUS_OK)
3252 {
3253 rw_cb.tcb.i93.state = RW_I93_STATE_BUSY;
3254 }
3255
3256 return (status);
3257}
3258
3259/*******************************************************************************
3260**
3261** Function RW_I93StayQuiet
3262**
3263** Description This function send Inventory command
3264**
3265** RW_I93_CMD_CMPL_EVT will be returned
3266**
3267** Returns NFC_STATUS_OK if success
3268** NFC_STATUS_NO_BUFFERS if out of buffer
3269** NFC_STATUS_BUSY if busy
3270** NFC_STATUS_FAILED if other error
3271**
3272*******************************************************************************/
3273tNFC_STATUS RW_I93StayQuiet (void)
3274{
3275 tNFC_STATUS status;
3276
3277 RW_TRACE_API0 ("RW_I93StayQuiet ()");
3278
3279 if (rw_cb.tcb.i93.state != RW_I93_STATE_IDLE)
3280 {
3281 RW_TRACE_ERROR1 ("RW_I93StayQuiet ():Unable to start command at state (0x%X)",
3282 rw_cb.tcb.i93.state);
3283 return NFC_STATUS_BUSY;
3284 }
3285
3286 status = rw_i93_send_cmd_stay_quiet ();
3287 if (status == NFC_STATUS_OK)
3288 {
3289 rw_cb.tcb.i93.state = RW_I93_STATE_BUSY;
3290 }
3291
3292 return status;
3293}
3294
3295/*******************************************************************************
3296**
3297** Function RW_I93ReadSingleBlock
3298**
3299** Description This function send Read Single Block command
3300**
3301** RW_I93_RESPONSE_EVT will be returned
3302**
3303** Returns NFC_STATUS_OK if success
3304** NFC_STATUS_NO_BUFFERS if out of buffer
3305** NFC_STATUS_BUSY if busy
3306** NFC_STATUS_FAILED if other error
3307**
3308*******************************************************************************/
Evan Chu85b7e842013-01-18 11:02:50 -05003309tNFC_STATUS RW_I93ReadSingleBlock (UINT16 block_number)
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08003310{
3311 tNFC_STATUS status;
3312
3313 RW_TRACE_API1 ("RW_I93ReadSingleBlock () block_number:0x%02X", block_number);
3314
3315 if (rw_cb.tcb.i93.state != RW_I93_STATE_IDLE)
3316 {
3317 RW_TRACE_ERROR1 ("RW_I93ReadSingleBlock ():Unable to start command at state (0x%X)",
3318 rw_cb.tcb.i93.state);
3319 return NFC_STATUS_BUSY;
3320 }
3321
3322 status = rw_i93_send_cmd_read_single_block (block_number, FALSE);
3323 if (status == NFC_STATUS_OK)
3324 {
3325 rw_cb.tcb.i93.state = RW_I93_STATE_BUSY;
3326 }
3327
3328 return status;
3329}
3330
3331/*******************************************************************************
3332**
3333** Function RW_I93WriteSingleBlock
3334**
3335** Description This function send Write Single Block command
3336** Application must get block size first by calling RW_I93GetSysInfo().
3337**
3338** RW_I93_CMD_CMPL_EVT will be returned
3339**
3340** Returns NFC_STATUS_OK if success
3341** NFC_STATUS_NO_BUFFERS if out of buffer
3342** NFC_STATUS_BUSY if busy
3343** NFC_STATUS_FAILED if other error
3344**
3345*******************************************************************************/
Evan Chu85b7e842013-01-18 11:02:50 -05003346tNFC_STATUS RW_I93WriteSingleBlock (UINT16 block_number,
3347 UINT8 *p_data)
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08003348{
3349 tNFC_STATUS status;
3350
3351 RW_TRACE_API0 ("RW_I93WriteSingleBlock ()");
3352
3353 if (rw_cb.tcb.i93.state != RW_I93_STATE_IDLE)
3354 {
3355 RW_TRACE_ERROR1 ("RW_I93WriteSingleBlock ():Unable to start command at state (0x%X)",
3356 rw_cb.tcb.i93.state);
3357 return NFC_STATUS_BUSY;
3358 }
3359
3360 if (rw_cb.tcb.i93.block_size == 0)
3361 {
3362 RW_TRACE_ERROR0 ("RW_I93WriteSingleBlock ():Block size is unknown");
3363 return NFC_STATUS_FAILED;
3364 }
3365
3366 status = rw_i93_send_cmd_write_single_block (block_number, p_data);
3367 if (status == NFC_STATUS_OK)
3368 {
3369 rw_cb.tcb.i93.state = RW_I93_STATE_BUSY;
3370 }
3371
3372 return status;
3373}
3374
3375/*******************************************************************************
3376**
3377** Function RW_I93LockBlock
3378**
3379** Description This function send Lock Block command
3380**
3381** RW_I93_CMD_CMPL_EVT will be returned
3382**
3383** Returns NFC_STATUS_OK if success
3384** NFC_STATUS_NO_BUFFERS if out of buffer
3385** NFC_STATUS_BUSY if busy
3386** NFC_STATUS_FAILED if other error
3387**
3388*******************************************************************************/
3389tNFC_STATUS RW_I93LockBlock (UINT8 block_number)
3390{
3391 tNFC_STATUS status;
3392
3393 RW_TRACE_API0 ("RW_I93LockBlock ()");
3394
3395 if (rw_cb.tcb.i93.state != RW_I93_STATE_IDLE)
3396 {
3397 RW_TRACE_ERROR1 ("RW_I93LockBlock ():Unable to start command at state (0x%X)",
3398 rw_cb.tcb.i93.state);
3399 return NFC_STATUS_BUSY;
3400 }
3401
3402 status = rw_i93_send_cmd_lock_block (block_number);
3403 if (status == NFC_STATUS_OK)
3404 {
3405 rw_cb.tcb.i93.state = RW_I93_STATE_BUSY;
3406 }
3407
3408 return status;
3409}
3410
3411/*******************************************************************************
3412**
3413** Function RW_I93ReadMultipleBlocks
3414**
3415** Description This function send Read Multiple Blocks command
3416**
3417** RW_I93_RESPONSE_EVT will be returned
3418**
3419** Returns NFC_STATUS_OK if success
3420** NFC_STATUS_NO_BUFFERS if out of buffer
3421** NFC_STATUS_BUSY if busy
3422** NFC_STATUS_FAILED if other error
3423**
3424*******************************************************************************/
Evan Chu85b7e842013-01-18 11:02:50 -05003425tNFC_STATUS RW_I93ReadMultipleBlocks (UINT16 first_block_number,
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08003426 UINT16 number_blocks)
3427{
3428 tNFC_STATUS status;
3429
3430 RW_TRACE_API0 ("RW_I93ReadMultipleBlocks ()");
3431
3432 if (rw_cb.tcb.i93.state != RW_I93_STATE_IDLE)
3433 {
3434 RW_TRACE_ERROR1 ("RW_I93ReadMultipleBlocks ():Unable to start command at state (0x%X)",
3435 rw_cb.tcb.i93.state);
3436 return NFC_STATUS_BUSY;
3437 }
3438
3439 status = rw_i93_send_cmd_read_multi_blocks (first_block_number, number_blocks);
3440 if (status == NFC_STATUS_OK)
3441 {
3442 rw_cb.tcb.i93.state = RW_I93_STATE_BUSY;
3443 }
3444
3445 return status;
3446}
3447
3448/*******************************************************************************
3449**
3450** Function RW_I93WriteMultipleBlocks
3451**
3452** Description This function send Write Multiple Blocks command
3453**
3454** RW_I93_CMD_CMPL_EVT will be returned
3455**
3456** Returns NFC_STATUS_OK if success
3457** NFC_STATUS_NO_BUFFERS if out of buffer
3458** NFC_STATUS_BUSY if busy
3459** NFC_STATUS_FAILED if other error
3460**
3461*******************************************************************************/
3462tNFC_STATUS RW_I93WriteMultipleBlocks (UINT8 first_block_number,
3463 UINT16 number_blocks,
3464 UINT8 *p_data)
3465{
3466 tNFC_STATUS status;
3467
3468 RW_TRACE_API0 ("RW_I93WriteMultipleBlocks ()");
3469
3470 if (rw_cb.tcb.i93.state != RW_I93_STATE_IDLE)
3471 {
3472 RW_TRACE_ERROR1 ("RW_I93WriteMultipleBlocks ():Unable to start command at state (0x%X)",
3473 rw_cb.tcb.i93.state);
3474 return NFC_STATUS_BUSY;
3475 }
3476
3477 if (rw_cb.tcb.i93.block_size == 0)
3478 {
3479 RW_TRACE_ERROR0 ("RW_I93WriteSingleBlock ():Block size is unknown");
3480 return NFC_STATUS_FAILED;
3481 }
3482
3483 status = rw_i93_send_cmd_write_multi_blocks (first_block_number, number_blocks, p_data);
3484 if (status == NFC_STATUS_OK)
3485 {
3486 rw_cb.tcb.i93.state = RW_I93_STATE_BUSY;
3487 }
3488
3489 return status;
3490}
3491
3492/*******************************************************************************
3493**
3494** Function RW_I93Select
3495**
3496** Description This function send Select command
3497**
3498** UID[0]: 0xE0, MSB
3499** UID[1]: IC Mfg Code
3500** ...
3501** UID[7]: LSB
3502**
3503** RW_I93_CMD_CMPL_EVT will be returned
3504**
3505** Returns NFC_STATUS_OK if success
3506** NFC_STATUS_NO_BUFFERS if out of buffer
3507** NFC_STATUS_BUSY if busy
3508** NFC_STATUS_FAILED if other error
3509**
3510*******************************************************************************/
3511tNFC_STATUS RW_I93Select (UINT8 *p_uid)
3512{
3513 tNFC_STATUS status;
3514
3515 RW_TRACE_API0 ("RW_I93Select ()");
3516
3517 if (rw_cb.tcb.i93.state != RW_I93_STATE_IDLE)
3518 {
3519 RW_TRACE_ERROR1 ("RW_I93Select ():Unable to start command at state (0x%X)",
3520 rw_cb.tcb.i93.state);
3521 return NFC_STATUS_BUSY;
3522 }
3523
3524 if (p_uid)
3525 {
3526 status = rw_i93_send_cmd_select (p_uid);
3527 if (status == NFC_STATUS_OK)
3528 {
3529 rw_cb.tcb.i93.state = RW_I93_STATE_BUSY;
3530 }
3531 }
3532 else
3533 {
3534 RW_TRACE_ERROR0 ("RW_I93Select ():UID shall be provided");
3535 status = NFC_STATUS_FAILED;
3536 }
3537
3538 return status;
3539}
3540
3541/*******************************************************************************
3542**
3543** Function RW_I93ResetToReady
3544**
3545** Description This function send Reset To Ready command
3546**
3547** RW_I93_CMD_CMPL_EVT will be returned
3548**
3549** Returns NFC_STATUS_OK if success
3550** NFC_STATUS_NO_BUFFERS if out of buffer
3551** NFC_STATUS_BUSY if busy
3552** NFC_STATUS_FAILED if other error
3553**
3554*******************************************************************************/
3555tNFC_STATUS RW_I93ResetToReady (void)
3556{
3557 tNFC_STATUS status;
3558
3559 RW_TRACE_API0 ("RW_I93ResetToReady ()");
3560
3561 if (rw_cb.tcb.i93.state != RW_I93_STATE_IDLE)
3562 {
3563 RW_TRACE_ERROR1 ("RW_I93ResetToReady ():Unable to start command at state (0x%X)",
3564 rw_cb.tcb.i93.state);
3565 return NFC_STATUS_BUSY;
3566 }
3567
3568 status = rw_i93_send_cmd_reset_to_ready ();
3569 if (status == NFC_STATUS_OK)
3570 {
3571 rw_cb.tcb.i93.state = RW_I93_STATE_BUSY;
3572 }
3573
3574 return status;
3575}
3576
3577/*******************************************************************************
3578**
3579** Function RW_I93WriteAFI
3580**
3581** Description This function send Write AFI command
3582**
3583** RW_I93_CMD_CMPL_EVT will be returned
3584**
3585** Returns NFC_STATUS_OK if success
3586** NFC_STATUS_NO_BUFFERS if out of buffer
3587** NFC_STATUS_BUSY if busy
3588** NFC_STATUS_FAILED if other error
3589**
3590*******************************************************************************/
3591tNFC_STATUS RW_I93WriteAFI (UINT8 afi)
3592{
3593 tNFC_STATUS status;
3594
3595 RW_TRACE_API0 ("RW_I93WriteAFI ()");
3596
3597 if (rw_cb.tcb.i93.state != RW_I93_STATE_IDLE)
3598 {
3599 RW_TRACE_ERROR1 ("RW_I93WriteAFI ():Unable to start command at state (0x%X)",
3600 rw_cb.tcb.i93.state);
3601 return NFC_STATUS_BUSY;
3602 }
3603
3604 status = rw_i93_send_cmd_write_afi (afi);
3605 if (status == NFC_STATUS_OK)
3606 {
3607 rw_cb.tcb.i93.state = RW_I93_STATE_BUSY;
3608 }
3609
3610 return status;
3611}
3612
3613/*******************************************************************************
3614**
3615** Function RW_I93LockAFI
3616**
3617** Description This function send Lock AFI command
3618**
3619** RW_I93_CMD_CMPL_EVT will be returned
3620**
3621** Returns NFC_STATUS_OK if success
3622** NFC_STATUS_NO_BUFFERS if out of buffer
3623** NFC_STATUS_BUSY if busy
3624** NFC_STATUS_FAILED if other error
3625**
3626*******************************************************************************/
3627tNFC_STATUS RW_I93LockAFI (void)
3628{
3629 tNFC_STATUS status;
3630
3631 RW_TRACE_API0 ("RW_I93LockAFI ()");
3632
3633 if (rw_cb.tcb.i93.state != RW_I93_STATE_IDLE)
3634 {
3635 RW_TRACE_ERROR1 ("RW_I93LockAFI ():Unable to start command at state (0x%X)",
3636 rw_cb.tcb.i93.state);
3637 return NFC_STATUS_BUSY;
3638 }
3639
3640 status = rw_i93_send_cmd_lock_afi ();
3641 if (status == NFC_STATUS_OK)
3642 {
3643 rw_cb.tcb.i93.state = RW_I93_STATE_BUSY;
3644 }
3645
3646 return status;
3647}
3648
3649/*******************************************************************************
3650**
3651** Function RW_I93WriteDSFID
3652**
3653** Description This function send Write DSFID command
3654**
3655** RW_I93_CMD_CMPL_EVT will be returned
3656**
3657** Returns NFC_STATUS_OK if success
3658** NFC_STATUS_NO_BUFFERS if out of buffer
3659** NFC_STATUS_BUSY if busy
3660** NFC_STATUS_FAILED if other error
3661**
3662*******************************************************************************/
3663tNFC_STATUS RW_I93WriteDSFID (UINT8 dsfid)
3664{
3665 tNFC_STATUS status;
3666
3667 RW_TRACE_API0 ("RW_I93WriteDSFID ()");
3668
3669 if (rw_cb.tcb.i93.state != RW_I93_STATE_IDLE)
3670 {
3671 RW_TRACE_ERROR1 ("RW_I93WriteDSFID ():Unable to start command at state (0x%X)",
3672 rw_cb.tcb.i93.state);
3673 return NFC_STATUS_BUSY;
3674 }
3675
3676 status = rw_i93_send_cmd_write_dsfid (dsfid);
3677 if (status == NFC_STATUS_OK)
3678 {
3679 rw_cb.tcb.i93.state = RW_I93_STATE_BUSY;
3680 }
3681
3682 return status;
3683}
3684
3685/*******************************************************************************
3686**
3687** Function RW_I93LockDSFID
3688**
3689** Description This function send Lock DSFID command
3690**
3691** RW_I93_CMD_CMPL_EVT will be returned
3692**
3693** Returns NFC_STATUS_OK if success
3694** NFC_STATUS_NO_BUFFERS if out of buffer
3695** NFC_STATUS_BUSY if busy
3696** NFC_STATUS_FAILED if other error
3697**
3698*******************************************************************************/
3699tNFC_STATUS RW_I93LockDSFID (void)
3700{
3701 tNFC_STATUS status;
3702
3703 RW_TRACE_API0 ("RW_I93LockDSFID ()");
3704
3705 if (rw_cb.tcb.i93.state != RW_I93_STATE_IDLE)
3706 {
3707 RW_TRACE_ERROR1 ("RW_I93LockDSFID ():Unable to start command at state (0x%X)",
3708 rw_cb.tcb.i93.state);
3709 return NFC_STATUS_BUSY;
3710 }
3711
3712 status = rw_i93_send_cmd_lock_dsfid ();
3713 if (status == NFC_STATUS_OK)
3714 {
3715 rw_cb.tcb.i93.state = RW_I93_STATE_BUSY;
3716 }
3717
3718 return status;
3719}
3720
3721/*******************************************************************************
3722**
3723** Function RW_I93GetSysInfo
3724**
3725** Description This function send Get System Information command
3726**
3727** RW_I93_RESPONSE_EVT will be returned
3728**
3729** Returns NFC_STATUS_OK if success
3730** NFC_STATUS_NO_BUFFERS if out of buffer
3731** NFC_STATUS_BUSY if busy
3732** NFC_STATUS_FAILED if other error
3733**
3734*******************************************************************************/
3735tNFC_STATUS RW_I93GetSysInfo (UINT8 *p_uid)
3736{
3737 tNFC_STATUS status;
3738
3739 RW_TRACE_API0 ("RW_I93GetSysInfo ()");
3740
3741 if (rw_cb.tcb.i93.state != RW_I93_STATE_IDLE)
3742 {
3743 RW_TRACE_ERROR1 ("RW_I93GetSysInfo ():Unable to start command at state (0x%X)",
3744 rw_cb.tcb.i93.state);
3745 return NFC_STATUS_BUSY;
3746 }
3747
3748 if (p_uid)
3749 {
Evan Chu85b7e842013-01-18 11:02:50 -05003750 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 -08003751 }
3752 else
3753 {
Evan Chu85b7e842013-01-18 11:02:50 -05003754 status = rw_i93_send_cmd_get_sys_info (NULL, I93_FLAG_PROT_EXT_NO);
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08003755 }
3756
3757 if (status == NFC_STATUS_OK)
3758 {
3759 rw_cb.tcb.i93.state = RW_I93_STATE_BUSY;
3760 }
3761
3762 return status;
3763}
3764
3765/*******************************************************************************
3766**
3767** Function RW_I93GetMultiBlockSecurityStatus
3768**
3769** Description This function send Get Multiple Block Security Status command
3770**
3771** RW_I93_RESPONSE_EVT will be returned
3772**
3773** Returns NFC_STATUS_OK if success
3774** NFC_STATUS_NO_BUFFERS if out of buffer
3775** NFC_STATUS_BUSY if busy
3776** NFC_STATUS_FAILED if other error
3777**
3778*******************************************************************************/
Evan Chu85b7e842013-01-18 11:02:50 -05003779tNFC_STATUS RW_I93GetMultiBlockSecurityStatus (UINT16 first_block_number,
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08003780 UINT16 number_blocks)
3781{
3782 tNFC_STATUS status;
3783
3784 RW_TRACE_API0 ("RW_I93GetMultiBlockSecurityStatus ()");
3785
3786 if (rw_cb.tcb.i93.state != RW_I93_STATE_IDLE)
3787 {
3788 RW_TRACE_ERROR1 ("RW_I93GetMultiBlockSecurityStatus ():Unable to start command at state (0x%X)",
3789 rw_cb.tcb.i93.state);
3790 return NFC_STATUS_BUSY;
3791 }
3792
3793 status = rw_i93_send_cmd_get_multi_block_sec (first_block_number, number_blocks);
3794 if (status == NFC_STATUS_OK)
3795 {
3796 rw_cb.tcb.i93.state = RW_I93_STATE_BUSY;
3797 }
3798
3799 return status;
3800}
3801
3802/*******************************************************************************
3803**
3804** Function RW_I93DetectNDef
3805**
3806** Description This function performs NDEF detection procedure
3807**
3808** RW_I93_NDEF_DETECT_EVT will be returned
3809**
3810** Returns NFC_STATUS_OK if success
3811** NFC_STATUS_FAILED if busy or other error
3812**
3813*******************************************************************************/
3814tNFC_STATUS RW_I93DetectNDef (void)
3815{
3816 tNFC_STATUS status;
3817 tRW_I93_RW_SUBSTATE sub_state;
3818
3819 RW_TRACE_API0 ("RW_I93DetectNDef ()");
3820
3821 if (rw_cb.tcb.i93.state != RW_I93_STATE_IDLE)
3822 {
3823 RW_TRACE_ERROR1 ("RW_I93DetectNDef ():Unable to start command at state (0x%X)",
3824 rw_cb.tcb.i93.state);
3825 return NFC_STATUS_FAILED;
3826 }
3827
3828 if (rw_cb.tcb.i93.uid[0] != I93_UID_FIRST_BYTE)
3829 {
Martijn Coenen5c65c3a2013-03-27 13:23:36 -07003830 status = rw_i93_send_cmd_inventory (NULL, FALSE, 0x00);
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08003831 sub_state = RW_I93_SUBSTATE_WAIT_UID;
3832 }
3833 else if ( (rw_cb.tcb.i93.num_block == 0)
3834 ||(rw_cb.tcb.i93.block_size == 0) )
3835 {
Evan Chu85b7e842013-01-18 11:02:50 -05003836 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 -08003837 sub_state = RW_I93_SUBSTATE_WAIT_SYS_INFO;
Evan Chu85b7e842013-01-18 11:02:50 -05003838
3839 /* clear all flags */
3840 rw_cb.tcb.i93.intl_flags = 0;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08003841 }
3842 else
3843 {
3844 /* read CC in the first block */
Evan Chu85b7e842013-01-18 11:02:50 -05003845 status = rw_i93_send_cmd_read_single_block (0x0000, FALSE);
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08003846 sub_state = RW_I93_SUBSTATE_WAIT_CC;
3847 }
3848
3849 if (status == NFC_STATUS_OK)
3850 {
3851 rw_cb.tcb.i93.state = RW_I93_STATE_DETECT_NDEF;
3852 rw_cb.tcb.i93.sub_state = sub_state;
Evan Chu85b7e842013-01-18 11:02:50 -05003853
3854 /* clear flags except flag for 2 bytes of number of blocks */
3855 rw_cb.tcb.i93.intl_flags &= RW_I93_FLAG_16BIT_NUM_BLOCK;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08003856 }
3857
3858 return (status);
3859}
3860
3861/*******************************************************************************
3862**
3863** Function RW_I93ReadNDef
3864**
3865** Description This function performs NDEF read procedure
3866** Note: RW_I93DetectNDef () must be called before using this
3867**
3868** The following event will be returned
3869** RW_I93_NDEF_READ_EVT for each segmented NDEF message
3870** RW_I93_NDEF_READ_CPLT_EVT for the last segment or complete NDEF
3871** RW_I93_NDEF_READ_FAIL_EVT for failure
3872**
3873** Returns NFC_STATUS_OK if success
3874** NFC_STATUS_FAILED if I93 is busy or other error
3875**
3876*******************************************************************************/
3877tNFC_STATUS RW_I93ReadNDef (void)
3878{
3879 RW_TRACE_API0 ("RW_I93ReadNDef ()");
3880
3881 if (rw_cb.tcb.i93.state != RW_I93_STATE_IDLE)
3882 {
3883 RW_TRACE_ERROR1 ("RW_I93ReadNDef ():Unable to start command at state (0x%X)",
3884 rw_cb.tcb.i93.state);
3885 return NFC_STATUS_FAILED;
3886 }
3887
3888 if ( (rw_cb.tcb.i93.tlv_type == I93_ICODE_TLV_TYPE_NDEF)
3889 &&(rw_cb.tcb.i93.ndef_length > 0) )
3890 {
3891 rw_cb.tcb.i93.rw_offset = rw_cb.tcb.i93.ndef_tlv_start_offset;
3892 rw_cb.tcb.i93.rw_length = 0;
3893
3894 if (rw_i93_get_next_blocks (rw_cb.tcb.i93.rw_offset) == NFC_STATUS_OK)
3895 {
3896 rw_cb.tcb.i93.state = RW_I93_STATE_READ_NDEF;
3897 }
3898 else
3899 {
3900 return NFC_STATUS_FAILED;
3901 }
3902 }
3903 else
3904 {
3905 RW_TRACE_ERROR0 ("RW_I93ReadNDef ():No NDEF detected");
3906 return NFC_STATUS_FAILED;
3907 }
3908
3909 return NFC_STATUS_OK;
3910}
3911
3912/*******************************************************************************
3913**
3914** Function RW_I93UpdateNDef
3915**
3916** Description This function performs NDEF update procedure
3917** Note: RW_I93DetectNDef () must be called before using this
3918** Updating data must not be removed until returning event
3919**
3920** The following event will be returned
3921** RW_I93_NDEF_UPDATE_CPLT_EVT for complete
3922** RW_I93_NDEF_UPDATE_FAIL_EVT for failure
3923**
3924** Returns NFC_STATUS_OK if success
3925** NFC_STATUS_FAILED if I93 is busy or other error
3926**
3927*******************************************************************************/
3928tNFC_STATUS RW_I93UpdateNDef (UINT16 length, UINT8 *p_data)
3929{
Evan Chu85b7e842013-01-18 11:02:50 -05003930 UINT16 block_number;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08003931
3932 RW_TRACE_API1 ("RW_I93UpdateNDef () length:%d", length);
3933
3934 if (rw_cb.tcb.i93.state != RW_I93_STATE_IDLE)
3935 {
3936 RW_TRACE_ERROR1 ("RW_I93UpdateNDef ():Unable to start command at state (0x%X)",
3937 rw_cb.tcb.i93.state);
3938 return NFC_STATUS_FAILED;
3939 }
3940
3941 if (rw_cb.tcb.i93.tlv_type == I93_ICODE_TLV_TYPE_NDEF)
3942 {
3943 if (rw_cb.tcb.i93.intl_flags & RW_I93_FLAG_READ_ONLY)
3944 {
3945 RW_TRACE_ERROR0 ("RW_I93UpdateNDef ():NDEF is read-only");
3946 return NFC_STATUS_FAILED;
3947 }
3948 if (rw_cb.tcb.i93.max_ndef_length < length)
3949 {
3950 RW_TRACE_ERROR2 ("RW_I93UpdateNDef ():data (%d bytes) is more than max NDEF length (%d)",
3951 length, rw_cb.tcb.i93.max_ndef_length);
3952 return NFC_STATUS_FAILED;
3953 }
3954
3955 rw_cb.tcb.i93.ndef_length = length;
3956 rw_cb.tcb.i93.p_update_data = p_data;
3957
3958 /* read length field */
3959 rw_cb.tcb.i93.rw_offset = rw_cb.tcb.i93.ndef_tlv_start_offset + 1;
3960 rw_cb.tcb.i93.rw_length = 0;
3961
Evan Chu85b7e842013-01-18 11:02:50 -05003962 block_number = rw_cb.tcb.i93.rw_offset / rw_cb.tcb.i93.block_size;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08003963
3964 if (rw_i93_send_cmd_read_single_block (block_number, FALSE) == NFC_STATUS_OK)
3965 {
3966 rw_cb.tcb.i93.state = RW_I93_STATE_UPDATE_NDEF;
3967 rw_cb.tcb.i93.sub_state = RW_I93_SUBSTATE_RESET_LEN;
3968 }
3969 else
3970 {
3971 return NFC_STATUS_FAILED;
3972 }
3973 }
3974 else
3975 {
3976 RW_TRACE_ERROR0 ("RW_I93ReadNDef ():No NDEF detected");
3977 return NFC_STATUS_FAILED;
3978 }
3979
3980 return NFC_STATUS_OK;
3981}
3982
3983/*******************************************************************************
3984**
3985** Function RW_I93FormatNDef
3986**
3987** Description This function performs formatting procedure
3988**
3989** RW_I93_FORMAT_CPLT_EVT will be returned
3990**
3991** Returns NFC_STATUS_OK if success
3992** NFC_STATUS_FAILED if busy or other error
3993**
3994*******************************************************************************/
3995tNFC_STATUS RW_I93FormatNDef (void)
3996{
3997 tNFC_STATUS status;
3998 tRW_I93_RW_SUBSTATE sub_state;
3999
4000 RW_TRACE_API0 ("RW_I93FormatNDef ()");
4001
4002 if (rw_cb.tcb.i93.state != RW_I93_STATE_IDLE)
4003 {
4004 RW_TRACE_ERROR1 ("RW_I93FormatNDef ():Unable to start command at state (0x%X)",
4005 rw_cb.tcb.i93.state);
4006 return NFC_STATUS_FAILED;
4007 }
4008
4009 if ( (rw_cb.tcb.i93.product_version == RW_I93_TAG_IT_HF_I_STD_CHIP_INLAY)
4010 ||(rw_cb.tcb.i93.product_version == RW_I93_TAG_IT_HF_I_PRO_CHIP_INLAY) )
4011 {
4012 /* These don't support GetSystemInformation and GetMultiBlockSecurityStatus */
4013 rw_cb.tcb.i93.rw_offset = 0;
4014
4015 /* read blocks with option flag to get block security status */
Evan Chu85b7e842013-01-18 11:02:50 -05004016 status = rw_i93_send_cmd_read_single_block (0x0000, TRUE);
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08004017 sub_state = RW_I93_SUBSTATE_CHECK_READ_ONLY;
4018 }
4019 else
4020 {
Martijn Coenen5c65c3a2013-03-27 13:23:36 -07004021 status = rw_i93_send_cmd_inventory (rw_cb.tcb.i93.uid, FALSE, 0x00);
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08004022 sub_state = RW_I93_SUBSTATE_WAIT_UID;
4023 }
4024
4025 if (status == NFC_STATUS_OK)
4026 {
4027 rw_cb.tcb.i93.state = RW_I93_STATE_FORMAT;
4028 rw_cb.tcb.i93.sub_state = sub_state;
4029 rw_cb.tcb.i93.intl_flags = 0;
4030 }
4031
4032 return (status);
4033}
4034
4035/*******************************************************************************
4036**
4037** Function RW_I93SetTagReadOnly
4038**
4039** Description This function performs NDEF read-only procedure
4040** Note: RW_I93DetectNDef () must be called before using this
4041** Updating data must not be removed until returning event
4042**
4043** The RW_I93_SET_TAG_RO_EVT event will be returned.
4044**
4045** Returns NFC_STATUS_OK if success
4046** NFC_STATUS_FAILED if I93 is busy or other error
4047**
4048*******************************************************************************/
4049tNFC_STATUS RW_I93SetTagReadOnly (void)
4050{
4051 RW_TRACE_API0 ("RW_I93SetTagReadOnly ()");
4052
4053 if (rw_cb.tcb.i93.state != RW_I93_STATE_IDLE)
4054 {
4055 RW_TRACE_ERROR1 ("RW_I93SetTagReadOnly ():Unable to start command at state (0x%X)",
4056 rw_cb.tcb.i93.state);
4057 return NFC_STATUS_FAILED;
4058 }
4059
4060 if (rw_cb.tcb.i93.tlv_type == I93_ICODE_TLV_TYPE_NDEF)
4061 {
4062 if (rw_cb.tcb.i93.intl_flags & RW_I93_FLAG_READ_ONLY)
4063 {
4064 RW_TRACE_ERROR0 ("RW_I93SetTagReadOnly ():NDEF is already read-only");
4065 return NFC_STATUS_FAILED;
4066 }
4067
4068 /* get CC in the first block */
4069 if (rw_i93_send_cmd_read_single_block (0, FALSE) == NFC_STATUS_OK)
4070 {
4071 rw_cb.tcb.i93.state = RW_I93_STATE_SET_READ_ONLY;
4072 rw_cb.tcb.i93.sub_state = RW_I93_SUBSTATE_WAIT_CC;
4073 }
4074 else
4075 {
4076 return NFC_STATUS_FAILED;
4077 }
4078 }
4079 else
4080 {
4081 RW_TRACE_ERROR0 ("RW_I93SetTagReadOnly ():No NDEF detected");
4082 return NFC_STATUS_FAILED;
4083 }
4084
4085 return NFC_STATUS_OK;
4086}
4087
4088/*****************************************************************************
4089**
4090** Function RW_I93PresenceCheck
4091**
4092** Description Check if the tag is still in the field.
4093**
4094** The RW_I93_PRESENCE_CHECK_EVT w/ status is used to indicate
4095** presence or non-presence.
4096**
4097** Returns NFC_STATUS_OK, if raw data frame sent
4098** NFC_STATUS_NO_BUFFERS: unable to allocate a buffer for this operation
4099** NFC_STATUS_FAILED: other error
4100**
4101*****************************************************************************/
4102tNFC_STATUS RW_I93PresenceCheck (void)
4103{
4104
4105 tNFC_STATUS status;
4106 tRW_DATA evt_data;
4107
4108 RW_TRACE_API0 ("RW_I93PresenceCheck ()");
4109
4110 if (!rw_cb.p_cback)
4111 {
4112 return NFC_STATUS_FAILED;
4113 }
4114 else if (rw_cb.tcb.i93.state == RW_I93_STATE_NOT_ACTIVATED)
4115 {
4116 evt_data.status = NFC_STATUS_FAILED;
4117 (*rw_cb.p_cback) (RW_T4T_PRESENCE_CHECK_EVT, &evt_data);
4118
4119 return NFC_STATUS_OK;
4120 }
4121 else if (rw_cb.tcb.i93.state != RW_I93_STATE_IDLE)
4122 {
4123 return NFC_STATUS_BUSY;
4124 }
4125 else
4126 {
Martijn Coenen5c65c3a2013-03-27 13:23:36 -07004127 /* The support of AFI by the VICC is optional, so do not include AFI */
4128 status = rw_i93_send_cmd_inventory (rw_cb.tcb.i93.uid, FALSE, 0x00);
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08004129
4130 if (status == NFC_STATUS_OK)
4131 {
Evan Chu85b7e842013-01-18 11:02:50 -05004132 /* do not retry during presence check */
4133 rw_cb.tcb.i93.retry_count = RW_MAX_RETRIES;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08004134 rw_cb.tcb.i93.state = RW_I93_STATE_PRESENCE_CHECK;
4135 }
4136 }
4137
4138 return (status);
4139}
4140
4141#if (BT_TRACE_VERBOSE == TRUE)
4142/*******************************************************************************
4143**
4144** Function rw_i93_get_state_name
4145**
4146** Description This function returns the state name.
4147**
4148** NOTE conditionally compiled to save memory.
4149**
4150** Returns pointer to the name
4151**
4152*******************************************************************************/
4153static char *rw_i93_get_state_name (UINT8 state)
4154{
4155 switch (state)
4156 {
4157 case RW_I93_STATE_NOT_ACTIVATED:
4158 return ("NOT_ACTIVATED");
4159 case RW_I93_STATE_IDLE:
4160 return ("IDLE");
4161 case RW_I93_STATE_BUSY:
4162 return ("BUSY");
4163
4164 case RW_I93_STATE_DETECT_NDEF:
4165 return ("NDEF_DETECTION");
4166 case RW_I93_STATE_READ_NDEF:
4167 return ("READ_NDEF");
4168 case RW_I93_STATE_UPDATE_NDEF:
4169 return ("UPDATE_NDEF");
4170 case RW_I93_STATE_FORMAT:
4171 return ("FORMAT");
4172 case RW_I93_STATE_SET_READ_ONLY:
4173 return ("SET_READ_ONLY");
4174
4175 case RW_I93_STATE_PRESENCE_CHECK:
4176 return ("PRESENCE_CHECK");
4177 default:
4178 return ("???? UNKNOWN STATE");
4179 }
4180}
4181
4182/*******************************************************************************
4183**
4184** Function rw_i93_get_sub_state_name
4185**
4186** Description This function returns the sub_state name.
4187**
4188** NOTE conditionally compiled to save memory.
4189**
4190** Returns pointer to the name
4191**
4192*******************************************************************************/
4193static char *rw_i93_get_sub_state_name (UINT8 sub_state)
4194{
4195 switch (sub_state)
4196 {
4197 case RW_I93_SUBSTATE_WAIT_UID:
4198 return ("WAIT_UID");
4199 case RW_I93_SUBSTATE_WAIT_SYS_INFO:
4200 return ("WAIT_SYS_INFO");
4201 case RW_I93_SUBSTATE_WAIT_CC:
4202 return ("WAIT_CC");
4203 case RW_I93_SUBSTATE_SEARCH_NDEF_TLV:
4204 return ("SEARCH_NDEF_TLV");
4205 case RW_I93_SUBSTATE_CHECK_LOCK_STATUS:
4206 return ("CHECK_LOCK_STATUS");
4207 case RW_I93_SUBSTATE_RESET_LEN:
4208 return ("RESET_LEN");
4209 case RW_I93_SUBSTATE_WRITE_NDEF:
4210 return ("WRITE_NDEF");
4211 case RW_I93_SUBSTATE_UPDATE_LEN:
4212 return ("UPDATE_LEN");
4213 case RW_I93_SUBSTATE_WAIT_RESET_DSFID_AFI:
4214 return ("WAIT_RESET_DSFID_AFI");
4215 case RW_I93_SUBSTATE_CHECK_READ_ONLY:
4216 return ("CHECK_READ_ONLY");
4217 case RW_I93_SUBSTATE_WRITE_CC_NDEF_TLV:
4218 return ("WRITE_CC_NDEF_TLV");
4219 case RW_I93_SUBSTATE_WAIT_UPDATE_CC:
4220 return ("WAIT_UPDATE_CC");
4221 case RW_I93_SUBSTATE_LOCK_NDEF_TLV:
4222 return ("LOCK_NDEF_TLV");
4223 case RW_I93_SUBSTATE_WAIT_LOCK_CC:
4224 return ("WAIT_LOCK_CC");
4225 default:
4226 return ("???? UNKNOWN SUBSTATE");
4227 }
4228}
Evan Chu85b7e842013-01-18 11:02:50 -05004229
4230/*******************************************************************************
4231**
4232** Function rw_i93_get_tag_name
4233**
4234** Description This function returns the tag name.
4235**
4236** NOTE conditionally compiled to save memory.
4237**
4238** Returns pointer to the name
4239**
4240*******************************************************************************/
4241static char *rw_i93_get_tag_name (UINT8 product_version)
4242{
4243 switch (product_version)
4244 {
4245 case RW_I93_ICODE_SLI:
4246 return ("SLI/SLIX");
4247 case RW_I93_ICODE_SLI_S:
4248 return ("SLI-S/SLIX-S");
4249 case RW_I93_ICODE_SLI_L:
4250 return ("SLI-L/SLIX-L");
4251 case RW_I93_TAG_IT_HF_I_PLUS_INLAY:
4252 return ("Tag-it HF-I Plus Inlay");
4253 case RW_I93_TAG_IT_HF_I_PLUS_CHIP:
4254 return ("Tag-it HF-I Plus Chip");
4255 case RW_I93_TAG_IT_HF_I_STD_CHIP_INLAY:
4256 return ("Tag-it HF-I Standard Chip/Inlyas");
4257 case RW_I93_TAG_IT_HF_I_PRO_CHIP_INLAY:
4258 return ("Tag-it HF-I Pro Chip/Inlays");
4259 case RW_I93_STM_LRI1K:
4260 return ("LRi1K");
4261 case RW_I93_STM_LRI2K:
4262 return ("LRi2K");
4263 case RW_I93_STM_LRIS2K:
4264 return ("LRiS2K");
4265 case RW_I93_STM_LRIS64K:
4266 return ("LRiS64K");
4267 case RW_I93_STM_M24LR64_R:
4268 return ("M24LR64");
4269 case RW_I93_STM_M24LR04E_R:
4270 return ("M24LR04E");
4271 case RW_I93_STM_M24LR16E_R:
4272 return ("M24LR16E");
4273 case RW_I93_STM_M24LR64E_R:
4274 return ("M24LR64E");
4275 case RW_I93_UNKNOWN_PRODUCT:
4276 default:
4277 return ("UNKNOWN");
4278 }
4279}
4280
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08004281#endif
4282
4283#endif /* (NFC_INCLUDED == TRUE) */