STMicroelectronics' M24SR NFC Dynamic Tag Library.

Dependencies:   ST_INTERFACES

Dependents:   X_NUCLEO_NFC01A1

Fork of M24SR by ST Expansion SW Team

M24SR series Dynamic NFC Tags

The M24SR series provides an NFC forum tag type 4 RF interface and supports the NFC data exchange format (NDEF). This enables NFC use cases such as simple Bluetooth pairing and other connection handovers, automatic links to URLs, storage of Vcard and other types of information. It can be used in a wide variety of applications, including consumer electronics, computer peripherals, home appliances, industrial automation and healthcare products.

  • NFC forum tag type 4 based on ISO 14443 RF interface
  • 1 MHz I²C serial interface operating from 2.7 to 5.5 V
  • EEPROM memory density from 2 Kbits to 64 Kbits with built-in NDEF message support
  • RF disable pin allowing the application to control RF access from NFC phones
  • 128-bit password protection
  • General-purpose output pin allowing flexibility for the applications (wake up on several types of events)
  • Simple antenna design, backward compatible with M24LR series

For further information and ordering please refer to the ST Page.

HelloWorld application

Import programHelloWorld_Async_M24SR

M24SR NFC example. Simple application to asynchronously write and read an URL from a M24SR tag.

Committer:
nikapov
Date:
Mon Jul 31 12:26:02 2017 +0000
Revision:
0:11161008d77a
First revision.

Who changed what in which revision?

