1 /*
2 *
3 * Copyright (C) 2010 NXP Semiconductors
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 * \file phFriNfc_ISO15693Map.c
20 * \brief This component encapsulates read/write/check ndef/process functionalities,
21 * for the ISO-15693 Card.
22 *
23 * Project: NFC-FRI
24 *
25 * $Date: $
26 * $Author: ing02260 $
27 * $Revision: $
28 * $Aliases: $
29 *
30 */
31
32 #ifndef PH_FRINFC_MAP_ISO15693_DISABLED
33
34 #include <phNfcTypes.h>
35 #include <phNfcConfig.h>
36 #include <phNfcInterface.h>
37 #include <phNfcHalTypes.h>
38 #include <phFriNfc.h>
39 #include <phFriNfc_NdefMap.h>
40 #include <phFriNfc_OvrHal.h>
41 #include <phFriNfc_MapTools.h>
42 #include <phFriNfc_ISO15693Map.h>
43
44 /************************** START DATA STRUCTURE *********************/
45
46 typedef enum phFriNfc_eChkNdefSeq
47 {
48 ISO15693_NDEF_TLV_T,
49 ISO15693_NDEF_TLV_L,
50 ISO15693_NDEF_TLV_V,
51 ISO15693_PROP_TLV_L,
52 ISO15693_PROP_TLV_V
53
54 }phFriNfc_eChkNdefSeq_t;
55
56 typedef enum phFriNfc_eWrNdefSeq
57 {
58 ISO15693_RD_BEFORE_WR_NDEF_L_0,
59 ISO15693_WRITE_DATA,
60 ISO15693_RD_BEFORE_WR_NDEF_L,
61 ISO15693_WRITE_NDEF_TLV_L
62
63 }phFriNfc_eWrNdefSeq_t;
64
65 #ifdef FRINFC_READONLY_NDEF
66
67 typedef enum phFriNfc_eRONdefSeq
68 {
69 ISO15693_RD_BEFORE_WR_CC,
70 ISO15693_WRITE_CC,
71 ISO15693_LOCK_BLOCK
72
73 }phFriNfc_eRONdefSeq_t;
74
75 #endif /* #ifdef FRINFC_READONLY_NDEF */
76
77 /************************** END DATA STRUCTURE *********************/
78
79 /************************** START MACROS definition *********************/
80
81
82
83
84 /* UID bytes to differentiate ICODE cards */
85 #define ISO15693_UID_BYTE_4 0x04U
86 #define ISO15693_UID_BYTE_5 0x05U
87 #define ISO15693_UID_BYTE_6 0x06U
88 #define ISO15693_UID_BYTE_7 0x07U
89
90 /* UID 7th byte value shall be 0xE0 */
91 #define ISO15693_UIDBYTE_7_VALUE 0xE0U
92 /* UID 6th byte value shall be 0x04 - NXP manufacturer */
93 #define ISO15693_UIDBYTE_6_VALUE 0x04U
94
95
96 /* UID value for
97 SL2 ICS20
98 SL2S2002
99 */
100 #define ISO15693_UIDBYTE_5_VALUE_SLI_X 0x01U
101 /* Card size SL2 ICS20 / SL2S2002 */
102 #define ISO15693_SL2_S2002_ICS20 112U
103
104 /* UID value for
105 SL2 ICS53,
106 SL2 ICS54
107 SL2S5302
108 */
109 #define ISO15693_UIDBYTE_5_VALUE_SLI_X_S 0x02U
110 #define ISO15693_UIDBYTE_4_VALUE_SLI_X_S 0x00U
111 #define ISO15693_UIDBYTE_4_VALUE_SLI_X_SHC 0x80U
112 #define ISO15693_UIDBYTE_4_VALUE_SLI_X_SY 0x40U
113 /* SL2 ICS53, SL2 ICS54 and SL2S5302 */
114 #define ISO15693_SL2_S5302_ICS53_ICS54 160U
115
116 /* UID value for
117 SL2 ICS50
118 SL2 ICS51
119 SL2S5002
120 */
121 #define ISO15693_UIDBYTE_5_VALUE_SLI_X_L 0x03U
122 #define ISO15693_UIDBYTE_4_VALUE_SLI_X_L 0x00U
123 #define ISO15693_UIDBYTE_4_VALUE_SLI_X_LHC 0x80U
124 /* SL2 ICS50, SL2 ICS51 and SL2S5002 */
125 #define ISO15693_SL2_S5002_ICS50_ICS51 32U
126
127
128 /* State Machine declaration
129 CHECK NDEF state */
130 #define ISO15693_CHECK_NDEF 0x01U
131 /* READ NDEF state */
132 #define ISO15693_READ_NDEF 0x02U
133 /* WRITE NDEF state */
134 #define ISO15693_WRITE_NDEF 0x03U
135 #ifdef FRINFC_READONLY_NDEF
136
137 /* READ ONLY NDEF state */
138 #define ISO15693_READ_ONLY_NDEF 0x04U
139
140 /* READ ONLY MASK byte for CC */
141 #define ISO15693_CC_READ_ONLY_MASK 0x03U
142
143 /* CC READ WRITE index */
144 #define ISO15693_RW_BTYE_INDEX 0x01U
145
146 /* LOCK BLOCK command */
147 #define ISO15693_LOCK_BLOCK_CMD 0x22U
148
149 #endif /* #ifdef FRINFC_READONLY_NDEF */
150
151 /* CC Bytes
152 Magic number */
153 #define ISO15693_CC_MAGIC_BYTE 0xE1U
154 /* Expected mapping version */
155 #define ISO15693_MAPPING_VERSION 0x01U
156 /* Major version is in upper 2 bits */
157 #define ISO15693_MAJOR_VERSION_MASK 0xC0U
158
159 /* CC indicating tag is capable of multi-block read */
160 #define ISO15693_CC_USE_MBR 0x01U
161 /* CC indicating tag is capable of inventory page read */
162 #define ISO15693_CC_USE_IPR 0x02U
163 /* EXTRA byte in the response */
164 #define ISO15693_EXTRA_RESP_BYTE 0x01U
165
166 /* Maximum card size multiplication factor */
167 #define ISO15693_MULT_FACTOR 0x08U
168 /* NIBBLE mask for READ WRITE access */
169 #define ISO15693_LSB_NIBBLE_MASK 0x0FU
170 #define ISO15693_RD_WR_PERMISSION 0x00U
171 #define ISO15693_RD_ONLY_PERMISSION 0x03U
172
173 /* READ command identifier */
174 #define ISO15693_READ_COMMAND 0x20U
175
176 /* READ multiple command identifier */
177 #define ISO15693_READ_MULTIPLE_COMMAND 0x23U
178
179 /* INVENTORY pageread command identifier */
180 #define ICODE_INVENTORY_PAGEREAD_COMMAND 0xB0U
181 #define INVENTORY_PAGEREAD_FLAGS 0x24U
182 #define NXP_MANUFACTURING_CODE 0x04U
183
184 /* WRITE command identifier */
185 #define ISO15693_WRITE_COMMAND 0x21U
186 /* FLAG option */
187 #define ISO15693_FLAGS 0x20U
188
189 /* RESPONSE length expected for single block READ */
190 #define ISO15693_SINGLE_BLK_RD_RESP_LEN 0x04U
191 /* NULL TLV identifier */
192 #define ISO15693_NULL_TLV_ID 0x00U
193 /* NDEF TLV, TYPE identifier */
194 #define ISO15693_NDEF_TLV_TYPE_ID 0x03U
195
196 /* 8 BIT shift */
197 #define ISO15693_BTYE_SHIFT 0x08U
198
199 /* Proprietary TLV TYPE identifier */
200 #define ISO15693_PROP_TLV_ID 0xFDU
201
202 /* CC SIZE in BYTES */
203 #define ISO15693_CC_SIZE 0x04U
204
205 /* To get the remaining size in the card.
206 Inputs are
207 1. maximum data size
208 2. block number
209 3. index of the block number */
210 #define ISO15693_GET_REMAINING_SIZE(max_data_size, blk, index) \
211 (max_data_size - ((blk * ISO15693_BYTES_PER_BLOCK) + index))
212
213 #define ISO15693_GET_LEN_FIELD_BLOCK_NO(blk, byte_addr, ndef_size) \
214 (((byte_addr + ((ndef_size >= ISO15693_THREE_BYTE_LENGTH_ID) ? 3 : 1)) > \
215 (ISO15693_BYTES_PER_BLOCK - 1)) ? (blk + 1) : blk)
216
217 #define ISO15693_GET_LEN_FIELD_BYTE_NO(blk, byte_addr, ndef_size) \
218 (((byte_addr + ((ndef_size >= ISO15693_THREE_BYTE_LENGTH_ID) ? 3 : 1)) % \
219 ISO15693_BYTES_PER_BLOCK))
220
221
222
223 /************************** END MACROS definition *********************/
224
225 /************************** START static functions declaration *********************/
226 static
227 NFCSTATUS
228 phFriNfc_ISO15693_H_ProcessReadOnly (
229 phFriNfc_NdefMap_t *psNdefMap);
230
231 static
232 NFCSTATUS
233 phFriNfc_ISO15693_H_ProcessWriteNdef (
234 phFriNfc_NdefMap_t *psNdefMap);
235
236 static
237 NFCSTATUS
238 phFriNfc_ISO15693_H_ProcessReadNdef (
239 phFriNfc_NdefMap_t *psNdefMap);
240
241 static
242 NFCSTATUS
243 phFriNfc_ISO15693_H_ProcessCheckNdef (
244 phFriNfc_NdefMap_t *psNdefMap);
245
246 static
247 void
248 phFriNfc_ISO15693_H_Complete (
249 phFriNfc_NdefMap_t *psNdefMap,
250 NFCSTATUS Status);
251
252 static
253 NFCSTATUS
254 phFriNfc_ISO15693_H_ReadWrite (
255 phFriNfc_NdefMap_t *psNdefMap,
256 uint8_t command,
257 uint8_t *p_data,
258 uint8_t data_length);
259
260 static
261 NFCSTATUS
262 phFriNfc_ReadRemainingInMultiple (
263 phFriNfc_NdefMap_t *psNdefMap,
264 uint32_t startBlock);
265
266 /************************** END static functions declaration *********************/
267
268 /************************** START static functions definition *********************/
269
270 static
271 NFCSTATUS
phFriNfc_ISO15693_H_ProcessWriteNdef(phFriNfc_NdefMap_t * psNdefMap)272 phFriNfc_ISO15693_H_ProcessWriteNdef (
273 phFriNfc_NdefMap_t *psNdefMap)
274 {
275 NFCSTATUS result = NFCSTATUS_SUCCESS;
276 phFriNfc_ISO15693Cont_t *ps_iso_15693_con =
277 &(psNdefMap->ISO15693Container);
278 phFriNfc_eWrNdefSeq_t e_wr_ndef_seq = (phFriNfc_eWrNdefSeq_t)
279 psNdefMap->ISO15693Container.ndef_seq;
280 uint8_t *p_recv_buf = NULL;
281 uint8_t recv_length = 0;
282 uint8_t write_flag = FALSE;
283 uint8_t a_write_buf[ISO15693_BYTES_PER_BLOCK] = {0};
284 uint8_t remaining_size = 0;
285
286 switch (e_wr_ndef_seq)
287 {
288 case ISO15693_RD_BEFORE_WR_NDEF_L_0:
289 {
290 /* L byte is read */
291 p_recv_buf = (psNdefMap->SendRecvBuf + ISO15693_EXTRA_RESP_BYTE);
292 recv_length = (uint8_t)
293 (*psNdefMap->SendRecvLength - ISO15693_EXTRA_RESP_BYTE);
294
295 if (ISO15693_SINGLE_BLK_RD_RESP_LEN == recv_length)
296 {
297 /* Response length is correct */
298 uint8_t byte_index = 0;
299
300 /* Copy the recevied buffer */
301 (void)memcpy ((void *)a_write_buf, (void *)p_recv_buf,
302 recv_length);
303
304 byte_index = ISO15693_GET_LEN_FIELD_BYTE_NO(
305 ps_iso_15693_con->ndef_tlv_type_blk,
306 ps_iso_15693_con->ndef_tlv_type_byte,
307 psNdefMap->ApduBufferSize);
308
309 /* Writing length field to 0, Update length field to 0 */
310 *(a_write_buf + byte_index) = 0x00;
311
312 if ((ISO15693_BYTES_PER_BLOCK - 1) != byte_index)
313 {
314 /* User data is updated in the buffer */
315 byte_index = (uint8_t)(byte_index + 1);
316 /* Block number shall be udate */
317 remaining_size = (ISO15693_BYTES_PER_BLOCK - byte_index);
318
319 if ((psNdefMap->ApduBufferSize - psNdefMap->ApduBuffIndex)
320 < remaining_size)
321 {
322 remaining_size = (uint8_t)(psNdefMap->ApduBufferSize -
323 psNdefMap->ApduBuffIndex);
324 }
325
326 /* Go to next byte to fill the write buffer */
327 (void)memcpy ((void *)(a_write_buf + byte_index),
328 (void *)(psNdefMap->ApduBuffer +
329 psNdefMap->ApduBuffIndex), remaining_size);
330
331 /* Write index updated */
332 psNdefMap->ApduBuffIndex = (uint8_t)(psNdefMap->ApduBuffIndex +
333 remaining_size);
334 }
335
336 /* After this write, user data can be written.
337 Update the sequence accordingly */
338 e_wr_ndef_seq = ISO15693_WRITE_DATA;
339 write_flag = TRUE;
340 } /* if (ISO15693_SINGLE_BLK_RD_RESP_LEN == recv_length) */
341 else
342 {
343 result = PHNFCSTVAL(CID_FRI_NFC_NDEF_MAP,
344 NFCSTATUS_INVALID_RECEIVE_LENGTH);
345 }
346 break;
347 } /* case ISO15693_RD_BEFORE_WR_NDEF_L_0: */
348
349 case ISO15693_RD_BEFORE_WR_NDEF_L:
350 {
351 p_recv_buf = (psNdefMap->SendRecvBuf + ISO15693_EXTRA_RESP_BYTE);
352 recv_length = (uint8_t)(*psNdefMap->SendRecvLength -
353 ISO15693_EXTRA_RESP_BYTE);
354
355 if (ISO15693_SINGLE_BLK_RD_RESP_LEN == recv_length)
356 {
357 uint8_t byte_index = 0;
358
359 (void)memcpy ((void *)a_write_buf, (void *)p_recv_buf,
360 recv_length);
361
362 byte_index = ISO15693_GET_LEN_FIELD_BYTE_NO(
363 ps_iso_15693_con->ndef_tlv_type_blk,
364 ps_iso_15693_con->ndef_tlv_type_byte,
365 psNdefMap->ApduBuffIndex);
366
367 *(a_write_buf + byte_index) = (uint8_t)psNdefMap->ApduBuffIndex;
368 e_wr_ndef_seq = ISO15693_WRITE_NDEF_TLV_L;
369 write_flag = TRUE;
370 }
371 else
372 {
373 result = PHNFCSTVAL(CID_FRI_NFC_NDEF_MAP,
374 NFCSTATUS_INVALID_RECEIVE_LENGTH);
375 }
376 break;
377 }
378
379 case ISO15693_WRITE_DATA:
380 {
381 if ((psNdefMap->ApduBufferSize == psNdefMap->ApduBuffIndex)
382 || (ps_iso_15693_con->current_block ==
383 (ps_iso_15693_con->max_data_size / ISO15693_BYTES_PER_BLOCK)))
384 {
385 ps_iso_15693_con->current_block =
386 ISO15693_GET_LEN_FIELD_BLOCK_NO(
387 ps_iso_15693_con->ndef_tlv_type_blk,
388 ps_iso_15693_con->ndef_tlv_type_byte,
389 psNdefMap->ApduBuffIndex);
390 e_wr_ndef_seq = ISO15693_RD_BEFORE_WR_NDEF_L;
391 }
392 else
393 {
394 remaining_size = ISO15693_BYTES_PER_BLOCK;
395
396 ps_iso_15693_con->current_block = (uint16_t)
397 (ps_iso_15693_con->current_block + 1);
398
399 if ((psNdefMap->ApduBufferSize - psNdefMap->ApduBuffIndex)
400 < remaining_size)
401 {
402 remaining_size = (uint8_t)(psNdefMap->ApduBufferSize -
403 psNdefMap->ApduBuffIndex);
404 }
405
406 (void)memcpy ((void *)a_write_buf, (void *)
407 (psNdefMap->ApduBuffer +
408 psNdefMap->ApduBuffIndex), remaining_size);
409
410 psNdefMap->ApduBuffIndex = (uint8_t)(psNdefMap->ApduBuffIndex +
411 remaining_size);
412 write_flag = TRUE;
413 }
414 break;
415 } /* case ISO15693_WRITE_DATA: */
416
417 case ISO15693_WRITE_NDEF_TLV_L:
418 {
419 *psNdefMap->WrNdefPacketLength = psNdefMap->ApduBuffIndex;
420 ps_iso_15693_con->actual_ndef_size = psNdefMap->ApduBuffIndex;
421 break;
422 }
423
424 default:
425 {
426 break;
427 }
428 } /* switch (e_wr_ndef_seq) */
429
430 if (((0 == psNdefMap->ApduBuffIndex)
431 || (*psNdefMap->WrNdefPacketLength != psNdefMap->ApduBuffIndex))
432 && (!result))
433 {
434 if (FALSE == write_flag)
435 {
436 result = phFriNfc_ISO15693_H_ReadWrite (psNdefMap,
437 ISO15693_READ_COMMAND, NULL, 0);
438 }
439 else
440 {
441 result = phFriNfc_ISO15693_H_ReadWrite (psNdefMap,
442 ISO15693_WRITE_COMMAND,
443 a_write_buf, sizeof (a_write_buf));
444 }
445 }
446
447 psNdefMap->ISO15693Container.ndef_seq = (uint8_t)e_wr_ndef_seq;
448 return result;
449 }
450
451 static
452 NFCSTATUS
phFriNfc_ISO15693_H_ReadWrite(phFriNfc_NdefMap_t * psNdefMap,uint8_t command,uint8_t * p_data,uint8_t data_length)453 phFriNfc_ISO15693_H_ReadWrite (
454 phFriNfc_NdefMap_t *psNdefMap,
455 uint8_t command,
456 uint8_t *p_data,
457 uint8_t data_length)
458 {
459 NFCSTATUS result = NFCSTATUS_SUCCESS;
460 uint8_t send_index = 0;
461
462 /* set the data for additional data exchange*/
463 psNdefMap->psDepAdditionalInfo.DepFlags.MetaChaining = 0;
464 psNdefMap->psDepAdditionalInfo.DepFlags.NADPresent = 0;
465 psNdefMap->psDepAdditionalInfo.NAD = 0;
466
467 psNdefMap->MapCompletionInfo.CompletionRoutine = phFriNfc_ISO15693_Process;
468 psNdefMap->MapCompletionInfo.Context = psNdefMap;
469
470 *psNdefMap->SendRecvLength = psNdefMap->TempReceiveLength;
471
472 psNdefMap->Cmd.Iso15693Cmd = phHal_eIso15693_Cmd;
473
474 *(psNdefMap->SendRecvBuf + send_index) = (uint8_t)ISO15693_FLAGS;
475 send_index = (uint8_t)(send_index + 1);
476
477 *(psNdefMap->SendRecvBuf + send_index) = (uint8_t)command;
478 send_index = (uint8_t)(send_index + 1);
479
480 (void)memcpy ((void *)(psNdefMap->SendRecvBuf + send_index),
481 (void *)psNdefMap->psRemoteDevInfo->RemoteDevInfo.Iso15693_Info.Uid,
482 psNdefMap->psRemoteDevInfo->RemoteDevInfo.Iso15693_Info.UidLength);
483 send_index = (uint8_t)(send_index +
484 psNdefMap->psRemoteDevInfo->RemoteDevInfo.Iso15693_Info.UidLength);
485
486 *(psNdefMap->SendRecvBuf + send_index) = (uint8_t)
487 psNdefMap->ISO15693Container.current_block;
488 send_index = (uint8_t)(send_index + 1);
489
490 if ((ISO15693_WRITE_COMMAND == command) ||
491 (ISO15693_READ_MULTIPLE_COMMAND == command))
492 {
493 (void)memcpy ((void *)(psNdefMap->SendRecvBuf + send_index),
494 (void *)p_data, data_length);
495 send_index = (uint8_t)(send_index + data_length);
496 }
497
498 psNdefMap->SendLength = send_index;
499 result = phFriNfc_OvrHal_Transceive(psNdefMap->LowerDevice,
500 &psNdefMap->MapCompletionInfo,
501 psNdefMap->psRemoteDevInfo,
502 psNdefMap->Cmd,
503 &psNdefMap->psDepAdditionalInfo,
504 psNdefMap->SendRecvBuf,
505 psNdefMap->SendLength,
506 psNdefMap->SendRecvBuf,
507 psNdefMap->SendRecvLength);
508
509 return result;
510 }
511
512 static
513 NFCSTATUS
phFriNfc_ISO15693_H_Inventory_Page_Read(phFriNfc_NdefMap_t * psNdefMap,uint8_t command,uint8_t page,uint8_t numPages)514 phFriNfc_ISO15693_H_Inventory_Page_Read (
515 phFriNfc_NdefMap_t *psNdefMap,
516 uint8_t command,
517 uint8_t page,
518 uint8_t numPages)
519 {
520 NFCSTATUS result = NFCSTATUS_SUCCESS;
521 uint8_t send_index = 0;
522
523 /* set the data for additional data exchange*/
524 psNdefMap->psDepAdditionalInfo.DepFlags.MetaChaining = 0;
525 psNdefMap->psDepAdditionalInfo.DepFlags.NADPresent = 0;
526 psNdefMap->psDepAdditionalInfo.NAD = 0;
527
528 psNdefMap->MapCompletionInfo.CompletionRoutine = phFriNfc_ISO15693_Process;
529 psNdefMap->MapCompletionInfo.Context = psNdefMap;
530
531 *psNdefMap->SendRecvLength = psNdefMap->TempReceiveLength;
532
533 psNdefMap->Cmd.Iso15693Cmd = phHal_eIso15693_Cmd;
534
535 *(psNdefMap->SendRecvBuf + send_index) = INVENTORY_PAGEREAD_FLAGS;
536 send_index = (uint8_t)(send_index + 1);
537
538 *(psNdefMap->SendRecvBuf + send_index) = (uint8_t)command;
539 send_index = (uint8_t)(send_index + 1);
540
541 *(psNdefMap->SendRecvBuf + send_index) = NXP_MANUFACTURING_CODE;
542 send_index = (uint8_t)(send_index + 1);
543
544 *(psNdefMap->SendRecvBuf + send_index) = 0x40;
545 send_index = (uint8_t)(send_index + 1);
546
547 (void)memcpy ((void *)(psNdefMap->SendRecvBuf + send_index),
548 (void *)psNdefMap->psRemoteDevInfo->RemoteDevInfo.Iso15693_Info.Uid,
549 psNdefMap->psRemoteDevInfo->RemoteDevInfo.Iso15693_Info.UidLength);
550 send_index = (uint8_t)(send_index +
551 psNdefMap->psRemoteDevInfo->RemoteDevInfo.Iso15693_Info.UidLength);
552
553 *(psNdefMap->SendRecvBuf + send_index) = (uint8_t)
554 page;
555 send_index = (uint8_t)(send_index + 1);
556
557 *(psNdefMap->SendRecvBuf + send_index) = (uint8_t)
558 numPages;
559 send_index = (uint8_t)(send_index + 1);
560
561 psNdefMap->SendLength = send_index;
562
563 result = phFriNfc_OvrHal_Transceive(psNdefMap->LowerDevice,
564 &psNdefMap->MapCompletionInfo,
565 psNdefMap->psRemoteDevInfo,
566 psNdefMap->Cmd,
567 &psNdefMap->psDepAdditionalInfo,
568 psNdefMap->SendRecvBuf,
569 psNdefMap->SendLength,
570 psNdefMap->SendRecvBuf,
571 psNdefMap->SendRecvLength);
572
573 return result;
574 }
575
576 static
577 NFCSTATUS
phFriNfc_ISO15693_Reformat_Pageread_Buffer(uint8_t * p_recv_buf,uint8_t recv_length,uint8_t * p_dst_buf,uint8_t dst_length)578 phFriNfc_ISO15693_Reformat_Pageread_Buffer (
579 uint8_t *p_recv_buf,
580 uint8_t recv_length,
581 uint8_t *p_dst_buf,
582 uint8_t dst_length)
583 {
584 // Inventory page reads return an extra security byte per page
585 // So we need to reformat the returned buffer in memory
586 uint32_t i = 0;
587 uint32_t reformatted_index = 0;
588 while (i < recv_length) {
589 // Going for another page of 16 bytes, check for space in dst buffer
590 if (reformatted_index + 16 > dst_length) {
591 break;
592 }
593 if (p_recv_buf[i] == 0x0F) {
594 // Security, insert 16 0 bytes
595 memset(&(p_dst_buf[reformatted_index]), 0, 16);
596 reformatted_index += 16;
597 i++;
598 } else {
599 // Skip security byte
600 i++;
601 if (i + 16 <= recv_length) {
602 memcpy(&(p_dst_buf[reformatted_index]), &(p_recv_buf[i]), 16);
603 reformatted_index += 16;
604 } else {
605 break;
606 }
607 i+=16;
608 }
609 }
610 return reformatted_index;
611 }
612
613 static
614 NFCSTATUS
phFriNfc_ISO15693_H_ProcessReadNdef(phFriNfc_NdefMap_t * psNdefMap)615 phFriNfc_ISO15693_H_ProcessReadNdef (
616 phFriNfc_NdefMap_t *psNdefMap)
617 {
618 NFCSTATUS result = NFCSTATUS_SUCCESS;
619 phFriNfc_ISO15693Cont_t *ps_iso_15693_con =
620 &(psNdefMap->ISO15693Container);
621 uint16_t remaining_data_size = 0;
622 uint8_t *p_recv_buf =
623 (psNdefMap->SendRecvBuf + ISO15693_EXTRA_RESP_BYTE);
624 uint8_t recv_length = (uint8_t)
625 (*psNdefMap->SendRecvLength - ISO15693_EXTRA_RESP_BYTE);
626
627 uint8_t *reformatted_buf = (uint8_t*) phOsalNfc_GetMemory(ps_iso_15693_con->max_data_size);
628
629 if (ps_iso_15693_con->read_capabilities & ISO15693_CC_USE_IPR)
630 {
631 uint8_t reformatted_size = phFriNfc_ISO15693_Reformat_Pageread_Buffer(p_recv_buf, recv_length,
632 reformatted_buf, ps_iso_15693_con->max_data_size);
633 p_recv_buf = reformatted_buf + (ps_iso_15693_con->current_block * ISO15693_BYTES_PER_BLOCK);
634 recv_length = reformatted_size - (ps_iso_15693_con->current_block * ISO15693_BYTES_PER_BLOCK);
635 }
636 if (ps_iso_15693_con->store_length)
637 {
638 /* Continue Offset option selected
639 So stored data already existing,
640 copy the information to the user buffer
641 */
642 if (ps_iso_15693_con->store_length
643 <= (psNdefMap->ApduBufferSize - psNdefMap->ApduBuffIndex))
644 {
645 /* Stored data length is less than or equal
646 to the user expected size */
647 (void)memcpy ((void *)(psNdefMap->ApduBuffer +
648 psNdefMap->ApduBuffIndex),
649 (void *)ps_iso_15693_con->store_read_data,
650 ps_iso_15693_con->store_length);
651
652 psNdefMap->ApduBuffIndex = (uint16_t)(psNdefMap->ApduBuffIndex +
653 ps_iso_15693_con->store_length);
654
655 remaining_data_size = ps_iso_15693_con->store_length;
656
657 ps_iso_15693_con->store_length = 0;
658 }
659 else
660 {
661 /* stored length is more than the user expected size */
662 remaining_data_size = (uint16_t)(ps_iso_15693_con->store_length -
663 (psNdefMap->ApduBufferSize - psNdefMap->ApduBuffIndex));
664
665 (void)memcpy ((void *)(psNdefMap->ApduBuffer +
666 psNdefMap->ApduBuffIndex),
667 (void *)ps_iso_15693_con->store_read_data,
668 remaining_data_size);
669
670 /* As stored data is more than the user expected data. So store
671 the remaining bytes again into the data structure */
672 (void)memcpy ((void *)ps_iso_15693_con->store_read_data,
673 (void *)(ps_iso_15693_con->store_read_data +
674 remaining_data_size),
675 (ps_iso_15693_con->store_length - remaining_data_size));
676
677 psNdefMap->ApduBuffIndex = (uint16_t)(psNdefMap->ApduBuffIndex +
678 remaining_data_size);
679
680 ps_iso_15693_con->store_length = (uint8_t)
681 (ps_iso_15693_con->store_length - remaining_data_size);
682 }
683 } /* if (ps_iso_15693_con->store_length) */
684 else
685 {
686 /* Data is read from the card. */
687 uint8_t byte_index = 0;
688
689 remaining_data_size = ps_iso_15693_con->remaining_size_to_read;
690
691 /* Check if the block number is to read the first VALUE field */
692 if (ISO15693_GET_VALUE_FIELD_BLOCK_NO(ps_iso_15693_con->ndef_tlv_type_blk,
693 ps_iso_15693_con->ndef_tlv_type_byte,
694 ps_iso_15693_con->actual_ndef_size)
695 == ps_iso_15693_con->current_block)
696 {
697 /* Read from the beginning option selected,
698 BYTE number may start from the middle */
699 byte_index = (uint8_t)ISO15693_GET_VALUE_FIELD_BYTE_NO(
700 ps_iso_15693_con->ndef_tlv_type_blk,
701 ps_iso_15693_con->ndef_tlv_type_byte,
702 ps_iso_15693_con->actual_ndef_size);
703 }
704
705 if ((psNdefMap->ApduBufferSize - psNdefMap->ApduBuffIndex)
706 < remaining_data_size)
707 {
708 remaining_data_size = (uint8_t)
709 (recv_length - byte_index);
710 /* user input is less than the remaining card size */
711 if ((psNdefMap->ApduBufferSize - psNdefMap->ApduBuffIndex)
712 < (uint16_t)remaining_data_size)
713 {
714 /* user data required is less than the data read */
715 remaining_data_size = (uint8_t)(psNdefMap->ApduBufferSize -
716 psNdefMap->ApduBuffIndex);
717
718 if (0 != (recv_length - (byte_index +
719 remaining_data_size)))
720 {
721 /* Store the data for the continue read option */
722 (void)memcpy ((void *)ps_iso_15693_con->store_read_data,
723 (void *)(p_recv_buf + (byte_index +
724 remaining_data_size)),
725 (recv_length - (byte_index +
726 remaining_data_size)));
727
728 ps_iso_15693_con->store_length = (uint8_t)
729 (recv_length - (byte_index +
730 remaining_data_size));
731 }
732 }
733 }
734 else
735 {
736 /* user data required is equal or greater than the data read */
737 if (remaining_data_size > (recv_length - byte_index))
738 {
739 remaining_data_size = (uint8_t)
740 (recv_length - byte_index);
741 }
742 }
743
744 /* Copy data in the user buffer */
745 (void)memcpy ((void *)(psNdefMap->ApduBuffer +
746 psNdefMap->ApduBuffIndex),
747 (void *)(p_recv_buf + byte_index),
748 remaining_data_size);
749
750 /* Update the read index */
751 psNdefMap->ApduBuffIndex = (uint16_t)(psNdefMap->ApduBuffIndex +
752 remaining_data_size);
753
754 } /* else part of if (ps_iso_15693_con->store_length) */
755
756 /* Remaining size is decremented */
757 ps_iso_15693_con->remaining_size_to_read = (uint8_t)
758 (ps_iso_15693_con->remaining_size_to_read -
759 remaining_data_size);
760
761 if ((psNdefMap->ApduBuffIndex != psNdefMap->ApduBufferSize)
762 && (0 != ps_iso_15693_con->remaining_size_to_read))
763 {
764 ps_iso_15693_con->current_block = (uint16_t)
765 (ps_iso_15693_con->current_block + 1);
766 /* READ again */
767 if ((ps_iso_15693_con->read_capabilities & ISO15693_CC_USE_MBR) ||
768 (ps_iso_15693_con->read_capabilities & ISO15693_CC_USE_IPR)) {
769 result = phFriNfc_ReadRemainingInMultiple(psNdefMap, ps_iso_15693_con->current_block);
770 }
771 else {
772 result = phFriNfc_ISO15693_H_ReadWrite (psNdefMap, ISO15693_READ_COMMAND,
773 NULL, 0);
774 }
775 }
776 else
777 {
778 /* Read completed, EITHER index has reached to the user size
779 OR end of the card is reached
780 update the user data structure with read data size */
781 *psNdefMap->NumOfBytesRead = psNdefMap->ApduBuffIndex;
782 }
783 if (reformatted_buf != NULL) {
784 phOsalNfc_FreeMemory(reformatted_buf);
785 }
786 return result;
787 }
788
789 static
790 NFCSTATUS
phFriNfc_ISO15693_H_CheckCCBytes(phFriNfc_NdefMap_t * psNdefMap)791 phFriNfc_ISO15693_H_CheckCCBytes (
792 phFriNfc_NdefMap_t *psNdefMap)
793 {
794 NFCSTATUS result = NFCSTATUS_SUCCESS;
795 phFriNfc_ISO15693Cont_t *ps_iso_15693_con =
796 &(psNdefMap->ISO15693Container);
797 uint8_t recv_index = 0;
798 uint8_t *p_recv_buf = (psNdefMap->SendRecvBuf + 1);
799
800 /* expected CC byte : E1 40 "MAX SIZE depends on tag" */
801 if (ISO15693_CC_MAGIC_BYTE == *p_recv_buf)
802 {
803 /* 0xE1 magic byte found*/
804 recv_index = (uint8_t)(recv_index + 1);
805 uint8_t tag_major_version = (*(p_recv_buf + recv_index) & ISO15693_MAJOR_VERSION_MASK) >> 6;
806 if (ISO15693_MAPPING_VERSION >= tag_major_version)
807 {
808 /* Correct mapping version found */
809 switch (*(p_recv_buf + recv_index) & ISO15693_LSB_NIBBLE_MASK)
810 {
811 case ISO15693_RD_WR_PERMISSION:
812 {
813 /* READ/WRITE possible */
814 psNdefMap->CardState = PH_NDEFMAP_CARD_STATE_READ_WRITE;
815 break;
816 }
817
818 case ISO15693_RD_ONLY_PERMISSION:
819 {
820 /* ONLY READ possible, WRITE NOT possible */
821 psNdefMap->CardState = PH_NDEFMAP_CARD_STATE_READ_ONLY;
822 break;
823 }
824
825 default:
826 {
827 result = PHNFCSTVAL(CID_FRI_NFC_NDEF_MAP,
828 NFCSTATUS_NO_NDEF_SUPPORT);
829 break;
830 }
831 }
832 recv_index = (uint8_t)(recv_index + 1);
833
834 if (!result)
835 {
836 /* Update MAX SIZE */
837 ps_iso_15693_con->max_data_size = (uint16_t)
838 (*(p_recv_buf + recv_index) *
839 ISO15693_MULT_FACTOR);
840 recv_index = (uint8_t)(recv_index + 1);
841 ps_iso_15693_con->read_capabilities = (*(p_recv_buf + recv_index));
842
843
844 }
845 }
846 else
847 {
848 result = PHNFCSTVAL(CID_FRI_NFC_NDEF_MAP,
849 NFCSTATUS_NO_NDEF_SUPPORT);
850 }
851 }
852 else
853 {
854 result = PHNFCSTVAL(CID_FRI_NFC_NDEF_MAP,
855 NFCSTATUS_NO_NDEF_SUPPORT);
856 }
857 return result;
858 }
859
860 static
861 NFCSTATUS
phFriNfc_ISO15693_H_ProcessCheckNdef(phFriNfc_NdefMap_t * psNdefMap)862 phFriNfc_ISO15693_H_ProcessCheckNdef (
863 phFriNfc_NdefMap_t *psNdefMap)
864 {
865 NFCSTATUS result = NFCSTATUS_SUCCESS;
866 phFriNfc_ISO15693Cont_t *ps_iso_15693_con =
867 &(psNdefMap->ISO15693Container);
868 phFriNfc_eChkNdefSeq_t e_chk_ndef_seq = (phFriNfc_eChkNdefSeq_t)
869 psNdefMap->ISO15693Container.ndef_seq;
870
871 uint8_t *p_recv_buf =
872 (psNdefMap->SendRecvBuf + ISO15693_EXTRA_RESP_BYTE);
873 uint8_t recv_length = (uint8_t)
874 (*psNdefMap->SendRecvLength - ISO15693_EXTRA_RESP_BYTE);
875 uint8_t parse_index = 0;
876 static uint16_t prop_ndef_index = 0;
877 uint8_t *reformatted_buf = (uint8_t*) phOsalNfc_GetMemory(ps_iso_15693_con->max_data_size);
878
879 if (0 == ps_iso_15693_con->current_block)
880 {
881 /* Check CC byte */
882 result = phFriNfc_ISO15693_H_CheckCCBytes (psNdefMap);
883 parse_index = (uint8_t)(parse_index + recv_length);
884 }
885 else if (1 == ps_iso_15693_con->current_block &&
886 (ps_iso_15693_con->read_capabilities & ISO15693_CC_USE_IPR))
887 {
888
889 uint8_t reformatted_size = phFriNfc_ISO15693_Reformat_Pageread_Buffer(p_recv_buf, recv_length,
890 reformatted_buf, ps_iso_15693_con->max_data_size);
891 // Skip initial CC bytes
892 p_recv_buf = reformatted_buf + (ps_iso_15693_con->current_block * ISO15693_BYTES_PER_BLOCK);
893 recv_length = reformatted_size - (ps_iso_15693_con->current_block * ISO15693_BYTES_PER_BLOCK);
894 }
895 else
896 {
897 /* Propreitary TLVs VALUE can end in between a block,
898 so when that block is read, update the parse_index
899 with byte address value */
900 if (ISO15693_PROP_TLV_V == e_chk_ndef_seq)
901 {
902 parse_index = ps_iso_15693_con->ndef_tlv_type_byte;
903 e_chk_ndef_seq = ISO15693_NDEF_TLV_T;
904 }
905 }
906
907 while ((parse_index < recv_length)
908 && (NFCSTATUS_SUCCESS == result)
909 && (ISO15693_NDEF_TLV_V != e_chk_ndef_seq))
910 {
911 /* Parse
912 1. till the received length of the block
913 2. till there is no error during parse
914 3. till LENGTH field of NDEF TLV is found
915 */
916 switch (e_chk_ndef_seq)
917 {
918 case ISO15693_NDEF_TLV_T:
919 {
920 /* Expected value is 0x03 TYPE identifier
921 of the NDEF TLV */
922 prop_ndef_index = 0;
923 switch (*(p_recv_buf + parse_index))
924 {
925 case ISO15693_NDEF_TLV_TYPE_ID:
926 {
927 /* Update the data structure with the byte address and
928 the block number */
929 ps_iso_15693_con->ndef_tlv_type_byte = parse_index;
930 ps_iso_15693_con->ndef_tlv_type_blk =
931 ps_iso_15693_con->current_block;
932 e_chk_ndef_seq = ISO15693_NDEF_TLV_L;
933
934 break;
935 }
936
937 case ISO15693_NULL_TLV_ID:
938 {
939 /* Dont do any thing, go to next byte */
940 break;
941 }
942
943 case ISO15693_PROP_TLV_ID:
944 {
945 /* Move the sequence to find the length
946 of the proprietary TLV */
947 e_chk_ndef_seq = ISO15693_PROP_TLV_L;
948 break;
949 }
950
951 default:
952 {
953 result = PHNFCSTVAL(CID_FRI_NFC_NDEF_MAP,
954 NFCSTATUS_NO_NDEF_SUPPORT);
955 break;
956 }
957 } /* switch (*(p_recv_buf + parse_index)) */
958 break;
959 }
960
961 case ISO15693_PROP_TLV_L:
962 {
963 /* Length field of the proprietary TLV */
964 switch (prop_ndef_index)
965 {
966 /* Length field can have 1 or 3 bytes depending
967 on the data size, so check for each index byte */
968 case 0:
969 {
970 /* 1st index of the length field of the TLV */
971 if (0 == *(p_recv_buf + parse_index))
972 {
973 /* LENGTH is 0, not possible, so error */
974 result = PHNFCSTVAL(CID_FRI_NFC_NDEF_MAP,
975 NFCSTATUS_NO_NDEF_SUPPORT);
976 e_chk_ndef_seq = ISO15693_NDEF_TLV_T;
977 }
978 else
979 {
980 if (ISO15693_THREE_BYTE_LENGTH_ID ==
981 *(p_recv_buf + parse_index))
982 {
983 /* 3 byte LENGTH field identified, so increment the
984 index, so next time 2nd byte is parsed */
985 prop_ndef_index = (uint8_t)(prop_ndef_index + 1);
986 }
987 else
988 {
989 /* 1 byte LENGTH field identified, so "static"
990 index is set to 0 and actual ndef size is
991 copied to the data structure
992 */
993 ps_iso_15693_con->actual_ndef_size =
994 *(p_recv_buf + parse_index);
995 e_chk_ndef_seq = ISO15693_PROP_TLV_V;
996 prop_ndef_index = 0;
997 }
998 }
999 break;
1000 }
1001
1002 case 1:
1003 {
1004 /* 2nd index of the LENGTH field that is MSB of the length,
1005 so the length is left shifted by 8 */
1006 ps_iso_15693_con->actual_ndef_size = (uint16_t)
1007 (*(p_recv_buf + parse_index) <<
1008 ISO15693_BTYE_SHIFT);
1009 prop_ndef_index = (uint8_t)(prop_ndef_index + 1);
1010 break;
1011 }
1012
1013 case 2:
1014 {
1015 /* 3rd index of the LENGTH field that is LSB of the length,
1016 so the length ORed with the previously stored size */
1017 ps_iso_15693_con->actual_ndef_size = (uint16_t)
1018 (ps_iso_15693_con->actual_ndef_size |
1019 *(p_recv_buf + parse_index));
1020
1021 e_chk_ndef_seq = ISO15693_PROP_TLV_V;
1022 prop_ndef_index = 0;
1023 break;
1024 }
1025
1026 default:
1027 {
1028 result = PHNFCSTVAL(CID_FRI_NFC_NDEF_MAP,
1029 NFCSTATUS_INVALID_DEVICE_REQUEST);
1030 break;
1031 }
1032 } /* switch (prop_ndef_index) */
1033
1034 if ((ISO15693_PROP_TLV_V == e_chk_ndef_seq)
1035 && (ISO15693_GET_REMAINING_SIZE(ps_iso_15693_con->max_data_size,
1036 ps_iso_15693_con->current_block, parse_index)
1037 <= ps_iso_15693_con->actual_ndef_size))
1038 {
1039 /* Check for the length field value has not exceeded the card size,
1040 if size is exceeded or then return error */
1041 e_chk_ndef_seq = ISO15693_NDEF_TLV_T;
1042 result = PHNFCSTVAL(CID_FRI_NFC_NDEF_MAP,
1043 NFCSTATUS_NO_NDEF_SUPPORT);
1044 }
1045 else
1046 {
1047 uint16_t prop_byte_addr = 0;
1048
1049 /* skip the proprietary TLVs value field */
1050 prop_byte_addr = (uint16_t)
1051 ((ps_iso_15693_con->current_block * ISO15693_BYTES_PER_BLOCK) +
1052 parse_index + ps_iso_15693_con->actual_ndef_size);
1053
1054 ps_iso_15693_con->ndef_tlv_type_byte = (uint8_t)(prop_byte_addr %
1055 ISO15693_BYTES_PER_BLOCK);
1056 ps_iso_15693_con->ndef_tlv_type_blk = (uint16_t)(prop_byte_addr /
1057 ISO15693_BYTES_PER_BLOCK);
1058 if (parse_index + ps_iso_15693_con->actual_ndef_size >=
1059 recv_length)
1060 {
1061 parse_index = (uint8_t)recv_length;
1062 }
1063 else
1064 {
1065 parse_index = (uint8_t)(parse_index +
1066 ps_iso_15693_con->actual_ndef_size);
1067 }
1068
1069 }
1070 break;
1071 } /* case ISO15693_PROP_TLV_L: */
1072
1073 case ISO15693_PROP_TLV_V:
1074 {
1075 uint8_t remaining_length = (uint8_t)(recv_length -
1076 parse_index);
1077
1078 if ((ps_iso_15693_con->actual_ndef_size - prop_ndef_index)
1079 > remaining_length)
1080 {
1081 parse_index = (uint8_t)(parse_index + remaining_length);
1082 prop_ndef_index = (uint8_t)(prop_ndef_index + remaining_length);
1083 }
1084 else if ((ps_iso_15693_con->actual_ndef_size - prop_ndef_index)
1085 == remaining_length)
1086 {
1087 parse_index = (uint8_t)(parse_index + remaining_length);
1088 e_chk_ndef_seq = ISO15693_NDEF_TLV_T;
1089 prop_ndef_index = 0;
1090 }
1091 else
1092 {
1093 parse_index = (uint8_t)(parse_index +
1094 (ps_iso_15693_con->actual_ndef_size -
1095 prop_ndef_index));
1096 e_chk_ndef_seq = ISO15693_NDEF_TLV_T;
1097 prop_ndef_index = 0;
1098 }
1099 break;
1100 } /* case ISO15693_PROP_TLV_V: */
1101
1102 case ISO15693_NDEF_TLV_L:
1103 {
1104 /* Length field of the NDEF TLV */
1105 switch (prop_ndef_index)
1106 {
1107 /* Length field can have 1 or 3 bytes depending
1108 on the data size, so check for each index byte */
1109 case 0:
1110 {
1111 /* 1st index of the length field of the TLV */
1112 if (0 == *(p_recv_buf + parse_index))
1113 {
1114 /* LENGTH is 0, card is in INITILIASED STATE */
1115 e_chk_ndef_seq = ISO15693_NDEF_TLV_V;
1116 ps_iso_15693_con->actual_ndef_size = 0;
1117 }
1118 else
1119 {
1120 prop_ndef_index = (uint8_t)(prop_ndef_index + 1);
1121
1122 if (ISO15693_THREE_BYTE_LENGTH_ID ==
1123 *(p_recv_buf + parse_index))
1124 {
1125 /* At present no CARD supports more than 255 bytes,
1126 so error is returned */
1127 prop_ndef_index = (uint8_t)(prop_ndef_index + 1);
1128 result = PHNFCSTVAL(CID_FRI_NFC_NDEF_MAP,
1129 NFCSTATUS_NO_NDEF_SUPPORT);
1130 prop_ndef_index = 0;
1131 }
1132 else
1133 {
1134 /* 1 byte LENGTH field identified, so "static"
1135 index is set to 0 and actual ndef size is
1136 copied to the data structure
1137 */
1138 ps_iso_15693_con->actual_ndef_size =
1139 *(p_recv_buf + parse_index);
1140 /* next values are the DATA field of the NDEF TLV */
1141 e_chk_ndef_seq = ISO15693_NDEF_TLV_V;
1142 prop_ndef_index = 0;
1143 }
1144 }
1145 break;
1146 }
1147
1148 case 1:
1149 {
1150 /* 2nd index of the LENGTH field that is MSB of the length,
1151 so the length is left shifted by 8 */
1152 ps_iso_15693_con->actual_ndef_size = (uint16_t)
1153 (*(p_recv_buf + parse_index) <<
1154 ISO15693_BTYE_SHIFT);
1155 prop_ndef_index = (uint8_t)(prop_ndef_index + 1);
1156 break;
1157 }
1158
1159 case 2:
1160 {
1161 /* 3rd index of the LENGTH field that is LSB of the length,
1162 so the length ORed with the previously stored size */
1163 ps_iso_15693_con->actual_ndef_size = (uint16_t)
1164 (ps_iso_15693_con->actual_ndef_size |
1165 *(p_recv_buf + parse_index));
1166
1167 e_chk_ndef_seq = ISO15693_NDEF_TLV_V;
1168 prop_ndef_index = 0;
1169 break;
1170 }
1171
1172 default:
1173 {
1174 result = PHNFCSTVAL(CID_FRI_NFC_NDEF_MAP,
1175 NFCSTATUS_INVALID_DEVICE_REQUEST);
1176 break;
1177 }
1178 } /* switch (prop_ndef_index) */
1179
1180 if ((ISO15693_NDEF_TLV_V == e_chk_ndef_seq)
1181 && (ISO15693_GET_REMAINING_SIZE(ps_iso_15693_con->max_data_size,
1182 /* parse_index + 1 is done because the data starts from the next index.
1183 "MOD" operation is used to know that parse_index >
1184 ISO15693_BYTES_PER_BLOCK, then block shall be incremented
1185 */
1186 (((parse_index + 1) % ISO15693_BYTES_PER_BLOCK) ?
1187 ps_iso_15693_con->current_block :
1188 ps_iso_15693_con->current_block + 1), ((parse_index + 1) %
1189 ISO15693_BYTES_PER_BLOCK))
1190 < ps_iso_15693_con->actual_ndef_size))
1191 {
1192 /* Check for the length field value has not exceeded the card size */
1193 e_chk_ndef_seq = ISO15693_NDEF_TLV_T;
1194 result = PHNFCSTVAL(CID_FRI_NFC_NDEF_MAP,
1195 NFCSTATUS_NO_NDEF_SUPPORT);
1196 }
1197 else
1198 {
1199 psNdefMap->CardState = (uint8_t)
1200 ((PH_NDEFMAP_CARD_STATE_READ_ONLY
1201 == psNdefMap->CardState) ?
1202 PH_NDEFMAP_CARD_STATE_READ_ONLY :
1203 ((ps_iso_15693_con->actual_ndef_size) ?
1204 PH_NDEFMAP_CARD_STATE_READ_WRITE :
1205 PH_NDEFMAP_CARD_STATE_INITIALIZED));
1206 }
1207 break;
1208 } /* case ISO15693_NDEF_TLV_L: */
1209
1210 case ISO15693_NDEF_TLV_V:
1211 {
1212 break;
1213 }
1214
1215 default:
1216 {
1217 result = PHNFCSTVAL(CID_FRI_NFC_NDEF_MAP,
1218 NFCSTATUS_INVALID_DEVICE_REQUEST);
1219 break;
1220 }
1221 } /* switch (e_chk_ndef_seq) */
1222 parse_index = (uint8_t)(parse_index + 1);
1223 } /* while ((parse_index < recv_length)
1224 && (NFCSTATUS_SUCCESS == result)
1225 && (ISO15693_NDEF_TLV_V != e_chk_ndef_seq)) */
1226
1227 if (result)
1228 {
1229 /* Error returned while parsing, so STOP read */
1230 e_chk_ndef_seq = ISO15693_NDEF_TLV_T;
1231 prop_ndef_index = 0;
1232 }
1233 else if (ISO15693_NDEF_TLV_V != e_chk_ndef_seq)
1234 {
1235 /* READ again */
1236 if (ISO15693_PROP_TLV_V != e_chk_ndef_seq)
1237 {
1238 ps_iso_15693_con->current_block = (uint16_t)
1239 (ps_iso_15693_con->current_block + 1);
1240 }
1241 else
1242 {
1243 /* Proprietary TLV detected, so skip the proprietary blocks */
1244 ps_iso_15693_con->current_block = ps_iso_15693_con->ndef_tlv_type_blk;
1245 }
1246
1247 uint32_t remaining_size = ISO15693_GET_REMAINING_SIZE(ps_iso_15693_con->max_data_size,
1248 ps_iso_15693_con->current_block, 0);
1249 if (remaining_size > 0)
1250 {
1251 if ((ps_iso_15693_con->read_capabilities & ISO15693_CC_USE_MBR) ||
1252 (ps_iso_15693_con->read_capabilities & ISO15693_CC_USE_IPR)) {
1253 result = phFriNfc_ReadRemainingInMultiple(psNdefMap, ps_iso_15693_con->current_block);
1254 } else {
1255 result = phFriNfc_ISO15693_H_ReadWrite (psNdefMap, ISO15693_READ_COMMAND,
1256 NULL, 0);
1257 }
1258 }
1259 else
1260 {
1261 /* End of card reached, error no NDEF information found */
1262 e_chk_ndef_seq = ISO15693_NDEF_TLV_T;
1263 prop_ndef_index = 0;
1264 /* Error, no size to parse */
1265 result = PHNFCSTVAL(CID_FRI_NFC_NDEF_MAP,
1266 NFCSTATUS_NO_NDEF_SUPPORT);
1267 }
1268
1269 }
1270 else
1271 {
1272 /* Successful read with proper NDEF information updated */
1273 prop_ndef_index = 0;
1274 e_chk_ndef_seq = ISO15693_NDEF_TLV_T;
1275 psNdefMap->CardType = (uint8_t)PH_FRINFC_NDEFMAP_ISO15693_CARD;
1276 }
1277
1278 psNdefMap->ISO15693Container.ndef_seq = (uint8_t)e_chk_ndef_seq;
1279
1280 if (reformatted_buf != NULL) {
1281 phOsalNfc_FreeMemory(reformatted_buf);
1282 }
1283 return result;
1284 }
1285
1286 static
1287 void
phFriNfc_ISO15693_H_Complete(phFriNfc_NdefMap_t * psNdefMap,NFCSTATUS Status)1288 phFriNfc_ISO15693_H_Complete (
1289 phFriNfc_NdefMap_t *psNdefMap,
1290 NFCSTATUS Status)
1291 {
1292 /* set the state back to the RESET_INIT state*/
1293 psNdefMap->State = PH_FRINFC_NDEFMAP_STATE_RESET_INIT;
1294
1295 /* set the completion routine*/
1296 psNdefMap->CompletionRoutine[psNdefMap->ISO15693Container.cr_index].
1297 CompletionRoutine (psNdefMap->CompletionRoutine->Context, Status);
1298 }
1299
1300 #ifdef FRINFC_READONLY_NDEF
1301
1302 static
1303 NFCSTATUS
phFriNfc_ISO15693_H_ProcessReadOnly(phFriNfc_NdefMap_t * psNdefMap)1304 phFriNfc_ISO15693_H_ProcessReadOnly (
1305 phFriNfc_NdefMap_t *psNdefMap)
1306 {
1307 NFCSTATUS result = NFCSTATUS_SUCCESS;
1308 phFriNfc_ISO15693Cont_t *ps_iso_15693_con =
1309 &(psNdefMap->ISO15693Container);
1310 phFriNfc_eRONdefSeq_t e_ro_ndef_seq = (phFriNfc_eRONdefSeq_t)
1311 ps_iso_15693_con->ndef_seq;
1312 uint8_t *p_recv_buf = (psNdefMap->SendRecvBuf +
1313 ISO15693_EXTRA_RESP_BYTE);
1314 uint8_t recv_length = (uint8_t)(*psNdefMap->SendRecvLength -
1315 ISO15693_EXTRA_RESP_BYTE);
1316 uint8_t a_write_buf[ISO15693_BYTES_PER_BLOCK] = {0};
1317
1318 switch (e_ro_ndef_seq)
1319 {
1320 case ISO15693_RD_BEFORE_WR_CC:
1321 {
1322 if (ISO15693_SINGLE_BLK_RD_RESP_LEN == recv_length)
1323 {
1324 result = phFriNfc_ISO15693_H_CheckCCBytes (psNdefMap);
1325 /* Check CC bytes and also the card state for READ ONLY,
1326 if the card is already read only, then dont continue with
1327 next operation */
1328 if ((PH_NDEFMAP_CARD_STATE_READ_ONLY != psNdefMap->CardState)
1329 && (!result))
1330 {
1331 /* CC byte read successful */
1332 (void)memcpy ((void *)a_write_buf, (void *)p_recv_buf,
1333 sizeof (a_write_buf));
1334
1335 /* Change the read write access to read only */
1336 *(a_write_buf + ISO15693_RW_BTYE_INDEX) = (uint8_t)
1337 (*(a_write_buf + ISO15693_RW_BTYE_INDEX) |
1338 ISO15693_CC_READ_ONLY_MASK);
1339
1340 result = phFriNfc_ISO15693_H_ReadWrite (psNdefMap,
1341 ISO15693_WRITE_COMMAND, a_write_buf,
1342 sizeof (a_write_buf));
1343
1344 e_ro_ndef_seq = ISO15693_WRITE_CC;
1345 }
1346 }
1347 break;
1348 }
1349
1350 case ISO15693_WRITE_CC:
1351 {
1352 /* Write to CC is successful. */
1353 e_ro_ndef_seq = ISO15693_LOCK_BLOCK;
1354 /* Start the lock block command to lock the blocks */
1355 result = phFriNfc_ISO15693_H_ReadWrite (psNdefMap,
1356 ISO15693_LOCK_BLOCK_CMD, NULL, 0);
1357 break;
1358 }
1359
1360 case ISO15693_LOCK_BLOCK:
1361 {
1362 if (ps_iso_15693_con->current_block ==
1363 ((ps_iso_15693_con->max_data_size / ISO15693_BYTES_PER_BLOCK) -
1364 1))
1365 {
1366 /* End of card reached, READ ONLY successful */
1367 }
1368 else
1369 {
1370 /* current block is incremented */
1371 ps_iso_15693_con->current_block = (uint16_t)
1372 (ps_iso_15693_con->current_block + 1);
1373 /* Lock the current block */
1374 result = phFriNfc_ISO15693_H_ReadWrite (psNdefMap,
1375 ISO15693_LOCK_BLOCK_CMD, NULL, 0);
1376 }
1377 break;
1378 }
1379
1380 default:
1381 {
1382 break;
1383 }
1384 }
1385
1386 ps_iso_15693_con->ndef_seq = (uint8_t)e_ro_ndef_seq;
1387 return result;
1388 }
1389
1390 #endif /* #ifdef FRINFC_READONLY_NDEF */
1391 /************************** END static functions definition *********************/
1392
1393 /************************** START external functions *********************/
1394
1395 NFCSTATUS
phFriNfc_ISO15693_ChkNdef(phFriNfc_NdefMap_t * psNdefMap)1396 phFriNfc_ISO15693_ChkNdef (
1397 phFriNfc_NdefMap_t *psNdefMap)
1398 {
1399 NFCSTATUS result = NFCSTATUS_SUCCESS;
1400 phHal_sIso15693Info_t *ps_iso_15693_info =
1401 &(psNdefMap->psRemoteDevInfo->RemoteDevInfo.Iso15693_Info);
1402
1403 /* Update the previous operation with current operation.
1404 This becomes the previous operation after this execution */
1405 psNdefMap->PrevOperation = PH_FRINFC_NDEFMAP_CHECK_OPE;
1406 /* Update the CR index to know from which operation completion
1407 routine has to be called */
1408 psNdefMap->ISO15693Container.cr_index = PH_FRINFC_NDEFMAP_CR_CHK_NDEF;
1409 /* State update */
1410 psNdefMap->State = ISO15693_CHECK_NDEF;
1411 /* Reset the NDEF sequence */
1412 psNdefMap->ISO15693Container.ndef_seq = 0;
1413 psNdefMap->ISO15693Container.current_block = 0;
1414 psNdefMap->ISO15693Container.actual_ndef_size = 0;
1415 psNdefMap->ISO15693Container.ndef_tlv_type_blk = 0;
1416 psNdefMap->ISO15693Container.ndef_tlv_type_byte = 0;
1417 psNdefMap->ISO15693Container.store_length = 0;
1418 psNdefMap->ISO15693Container.remaining_size_to_read = 0;
1419 psNdefMap->ISO15693Container.read_capabilities = 0;
1420
1421 if ((ISO15693_UIDBYTE_6_VALUE ==
1422 ps_iso_15693_info->Uid[ISO15693_UID_BYTE_6])
1423 && (ISO15693_UIDBYTE_7_VALUE ==
1424 ps_iso_15693_info->Uid[ISO15693_UID_BYTE_7]))
1425 {
1426 /* Check if the card is manufactured by NXP (6th byte
1427 index of UID value = 0x04 and the
1428 last byte i.e., 7th byte of UID is 0xE0, only then the card detected
1429 is NDEF compliant */
1430 switch (ps_iso_15693_info->Uid[ISO15693_UID_BYTE_5])
1431 {
1432 /* Check for supported tags, by checking the 5th byte index of UID */
1433 case ISO15693_UIDBYTE_5_VALUE_SLI_X:
1434 {
1435 /* ISO 15693 card type is ICODE SLI
1436 so maximum size is 112 */
1437 psNdefMap->ISO15693Container.max_data_size =
1438 ISO15693_SL2_S2002_ICS20;
1439 break;
1440 }
1441
1442 case ISO15693_UIDBYTE_5_VALUE_SLI_X_S:
1443 {
1444 /* ISO 15693 card type is ICODE SLI/X S
1445 so maximum size depends on the 4th UID byte index */
1446 switch (ps_iso_15693_info->Uid[ISO15693_UID_BYTE_4])
1447 {
1448 case ISO15693_UIDBYTE_4_VALUE_SLI_X_S:
1449 case ISO15693_UIDBYTE_4_VALUE_SLI_X_SHC:
1450 case ISO15693_UIDBYTE_4_VALUE_SLI_X_SY:
1451 {
1452 /* Supported tags are with value (4th byte UID index)
1453 of 0x00, 0x80 and 0x40
1454 For these cards max size is 160 bytes */
1455 psNdefMap->ISO15693Container.max_data_size =
1456 ISO15693_SL2_S5302_ICS53_ICS54;
1457 break;
1458 }
1459
1460 default:
1461 {
1462 /* Tag not supported */
1463 result = PHNFCSTVAL(CID_FRI_NFC_NDEF_MAP,
1464 NFCSTATUS_INVALID_DEVICE_REQUEST);
1465 break;
1466 }
1467 }
1468 break;
1469 }
1470
1471 case ISO15693_UIDBYTE_5_VALUE_SLI_X_L:
1472 {
1473 /* ISO 15693 card type is ICODE SLI/X L
1474 so maximum size depends on the 4th UID byte index */
1475 switch (ps_iso_15693_info->Uid[ISO15693_UID_BYTE_4])
1476 {
1477 case ISO15693_UIDBYTE_4_VALUE_SLI_X_L:
1478 case ISO15693_UIDBYTE_4_VALUE_SLI_X_LHC:
1479 {
1480 /* Supported tags are with value (4th byte UID index)
1481 of 0x00 and 0x80
1482 For these cards max size is 32 bytes */
1483 psNdefMap->ISO15693Container.max_data_size =
1484 ISO15693_SL2_S5002_ICS50_ICS51;
1485 break;
1486 }
1487
1488 default:
1489 {
1490 /* Tag not supported */
1491 result = PHNFCSTVAL(CID_FRI_NFC_NDEF_MAP,
1492 NFCSTATUS_INVALID_DEVICE_REQUEST);
1493 break;
1494 }
1495 }
1496 break;
1497 }
1498
1499 default:
1500 {
1501 /* Tag not supported */
1502 result = PHNFCSTVAL(CID_FRI_NFC_NDEF_MAP,
1503 NFCSTATUS_INVALID_DEVICE_REQUEST);
1504 break;
1505 }
1506 }
1507 }
1508 else
1509 {
1510 /* Tag not supported */
1511 result = PHNFCSTVAL(CID_FRI_NFC_NDEF_MAP,
1512 NFCSTATUS_INVALID_DEVICE_REQUEST);
1513 }
1514
1515 if (!result)
1516 {
1517 /* Start reading the data */
1518 result = phFriNfc_ISO15693_H_ReadWrite (psNdefMap, ISO15693_READ_COMMAND,
1519 NULL, 0);
1520 }
1521
1522
1523 return result;
1524 }
1525
1526 NFCSTATUS
phFriNfc_ISO15693_RdNdef(phFriNfc_NdefMap_t * psNdefMap,uint8_t * pPacketData,uint32_t * pPacketDataLength,uint8_t Offset)1527 phFriNfc_ISO15693_RdNdef (
1528 phFriNfc_NdefMap_t *psNdefMap,
1529 uint8_t *pPacketData,
1530 uint32_t *pPacketDataLength,
1531 uint8_t Offset)
1532 {
1533 NFCSTATUS result = NFCSTATUS_SUCCESS;
1534 phFriNfc_ISO15693Cont_t *ps_iso_15693_con =
1535 &(psNdefMap->ISO15693Container);
1536
1537 /* Update the previous operation with current operation.
1538 This becomes the previous operation after this execution */
1539 psNdefMap->PrevOperation = PH_FRINFC_NDEFMAP_READ_OPE;
1540 /* Update the CR index to know from which operation completion
1541 routine has to be called */
1542 psNdefMap->ISO15693Container.cr_index = PH_FRINFC_NDEFMAP_CR_RD_NDEF;
1543 /* State update */
1544 psNdefMap->State = ISO15693_READ_NDEF;
1545 /* Copy user buffer to the context */
1546 psNdefMap->ApduBuffer = pPacketData;
1547 /* Copy user length to the context */
1548 psNdefMap->ApduBufferSize = *pPacketDataLength;
1549 /* Update the user memory size to a context variable */
1550 psNdefMap->NumOfBytesRead = pPacketDataLength;
1551 /* Number of bytes read from the card is zero.
1552 This variable returns the number of bytes read
1553 from the card. */
1554 *psNdefMap->NumOfBytesRead = 0;
1555 /* Index to know the length read */
1556 psNdefMap->ApduBuffIndex = 0;
1557 /* Store the offset in the context */
1558 psNdefMap->Offset = Offset;
1559
1560 if ((!ps_iso_15693_con->remaining_size_to_read)
1561 && (!psNdefMap->Offset))
1562 {
1563 /* Entire data is already read from the card.
1564 There is no data to give */
1565 result = PHNFCSTVAL(CID_FRI_NFC_NDEF_MAP,
1566 NFCSTATUS_EOF_NDEF_CONTAINER_REACHED);
1567 }
1568 else if (0 == ps_iso_15693_con->actual_ndef_size)
1569 {
1570 /* Card is NDEF, but no data in the card. */
1571 result = PHNFCSTVAL(CID_FRI_NFC_NDEF_MAP,
1572 NFCSTATUS_READ_FAILED);
1573 }
1574 else if (PH_NDEFMAP_CARD_STATE_INITIALIZED == psNdefMap->CardState)
1575 {
1576 /* Card is NDEF, but no data in the card. */
1577 result = PHNFCSTVAL(CID_FRI_NFC_NDEF_MAP,
1578 NFCSTATUS_READ_FAILED);
1579 }
1580 else if (psNdefMap->Offset)
1581 {
1582 /* BEGIN offset, so reset the remaining read size and
1583 also the curretn block */
1584 ps_iso_15693_con->remaining_size_to_read =
1585 ps_iso_15693_con->actual_ndef_size;
1586 ps_iso_15693_con->current_block =
1587 ISO15693_GET_VALUE_FIELD_BLOCK_NO(
1588 ps_iso_15693_con->ndef_tlv_type_blk,
1589 ps_iso_15693_con->ndef_tlv_type_byte,
1590 ps_iso_15693_con->actual_ndef_size);
1591
1592 // Check capabilities
1593 if ((ps_iso_15693_con->read_capabilities & ISO15693_CC_USE_MBR) ||
1594 (ps_iso_15693_con->read_capabilities & ISO15693_CC_USE_IPR)) {
1595 result = phFriNfc_ReadRemainingInMultiple(psNdefMap, ps_iso_15693_con->current_block);
1596 } else {
1597 result = phFriNfc_ISO15693_H_ReadWrite (psNdefMap, ISO15693_READ_COMMAND,
1598 NULL, 0);
1599 }
1600 }
1601 else
1602 {
1603 /* CONTINUE offset */
1604 if (ps_iso_15693_con->store_length > 0)
1605 {
1606 /* Previous read had extra bytes, so data is stored, so give that take
1607 that data from store. If more data is required, then read remaining bytes */
1608 result = phFriNfc_ISO15693_H_ProcessReadNdef (psNdefMap);
1609 }
1610 else
1611 {
1612 ps_iso_15693_con->current_block = (uint16_t)
1613 (ps_iso_15693_con->current_block + 1);
1614 result = phFriNfc_ISO15693_H_ReadWrite (psNdefMap,
1615 ISO15693_READ_COMMAND, NULL, 0);
1616 }
1617 }
1618
1619 return result;
1620 }
1621
1622 static
1623 NFCSTATUS
phFriNfc_ReadRemainingInMultiple(phFriNfc_NdefMap_t * psNdefMap,uint32_t startBlock)1624 phFriNfc_ReadRemainingInMultiple (
1625 phFriNfc_NdefMap_t *psNdefMap,
1626 uint32_t startBlock)
1627 {
1628 NFCSTATUS result = NFCSTATUS_FAILED;
1629 phFriNfc_ISO15693Cont_t *ps_iso_15693_con = &(psNdefMap->ISO15693Container);
1630
1631 uint32_t remaining_size = ISO15693_GET_REMAINING_SIZE(ps_iso_15693_con->max_data_size,
1632 startBlock, 0);
1633 // Check capabilities
1634 if (ps_iso_15693_con->read_capabilities & ISO15693_CC_USE_MBR) {
1635 // Multi-page read command
1636 uint8_t mbread[1];
1637 mbread[0] = (remaining_size / ISO15693_BYTES_PER_BLOCK) - 1;
1638 result = phFriNfc_ISO15693_H_ReadWrite (psNdefMap, ISO15693_READ_MULTIPLE_COMMAND,
1639 mbread, 1);
1640 } else if (ps_iso_15693_con->read_capabilities & ISO15693_CC_USE_IPR) {
1641 uint32_t page = 0;
1642 uint32_t pagesToRead = (remaining_size / ISO15693_BYTES_PER_BLOCK / 4) - 1;
1643 if ((remaining_size % (ISO15693_BYTES_PER_BLOCK * ISO15693_BLOCKS_PER_PAGE)) != 0) {
1644 pagesToRead++;
1645 }
1646 result = phFriNfc_ISO15693_H_Inventory_Page_Read (psNdefMap, ICODE_INVENTORY_PAGEREAD_COMMAND,
1647 page, pagesToRead);
1648 // Inventory
1649 } else {
1650 result = NFCSTATUS_FAILED;
1651 }
1652 return result;
1653 }
1654
1655 NFCSTATUS
phFriNfc_ISO15693_WrNdef(phFriNfc_NdefMap_t * psNdefMap,uint8_t * pPacketData,uint32_t * pPacketDataLength,uint8_t Offset)1656 phFriNfc_ISO15693_WrNdef (
1657 phFriNfc_NdefMap_t *psNdefMap,
1658 uint8_t *pPacketData,
1659 uint32_t *pPacketDataLength,
1660 uint8_t Offset)
1661 {
1662 NFCSTATUS result = NFCSTATUS_SUCCESS;
1663 phFriNfc_ISO15693Cont_t *ps_iso_15693_con =
1664 &(psNdefMap->ISO15693Container);
1665 uint8_t a_write_buf[ISO15693_BYTES_PER_BLOCK] = {0};
1666
1667 /* Update the previous operation with current operation.
1668 This becomes the previous operation after this execution */
1669 psNdefMap->PrevOperation = PH_FRINFC_NDEFMAP_WRITE_OPE;
1670 /* Update the CR index to know from which operation completion
1671 routine has to be called */
1672 psNdefMap->ISO15693Container.cr_index = PH_FRINFC_NDEFMAP_CR_WR_NDEF;
1673 /* State update */
1674 psNdefMap->State = ISO15693_WRITE_NDEF;
1675 /* Copy user buffer to the context */
1676 psNdefMap->ApduBuffer = pPacketData;
1677 /* Copy user length to the context */
1678 psNdefMap->ApduBufferSize = *pPacketDataLength;
1679 /* Update the user memory size to a context variable */
1680 psNdefMap->NumOfBytesRead = pPacketDataLength;
1681 /* Number of bytes written to the card is zero.
1682 This variable returns the number of bytes written
1683 to the card. */
1684 *psNdefMap->WrNdefPacketLength = 0;
1685 /* Index to know the length read */
1686 psNdefMap->ApduBuffIndex = 0;
1687 /* Store the offset in the context */
1688 psNdefMap->Offset = Offset;
1689
1690 /* Set the current block correctly to write the length field to 0 */
1691 ps_iso_15693_con->current_block =
1692 ISO15693_GET_LEN_FIELD_BLOCK_NO(
1693 ps_iso_15693_con->ndef_tlv_type_blk,
1694 ps_iso_15693_con->ndef_tlv_type_byte,
1695 *pPacketDataLength);
1696
1697 if (ISO15693_GET_LEN_FIELD_BYTE_NO(
1698 ps_iso_15693_con->ndef_tlv_type_blk,
1699 ps_iso_15693_con->ndef_tlv_type_byte,
1700 *pPacketDataLength))
1701 {
1702 /* Check the byte address to write. If length byte address is in between or
1703 is the last byte of the block, then READ before write
1704 reason, write should not corrupt other data
1705 */
1706 ps_iso_15693_con->ndef_seq = (uint8_t)ISO15693_RD_BEFORE_WR_NDEF_L_0;
1707 result = phFriNfc_ISO15693_H_ReadWrite (psNdefMap,
1708 ISO15693_READ_COMMAND, NULL, 0);
1709 }
1710 else
1711 {
1712 /* If length byte address is at the beginning of the block then WRITE
1713 length field to 0 and as also write user DATA */
1714 ps_iso_15693_con->ndef_seq = (uint8_t)ISO15693_WRITE_DATA;
1715
1716 /* Length is made 0x00 */
1717 *a_write_buf = 0x00;
1718
1719 /* Write remaining data */
1720 (void)memcpy ((void *)(a_write_buf + 1),
1721 (void *)psNdefMap->ApduBuffer,
1722 (ISO15693_BYTES_PER_BLOCK - 1));
1723
1724 /* Write data */
1725 result = phFriNfc_ISO15693_H_ReadWrite (psNdefMap,
1726 ISO15693_WRITE_COMMAND,
1727 a_write_buf, ISO15693_BYTES_PER_BLOCK);
1728
1729 /* Increment the index to keep track of bytes sent for write */
1730 psNdefMap->ApduBuffIndex = (uint16_t)(psNdefMap->ApduBuffIndex
1731 + (ISO15693_BYTES_PER_BLOCK - 1));
1732 }
1733
1734 return result;
1735 }
1736
1737 #ifdef FRINFC_READONLY_NDEF
1738
1739 NFCSTATUS
phFriNfc_ISO15693_ConvertToReadOnly(phFriNfc_NdefMap_t * psNdefMap)1740 phFriNfc_ISO15693_ConvertToReadOnly (
1741 phFriNfc_NdefMap_t *psNdefMap)
1742 {
1743 NFCSTATUS result = NFCSTATUS_SUCCESS;
1744 phFriNfc_ISO15693Cont_t *ps_iso_15693_con =
1745 &(psNdefMap->ISO15693Container);
1746
1747 psNdefMap->State = ISO15693_READ_ONLY_NDEF;
1748 /* READ CC bytes */
1749 ps_iso_15693_con->ndef_seq = (uint8_t)ISO15693_RD_BEFORE_WR_CC;
1750 ps_iso_15693_con->current_block = 0;
1751
1752 result = phFriNfc_ISO15693_H_ReadWrite (psNdefMap,
1753 ISO15693_READ_COMMAND, NULL, 0);
1754
1755 return result;
1756 }
1757
1758 #endif /* #ifdef FRINFC_READONLY_NDEF */
1759
1760
1761 void
phFriNfc_ISO15693_Process(void * pContext,NFCSTATUS Status)1762 phFriNfc_ISO15693_Process (
1763 void *pContext,
1764 NFCSTATUS Status)
1765 {
1766 phFriNfc_NdefMap_t *psNdefMap =
1767 (phFriNfc_NdefMap_t *)pContext;
1768
1769 if ((NFCSTATUS_SUCCESS & PHNFCSTBLOWER) == (Status & PHNFCSTBLOWER))
1770 {
1771 switch (psNdefMap->State)
1772 {
1773 case ISO15693_CHECK_NDEF:
1774 {
1775 /* State = CHECK NDEF in progress */
1776 Status = phFriNfc_ISO15693_H_ProcessCheckNdef (psNdefMap);
1777 break;
1778 }
1779
1780 case ISO15693_READ_NDEF:
1781 {
1782 /* State = READ NDEF in progress */
1783 Status = phFriNfc_ISO15693_H_ProcessReadNdef (psNdefMap);
1784 break;
1785 }
1786
1787 case ISO15693_WRITE_NDEF:
1788 {
1789 /* State = WRITE NDEF in progress */
1790 Status = phFriNfc_ISO15693_H_ProcessWriteNdef (psNdefMap);
1791 break;
1792 }
1793
1794 #ifdef FRINFC_READONLY_NDEF
1795 case ISO15693_READ_ONLY_NDEF:
1796 {
1797 /* State = RAD ONLY NDEF in progress */
1798 Status = phFriNfc_ISO15693_H_ProcessReadOnly (psNdefMap);
1799 break;
1800 }
1801 #endif /* #ifdef FRINFC_READONLY_NDEF */
1802
1803 default:
1804 {
1805 break;
1806 }
1807 }
1808 }
1809
1810 /* Call for the Completion Routine*/
1811 if (NFCSTATUS_PENDING != Status)
1812 {
1813 phFriNfc_ISO15693_H_Complete(psNdefMap, Status);
1814 }
1815 }
1816
1817 /************************** END external functions *********************/
1818
1819 #endif /* #ifndef PH_FRINFC_MAP_ISO15693_DISABLED */
1820