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