UserRevisionLine numberNew contents of line
nikapov 0:11161008d77a 1 /**
nikapov 0:11161008d77a 2 ******************************************************************************
nikapov 0:11161008d77a 3 * @file m24sr_class.cpp
nikapov 0:11161008d77a 4 * @author ST Central Labs
nikapov 0:11161008d77a 5 * @version V2.0.0
nikapov 0:11161008d77a 6 * @date 28 Apr 2017
nikapov 0:11161008d77a 7 * @brief This file provides a set of functions to interface with the M24SR
nikapov 0:11161008d77a 8 * device.
nikapov 0:11161008d77a 9 ******************************************************************************
nikapov 0:11161008d77a 10 * @attention
nikapov 0:11161008d77a 11 *
nikapov 0:11161008d77a 12 * <h2><center>&copy; COPYRIGHT(c) 2014 STMicroelectronics</center></h2>
nikapov 0:11161008d77a 13 *
nikapov 0:11161008d77a 14 * Redistribution and use in source and binary forms, with or without modification,
nikapov 0:11161008d77a 15 * are permitted provided that the following conditions are met:
nikapov 0:11161008d77a 16 * 1. Redistributions of source code must retain the above copyright notice,
nikapov 0:11161008d77a 17 * this list of conditions and the following disclaimer.
nikapov 0:11161008d77a 18 * 2. Redistributions in binary form must reproduce the above copyright notice,
nikapov 0:11161008d77a 19 * this list of conditions and the following disclaimer in the documentation
nikapov 0:11161008d77a 20 * and/or other materials provided with the distribution.
nikapov 0:11161008d77a 21 * 3. Neither the name of STMicroelectronics nor the names of its contributors
nikapov 0:11161008d77a 22 * may be used to endorse or promote products derived from this software
nikapov 0:11161008d77a 23 * without specific prior written permission.
nikapov 0:11161008d77a 24 *
nikapov 0:11161008d77a 25 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
nikapov 0:11161008d77a 26 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
nikapov 0:11161008d77a 27 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
nikapov 0:11161008d77a 28 * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
nikapov 0:11161008d77a 29 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
nikapov 0:11161008d77a 30 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
nikapov 0:11161008d77a 31 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
nikapov 0:11161008d77a 32 * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
nikapov 0:11161008d77a 33 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
nikapov 0:11161008d77a 34 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
nikapov 0:11161008d77a 35 *
nikapov 0:11161008d77a 36 ******************************************************************************
nikapov 0:11161008d77a 37 */
nikapov 0:11161008d77a 38
nikapov 0:11161008d77a 39
nikapov 0:11161008d77a 40
nikapov 0:11161008d77a 41 /* Includes ------------------------------------------------------------------*/
nikapov 0:11161008d77a 42 #include "m24sr_def.h"
nikapov 0:11161008d77a 43 #include "M24SR.h"
nikapov 0:11161008d77a 44 #include "NDefNfcTagM24SR.h"
nikapov 0:11161008d77a 45
nikapov 0:11161008d77a 46 #ifdef GPIO_PIN_RESET
nikapov 0:11161008d77a 47 #undef GPIO_PIN_RESET
nikapov 0:11161008d77a 48 #endif
nikapov 0:11161008d77a 49 #define GPIO_PIN_RESET (0)
nikapov 0:11161008d77a 50
nikapov 0:11161008d77a 51 #ifdef GPIO_PIN_SET
nikapov 0:11161008d77a 52 #undef GPIO_PIN_SET
nikapov 0:11161008d77a 53 #endif
nikapov 0:11161008d77a 54 #define GPIO_PIN_SET (1)
nikapov 0:11161008d77a 55
nikapov 0:11161008d77a 56 #define M24SR_MAX_BYTE_OPERATION_LENGHT (246)
nikapov 0:11161008d77a 57
nikapov 0:11161008d77a 58 /**
nikapov 0:11161008d77a 59 * default password, also used to enable super user mode through the I2C channel
nikapov 0:11161008d77a 60 */
nikapov 0:11161008d77a 61 const uint8_t M24SR::DEFAULT_PASSWORD[16] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
nikapov 0:11161008d77a 62 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
nikapov 0:11161008d77a 63
nikapov 0:11161008d77a 64 /** @addtogroup M24SR_Driver
nikapov 0:11161008d77a 65 * @{
nikapov 0:11161008d77a 66 * @brief <b>This folder contains the driver layer of M24SR family (M24SR64, M24SR16, M24SR04, M24SR02)</b>
nikapov 0:11161008d77a 67 */
nikapov 0:11161008d77a 68
nikapov 0:11161008d77a 69 /** @defgroup drv_M24SR
nikapov 0:11161008d77a 70 * @{
nikapov 0:11161008d77a 71 * @brief This file contains the driver which implements all the M24SR commands.
nikapov 0:11161008d77a 72 */
nikapov 0:11161008d77a 73
nikapov 0:11161008d77a 74 #ifndef errchk
nikapov 0:11161008d77a 75
nikapov 0:11161008d77a 76 /** value returned by the NFC chip when a command is successfully completed */
nikapov 0:11161008d77a 77 #define NFC_COMMAND_SUCCESS 0x9000
nikapov 0:11161008d77a 78
nikapov 0:11161008d77a 79 /** call the fCall function and check that the return status is M24SR_SUCCESS,
nikapov 0:11161008d77a 80 * otherwise return the error status*/
nikapov 0:11161008d77a 81 #define errchk(fCall) {\
nikapov 0:11161008d77a 82 const int status = (int) (fCall); \
nikapov 0:11161008d77a 83 if((status!=M24SR_SUCCESS)) { \
nikapov 0:11161008d77a 84 return (M24SR::StatusTypeDef)status; \
nikapov 0:11161008d77a 85 }\
nikapov 0:11161008d77a 86 }
nikapov 0:11161008d77a 87 #endif
nikapov 0:11161008d77a 88
nikapov 0:11161008d77a 89 /**
nikapov 0:11161008d77a 90 * @brief This function updates the CRC
nikapov 0:11161008d77a 91 * @param None
nikapov 0:11161008d77a 92 * @retval None
nikapov 0:11161008d77a 93 */
nikapov 0:11161008d77a 94 static uint16_t M24SR_UpdateCrc(uint8_t ch, uint16_t *lpwCrc) {
nikapov 0:11161008d77a 95 ch = (ch ^ (uint8_t) ((*lpwCrc) & 0x00FF));
nikapov 0:11161008d77a 96 ch = (ch ^ (ch << 4));
nikapov 0:11161008d77a 97 *lpwCrc = (*lpwCrc >> 8) ^ ((uint16_t) ch << 8) ^ ((uint16_t) ch << 3) ^ ((uint16_t) ch >> 4);
nikapov 0:11161008d77a 98
nikapov 0:11161008d77a 99 return (*lpwCrc);
nikapov 0:11161008d77a 100 }
nikapov 0:11161008d77a 101
nikapov 0:11161008d77a 102 /**
nikapov 0:11161008d77a 103 * @brief This function returns the CRC 16
nikapov 0:11161008d77a 104 * @param Data : pointer on the data used to compute the CRC16
nikapov 0:11161008d77a 105 * @param Length : number of bytes of the data
nikapov 0:11161008d77a 106 * @retval CRC16
nikapov 0:11161008d77a 107 */
nikapov 0:11161008d77a 108 static uint16_t M24SR_ComputeCrc(uint8_t *Data, uint8_t Length) {
nikapov 0:11161008d77a 109 uint8_t chBlock;
nikapov 0:11161008d77a 110 uint16_t wCrc = 0x6363; // ITU-V.41
nikapov 0:11161008d77a 111
nikapov 0:11161008d77a 112 do {
nikapov 0:11161008d77a 113 chBlock = *Data++;
nikapov 0:11161008d77a 114 M24SR_UpdateCrc(chBlock, &wCrc);
nikapov 0:11161008d77a 115 } while (--Length);
nikapov 0:11161008d77a 116
nikapov 0:11161008d77a 117 return wCrc;
nikapov 0:11161008d77a 118 }
nikapov 0:11161008d77a 119
nikapov 0:11161008d77a 120 /**
nikapov 0:11161008d77a 121 * @brief This function computes the CRC16 residue as defined by CRC ISO/IEC 13239
nikapov 0:11161008d77a 122 * @param DataIn : input data
nikapov 0:11161008d77a 123 * @param Length : Number of bits of DataIn
nikapov 0:11161008d77a 124 * @retval Status (SW1&SW2) : CRC16 residue is correct
nikapov 0:11161008d77a 125 * @retval M24SR_ERROR_CRC : CRC16 residue is false
nikapov 0:11161008d77a 126 */
nikapov 0:11161008d77a 127 static M24SR::StatusTypeDef M24SR_IsCorrectCRC16Residue(uint8_t *DataIn, uint8_t Length) {
nikapov 0:11161008d77a 128 uint16_t ResCRC = 0x0000;
nikapov 0:11161008d77a 129 M24SR::StatusTypeDef status;
nikapov 0:11161008d77a 130 /* check the CRC16 Residue */
nikapov 0:11161008d77a 131 if (Length != 0) {
nikapov 0:11161008d77a 132 ResCRC = M24SR_ComputeCrc(DataIn, Length);
nikapov 0:11161008d77a 133 }
nikapov 0:11161008d77a 134
nikapov 0:11161008d77a 135 if (ResCRC == 0x0000) {
nikapov 0:11161008d77a 136 /* Good CRC, but error status from M24SR */
nikapov 0:11161008d77a 137 status = (M24SR::StatusTypeDef) (((DataIn[Length - UB_STATUS_OFFSET] << 8)
nikapov 0:11161008d77a 138 & 0xFF00) | (DataIn[Length - LB_STATUS_OFFSET] & 0x00FF));
nikapov 0:11161008d77a 139 } else {
nikapov 0:11161008d77a 140 ResCRC = 0x0000;
nikapov 0:11161008d77a 141 ResCRC = M24SR_ComputeCrc(DataIn, 5);
nikapov 0:11161008d77a 142 if (ResCRC != 0x0000) {
nikapov 0:11161008d77a 143 /* Bad CRC */
nikapov 0:11161008d77a 144 return M24SR::M24SR_IO_ERROR_CRC;
nikapov 0:11161008d77a 145 } else {
nikapov 0:11161008d77a 146 /* Good CRC, but error status from M24SR */
nikapov 0:11161008d77a 147 status= (M24SR::StatusTypeDef) (((DataIn[1] << 8) & 0xFF00)
nikapov 0:11161008d77a 148 | (DataIn[2] & 0x00FF));
nikapov 0:11161008d77a 149 }
nikapov 0:11161008d77a 150 }
nikapov 0:11161008d77a 151 if (status==NFC_COMMAND_SUCCESS) {
nikapov 0:11161008d77a 152 status =M24SR::M24SR_SUCCESS;
nikapov 0:11161008d77a 153 }
nikapov 0:11161008d77a 154
nikapov 0:11161008d77a 155 return status;
nikapov 0:11161008d77a 156 }
nikapov 0:11161008d77a 157
nikapov 0:11161008d77a 158 /**
nikapov 0:11161008d77a 159 * @brief This functions creates an I block command according to the structures CommandStructure and Command.
nikapov 0:11161008d77a 160 * @param Command : structure which contains the field of the different parameters
nikapov 0:11161008d77a 161 * @param CommandStructure : structure of the command
nikapov 0:11161008d77a 162 * @param NbByte : number of bytes of the command
nikapov 0:11161008d77a 163 * @param pCommand : pointer to the command created
nikapov 0:11161008d77a 164 */
nikapov 0:11161008d77a 165 static void M24SR_BuildIBlockCommand(uint16_t CommandStructure, C_APDU *Command, uint8_t uDIDbyte, uint16_t *NbByte, uint8_t *pCommand) {
nikapov 0:11161008d77a 166 uint16_t uCRC16;
nikapov 0:11161008d77a 167 static uint8_t BlockNumber = 0x01;
nikapov 0:11161008d77a 168
nikapov 0:11161008d77a 169 (*NbByte) = 0;
nikapov 0:11161008d77a 170
nikapov 0:11161008d77a 171 /* add the PCD byte */
nikapov 0:11161008d77a 172 if ((CommandStructure & M24SR_PCB_NEEDED) != 0) {
nikapov 0:11161008d77a 173 /* toggle the block number */
nikapov 0:11161008d77a 174 BlockNumber = TOGGLE(BlockNumber);
nikapov 0:11161008d77a 175 /* Add the I block byte */
nikapov 0:11161008d77a 176 pCommand[(*NbByte)++] = 0x02 | BlockNumber;
nikapov 0:11161008d77a 177 }
nikapov 0:11161008d77a 178
nikapov 0:11161008d77a 179 /* add the DID byte */
nikapov 0:11161008d77a 180 if ((BlockNumber & M24SR_DID_NEEDED) != 0) {
nikapov 0:11161008d77a 181 /* Add the I block byte */
nikapov 0:11161008d77a 182 pCommand[(*NbByte)++] = uDIDbyte;
nikapov 0:11161008d77a 183 }
nikapov 0:11161008d77a 184
nikapov 0:11161008d77a 185 /* add the Class byte */
nikapov 0:11161008d77a 186 if ((CommandStructure & M24SR_CLA_NEEDED) != 0) {
nikapov 0:11161008d77a 187 pCommand[(*NbByte)++] = Command->Header.CLA;
nikapov 0:11161008d77a 188 }
nikapov 0:11161008d77a 189 /* add the instruction byte byte */
nikapov 0:11161008d77a 190 if ((CommandStructure & M24SR_INS_NEEDED) != 0) {
nikapov 0:11161008d77a 191 pCommand[(*NbByte)++] = Command->Header.INS;
nikapov 0:11161008d77a 192 }
nikapov 0:11161008d77a 193 /* add the Selection Mode byte */
nikapov 0:11161008d77a 194 if ((CommandStructure & M24SR_P1_NEEDED) != 0) {
nikapov 0:11161008d77a 195 pCommand[(*NbByte)++] = Command->Header.P1;
nikapov 0:11161008d77a 196 }
nikapov 0:11161008d77a 197 /* add the Selection Mode byte */
nikapov 0:11161008d77a 198 if ((CommandStructure & M24SR_P2_NEEDED) != 0) {
nikapov 0:11161008d77a 199 pCommand[(*NbByte)++] = Command->Header.P2;
nikapov 0:11161008d77a 200 }
nikapov 0:11161008d77a 201 /* add Data field lengthbyte */
nikapov 0:11161008d77a 202 if ((CommandStructure & M24SR_LC_NEEDED) != 0) {
nikapov 0:11161008d77a 203 pCommand[(*NbByte)++] = Command->Body.LC;
nikapov 0:11161008d77a 204 }
nikapov 0:11161008d77a 205 /* add Data field */
nikapov 0:11161008d77a 206 if ((CommandStructure & M24SR_DATA_NEEDED) != 0) {
nikapov 0:11161008d77a 207 memcpy(&(pCommand[(*NbByte)]), Command->Body.pData, Command->Body.LC);
nikapov 0:11161008d77a 208 (*NbByte) += Command->Body.LC;
nikapov 0:11161008d77a 209 }
nikapov 0:11161008d77a 210 /* add Le field */
nikapov 0:11161008d77a 211 if ((CommandStructure & M24SR_LE_NEEDED) != 0) {
nikapov 0:11161008d77a 212 pCommand[(*NbByte)++] = Command->Body.LE;
nikapov 0:11161008d77a 213 }
nikapov 0:11161008d77a 214 /* add CRC field */
nikapov 0:11161008d77a 215 if ((CommandStructure & M24SR_CRC_NEEDED) != 0) {
nikapov 0:11161008d77a 216 uCRC16 = M24SR_ComputeCrc(pCommand, (uint8_t) (*NbByte));
nikapov 0:11161008d77a 217 /* append the CRC16 */
nikapov 0:11161008d77a 218 pCommand[(*NbByte)++] = GETLSB(uCRC16);
nikapov 0:11161008d77a 219 pCommand[(*NbByte)++] = GETMSB(uCRC16);
nikapov 0:11161008d77a 220 }
nikapov 0:11161008d77a 221
nikapov 0:11161008d77a 222 }
nikapov 0:11161008d77a 223
nikapov 0:11161008d77a 224
nikapov 0:11161008d77a 225
nikapov 0:11161008d77a 226
nikapov 0:11161008d77a 227 /**
nikapov 0:11161008d77a 228 * @brief This function returns M24SR_STATUS_SUCCESS if the pBuffer is an s-block
nikapov 0:11161008d77a 229 * @param pBuffer : pointer to the data
nikapov 0:11161008d77a 230 * @retval M24SR_SUCCESS : the data is a S-Block
nikapov 0:11161008d77a 231 * @retval NFC_ERROR : the data is not a S-Block
nikapov 0:11161008d77a 232 */
nikapov 0:11161008d77a 233 static M24SR::StatusTypeDef IsSBlock(uint8_t *pBuffer) {
nikapov 0:11161008d77a 234
nikapov 0:11161008d77a 235 if ((pBuffer[M24SR_OFFSET_PCB] & M24SR_MASK_BLOCK) == M24SR_MASK_SBLOCK) {
nikapov 0:11161008d77a 236 return M24SR::M24SR_SUCCESS;
nikapov 0:11161008d77a 237 } else {
nikapov 0:11161008d77a 238 return M24SR::M24SR_ERROR;
nikapov 0:11161008d77a 239 }
nikapov 0:11161008d77a 240
nikapov 0:11161008d77a 241 }
nikapov 0:11161008d77a 242
nikapov 0:11161008d77a 243 M24SR::M24SR(const uint8_t address, I2C &I2C,gpoEventCallback eventCallback, const PinName& GPOPinName,
nikapov 0:11161008d77a 244 const PinName& RFDISPinName) :
nikapov 0:11161008d77a 245 who_am_i(0),
nikapov 0:11161008d77a 246 type(0),
nikapov 0:11161008d77a 247 address(address),
nikapov 0:11161008d77a 248 dev_I2C(I2C),
nikapov 0:11161008d77a 249 GPOPin(GPOPinName),
nikapov 0:11161008d77a 250 RFDisablePin(RFDISPinName),
nikapov 0:11161008d77a 251 mCommunicationType(SYNC),
nikapov 0:11161008d77a 252 mLastCommandSend(NONE),
nikapov 0:11161008d77a 253 mGpoEventInterrupt(GPOPinName),
nikapov 0:11161008d77a 254 mCallback(&defaultCallback),
nikapov 0:11161008d77a 255 mComponentCallback(NULL),
nikapov 0:11161008d77a 256 mNDefTagUtil(new NDefNfcTagM24SR(*this)),
nikapov 0:11161008d77a 257 mManageGPOCallback(*this),
nikapov 0:11161008d77a 258 mReadIDCallback(*this){
nikapov 0:11161008d77a 259 //mNDefTagUtil(NULL){
nikapov 0:11161008d77a 260 memset(uM24SRbuffer, 0, 0xFF * sizeof(int8_t));
nikapov 0:11161008d77a 261 uDIDbyte = 0;
nikapov 0:11161008d77a 262 if (RFDisablePin.is_connected()!=0) {
nikapov 0:11161008d77a 263 RFDisablePin = 0;
nikapov 0:11161008d77a 264 }
nikapov 0:11161008d77a 265 if(GPOPin.is_connected()!=0){
nikapov 0:11161008d77a 266 if(eventCallback!=NULL)
nikapov 0:11161008d77a 267 mGpoEventInterrupt.fall(eventCallback);
nikapov 0:11161008d77a 268 mGpoEventInterrupt.mode(PullUp);
nikapov 0:11161008d77a 269 mGpoEventInterrupt.disable_irq();
nikapov 0:11161008d77a 270 }
nikapov 0:11161008d77a 271 }
nikapov 0:11161008d77a 272
nikapov 0:11161008d77a 273 M24SR::~M24SR(){
nikapov 0:11161008d77a 274 delete mNDefTagUtil;
nikapov 0:11161008d77a 275 }
nikapov 0:11161008d77a 276
nikapov 0:11161008d77a 277 /**
nikapov 0:11161008d77a 278 * @brief This function sends the FWT extension command (S-Block format)
nikapov 0:11161008d77a 279 * @param FWTbyte : FWT value
nikapov 0:11161008d77a 280 * @return M24SR_SUCCESS if no errors
nikapov 0:11161008d77a 281 */
nikapov 0:11161008d77a 282 M24SR::StatusTypeDef M24SR::M24SR_SendFWTExtension(uint8_t FWTbyte) {
nikapov 0:11161008d77a 283 uint8_t pBuffer[M24SR_STATUSRESPONSE_NBBYTE];
nikapov 0:11161008d77a 284 M24SR::StatusTypeDef status;
nikapov 0:11161008d77a 285 uint8_t NthByte = 0;
nikapov 0:11161008d77a 286 uint16_t uCRC16;
nikapov 0:11161008d77a 287
nikapov 0:11161008d77a 288 /* create the response */
nikapov 0:11161008d77a 289 pBuffer[NthByte++] = 0xF2;
nikapov 0:11161008d77a 290 pBuffer[NthByte++] = FWTbyte;
nikapov 0:11161008d77a 291 /* compute the CRC */
nikapov 0:11161008d77a 292 uCRC16 = M24SR_ComputeCrc(pBuffer, 0x02);
nikapov 0:11161008d77a 293 /* append the CRC16 */
nikapov 0:11161008d77a 294 pBuffer[NthByte++] = GETLSB(uCRC16);
nikapov 0:11161008d77a 295 pBuffer[NthByte++] = GETMSB(uCRC16);
nikapov 0:11161008d77a 296
nikapov 0:11161008d77a 297 /* send the request */
nikapov 0:11161008d77a 298 status = M24SR_IO_SendI2Ccommand(NthByte, pBuffer);
nikapov 0:11161008d77a 299 if (status != M24SR_SUCCESS) {
nikapov 0:11161008d77a 300 return status;
nikapov 0:11161008d77a 301 }
nikapov 0:11161008d77a 302
nikapov 0:11161008d77a 303 mLastCommandSend=UPDATE;
nikapov 0:11161008d77a 304
nikapov 0:11161008d77a 305 if (mCommunicationType==M24SR::SYNC) {
nikapov 0:11161008d77a 306 status = M24SR_IO_PollI2C();
nikapov 0:11161008d77a 307 if (status == M24SR_SUCCESS) {
nikapov 0:11161008d77a 308 return M24SR_ReceiveUpdateBinary();
nikapov 0:11161008d77a 309 } else {
nikapov 0:11161008d77a 310 mLastCommandSend = NONE;
nikapov 0:11161008d77a 311 getCallback()->on_updated_binary(this,status,mLastCommandData.offset, mLastCommandData.data,mLastCommandData.length);
nikapov 0:11161008d77a 312 return status;
nikapov 0:11161008d77a 313 }//if-else
nikapov 0:11161008d77a 314 }//if
nikapov 0:11161008d77a 315
nikapov 0:11161008d77a 316 return M24SR_SUCCESS;
nikapov 0:11161008d77a 317 }
nikapov 0:11161008d77a 318
nikapov 0:11161008d77a 319 /**
nikapov 0:11161008d77a 320 * @brief This function initialize the M24SR device
nikapov 0:11161008d77a 321 * @retval None
nikapov 0:11161008d77a 322 */
nikapov 0:11161008d77a 323 M24SR::StatusTypeDef M24SR::M24SR_Init(M24SR_InitTypeDef *notUsed) {
nikapov 0:11161008d77a 324 (void) notUsed;
nikapov 0:11161008d77a 325 //force to open a i2c session
nikapov 0:11161008d77a 326 StatusTypeDef status = M24SR_ForceSession();
nikapov 0:11161008d77a 327 if(status!= M24SR_SUCCESS) {
nikapov 0:11161008d77a 328 return status;
nikapov 0:11161008d77a 329 }
nikapov 0:11161008d77a 330 //leave the gpo always up
nikapov 0:11161008d77a 331 if(GPOPin.is_connected()!=0) {
nikapov 0:11161008d77a 332 status = M24SR_ManageI2CGPO(DEFAULT_GPO_STATUS);
nikapov 0:11161008d77a 333 if(status!= M24SR_SUCCESS)
nikapov 0:11161008d77a 334 return status;
nikapov 0:11161008d77a 335 }
nikapov 0:11161008d77a 336 if(RFDisablePin.is_connected()!=0) {
nikapov 0:11161008d77a 337 status = M24SR_ManageRFGPO(DEFAULT_GPO_STATUS);
nikapov 0:11161008d77a 338 if(status!= M24SR_SUCCESS)
nikapov 0:11161008d77a 339 return status;
nikapov 0:11161008d77a 340 }
nikapov 0:11161008d77a 341 //close the session
nikapov 0:11161008d77a 342 status = M24SR_Deselect();
nikapov 0:11161008d77a 343 if (status!= M24SR_SUCCESS) {
nikapov 0:11161008d77a 344 return status;
nikapov 0:11161008d77a 345 }
nikapov 0:11161008d77a 346 if(GPOPin.is_connected()!=0) {
nikapov 0:11161008d77a 347 mGpoEventInterrupt.enable_irq();
nikapov 0:11161008d77a 348 }
nikapov 0:11161008d77a 349 return M24SR_SUCCESS;
nikapov 0:11161008d77a 350 }
nikapov 0:11161008d77a 351
nikapov 0:11161008d77a 352
nikapov 0:11161008d77a 353 /**
nikapov 0:11161008d77a 354 * @brief This function sends the KillSession command to the M24SR device
nikapov 0:11161008d77a 355 * @param None
nikapov 0:11161008d77a 356 * @return M24SR_SUCCESS if no errors
nikapov 0:11161008d77a 357 */
nikapov 0:11161008d77a 358 M24SR::StatusTypeDef M24SR::M24SR_ForceSession(void) {
nikapov 0:11161008d77a 359 uint8_t commandBuffer[] = M24SR_KILLSESSION_COMMAND;
nikapov 0:11161008d77a 360 M24SR::StatusTypeDef status;
nikapov 0:11161008d77a 361 status = M24SR_IO_SendI2Ccommand(sizeof(commandBuffer), commandBuffer);
nikapov 0:11161008d77a 362 if(status!=M24SR_SUCCESS) {
nikapov 0:11161008d77a 363 mCallback->on_session_open(this,status);
nikapov 0:11161008d77a 364 return status;
nikapov 0:11161008d77a 365 }
nikapov 0:11161008d77a 366
nikapov 0:11161008d77a 367 /* Insure no access will be done just after open session */
nikapov 0:11161008d77a 368 /* The only way here is to poll I2C to know when M24SR is ready */
nikapov 0:11161008d77a 369 /* GPO can not be use with KillSession command */
nikapov 0:11161008d77a 370 status = M24SR_IO_PollI2C();
nikapov 0:11161008d77a 371
nikapov 0:11161008d77a 372 getCallback()->on_session_open(this,status);
nikapov 0:11161008d77a 373 return status;
nikapov 0:11161008d77a 374
nikapov 0:11161008d77a 375 }
nikapov 0:11161008d77a 376
nikapov 0:11161008d77a 377 /**
nikapov 0:11161008d77a 378 * @brief This function sends the Deselect command (S-Block format)
nikapov 0:11161008d77a 379 * @return M24SR_SUCCESS if no errors
nikapov 0:11161008d77a 380 */
nikapov 0:11161008d77a 381 M24SR::StatusTypeDef M24SR::M24SR_Deselect(void) {
nikapov 0:11161008d77a 382 uint8_t pBuffer[] = M24SR_DESELECTREQUEST_COMMAND;
nikapov 0:11161008d77a 383 M24SR::StatusTypeDef status;
nikapov 0:11161008d77a 384 /* send the request */
nikapov 0:11161008d77a 385 status = M24SR_IO_SendI2Ccommand(sizeof(pBuffer), pBuffer);
nikapov 0:11161008d77a 386 if(status!=M24SR_SUCCESS) {
nikapov 0:11161008d77a 387 getCallback()->on_deselect(this,status);
nikapov 0:11161008d77a 388 }
nikapov 0:11161008d77a 389
nikapov 0:11161008d77a 390 mLastCommandSend=DESELECT;
nikapov 0:11161008d77a 391
nikapov 0:11161008d77a 392 if (mCommunicationType==M24SR::SYNC) {
nikapov 0:11161008d77a 393 status = M24SR_IO_PollI2C();
nikapov 0:11161008d77a 394 if(status == M24SR_SUCCESS) {
nikapov 0:11161008d77a 395 return M24SR_ReceiveDeselect();
nikapov 0:11161008d77a 396 } else {
nikapov 0:11161008d77a 397 mLastCommandSend = NONE;
nikapov 0:11161008d77a 398 getCallback()->on_selected_application(this,status);
nikapov 0:11161008d77a 399 return status;
nikapov 0:11161008d77a 400 }//if-else
nikapov 0:11161008d77a 401
nikapov 0:11161008d77a 402 }
nikapov 0:11161008d77a 403
nikapov 0:11161008d77a 404 return M24SR_SUCCESS;
nikapov 0:11161008d77a 405 }
nikapov 0:11161008d77a 406
nikapov 0:11161008d77a 407 M24SR::StatusTypeDef M24SR::M24SR_ReceiveDeselect(void) {
nikapov 0:11161008d77a 408 uint8_t pBuffer[4];
nikapov 0:11161008d77a 409 M24SR::StatusTypeDef status;
nikapov 0:11161008d77a 410 status = M24SR_IO_ReceiveI2Cresponse(sizeof(pBuffer), pBuffer);
nikapov 0:11161008d77a 411 getCallback()->on_deselect(this,status);
nikapov 0:11161008d77a 412 return status;
nikapov 0:11161008d77a 413 }
nikapov 0:11161008d77a 414
nikapov 0:11161008d77a 415 /**
nikapov 0:11161008d77a 416 * @brief This function sends the GetSession command to the M24SR device
nikapov 0:11161008d77a 417 * @retval M24SR_SUCCESS the function is successful.
nikapov 0:11161008d77a 418 * @retval Status (SW1&SW2) if operation does not complete.
nikapov 0:11161008d77a 419 */
nikapov 0:11161008d77a 420 M24SR::StatusTypeDef M24SR::M24SR_GetSession(void) {
nikapov 0:11161008d77a 421 uint8_t commandBuffer[] = M24SR_OPENSESSION_COMMAND;
nikapov 0:11161008d77a 422
nikapov 0:11161008d77a 423 M24SR::StatusTypeDef status;
nikapov 0:11161008d77a 424 status = M24SR_IO_SendI2Ccommand(sizeof(commandBuffer), commandBuffer);
nikapov 0:11161008d77a 425 if (status!=M24SR_SUCCESS) {
nikapov 0:11161008d77a 426 getCallback()->on_session_open(this,status);
nikapov 0:11161008d77a 427 return status;
nikapov 0:11161008d77a 428 }
nikapov 0:11161008d77a 429
nikapov 0:11161008d77a 430 /* Insure no access will be done just after open session */
nikapov 0:11161008d77a 431 /* The only way here is to poll I2C to know when M24SR is ready */
nikapov 0:11161008d77a 432 /* GPO can not be use with KillSession command */
nikapov 0:11161008d77a 433 status = M24SR_IO_PollI2C();
nikapov 0:11161008d77a 434
nikapov 0:11161008d77a 435 getCallback()->on_session_open(this,status);
nikapov 0:11161008d77a 436 return status;
nikapov 0:11161008d77a 437 }
nikapov 0:11161008d77a 438
nikapov 0:11161008d77a 439 /**
nikapov 0:11161008d77a 440 * @brief This function sends the SelectApplication command
nikapov 0:11161008d77a 441 * @return M24SR_SUCCESS if no errors
nikapov 0:11161008d77a 442 */
nikapov 0:11161008d77a 443 M24SR::StatusTypeDef M24SR::M24SR_SendSelectApplication(void) {
nikapov 0:11161008d77a 444
nikapov 0:11161008d77a 445 C_APDU command;
nikapov 0:11161008d77a 446 M24SR::StatusTypeDef status;
nikapov 0:11161008d77a 447 uint8_t *pBuffer = uM24SRbuffer;
nikapov 0:11161008d77a 448 uint8_t pDataOut[] = M24SR_SELECTAPPLICATION_COMMAND;
nikapov 0:11161008d77a 449 uint8_t uLe = 0x00;
nikapov 0:11161008d77a 450 uint16_t uP1P2 =0x0400, NbByte;
nikapov 0:11161008d77a 451
nikapov 0:11161008d77a 452 /* build the command */
nikapov 0:11161008d77a 453 command.Header.CLA = C_APDU_CLA_DEFAULT;
nikapov 0:11161008d77a 454 command.Header.INS = C_APDU_SELECT_FILE;
nikapov 0:11161008d77a 455 /* copy the offset */
nikapov 0:11161008d77a 456 command.Header.P1 = GETMSB(uP1P2);
nikapov 0:11161008d77a 457 command.Header.P2 = GETLSB(uP1P2);
nikapov 0:11161008d77a 458 /* copy the number of byte of the data field */
nikapov 0:11161008d77a 459 command.Body.LC = sizeof(pDataOut);
nikapov 0:11161008d77a 460 /* copy the data */
nikapov 0:11161008d77a 461 command.Body.pData = pDataOut;
nikapov 0:11161008d77a 462 /* copy the number of byte to read */
nikapov 0:11161008d77a 463 command.Body.LE = uLe;
nikapov 0:11161008d77a 464 /* build the I2C command */
nikapov 0:11161008d77a 465 M24SR_BuildIBlockCommand( M24SR_CMDSTRUCT_SELECTAPPLICATION, &command, uDIDbyte, &NbByte, pBuffer);
nikapov 0:11161008d77a 466
nikapov 0:11161008d77a 467 /* send the request */
nikapov 0:11161008d77a 468 status = M24SR_IO_SendI2Ccommand(NbByte, pBuffer);
nikapov 0:11161008d77a 469 if (status != M24SR_SUCCESS) {
nikapov 0:11161008d77a 470 getCallback()->on_selected_application(this,status);
nikapov 0:11161008d77a 471 return status;
nikapov 0:11161008d77a 472 }
nikapov 0:11161008d77a 473
nikapov 0:11161008d77a 474 mLastCommandSend=SELECT_APPLICATION;
nikapov 0:11161008d77a 475
nikapov 0:11161008d77a 476 if (mCommunicationType==M24SR::SYNC) {
nikapov 0:11161008d77a 477 status = M24SR_IO_PollI2C();
nikapov 0:11161008d77a 478 if (status == M24SR_SUCCESS) {
nikapov 0:11161008d77a 479 return M24SR_ReceiveSelectApplication();
nikapov 0:11161008d77a 480 } else {
nikapov 0:11161008d77a 481 mLastCommandSend = NONE;
nikapov 0:11161008d77a 482 getCallback()->on_selected_application(this,status);
nikapov 0:11161008d77a 483 return status;
nikapov 0:11161008d77a 484 }//if-else
nikapov 0:11161008d77a 485 }//if
nikapov 0:11161008d77a 486
nikapov 0:11161008d77a 487 return M24SR_SUCCESS;
nikapov 0:11161008d77a 488 }
nikapov 0:11161008d77a 489
nikapov 0:11161008d77a 490 M24SR::StatusTypeDef M24SR::M24SR_ReceiveSelectApplication(void) {
nikapov 0:11161008d77a 491 uint8_t pDataIn[M24SR_STATUSRESPONSE_NBBYTE];
nikapov 0:11161008d77a 492 M24SR::StatusTypeDef status;
nikapov 0:11161008d77a 493
nikapov 0:11161008d77a 494 mLastCommandSend = NONE;
nikapov 0:11161008d77a 495
nikapov 0:11161008d77a 496 status = M24SR_IO_ReceiveI2Cresponse(sizeof(pDataIn), pDataIn);
nikapov 0:11161008d77a 497 if (status!=M24SR_SUCCESS) {
nikapov 0:11161008d77a 498 getCallback()->on_selected_application(this,status);
nikapov 0:11161008d77a 499 return status;
nikapov 0:11161008d77a 500 }//else
nikapov 0:11161008d77a 501 status = M24SR_IsCorrectCRC16Residue(pDataIn, sizeof(pDataIn));
nikapov 0:11161008d77a 502 getCallback()->on_selected_application(this,status);
nikapov 0:11161008d77a 503
nikapov 0:11161008d77a 504 return status;
nikapov 0:11161008d77a 505 }
nikapov 0:11161008d77a 506
nikapov 0:11161008d77a 507 M24SR::StatusTypeDef M24SR::M24SR_ReadID(uint8_t *nfc_id) {
nikapov 0:11161008d77a 508 if (!nfc_id) {
nikapov 0:11161008d77a 509 return M24SR_ERROR;
nikapov 0:11161008d77a 510 }
nikapov 0:11161008d77a 511
nikapov 0:11161008d77a 512 //enable the callback for change the gpo
nikapov 0:11161008d77a 513 mComponentCallback = &mReadIDCallback;
nikapov 0:11161008d77a 514 mReadIDCallback.read_id_on(nfc_id);
nikapov 0:11161008d77a 515
nikapov 0:11161008d77a 516 //start the readID procedure
nikapov 0:11161008d77a 517 return M24SR_SendSelectApplication();
nikapov 0:11161008d77a 518 }
nikapov 0:11161008d77a 519
nikapov 0:11161008d77a 520 /**
nikapov 0:11161008d77a 521 * @brief This function sends the SelectCCFile command
nikapov 0:11161008d77a 522 * @retval M24SR_SUCCESS the function is successful.
nikapov 0:11161008d77a 523 * @retval M24SR_ERROR_I2CTIMEOUT I2C timeout occurred.
nikapov 0:11161008d77a 524 * @retval Status (SW1&SW2) if operation does not complete for another reason.
nikapov 0:11161008d77a 525 */
nikapov 0:11161008d77a 526 M24SR::StatusTypeDef M24SR::M24SR_SendSelectCCfile(void) {
nikapov 0:11161008d77a 527 C_APDU command;
nikapov 0:11161008d77a 528 M24SR::StatusTypeDef status;
nikapov 0:11161008d77a 529 uint8_t *pBuffer = uM24SRbuffer;
nikapov 0:11161008d77a 530 uint8_t pDataOut[] = CC_FILE_ID_BYTES;
nikapov 0:11161008d77a 531 uint16_t uP1P2 =0x000C,
nikapov 0:11161008d77a 532 NbByte;
nikapov 0:11161008d77a 533
nikapov 0:11161008d77a 534 /* build the command */
nikapov 0:11161008d77a 535 command.Header.CLA = C_APDU_CLA_DEFAULT;
nikapov 0:11161008d77a 536 command.Header.INS = C_APDU_SELECT_FILE;
nikapov 0:11161008d77a 537 /* copy the offset */
nikapov 0:11161008d77a 538 command.Header.P1 = GETMSB(uP1P2);
nikapov 0:11161008d77a 539 command.Header.P2 = GETLSB(uP1P2);
nikapov 0:11161008d77a 540 /* copy the number of byte of the data field */
nikapov 0:11161008d77a 541 command.Body.LC = sizeof(pDataOut);
nikapov 0:11161008d77a 542 command.Body.pData = pDataOut;
nikapov 0:11161008d77a 543 /* build the I2C command */
nikapov 0:11161008d77a 544 M24SR_BuildIBlockCommand(M24SR_CMDSTRUCT_SELECTCCFILE, &command, uDIDbyte, &NbByte, pBuffer);
nikapov 0:11161008d77a 545
nikapov 0:11161008d77a 546 /* send the request */
nikapov 0:11161008d77a 547 status = M24SR_IO_SendI2Ccommand(NbByte, pBuffer);
nikapov 0:11161008d77a 548 if(status!=M24SR_SUCCESS) {
nikapov 0:11161008d77a 549 getCallback()->on_selected_CC_file(this,status);
nikapov 0:11161008d77a 550 return status;
nikapov 0:11161008d77a 551 }//else
nikapov 0:11161008d77a 552
nikapov 0:11161008d77a 553 mLastCommandSend=SELECT_CC_FILE;
nikapov 0:11161008d77a 554
nikapov 0:11161008d77a 555 if (mCommunicationType==M24SR::SYNC){
nikapov 0:11161008d77a 556 status = M24SR_IO_PollI2C();
nikapov 0:11161008d77a 557 if (status==M24SR_SUCCESS) {
nikapov 0:11161008d77a 558 return M24SR_ReceiveSelectCCfile();
nikapov 0:11161008d77a 559 } else {
nikapov 0:11161008d77a 560 mLastCommandSend = NONE;
nikapov 0:11161008d77a 561 getCallback()->on_selected_CC_file(this,status);
nikapov 0:11161008d77a 562 return status;
nikapov 0:11161008d77a 563 }//if-else
nikapov 0:11161008d77a 564 }//if
nikapov 0:11161008d77a 565
nikapov 0:11161008d77a 566 return M24SR_SUCCESS;
nikapov 0:11161008d77a 567 }
nikapov 0:11161008d77a 568
nikapov 0:11161008d77a 569 M24SR::StatusTypeDef M24SR::M24SR_ReceiveSelectCCfile(void){
nikapov 0:11161008d77a 570
nikapov 0:11161008d77a 571 uint8_t pDataIn[M24SR_STATUSRESPONSE_NBBYTE];
nikapov 0:11161008d77a 572 M24SR::StatusTypeDef status;
nikapov 0:11161008d77a 573
nikapov 0:11161008d77a 574 mLastCommandSend = NONE;
nikapov 0:11161008d77a 575
nikapov 0:11161008d77a 576 status = M24SR_IO_ReceiveI2Cresponse(sizeof(pDataIn), pDataIn);
nikapov 0:11161008d77a 577 if (status!=M24SR_SUCCESS) {
nikapov 0:11161008d77a 578 getCallback()->on_selected_CC_file(this,status);
nikapov 0:11161008d77a 579 return status;
nikapov 0:11161008d77a 580 }//else
nikapov 0:11161008d77a 581 status = M24SR_IsCorrectCRC16Residue(pDataIn, sizeof(pDataIn));
nikapov 0:11161008d77a 582 getCallback()->on_selected_CC_file(this,status);
nikapov 0:11161008d77a 583
nikapov 0:11161008d77a 584 return status;
nikapov 0:11161008d77a 585 }
nikapov 0:11161008d77a 586
nikapov 0:11161008d77a 587 /**
nikapov 0:11161008d77a 588 * @brief This function sends the SelectSystemFile command
nikapov 0:11161008d77a 589 * @retval Status (SW1&SW2) Status of the operation to complete.
nikapov 0:11161008d77a 590 * @retval M24SR_ERROR_I2CTIMEOUT I2C timeout occurred.
nikapov 0:11161008d77a 591 */
nikapov 0:11161008d77a 592 M24SR::StatusTypeDef M24SR::M24SR_SendSelectSystemfile(void) {
nikapov 0:11161008d77a 593 C_APDU command;
nikapov 0:11161008d77a 594
nikapov 0:11161008d77a 595 uint8_t *pBuffer = uM24SRbuffer;
nikapov 0:11161008d77a 596 uint8_t pDataOut[] = SYSTEM_FILE_ID_BYTES;
nikapov 0:11161008d77a 597 M24SR::StatusTypeDef status;
nikapov 0:11161008d77a 598 uint16_t uP1P2 =0x000C, NbByte;
nikapov 0:11161008d77a 599
nikapov 0:11161008d77a 600 /* build the command */
nikapov 0:11161008d77a 601 command.Header.CLA = C_APDU_CLA_DEFAULT;
nikapov 0:11161008d77a 602 command.Header.INS = C_APDU_SELECT_FILE;
nikapov 0:11161008d77a 603 /* copy the offset */
nikapov 0:11161008d77a 604 command.Header.P1 = GETMSB(uP1P2);
nikapov 0:11161008d77a 605 command.Header.P2 = GETLSB(uP1P2);
nikapov 0:11161008d77a 606 /* copy the number of byte of the data field */
nikapov 0:11161008d77a 607 command.Body.LC = sizeof(pDataOut);
nikapov 0:11161008d77a 608 command.Body.pData = pDataOut;
nikapov 0:11161008d77a 609 /* build the I²C command */
nikapov 0:11161008d77a 610 M24SR_BuildIBlockCommand(M24SR_CMDSTRUCT_SELECTCCFILE, &command, uDIDbyte, &NbByte, pBuffer);
nikapov 0:11161008d77a 611
nikapov 0:11161008d77a 612 /* send the request */
nikapov 0:11161008d77a 613 status = M24SR_IO_SendI2Ccommand(NbByte, pBuffer);
nikapov 0:11161008d77a 614 if (status!=M24SR_SUCCESS) {
nikapov 0:11161008d77a 615 getCallback()->on_selected_system_file(this,status);
nikapov 0:11161008d77a 616 return status;
nikapov 0:11161008d77a 617 }//else
nikapov 0:11161008d77a 618
nikapov 0:11161008d77a 619 mLastCommandSend=SELECT_SYSTEM_FILE;
nikapov 0:11161008d77a 620
nikapov 0:11161008d77a 621 if (mCommunicationType==M24SR::SYNC) {
nikapov 0:11161008d77a 622 status = M24SR_IO_PollI2C();
nikapov 0:11161008d77a 623 if (status == M24SR_SUCCESS) {
nikapov 0:11161008d77a 624 return M24SR_ReceiveSelectSystemfile();
nikapov 0:11161008d77a 625 } else {
nikapov 0:11161008d77a 626 mLastCommandSend = NONE;
nikapov 0:11161008d77a 627 getCallback()->on_selected_system_file(this,status);
nikapov 0:11161008d77a 628 return status;
nikapov 0:11161008d77a 629 }//if-else
nikapov 0:11161008d77a 630 }//if
nikapov 0:11161008d77a 631
nikapov 0:11161008d77a 632 return M24SR_SUCCESS;
nikapov 0:11161008d77a 633 }
nikapov 0:11161008d77a 634
nikapov 0:11161008d77a 635 M24SR::StatusTypeDef M24SR::M24SR_ReceiveSelectSystemfile() {
nikapov 0:11161008d77a 636 uint8_t pDataIn[M24SR_STATUSRESPONSE_NBBYTE];
nikapov 0:11161008d77a 637 M24SR::StatusTypeDef status;
nikapov 0:11161008d77a 638
nikapov 0:11161008d77a 639 mLastCommandSend = NONE;
nikapov 0:11161008d77a 640
nikapov 0:11161008d77a 641 status = M24SR_IO_ReceiveI2Cresponse(sizeof(pDataIn), pDataIn);
nikapov 0:11161008d77a 642 if (status!=M24SR_SUCCESS) {
nikapov 0:11161008d77a 643 getCallback()->on_selected_system_file(this,status);
nikapov 0:11161008d77a 644 return status;
nikapov 0:11161008d77a 645 }//else
nikapov 0:11161008d77a 646 status = M24SR_IsCorrectCRC16Residue(pDataIn, sizeof(pDataIn));
nikapov 0:11161008d77a 647 getCallback()->on_selected_system_file(this,status);
nikapov 0:11161008d77a 648
nikapov 0:11161008d77a 649 return status;
nikapov 0:11161008d77a 650 }
nikapov 0:11161008d77a 651
nikapov 0:11161008d77a 652 /**
nikapov 0:11161008d77a 653 * @brief This function sends the SelectNDEFfile command
nikapov 0:11161008d77a 654 * @retval Status (SW1&SW2) Status of the operation to complete.
nikapov 0:11161008d77a 655 * @retval M24SR_ERROR_I2CTIMEOUT I2C timeout occurred.
nikapov 0:11161008d77a 656 */
nikapov 0:11161008d77a 657 M24SR::StatusTypeDef M24SR::M24SR_SendSelectNDEFfile(uint16_t NDEFfileId) {
nikapov 0:11161008d77a 658 C_APDU command;
nikapov 0:11161008d77a 659 M24SR::StatusTypeDef status;
nikapov 0:11161008d77a 660 uint8_t *pBuffer = uM24SRbuffer;
nikapov 0:11161008d77a 661 uint8_t pDataOut[] = { GETMSB(NDEFfileId), GETLSB(NDEFfileId) };
nikapov 0:11161008d77a 662 uint16_t uP1P2 = 0x000C, NbByte;
nikapov 0:11161008d77a 663
nikapov 0:11161008d77a 664 /* build the command */
nikapov 0:11161008d77a 665 command.Header.CLA = C_APDU_CLA_DEFAULT;
nikapov 0:11161008d77a 666 command.Header.INS = C_APDU_SELECT_FILE;
nikapov 0:11161008d77a 667 /* copy the offset */
nikapov 0:11161008d77a 668 command.Header.P1 = GETMSB(uP1P2);
nikapov 0:11161008d77a 669 command.Header.P2 = GETLSB(uP1P2);
nikapov 0:11161008d77a 670 /* copy the number of byte of the data field */
nikapov 0:11161008d77a 671 command.Body.LC = sizeof(pDataOut);
nikapov 0:11161008d77a 672 command.Body.pData = pDataOut;
nikapov 0:11161008d77a 673 /* copy the offset */
nikapov 0:11161008d77a 674 /* build the I2C command */
nikapov 0:11161008d77a 675 M24SR_BuildIBlockCommand(M24SR_CMDSTRUCT_SELECTNDEFFILE, &command, uDIDbyte, &NbByte, pBuffer);
nikapov 0:11161008d77a 676
nikapov 0:11161008d77a 677 /* send the request */
nikapov 0:11161008d77a 678 status = M24SR_IO_SendI2Ccommand(NbByte, pBuffer);
nikapov 0:11161008d77a 679 if (status!=M24SR_SUCCESS) {
nikapov 0:11161008d77a 680 return status;
nikapov 0:11161008d77a 681 }
nikapov 0:11161008d77a 682 mLastCommandSend=SELECT_NDEF_FILE;
nikapov 0:11161008d77a 683
nikapov 0:11161008d77a 684 if (mCommunicationType==M24SR::SYNC) {
nikapov 0:11161008d77a 685 status = M24SR_IO_PollI2C();
nikapov 0:11161008d77a 686 if (status==M24SR_SUCCESS) {
nikapov 0:11161008d77a 687 return M24SR_ReceiveSelectNDEFfile();
nikapov 0:11161008d77a 688 } else {
nikapov 0:11161008d77a 689 mLastCommandSend = NONE;
nikapov 0:11161008d77a 690 getCallback()->on_selected_NDEF_file(this,status);
nikapov 0:11161008d77a 691 return status;
nikapov 0:11161008d77a 692 }
nikapov 0:11161008d77a 693 }
nikapov 0:11161008d77a 694
nikapov 0:11161008d77a 695 return M24SR_SUCCESS;
nikapov 0:11161008d77a 696
nikapov 0:11161008d77a 697 }
nikapov 0:11161008d77a 698
nikapov 0:11161008d77a 699 M24SR::StatusTypeDef M24SR::M24SR_ReceiveSelectNDEFfile(){
nikapov 0:11161008d77a 700
nikapov 0:11161008d77a 701 uint8_t pDataIn[M24SR_STATUSRESPONSE_NBBYTE];
nikapov 0:11161008d77a 702 M24SR::StatusTypeDef status;
nikapov 0:11161008d77a 703
nikapov 0:11161008d77a 704 mLastCommandSend = NONE;
nikapov 0:11161008d77a 705
nikapov 0:11161008d77a 706 status = M24SR_IO_ReceiveI2Cresponse(sizeof(pDataIn), pDataIn);
nikapov 0:11161008d77a 707 if (status!=M24SR_SUCCESS) {
nikapov 0:11161008d77a 708 getCallback()->on_selected_NDEF_file(this,status);
nikapov 0:11161008d77a 709 return status;
nikapov 0:11161008d77a 710 }//else
nikapov 0:11161008d77a 711 status= M24SR_IsCorrectCRC16Residue(pDataIn, sizeof(pDataIn));
nikapov 0:11161008d77a 712 getCallback()->on_selected_NDEF_file(this,status);
nikapov 0:11161008d77a 713
nikapov 0:11161008d77a 714 return status;
nikapov 0:11161008d77a 715 }
nikapov 0:11161008d77a 716
nikapov 0:11161008d77a 717 /**
nikapov 0:11161008d77a 718 * @brief This function sends a read binary command
nikapov 0:11161008d77a 719 * @param Offset first byte to read
nikapov 0:11161008d77a 720 * @param NbByteToRead number of bytes to read
nikapov 0:11161008d77a 721 * @param pBufferRead pointer to the buffer read from the M24SR device
nikapov 0:11161008d77a 722 * @retval Status (SW1&SW2) Status of the operation to complete.
nikapov 0:11161008d77a 723 * @retval M24SR_ERROR_I2CTIMEOUT I2C timeout occurred.
nikapov 0:11161008d77a 724 */
nikapov 0:11161008d77a 725 M24SR::StatusTypeDef M24SR::M24SR_SendReadBinary(uint16_t Offset, uint8_t NbByteToRead, uint8_t *pBufferRead) {
nikapov 0:11161008d77a 726 //clamp the buffer to the max size
nikapov 0:11161008d77a 727 if (NbByteToRead>M24SR_MAX_BYTE_OPERATION_LENGHT) {
nikapov 0:11161008d77a 728 NbByteToRead=M24SR_MAX_BYTE_OPERATION_LENGHT;
nikapov 0:11161008d77a 729 }
nikapov 0:11161008d77a 730
nikapov 0:11161008d77a 731 C_APDU command;
nikapov 0:11161008d77a 732 uint8_t *pBuffer = uM24SRbuffer;
nikapov 0:11161008d77a 733 uint16_t NbByte;
nikapov 0:11161008d77a 734 M24SR::StatusTypeDef status;
nikapov 0:11161008d77a 735
nikapov 0:11161008d77a 736 /* build the command */
nikapov 0:11161008d77a 737 command.Header.CLA = C_APDU_CLA_DEFAULT;
nikapov 0:11161008d77a 738 command.Header.INS = C_APDU_READ_BINARY;
nikapov 0:11161008d77a 739 /* copy the offset */
nikapov 0:11161008d77a 740 command.Header.P1 = GETMSB(Offset);
nikapov 0:11161008d77a 741 command.Header.P2 = GETLSB(Offset);
nikapov 0:11161008d77a 742 /* copy the number of byte to read */
nikapov 0:11161008d77a 743 command.Body.LE = NbByteToRead;
nikapov 0:11161008d77a 744
nikapov 0:11161008d77a 745 M24SR_BuildIBlockCommand(M24SR_CMDSTRUCT_READBINARY, &command, uDIDbyte, &NbByte, pBuffer);
nikapov 0:11161008d77a 746
nikapov 0:11161008d77a 747 status = M24SR_IO_SendI2Ccommand(NbByte, pBuffer);
nikapov 0:11161008d77a 748 if (status!=M24SR_SUCCESS) {
nikapov 0:11161008d77a 749 getCallback()->on_read_byte(this,status,Offset,pBufferRead,NbByteToRead);
nikapov 0:11161008d77a 750 return status;
nikapov 0:11161008d77a 751 }
nikapov 0:11161008d77a 752
nikapov 0:11161008d77a 753 mLastCommandSend=READ;
nikapov 0:11161008d77a 754 mLastCommandData.data=pBufferRead;
nikapov 0:11161008d77a 755 mLastCommandData.length=NbByteToRead;
nikapov 0:11161008d77a 756 mLastCommandData.offset=Offset;
nikapov 0:11161008d77a 757
nikapov 0:11161008d77a 758 if (mCommunicationType==M24SR::SYNC) {
nikapov 0:11161008d77a 759 status = M24SR_IO_PollI2C();
nikapov 0:11161008d77a 760 if (status==M24SR_SUCCESS) {
nikapov 0:11161008d77a 761 return M24SR_ReceiveReadBinary();
nikapov 0:11161008d77a 762 } else {
nikapov 0:11161008d77a 763 mLastCommandSend = NONE;
nikapov 0:11161008d77a 764 getCallback()->on_read_byte(this,status,Offset,pBufferRead,NbByteToRead);
nikapov 0:11161008d77a 765 return status;
nikapov 0:11161008d77a 766 }//if-else
nikapov 0:11161008d77a 767 }//if
nikapov 0:11161008d77a 768
nikapov 0:11161008d77a 769 return M24SR_SUCCESS;
nikapov 0:11161008d77a 770 }
nikapov 0:11161008d77a 771
nikapov 0:11161008d77a 772 M24SR::StatusTypeDef M24SR::M24SR_ReceiveReadBinary() {
nikapov 0:11161008d77a 773 M24SR::StatusTypeDef status;
nikapov 0:11161008d77a 774 const uint16_t length = mLastCommandData.length;
nikapov 0:11161008d77a 775 const uint16_t offset = mLastCommandData.offset;
nikapov 0:11161008d77a 776 uint8_t *data = mLastCommandData.data;
nikapov 0:11161008d77a 777
nikapov 0:11161008d77a 778 mLastCommandSend = NONE;
nikapov 0:11161008d77a 779
nikapov 0:11161008d77a 780 status = M24SR_IO_ReceiveI2Cresponse (length + M24SR_STATUSRESPONSE_NBBYTE , uM24SRbuffer );
nikapov 0:11161008d77a 781 if (status!=M24SR_SUCCESS) {
nikapov 0:11161008d77a 782 getCallback()->on_read_byte(this,status,offset,data,length);
nikapov 0:11161008d77a 783 return status;
nikapov 0:11161008d77a 784 }
nikapov 0:11161008d77a 785 status = M24SR_IsCorrectCRC16Residue(uM24SRbuffer, length + M24SR_STATUSRESPONSE_NBBYTE);
nikapov 0:11161008d77a 786 if (status != M24SR_SUCCESS) {
nikapov 0:11161008d77a 787 getCallback()->on_read_byte(this,status,offset,data,length);
nikapov 0:11161008d77a 788 } else{
nikapov 0:11161008d77a 789 /* retrieve the data without SW1 & SW2 as provided as return value of the function */
nikapov 0:11161008d77a 790 memcpy(mLastCommandData.data, &uM24SRbuffer[1], length);
nikapov 0:11161008d77a 791 getCallback()->on_read_byte(this,status,offset,data,length);
nikapov 0:11161008d77a 792 }
nikapov 0:11161008d77a 793
nikapov 0:11161008d77a 794 return status;
nikapov 0:11161008d77a 795 }
nikapov 0:11161008d77a 796
nikapov 0:11161008d77a 797 /**
nikapov 0:11161008d77a 798 * @brief This function sends a ST read binary command (no error if access is not inside NDEF file)
nikapov 0:11161008d77a 799 * @param Offset first byte to read
nikapov 0:11161008d77a 800 * @param NbByteToRead number of bytes to read
nikapov 0:11161008d77a 801 * @param pBufferRead pointer to the buffer read from the M24SR device
nikapov 0:11161008d77a 802 * @retval Status (SW1&SW2) Status of the operation to complete.
nikapov 0:11161008d77a 803 * @retval M24SR_ERROR_I2CTIMEOUT I2C timeout occurred.
nikapov 0:11161008d77a 804 */
nikapov 0:11161008d77a 805 M24SR::StatusTypeDef M24SR::M24SR_SendSTReadBinary(uint16_t Offset, uint8_t NbByteToRead, uint8_t *pBufferRead) {
nikapov 0:11161008d77a 806 //clamp the buffer to the max size
nikapov 0:11161008d77a 807 if (NbByteToRead>M24SR_MAX_BYTE_OPERATION_LENGHT) {
nikapov 0:11161008d77a 808 NbByteToRead=M24SR_MAX_BYTE_OPERATION_LENGHT;
nikapov 0:11161008d77a 809 }
nikapov 0:11161008d77a 810
nikapov 0:11161008d77a 811 C_APDU command;
nikapov 0:11161008d77a 812 uint8_t *pBuffer = uM24SRbuffer;
nikapov 0:11161008d77a 813 uint16_t NbByte;
nikapov 0:11161008d77a 814 M24SR::StatusTypeDef status;
nikapov 0:11161008d77a 815
nikapov 0:11161008d77a 816 /* build the command */
nikapov 0:11161008d77a 817 command.Header.CLA = C_APDU_CLA_ST;
nikapov 0:11161008d77a 818 command.Header.INS = C_APDU_READ_BINARY;
nikapov 0:11161008d77a 819 /* copy the offset */
nikapov 0:11161008d77a 820 command.Header.P1 = GETMSB(Offset);
nikapov 0:11161008d77a 821 command.Header.P2 = GETLSB(Offset);
nikapov 0:11161008d77a 822 /* copy the number of byte to read */
nikapov 0:11161008d77a 823 command.Body.LE = NbByteToRead;
nikapov 0:11161008d77a 824
nikapov 0:11161008d77a 825 M24SR_BuildIBlockCommand(M24SR_CMDSTRUCT_READBINARY, &command, uDIDbyte, &NbByte, pBuffer);
nikapov 0:11161008d77a 826
nikapov 0:11161008d77a 827 status = M24SR_IO_SendI2Ccommand(NbByte, pBuffer);
nikapov 0:11161008d77a 828 if (status!=M24SR_SUCCESS) {
nikapov 0:11161008d77a 829 getCallback()->on_read_byte(this,status,Offset,pBufferRead,NbByteToRead);
nikapov 0:11161008d77a 830 return status;
nikapov 0:11161008d77a 831 }
nikapov 0:11161008d77a 832
nikapov 0:11161008d77a 833 mLastCommandSend=READ;
nikapov 0:11161008d77a 834 mLastCommandData.data=pBufferRead;
nikapov 0:11161008d77a 835 mLastCommandData.length=NbByteToRead;
nikapov 0:11161008d77a 836
nikapov 0:11161008d77a 837 if (mCommunicationType==M24SR::SYNC) {
nikapov 0:11161008d77a 838 status = M24SR_IO_PollI2C();
nikapov 0:11161008d77a 839 if (status==M24SR_SUCCESS) {
nikapov 0:11161008d77a 840 return M24SR_ReceiveReadBinary();
nikapov 0:11161008d77a 841 } else {
nikapov 0:11161008d77a 842 mLastCommandSend = NONE;
nikapov 0:11161008d77a 843 getCallback()->on_read_byte(this,status,Offset,pBufferRead,NbByteToRead);
nikapov 0:11161008d77a 844 return status;
nikapov 0:11161008d77a 845 }//if-else
nikapov 0:11161008d77a 846 }//if
nikapov 0:11161008d77a 847
nikapov 0:11161008d77a 848 return M24SR_SUCCESS;
nikapov 0:11161008d77a 849 }
nikapov 0:11161008d77a 850
nikapov 0:11161008d77a 851 /**
nikapov 0:11161008d77a 852 * @brief This function sends a Update binary command
nikapov 0:11161008d77a 853 * @param Offset first byte to read
nikapov 0:11161008d77a 854 * @param NbByteToWrite number of bytes to write
nikapov 0:11161008d77a 855 * @param pBufferRead pointer to the buffer read from the M24SR device
nikapov 0:11161008d77a 856 * @retval Status (SW1&SW2) Status of the operation to complete.
nikapov 0:11161008d77a 857 * @retval M24SR_ERROR_I2CTIMEOUT I2C timeout occurred.
nikapov 0:11161008d77a 858 */
nikapov 0:11161008d77a 859 M24SR::StatusTypeDef M24SR::M24SR_SendUpdateBinary(uint16_t Offset, uint8_t NbByteToWrite, uint8_t *pDataToWrite) {
nikapov 0:11161008d77a 860 //clamp the buffer to the max size
nikapov 0:11161008d77a 861 if (NbByteToWrite>M24SR_MAX_BYTE_OPERATION_LENGHT) {
nikapov 0:11161008d77a 862 NbByteToWrite=M24SR_MAX_BYTE_OPERATION_LENGHT;
nikapov 0:11161008d77a 863 }
nikapov 0:11161008d77a 864
nikapov 0:11161008d77a 865 C_APDU command;
nikapov 0:11161008d77a 866 M24SR::StatusTypeDef status;
nikapov 0:11161008d77a 867 uint8_t *pBuffer = uM24SRbuffer;
nikapov 0:11161008d77a 868 uint16_t NbByte;
nikapov 0:11161008d77a 869
nikapov 0:11161008d77a 870 /* build the command */
nikapov 0:11161008d77a 871 command.Header.CLA = C_APDU_CLA_DEFAULT;
nikapov 0:11161008d77a 872 command.Header.INS = C_APDU_UPDATE_BINARY;
nikapov 0:11161008d77a 873 /* copy the offset */
nikapov 0:11161008d77a 874 command.Header.P1 = GETMSB(Offset);
nikapov 0:11161008d77a 875 command.Header.P2 = GETLSB(Offset);
nikapov 0:11161008d77a 876 /* copy the number of byte of the data field */
nikapov 0:11161008d77a 877 command.Body.LC = NbByteToWrite;
nikapov 0:11161008d77a 878 command.Body.pData = pDataToWrite;
nikapov 0:11161008d77a 879 /* copy the File Id */
nikapov 0:11161008d77a 880 //memcpy(command.Body.pData ,pDataToWrite, NbByteToWrite );
nikapov 0:11161008d77a 881 M24SR_BuildIBlockCommand(M24SR_CMDSTRUCT_UPDATEBINARY, &command, uDIDbyte, &NbByte, pBuffer);
nikapov 0:11161008d77a 882
nikapov 0:11161008d77a 883 status = M24SR_IO_SendI2Ccommand(NbByte, pBuffer);
nikapov 0:11161008d77a 884 if (status!=M24SR_SUCCESS){
nikapov 0:11161008d77a 885 getCallback()->on_updated_binary(this,status,Offset,pDataToWrite,NbByteToWrite);
nikapov 0:11161008d77a 886 return status;
nikapov 0:11161008d77a 887 }
nikapov 0:11161008d77a 888
nikapov 0:11161008d77a 889 mLastCommandSend=UPDATE;
nikapov 0:11161008d77a 890 mLastCommandData.data=pDataToWrite;
nikapov 0:11161008d77a 891 mLastCommandData.length=NbByteToWrite;
nikapov 0:11161008d77a 892 mLastCommandData.offset=Offset;
nikapov 0:11161008d77a 893
nikapov 0:11161008d77a 894 if (mCommunicationType==M24SR::SYNC) {
nikapov 0:11161008d77a 895 status = M24SR_IO_PollI2C();
nikapov 0:11161008d77a 896 if (status==M24SR_SUCCESS) {
nikapov 0:11161008d77a 897 return M24SR_ReceiveUpdateBinary();
nikapov 0:11161008d77a 898 } else {
nikapov 0:11161008d77a 899 mLastCommandSend = NONE;
nikapov 0:11161008d77a 900 getCallback()->on_updated_binary(this,status,Offset,pDataToWrite,NbByteToWrite);
nikapov 0:11161008d77a 901 return status;
nikapov 0:11161008d77a 902 }//if-else
nikapov 0:11161008d77a 903 }
nikapov 0:11161008d77a 904
nikapov 0:11161008d77a 905 return M24SR_SUCCESS;
nikapov 0:11161008d77a 906 }
nikapov 0:11161008d77a 907
nikapov 0:11161008d77a 908 M24SR::StatusTypeDef M24SR::M24SR_ReceiveUpdateBinary() {
nikapov 0:11161008d77a 909 uint8_t respBuffer[M24SR_STATUSRESPONSE_NBBYTE];
nikapov 0:11161008d77a 910 M24SR::StatusTypeDef status;
nikapov 0:11161008d77a 911 const uint16_t length = mLastCommandData.length;
nikapov 0:11161008d77a 912 uint8_t *data = mLastCommandData.data;
nikapov 0:11161008d77a 913 const uint16_t offset = mLastCommandData.offset;
nikapov 0:11161008d77a 914
nikapov 0:11161008d77a 915 mLastCommandSend=NONE;
nikapov 0:11161008d77a 916
nikapov 0:11161008d77a 917 status= M24SR_IO_ReceiveI2Cresponse (sizeof(respBuffer) , respBuffer);
nikapov 0:11161008d77a 918 if(status != M24SR_SUCCESS){
nikapov 0:11161008d77a 919 getCallback()->on_updated_binary(this,status,offset,data,length);
nikapov 0:11161008d77a 920 return status;
nikapov 0:11161008d77a 921 }
nikapov 0:11161008d77a 922
nikapov 0:11161008d77a 923 if (IsSBlock(respBuffer) == M24SR_SUCCESS) {
nikapov 0:11161008d77a 924 /*check the CRC */
nikapov 0:11161008d77a 925 status = M24SR_IsCorrectCRC16Residue(respBuffer, M24SR_WATINGTIMEEXTRESPONSE_NBBYTE);
nikapov 0:11161008d77a 926 // TODO: why if we check ==NFC_Commandsuccess it fail?
nikapov 0:11161008d77a 927 if (status != M24SR_IO_ERROR_CRC) {
nikapov 0:11161008d77a 928 /* send the FrameExension response*/
nikapov 0:11161008d77a 929 status = M24SR_SendFWTExtension(respBuffer[M24SR_OFFSET_PCB + 1]);
nikapov 0:11161008d77a 930 if(status!=M24SR_SUCCESS){ //something get wrong -> abort the update
nikapov 0:11161008d77a 931 getCallback()->on_updated_binary(this,status,offset,data,length);
nikapov 0:11161008d77a 932 }//status
nikapov 0:11161008d77a 933 }//if
nikapov 0:11161008d77a 934 } else { //isSBlock
nikapov 0:11161008d77a 935 status = M24SR_IsCorrectCRC16Residue(respBuffer, M24SR_STATUSRESPONSE_NBBYTE);
nikapov 0:11161008d77a 936 getCallback()->on_updated_binary(this,status,offset,data,length);
nikapov 0:11161008d77a 937 }//if else
nikapov 0:11161008d77a 938
nikapov 0:11161008d77a 939 return status;
nikapov 0:11161008d77a 940 }//M24SR_ReceiveUpdateBinary
nikapov 0:11161008d77a 941
nikapov 0:11161008d77a 942 /**
nikapov 0:11161008d77a 943 * @brief This function sends the Verify command
nikapov 0:11161008d77a 944 * @param uPwdId PasswordId ( 0x0001 : Read NDEF pwd or 0x0002 : Write NDEF pwd or 0x0003 : I2C pwd)
nikapov 0:11161008d77a 945 * @param NbPwdByte Number of bytes ( 0x00 or 0x10)
nikapov 0:11161008d77a 946 * @param pPwd pointer to the password
nikapov 0:11161008d77a 947 * @retval Status (SW1&SW2) Status of the operation to complete.
nikapov 0:11161008d77a 948 * @retval M24SR_ERROR_I2CTIMEOUT I2C timeout occurred.
nikapov 0:11161008d77a 949 */
nikapov 0:11161008d77a 950 M24SR::StatusTypeDef M24SR::M24SR_SendVerify(uint16_t uPwdId, uint8_t NbPwdByte, const uint8_t *pPwd) {
nikapov 0:11161008d77a 951 C_APDU command;
nikapov 0:11161008d77a 952 M24SR::StatusTypeDef status;
nikapov 0:11161008d77a 953 uint8_t *pBuffer = uM24SRbuffer;
nikapov 0:11161008d77a 954 uint16_t NbByte;
nikapov 0:11161008d77a 955
nikapov 0:11161008d77a 956 /*check the parameters */
nikapov 0:11161008d77a 957 if ((uPwdId > 0x0003)|| ((NbPwdByte != 0x00) && (NbPwdByte != 0x10))) {
nikapov 0:11161008d77a 958 getCallback()->on_verified(this,M24SR_IO_ERROR_PARAMETER,constToPasswordType(uPwdId),pPwd);
nikapov 0:11161008d77a 959 return M24SR_IO_ERROR_PARAMETER;
nikapov 0:11161008d77a 960 }
nikapov 0:11161008d77a 961
nikapov 0:11161008d77a 962 /* build the command */
nikapov 0:11161008d77a 963 command.Header.CLA = C_APDU_CLA_DEFAULT;
nikapov 0:11161008d77a 964 command.Header.INS = C_APDU_VERIFY;
nikapov 0:11161008d77a 965 /* copy the Password Id */
nikapov 0:11161008d77a 966 command.Header.P1 = GETMSB(uPwdId);
nikapov 0:11161008d77a 967 command.Header.P2 = GETLSB(uPwdId);
nikapov 0:11161008d77a 968 /* copy the number of bytes of the data field */
nikapov 0:11161008d77a 969 command.Body.LC = NbPwdByte;
nikapov 0:11161008d77a 970
nikapov 0:11161008d77a 971 if (NbPwdByte == 0x10) {
nikapov 0:11161008d77a 972 /* copy the password */
nikapov 0:11161008d77a 973 command.Body.pData = pPwd;
nikapov 0:11161008d77a 974 /* build the I2C command */
nikapov 0:11161008d77a 975 M24SR_BuildIBlockCommand(M24SR_CMDSTRUCT_VERIFYBINARYWITHPWD, &command, uDIDbyte, &NbByte, pBuffer);
nikapov 0:11161008d77a 976 } else {
nikapov 0:11161008d77a 977 command.Body.pData = NULL;
nikapov 0:11161008d77a 978 /* build the I2C command */
nikapov 0:11161008d77a 979 M24SR_BuildIBlockCommand(M24SR_CMDSTRUCT_VERIFYBINARYWOPWD, &command, uDIDbyte, &NbByte, pBuffer);
nikapov 0:11161008d77a 980 }
nikapov 0:11161008d77a 981
nikapov 0:11161008d77a 982 /* send the request */
nikapov 0:11161008d77a 983 status = M24SR_IO_SendI2Ccommand(NbByte, pBuffer);
nikapov 0:11161008d77a 984 if (status!=M24SR_SUCCESS) {
nikapov 0:11161008d77a 985 getCallback()->on_verified(this,status,constToPasswordType(uPwdId),pPwd);
nikapov 0:11161008d77a 986 return status;
nikapov 0:11161008d77a 987 }
nikapov 0:11161008d77a 988 mLastCommandSend=VERIFY;
nikapov 0:11161008d77a 989 mLastCommandData.data=(uint8_t*)pPwd;
nikapov 0:11161008d77a 990 mLastCommandData.offset=uPwdId;
nikapov 0:11161008d77a 991
nikapov 0:11161008d77a 992 if (mCommunicationType==M24SR::SYNC) {
nikapov 0:11161008d77a 993 status = M24SR_IO_PollI2C();
nikapov 0:11161008d77a 994 if(status == M24SR_SUCCESS) {
nikapov 0:11161008d77a 995 return M24SR_ReceiveVerify();
nikapov 0:11161008d77a 996 } else {
nikapov 0:11161008d77a 997 mLastCommandSend = NONE;
nikapov 0:11161008d77a 998 getCallback()->on_verified(this,status,constToPasswordType(uPwdId),pPwd);
nikapov 0:11161008d77a 999 return status;
nikapov 0:11161008d77a 1000 }
nikapov 0:11161008d77a 1001 }
nikapov 0:11161008d77a 1002
nikapov 0:11161008d77a 1003 return M24SR_SUCCESS;
nikapov 0:11161008d77a 1004 }
nikapov 0:11161008d77a 1005
nikapov 0:11161008d77a 1006 M24SR::StatusTypeDef M24SR::M24SR_ReceiveVerify() {
nikapov 0:11161008d77a 1007 M24SR::StatusTypeDef status;
nikapov 0:11161008d77a 1008 uint8_t respBuffer[M24SR_STATUSRESPONSE_NBBYTE];
nikapov 0:11161008d77a 1009 mLastCommandSend=NONE;
nikapov 0:11161008d77a 1010
nikapov 0:11161008d77a 1011 const uint8_t *data = mLastCommandData.data;
nikapov 0:11161008d77a 1012 const PasswordType_t type = constToPasswordType(mLastCommandData.offset);
nikapov 0:11161008d77a 1013
nikapov 0:11161008d77a 1014 status=M24SR_IO_ReceiveI2Cresponse (sizeof(respBuffer),respBuffer);
nikapov 0:11161008d77a 1015
nikapov 0:11161008d77a 1016 if (status !=M24SR_SUCCESS) {
nikapov 0:11161008d77a 1017 getCallback()->on_verified(this,status,type,data);
nikapov 0:11161008d77a 1018 return status;
nikapov 0:11161008d77a 1019 }
nikapov 0:11161008d77a 1020
nikapov 0:11161008d77a 1021 status = M24SR_IsCorrectCRC16Residue(respBuffer, M24SR_STATUSRESPONSE_NBBYTE);
nikapov 0:11161008d77a 1022 getCallback()->on_verified(this,status,type,data);
nikapov 0:11161008d77a 1023 return status;
nikapov 0:11161008d77a 1024 }
nikapov 0:11161008d77a 1025
nikapov 0:11161008d77a 1026 /**
nikapov 0:11161008d77a 1027 * @brief This function sends the ChangeReferenceData command
nikapov 0:11161008d77a 1028 * @param uPwdId PasswordId ( 0x0001 : Read NDEF pwd or 0x0002 : Write NDEF pwd or 0x0003 : I2C pwd)
nikapov 0:11161008d77a 1029 * @param pPwd pointer to the passwaord
nikapov 0:11161008d77a 1030 * @retval Status (SW1&SW2) Satus of the operation to complete.
nikapov 0:11161008d77a 1031 * @retval M24SR_ERROR_I2CTIMEOUT I2C timeout occurred.
nikapov 0:11161008d77a 1032 */
nikapov 0:11161008d77a 1033 M24SR::StatusTypeDef M24SR::M24SR_SendChangeReferenceData(uint16_t uPwdId, uint8_t *pPwd) {
nikapov 0:11161008d77a 1034 C_APDU command;
nikapov 0:11161008d77a 1035 M24SR::StatusTypeDef status;
nikapov 0:11161008d77a 1036 uint8_t *pBuffer = uM24SRbuffer;
nikapov 0:11161008d77a 1037 uint16_t NbByte;
nikapov 0:11161008d77a 1038
nikapov 0:11161008d77a 1039 /*check the parameters */
nikapov 0:11161008d77a 1040 if (uPwdId > 0x0003) {
nikapov 0:11161008d77a 1041 getCallback()->on_change_reference_data(this,M24SR_IO_ERROR_PARAMETER, constToPasswordType(uPwdId), pPwd);
nikapov 0:11161008d77a 1042 return M24SR_IO_ERROR_PARAMETER;
nikapov 0:11161008d77a 1043 }
nikapov 0:11161008d77a 1044
nikapov 0:11161008d77a 1045 /* build the command */
nikapov 0:11161008d77a 1046 command.Header.CLA = C_APDU_CLA_DEFAULT;
nikapov 0:11161008d77a 1047 command.Header.INS = C_APDU_CHANGE;
nikapov 0:11161008d77a 1048 /* copy the Password Id */
nikapov 0:11161008d77a 1049 command.Header.P1 = GETMSB(uPwdId);
nikapov 0:11161008d77a 1050 command.Header.P2 = GETLSB(uPwdId);
nikapov 0:11161008d77a 1051 /* copy the number of byte of the data field */
nikapov 0:11161008d77a 1052 command.Body.LC = M24SR_PASSWORD_NBBYTE;
nikapov 0:11161008d77a 1053 /* copy the password */
nikapov 0:11161008d77a 1054 command.Body.pData = pPwd;
nikapov 0:11161008d77a 1055 /* build the I²C command */
nikapov 0:11161008d77a 1056 M24SR_BuildIBlockCommand(M24SR_CMDSTRUCT_CHANGEREFDATA, &command, uDIDbyte, &NbByte, pBuffer);
nikapov 0:11161008d77a 1057
nikapov 0:11161008d77a 1058 /* send the request */
nikapov 0:11161008d77a 1059 status = M24SR_IO_SendI2Ccommand(NbByte, pBuffer);
nikapov 0:11161008d77a 1060 if (status != M24SR_SUCCESS) {
nikapov 0:11161008d77a 1061 getCallback()->on_change_reference_data(this,status, constToPasswordType(uPwdId), pPwd);
nikapov 0:11161008d77a 1062 return status;
nikapov 0:11161008d77a 1063 }
nikapov 0:11161008d77a 1064
nikapov 0:11161008d77a 1065 mLastCommandSend = CHANGE_REFERENCE_DATA;
nikapov 0:11161008d77a 1066 mLastCommandData.data = pPwd;
nikapov 0:11161008d77a 1067 //use the offset filed for store the pwd id;
nikapov 0:11161008d77a 1068 mLastCommandData.offset = (uint8_t)uPwdId;
nikapov 0:11161008d77a 1069
nikapov 0:11161008d77a 1070 if (mCommunicationType==M24SR::SYNC) {
nikapov 0:11161008d77a 1071 status = M24SR_IO_PollI2C();
nikapov 0:11161008d77a 1072 if (status == M24SR_SUCCESS) {
nikapov 0:11161008d77a 1073 return M24SR_ReceiveChangeReferenceData();
nikapov 0:11161008d77a 1074 } else {
nikapov 0:11161008d77a 1075 mLastCommandSend = NONE;
nikapov 0:11161008d77a 1076 getCallback()->on_change_reference_data(this, status, constToPasswordType(uPwdId), pPwd);
nikapov 0:11161008d77a 1077 return status;
nikapov 0:11161008d77a 1078 }//if-else
nikapov 0:11161008d77a 1079 }//if
nikapov 0:11161008d77a 1080
nikapov 0:11161008d77a 1081 return M24SR_SUCCESS;
nikapov 0:11161008d77a 1082 }
nikapov 0:11161008d77a 1083
nikapov 0:11161008d77a 1084 M24SR::StatusTypeDef M24SR::M24SR_ReceiveChangeReferenceData(){
nikapov 0:11161008d77a 1085 M24SR::StatusTypeDef status;
nikapov 0:11161008d77a 1086 //TODO the size is 3?
nikapov 0:11161008d77a 1087 uint8_t rensponseBuffer[M24SR_STATUSRESPONSE_NBBYTE];
nikapov 0:11161008d77a 1088
nikapov 0:11161008d77a 1089 PasswordType_t type = constToPasswordType(mLastCommandData.offset);
nikapov 0:11161008d77a 1090 uint8_t *data = mLastCommandData.data;
nikapov 0:11161008d77a 1091
nikapov 0:11161008d77a 1092 status = M24SR_IO_ReceiveI2Cresponse (M24SR_STATUSRESPONSE_NBBYTE , rensponseBuffer );
nikapov 0:11161008d77a 1093 if (status!=M24SR_SUCCESS) {
nikapov 0:11161008d77a 1094 getCallback()->on_change_reference_data(this,status,type,data);
nikapov 0:11161008d77a 1095 return status;
nikapov 0:11161008d77a 1096 }//else
nikapov 0:11161008d77a 1097
nikapov 0:11161008d77a 1098 status = M24SR_IsCorrectCRC16Residue(rensponseBuffer, M24SR_STATUSRESPONSE_NBBYTE);
nikapov 0:11161008d77a 1099 getCallback()->on_change_reference_data(this,status,type,data);
nikapov 0:11161008d77a 1100 return status;
nikapov 0:11161008d77a 1101 }
nikapov 0:11161008d77a 1102
nikapov 0:11161008d77a 1103 /**
nikapov 0:11161008d77a 1104 * @brief This function sends the EnableVerificationRequirement command
nikapov 0:11161008d77a 1105 * @param uReadOrWrite enable the read or write protection ( 0x0001 : Read or 0x0002 : Write )
nikapov 0:11161008d77a 1106 * @retval Status (SW1&SW2) Status of the operation to complete.
nikapov 0:11161008d77a 1107 * @retval M24SR_ERROR_I2CTIMEOUT I2C timeout occurred.
nikapov 0:11161008d77a 1108 */
nikapov 0:11161008d77a 1109 M24SR::StatusTypeDef M24SR::M24SR_SendEnableVerificationRequirement(uint16_t uReadOrWrite) {
nikapov 0:11161008d77a 1110 C_APDU command;
nikapov 0:11161008d77a 1111 M24SR::StatusTypeDef status;
nikapov 0:11161008d77a 1112 uint8_t *pBuffer = uM24SRbuffer;
nikapov 0:11161008d77a 1113 uint16_t NbByte;
nikapov 0:11161008d77a 1114
nikapov 0:11161008d77a 1115 /*check the parameters */
nikapov 0:11161008d77a 1116 if ((uReadOrWrite != 0x0001) && (uReadOrWrite != 0x0002)) {
nikapov 0:11161008d77a 1117 getCallback()->on_enable_verification_requirement(this,M24SR_IO_ERROR_PARAMETER, constToPasswordType(uReadOrWrite));
nikapov 0:11161008d77a 1118 return M24SR_IO_ERROR_PARAMETER;
nikapov 0:11161008d77a 1119 }
nikapov 0:11161008d77a 1120
nikapov 0:11161008d77a 1121 /* build the command */
nikapov 0:11161008d77a 1122 command.Header.CLA = C_APDU_CLA_DEFAULT;
nikapov 0:11161008d77a 1123 command.Header.INS = C_APDU_ENABLE;
nikapov 0:11161008d77a 1124 /* copy the Password Id */
nikapov 0:11161008d77a 1125 command.Header.P1 = GETMSB(uReadOrWrite);
nikapov 0:11161008d77a 1126 command.Header.P2 = GETLSB(uReadOrWrite);
nikapov 0:11161008d77a 1127 /* build the I2C command */
nikapov 0:11161008d77a 1128 M24SR_BuildIBlockCommand( M24SR_CMDSTRUCT_ENABLEVERIFREQ, &command, uDIDbyte, &NbByte, pBuffer);
nikapov 0:11161008d77a 1129
nikapov 0:11161008d77a 1130 /* send the request */
nikapov 0:11161008d77a 1131 status = M24SR_IO_SendI2Ccommand(NbByte, pBuffer);
nikapov 0:11161008d77a 1132 if (status != M24SR_SUCCESS) {
nikapov 0:11161008d77a 1133 getCallback()->on_enable_verification_requirement(this, status, constToPasswordType(uReadOrWrite));
nikapov 0:11161008d77a 1134 return status;
nikapov 0:11161008d77a 1135 }//if
nikapov 0:11161008d77a 1136
nikapov 0:11161008d77a 1137 mLastCommandSend = ENABLE_VERIFICATION_REQUIREMENT;
nikapov 0:11161008d77a 1138 //use the offset filed for store the pwd id;
nikapov 0:11161008d77a 1139 mLastCommandData.offset = (uint8_t)uReadOrWrite;
nikapov 0:11161008d77a 1140
nikapov 0:11161008d77a 1141 if (mCommunicationType==M24SR::SYNC) {
nikapov 0:11161008d77a 1142 status = M24SR_IO_PollI2C();
nikapov 0:11161008d77a 1143 if (status == M24SR_SUCCESS) {
nikapov 0:11161008d77a 1144 return M24SR_ReceiveEnableVerificationRequirement();
nikapov 0:11161008d77a 1145 } else {
nikapov 0:11161008d77a 1146 mLastCommandSend = NONE;
nikapov 0:11161008d77a 1147 getCallback()->on_enable_verification_requirement(this, status, constToPasswordType(uReadOrWrite));
nikapov 0:11161008d77a 1148 return status;
nikapov 0:11161008d77a 1149 }//if-else
nikapov 0:11161008d77a 1150 }//if
nikapov 0:11161008d77a 1151
nikapov 0:11161008d77a 1152 return M24SR_SUCCESS;
nikapov 0:11161008d77a 1153 }
nikapov 0:11161008d77a 1154
nikapov 0:11161008d77a 1155 M24SR::StatusTypeDef M24SR::M24SR_ReceiveEnableVerificationRequirement(){
nikapov 0:11161008d77a 1156 M24SR::StatusTypeDef status;
nikapov 0:11161008d77a 1157 //TODO the size is 3?
nikapov 0:11161008d77a 1158 uint8_t rensponseBuffer[M24SR_STATUSRESPONSE_NBBYTE];
nikapov 0:11161008d77a 1159
nikapov 0:11161008d77a 1160 const PasswordType_t type = constToPasswordType(mLastCommandData.offset);
nikapov 0:11161008d77a 1161
nikapov 0:11161008d77a 1162 status = M24SR_IO_ReceiveI2Cresponse (M24SR_STATUSRESPONSE_NBBYTE , rensponseBuffer );
nikapov 0:11161008d77a 1163 if (status!=M24SR_SUCCESS) {
nikapov 0:11161008d77a 1164 getCallback()->on_enable_verification_requirement(this,status,type);
nikapov 0:11161008d77a 1165 return status;
nikapov 0:11161008d77a 1166 }//else
nikapov 0:11161008d77a 1167
nikapov 0:11161008d77a 1168 status = M24SR_IsCorrectCRC16Residue(rensponseBuffer, M24SR_STATUSRESPONSE_NBBYTE);
nikapov 0:11161008d77a 1169 getCallback()->on_enable_verification_requirement(this,status,type);
nikapov 0:11161008d77a 1170 return status;
nikapov 0:11161008d77a 1171 }
nikapov 0:11161008d77a 1172
nikapov 0:11161008d77a 1173 /**
nikapov 0:11161008d77a 1174 * @brief This function sends the DisableVerificationRequirement command
nikapov 0:11161008d77a 1175 * @param uReadOrWrite enable the read or write protection ( 0x0001 : Read or 0x0002 : Write )
nikapov 0:11161008d77a 1176 * @retval Status (SW1&SW2) Status of the operation to complete.
nikapov 0:11161008d77a 1177 * @retval M24SR_ERROR_I2CTIMEOUT I2C timeout occurred.
nikapov 0:11161008d77a 1178 */
nikapov 0:11161008d77a 1179 M24SR::StatusTypeDef M24SR::M24SR_SendDisableVerificationRequirement(uint16_t uReadOrWrite) {
nikapov 0:11161008d77a 1180 C_APDU command;
nikapov 0:11161008d77a 1181 M24SR::StatusTypeDef status;
nikapov 0:11161008d77a 1182 uint8_t *pBuffer = uM24SRbuffer;
nikapov 0:11161008d77a 1183 uint16_t NbByte;
nikapov 0:11161008d77a 1184
nikapov 0:11161008d77a 1185 /*check the parameters */
nikapov 0:11161008d77a 1186 if ((uReadOrWrite != 0x0001) && (uReadOrWrite != 0x0002)) {
nikapov 0:11161008d77a 1187 getCallback()->on_disable_verification_requirement(this,M24SR_IO_ERROR_PARAMETER, constToPasswordType(uReadOrWrite));
nikapov 0:11161008d77a 1188 return M24SR_IO_ERROR_PARAMETER;
nikapov 0:11161008d77a 1189 }
nikapov 0:11161008d77a 1190
nikapov 0:11161008d77a 1191 /* build the command */
nikapov 0:11161008d77a 1192 command.Header.CLA = C_APDU_CLA_DEFAULT;
nikapov 0:11161008d77a 1193 command.Header.INS = C_APDU_DISABLE;
nikapov 0:11161008d77a 1194 /* copy the Password Id */
nikapov 0:11161008d77a 1195 command.Header.P1 = GETMSB(uReadOrWrite);
nikapov 0:11161008d77a 1196 command.Header.P2 = GETLSB(uReadOrWrite);
nikapov 0:11161008d77a 1197 /* build the I²C command */
nikapov 0:11161008d77a 1198 M24SR_BuildIBlockCommand(M24SR_CMDSTRUCT_DISABLEVERIFREQ, &command, uDIDbyte, &NbByte, pBuffer);
nikapov 0:11161008d77a 1199
nikapov 0:11161008d77a 1200 /* send the request */
nikapov 0:11161008d77a 1201 status = M24SR_IO_SendI2Ccommand(NbByte, pBuffer);
nikapov 0:11161008d77a 1202 if (status != M24SR_SUCCESS) {
nikapov 0:11161008d77a 1203 getCallback()->on_disable_verification_requirement(this, status, constToPasswordType(uReadOrWrite));
nikapov 0:11161008d77a 1204 return status;
nikapov 0:11161008d77a 1205 }
nikapov 0:11161008d77a 1206
nikapov 0:11161008d77a 1207 mLastCommandSend = DISABLE_VERIFICATION_REQUIREMENT;
nikapov 0:11161008d77a 1208 //use the offset filed for store the pwd id;
nikapov 0:11161008d77a 1209 mLastCommandData.offset = (uint8_t)uReadOrWrite;
nikapov 0:11161008d77a 1210
nikapov 0:11161008d77a 1211 if (mCommunicationType==M24SR::SYNC) {
nikapov 0:11161008d77a 1212 status = M24SR_IO_PollI2C();
nikapov 0:11161008d77a 1213 if (status==M24SR_SUCCESS) {
nikapov 0:11161008d77a 1214 return M24SR_ReceiveDisableVerificationRequirement();
nikapov 0:11161008d77a 1215 } else {
nikapov 0:11161008d77a 1216 mLastCommandSend = NONE;
nikapov 0:11161008d77a 1217 getCallback()->on_disable_verification_requirement(this, status, constToPasswordType(uReadOrWrite));
nikapov 0:11161008d77a 1218 return status;
nikapov 0:11161008d77a 1219 }//if-else
nikapov 0:11161008d77a 1220 }
nikapov 0:11161008d77a 1221
nikapov 0:11161008d77a 1222 return M24SR_SUCCESS;
nikapov 0:11161008d77a 1223 }
nikapov 0:11161008d77a 1224
nikapov 0:11161008d77a 1225 M24SR::StatusTypeDef M24SR::M24SR_ReceiveDisableVerificationRequirement() {
nikapov 0:11161008d77a 1226 M24SR::StatusTypeDef status;
nikapov 0:11161008d77a 1227 //TODO the size is 3?
nikapov 0:11161008d77a 1228 uint8_t rensponseBuffer[M24SR_STATUSRESPONSE_NBBYTE];
nikapov 0:11161008d77a 1229
nikapov 0:11161008d77a 1230 PasswordType_t type = constToPasswordType(mLastCommandData.offset);
nikapov 0:11161008d77a 1231
nikapov 0:11161008d77a 1232 status = M24SR_IO_ReceiveI2Cresponse (M24SR_STATUSRESPONSE_NBBYTE , rensponseBuffer );
nikapov 0:11161008d77a 1233 if (status!=M24SR_SUCCESS) {
nikapov 0:11161008d77a 1234 getCallback()->on_disable_verification_requirement(this,status,type);
nikapov 0:11161008d77a 1235 return status;
nikapov 0:11161008d77a 1236 }//else
nikapov 0:11161008d77a 1237
nikapov 0:11161008d77a 1238 status = M24SR_IsCorrectCRC16Residue(rensponseBuffer, M24SR_STATUSRESPONSE_NBBYTE);
nikapov 0:11161008d77a 1239 getCallback()->on_disable_verification_requirement(this,status,type);
nikapov 0:11161008d77a 1240 return status;
nikapov 0:11161008d77a 1241 }
nikapov 0:11161008d77a 1242
nikapov 0:11161008d77a 1243 /**
nikapov 0:11161008d77a 1244 * @brief This function sends the EnablePermananentState command
nikapov 0:11161008d77a 1245 * @param uReadOrWrite enable the read or write protection ( 0x0001 : Read or 0x0002 : Write )
nikapov 0:11161008d77a 1246 * @retval Status (SW1&SW2) Status of the operation to complete.
nikapov 0:11161008d77a 1247 * @retval M24SR_ERROR_I2CTIMEOUT I2C timeout occurred.
nikapov 0:11161008d77a 1248 */
nikapov 0:11161008d77a 1249 M24SR::StatusTypeDef M24SR::M24SR_SendEnablePermanentState(uint16_t uReadOrWrite) {
nikapov 0:11161008d77a 1250 C_APDU command;
nikapov 0:11161008d77a 1251 M24SR::StatusTypeDef status;
nikapov 0:11161008d77a 1252
nikapov 0:11161008d77a 1253 uint8_t *pBuffer = uM24SRbuffer;
nikapov 0:11161008d77a 1254 uint16_t NbByte;
nikapov 0:11161008d77a 1255
nikapov 0:11161008d77a 1256 /*check the parameters */
nikapov 0:11161008d77a 1257 if ((uReadOrWrite != 0x0001) && (uReadOrWrite != 0x0002)) {
nikapov 0:11161008d77a 1258 getCallback()->on_enable_permanent_state(this, M24SR_IO_ERROR_PARAMETER, constToPasswordType(uReadOrWrite));
nikapov 0:11161008d77a 1259 return M24SR_IO_ERROR_PARAMETER;
nikapov 0:11161008d77a 1260 }
nikapov 0:11161008d77a 1261
nikapov 0:11161008d77a 1262 /* build the command */
nikapov 0:11161008d77a 1263 command.Header.CLA = C_APDU_CLA_ST;
nikapov 0:11161008d77a 1264 command.Header.INS = C_APDU_ENABLE;
nikapov 0:11161008d77a 1265 /* copy the Password Id */
nikapov 0:11161008d77a 1266 command.Header.P1 = GETMSB(uReadOrWrite);
nikapov 0:11161008d77a 1267 command.Header.P2 = GETLSB(uReadOrWrite);
nikapov 0:11161008d77a 1268 /* build the I2C command */
nikapov 0:11161008d77a 1269 M24SR_BuildIBlockCommand(M24SR_CMDSTRUCT_ENABLEVERIFREQ, &command, uDIDbyte, &NbByte, pBuffer);
nikapov 0:11161008d77a 1270
nikapov 0:11161008d77a 1271 /* send the request */
nikapov 0:11161008d77a 1272 status = M24SR_IO_SendI2Ccommand(NbByte, pBuffer);
nikapov 0:11161008d77a 1273 if (status != M24SR_SUCCESS) {
nikapov 0:11161008d77a 1274 getCallback()->on_enable_permanent_state(this, status, constToPasswordType(uReadOrWrite));
nikapov 0:11161008d77a 1275 return status;
nikapov 0:11161008d77a 1276 }
nikapov 0:11161008d77a 1277
nikapov 0:11161008d77a 1278 mLastCommandSend = ENABLE_PERMANET_STATE;
nikapov 0:11161008d77a 1279 //use the offset filed for store the pwd id;
nikapov 0:11161008d77a 1280 mLastCommandData.offset = (uint8_t)uReadOrWrite;
nikapov 0:11161008d77a 1281
nikapov 0:11161008d77a 1282 if (mCommunicationType==M24SR::SYNC) {
nikapov 0:11161008d77a 1283 status = M24SR_IO_PollI2C();
nikapov 0:11161008d77a 1284 if (status == M24SR_SUCCESS) {
nikapov 0:11161008d77a 1285 return M24SR_ReceiveEnablePermanentState();
nikapov 0:11161008d77a 1286 } else {
nikapov 0:11161008d77a 1287 mLastCommandSend = NONE;
nikapov 0:11161008d77a 1288 getCallback()->on_enable_permanent_state(this, status, constToPasswordType(uReadOrWrite));
nikapov 0:11161008d77a 1289 return status;
nikapov 0:11161008d77a 1290 }//if-else
nikapov 0:11161008d77a 1291 }
nikapov 0:11161008d77a 1292
nikapov 0:11161008d77a 1293 return M24SR_SUCCESS;
nikapov 0:11161008d77a 1294 }
nikapov 0:11161008d77a 1295
nikapov 0:11161008d77a 1296 M24SR::StatusTypeDef M24SR::M24SR_ReceiveEnablePermanentState() {
nikapov 0:11161008d77a 1297 M24SR::StatusTypeDef status;
nikapov 0:11161008d77a 1298 //TODO the size is 3?
nikapov 0:11161008d77a 1299 uint8_t rensponseBuffer[M24SR_STATUSRESPONSE_NBBYTE];
nikapov 0:11161008d77a 1300
nikapov 0:11161008d77a 1301 PasswordType_t type = constToPasswordType(mLastCommandData.offset);
nikapov 0:11161008d77a 1302
nikapov 0:11161008d77a 1303 status = M24SR_IO_ReceiveI2Cresponse (M24SR_STATUSRESPONSE_NBBYTE , rensponseBuffer );
nikapov 0:11161008d77a 1304 if (status!=M24SR_SUCCESS) {
nikapov 0:11161008d77a 1305 getCallback()->on_enable_permanent_state(this,status,type);
nikapov 0:11161008d77a 1306 return status;
nikapov 0:11161008d77a 1307 }//else
nikapov 0:11161008d77a 1308
nikapov 0:11161008d77a 1309 status = M24SR_IsCorrectCRC16Residue(rensponseBuffer, M24SR_STATUSRESPONSE_NBBYTE);
nikapov 0:11161008d77a 1310 getCallback()->on_enable_permanent_state(this,status,type);
nikapov 0:11161008d77a 1311 return status;
nikapov 0:11161008d77a 1312 }
nikapov 0:11161008d77a 1313
nikapov 0:11161008d77a 1314 /**
nikapov 0:11161008d77a 1315 * @brief This function sends the DisablePermanentState command
nikapov 0:11161008d77a 1316 * @param uReadOrWrite enable the read or write protection ( 0x0001 : Read or 0x0002 : Write )
nikapov 0:11161008d77a 1317 * @retval Status (SW1&SW2) Status of the operation to complete.
nikapov 0:11161008d77a 1318 * @retval M24SR_ERROR_I2CTIMEOUT I2C timeout occurred.
nikapov 0:11161008d77a 1319 */
nikapov 0:11161008d77a 1320 M24SR::StatusTypeDef M24SR::M24SR_SendDisablePermanentState(uint16_t uReadOrWrite) {
nikapov 0:11161008d77a 1321 C_APDU command;
nikapov 0:11161008d77a 1322 M24SR::StatusTypeDef status;
nikapov 0:11161008d77a 1323 uint8_t *pBuffer = uM24SRbuffer;
nikapov 0:11161008d77a 1324 uint16_t NbByte;
nikapov 0:11161008d77a 1325
nikapov 0:11161008d77a 1326 /*check the parameters */
nikapov 0:11161008d77a 1327 if ((uReadOrWrite != 0x0001) && (uReadOrWrite != 0x0002)) {
nikapov 0:11161008d77a 1328 getCallback()->on_disable_permanent_state(this, M24SR_IO_ERROR_PARAMETER, constToPasswordType(uReadOrWrite));
nikapov 0:11161008d77a 1329 return M24SR_IO_ERROR_PARAMETER;
nikapov 0:11161008d77a 1330 }
nikapov 0:11161008d77a 1331
nikapov 0:11161008d77a 1332 /* build the command */
nikapov 0:11161008d77a 1333 command.Header.CLA = C_APDU_CLA_ST;
nikapov 0:11161008d77a 1334 command.Header.INS = C_APDU_DISABLE;
nikapov 0:11161008d77a 1335 /* copy the Password Id */
nikapov 0:11161008d77a 1336 command.Header.P1 = GETMSB(uReadOrWrite);
nikapov 0:11161008d77a 1337 command.Header.P2 = GETLSB(uReadOrWrite);
nikapov 0:11161008d77a 1338 /* build the I2C command */
nikapov 0:11161008d77a 1339 M24SR_BuildIBlockCommand(M24SR_CMDSTRUCT_DISABLEVERIFREQ, &command, uDIDbyte, &NbByte, pBuffer);
nikapov 0:11161008d77a 1340
nikapov 0:11161008d77a 1341 /* send the request */
nikapov 0:11161008d77a 1342 status = M24SR_IO_SendI2Ccommand(NbByte, pBuffer);
nikapov 0:11161008d77a 1343 if (status != M24SR_SUCCESS) {
nikapov 0:11161008d77a 1344 getCallback()->on_enable_permanent_state(this, status, constToPasswordType(uReadOrWrite));
nikapov 0:11161008d77a 1345 return status;
nikapov 0:11161008d77a 1346 }
nikapov 0:11161008d77a 1347
nikapov 0:11161008d77a 1348 mLastCommandSend = DISABLE_PERMANET_STATE;
nikapov 0:11161008d77a 1349 //use the offset filed for store the pwd id;
nikapov 0:11161008d77a 1350 mLastCommandData.offset = (uint8_t)uReadOrWrite;
nikapov 0:11161008d77a 1351
nikapov 0:11161008d77a 1352 if (mCommunicationType == M24SR::SYNC) {
nikapov 0:11161008d77a 1353 status = M24SR_IO_PollI2C();
nikapov 0:11161008d77a 1354 if (status == M24SR_SUCCESS) {
nikapov 0:11161008d77a 1355 return M24SR_ReceiveDisablePermanentState();
nikapov 0:11161008d77a 1356 } else {
nikapov 0:11161008d77a 1357 mLastCommandSend = NONE;
nikapov 0:11161008d77a 1358 getCallback()->on_disable_permanent_state(this, status, constToPasswordType(uReadOrWrite));
nikapov 0:11161008d77a 1359 return status;
nikapov 0:11161008d77a 1360 }//if-else
nikapov 0:11161008d77a 1361 }
nikapov 0:11161008d77a 1362
nikapov 0:11161008d77a 1363 return M24SR_SUCCESS;
nikapov 0:11161008d77a 1364 }
nikapov 0:11161008d77a 1365
nikapov 0:11161008d77a 1366 M24SR::StatusTypeDef M24SR::M24SR_ReceiveDisablePermanentState() {
nikapov 0:11161008d77a 1367 M24SR::StatusTypeDef status;
nikapov 0:11161008d77a 1368 //TODO the size is 3?
nikapov 0:11161008d77a 1369 uint8_t rensponseBuffer[M24SR_STATUSRESPONSE_NBBYTE];
nikapov 0:11161008d77a 1370
nikapov 0:11161008d77a 1371 PasswordType_t type = constToPasswordType(mLastCommandData.offset);
nikapov 0:11161008d77a 1372
nikapov 0:11161008d77a 1373 status = M24SR_IO_ReceiveI2Cresponse (M24SR_STATUSRESPONSE_NBBYTE , rensponseBuffer );
nikapov 0:11161008d77a 1374 if (status!=M24SR_SUCCESS) {
nikapov 0:11161008d77a 1375 getCallback()->on_disable_permanent_state(this,status,type);
nikapov 0:11161008d77a 1376 return status;
nikapov 0:11161008d77a 1377 }//else
nikapov 0:11161008d77a 1378
nikapov 0:11161008d77a 1379 status = M24SR_IsCorrectCRC16Residue(rensponseBuffer, M24SR_STATUSRESPONSE_NBBYTE);
nikapov 0:11161008d77a 1380 getCallback()->on_disable_permanent_state(this,status,type);
nikapov 0:11161008d77a 1381 return status;
nikapov 0:11161008d77a 1382 }
nikapov 0:11161008d77a 1383
nikapov 0:11161008d77a 1384 /**
nikapov 0:11161008d77a 1385 * @brief This function generates an interrupt on GPO pin
nikapov 0:11161008d77a 1386 * @param None
nikapov 0:11161008d77a 1387 * @retval Status (SW1&SW2) Status of the operation to complete.
nikapov 0:11161008d77a 1388 * @retval M24SR_ERROR_I2CTIMEOUT I2C timeout occurred.
nikapov 0:11161008d77a 1389 */
nikapov 0:11161008d77a 1390 M24SR::StatusTypeDef M24SR::M24SR_SendInterrupt(void) {
nikapov 0:11161008d77a 1391 C_APDU command;
nikapov 0:11161008d77a 1392
nikapov 0:11161008d77a 1393 uint8_t *pBuffer = uM24SRbuffer;
nikapov 0:11161008d77a 1394 uint16_t uP1P2 = 0x001E;
nikapov 0:11161008d77a 1395 uint16_t NbByte;
nikapov 0:11161008d77a 1396
nikapov 0:11161008d77a 1397
nikapov 0:11161008d77a 1398 StatusTypeDef status = M24SR_ManageI2CGPO(INTERRUPT);
nikapov 0:11161008d77a 1399 if (status!=M24SR_SUCCESS) {
nikapov 0:11161008d77a 1400 return status;
nikapov 0:11161008d77a 1401 }
nikapov 0:11161008d77a 1402
nikapov 0:11161008d77a 1403 /* build the command */
nikapov 0:11161008d77a 1404 command.Header.CLA = C_APDU_CLA_ST;
nikapov 0:11161008d77a 1405 command.Header.INS = C_APDU_INTERRUPT;
nikapov 0:11161008d77a 1406 /* copy the Password Id */
nikapov 0:11161008d77a 1407 command.Header.P1 = GETMSB(uP1P2);
nikapov 0:11161008d77a 1408 command.Header.P2 = GETLSB(uP1P2);
nikapov 0:11161008d77a 1409 command.Body.LC = 0x00;
nikapov 0:11161008d77a 1410 /* build the I2C command */
nikapov 0:11161008d77a 1411 M24SR_BuildIBlockCommand(M24SR_CMDSTRUCT_SENDINTERRUPT, &command, uDIDbyte, &NbByte, pBuffer);
nikapov 0:11161008d77a 1412
nikapov 0:11161008d77a 1413 /* send the request */
nikapov 0:11161008d77a 1414 errchk(M24SR_IO_SendI2Ccommand(NbByte, pBuffer));
nikapov 0:11161008d77a 1415 errchk(M24SR_IO_PollI2C());
nikapov 0:11161008d77a 1416 /* read the response */
nikapov 0:11161008d77a 1417 errchk(M24SR_IO_ReceiveI2Cresponse (M24SR_STATUSRESPONSE_NBBYTE , pBuffer ));
nikapov 0:11161008d77a 1418
nikapov 0:11161008d77a 1419 return M24SR_IsCorrectCRC16Residue(pBuffer, M24SR_STATUSRESPONSE_NBBYTE);
nikapov 0:11161008d77a 1420
nikapov 0:11161008d77a 1421 }
nikapov 0:11161008d77a 1422
nikapov 0:11161008d77a 1423 /**
nikapov 0:11161008d77a 1424 * @brief This function forces GPO pin to low state or high Z
nikapov 0:11161008d77a 1425 * @param uSetOrReset select if GPO must be low (reset) or HiZ
nikapov 0:11161008d77a 1426 * @retval Status (SW1&SW2) Status of the operation to complete.
nikapov 0:11161008d77a 1427 * @retval M24SR_ERROR_I2CTIMEOUT I2C timeout occurred.
nikapov 0:11161008d77a 1428 */
nikapov 0:11161008d77a 1429 M24SR::StatusTypeDef M24SR::M24SR_StateControl(uint8_t uSetOrReset) {
nikapov 0:11161008d77a 1430 C_APDU command;
nikapov 0:11161008d77a 1431 uint8_t *pBuffer = uM24SRbuffer;
nikapov 0:11161008d77a 1432 uint16_t uP1P2 = 0x001F;
nikapov 0:11161008d77a 1433 uint16_t NbByte;
nikapov 0:11161008d77a 1434
nikapov 0:11161008d77a 1435 /*check the parameters */
nikapov 0:11161008d77a 1436 if ((uSetOrReset != 0x01) && (uSetOrReset != 0x00)) {
nikapov 0:11161008d77a 1437 return M24SR_IO_ERROR_PARAMETER;
nikapov 0:11161008d77a 1438 }
nikapov 0:11161008d77a 1439
nikapov 0:11161008d77a 1440
nikapov 0:11161008d77a 1441 StatusTypeDef status = M24SR_ManageI2CGPO(STATE_CONTROL);
nikapov 0:11161008d77a 1442 if (status == M24SR_SUCCESS) {
nikapov 0:11161008d77a 1443 return status;
nikapov 0:11161008d77a 1444 }
nikapov 0:11161008d77a 1445
nikapov 0:11161008d77a 1446 /* build the command */
nikapov 0:11161008d77a 1447 command.Header.CLA = C_APDU_CLA_ST;
nikapov 0:11161008d77a 1448 command.Header.INS = C_APDU_INTERRUPT;
nikapov 0:11161008d77a 1449 /* copy the Password Id */
nikapov 0:11161008d77a 1450 command.Header.P1 = GETMSB(uP1P2);
nikapov 0:11161008d77a 1451 command.Header.P2 = GETLSB(uP1P2);
nikapov 0:11161008d77a 1452 command.Body.LC = 0x01;
nikapov 0:11161008d77a 1453 command.Body.pData = &uSetOrReset;
nikapov 0:11161008d77a 1454 /* copy the data */
nikapov 0:11161008d77a 1455 //memcpy(command.Body.pData , &uSetOrReset, 0x01 );
nikapov 0:11161008d77a 1456 //command.Body.LE = 0x00 ;
nikapov 0:11161008d77a 1457 /* build the I2C command */
nikapov 0:11161008d77a 1458 M24SR_BuildIBlockCommand( M24SR_CMDSTRUCT_GPOSTATE, &command, uDIDbyte, &NbByte, pBuffer);
nikapov 0:11161008d77a 1459
nikapov 0:11161008d77a 1460 /* send the request */
nikapov 0:11161008d77a 1461 errchk(M24SR_IO_SendI2Ccommand(NbByte, pBuffer));
nikapov 0:11161008d77a 1462 errchk(M24SR_IO_PollI2C());
nikapov 0:11161008d77a 1463 /* read the response */
nikapov 0:11161008d77a 1464 errchk(M24SR_IO_ReceiveI2Cresponse (M24SR_STATUSRESPONSE_NBBYTE , pBuffer ));
nikapov 0:11161008d77a 1465
nikapov 0:11161008d77a 1466 return M24SR_IsCorrectCRC16Residue(pBuffer, M24SR_STATUSRESPONSE_NBBYTE);
nikapov 0:11161008d77a 1467 }
nikapov 0:11161008d77a 1468
nikapov 0:11161008d77a 1469 M24SR::StatusTypeDef M24SR::M24SR_ManageI2CGPO(NFC_GPO_MGMT GPO_I2Cconfig) {
nikapov 0:11161008d77a 1470
nikapov 0:11161008d77a 1471 if (GPOPin.is_connected() == 0) {
nikapov 0:11161008d77a 1472 return M24SR_IO_PIN_NOT_CONNECTED;
nikapov 0:11161008d77a 1473 }
nikapov 0:11161008d77a 1474 if (GPO_I2Cconfig > STATE_CONTROL) {
nikapov 0:11161008d77a 1475 return M24SR_IO_ERROR_PARAMETER;
nikapov 0:11161008d77a 1476 }
nikapov 0:11161008d77a 1477
nikapov 0:11161008d77a 1478 //enable the callback for change the gpo
nikapov 0:11161008d77a 1479 mComponentCallback = &mManageGPOCallback;
nikapov 0:11161008d77a 1480 mManageGPOCallback.set_new_GPO_config(true,GPO_I2Cconfig);
nikapov 0:11161008d77a 1481
nikapov 0:11161008d77a 1482 //start the manageGPO procedure
nikapov 0:11161008d77a 1483 return M24SR_SendSelectApplication();
nikapov 0:11161008d77a 1484 }
nikapov 0:11161008d77a 1485
nikapov 0:11161008d77a 1486 M24SR::StatusTypeDef M24SR::M24SR_ManageRFGPO(NFC_GPO_MGMT GPO_I2Cconfig) {
nikapov 0:11161008d77a 1487
nikapov 0:11161008d77a 1488 if(RFDisablePin.is_connected()==0) {
nikapov 0:11161008d77a 1489 return M24SR_IO_PIN_NOT_CONNECTED;
nikapov 0:11161008d77a 1490 }
nikapov 0:11161008d77a 1491 if (GPO_I2Cconfig > STATE_CONTROL) {
nikapov 0:11161008d77a 1492 return M24SR_IO_ERROR_PARAMETER;
nikapov 0:11161008d77a 1493 }
nikapov 0:11161008d77a 1494
nikapov 0:11161008d77a 1495 //enable the callback for change the gpo
nikapov 0:11161008d77a 1496 mComponentCallback = &mManageGPOCallback;
nikapov 0:11161008d77a 1497 mManageGPOCallback.set_new_GPO_config(false,GPO_I2Cconfig);
nikapov 0:11161008d77a 1498
nikapov 0:11161008d77a 1499 //start the manageGPO procedure
nikapov 0:11161008d77a 1500 return M24SR_SendSelectApplication();
nikapov 0:11161008d77a 1501 }
nikapov 0:11161008d77a 1502
nikapov 0:11161008d77a 1503 M24SR::StatusTypeDef M24SR::M24SR_RFConfig(uint8_t OnOffChoice) {
nikapov 0:11161008d77a 1504 if (RFDisablePin.is_connected()==0) {
nikapov 0:11161008d77a 1505 return M24SR_IO_PIN_NOT_CONNECTED;
nikapov 0:11161008d77a 1506 }
nikapov 0:11161008d77a 1507 /* Disable RF */
nikapov 0:11161008d77a 1508 if (OnOffChoice != 0) {
nikapov 0:11161008d77a 1509 M24SR_IO_RFDIS_WritePin(GPIO_PIN_RESET);
nikapov 0:11161008d77a 1510 } else {
nikapov 0:11161008d77a 1511 M24SR_IO_RFDIS_WritePin(GPIO_PIN_SET);
nikapov 0:11161008d77a 1512 }
nikapov 0:11161008d77a 1513 return M24SR_SUCCESS;
nikapov 0:11161008d77a 1514 }
nikapov 0:11161008d77a 1515
nikapov 0:11161008d77a 1516 M24SR::StatusTypeDef M24SR::M24SR_IO_SendI2Ccommand(uint8_t NbByte, uint8_t *pBuffer) {
nikapov 0:11161008d77a 1517 int ret = dev_I2C.write(address, (char*) pBuffer, NbByte);
nikapov 0:11161008d77a 1518 if (ret == 0) {
nikapov 0:11161008d77a 1519 return M24SR_SUCCESS;
nikapov 0:11161008d77a 1520 }
nikapov 0:11161008d77a 1521 return M24SR_IO_ERROR_I2CTIMEOUT;
nikapov 0:11161008d77a 1522 }
nikapov 0:11161008d77a 1523
nikapov 0:11161008d77a 1524 M24SR::StatusTypeDef M24SR::M24SR_IO_ReceiveI2Cresponse(uint8_t NbByte, uint8_t *pBuffer) {
nikapov 0:11161008d77a 1525 int ret = dev_I2C.read(address, (char*) pBuffer, NbByte);
nikapov 0:11161008d77a 1526 if (ret == 0) {
nikapov 0:11161008d77a 1527 return M24SR_SUCCESS;
nikapov 0:11161008d77a 1528 }
nikapov 0:11161008d77a 1529
nikapov 0:11161008d77a 1530 return M24SR_IO_ERROR_I2CTIMEOUT;
nikapov 0:11161008d77a 1531 }
nikapov 0:11161008d77a 1532
nikapov 0:11161008d77a 1533 M24SR::StatusTypeDef M24SR::M24SR_IO_PollI2C(void) {
nikapov 0:11161008d77a 1534
nikapov 0:11161008d77a 1535 int status = 1;
nikapov 0:11161008d77a 1536 while (status != 0 ) {
nikapov 0:11161008d77a 1537 //send the device address and wait to recevie an ack bit
nikapov 0:11161008d77a 1538 status = dev_I2C.write(address,NULL,0);
nikapov 0:11161008d77a 1539 }
nikapov 0:11161008d77a 1540 return M24SR_SUCCESS;
nikapov 0:11161008d77a 1541 }
nikapov 0:11161008d77a 1542
nikapov 0:11161008d77a 1543 M24SR::StatusTypeDef M24SR::manage_event(void){
nikapov 0:11161008d77a 1544
nikapov 0:11161008d77a 1545 switch(mLastCommandSend) {
nikapov 0:11161008d77a 1546 case SELECT_APPLICATION:
nikapov 0:11161008d77a 1547 return M24SR_ReceiveSelectApplication();
nikapov 0:11161008d77a 1548 case SELECT_CC_FILE:
nikapov 0:11161008d77a 1549 return M24SR_ReceiveSelectCCfile();
nikapov 0:11161008d77a 1550 case SELECT_NDEF_FILE:
nikapov 0:11161008d77a 1551 return M24SR_ReceiveSelectNDEFfile();
nikapov 0:11161008d77a 1552 case SELECT_SYSTEM_FILE:
nikapov 0:11161008d77a 1553 return M24SR_ReceiveSelectSystemfile();
nikapov 0:11161008d77a 1554 case READ:
nikapov 0:11161008d77a 1555 return M24SR_ReceiveReadBinary();
nikapov 0:11161008d77a 1556 case UPDATE:
nikapov 0:11161008d77a 1557 return M24SR_ReceiveUpdateBinary();
nikapov 0:11161008d77a 1558 case VERIFY:
nikapov 0:11161008d77a 1559 return M24SR_ReceiveVerify();
nikapov 0:11161008d77a 1560 case DESELECT:
nikapov 0:11161008d77a 1561 return M24SR_ReceiveDeselect();
nikapov 0:11161008d77a 1562 case CHANGE_REFERENCE_DATA:
nikapov 0:11161008d77a 1563 return M24SR_ReceiveChangeReferenceData();
nikapov 0:11161008d77a 1564 case ENABLE_VERIFICATION_REQUIREMENT:
nikapov 0:11161008d77a 1565 return M24SR_ReceiveEnableVerificationRequirement();
nikapov 0:11161008d77a 1566 case DISABLE_VERIFICATION_REQUIREMENT:
nikapov 0:11161008d77a 1567 return M24SR_ReceiveDisableVerificationRequirement();
nikapov 0:11161008d77a 1568 case ENABLE_PERMANET_STATE:
nikapov 0:11161008d77a 1569 return M24SR_ReceiveEnablePermanentState();
nikapov 0:11161008d77a 1570 case DISABLE_PERMANET_STATE:
nikapov 0:11161008d77a 1571 return M24SR_ReceiveDisablePermanentState();
nikapov 0:11161008d77a 1572 default:
nikapov 0:11161008d77a 1573 return M24SR_SUCCESS;
nikapov 0:11161008d77a 1574 }//switch
nikapov 0:11161008d77a 1575 }//manageInterrupt
nikapov 0:11161008d77a 1576
nikapov 0:11161008d77a 1577 NDefLib::NDefNfcTag&M24SR::get_NDef_tag(){
nikapov 0:11161008d77a 1578 return *mNDefTagUtil;
nikapov 0:11161008d77a 1579 }
nikapov 0:11161008d77a 1580
nikapov 0:11161008d77a 1581
nikapov 0:11161008d77a 1582 /******************* (C) COPYRIGHT 2013 STMicroelectronics *****END OF FILE****/