1/******************************************************************************
2 *
3 *  Copyright (C) 2009-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 Near Field Communication (NFC) Reader/Writer mode
22 *  related internal function / definitions.
23 *
24 ******************************************************************************/
25
26#ifndef RW_INT_H_
27#define RW_INT_H_
28
29#include "rw_api.h"
30#include "tags_defs.h"
31#include "tags_int.h"
32
33/* Proprietary definitions for HR0 and HR1 */
34/* TOPAZ96 Tag                                              */
35#define RW_T1T_IS_TOPAZ96 0x11
36/* TOPAZ512 Tag                                             */
37#define RW_T1T_IS_TOPAZ512 0x12
38/* Supports dynamic commands on static tag if HR1 > 0x49    */
39#define RW_T1T_HR1_MIN 0x49
40
41/* Maximum supported Memory control TLVS in the tag         */
42#define RW_T1T_MAX_MEM_TLVS 0x05
43/* Maximum supported Lock control TLVS in the tag           */
44#define RW_T1T_MAX_LOCK_TLVS 0x05
45/* Maximum supported dynamic lock bytes                     */
46#define RW_T1T_MAX_LOCK_BYTES 0x1E
47
48/* State of the Tag as interpreted by RW */
49/* TAG State is unknown to RW                               */
50#define RW_T1_TAG_ATTRB_UNKNOWN 0x00
51/* TAG is in INITIALIZED state                              */
52#define RW_T1_TAG_ATTRB_INITIALIZED 0x01
53/* TAG is in INITIALIZED state and has NDEF tlv with len=0  */
54#define RW_T1_TAG_ATTRB_INITIALIZED_NDEF 0x02
55/* TAG is in READ ONLY state                                */
56#define RW_T1_TAG_ATTRB_READ_ONLY 0x03
57/* TAG is in READ WRITE state                               */
58#define RW_T1_TAG_ATTRB_READ_WRITE 0x04
59
60/* Lock not yet set as part of SET TAG RO op                */
61#define RW_T1T_LOCK_NOT_UPDATED 0x00
62/* Sent command to set the Lock bytes                       */
63#define RW_T1T_LOCK_UPDATE_INITIATED 0x01
64/* Lock bytes are set                                       */
65#define RW_T1T_LOCK_UPDATED 0x02
66typedef uint8_t tRW_T1T_LOCK_STATUS;
67
68/* States */
69/* Tag not activated and or response not received for RID   */
70#define RW_T1T_STATE_NOT_ACTIVATED 0x00
71/* T1 Tag activated and ready to perform rw operation on Tag*/
72#define RW_T1T_STATE_IDLE 0x01
73/* waiting rsp for read command sent to tag                 */
74#define RW_T1T_STATE_READ 0x02
75/* waiting rsp for write command sent to tag                */
76#define RW_T1T_STATE_WRITE 0x03
77/* performing TLV detection procedure                       */
78#define RW_T1T_STATE_TLV_DETECT 0x04
79/* performing read NDEF procedure                           */
80#define RW_T1T_STATE_READ_NDEF 0x05
81/* performing update NDEF procedure                         */
82#define RW_T1T_STATE_WRITE_NDEF 0x06
83/* Setting Tag as read only tag                             */
84#define RW_T1T_STATE_SET_TAG_RO 0x07
85/* Check if Tag is still present                            */
86#define RW_T1T_STATE_CHECK_PRESENCE 0x08
87/* Format T1 Tag                                            */
88#define RW_T1T_STATE_FORMAT_TAG 0x09
89
90/* Sub states */
91/* Default substate                                         */
92#define RW_T1T_SUBSTATE_NONE 0x00
93
94/* Sub states in RW_T1T_STATE_TLV_DETECT state */
95/* waiting for the detection of a tlv in a tag              */
96#define RW_T1T_SUBSTATE_WAIT_TLV_DETECT 0x01
97/* waiting for finding the len field is 1 or 3 bytes long   */
98#define RW_T1T_SUBSTATE_WAIT_FIND_LEN_FIELD_LEN 0x02
99/* waiting for extracting len field value                   */
100#define RW_T1T_SUBSTATE_WAIT_READ_TLV_LEN0 0x03
101/* waiting for extracting len field value                   */
102#define RW_T1T_SUBSTATE_WAIT_READ_TLV_LEN1 0x04
103/* waiting for extracting value field in the TLV            */
104#define RW_T1T_SUBSTATE_WAIT_READ_TLV_VALUE 0x05
105/* waiting for reading dynamic locks in the TLV             */
106#define RW_T1T_SUBSTATE_WAIT_READ_LOCKS 0x06
107
108/* Sub states in RW_T1T_STATE_WRITE_NDEF state */
109/* waiting for response of reading a block that will be partially updated */
110#define RW_T1T_SUBSTATE_WAIT_READ_NDEF_BLOCK 0x07
111/* waiting for response of invalidating NDEF Msg                          */
112#define RW_T1T_SUBSTATE_WAIT_INVALIDATE_NDEF 0x08
113/* waiting for response of writing a part of NDEF Msg                     */
114#define RW_T1T_SUBSTATE_WAIT_NDEF_WRITE 0x09
115/* waiting for response of writing last part of NDEF Msg                  */
116#define RW_T1T_SUBSTATE_WAIT_NDEF_UPDATED 0x0A
117/* waiting for response of validating NDEF Msg                            */
118#define RW_T1T_SUBSTATE_WAIT_VALIDATE_NDEF 0x0B
119
120/* Sub states in RW_T1T_STATE_SET_TAG_RO state */
121/* waiting for response of setting CC-RWA to read only      */
122#define RW_T1T_SUBSTATE_WAIT_SET_CC_RWA_RO 0x0C
123/* waiting for response of setting all static lock bits     */
124#define RW_T1T_SUBSTATE_WAIT_SET_ST_LOCK_BITS 0x0D
125/* waiting for response of setting all dynamic lock bits    */
126#define RW_T1T_SUBSTATE_WAIT_SET_DYN_LOCK_BITS 0x0E
127
128/* Sub states in RW_T1T_STATE_FORMAT_TAG state */
129/* waiting for response to format/set capability container  */
130#define RW_T1T_SUBSTATE_WAIT_SET_CC 0x0F
131/* waiting for response to format/set NULL NDEF             */
132#define RW_T1T_SUBSTATE_WAIT_SET_NULL_NDEF 0x10
133
134typedef struct {
135  uint16_t offset;  /* Offset of the lock byte in the Tag                   */
136  uint8_t num_bits; /* Number of lock bits in the lock byte                 */
137  uint8_t bytes_locked_per_bit; /* No. of tag bytes gets locked by a bit in this
138                                   byte   */
139} tRW_T1T_LOCK_INFO;
140
141typedef struct {
142  uint16_t offset;   /* Reserved bytes offset taken from Memory control TLV  */
143  uint8_t num_bytes; /* Number of reserved bytes as per the TLV              */
144} tRW_T1T_RES_INFO;
145
146typedef struct {
147  uint8_t tlv_index;  /* Index of Lock control tlv that points to this address*/
148  uint8_t byte_index; /* Index of Lock byte pointed by the TLV                */
149  uint8_t lock_byte;  /* Value in the lock byte                               */
150  tRW_T1T_LOCK_STATUS
151      lock_status;  /* Indicates if it is modifed to set tag as Read only   */
152  bool b_lock_read; /* Is the lock byte is already read from tag            */
153} tRW_T1T_LOCK;
154
155typedef struct {
156  uint8_t addr;    /* ADD/ADD8/ADDS field value                            */
157  uint8_t op_code; /* Command sent                                         */
158  uint8_t rsp_len; /* expected length of the response                      */
159  uint8_t
160      pend_retx_rsp; /* Number of pending rsps to retransmission on prev cmd */
161} tRW_T1T_PREV_CMD_RSP_INFO;
162
163#if (RW_NDEF_INCLUDED == TRUE)
164/* Buffer 0-E block, for easier tlv operation           */
165#define T1T_BUFFER_SIZE T1T_STATIC_SIZE
166#else
167/* Buffer UID                                           */
168#define T1T_BUFFER_SIZE T1T_UID_LEN
169#endif
170
171/* RW Type 1 Tag control blocks */
172typedef struct {
173  uint8_t
174      hr[T1T_HR_LEN]; /* Header ROM byte 0 - 0x1y,Header ROM byte 1 - 0x00    */
175  uint8_t mem[T1T_SEGMENT_SIZE]; /* Tag contents of block 0 or from block 0-E */
176  tT1T_CMD_RSP_INFO*
177      p_cmd_rsp_info; /* Pointer to Command rsp info of last sent command     */
178  uint8_t state;      /* Current state of RW module                           */
179  uint8_t tag_attribute; /* Present state of the Tag as interpreted by RW */
180  NFC_HDR*
181      p_cur_cmd_buf; /* Buffer to hold cur sent command for retransmission   */
182  uint8_t addr;      /* ADD/ADD8/ADDS value                                  */
183  tRW_T1T_PREV_CMD_RSP_INFO
184      prev_cmd_rsp_info; /* Information about previous sent command if retx */
185  TIMER_LIST_ENT timer; /* timer to set timelimit for the response to command */
186  bool b_update;    /* Tag header updated                                   */
187  bool b_rseg;      /* Segment 0 read from tag                              */
188  bool b_hard_lock; /* Hard lock the tag as part of config tag to Read only */
189#if (RW_NDEF_INCLUDED == TRUE)
190  uint8_t segment;  /* Current Tag segment                                  */
191  uint8_t substate; /* Current substate of RW module                        */
192  uint16_t work_offset;                     /* Working byte offset */
193  uint8_t ndef_first_block[T1T_BLOCK_SIZE]; /* Buffer for ndef first block */
194  uint8_t ndef_final_block[T1T_BLOCK_SIZE]; /* Buffer for ndef last block */
195  uint8_t* p_ndef_buffer;                   /* Buffer to store ndef message */
196  uint16_t new_ndef_msg_len; /* Lenght of new updating NDEF Message */
197  uint8_t block_read; /* Last read Block                                      */
198  uint8_t write_byte; /* Index of last written byte                           */
199  uint8_t tlv_detect; /* TLV type under detection                             */
200  uint16_t ndef_msg_offset; /* The offset on Tag where first NDEF message is
201                               present*/
202  uint16_t ndef_msg_len;    /* Lenght of NDEF Message */
203  uint16_t
204      max_ndef_msg_len; /* Maximum size of NDEF that can be written on the tag
205                           */
206  uint16_t ndef_header_offset; /* The offset on Tag where first NDEF tlv is
207                                  present    */
208  uint8_t ndef_block_written;  /* Last block where NDEF bytes are written */
209  uint8_t num_ndef_finalblock; /* Block number where NDEF's last byte will be
210                                  present  */
211  uint8_t num_lock_tlvs;       /* Number of lcok tlvs detected in the tag */
212  tRW_T1T_LOCK_INFO lock_tlv[RW_T1T_MAX_LOCK_TLVS]; /* Information retrieved
213                                                       from lock control tlv */
214  uint8_t num_lockbytes; /* Number of dynamic lock bytes present in the tag */
215  tRW_T1T_LOCK
216      lockbyte[RW_T1T_MAX_LOCK_BYTES]; /* Dynamic Lock byte information */
217  uint8_t num_mem_tlvs; /* Number of memory tlvs detected in the tag */
218  tRW_T1T_RES_INFO
219      mem_tlv[RW_T1T_MAX_MEM_TLVS]; /* Information retrieved from mem tlv */
220  uint8_t attr_seg; /* Tag segment for which attributes are prepared        */
221  uint8_t
222      lock_attr_seg; /* Tag segment for which lock attributes are prepared   */
223  uint8_t
224      attr[T1T_BLOCKS_PER_SEGMENT]; /* byte information - Reserved/lock/otp or
225                                       data         */
226  uint8_t lock_attr
227      [T1T_BLOCKS_PER_SEGMENT]; /* byte information - read only or read write */
228#endif
229} tRW_T1T_CB;
230
231/* Mifare Ultalight/ Ultralight Family blank tag version block settings */
232/* Block where version number of the tag is stored */
233#define T2T_MIFARE_VERSION_BLOCK 0x04
234/* Blank Ultralight tag - Block 4 (byte 0, byte 1) */
235#define T2T_MIFARE_ULTRALIGHT_VER_NO 0xFFFF
236/* Blank Ultralight family tag - Block 4 (byte 0, byte 1) */
237#define T2T_MIFARE_ULTRALIGHT_FAMILY_VER_NO 0x0200
238
239/* Infineon my-d move / my-d blank tag uid block settings */
240#define T2T_INFINEON_VERSION_BLOCK 0x00
241#define T2T_INFINEON_MYD_MOVE_LEAN 0x0570
242#define T2T_INFINEON_MYD_MOVE 0x0530
243
244#define T2T_BRCM_VERSION_BLOCK 0x00
245#define T2T_BRCM_STATIC_MEM 0x2E01
246#define T2T_BRCM_DYNAMIC_MEM 0x2E02
247
248#define T2T_NDEF_NOT_DETECTED 0x00
249#define T2T_NDEF_DETECTED 0x01
250#define T2T_NDEF_READ 0x02
251
252/* Maximum supported Memory control TLVS in the tag         */
253#define RW_T2T_MAX_MEM_TLVS 0x05
254/* Maximum supported Lock control TLVS in the tag           */
255#define RW_T2T_MAX_LOCK_TLVS 0x05
256/* Maximum supported dynamic lock bytes                     */
257#define RW_T2T_MAX_LOCK_BYTES 0x1E
258#define RW_T2T_SEGMENT_BYTES 128
259#define RW_T2T_SEGMENT_SIZE 16
260
261/* Lock not yet set as part of SET TAG RO op                */
262#define RW_T2T_LOCK_NOT_UPDATED 0x00
263/* Sent command to set the Lock bytes                       */
264#define RW_T2T_LOCK_UPDATE_INITIATED 0x01
265/* Lock bytes are set                                       */
266#define RW_T2T_LOCK_UPDATED 0x02
267typedef uint8_t tRW_T2T_LOCK_STATUS;
268
269/* States */
270/* Tag not activated                                        */
271#define RW_T2T_STATE_NOT_ACTIVATED 0x00
272/* T1 Tag activated and ready to perform rw operation on Tag*/
273#define RW_T2T_STATE_IDLE 0x01
274/* waiting response for read command sent to tag            */
275#define RW_T2T_STATE_READ 0x02
276/* waiting response for write command sent to tag           */
277#define RW_T2T_STATE_WRITE 0x03
278/* Waiting response for sector select command               */
279#define RW_T2T_STATE_SELECT_SECTOR 0x04
280/* Detecting Lock/Memory/NDEF/Proprietary TLV in the Tag    */
281#define RW_T2T_STATE_DETECT_TLV 0x05
282/* Performing NDEF Read procedure                           */
283#define RW_T2T_STATE_READ_NDEF 0x06
284/* Performing NDEF Write procedure                          */
285#define RW_T2T_STATE_WRITE_NDEF 0x07
286/* Setting Tag as Read only tag                             */
287#define RW_T2T_STATE_SET_TAG_RO 0x08
288/* Check if Tag is still present                            */
289#define RW_T2T_STATE_CHECK_PRESENCE 0x09
290/* Format the tag                                           */
291#define RW_T2T_STATE_FORMAT_TAG 0x0A
292/* Tag is in HALT State */
293#define RW_T2T_STATE_HALT 0x0B
294
295/* rw_t2t_read/rw_t2t_write takes care of sector change if the block to
296 * read/write is in a different sector
297 * Next Substate should be assigned to control variable 'substate' before
298 * calling these function for State Machine to
299 * move back to the particular substate after Sector change is completed and
300 * read/write command is sent on new sector       */
301
302/* Sub states */
303#define RW_T2T_SUBSTATE_NONE 0x00
304
305/* Sub states in RW_T2T_STATE_SELECT_SECTOR state */
306/* waiting for response of sector select CMD 1              */
307#define RW_T2T_SUBSTATE_WAIT_SELECT_SECTOR_SUPPORT 0x01
308/* waiting for response of sector select CMD 2              */
309#define RW_T2T_SUBSTATE_WAIT_SELECT_SECTOR 0x02
310
311/* Sub states in RW_T1T_STATE_DETECT_XXX state */
312/* waiting for the detection of a tlv in a tag              */
313#define RW_T2T_SUBSTATE_WAIT_READ_CC 0x03
314/* waiting for the detection of a tlv in a tag              */
315#define RW_T2T_SUBSTATE_WAIT_TLV_DETECT 0x04
316/* waiting for finding the len field is 1 or 3 bytes long   */
317#define RW_T2T_SUBSTATE_WAIT_FIND_LEN_FIELD_LEN 0x05
318/* waiting for extracting len field value                   */
319#define RW_T2T_SUBSTATE_WAIT_READ_TLV_LEN0 0x06
320/* waiting for extracting len field value                   */
321#define RW_T2T_SUBSTATE_WAIT_READ_TLV_LEN1 0x07
322/* waiting for extracting value field in the TLV            */
323#define RW_T2T_SUBSTATE_WAIT_READ_TLV_VALUE 0x08
324/* waiting for reading dynamic locks in the TLV             */
325#define RW_T2T_SUBSTATE_WAIT_READ_LOCKS 0x09
326
327/* Sub states in RW_T2T_STATE_WRITE_NDEF state */
328/* waiting for rsp to reading the block where NDEF starts   */
329#define RW_T2T_SUBSTATE_WAIT_READ_NDEF_FIRST_BLOCK 0x0A
330/* waiting for rsp to reading block where new NDEF Msg ends */
331#define RW_T2T_SUBSTATE_WAIT_READ_NDEF_LAST_BLOCK 0x0B
332/* waiting for rsp to reading block where Trm tlv gets added*/
333#define RW_T2T_SUBSTATE_WAIT_READ_TERM_TLV_BLOCK 0x0C
334/* waiting for rsp to reading block where nxt NDEF write    */
335#define RW_T2T_SUBSTATE_WAIT_READ_NDEF_NEXT_BLOCK 0x0D
336/* waiting for rsp to writting NDEF block                   */
337#define RW_T2T_SUBSTATE_WAIT_WRITE_NDEF_NEXT_BLOCK 0x0E
338/* waiting for rsp to last NDEF block write cmd             */
339#define RW_T2T_SUBSTATE_WAIT_WRITE_NDEF_LAST_BLOCK 0x0F
340/* waiting for rsp to reading NDEF len field block          */
341#define RW_T2T_SUBSTATE_WAIT_READ_NDEF_LEN_BLOCK 0x10
342/* waiting for rsp of updating first NDEF len field block   */
343#define RW_T2T_SUBSTATE_WAIT_WRITE_NDEF_LEN_BLOCK 0x11
344/* waiting for rsp of updating next NDEF len field block    */
345#define RW_T2T_SUBSTATE_WAIT_WRITE_NDEF_LEN_NEXT_BLOCK 0x12
346/* waiting for rsp to writing to Terminator tlv             */
347#define RW_T2T_SUBSTATE_WAIT_WRITE_TERM_TLV_CMPLT 0x13
348
349/* Sub states in RW_T2T_STATE_FORMAT_TAG state */
350#define RW_T2T_SUBSTATE_WAIT_READ_VERSION_INFO 0x14
351/* waiting for response to format/set capability container  */
352#define RW_T2T_SUBSTATE_WAIT_SET_CC 0x15
353#define RW_T2T_SUBSTATE_WAIT_SET_LOCK_TLV 0x16
354/* waiting for response to format/set NULL NDEF             */
355#define RW_T2T_SUBSTATE_WAIT_SET_NULL_NDEF 0x17
356
357/* Sub states in RW_T2T_STATE_SET_TAG_RO state */
358/* waiting for response to set CC3 to RO                    */
359#define RW_T2T_SUBSTATE_WAIT_SET_CC_RO 0x19
360/* waiting for response to read dynamic lock bytes block    */
361#define RW_T2T_SUBSTATE_WAIT_READ_DYN_LOCK_BYTE_BLOCK 0x1A
362/* waiting for response to set dynamic lock bits            */
363#define RW_T2T_SUBSTATE_WAIT_SET_DYN_LOCK_BITS 0x1B
364/* waiting for response to set static lock bits             */
365#define RW_T2T_SUBSTATE_WAIT_SET_ST_LOCK_BITS 0x1C
366
367typedef struct {
368  uint16_t offset;              /* Offset of the lock byte in the Tag */
369  uint8_t num_bits;             /* Number of lock bits in the lock byte */
370  uint8_t bytes_locked_per_bit; /* No. of tag bytes gets locked by a bit in this
371                                   byte       */
372} tRW_T2T_LOCK_INFO;
373
374typedef struct {
375  uint16_t offset;   /* Reserved bytes offset taken from Memory control TLV */
376  uint8_t num_bytes; /* Number of reserved bytes as per the TLV */
377} tRW_T2T_RES_INFO;
378
379typedef struct {
380  uint8_t tlv_index; /* Index of Lock control tlv that points to this address */
381  uint8_t byte_index; /* Index of Lock byte pointed by the TLV */
382  uint8_t lock_byte;  /* Value in the lock byte */
383  tRW_T2T_LOCK_STATUS
384      lock_status;  /* Indicates if it is modifed to set tag as Read only */
385  bool b_lock_read; /* Is the lock byte is already read from tag */
386} tRW_T2T_LOCK;
387
388/* RW Type 2 Tag control block */
389typedef struct {
390  uint8_t state;    /* Reader/writer state */
391  uint8_t substate; /* Reader/write substate in NDEF write state */
392  uint8_t
393      prev_substate; /* Substate of the tag before moving to different sector */
394  uint8_t sector;    /* Sector number that is selected */
395  uint8_t select_sector; /* Sector number that is expected to get selected */
396  uint8_t tag_hdr[T2T_READ_DATA_LEN];  /* T2T Header blocks */
397  uint8_t tag_data[T2T_READ_DATA_LEN]; /* T2T Block 4 - 7 data */
398  uint8_t ndef_status;    /* The current status of NDEF Write operation */
399  uint16_t block_read;    /* Read block */
400  uint16_t block_written; /* Written block */
401  tT2T_CMD_RSP_INFO*
402      p_cmd_rsp_info;     /* Pointer to Command rsp info of last sent command */
403  NFC_HDR* p_cur_cmd_buf; /* Copy of current command, for retx/send after sector
404                             change   */
405  NFC_HDR* p_sec_cmd_buf; /* Copy of command, to send after sector change */
406  TIMER_LIST_ENT t2_timer; /* timeout for each API call */
407  bool b_read_hdr;         /* Tag header read from tag */
408  bool b_read_data;        /* Tag data block read from tag */
409  bool b_hard_lock; /* Hard lock the tag as part of config tag to Read only */
410  bool check_tag_halt; /* Resent command after NACK rsp to find tag is in HALT
411                          State   */
412#if (RW_NDEF_INCLUDED == TRUE)
413  bool skip_dyn_locks;   /* Skip reading dynamic lock bytes from the tag */
414  uint8_t found_tlv;     /* The Tlv found while searching a particular TLV */
415  uint8_t tlv_detect;    /* TLV type under detection */
416  uint8_t num_lock_tlvs; /* Number of lcok tlvs detected in the tag */
417  uint8_t attr_seg;      /* Tag segment for which attributes are prepared */
418  uint8_t
419      lock_attr_seg; /* Tag segment for which lock attributes are prepared */
420  uint8_t segment;   /* Current operating segment */
421  uint8_t ndef_final_block[T2T_BLOCK_SIZE]; /* Buffer for ndef last block */
422  uint8_t num_mem_tlvs;  /* Number of memory tlvs detected in the tag */
423  uint8_t num_lockbytes; /* Number of dynamic lock bytes present in the tag */
424  uint8_t attr
425      [RW_T2T_SEGMENT_SIZE]; /* byte information - Reserved/lock/otp or data */
426  uint8_t lock_attr[RW_T2T_SEGMENT_SIZE];  /* byte information - read only or
427                                              read write                   */
428  uint8_t tlv_value[3];                    /* Read value field of TLV */
429  uint8_t ndef_first_block[T2T_BLOCK_LEN]; /* NDEF TLV Header block */
430  uint8_t ndef_read_block[T2T_BLOCK_LEN];  /* Buffer to hold read before write
431                                              block                       */
432  uint8_t ndef_last_block[T2T_BLOCK_LEN];  /* Terminator TLV block after NDEF
433                                              Write operation              */
434  uint8_t terminator_tlv_block[T2T_BLOCK_LEN]; /* Terminator TLV Block */
435  uint16_t ndef_last_block_num; /* Block where last byte of updating ndef
436                                   message will exist    */
437  uint16_t ndef_read_block_num; /* Block read during NDEF Write to avoid
438                                   overwritting res bytes */
439  uint16_t
440      bytes_count; /* No. of bytes remaining to collect during tlv detect */
441  uint16_t
442      terminator_byte_index; /* The offset of the tag where terminator tlv may
443                                be added      */
444  uint16_t work_offset;      /* Working byte offset */
445  uint16_t ndef_header_offset;
446  uint16_t
447      ndef_msg_offset;   /* Offset on Tag where first NDEF message is present */
448  uint16_t ndef_msg_len; /* Lenght of NDEF Message */
449  uint16_t
450      max_ndef_msg_len; /* Maximum size of NDEF that can be written on the tag
451                           */
452  uint16_t new_ndef_msg_len; /* Lenght of new updating NDEF Message */
453  uint16_t ndef_write_block;
454  uint16_t prop_msg_len;      /* Proprietary tlv length */
455  uint8_t* p_new_ndef_buffer; /* Pointer to updating NDEF Message */
456  uint8_t* p_ndef_buffer;     /* Pointer to NDEF Message */
457  tRW_T2T_LOCK_INFO lock_tlv[RW_T2T_MAX_LOCK_TLVS]; /* Information retrieved
458                                                       from lock control tlv */
459  tRW_T2T_LOCK
460      lockbyte[RW_T2T_MAX_LOCK_BYTES]; /* Dynamic Lock byte information */
461  tRW_T2T_RES_INFO
462      mem_tlv[RW_T2T_MAX_MEM_TLVS]; /* Information retrieved from mem tlv */
463#endif
464} tRW_T2T_CB;
465
466/* Type 3 Tag control block */
467typedef uint8_t tRW_T3T_RW_STATE;
468
469typedef struct {
470  tNFC_STATUS status;
471  uint8_t version; /* Ver: peer version */
472  uint8_t
473      nbr; /* NBr: number of blocks that can be read using one Check command */
474  uint8_t nbw;    /* Nbw: number of blocks that can be written using one Update
475                     command */
476  uint16_t nmaxb; /* Nmaxb: maximum number of blocks available for NDEF data */
477  uint8_t writef; /* WriteFlag: 00h if writing data finished; 0Fh if writing
478                     data in progress */
479  uint8_t
480      rwflag;  /* RWFlag: 00h NDEF is read-only; 01h if read/write available */
481  uint32_t ln; /* Ln: actual size of stored NDEF data (in bytes) */
482} tRW_T3T_DETECT;
483
484/* RW_T3T control block flags */
485/* The final command for completing the NDEF read/write */
486#define RW_T3T_FL_IS_FINAL_NDEF_SEGMENT 0x01
487/* Waiting for POLL response for presence check */
488#define RW_T3T_FL_W4_PRESENCE_CHECK_POLL_RSP 0x02
489/* Waiting for POLL response for RW_T3tGetSystemCodes */
490#define RW_T3T_FL_W4_GET_SC_POLL_RSP 0x04
491/* Waiting for POLL response for RW_T3tDetectNDef */
492#define RW_T3T_FL_W4_NDEF_DETECT_POLL_RSP 0x08
493/* Waiting for POLL response for RW_T3tFormat */
494#define RW_T3T_FL_W4_FMT_FELICA_LITE_POLL_RSP 0x10
495/* Waiting for POLL response for RW_T3tSetReadOnly */
496#define RW_T3T_FL_W4_SRO_FELICA_LITE_POLL_RSP 0x20
497
498typedef struct {
499  uint32_t cur_tout; /* Current command timeout */
500  /* check timeout is check_tout_a + n * check_tout_b; X is T/t3t * 4^E */
501  uint32_t check_tout_a; /* Check command timeout (A+1)*X */
502  uint32_t check_tout_b; /* Check command timeout (B+1)*X */
503  /* update timeout is update_tout_a + n * update_tout_b; X is T/t3t * 4^E */
504  uint32_t update_tout_a;    /* Update command timeout (A+1)*X */
505  uint32_t update_tout_b;    /* Update command timeout (B+1)*X */
506  tRW_T3T_RW_STATE rw_state; /* Reader/writer state */
507  uint8_t rw_substate;
508  uint8_t cur_cmd;           /* Current command being executed */
509  NFC_HDR* p_cur_cmd_buf;    /* Copy of current command, for retransmission */
510  TIMER_LIST_ENT timer;      /* timeout for waiting for response */
511  TIMER_LIST_ENT poll_timer; /* timeout for waiting for response */
512
513  tRW_T3T_DETECT ndef_attrib; /* T3T NDEF attribute information */
514
515  uint32_t ndef_msg_len;        /* Length of ndef message to send */
516  uint32_t ndef_msg_bytes_sent; /* Length of ndef message sent so far */
517  uint8_t* ndef_msg;            /* Buffer for outgoing NDEF message */
518  uint32_t ndef_rx_readlen; /* Number of bytes read in current CHECK command */
519  uint32_t ndef_rx_offset;  /* Length of ndef message read so far */
520
521  uint8_t num_system_codes; /* System codes detected */
522  uint16_t system_codes[T3T_MAX_SYSTEM_CODES];
523
524  uint8_t peer_nfcid2[NCI_NFCID2_LEN];
525  uint8_t cur_poll_rc; /* RC used in current POLL command */
526
527  uint8_t flags; /* Flags see RW_T3T_FL_* */
528} tRW_T3T_CB;
529
530/*
531**  Type 4 Tag
532*/
533
534/* Max data size using a single ReadBinary. 2 bytes are for status bytes */
535#define RW_T4T_MAX_DATA_PER_READ                             \
536  (NFC_RW_POOL_BUF_SIZE - NFC_HDR_SIZE - NCI_DATA_HDR_SIZE - \
537   T4T_RSP_STATUS_WORDS_SIZE)
538
539/* Max data size using a single UpdateBinary. 6 bytes are for CLA, INS, P1, P2,
540 * Lc */
541#define RW_T4T_MAX_DATA_PER_WRITE                              \
542  (NFC_RW_POOL_BUF_SIZE - NFC_HDR_SIZE - NCI_MSG_OFFSET_SIZE - \
543   NCI_DATA_HDR_SIZE - T4T_CMD_MAX_HDR_SIZE)
544
545/* Mandatory NDEF file control */
546typedef struct {
547  uint16_t file_id;       /* File Identifier          */
548  uint16_t max_file_size; /* Max NDEF file size       */
549  uint8_t read_access;    /* read access condition    */
550  uint8_t write_access;   /* write access condition   */
551} tRW_T4T_NDEF_FC;
552
553/* Capability Container */
554typedef struct {
555  uint16_t cclen;          /* the size of this capability container        */
556  uint8_t version;         /* the mapping specification version            */
557  uint16_t max_le;         /* the max data size by a single ReadBinary     */
558  uint16_t max_lc;         /* the max data size by a single UpdateBinary   */
559  tRW_T4T_NDEF_FC ndef_fc; /* Mandatory NDEF file control                  */
560} tRW_T4T_CC;
561
562typedef uint8_t tRW_T4T_RW_STATE;
563typedef uint8_t tRW_T4T_RW_SUBSTATE;
564
565/* Type 4 Tag Control Block */
566typedef struct {
567  tRW_T4T_RW_STATE state;        /* main state                       */
568  tRW_T4T_RW_SUBSTATE sub_state; /* sub state                        */
569  uint8_t version;               /* currently effective version      */
570  TIMER_LIST_ENT timer;          /* timeout for each API call        */
571
572  uint16_t ndef_length;    /* length of NDEF data              */
573  uint8_t* p_update_data;  /* pointer of data to update        */
574  uint16_t rw_length;      /* remaining bytes to read/write    */
575  uint16_t rw_offset;      /* remaining offset to read/write   */
576  NFC_HDR* p_data_to_free; /* GKI buffet to delete after done  */
577
578  tRW_T4T_CC cc_file; /* Capability Container File        */
579
580/* NDEF has been detected   */
581#define RW_T4T_NDEF_STATUS_NDEF_DETECTED 0x01
582/* NDEF file is read-only   */
583#define RW_T4T_NDEF_STATUS_NDEF_READ_ONLY 0x02
584
585  uint8_t ndef_status; /* bitmap for NDEF status           */
586  uint8_t channel;     /* channel id: used for read-binary */
587
588  uint16_t max_read_size;   /* max reading size per a command   */
589  uint16_t max_update_size; /* max updating size per a command  */
590  uint16_t card_size;
591  uint8_t card_type;
592} tRW_T4T_CB;
593
594/* RW retransmission statistics */
595#if (RW_STATS_INCLUDED == TRUE)
596typedef struct {
597  uint32_t start_tick;     /* System tick count at activation */
598  uint32_t bytes_sent;     /* Total bytes sent since activation */
599  uint32_t bytes_received; /* Total bytes received since activation */
600  uint32_t num_ops;        /* Number of operations since activation */
601  uint32_t num_retries;    /* Number of retranmissions since activation */
602  uint32_t num_crc;        /* Number of crc failures */
603  uint32_t num_trans_err;  /* Number of transmission error notifications */
604  uint32_t num_fail;       /* Number of aborts (failures after retries) */
605} tRW_STATS;
606#endif /* RW_STATS_INCLUDED */
607
608/* ISO 15693 RW Control Block */
609typedef uint8_t tRW_I93_RW_STATE;
610typedef uint8_t tRW_I93_RW_SUBSTATE;
611
612/* tag is read-only                        */
613#define RW_I93_FLAG_READ_ONLY 0x01
614/* tag supports read multi block           */
615#define RW_I93_FLAG_READ_MULTI_BLOCK 0x02
616/* need to reset DSFID for formatting      */
617#define RW_I93_FLAG_RESET_DSFID 0x04
618/* need to reset AFI for formatting        */
619#define RW_I93_FLAG_RESET_AFI 0x08
620/* use 2 bytes for number of blocks        */
621#define RW_I93_FLAG_16BIT_NUM_BLOCK 0x10
622/* use extended commands */
623#define RW_I93_FLAG_EXT_COMMANDS 0x20
624
625/* searching for type                      */
626#define RW_I93_TLV_DETECT_STATE_TYPE 0x01
627/* searching for the first byte of length  */
628#define RW_I93_TLV_DETECT_STATE_LENGTH_1 0x02
629/* searching for the second byte of length */
630#define RW_I93_TLV_DETECT_STATE_LENGTH_2 0x03
631/* searching for the third byte of length  */
632#define RW_I93_TLV_DETECT_STATE_LENGTH_3 0x04
633/* reading value field                     */
634#define RW_I93_TLV_DETECT_STATE_VALUE 0x05
635
636enum {
637  RW_I93_ICODE_SLI,                  /* ICODE SLI, SLIX                  */
638  RW_I93_ICODE_SLI_S,                /* ICODE SLI-S, SLIX-S              */
639  RW_I93_ICODE_SLI_L,                /* ICODE SLI-L, SLIX-L              */
640  RW_I93_TAG_IT_HF_I_PLUS_INLAY,     /* Tag-it HF-I Plus Inlay           */
641  RW_I93_TAG_IT_HF_I_PLUS_CHIP,      /* Tag-it HF-I Plus Chip            */
642  RW_I93_TAG_IT_HF_I_STD_CHIP_INLAY, /* Tag-it HF-I Standard Chip/Inlyas */
643  RW_I93_TAG_IT_HF_I_PRO_CHIP_INLAY, /* Tag-it HF-I Pro Chip/Inlyas      */
644  RW_I93_STM_LRI1K,                  /* STM LRI1K                        */
645  RW_I93_STM_LRI2K,                  /* STM LRI2K                        */
646  RW_I93_STM_LRIS2K,                 /* STM LRIS2K                       */
647  RW_I93_STM_LRIS64K,                /* STM LRIS64K                      */
648  RW_I93_STM_M24LR64_R,              /* STM M24LR64-R                    */
649  RW_I93_STM_M24LR04E_R,             /* STM M24LR04E-R                   */
650  RW_I93_STM_M24LR16E_R,             /* STM M24LR16E-R                   */
651  RW_I93_STM_M24LR64E_R,             /* STM M24LR64E-R                   */
652  RW_I93_STM_ST25DV04K,              /* STM ST25DV04K                    */
653  RW_I93_STM_ST25DVHIK,              /* STM ST25DV 16K OR 64K            */
654  RW_I93_UNKNOWN_PRODUCT             /* Unknwon product version          */
655};
656
657typedef struct {
658  tRW_I93_RW_STATE state;        /* main state                       */
659  tRW_I93_RW_SUBSTATE sub_state; /* sub state                        */
660  TIMER_LIST_ENT timer;          /* timeout for each sent command    */
661  uint8_t sent_cmd;              /* last sent command                */
662  uint8_t retry_count;           /* number of retry                  */
663  NFC_HDR* p_retry_cmd;          /* buffer to store cmd sent last    */
664
665  uint8_t info_flags;            /* information flags                */
666  uint8_t uid[I93_UID_BYTE_LEN]; /* UID of currently activated       */
667  uint8_t dsfid;                 /* DSFID if I93_INFO_FLAG_DSFID     */
668  uint8_t afi;                   /* AFI if I93_INFO_FLAG_AFI         */
669  uint8_t block_size;            /* block size of tag, in bytes      */
670  uint16_t num_block;            /* number of blocks in tag          */
671  uint8_t ic_reference;          /* IC Reference of tag              */
672  uint8_t product_version;       /* tag product version              */
673
674  uint8_t intl_flags; /* flags for internal information   */
675
676  uint8_t tlv_detect_state; /* TLV detecting state              */
677  uint8_t tlv_type;         /* currently detected type          */
678  uint16_t tlv_length;      /* currently detected length        */
679
680  uint16_t ndef_tlv_start_offset; /* offset of first byte of NDEF TLV */
681  uint16_t ndef_tlv_last_offset;  /* offset of last byte of NDEF TLV  */
682  uint16_t max_ndef_length;       /* max NDEF length the tag contains */
683  uint16_t ndef_length;           /* length of NDEF data              */
684
685  uint8_t* p_update_data; /* pointer of data to update        */
686  uint16_t rw_length;     /* bytes to read/write              */
687  uint16_t rw_offset;     /* offset to read/write             */
688} tRW_I93_CB;
689
690/* RW memory control blocks */
691typedef union {
692  tRW_T1T_CB t1t;
693  tRW_T2T_CB t2t;
694  tRW_T3T_CB t3t;
695  tRW_T4T_CB t4t;
696  tRW_I93_CB i93;
697} tRW_TCB;
698
699/* RW control blocks */
700typedef struct {
701  tRW_TCB tcb;
702  tRW_CBACK* p_cback;
703  uint32_t cur_retry; /* Retry count for the current operation */
704#if (RW_STATS_INCLUDED == TRUE)
705  tRW_STATS stats;
706#endif /* RW_STATS_INCLUDED */
707} tRW_CB;
708
709/*****************************************************************************
710**  EXTERNAL FUNCTION DECLARATIONS
711*****************************************************************************/
712
713/* Global NFC data */
714extern tRW_CB rw_cb;
715
716/* from .c */
717
718#if (RW_NDEF_INCLUDED == TRUE)
719extern tRW_EVENT rw_t1t_handle_rsp(const tT1T_CMD_RSP_INFO* p_info,
720                                   bool* p_notify, uint8_t* p_data,
721                                   tNFC_STATUS* p_status);
722extern tRW_EVENT rw_t1t_info_to_event(const tT1T_CMD_RSP_INFO* p_info);
723#else
724#define rw_t1t_handle_rsp(p, a, b, c) t1t_info_to_evt(p)
725#define rw_t1t_info_to_event(p) t1t_info_to_evt(p)
726#endif
727
728extern void rw_init(void);
729extern tNFC_STATUS rw_t1t_select(uint8_t hr[T1T_HR_LEN],
730                                 uint8_t uid[T1T_CMD_UID_LEN]);
731extern tNFC_STATUS rw_t1t_send_dyn_cmd(uint8_t opcode, uint8_t add,
732                                       uint8_t* p_dat);
733extern tNFC_STATUS rw_t1t_send_static_cmd(uint8_t opcode, uint8_t add,
734                                          uint8_t dat);
735extern void rw_t1t_process_timeout(TIMER_LIST_ENT* p_tle);
736extern void rw_t1t_handle_op_complete(void);
737
738#if (RW_NDEF_INCLUDED == TRUE)
739extern tRW_EVENT rw_t2t_info_to_event(const tT2T_CMD_RSP_INFO* p_info);
740extern void rw_t2t_handle_rsp(uint8_t* p_data);
741#else
742#define rw_t2t_info_to_event(p) t2t_info_to_evt(p)
743#define rw_t2t_handle_rsp(p)
744#endif
745
746extern tNFC_STATUS rw_t2t_sector_change(uint8_t sector);
747extern tNFC_STATUS rw_t2t_read(uint16_t block);
748extern tNFC_STATUS rw_t2t_write(uint16_t block, uint8_t* p_write_data);
749extern void rw_t2t_process_timeout();
750extern tNFC_STATUS rw_t2t_select(void);
751void rw_t2t_handle_op_complete(void);
752
753extern void rw_t3t_process_timeout(TIMER_LIST_ENT* p_tle);
754extern tNFC_STATUS rw_t3t_select(uint8_t peer_nfcid2[NCI_RF_F_UID_LEN],
755                                 uint8_t mrti_check, uint8_t mrti_update);
756void rw_t3t_handle_nci_poll_ntf(uint8_t nci_status, uint8_t num_responses,
757                                uint8_t sensf_res_buf_size,
758                                uint8_t* p_sensf_res_buf);
759
760extern tNFC_STATUS rw_t4t_select(void);
761extern void rw_t4t_process_timeout(TIMER_LIST_ENT* p_tle);
762
763extern tNFC_STATUS rw_i93_select(uint8_t* p_uid);
764extern void rw_i93_process_timeout(TIMER_LIST_ENT* p_tle);
765extern void rw_t4t_handle_isodep_nak_rsp(uint8_t status, bool is_ntf);
766#if (RW_STATS_INCLUDED == TRUE)
767/* Internal fcns for statistics (from rw_main.c) */
768void rw_main_reset_stats(void);
769void rw_main_update_tx_stats(uint32_t bytes_tx, bool is_retry);
770void rw_main_update_rx_stats(uint32_t bytes_rx);
771void rw_main_update_crc_error_stats(void);
772void rw_main_update_trans_error_stats(void);
773void rw_main_update_fail_stats(void);
774void rw_main_log_stats(void);
775#endif /* RW_STATS_INCLUDED */
776
777#endif /* RW_INT_H_ */
778