rw_t1t_ndef.c revision e9629bad30a9f478b336ab46b8e6e02f7f87af46
15f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer/******************************************************************************
25f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer *
35f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer *  Copyright (C) 2010-2014 Broadcom Corporation
45f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer *
50bc735ffcfb223c0186419547abaa5c84482663eChris Lattner *  Licensed under the Apache License, Version 2.0 (the "License");
60bc735ffcfb223c0186419547abaa5c84482663eChris Lattner *  you may not use this file except in compliance with the License.
75f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer *  You may obtain a copy of the License at:
85f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer *
95f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer *  http://www.apache.org/licenses/LICENSE-2.0
105f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer *
115f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer *  Unless required by applicable law or agreed to in writing, software
125f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer *  distributed under the License is distributed on an "AS IS" BASIS,
135f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
145f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer *  See the License for the specific language governing permissions and
155f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer *  limitations under the License.
165f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer *
177573098b83e780d1c5bea13b384b610d8f155676Steve Naroff ******************************************************************************/
18a95d3750441ac8ad03e36af8e6e74039c9a3109dTed Kremenek
195f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
20d249e1d1f1498b81314459ceda19d6ff25c278adDouglas Gregor/******************************************************************************
219caf8b1ca6beb254f420dada3c0e94d5ef027f58Ted Kremenek *
228ffb159441e923322bef6b5dee1aaf24c738d75eTed Kremenek *  This file contains the implementation for Type 1 tag NDEF operation in
235f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer *  Reader/Writer mode.
248189cde56b4f6f938cd65f53c932fe1860d0204cTed Kremenek *
256e340496341a4704be0ede9c1ff4f8eacea7ee2cChris Lattner ******************************************************************************/
267573098b83e780d1c5bea13b384b610d8f155676Steve Naroff#include <string.h>
277573098b83e780d1c5bea13b384b610d8f155676Steve Naroff#include "nfc_target.h"
2841ef0c3472a3d09c29bc1792f3d26842f2b8a695Douglas Gregor
2941ef0c3472a3d09c29bc1792f3d26842f2b8a695Douglas Gregor#if (NFC_INCLUDED == TRUE)
3041ef0c3472a3d09c29bc1792f3d26842f2b8a695Douglas Gregor#include "nfc_api.h"
3141ef0c3472a3d09c29bc1792f3d26842f2b8a695Douglas Gregor#include "nci_hmsgs.h"
325f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer#include "rw_api.h"
33e2563ca02a519c2ad6d64dfed87d6e86c5d3c072Sam Bishop#include "rw_int.h"
345f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer#include "nfc_int.h"
355f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer#include "gki.h"
367ba138abd329e591a8f6d5001f60dd7082f71b3bSteve Naroff
374b07b2968f87f3cd5a3d8c76145f1cbfd718d42dSebastian Redl#if (defined (RW_NDEF_INCLUDED) && (RW_NDEF_INCLUDED == TRUE))
385f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
390c727a35718556866a978f64ac549d9798735f08Chris Lattner/* Local Functions */
406a0ef4b83c91a6d6d5acb4ed5577c4659fe022a3Anders Carlssonstatic tNFC_STATUS rw_t1t_handle_rall_rsp (BOOLEAN *p_notify,UINT8 *p_data);
416c36be5b383875b490684bcf439d6d427298c1afChris Lattnerstatic tNFC_STATUS rw_t1t_handle_dyn_read_rsp (BOOLEAN *p_notify, UINT8 *p_data);
421eb4433ac451dc16f4133a88af2d002ac26c58efMike Stumpstatic tNFC_STATUS rw_t1t_handle_write_rsp (BOOLEAN *p_notify, UINT8 *p_data);
43ce2fc3a343ea6098a96d587071cee7299f11957aTed Kremenekstatic tNFC_STATUS rw_t1t_handle_read_rsp (BOOLEAN *p_callback, UINT8 *p_data);
44ce2fc3a343ea6098a96d587071cee7299f11957aTed Kremenekstatic tNFC_STATUS rw_t1t_handle_tlv_detect_rsp (UINT8 *p_data);
45ce2fc3a343ea6098a96d587071cee7299f11957aTed Kremenekstatic tNFC_STATUS rw_t1t_handle_ndef_read_rsp (UINT8 *p_data);
46ce2fc3a343ea6098a96d587071cee7299f11957aTed Kremenekstatic tNFC_STATUS rw_t1t_handle_ndef_write_rsp (UINT8 *p_data);
47ce2fc3a343ea6098a96d587071cee7299f11957aTed Kremenekstatic tNFC_STATUS rw_t1t_handle_ndef_rall_rsp (void);
481eb4433ac451dc16f4133a88af2d002ac26c58efMike Stumpstatic tNFC_STATUS rw_t1t_ndef_write_first_block (void);
49ce2fc3a343ea6098a96d587071cee7299f11957aTed Kremenekstatic tNFC_STATUS rw_t1t_next_ndef_write_block (void);
50ce2fc3a343ea6098a96d587071cee7299f11957aTed Kremenekstatic tNFC_STATUS rw_t1t_send_ndef_byte (UINT8 data, UINT8 block, UINT8 index, UINT8 msg_len);
511eb4433ac451dc16f4133a88af2d002ac26c58efMike Stumpstatic tNFC_STATUS rw_t1t_send_ndef_block (UINT8 *p_data, UINT8 block);
52ce2fc3a343ea6098a96d587071cee7299f11957aTed Kremenekstatic UINT8 rw_t1t_prepare_ndef_bytes (UINT8 *p_data, UINT8 *p_length_field, UINT8 *p_index, BOOLEAN b_one_byte, UINT8 block, UINT8 lengthfield_len);
53ce2fc3a343ea6098a96d587071cee7299f11957aTed Kremenekstatic UINT8 rw_t1t_get_ndef_flags (void);
54ce2fc3a343ea6098a96d587071cee7299f11957aTed Kremenekstatic UINT16 rw_t1t_get_ndef_max_size (void);
55ce2fc3a343ea6098a96d587071cee7299f11957aTed Kremenekstatic BOOLEAN rw_t1t_is_lock_reserved_otp_byte (UINT16 index);
561eb4433ac451dc16f4133a88af2d002ac26c58efMike Stumpstatic BOOLEAN rw_t1t_is_read_only_byte (UINT16 index);
57ce2fc3a343ea6098a96d587071cee7299f11957aTed Kremenekstatic UINT8 rw_t1t_get_lock_bits_for_segment (UINT8 segment,UINT8 *p_start_byte, UINT8 *p_start_bit,UINT8 *p_end_byte);
58ce2fc3a343ea6098a96d587071cee7299f11957aTed Kremenekstatic void rw_t1t_update_attributes (void);
59ce2fc3a343ea6098a96d587071cee7299f11957aTed Kremenekstatic void rw_t1t_update_lock_attributes (void);
60ce2fc3a343ea6098a96d587071cee7299f11957aTed Kremenekstatic void rw_t1t_extract_lock_bytes (UINT8 *p_data);
61ce2fc3a343ea6098a96d587071cee7299f11957aTed Kremenekstatic void rw_t1t_update_tag_state (void);
62ce2fc3a343ea6098a96d587071cee7299f11957aTed Kremenek
63ce2fc3a343ea6098a96d587071cee7299f11957aTed Kremenekconst UINT8 rw_t1t_mask_bits[8] =
64ce2fc3a343ea6098a96d587071cee7299f11957aTed Kremenek{0x01,0x02,0x04,0x08,0x10,0x20,0x40,0x80};
65ce2fc3a343ea6098a96d587071cee7299f11957aTed Kremenek
66ce2fc3a343ea6098a96d587071cee7299f11957aTed Kremenek/*******************************************************************************
67ce2fc3a343ea6098a96d587071cee7299f11957aTed Kremenek**
68ce2fc3a343ea6098a96d587071cee7299f11957aTed Kremenek** Function         rw_t1t_handle_rsp
69ce2fc3a343ea6098a96d587071cee7299f11957aTed Kremenek**
701eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump** Description      This function handles the response received for all commands
71ce2fc3a343ea6098a96d587071cee7299f11957aTed Kremenek**                  sent to tag
721705fe9ec0efb65f77a46e669e48302923204fe8Benjamin Kramer**
73ce2fc3a343ea6098a96d587071cee7299f11957aTed Kremenek** Returns          event to be sent to application
741705fe9ec0efb65f77a46e669e48302923204fe8Benjamin Kramer**
751eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump*******************************************************************************/
76ce2fc3a343ea6098a96d587071cee7299f11957aTed KremenektRW_EVENT rw_t1t_handle_rsp (const tT1T_CMD_RSP_INFO * p_info, BOOLEAN *p_notify, UINT8 *p_data, tNFC_STATUS *p_status)
771705fe9ec0efb65f77a46e669e48302923204fe8Benjamin Kramer{
781705fe9ec0efb65f77a46e669e48302923204fe8Benjamin Kramer    tRW_EVENT   rw_event;
79ce2fc3a343ea6098a96d587071cee7299f11957aTed Kremenek    tRW_T1T_CB  *p_t1t  = &rw_cb.tcb.t1t;
80ce2fc3a343ea6098a96d587071cee7299f11957aTed Kremenek    UINT8       adds;
81ce2fc3a343ea6098a96d587071cee7299f11957aTed Kremenek
82ce2fc3a343ea6098a96d587071cee7299f11957aTed Kremenek    if(  (p_t1t->state == RW_T1T_STATE_READ)
83ce2fc3a343ea6098a96d587071cee7299f11957aTed Kremenek       ||(p_t1t->state == RW_T1T_STATE_WRITE)  )
84ce2fc3a343ea6098a96d587071cee7299f11957aTed Kremenek    {
85ce2fc3a343ea6098a96d587071cee7299f11957aTed Kremenek        return t1t_info_to_evt (p_info);
86ce2fc3a343ea6098a96d587071cee7299f11957aTed Kremenek    }
871eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
881eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump    rw_event = rw_t1t_info_to_event (p_info);
89ce2fc3a343ea6098a96d587071cee7299f11957aTed Kremenek
90ce2fc3a343ea6098a96d587071cee7299f11957aTed Kremenek    if (p_info->opcode == T1T_CMD_RALL)
91ce2fc3a343ea6098a96d587071cee7299f11957aTed Kremenek    {
921eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump        *p_status = rw_t1t_handle_rall_rsp (p_notify,p_data);
935f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    }
945f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    else if (p_info->opcode == T1T_CMD_RSEG)
955f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    {
965f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer        adds = *p_data;
975f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer        if (adds == 0)
98f2cad8633e46cce12fc3d77c0bd451ffd7264bafDouglas Gregor        {
99f2cad8633e46cce12fc3d77c0bd451ffd7264bafDouglas Gregor            p_t1t->b_rseg   = TRUE;
1007381d5cfbd599fa2b9e215011ad7cbd449de231aSean Hunt            rw_t1t_update_tag_state ();
1019a55591af3e5506b95a9718e15380129fbfc5ebcSean Hunt            rw_t1t_update_attributes ();
1027381d5cfbd599fa2b9e215011ad7cbd449de231aSean Hunt            rw_t1t_update_lock_attributes ();
1039a55591af3e5506b95a9718e15380129fbfc5ebcSean Hunt            memcpy (p_t1t->mem, (UINT8 *) (p_data + T1T_ADD_LEN), T1T_SEGMENT_SIZE);
1047381d5cfbd599fa2b9e215011ad7cbd449de231aSean Hunt        }
1054bfe1968410ea8ffe3b4f629addd7c4bcf484765Sean Hunt        *p_status = rw_t1t_handle_dyn_read_rsp (p_notify,p_data);
1068e6285af719adc6f86d6faa235d22a08eb68ee3aJohn McCall    }
1071eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump    else if (p_info->opcode == T1T_CMD_READ8)
1088189cde56b4f6f938cd65f53c932fe1860d0204cTed Kremenek    {
1098189cde56b4f6f938cd65f53c932fe1860d0204cTed Kremenek        *p_status = rw_t1t_handle_dyn_read_rsp (p_notify,p_data);
1108189cde56b4f6f938cd65f53c932fe1860d0204cTed Kremenek    }
1118189cde56b4f6f938cd65f53c932fe1860d0204cTed Kremenek    else
1128189cde56b4f6f938cd65f53c932fe1860d0204cTed Kremenek    {
1138189cde56b4f6f938cd65f53c932fe1860d0204cTed Kremenek        *p_status = rw_t1t_handle_write_rsp (p_notify,p_data);
1148189cde56b4f6f938cd65f53c932fe1860d0204cTed Kremenek    }
1158189cde56b4f6f938cd65f53c932fe1860d0204cTed Kremenek    return rw_event;
1168189cde56b4f6f938cd65f53c932fe1860d0204cTed Kremenek}
1171eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
1188e6285af719adc6f86d6faa235d22a08eb68ee3aJohn McCall/*******************************************************************************
1198e6285af719adc6f86d6faa235d22a08eb68ee3aJohn McCall**
1208e6285af719adc6f86d6faa235d22a08eb68ee3aJohn McCall** Function         rw_t1t_info_to_event
1218e6285af719adc6f86d6faa235d22a08eb68ee3aJohn McCall**
1228e6285af719adc6f86d6faa235d22a08eb68ee3aJohn McCall** Description      This function returns RW event code based on the current state
1238e6285af719adc6f86d6faa235d22a08eb68ee3aJohn McCall**
1248e6285af719adc6f86d6faa235d22a08eb68ee3aJohn McCall** Returns          RW event code
1258e6285af719adc6f86d6faa235d22a08eb68ee3aJohn McCall**
1268e6285af719adc6f86d6faa235d22a08eb68ee3aJohn McCall*******************************************************************************/
1278e6285af719adc6f86d6faa235d22a08eb68ee3aJohn McCalltRW_EVENT rw_t1t_info_to_event (const tT1T_CMD_RSP_INFO * p_info)
1288e6285af719adc6f86d6faa235d22a08eb68ee3aJohn McCall{
1298e6285af719adc6f86d6faa235d22a08eb68ee3aJohn McCall    tRW_EVENT   rw_event;
1308e6285af719adc6f86d6faa235d22a08eb68ee3aJohn McCall    tRW_T1T_CB  *p_t1t  = &rw_cb.tcb.t1t;
1318e6285af719adc6f86d6faa235d22a08eb68ee3aJohn McCall
1328e6285af719adc6f86d6faa235d22a08eb68ee3aJohn McCall    switch (p_t1t->state)
1338e6285af719adc6f86d6faa235d22a08eb68ee3aJohn McCall    {
1348e6285af719adc6f86d6faa235d22a08eb68ee3aJohn McCall    case RW_T1T_STATE_TLV_DETECT:
1358e6285af719adc6f86d6faa235d22a08eb68ee3aJohn McCall        if (p_t1t->tlv_detect == TAG_NDEF_TLV)
1368e6285af719adc6f86d6faa235d22a08eb68ee3aJohn McCall            rw_event = RW_T1T_NDEF_DETECT_EVT;
1378e6285af719adc6f86d6faa235d22a08eb68ee3aJohn McCall        else
1388e6285af719adc6f86d6faa235d22a08eb68ee3aJohn McCall            rw_event = RW_T1T_TLV_DETECT_EVT;
1398e6285af719adc6f86d6faa235d22a08eb68ee3aJohn McCall        break;
1408e6285af719adc6f86d6faa235d22a08eb68ee3aJohn McCall
1418e6285af719adc6f86d6faa235d22a08eb68ee3aJohn McCall    case RW_T1T_STATE_READ_NDEF:
1428e6285af719adc6f86d6faa235d22a08eb68ee3aJohn McCall        rw_event = RW_T1T_NDEF_READ_EVT;
1438e6285af719adc6f86d6faa235d22a08eb68ee3aJohn McCall        break;
1448e6285af719adc6f86d6faa235d22a08eb68ee3aJohn McCall
1458e6285af719adc6f86d6faa235d22a08eb68ee3aJohn McCall    case RW_T1T_STATE_WRITE_NDEF:
146d0937224f383c7cc72c947119380f9713a070c73Douglas Gregor        rw_event = RW_T1T_NDEF_WRITE_EVT;
1478e6285af719adc6f86d6faa235d22a08eb68ee3aJohn McCall        break;
1488e6285af719adc6f86d6faa235d22a08eb68ee3aJohn McCall
1498e6285af719adc6f86d6faa235d22a08eb68ee3aJohn McCall    case RW_T1T_STATE_SET_TAG_RO:
150f89e55ab1bfb3ea997f8b02997c611a02254eb2dJohn McCall        rw_event = RW_T1T_SET_TAG_RO_EVT;
1518e6285af719adc6f86d6faa235d22a08eb68ee3aJohn McCall        break;
1528e6285af719adc6f86d6faa235d22a08eb68ee3aJohn McCall
153d0937224f383c7cc72c947119380f9713a070c73Douglas Gregor    case RW_T1T_STATE_CHECK_PRESENCE:
1548e6285af719adc6f86d6faa235d22a08eb68ee3aJohn McCall        rw_event = RW_T1T_PRESENCE_CHECK_EVT;
155d0937224f383c7cc72c947119380f9713a070c73Douglas Gregor        break;
1568e6285af719adc6f86d6faa235d22a08eb68ee3aJohn McCall
1578e6285af719adc6f86d6faa235d22a08eb68ee3aJohn McCall    case RW_T1T_STATE_FORMAT_TAG:
1588e6285af719adc6f86d6faa235d22a08eb68ee3aJohn McCall        rw_event = RW_T1T_FORMAT_CPLT_EVT;
1598e6285af719adc6f86d6faa235d22a08eb68ee3aJohn McCall        break;
1608e6285af719adc6f86d6faa235d22a08eb68ee3aJohn McCall
1612bb5d00fcf71a7b4d478d478be778fff0494aff6John McCall    default:
1622bb5d00fcf71a7b4d478d478be778fff0494aff6John McCall	    rw_event = t1t_info_to_evt (p_info);
1638e6285af719adc6f86d6faa235d22a08eb68ee3aJohn McCall        break;
1648e6285af719adc6f86d6faa235d22a08eb68ee3aJohn McCall    }
1658e6285af719adc6f86d6faa235d22a08eb68ee3aJohn McCall    return rw_event;
1668e6285af719adc6f86d6faa235d22a08eb68ee3aJohn McCall}
1678e6285af719adc6f86d6faa235d22a08eb68ee3aJohn McCall
1688e6285af719adc6f86d6faa235d22a08eb68ee3aJohn McCall/*******************************************************************************
1698e6285af719adc6f86d6faa235d22a08eb68ee3aJohn McCall**
1708e6285af719adc6f86d6faa235d22a08eb68ee3aJohn McCall** Function         rw_t1t_extract_lock_bytes
1718e6285af719adc6f86d6faa235d22a08eb68ee3aJohn McCall**
1728e6285af719adc6f86d6faa235d22a08eb68ee3aJohn McCall** Description      This function will extract lock bytes if any present in the
173d0937224f383c7cc72c947119380f9713a070c73Douglas Gregor**                  response data
174d0937224f383c7cc72c947119380f9713a070c73Douglas Gregor**
1758189cde56b4f6f938cd65f53c932fe1860d0204cTed Kremenek** Parameters       p_data: Data bytes in the response of RSEG/READ8/RALL command
1768189cde56b4f6f938cd65f53c932fe1860d0204cTed Kremenek**
1771eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump** Returns          None
1788189cde56b4f6f938cd65f53c932fe1860d0204cTed Kremenek**
179f4e689b8528770001f4792f1f4ebdfb09d859e3dDouglas Gregor*******************************************************************************/
1808189cde56b4f6f938cd65f53c932fe1860d0204cTed Kremenekvoid rw_t1t_extract_lock_bytes (UINT8 *p_data)
1818189cde56b4f6f938cd65f53c932fe1860d0204cTed Kremenek{
1821eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump    UINT16              end;
1838189cde56b4f6f938cd65f53c932fe1860d0204cTed Kremenek    UINT16              start;
184f4e689b8528770001f4792f1f4ebdfb09d859e3dDouglas Gregor    UINT8               num_locks;
1858189cde56b4f6f938cd65f53c932fe1860d0204cTed Kremenek    UINT16              lock_offset = 0;
1868189cde56b4f6f938cd65f53c932fe1860d0204cTed Kremenek    UINT16              offset;
1871eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump    tRW_T1T_CB          *p_t1t          = &rw_cb.tcb.t1t;
1888189cde56b4f6f938cd65f53c932fe1860d0204cTed Kremenek    tT1T_CMD_RSP_INFO   *p_cmd_rsp_info = (tT1T_CMD_RSP_INFO *) rw_cb.tcb.t1t.p_cmd_rsp_info;
1898189cde56b4f6f938cd65f53c932fe1860d0204cTed Kremenek
1908189cde56b4f6f938cd65f53c932fe1860d0204cTed Kremenek    num_locks = 0;
191e2dedf8f61b8f306f704781456b482eb61871e8eDouglas Gregor    /* Based on the Command used to read Tag, calculate the offset of the tag read */
192fb523e16dd1f860ff02a3ae03e5e3e25327a5860Chris Lattner    if (p_cmd_rsp_info->opcode == T1T_CMD_RSEG)
193fb523e16dd1f860ff02a3ae03e5e3e25327a5860Chris Lattner    {
194e2dedf8f61b8f306f704781456b482eb61871e8eDouglas Gregor        start = p_t1t->segment * T1T_SEGMENT_SIZE;
195fb523e16dd1f860ff02a3ae03e5e3e25327a5860Chris Lattner        end   = start + T1T_SEGMENT_SIZE;
196e2dedf8f61b8f306f704781456b482eb61871e8eDouglas Gregor    }
197025452fa0eda63e150cfaeebe64f0a19c96b3a06Douglas Gregor    else if (p_cmd_rsp_info->opcode == T1T_CMD_READ8)
198025452fa0eda63e150cfaeebe64f0a19c96b3a06Douglas Gregor    {
199025452fa0eda63e150cfaeebe64f0a19c96b3a06Douglas Gregor        start = p_t1t->block_read * T1T_BLOCK_SIZE;
200025452fa0eda63e150cfaeebe64f0a19c96b3a06Douglas Gregor        end   = start + T1T_BLOCK_SIZE;
201025452fa0eda63e150cfaeebe64f0a19c96b3a06Douglas Gregor    }
202025452fa0eda63e150cfaeebe64f0a19c96b3a06Douglas Gregor    else if (p_cmd_rsp_info->opcode == T1T_CMD_RALL)
2039c1863ef36a74e8203f00289d19856ad956f48b9Ted Kremenek    {
204025452fa0eda63e150cfaeebe64f0a19c96b3a06Douglas Gregor        start = 0;
2058e6285af719adc6f86d6faa235d22a08eb68ee3aJohn McCall        end   = T1T_STATIC_SIZE;
2068e6285af719adc6f86d6faa235d22a08eb68ee3aJohn McCall    }
207025452fa0eda63e150cfaeebe64f0a19c96b3a06Douglas Gregor    else
208025452fa0eda63e150cfaeebe64f0a19c96b3a06Douglas Gregor        return;
209025452fa0eda63e150cfaeebe64f0a19c96b3a06Douglas Gregor
2105f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    /* Collect lock bytes that are present in the part of the data read from Tag */
2118e6285af719adc6f86d6faa235d22a08eb68ee3aJohn McCall    while (num_locks < p_t1t->num_lockbytes)
2128e6285af719adc6f86d6faa235d22a08eb68ee3aJohn McCall    {
2135f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer        if (p_t1t->lockbyte[num_locks].b_lock_read == FALSE)
2145f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer        {
2155f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer            /* Get the exact offset of the dynamic lock byte in the tag */
2161eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump            offset = p_t1t->lock_tlv[p_t1t->lockbyte[num_locks].tlv_index].offset + p_t1t->lockbyte[num_locks].byte_index;
217c302113179a1c2b1254224ea9b6f5316ceeb375cSean Hunt            if (  (offset <  end)
2188e6285af719adc6f86d6faa235d22a08eb68ee3aJohn McCall                &&(offset >= start)  )
219b2f81cf7f8445e0c65c0428f4fbb0442566916b8Douglas Gregor
2205f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer            {
2211eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump                /* This dynamic lock byte is in the response */
222b5a69586f1b8855ee4c1f0bb7a8f0ff4fe32ce09Steve Naroff                if (p_cmd_rsp_info->opcode == T1T_CMD_RSEG)
223b5a69586f1b8855ee4c1f0bb7a8f0ff4fe32ce09Steve Naroff                {
224b5a69586f1b8855ee4c1f0bb7a8f0ff4fe32ce09Steve Naroff                    lock_offset = (offset % T1T_SEGMENT_SIZE);
225b5a69586f1b8855ee4c1f0bb7a8f0ff4fe32ce09Steve Naroff                }
226311ff02fae0392bee6abe7723cdf5a69b2899a47Chris Lattner                else if (p_cmd_rsp_info->opcode == T1T_CMD_READ8)
227311ff02fae0392bee6abe7723cdf5a69b2899a47Chris Lattner                {
2285f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer                    lock_offset = (offset % T1T_BLOCK_SIZE);
2295f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer                }
2305f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer                else if (p_cmd_rsp_info->opcode == T1T_CMD_RALL)
2312024f4d4b0d57616f79ea742fa782d633d414462Kovarththanan Rajaratnam                {
2325f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer                    lock_offset = offset;
2336000dace22f110d8768476989313e9d981d690d0Chris Lattner                }
2346000dace22f110d8768476989313e9d981d690d0Chris Lattner
2356000dace22f110d8768476989313e9d981d690d0Chris Lattner                p_t1t->lockbyte[num_locks].lock_byte    = p_data[lock_offset];
2366000dace22f110d8768476989313e9d981d690d0Chris Lattner                p_t1t->lockbyte[num_locks].b_lock_read  = TRUE;
2375f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer            }
238e300c870f08d08badf2ebcb53ded49f304af37fcChris Lattner            else
2399668033ee4c25efd019e6c7e6dd96aa2e6364a46Argyrios Kyrtzidis                break;
2406000dace22f110d8768476989313e9d981d690d0Chris Lattner        }
2416000dace22f110d8768476989313e9d981d690d0Chris Lattner        num_locks++;
2426000dace22f110d8768476989313e9d981d690d0Chris Lattner    }
243e300c870f08d08badf2ebcb53ded49f304af37fcChris Lattner}
2446000dace22f110d8768476989313e9d981d690d0Chris Lattner
2456000dace22f110d8768476989313e9d981d690d0Chris Lattner/*******************************************************************************
2466000dace22f110d8768476989313e9d981d690d0Chris Lattner**
24748d14a222276fad5279e994d1a062f36ae6fcbceEli Friedman** Function         rw_t1t_update_tag_attributes
2481eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump**
249e4f2142d00fa5fdb580c4e2413da91882d955381Chris Lattner** Description      This function will update tag attributes based on cc, ndef
25048d14a222276fad5279e994d1a062f36ae6fcbceEli Friedman**                  message length
25148d14a222276fad5279e994d1a062f36ae6fcbceEli Friedman**
25248d14a222276fad5279e994d1a062f36ae6fcbceEli Friedman** Returns          None
253e4f2142d00fa5fdb580c4e2413da91882d955381Chris Lattner**
2541eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump*******************************************************************************/
255e4f2142d00fa5fdb580c4e2413da91882d955381Chris Lattnervoid rw_t1t_update_tag_state (void)
256d249e1d1f1498b81314459ceda19d6ff25c278adDouglas Gregor{
2571eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump    tRW_T1T_CB  *p_t1t          = &rw_cb.tcb.t1t;
258d2a4a1af1088fca80e2dc76eb3369db0fbbfdefdTed Kremenek
259d2a4a1af1088fca80e2dc76eb3369db0fbbfdefdTed Kremenek    /* Set Tag state based on CC value and NDEF Message length */
260d2a4a1af1088fca80e2dc76eb3369db0fbbfdefdTed Kremenek    if (  ((p_t1t->mem[T1T_CC_NMN_BYTE] == T1T_CC_NMN) || (p_t1t->mem[T1T_CC_NMN_BYTE] == 0))
2611eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump        &&((p_t1t->mem[T1T_CC_VNO_BYTE] == T1T_CC_VNO) || (p_t1t->mem[T1T_CC_VNO_BYTE] == T1T_CC_LEGACY_VNO))
2625f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer        &&((p_t1t->mem[T1T_CC_RWA_BYTE] == T1T_CC_RWA_RW) || (p_t1t->mem[T1T_CC_RWA_BYTE] == T1T_CC_RWA_RO))  )
2631eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump    {
2641eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump        /* Valid CC value, so Tag is initialized */
265d48ade633d96b94cb435d73e2c935ea457152decTed Kremenek        if (p_t1t->ndef_msg_len > 0)
266d48ade633d96b94cb435d73e2c935ea457152decTed Kremenek        {
267d48ade633d96b94cb435d73e2c935ea457152decTed Kremenek            if (p_t1t->mem[T1T_CC_RWA_BYTE] == T1T_CC_RWA_RO)
268d48ade633d96b94cb435d73e2c935ea457152decTed Kremenek            {
269d48ade633d96b94cb435d73e2c935ea457152decTed Kremenek                /* NDEF Message presence, CC indication sets Tag as READ ONLY  */
270d48ade633d96b94cb435d73e2c935ea457152decTed Kremenek                p_t1t->tag_attribute = RW_T1_TAG_ATTRB_READ_ONLY;
271d48ade633d96b94cb435d73e2c935ea457152decTed Kremenek            }
27277ed8e4edf6ed78c53fb20ec3210aff2a59c9d87Ted Kremenek            else if (p_t1t->mem[T1T_CC_RWA_BYTE] == T1T_CC_RWA_RW)
27377ed8e4edf6ed78c53fb20ec3210aff2a59c9d87Ted Kremenek            {
27477ed8e4edf6ed78c53fb20ec3210aff2a59c9d87Ted Kremenek                /* NDEF Message presence, CC indication sets Tag as READ WRITE */
2759caf8b1ca6beb254f420dada3c0e94d5ef027f58Ted Kremenek                p_t1t->tag_attribute = RW_T1_TAG_ATTRB_READ_WRITE;
2769caf8b1ca6beb254f420dada3c0e94d5ef027f58Ted Kremenek            }
2771eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump        }
2788297777fbe19c4d39e8a70c55346474868055fa1Ted Kremenek        else
2798297777fbe19c4d39e8a70c55346474868055fa1Ted Kremenek        {
2801eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump            /* If NDEF is not yet detected then Tag remains in Initialized state
28177ed8e4edf6ed78c53fb20ec3210aff2a59c9d87Ted Kremenek            *  after NDEF Detection the Tag state may be updated */
2829caf8b1ca6beb254f420dada3c0e94d5ef027f58Ted Kremenek            p_t1t->tag_attribute = RW_T1_TAG_ATTRB_INITIALIZED;
28377ed8e4edf6ed78c53fb20ec3210aff2a59c9d87Ted Kremenek        }
2841eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump    }
28577ed8e4edf6ed78c53fb20ec3210aff2a59c9d87Ted Kremenek    else
2869caf8b1ca6beb254f420dada3c0e94d5ef027f58Ted Kremenek    {
28777ed8e4edf6ed78c53fb20ec3210aff2a59c9d87Ted Kremenek        p_t1t->tag_attribute = RW_T1_TAG_ATTRB_UNKNOWN;
28841ef0c3472a3d09c29bc1792f3d26842f2b8a695Douglas Gregor    }
28941ef0c3472a3d09c29bc1792f3d26842f2b8a695Douglas Gregor}
29041ef0c3472a3d09c29bc1792f3d26842f2b8a695Douglas Gregor
29141ef0c3472a3d09c29bc1792f3d26842f2b8a695Douglas Gregor/*******************************************************************************
29241ef0c3472a3d09c29bc1792f3d26842f2b8a695Douglas Gregor**
29341ef0c3472a3d09c29bc1792f3d26842f2b8a695Douglas Gregor** Function         rw_t1t_read_locks
29441ef0c3472a3d09c29bc1792f3d26842f2b8a695Douglas Gregor**
29541ef0c3472a3d09c29bc1792f3d26842f2b8a695Douglas Gregor** Description      This function will send command to read next unread locks
29641ef0c3472a3d09c29bc1792f3d26842f2b8a695Douglas Gregor**
29741ef0c3472a3d09c29bc1792f3d26842f2b8a695Douglas Gregor** Returns          NFC_STATUS_OK, if all locks are read successfully
2981eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump**                  NFC_STATUS_FAILED, if reading locks failed
29941ef0c3472a3d09c29bc1792f3d26842f2b8a695Douglas Gregor**                  NFC_STATUS_CONTINUE, if reading locks is in progress
30041ef0c3472a3d09c29bc1792f3d26842f2b8a695Douglas Gregor**
30141ef0c3472a3d09c29bc1792f3d26842f2b8a695Douglas Gregor*******************************************************************************/
30241ef0c3472a3d09c29bc1792f3d26842f2b8a695Douglas GregortNFC_STATUS rw_t1t_read_locks (void)
3035f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer{
3045f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    UINT8       num_locks   = 0;
3055f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    tRW_T1T_CB  *p_t1t      = &rw_cb.tcb.t1t;
3065f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    tNFC_STATUS status      = NFC_STATUS_CONTINUE;
3071eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump    UINT16      offset;
3085f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
3095f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    while (num_locks < p_t1t->num_lockbytes)
3105f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    {
3119653db7bd0e3665b955a0445859285f2e1e7dacdDouglas Gregor        if (p_t1t->lockbyte[num_locks].b_lock_read == FALSE)
31281c018d9482e7cc2addadc6202dcf162a01faefdChris Lattner        {
3131eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump            offset = p_t1t->lock_tlv[p_t1t->lockbyte[num_locks].tlv_index].offset + p_t1t->lockbyte[num_locks].byte_index;
3145f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer            if (offset < T1T_STATIC_SIZE)
3151eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump            {
3168ffb159441e923322bef6b5dee1aaf24c738d75eTed Kremenek               p_t1t->lockbyte[num_locks].lock_byte   = p_t1t->mem[offset];
3178ffb159441e923322bef6b5dee1aaf24c738d75eTed Kremenek               p_t1t->lockbyte[num_locks].b_lock_read = TRUE;
3181eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump            }
31984f2170062014d268951902164bed0d8bdea0e82Douglas Gregor            else if (offset < (p_t1t->mem[T1T_CC_TMS_BYTE] + 1) * T1T_BLOCK_SIZE)
32084f2170062014d268951902164bed0d8bdea0e82Douglas Gregor            {
32184f2170062014d268951902164bed0d8bdea0e82Douglas Gregor                /* send READ8 command */
3227e24e82a70a2c681f4291a3397bcd1e1005f251aChris Lattner                p_t1t->block_read = (UINT8) (offset/T1T_BLOCK_SIZE);
323fe95deaf66e4fbd82d44b5f6afa8162fa69cb85cChris Lattner                if ((status = rw_t1t_send_dyn_cmd (T1T_CMD_READ8, p_t1t->block_read, NULL)) == NFC_STATUS_OK)
3247e24e82a70a2c681f4291a3397bcd1e1005f251aChris Lattner                {
325fe95deaf66e4fbd82d44b5f6afa8162fa69cb85cChris Lattner                    /* Reading Locks */
3268ffb159441e923322bef6b5dee1aaf24c738d75eTed Kremenek                    status          = NFC_STATUS_CONTINUE;
3271eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump                    p_t1t->substate = RW_T1T_SUBSTATE_WAIT_READ_LOCKS;
3287e24e82a70a2c681f4291a3397bcd1e1005f251aChris Lattner                }
3291eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump                break;
3301eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump            }
331e66a8cf9117e5fb95a05ff76ec06615e63dd5adeChris Lattner            else
332e66a8cf9117e5fb95a05ff76ec06615e63dd5adeChris Lattner            {
33384f2170062014d268951902164bed0d8bdea0e82Douglas Gregor                /* Read locks failed */
334b5a69586f1b8855ee4c1f0bb7a8f0ff4fe32ce09Steve Naroff                status = NFC_STATUS_FAILED;
33581c018d9482e7cc2addadc6202dcf162a01faefdChris Lattner                break;
33684f2170062014d268951902164bed0d8bdea0e82Douglas Gregor            }
33781c018d9482e7cc2addadc6202dcf162a01faefdChris Lattner        }
33884f2170062014d268951902164bed0d8bdea0e82Douglas Gregor        num_locks++;
33984f2170062014d268951902164bed0d8bdea0e82Douglas Gregor    }
3408ffb159441e923322bef6b5dee1aaf24c738d75eTed Kremenek    if (num_locks == p_t1t->num_lockbytes)
34181c018d9482e7cc2addadc6202dcf162a01faefdChris Lattner    {
34281c018d9482e7cc2addadc6202dcf162a01faefdChris Lattner        /* All locks are read */
3431eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump        status = NFC_STATUS_OK;
3441eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump    }
3451eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
3465f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    return status;
3475f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer}
3481eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
34914f8b4ff660bcaa763974b8d0fae81857c594495Ted Kremenek/*******************************************************************************
3508297777fbe19c4d39e8a70c55346474868055fa1Ted Kremenek**
3518297777fbe19c4d39e8a70c55346474868055fa1Ted Kremenek** Function         rw_t1t_handle_write_rsp
3521eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump**
3530632dd6fe068011af5710c0d6a745724021ff620Chris Lattner** Description      This function handles response received for WRITE_E8,
3540632dd6fe068011af5710c0d6a745724021ff620Chris Lattner**                  WRITE_NE8, WRITE_E, WRITE_NE commands
3551eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump**
3568ffb159441e923322bef6b5dee1aaf24c738d75eTed Kremenek** Returns          status of the current NDEF/TLV Operation
3578ffb159441e923322bef6b5dee1aaf24c738d75eTed Kremenek**
3588ffb159441e923322bef6b5dee1aaf24c738d75eTed Kremenek*******************************************************************************/
3598ffb159441e923322bef6b5dee1aaf24c738d75eTed Kremenekstatic tNFC_STATUS rw_t1t_handle_write_rsp (BOOLEAN *p_notify, UINT8 *p_data)
3605f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer{
3615f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    tRW_T1T_CB  *p_t1t      = &rw_cb.tcb.t1t;
3625f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    tNFC_STATUS status      = NFC_STATUS_OK;
3635f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    UINT8       num_locks;
3645f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    UINT8       lock_count;
3655f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    UINT8       value;
36644aa1f397855f130e88e62ffc1029f7f83bb5d2eArgyrios Kyrtzidis    UINT8       addr;
36744aa1f397855f130e88e62ffc1029f7f83bb5d2eArgyrios Kyrtzidis    UINT8       write_block[T1T_BLOCK_SIZE];
36844aa1f397855f130e88e62ffc1029f7f83bb5d2eArgyrios Kyrtzidis    UINT16      offset;
36944aa1f397855f130e88e62ffc1029f7f83bb5d2eArgyrios Kyrtzidis    UINT16      next_offset;
37044aa1f397855f130e88e62ffc1029f7f83bb5d2eArgyrios Kyrtzidis    UINT8       num_bits;
37144aa1f397855f130e88e62ffc1029f7f83bb5d2eArgyrios Kyrtzidis    UINT8       next_num_bits;
37244aa1f397855f130e88e62ffc1029f7f83bb5d2eArgyrios Kyrtzidis
3735f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    *p_notify = FALSE;
37444aa1f397855f130e88e62ffc1029f7f83bb5d2eArgyrios Kyrtzidis
37544aa1f397855f130e88e62ffc1029f7f83bb5d2eArgyrios Kyrtzidis    switch (p_t1t->state)
3765f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    {
377025452fa0eda63e150cfaeebe64f0a19c96b3a06Douglas Gregor    case RW_T1T_STATE_WRITE:
378025452fa0eda63e150cfaeebe64f0a19c96b3a06Douglas Gregor        *p_notify = TRUE;
379025452fa0eda63e150cfaeebe64f0a19c96b3a06Douglas Gregor        break;
3805f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
381025452fa0eda63e150cfaeebe64f0a19c96b3a06Douglas Gregor    case RW_T1T_STATE_FORMAT_TAG:
382b5a69586f1b8855ee4c1f0bb7a8f0ff4fe32ce09Steve Naroff        if (p_t1t->substate == RW_T1T_SUBSTATE_WAIT_SET_NULL_NDEF)
38344aa1f397855f130e88e62ffc1029f7f83bb5d2eArgyrios Kyrtzidis        {
38444aa1f397855f130e88e62ffc1029f7f83bb5d2eArgyrios Kyrtzidis            if (rw_cb.tcb.t1t.hr[0] != T1T_STATIC_HR0 || rw_cb.tcb.t1t.hr[1] >= RW_T1T_HR1_MIN)
385507f2d5811bd7da1a4d9d2f4960f32177dfab9deSteve Naroff                *p_notify = TRUE;
3861eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump            else
3871eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump            {
3881eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump                if (p_t1t->work_offset < (T1T_BLOCK_SIZE - 1))
3895f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer                {
3905f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer                    p_t1t->work_offset++;
3911eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump                    /* send WRITE-E command */
3928297777fbe19c4d39e8a70c55346474868055fa1Ted Kremenek                    RW_T1T_BLD_ADD ((addr), 1, (UINT8) p_t1t->work_offset);
3938297777fbe19c4d39e8a70c55346474868055fa1Ted Kremenek
3948297777fbe19c4d39e8a70c55346474868055fa1Ted Kremenek                    if ((status = rw_t1t_send_static_cmd (T1T_CMD_WRITE_E, addr, p_t1t->ndef_first_block[(UINT8) p_t1t->work_offset])) != NFC_STATUS_OK)
39544aa1f397855f130e88e62ffc1029f7f83bb5d2eArgyrios Kyrtzidis                        *p_notify = TRUE;
39644aa1f397855f130e88e62ffc1029f7f83bb5d2eArgyrios Kyrtzidis                }
39744aa1f397855f130e88e62ffc1029f7f83bb5d2eArgyrios Kyrtzidis                else
3985f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer                    *p_notify = TRUE;
3995f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer            }
4005f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
4015f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer        }
4025f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer        else
4038189cde56b4f6f938cd65f53c932fe1860d0204cTed Kremenek        {
404b5a69586f1b8855ee4c1f0bb7a8f0ff4fe32ce09Steve Naroff            /* send WRITE-E8 command */
4055f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer            if ((status = rw_t1t_send_dyn_cmd (T1T_CMD_WRITE_E8, 2, p_t1t->ndef_final_block)) != NFC_STATUS_OK)
4068e6285af719adc6f86d6faa235d22a08eb68ee3aJohn McCall                *p_notify = TRUE;
4078e6285af719adc6f86d6faa235d22a08eb68ee3aJohn McCall            else
4088e6285af719adc6f86d6faa235d22a08eb68ee3aJohn McCall                p_t1t->substate = RW_T1T_SUBSTATE_WAIT_SET_NULL_NDEF;
4098e6285af719adc6f86d6faa235d22a08eb68ee3aJohn McCall        }
4108e6285af719adc6f86d6faa235d22a08eb68ee3aJohn McCall        break;
411026dc96ac6ece60da5e1b98e2a71bd0ff0939fd8Chris Lattner
412026dc96ac6ece60da5e1b98e2a71bd0ff0939fd8Chris Lattner    case RW_T1T_STATE_SET_TAG_RO:
413026dc96ac6ece60da5e1b98e2a71bd0ff0939fd8Chris Lattner        switch (p_t1t->substate)
414026dc96ac6ece60da5e1b98e2a71bd0ff0939fd8Chris Lattner        {
4151eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump        case RW_T1T_SUBSTATE_WAIT_SET_CC_RWA_RO:
416026dc96ac6ece60da5e1b98e2a71bd0ff0939fd8Chris Lattner
4178e6285af719adc6f86d6faa235d22a08eb68ee3aJohn McCall            if (!p_t1t->b_hard_lock)
4181eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump            {
419025452fa0eda63e150cfaeebe64f0a19c96b3a06Douglas Gregor                status    = NFC_STATUS_OK;
420025452fa0eda63e150cfaeebe64f0a19c96b3a06Douglas Gregor                *p_notify = TRUE;
421025452fa0eda63e150cfaeebe64f0a19c96b3a06Douglas Gregor                break;
4228e6285af719adc6f86d6faa235d22a08eb68ee3aJohn McCall            }
4238e6285af719adc6f86d6faa235d22a08eb68ee3aJohn McCall
4248e6285af719adc6f86d6faa235d22a08eb68ee3aJohn McCall            if ((p_t1t->hr[0] & 0x0F) != 1)
425025452fa0eda63e150cfaeebe64f0a19c96b3a06Douglas Gregor            {
426025452fa0eda63e150cfaeebe64f0a19c96b3a06Douglas Gregor                memset (write_block,0,T1T_BLOCK_SIZE);
4271eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump                write_block[0] = 0xFF;
4288e6285af719adc6f86d6faa235d22a08eb68ee3aJohn McCall                write_block[1] = 0xFF;
4298e6285af719adc6f86d6faa235d22a08eb68ee3aJohn McCall
430025452fa0eda63e150cfaeebe64f0a19c96b3a06Douglas Gregor                /* send WRITE-NE8 command */
4318189cde56b4f6f938cd65f53c932fe1860d0204cTed Kremenek                if ((status = rw_t1t_send_dyn_cmd (T1T_CMD_WRITE_NE8, T1T_LOCK_BLOCK, write_block)) != NFC_STATUS_OK)
4328189cde56b4f6f938cd65f53c932fe1860d0204cTed Kremenek                    *p_notify       = TRUE;
4338e6285af719adc6f86d6faa235d22a08eb68ee3aJohn McCall                else
4348e6285af719adc6f86d6faa235d22a08eb68ee3aJohn McCall                    p_t1t->substate = RW_T1T_SUBSTATE_WAIT_SET_DYN_LOCK_BITS;
435e946fc833d8592aa2890bfd9839f1ad839b3d284Fariborz Jahanian            }
4368e6285af719adc6f86d6faa235d22a08eb68ee3aJohn McCall            else
4378e6285af719adc6f86d6faa235d22a08eb68ee3aJohn McCall            {
4388e6285af719adc6f86d6faa235d22a08eb68ee3aJohn McCall                /* send WRITE-NE command */
4398e6285af719adc6f86d6faa235d22a08eb68ee3aJohn McCall                RW_T1T_BLD_ADD ((addr), (T1T_LOCK_BLOCK), (0));
4405f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer                if ((status = rw_t1t_send_static_cmd (T1T_CMD_WRITE_NE, addr, 0xFF)) != NFC_STATUS_OK)
4418189cde56b4f6f938cd65f53c932fe1860d0204cTed Kremenek                    *p_notify       = TRUE;
4428189cde56b4f6f938cd65f53c932fe1860d0204cTed Kremenek                else
4438e6285af719adc6f86d6faa235d22a08eb68ee3aJohn McCall                    p_t1t->substate = RW_T1T_SUBSTATE_WAIT_SET_ST_LOCK_BITS;
4448e6285af719adc6f86d6faa235d22a08eb68ee3aJohn McCall            }
4458189cde56b4f6f938cd65f53c932fe1860d0204cTed Kremenek            break;
4468189cde56b4f6f938cd65f53c932fe1860d0204cTed Kremenek
4478189cde56b4f6f938cd65f53c932fe1860d0204cTed Kremenek        case RW_T1T_SUBSTATE_WAIT_SET_ST_LOCK_BITS:
4488189cde56b4f6f938cd65f53c932fe1860d0204cTed Kremenek
4498189cde56b4f6f938cd65f53c932fe1860d0204cTed Kremenek            /* send WRITE-NE command */
4508189cde56b4f6f938cd65f53c932fe1860d0204cTed Kremenek            RW_T1T_BLD_ADD ((addr), (T1T_LOCK_BLOCK), (1));
4518189cde56b4f6f938cd65f53c932fe1860d0204cTed Kremenek            if ((status = rw_t1t_send_static_cmd (T1T_CMD_WRITE_NE, addr, 0xFF)) != NFC_STATUS_OK)
4528189cde56b4f6f938cd65f53c932fe1860d0204cTed Kremenek                *p_notify       = TRUE;
4534ce854736dd196e2304f554ebeac8b43c89cf9e2Ted Kremenek            else
4548189cde56b4f6f938cd65f53c932fe1860d0204cTed Kremenek                p_t1t->substate = RW_T1T_SUBSTATE_WAIT_SET_DYN_LOCK_BITS;
4558189cde56b4f6f938cd65f53c932fe1860d0204cTed Kremenek
4564ce854736dd196e2304f554ebeac8b43c89cf9e2Ted Kremenek            break;
4578189cde56b4f6f938cd65f53c932fe1860d0204cTed Kremenek
4588189cde56b4f6f938cd65f53c932fe1860d0204cTed Kremenek        case RW_T1T_SUBSTATE_WAIT_SET_DYN_LOCK_BITS:
4598189cde56b4f6f938cd65f53c932fe1860d0204cTed Kremenek            num_locks = 0;
4601eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump            while (num_locks < p_t1t->num_lockbytes)
4618189cde56b4f6f938cd65f53c932fe1860d0204cTed Kremenek            {
4628189cde56b4f6f938cd65f53c932fe1860d0204cTed Kremenek                if (p_t1t->lockbyte[num_locks].lock_status == RW_T1T_LOCK_UPDATE_INITIATED)
4638189cde56b4f6f938cd65f53c932fe1860d0204cTed Kremenek                {
4641eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump                    p_t1t->lockbyte[num_locks].lock_status = RW_T1T_LOCK_UPDATED;
4651eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump                }
4661eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump                num_locks++;
467b5a69586f1b8855ee4c1f0bb7a8f0ff4fe32ce09Steve Naroff            }
4681eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
469cc326204dd97771c336b9aab3b9963ea30d69c29Ted Kremenek            num_locks = 0;
470025452fa0eda63e150cfaeebe64f0a19c96b3a06Douglas Gregor            while (num_locks < p_t1t->num_lockbytes)
471cc326204dd97771c336b9aab3b9963ea30d69c29Ted Kremenek            {
472025452fa0eda63e150cfaeebe64f0a19c96b3a06Douglas Gregor                if (p_t1t->lockbyte[num_locks].lock_status == RW_T1T_LOCK_NOT_UPDATED)
4731eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump                {
4741eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump                    offset = p_t1t->lock_tlv[p_t1t->lockbyte[num_locks].tlv_index].offset + p_t1t->lockbyte[num_locks].byte_index;
4751eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump                    num_bits = ((p_t1t->lockbyte[num_locks].byte_index + 1)* 8 <= p_t1t->lock_tlv[p_t1t->lockbyte[num_locks].tlv_index].num_bits) ? 8 : p_t1t->lock_tlv[p_t1t->lockbyte[num_locks].tlv_index].num_bits % 8;
4765f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
4775f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer                    if ((p_t1t->hr[0] & 0x0F) != 1)
4781eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump                    {
4798297777fbe19c4d39e8a70c55346474868055fa1Ted Kremenek                        memset (write_block,0,T1T_BLOCK_SIZE);
4808297777fbe19c4d39e8a70c55346474868055fa1Ted Kremenek
4818297777fbe19c4d39e8a70c55346474868055fa1Ted Kremenek                        write_block[(UINT8) (offset%T1T_BLOCK_SIZE)] |=  tags_pow (2,num_bits) - 1;
4825f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer                        lock_count = num_locks + 1;
4835f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer                        while (lock_count < p_t1t->num_lockbytes)
484c1fcb7762673be706b0a40477d5e93411e918f93Anders Carlsson                        {
485c1fcb7762673be706b0a40477d5e93411e918f93Anders Carlsson                            next_offset = p_t1t->lock_tlv[p_t1t->lockbyte[lock_count].tlv_index].offset + p_t1t->lockbyte[lock_count].byte_index;
486103fc81f12aa635aa0a573c94b1aceb496b4e587Ted Kremenek                            next_num_bits = ((p_t1t->lockbyte[lock_count].byte_index + 1)* 8 <= p_t1t->lock_tlv[p_t1t->lockbyte[lock_count].tlv_index].num_bits) ? 8 : p_t1t->lock_tlv[p_t1t->lockbyte[lock_count].tlv_index].num_bits % 8;
487c1fcb7762673be706b0a40477d5e93411e918f93Anders Carlsson
488c1fcb7762673be706b0a40477d5e93411e918f93Anders Carlsson                            if (next_offset/T1T_BLOCK_SIZE == offset/T1T_BLOCK_SIZE)
489c1fcb7762673be706b0a40477d5e93411e918f93Anders Carlsson                            {
490103fc81f12aa635aa0a573c94b1aceb496b4e587Ted Kremenek                                write_block[(UINT8) (next_offset%T1T_BLOCK_SIZE)] |=  tags_pow (2,next_num_bits) - 1;
491d97bb6c1384cb773ba5cdbd198008dec127cebadTed Kremenek                            }
4921eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump                            else
493c1fcb7762673be706b0a40477d5e93411e918f93Anders Carlsson                                break;
494c1fcb7762673be706b0a40477d5e93411e918f93Anders Carlsson                            lock_count ++;
495c1fcb7762673be706b0a40477d5e93411e918f93Anders Carlsson                        }
496c1fcb7762673be706b0a40477d5e93411e918f93Anders Carlsson
497c1fcb7762673be706b0a40477d5e93411e918f93Anders Carlsson                        /* send WRITE-NE8 command */
498c1fcb7762673be706b0a40477d5e93411e918f93Anders Carlsson                        if ((status = rw_t1t_send_dyn_cmd (T1T_CMD_WRITE_NE8, (UINT8) (offset/T1T_BLOCK_SIZE), write_block)) == NFC_STATUS_OK)
499d97bb6c1384cb773ba5cdbd198008dec127cebadTed Kremenek                        {
500d97bb6c1384cb773ba5cdbd198008dec127cebadTed Kremenek                            p_t1t->substate = RW_T1T_SUBSTATE_WAIT_SET_DYN_LOCK_BITS;
501b5a69586f1b8855ee4c1f0bb7a8f0ff4fe32ce09Steve Naroff                            while (lock_count >  num_locks)
502b5a69586f1b8855ee4c1f0bb7a8f0ff4fe32ce09Steve Naroff                            {
5031eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump                                p_t1t->lockbyte[lock_count - 1].lock_status = RW_T1T_LOCK_UPDATE_INITIATED;
5041eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump                                lock_count --;
5051eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump                            }
506c1fcb7762673be706b0a40477d5e93411e918f93Anders Carlsson                        }
507c1fcb7762673be706b0a40477d5e93411e918f93Anders Carlsson                        else
508c1fcb7762673be706b0a40477d5e93411e918f93Anders Carlsson                            *p_notify       = TRUE;
5093fb94a4918bd427fdb12df997dd87fd1017f0388Chris Lattner                    }
5101eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump                    else
511c1fcb7762673be706b0a40477d5e93411e918f93Anders Carlsson                    {
512c1fcb7762673be706b0a40477d5e93411e918f93Anders Carlsson                        /* send WRITE-NE command */
513c1fcb7762673be706b0a40477d5e93411e918f93Anders Carlsson                        RW_T1T_BLD_ADD ((addr), ((UINT8) (offset/T1T_BLOCK_SIZE)), ((UINT8) (offset%T1T_BLOCK_SIZE)));
514d97bb6c1384cb773ba5cdbd198008dec127cebadTed Kremenek                        value = (UINT8) (tags_pow (2,num_bits) - 1);
5151eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump                        if ((status = rw_t1t_send_static_cmd (T1T_CMD_WRITE_NE, addr, value)) == NFC_STATUS_OK)
516d97bb6c1384cb773ba5cdbd198008dec127cebadTed Kremenek                        {
517b5a69586f1b8855ee4c1f0bb7a8f0ff4fe32ce09Steve Naroff                            p_t1t->substate = RW_T1T_SUBSTATE_WAIT_SET_DYN_LOCK_BITS;
518dbb26db1d426fb6caaaf1b4fa47b46d1947c12c9Douglas Gregor                            p_t1t->lockbyte[num_locks].lock_status = RW_T1T_LOCK_UPDATE_INITIATED;
519dbb26db1d426fb6caaaf1b4fa47b46d1947c12c9Douglas Gregor                        }
520dbb26db1d426fb6caaaf1b4fa47b46d1947c12c9Douglas Gregor                        else
5213fb94a4918bd427fdb12df997dd87fd1017f0388Chris Lattner                            *p_notify       = TRUE;
5225f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer                    }
523dbb26db1d426fb6caaaf1b4fa47b46d1947c12c9Douglas Gregor                    break;
5241eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump                }
525d97bb6c1384cb773ba5cdbd198008dec127cebadTed Kremenek                num_locks++;
52624e1e707b4c362f18e371e2bbf054a8345b57bfaChris Lattner            }
527d97bb6c1384cb773ba5cdbd198008dec127cebadTed Kremenek            if (num_locks == p_t1t->num_lockbytes)
528d97bb6c1384cb773ba5cdbd198008dec127cebadTed Kremenek            {
529b5a69586f1b8855ee4c1f0bb7a8f0ff4fe32ce09Steve Naroff                rw_t1t_update_lock_attributes ();
530dbb26db1d426fb6caaaf1b4fa47b46d1947c12c9Douglas Gregor                status    = NFC_STATUS_OK;
531dbb26db1d426fb6caaaf1b4fa47b46d1947c12c9Douglas Gregor                *p_notify = TRUE;
532d97bb6c1384cb773ba5cdbd198008dec127cebadTed Kremenek            }
533025452fa0eda63e150cfaeebe64f0a19c96b3a06Douglas Gregor            break;
534025452fa0eda63e150cfaeebe64f0a19c96b3a06Douglas Gregor        }
535025452fa0eda63e150cfaeebe64f0a19c96b3a06Douglas Gregor        break;
536025452fa0eda63e150cfaeebe64f0a19c96b3a06Douglas Gregor
537764a7ce5217f9569e100a3445f47496ee82daf86Chris Lattner    case RW_T1T_STATE_WRITE_NDEF:
538025452fa0eda63e150cfaeebe64f0a19c96b3a06Douglas Gregor        switch (p_t1t->substate)
539dbb26db1d426fb6caaaf1b4fa47b46d1947c12c9Douglas Gregor        {
540dbb26db1d426fb6caaaf1b4fa47b46d1947c12c9Douglas Gregor        case RW_T1T_SUBSTATE_WAIT_VALIDATE_NDEF:
541dbb26db1d426fb6caaaf1b4fa47b46d1947c12c9Douglas Gregor            p_t1t->ndef_msg_len  = p_t1t->new_ndef_msg_len;
542dbb26db1d426fb6caaaf1b4fa47b46d1947c12c9Douglas Gregor            p_t1t->tag_attribute = RW_T1_TAG_ATTRB_READ_WRITE;
543025452fa0eda63e150cfaeebe64f0a19c96b3a06Douglas Gregor            *p_notify = TRUE;
544d97bb6c1384cb773ba5cdbd198008dec127cebadTed Kremenek            break;
545d97bb6c1384cb773ba5cdbd198008dec127cebadTed Kremenek
546d97bb6c1384cb773ba5cdbd198008dec127cebadTed Kremenek        case RW_T1T_SUBSTATE_WAIT_NDEF_UPDATED:
547025452fa0eda63e150cfaeebe64f0a19c96b3a06Douglas Gregor            status      = rw_t1t_handle_ndef_write_rsp (p_data);
5481eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump            if (status == NFC_STATUS_OK)
5491eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump            {
55051b09f2c528c8460b5465c676173324e44176d62Devang Patel                p_t1t->substate = RW_T1T_SUBSTATE_WAIT_VALIDATE_NDEF;
5511eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump            }
5521eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump            else if (status == NFC_STATUS_FAILED)
55351b09f2c528c8460b5465c676173324e44176d62Devang Patel            {
55451b09f2c528c8460b5465c676173324e44176d62Devang Patel                /* Send Negative response to upper layer */
5555f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer                *p_notify       = TRUE;
55620dabe8b8ff7ed6d2d0158fee43755a4bc7642c3Chris Lattner            }
55720dabe8b8ff7ed6d2d0158fee43755a4bc7642c3Chris Lattner            break;
55820dabe8b8ff7ed6d2d0158fee43755a4bc7642c3Chris Lattner
5591eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump        case RW_T1T_SUBSTATE_WAIT_NDEF_WRITE:
5601eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump            status = rw_t1t_handle_ndef_write_rsp (p_data);
5613fb94a4918bd427fdb12df997dd87fd1017f0388Chris Lattner
5623fb94a4918bd427fdb12df997dd87fd1017f0388Chris Lattner            if (status == NFC_STATUS_FAILED)
5633fb94a4918bd427fdb12df997dd87fd1017f0388Chris Lattner            {
56491ee0140ecb60b5c1402edc9e577257636c4ca60Chris Lattner                /* Send Negative response to upper layer */
5653fb94a4918bd427fdb12df997dd87fd1017f0388Chris Lattner                *p_notify       = TRUE;
5661eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump            }
5671eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump            else if (status == NFC_STATUS_OK)
568b5a69586f1b8855ee4c1f0bb7a8f0ff4fe32ce09Steve Naroff            {
5691eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump                p_t1t->substate = RW_T1T_SUBSTATE_WAIT_NDEF_UPDATED;
5701eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump            }
5715f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer            break;
5725f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
5731eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump        case RW_T1T_SUBSTATE_WAIT_INVALIDATE_NDEF:
574d97bb6c1384cb773ba5cdbd198008dec127cebadTed Kremenek            status = rw_t1t_handle_ndef_write_rsp (p_data);
575d97bb6c1384cb773ba5cdbd198008dec127cebadTed Kremenek            if (status == NFC_STATUS_FAILED)
576d97bb6c1384cb773ba5cdbd198008dec127cebadTed Kremenek            {
5775f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer                /* Send Negative response to upper layer */
5785f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer                *p_notify   = TRUE;
579c1fcb7762673be706b0a40477d5e93411e918f93Anders Carlsson            }
580d97bb6c1384cb773ba5cdbd198008dec127cebadTed Kremenek            else if (status == NFC_STATUS_CONTINUE)
5816c36be5b383875b490684bcf439d6d427298c1afChris Lattner            {
582dbb26db1d426fb6caaaf1b4fa47b46d1947c12c9Douglas Gregor                p_t1t->substate = RW_T1T_SUBSTATE_WAIT_NDEF_WRITE;
5833fb94a4918bd427fdb12df997dd87fd1017f0388Chris Lattner            }
5845f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer            else
5851eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump            {
586dbb26db1d426fb6caaaf1b4fa47b46d1947c12c9Douglas Gregor                p_t1t->substate = RW_T1T_SUBSTATE_WAIT_NDEF_UPDATED;
587dbb26db1d426fb6caaaf1b4fa47b46d1947c12c9Douglas Gregor            }
588025452fa0eda63e150cfaeebe64f0a19c96b3a06Douglas Gregor            break;
589025452fa0eda63e150cfaeebe64f0a19c96b3a06Douglas Gregor        }
590025452fa0eda63e150cfaeebe64f0a19c96b3a06Douglas Gregor        break;
591025452fa0eda63e150cfaeebe64f0a19c96b3a06Douglas Gregor    }
592d97bb6c1384cb773ba5cdbd198008dec127cebadTed Kremenek    return status;
59351b09f2c528c8460b5465c676173324e44176d62Devang Patel}
594025452fa0eda63e150cfaeebe64f0a19c96b3a06Douglas Gregor
595025452fa0eda63e150cfaeebe64f0a19c96b3a06Douglas Gregor/*******************************************************************************
5966c36be5b383875b490684bcf439d6d427298c1afChris Lattner**
597025452fa0eda63e150cfaeebe64f0a19c96b3a06Douglas Gregor** Function         rw_t1t_handle_read_rsp
598dbb26db1d426fb6caaaf1b4fa47b46d1947c12c9Douglas Gregor**
599dbb26db1d426fb6caaaf1b4fa47b46d1947c12c9Douglas Gregor** Description      This function handle the data bytes excluding ADD(S)/ADD8 field
6005f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer**                  received as part of RSEG, RALL, READ8 command response
6011eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump**
6021eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump** Returns          status of the current NDEF/TLV Operation
603b5a69586f1b8855ee4c1f0bb7a8f0ff4fe32ce09Steve Naroff**
6041eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump*******************************************************************************/
6051eb4433ac451dc16f4133a88af2d002ac26c58efMike StumptNFC_STATUS rw_t1t_handle_read_rsp (BOOLEAN *p_notify, UINT8 *p_data)
6065f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer{
6075f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    tRW_T1T_CB              *p_t1t  = &rw_cb.tcb.t1t;
6081eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump    tNFC_STATUS             status  = NFC_STATUS_OK;
609d97bb6c1384cb773ba5cdbd198008dec127cebadTed Kremenek    tRW_DETECT_NDEF_DATA    ndef_data;
610d97bb6c1384cb773ba5cdbd198008dec127cebadTed Kremenek    tRW_DETECT_TLV_DATA     tlv_data;
611d97bb6c1384cb773ba5cdbd198008dec127cebadTed Kremenek    UINT8                   count;
6125f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    tRW_READ_DATA           evt_data;
6135f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
6145f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    *p_notify = FALSE;
6155f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    /* Handle the response based on the current state */
6165f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    switch (p_t1t->state)
617b5a69586f1b8855ee4c1f0bb7a8f0ff4fe32ce09Steve Naroff    {
6185f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    case RW_T1T_STATE_READ:
6191a18600b85aaa691122983dd8dcf4225cfc9ef68Argyrios Kyrtzidis        *p_notify = TRUE;
6201a18600b85aaa691122983dd8dcf4225cfc9ef68Argyrios Kyrtzidis        break;
6218e6285af719adc6f86d6faa235d22a08eb68ee3aJohn McCall
6228e6285af719adc6f86d6faa235d22a08eb68ee3aJohn McCall    case RW_T1T_STATE_READ_NDEF:
6238e6285af719adc6f86d6faa235d22a08eb68ee3aJohn McCall        status = rw_t1t_handle_ndef_rall_rsp ();
6248e6285af719adc6f86d6faa235d22a08eb68ee3aJohn McCall        if (status != NFC_STATUS_CONTINUE)
6251de05feeeafe5b215fe7617594a7076a5192a6e2Douglas Gregor        {
6261de05feeeafe5b215fe7617594a7076a5192a6e2Douglas Gregor            evt_data.status = status;
6271de05feeeafe5b215fe7617594a7076a5192a6e2Douglas Gregor            evt_data.p_data = NULL;
6281eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump            rw_t1t_handle_op_complete ();
6295f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer            (*rw_cb.p_cback) (RW_T1T_NDEF_READ_EVT, (tRW_DATA *) &evt_data);
6305f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer        }
6311de05feeeafe5b215fe7617594a7076a5192a6e2Douglas Gregor        break;
6325f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
6335f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    case RW_T1T_STATE_TLV_DETECT:
6345f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer        switch (p_t1t->substate)
6355f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer        {
6365f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer        case RW_T1T_SUBSTATE_WAIT_READ_LOCKS:
637b5a69586f1b8855ee4c1f0bb7a8f0ff4fe32ce09Steve Naroff            status = rw_t1t_read_locks ();
638355a9fe26a6dec89680ddf713dd5bc7a671b298aArgyrios Kyrtzidis            if (status != NFC_STATUS_CONTINUE)
6391a18600b85aaa691122983dd8dcf4225cfc9ef68Argyrios Kyrtzidis            {
6408e6285af719adc6f86d6faa235d22a08eb68ee3aJohn McCall                rw_t1t_update_lock_attributes ();
6418e6285af719adc6f86d6faa235d22a08eb68ee3aJohn McCall                /* Send positive response to upper layer */
6421a18600b85aaa691122983dd8dcf4225cfc9ef68Argyrios Kyrtzidis                if (p_t1t->tlv_detect == TAG_LOCK_CTRL_TLV)
6438e6285af719adc6f86d6faa235d22a08eb68ee3aJohn McCall                {
644355a9fe26a6dec89680ddf713dd5bc7a671b298aArgyrios Kyrtzidis                    tlv_data.protocol   = NFC_PROTOCOL_T1T;
6458e6285af719adc6f86d6faa235d22a08eb68ee3aJohn McCall                    tlv_data.num_bytes  = p_t1t->num_lockbytes;
6468e6285af719adc6f86d6faa235d22a08eb68ee3aJohn McCall                    tlv_data.status = status;
6471a18600b85aaa691122983dd8dcf4225cfc9ef68Argyrios Kyrtzidis                    rw_t1t_handle_op_complete ();
6481eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump                    (*rw_cb.p_cback) (RW_T1T_TLV_DETECT_EVT, (tRW_DATA *) &tlv_data);
6491eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump                }
6501eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump                else if (p_t1t->tlv_detect == TAG_NDEF_TLV)
6511eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump                {
6521eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump                    ndef_data.protocol  = NFC_PROTOCOL_T1T;
6535f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer                    ndef_data.flags     = rw_t1t_get_ndef_flags ();
6545f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer                    ndef_data.flags    |= RW_NDEF_FL_FORMATED;
6551eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump                    ndef_data.max_size  = (UINT32) rw_t1t_get_ndef_max_size ();
6568297777fbe19c4d39e8a70c55346474868055fa1Ted Kremenek                    ndef_data.cur_size  = p_t1t->ndef_msg_len;
6578297777fbe19c4d39e8a70c55346474868055fa1Ted Kremenek
6588297777fbe19c4d39e8a70c55346474868055fa1Ted Kremenek                    if (ndef_data.max_size  < ndef_data.cur_size)
6595f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer                    {
6605f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer                        ndef_data.flags    |= RW_NDEF_FL_READ_ONLY;
6615f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer                        ndef_data.max_size  = ndef_data.cur_size;
6625f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer                    }
6635f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
6645f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer                    if (!(ndef_data.flags & RW_NDEF_FL_READ_ONLY))
66543dec6bbde2d0a16c35978983761c8b7030c8e18Douglas Gregor                    {
6668297777fbe19c4d39e8a70c55346474868055fa1Ted Kremenek                        ndef_data.flags    |= RW_NDEF_FL_SOFT_LOCKABLE;
6678cfe5a784133d90bf329fd20801824a6f71bb8caDouglas Gregor                        if (status == NFC_STATUS_OK)
668b5a69586f1b8855ee4c1f0bb7a8f0ff4fe32ce09Steve Naroff                            ndef_data.flags    |= RW_NDEF_FL_HARD_LOCKABLE;
669d06f6ca61062f85926eb9d409eb3d4f8afcf93c7Douglas Gregor                    }
67044aa1f397855f130e88e62ffc1029f7f83bb5d2eArgyrios Kyrtzidis                    ndef_data.status = status;
6715f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer                    rw_t1t_handle_op_complete ();
67243dec6bbde2d0a16c35978983761c8b7030c8e18Douglas Gregor                    (*rw_cb.p_cback) (RW_T1T_NDEF_DETECT_EVT, (tRW_DATA *)&ndef_data);
67344aa1f397855f130e88e62ffc1029f7f83bb5d2eArgyrios Kyrtzidis                }
67443dec6bbde2d0a16c35978983761c8b7030c8e18Douglas Gregor            }
675025452fa0eda63e150cfaeebe64f0a19c96b3a06Douglas Gregor            break;
676025452fa0eda63e150cfaeebe64f0a19c96b3a06Douglas Gregor
677025452fa0eda63e150cfaeebe64f0a19c96b3a06Douglas Gregor        case RW_T1T_SUBSTATE_NONE:
6788cfe5a784133d90bf329fd20801824a6f71bb8caDouglas Gregor            if (p_t1t->tlv_detect == TAG_MEM_CTRL_TLV)
6798cfe5a784133d90bf329fd20801824a6f71bb8caDouglas Gregor            {
6808cfe5a784133d90bf329fd20801824a6f71bb8caDouglas Gregor                tlv_data.status    = rw_t1t_handle_tlv_detect_rsp (p_t1t->mem);
6818cfe5a784133d90bf329fd20801824a6f71bb8caDouglas Gregor                tlv_data.protocol  = NFC_PROTOCOL_T1T;
6828cfe5a784133d90bf329fd20801824a6f71bb8caDouglas Gregor                tlv_data.num_bytes = 0;
6838cfe5a784133d90bf329fd20801824a6f71bb8caDouglas Gregor                count              = 0;
6848cfe5a784133d90bf329fd20801824a6f71bb8caDouglas Gregor                while (count < p_t1t->num_mem_tlvs)
6858cfe5a784133d90bf329fd20801824a6f71bb8caDouglas Gregor                {
68643dec6bbde2d0a16c35978983761c8b7030c8e18Douglas Gregor                    tlv_data.num_bytes += p_t1t->mem_tlv[p_t1t->num_mem_tlvs].num_bytes;
68743dec6bbde2d0a16c35978983761c8b7030c8e18Douglas Gregor                    count++;
688c302113179a1c2b1254224ea9b6f5316ceeb375cSean Hunt                }
6898297777fbe19c4d39e8a70c55346474868055fa1Ted Kremenek                rw_t1t_handle_op_complete ();
690025452fa0eda63e150cfaeebe64f0a19c96b3a06Douglas Gregor                /* Send response to upper layer */
6918297777fbe19c4d39e8a70c55346474868055fa1Ted Kremenek                (*rw_cb.p_cback) (RW_T1T_TLV_DETECT_EVT, (tRW_DATA *) &tlv_data);
6921eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump            }
6938297777fbe19c4d39e8a70c55346474868055fa1Ted Kremenek            else if (p_t1t->tlv_detect == TAG_LOCK_CTRL_TLV)
694025452fa0eda63e150cfaeebe64f0a19c96b3a06Douglas Gregor            {
6955f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer                tlv_data.status    = rw_t1t_handle_tlv_detect_rsp (p_t1t->mem);
6968297777fbe19c4d39e8a70c55346474868055fa1Ted Kremenek                tlv_data.protocol  = NFC_PROTOCOL_T1T;
6978297777fbe19c4d39e8a70c55346474868055fa1Ted Kremenek                tlv_data.num_bytes = p_t1t->num_lockbytes;
6988297777fbe19c4d39e8a70c55346474868055fa1Ted Kremenek
699b5a69586f1b8855ee4c1f0bb7a8f0ff4fe32ce09Steve Naroff                if (tlv_data.status == NFC_STATUS_FAILED)
700025452fa0eda63e150cfaeebe64f0a19c96b3a06Douglas Gregor                {
701025452fa0eda63e150cfaeebe64f0a19c96b3a06Douglas Gregor                    rw_t1t_handle_op_complete ();
702d06f6ca61062f85926eb9d409eb3d4f8afcf93c7Douglas Gregor
703d06f6ca61062f85926eb9d409eb3d4f8afcf93c7Douglas Gregor                    /* Send Negative response to upper layer */
704025452fa0eda63e150cfaeebe64f0a19c96b3a06Douglas Gregor                    (*rw_cb.p_cback) (RW_T1T_TLV_DETECT_EVT, (tRW_DATA *)&tlv_data);
7051eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump                }
706b5a69586f1b8855ee4c1f0bb7a8f0ff4fe32ce09Steve Naroff                else
707b5a69586f1b8855ee4c1f0bb7a8f0ff4fe32ce09Steve Naroff                {
708b5a69586f1b8855ee4c1f0bb7a8f0ff4fe32ce09Steve Naroff                    rw_t1t_extract_lock_bytes (p_data);
709b5a69586f1b8855ee4c1f0bb7a8f0ff4fe32ce09Steve Naroff                    status = rw_t1t_read_locks ();
710b5a69586f1b8855ee4c1f0bb7a8f0ff4fe32ce09Steve Naroff                    if (status != NFC_STATUS_CONTINUE)
7111eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump                    {
7121eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump                        /* Send positive response to upper layer */
7131eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump                        tlv_data.status = status;
7145f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer                        rw_t1t_handle_op_complete ();
7155f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
7161eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump                        (*rw_cb.p_cback) (RW_T1T_TLV_DETECT_EVT, (tRW_DATA *) &tlv_data);
71735628d1f17c817f8c240208db7ba490e3109981bTed Kremenek                    }
71835628d1f17c817f8c240208db7ba490e3109981bTed Kremenek                }
7198297777fbe19c4d39e8a70c55346474868055fa1Ted Kremenek            }
7208297777fbe19c4d39e8a70c55346474868055fa1Ted Kremenek            else if (p_t1t->tlv_detect == TAG_NDEF_TLV)
7215f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer            {
7225f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer                ndef_data.protocol  = NFC_PROTOCOL_T1T;
7235f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer                ndef_data.flags     = rw_t1t_get_ndef_flags ();
7245f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
7255f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer                if (p_t1t->mem[T1T_CC_NMN_BYTE] == T1T_CC_NMN)
72643dec6bbde2d0a16c35978983761c8b7030c8e18Douglas Gregor                {
7271eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump                    ndef_data.status    = rw_t1t_handle_tlv_detect_rsp (p_t1t->mem);
728c1fcb7762673be706b0a40477d5e93411e918f93Anders Carlsson
729c1fcb7762673be706b0a40477d5e93411e918f93Anders Carlsson                    ndef_data.cur_size  = p_t1t->ndef_msg_len;
7309dcbfa450d751bd68fc4af8b75da381d4f6984b9Steve Naroff                    if (ndef_data.status == NFC_STATUS_FAILED)
7311eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump                    {
732559fb554602bedb57dbbf3cc14ac8a38264b4547Ted Kremenek                        ndef_data.max_size  = (UINT32) rw_t1t_get_ndef_max_size ();
733559fb554602bedb57dbbf3cc14ac8a38264b4547Ted Kremenek                        if (ndef_data.max_size  < ndef_data.cur_size)
734559fb554602bedb57dbbf3cc14ac8a38264b4547Ted Kremenek                        {
735559fb554602bedb57dbbf3cc14ac8a38264b4547Ted Kremenek                            ndef_data.flags    |= RW_NDEF_FL_READ_ONLY;
736559fb554602bedb57dbbf3cc14ac8a38264b4547Ted Kremenek                            ndef_data.max_size  = ndef_data.cur_size;
7375f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer                        }
73843dec6bbde2d0a16c35978983761c8b7030c8e18Douglas Gregor                        if (!(ndef_data.flags & RW_NDEF_FL_READ_ONLY))
7391eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump                        {
740025452fa0eda63e150cfaeebe64f0a19c96b3a06Douglas Gregor                            ndef_data.flags    |= RW_NDEF_FL_SOFT_LOCKABLE;
741025452fa0eda63e150cfaeebe64f0a19c96b3a06Douglas Gregor                        }
742025452fa0eda63e150cfaeebe64f0a19c96b3a06Douglas Gregor                        /* Send Negative response to upper layer */
743d3d5301c44138b92bf01286183f5bf310cdd37cfDouglas Gregor                        rw_t1t_handle_op_complete ();
744d3d5301c44138b92bf01286183f5bf310cdd37cfDouglas Gregor
745d3d5301c44138b92bf01286183f5bf310cdd37cfDouglas Gregor                        (*rw_cb.p_cback) (RW_T1T_NDEF_DETECT_EVT, (tRW_DATA *) &ndef_data);
746d3d5301c44138b92bf01286183f5bf310cdd37cfDouglas Gregor                    }
747d3d5301c44138b92bf01286183f5bf310cdd37cfDouglas Gregor                    else
748d3d5301c44138b92bf01286183f5bf310cdd37cfDouglas Gregor                    {
749d3d5301c44138b92bf01286183f5bf310cdd37cfDouglas Gregor                        ndef_data.flags    |= RW_NDEF_FL_FORMATED;
750d3d5301c44138b92bf01286183f5bf310cdd37cfDouglas Gregor                        rw_t1t_extract_lock_bytes (p_data);
751d3d5301c44138b92bf01286183f5bf310cdd37cfDouglas Gregor                        status = rw_t1t_read_locks ();
75243dec6bbde2d0a16c35978983761c8b7030c8e18Douglas Gregor                        if (status != NFC_STATUS_CONTINUE)
75343dec6bbde2d0a16c35978983761c8b7030c8e18Douglas Gregor                        {
754d3d5301c44138b92bf01286183f5bf310cdd37cfDouglas Gregor                            ndef_data.max_size  = (UINT32) rw_t1t_get_ndef_max_size ();
7558297777fbe19c4d39e8a70c55346474868055fa1Ted Kremenek                            if (ndef_data.max_size  < ndef_data.cur_size)
7568297777fbe19c4d39e8a70c55346474868055fa1Ted Kremenek                            {
757c1fcb7762673be706b0a40477d5e93411e918f93Anders Carlsson                                ndef_data.flags    |= RW_NDEF_FL_READ_ONLY;
758c1fcb7762673be706b0a40477d5e93411e918f93Anders Carlsson                                ndef_data.max_size  = ndef_data.cur_size;
7598297777fbe19c4d39e8a70c55346474868055fa1Ted Kremenek                            }
760025452fa0eda63e150cfaeebe64f0a19c96b3a06Douglas Gregor
7618297777fbe19c4d39e8a70c55346474868055fa1Ted Kremenek                            if (!(ndef_data.flags & RW_NDEF_FL_READ_ONLY))
762025452fa0eda63e150cfaeebe64f0a19c96b3a06Douglas Gregor                            {
763c1fcb7762673be706b0a40477d5e93411e918f93Anders Carlsson                                ndef_data.flags    |= RW_NDEF_FL_SOFT_LOCKABLE;
7641eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump                                if (status == NFC_STATUS_OK)
76543d9d9243329b1b75d1a6efdad9f16d6fb386b8eDouglas Gregor                                    ndef_data.flags    |= RW_NDEF_FL_HARD_LOCKABLE;
76643d9d9243329b1b75d1a6efdad9f16d6fb386b8eDouglas Gregor                            }
76743d9d9243329b1b75d1a6efdad9f16d6fb386b8eDouglas Gregor                            /* Send positive response to upper layer */
76843d9d9243329b1b75d1a6efdad9f16d6fb386b8eDouglas Gregor                            ndef_data.status = status;
769025452fa0eda63e150cfaeebe64f0a19c96b3a06Douglas Gregor                            rw_t1t_handle_op_complete ();
770025452fa0eda63e150cfaeebe64f0a19c96b3a06Douglas Gregor
771025452fa0eda63e150cfaeebe64f0a19c96b3a06Douglas Gregor                            (*rw_cb.p_cback) (RW_T1T_NDEF_DETECT_EVT, (tRW_DATA *)&ndef_data);
772025452fa0eda63e150cfaeebe64f0a19c96b3a06Douglas Gregor                        }
773c1fcb7762673be706b0a40477d5e93411e918f93Anders Carlsson                    }
7741eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump                }
7751eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump                else
7769dcbfa450d751bd68fc4af8b75da381d4f6984b9Steve Naroff                {
7771eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump                    /* Send Negative response to upper layer */
778c1fcb7762673be706b0a40477d5e93411e918f93Anders Carlsson                    ndef_data.status    = NFC_STATUS_FAILED;
779c2ee10d79f70036af652a395ac1f8273f3d04e12Douglas Gregor                    ndef_data.max_size  = (UINT32) rw_t1t_get_ndef_max_size ();
780c2ee10d79f70036af652a395ac1f8273f3d04e12Douglas Gregor                    ndef_data.cur_size  = p_t1t->ndef_msg_len;
781c1fcb7762673be706b0a40477d5e93411e918f93Anders Carlsson                    if (ndef_data.max_size  < ndef_data.cur_size)
782c1fcb7762673be706b0a40477d5e93411e918f93Anders Carlsson                    {
783559fb554602bedb57dbbf3cc14ac8a38264b4547Ted Kremenek                        ndef_data.flags    |= RW_NDEF_FL_READ_ONLY;
784559fb554602bedb57dbbf3cc14ac8a38264b4547Ted Kremenek                        ndef_data.max_size  = ndef_data.cur_size;
785559fb554602bedb57dbbf3cc14ac8a38264b4547Ted Kremenek                    }
786559fb554602bedb57dbbf3cc14ac8a38264b4547Ted Kremenek                    if (!(ndef_data.flags & RW_NDEF_FL_READ_ONLY))
787559fb554602bedb57dbbf3cc14ac8a38264b4547Ted Kremenek                    {
788559fb554602bedb57dbbf3cc14ac8a38264b4547Ted Kremenek                        ndef_data.flags    |= RW_NDEF_FL_SOFT_LOCKABLE;
789559fb554602bedb57dbbf3cc14ac8a38264b4547Ted Kremenek                        ndef_data.flags    |= RW_NDEF_FL_SOFT_LOCKABLE;
790559fb554602bedb57dbbf3cc14ac8a38264b4547Ted Kremenek                    }
791559fb554602bedb57dbbf3cc14ac8a38264b4547Ted Kremenek                    rw_t1t_handle_op_complete ();
792559fb554602bedb57dbbf3cc14ac8a38264b4547Ted Kremenek
793559fb554602bedb57dbbf3cc14ac8a38264b4547Ted Kremenek                    (*rw_cb.p_cback) (RW_T1T_NDEF_DETECT_EVT, (tRW_DATA *) &ndef_data);
794559fb554602bedb57dbbf3cc14ac8a38264b4547Ted Kremenek                }
795559fb554602bedb57dbbf3cc14ac8a38264b4547Ted Kremenek            }
7961eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump            break;
7971eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump        }
7989dcbfa450d751bd68fc4af8b75da381d4f6984b9Steve Naroff        break;
7991eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump    }
8001eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump    return status;
8015f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer}
8025f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
8031eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump/*******************************************************************************
8048297777fbe19c4d39e8a70c55346474868055fa1Ted Kremenek**
8058297777fbe19c4d39e8a70c55346474868055fa1Ted Kremenek** Function         rw_t1t_handle_dyn_read_rsp
8068297777fbe19c4d39e8a70c55346474868055fa1Ted Kremenek**
8075f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer** Description      This function handles response received for READ8, RSEG
8085f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer**                  commands based on the current state
8095f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer**
8105f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer** Returns          status of the current NDEF/TLV Operation
8115f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer**
8125f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer*******************************************************************************/
81343dec6bbde2d0a16c35978983761c8b7030c8e18Douglas Gregorstatic tNFC_STATUS rw_t1t_handle_dyn_read_rsp (BOOLEAN *p_notify, UINT8 *p_data)
8148297777fbe19c4d39e8a70c55346474868055fa1Ted Kremenek{
815b5a69586f1b8855ee4c1f0bb7a8f0ff4fe32ce09Steve Naroff    tNFC_STATUS status  = NFC_STATUS_OK;
8165f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    tRW_T1T_CB  *p_t1t  = &rw_cb.tcb.t1t;
81743dec6bbde2d0a16c35978983761c8b7030c8e18Douglas Gregor
81843dec6bbde2d0a16c35978983761c8b7030c8e18Douglas Gregor    *p_notify = FALSE;
8191eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
820d921cf976b4769af8d06d6763a2547dadf7940abDouglas Gregor    p_data += T1T_ADD_LEN;
821d921cf976b4769af8d06d6763a2547dadf7940abDouglas Gregor
822d921cf976b4769af8d06d6763a2547dadf7940abDouglas Gregor    rw_t1t_extract_lock_bytes (p_data);
8235656e14d91405417182171a705ed3e3d2d6d7aa3Douglas Gregor
8245656e14d91405417182171a705ed3e3d2d6d7aa3Douglas Gregor    if (p_t1t->state == RW_T1T_STATE_READ_NDEF)
8255656e14d91405417182171a705ed3e3d2d6d7aa3Douglas Gregor    {
8265656e14d91405417182171a705ed3e3d2d6d7aa3Douglas Gregor        status = rw_t1t_handle_ndef_read_rsp (p_data);
8275656e14d91405417182171a705ed3e3d2d6d7aa3Douglas Gregor        if (  (status == NFC_STATUS_FAILED)
8285656e14d91405417182171a705ed3e3d2d6d7aa3Douglas Gregor            ||(status == NFC_STATUS_OK)  )
8295656e14d91405417182171a705ed3e3d2d6d7aa3Douglas Gregor        {
8305656e14d91405417182171a705ed3e3d2d6d7aa3Douglas Gregor            /* Send response to upper layer */
83143dec6bbde2d0a16c35978983761c8b7030c8e18Douglas Gregor            *p_notify = TRUE;
83243dec6bbde2d0a16c35978983761c8b7030c8e18Douglas Gregor        }
8335656e14d91405417182171a705ed3e3d2d6d7aa3Douglas Gregor    }
8348297777fbe19c4d39e8a70c55346474868055fa1Ted Kremenek    else if (p_t1t->state == RW_T1T_STATE_WRITE_NDEF)
8358297777fbe19c4d39e8a70c55346474868055fa1Ted Kremenek    {
836d921cf976b4769af8d06d6763a2547dadf7940abDouglas Gregor        status = rw_t1t_handle_ndef_write_rsp (p_data);
8378297777fbe19c4d39e8a70c55346474868055fa1Ted Kremenek        if (status == NFC_STATUS_FAILED)
8388297777fbe19c4d39e8a70c55346474868055fa1Ted Kremenek        {
839d921cf976b4769af8d06d6763a2547dadf7940abDouglas Gregor            /* Send response to upper layer */
840d921cf976b4769af8d06d6763a2547dadf7940abDouglas Gregor            *p_notify = TRUE;
841d921cf976b4769af8d06d6763a2547dadf7940abDouglas Gregor        }
842d921cf976b4769af8d06d6763a2547dadf7940abDouglas Gregor        else if (status == NFC_STATUS_CONTINUE)
843b5a69586f1b8855ee4c1f0bb7a8f0ff4fe32ce09Steve Naroff        {
8441eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump            p_t1t->substate = RW_T1T_SUBSTATE_WAIT_INVALIDATE_NDEF;
8451eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump        }
846b5a69586f1b8855ee4c1f0bb7a8f0ff4fe32ce09Steve Naroff    }
8471eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump    else
8481eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump    {
8495f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer        status = rw_t1t_handle_read_rsp (p_notify, p_data);
8505f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    }
8511eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump    return status;
8528297777fbe19c4d39e8a70c55346474868055fa1Ted Kremenek}
8538297777fbe19c4d39e8a70c55346474868055fa1Ted Kremenek
8548297777fbe19c4d39e8a70c55346474868055fa1Ted Kremenek/*****************************************************************************
8555f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer**
8565f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer** Function         rw_t1t_handle_rall_rsp
8575f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer**
8585f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer** Description      Handle response to RALL - Collect CC, set Tag state
8595f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer**
8608297777fbe19c4d39e8a70c55346474868055fa1Ted Kremenek** Returns          None
8618297777fbe19c4d39e8a70c55346474868055fa1Ted Kremenek**
862b5a69586f1b8855ee4c1f0bb7a8f0ff4fe32ce09Steve Naroff*****************************************************************************/
8639f3ca2a7747bd47f14d7693f333103fac29a24d2Douglas Gregorstatic tNFC_STATUS rw_t1t_handle_rall_rsp (BOOLEAN *p_notify,UINT8 *p_data)
864989135901c750af61ef012b6b0a0368be415bc46Chris Lattner{
8659f3ca2a7747bd47f14d7693f333103fac29a24d2Douglas Gregor    tRW_T1T_CB  *p_t1t   = &rw_cb.tcb.t1t;
8665f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
867989135901c750af61ef012b6b0a0368be415bc46Chris Lattner    p_data      += T1T_HR_LEN; /* skip HR */
868989135901c750af61ef012b6b0a0368be415bc46Chris Lattner    memcpy (p_t1t->mem, (UINT8 *) p_data, T1T_STATIC_SIZE);
869989135901c750af61ef012b6b0a0368be415bc46Chris Lattner    p_t1t->segment  = 0;
8708297777fbe19c4d39e8a70c55346474868055fa1Ted Kremenek    rw_t1t_extract_lock_bytes (p_data);
8718297777fbe19c4d39e8a70c55346474868055fa1Ted Kremenek
8721eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump    p_data      += T1T_UID_LEN + T1T_RES_BYTE_LEN; /* skip Block 0, UID and Reserved byte */
87367d8249924ef38a5375ff9c92cd21c1854d6ababDouglas Gregor
87467d8249924ef38a5375ff9c92cd21c1854d6ababDouglas Gregor    RW_TRACE_DEBUG0 ("rw_t1t_handle_rall_rsp ()");
87567d8249924ef38a5375ff9c92cd21c1854d6ababDouglas Gregor
8761eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump    rw_t1t_update_tag_state ();
8778297777fbe19c4d39e8a70c55346474868055fa1Ted Kremenek    rw_t1t_update_attributes ();
8788297777fbe19c4d39e8a70c55346474868055fa1Ted Kremenek    rw_t1t_update_lock_attributes ();
87967d8249924ef38a5375ff9c92cd21c1854d6ababDouglas Gregor    p_t1t->b_update = TRUE;
8808297777fbe19c4d39e8a70c55346474868055fa1Ted Kremenek    return (rw_t1t_handle_read_rsp (p_notify, p_t1t->mem));
8811eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump}
88267d8249924ef38a5375ff9c92cd21c1854d6ababDouglas Gregor
88367d8249924ef38a5375ff9c92cd21c1854d6ababDouglas Gregor/*******************************************************************************
88467d8249924ef38a5375ff9c92cd21c1854d6ababDouglas Gregor**
88567d8249924ef38a5375ff9c92cd21c1854d6ababDouglas Gregor** Function         rw_t1t_handle_tlv_detect_rsp
8869f3ca2a7747bd47f14d7693f333103fac29a24d2Douglas Gregor**
8879f3ca2a7747bd47f14d7693f333103fac29a24d2Douglas Gregor** Description      Handle response to the last command sent while
888b5a69586f1b8855ee4c1f0bb7a8f0ff4fe32ce09Steve Naroff**                  detecting tlv
889989135901c750af61ef012b6b0a0368be415bc46Chris Lattner**
890989135901c750af61ef012b6b0a0368be415bc46Chris Lattner** Returns          NFC_STATUS_OK, if tlv detect is complete & success
891989135901c750af61ef012b6b0a0368be415bc46Chris Lattner**                  NFC_STATUS_FAILED,if tlv detect failed
8921eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump**
8931eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump*******************************************************************************/
894b5a69586f1b8855ee4c1f0bb7a8f0ff4fe32ce09Steve Naroffstatic tNFC_STATUS rw_t1t_handle_tlv_detect_rsp (UINT8 *p_data)
8951eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump{
8961eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump    UINT16      offset;
8975f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    UINT16      len;
8985f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    UINT8       xx;
8998297777fbe19c4d39e8a70c55346474868055fa1Ted Kremenek    UINT8       *p_readbytes;
9008297777fbe19c4d39e8a70c55346474868055fa1Ted Kremenek    UINT8       index;
9018297777fbe19c4d39e8a70c55346474868055fa1Ted Kremenek    UINT8       tlv_detect_state = RW_T1T_SUBSTATE_WAIT_TLV_DETECT;
9028297777fbe19c4d39e8a70c55346474868055fa1Ted Kremenek    UINT8       found_tlv = TAG_NULL_TLV;
9035f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    tRW_T1T_CB  *p_t1t          = &rw_cb.tcb.t1t;
9045f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    BOOLEAN     failed          = FALSE;
9055f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    BOOLEAN     found           = FALSE;
9065f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    UINT8       count           = 0;
9075f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    tNFC_STATUS status          = NFC_STATUS_FAILED;
9085f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    UINT8       start_offset    = T1T_UID_LEN + T1T_CC_LEN + T1T_RES_BYTE_LEN;
9095f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    UINT8       end_offset      = T1T_STATIC_SIZE - (2*T1T_BLOCK_SIZE);
9105f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    UINT8       bytes_read      = T1T_STATIC_SIZE;
91143dec6bbde2d0a16c35978983761c8b7030c8e18Douglas Gregor    UINT8       tlv_value[T1T_DEFAULT_TLV_LEN];
9128297777fbe19c4d39e8a70c55346474868055fa1Ted Kremenek    UINT16      bytes_count = 0;
913b5a69586f1b8855ee4c1f0bb7a8f0ff4fe32ce09Steve Naroff
9145831c6a1efc47e6a19d82fe3dd25b5b8fef6979dDouglas Gregor    p_readbytes = p_data;
9155831c6a1efc47e6a19d82fe3dd25b5b8fef6979dDouglas Gregor
9165f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    for (offset = start_offset; offset < end_offset  && !failed && !found;)
91743dec6bbde2d0a16c35978983761c8b7030c8e18Douglas Gregor    {
91843dec6bbde2d0a16c35978983761c8b7030c8e18Douglas Gregor        if (rw_t1t_is_lock_reserved_otp_byte ((UINT16) (offset)) == TRUE)
9191eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump        {
92067d8249924ef38a5375ff9c92cd21c1854d6ababDouglas Gregor            offset++;
92167d8249924ef38a5375ff9c92cd21c1854d6ababDouglas Gregor            continue;
92267d8249924ef38a5375ff9c92cd21c1854d6ababDouglas Gregor        }
9238297777fbe19c4d39e8a70c55346474868055fa1Ted Kremenek        switch (tlv_detect_state)
924c302113179a1c2b1254224ea9b6f5316ceeb375cSean Hunt        {
92599e9b4d172f6877e6ba5ebe75bb8238721f5e01cDouglas Gregor        case RW_T1T_SUBSTATE_WAIT_TLV_DETECT:
92699e9b4d172f6877e6ba5ebe75bb8238721f5e01cDouglas Gregor            /* Search for the tag */
92799e9b4d172f6877e6ba5ebe75bb8238721f5e01cDouglas Gregor            found_tlv = p_readbytes[offset++];
92899e9b4d172f6877e6ba5ebe75bb8238721f5e01cDouglas Gregor            switch (found_tlv)
92999e9b4d172f6877e6ba5ebe75bb8238721f5e01cDouglas Gregor            {
93099e9b4d172f6877e6ba5ebe75bb8238721f5e01cDouglas Gregor            case TAG_NULL_TLV:         /* May be used for padding. SHALL ignore this */
93199e9b4d172f6877e6ba5ebe75bb8238721f5e01cDouglas Gregor                break;
93299e9b4d172f6877e6ba5ebe75bb8238721f5e01cDouglas Gregor
93343dec6bbde2d0a16c35978983761c8b7030c8e18Douglas Gregor            case TAG_NDEF_TLV:
93443dec6bbde2d0a16c35978983761c8b7030c8e18Douglas Gregor                if (p_t1t->tlv_detect == TAG_NDEF_TLV)
935c302113179a1c2b1254224ea9b6f5316ceeb375cSean Hunt                {
9368297777fbe19c4d39e8a70c55346474868055fa1Ted Kremenek                    index = (offset % T1T_BLOCK_SIZE);
9378297777fbe19c4d39e8a70c55346474868055fa1Ted Kremenek                    /* Backup ndef first block */
9388297777fbe19c4d39e8a70c55346474868055fa1Ted Kremenek                    memcpy (&p_t1t->ndef_first_block[0],&p_readbytes[offset-index],index);
9398297777fbe19c4d39e8a70c55346474868055fa1Ted Kremenek                    memcpy (&p_t1t->ndef_first_block[index],&p_readbytes[offset],T1T_BLOCK_SIZE - index);
9408297777fbe19c4d39e8a70c55346474868055fa1Ted Kremenek                    tlv_detect_state = RW_T1T_SUBSTATE_WAIT_FIND_LEN_FIELD_LEN;
9418297777fbe19c4d39e8a70c55346474868055fa1Ted Kremenek                }
9428297777fbe19c4d39e8a70c55346474868055fa1Ted Kremenek                else if (p_t1t->tlv_detect == TAG_PROPRIETARY_TLV)
9438297777fbe19c4d39e8a70c55346474868055fa1Ted Kremenek                {
944b5a69586f1b8855ee4c1f0bb7a8f0ff4fe32ce09Steve Naroff                    tlv_detect_state = RW_T1T_SUBSTATE_WAIT_FIND_LEN_FIELD_LEN;
94567d8249924ef38a5375ff9c92cd21c1854d6ababDouglas Gregor                }
94667d8249924ef38a5375ff9c92cd21c1854d6ababDouglas Gregor                else if (  ((p_t1t->tlv_detect == TAG_LOCK_CTRL_TLV) && (p_t1t->num_lockbytes > 0))
94767d8249924ef38a5375ff9c92cd21c1854d6ababDouglas Gregor                         ||((p_t1t->tlv_detect == TAG_MEM_CTRL_TLV) && (p_t1t->num_mem_tlvs > 0))  )
94867d8249924ef38a5375ff9c92cd21c1854d6ababDouglas Gregor                {
94967d8249924ef38a5375ff9c92cd21c1854d6ababDouglas Gregor                    found = TRUE;
95067d8249924ef38a5375ff9c92cd21c1854d6ababDouglas Gregor                }
95167d8249924ef38a5375ff9c92cd21c1854d6ababDouglas Gregor                else
9525831c6a1efc47e6a19d82fe3dd25b5b8fef6979dDouglas Gregor                {
9535831c6a1efc47e6a19d82fe3dd25b5b8fef6979dDouglas Gregor                    failed = TRUE;
9545831c6a1efc47e6a19d82fe3dd25b5b8fef6979dDouglas Gregor                }
9555831c6a1efc47e6a19d82fe3dd25b5b8fef6979dDouglas Gregor                break;
95667d8249924ef38a5375ff9c92cd21c1854d6ababDouglas Gregor
9571eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump            case TAG_LOCK_CTRL_TLV:
9581eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump            case TAG_MEM_CTRL_TLV:
959b5a69586f1b8855ee4c1f0bb7a8f0ff4fe32ce09Steve Naroff                tlv_detect_state = RW_T1T_SUBSTATE_WAIT_READ_TLV_LEN0;
9601eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump                break;
9611eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
9625f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer            case TAG_PROPRIETARY_TLV:
9635f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer                if (p_t1t->tlv_detect == TAG_PROPRIETARY_TLV)
9641eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump                {
9658297777fbe19c4d39e8a70c55346474868055fa1Ted Kremenek                    index = (offset % T1T_BLOCK_SIZE);
9668297777fbe19c4d39e8a70c55346474868055fa1Ted Kremenek                    /* Backup ndef first block */
9678297777fbe19c4d39e8a70c55346474868055fa1Ted Kremenek                    tlv_detect_state = RW_T1T_SUBSTATE_WAIT_FIND_LEN_FIELD_LEN;
9685f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer                }
9691eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump                else
9705f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer                {
9715f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer                    /* NDEF/LOCK/MEM TLV can exist after Proprietary Tlv so we continue searching, skiping proprietary tlv */
9725f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer                    tlv_detect_state = RW_T1T_SUBSTATE_WAIT_FIND_LEN_FIELD_LEN;
9735f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer                }
974507f2d5811bd7da1a4d9d2f4960f32177dfab9deSteve Naroff                break;
97561f62165220e75694fe333179c78815e2e48d71fTed Kremenek
9765f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer            case TAG_TERMINATOR_TLV:   /* Last TLV block in the data area. Must be no NDEF nessage */
9771eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump                if (  ((p_t1t->tlv_detect == TAG_LOCK_CTRL_TLV) && (p_t1t->num_lockbytes > 0))
97861f62165220e75694fe333179c78815e2e48d71fTed Kremenek                    ||((p_t1t->tlv_detect == TAG_MEM_CTRL_TLV) && (p_t1t->num_mem_tlvs > 0))  )
9791eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump                {
9801de05feeeafe5b215fe7617594a7076a5192a6e2Douglas Gregor                    found = TRUE;
9811de05feeeafe5b215fe7617594a7076a5192a6e2Douglas Gregor                }
9821de05feeeafe5b215fe7617594a7076a5192a6e2Douglas Gregor                else
9835f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer                {
9841de05feeeafe5b215fe7617594a7076a5192a6e2Douglas Gregor                    failed = TRUE;
9851de05feeeafe5b215fe7617594a7076a5192a6e2Douglas Gregor                }
9861de05feeeafe5b215fe7617594a7076a5192a6e2Douglas Gregor                break;
9871de05feeeafe5b215fe7617594a7076a5192a6e2Douglas Gregor            default:
9881de05feeeafe5b215fe7617594a7076a5192a6e2Douglas Gregor                failed = TRUE;
9891de05feeeafe5b215fe7617594a7076a5192a6e2Douglas Gregor            }
990b5a69586f1b8855ee4c1f0bb7a8f0ff4fe32ce09Steve Naroff            break;
9911eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
9921eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump        case RW_T1T_SUBSTATE_WAIT_FIND_LEN_FIELD_LEN:
993507f2d5811bd7da1a4d9d2f4960f32177dfab9deSteve Naroff            len = p_readbytes[offset];
9941eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump            switch (found_tlv)
9951eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump            {
9965f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer            case TAG_NDEF_TLV:
9975f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer                p_t1t->ndef_header_offset = offset + p_t1t->work_offset;
9981eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump                if (len == T1T_LONG_NDEF_LEN_FIELD_BYTE0)
9998297777fbe19c4d39e8a70c55346474868055fa1Ted Kremenek                {
10008297777fbe19c4d39e8a70c55346474868055fa1Ted Kremenek                    /* The next two bytes constitute length bytes */
10018297777fbe19c4d39e8a70c55346474868055fa1Ted Kremenek                    tlv_detect_state     = RW_T1T_SUBSTATE_WAIT_READ_TLV_LEN0;
10025f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer                }
10035f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer                else
10045f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer                {
10055f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer                    /* one byte length field */
10065f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer                    p_t1t->ndef_msg_len = len;
1007ad56d684259f706b7c0ae5ad9c23adb4f2926817Chris Lattner                    bytes_count  = p_t1t->ndef_msg_len;
10085f1b9e689fa5c101512aef99225f2afea1673449Douglas Gregor                    tlv_detect_state     = RW_T1T_SUBSTATE_WAIT_READ_TLV_VALUE;
10091060aff23f72135f8b50034a1e80f16725ebc56cTed Kremenek                }
10105f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer                break;
10111eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
10125f1b9e689fa5c101512aef99225f2afea1673449Douglas Gregor            case TAG_PROPRIETARY_TLV:
10135f1b9e689fa5c101512aef99225f2afea1673449Douglas Gregor                if (len == 0xFF)
10145f1b9e689fa5c101512aef99225f2afea1673449Douglas Gregor                {
10157d5c2f241c74e5f8d9ec492e8f9f268e5e9ae41fDouglas Gregor                    /* The next two bytes constitute length bytes */
10167d5c2f241c74e5f8d9ec492e8f9f268e5e9ae41fDouglas Gregor                    tlv_detect_state     = RW_T1T_SUBSTATE_WAIT_READ_TLV_LEN0;
10171eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump                }
10187d5c2f241c74e5f8d9ec492e8f9f268e5e9ae41fDouglas Gregor                else
10191eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump                {
1020ad56d684259f706b7c0ae5ad9c23adb4f2926817Chris Lattner                    /* one byte length field */
1021ad56d684259f706b7c0ae5ad9c23adb4f2926817Chris Lattner                    bytes_count  = len;
10225f1b9e689fa5c101512aef99225f2afea1673449Douglas Gregor                    tlv_detect_state     = RW_T1T_SUBSTATE_WAIT_READ_TLV_VALUE;
10235f1b9e689fa5c101512aef99225f2afea1673449Douglas Gregor                }
10241eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump                break;
102595c225de9fa3d79f70ef5008c0279580a7d9dcadJohn McCall            }
102695c225de9fa3d79f70ef5008c0279580a7d9dcadJohn McCall            offset++;
10277d5c2f241c74e5f8d9ec492e8f9f268e5e9ae41fDouglas Gregor            break;
1028b5a69586f1b8855ee4c1f0bb7a8f0ff4fe32ce09Steve Naroff
102995c225de9fa3d79f70ef5008c0279580a7d9dcadJohn McCall        case RW_T1T_SUBSTATE_WAIT_READ_TLV_LEN0:
103095c225de9fa3d79f70ef5008c0279580a7d9dcadJohn McCall            switch (found_tlv)
103195c225de9fa3d79f70ef5008c0279580a7d9dcadJohn McCall            {
103295c225de9fa3d79f70ef5008c0279580a7d9dcadJohn McCall            case TAG_LOCK_CTRL_TLV:
103395c225de9fa3d79f70ef5008c0279580a7d9dcadJohn McCall            case TAG_MEM_CTRL_TLV:
103495c225de9fa3d79f70ef5008c0279580a7d9dcadJohn McCall
103595c225de9fa3d79f70ef5008c0279580a7d9dcadJohn McCall                len = p_readbytes[offset];
1036ad56d684259f706b7c0ae5ad9c23adb4f2926817Chris Lattner                if (len == T1T_DEFAULT_TLV_LEN)
1037ad56d684259f706b7c0ae5ad9c23adb4f2926817Chris Lattner                {
1038ad56d684259f706b7c0ae5ad9c23adb4f2926817Chris Lattner                    /* Valid Lock control TLV */
10391eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump                    tlv_detect_state = RW_T1T_SUBSTATE_WAIT_READ_TLV_VALUE;
10401eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump                    bytes_count = T1T_DEFAULT_TLV_LEN;
10411eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump                }
10425f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer                else if (  ((p_t1t->tlv_detect == TAG_LOCK_CTRL_TLV) && (p_t1t->num_lockbytes > 0))
10435f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer                         ||((p_t1t->tlv_detect == TAG_MEM_CTRL_TLV) && (p_t1t->num_mem_tlvs > 0))  )
10441eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump                {
10458297777fbe19c4d39e8a70c55346474868055fa1Ted Kremenek                    found = TRUE;
10468297777fbe19c4d39e8a70c55346474868055fa1Ted Kremenek                }
10478297777fbe19c4d39e8a70c55346474868055fa1Ted Kremenek                else
10485f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer                {
10495f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer                    failed = TRUE;
10505f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer                }
10515f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer                break;
10525f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
10535f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer            case TAG_NDEF_TLV:
1054507f2d5811bd7da1a4d9d2f4960f32177dfab9deSteve Naroff            case TAG_PROPRIETARY_TLV:
10555f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer                /* The first length byte */
1056507f2d5811bd7da1a4d9d2f4960f32177dfab9deSteve Naroff                bytes_count  = (UINT8) p_readbytes[offset];
10571eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump                tlv_detect_state     = RW_T1T_SUBSTATE_WAIT_READ_TLV_LEN1;
1058d921cf976b4769af8d06d6763a2547dadf7940abDouglas Gregor                break;
1059d921cf976b4769af8d06d6763a2547dadf7940abDouglas Gregor            }
1060d921cf976b4769af8d06d6763a2547dadf7940abDouglas Gregor            offset++;
1061d921cf976b4769af8d06d6763a2547dadf7940abDouglas Gregor            break;
1062d921cf976b4769af8d06d6763a2547dadf7940abDouglas Gregor
1063d921cf976b4769af8d06d6763a2547dadf7940abDouglas Gregor        case RW_T1T_SUBSTATE_WAIT_READ_TLV_LEN1:
10641eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump            bytes_count  = (bytes_count << 8) + p_readbytes[offset];
10651eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump            if (found_tlv == TAG_NDEF_TLV)
1066507f2d5811bd7da1a4d9d2f4960f32177dfab9deSteve Naroff            {
1067861ce3178c70cfb0fa50baf685e1ad363538eaa9Douglas Gregor                p_t1t->ndef_msg_len = bytes_count;
10681eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump            }
10691eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump            tlv_detect_state     = RW_T1T_SUBSTATE_WAIT_READ_TLV_VALUE;
10705f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer            offset++;
10715f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer            break;
10721eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
10738297777fbe19c4d39e8a70c55346474868055fa1Ted Kremenek        case RW_T1T_SUBSTATE_WAIT_READ_TLV_VALUE:
10748297777fbe19c4d39e8a70c55346474868055fa1Ted Kremenek            switch (found_tlv)
10758297777fbe19c4d39e8a70c55346474868055fa1Ted Kremenek            {
10765f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer            case TAG_NDEF_TLV:
10775f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer                if ((bytes_count == p_t1t->ndef_msg_len) && (p_t1t->tlv_detect == TAG_NDEF_TLV))
10785f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer                {
10795f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer                    /* The first byte offset after length field */
10805f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer                    p_t1t->ndef_msg_offset = offset + p_t1t->work_offset;
1081507f2d5811bd7da1a4d9d2f4960f32177dfab9deSteve Naroff                }
10825f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer                if (bytes_count > 0)
1083507f2d5811bd7da1a4d9d2f4960f32177dfab9deSteve Naroff                    bytes_count--;
10841eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
1085025452fa0eda63e150cfaeebe64f0a19c96b3a06Douglas Gregor                if (p_t1t->tlv_detect == TAG_NDEF_TLV)
1086025452fa0eda63e150cfaeebe64f0a19c96b3a06Douglas Gregor                {
1087025452fa0eda63e150cfaeebe64f0a19c96b3a06Douglas Gregor                    if (p_t1t->ndef_msg_len > 0)
1088025452fa0eda63e150cfaeebe64f0a19c96b3a06Douglas Gregor                    {
1089025452fa0eda63e150cfaeebe64f0a19c96b3a06Douglas Gregor                        rw_t1t_update_tag_state ();
1090025452fa0eda63e150cfaeebe64f0a19c96b3a06Douglas Gregor                    }
1091507f2d5811bd7da1a4d9d2f4960f32177dfab9deSteve Naroff                    else
1092b5a69586f1b8855ee4c1f0bb7a8f0ff4fe32ce09Steve Naroff                    {
10931eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump                        p_t1t->tag_attribute = RW_T1_TAG_ATTRB_INITIALIZED_NDEF;
10941eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump                    }
10955f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer                    found = TRUE;
10965f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer                }
10971eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump                else if (bytes_count == 0)
10988297777fbe19c4d39e8a70c55346474868055fa1Ted Kremenek                {
10998297777fbe19c4d39e8a70c55346474868055fa1Ted Kremenek                    tlv_detect_state = RW_T1T_SUBSTATE_WAIT_TLV_DETECT;
11008297777fbe19c4d39e8a70c55346474868055fa1Ted Kremenek                }
11015f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer                break;
11025f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
11035f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer            case TAG_LOCK_CTRL_TLV:
1104c8edf6bd5f76bf50411d037c83d36847edfa68f0Chris Lattner                bytes_count--;
1105c8edf6bd5f76bf50411d037c83d36847edfa68f0Chris Lattner                if (  (p_t1t->tlv_detect == TAG_LOCK_CTRL_TLV)
1106c8edf6bd5f76bf50411d037c83d36847edfa68f0Chris Lattner                    ||(p_t1t->tlv_detect == TAG_NDEF_TLV)  )
1107c8edf6bd5f76bf50411d037c83d36847edfa68f0Chris Lattner                {
1108c8edf6bd5f76bf50411d037c83d36847edfa68f0Chris Lattner                    tlv_value[2 - bytes_count] = p_readbytes[offset];
1109c8edf6bd5f76bf50411d037c83d36847edfa68f0Chris Lattner                    if (bytes_count == 0)
1110c8edf6bd5f76bf50411d037c83d36847edfa68f0Chris Lattner                    {
1111c8edf6bd5f76bf50411d037c83d36847edfa68f0Chris Lattner                        if (p_t1t->num_lock_tlvs < RW_T1T_MAX_LOCK_TLVS)
11125f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer                        {
11135f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer                            p_t1t->lock_tlv[p_t1t->num_lock_tlvs].offset   = (tlv_value[0] >> 4) & 0x0F;
11141060aff23f72135f8b50034a1e80f16725ebc56cTed Kremenek                            p_t1t->lock_tlv[p_t1t->num_lock_tlvs].offset  *= (UINT8) tags_pow (2, tlv_value[2] & 0x0F);
1115507f2d5811bd7da1a4d9d2f4960f32177dfab9deSteve Naroff                            p_t1t->lock_tlv[p_t1t->num_lock_tlvs].offset  += tlv_value[0] & 0x0F;
11165077c3876beeaed32280af88244e8050078619a8Douglas Gregor                            p_t1t->lock_tlv[p_t1t->num_lock_tlvs].bytes_locked_per_bit = (UINT8) tags_pow (2, ((tlv_value[2] & 0xF0) >> 4));
11175077c3876beeaed32280af88244e8050078619a8Douglas Gregor                            p_t1t->lock_tlv[p_t1t->num_lock_tlvs].num_bits = tlv_value[1];
11185f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer                            count = tlv_value[1] / 8 + ((tlv_value[1] % 8 != 0)? 1:0);
11195077c3876beeaed32280af88244e8050078619a8Douglas Gregor                            xx = 0;
112025a0fe2a99aaf2d1bf5bdfdae7ab11e2a5e7622fAbramo Bagnara                            while (xx < count)
11215077c3876beeaed32280af88244e8050078619a8Douglas Gregor                            {
11225077c3876beeaed32280af88244e8050078619a8Douglas Gregor                                if (p_t1t->num_lockbytes < RW_T1T_MAX_LOCK_BYTES)
11235077c3876beeaed32280af88244e8050078619a8Douglas Gregor                                {
11245077c3876beeaed32280af88244e8050078619a8Douglas Gregor                                    p_t1t->lockbyte[p_t1t->num_lockbytes].tlv_index = p_t1t->num_lock_tlvs;
11250de9d8857b715c2f45c987651f4ce06d73330d93Douglas Gregor                                    p_t1t->lockbyte[p_t1t->num_lockbytes].byte_index = xx;
11260de9d8857b715c2f45c987651f4ce06d73330d93Douglas Gregor                                    p_t1t->lockbyte[p_t1t->num_lockbytes].b_lock_read = FALSE;
11270de9d8857b715c2f45c987651f4ce06d73330d93Douglas Gregor                                    p_t1t->num_lockbytes++;
11280de9d8857b715c2f45c987651f4ce06d73330d93Douglas Gregor                                }
11291060aff23f72135f8b50034a1e80f16725ebc56cTed Kremenek                                else
11301060aff23f72135f8b50034a1e80f16725ebc56cTed Kremenek                                    RW_TRACE_ERROR1 ("T1T Buffer overflow error. Max supported lock bytes=0x%02X", RW_T1T_MAX_LOCK_BYTES);
11310de9d8857b715c2f45c987651f4ce06d73330d93Douglas Gregor                                xx++;
11320de9d8857b715c2f45c987651f4ce06d73330d93Douglas Gregor                            }
11330de9d8857b715c2f45c987651f4ce06d73330d93Douglas Gregor                            p_t1t->num_lock_tlvs++;
11340de9d8857b715c2f45c987651f4ce06d73330d93Douglas Gregor                            rw_t1t_update_attributes ();
1135b5a69586f1b8855ee4c1f0bb7a8f0ff4fe32ce09Steve Naroff                        }
11365077c3876beeaed32280af88244e8050078619a8Douglas Gregor                        else
11375077c3876beeaed32280af88244e8050078619a8Douglas Gregor                            RW_TRACE_ERROR1 ("T1T Buffer overflow error. Max supported lock tlvs=0x%02X", RW_T1T_MAX_LOCK_TLVS);
11385077c3876beeaed32280af88244e8050078619a8Douglas Gregor
11395077c3876beeaed32280af88244e8050078619a8Douglas Gregor                        tlv_detect_state = RW_T1T_SUBSTATE_WAIT_TLV_DETECT;
11405077c3876beeaed32280af88244e8050078619a8Douglas Gregor                    }
11415077c3876beeaed32280af88244e8050078619a8Douglas Gregor                }
11425077c3876beeaed32280af88244e8050078619a8Douglas Gregor                else
11435077c3876beeaed32280af88244e8050078619a8Douglas Gregor                {
1144507f2d5811bd7da1a4d9d2f4960f32177dfab9deSteve Naroff                    if (bytes_count == 0)
11451eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump                    {
11461eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump                        tlv_detect_state = RW_T1T_SUBSTATE_WAIT_TLV_DETECT;
11471eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump                    }
11485f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer                }
11495f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer                break;
11501eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
11518297777fbe19c4d39e8a70c55346474868055fa1Ted Kremenek            case TAG_MEM_CTRL_TLV:
11528297777fbe19c4d39e8a70c55346474868055fa1Ted Kremenek                bytes_count--;
11538297777fbe19c4d39e8a70c55346474868055fa1Ted Kremenek                if (  (p_t1t->tlv_detect == TAG_MEM_CTRL_TLV)
11545f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer                    ||(p_t1t->tlv_detect == TAG_NDEF_TLV)  )
11555f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer                {
1156fe795956194141c91ae555985c9b930595bff43fChris Lattner                    tlv_value[2 - bytes_count] = p_readbytes[offset];
1157fe795956194141c91ae555985c9b930595bff43fChris Lattner                    if (bytes_count == 0)
1158fe795956194141c91ae555985c9b930595bff43fChris Lattner                    {
1159fe795956194141c91ae555985c9b930595bff43fChris Lattner                        if (p_t1t->num_mem_tlvs >= RW_T1T_MAX_MEM_TLVS)
11606a0ef4b83c91a6d6d5acb4ed5577c4659fe022a3Anders Carlsson                        {
1161b235fc2cf37621c7fc6511bb2b8788c95f9fb9fcAnders Carlsson                            RW_TRACE_ERROR0 ("rw_t1t_handle_tlv_detect_rsp - Maximum buffer allocated for Memory tlv has reached");
1162dfab34a696d1dba8622248c31aaf605906cb6109Anders Carlsson                            failed  = TRUE;
116339c47b56f45437bbc49c9568b7308a400234a730Anders Carlsson                        }
11643b11fd3b52e7b88233c602407c151d07cb093e75Mike Stump                        else
11651eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump                        {
1166b235fc2cf37621c7fc6511bb2b8788c95f9fb9fcAnders Carlsson                            /* Extract dynamic reserved bytes */
1167b235fc2cf37621c7fc6511bb2b8788c95f9fb9fcAnders Carlsson                            p_t1t->mem_tlv[p_t1t->num_mem_tlvs].offset   = (tlv_value[0] >> 4) & 0x0F;
1168966146e89141804ff6492739a2a6e6592ca671c7Anders Carlsson                            p_t1t->mem_tlv[p_t1t->num_mem_tlvs].offset  *= (UINT8) tags_pow (2, tlv_value[2] & 0x0F);
11691eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump                            p_t1t->mem_tlv[p_t1t->num_mem_tlvs].offset  += tlv_value[0] & 0x0F;
1170966146e89141804ff6492739a2a6e6592ca671c7Anders Carlsson                            p_t1t->mem_tlv[p_t1t->num_mem_tlvs].num_bytes = tlv_value[1];
1171966146e89141804ff6492739a2a6e6592ca671c7Anders Carlsson                            p_t1t->num_mem_tlvs++;
1172966146e89141804ff6492739a2a6e6592ca671c7Anders Carlsson                            rw_t1t_update_attributes ();
1173966146e89141804ff6492739a2a6e6592ca671c7Anders Carlsson                            tlv_detect_state = RW_T1T_SUBSTATE_WAIT_TLV_DETECT;
1174966146e89141804ff6492739a2a6e6592ca671c7Anders Carlsson                        }
1175c302113179a1c2b1254224ea9b6f5316ceeb375cSean Hunt                    }
1176fe795956194141c91ae555985c9b930595bff43fChris Lattner                }
1177c302113179a1c2b1254224ea9b6f5316ceeb375cSean Hunt                else
1178966146e89141804ff6492739a2a6e6592ca671c7Anders Carlsson                {
1179ff93dbd887e40588ed55d135037bb9287488b285Anders Carlsson                    if (bytes_count == 0)
1180db6ed1786bf460e1143f67d14bf2d71ad9856f81Chris Lattner                    {
1181db6ed1786bf460e1143f67d14bf2d71ad9856f81Chris Lattner                        tlv_detect_state = RW_T1T_SUBSTATE_WAIT_TLV_DETECT;
1182b235fc2cf37621c7fc6511bb2b8788c95f9fb9fcAnders Carlsson                    }
1183cd7d5a9dc558178ed7a66032f888781b3c592e4fDouglas Gregor                }
1184c302113179a1c2b1254224ea9b6f5316ceeb375cSean Hunt                break;
1185966146e89141804ff6492739a2a6e6592ca671c7Anders Carlsson
1186cd7d5a9dc558178ed7a66032f888781b3c592e4fDouglas Gregor            case TAG_PROPRIETARY_TLV:
1187cd7d5a9dc558178ed7a66032f888781b3c592e4fDouglas Gregor                bytes_count--;
1188cd7d5a9dc558178ed7a66032f888781b3c592e4fDouglas Gregor                if (p_t1t->tlv_detect == TAG_PROPRIETARY_TLV)
1189cd7d5a9dc558178ed7a66032f888781b3c592e4fDouglas Gregor                    found = TRUE;
1190cd7d5a9dc558178ed7a66032f888781b3c592e4fDouglas Gregor                else
1191cd7d5a9dc558178ed7a66032f888781b3c592e4fDouglas Gregor                {
119239c47b56f45437bbc49c9568b7308a400234a730Anders Carlsson                    if (bytes_count == 0)
1193cd7d5a9dc558178ed7a66032f888781b3c592e4fDouglas Gregor                    {
1194dfab34a696d1dba8622248c31aaf605906cb6109Anders Carlsson                        tlv_detect_state = RW_T1T_SUBSTATE_WAIT_TLV_DETECT;
11956ffe643322949dd776285a6df60d3578f3918be4Chris Lattner                    }
11963b11fd3b52e7b88233c602407c151d07cb093e75Mike Stump                }
11973b11fd3b52e7b88233c602407c151d07cb093e75Mike Stump                break;
1198dfab34a696d1dba8622248c31aaf605906cb6109Anders Carlsson            }
1199458cd9c8a79b25b87dcea43c9d97a4c59f194799Chris Lattner            offset++;
1200458cd9c8a79b25b87dcea43c9d97a4c59f194799Chris Lattner            break;
1201458cd9c8a79b25b87dcea43c9d97a4c59f194799Chris Lattner        }
1202458cd9c8a79b25b87dcea43c9d97a4c59f194799Chris Lattner    }
1203cd7d5a9dc558178ed7a66032f888781b3c592e4fDouglas Gregor
1204cd7d5a9dc558178ed7a66032f888781b3c592e4fDouglas Gregor    p_t1t->work_offset += bytes_read;
1205458cd9c8a79b25b87dcea43c9d97a4c59f194799Chris Lattner
1206458cd9c8a79b25b87dcea43c9d97a4c59f194799Chris Lattner    /* NDEF/Lock/Mem TLV to be found in segment 0, if not assume detection failed */
1207458cd9c8a79b25b87dcea43c9d97a4c59f194799Chris Lattner    if (!found && !failed)
1208458cd9c8a79b25b87dcea43c9d97a4c59f194799Chris Lattner    {
1209458cd9c8a79b25b87dcea43c9d97a4c59f194799Chris Lattner        if (  ((p_t1t->tlv_detect == TAG_LOCK_CTRL_TLV) && (p_t1t->num_lockbytes > 0))
1210458cd9c8a79b25b87dcea43c9d97a4c59f194799Chris Lattner            ||((p_t1t->tlv_detect == TAG_MEM_CTRL_TLV) && (p_t1t->num_mem_tlvs > 0))  )
1211458cd9c8a79b25b87dcea43c9d97a4c59f194799Chris Lattner        {
1212458cd9c8a79b25b87dcea43c9d97a4c59f194799Chris Lattner            found = TRUE;
1213458cd9c8a79b25b87dcea43c9d97a4c59f194799Chris Lattner        }
1214458cd9c8a79b25b87dcea43c9d97a4c59f194799Chris Lattner        else
1215458cd9c8a79b25b87dcea43c9d97a4c59f194799Chris Lattner        {
1216458cd9c8a79b25b87dcea43c9d97a4c59f194799Chris Lattner            if (p_t1t->tlv_detect == TAG_NDEF_TLV)
1217458cd9c8a79b25b87dcea43c9d97a4c59f194799Chris Lattner            {
1218458cd9c8a79b25b87dcea43c9d97a4c59f194799Chris Lattner                p_t1t->tag_attribute = RW_T1_TAG_ATTRB_INITIALIZED;
1219458cd9c8a79b25b87dcea43c9d97a4c59f194799Chris Lattner            }
1220458cd9c8a79b25b87dcea43c9d97a4c59f194799Chris Lattner            failed = TRUE;
1221458cd9c8a79b25b87dcea43c9d97a4c59f194799Chris Lattner        }
1222458cd9c8a79b25b87dcea43c9d97a4c59f194799Chris Lattner    }
1223458cd9c8a79b25b87dcea43c9d97a4c59f194799Chris Lattner
12241eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
1225458cd9c8a79b25b87dcea43c9d97a4c59f194799Chris Lattner    status = failed ? NFC_STATUS_FAILED : NFC_STATUS_OK;
1226458cd9c8a79b25b87dcea43c9d97a4c59f194799Chris Lattner    return status;
12271eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump}
1228458cd9c8a79b25b87dcea43c9d97a4c59f194799Chris Lattner
1229458cd9c8a79b25b87dcea43c9d97a4c59f194799Chris Lattner/*******************************************************************************
1230458cd9c8a79b25b87dcea43c9d97a4c59f194799Chris Lattner**
1231458cd9c8a79b25b87dcea43c9d97a4c59f194799Chris Lattner** Function         rw_t1t_handle_ndef_rall_rsp
1232458cd9c8a79b25b87dcea43c9d97a4c59f194799Chris Lattner**
1233458cd9c8a79b25b87dcea43c9d97a4c59f194799Chris Lattner** Description      Handle response to RALL command sent while reading an
1234458cd9c8a79b25b87dcea43c9d97a4c59f194799Chris Lattner**                  NDEF message
1235458cd9c8a79b25b87dcea43c9d97a4c59f194799Chris Lattner**
1236458cd9c8a79b25b87dcea43c9d97a4c59f194799Chris Lattner** Returns          NFC_STATUS_CONTINUE, if NDEF read operation is not complete
12371eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump**                  NFC_STATUS_OK, if NDEF read is successfull
1238458cd9c8a79b25b87dcea43c9d97a4c59f194799Chris Lattner**                  NFC_STATUS_FAILED,if NDEF read failed
1239458cd9c8a79b25b87dcea43c9d97a4c59f194799Chris Lattner**
1240458cd9c8a79b25b87dcea43c9d97a4c59f194799Chris Lattner*******************************************************************************/
1241458cd9c8a79b25b87dcea43c9d97a4c59f194799Chris Lattnerstatic tNFC_STATUS rw_t1t_handle_ndef_rall_rsp (void)
1242458cd9c8a79b25b87dcea43c9d97a4c59f194799Chris Lattner{
1243458cd9c8a79b25b87dcea43c9d97a4c59f194799Chris Lattner    tRW_T1T_CB  *p_t1t  = &rw_cb.tcb.t1t;
1244458cd9c8a79b25b87dcea43c9d97a4c59f194799Chris Lattner    tNFC_STATUS status  = NFC_STATUS_CONTINUE;
12451eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump    UINT8       count;
1246458cd9c8a79b25b87dcea43c9d97a4c59f194799Chris Lattner    UINT8       adds;
1247458cd9c8a79b25b87dcea43c9d97a4c59f194799Chris Lattner
1248458cd9c8a79b25b87dcea43c9d97a4c59f194799Chris Lattner    count               = (UINT8) p_t1t->ndef_msg_offset;
1249458cd9c8a79b25b87dcea43c9d97a4c59f194799Chris Lattner    p_t1t->work_offset  = 0;
12501eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump    p_t1t->segment      = 0;
1251fb5058ef67c054296c88db18ab1b3717845cb71dChris Lattner
1252fb5058ef67c054296c88db18ab1b3717845cb71dChris Lattner    while (count < T1T_STATIC_SIZE && p_t1t->work_offset < p_t1t->ndef_msg_len)
12531eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump    {
12541eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump        if (rw_t1t_is_lock_reserved_otp_byte (count) == FALSE)
1255b327793860737d1c103a73aeda8057dd628a101dChris Lattner        {
1256b327793860737d1c103a73aeda8057dd628a101dChris Lattner            p_t1t->p_ndef_buffer[p_t1t->work_offset] = p_t1t->mem[count];
1257b235fc2cf37621c7fc6511bb2b8788c95f9fb9fcAnders Carlsson            p_t1t->work_offset++;
1258ce2fc3a343ea6098a96d587071cee7299f11957aTed Kremenek        }
1259ff93dbd887e40588ed55d135037bb9287488b285Anders Carlsson        count++;
1260ce2fc3a343ea6098a96d587071cee7299f11957aTed Kremenek    }
1261ce2fc3a343ea6098a96d587071cee7299f11957aTed Kremenek    if (p_t1t->work_offset != p_t1t->ndef_msg_len)
1262ce2fc3a343ea6098a96d587071cee7299f11957aTed Kremenek    {
1263ff93dbd887e40588ed55d135037bb9287488b285Anders Carlsson        if ((p_t1t->hr[0] & 0x0F) != 1)
1264ff93dbd887e40588ed55d135037bb9287488b285Anders Carlsson        {
1265ff93dbd887e40588ed55d135037bb9287488b285Anders Carlsson            if (p_t1t->work_offset == 0)
1266c302113179a1c2b1254224ea9b6f5316ceeb375cSean Hunt                return NFC_STATUS_FAILED;
1267ff93dbd887e40588ed55d135037bb9287488b285Anders Carlsson
1268ff93dbd887e40588ed55d135037bb9287488b285Anders Carlsson            else
1269ff93dbd887e40588ed55d135037bb9287488b285Anders Carlsson            {
1270b327793860737d1c103a73aeda8057dd628a101dChris Lattner                p_t1t->block_read   = T1T_STATIC_BLOCKS + 1;
1271b327793860737d1c103a73aeda8057dd628a101dChris Lattner                p_t1t->segment++;
1272b327793860737d1c103a73aeda8057dd628a101dChris Lattner            }
1273acb6bcb442936f3c14126fdd473307c17647cb84Anders Carlsson            if (p_t1t->ndef_msg_len - p_t1t->work_offset <= 8)
12741eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump            {
1275b327793860737d1c103a73aeda8057dd628a101dChris Lattner                if ((status = rw_t1t_send_dyn_cmd (T1T_CMD_READ8, p_t1t->block_read, NULL)) == NFC_STATUS_OK)
1276ce2fc3a343ea6098a96d587071cee7299f11957aTed Kremenek                {
1277ce2fc3a343ea6098a96d587071cee7299f11957aTed Kremenek                    p_t1t->tlv_detect  = TAG_NDEF_TLV;
1278b327793860737d1c103a73aeda8057dd628a101dChris Lattner                    p_t1t->state    = RW_T1T_STATE_READ_NDEF;
1279b327793860737d1c103a73aeda8057dd628a101dChris Lattner                    status          = NFC_STATUS_CONTINUE;
1280b327793860737d1c103a73aeda8057dd628a101dChris Lattner                }
12811eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump            }
1282ce2fc3a343ea6098a96d587071cee7299f11957aTed Kremenek            else
12831eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump            {
1284b327793860737d1c103a73aeda8057dd628a101dChris Lattner                /* send RSEG command */
1285b327793860737d1c103a73aeda8057dd628a101dChris Lattner                RW_T1T_BLD_ADDS ((adds), (p_t1t->segment));
1286b327793860737d1c103a73aeda8057dd628a101dChris Lattner                if ((status = rw_t1t_send_dyn_cmd (T1T_CMD_RSEG, adds, NULL)) == NFC_STATUS_OK)
12871eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump                {
1288b327793860737d1c103a73aeda8057dd628a101dChris Lattner                    p_t1t->state    = RW_T1T_STATE_READ_NDEF;
1289b327793860737d1c103a73aeda8057dd628a101dChris Lattner                    status          = NFC_STATUS_CONTINUE;
1290b327793860737d1c103a73aeda8057dd628a101dChris Lattner                }
1291b327793860737d1c103a73aeda8057dd628a101dChris Lattner            }
1292b327793860737d1c103a73aeda8057dd628a101dChris Lattner        }
1293b327793860737d1c103a73aeda8057dd628a101dChris Lattner        else
12941eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump        {
129585759278332404e96d4bb89d0e976e46158cd026Chris Lattner            RW_TRACE_ERROR1 ("RW_T1tReadNDef - Invalid NDEF len: %u or NDEF corrupted", p_t1t->ndef_msg_len);
129685759278332404e96d4bb89d0e976e46158cd026Chris Lattner            status = NFC_STATUS_FAILED;
129785759278332404e96d4bb89d0e976e46158cd026Chris Lattner        }
12981eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump    }
1299b327793860737d1c103a73aeda8057dd628a101dChris Lattner    else
13001eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump    {
13011eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump        status = NFC_STATUS_OK;
13021eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump    }
1303ff93dbd887e40588ed55d135037bb9287488b285Anders Carlsson    return status;
1304ce2fc3a343ea6098a96d587071cee7299f11957aTed Kremenek}
1305ce2fc3a343ea6098a96d587071cee7299f11957aTed Kremenek
13061eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump/*******************************************************************************
1307ff93dbd887e40588ed55d135037bb9287488b285Anders Carlsson**
1308ff93dbd887e40588ed55d135037bb9287488b285Anders Carlsson** Function         rw_t1t_handle_ndef_read_rsp
1309ff93dbd887e40588ed55d135037bb9287488b285Anders Carlsson**
1310ff93dbd887e40588ed55d135037bb9287488b285Anders Carlsson** Description      Handle response to commands sent while reading an
1311ff93dbd887e40588ed55d135037bb9287488b285Anders Carlsson**                  NDEF message
1312ff93dbd887e40588ed55d135037bb9287488b285Anders Carlsson**
1313ff93dbd887e40588ed55d135037bb9287488b285Anders Carlsson** Returns          NFC_STATUS_CONTINUE, if tlv read is not yet complete
1314b327793860737d1c103a73aeda8057dd628a101dChris Lattner**                  NFC_STATUS_OK, if tlv read is complete & success
1315b327793860737d1c103a73aeda8057dd628a101dChris Lattner**                  NFC_STATUS_FAILED,if tlv read failed
1316acb6bcb442936f3c14126fdd473307c17647cb84Anders Carlsson**
13171eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump*******************************************************************************/
1318b327793860737d1c103a73aeda8057dd628a101dChris Lattnerstatic tNFC_STATUS rw_t1t_handle_ndef_read_rsp (UINT8 *p_data)
1319ce2fc3a343ea6098a96d587071cee7299f11957aTed Kremenek{
1320ce2fc3a343ea6098a96d587071cee7299f11957aTed Kremenek    tNFC_STATUS         ndef_status = NFC_STATUS_CONTINUE;
1321b327793860737d1c103a73aeda8057dd628a101dChris Lattner    tRW_T1T_CB          *p_t1t      = &rw_cb.tcb.t1t;
1322ce2fc3a343ea6098a96d587071cee7299f11957aTed Kremenek    UINT8               index;
1323ce2fc3a343ea6098a96d587071cee7299f11957aTed Kremenek    UINT8               adds;
13241eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump    tT1T_CMD_RSP_INFO   *p_cmd_rsp_info = (tT1T_CMD_RSP_INFO *) rw_cb.tcb.t1t.p_cmd_rsp_info;
1325ce2fc3a343ea6098a96d587071cee7299f11957aTed Kremenek
13261eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump    /* The Response received could be for Read8 or Read Segment command */
1327b327793860737d1c103a73aeda8057dd628a101dChris Lattner    switch(p_cmd_rsp_info->opcode)
1328b327793860737d1c103a73aeda8057dd628a101dChris Lattner    {
1329b327793860737d1c103a73aeda8057dd628a101dChris Lattner    case T1T_CMD_READ8:
1330cd7d5a9dc558178ed7a66032f888781b3c592e4fDouglas Gregor        if (p_t1t->work_offset == 0)
1331acb6bcb442936f3c14126fdd473307c17647cb84Anders Carlsson        {
1332ff93dbd887e40588ed55d135037bb9287488b285Anders Carlsson            index = p_t1t->ndef_msg_offset % T1T_BLOCK_SIZE;
1333fdba9c069023f686e2608affde02c82131ee1cf8Anders Carlsson        }
1334fdba9c069023f686e2608affde02c82131ee1cf8Anders Carlsson        else
1335fdba9c069023f686e2608affde02c82131ee1cf8Anders Carlsson        {
1336c302113179a1c2b1254224ea9b6f5316ceeb375cSean Hunt            index = 0;
1337fdba9c069023f686e2608affde02c82131ee1cf8Anders Carlsson        }
1338fdba9c069023f686e2608affde02c82131ee1cf8Anders Carlsson        p_t1t->segment = (p_t1t->block_read * T1T_BLOCK_SIZE)/T1T_SEGMENT_SIZE;
1339cd7d5a9dc558178ed7a66032f888781b3c592e4fDouglas Gregor        while (index < T1T_BLOCK_SIZE && p_t1t->work_offset < p_t1t->ndef_msg_len)
134010ca96ae9aed6906c3302403ef1a146a8d4c6b74Chris Lattner        {
13411eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump            if (rw_t1t_is_lock_reserved_otp_byte ((UINT16) ((p_t1t->block_read * T1T_BLOCK_SIZE) + index)) == FALSE)
134210ca96ae9aed6906c3302403ef1a146a8d4c6b74Chris Lattner            {
134310ca96ae9aed6906c3302403ef1a146a8d4c6b74Chris Lattner                p_t1t->p_ndef_buffer[p_t1t->work_offset] = p_data[index];
134410ca96ae9aed6906c3302403ef1a146a8d4c6b74Chris Lattner                p_t1t->work_offset++;
1345acb6bcb442936f3c14126fdd473307c17647cb84Anders Carlsson            }
134610ca96ae9aed6906c3302403ef1a146a8d4c6b74Chris Lattner            index++;
1347966146e89141804ff6492739a2a6e6592ca671c7Anders Carlsson        }
1348b235fc2cf37621c7fc6511bb2b8788c95f9fb9fcAnders Carlsson        break;
1349d04c6e23f2e10eeb9936778d67f4a1c4a14cc4f6Anders Carlsson
1350cd7d5a9dc558178ed7a66032f888781b3c592e4fDouglas Gregor    case T1T_CMD_RSEG:
1351fe795956194141c91ae555985c9b930595bff43fChris Lattner        if (p_t1t->work_offset == 0)
1352fe795956194141c91ae555985c9b930595bff43fChris Lattner        {
1353fe795956194141c91ae555985c9b930595bff43fChris Lattner            index = p_t1t->ndef_msg_offset % T1T_SEGMENT_SIZE;
13541eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump        }
1355fe795956194141c91ae555985c9b930595bff43fChris Lattner        else
1356fe795956194141c91ae555985c9b930595bff43fChris Lattner        {
13571eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump            index = 0;
1358ec2f7dccb1f30ae137f74e764e44c2332b0a2ec0Ted Kremenek        }
13591eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump        p_t1t->block_read = ((p_t1t->segment + 1) * T1T_BLOCKS_PER_SEGMENT) - 1;
1360ce2fc3a343ea6098a96d587071cee7299f11957aTed Kremenek
1361ce2fc3a343ea6098a96d587071cee7299f11957aTed Kremenek        while (index < T1T_SEGMENT_SIZE && p_t1t->work_offset < p_t1t->ndef_msg_len)
13621eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump        {
1363ce2fc3a343ea6098a96d587071cee7299f11957aTed Kremenek            if (rw_t1t_is_lock_reserved_otp_byte ((UINT16) (index)) == FALSE)
1364966146e89141804ff6492739a2a6e6592ca671c7Anders Carlsson            {
1365ce2fc3a343ea6098a96d587071cee7299f11957aTed Kremenek                p_t1t->p_ndef_buffer[p_t1t->work_offset] = p_data[index];
13661eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump                p_t1t->work_offset++;
1367ce2fc3a343ea6098a96d587071cee7299f11957aTed Kremenek            }
1368966146e89141804ff6492739a2a6e6592ca671c7Anders Carlsson            index++;
1369ce2fc3a343ea6098a96d587071cee7299f11957aTed Kremenek        }
13701eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump        break;
1371ce2fc3a343ea6098a96d587071cee7299f11957aTed Kremenek
1372966146e89141804ff6492739a2a6e6592ca671c7Anders Carlsson    default:
1373ce2fc3a343ea6098a96d587071cee7299f11957aTed Kremenek        break;
13741eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump    }
1375ce2fc3a343ea6098a96d587071cee7299f11957aTed Kremenek    if (p_t1t->work_offset < p_t1t->ndef_msg_len)
1376966146e89141804ff6492739a2a6e6592ca671c7Anders Carlsson    {
1377d59a5bd0ab7821a643c540df8c84c70fef76a1c2Ted Kremenek        if ((p_t1t->hr[0] & 0x0F) != 1)
13781eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump        {
1379ec2f7dccb1f30ae137f74e764e44c2332b0a2ec0Ted Kremenek            if ((p_t1t->ndef_msg_len - p_t1t->work_offset) <= T1T_BLOCK_SIZE)
13801eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump            {
1381ce2fc3a343ea6098a96d587071cee7299f11957aTed Kremenek                p_t1t->block_read++;
1382ce2fc3a343ea6098a96d587071cee7299f11957aTed Kremenek                if ((ndef_status = rw_t1t_send_dyn_cmd (T1T_CMD_READ8, (UINT8) (p_t1t->block_read), NULL)) == NFC_STATUS_OK)
13831eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump                {
1384d59a5bd0ab7821a643c540df8c84c70fef76a1c2Ted Kremenek                    ndef_status  = NFC_STATUS_CONTINUE;
1385966146e89141804ff6492739a2a6e6592ca671c7Anders Carlsson                }
1386d59a5bd0ab7821a643c540df8c84c70fef76a1c2Ted Kremenek            }
1387d59a5bd0ab7821a643c540df8c84c70fef76a1c2Ted Kremenek            else
1388966146e89141804ff6492739a2a6e6592ca671c7Anders Carlsson            {
1389d59a5bd0ab7821a643c540df8c84c70fef76a1c2Ted Kremenek                p_t1t->segment++;
13901eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump                /* send RSEG command */
1391d59a5bd0ab7821a643c540df8c84c70fef76a1c2Ted Kremenek                RW_T1T_BLD_ADDS ((adds), (p_t1t->segment));
1392966146e89141804ff6492739a2a6e6592ca671c7Anders Carlsson                if ((ndef_status = rw_t1t_send_dyn_cmd (T1T_CMD_RSEG, adds, NULL)) == NFC_STATUS_OK)
1393d59a5bd0ab7821a643c540df8c84c70fef76a1c2Ted Kremenek                {
1394d59a5bd0ab7821a643c540df8c84c70fef76a1c2Ted Kremenek                    ndef_status  = NFC_STATUS_CONTINUE;
1395966146e89141804ff6492739a2a6e6592ca671c7Anders Carlsson                }
1396d59a5bd0ab7821a643c540df8c84c70fef76a1c2Ted Kremenek            }
13971eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump        }
13981eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump    }
13991eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump    else
1400fe795956194141c91ae555985c9b930595bff43fChris Lattner    {
1401fe795956194141c91ae555985c9b930595bff43fChris Lattner        ndef_status = NFC_STATUS_OK;
1402fe795956194141c91ae555985c9b930595bff43fChris Lattner    }
140378492dae00fb85e0da0f966df4745edafdafb66cTed Kremenek    return ndef_status;
14045f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer}
14055f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
14065f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer/*******************************************************************************
1407**
1408** Function         rw_t1t_next_ndef_write_block
1409**
1410** Description      This function prepare and writes ndef blocks
1411**
1412** Returns          NFC_STATUS_CONTINUE, if tlv write is not yet complete
1413**                  NFC_STATUS_OK, if tlv write is complete & success
1414**                  NFC_STATUS_FAILED,if tlv write failed
1415**
1416*******************************************************************************/
1417static tNFC_STATUS rw_t1t_next_ndef_write_block (void)
1418{
1419    BOOLEAN     b_block_write_cmd   = FALSE;
1420    tRW_T1T_CB  *p_t1t              = &rw_cb.tcb.t1t;
1421    tNFC_STATUS ndef_status         = NFC_STATUS_CONTINUE;
1422    UINT8       write_block[8];
1423    UINT8       block;
1424    UINT8       index;
1425    UINT8       new_lengthfield_len;
1426    UINT8       length_field[3];
1427    UINT16      initial_offset;
1428    UINT8       count;
1429    /* Write NDEF Message */
1430    new_lengthfield_len = p_t1t->new_ndef_msg_len > 254 ? 3:1;
1431
1432    /* Identify the command to use for NDEF write operation */
1433    if ((p_t1t->hr[0] & 0x0F) != 1)
1434    {
1435        /* Dynamic memory structure */
1436        b_block_write_cmd = FALSE;
1437        block           = p_t1t->ndef_block_written + 1;
1438        p_t1t->segment  = (block * T1T_BLOCK_SIZE) /T1T_SEGMENT_SIZE;
1439
1440        count = 0;
1441        while (block <= p_t1t->mem[T1T_CC_TMS_BYTE])
1442        {
1443            index = 0;
1444            if (block == p_t1t->num_ndef_finalblock)
1445            {
1446                /* T1T_CMD_WRITE_E8 Command */
1447                b_block_write_cmd = TRUE;
1448                break;
1449            }
1450            while (index < T1T_BLOCK_SIZE && p_t1t->work_offset < (p_t1t->new_ndef_msg_len + new_lengthfield_len))
1451            {
1452                if (rw_t1t_is_lock_reserved_otp_byte ((UINT16) ((block * T1T_BLOCK_SIZE) + index)) == FALSE)
1453                {
1454                    count++;
1455                }
1456                index++;
1457            }
1458            if (count == T1T_BLOCK_SIZE)
1459            {
1460                /* T1T_CMD_WRITE_E8 Command */
1461                b_block_write_cmd = TRUE;
1462                break;
1463            }
1464            else if (count == 0)
1465            {
1466                index = 0;
1467                block++;
1468                if (p_t1t->segment != (block * T1T_BLOCK_SIZE) /T1T_SEGMENT_SIZE)
1469                {
1470                    p_t1t->segment = (block * T1T_BLOCK_SIZE) /T1T_SEGMENT_SIZE;
1471                }
1472            }
1473            else
1474            {
1475                /* T1T_CMD_WRITE_E Command */
1476                b_block_write_cmd = FALSE;
1477                break;
1478            }
1479        }
1480    }
1481    else
1482    {
1483        /* Static memory structure */
1484        block       = p_t1t->ndef_block_written;
1485        b_block_write_cmd = FALSE;
1486    }
1487
1488    new_lengthfield_len = p_t1t->new_ndef_msg_len > 254 ? 3:1;
1489    if (new_lengthfield_len == 3)
1490    {
1491        length_field[0] = T1T_LONG_NDEF_LEN_FIELD_BYTE0;
1492        length_field[1] = (UINT8) (p_t1t->new_ndef_msg_len >> 8);
1493        length_field[2] = (UINT8) (p_t1t->new_ndef_msg_len);
1494    }
1495    else
1496    {
1497        length_field[0] = (UINT8) (p_t1t->new_ndef_msg_len);
1498    }
1499
1500    if (b_block_write_cmd)
1501    {
1502        /* Dynamic memory structure */
1503        index           = 0;
1504        p_t1t->segment  = (block * T1T_BLOCK_SIZE) /T1T_SEGMENT_SIZE;
1505
1506        initial_offset  = p_t1t->work_offset;
1507        block = rw_t1t_prepare_ndef_bytes (write_block, length_field,  &index, FALSE, block, new_lengthfield_len);
1508        if (p_t1t->work_offset == initial_offset)
1509        {
1510            ndef_status = NFC_STATUS_FAILED;
1511        }
1512        else
1513        {
1514            /* Send WRITE_E8 command */
1515            ndef_status = rw_t1t_send_ndef_block (write_block, block);
1516        }
1517    }
1518    else
1519    {
1520        /* Static memory structure */
1521        if (p_t1t->write_byte + 1 >= T1T_BLOCK_SIZE)
1522        {
1523            index = 0;
1524            block++;
1525        }
1526        else
1527        {
1528            index       = p_t1t->write_byte + 1;
1529        }
1530        initial_offset  = p_t1t->work_offset;
1531        block = rw_t1t_prepare_ndef_bytes (write_block, length_field, &index, TRUE, block, new_lengthfield_len);
1532        if (p_t1t->work_offset == initial_offset)
1533        {
1534            ndef_status = NFC_STATUS_FAILED;
1535        }
1536        else
1537        {
1538            /* send WRITE-E command */
1539            ndef_status = rw_t1t_send_ndef_byte (write_block[index], block, index, new_lengthfield_len);
1540        }
1541    }
1542    return ndef_status;
1543
1544}
1545
1546/*******************************************************************************
1547**
1548** Function         rw_t1t_ndef_write_first_block
1549**
1550** Description      This function writes ndef first block
1551**
1552** Returns          NFC_STATUS_CONTINUE, if tlv write is not yet complete
1553**                  NFC_STATUS_OK, if tlv write is complete & success
1554**                  NFC_STATUS_FAILED,if tlv write failed
1555**
1556*******************************************************************************/
1557static tNFC_STATUS rw_t1t_ndef_write_first_block (void)
1558{
1559    tNFC_STATUS ndef_status = NFC_STATUS_CONTINUE;
1560    tRW_T1T_CB  *p_t1t      = &rw_cb.tcb.t1t;
1561    UINT8       block;
1562    UINT8       index;
1563    UINT8       new_lengthfield_len;
1564    UINT8       length_field[3];
1565    UINT8       write_block[8];
1566
1567    /* handle positive response to invalidating existing NDEF Message */
1568    p_t1t->work_offset = 0;
1569    new_lengthfield_len = p_t1t->new_ndef_msg_len > 254 ? 3:1;
1570    if (new_lengthfield_len == 3)
1571    {
1572        length_field[0] = T1T_LONG_NDEF_LEN_FIELD_BYTE0;
1573        length_field[1] = (UINT8) (p_t1t->new_ndef_msg_len >> 8);
1574        length_field[2] = (UINT8) (p_t1t->new_ndef_msg_len);
1575    }
1576    else
1577    {
1578        length_field[0] = (UINT8) (p_t1t->new_ndef_msg_len);
1579    }
1580    /* updating ndef_first_block with new ndef message */
1581    memcpy(write_block,p_t1t->ndef_first_block,T1T_BLOCK_SIZE);
1582    index = p_t1t->ndef_header_offset % T1T_BLOCK_SIZE;
1583    block = (UINT8) (p_t1t->ndef_header_offset / T1T_BLOCK_SIZE);
1584    p_t1t->segment      = (UINT8) (p_t1t->ndef_header_offset/T1T_SEGMENT_SIZE);
1585
1586    if ((p_t1t->hr[0] & 0x0F) != 1)
1587    {
1588        /* Dynamic Memory structure */
1589        block = rw_t1t_prepare_ndef_bytes (write_block, length_field, &index, FALSE, block, new_lengthfield_len);
1590
1591        if (p_t1t->work_offset == 0)
1592        {
1593            ndef_status = NFC_STATUS_FAILED;
1594        }
1595        else
1596        {
1597            /* Send WRITE-E8 command based on the prepared write_block */
1598            ndef_status = rw_t1t_send_ndef_block (write_block, block);
1599        }
1600    }
1601    else
1602    {
1603        /* Static Memory structure */
1604        block = rw_t1t_prepare_ndef_bytes (write_block, length_field, &index, TRUE, block, new_lengthfield_len);
1605        if (p_t1t->work_offset == 0)
1606        {
1607            ndef_status = NFC_STATUS_FAILED;
1608        }
1609        else
1610        {
1611            /* send WRITE-E command */
1612            ndef_status = rw_t1t_send_ndef_byte (write_block[index], block, index, new_lengthfield_len);
1613        }
1614    }
1615
1616    return ndef_status;
1617}
1618
1619/*******************************************************************************
1620**
1621** Function         rw_t1t_send_ndef_byte
1622**
1623** Description      Sends ndef message or length field byte and update
1624**                  status
1625**
1626** Returns          NFC_STATUS_CONTINUE, if tlv write is not yet complete
1627**                  NFC_STATUS_OK, if tlv write is complete & success
1628**                  NFC_STATUS_FAILED,if tlv write failed
1629**
1630*******************************************************************************/
1631static tNFC_STATUS rw_t1t_send_ndef_byte (UINT8 data, UINT8 block, UINT8 index, UINT8 msg_len)
1632{
1633    tNFC_STATUS ndef_status = NFC_STATUS_CONTINUE;
1634    tRW_T1T_CB  *p_t1t      = &rw_cb.tcb.t1t;
1635    UINT8       addr;
1636
1637    /* send WRITE-E command */
1638    RW_T1T_BLD_ADD ((addr), (block), (index));
1639    if (NFC_STATUS_OK == rw_t1t_send_static_cmd (T1T_CMD_WRITE_E, addr, data))
1640    {
1641        p_t1t->write_byte           = index;
1642        p_t1t->ndef_block_written   = block;
1643        if (p_t1t->work_offset == p_t1t->new_ndef_msg_len + msg_len)
1644        {
1645            ndef_status =  NFC_STATUS_OK;
1646        }
1647        else
1648        {
1649            ndef_status = NFC_STATUS_CONTINUE;
1650        }
1651    }
1652    else
1653    {
1654        ndef_status = NFC_STATUS_FAILED;
1655    }
1656    return ndef_status;
1657}
1658
1659/*******************************************************************************
1660**
1661** Function         rw_t1t_prepare_ndef_bytes
1662**
1663** Description      prepares ndef block to write
1664**
1665** Returns          block number where to write
1666**
1667*******************************************************************************/
1668static UINT8 rw_t1t_prepare_ndef_bytes (UINT8 *p_data, UINT8 *p_length_field, UINT8 *p_index, BOOLEAN b_one_byte, UINT8 block, UINT8 lengthfield_len)
1669{
1670    tRW_T1T_CB  *p_t1t          = &rw_cb.tcb.t1t;
1671    UINT8       first_block     = (UINT8) (p_t1t->ndef_header_offset / T1T_BLOCK_SIZE);
1672    UINT16      initial_offset  = p_t1t->work_offset;
1673
1674    while (p_t1t->work_offset == initial_offset && block <= p_t1t->mem[T1T_CC_TMS_BYTE])
1675    {
1676        if (  (block == p_t1t->num_ndef_finalblock)
1677            &&(block != first_block)  )
1678        {
1679            memcpy (p_data,p_t1t->ndef_final_block,T1T_BLOCK_SIZE);
1680        }
1681        /* Update length field */
1682        while (  (*p_index < T1T_BLOCK_SIZE)
1683               &&(p_t1t->work_offset < lengthfield_len)  )
1684        {
1685            if (rw_t1t_is_lock_reserved_otp_byte ((UINT16) ((block * T1T_BLOCK_SIZE) + *p_index)) == FALSE)
1686            {
1687                p_data[*p_index] = p_length_field[p_t1t->work_offset];
1688                p_t1t->work_offset++;
1689                if (b_one_byte)
1690                    return block;
1691            }
1692            (*p_index)++;
1693            if (p_t1t->work_offset == lengthfield_len)
1694            {
1695                break;
1696            }
1697        }
1698        /* Update ndef message field */
1699        while (*p_index < T1T_BLOCK_SIZE && p_t1t->work_offset < (p_t1t->new_ndef_msg_len + lengthfield_len))
1700        {
1701            if (rw_t1t_is_lock_reserved_otp_byte ((UINT16) ((block * T1T_BLOCK_SIZE) + *p_index)) == FALSE)
1702            {
1703                p_data[*p_index] = p_t1t->p_ndef_buffer[p_t1t->work_offset - lengthfield_len];
1704                p_t1t->work_offset++;
1705                if (b_one_byte)
1706                    return block;
1707            }
1708            (*p_index)++;
1709        }
1710        if (p_t1t->work_offset == initial_offset)
1711        {
1712            *p_index = 0;
1713            block++;
1714            if (p_t1t->segment != (block * T1T_BLOCK_SIZE) /T1T_SEGMENT_SIZE)
1715            {
1716                p_t1t->segment = (block * T1T_BLOCK_SIZE) /T1T_SEGMENT_SIZE;
1717            }
1718        }
1719    }
1720    return block;
1721}
1722
1723/*******************************************************************************
1724**
1725** Function         rw_t1t_send_ndef_block
1726**
1727** Description      Sends ndef block and update status
1728**
1729** Returns          NFC_STATUS_CONTINUE, if tlv write is not yet complete
1730**                  NFC_STATUS_OK, if tlv write is complete & success
1731**                  NFC_STATUS_FAILED,if tlv write failed
1732**
1733*******************************************************************************/
1734static tNFC_STATUS rw_t1t_send_ndef_block (UINT8 *p_data, UINT8 block)
1735{
1736    tRW_T1T_CB  *p_t1t      = &rw_cb.tcb.t1t;
1737    tNFC_STATUS ndef_status = NFC_STATUS_CONTINUE;
1738
1739    if (NFC_STATUS_OK == rw_t1t_send_dyn_cmd (T1T_CMD_WRITE_E8, block, p_data))
1740    {
1741        p_t1t->ndef_block_written = block;
1742        if (p_t1t->ndef_block_written == p_t1t->num_ndef_finalblock)
1743        {
1744            ndef_status  =  NFC_STATUS_OK;
1745        }
1746        else
1747        {
1748             ndef_status =  NFC_STATUS_CONTINUE;
1749        }
1750    }
1751    else
1752    {
1753        ndef_status = NFC_STATUS_FAILED;
1754    }
1755    return ndef_status;
1756}
1757
1758/*******************************************************************************
1759**
1760** Function         rw_t1t_get_ndef_flags
1761**
1762** Description      Prepare NDEF Flags
1763**
1764** Returns          NDEF Flag value
1765**
1766*******************************************************************************/
1767static UINT8 rw_t1t_get_ndef_flags (void)
1768{
1769    UINT8       flags   = 0;
1770    tRW_T1T_CB  *p_t1t  = &rw_cb.tcb.t1t;
1771
1772    if ((p_t1t->hr[0] & 0xF0) == T1T_NDEF_SUPPORTED)
1773        flags |= RW_NDEF_FL_SUPPORTED;
1774
1775    if (t1t_tag_init_data (p_t1t->hr[0]) != NULL)
1776        flags |= RW_NDEF_FL_FORMATABLE;
1777
1778    if ((p_t1t->mem[T1T_CC_RWA_BYTE] & 0x0F) == T1T_CC_RWA_RO)
1779        flags |=RW_NDEF_FL_READ_ONLY;
1780
1781    return flags;
1782}
1783
1784/*******************************************************************************
1785**
1786** Function         rw_t1t_get_ndef_max_size
1787**
1788** Description      Calculate maximum size of NDEF message that can be written
1789**                  on to the tag
1790**
1791** Returns          Maximum size of NDEF Message
1792**
1793*******************************************************************************/
1794static UINT16 rw_t1t_get_ndef_max_size (void)
1795{
1796    UINT16              offset;
1797    tRW_T1T_CB          *p_t1t   = &rw_cb.tcb.t1t;
1798    UINT16              tag_size = (p_t1t->mem[T1T_CC_TMS_BYTE] +1)* T1T_BLOCK_SIZE;
1799    const tT1T_INIT_TAG *p_ret;
1800    UINT8               init_segment = p_t1t->segment;
1801
1802    p_t1t->max_ndef_msg_len = 0;
1803    offset                  = p_t1t->ndef_msg_offset;
1804    p_t1t->segment          = (UINT8) (p_t1t->ndef_msg_offset/T1T_SEGMENT_SIZE);
1805
1806    if (  (tag_size < T1T_STATIC_SIZE)
1807        ||(tag_size > (T1T_SEGMENT_SIZE * T1T_MAX_SEGMENTS))
1808        ||((p_t1t->mem[T1T_CC_NMN_BYTE] != T1T_CC_NMN) && (p_t1t->mem[T1T_CC_NMN_BYTE] != 0))  )
1809    {
1810        /* Tag not formated, determine maximum NDEF size from HR */
1811        if  (  ((p_t1t->hr[0] & 0xF0) == T1T_NDEF_SUPPORTED)
1812             &&((p_ret = t1t_tag_init_data (p_t1t->hr[0])) != NULL)  )
1813        {
1814            p_t1t->max_ndef_msg_len = ((p_ret->tms +1)* T1T_BLOCK_SIZE) - T1T_OTP_LOCK_RES_BYTES - T1T_UID_LEN - T1T_ADD_LEN - T1T_CC_LEN - T1T_TLV_TYPE_LEN - T1T_SHORT_NDEF_LEN_FIELD_LEN;
1815            if (p_ret->b_dynamic)
1816            {
1817                p_t1t->max_ndef_msg_len -= (T1T_TLV_TYPE_LEN + T1T_DEFAULT_TLV_LEN_FIELD_LEN + T1T_DEFAULT_TLV_LEN + T1T_TLV_TYPE_LEN + T1T_DEFAULT_TLV_LEN_FIELD_LEN + T1T_DEFAULT_TLV_LEN);
1818                p_t1t->max_ndef_msg_len -= T1T_DYNAMIC_LOCK_BYTES;
1819            }
1820            offset = tag_size;
1821        }
1822        else
1823        {
1824            p_t1t->segment = init_segment;
1825            return p_t1t->max_ndef_msg_len;
1826        }
1827    }
1828
1829    /* Starting from NDEF Message offset find the first locked data byte */
1830    while (offset < tag_size)
1831    {
1832        if (rw_t1t_is_lock_reserved_otp_byte ((UINT16) (offset)) == FALSE)
1833        {
1834            if (rw_t1t_is_read_only_byte ((UINT16) offset) == TRUE)
1835                break;
1836            p_t1t->max_ndef_msg_len++;
1837        }
1838        offset++;
1839        if (offset % T1T_SEGMENT_SIZE == 0)
1840        {
1841            p_t1t->segment = (UINT8) (offset / T1T_SEGMENT_SIZE);
1842        }
1843    }
1844    /* NDEF Length field length changes based on NDEF size */
1845    if (  (p_t1t->max_ndef_msg_len >= T1T_LONG_NDEF_LEN_FIELD_BYTE0)
1846        &&((p_t1t->ndef_msg_offset - p_t1t->ndef_header_offset) == T1T_SHORT_NDEF_LEN_FIELD_LEN)  )
1847    {
1848        p_t1t->max_ndef_msg_len -=  (p_t1t->max_ndef_msg_len == T1T_LONG_NDEF_LEN_FIELD_BYTE0)? 1 : (T1T_LONG_NDEF_LEN_FIELD_LEN - T1T_SHORT_NDEF_LEN_FIELD_LEN);
1849    }
1850
1851    p_t1t->segment = init_segment;
1852    return p_t1t->max_ndef_msg_len;
1853}
1854
1855/*******************************************************************************
1856**
1857** Function         rw_t1t_handle_ndef_write_rsp
1858**
1859** Description      Handle response to commands sent while writing an
1860**                  NDEF message
1861**
1862** Returns          NFC_STATUS_CONTINUE, if tlv write is not yet complete
1863**                  NFC_STATUS_OK, if tlv write is complete & success
1864**                  NFC_STATUS_FAILED,if tlv write failed
1865**
1866*******************************************************************************/
1867static tNFC_STATUS rw_t1t_handle_ndef_write_rsp (UINT8 *p_data)
1868{
1869    tRW_T1T_CB  *p_t1t      = &rw_cb.tcb.t1t;
1870    tNFC_STATUS ndef_status = NFC_STATUS_CONTINUE;
1871    UINT8       addr;
1872
1873    switch (p_t1t->substate)
1874    {
1875    case RW_T1T_SUBSTATE_WAIT_READ_NDEF_BLOCK:
1876        /* Backup ndef_final_block */
1877        memcpy (p_t1t->ndef_final_block, p_data, T1T_BLOCK_SIZE);
1878        /* Invalidate existing NDEF Message */
1879        RW_T1T_BLD_ADD ((addr), (T1T_CC_BLOCK), (T1T_CC_NMN_OFFSET));
1880        if (NFC_STATUS_OK == rw_t1t_send_static_cmd (T1T_CMD_WRITE_E, addr, 0))
1881        {
1882            ndef_status     = NFC_STATUS_CONTINUE;
1883            p_t1t->state    = RW_T1T_STATE_WRITE_NDEF;
1884            p_t1t->substate = RW_T1T_SUBSTATE_WAIT_INVALIDATE_NDEF;
1885        }
1886        else
1887        {
1888            ndef_status = NFC_STATUS_FAILED;
1889        }
1890        break;
1891
1892    case RW_T1T_SUBSTATE_WAIT_INVALIDATE_NDEF:
1893        ndef_status = rw_t1t_ndef_write_first_block ();
1894        break;
1895
1896    case RW_T1T_SUBSTATE_WAIT_NDEF_WRITE:
1897        ndef_status = rw_t1t_next_ndef_write_block ();
1898        break;
1899
1900    case RW_T1T_SUBSTATE_WAIT_NDEF_UPDATED:
1901        /* Validate new NDEF Message */
1902        RW_T1T_BLD_ADD ((addr), (T1T_CC_BLOCK), (T1T_CC_NMN_OFFSET));
1903        if (NFC_STATUS_OK == rw_t1t_send_static_cmd (T1T_CMD_WRITE_E, addr, T1T_CC_NMN))
1904        {
1905            ndef_status     = NFC_STATUS_OK;
1906        }
1907        else
1908        {
1909            ndef_status     = NFC_STATUS_FAILED;
1910        }
1911        break;
1912    default:
1913        break;
1914    }
1915
1916    return ndef_status;
1917}
1918
1919/*******************************************************************************
1920**
1921** Function         rw_t1t_update_attributes
1922**
1923** Description      This function will prepare attributes for the current
1924**                  segment. Every bit in the attribute refers to one byte of
1925**                  tag content.The bit corresponding to a tag byte will be set
1926**                  to '1' when the Tag byte is read only,otherwise will be set
1927**                  to '0'
1928**
1929** Returns          None
1930**
1931*******************************************************************************/
1932static void rw_t1t_update_attributes (void)
1933{
1934    UINT8       count       = 0;
1935    tRW_T1T_CB  *p_t1t      = &rw_cb.tcb.t1t;
1936    UINT16      lower_offset;
1937    UINT16      upper_offset;
1938    UINT8       num_bytes;
1939    UINT16      offset;
1940    UINT8       bits_per_byte  = 8;
1941
1942    count = 0;
1943    while (count < T1T_BLOCKS_PER_SEGMENT)
1944    {
1945        p_t1t->attr[count] = 0x00;
1946        count++;
1947    }
1948
1949    lower_offset  = p_t1t->segment * T1T_SEGMENT_SIZE;
1950    upper_offset  = (p_t1t->segment + 1)* T1T_SEGMENT_SIZE;
1951
1952    if (p_t1t->segment == 0)
1953    {
1954        /* UID/Lock/Reserved/OTP bytes */
1955        p_t1t->attr[0x00] = 0xFF; /* Uid bytes */
1956        p_t1t->attr[0x0D] = 0xFF; /* Reserved bytes */
1957        p_t1t->attr[0x0E] = 0xFF; /* lock/otp bytes */
1958        p_t1t->attr[0x0F] = 0xFF; /* lock/otp bytes */
1959    }
1960
1961    /* update attr based on lock control and mem control tlvs */
1962    count = 0;
1963    while (count < p_t1t->num_lockbytes)
1964    {
1965        offset = p_t1t->lock_tlv[p_t1t->lockbyte[count].tlv_index].offset + p_t1t->lockbyte[count].byte_index;
1966        if (offset >= lower_offset && offset < upper_offset)
1967        {
1968            /* Set the corresponding bit in attr to indicate - lock byte */
1969            p_t1t->attr[(offset % T1T_SEGMENT_SIZE) / bits_per_byte] |= rw_t1t_mask_bits[(offset % T1T_SEGMENT_SIZE) % bits_per_byte];
1970        }
1971        count++;
1972    }
1973    count = 0;
1974    while (count < p_t1t->num_mem_tlvs)
1975    {
1976        num_bytes = 0;
1977        while (num_bytes < p_t1t->mem_tlv[count].num_bytes)
1978        {
1979            offset = p_t1t->mem_tlv[count].offset + num_bytes;
1980            if (offset >= lower_offset && offset < upper_offset)
1981            {
1982                /* Set the corresponding bit in attr to indicate - reserved byte */
1983                p_t1t->attr[(offset % T1T_SEGMENT_SIZE) / bits_per_byte] |= rw_t1t_mask_bits[(offset % T1T_SEGMENT_SIZE) % bits_per_byte];
1984            }
1985            num_bytes++;
1986        }
1987        count++;
1988    }
1989}
1990
1991/*******************************************************************************
1992**
1993** Function         rw_t1t_get_lock_bits_for_segment
1994**
1995** Description      This function will identify the index of the dynamic lock
1996**                  byte that covers the current segment
1997**
1998** Parameters:      segment, segment number
1999**                  p_start_byte, pointer to hold the first lock byte index
2000**                  p_start_bit, pointer to hold the first lock bit index
2001**                  p_end_byte, pointer to hold the last lock byte index
2002**
2003** Returns          Total lock bits that covers the specified segment
2004**
2005*******************************************************************************/
2006static UINT8 rw_t1t_get_lock_bits_for_segment (UINT8 segment,UINT8 *p_start_byte, UINT8 *p_start_bit,UINT8 *p_end_byte)
2007{
2008    tRW_T1T_CB  *p_t1t              = &rw_cb.tcb.t1t;
2009    UINT16      byte_count          = T1T_SEGMENT_SIZE;
2010    UINT8       total_bits          = 0;
2011    UINT8       num_dynamic_locks   = 0;
2012    UINT8       bit_count           = 0;
2013    UINT16      tag_size            = (p_t1t->mem[T1T_CC_TMS_BYTE] +1) * T1T_BLOCK_SIZE;
2014    UINT16      lower_offset;
2015    UINT16      upper_offset;
2016    BOOLEAN     b_all_bits_are_locks = TRUE;
2017    UINT8       bytes_locked_per_bit;
2018    UINT8       num_bits;
2019
2020    upper_offset    = (segment + 1) * T1T_SEGMENT_SIZE;
2021
2022    if (upper_offset > tag_size)
2023        upper_offset = tag_size;
2024
2025    lower_offset    = segment * T1T_SEGMENT_SIZE;
2026    *p_start_byte   = num_dynamic_locks;
2027    *p_start_bit    = 0;
2028
2029    while (  (byte_count <= lower_offset)
2030           &&(num_dynamic_locks < p_t1t->num_lockbytes)  )
2031    {
2032        bytes_locked_per_bit = p_t1t->lock_tlv[p_t1t->lockbyte[num_dynamic_locks].tlv_index].bytes_locked_per_bit;
2033        /* Number of bits in the current lock byte */
2034        b_all_bits_are_locks = ((p_t1t->lockbyte[num_dynamic_locks].byte_index + 1) * TAG_BITS_PER_BYTE <= p_t1t->lock_tlv[p_t1t->lockbyte[num_dynamic_locks].tlv_index].num_bits);
2035        num_bits = b_all_bits_are_locks ? TAG_BITS_PER_BYTE : p_t1t->lock_tlv[p_t1t->lockbyte[num_dynamic_locks].tlv_index].num_bits % TAG_BITS_PER_BYTE;
2036
2037        /* Skip lock bits that covers all previous segments */
2038        if (bytes_locked_per_bit * num_bits + byte_count <= lower_offset)
2039        {
2040            byte_count += bytes_locked_per_bit * num_bits;
2041            num_dynamic_locks++;
2042        }
2043        else
2044        {
2045            /* The first lock bit that covers this segment is present in this segment */
2046            bit_count = 0;
2047            while (bit_count < num_bits)
2048            {
2049                byte_count += bytes_locked_per_bit;
2050                if (byte_count > lower_offset)
2051                {
2052                    *p_start_byte = num_dynamic_locks;
2053                    *p_end_byte = num_dynamic_locks;
2054                    *p_start_bit  = bit_count;
2055                    bit_count++;
2056                    total_bits = 1;
2057                    break;
2058                }
2059                bit_count++;
2060            }
2061        }
2062    }
2063    if (num_dynamic_locks == p_t1t->num_lockbytes)
2064    {
2065        return 0;
2066    }
2067    while (  (byte_count < upper_offset)
2068           &&(num_dynamic_locks < p_t1t->num_lockbytes)  )
2069    {
2070        bytes_locked_per_bit = p_t1t->lock_tlv[p_t1t->lockbyte[num_dynamic_locks].tlv_index].bytes_locked_per_bit;
2071
2072        /* Number of bits in the current lock byte */
2073        b_all_bits_are_locks = ((p_t1t->lockbyte[num_dynamic_locks].byte_index + 1) * TAG_BITS_PER_BYTE <= p_t1t->lock_tlv[p_t1t->lockbyte[num_dynamic_locks].tlv_index].num_bits);
2074        num_bits             =  b_all_bits_are_locks ? TAG_BITS_PER_BYTE : p_t1t->lock_tlv[p_t1t->lockbyte[num_dynamic_locks].tlv_index].num_bits % TAG_BITS_PER_BYTE;
2075
2076        /* Collect all lock bits that covers the current segment */
2077        if ((bytes_locked_per_bit * (num_bits - bit_count)) + byte_count < upper_offset)
2078        {
2079            byte_count       += bytes_locked_per_bit * (num_bits - bit_count);
2080            total_bits       += num_bits - bit_count;
2081            bit_count         = 0;
2082            *p_end_byte       = num_dynamic_locks;
2083            num_dynamic_locks++;
2084        }
2085        else
2086        {
2087            /* The last lock byte that covers the current segment */
2088            bit_count = 0;
2089            while (bit_count < num_bits)
2090            {
2091                byte_count += bytes_locked_per_bit;
2092                if (byte_count >= upper_offset)
2093                {
2094                    *p_end_byte = num_dynamic_locks;
2095                    total_bits += (bit_count + 1);
2096                    break;
2097                }
2098                bit_count++;
2099            }
2100        }
2101    }
2102    return total_bits;
2103}
2104
2105/*******************************************************************************
2106**
2107** Function         rw_t1t_update_lock_attributes
2108**
2109** Description      This function will check if the tag index passed as
2110**                  argument is a locked byte and return
2111**                  TRUE or FALSE
2112**
2113** Parameters:      index, the index of the byte in the tag
2114**
2115**
2116** Returns          TRUE, if the specified index in the tag is a locked or
2117**                        reserved or otp byte
2118**                  FALSE, otherwise
2119**
2120*******************************************************************************/
2121static void rw_t1t_update_lock_attributes (void)
2122{
2123    UINT8       xx = 0;
2124    UINT8       bytes_locked_per_lock_bit;
2125    UINT8       num_static_lock_bytes       = 0;
2126    UINT8       num_dynamic_lock_bytes      = 0;
2127    UINT8       bits_covered                = 0;
2128    UINT8       bytes_covered               = 0;
2129    UINT8       block_count                 = 0;
2130    tRW_T1T_CB  *p_t1t = &rw_cb.tcb.t1t;
2131    UINT8       start_lock_byte;
2132    UINT8       start_lock_bit;
2133    UINT8       end_lock_byte;
2134    UINT8       num_lock_bits;
2135    UINT8       total_bits;
2136
2137
2138    block_count = 0;
2139    while (block_count < T1T_BLOCKS_PER_SEGMENT)
2140    {
2141        p_t1t->lock_attr[block_count] = 0x00;
2142        block_count++;
2143    }
2144
2145    /* update lock_attr based on static lock bytes */
2146    if (p_t1t->segment == 0)
2147    {
2148        xx                      = 0;
2149        num_static_lock_bytes   = 0;
2150        block_count             = 0;
2151        num_lock_bits           = 8;
2152
2153        while (num_static_lock_bytes < T1T_NUM_STATIC_LOCK_BYTES)
2154        {
2155            /* Update lock attribute based on 2 static locks */
2156            while (xx < num_lock_bits)
2157            {
2158                p_t1t->lock_attr[block_count] = 0x00;
2159
2160                if (p_t1t->mem[T1T_LOCK_0_OFFSET + num_static_lock_bytes] & rw_t1t_mask_bits[xx++])
2161                {
2162                    /* If the bit is set then 1 block is locked */
2163                    p_t1t->lock_attr[block_count] = 0xFF;
2164                }
2165
2166                block_count++;
2167            }
2168            num_static_lock_bytes++;
2169            xx = 0;
2170        }
2171        /* Locked bytes */
2172        p_t1t->lock_attr[0x00] = 0xFF;
2173        p_t1t->lock_attr[0x0D] = 0xFF;
2174    }
2175    else
2176    {
2177        /* update lock_attr based on segment and using dynamic lock bytes */
2178        if ((total_bits = rw_t1t_get_lock_bits_for_segment (p_t1t->segment,&start_lock_byte, &start_lock_bit,&end_lock_byte)) != 0)
2179        {
2180            xx                       = start_lock_bit;
2181            num_dynamic_lock_bytes   = start_lock_byte;
2182            bits_covered             = 0;
2183            bytes_covered            = 0;
2184            block_count              = 0;
2185            num_lock_bits            = 8;
2186
2187            p_t1t->lock_attr[block_count] = 0;
2188
2189            while (num_dynamic_lock_bytes <= end_lock_byte)
2190            {
2191                bytes_locked_per_lock_bit   = p_t1t->lock_tlv[p_t1t->lockbyte[num_dynamic_lock_bytes].tlv_index].bytes_locked_per_bit;
2192                if (num_dynamic_lock_bytes == end_lock_byte)
2193                {
2194                    num_lock_bits = (total_bits % 8 == 0)? 8:total_bits % 8;
2195                }
2196                while (xx < num_lock_bits)
2197                {
2198                    bytes_covered = 0;
2199                    while (bytes_covered < bytes_locked_per_lock_bit)
2200                    {
2201                        /* Set/clear lock_attr byte bits based on whether a particular lock bit is set or not
2202                         * each bit in lock_attr represents one byte in Tag read only attribute */
2203                        if (p_t1t->lockbyte[num_dynamic_lock_bytes].lock_byte & rw_t1t_mask_bits[xx])
2204                        {
2205                            p_t1t->lock_attr[block_count] |= 0x01 << bits_covered;
2206                        }
2207                        bytes_covered++;
2208                        bits_covered++;
2209                        if (bits_covered == 8)
2210                        {
2211                            bits_covered = 0;
2212                            block_count++;
2213                            if (block_count < T1T_BLOCKS_PER_SEGMENT)
2214                                p_t1t->lock_attr[block_count] = 0;
2215                        }
2216                    }
2217                    xx++;
2218                }
2219                num_dynamic_lock_bytes++;
2220                xx = 0;
2221            }
2222        }
2223    }
2224}
2225
2226/*******************************************************************************
2227**
2228** Function         rw_t1t_is_lock_reserved_otp_byte
2229**
2230** Description      This function will check if the tag index passed as
2231**                  argument is a lock or reserved or otp byte
2232**
2233** Parameters:      index, the index of the byte in the tag's current segment
2234**
2235**
2236** Returns          TRUE, if the specified index in the tag is a locked or
2237**                        reserved or otp byte
2238**                  FALSE, otherwise
2239**
2240*******************************************************************************/
2241static BOOLEAN rw_t1t_is_lock_reserved_otp_byte (UINT16 index)
2242{
2243    tRW_T1T_CB  *p_t1t = &rw_cb.tcb.t1t;
2244
2245    if (p_t1t->attr_seg != p_t1t->segment)
2246    {
2247        /* Update p_t1t->attr to reflect the current segment */
2248        rw_t1t_update_attributes ();
2249        p_t1t->attr_seg = p_t1t->segment;
2250    }
2251    index = index % T1T_SEGMENT_SIZE;
2252
2253    /* Every bit in p_t1t->attr indicates one specific byte of the tag is either a lock/reserved/otp byte or not
2254     * So, each array element in p_t1t->attr covers one block in the tag as T1 block size and array element size is 8
2255     * Find the block and offset for the index (passed as argument) and Check if the offset bit in the
2256     * p_t1t->attr[block] is set or not. If the bit is set then it is a lock/reserved/otp byte, otherwise not */
2257
2258    return ((p_t1t->attr[index /8] & rw_t1t_mask_bits[index % 8]) == 0) ? FALSE:TRUE;
2259}
2260
2261/*******************************************************************************
2262**
2263** Function         rw_t1t_is_read_only_byte
2264**
2265** Description      This function will check if the tag index passed as
2266**                  argument is a read only byte
2267**
2268** Parameters:      index, the index of the byte in the tag's current segment
2269**
2270**
2271** Returns          TRUE, if the specified index in the tag is a locked or
2272**                        reserved or otp byte
2273**                  FALSE, otherwise
2274**
2275*******************************************************************************/
2276static BOOLEAN rw_t1t_is_read_only_byte (UINT16 index)
2277{
2278    tRW_T1T_CB  *p_t1t = &rw_cb.tcb.t1t;
2279
2280    if (p_t1t->lock_attr_seg != p_t1t->segment)
2281    {
2282        /* Update p_t1t->lock_attr to reflect the current segment */
2283        rw_t1t_update_lock_attributes ();
2284        p_t1t->lock_attr_seg = p_t1t->segment;
2285    }
2286
2287    index = index % T1T_SEGMENT_SIZE;
2288    /* Every bit in p_t1t->lock_attr indicates one specific byte of the tag is a read only byte or read write byte
2289     * So, each array element in p_t1t->lock_attr covers one block in the tag as T1 block size and array element size is 8
2290     * Find the block and offset for the index (passed as argument) and Check if the offset bit in the
2291     * p_t1t->lock_attr[block] is set or not. If the bit is set then it is a read only byte, otherwise read write byte */
2292
2293    return ((p_t1t->lock_attr[index /8] & rw_t1t_mask_bits[index % 8]) == 0) ? FALSE:TRUE;
2294}
2295
2296/*****************************************************************************
2297**
2298** Function         RW_T1tFormatNDef
2299**
2300** Description
2301**      Format Tag content
2302**
2303** Returns
2304**      NFC_STATUS_OK, Command sent to format Tag
2305**      NFC_STATUS_REJECTED: Invalid HR0 and cannot format the tag
2306**      NFC_STATUS_FAILED: other error
2307**
2308*****************************************************************************/
2309tNFC_STATUS RW_T1tFormatNDef (void)
2310{
2311    tRW_T1T_CB          *p_t1t  = &rw_cb.tcb.t1t;
2312    tNFC_STATUS         status  = NFC_STATUS_FAILED;
2313    const tT1T_INIT_TAG *p_ret;
2314    UINT8               addr;
2315    UINT8               *p;
2316
2317    if (p_t1t->state != RW_T1T_STATE_IDLE)
2318    {
2319        RW_TRACE_WARNING1 ("RW_T1tFormatNDef - Tag not initialized/ Busy! State: %u", p_t1t->state);
2320        return (NFC_STATUS_FAILED);
2321    }
2322
2323    if ((p_t1t->hr[0] & 0xF0) != T1T_NDEF_SUPPORTED)
2324    {
2325        RW_TRACE_WARNING1 ("RW_T1tFormatNDef - Cannot format tag as NDEF not supported. HR0: %u", p_t1t->hr[0]);
2326        return (NFC_STATUS_REJECTED);
2327    }
2328
2329    if ((p_ret = t1t_tag_init_data (p_t1t->hr[0])) == NULL)
2330    {
2331        RW_TRACE_WARNING2 ("RW_T1tFormatNDef - Invalid HR - HR0: %u, HR1: %u", p_t1t->hr[0], p_t1t->hr[1]);
2332        return (NFC_STATUS_REJECTED);
2333    }
2334
2335    memset (p_t1t->ndef_first_block, 0, T1T_BLOCK_SIZE);
2336    memset (p_t1t->ndef_final_block, 0, T1T_BLOCK_SIZE);
2337    p = p_t1t->ndef_first_block;
2338
2339    /* Prepare Capability Container */
2340    UINT8_TO_BE_STREAM (p, T1T_CC_NMN);
2341    UINT8_TO_BE_STREAM (p, T1T_CC_VNO);
2342    UINT8_TO_BE_STREAM (p, p_ret->tms);
2343    UINT8_TO_BE_STREAM (p, T1T_CC_RWA_RW);
2344    if (p_ret->b_dynamic)
2345    {
2346        /* Prepare Lock and Memory TLV */
2347        UINT8_TO_BE_STREAM (p, TAG_LOCK_CTRL_TLV);
2348        UINT8_TO_BE_STREAM (p, T1T_DEFAULT_TLV_LEN);
2349        UINT8_TO_BE_STREAM (p, p_ret->lock_tlv[0]);
2350        UINT8_TO_BE_STREAM (p, p_ret->lock_tlv[1]);
2351        p = p_t1t->ndef_final_block;
2352        UINT8_TO_BE_STREAM (p, p_ret->lock_tlv[2]);
2353        UINT8_TO_BE_STREAM (p, TAG_MEM_CTRL_TLV);
2354        UINT8_TO_BE_STREAM (p, T1T_DEFAULT_TLV_LEN);
2355        UINT8_TO_BE_STREAM (p, p_ret->mem_tlv[0]);
2356        UINT8_TO_BE_STREAM (p, p_ret->mem_tlv[1]);
2357        UINT8_TO_BE_STREAM (p, p_ret->mem_tlv[2]);
2358    }
2359    /* Prepare NULL NDEF TLV */
2360    UINT8_TO_BE_STREAM (p, TAG_NDEF_TLV);
2361    UINT8_TO_BE_STREAM (p, 0);
2362
2363    if (rw_cb.tcb.t1t.hr[0] != T1T_STATIC_HR0 || rw_cb.tcb.t1t.hr[1] >= RW_T1T_HR1_MIN)
2364    {
2365        /* send WRITE-E8 command */
2366        if ((status = rw_t1t_send_dyn_cmd (T1T_CMD_WRITE_E8, 1, p_t1t->ndef_first_block)) == NFC_STATUS_OK)
2367        {
2368            p_t1t->state    = RW_T1T_STATE_FORMAT_TAG;
2369            p_t1t->b_update = FALSE;
2370            p_t1t->b_rseg   = FALSE;
2371            if (p_ret->b_dynamic)
2372                p_t1t->substate = RW_T1T_SUBSTATE_WAIT_SET_CC;
2373            else
2374                p_t1t->substate = RW_T1T_SUBSTATE_WAIT_SET_NULL_NDEF;
2375        }
2376    }
2377    else
2378    {
2379        /* send WRITE-E command */
2380        RW_T1T_BLD_ADD ((addr), 1, 0);
2381
2382        if ((status = rw_t1t_send_static_cmd (T1T_CMD_WRITE_E, addr, p_t1t->ndef_first_block[0])) == NFC_STATUS_OK)
2383        {
2384            p_t1t->work_offset  = 0;
2385            p_t1t->state        = RW_T1T_STATE_FORMAT_TAG;
2386            p_t1t->substate     = RW_T1T_SUBSTATE_WAIT_SET_NULL_NDEF;
2387            p_t1t->b_update     = FALSE;
2388            p_t1t->b_rseg       = FALSE;
2389        }
2390    }
2391
2392    return status;
2393}
2394
2395/*******************************************************************************
2396**
2397** Function         RW_T1tLocateTlv
2398**
2399** Description      This function is called to find the start of the given TLV
2400**
2401** Parameters:      tlv_type, Type of TLV to find
2402**
2403** Returns          NCI_STATUS_OK, if detection was started. Otherwise, error status.
2404**
2405*******************************************************************************/
2406tNFC_STATUS RW_T1tLocateTlv (UINT8 tlv_type)
2407{
2408    tNFC_STATUS     status = NFC_STATUS_FAILED;
2409    tRW_T1T_CB      *p_t1t= &rw_cb.tcb.t1t;
2410    UINT8           adds;
2411
2412    if (p_t1t->state != RW_T1T_STATE_IDLE)
2413    {
2414        RW_TRACE_WARNING1 ("RW_T1tLocateTlv - Busy - State: %u", p_t1t->state);
2415        return (NFC_STATUS_FAILED);
2416    }
2417    p_t1t->tlv_detect = tlv_type;
2418
2419    if(  (p_t1t->tlv_detect == TAG_NDEF_TLV)
2420       &&(((p_t1t->hr[0]) & 0xF0) != T1T_NDEF_SUPPORTED)  )
2421    {
2422        RW_TRACE_ERROR0 ("RW_T1tLocateTlv - Error: NDEF not supported by the tag");
2423        return (NFC_STATUS_REFUSED);
2424    }
2425
2426    if (  (p_t1t->tlv_detect == TAG_MEM_CTRL_TLV)
2427        ||(p_t1t->tlv_detect == TAG_NDEF_TLV)  )
2428    {
2429        p_t1t->num_mem_tlvs = 0;
2430    }
2431
2432    if (  (p_t1t->tlv_detect == TAG_LOCK_CTRL_TLV)
2433        ||(p_t1t->tlv_detect == TAG_NDEF_TLV)  )
2434    {
2435        p_t1t->num_lockbytes = 0;
2436        p_t1t->num_lock_tlvs = 0;
2437    }
2438
2439    /* Start reading memory, looking for the TLV */
2440    p_t1t->segment = 0;
2441    if ((p_t1t->hr[0] & 0x0F) != 1)
2442    {
2443        /* send RSEG command */
2444        RW_T1T_BLD_ADDS ((adds), (p_t1t->segment));
2445        status = rw_t1t_send_dyn_cmd (T1T_CMD_RSEG, adds, NULL);
2446    }
2447    else
2448    {
2449        status = rw_t1t_send_static_cmd (T1T_CMD_RALL, 0, 0);
2450    }
2451    if (status == NFC_STATUS_OK)
2452    {
2453        p_t1t->tlv_detect   = tlv_type;
2454        p_t1t->work_offset  = 0;
2455        p_t1t->state        = RW_T1T_STATE_TLV_DETECT;
2456        p_t1t->substate     = RW_T1T_SUBSTATE_NONE;
2457    }
2458
2459    return status;
2460}
2461
2462/*****************************************************************************
2463**
2464** Function         RW_T1tDetectNDef
2465**
2466** Description
2467**      This function is used to perform NDEF detection on a Type 1 tag, and
2468**      retrieve the tag's NDEF attribute information (block 0).
2469**
2470**      Before using this API, the application must call RW_SelectTagType to
2471**      indicate that a Type 1 tag has been activated.
2472**
2473** Returns
2474**      NFC_STATUS_OK: ndef detection procedure started
2475**      NFC_STATUS_WRONG_PROTOCOL: type 1 tag not activated
2476**      NFC_STATUS_BUSY: another command is already in progress
2477**      NFC_STATUS_FAILED: other error
2478**
2479*****************************************************************************/
2480tNFC_STATUS RW_T1tDetectNDef (void)
2481{
2482    return RW_T1tLocateTlv (TAG_NDEF_TLV);
2483}
2484
2485/*******************************************************************************
2486**
2487** Function         RW_T1tReadNDef
2488**
2489** Description      This function can be called to read the NDEF message on the tag.
2490**
2491** Parameters:      p_buffer:   The buffer into which to read the NDEF message
2492**                  buf_len:    The length of the buffer
2493**
2494** Returns          NCI_STATUS_OK, if read was started. Otherwise, error status.
2495**
2496*******************************************************************************/
2497tNFC_STATUS RW_T1tReadNDef (UINT8 *p_buffer, UINT16 buf_len)
2498{
2499    tNFC_STATUS     status = NFC_STATUS_FAILED;
2500    tRW_T1T_CB      *p_t1t = &rw_cb.tcb.t1t;
2501    BOOLEAN         b_notify;
2502    UINT8           adds;
2503    const tT1T_CMD_RSP_INFO *p_cmd_rsp_info_rall = t1t_cmd_to_rsp_info (T1T_CMD_RALL);
2504    const tT1T_CMD_RSP_INFO *p_cmd_rsp_info_rseg = t1t_cmd_to_rsp_info (T1T_CMD_RSEG);
2505
2506
2507
2508    if (p_t1t->state != RW_T1T_STATE_IDLE)
2509    {
2510        RW_TRACE_WARNING1 ("RW_T1tReadNDef - Busy - State: %u", p_t1t->state);
2511        return (NFC_STATUS_FAILED);
2512    }
2513
2514    /* Check HR0 if NDEF supported by the tag */
2515    if (((p_t1t->hr[0]) & 0xF0) != T1T_NDEF_SUPPORTED)
2516    {
2517        RW_TRACE_ERROR0 ("RW_T1tReadNDef - Error: NDEF not supported by the tag");
2518        return (NFC_STATUS_REFUSED);
2519    }
2520
2521    if (p_t1t->tag_attribute  == RW_T1_TAG_ATTRB_INITIALIZED_NDEF)
2522    {
2523        RW_TRACE_WARNING1 ("RW_T1tReadNDef - NDEF Message length is zero, NDEF Length : %u ", p_t1t->ndef_msg_len);
2524        return (NFC_STATUS_NOT_INITIALIZED);
2525    }
2526
2527    if (  (p_t1t->tag_attribute != RW_T1_TAG_ATTRB_READ_WRITE)
2528        &&(p_t1t->tag_attribute != RW_T1_TAG_ATTRB_READ_ONLY)  )
2529    {
2530        RW_TRACE_ERROR0 ("RW_T1tReadNDef - Error: NDEF detection not performed yet/ Tag is in Initialized state");
2531        return (NFC_STATUS_FAILED);
2532    }
2533
2534    if (buf_len < p_t1t->ndef_msg_len)
2535    {
2536        RW_TRACE_WARNING2 ("RW_T1tReadNDef - buffer size: %u  less than NDEF msg sise: %u", buf_len, p_t1t->ndef_msg_len);
2537        return (NFC_STATUS_FAILED);
2538    }
2539    p_t1t->p_ndef_buffer = p_buffer;
2540
2541    if (p_t1t->b_rseg == TRUE)
2542    {
2543        /* If already got response to RSEG 0 */
2544        p_t1t->state = RW_T1T_STATE_READ_NDEF;
2545        p_t1t->p_cmd_rsp_info = (tT1T_CMD_RSP_INFO *)p_cmd_rsp_info_rseg;
2546
2547        rw_t1t_handle_read_rsp (&b_notify,p_t1t->mem);
2548        status       = NFC_STATUS_OK;
2549    }
2550    else if (p_t1t->b_update == TRUE)
2551    {
2552        /* If already got response to RALL */
2553        p_t1t->state = RW_T1T_STATE_READ_NDEF;
2554        p_t1t->p_cmd_rsp_info = (tT1T_CMD_RSP_INFO *) p_cmd_rsp_info_rall;
2555
2556        rw_t1t_handle_read_rsp (&b_notify,p_t1t->mem);
2557        status       = NFC_STATUS_OK;
2558
2559    }
2560    else
2561    {
2562        p_t1t->segment      = 0;
2563        p_t1t->work_offset  = 0;
2564        if ((p_t1t->hr[0] & 0x0F) != 1)
2565        {
2566            /* send RSEG command */
2567            RW_T1T_BLD_ADDS ((adds), (p_t1t->segment));
2568            status = rw_t1t_send_dyn_cmd (T1T_CMD_RSEG, adds, NULL);
2569        }
2570        else
2571        {
2572            status = rw_t1t_send_static_cmd (T1T_CMD_RALL, 0, 0);
2573        }
2574        if (status == NFC_STATUS_OK)
2575            p_t1t->state = RW_T1T_STATE_READ_NDEF;
2576
2577    }
2578
2579    return status;
2580}
2581
2582/*******************************************************************************
2583**
2584** Function         RW_T1tWriteNDef
2585**
2586** Description      This function can be called to write an NDEF message to the tag.
2587**
2588** Parameters:      msg_len:    The length of the buffer
2589**                  p_msg:      The NDEF message to write
2590**
2591** Returns          NCI_STATUS_OK, if write was started. Otherwise, error status.
2592**
2593*******************************************************************************/
2594tNFC_STATUS RW_T1tWriteNDef (UINT16 msg_len, UINT8 *p_msg)
2595{
2596    tNFC_STATUS status          = NFC_STATUS_FAILED;
2597    tRW_T1T_CB  *p_t1t          = &rw_cb.tcb.t1t;
2598    UINT16      num_ndef_bytes;
2599    UINT16      offset;
2600    UINT8       addr;
2601    UINT8       init_lengthfield_len;
2602    UINT8       new_lengthfield_len;
2603    UINT16      init_ndef_msg_offset;
2604
2605    if (p_t1t->state != RW_T1T_STATE_IDLE)
2606    {
2607        RW_TRACE_WARNING1 ("RW_T1tWriteNDef - Busy - State: %u", p_t1t->state);
2608        return (NFC_STATUS_FAILED);
2609    }
2610
2611    /* Check HR0 if NDEF supported by the tag */
2612    if (((p_t1t->hr[0]) & 0xF0) != T1T_NDEF_SUPPORTED)
2613    {
2614        RW_TRACE_ERROR0 ("RW_T1tWriteNDef - Error: NDEF not supported by the tag");
2615        return (NFC_STATUS_REFUSED);
2616    }
2617
2618    if (  (p_t1t->tag_attribute  != RW_T1_TAG_ATTRB_READ_WRITE)
2619        &&(p_t1t->tag_attribute  != RW_T1_TAG_ATTRB_INITIALIZED_NDEF)  )
2620    {
2621        RW_TRACE_ERROR0 ("RW_T1tWriteNDef - Tag cannot update NDEF");
2622        return (NFC_STATUS_REFUSED);
2623    }
2624
2625    if (msg_len > p_t1t->max_ndef_msg_len)
2626    {
2627        RW_TRACE_ERROR1 ("RW_T1tWriteNDef - Cannot write NDEF of size greater than %u bytes", p_t1t->max_ndef_msg_len);
2628        return (NFC_STATUS_REFUSED);
2629    }
2630
2631    p_t1t->p_ndef_buffer        = p_msg;
2632    p_t1t->new_ndef_msg_len     = msg_len;
2633    new_lengthfield_len         = p_t1t->new_ndef_msg_len > 254 ? 3:1;
2634    init_lengthfield_len        = (UINT8) (p_t1t->ndef_msg_offset - p_t1t->ndef_header_offset);
2635    init_ndef_msg_offset        = p_t1t->ndef_msg_offset;
2636
2637    /* ndef_msg_offset should reflect the new ndef message offset */
2638    if (init_lengthfield_len > new_lengthfield_len)
2639    {
2640        p_t1t->ndef_msg_offset  =  init_ndef_msg_offset - (T1T_LONG_NDEF_LEN_FIELD_LEN - T1T_SHORT_NDEF_LEN_FIELD_LEN);
2641    }
2642    else if (init_lengthfield_len < new_lengthfield_len)
2643    {
2644        p_t1t->ndef_msg_offset  =  init_ndef_msg_offset + (T1T_LONG_NDEF_LEN_FIELD_LEN - T1T_SHORT_NDEF_LEN_FIELD_LEN);
2645    }
2646
2647    num_ndef_bytes              = 0;
2648    offset                      = p_t1t->ndef_msg_offset;
2649    p_t1t->segment              = (UINT8) (p_t1t->ndef_msg_offset/T1T_SEGMENT_SIZE);
2650
2651    /* Locate NDEF final block based on the size of new NDEF Message */
2652    while (num_ndef_bytes < p_t1t->new_ndef_msg_len)
2653    {
2654        if (rw_t1t_is_lock_reserved_otp_byte ((UINT16) offset) == FALSE)
2655            num_ndef_bytes++;
2656
2657        offset++;
2658        if (offset % T1T_SEGMENT_SIZE == 0)
2659        {
2660            p_t1t->segment      = (UINT8) (offset / T1T_SEGMENT_SIZE);
2661        }
2662    }
2663
2664    p_t1t->b_update = FALSE;
2665    p_t1t->b_rseg   = FALSE;
2666
2667    if ((p_t1t->hr[0] & 0x0F) != 1)
2668    {
2669        /* Dynamic data structure */
2670        p_t1t->block_read = (UINT8) ((offset - 1)/T1T_BLOCK_SIZE);
2671        /* Read NDEF final block before updating */
2672        if ((status = rw_t1t_send_dyn_cmd (T1T_CMD_READ8, p_t1t->block_read, NULL)) == NFC_STATUS_OK)
2673        {
2674            p_t1t->num_ndef_finalblock = p_t1t->block_read;
2675            p_t1t->state    = RW_T1T_STATE_WRITE_NDEF;
2676            p_t1t->substate = RW_T1T_SUBSTATE_WAIT_READ_NDEF_BLOCK;
2677        }
2678    }
2679    else
2680    {
2681        /* NDEF detected and Static memory structure so send WRITE-E command */
2682        RW_T1T_BLD_ADD ((addr), (T1T_CC_BLOCK), (T1T_CC_NMN_OFFSET));
2683        if ((status = rw_t1t_send_static_cmd (T1T_CMD_WRITE_E, addr, 0)) == NFC_STATUS_OK)
2684        {
2685            p_t1t->state    = RW_T1T_STATE_WRITE_NDEF;
2686            p_t1t->substate = RW_T1T_SUBSTATE_WAIT_INVALIDATE_NDEF;
2687        }
2688
2689    }
2690
2691    if (status != NFC_STATUS_OK)
2692    {
2693        /* if status failed, reset ndef_msg_offset to initial message */
2694        p_t1t->ndef_msg_offset = init_ndef_msg_offset;
2695    }
2696    return status;
2697}
2698
2699/*******************************************************************************
2700**
2701** Function         RW_T1tSetTagReadOnly
2702**
2703** Description      This function can be called to set t1 tag as read only.
2704**
2705** Parameters:      None
2706**
2707** Returns          NCI_STATUS_OK, if setting tag as read only was started.
2708**                  Otherwise, error status.
2709**
2710*******************************************************************************/
2711tNFC_STATUS RW_T1tSetTagReadOnly (BOOLEAN b_hard_lock)
2712{
2713    tNFC_STATUS status      = NFC_STATUS_FAILED;
2714    tRW_T1T_CB  *p_t1t      = &rw_cb.tcb.t1t;
2715    UINT8       addr;
2716    UINT8       num_locks;
2717
2718    if (p_t1t->state != RW_T1T_STATE_IDLE)
2719    {
2720        RW_TRACE_WARNING1 ("RW_T1tSetTagReadOnly - Busy - State: %u", p_t1t->state);
2721        return (NFC_STATUS_BUSY);
2722    }
2723
2724    p_t1t->b_hard_lock = b_hard_lock;
2725
2726    if (  (p_t1t->tag_attribute == RW_T1_TAG_ATTRB_READ_WRITE)
2727        ||(p_t1t->tag_attribute == RW_T1_TAG_ATTRB_INITIALIZED)
2728        ||(p_t1t->tag_attribute == RW_T1_TAG_ATTRB_INITIALIZED_NDEF)  )
2729    {
2730        /* send WRITE-NE command */
2731        RW_T1T_BLD_ADD ((addr), (T1T_CC_BLOCK), (T1T_CC_RWA_OFFSET));
2732        if ((status = rw_t1t_send_static_cmd (T1T_CMD_WRITE_NE, addr, 0x0F)) == NFC_STATUS_OK)
2733        {
2734            p_t1t->b_update = FALSE;
2735            p_t1t->b_rseg   = FALSE;
2736
2737            if (p_t1t->b_hard_lock)
2738            {
2739                num_locks = 0;
2740                while (num_locks < p_t1t->num_lockbytes)
2741                {
2742                    p_t1t->lockbyte[num_locks].lock_status = RW_T1T_LOCK_NOT_UPDATED;
2743                    num_locks++;
2744                }
2745            }
2746            p_t1t->state    = RW_T1T_STATE_SET_TAG_RO;
2747            p_t1t->substate = RW_T1T_SUBSTATE_WAIT_SET_CC_RWA_RO;
2748        }
2749    }
2750
2751    return status;
2752}
2753
2754#if (BT_TRACE_VERBOSE == TRUE)
2755/*******************************************************************************
2756**
2757** Function         rw_t1t_get_sub_state_name
2758**
2759** Description      This function returns the sub_state name.
2760**
2761** NOTE             conditionally compiled to save memory.
2762**
2763** Returns          pointer to the name
2764**
2765*******************************************************************************/
2766static char *rw_t1t_get_sub_state_name (UINT8 sub_state)
2767{
2768    switch (sub_state)
2769    {
2770    case RW_T1T_SUBSTATE_NONE:
2771        return ("NONE");
2772    case RW_T1T_SUBSTATE_WAIT_READ_TLV_VALUE:
2773        return ("EXTRACT_TLV_VALUE");
2774    case RW_T1T_SUBSTATE_WAIT_READ_LOCKS:
2775        return ("READING_LOCKS");
2776    case RW_T1T_SUBSTATE_WAIT_READ_NDEF_BLOCK:
2777        return ("READ_NDEF_FINAL_BLOCK");
2778    case RW_T1T_SUBSTATE_WAIT_INVALIDATE_NDEF:
2779        return ("INVALIDATING_NDEF");
2780    case RW_T1T_SUBSTATE_WAIT_NDEF_WRITE:
2781        return ("WRITE_NDEF_TLV_MESSAGE");
2782    case RW_T1T_SUBSTATE_WAIT_NDEF_UPDATED:
2783        return ("WAITING_RSP_FOR_LAST_NDEF_WRITE");
2784    case RW_T1T_SUBSTATE_WAIT_VALIDATE_NDEF:
2785        return ("VALIDATING_NDEF");
2786    case RW_T1T_SUBSTATE_WAIT_SET_CC_RWA_RO:
2787        return ("SET_RWA_RO");
2788    case RW_T1T_SUBSTATE_WAIT_SET_ST_LOCK_BITS:
2789        return ("SET_STATIC_LOCK_BITS");
2790    case RW_T1T_SUBSTATE_WAIT_SET_DYN_LOCK_BITS:
2791        return ("SET_DYNAMIC_LOCK_BITS");
2792
2793    default:
2794        return ("???? UNKNOWN SUBSTATE");
2795    }
2796}
2797#endif /* (BT_TRACE_VERBOSE == TRUE) */
2798
2799#endif /* (defined ((RW_NDEF_INCLUDED) && (RW_NDEF_INCLUDED == TRUE)) */
2800
2801#endif /* (NFC_INCLUDED == TRUE) */
2802