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