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