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