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