initial commit
This commit is contained in:
23
LICENSE.md
Normal file
23
LICENSE.md
Normal file
@@ -0,0 +1,23 @@
|
||||
COPYRIGHT(c) 2017 STMicroelectronics
|
||||
|
||||
Redistribution and use in source and binary forms, with or without modification,
|
||||
are permitted provided that the following conditions are met:
|
||||
1. Redistributions of source code must retain the above copyright notice,
|
||||
this list of conditions and the following disclaimer.
|
||||
2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
this list of conditions and the following disclaimer in the documentation
|
||||
and/or other materials provided with the distribution.
|
||||
3. Neither the name of STMicroelectronics nor the names of its contributors
|
||||
may be used to endorse or promote products derived from this software
|
||||
without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
|
||||
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
||||
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
22
README.md
Normal file
22
README.md
Normal file
@@ -0,0 +1,22 @@
|
||||
# X-NUCLEO-NFC03A1
|
||||
|
||||
The code has been designed for ST X-NUCLEO-NFC03A1 expansion board to show how to detect, read and write NFC tags.
|
||||
The X-NUCLEO-NFC03A1 is an NFC card reader evaluation board based on CR95HF-VMD5T to enable expansion of the STM32 Nucleo boards.
|
||||
The CR95HF manages frame coding and decoding in Reader mode for standard applications, such as NFC, proximity and vicinity standards.
|
||||
The CR95HF embeds an analog front end to provide the 13.56 MHz air interface. The CR95HF supports ISO/IEC 14443 Type A and B, ISO/IEC 15693
|
||||
(single or double subcarrier) and ISO/IEC 18092 communication protocols, besides being MIFARE® Classic compatible.
|
||||
It also supports the detection, reading and writing of NFC Forum Type 1, 2, 3 and 4 tags.
|
||||
|
||||
## Examples
|
||||
|
||||
There is one example with the X-NUCLEO-NFC03A1 library:
|
||||
* X_NUCLEO_NFC03A1_HelloWorld: This application is to show how to detect, read and write NFC Forum Type 1, 2, 3 and 4 tags.
|
||||
|
||||
## Documentation
|
||||
|
||||
You can find the source files at
|
||||
https://github.com/stm32duino/X-NUCLEO-NFC03A1
|
||||
|
||||
The CR95HF datasheet is available at
|
||||
http://www.st.com/content/st_com/en/products/nfc/st25-nfc-rfid-tags-readers/st25-nfc-rfid-readers/cr95hf.html
|
||||
|
||||
@@ -0,0 +1,329 @@
|
||||
/**
|
||||
******************************************************************************
|
||||
* @file X_NUCLEO_NFC03A1_HelloWorld.ino
|
||||
* @author AST
|
||||
* @version V1.0.0
|
||||
* @date 6 December 2017
|
||||
* @brief Arduino test application for the STMicrolectronics X-NUCLEO-NFC03A1
|
||||
* NFC reader/writer expansion board.
|
||||
* This application makes use of C++ classes obtained from the C
|
||||
* components' drivers.
|
||||
******************************************************************************
|
||||
* @attention
|
||||
*
|
||||
* <h2><center>© COPYRIGHT(c) 2017 STMicroelectronics</center></h2>
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification,
|
||||
* are permitted provided that the following conditions are met:
|
||||
* 1. Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
* 3. Neither the name of STMicroelectronics nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
||||
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
******************************************************************************
|
||||
*/
|
||||
|
||||
|
||||
/* Includes ------------------------------------------------------------------*/
|
||||
#include "stdint.h"
|
||||
#include "stdbool.h"
|
||||
#include "string.h"
|
||||
#include "lib_NDEF_URI.h"
|
||||
#include "lib_NDEF_SMS.h"
|
||||
#include "lib_NDEF_Text.h"
|
||||
#include "lib_NDEF_Email.h"
|
||||
#include "lib_NDEF_Geo.h"
|
||||
#include "lib_95HFConfigManager.h"
|
||||
#include "miscellaneous.h"
|
||||
#include "lib_95HFConfigManager.h"
|
||||
#include "lib_wrapper.h"
|
||||
#include "lib_NDEF_URI.h"
|
||||
#include "drv_spi.h"
|
||||
|
||||
#define SerialPort Serial
|
||||
|
||||
/* Exported define -----------------------------------------------------------*/
|
||||
#define BULK_MAX_PACKET_SIZE 0x00000040
|
||||
|
||||
/* Regarding board antenna (and matching) appropriate
|
||||
value may be modified to optimized RF performances */
|
||||
/* Analogue configuration register
|
||||
ARConfigB bits 7:4 MOD_INDEX Modulation index to modulator
|
||||
3:0 RX_AMP_GAIN Defines receiver amplifier gain
|
||||
For type A you can also adjust the Timer Window
|
||||
*/
|
||||
|
||||
/****************** PICC ******************/
|
||||
/* ISO14443A */
|
||||
#define PICC_TYPEA_ACConfigA 0x27 /* backscaterring */
|
||||
|
||||
/* ISO14443B */
|
||||
#define PICC_TYPEB_ARConfigD 0x0E /* card demodulation gain */
|
||||
#define PICC_TYPEB_ACConfigA 0x17 /* backscaterring */
|
||||
|
||||
/* Felica */
|
||||
#define PICC_TYPEF_ACConfigA 0x17 /* backscaterring */
|
||||
|
||||
/* Private variables ---------------------------------------------------------*/
|
||||
|
||||
/* TT1 (PCD only)*/
|
||||
uint8_t TT1Tag[NFCT1_MAX_TAGMEMORY];
|
||||
|
||||
/* TT2 */
|
||||
uint8_t TT2Tag[NFCT2_MAX_TAGMEMORY];
|
||||
|
||||
/* TT3 */
|
||||
uint8_t TT3Tag[NFCT3_MAX_TAGMEMORY];
|
||||
uint8_t *TT3AttribInfo = TT3Tag, *TT3NDEFfile = &TT3Tag[NFCT3_ATTRIB_INFO_SIZE];
|
||||
|
||||
/* TT4 */
|
||||
uint8_t CardCCfile [NFCT4_MAX_CCMEMORY];
|
||||
uint8_t CardNDEFfileT4A [NFCT4_MAX_NDEFMEMORY];
|
||||
uint8_t CardNDEFfileT4B [NFCT4_MAX_NDEFMEMORY];
|
||||
|
||||
/* TT5 (PCD only)*/
|
||||
uint8_t TT5Tag[NFCT5_MAX_TAGMEMORY];
|
||||
|
||||
sURI_Info url;
|
||||
extern uint8_t NDEF_Buffer [];
|
||||
extern DeviceMode_t devicemode;
|
||||
|
||||
sRecordInfo_uri RecordStruct;
|
||||
|
||||
int8_t TagType = TRACK_NOTHING;
|
||||
bool TagDetected = false;
|
||||
bool terminal_msg_flag = false ;
|
||||
uint8_t status = ERRORCODE_GENERIC;
|
||||
static char dataOut[256];
|
||||
|
||||
#define X_NUCLEO_NFC03A1_LED1 D7
|
||||
#define X_NUCLEO_NFC03A1_LED2 D6
|
||||
#define X_NUCLEO_NFC03A1_LED3 D5
|
||||
#define X_NUCLEO_NFC03A1_LED4 D4
|
||||
|
||||
void setup() {
|
||||
// 95HF HW Init
|
||||
ConfigManager_HWInit();
|
||||
|
||||
// LED1
|
||||
pinMode(X_NUCLEO_NFC03A1_LED1, OUTPUT);
|
||||
|
||||
// LED2
|
||||
pinMode(X_NUCLEO_NFC03A1_LED2, OUTPUT);
|
||||
|
||||
// LED3
|
||||
pinMode(X_NUCLEO_NFC03A1_LED3, OUTPUT);
|
||||
|
||||
// LED4
|
||||
pinMode(X_NUCLEO_NFC03A1_LED4, OUTPUT);
|
||||
|
||||
// Configure USB serial interface
|
||||
SerialPort.begin(115200);
|
||||
|
||||
SerialPort.print("\r\n\r\n---------------------------------------\r\n******Welcome to x-nucleo-nfc03a1 demo******\r\n----------------------------------------");
|
||||
SerialPort.print("\r\n\r\nPlease bring an NFC tag to the board vicinity and Press User Button B1 on the board to start URI Writer/Reader demo on the tag");
|
||||
|
||||
terminal_msg_flag = true;
|
||||
|
||||
digitalWrite(X_NUCLEO_NFC03A1_LED1, HIGH);
|
||||
}
|
||||
|
||||
|
||||
/* Loop ----------------------------------------------------------------------*/
|
||||
|
||||
void loop()
|
||||
{
|
||||
devicemode = PCD;
|
||||
|
||||
/* Scan to find if there is a tag */
|
||||
TagType = ConfigManager_TagHunting(TRACK_ALL);
|
||||
|
||||
switch(TagType)
|
||||
{
|
||||
case TRACK_NFCTYPE1:
|
||||
{
|
||||
TagDetected = true;
|
||||
|
||||
if(terminal_msg_flag == true )
|
||||
{
|
||||
terminal_msg_flag = false ;
|
||||
/*---HT UI msg----------*/
|
||||
SerialPort.print( "\r\n\r\nTRACK_NFCTYPE1 NFC tag detected nearby");
|
||||
digitalWrite(X_NUCLEO_NFC03A1_LED2, HIGH);
|
||||
}
|
||||
|
||||
}
|
||||
break;
|
||||
case TRACK_NFCTYPE2:
|
||||
{
|
||||
TagDetected = true;
|
||||
|
||||
if(terminal_msg_flag == true )
|
||||
{
|
||||
terminal_msg_flag = false ;
|
||||
|
||||
/*---HT UI msg----------*/
|
||||
SerialPort.print( "\r\n\r\nTRACK_NFCTYPE2 NFC tag detected nearby");
|
||||
digitalWrite(X_NUCLEO_NFC03A1_LED2, HIGH);
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case TRACK_NFCTYPE3:
|
||||
{
|
||||
TagDetected = true;
|
||||
|
||||
if(terminal_msg_flag == true )
|
||||
{
|
||||
terminal_msg_flag = false ;
|
||||
|
||||
/*---HT UI msg----------*/
|
||||
SerialPort.print( "\r\n\r\nTRACK_NFCTYPE3 NFC tag detected nearby");
|
||||
digitalWrite(X_NUCLEO_NFC03A1_LED2, HIGH);
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case TRACK_NFCTYPE4A:
|
||||
{
|
||||
TagDetected = true;
|
||||
|
||||
if(terminal_msg_flag == true )
|
||||
{
|
||||
terminal_msg_flag = false ;
|
||||
|
||||
/*---HT UI msg----------*/
|
||||
SerialPort.print( "\r\n\r\nTRACK_NFCTYPE4A NFC tag detected nearby");
|
||||
digitalWrite(X_NUCLEO_NFC03A1_LED2, HIGH);
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case TRACK_NFCTYPE4B:
|
||||
{
|
||||
TagDetected = true;
|
||||
|
||||
if(terminal_msg_flag == true )
|
||||
{
|
||||
terminal_msg_flag = false ;
|
||||
|
||||
/*---HT UI msg----------*/
|
||||
SerialPort.print( "\r\n\r\nTRACK_NFCTYPE4B NFC tag detected nearby");
|
||||
digitalWrite(X_NUCLEO_NFC03A1_LED2, HIGH);
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case TRACK_NFCTYPE5:
|
||||
{
|
||||
TagDetected = true;
|
||||
|
||||
if(terminal_msg_flag == true )
|
||||
{
|
||||
terminal_msg_flag = false ;
|
||||
|
||||
/*---HT UI msg----------*/
|
||||
SerialPort.print( "\r\n\r\nTRACK_NFCTYPE5 NFC tag detected nearby");
|
||||
digitalWrite(X_NUCLEO_NFC03A1_LED2, HIGH);
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
{
|
||||
TagDetected = false;
|
||||
|
||||
if(terminal_msg_flag == false)
|
||||
{
|
||||
terminal_msg_flag = true ;
|
||||
/*---HT UI msg----------*/
|
||||
SerialPort.print( "\r\n\r\nCurrently there is no NFC tag in the vicinity");
|
||||
digitalWrite(X_NUCLEO_NFC03A1_LED2, LOW);
|
||||
digitalWrite(X_NUCLEO_NFC03A1_LED3, LOW);
|
||||
digitalWrite(X_NUCLEO_NFC03A1_LED4, LOW);
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
delay(300);
|
||||
|
||||
if (TagDetected == true)
|
||||
{
|
||||
TagDetected = false;
|
||||
|
||||
/* Fill the structure of the NDEF URI */
|
||||
strcpy(url.Information,"ST website for near field communication");
|
||||
strcpy(url.protocol,"http://");
|
||||
strcpy(url.URI_Message,"st.com/st25");
|
||||
|
||||
status = NDEF_WriteURI(&url);
|
||||
|
||||
delay(500);
|
||||
|
||||
if(status == RESULTOK) /*---if URI write passed----------*/
|
||||
{
|
||||
status = ERRORCODE_GENERIC;
|
||||
|
||||
snprintf( dataOut, 256, "\r\n\r\n--------------------\r\n*****URI Writer*****\r\n--------------------\r\nURI Information written successfully on the tag: \r\n URI Information: [%s], \r\n URI Protocol: [%s] , \r\n URI Message: [%s]", (char *)url.Information, (char *)url.protocol, (char *)url.URI_Message );
|
||||
SerialPort.print( dataOut );
|
||||
|
||||
digitalWrite(X_NUCLEO_NFC03A1_LED3, HIGH);
|
||||
|
||||
memset(url.Information,'\0',400); /*Clear url buffer before reading*/
|
||||
|
||||
if (TagType == TRACK_NFCTYPE1)
|
||||
{
|
||||
status = PCDNFCT1_ReadNDEF();
|
||||
} else if (TagType == TRACK_NFCTYPE2)
|
||||
{
|
||||
status = PCDNFCT2_ReadNDEF();
|
||||
} else if (TagType == TRACK_NFCTYPE3)
|
||||
{
|
||||
status = PCDNFCT3_ReadNDEF();
|
||||
} else if (TagType == TRACK_NFCTYPE4A || TagType == TRACK_NFCTYPE4B)
|
||||
{
|
||||
status = PCDNFCT4_ReadNDEF();
|
||||
} else if (TagType == TRACK_NFCTYPE5)
|
||||
{
|
||||
status = PCDNFCT5_ReadNDEF();
|
||||
}
|
||||
|
||||
if ( status == RESULTOK )
|
||||
{
|
||||
status = ERRORCODE_GENERIC;
|
||||
|
||||
memset(NDEF_Buffer,'\0',20); /* Avoid printing useless characters */
|
||||
status = NDEF_IdentifyNDEF( &RecordStruct, NDEF_Buffer);
|
||||
|
||||
if(status == RESULTOK && RecordStruct.TypeLength != 0)
|
||||
{
|
||||
if (NDEF_ReadURI(&RecordStruct, &url)==RESULTOK) /*---if URI read passed---*/
|
||||
{
|
||||
snprintf( dataOut, 256, "\r\n\r\n--------------------\r\n*****URI Reader*****\r\n--------------------\r\nURI Information read successfully from the tag: \r\n URI Information: [%s], \r\n URI Protocol: [%s] , \r\n URI Message: [%s]", (char *)url.Information, (char *)url.protocol, (char *)url.URI_Message );
|
||||
|
||||
SerialPort.print( dataOut );
|
||||
|
||||
digitalWrite(X_NUCLEO_NFC03A1_LED4, HIGH);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
9
library.properties
Normal file
9
library.properties
Normal file
@@ -0,0 +1,9 @@
|
||||
name=STM32duino X-NUCLEO-NFC03A1
|
||||
version=1.0.2
|
||||
author=STMicroelectronics
|
||||
maintainer=stm32duino
|
||||
sentence=Allows controlling the ST X-NUCLEO-NFC03A1 expansion board
|
||||
paragraph=This library provides the drivers and a sample application to control ST X-NUCLEO-NFC03A1 expansion board
|
||||
category=Communication
|
||||
url=https://github.com/stm32duino/x-nucleo-nfc03a1
|
||||
architectures=stm32
|
||||
122
src/common.h
Normal file
122
src/common.h
Normal file
@@ -0,0 +1,122 @@
|
||||
/**
|
||||
******************************************************************************
|
||||
* @file common.h
|
||||
* @author MMY Application Team
|
||||
* @version $Revision: 1507 $
|
||||
* @date $Date: 2016-01-08 09:48:35 +0100 (Fri, 08 Jan 2016) $
|
||||
* @brief This file provides all the headers of the common functions.
|
||||
******************************************************************************
|
||||
* @attention
|
||||
*
|
||||
* <h2><center>© COPYRIGHT 2016 STMicroelectronics</center></h2>
|
||||
*
|
||||
* Licensed under ST MYLIBERTY SOFTWARE LICENSE AGREEMENT (the "License");
|
||||
* You may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at:
|
||||
*
|
||||
* http://www.st.com/myliberty
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied,
|
||||
* AND SPECIFICALLY DISCLAIMING THE IMPLIED WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE, AND NON-INFRINGEMENT.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
******************************************************************************
|
||||
*/
|
||||
|
||||
|
||||
/* Define to prevent recursive inclusion -------------------------------------*/
|
||||
#ifndef _COMMON_H
|
||||
#define _COMMON_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/* Includes ------------------------------------------------------------------*/
|
||||
#define NFC_TAG_MEMORY 512
|
||||
|
||||
#include "miscellaneous.h"
|
||||
#include "lib_95HFConfigManager.h"
|
||||
#include "lib_wrapper.h"
|
||||
#include "lib_NDEF_URI.h"
|
||||
#include "drv_spi.h"
|
||||
|
||||
|
||||
#define MAX_NDEF_MEM 0x50
|
||||
|
||||
/* Nfc Mandatory define ------------------------------------------------------*/
|
||||
|
||||
#define RESULTOK 0x00
|
||||
#define ERRORCODE_GENERIC 1
|
||||
#define ACTION_COMPLETED 0x9000
|
||||
|
||||
/* status and erroc code --------------------------------------------------- */
|
||||
#define MAIN_SUCCESS_CODE RESULTOK
|
||||
|
||||
/* Enum for ST95 state aligned with new lib Ndef*/
|
||||
typedef enum {UNDEFINED_MODE=0,PICC,PCD}DeviceMode_t;
|
||||
typedef enum {UNDEFINED_TAG_TYPE=0,TT1,TT2,TT3,TT4A,TT4B,TT5}TagType_t;
|
||||
|
||||
/* external constants --------------------------------------------------------*/
|
||||
extern bool HID_TRANSACTION;
|
||||
|
||||
/* Exported types ------------------------------------------------------------*/
|
||||
typedef void (*pFunction)(void);
|
||||
|
||||
/* Exported constants --------------------------------------------------------*/
|
||||
/* Constants used by Serial Command Line Mode */
|
||||
#define CMD_STRING_SIZE 128
|
||||
|
||||
#define ApplicationAddress 0x8009000
|
||||
|
||||
#define ADDR_FLASH_SECTOR_0 ((uint32_t)0x08000000) /* Base @ of Sector 0, 16 Kbytes */
|
||||
#define ADDR_FLASH_SECTOR_1 ((uint32_t)0x08004000) /* Base @ of Sector 1, 16 Kbytes */
|
||||
#define ADDR_FLASH_SECTOR_2 ((uint32_t)0x08008000) /* Base @ of Sector 2, 16 Kbytes */
|
||||
#define ADDR_FLASH_SECTOR_3 ((uint32_t)0x0800C000) /* Base @ of Sector 3, 16 Kbytes */
|
||||
#define ADDR_FLASH_SECTOR_4 ((uint32_t)0x08010000) /* Base @ of Sector 4, 64 Kbytes */
|
||||
#define ADDR_FLASH_SECTOR_5 ((uint32_t)0x08020000) /* Base @ of Sector 5, 128 Kbytes */
|
||||
|
||||
/* Compute the FLASH upload image size */
|
||||
#define FLASH_IMAGE_SIZE (uint32_t) (FLASH_SIZE - (ApplicationAddress - 0x08000000))
|
||||
|
||||
/* TT1 */
|
||||
#define NFCT1_MAX_TAGMEMORY (120+2)
|
||||
|
||||
/* TT2 */
|
||||
#define NFCT2_MAX_TAGMEMORY NFC_TAG_MEMORY /*(must be a multiple of 8) */
|
||||
#define NFCT2_MAX_CC_SIZE 4
|
||||
#define NFCT2_MAX_CONFIG 12
|
||||
#define NFCT2_MAX_NDEFFILE (NFCT2_MAX_TAGMEMORY-NFCT2_MAX_CC_SIZE-NFCT2_MAX_CONFIG)
|
||||
|
||||
/* TT3 */
|
||||
#define NFCT3_ATTRIB_INFO_SIZE 16
|
||||
#define NFCT3_MAX_NDEFFILE NFC_TAG_MEMORY
|
||||
#define NFCT3_MAX_TAGMEMORY (NFCT3_MAX_NDEFFILE+NFCT3_ATTRIB_INFO_SIZE)
|
||||
#define NFCT3_NB_BLOC_MSB ((NFCT3_MAX_TAGMEMORY/16)>>8)
|
||||
#define NFCT3_NB_BLOC_LSB ((NFCT3_MAX_TAGMEMORY/16)&0x00FF)
|
||||
|
||||
/* TT4 */
|
||||
#define NFCT4_MAX_CCMEMORY 16
|
||||
#define NFCT4A_MAX_NDEFMEMORY NFC_TAG_MEMORY
|
||||
#define NFCT4B_MAX_NDEFMEMORY NFC_TAG_MEMORY
|
||||
#define NFCT4_MAX_NDEFMEMORY NFCT4A_MAX_NDEFMEMORY
|
||||
|
||||
/* TT5 */
|
||||
#define NFCT5_MAX_TAGMEMORY NFC_TAG_MEMORY
|
||||
|
||||
#define NFC_DEVICE_MAX_NDEFMEMORY NFCT4_MAX_NDEFMEMORY
|
||||
/* Exported macro ------------------------------------------------------------*/
|
||||
/* Common routines */
|
||||
/* Exported functions ------------------------------------------------------- */
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* _COMMON_H */
|
||||
|
||||
/*******************(C)COPYRIGHT 2016 STMicroelectronics *****END OF FILE******/
|
||||
248
src/drv_95HF.h
Normal file
248
src/drv_95HF.h
Normal file
@@ -0,0 +1,248 @@
|
||||
/**
|
||||
******************************************************************************
|
||||
* @file drv_95HF.h
|
||||
* @author MMY Application Team
|
||||
* @version $Revision: 1347 $
|
||||
* @date $Date: 2015-11-05 11:36:05 +0100 (Thu, 05 Nov 2015) $
|
||||
* @brief This file provides set of firmware functions to manage communication
|
||||
* @brief between MCU and 95HF device (CR95HF)
|
||||
******************************************************************************
|
||||
* @attention
|
||||
*
|
||||
* <h2><center>© COPYRIGHT 2016 STMicroelectronics</center></h2>
|
||||
*
|
||||
* Licensed under ST MYLIBERTY SOFTWARE LICENSE AGREEMENT (the "License");
|
||||
* You may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at:
|
||||
*
|
||||
* http://www.st.com/myliberty
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied,
|
||||
* AND SPECIFICALLY DISCLAIMING THE IMPLIED WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE, AND NON-INFRINGEMENT.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
******************************************************************************
|
||||
*/
|
||||
|
||||
/* Define to prevent recursive inclusion ------------------------------------------------ */
|
||||
#ifndef __DRV_95HF_H
|
||||
#define __DRV_95HF_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/* Includes ----------------------------------------------------------------------------- */
|
||||
#include "drv_spi.h"
|
||||
//#include "drv_uart.h"
|
||||
|
||||
/** @addtogroup BSP
|
||||
* @{
|
||||
*/
|
||||
|
||||
/** @addtogroup Components
|
||||
* @{
|
||||
*/
|
||||
|
||||
/** @defgroup XX95HF
|
||||
* @{
|
||||
*/
|
||||
|
||||
/* Exported constants --------------------------------------------------------*/
|
||||
/** @defgroup XX95HF_Exported_Constants
|
||||
* @{
|
||||
*/
|
||||
/* RFtransceiver HEADER command definition ---------------------------------------------- */
|
||||
#define RFTRANS_95HF_COMMAND_SEND 0x00
|
||||
#define RFTRANS_95HF_COMMAND_RESET 0x01
|
||||
#define RFTRANS_95HF_COMMAND_RECEIVE 0x02
|
||||
#define RFTRANS_95HF_COMMAND_POLLING 0x03
|
||||
#define RFTRANS_95HF_COMMAND_IDLE 0x07
|
||||
|
||||
/* RFtransceiver mask and data to check the data (SPI polling)--------------------------- */
|
||||
#define RFTRANS_95HF_FLAG_DATA_READY 0x08
|
||||
#define RFTRANS_95HF_FLAG_DATA_READY_MASK 0x08
|
||||
|
||||
/* RF transceiver status --------------------------------------------------------------- */
|
||||
#define RFTRANS_95HF_SUCCESS_CODE RESULTOK
|
||||
#define RFTRANS_95HF_NOREPLY_CODE 0x01
|
||||
#define RFTRANS_95HF_ERRORCODE_DEFAULT 0xFE
|
||||
#define RFTRANS_95HF_ERRORCODE_TIMEOUT 0xFD
|
||||
#define RFTRANS_95HF_ERRORCODE_POR 0x44
|
||||
|
||||
/* RF transceiver polling status ------------------------------------------------------- */
|
||||
#define RFTRANS_95HF_POLLING_RFTRANS_95HF 0x00
|
||||
#define RFTRANS_95HF_POLLING_TIMEOUT 0x01
|
||||
|
||||
/* RF transceiver number of byte of the buffers------------------------------------------ */
|
||||
#define RFTRANS_95HF_RESPONSEBUFFER_SIZE 0xFF
|
||||
#define RFTRANS_95HF_MAX_BUFFER_SIZE 0xFF
|
||||
/* Max of 256 (for QJC) and 768 (for QJE. Should be 512 but bug Design) */
|
||||
#define RFTRANS_95HF_MAX_ECHO 768
|
||||
|
||||
/* RF transceiver Offset of the command and the response -------------------------------- */
|
||||
#define RFTRANS_95HF_COMMAND_OFFSET 0x00
|
||||
#define RFTRANS_95HF_LENGTH_OFFSET 0x01
|
||||
#define RFTRANS_95HF_DATA_OFFSET 0x02
|
||||
|
||||
/* ECHO response ------------------------------------------------------------------------ */
|
||||
#define ECHORESPONSE 0x55
|
||||
|
||||
/* Sleep parameters --------------------------------------------------------------------- */
|
||||
#define IDLE_SLEEP_MODE 0x00
|
||||
#define IDLE_HIBERNATE_MODE 0x01
|
||||
|
||||
#define IDLE_CMD_LENTH 0x0E
|
||||
|
||||
#define WU_TIMEOUT 0x01
|
||||
#define WU_TAG 0x02
|
||||
#define WU_FIELD 0x04
|
||||
#define WU_IRQ 0x08
|
||||
#define WU_SPI 0x10
|
||||
|
||||
#define HIBERNATE_ENTER_CTRL 0x0400
|
||||
#define SLEEP_ENTER_CTRL 0x0100
|
||||
#define SLEEP_FIELD_ENTER_CTRL 0x0142
|
||||
|
||||
#define HIBERNATE_WU_CTRL 0x0400
|
||||
#define SLEEP_WU_CTRL 0x3800
|
||||
|
||||
#define LEAVE_CTRL 0x1800
|
||||
|
||||
/* Calibration parameters---------------------------------------------------------------- */
|
||||
#define WU_SOURCE_OFFSET 0x02
|
||||
#define WU_PERIOD_OFFSET 0x09
|
||||
#define DACDATAL_OFFSET 0x0C
|
||||
#define DACDATAH_OFFSET 0x0D
|
||||
#define NBTRIALS_OFFSET 0x0F
|
||||
|
||||
|
||||
|
||||
#define MAX_BUFFER_SIZE 256
|
||||
|
||||
#define ECHO 0x55
|
||||
#define LISTEN 0x05
|
||||
#define DUMMY_BYTE 0xFF
|
||||
|
||||
/* set state on IRQ in pin */
|
||||
//#define RFTRANS_95HF_GET_INTERFACE() HAL_GPIO_ReadPin(INTERFACE_GPIO_PORT,INTERFACE_PIN)
|
||||
|
||||
#define READERREPLY_MAX_BUFFER_SIZE 0x40
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/* Exported types ------------------------------------------------------------*/
|
||||
/** @defgroup XX95HF_Exported_Types
|
||||
* @{
|
||||
*/
|
||||
typedef enum {
|
||||
RFTRANS_95HF_INTERFACE_UART = 0,
|
||||
RFTRANS_95HF_INTERFACE_SPI,
|
||||
RFTRANS_95HF_INTERFACE_TWI
|
||||
}RFTRANS_95HF_INTERFACE;
|
||||
|
||||
|
||||
/**
|
||||
* @brief the different states of the RF transceiver
|
||||
*/
|
||||
typedef enum {
|
||||
RFTRANS_95HF_STATE_UNKNOWN = 0,
|
||||
RFTRANS_95HF_STATE_HIBERNATE ,
|
||||
RFTRANS_95HF_STATE_SLEEP,
|
||||
RFTRANS_95HF_STATE_POWERUP,
|
||||
RFTRANS_95HF_STATE_TAGDETECTOR,
|
||||
RFTRANS_95HF_STATE_READY,
|
||||
RFTRANS_95HF_STATE_READER,
|
||||
RFTRANS_95HF_STATE_TAGHUNTING,
|
||||
}RFTRANS_95HF_STATE;
|
||||
|
||||
/**
|
||||
* @brief the RF transceiver can be configured as either a reader or a card emulator
|
||||
* @brief or as P2P device
|
||||
*/
|
||||
typedef enum {
|
||||
RFTRANS_95HF_MODE_UNKNOWN = 0,
|
||||
RFTRANS_95HF_MODE_READER ,
|
||||
RFTRANS_95HF_MODE_CARDEMULATOR ,
|
||||
RFTRANS_95HF_MODE_PASSIVEP2P ,
|
||||
RFTRANS_95HF_MODE_ACTIVEP2P ,
|
||||
}RFTRANS_95HF_MODE;
|
||||
|
||||
/**
|
||||
* @brief the Rf transceiver supports the differrent protocols
|
||||
*/
|
||||
typedef enum {
|
||||
RFTRANS_95HF_PROTOCOL_UNKNOWN = 0,
|
||||
RFTRANS_95HF_PCD_14443A,
|
||||
RFTRANS_95HF_PCD_14443B,
|
||||
RFTRANS_95HF_PCD_15693,
|
||||
RFTRANS_95HF_PCD_18092,
|
||||
RFTRANS_95HF_PICC_14443A,
|
||||
RFTRANS_95HF_PICC_14443B,
|
||||
RFTRANS_95HF_PICC_15693,
|
||||
RFTRANS_95HF_PICC_18092,
|
||||
}RFTRANS_95HF_PROTOCOL;
|
||||
|
||||
|
||||
/**
|
||||
* @brief structure to store driver information
|
||||
*/
|
||||
typedef struct {
|
||||
RFTRANS_95HF_INTERFACE uInterface;
|
||||
RFTRANS_95HF_STATE uState;
|
||||
RFTRANS_95HF_MODE uMode;
|
||||
RFTRANS_95HF_PROTOCOL uCurrentProtocol;
|
||||
}drv95HF_ConfigStruct;
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/* External variables --------------------------------------------------------*/
|
||||
/* Exported macro ------------------------------------------------------------*/
|
||||
/* Exported functions ------------------------------------------------------- */
|
||||
/** @defgroup XX95HF_Exported_Functions
|
||||
* @{
|
||||
*/
|
||||
void drv95HF_ResetSPI(void);
|
||||
//int8_t drv95HF_GetInterfacePinState(void);
|
||||
uint8_t drv95HF_GetSerialInterface(void);
|
||||
//int8_t drv95HF_GetIRQOutState(void);
|
||||
void drv95HF_InitConfigStructure(void);
|
||||
void drv95HF_InitilizeSerialInterface(void);
|
||||
void drv95HF_ReceiveSPIResponse(uint8_t *pData);
|
||||
void drv95HF_SendSPICommand(const uint8_t *pData );
|
||||
int8_t drv95HF_SendReceive(const uint8_t *pCommand, uint8_t *pResponse);
|
||||
void drv95HF_SendCmd(const uint8_t *pCommand);
|
||||
int8_t drv95HF_PoolingReading(uint8_t *pResponse);
|
||||
|
||||
void drv95HF_Idle(const uint8_t WU_source, const uint8_t mode);
|
||||
void drv95HF_SendIRQINPulse(void);
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* __DRV_95HF_H */
|
||||
|
||||
/******************* (C) COPYRIGHT 2016 STMicroelectronics *****END OF FILE****/
|
||||
515
src/drv_95hf.cpp
Normal file
515
src/drv_95hf.cpp
Normal file
@@ -0,0 +1,515 @@
|
||||
/**
|
||||
******************************************************************************
|
||||
* @file drv_95HF.c
|
||||
* @author MMY Application Team
|
||||
* @version $Revision: 1348 $
|
||||
* @date $Date: 2015-11-05 11:36:33 +0100 (Thu, 05 Nov 2015) $
|
||||
* @brief This file provides set of driver functions to manage communication
|
||||
* between MCU and xx95HF chip (CR95HF)
|
||||
******************************************************************************
|
||||
* @attention
|
||||
*
|
||||
* <h2><center>© COPYRIGHT 2016 STMicroelectronics</center></h2>
|
||||
*
|
||||
* Licensed under ST MYLIBERTY SOFTWARE LICENSE AGREEMENT (the "License");
|
||||
* You may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at:
|
||||
*
|
||||
* http://www.st.com/myliberty
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied,
|
||||
* AND SPECIFICALLY DISCLAIMING THE IMPLIED WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE, AND NON-INFRINGEMENT.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
******************************************************************************
|
||||
*/
|
||||
|
||||
//#ifdef __cplusplus
|
||||
// extern "C" {
|
||||
//#endif
|
||||
|
||||
/* Includes ------------------------------------------------------------------------------ */
|
||||
#include "SPI.h"
|
||||
#include "stdbool.h"
|
||||
#include "drv_95HF.h"
|
||||
#include "lib_pcd.h"
|
||||
|
||||
/** @addtogroup BSP
|
||||
* @{
|
||||
*/
|
||||
|
||||
/** @addtogroup Components
|
||||
* @{
|
||||
*/
|
||||
|
||||
|
||||
/** @addtogroup XX95HF
|
||||
* @{
|
||||
*/
|
||||
|
||||
/* External variables --------------------------------------------------------*/
|
||||
/* Private typedef -----------------------------------------------------------*/
|
||||
/* Private defines -----------------------------------------------------------*/
|
||||
/* Private macros ------------------------------------------------------------*/
|
||||
/* Private function prototypes -----------------------------------------------*/
|
||||
static void drv95HF_InitializeSPI(void);
|
||||
static void drv95HF_SendSPIResetByte(void);
|
||||
static int8_t drv95HF_SPIPollingCommand(void);
|
||||
/* Global variables ---------------------------------------------------------*/
|
||||
/** @defgroup XX95HF_Global variables
|
||||
* @{
|
||||
*/
|
||||
/**
|
||||
* @brief buffer to exchange data with the RF tranceiver.
|
||||
*/
|
||||
uint8_t u95HFBuffer [RFTRANS_95HF_MAX_BUFFER_SIZE+3];
|
||||
|
||||
/**
|
||||
* @brief This uTimeOut variable is used as a timeout duting the communication with the RF tranceiver
|
||||
*/
|
||||
|
||||
extern volatile bool uDataReady;
|
||||
bool EnableTimeOut = true;
|
||||
|
||||
/* ConfigStructure */
|
||||
drv95HF_ConfigStruct drv95HFConfig;
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/* Private functions ---------------------------------------------------------*/
|
||||
/** @defgroup XX95HF_Private_Functions
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* @brief this functions initializes the SPI in order to communicate with the 95HF device
|
||||
* @param None
|
||||
* @retval void
|
||||
*/
|
||||
static void drv95HF_InitializeSPI(void)
|
||||
{
|
||||
RFTRANS_SPI_Init();
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief This function sends a reset command over SPI bus
|
||||
* @param None
|
||||
* @retval None
|
||||
*/
|
||||
static void drv95HF_SendSPIResetByte(void)
|
||||
{
|
||||
/* Send reset control byte */
|
||||
SPI_SendReceiveByte(RFTRANS_95HF_COMMAND_RESET);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief This function polls 95HF chip until a response is ready or
|
||||
* the counter of the timeout overflows
|
||||
* @param None
|
||||
* @retval PCD_POLLING_TIMEOUT : The time out was reached
|
||||
* @retval PCD_SUCCESS_CODE : A response is available
|
||||
*/
|
||||
static int8_t drv95HF_SPIPollingCommand( void )
|
||||
{
|
||||
uint8_t Polling_Status = 0;
|
||||
int timestamp_start = -1;
|
||||
int timestamp_final = -1;
|
||||
bool uTimeOut = false;
|
||||
|
||||
if(EnableTimeOut)
|
||||
{
|
||||
timestamp_start = millis();
|
||||
}
|
||||
|
||||
DEV_SPI.beginTransaction(SPISettings(1500000, MSBFIRST, SPI_MODE3));
|
||||
|
||||
do
|
||||
{
|
||||
/* Low level on NSS */
|
||||
RFTRANS_95HF_NSS_LOW();
|
||||
delay(2);
|
||||
|
||||
/* poll the 95HF transceiver until he's ready ! */
|
||||
Polling_Status = SPI_SendReceiveByte(RFTRANS_95HF_COMMAND_POLLING);
|
||||
Polling_Status &= RFTRANS_95HF_FLAG_DATA_READY_MASK;
|
||||
if(EnableTimeOut)
|
||||
{
|
||||
/* 3sec for LLCP can be improved to adjust it dynamically */
|
||||
timestamp_final = millis();
|
||||
if((timestamp_final - timestamp_start) > 3000)
|
||||
{
|
||||
uTimeOut = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
while( Polling_Status != RFTRANS_95HF_FLAG_DATA_READY && uTimeOut != true );
|
||||
|
||||
/* High level on NSS */
|
||||
RFTRANS_95HF_NSS_HIGH();
|
||||
|
||||
DEV_SPI.endTransaction();
|
||||
|
||||
if ( uTimeOut == true )
|
||||
{
|
||||
return RFTRANS_95HF_POLLING_TIMEOUT;
|
||||
}
|
||||
|
||||
return RFTRANS_95HF_SUCCESS_CODE;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/** @defgroup drv_95HF_Public_Functions
|
||||
* @{
|
||||
*/
|
||||
|
||||
|
||||
/**
|
||||
* @brief Initilize the 95HF device config structure
|
||||
* @param None
|
||||
* @retval None
|
||||
*/
|
||||
void drv95HF_InitConfigStructure (void)
|
||||
{
|
||||
drv95HFConfig.uInterface = RFTRANS_95HF_INTERFACE_SPI;
|
||||
drv95HFConfig.uState = RFTRANS_95HF_STATE_POWERUP;
|
||||
drv95HFConfig.uCurrentProtocol = RFTRANS_95HF_PROTOCOL_UNKNOWN;
|
||||
drv95HFConfig.uMode = RFTRANS_95HF_MODE_UNKNOWN;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Send a reset sequence over SPI bus (Reset command ,wait ,negative pulse on IRQin).
|
||||
* @param None
|
||||
* @retval None
|
||||
*/
|
||||
void drv95HF_ResetSPI(void)
|
||||
{
|
||||
/* Deselect Rftransceiver over SPI */
|
||||
RFTRANS_95HF_NSS_HIGH();
|
||||
delay(1);
|
||||
|
||||
DEV_SPI.beginTransaction(SPISettings(1500000, MSBFIRST, SPI_MODE3));
|
||||
/* Select 95HF device over SPI */
|
||||
RFTRANS_95HF_NSS_LOW();
|
||||
/* Send reset control byte */
|
||||
drv95HF_SendSPIResetByte();
|
||||
/* Deselect 95HF device over SPI */
|
||||
RFTRANS_95HF_NSS_HIGH();
|
||||
|
||||
DEV_SPI.endTransaction();
|
||||
|
||||
delay(3);
|
||||
/* send a pulse on IRQ_in*/
|
||||
drv95HF_SendIRQINPulse();
|
||||
delay(10); /* mandatory before issuing a new command */
|
||||
|
||||
drv95HFConfig.uState = RFTRANS_95HF_STATE_READY;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief returns the value of interface pin.
|
||||
* Low level means UART bus was choose.
|
||||
* High level means SPI bus was choose.
|
||||
* @param None
|
||||
* @retval Bit_RESET : 0
|
||||
* @retval Bit_SET : 1
|
||||
*/
|
||||
//int8_t drv95HF_GetInterfacePinState(void)
|
||||
//{
|
||||
// return RFTRANS_95HF_GET_INTERFACE();
|
||||
//}
|
||||
|
||||
/**
|
||||
* @brief This function returns the IRQout state
|
||||
* @param None
|
||||
* @retval Pin set : 1
|
||||
* @retval Pin reset : 0
|
||||
*/
|
||||
//int8_t drv95HF_GetIRQOutState(void)
|
||||
//{
|
||||
// if (HAL_GPIO_ReadPin(IRQOUT_RFTRANS_95HF_PORT, IRQOUT_RFTRANS_95HF_PIN) != GPIO_PIN_RESET)
|
||||
// {
|
||||
// return 0x01;
|
||||
// }
|
||||
// else
|
||||
// {
|
||||
// return 0x00;
|
||||
// }
|
||||
//}
|
||||
|
||||
/**
|
||||
* @brief This function initialize MCU serial interface peripheral (SPI or UART)
|
||||
* @param None
|
||||
* @retval None
|
||||
*/
|
||||
void drv95HF_InitilizeSerialInterface(void)
|
||||
{
|
||||
/* -- Get interface pin state to select UART or SPI mode -- */
|
||||
//if (drv95HF_GetInterfacePinState() != RFTRANS_95HF_INTERFACE_UART)
|
||||
//{
|
||||
/* -- Set communication type -- */
|
||||
drv95HFConfig.uInterface = RFTRANS_95HF_INTERFACE_SPI;
|
||||
/* -- Initialize SPI Interface -- */
|
||||
drv95HF_InitializeSPI( );
|
||||
//}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @brief This function returns the Interface selected(UART or SPI)
|
||||
* @param None
|
||||
* @retval RFTRANS_INTERFACE_UART : the UART interface is selected
|
||||
* @retval RFTRANS_INTERFACE_SPI : the SPI interface is selected
|
||||
*/
|
||||
uint8_t drv95HF_GetSerialInterface(void)
|
||||
{
|
||||
return drv95HFConfig.uInterface;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief This function sends a command over SPI bus
|
||||
* @param *pData : pointer on data to send to the xx95HF
|
||||
* @retval None
|
||||
*/
|
||||
void drv95HF_SendSPICommand(const uint8_t *pData)
|
||||
{
|
||||
uint8_t DummyBuffer[MAX_BUFFER_SIZE];
|
||||
|
||||
DEV_SPI.beginTransaction(SPISettings(1500000, MSBFIRST, SPI_MODE3));
|
||||
|
||||
/* Select xx95HF over SPI */
|
||||
RFTRANS_95HF_NSS_LOW();
|
||||
|
||||
/* Send a sending request to xx95HF */
|
||||
SPI_SendReceiveByte(RFTRANS_95HF_COMMAND_SEND);
|
||||
|
||||
if(*pData == ECHO)
|
||||
{
|
||||
/* Send a sending request to xx95HF */
|
||||
SPI_SendReceiveByte(ECHO);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Transmit the buffer over SPI */
|
||||
SPI_SendReceiveBuffer(pData, pData[RFTRANS_95HF_LENGTH_OFFSET]+RFTRANS_95HF_DATA_OFFSET, DummyBuffer);
|
||||
}
|
||||
|
||||
/* Deselect xx95HF over SPI */
|
||||
RFTRANS_95HF_NSS_HIGH();
|
||||
|
||||
DEV_SPI.endTransaction();
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* @brief This fucntion recovers a response from 95HF device
|
||||
* @param *pData : pointer on data received from 95HF device
|
||||
* @retval None
|
||||
*/
|
||||
void drv95HF_ReceiveSPIResponse(uint8_t *pData)
|
||||
{
|
||||
uint8_t DummyBuffer[MAX_BUFFER_SIZE];
|
||||
|
||||
DEV_SPI.beginTransaction(SPISettings(1500000, MSBFIRST, SPI_MODE3));
|
||||
|
||||
/* Select 95HF transceiver over SPI */
|
||||
RFTRANS_95HF_NSS_LOW();
|
||||
|
||||
/* Request a response from 95HF transceiver */
|
||||
SPI_SendReceiveByte(RFTRANS_95HF_COMMAND_RECEIVE);
|
||||
|
||||
/* Recover the "Command" byte */
|
||||
pData[RFTRANS_95HF_COMMAND_OFFSET] = SPI_SendReceiveByte(DUMMY_BYTE);
|
||||
|
||||
if(pData[RFTRANS_95HF_COMMAND_OFFSET] == ECHO)
|
||||
{
|
||||
pData[RFTRANS_95HF_LENGTH_OFFSET] = 0x00;
|
||||
/* In case we were in listen mode error code cancelled by user (0x85 0x00) must be retrieved */
|
||||
pData[RFTRANS_95HF_LENGTH_OFFSET+1] = SPI_SendReceiveByte(DUMMY_BYTE);
|
||||
pData[RFTRANS_95HF_LENGTH_OFFSET+2] = SPI_SendReceiveByte(DUMMY_BYTE);
|
||||
}
|
||||
else if(pData[RFTRANS_95HF_COMMAND_OFFSET] == 0xFF)
|
||||
{
|
||||
pData[RFTRANS_95HF_LENGTH_OFFSET] = 0x00;
|
||||
pData[RFTRANS_95HF_LENGTH_OFFSET+1] = SPI_SendReceiveByte(DUMMY_BYTE);
|
||||
pData[RFTRANS_95HF_LENGTH_OFFSET+2] = SPI_SendReceiveByte(DUMMY_BYTE);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Recover the "Length" byte */
|
||||
pData[RFTRANS_95HF_LENGTH_OFFSET] = SPI_SendReceiveByte(DUMMY_BYTE);
|
||||
/* Checks the data length */
|
||||
if(pData[RFTRANS_95HF_LENGTH_OFFSET] != 0x00)
|
||||
SPI_SendReceiveBuffer(DummyBuffer, pData[RFTRANS_95HF_LENGTH_OFFSET], &pData[RFTRANS_95HF_DATA_OFFSET]);
|
||||
}
|
||||
|
||||
/* Deselect xx95HF over SPI */
|
||||
RFTRANS_95HF_NSS_HIGH();
|
||||
|
||||
DEV_SPI.endTransaction();
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief This function send a command to 95HF device over SPI or UART bus and receive its response
|
||||
* @param *pCommand : pointer on the buffer to send to the 95HF device ( Command | Length | Data)
|
||||
* @param *pResponse : pointer on the 95HF device response ( Command | Length | Data)
|
||||
* @retval RFTRANS_95HF_SUCCESS_CODE : the function is succesful
|
||||
*/
|
||||
int8_t drv95HF_SendReceive(const uint8_t *pCommand, uint8_t *pResponse)
|
||||
{
|
||||
|
||||
if(drv95HFConfig.uInterface == RFTRANS_95HF_INTERFACE_SPI)
|
||||
{
|
||||
/* First step - Sending command */
|
||||
drv95HF_SendSPICommand(pCommand);
|
||||
/* Second step - Polling */
|
||||
if (drv95HF_SPIPollingCommand( ) != RFTRANS_95HF_SUCCESS_CODE)
|
||||
{
|
||||
*pResponse = RFTRANS_95HF_ERRORCODE_TIMEOUT;
|
||||
return RFTRANS_95HF_POLLING_TIMEOUT;
|
||||
}
|
||||
/* Third step - Receiving bytes */
|
||||
drv95HF_ReceiveSPIResponse(pResponse);
|
||||
}
|
||||
|
||||
return RFTRANS_95HF_SUCCESS_CODE;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief This function send a command to 95HF device over SPI or UART bus
|
||||
* @param *pCommand : pointer on the buffer to send to the 95HF ( Command | Length | Data)
|
||||
* @retval None
|
||||
*/
|
||||
void drv95HF_SendCmd(const uint8_t *pCommand)
|
||||
{
|
||||
if(drv95HFConfig.uInterface == RFTRANS_95HF_INTERFACE_SPI)
|
||||
/* First step - Sending command */
|
||||
drv95HF_SendSPICommand(pCommand);
|
||||
|
||||
// else if(drv95HFConfig.uInterface == RFTRANS_95HF_INTERFACE_UART)
|
||||
/* First step - Sending command */
|
||||
// drv95HF_SendUARTCommand(pCommand);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief This function is a specific command. It's made polling and reading sequence.
|
||||
* @param *pResponse : pointer on the 95HF device response ( Command | Length | Data)
|
||||
* @retval RFTRANS_95HF_SUCCESS_CODE : the function is succesful
|
||||
* @retval RFTRANS_95HF_POLLING_RFTRANS_95HF : the polling sequence returns an error
|
||||
*/
|
||||
int8_t drv95HF_PoolingReading (uint8_t *pResponse)
|
||||
{
|
||||
*pResponse =RFTRANS_95HF_ERRORCODE_DEFAULT;
|
||||
*(pResponse+1) = 0x00;
|
||||
|
||||
if(drv95HFConfig.uInterface == RFTRANS_95HF_INTERFACE_SPI)
|
||||
{
|
||||
/* First step - Polling */
|
||||
if (drv95HF_SPIPollingCommand( ) != RFTRANS_95HF_SUCCESS_CODE)
|
||||
{ *pResponse = RFTRANS_95HF_ERRORCODE_TIMEOUT;
|
||||
return RFTRANS_95HF_ERRORCODE_TIMEOUT;
|
||||
}
|
||||
/* Second step - Receiving bytes */
|
||||
drv95HF_ReceiveSPIResponse(pResponse);
|
||||
}
|
||||
|
||||
return RFTRANS_95HF_SUCCESS_CODE;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Send a negative pulse on IRQin pin
|
||||
* @param None
|
||||
* @retval None
|
||||
*/
|
||||
void drv95HF_SendIRQINPulse(void)
|
||||
{
|
||||
if (drv95HFConfig.uInterface == RFTRANS_95HF_INTERFACE_SPI)
|
||||
{
|
||||
/* Send a pulse on IRQ_IN */
|
||||
RFTRANS_95HF_IRQIN_HIGH() ;
|
||||
delay(1);
|
||||
RFTRANS_95HF_IRQIN_LOW() ;
|
||||
delay(1);
|
||||
RFTRANS_95HF_IRQIN_HIGH() ;
|
||||
}
|
||||
|
||||
/* Need to wait 10ms after the pulse before to send the first command */
|
||||
delay(10);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief this functions put the ST95HF in sleep/hibernate mode
|
||||
* @param WU_source : Source selected to wake up the device (WU_TIMEOUT,WU_TAG,WU_FIELD,WU_IRQ,WU_SPI)
|
||||
* @param mode : Can be IDLE_SLEEP_MODE or IDLE_HIBERNATE_MODE
|
||||
* @retval None
|
||||
*/
|
||||
void drv95HF_Idle(const uint8_t WU_source, const uint8_t mode)
|
||||
{
|
||||
uint8_t pCommand[] = {RFTRANS_95HF_COMMAND_IDLE, IDLE_CMD_LENTH, 0, 0, 0, 0, 0 ,0x18 ,0x00 ,0x00 ,0x60 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00};
|
||||
|
||||
if (mode == IDLE_SLEEP_MODE) /* SLEEP */
|
||||
{
|
||||
/* Select the wake up source*/
|
||||
pCommand[2] = WU_source;
|
||||
/* Select SLEEP mode */
|
||||
if (WU_source == WU_FIELD)
|
||||
{
|
||||
pCommand[3] = GETMSB(SLEEP_FIELD_ENTER_CTRL);
|
||||
pCommand[4] = GETLSB(SLEEP_FIELD_ENTER_CTRL);
|
||||
}
|
||||
else
|
||||
{
|
||||
pCommand[3] = GETMSB(SLEEP_ENTER_CTRL);
|
||||
pCommand[4] = GETLSB(SLEEP_ENTER_CTRL);
|
||||
}
|
||||
pCommand[5] = GETMSB(SLEEP_WU_CTRL);
|
||||
pCommand[6] = GETLSB(SLEEP_WU_CTRL);
|
||||
}
|
||||
else /* HIBERNATE */
|
||||
{
|
||||
/* Select the wake up source, only IRQ is available for HIBERNATE mode*/
|
||||
pCommand[2] = WU_IRQ;
|
||||
/* Select HIBERNATE mode */
|
||||
pCommand[3] = GETMSB(HIBERNATE_ENTER_CTRL);
|
||||
pCommand[4] = GETLSB(HIBERNATE_ENTER_CTRL);
|
||||
pCommand[5] = GETMSB(HIBERNATE_WU_CTRL);
|
||||
pCommand[6] = GETLSB(HIBERNATE_WU_CTRL);
|
||||
pCommand[10] = 0x00;
|
||||
}
|
||||
|
||||
/* Send the command */
|
||||
if(drv95HFConfig.uInterface == RFTRANS_95HF_INTERFACE_SPI)
|
||||
/* First step - Sending command */
|
||||
drv95HF_SendSPICommand(pCommand);
|
||||
}
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
//#ifdef __cplusplus
|
||||
//}
|
||||
//#endif
|
||||
|
||||
/******************* (C) COPYRIGHT 2016 STMicroelectronics *****END OF FILE****/
|
||||
123
src/drv_spi.cpp
Normal file
123
src/drv_spi.cpp
Normal file
@@ -0,0 +1,123 @@
|
||||
/**
|
||||
******************************************************************************
|
||||
* @file drv_spi.c
|
||||
* @author MMY Application Team
|
||||
* @version $Revision: 1508 $
|
||||
* @date $Date: 2016-01-08 09:50:04 +0100 (Fri, 08 Jan 2016) $
|
||||
* @brief This file provides a set of firmware functions to manages SPI communications
|
||||
******************************************************************************
|
||||
* @copyright
|
||||
*
|
||||
* <h2><center>© COPYRIGHT 2016 STMicroelectronics</center></h2>
|
||||
*
|
||||
* Licensed under MMY-ST Liberty SW License Agreement V2, (the "License");
|
||||
* You may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at:
|
||||
*
|
||||
* http://www.st.com/software_license_agreement_liberty_v2
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
******************************************************************************
|
||||
*/
|
||||
|
||||
//#ifdef __cplusplus
|
||||
// extern "C" {
|
||||
//#endif
|
||||
|
||||
/* Includes ------------------------------------------------------------------*/
|
||||
#include "SPI.h"
|
||||
#include "drv_spi.h"
|
||||
|
||||
/** @addtogroup BSP
|
||||
* @{
|
||||
*/
|
||||
|
||||
/** @addtogroup X_NUCLEO_NFC03A1_Spi
|
||||
* @{
|
||||
*/
|
||||
/* Private typedef -----------------------------------------------------------*/
|
||||
/* Private defines -----------------------------------------------------------*/
|
||||
/* Private macros ------------------------------------------------------------*/
|
||||
/* Private variables ---------------------------------------------------------*/
|
||||
/* External variables --------------------------------------------------------*/
|
||||
/* Global variables ----------------------------------------------------------*/
|
||||
/* Public Functions ----------------------------------------------------------*/
|
||||
/** @defgroup X_NUCLEO_NFC03A1_Spi_Public_Functions
|
||||
* @{
|
||||
*/
|
||||
/**
|
||||
* @brief Initialise HAL SPI for NFC03A1
|
||||
* @param None
|
||||
* @retval None
|
||||
*/
|
||||
void RFTRANS_SPI_Init(void)
|
||||
{
|
||||
// Configure NSS pin for CR95HF
|
||||
pinMode(10, OUTPUT);
|
||||
|
||||
// Configure interface pin select for CR95HF
|
||||
pinMode(9, OUTPUT);
|
||||
|
||||
// Configure interrupt input pin for CR95HF
|
||||
pinMode(8, OUTPUT);
|
||||
|
||||
// Set the interface pin select high in order to configure the NFC reader to use the SPI interface
|
||||
digitalWrite(9, HIGH);
|
||||
|
||||
/* SPI_NSS = High Level */
|
||||
RFTRANS_95HF_NSS_HIGH();
|
||||
|
||||
/* Set signal to high */
|
||||
RFTRANS_95HF_IRQIN_HIGH();
|
||||
|
||||
DEV_SPI.begin();
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Sends one byte over SPI and recovers a response
|
||||
* @param data : data to send
|
||||
* @retval data response from SPIx
|
||||
*/
|
||||
uint8_t SPI_SendReceiveByte(uint8_t data)
|
||||
{
|
||||
return DEV_SPI.transfer(data);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief reveive a byte array over SPI
|
||||
* @param pCommand : pointer on the buffer to send
|
||||
* @param length : length of the buffer to send
|
||||
* @param pResponse : pointer on the buffer response
|
||||
* @retval None
|
||||
*/
|
||||
void SPI_SendReceiveBuffer(const uint8_t *pCommand, uint8_t length, uint8_t *pResponse)
|
||||
{
|
||||
uint8_t i;
|
||||
|
||||
for(i=0; i<length; i++)
|
||||
pResponse[i] = SPI_SendReceiveByte(pCommand[i]);
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
//#ifdef __cplusplus
|
||||
//}
|
||||
//#endif
|
||||
|
||||
/******************* (C) COPYRIGHT 2016 STMicroelectronics *****END OF FILE****/
|
||||
86
src/drv_spi.h
Normal file
86
src/drv_spi.h
Normal file
@@ -0,0 +1,86 @@
|
||||
/**
|
||||
******************************************************************************
|
||||
* @file drv_spi.h
|
||||
* @author MMY Application Team
|
||||
* @version $Revision: 1508 $
|
||||
* @date $Date: 2016-01-08 09:50:04 +0100 (Fri, 08 Jan 2016) $
|
||||
* @brief This file provides a set of firmware functions to manages SPI communications
|
||||
******************************************************************************
|
||||
* @attention
|
||||
*
|
||||
* <h2><center>© COPYRIGHT 2016 STMicroelectronics</center></h2>
|
||||
*
|
||||
* Licensed under ST MYLIBERTY SOFTWARE LICENSE AGREEMENT (the "License");
|
||||
* You may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at:
|
||||
*
|
||||
* http://www.st.com/myliberty
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied,
|
||||
* AND SPECIFICALLY DISCLAIMING THE IMPLIED WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE, AND NON-INFRINGEMENT.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
******************************************************************************
|
||||
*/
|
||||
|
||||
/* Define to prevent recursive inclusion ------------------------------------ */
|
||||
#ifndef __DRV_SPI_H
|
||||
#define __DRV_SPI_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/* Includes ----------------------------------------------------------------- */
|
||||
#include <stdint.h>
|
||||
|
||||
/** @addtogroup BSP
|
||||
* @{
|
||||
*/
|
||||
|
||||
/** @defgroup X_NUCLEO_NFC03A1_Spi
|
||||
* @{
|
||||
*/
|
||||
|
||||
/* Exported types ------------------------------------------------------------*/
|
||||
/* Exported constants --------------------------------------------------------*/
|
||||
/* External variables --------------------------------------------------------*/
|
||||
/* Exported macro ------------------------------------------------------------*/
|
||||
#define DEV_SPI SPI
|
||||
/* set state on SPI_NSS pin */
|
||||
#define RFTRANS_95HF_NSS_LOW() digitalWrite(10, 0)
|
||||
#define RFTRANS_95HF_NSS_HIGH() digitalWrite(10, 1)
|
||||
/* set state on IRQ_In pin */
|
||||
#define RFTRANS_95HF_IRQIN_LOW() digitalWrite(8, 0)
|
||||
#define RFTRANS_95HF_IRQIN_HIGH() digitalWrite(8, 1)
|
||||
/* Exported functions ------------------------------------------------------- */
|
||||
/** @defgroup X_NUCLEO_NFC03A1_Spi_Exported_Functions
|
||||
* @{
|
||||
*/
|
||||
void RFTRANS_SPI_Init(void);
|
||||
void SPI_SendReceiveBuffer(const uint8_t *pCommand, uint8_t length, uint8_t *pResponse);
|
||||
uint8_t SPI_SendReceiveByte(uint8_t data);
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* __DRV_SPI_H */
|
||||
|
||||
/******************* (C) COPYRIGHT 2016 STMicroelectronics *****END OF FILE****/
|
||||
128
src/lib_95HF.h
Normal file
128
src/lib_95HF.h
Normal file
@@ -0,0 +1,128 @@
|
||||
/**
|
||||
******************************************************************************
|
||||
* @file lib_95HF.h
|
||||
* @author MMY Application Team
|
||||
* @version $Revision: 1327 $
|
||||
* @date $Date: 2015-11-05 10:28:31 +0100 (Thu, 05 Nov 2015) $
|
||||
* @brief This file provides set of xx95HF device.
|
||||
* @brief The commands as defined in 95HF's family product datasheet.
|
||||
******************************************************************************
|
||||
* @attention
|
||||
*
|
||||
* <h2><center>© COPYRIGHT 2015 STMicroelectronics</center></h2>
|
||||
*
|
||||
* Licensed under ST MYLIBERTY SOFTWARE LICENSE AGREEMENT (the "License");
|
||||
* You may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at:
|
||||
*
|
||||
* http://www.st.com/myliberty
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied,
|
||||
* AND SPECIFICALLY DISCLAIMING THE IMPLIED WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE, AND NON-INFRINGEMENT.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
******************************************************************************
|
||||
*/
|
||||
|
||||
/* Define to prevent recursive inclusion -------------------------------------*/
|
||||
#ifndef _LIB_95HF_H
|
||||
#define _LIB_95HF_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/* Includes ------------------------------------------------------------------*/
|
||||
#include "drv_95HF.h"
|
||||
#include "common.h"
|
||||
|
||||
#include "lib_nfctype1pcd.h"
|
||||
#include "lib_nfctype2pcd.h"
|
||||
#include "lib_nfctype3pcd.h"
|
||||
#include "lib_nfctype4pcd.h"
|
||||
#include "lib_nfctype5pcd.h"
|
||||
|
||||
/* Analogue configuration register for protocol initialization -------------------------------------------*/
|
||||
#define TIMER_WINDOW_REG_ADD 0x3A
|
||||
#define TIMER_WINDOW_UPDATE_CONFIRM_CMD 0x04
|
||||
|
||||
|
||||
#define AFE_ANALOG_CONF_REG_SELECTION 0x68
|
||||
#define AFE_ANALOG_CONF_REG_UPDATE 0x69
|
||||
|
||||
#define AFE_ACCONFIGA_OFFSET 0x04
|
||||
|
||||
/* ROM CODE Revision --------------------------------------------------------------*/
|
||||
#define ROM_CODE_REVISION_OFFSET 13
|
||||
|
||||
/* RFtrans 95HF family command definition ---------------------------------------------------------------*/
|
||||
#define IDN 0x01
|
||||
#define PROTOCOL_SELECT 0x02
|
||||
#define POLL_FIELD 0x03
|
||||
#define SEND_RECEIVE 0x04
|
||||
#define LISTEN 0x05
|
||||
#define SEND 0x06
|
||||
#define IDLE 0x07
|
||||
#define READ_REGISTER 0x08
|
||||
#define WRITE_REGISTER 0x09
|
||||
#define BAUD_RATE 0x0A
|
||||
#define SUB_FREQ_RES 0x0B
|
||||
#define AC_FILTER 0x0D
|
||||
#define TEST_MODE 0x0E
|
||||
#define SLEEP_MODE 0x0F
|
||||
#define ECHO 0x55
|
||||
|
||||
|
||||
/* poll field status ------------------------------------------------------------------ */
|
||||
#define POLLFIELD_RESULTSCODE_OK 0x00
|
||||
|
||||
|
||||
|
||||
// Send command field status
|
||||
#define SEND_RESULTSCODE_OK 0x00
|
||||
#define SEND_ERRORCODE_LENGTH 0x82
|
||||
#define SEND_ERRORCODE_PROTOCOL 0x83
|
||||
/* Idle command field status ----------------------------------------------------------------- */
|
||||
#define IDLE_RESULTSCODE_OK 0x00
|
||||
#define IDLE_ERRORCODE_LENGTH 0x82
|
||||
/* read register command field status -------------------------------------------------------- */
|
||||
#define READREG_RESULTSCODE_OK 0x00
|
||||
#define READREG_ERRORCODE_LENGTH 0x82
|
||||
/* write register command field status ------------------------------------------------------- */
|
||||
#define WRITEREG_RESULTSCODE_OK 0x00
|
||||
/* Baud rate command field status ------------------------------------------------------------ */
|
||||
#define BAUDRATE_RESULTSCODE_OK 0x55
|
||||
/* AC filter command field status ------------------------------------------------------------ */
|
||||
#define ACFILTER_RESULTSCODE_OK 0x00
|
||||
#define ACFILTER_ERRORCODE_LENGTH 0x82
|
||||
/* sub freq command field status ------------------------------------------------------------- */
|
||||
#define SUBFREQ_RESULTSCODE_OK 0x00
|
||||
/* Test mode command field status ------------------------------------------------------------ */
|
||||
#define TESTMODE_RESULTSCODE_OK 0x00
|
||||
|
||||
#define ASK_FOR_SESSION 0x0000
|
||||
#define TAKE_SESSION 0xFFFF
|
||||
|
||||
#define XX95_ACTION_COMPLETED 0x9000
|
||||
|
||||
|
||||
|
||||
typedef enum {
|
||||
QJA = 0x30,
|
||||
QJB,
|
||||
QJC,
|
||||
QJD,
|
||||
QJE
|
||||
}IC_VERSION;
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* _LIB_95HF_H */
|
||||
|
||||
/******************* (C) COPYRIGHT 2015 STMicroelectronics *****END OF FILE****/
|
||||
324
src/lib_95HFConfigManager.cpp
Normal file
324
src/lib_95HFConfigManager.cpp
Normal file
@@ -0,0 +1,324 @@
|
||||
/**
|
||||
******************************************************************************
|
||||
* @file lib_95HFConfigManager.c
|
||||
* @author MMY Application Team
|
||||
* @version $Revision: 1328 $
|
||||
* @date $Date: 2015-11-05 10:30:08 +0100 (Thu, 05 Nov 2015) $
|
||||
* @brief This file provides set of firmware functions to manages device modes.
|
||||
******************************************************************************
|
||||
* @attention
|
||||
*
|
||||
* <h2><center>© COPYRIGHT 2015 STMicroelectronics</center></h2>
|
||||
*
|
||||
* Licensed under ST MYLIBERTY SOFTWARE LICENSE AGREEMENT (the "License");
|
||||
* You may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at:
|
||||
*
|
||||
* http://www.st.com/myliberty
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied,
|
||||
* AND SPECIFICALLY DISCLAIMING THE IMPLIED WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE, AND NON-INFRINGEMENT.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
******************************************************************************
|
||||
*/
|
||||
|
||||
//#ifdef __cplusplus
|
||||
// extern "C" {
|
||||
//#endif
|
||||
|
||||
/* Includes ------------------------------------------------------------------------------ */
|
||||
#include "Arduino.h"
|
||||
#include "lib_95HFConfigManager.h"
|
||||
|
||||
/** @addtogroup _95HF_Libraries
|
||||
* @{
|
||||
* @brief <b>This is the library used by the whole 95HF family ( CR95HF ) <br />
|
||||
* You will find ISO libraries ( 14443A, 14443B, 15693, ...) for PICC and PCD <br />
|
||||
* The libraries selected in the project will depend of the application targetted <br />
|
||||
* and the product chosen (RX95HF emulate PICC, CR95HF emulate PCD, ST95HF can do both)</b>
|
||||
*/
|
||||
|
||||
/** @addtogroup Config_Manager
|
||||
* @{
|
||||
* @brief This part of the library manage the configuration of the chip.
|
||||
*/
|
||||
/**
|
||||
* @brief This buffer contains the data send/received by xx95HF
|
||||
*/
|
||||
extern uint8_t u95HFBuffer[RFTRANS_95HF_MAX_BUFFER_SIZE+3];
|
||||
extern ISO14443A_CARD ISO14443A_Card;
|
||||
|
||||
/** @addtogroup Configuration_Manager
|
||||
* @{
|
||||
* @brief This file is used to select a configuration, PICC or PCD or Initiator/Target.
|
||||
*/
|
||||
|
||||
/** @addtogroup lib_ConfigManager_Private_Functions
|
||||
* @{
|
||||
*/
|
||||
static void ConfigManager_Init( void);
|
||||
static int8_t ConfigManager_IDN(uint8_t *pResponse);
|
||||
static void ConfigManager_Start(void );
|
||||
static int8_t ConfigManager_PORsequence( void );
|
||||
|
||||
/* Variables for the different modes */
|
||||
DeviceMode_t devicemode = UNDEFINED_MODE;
|
||||
TagType_t nfc_tagtype = UNDEFINED_TAG_TYPE;
|
||||
|
||||
/* Variable to know IC version */
|
||||
IC_VERSION IcVers = QJE; /* default set last IC version */
|
||||
|
||||
bool StopProcess = false;
|
||||
bool TargetMode = true;
|
||||
uint8_t TagUID[16];
|
||||
|
||||
/**
|
||||
* @brief This function initialize the PICC
|
||||
* @param None
|
||||
* @retval None
|
||||
*/
|
||||
static void ConfigManager_Init( void)
|
||||
{
|
||||
/* initialize the structure of the Rf tranceiver */
|
||||
drv95HF_InitConfigStructure ();
|
||||
|
||||
/* configure the Serial interface to communicate with the RF transceiver */
|
||||
drv95HF_InitilizeSerialInterface ( );
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief this function sends an IDN command to the PICC device
|
||||
* @param pResponse : pointer on the PICC device reply
|
||||
* @retval PICC_SUCCESSCODE : the function is succesful
|
||||
*/
|
||||
static int8_t ConfigManager_IDN(uint8_t *pResponse)
|
||||
{
|
||||
uint8_t DataToSend[] = {IDN ,0x00};
|
||||
|
||||
/* send the command to the PICC and retrieve its response */
|
||||
drv95HF_SendReceive(DataToSend, pResponse);
|
||||
|
||||
return MANAGER_SUCCESSCODE;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief This function set a variable to inform Manager that a task is on going
|
||||
* @param none
|
||||
* @retval none
|
||||
*/
|
||||
static void ConfigManager_Start( void )
|
||||
{
|
||||
StopProcess = false;
|
||||
|
||||
devicemode = UNDEFINED_MODE;
|
||||
nfc_tagtype = UNDEFINED_TAG_TYPE;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief This function sends POR sequence. It is used to initialize chip after a POR.
|
||||
* @param none
|
||||
* @retval MANAGER_ERRORCODE_PORERROR : the POR sequence doesn't succeded
|
||||
* @retval MANAGER_SUCCESSCODE : chip is ready
|
||||
*/
|
||||
static int8_t ConfigManager_PORsequence( void )
|
||||
{
|
||||
uint16_t NthAttempt=0;
|
||||
uint8_t command[]= {ECHO};
|
||||
|
||||
/* Power up sequence: Pulse on IRQ_IN to select UART or SPI mode */
|
||||
drv95HF_SendIRQINPulse();
|
||||
|
||||
/* SPI Reset */
|
||||
if(drv95HF_GetSerialInterface() == RFTRANS_95HF_INTERFACE_SPI)
|
||||
{
|
||||
drv95HF_ResetSPI();
|
||||
}
|
||||
|
||||
do
|
||||
{
|
||||
/* send an ECHO command and checks response */
|
||||
drv95HF_SendReceive(command, u95HFBuffer);
|
||||
|
||||
if (u95HFBuffer[0]==ECHORESPONSE)
|
||||
return MANAGER_SUCCESSCODE;
|
||||
|
||||
/* if the SPI interface is selected then send a reset command*/
|
||||
if(drv95HF_GetSerialInterface() == RFTRANS_95HF_INTERFACE_SPI)
|
||||
{
|
||||
drv95HF_ResetSPI();
|
||||
}
|
||||
/* if the UART interface is selected then send 255 ECHO commands*/
|
||||
else if(drv95HF_GetSerialInterface() == RFTRANS_95HF_INTERFACE_UART)
|
||||
{
|
||||
do {
|
||||
/* send an ECHO command and checks response */
|
||||
drv95HF_SendReceive(command, u95HFBuffer);
|
||||
if (u95HFBuffer[0] == ECHORESPONSE)
|
||||
return MANAGER_SUCCESSCODE;
|
||||
}while(NthAttempt++ < RFTRANS_95HF_MAX_ECHO);
|
||||
}
|
||||
} while (u95HFBuffer[0]!=ECHORESPONSE && NthAttempt++ <5);
|
||||
|
||||
return MANAGER_ERRORCODE_PORERROR;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/** @addtogroup lib_ConfigManager_Public_Functions
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* @brief This interface function inform Manager that current task must be stopped
|
||||
* @param none
|
||||
* @retval none
|
||||
*/
|
||||
void ConfigManager_Stop(void )
|
||||
{
|
||||
StopProcess = true;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief This function initialize the NFC chip
|
||||
* @brief Physical communication with chip enabled, RF communication not enabled
|
||||
* @param None
|
||||
* @retval None
|
||||
*/
|
||||
void ConfigManager_HWInit (void)
|
||||
{
|
||||
|
||||
/* Initialize HW according to protocol to use */
|
||||
ConfigManager_Init();
|
||||
|
||||
/* initilialize the RF transceiver */
|
||||
if (ConfigManager_PORsequence( ) != MANAGER_SUCCESSCODE)
|
||||
{
|
||||
/* nothing to do, this is a trap for debug purpose you can use it to detect HW issue */
|
||||
/* or GPIO config issue */
|
||||
}
|
||||
|
||||
/* Retrieve the IC version of the chip */
|
||||
ConfigManager_IDN(u95HFBuffer);
|
||||
|
||||
IcVers = (IC_VERSION) (u95HFBuffer[ROM_CODE_REVISION_OFFSET]);
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief this function searches if a NFC or RFID tag is in the RF field.
|
||||
* @brief The method used is this described by the NFC specification
|
||||
* @param tagsToFind : Flags to select the different kinds of tag to track, same as return value
|
||||
* @retval TRACK_NOTHING : No tag in the RF field
|
||||
* @retval TRACK_NFCTYPE1 : A NFC type1 tag is present in the RF field
|
||||
* @retval TRACK_NFCTYPE2 : A NFC type2 tag is present in the RF field
|
||||
* @retval TRACK_NFCTYPE3 : A NFC type3 tag is present in the RF field
|
||||
* @retval TRACK_NFCTYPE4A : A NFC type4A tag is present in the RF field
|
||||
* @retval TRACK_NFCTYPE4B : A NFC type4B tag is present in the RF field
|
||||
* @retval TRACK_NFCTYPE5 : A ISO/IEC 15693 type A tag is present in the RF field
|
||||
*/
|
||||
uint8_t ConfigManager_TagHunting ( uint8_t tagsToFind )
|
||||
{
|
||||
/* Start the config manager*/
|
||||
ConfigManager_Start();
|
||||
|
||||
/******* NFC type 1 ********/
|
||||
if (tagsToFind&TRACK_NFCTYPE1)
|
||||
{
|
||||
PCD_FieldOff();
|
||||
delay(5);
|
||||
ISO14443A_Init( );
|
||||
if(ISO14443A_IsPresent() == RESULTOK)
|
||||
{
|
||||
if(TOPAZ_ID(TagUID) == RESULTOK)
|
||||
return TRACK_NFCTYPE1;
|
||||
}
|
||||
}
|
||||
|
||||
/******* NFC type 2 and 4A ********/
|
||||
if ((tagsToFind&TRACK_NFCTYPE2) || (tagsToFind&TRACK_NFCTYPE4A))
|
||||
{
|
||||
PCD_FieldOff();
|
||||
delay(5);
|
||||
ISO14443A_Init( );
|
||||
if(ISO14443A_IsPresent() == RESULTOK)
|
||||
{
|
||||
if(ISO14443A_Anticollision() == RESULTOK)
|
||||
{
|
||||
if (((ISO14443A_Card.SAK&0x60) == 0x00) && (tagsToFind&TRACK_NFCTYPE2)) /* TT2 */
|
||||
return TRACK_NFCTYPE2;
|
||||
else if (((ISO14443A_Card.SAK&0x20) != 0x00) && (tagsToFind&TRACK_NFCTYPE4A))/* TT4A */
|
||||
return TRACK_NFCTYPE4A;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/******* NFC type 3 ********/
|
||||
if (tagsToFind&TRACK_NFCTYPE3)
|
||||
{
|
||||
PCD_FieldOff();
|
||||
delay(5);
|
||||
FELICA_Initialization();
|
||||
if(FELICA_IsPresent() == RESULTOK )
|
||||
return TRACK_NFCTYPE3;
|
||||
}
|
||||
|
||||
/******* NFC type 4B ********/
|
||||
if (tagsToFind&TRACK_NFCTYPE4B)
|
||||
{
|
||||
PCD_FieldOff();
|
||||
delay(5);
|
||||
if(ISO14443B_IsPresent() == RESULTOK )
|
||||
{
|
||||
if(ISO14443B_Anticollision() == RESULTOK)
|
||||
{
|
||||
return TRACK_NFCTYPE4B;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/******* ISO15693 ********/
|
||||
if (tagsToFind&TRACK_NFCTYPE5)
|
||||
{
|
||||
PCD_FieldOff();
|
||||
delay(5);
|
||||
if(ISO15693_GetUID (TagUID) == RESULTOK)
|
||||
return TRACK_NFCTYPE5;
|
||||
}
|
||||
|
||||
|
||||
/* Turn off the field if no tag has been detected*/
|
||||
PCD_FieldOff();
|
||||
|
||||
/* No tag found */
|
||||
return TRACK_NOTHING;
|
||||
}
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
//#ifdef __cplusplus
|
||||
//}
|
||||
//#endif
|
||||
|
||||
/******************* (C) COPYRIGHT 2015 STMicroelectronics *****END OF FILE****/
|
||||
112
src/lib_95HFConfigManager.h
Normal file
112
src/lib_95HFConfigManager.h
Normal file
@@ -0,0 +1,112 @@
|
||||
/**
|
||||
******************************************************************************
|
||||
* @file lib_95HFConfigManager.h
|
||||
* @author MMY Application Team
|
||||
* @version $Revision: 1327 $
|
||||
* @date $Date: 2015-11-05 10:28:31 +0100 (Thu, 05 Nov 2015) $
|
||||
* @brief This file provides set of firmware functions to manage device modes.
|
||||
******************************************************************************
|
||||
* @attention
|
||||
*
|
||||
* <h2><center>© COPYRIGHT 2015 STMicroelectronics</center></h2>
|
||||
*
|
||||
* Licensed under ST MYLIBERTY SOFTWARE LICENSE AGREEMENT (the "License");
|
||||
* You may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at:
|
||||
*
|
||||
* http://www.st.com/myliberty
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied,
|
||||
* AND SPECIFICALLY DISCLAIMING THE IMPLIED WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE, AND NON-INFRINGEMENT.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
******************************************************************************
|
||||
*/
|
||||
|
||||
/* Define to prevent recursive inclusion --------------------------------------------*/
|
||||
#ifndef _LIB_95HFCONFIGMANAGER_H
|
||||
#define _LIB_95HFCONFIGMANAGER_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/* Includes -------------------------------------------------------------------------*/
|
||||
#include "lib_iso15693pcd.h"
|
||||
#include "lib_iso14443Apcd.h"
|
||||
#include "lib_iso14443Bpcd.h"
|
||||
#include "lib_iso18092pcd.h"
|
||||
|
||||
/* Manager status and erroc code ----------------------------------------------------*/
|
||||
#define MANAGER_SUCCESSCODE RESULTOK
|
||||
#define MANAGER_ERRORCODE_DEFAULT 0xF1
|
||||
#define MANAGER_ERRORCODE_PORERROR 0xF2
|
||||
#define MANAGER_ERRORCODE_COMMUNICATION_LOST 0xF3
|
||||
|
||||
/* Flags for PICC/PCD tracking ----------------------------------------------------------*/
|
||||
#define TRACK_NOTHING 0x00
|
||||
#define TRACK_NFCTYPE1 0x01 /* 0000 0001 */
|
||||
#define TRACK_NFCTYPE2 0x02 /* 0000 0010 */
|
||||
#define TRACK_NFCTYPE3 0x04 /* 0000 0100 */
|
||||
#define TRACK_NFCTYPE4A 0x08 /* 0000 1000 */
|
||||
#define TRACK_NFCTYPE4B 0x10 /* 0001 0000 */
|
||||
#define TRACK_NFCTYPE5 0x20 /* 0010 0000 */
|
||||
#define TRACK_ALL 0xFF /* 1111 1111 */
|
||||
|
||||
/* Flags for Initiator/Target tracking ------------------------------------------------------*/
|
||||
#define P2P_NOTHING 0x00
|
||||
#define INITIATOR_NFCA 0x01 /* 0000 0001 */
|
||||
#define INITIATOR_NFCF 0x02 /* 0000 0010 */
|
||||
#define TARGET_NFCA 0x04 /* 0000 0100 */
|
||||
#define TARGET_NFCF 0x08 /* 0000 1000 */
|
||||
#define TARGET_LLCPA 0x10 /* 0000 0100 */
|
||||
#define TARGET_LLCPF 0x20 /* 0000 1000 */
|
||||
#define INITIATOR_LLCPA 0x40 /* 0000 0100 */
|
||||
#define INITIATOR_LLCPF 0x80 /* 0000 1000 */
|
||||
#define P2P_ALL 0xFF /* 1111 1111 */
|
||||
|
||||
/* Flags for Proprietary P2P tracking ------------------------------------------------------*/
|
||||
#define PP2P_NOTHING 0x00
|
||||
#define PP2P_INITIATOR_NFCA 0x01 /* 0000 0001 */
|
||||
#define PP2P_TARGET_NFCA 0x10 /* 0000 0100 */
|
||||
#define PP2P_ALL 0xFF /* 1111 1111 */
|
||||
|
||||
/* Flags for SelectMode ----------------------------------------------------------*/
|
||||
#define SELECT_NOTHING 0x00
|
||||
#define SELECT_PCD 0x01 /* 0000 0001 */
|
||||
#define SELECT_PICC 0x02 /* 0000 0010 */
|
||||
#define SELECT_P2P 0x04 /* 0000 0100 */
|
||||
#define SELECT_ALL 0xFF /* 1111 1111 */
|
||||
|
||||
/* structure of the manager state --------------------------------------------------*/
|
||||
typedef struct {
|
||||
uint8_t SelectedMode;
|
||||
uint8_t PcdMode;
|
||||
uint8_t PiccMode;
|
||||
uint8_t P2pMode;
|
||||
uint8_t Result;
|
||||
uint16_t timeoutEmul;
|
||||
uint16_t timeoutReadEmul;
|
||||
}MANAGER_CONFIG;
|
||||
|
||||
//typedef enum PICCEMULATOR_SELECT_TAG_TYPE PICCEMULATOR_SELECT_TAG_TYPE;
|
||||
|
||||
/* public function ----------------------------------------------------------------*/
|
||||
|
||||
void ConfigManager_HWInit (void);
|
||||
|
||||
uint8_t ConfigManager_TagHunting ( uint8_t tagsToFind );
|
||||
|
||||
void ConfigManager_Stop(void);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
/******************* (C) COPYRIGHT 2016 STMicroelectronics *****END OF FILE****/
|
||||
401
src/lib_95HF_wrapper.cpp
Normal file
401
src/lib_95HF_wrapper.cpp
Normal file
@@ -0,0 +1,401 @@
|
||||
/**
|
||||
******************************************************************************
|
||||
* @file lib_95HF_wrapper.c
|
||||
* @author MMY Application Team
|
||||
* @version $Revision: 1330 $
|
||||
* @date $Date: 2015-11-05 10:39:11 +0100 (Thu, 05 Nov 2015) $
|
||||
* @brief Interface for xx95HF in order to use NDEF lib
|
||||
******************************************************************************
|
||||
* @attention
|
||||
*
|
||||
* <h2><center>© COPYRIGHT 2015 STMicroelectronics</center></h2>
|
||||
*
|
||||
* Licensed under ST MYLIBERTY SOFTWARE LICENSE AGREEMENT (the "License");
|
||||
* You may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at:
|
||||
*
|
||||
* http://www.st.com/myliberty
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied,
|
||||
* AND SPECIFICALLY DISCLAIMING THE IMPLIED WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE, AND NON-INFRINGEMENT.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
******************************************************************************
|
||||
*/
|
||||
|
||||
//#ifdef __cplusplus
|
||||
// extern "C" {
|
||||
//#endif
|
||||
|
||||
/* Includes ------------------------------------------------------------------*/
|
||||
#include "lib_wrapper.h"
|
||||
#include "lib_NDEF.h"
|
||||
|
||||
#include "lib_nfctype1pcd.h"
|
||||
#include "lib_nfctype2pcd.h"
|
||||
#include "lib_nfctype3pcd.h"
|
||||
#include "lib_nfctype4pcd.h"
|
||||
#include "lib_nfctype5pcd.h"
|
||||
|
||||
/* Variables for the different modes */
|
||||
extern DeviceMode_t devicemode;
|
||||
extern TagType_t nfc_tagtype;
|
||||
|
||||
bool updateFlash = false;
|
||||
|
||||
/* Tag type 1 */
|
||||
extern uint8_t TT1Tag[];
|
||||
|
||||
/* Tag type 2 */
|
||||
extern uint8_t TT2Tag[];
|
||||
|
||||
/* Tag type 3 */
|
||||
extern uint8_t TT3Tag[];
|
||||
extern uint8_t *TT3AttribInfo, *TT3NDEFfile;
|
||||
|
||||
/* Tag type 4 */
|
||||
/* NDEF buffer */
|
||||
extern uint8_t CardNDEFfileT4A [];
|
||||
extern uint8_t CardNDEFfileT4B [];
|
||||
/* CC buffer*/
|
||||
extern uint8_t CardCCfile [];
|
||||
|
||||
/* Tag type 5 */
|
||||
extern uint8_t TT5Tag[];
|
||||
|
||||
/** @addtogroup NFC_libraries
|
||||
* @{
|
||||
* @brief <b>This is the library used to manage the content of the TAG (data)
|
||||
* But also the specific feature of the tag, for instance
|
||||
* password, gpo... </b>
|
||||
*/
|
||||
|
||||
|
||||
/** @addtogroup libNFC_FORUM
|
||||
* @{
|
||||
* @brief This part of the library manage data which follow NFC forum organisation.
|
||||
*/
|
||||
|
||||
|
||||
/** @defgroup lib_95HF_Private_Functions
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/** @defgroup lib_95HF_Public_Functions
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* @brief This fonction read the data stored in NDEF file at defined offset.
|
||||
* @param Offset : Offset in the NDEF file.
|
||||
* @param DataSize : Number of byte to read.
|
||||
* @param pData : pointer on buffer to store read data.
|
||||
* @retval ACTION_COMPLETED : The operation is completed.
|
||||
*/
|
||||
uint16_t ReadData( uint16_t Offset , uint16_t DataSize , uint8_t* pData )
|
||||
{
|
||||
uint16_t i;
|
||||
switch( nfc_tagtype )
|
||||
{
|
||||
case TT1:
|
||||
if( DataSize > NFCT1_MAX_TAGMEMORY )
|
||||
return NDEF_ERROR_MEMORY_INTERNAL;
|
||||
for( i = Offset; i < (DataSize+Offset); i++ )
|
||||
{
|
||||
if( i == 0 ) // We need the size
|
||||
{
|
||||
/* 2 bytes length */
|
||||
if( TT1Tag[17] == 0xFF )
|
||||
{
|
||||
pData[0] = TT1Tag[18];
|
||||
pData[1] = TT1Tag[19];
|
||||
}
|
||||
/* 1 bytes length */
|
||||
else
|
||||
{
|
||||
pData[0] = 0x00;
|
||||
pData[1] = TT1Tag[17];
|
||||
}
|
||||
i++;
|
||||
}
|
||||
else // We need the NDEF message
|
||||
{
|
||||
/* 2 bytes length */
|
||||
if( TT1Tag[17] == 0xFF )
|
||||
pData[i-Offset] = TT1Tag[18+i];
|
||||
/* 1 bytes length */
|
||||
else
|
||||
pData[i-Offset] = TT1Tag[16+i];
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case TT2:
|
||||
if( DataSize > NFCT2_MAX_TAGMEMORY )
|
||||
return NDEF_ERROR_MEMORY_INTERNAL;
|
||||
for( i = Offset; i < (DataSize+Offset); i++ )
|
||||
{
|
||||
if( i == 0 ) // We need the size
|
||||
{
|
||||
/* 2 bytes length */
|
||||
if( TT2Tag[NFCT2_MAX_CONFIG+NFCT2_MAX_CC_SIZE+1] == 0xFF )
|
||||
{
|
||||
pData[0] = TT2Tag[NFCT2_MAX_CONFIG+NFCT2_MAX_CC_SIZE+2];
|
||||
pData[1] = TT2Tag[NFCT2_MAX_CONFIG+NFCT2_MAX_CC_SIZE+3];
|
||||
}
|
||||
/* 1 bytes length */
|
||||
else
|
||||
{
|
||||
pData[0] = 0x00;
|
||||
pData[1] = TT2Tag[NFCT2_MAX_CONFIG+NFCT2_MAX_CC_SIZE+1];
|
||||
}
|
||||
i++;
|
||||
}
|
||||
else // We need the NDEF message
|
||||
{
|
||||
/* 2 bytes length */
|
||||
if( TT2Tag[NFCT2_MAX_CONFIG+NFCT2_MAX_CC_SIZE+1] == 0xFF )
|
||||
pData[i-Offset] = TT2Tag[NFCT2_MAX_CONFIG+NFCT2_MAX_CC_SIZE+2+i];
|
||||
/* 1 bytes length */
|
||||
else
|
||||
pData[i-Offset] = TT2Tag[NFCT2_MAX_CONFIG+NFCT2_MAX_CC_SIZE+i];
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case TT3:
|
||||
if( DataSize > NFCT3_MAX_TAGMEMORY )
|
||||
return NDEF_ERROR_MEMORY_INTERNAL;
|
||||
for( i = Offset; i < (DataSize+Offset); i++ )
|
||||
{
|
||||
if( i == 0 ) // We need the size
|
||||
{
|
||||
pData[0] = TT3AttribInfo[12];
|
||||
pData[1] = TT3AttribInfo[13];
|
||||
i++;
|
||||
}
|
||||
else
|
||||
{
|
||||
pData[i-Offset] = *(TT3NDEFfile + i - 2);
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case TT4A:
|
||||
if( DataSize > NFCT4A_MAX_NDEFMEMORY )
|
||||
return NDEF_ERROR_MEMORY_INTERNAL;
|
||||
memcpy( pData, &CardNDEFfileT4A[Offset], DataSize );
|
||||
break;
|
||||
|
||||
case TT4B:
|
||||
if( DataSize > NFCT4B_MAX_NDEFMEMORY )
|
||||
return NDEF_ERROR_MEMORY_INTERNAL;
|
||||
memcpy( pData, &CardNDEFfileT4B[Offset], DataSize );
|
||||
break;
|
||||
|
||||
case TT5:
|
||||
if( DataSize > NFCT5_MAX_TAGMEMORY )
|
||||
return NDEF_ERROR_MEMORY_INTERNAL;
|
||||
for( i = Offset; i < (DataSize+Offset); i++ )
|
||||
{
|
||||
if( i == 0 ) // We need the size
|
||||
{
|
||||
/* 2 bytes length */
|
||||
if( TT5Tag[5] == 0xFF )
|
||||
{
|
||||
pData[0] = TT5Tag[6];
|
||||
pData[1] = TT5Tag[7];
|
||||
}
|
||||
/* 1 bytes length */
|
||||
else
|
||||
{
|
||||
pData[0] = 0x00;
|
||||
pData[1] = TT5Tag[5];
|
||||
}
|
||||
i++;
|
||||
}
|
||||
else // We need the NDEF message
|
||||
{
|
||||
/* 2 bytes length */
|
||||
if( TT5Tag[5] == 0xFF )
|
||||
pData[i-Offset] = TT5Tag[6+i];
|
||||
/* 1 bytes length */
|
||||
else
|
||||
pData[i-Offset] = TT5Tag[4+i];
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return NDEF_OK;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief This fonction write data in NDEF file at defined offset.
|
||||
* @param Offset : Offset in the NDEF file.
|
||||
* @param DataSize : Number of byte to write.
|
||||
* @param pData : pointer on buffer to copy.
|
||||
* @retval ACTION_COMPLETED : The operation is completed.
|
||||
*/
|
||||
uint16_t WriteData( uint16_t Offset, uint32_t DataSize, uint8_t* pData )
|
||||
{
|
||||
uint16_t index = 0, i, sum = 0;
|
||||
switch( nfc_tagtype )
|
||||
{
|
||||
case TT1:
|
||||
if( DataSize > NFCT1_MAX_TAGMEMORY )
|
||||
return NDEF_ERROR_MEMORY_INTERNAL;
|
||||
index = Offset + 14;
|
||||
DataSize -= 2;
|
||||
/* Write the NDEF TLV [0x03 length message] */
|
||||
TT1Tag[index++] = 0x03;
|
||||
/* Size can be stored in one byte or 3 bytes depending on the length */
|
||||
if( DataSize < 255 )
|
||||
{
|
||||
TT1Tag[index++] = DataSize;
|
||||
}
|
||||
else
|
||||
{
|
||||
TT1Tag[index++] = 0xFF;
|
||||
TT1Tag[index++] = ( DataSize&0x0000FF00 ) >> 8;
|
||||
TT1Tag[index++] = DataSize & 0x000000FF;
|
||||
}
|
||||
memcpy( &(TT1Tag[index]), pData+2, DataSize );
|
||||
/* Write the terminating TLV [0xFE] */
|
||||
TT1Tag[index+DataSize] = 0xFE;
|
||||
/* Update the phisical tag if needed */
|
||||
if( devicemode == PCD )
|
||||
return PCDNFCT1_WriteNDEF( );
|
||||
break;
|
||||
|
||||
case TT2:
|
||||
if( DataSize > NFCT2_MAX_TAGMEMORY )
|
||||
return NDEF_ERROR_MEMORY_INTERNAL;
|
||||
index = Offset + NFCT2_MAX_CONFIG + NFCT2_MAX_CC_SIZE;
|
||||
DataSize -= 2;
|
||||
/* Write the NDEF TLV [0x03 length message] */
|
||||
TT2Tag[index++] = 0x03;
|
||||
/* Size can be stored in one byte or 3 bytes depending on the length */
|
||||
if( DataSize < 255 )
|
||||
{
|
||||
TT2Tag[index++] = DataSize;
|
||||
}
|
||||
else
|
||||
{
|
||||
TT2Tag[index++] = 0xFF;
|
||||
TT2Tag[index++] = ( DataSize&0x0000FF00 ) >> 8;
|
||||
TT2Tag[index++] = DataSize & 0x000000FF;
|
||||
}
|
||||
memcpy( &(TT2Tag[index]), pData+2, DataSize );
|
||||
/* Write the terminating TLV [0xFE] */
|
||||
TT2Tag[index+DataSize] = 0xFE;
|
||||
/* Update the phisical tag if needed */
|
||||
if( devicemode == PCD )
|
||||
return PCDNFCT2_WriteNDEF( );
|
||||
else
|
||||
updateFlash = true;
|
||||
break;
|
||||
|
||||
case TT3:
|
||||
if( DataSize > NFCT3_MAX_TAGMEMORY )
|
||||
return NDEF_ERROR_MEMORY_INTERNAL;
|
||||
DataSize -= 2;
|
||||
/* Write the ndef message first */
|
||||
memcpy( TT3NDEFfile, pData+2, DataSize );
|
||||
/* Update AttribInfo */
|
||||
TT3AttribInfo[11] = ( DataSize&0x00FF0000 ) >> 16;
|
||||
TT3AttribInfo[12] = ( DataSize&0x0000FF00 ) >> 8;
|
||||
TT3AttribInfo[13] = DataSize & 0x000000FF;
|
||||
/* Update checksum */
|
||||
for( i = 0; i < 14; i++ )
|
||||
sum += TT3AttribInfo[i];
|
||||
TT3AttribInfo[14] = ( sum&0xFF00 ) >> 8;
|
||||
TT3AttribInfo[15] = sum & 0x00FF;
|
||||
/* Update the phisical tag if needed */
|
||||
if( devicemode == PCD )
|
||||
return PCDNFCT3_WriteNDEF( );
|
||||
else
|
||||
updateFlash = true;
|
||||
break;
|
||||
|
||||
case TT4A:
|
||||
if( DataSize > NFCT4A_MAX_NDEFMEMORY )
|
||||
return NDEF_ERROR_MEMORY_INTERNAL;
|
||||
memcpy( &(CardNDEFfileT4A[Offset]), pData, DataSize );
|
||||
/* Update the phisical tag if needed */
|
||||
if( devicemode == PCD )
|
||||
return PCDNFCT4_WriteNDEF( );
|
||||
else
|
||||
updateFlash = true;
|
||||
break;
|
||||
|
||||
case TT4B:
|
||||
if( DataSize > NFCT4_MAX_NDEFMEMORY )
|
||||
return NDEF_ERROR_MEMORY_INTERNAL;
|
||||
memcpy( &(CardNDEFfileT4B[Offset]), pData, DataSize );
|
||||
/* Update the phisical tag if needed */
|
||||
if( devicemode == PCD )
|
||||
return PCDNFCT4_WriteNDEF( );
|
||||
else
|
||||
updateFlash = true;
|
||||
break;
|
||||
|
||||
case TT5:
|
||||
if( DataSize > NFCT5_MAX_TAGMEMORY )
|
||||
return NDEF_ERROR_MEMORY_INTERNAL;
|
||||
index = 4;
|
||||
DataSize -= 2;
|
||||
/* Write the NDEF TLV [0x03 length message] */
|
||||
TT5Tag[index++] = 0x03;
|
||||
/* Size can be stored in one byte or 3 bytes depending on the length */
|
||||
if( DataSize < 255 )
|
||||
{
|
||||
TT5Tag[index++] = DataSize;
|
||||
}
|
||||
else
|
||||
{
|
||||
TT5Tag[index++] = 0xFF;
|
||||
TT5Tag[index++] = ( DataSize&0x0000FF00 ) >> 8;
|
||||
TT5Tag[index++] = DataSize & 0x000000FF;
|
||||
}
|
||||
memcpy( &(TT5Tag[index]), pData + 2, DataSize );
|
||||
/* Write the terminating TLV [0xFE] */
|
||||
TT5Tag[index+DataSize] = 0xFE;
|
||||
/* Update the phisical tag if needed */
|
||||
if( devicemode == PCD )
|
||||
return PCDNFCT5_WriteNDEF( );
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return NDEF_OK;
|
||||
}
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
//#ifdef __cplusplus
|
||||
//}
|
||||
//#endif
|
||||
|
||||
/******************* (C) COPYRIGHT 2015 STMicroelectronics *****END OF FILE****/
|
||||
613
src/lib_NDEF.cpp
Normal file
613
src/lib_NDEF.cpp
Normal file
@@ -0,0 +1,613 @@
|
||||
/**
|
||||
******************************************************************************
|
||||
* @file lib_NDEF.c
|
||||
* @author MMY Application Team
|
||||
* @version $Revision: 1330 $
|
||||
* @date $Date: 2015-11-05 10:39:11 +0100 (Thu, 05 Nov 2015) $
|
||||
* @brief This file help to manage NDEF file, to parse and identify them.
|
||||
******************************************************************************
|
||||
* @attention
|
||||
*
|
||||
* <h2><center>© COPYRIGHT 2015 STMicroelectronics</center></h2>
|
||||
*
|
||||
* Licensed under ST MYLIBERTY SOFTWARE LICENSE AGREEMENT (the "License");
|
||||
* You may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at:
|
||||
*
|
||||
* http://www.st.com/myliberty
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied,
|
||||
* AND SPECIFICALLY DISCLAIMING THE IMPLIED WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE, AND NON-INFRINGEMENT.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
******************************************************************************
|
||||
*/
|
||||
|
||||
//#ifdef __cplusplus
|
||||
// extern "C" {
|
||||
//#endif
|
||||
|
||||
/* Includes ------------------------------------------------------------------*/
|
||||
#include "lib_NDEF.h"
|
||||
|
||||
/** @addtogroup NFC_libraries
|
||||
* @{
|
||||
* @brief <b>This is the library used to manage the content of the TAG (data)
|
||||
* But also the specific feature of the tag, for instance
|
||||
* password, gpo... </b>
|
||||
*/
|
||||
|
||||
|
||||
/** @addtogroup libNFC_FORUM
|
||||
* @{
|
||||
* @brief This part of the library manage data which follow NFC forum organisation.
|
||||
*/
|
||||
|
||||
/** @defgroup libNDEF_Private_Functions
|
||||
* @{
|
||||
*/
|
||||
|
||||
|
||||
static uint16_t NDEF_IsNDEFPresent( void );
|
||||
static uint16_t NDEF_ParseRecordHeader( sRecordInfo_t *pRecordStruct );
|
||||
static void NDEF_ParseWellKnownType( sRecordInfo_t *pRecordStruct );
|
||||
static void NDEF_ParseMediaType( sRecordInfo_t *pRecordStruct );
|
||||
static void NDEF_ParseForumExternalType( sRecordInfo_t *pRecordStruct );
|
||||
static void NDEF_ParseURI( sRecordInfo_t *pRecordStruct );
|
||||
static void NDEF_ParseSP( sRecordInfo_t *pRecordStruct );
|
||||
static uint16_t NDEF_IdentifySPRecord( sRecordInfo_t *pRecordStruct, uint8_t* pPayload );
|
||||
|
||||
uint8_t NDEF_Buffer [NDEF_MAX_SIZE];
|
||||
|
||||
/* In case of smart Poster composed with different record, 2 records supported so far */
|
||||
sRecordInfo_t SPRecordStruct1, SPRecordStruct2;
|
||||
sRecordInfo_t *SPRecordStructAdd[SP_MAX_RECORD] = { &SPRecordStruct1, &SPRecordStruct2 };
|
||||
|
||||
|
||||
/**
|
||||
* @brief This function check that the tag contain a NDEF message.
|
||||
* @retval NDEF_OK : There is a NDEF file stored in tag.
|
||||
* @retval NDEF_ERROR : No NDEF in the tag.
|
||||
*/
|
||||
static uint16_t NDEF_IsNDEFPresent( void )
|
||||
{
|
||||
uint16_t FileSize;
|
||||
uint8_t uNDEFHeader [0x2];
|
||||
|
||||
/* Check NDEF existence */
|
||||
ReadData( NDEF_SIZE_OFFSET, 2, uNDEFHeader );
|
||||
FileSize = (uint16_t)( (uNDEFHeader[0x00]<<8) | uNDEFHeader[0x01] );
|
||||
|
||||
if( FileSize != 0 )
|
||||
return NDEF_OK;
|
||||
else
|
||||
return NDEF_ERROR;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief This function identify the type of record.
|
||||
* @param pRecordStruct : pointer on the record structure to fill.
|
||||
* @param pPayload : pointer on the payload.
|
||||
* @retval Status : Status of the operation.
|
||||
*/
|
||||
static uint16_t NDEF_IdentifySPRecord( sRecordInfo_t *pRecordStruct, uint8_t* pPayload )
|
||||
{
|
||||
uint16_t status = NDEF_ERROR;
|
||||
uint16_t SizeOfRecordHeader, TypeNbByte, PayloadLengthField, IDLengthField, IDNbByte;
|
||||
|
||||
/* Is ID length field present */
|
||||
if( (*pPayload) & IL_Mask )
|
||||
{
|
||||
IDLengthField = ID_LENGTH_FIELD;
|
||||
}
|
||||
else
|
||||
{
|
||||
IDLengthField = 0;
|
||||
}
|
||||
|
||||
/* it's a SR */
|
||||
if( (*pPayload) & SR_Mask )
|
||||
{
|
||||
TypeNbByte = pPayload[1];
|
||||
PayloadLengthField = 1;
|
||||
if( IDLengthField == ID_LENGTH_FIELD )
|
||||
IDNbByte = pPayload[3];
|
||||
else
|
||||
IDNbByte = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
TypeNbByte = pPayload[1];
|
||||
PayloadLengthField = 4;
|
||||
if( IDLengthField == ID_LENGTH_FIELD )
|
||||
IDNbByte = pPayload[6];
|
||||
else
|
||||
IDNbByte = 0;
|
||||
}
|
||||
|
||||
SizeOfRecordHeader = RECORD_FLAG_FIELD + TYPE_LENGTH_FIELD + PayloadLengthField + IDLengthField + TypeNbByte + IDNbByte;
|
||||
|
||||
/* it's a SR */
|
||||
if( pPayload[0] & SR_Mask )
|
||||
{
|
||||
pRecordStruct->RecordFlags = pPayload[0];
|
||||
pRecordStruct->TypeLength = TypeNbByte;
|
||||
pRecordStruct->PayloadLength3 = 0;
|
||||
pRecordStruct->PayloadLength2 = 0;
|
||||
pRecordStruct->PayloadLength1 = 0;
|
||||
pRecordStruct->PayloadLength0 = pPayload[2];
|
||||
pRecordStruct->IDLength = IDNbByte;
|
||||
memcpy( pRecordStruct->Type, &pPayload[3+IDNbByte], TypeNbByte );
|
||||
memcpy( pRecordStruct->ID, &pPayload[3+IDNbByte+TypeNbByte], IDNbByte );
|
||||
pRecordStruct->PayloadOffset = SizeOfRecordHeader;
|
||||
}
|
||||
else
|
||||
{
|
||||
pRecordStruct->RecordFlags = pPayload[0];
|
||||
pRecordStruct->TypeLength = TypeNbByte;
|
||||
pRecordStruct->PayloadLength3 = pPayload[2];
|
||||
pRecordStruct->PayloadLength2 = pPayload[3];
|
||||
pRecordStruct->PayloadLength1 = pPayload[4];
|
||||
pRecordStruct->PayloadLength0 = pPayload[5];
|
||||
pRecordStruct->IDLength = IDNbByte;
|
||||
memcpy( pRecordStruct->Type, &pPayload[6+IDNbByte], TypeNbByte );
|
||||
memcpy( pRecordStruct->ID, &pPayload[6+IDNbByte+TypeNbByte], IDNbByte );
|
||||
pRecordStruct->PayloadOffset = SizeOfRecordHeader;
|
||||
}
|
||||
|
||||
pRecordStruct->PayloadBufferAdd = (uint32_t)( pPayload + SizeOfRecordHeader );
|
||||
|
||||
status = NDEF_ParseRecordHeader( pRecordStruct );
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief This function parse the record header and dispatch regarding TNF value.
|
||||
* @param pRecordStruct : pointer on the record structure to fill.
|
||||
* @retval NDEF_OK : record identified and structure filled.
|
||||
* @retval NDEF_ERROR : Not supported.
|
||||
*/
|
||||
static uint16_t NDEF_ParseRecordHeader( sRecordInfo_t *pRecordStruct )
|
||||
{
|
||||
uint16_t status = NDEF_OK;
|
||||
|
||||
switch( (pRecordStruct->RecordFlags & TNF_Mask) )
|
||||
{
|
||||
case TNF_WellKnown:
|
||||
NDEF_ParseWellKnownType( pRecordStruct );
|
||||
break;
|
||||
|
||||
case TNF_MediaType:
|
||||
NDEF_ParseMediaType( pRecordStruct );
|
||||
break;
|
||||
|
||||
case TNF_NFCForumExternal:
|
||||
NDEF_ParseForumExternalType( pRecordStruct);
|
||||
break;
|
||||
|
||||
default:
|
||||
/* currently not supported or unknown*/
|
||||
pRecordStruct->NDEF_Type = UNKNOWN_TYPE;
|
||||
status = NDEF_ERROR;
|
||||
}
|
||||
return status;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief This function parse the Well Known type record.
|
||||
* @param pRecordStruct : pointer on the record structure to fill.
|
||||
*/
|
||||
static void NDEF_ParseWellKnownType( sRecordInfo_t *pRecordStruct )
|
||||
{
|
||||
uint8_t* pPayload;
|
||||
|
||||
pPayload = (uint8_t*)( pRecordStruct->PayloadBufferAdd );
|
||||
|
||||
if( !memcmp( &(pRecordStruct->Type), SMART_POSTER_TYPE_STRING, pRecordStruct->TypeLength ) )
|
||||
{
|
||||
/* special case where we have to parse others records */
|
||||
pRecordStruct->NDEF_Type = SMARTPOSTER_TYPE;
|
||||
NDEF_ParseSP( pRecordStruct );
|
||||
}
|
||||
|
||||
else if( !memcmp( &(pRecordStruct->Type), URI_TYPE_STRING, pRecordStruct->TypeLength ) )
|
||||
{
|
||||
/* it's an URI Type check if it's an URL or SMS or ... */
|
||||
/* check identifier */
|
||||
if( *pPayload == URI_ID_0x00 )
|
||||
{
|
||||
NDEF_ParseURI( pRecordStruct );
|
||||
}
|
||||
else if( (*pPayload > URI_ID_0x00) && (*pPayload < URI_RFU) )
|
||||
{
|
||||
/* email special case */
|
||||
if( *pPayload == (uint8_t) URI_ID_0x06 )
|
||||
{
|
||||
pRecordStruct->NDEF_Type = URI_EMAIL_TYPE;
|
||||
}
|
||||
else
|
||||
{
|
||||
pRecordStruct->NDEF_Type = WELL_KNOWN_ABRIDGED_URI_TYPE;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
pRecordStruct->NDEF_Type = UNKNOWN_TYPE;
|
||||
}
|
||||
}
|
||||
|
||||
else if( !memcmp( &(pRecordStruct->Type), TEXT_TYPE_STRING, pRecordStruct->TypeLength ) )
|
||||
{
|
||||
pRecordStruct->NDEF_Type = TEXT_TYPE;
|
||||
}
|
||||
else
|
||||
pRecordStruct->NDEF_Type = UNKNOWN_TYPE;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief This function parse the Media type record.
|
||||
* @param pRecordStruct : pointer on the record structure to fill.
|
||||
*/
|
||||
static void NDEF_ParseMediaType( sRecordInfo_t *pRecordStruct )
|
||||
{
|
||||
if( !memcmp( &(pRecordStruct->Type), VCARD_TYPE_STRING, pRecordStruct->TypeLength ) )
|
||||
pRecordStruct->NDEF_Type = VCARD_TYPE;
|
||||
else if( !memcmp( &(pRecordStruct->Type), XVCARD_TYPE_STRING, pRecordStruct->TypeLength ) )
|
||||
pRecordStruct->NDEF_Type = VCARD_TYPE;
|
||||
else if( !memcmp( &(pRecordStruct->Type), XVCARD2_TYPE_STRING, pRecordStruct->TypeLength ) )
|
||||
pRecordStruct->NDEF_Type = VCARD_TYPE;
|
||||
else
|
||||
pRecordStruct->NDEF_Type = UNKNOWN_TYPE;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief This function parse the Forum External type record.
|
||||
* @param pRecordStruct : pointer on the record structure to fill.
|
||||
*/
|
||||
static void NDEF_ParseForumExternalType( sRecordInfo_t *pRecordStruct )
|
||||
{
|
||||
if( !memcmp( &(pRecordStruct->Type), M24SR_DISCOVERY_APP_STRING, pRecordStruct->TypeLength ) )
|
||||
pRecordStruct->NDEF_Type = M24SR_DISCOVERY_APP_TYPE;
|
||||
else
|
||||
pRecordStruct->NDEF_Type = UNKNOWN_TYPE;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief This function parse the URI type record.
|
||||
* @param pRecordStruct : pointer on the record structure to fill.
|
||||
*/
|
||||
static void NDEF_ParseURI( sRecordInfo_t *pRecordStruct )
|
||||
{
|
||||
uint8_t* pPayload;
|
||||
|
||||
pPayload = (uint8_t*)( pRecordStruct->PayloadBufferAdd );
|
||||
pPayload++; /* to skip URI identifier first URI payload byte */
|
||||
|
||||
if( !memcmp( pPayload, SMS_TYPE_STRING, strlen(SMS_TYPE_STRING) ) )
|
||||
{
|
||||
pRecordStruct->NDEF_Type = URI_SMS_TYPE;
|
||||
}
|
||||
else if( !memcmp( pPayload, GEO_TYPE_STRING, strlen(GEO_TYPE_STRING) ) )
|
||||
{
|
||||
pRecordStruct->NDEF_Type = URI_GEO_TYPE;
|
||||
}
|
||||
else
|
||||
pRecordStruct->NDEF_Type = UNKNOWN_TYPE;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief This function parse the Smart Poster.
|
||||
* @param pRecordStruct : pointer on the record structure to fill.
|
||||
*/
|
||||
static void NDEF_ParseSP( sRecordInfo_t *pRecordStruct )
|
||||
{
|
||||
uint8_t* pPayload;
|
||||
uint32_t PayloadSize = 0;
|
||||
uint32_t SPPayloadSize = 0;
|
||||
uint32_t OffsetInSPPayload = 0;
|
||||
uint32_t RecordPosition = 0;
|
||||
sRecordInfo_t *pSPRecordStruct;
|
||||
|
||||
/* initialize variable with size of the payload and poiter on data */
|
||||
PayloadSize = ((uint32_t)(pRecordStruct->PayloadLength3) << 24) | ((uint32_t)(pRecordStruct->PayloadLength2) << 16) |
|
||||
((uint32_t)(pRecordStruct->PayloadLength1) << 8) | pRecordStruct->PayloadLength0;
|
||||
|
||||
pPayload = (uint8_t*)( pRecordStruct->PayloadBufferAdd );
|
||||
|
||||
pSPRecordStruct = SPRecordStructAdd[0];
|
||||
|
||||
/* Initailize the number of record find in the SP payload */
|
||||
pRecordStruct->NbOfRecordInSPPayload = 0;
|
||||
|
||||
do
|
||||
{
|
||||
pSPRecordStruct = SPRecordStructAdd[RecordPosition];
|
||||
/* identify the record in the SP payload */
|
||||
if( NDEF_IdentifySPRecord( pSPRecordStruct, pPayload ) == NDEF_OK )
|
||||
{
|
||||
/* store add of structure that will contain the other record information */
|
||||
pRecordStruct->NbOfRecordInSPPayload++;
|
||||
pRecordStruct->SPRecordStructAdd[RecordPosition] = pSPRecordStruct;
|
||||
|
||||
/* After SPRecord + First Record check if we are at the end of NDEF file */
|
||||
SPPayloadSize = ((uint32_t)(pSPRecordStruct->PayloadLength3) << 24) | ((uint32_t)(pSPRecordStruct->PayloadLength2) << 16) |
|
||||
((uint32_t)(pSPRecordStruct->PayloadLength1) << 8) | pSPRecordStruct->PayloadLength0;
|
||||
|
||||
OffsetInSPPayload += pSPRecordStruct->PayloadOffset + SPPayloadSize;
|
||||
pPayload += OffsetInSPPayload;
|
||||
}
|
||||
else /* Recommended Action Record for example */
|
||||
{
|
||||
SPPayloadSize = 0;
|
||||
}
|
||||
RecordPosition++;
|
||||
}
|
||||
while( (OffsetInSPPayload < PayloadSize) && RecordPosition<SP_MAX_RECORD); /* there is another record */
|
||||
}
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/** @defgroup libNDEF_Public_Functions
|
||||
* @{
|
||||
*/
|
||||
|
||||
|
||||
/**
|
||||
* @brief This function identify the NDEF message stored in tag.
|
||||
* @param pRecordStruct : Structure to fill with record information.
|
||||
* @param pNDEF : pointer on the NDEF message data.
|
||||
* @retval NDEF_OK : record struct filled.
|
||||
* @retval NDEF_ERROR : record struct not updated.
|
||||
*/
|
||||
uint16_t NDEF_IdentifyNDEF( sRecordInfo_t *pRecordStruct, uint8_t* pNDEF )
|
||||
{
|
||||
uint16_t status = NDEF_ERROR;
|
||||
uint16_t SizeOfRecordHeader, TypeNbByte, PayloadLengthField, IDLengthField, IDNbByte;
|
||||
uint32_t PayloadSize;
|
||||
|
||||
/* check NDEF present */
|
||||
if( NDEF_IsNDEFPresent() != NDEF_OK )
|
||||
{
|
||||
return NDEF_ERROR;
|
||||
}
|
||||
|
||||
/* Analyse record layout */
|
||||
ReadData( FIRST_RECORD_OFFSET, 1, pNDEF );
|
||||
|
||||
/* Is ID length field present */
|
||||
if( (*pNDEF) & IL_Mask )
|
||||
{
|
||||
IDLengthField = ID_LENGTH_FIELD;
|
||||
}
|
||||
else
|
||||
{
|
||||
IDLengthField = 0;
|
||||
}
|
||||
|
||||
/* it's a SR */
|
||||
if( (*pNDEF) & SR_Mask )
|
||||
{
|
||||
/* Analyse short record layout */
|
||||
ReadData( FIRST_RECORD_OFFSET, 4, pNDEF );
|
||||
TypeNbByte = pNDEF[1];
|
||||
PayloadLengthField = 1;
|
||||
if( IDLengthField == ID_LENGTH_FIELD )
|
||||
IDNbByte = pNDEF[3];
|
||||
else
|
||||
IDNbByte = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Analyse normal record layout */
|
||||
ReadData( FIRST_RECORD_OFFSET, 7, pNDEF );
|
||||
TypeNbByte = pNDEF[1];
|
||||
PayloadLengthField = 4;
|
||||
if( IDLengthField == ID_LENGTH_FIELD )
|
||||
IDNbByte = pNDEF[6];
|
||||
else
|
||||
IDNbByte = 0;
|
||||
}
|
||||
|
||||
SizeOfRecordHeader = RECORD_FLAG_FIELD + TYPE_LENGTH_FIELD + PayloadLengthField + IDLengthField + TypeNbByte + IDNbByte;
|
||||
|
||||
/* Read record header */
|
||||
ReadData( FIRST_RECORD_OFFSET, SizeOfRecordHeader, pNDEF );
|
||||
/* it's a SR */
|
||||
if( pNDEF[0] & SR_Mask )
|
||||
{
|
||||
pRecordStruct->RecordFlags = pNDEF[0];
|
||||
pRecordStruct->TypeLength = TypeNbByte;
|
||||
pRecordStruct->PayloadLength3 = 0;
|
||||
pRecordStruct->PayloadLength2 = 0;
|
||||
pRecordStruct->PayloadLength1 = 0;
|
||||
pRecordStruct->PayloadLength0 = pNDEF[2];
|
||||
pRecordStruct->IDLength = IDNbByte;
|
||||
memcpy( pRecordStruct->Type, &pNDEF[3+IDNbByte], TypeNbByte );
|
||||
memcpy( pRecordStruct->ID, &pNDEF[3+IDNbByte+TypeNbByte], IDNbByte );
|
||||
pRecordStruct->PayloadOffset = SizeOfRecordHeader;
|
||||
}
|
||||
else
|
||||
{
|
||||
pRecordStruct->RecordFlags = pNDEF[0];
|
||||
pRecordStruct->TypeLength = TypeNbByte;
|
||||
pRecordStruct->PayloadLength3 = pNDEF[2];
|
||||
pRecordStruct->PayloadLength2 = pNDEF[3];
|
||||
pRecordStruct->PayloadLength1 = pNDEF[4];
|
||||
pRecordStruct->PayloadLength0 = pNDEF[5];
|
||||
pRecordStruct->IDLength = IDNbByte;
|
||||
memcpy( pRecordStruct->Type, &pNDEF[6+IDNbByte], TypeNbByte );
|
||||
memcpy( pRecordStruct->ID, &pNDEF[6+IDNbByte+TypeNbByte], IDNbByte );
|
||||
pRecordStruct->PayloadOffset = SizeOfRecordHeader;
|
||||
}
|
||||
|
||||
PayloadSize = ((uint32_t)(pRecordStruct->PayloadLength3) << 24) | ((uint32_t)(pRecordStruct->PayloadLength2) << 16) |
|
||||
((uint32_t)(pRecordStruct->PayloadLength1) << 8) | pRecordStruct->PayloadLength0;
|
||||
|
||||
/* read Payload */
|
||||
status = ReadData( (uint16_t)((FIRST_RECORD_OFFSET) + pRecordStruct->PayloadOffset) , PayloadSize , pNDEF );
|
||||
|
||||
if( status != NDEF_OK )
|
||||
return NDEF_ERROR;
|
||||
else
|
||||
pRecordStruct->PayloadBufferAdd = (uint32_t)(pNDEF);
|
||||
|
||||
NDEF_ParseRecordHeader( pRecordStruct );
|
||||
|
||||
return NDEF_OK;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief This function read the NDEF content of the TAG.
|
||||
* @param pNDEF : pointer on the buffer to store NDEF data.
|
||||
* @retval NDEF_OK : NDEF file data retrieve and store in the buffer.
|
||||
* @retval NDEF_ERROR : not able to read NDEF from tag.
|
||||
* @retval NDEF_ERROR_MEMORY_INTERNAL : Cannot read tag.
|
||||
* @retval NDEF_ERROR_NOT_FORMATED : CCFile data not supported or not present.
|
||||
* @retval NDEF_ERROR_MEMORY_TAG : Size not compatible with memory.
|
||||
* @retval NDEF_ERROR_LOCKED : Tag locked, cannot be read.
|
||||
*/
|
||||
uint16_t NDEF_ReadNDEF( uint8_t* pNDEF )
|
||||
{
|
||||
uint16_t status = NDEF_ERROR;
|
||||
uint16_t NDEF_Size = 0;
|
||||
|
||||
status = ReadData( 0, 2, pNDEF );
|
||||
|
||||
if( status == NDEF_OK )
|
||||
{
|
||||
NDEF_Size = (uint16_t)(*pNDEF << 8);
|
||||
NDEF_Size = NDEF_Size | (uint16_t)(*++pNDEF );
|
||||
|
||||
status = ReadData( 0, NDEF_Size + 2, --pNDEF );
|
||||
}
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief This function write the NDEF in the TAG.
|
||||
* @param pNDEF : pointer on the buffer containing the NDEF data.
|
||||
* @retval NDEF_OK : NDEF file data written in the tag.
|
||||
* @retval NDEF_ERROR : not able to store NDEF in tag.
|
||||
* @retval NDEF_ERROR_MEMORY_INTERNAL : Cannot write to tag.
|
||||
* @retval NDEF_ERROR_NOT_FORMATED : CCFile data not supported or not present.
|
||||
* @retval NDEF_ERROR_MEMORY_TAG : Size not compatible with memory.
|
||||
* @retval NDEF_ERROR_LOCKED : Tag locked, cannot be write.
|
||||
*/
|
||||
uint16_t NDEF_WriteNDEF( uint8_t *pNDEF )
|
||||
{
|
||||
uint16_t status = NDEF_ERROR;
|
||||
uint16_t NDEF_Size = 0;
|
||||
|
||||
NDEF_Size = (uint16_t)(*pNDEF << 8);
|
||||
NDEF_Size = NDEF_Size | (uint16_t)(*++pNDEF );
|
||||
|
||||
status = WriteData( 0, NDEF_Size + 2, --pNDEF );
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief This function identify the NDEF message stored in tag.
|
||||
* @param pRecordStruct : Structure to fill with record information.
|
||||
* @param pNDEF : pointer on the NDEF message data.
|
||||
* @retval NDEF_OK : record struct filled.
|
||||
* @retval NDEF_ERROR : record struct not updated.
|
||||
*/
|
||||
uint16_t NDEF_IdentifyBuffer( sRecordInfo_t *pRecordStruct, uint8_t* pNDEF )
|
||||
{
|
||||
uint16_t SizeOfRecordHeader, TypeNbByte, PayloadLengthField, IDLengthField, IDNbByte;
|
||||
|
||||
/* Is ID length field present */
|
||||
if( (*pNDEF) & IL_Mask )
|
||||
{
|
||||
IDLengthField = ID_LENGTH_FIELD;
|
||||
}
|
||||
else
|
||||
{
|
||||
IDLengthField = 0;
|
||||
}
|
||||
|
||||
/* it's a SR */
|
||||
if( (*pNDEF) & SR_Mask )
|
||||
{
|
||||
/* Analyse short record layout */
|
||||
TypeNbByte = pNDEF[1];
|
||||
PayloadLengthField = 1;
|
||||
if( IDLengthField == ID_LENGTH_FIELD )
|
||||
IDNbByte = pNDEF[3];
|
||||
else
|
||||
IDNbByte = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Analyse normal record layout */
|
||||
TypeNbByte = pNDEF[1];
|
||||
PayloadLengthField = 4;
|
||||
if( IDLengthField == ID_LENGTH_FIELD )
|
||||
IDNbByte = pNDEF[6];
|
||||
else
|
||||
IDNbByte = 0;
|
||||
}
|
||||
|
||||
SizeOfRecordHeader = RECORD_FLAG_FIELD + TYPE_LENGTH_FIELD + PayloadLengthField + IDLengthField + TypeNbByte + IDNbByte;
|
||||
|
||||
/* it's a SR */
|
||||
if( pNDEF[0] & SR_Mask )
|
||||
{
|
||||
pRecordStruct->RecordFlags = pNDEF[0];
|
||||
pRecordStruct->TypeLength = TypeNbByte;
|
||||
pRecordStruct->PayloadLength3 = 0;
|
||||
pRecordStruct->PayloadLength2 = 0;
|
||||
pRecordStruct->PayloadLength1 = 0;
|
||||
pRecordStruct->PayloadLength0 = pNDEF[2];
|
||||
pRecordStruct->IDLength = IDNbByte;
|
||||
memcpy( pRecordStruct->Type, &pNDEF[3+IDNbByte], TypeNbByte );
|
||||
memcpy( pRecordStruct->ID, &pNDEF[3+IDNbByte+TypeNbByte], IDNbByte );
|
||||
pRecordStruct->PayloadOffset = SizeOfRecordHeader;
|
||||
}
|
||||
else
|
||||
{
|
||||
pRecordStruct->RecordFlags = pNDEF[0];
|
||||
pRecordStruct->TypeLength = TypeNbByte;
|
||||
pRecordStruct->PayloadLength3 = pNDEF[2];
|
||||
pRecordStruct->PayloadLength2 = pNDEF[3];
|
||||
pRecordStruct->PayloadLength1 = pNDEF[4];
|
||||
pRecordStruct->PayloadLength0 = pNDEF[5];
|
||||
pRecordStruct->IDLength = IDNbByte;
|
||||
memcpy( pRecordStruct->Type, &pNDEF[6+IDNbByte], TypeNbByte );
|
||||
memcpy( pRecordStruct->ID, &pNDEF[6+IDNbByte+TypeNbByte], IDNbByte );
|
||||
pRecordStruct->PayloadOffset = SizeOfRecordHeader;
|
||||
}
|
||||
|
||||
pRecordStruct->PayloadBufferAdd = (uint32_t)(&pNDEF[pRecordStruct->PayloadOffset]);
|
||||
|
||||
NDEF_ParseRecordHeader( pRecordStruct );
|
||||
|
||||
return NDEF_OK;
|
||||
}
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
//#ifdef __cplusplus
|
||||
//}
|
||||
//#endif
|
||||
|
||||
/******************* (C) COPYRIGHT 2015 STMicroelectronics *****END OF FILE****/
|
||||
259
src/lib_NDEF.h
Normal file
259
src/lib_NDEF.h
Normal file
@@ -0,0 +1,259 @@
|
||||
/**
|
||||
******************************************************************************
|
||||
* @file lib_NDEF.h
|
||||
* @author MMY Application Team
|
||||
* @version $Revision: 1329 $
|
||||
* @date $Date: 2015-11-05 10:34:25 +0100 (Thu, 05 Nov 2015) $
|
||||
* @brief This file help to manage NDEF file.
|
||||
******************************************************************************
|
||||
* @attention
|
||||
*
|
||||
* <h2><center>© COPYRIGHT 2015 STMicroelectronics</center></h2>
|
||||
*
|
||||
* Licensed under ST MYLIBERTY SOFTWARE LICENSE AGREEMENT (the "License");
|
||||
* You may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at:
|
||||
*
|
||||
* http://www.st.com/myliberty
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied,
|
||||
* AND SPECIFICALLY DISCLAIMING THE IMPLIED WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE, AND NON-INFRINGEMENT.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
******************************************************************************
|
||||
*/
|
||||
|
||||
/* Define to prevent recursive inclusion -------------------------------------*/
|
||||
#ifndef __LIB_NDEF_H
|
||||
#define __LIB_NDEF_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/* Includes ------------------------------------------------------------------*/
|
||||
/* include file which match the HW configuration */
|
||||
#include "common.h"
|
||||
#include "lib_wrapper.h"
|
||||
|
||||
#define NDEF_ACTION_COMPLETED 0x9000
|
||||
|
||||
#ifndef errorchk
|
||||
#define errorchk(fCall) if (status = (fCall), status != NDEF_ACTION_COMPLETED) \
|
||||
{goto Error;} else
|
||||
#endif
|
||||
|
||||
/* Error codes for Higher level */
|
||||
#define NDEF_OK RESULTOK
|
||||
#define NDEF_ERROR ERRORCODE_GENERIC
|
||||
#define NDEF_ERROR_MEMORY_TAG 2
|
||||
#define NDEF_ERROR_MEMORY_INTERNAL 3
|
||||
#define NDEF_ERROR_LOCKED 4
|
||||
#define NDEF_ERROR_NOT_FORMATED 5
|
||||
|
||||
#define NDEF_MAX_SIZE NFC_DEVICE_MAX_NDEFMEMORY
|
||||
|
||||
#define NDEF_SIZE_OFFSET 0
|
||||
#define FIRST_RECORD_OFFSET 2
|
||||
|
||||
#define RECORD_FLAG_FIELD 1
|
||||
#define TYPE_LENGTH_FIELD 1
|
||||
#define ID_LENGTH_FIELD 1
|
||||
|
||||
|
||||
#define MB_Mask ((uint8_t)(0x80))
|
||||
#define ME_Mask ((uint8_t)(0x40))
|
||||
#define CF_Mask ((uint8_t)(0x20))
|
||||
#define SR_Mask ((uint8_t)(0x10))
|
||||
#define IL_Mask ((uint8_t)(0x08))
|
||||
#define TNF_Mask ((uint8_t)(0x07))
|
||||
|
||||
#define TNF_Empty 0x00
|
||||
#define TNF_WellKnown 0x01
|
||||
#define TNF_MediaType 0x02
|
||||
#define TNF_AbsoluteURI 0x03
|
||||
#define TNF_NFCForumExternal 0x04
|
||||
#define TNF_Unknown 0x05
|
||||
#define TNF_Unchanged 0x06
|
||||
#define TNF_Reserved 0x07
|
||||
|
||||
#define SP_MAX_RECORD 2
|
||||
|
||||
#define AAR_TYPE_STRING "android.com:pkg"
|
||||
#define AAR_TYPE_STRING_LENGTH 15
|
||||
|
||||
#define M24SR_DISCOVERY_APP_STRING "st.com:m24sr_discovery_democtrl"
|
||||
#define M24SR_DISCOVERY_APP_STRING_LENGTH 31
|
||||
|
||||
#define VCARD_TYPE_STRING "text/vcard"
|
||||
#define VCARD_TYPE_STRING_LENGTH 10
|
||||
|
||||
#define XVCARD_TYPE_STRING "text/x-vCard"
|
||||
#define XVCARD_TYPE_STRING_LENGTH 12
|
||||
|
||||
#define XVCARD2_TYPE_STRING "text/x-vcard"
|
||||
#define XVCARD2_TYPE_STRING_LENGTH 12
|
||||
|
||||
#define SMART_POSTER_TYPE_STRING "Sp"
|
||||
#define SMART_POSTER_TYPE_STRING_LENGTH 2
|
||||
|
||||
#define URI_TYPE_STRING "U"
|
||||
#define URI_TYPE_STRING_LENGTH 1
|
||||
|
||||
#define SMS_TYPE_STRING "sms:"
|
||||
#define SMS_TYPE_STRING_LENGTH 4
|
||||
|
||||
#define GEO_TYPE_STRING "geo:"
|
||||
#define GEO_TYPE_STRING_LENGTH 4
|
||||
|
||||
#define URI_LATITUDE_END ","
|
||||
#define URI_LATITUDE_END_LENGTH 1
|
||||
|
||||
#define EMAIL_TYPE_STRING "mailto:"
|
||||
#define EMAIL_TYPE_STRING_LENGTH 7
|
||||
|
||||
#define URI_FIRST_DATA_END "?"
|
||||
#define URI_FIRST_DATA_END_LENGTH 1
|
||||
|
||||
#define SUBJECT_BEGIN_STRING "subject="
|
||||
#define SUBJECT_BEGIN_STRING_LENGTH 8
|
||||
|
||||
#define MESSAGE_BEGIN_STRING "body="
|
||||
#define MESSAGE_BEGIN_STRING_LENGTH 5
|
||||
|
||||
#define URI_SECOND_DATA_END "&"
|
||||
#define URI_SECOND_DATA_END_LENGTH 1
|
||||
|
||||
#define TEXT_TYPE_STRING "T"
|
||||
#define TEXT_TYPE_STRING_LENGTH 1
|
||||
|
||||
#define ISO_ENGLISH_CODE_STRING "en"
|
||||
#define ISO_ENGLISH_CODE_STRING_LENGTH 2
|
||||
|
||||
|
||||
#define URI_ID_0x00 0x00
|
||||
#define URI_ID_0x01 0x01
|
||||
#define URI_ID_0x02 0x02
|
||||
#define URI_ID_0x03 0x03
|
||||
#define URI_ID_0x04 0x04
|
||||
#define URI_ID_0x05 0x05
|
||||
#define URI_ID_0x06 0x06
|
||||
#define URI_ID_0x07 0x07
|
||||
#define URI_ID_0x08 0x08
|
||||
#define URI_ID_0x09 0x09
|
||||
#define URI_ID_0x0A 0x0A
|
||||
#define URI_ID_0x0B 0x0B
|
||||
#define URI_ID_0x0C 0x0C
|
||||
#define URI_ID_0x0D 0x0D
|
||||
#define URI_ID_0x0E 0x0E
|
||||
#define URI_ID_0x0F 0x0F
|
||||
#define URI_ID_0x10 0x10
|
||||
#define URI_ID_0x11 0x11
|
||||
#define URI_ID_0x12 0x12
|
||||
#define URI_ID_0x13 0x13
|
||||
#define URI_ID_0x14 0x14
|
||||
#define URI_ID_0x15 0x15
|
||||
#define URI_ID_0x16 0x16
|
||||
#define URI_ID_0x17 0x17
|
||||
#define URI_ID_0x18 0x18
|
||||
#define URI_ID_0x19 0x19
|
||||
#define URI_ID_0x1A 0x1A
|
||||
#define URI_ID_0x1B 0x1B
|
||||
#define URI_ID_0x1C 0x1C
|
||||
#define URI_ID_0x1D 0x1D
|
||||
#define URI_ID_0x1E 0x1E
|
||||
#define URI_ID_0x1F 0x1F
|
||||
#define URI_ID_0x20 0x20
|
||||
#define URI_ID_0x21 0x21
|
||||
#define URI_ID_0x22 0x22
|
||||
#define URI_ID_0x23 0x23
|
||||
#define URI_RFU 0x24
|
||||
|
||||
#define URI_ID_0x01_STRING "http://www.\0"
|
||||
#define URI_ID_0x02_STRING "https://www.\0"
|
||||
#define URI_ID_0x03_STRING "http://\0"
|
||||
#define URI_ID_0x04_STRING "https://\0"
|
||||
#define URI_ID_0x05_STRING "tel:\0"
|
||||
#define URI_ID_0x06_STRING "mailto:\0"
|
||||
#define URI_ID_0x07_STRING "ftp://anonymous:anonymous@\0"
|
||||
#define URI_ID_0x08_STRING "ftp://ftp.\0"
|
||||
#define URI_ID_0x09_STRING "ftps://\0"
|
||||
#define URI_ID_0x0A_STRING "sftp://\0"
|
||||
#define URI_ID_0x0B_STRING "smb://\0"
|
||||
#define URI_ID_0x0C_STRING "nfs://\0"
|
||||
#define URI_ID_0x0D_STRING "ftp://\0"
|
||||
#define URI_ID_0x0E_STRING "dav://\0"
|
||||
#define URI_ID_0x0F_STRING "news:\0"
|
||||
#define URI_ID_0x10_STRING "telnet://\0"
|
||||
#define URI_ID_0x11_STRING "imap:\0"
|
||||
#define URI_ID_0x12_STRING "rtsp://\0"
|
||||
#define URI_ID_0x13_STRING "urn:\0"
|
||||
#define URI_ID_0x14_STRING "pop:\0"
|
||||
#define URI_ID_0x15_STRING "sip:\0"
|
||||
#define URI_ID_0x16_STRING "sips:\0"
|
||||
#define URI_ID_0x17_STRING "tftp:\0"
|
||||
#define URI_ID_0x18_STRING "btspp://\0"
|
||||
#define URI_ID_0x19_STRING "btl2cap://\0"
|
||||
#define URI_ID_0x1A_STRING "btgoep://\0"
|
||||
#define URI_ID_0x1B_STRING "tcpobex://\0"
|
||||
#define URI_ID_0x1C_STRING "irdaobex://\0"
|
||||
#define URI_ID_0x1D_STRING "file://\0"
|
||||
#define URI_ID_0x1E_STRING "urn:epc:id:\0"
|
||||
#define URI_ID_0x1F_STRING "urn:epc:tag\0"
|
||||
#define URI_ID_0x20_STRING "urn:epc:pat:\0"
|
||||
#define URI_ID_0x21_STRING "urn:epc:raw:\0"
|
||||
#define URI_ID_0x22_STRING "urn:epc:\0"
|
||||
#define URI_ID_0x23_STRING "urn:nfc:\0"
|
||||
|
||||
typedef enum
|
||||
{
|
||||
UNKNOWN_TYPE = 0,
|
||||
VCARD_TYPE,
|
||||
WELL_KNOWN_ABRIDGED_URI_TYPE,
|
||||
URI_SMS_TYPE,
|
||||
URI_GEO_TYPE,
|
||||
URI_EMAIL_TYPE,
|
||||
SMARTPOSTER_TYPE,
|
||||
URL_TYPE,
|
||||
TEXT_TYPE,
|
||||
BT_TYPE,
|
||||
/* list of "external type" known by this demo, other external type will be addressed as UNKNWON_TYPE */
|
||||
M24SR_DISCOVERY_APP_TYPE
|
||||
} NDEF_TypeDef;
|
||||
|
||||
typedef struct sRecordInfo sRecordInfo_t;
|
||||
struct sRecordInfo
|
||||
{
|
||||
uint8_t RecordFlags;
|
||||
uint8_t TypeLength;
|
||||
uint8_t PayloadLength3;
|
||||
uint8_t PayloadLength2;
|
||||
uint8_t PayloadLength1;
|
||||
uint8_t PayloadLength0;
|
||||
uint8_t IDLength;
|
||||
uint8_t Type[0xFF];
|
||||
uint8_t ID[0xFF];
|
||||
uint16_t PayloadOffset;
|
||||
uint32_t PayloadBufferAdd; /* add where payload content has been stored */
|
||||
NDEF_TypeDef NDEF_Type; /* to store identification ID for application */
|
||||
sRecordInfo_t *SPRecordStructAdd[SP_MAX_RECORD]; /*in case of smart poster array to store add of other sRecordInfo struct */
|
||||
uint8_t NbOfRecordInSPPayload;
|
||||
};
|
||||
|
||||
|
||||
uint16_t NDEF_IdentifyNDEF( sRecordInfo_t *pRecordStruct, uint8_t* pNDEF );
|
||||
uint16_t NDEF_IdentifyBuffer( sRecordInfo_t *pRecordStruct, uint8_t* pNDEF );
|
||||
uint16_t NDEF_ReadNDEF( uint8_t *pNDEF );
|
||||
uint16_t NDEF_WriteNDEF( uint8_t *pNDEF );
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
#endif /* __LIB_NDEF_H */
|
||||
|
||||
|
||||
/******************* (C) COPYRIGHT 2015 STMicroelectronics *****END OF FILE****/
|
||||
188
src/lib_NDEF_AAR.cpp
Normal file
188
src/lib_NDEF_AAR.cpp
Normal file
@@ -0,0 +1,188 @@
|
||||
/**
|
||||
******************************************************************************
|
||||
* @file lib_NDEF_AAR.c
|
||||
* @author MMY Application Team
|
||||
* @version $Revision: 1330 $
|
||||
* @date $Date: 2015-11-05 10:39:11 +0100 (Thu, 05 Nov 2015) $
|
||||
* @brief This file help to add AAR to NDEF file.
|
||||
******************************************************************************
|
||||
* @attention
|
||||
*
|
||||
* <h2><center>© COPYRIGHT 2015 STMicroelectronics</center></h2>
|
||||
*
|
||||
* Licensed under ST MYLIBERTY SOFTWARE LICENSE AGREEMENT (the "License");
|
||||
* You may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at:
|
||||
*
|
||||
* http://www.st.com/myliberty
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied,
|
||||
* AND SPECIFICALLY DISCLAIMING THE IMPLIED WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE, AND NON-INFRINGEMENT.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
******************************************************************************
|
||||
*/
|
||||
|
||||
//#ifdef __cplusplus
|
||||
// extern "C" {
|
||||
//#endif
|
||||
|
||||
/* Includes ------------------------------------------------------------------*/
|
||||
#include "lib_NDEF_AAR.h"
|
||||
|
||||
/** @addtogroup NFC_libraries
|
||||
* @{
|
||||
* @brief <b>This is the library used to manage the content of the TAG (data)
|
||||
* But also the specific feature of the tag, for instance
|
||||
* password, gpo... </b>
|
||||
*/
|
||||
|
||||
|
||||
/** @addtogroup libNFC_FORUM
|
||||
* @{
|
||||
* @brief This part of the library manage data which follow NFC forum organisation.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @brief This buffer contains the data send/received by TAG
|
||||
*/
|
||||
extern uint8_t NDEF_Buffer [];
|
||||
|
||||
/** @defgroup libAAR_Private_Functions
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/** @defgroup libAAR_Public_Functions
|
||||
* @{
|
||||
* @brief This file is used to manage AAR (stored or loaded in tag)
|
||||
*/
|
||||
|
||||
|
||||
/**
|
||||
* @brief This function add AAR (Android Application Record) in the tag.
|
||||
* @param pAARStruct : pointer on structure that contain AAR information.
|
||||
* @retval NDEF_OK : AAR added.
|
||||
* @retval NDEF_ERROR : not able to store NDEF in tag.
|
||||
* @retval NDEF_ERROR_MEMORY_INTERNAL : Cannot write to tag.
|
||||
* @retval NDEF_ERROR_NOT_FORMATED : CCFile data not supported or not present.
|
||||
* @retval NDEF_ERROR_MEMORY_TAG : Size not compatible with memory.
|
||||
* @retval NDEF_ERROR_LOCKED : Tag locked, cannot be write.
|
||||
*/
|
||||
uint16_t NDEF_AddAAR( sAARInfo *pAARStruct )
|
||||
{
|
||||
uint16_t status = NDEF_ERROR;
|
||||
uint16_t DataSize = 0;
|
||||
uint16_t Offset = 0;
|
||||
uint32_t AAROffset = 0;
|
||||
uint16_t NDEF_Size = 0;
|
||||
uint8_t RecordFlag = 0;
|
||||
uint8_t AARRecordFlag = 0;
|
||||
|
||||
/* AAR: External Type Record Header */
|
||||
/************************************/
|
||||
/* 7 | 6 | 5 | 4 | 3 | 2 1 0 */
|
||||
/*----------------------------------*/
|
||||
/* MB ME CF SR IL TNF */ /* <---- IL=0, CF=0 and SR=1 TNF=4 NFC Forum external type*/
|
||||
/*----------------------------------*/
|
||||
/* TYPE LENGTH */
|
||||
/*----------------------------------*/
|
||||
/* PAYLOAD LENGTH 3 */ /* <---- Not Used */
|
||||
/*----------------------------------*/
|
||||
/* PAYLOAD LENGTH 2 */ /* <---- Not Used */
|
||||
/*----------------------------------*/
|
||||
/* PAYLOAD LENGTH 1 */ /* <---- Not Used */
|
||||
/*----------------------------------*/
|
||||
/* PAYLOAD LENGTH 0 */
|
||||
/*----------------------------------*/
|
||||
/* ID LENGTH */ /* <---- Not Used */
|
||||
/*----------------------------------*/
|
||||
/* TYPE */ /* android.com:pkg */
|
||||
/*----------------------------------*/
|
||||
/* ID */ /* <---- Not Used */
|
||||
/************************************/
|
||||
|
||||
/* Do we have to add AAR to an existing NDEF message */
|
||||
/* retrieve current NDEF size and current record flag*/
|
||||
status = ReadData( 0, 3, NDEF_Buffer );
|
||||
|
||||
if( status == NDEF_OK )
|
||||
{
|
||||
NDEF_Size = (uint16_t)(NDEF_Buffer[0] << 8);
|
||||
NDEF_Size = NDEF_Size | (uint16_t)(NDEF_Buffer[1]);
|
||||
RecordFlag = NDEF_Buffer[2];
|
||||
}
|
||||
|
||||
if( NDEF_Size != 0 )
|
||||
{
|
||||
AAROffset = NDEF_Size + 2;
|
||||
RecordFlag &= 0xBF; /* remove ME flag on NDEF */
|
||||
AARRecordFlag = 0x54; /* don't put MB flag */
|
||||
}
|
||||
else
|
||||
{
|
||||
AAROffset = 2;
|
||||
AARRecordFlag = 0xD4; /* put MB and ME flag */
|
||||
}
|
||||
|
||||
/* fill AAR record header */
|
||||
Offset = 0;
|
||||
NDEF_Buffer[Offset++] = AARRecordFlag; /* Record Flag */
|
||||
NDEF_Buffer[Offset++] = AAR_TYPE_STRING_LENGTH;
|
||||
NDEF_Buffer[Offset++] = 0x00; /* Will be filled at the end when payload size is known */
|
||||
|
||||
memcpy( &NDEF_Buffer[Offset], AAR_TYPE_STRING, AAR_TYPE_STRING_LENGTH );
|
||||
|
||||
/* fill AAR payload */
|
||||
memcpy( &NDEF_Buffer[Offset + AAR_TYPE_STRING_LENGTH], pAARStruct->PakageName, strlen(pAARStruct->PakageName) );
|
||||
|
||||
NDEF_Buffer[2] = strlen( pAARStruct->PakageName );
|
||||
|
||||
DataSize = Offset + AAR_TYPE_STRING_LENGTH + strlen( pAARStruct->PakageName );
|
||||
|
||||
/* Write NDEF */
|
||||
status = WriteData( AAROffset, DataSize, NDEF_Buffer );
|
||||
|
||||
/* Write NDEF size to complete*/
|
||||
if( status == NDEF_OK )
|
||||
{
|
||||
DataSize = NDEF_Size + DataSize; /* Must add to the NDEF size the size of the AAR record*/
|
||||
NDEF_Buffer[0] = (DataSize & 0xFF00) >> 8;
|
||||
NDEF_Buffer[1] = DataSize & 0x00FF;
|
||||
if( NDEF_Size != 0 )
|
||||
{
|
||||
NDEF_Buffer[2] = RecordFlag;
|
||||
status = WriteData( 0x00, 3, NDEF_Buffer );
|
||||
}
|
||||
else
|
||||
status = WriteData( 0x00, 2, NDEF_Buffer );
|
||||
}
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
//#ifdef __cplusplus
|
||||
//}
|
||||
//#endif
|
||||
|
||||
/******************* (C) COPYRIGHT 2015 STMicroelectronics *****END OF FILE****/
|
||||
57
src/lib_NDEF_AAR.h
Normal file
57
src/lib_NDEF_AAR.h
Normal file
@@ -0,0 +1,57 @@
|
||||
/**
|
||||
******************************************************************************
|
||||
* @file lib_NDEF_AAR.h
|
||||
* @author MMY Application Team
|
||||
* @version $Revision: 1329 $
|
||||
* @date $Date: 2015-11-05 10:34:25 +0100 (Thu, 05 Nov 2015) $
|
||||
* @brief This file help to manage AAR.
|
||||
******************************************************************************
|
||||
* @attention
|
||||
*
|
||||
* <h2><center>© COPYRIGHT 2015 STMicroelectronics</center></h2>
|
||||
*
|
||||
* Licensed under ST MYLIBERTY SOFTWARE LICENSE AGREEMENT (the "License");
|
||||
* You may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at:
|
||||
*
|
||||
* http://www.st.com/myliberty
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied,
|
||||
* AND SPECIFICALLY DISCLAIMING THE IMPLIED WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE, AND NON-INFRINGEMENT.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
******************************************************************************
|
||||
*/
|
||||
|
||||
/* Define to prevent recursive inclusion -------------------------------------*/
|
||||
#ifndef __LIB_NDEF_AAR_H
|
||||
#define __LIB_NDEF_AAR_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/* Includes ------------------------------------------------------------------*/
|
||||
#include "lib_NDEF.h"
|
||||
|
||||
typedef struct
|
||||
{
|
||||
char PakageName[80];
|
||||
}sAARInfo;
|
||||
|
||||
/* Struct defined in lib_NDEF.h */
|
||||
typedef struct sRecordInfo sRecordInfo_AAR;
|
||||
|
||||
uint16_t NDEF_AddAAR( sAARInfo *pAARStruct );
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* __LIB_NDEF_AAR_H */
|
||||
|
||||
/******************* (C) COPYRIGHT 2015 STMicroelectronics *****END OF FILE****/
|
||||
413
src/lib_NDEF_Email.cpp
Normal file
413
src/lib_NDEF_Email.cpp
Normal file
@@ -0,0 +1,413 @@
|
||||
/**
|
||||
******************************************************************************
|
||||
* @file lib_NDEF_Email.c
|
||||
* @author MMY Application Team
|
||||
* @version $Revision: 1330 $
|
||||
* @date $Date: 2015-11-05 10:39:11 +0100 (Thu, 05 Nov 2015) $
|
||||
* @brief This file help to manage NDEF file that represent Email.
|
||||
******************************************************************************
|
||||
* @attention
|
||||
*
|
||||
* <h2><center>© COPYRIGHT 2015 STMicroelectronics</center></h2>
|
||||
*
|
||||
* Licensed under ST MYLIBERTY SOFTWARE LICENSE AGREEMENT (the "License");
|
||||
* You may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at:
|
||||
*
|
||||
* http://www.st.com/myliberty
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied,
|
||||
* AND SPECIFICALLY DISCLAIMING THE IMPLIED WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE, AND NON-INFRINGEMENT.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
******************************************************************************
|
||||
*/
|
||||
|
||||
//#ifdef __cplusplus
|
||||
// extern "C" {
|
||||
//#endif
|
||||
|
||||
/* Includes ------------------------------------------------------------------*/
|
||||
#include "lib_NDEF_Email.h"
|
||||
|
||||
/** @addtogroup NFC_libraries
|
||||
* @{
|
||||
* @brief <b>This is the library used to manage the content of the TAG (data)
|
||||
* But also the specific feature of the tag, for instance
|
||||
* password, gpo... </b>
|
||||
*/
|
||||
|
||||
|
||||
/** @addtogroup libNFC_FORUM
|
||||
* @{
|
||||
* @brief This part of the library manage data which follow NFC forum organisation.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @brief This buffer contains the data send/received by TAG
|
||||
*/
|
||||
extern uint8_t NDEF_Buffer [];
|
||||
|
||||
|
||||
/** @defgroup libEmail_Private_Functions
|
||||
* @{
|
||||
*/
|
||||
|
||||
|
||||
static void NDEF_FillEmailStruct( uint8_t* pPayload, uint32_t PayloadSize, sEmailInfo *pEmailStruct );
|
||||
static void NDEF_ReadURI_Email( sRecordInfo_email *pRecordStruct, sEmailInfo *pEmailStruct );
|
||||
|
||||
/**
|
||||
* @brief This function fill Email structure with information of NDEF message
|
||||
* @param pPayload : pointer on the payload data of the NDEF message
|
||||
* @param PayloadSize : number of data in the payload
|
||||
* @param pEmailStruct : pointer on the structure to fill
|
||||
* @retval NONE
|
||||
*/
|
||||
static void NDEF_FillEmailStruct( uint8_t* pPayload, uint32_t PayloadSize, sEmailInfo *pEmailStruct )
|
||||
{
|
||||
uint8_t* pLastByteAdd, *pLook4Word, *pEndString;
|
||||
uint32_t SizeOfKeyWord = 0;
|
||||
|
||||
pEndString = 0;
|
||||
|
||||
/* First character force to NULL in case not matching found */
|
||||
*pEmailStruct->EmailAdd = 0;
|
||||
*pEmailStruct->Subject = 0;
|
||||
*pEmailStruct->Message = 0;
|
||||
|
||||
/* Interesting information are stored before picture if any */
|
||||
/* Moreover picture is not used in this demonstration SW */
|
||||
pLastByteAdd = (uint8_t*)(pPayload + PayloadSize);
|
||||
|
||||
/* first byte should be the "mailto:" well know URI type, skip it */
|
||||
pLook4Word = ++pPayload;
|
||||
|
||||
/* Retrieve email add */
|
||||
if( pLook4Word != pLastByteAdd )
|
||||
{
|
||||
pEndString = pLook4Word;
|
||||
while( memcmp( pEndString, URI_FIRST_DATA_END, URI_FIRST_DATA_END_LENGTH ) && (pEndString < pLastByteAdd) )
|
||||
{
|
||||
pEndString++;
|
||||
}
|
||||
if( ( !memcmp( pEndString, URI_FIRST_DATA_END, URI_FIRST_DATA_END_LENGTH ) ) || (pEndString == pLastByteAdd) )
|
||||
{
|
||||
memcpy( pEmailStruct->EmailAdd, pLook4Word, pEndString-pLook4Word);
|
||||
/* add end of string character */
|
||||
pEmailStruct->EmailAdd[pEndString-pLook4Word] = 0;
|
||||
}
|
||||
}
|
||||
|
||||
pEndString += URI_FIRST_DATA_END_LENGTH;
|
||||
pLook4Word = pEndString;
|
||||
|
||||
/* check if e-mail subject is present */
|
||||
if( !memcmp( pLook4Word, SUBJECT_BEGIN_STRING, SUBJECT_BEGIN_STRING_LENGTH ) )
|
||||
{
|
||||
SizeOfKeyWord = SUBJECT_BEGIN_STRING_LENGTH;
|
||||
|
||||
/* Retrieve subject */
|
||||
if( pLook4Word != pLastByteAdd )
|
||||
{
|
||||
pLook4Word += SizeOfKeyWord;
|
||||
pEndString = pLook4Word;
|
||||
while( memcmp( pEndString, URI_SECOND_DATA_END, URI_SECOND_DATA_END_LENGTH ) && (pEndString < pLastByteAdd) )
|
||||
{
|
||||
pEndString++;
|
||||
}
|
||||
if( ( !memcmp( pEndString, URI_SECOND_DATA_END, URI_SECOND_DATA_END_LENGTH ) ) || (pEndString == pLastByteAdd) )
|
||||
{
|
||||
memcpy( pEmailStruct->Subject, pLook4Word, pEndString-pLook4Word );
|
||||
/* add end of string character */
|
||||
pEmailStruct->Subject[pEndString-pLook4Word] = 0;
|
||||
}
|
||||
pEndString += URI_SECOND_DATA_END_LENGTH;
|
||||
}
|
||||
}
|
||||
|
||||
pLook4Word = pEndString;
|
||||
|
||||
/* check if e-mail message is present */
|
||||
if( !memcmp( pLook4Word, MESSAGE_BEGIN_STRING, MESSAGE_BEGIN_STRING_LENGTH ) )
|
||||
{
|
||||
pEndString += MESSAGE_BEGIN_STRING_LENGTH;
|
||||
/* Retrieve message */
|
||||
memcpy( pEmailStruct->Message, pEndString, PayloadSize - (pEndString - pPayload + 1) );
|
||||
/* add end of string character */
|
||||
pEmailStruct->Message[PayloadSize-(pEndString-pPayload+1)] = 0;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief This function read the Email and store data in a structure.
|
||||
* @param pRecordStruct : Pointer on the record structure.
|
||||
* @param pEmailStruct : pointer on the structure to fill.
|
||||
*/
|
||||
static void NDEF_ReadURI_Email( sRecordInfo_email *pRecordStruct, sEmailInfo *pEmailStruct )
|
||||
{
|
||||
uint8_t* pPayload;
|
||||
uint32_t PayloadSize;
|
||||
|
||||
PayloadSize = ((uint32_t)(pRecordStruct->PayloadLength3) << 24) | ((uint32_t)(pRecordStruct->PayloadLength2) << 16) |
|
||||
((uint32_t)(pRecordStruct->PayloadLength1) << 8) | pRecordStruct->PayloadLength0;
|
||||
|
||||
/* Read record header */
|
||||
pPayload = (uint8_t*)(pRecordStruct->PayloadBufferAdd);
|
||||
|
||||
if( pRecordStruct->NDEF_Type == URI_EMAIL_TYPE )
|
||||
NDEF_FillEmailStruct( pPayload , PayloadSize, pEmailStruct );
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/** @defgroup libEmail_Public_Functions
|
||||
* @{
|
||||
* @brief This file is used to manage Email (stored or loaded in tag)
|
||||
*/
|
||||
|
||||
/**
|
||||
* @brief This function read NDEF and retrieve Eamil information if any.
|
||||
* @param pRecordStruct : Pointer on the record structure.
|
||||
* @param pEmailStruct : pointer on the structure to fill .
|
||||
* @retval NDEF_OK : Email information from NDEF have been retrieved.
|
||||
* @retval NDEF_ERROR : not able to read NDEF in tag.
|
||||
*/
|
||||
uint16_t NDEF_ReadEmail( sRecordInfo_email *pRecordStruct, sEmailInfo *pEmailStruct )
|
||||
{
|
||||
uint16_t status = NDEF_ERROR;
|
||||
sRecordInfo_email *pSPRecordStruct;
|
||||
uint32_t PayloadSize, RecordPosition;
|
||||
uint8_t* pData;
|
||||
|
||||
|
||||
if( pRecordStruct->NDEF_Type == URI_EMAIL_TYPE )
|
||||
{
|
||||
NDEF_ReadURI_Email( pRecordStruct, pEmailStruct );
|
||||
status = NDEF_OK;
|
||||
}
|
||||
else if( pRecordStruct->NDEF_Type == SMARTPOSTER_TYPE )
|
||||
{
|
||||
for( RecordPosition = 0; RecordPosition < pRecordStruct->NbOfRecordInSPPayload; RecordPosition++ )
|
||||
{
|
||||
pSPRecordStruct = pRecordStruct->SPRecordStructAdd[RecordPosition];
|
||||
if( pSPRecordStruct->NDEF_Type == URI_EMAIL_TYPE )
|
||||
{
|
||||
NDEF_ReadURI_Email( pSPRecordStruct, pEmailStruct );
|
||||
status = NDEF_OK;
|
||||
}
|
||||
if( pSPRecordStruct->NDEF_Type == TEXT_TYPE )
|
||||
{
|
||||
PayloadSize = ((uint32_t)(pSPRecordStruct->PayloadLength3) << 24) | ((uint32_t)(pSPRecordStruct->PayloadLength2) << 16) |
|
||||
((uint32_t)(pSPRecordStruct->PayloadLength1) << 8) | pSPRecordStruct->PayloadLength0;
|
||||
|
||||
/* The instruction content the UTF-8 language code that is not used here */
|
||||
pData = (uint8_t*)pSPRecordStruct->PayloadBufferAdd;
|
||||
PayloadSize -= *pData + 1; /* remove not usefull data */
|
||||
pData += *pData + 1;
|
||||
|
||||
memcpy( pEmailStruct->Information, pData, PayloadSize );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief This function write the NDEF file with the Email data given in the structure.
|
||||
* @param pEmailStruct : pointer on structure that contain the Email information.
|
||||
* @retval NDEF_OK : the function is successful.
|
||||
* @retval NDEF_ERROR : not able to store NDEF in tag.
|
||||
* @retval NDEF_ERROR_MEMORY_INTERNAL : Cannot write to tag.
|
||||
* @retval NDEF_ERROR_NOT_FORMATED : CCFile data not supported or not present.
|
||||
* @retval NDEF_ERROR_MEMORY_TAG : Size not compatible with memory.
|
||||
* @retval NDEF_ERROR_LOCKED : Tag locked, cannot be write.
|
||||
*/
|
||||
uint16_t NDEF_WriteEmail( sEmailInfo *pEmailStruct )
|
||||
{
|
||||
uint16_t status = NDEF_ERROR, Offset = 0;
|
||||
|
||||
NDEF_PrepareEmailMessage( pEmailStruct, &NDEF_Buffer[FIRST_RECORD_OFFSET], &Offset );
|
||||
|
||||
/* Write NDEF */
|
||||
NDEF_Buffer[0] = (Offset & 0xFF00) >> 8;
|
||||
NDEF_Buffer[1] = (Offset & 0x00FF);
|
||||
|
||||
status = WriteData( 0x00, Offset + FIRST_RECORD_OFFSET, NDEF_Buffer );
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief This function write the NDEF file with the Email data given in the structure.
|
||||
* @param pEmailStruct : pointer on structure that contain the Email information.
|
||||
* @param pNDEFMessage : pointer on the NDEF message.
|
||||
* @param size : to store the size of the NDEF message generated.
|
||||
*/
|
||||
void NDEF_PrepareEmailMessage( sEmailInfo *pEmailStruct, uint8_t *pNDEFMessage, uint16_t *size )
|
||||
{
|
||||
uint16_t Offset = 0;
|
||||
uint32_t emailSize = 0;
|
||||
uint32_t infoSize = 0;
|
||||
uint32_t totalSize = 0;
|
||||
|
||||
/* Email is an URI but can be included in a smart poster to add text to give instruction to user for instance */
|
||||
|
||||
/* Email (smart poster) Record Header */
|
||||
/************************************/
|
||||
/* 7 | 6 | 5 | 4 | 3 | 2 1 0 */
|
||||
/*----------------------------------*/
|
||||
/* MB ME CF SR IL TNF */ /* <---- CF=0, IL=0 and SR=1 TNF=1 NFC Forum Well-known type*/
|
||||
/*----------------------------------*/
|
||||
/* TYPE LENGTH */
|
||||
/*----------------------------------*/
|
||||
/* PAYLOAD LENGTH 3 */ /* <---- Used only if SR=0 */
|
||||
/*----------------------------------*/
|
||||
/* PAYLOAD LENGTH 2 */ /* <---- Used only if SR=0 */
|
||||
/*----------------------------------*/
|
||||
/* PAYLOAD LENGTH 1 */ /* <---- Used only if SR=0 */
|
||||
/*----------------------------------*/
|
||||
/* PAYLOAD LENGTH 0 */
|
||||
/*----------------------------------*/
|
||||
/* ID LENGTH */ /* <---- Not Used */
|
||||
/*----------------------------------*/
|
||||
/* TYPE */
|
||||
/*----------------------------------*/
|
||||
/* ID */ /* <---- Not Used */
|
||||
/************************************/
|
||||
|
||||
/* Email : 1+@+1+subject+1+message */
|
||||
emailSize = 1 + strlen( pEmailStruct->EmailAdd ) + URI_FIRST_DATA_END_LENGTH + SUBJECT_BEGIN_STRING_LENGTH +
|
||||
strlen( pEmailStruct->Subject ) + URI_SECOND_DATA_END_LENGTH + MESSAGE_BEGIN_STRING_LENGTH + strlen( pEmailStruct->Message );
|
||||
|
||||
/* Check if a Smart poster is needed */
|
||||
if( pEmailStruct->Information[0] != '\0' )
|
||||
{
|
||||
/* Info : 1+2+info */
|
||||
infoSize = 1 + ISO_ENGLISH_CODE_STRING_LENGTH + strlen( pEmailStruct->Information );
|
||||
/* Total */
|
||||
totalSize = 4 + emailSize + 4 + infoSize;
|
||||
if( emailSize > 255 ) totalSize += 3; /* Normal Email size */
|
||||
if( infoSize > 255 ) totalSize += 3; /* Normal Info size */
|
||||
|
||||
/* SmartPoster header */
|
||||
if( totalSize > 255 )
|
||||
{
|
||||
pNDEFMessage[Offset++] = 0xC1;
|
||||
pNDEFMessage[Offset++] = SMART_POSTER_TYPE_STRING_LENGTH;
|
||||
pNDEFMessage[Offset++] = (totalSize & 0xFF000000) >> 24;
|
||||
pNDEFMessage[Offset++] = (totalSize & 0x00FF0000) >> 16;
|
||||
pNDEFMessage[Offset++] = (totalSize & 0x0000FF00) >> 8;
|
||||
pNDEFMessage[Offset++] = totalSize & 0x000000FF;
|
||||
}
|
||||
else
|
||||
{
|
||||
pNDEFMessage[Offset++] = 0xD1;
|
||||
pNDEFMessage[Offset++] = SMART_POSTER_TYPE_STRING_LENGTH;
|
||||
pNDEFMessage[Offset++] = (uint8_t)totalSize;
|
||||
}
|
||||
memcpy( &pNDEFMessage[Offset], SMART_POSTER_TYPE_STRING, SMART_POSTER_TYPE_STRING_LENGTH );
|
||||
Offset += SMART_POSTER_TYPE_STRING_LENGTH;
|
||||
}
|
||||
|
||||
/* Email header */
|
||||
pNDEFMessage[Offset] = 0x81;
|
||||
if( emailSize < 256 ) pNDEFMessage[Offset] |= 0x10; // Set the SR bit
|
||||
if( pEmailStruct->Information[0] == '\0' ) pNDEFMessage[Offset] |= 0x40; // Set the ME bit
|
||||
Offset++;
|
||||
|
||||
pNDEFMessage[Offset++] = URI_TYPE_STRING_LENGTH;
|
||||
if( emailSize > 255 )
|
||||
{
|
||||
pNDEFMessage[Offset++] = (emailSize & 0xFF000000) >> 24;
|
||||
pNDEFMessage[Offset++] = (emailSize & 0x00FF0000) >> 16;
|
||||
pNDEFMessage[Offset++] = (emailSize & 0x0000FF00) >> 8;
|
||||
pNDEFMessage[Offset++] = emailSize & 0x000000FF;
|
||||
}
|
||||
else
|
||||
{
|
||||
pNDEFMessage[Offset++] = (uint8_t)emailSize;
|
||||
}
|
||||
memcpy( &pNDEFMessage[Offset], URI_TYPE_STRING, URI_TYPE_STRING_LENGTH );
|
||||
Offset += URI_TYPE_STRING_LENGTH;
|
||||
|
||||
/* Email pay load */
|
||||
pNDEFMessage[Offset++] = URI_ID_0x06;
|
||||
memcpy( &pNDEFMessage[Offset], pEmailStruct->EmailAdd, strlen(pEmailStruct->EmailAdd) );
|
||||
Offset += strlen( pEmailStruct->EmailAdd );
|
||||
memcpy( &pNDEFMessage[Offset], URI_FIRST_DATA_END, URI_FIRST_DATA_END_LENGTH );
|
||||
Offset += URI_FIRST_DATA_END_LENGTH;
|
||||
|
||||
memcpy( &pNDEFMessage[Offset], SUBJECT_BEGIN_STRING, SUBJECT_BEGIN_STRING_LENGTH );
|
||||
Offset += SUBJECT_BEGIN_STRING_LENGTH;
|
||||
memcpy( &pNDEFMessage[Offset], pEmailStruct->Subject, strlen(pEmailStruct->Subject) );
|
||||
Offset += strlen( pEmailStruct->Subject );
|
||||
memcpy( &pNDEFMessage[Offset], URI_SECOND_DATA_END, URI_SECOND_DATA_END_LENGTH );
|
||||
Offset += URI_SECOND_DATA_END_LENGTH;
|
||||
|
||||
memcpy( &pNDEFMessage[Offset], MESSAGE_BEGIN_STRING, MESSAGE_BEGIN_STRING_LENGTH );
|
||||
Offset += MESSAGE_BEGIN_STRING_LENGTH;
|
||||
memcpy( &pNDEFMessage[Offset], pEmailStruct->Message, strlen(pEmailStruct->Message) );
|
||||
Offset += strlen( pEmailStruct->Message );
|
||||
|
||||
/* Information header */
|
||||
if( pEmailStruct->Information[0] != '\0' )
|
||||
{
|
||||
if( infoSize > 255 )
|
||||
{
|
||||
pNDEFMessage[Offset++] = 0x41;
|
||||
pNDEFMessage[Offset++] = TEXT_TYPE_STRING_LENGTH;
|
||||
pNDEFMessage[Offset++] = (infoSize & 0xFF000000) >> 24;
|
||||
pNDEFMessage[Offset++] = (infoSize & 0x00FF0000) >> 16;
|
||||
pNDEFMessage[Offset++] = (infoSize & 0x0000FF00) >> 8;
|
||||
pNDEFMessage[Offset++] = infoSize & 0x000000FF;
|
||||
}
|
||||
else
|
||||
{
|
||||
pNDEFMessage[Offset++] = 0x51;
|
||||
pNDEFMessage[Offset++] = TEXT_TYPE_STRING_LENGTH;
|
||||
pNDEFMessage[Offset++] = (uint8_t)infoSize;
|
||||
}
|
||||
|
||||
memcpy( &pNDEFMessage[Offset], TEXT_TYPE_STRING, TEXT_TYPE_STRING_LENGTH );
|
||||
Offset += TEXT_TYPE_STRING_LENGTH;
|
||||
pNDEFMessage[Offset++] = ISO_ENGLISH_CODE_STRING_LENGTH; /* UTF-8 with x byte language code */
|
||||
memcpy( &pNDEFMessage[Offset], ISO_ENGLISH_CODE_STRING, ISO_ENGLISH_CODE_STRING_LENGTH );
|
||||
Offset += ISO_ENGLISH_CODE_STRING_LENGTH;
|
||||
|
||||
/* Information payload */
|
||||
memcpy( &pNDEFMessage[Offset], pEmailStruct->Information, strlen(pEmailStruct->Information) );
|
||||
Offset += strlen( pEmailStruct->Information );
|
||||
|
||||
}
|
||||
|
||||
*size = (uint16_t)(Offset);
|
||||
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
//#ifdef __cplusplus
|
||||
//}
|
||||
//#endif
|
||||
|
||||
/******************* (C) COPYRIGHT 2015 STMicroelectronics *****END OF FILE****/
|
||||
64
src/lib_NDEF_Email.h
Normal file
64
src/lib_NDEF_Email.h
Normal file
@@ -0,0 +1,64 @@
|
||||
/**
|
||||
******************************************************************************
|
||||
* @file lib_NDEF_Email.h
|
||||
* @author MMY Application Team
|
||||
* @version $Revision: 1329 $
|
||||
* @date $Date: 2015-11-05 10:34:25 +0100 (Thu, 05 Nov 2015) $
|
||||
* @brief This file help to manage Email NDEF file.
|
||||
******************************************************************************
|
||||
* @attention
|
||||
*
|
||||
* <h2><center>© COPYRIGHT 2015 STMicroelectronics</center></h2>
|
||||
*
|
||||
* Licensed under ST MYLIBERTY SOFTWARE LICENSE AGREEMENT (the "License");
|
||||
* You may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at:
|
||||
*
|
||||
* http://www.st.com/myliberty
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied,
|
||||
* AND SPECIFICALLY DISCLAIMING THE IMPLIED WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE, AND NON-INFRINGEMENT.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
******************************************************************************
|
||||
*/
|
||||
|
||||
/* Define to prevent recursive inclusion -------------------------------------*/
|
||||
#ifndef __LIB_NDEF_EMAIL_H
|
||||
#define __LIB_NDEF_EMAIL_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/* Includes ------------------------------------------------------------------*/
|
||||
#include "lib_NDEF.h"
|
||||
|
||||
/* "mailto:customer.service@st.com?subject=M24SR S/N 754FHFGJF46G329 WARRANTY&body=this is an auomatic warranty activation email" */
|
||||
|
||||
typedef struct
|
||||
{
|
||||
char EmailAdd[64];
|
||||
char Subject[100];
|
||||
char Message[2000];
|
||||
char Information[400];
|
||||
}sEmailInfo;
|
||||
|
||||
/* Struct defined in lib_NDEF.h */
|
||||
typedef struct sRecordInfo sRecordInfo_email;
|
||||
|
||||
uint16_t NDEF_ReadEmail( sRecordInfo_email *pRecordStruct, sEmailInfo *pEmailStruct );
|
||||
uint16_t NDEF_WriteEmail( sEmailInfo *pEmailStruct );
|
||||
void NDEF_PrepareEmailMessage( sEmailInfo *pEmailStruct, uint8_t *pNDEFMessage, uint16_t *size );
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* __LIB_NDEF_EMAIL_H */
|
||||
|
||||
/******************* (C) COPYRIGHT 2015 STMicroelectronics *****END OF FILE****/
|
||||
372
src/lib_NDEF_Geo.cpp
Normal file
372
src/lib_NDEF_Geo.cpp
Normal file
@@ -0,0 +1,372 @@
|
||||
/**
|
||||
******************************************************************************
|
||||
* @file lib_NDEF_Geo.c
|
||||
* @author MMY Application Team
|
||||
* @version $Revision: 1330 $
|
||||
* @date $Date: 2015-11-05 10:39:11 +0100 (Thu, 05 Nov 2015) $
|
||||
* @brief This file help to manage NDEF file that represent geolocation.
|
||||
******************************************************************************
|
||||
* @attention
|
||||
*
|
||||
* <h2><center>© COPYRIGHT 2015 STMicroelectronics</center></h2>
|
||||
*
|
||||
* Licensed under ST MYLIBERTY SOFTWARE LICENSE AGREEMENT (the "License");
|
||||
* You may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at:
|
||||
*
|
||||
* http://www.st.com/myliberty
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied,
|
||||
* AND SPECIFICALLY DISCLAIMING THE IMPLIED WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE, AND NON-INFRINGEMENT.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
******************************************************************************
|
||||
*/
|
||||
|
||||
//#ifdef __cplusplus
|
||||
// extern "C" {
|
||||
//#endif
|
||||
|
||||
/* Includes ------------------------------------------------------------------*/
|
||||
#include "lib_NDEF_Geo.h"
|
||||
|
||||
/** @addtogroup NFC_libraries
|
||||
* @{
|
||||
* @brief <b>This is the library used to manage the content of the TAG (data)
|
||||
* But also the specific feature of the tag, for instance
|
||||
* password, gpo... </b>
|
||||
*/
|
||||
|
||||
|
||||
/** @addtogroup libNFC_FORUM
|
||||
* @{
|
||||
* @brief This part of the library manage data which follow NFC forum organisation.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @brief This buffer contains the data send/received by TAG
|
||||
*/
|
||||
extern uint8_t NDEF_Buffer [];
|
||||
|
||||
/** @defgroup libGeo_Private_Functions
|
||||
* @{
|
||||
*/
|
||||
|
||||
static void NDEF_FillGeoStruct( uint8_t* pPayload, uint32_t PayloadSize, sGeoInfo *pGeoStruct );
|
||||
static void NDEF_ReadURI_Geo( sRecordInfo_geo *pRecordStruct, sGeoInfo *pGeoStruct );
|
||||
|
||||
/**
|
||||
* @brief This function fill Geo structure with information of NDEF message.
|
||||
* @param pPayload : pointer on the payload data of the NDEF message.
|
||||
* @param PayloadSize : number of data in the payload.
|
||||
* @param pGeoStruct : pointer on the structure to fill.
|
||||
*/
|
||||
static void NDEF_FillGeoStruct( uint8_t* pPayload, uint32_t PayloadSize, sGeoInfo *pGeoStruct )
|
||||
{
|
||||
uint8_t* pLastByteAdd, *pLook4Word, *pEndString;
|
||||
char* pKeyWord;
|
||||
uint32_t SizeOfKeyWord;
|
||||
pEndString = 0;
|
||||
|
||||
pKeyWord = GEO_TYPE_STRING;
|
||||
SizeOfKeyWord = GEO_TYPE_STRING_LENGTH;
|
||||
|
||||
/* First character force to NULL in case not matching found */
|
||||
*pGeoStruct->Latitude = 0;
|
||||
*pGeoStruct->Longitude = 0;
|
||||
|
||||
/* Interresting information are stored before picture if any */
|
||||
/* Moreover picture is not used in this demonstration SW */
|
||||
pLastByteAdd = (uint8_t*)(pPayload + PayloadSize);
|
||||
|
||||
pLook4Word = pPayload;
|
||||
while( memcmp( pLook4Word, pKeyWord, SizeOfKeyWord ) && (pLook4Word < pLastByteAdd) )
|
||||
{
|
||||
pLook4Word++;
|
||||
}
|
||||
|
||||
/* Retrieve phone number */
|
||||
if( pLook4Word != pLastByteAdd )
|
||||
{
|
||||
pLook4Word += SizeOfKeyWord;
|
||||
pEndString = pLook4Word;
|
||||
while( memcmp( pEndString, URI_LATITUDE_END, URI_LATITUDE_END_LENGTH ) && (pEndString < pLastByteAdd) )
|
||||
{
|
||||
pEndString++;
|
||||
}
|
||||
if( pEndString != pLastByteAdd )
|
||||
{
|
||||
memcpy( pGeoStruct->Latitude, pLook4Word, pEndString-pLook4Word );
|
||||
/* add end of string character */
|
||||
pGeoStruct->Latitude[pEndString-pLook4Word] = 0;
|
||||
}
|
||||
}
|
||||
pEndString += URI_LATITUDE_END_LENGTH;
|
||||
pLook4Word = pEndString;
|
||||
|
||||
memcpy( pGeoStruct->Longitude, pEndString, PayloadSize - (pEndString - pPayload) );
|
||||
/* add end of string character */
|
||||
pGeoStruct->Longitude[PayloadSize-(pEndString-pPayload)] = 0;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief This function read the geoloccation information and store data in a structure.
|
||||
* @param pRecordStruct : Pointer on the record structure.
|
||||
* @param pGeoStruct : pointer on the structure to fill.
|
||||
*/
|
||||
static void NDEF_ReadURI_Geo( sRecordInfo_geo *pRecordStruct, sGeoInfo *pGeoStruct )
|
||||
{
|
||||
uint8_t* pPayload;
|
||||
uint32_t PayloadSize;
|
||||
|
||||
PayloadSize = ((uint32_t)(pRecordStruct->PayloadLength3) << 24) | ((uint32_t)(pRecordStruct->PayloadLength2) << 16) |
|
||||
((uint32_t)(pRecordStruct->PayloadLength1) << 8) | pRecordStruct->PayloadLength0;
|
||||
|
||||
/* Read record header */
|
||||
pPayload = (uint8_t*)(pRecordStruct->PayloadBufferAdd);
|
||||
|
||||
if( pRecordStruct->NDEF_Type == URI_GEO_TYPE )
|
||||
NDEF_FillGeoStruct( pPayload , PayloadSize, pGeoStruct );
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/** @defgroup libGeo_Public_Functions
|
||||
* @{
|
||||
* @brief This file is used to manage geolocation (stored or loaded in tag)
|
||||
*/
|
||||
|
||||
/**
|
||||
* @brief This function read NDEF and retrieve Geo information if any.
|
||||
* @param pRecordStruct : Pointer on the record structure.
|
||||
* @param pGeoStruct : pointer on the structure to fill .
|
||||
* @retval NDEF_OK : Geolocation information from NDEF have been retrieved.
|
||||
* @retval NDEF_ERROR : not able to read NDEF from tag.
|
||||
*/
|
||||
uint16_t NDEF_ReadGeo( sRecordInfo_geo *pRecordStruct, sGeoInfo *pGeoStruct )
|
||||
{
|
||||
uint16_t status = NDEF_ERROR;
|
||||
sRecordInfo_geo *pSPRecordStruct;
|
||||
uint32_t PayloadSize, RecordPosition;
|
||||
uint8_t* pData;
|
||||
|
||||
if( pRecordStruct->NDEF_Type == URI_GEO_TYPE )
|
||||
{
|
||||
NDEF_ReadURI_Geo( pRecordStruct, pGeoStruct );
|
||||
status = NDEF_OK;
|
||||
}
|
||||
else if( pRecordStruct->NDEF_Type == SMARTPOSTER_TYPE )
|
||||
{
|
||||
for( RecordPosition = 0; RecordPosition < pRecordStruct->NbOfRecordInSPPayload; RecordPosition++ )
|
||||
{
|
||||
pSPRecordStruct = pRecordStruct->SPRecordStructAdd[RecordPosition];
|
||||
if( pSPRecordStruct->NDEF_Type == URI_GEO_TYPE )
|
||||
{
|
||||
NDEF_ReadURI_Geo( pSPRecordStruct, pGeoStruct );
|
||||
status = NDEF_OK;
|
||||
}
|
||||
if( pSPRecordStruct->NDEF_Type == TEXT_TYPE )
|
||||
{
|
||||
PayloadSize = ((uint32_t)(pSPRecordStruct->PayloadLength3) << 24) | ((uint32_t)(pSPRecordStruct->PayloadLength2) << 16) |
|
||||
((uint32_t)(pSPRecordStruct->PayloadLength1) << 8) | pSPRecordStruct->PayloadLength0;
|
||||
|
||||
/* The instruction content the UTF-8 language code that is not used here */
|
||||
pData = (uint8_t*)pSPRecordStruct->PayloadBufferAdd;
|
||||
PayloadSize -= *pData + 1; /* remove not usefull data */
|
||||
pData += *pData + 1; /* set pointer on usefull data */
|
||||
|
||||
memcpy( pGeoStruct->Information, pData, PayloadSize );
|
||||
/* add end of string character */
|
||||
pGeoStruct->Information[PayloadSize] = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief This function write the NDEF file with the geolocation data given in the structure.
|
||||
* @param pGeoStruct : pointer on structure that contain the geolocation information.
|
||||
* @retval NDEF_OK : the function is succesful.
|
||||
* @retval NDEF_ERROR_MEMORY_INTERNAL : Cannot write to tag.
|
||||
* @retval NDEF_ERROR_NOT_FORMATED : CCFile data not supported or not present.
|
||||
* @retval NDEF_ERROR_MEMORY_TAG : Size not compatible with memory.
|
||||
* @retval NDEF_ERROR_LOCKED : Tag locked, cannot be write.
|
||||
*/
|
||||
uint16_t NDEF_WriteGeo( sGeoInfo *pGeoStruct )
|
||||
{
|
||||
uint16_t status = NDEF_ERROR,Offset = 0;
|
||||
|
||||
NDEF_PrepareGeoMessage( pGeoStruct, &NDEF_Buffer[FIRST_RECORD_OFFSET], &Offset );
|
||||
|
||||
/* Write NDEF */
|
||||
NDEF_Buffer[0] = (Offset & 0xFF00) >> 8;
|
||||
NDEF_Buffer[1] = Offset & 0x00FF;
|
||||
|
||||
status = WriteData( 0x00, Offset+FIRST_RECORD_OFFSET, NDEF_Buffer );
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief This function write the NDEF file with the geolocation data given in the structure.
|
||||
* @param pGeoStruct : pointer on structure that contain the geolocation information.
|
||||
* @param pNDEFMessage : pointer on the NDEF message.
|
||||
* @param size : to store the size of the NDEF message generated.
|
||||
*/
|
||||
void NDEF_PrepareGeoMessage( sGeoInfo *pGeoStruct, uint8_t *pNDEFMessage, uint16_t *size )
|
||||
{
|
||||
uint16_t Offset = 0;
|
||||
uint32_t geoSize = 0;
|
||||
uint32_t infoSize = 0;
|
||||
uint32_t totalSize = 0;
|
||||
|
||||
/* GEO is an URI but can be included in a smart poster to add text to give instruction to user for instance */
|
||||
|
||||
/* GEO (smart poster) Record Header */
|
||||
/************************************/
|
||||
/* 7 | 6 | 5 | 4 | 3 | 2 1 0 */
|
||||
/*----------------------------------*/
|
||||
/* MB ME CF SR IL TNF */ /* <---- CF=0, IL=0 and SR=1 TNF=1 NFC Forum Well-known type*/
|
||||
/*----------------------------------*/
|
||||
/* TYPE LENGTH */
|
||||
/*----------------------------------*/
|
||||
/* PAYLOAD LENGTH 3 */ /* <---- Used only if SR=0 */
|
||||
/*----------------------------------*/
|
||||
/* PAYLOAD LENGTH 2 */ /* <---- Used only if SR=0 */
|
||||
/*----------------------------------*/
|
||||
/* PAYLOAD LENGTH 1 */ /* <---- Used only if SR=0 */
|
||||
/*----------------------------------*/
|
||||
/* PAYLOAD LENGTH 0 */
|
||||
/*----------------------------------*/
|
||||
/* ID LENGTH */ /* <---- Not Used */
|
||||
/*----------------------------------*/
|
||||
/* TYPE */
|
||||
/*----------------------------------*/
|
||||
/* ID */ /* <---- Not Used */
|
||||
/************************************/
|
||||
|
||||
/* GEO : 1+geo:+latitude+1+longitude */
|
||||
geoSize = 1 + GEO_TYPE_STRING_LENGTH + strlen(pGeoStruct->Latitude) + URI_LATITUDE_END_LENGTH + strlen(pGeoStruct->Longitude);
|
||||
|
||||
/* Check if a Smart poster is needed */
|
||||
if( pGeoStruct->Information[0] != '\0' )
|
||||
{
|
||||
/* Info : 1+2+info */
|
||||
infoSize = 1 + ISO_ENGLISH_CODE_STRING_LENGTH + strlen(pGeoStruct->Information);
|
||||
/* Total */
|
||||
totalSize = 4 + geoSize + 4 + infoSize;
|
||||
if( geoSize > 255 ) totalSize += 3; /* Normal Geo size */
|
||||
if( infoSize > 255 ) totalSize += 3; /* Normal Info size */
|
||||
|
||||
/* SmartPoster header */
|
||||
if( totalSize > 255 )
|
||||
{
|
||||
pNDEFMessage[Offset++] = 0xC1;
|
||||
pNDEFMessage[Offset++] = SMART_POSTER_TYPE_STRING_LENGTH;
|
||||
pNDEFMessage[Offset++] = (totalSize & 0xFF000000) >> 24;
|
||||
pNDEFMessage[Offset++] = (totalSize & 0x00FF0000) >> 16;
|
||||
pNDEFMessage[Offset++] = (totalSize & 0x0000FF00) >> 8;
|
||||
pNDEFMessage[Offset++] = totalSize & 0x000000FF;
|
||||
}
|
||||
else
|
||||
{
|
||||
pNDEFMessage[Offset++] = 0xD1;
|
||||
pNDEFMessage[Offset++] = SMART_POSTER_TYPE_STRING_LENGTH;
|
||||
pNDEFMessage[Offset++] = (uint8_t)totalSize;
|
||||
}
|
||||
memcpy( &pNDEFMessage[Offset], SMART_POSTER_TYPE_STRING, SMART_POSTER_TYPE_STRING_LENGTH );
|
||||
Offset += SMART_POSTER_TYPE_STRING_LENGTH;
|
||||
}
|
||||
|
||||
/* GEO header */
|
||||
pNDEFMessage[Offset] = 0x81;
|
||||
if( geoSize < 256 ) pNDEFMessage[Offset] |= 0x10; // Set the SR bit
|
||||
if( pGeoStruct->Information[0] == '\0' ) pNDEFMessage[Offset] |= 0x40; // Set the ME bit
|
||||
Offset++;
|
||||
|
||||
pNDEFMessage[Offset++] = URI_TYPE_STRING_LENGTH;
|
||||
if( geoSize > 255 )
|
||||
{
|
||||
pNDEFMessage[Offset++] = (geoSize & 0xFF000000) >> 24;
|
||||
pNDEFMessage[Offset++] = (geoSize & 0x00FF0000) >> 16;
|
||||
pNDEFMessage[Offset++] = (geoSize & 0x0000FF00) >> 8;
|
||||
pNDEFMessage[Offset++] = geoSize & 0x000000FF;
|
||||
}
|
||||
else
|
||||
{
|
||||
pNDEFMessage[Offset++] = (uint8_t)geoSize;
|
||||
}
|
||||
memcpy( &pNDEFMessage[Offset], URI_TYPE_STRING, URI_TYPE_STRING_LENGTH );
|
||||
Offset += URI_TYPE_STRING_LENGTH;
|
||||
|
||||
/* GEO payload */
|
||||
pNDEFMessage[Offset++] = URI_ID_0x00; /* URI identifier no abbreviation */
|
||||
memcpy( &pNDEFMessage[Offset], GEO_TYPE_STRING, GEO_TYPE_STRING_LENGTH );
|
||||
Offset += GEO_TYPE_STRING_LENGTH;
|
||||
memcpy( &pNDEFMessage[Offset], pGeoStruct->Latitude, strlen(pGeoStruct->Latitude) );
|
||||
Offset += strlen( pGeoStruct->Latitude );
|
||||
memcpy( &pNDEFMessage[Offset], URI_LATITUDE_END, URI_LATITUDE_END_LENGTH );
|
||||
Offset += URI_LATITUDE_END_LENGTH;
|
||||
memcpy( &pNDEFMessage[Offset], pGeoStruct->Longitude, strlen(pGeoStruct->Longitude) );
|
||||
Offset += strlen( pGeoStruct->Longitude );
|
||||
|
||||
/* Information header */
|
||||
if( pGeoStruct->Information[0] != '\0' )
|
||||
{
|
||||
if( infoSize > 255 )
|
||||
{
|
||||
pNDEFMessage[Offset++] = 0x41;
|
||||
pNDEFMessage[Offset++] = TEXT_TYPE_STRING_LENGTH;
|
||||
pNDEFMessage[Offset++] = (infoSize & 0xFF000000) >> 24;
|
||||
pNDEFMessage[Offset++] = (infoSize & 0x00FF0000) >> 16;
|
||||
pNDEFMessage[Offset++] = (infoSize & 0x0000FF00) >> 8;
|
||||
pNDEFMessage[Offset++] = infoSize & 0x000000FF;
|
||||
}
|
||||
else
|
||||
{
|
||||
pNDEFMessage[Offset++] = 0x51;
|
||||
pNDEFMessage[Offset++] = TEXT_TYPE_STRING_LENGTH;
|
||||
pNDEFMessage[Offset++] = (uint8_t)infoSize;
|
||||
}
|
||||
|
||||
memcpy( &pNDEFMessage[Offset], TEXT_TYPE_STRING, TEXT_TYPE_STRING_LENGTH );
|
||||
Offset += TEXT_TYPE_STRING_LENGTH;
|
||||
pNDEFMessage[Offset++] = ISO_ENGLISH_CODE_STRING_LENGTH; /* UTF-8 with x byte language code */
|
||||
memcpy( &pNDEFMessage[Offset], ISO_ENGLISH_CODE_STRING, ISO_ENGLISH_CODE_STRING_LENGTH );
|
||||
Offset += ISO_ENGLISH_CODE_STRING_LENGTH;
|
||||
|
||||
/* Information payload */
|
||||
memcpy( &pNDEFMessage[Offset], pGeoStruct->Information, strlen(pGeoStruct->Information) );
|
||||
Offset += strlen( pGeoStruct->Information );
|
||||
}
|
||||
|
||||
*size = (uint16_t)(Offset);
|
||||
}
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
//#ifdef __cplusplus
|
||||
//}
|
||||
//#endif
|
||||
|
||||
/******************* (C) COPYRIGHT 2015 STMicroelectronics *****END OF FILE****/
|
||||
61
src/lib_NDEF_Geo.h
Normal file
61
src/lib_NDEF_Geo.h
Normal file
@@ -0,0 +1,61 @@
|
||||
/**
|
||||
******************************************************************************
|
||||
* @file lib_NDEF_Geo.h
|
||||
* @author MMY Application Team
|
||||
* @version $Revision: 1329 $
|
||||
* @date $Date: 2015-11-05 10:34:25 +0100 (Thu, 05 Nov 2015) $
|
||||
* @brief This file help to manage Geolocation NDEF file.
|
||||
******************************************************************************
|
||||
* @attention
|
||||
*
|
||||
* <h2><center>© COPYRIGHT 2015 STMicroelectronics</center></h2>
|
||||
*
|
||||
* Licensed under ST MYLIBERTY SOFTWARE LICENSE AGREEMENT (the "License");
|
||||
* You may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at:
|
||||
*
|
||||
* http://www.st.com/myliberty
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied,
|
||||
* AND SPECIFICALLY DISCLAIMING THE IMPLIED WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE, AND NON-INFRINGEMENT.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
******************************************************************************
|
||||
*/
|
||||
|
||||
/* Define to prevent recursive inclusion -------------------------------------*/
|
||||
#ifndef __LIB_NDEF_GEO_H
|
||||
#define __LIB_NDEF_GEO_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/* Includes ------------------------------------------------------------------*/
|
||||
#include "lib_NDEF.h"
|
||||
|
||||
typedef struct
|
||||
{
|
||||
char Latitude[20];
|
||||
char Longitude[20];
|
||||
char Information[100];
|
||||
}sGeoInfo;
|
||||
|
||||
/* Struct defined in lib_NDEF.h */
|
||||
typedef struct sRecordInfo sRecordInfo_geo;
|
||||
|
||||
uint16_t NDEF_ReadGeo( sRecordInfo_geo *pRecordStruct, sGeoInfo *pGeoStruct );
|
||||
uint16_t NDEF_WriteGeo( sGeoInfo *pGeoStruct );
|
||||
void NDEF_PrepareGeoMessage( sGeoInfo *pGeoStruct, uint8_t *pNDEFMessage, uint16_t *size );
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* __LIB_NDEF_GEO_H */
|
||||
|
||||
/******************* (C) COPYRIGHT 2015 STMicroelectronics *****END OF FILE****/
|
||||
297
src/lib_NDEF_MyApp.cpp
Normal file
297
src/lib_NDEF_MyApp.cpp
Normal file
@@ -0,0 +1,297 @@
|
||||
/**
|
||||
******************************************************************************
|
||||
* @file lib_NDEF_MyApp.c
|
||||
* @author MMY Application Team
|
||||
* @version $Revision: 1330 $
|
||||
* @date $Date: 2015-11-05 10:39:11 +0100 (Thu, 05 Nov 2015) $
|
||||
* @brief This file help to manage the NDEF file of a private application.
|
||||
******************************************************************************
|
||||
* @attention
|
||||
*
|
||||
* <h2><center>© COPYRIGHT 2015 STMicroelectronics</center></h2>
|
||||
*
|
||||
* Licensed under ST MYLIBERTY SOFTWARE LICENSE AGREEMENT (the "License");
|
||||
* You may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at:
|
||||
*
|
||||
* http://www.st.com/myliberty
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied,
|
||||
* AND SPECIFICALLY DISCLAIMING THE IMPLIED WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE, AND NON-INFRINGEMENT.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
******************************************************************************
|
||||
*/
|
||||
|
||||
//#ifdef __cplusplus
|
||||
// extern "C" {
|
||||
//#endif
|
||||
|
||||
/* Includes ------------------------------------------------------------------*/
|
||||
#include "lib_NDEF_MyApp.h"
|
||||
|
||||
|
||||
/** @addtogroup NFC_libraries
|
||||
* @{
|
||||
* @brief <b>This is the library used to manage the content of the TAG (data)
|
||||
* But also the specific feature of the tag, for instance
|
||||
* password, gpio... </b>
|
||||
*/
|
||||
|
||||
|
||||
/** @addtogroup libNFC_FORUM
|
||||
* @{
|
||||
* @brief This part of the library manage data which follow NFC forum organisation.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @brief This buffer contains the data send/received by TAG
|
||||
*/
|
||||
extern uint8_t NDEF_Buffer [];
|
||||
|
||||
/** @defgroup libMyApp_Private_Functions
|
||||
* @{
|
||||
*/
|
||||
|
||||
static void NDEF_Extract_M24SRDiscoveryApp_Input( sRecordInfo_myapp *pRecordStruct, sMyAppInfo *pMyAppStruct );
|
||||
|
||||
/**
|
||||
* @brief This function read the NDEF file and store application data in a structure.
|
||||
* @param pRecordStruct : Pointer on the record structure.
|
||||
* @param pMyAppStruct : pointer on the structure to fill.
|
||||
*/
|
||||
static void NDEF_Extract_M24SRDiscoveryApp_Input( sRecordInfo_myapp *pRecordStruct, sMyAppInfo *pMyAppStruct )
|
||||
{
|
||||
uint8_t* pPayload;
|
||||
uint8_t* pLook4Word;
|
||||
uint16_t BackGroundColor, FontColor;
|
||||
uint8_t i;
|
||||
|
||||
/* Read record header */
|
||||
pPayload = (uint8_t*)(pRecordStruct->PayloadBufferAdd);
|
||||
|
||||
/* initialize struct in case not matching found */
|
||||
for( i = 0; i < 8; i++ )
|
||||
{
|
||||
/* Set the Back Color */
|
||||
pMyAppStruct->LineX[i].BackGroundColor = 0xFFFF;
|
||||
/* Set the Text Color */
|
||||
pMyAppStruct->LineX[i].FontColor = 0x0000;
|
||||
/* Set the line number */
|
||||
pMyAppStruct->LineX[i].LineNb = i + 1;
|
||||
/* Set the line content */
|
||||
memcpy( pMyAppStruct->LineX[i].String, " ", 20 );
|
||||
}
|
||||
|
||||
pLook4Word = pPayload;
|
||||
|
||||
for( i = 0; i < 4; i++ )
|
||||
{
|
||||
pMyAppStruct->LedBlinkConf.LedConf[i] = *pLook4Word;
|
||||
pLook4Word++;
|
||||
}
|
||||
pMyAppStruct->LedBlinkConf.Speed = *pLook4Word;
|
||||
pLook4Word++;
|
||||
|
||||
for( i = 0; i < 8; i++ )
|
||||
{
|
||||
/* Set the line number */
|
||||
pMyAppStruct->LineX[i].LineNb = *pLook4Word;
|
||||
pLook4Word++;
|
||||
/* Set the Back Color */
|
||||
BackGroundColor = (uint16_t)(*pLook4Word << 8);
|
||||
BackGroundColor = BackGroundColor | (uint16_t)(*++pLook4Word );
|
||||
pMyAppStruct->LineX[i].BackGroundColor = BackGroundColor;
|
||||
pLook4Word++;
|
||||
/* Set the Text Color */
|
||||
FontColor = (uint16_t)(*pLook4Word << 8);
|
||||
FontColor = FontColor | (uint16_t)(*++pLook4Word);
|
||||
pMyAppStruct->LineX[i].FontColor = FontColor;
|
||||
pLook4Word++;
|
||||
/* Set the line content */
|
||||
memcpy( pMyAppStruct->LineX[i].String, (char*)pLook4Word, 20 );
|
||||
pLook4Word += 20;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/** @defgroup libMyApp_Public_Functions
|
||||
* @{
|
||||
* @brief This file is used to manage proprietary NDEF (stored or loaded in tag)
|
||||
*/
|
||||
|
||||
/**
|
||||
* @brief This function read NDEF and retrieve Application information if any.
|
||||
* @param pRecordStruct : Pointer on the record structure.
|
||||
* @param pMyAppStruct : pointer on the structure to fill.
|
||||
* @retval NDEF_OK : NDEF file data read in the tag.
|
||||
* @retval NDEF_ERROR : not able to read NDEF in tag.
|
||||
*/
|
||||
uint16_t NDEF_ReadMyApp( sRecordInfo_myapp *pRecordStruct, sMyAppInfo *pMyAppStruct )
|
||||
{
|
||||
uint16_t status = NDEF_ERROR;
|
||||
|
||||
if( pRecordStruct->NDEF_Type == M24SR_DISCOVERY_APP_TYPE )
|
||||
{
|
||||
NDEF_Extract_M24SRDiscoveryApp_Input( pRecordStruct, pMyAppStruct );
|
||||
status = NDEF_OK;
|
||||
}
|
||||
else
|
||||
{
|
||||
status = NDEF_ERROR;
|
||||
}
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief This function write the NDEF file with the Application data given in the structure.
|
||||
* @brief Only used for debug purpose in this firmware version.
|
||||
* @param pMyAppStruct : pointer on structure that contain the application information.
|
||||
* @retval NDEF_OK : NDEF file data written in the tag.
|
||||
* @retval NDEF_ERROR : not able to store NDEF in tag.
|
||||
* @retval NDEF_ERROR_MEMORY_INTERNAL : Cannot write to tag.
|
||||
* @retval NDEF_ERROR_NOT_FORMATED : CCFile data not supported or not present.
|
||||
* @retval NDEF_ERROR_MEMORY_TAG : Size not compatible with memory.
|
||||
* @retval NDEF_ERROR_LOCKED : Tag locked, cannot be write.
|
||||
*/
|
||||
uint16_t NDEF_WriteMyApp( sMyAppInfo *pMyAppStruct )
|
||||
{
|
||||
uint16_t status = NDEF_ERROR;
|
||||
uint16_t DataSize;
|
||||
uint32_t PayloadSize;
|
||||
uint8_t i;
|
||||
uint8_t* pPayload;
|
||||
|
||||
|
||||
/* External Type Record Header */
|
||||
/************************************/
|
||||
/* 7 | 6 | 5 | 4 | 3 | 2 1 0 */
|
||||
/*----------------------------------*/
|
||||
/* MB ME CF SR IL TNF */ /* <---- IL=0, CF=0 and SR=1 TNF=4 NFC Forum external type*/
|
||||
/*----------------------------------*/
|
||||
/* TYPE LENGTH */
|
||||
/*----------------------------------*/
|
||||
/* PAYLOAD LENGTH 3 */ /* <---- Not Used */
|
||||
/*----------------------------------*/
|
||||
/* PAYLOAD LENGTH 2 */ /* <---- Not Used */
|
||||
/*----------------------------------*/
|
||||
/* PAYLOAD LENGTH 1 */ /* <---- Not Used */
|
||||
/*----------------------------------*/
|
||||
/* PAYLOAD LENGTH 0 */ /* The payload will always be 5 + 25*8=205 bytes for this application */
|
||||
/*----------------------------------*/
|
||||
/* ID LENGTH */ /* <---- Not Used */
|
||||
/*----------------------------------*/
|
||||
/* TYPE */ /* st.com:m24sr_discovery_democtrl */
|
||||
/*----------------------------------*/
|
||||
/* ID */ /* <---- Not Used */
|
||||
/************************************/
|
||||
|
||||
/* NDEF file must be written in 2 phases, first phase NDEF size is Null */
|
||||
NDEF_Buffer[NDEF_SIZE_OFFSET] = 0x00;
|
||||
NDEF_Buffer[NDEF_SIZE_OFFSET+1] = 0x00;
|
||||
|
||||
/* fill URI record header */
|
||||
NDEF_Buffer[FIRST_RECORD_OFFSET] = 0xD4; /* Record Flag */
|
||||
NDEF_Buffer[FIRST_RECORD_OFFSET+1] = M24SR_DISCOVERY_APP_STRING_LENGTH;
|
||||
NDEF_Buffer[FIRST_RECORD_OFFSET+2] = 0x00; /* Will be filled at the end when payload size is known */
|
||||
|
||||
memcpy( &NDEF_Buffer[FIRST_RECORD_OFFSET+3], M24SR_DISCOVERY_APP_STRING, M24SR_DISCOVERY_APP_STRING_LENGTH );
|
||||
|
||||
pPayload = &NDEF_Buffer[FIRST_RECORD_OFFSET + 3 + M24SR_DISCOVERY_APP_STRING_LENGTH];
|
||||
PayloadSize = 0;
|
||||
|
||||
/**************************************************************/
|
||||
/* BLINK CONFIG data */
|
||||
|
||||
/* led 1 blinking */
|
||||
*pPayload = 0x03;
|
||||
pPayload++;
|
||||
/* led 2 blinking */
|
||||
*pPayload = 0x02;
|
||||
pPayload++;
|
||||
/* led 3 blinking */
|
||||
*pPayload = 0x02;
|
||||
pPayload++;
|
||||
/* led 4 blinking */
|
||||
*pPayload = 0x03;
|
||||
pPayload++;
|
||||
/* speed */
|
||||
*pPayload = 0x03;
|
||||
pPayload++;
|
||||
|
||||
PayloadSize += 5;
|
||||
|
||||
/**************************************************************/
|
||||
|
||||
/**************************************************************/
|
||||
/* SCREEN config data */
|
||||
for( i = 0; i < 8; i++ )
|
||||
{
|
||||
/* Line number */
|
||||
*pPayload = (uint8_t)(i + 1);
|
||||
pPayload++;
|
||||
/* Background color */
|
||||
*pPayload = 0xFF;
|
||||
pPayload++;
|
||||
*pPayload = 0xFF;
|
||||
pPayload++;
|
||||
/* Font Color */
|
||||
*pPayload = 0x00;
|
||||
pPayload++;
|
||||
*pPayload = 0x00;
|
||||
pPayload++;
|
||||
/* String */
|
||||
memcpy( pPayload, "ABCDEFGHIJKLMNOPQRST", 20 );
|
||||
pPayload += 20;
|
||||
|
||||
PayloadSize += 25;
|
||||
|
||||
}
|
||||
|
||||
NDEF_Buffer[FIRST_RECORD_OFFSET+2] = PayloadSize & 0x000000FF;
|
||||
|
||||
DataSize = PayloadSize + 5 + M24SR_DISCOVERY_APP_STRING_LENGTH;
|
||||
|
||||
/* Write NDEF */
|
||||
status = WriteData( 0x00, DataSize, NDEF_Buffer );
|
||||
|
||||
/* Write NDEF size to complete*/
|
||||
if( status == NDEF_OK )
|
||||
{
|
||||
DataSize -= 2; /* Must not count the 2 byte that represent the NDEF size */
|
||||
NDEF_Buffer[0] = (DataSize & 0xFF00) >> 8;
|
||||
NDEF_Buffer[1] = DataSize & 0x00FF;
|
||||
|
||||
status = WriteData( 0x00, 2, NDEF_Buffer );
|
||||
}
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
//#ifdef __cplusplus
|
||||
//}
|
||||
//#endif
|
||||
|
||||
/******************* (C) COPYRIGHT 2015 STMicroelectronics *****END OF FILE****/
|
||||
89
src/lib_NDEF_MyApp.h
Normal file
89
src/lib_NDEF_MyApp.h
Normal file
@@ -0,0 +1,89 @@
|
||||
/**
|
||||
******************************************************************************
|
||||
* @file lib_NDEF_MyApp.h
|
||||
* @author MMY Application Team
|
||||
* @version $Revision: 1329 $
|
||||
* @date $Date: 2015-11-05 10:34:25 +0100 (Thu, 05 Nov 2015) $
|
||||
* @brief This file illustrate how to use M24SR with a proprietary protocol.
|
||||
******************************************************************************
|
||||
* @attention
|
||||
*
|
||||
* <h2><center>© COPYRIGHT 2015 STMicroelectronics</center></h2>
|
||||
*
|
||||
* Licensed under ST MYLIBERTY SOFTWARE LICENSE AGREEMENT (the "License");
|
||||
* You may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at:
|
||||
*
|
||||
* http://www.st.com/myliberty
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied,
|
||||
* AND SPECIFICALLY DISCLAIMING THE IMPLIED WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE, AND NON-INFRINGEMENT.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
******************************************************************************
|
||||
*/
|
||||
|
||||
/* Define to prevent recursive inclusion -------------------------------------*/
|
||||
#ifndef __LIB_NDEF_MYAPP_H
|
||||
#define __LIB_NDEF_MYAPP_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/* Includes ------------------------------------------------------------------*/
|
||||
#include "lib_NDEF.h"
|
||||
|
||||
#define BLINK_CONFIG "<BLINK_CONFIG>"
|
||||
#define BLINK_CONFIG_STRING_SIZE 14
|
||||
#define BLINK_CONFIG_END "<\\BLINK_CONFIG>"
|
||||
#define BLINK_CONFIG_END_STRING_SIZE 15
|
||||
|
||||
#define LINE_DESCR "<LINE_DESCR>"
|
||||
#define LINE_DESCR_STRING_SIZE 12
|
||||
#define LINE_DESCR_END "<\\LINE_DESCR>"
|
||||
#define LINE_DESCR_END_STRING_SIZE 13
|
||||
|
||||
#define BLINKING_NONE 0x00
|
||||
#define BLINKING_SLOW 0x01
|
||||
#define BLINKING_MEDIUM 0x02
|
||||
#define BLINKING_FAST 0x03
|
||||
|
||||
|
||||
typedef struct
|
||||
{
|
||||
uint8_t LedConf[4];
|
||||
uint8_t Speed;
|
||||
}sLedBlinkConfig;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
uint8_t LineNb;
|
||||
uint16_t BackGroundColor;
|
||||
uint16_t FontColor;
|
||||
char String[20];
|
||||
}sLineConfig;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
sLedBlinkConfig LedBlinkConf;
|
||||
sLineConfig LineX[8];
|
||||
}sMyAppInfo;
|
||||
|
||||
/* Struct defined in lib_NDEF.h */
|
||||
typedef struct sRecordInfo sRecordInfo_myapp;
|
||||
|
||||
uint16_t NDEF_ReadMyApp( sRecordInfo_myapp *pRecordStruct, sMyAppInfo *pMyAppStruct );
|
||||
uint16_t NDEF_WriteMyApp( sMyAppInfo *pMyAppStruct );
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* __LIB_NDEF_MYAPP_H */
|
||||
|
||||
/******************* (C) COPYRIGHT 2015 STMicroelectronics *****END OF FILE****/
|
||||
384
src/lib_NDEF_SMS.cpp
Normal file
384
src/lib_NDEF_SMS.cpp
Normal file
@@ -0,0 +1,384 @@
|
||||
/**
|
||||
******************************************************************************
|
||||
* @file lib_NDEF_SMS.c
|
||||
* @author MMY Application Team
|
||||
* @version $Revision: 1330 $
|
||||
* @date $Date: 2015-11-05 10:39:11 +0100 (Thu, 05 Nov 2015) $
|
||||
* @brief This file help to manage NDEF file that represent SMS.
|
||||
******************************************************************************
|
||||
* @attention
|
||||
*
|
||||
* <h2><center>© COPYRIGHT 2015 STMicroelectronics</center></h2>
|
||||
*
|
||||
* Licensed under ST MYLIBERTY SOFTWARE LICENSE AGREEMENT (the "License");
|
||||
* You may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at:
|
||||
*
|
||||
* http://www.st.com/myliberty
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied,
|
||||
* AND SPECIFICALLY DISCLAIMING THE IMPLIED WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE, AND NON-INFRINGEMENT.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
******************************************************************************
|
||||
*/
|
||||
|
||||
//#ifdef __cplusplus
|
||||
// extern "C" {
|
||||
//#endif
|
||||
|
||||
/* Includes ------------------------------------------------------------------*/
|
||||
#include "lib_NDEF_SMS.h"
|
||||
|
||||
|
||||
/** @addtogroup NFC_libraries
|
||||
* @{
|
||||
* @brief <b>This is the library used to manage the content of the TAG (data)
|
||||
* But also the specific feature of the tag, for instance
|
||||
* password, gpo... </b>
|
||||
*/
|
||||
|
||||
|
||||
/** @addtogroup libNFC_FORUM
|
||||
* @{
|
||||
* @brief This part of the library manage data which follow NFC forum organisation.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @brief This buffer contains the data send/received by TAG
|
||||
*/
|
||||
extern uint8_t NDEF_Buffer [];
|
||||
|
||||
/** @defgroup libSMS_Private_Functions
|
||||
* @{
|
||||
*/
|
||||
|
||||
static void NDEF_FillSMSStruct( uint8_t* pPayload, uint32_t PayloadSize, sSMSInfo *pSMSStruct );
|
||||
static void NDEF_ReadURI_SMS( sRecordInfo_sms *pRecordStruct, sSMSInfo *pSMSStruct );
|
||||
|
||||
/**
|
||||
* @brief This function fill SMS structure with information of NDEF message.
|
||||
* @param pPayload : pointer on the payload data of the NDEF message.
|
||||
* @param PayloadSize : number of data in the payload.
|
||||
* @param pSMSStruct : pointer on the structure to fill.
|
||||
*/
|
||||
static void NDEF_FillSMSStruct( uint8_t* pPayload, uint32_t PayloadSize, sSMSInfo *pSMSStruct )
|
||||
{
|
||||
uint8_t* pLastByteAdd, *pLook4Word, *pEndString ;
|
||||
char* pKeyWord;
|
||||
uint32_t SizeOfKeyWord;
|
||||
pEndString = 0;
|
||||
|
||||
pKeyWord = SMS_TYPE_STRING;
|
||||
SizeOfKeyWord = SMS_TYPE_STRING_LENGTH;
|
||||
|
||||
/* First character force to NULL in case not matching found */
|
||||
*pSMSStruct->PhoneNumber = 0;
|
||||
*pSMSStruct->Message = 0;
|
||||
|
||||
/* Interesting information are stored before picture if any */
|
||||
/* Moreover picture is not used in this demonstration SW */
|
||||
pLastByteAdd = (uint8_t*)(pPayload + PayloadSize);
|
||||
|
||||
pLook4Word = pPayload;
|
||||
while( memcmp( pLook4Word, pKeyWord, SizeOfKeyWord ) && (pLook4Word < pLastByteAdd) )
|
||||
{
|
||||
pLook4Word++;
|
||||
}
|
||||
|
||||
/* Retrieve phone number */
|
||||
if( pLook4Word != pLastByteAdd )
|
||||
{
|
||||
pLook4Word += SizeOfKeyWord;
|
||||
pEndString = pLook4Word;
|
||||
while( memcmp( pEndString, URI_FIRST_DATA_END, URI_FIRST_DATA_END_LENGTH ) && (pEndString < pLastByteAdd) )
|
||||
{
|
||||
pEndString++;
|
||||
}
|
||||
if( pEndString != pLastByteAdd )
|
||||
{
|
||||
memcpy( pSMSStruct->PhoneNumber, pLook4Word, pEndString-pLook4Word );
|
||||
/* add end of string character */
|
||||
pSMSStruct->PhoneNumber[pEndString-pLook4Word] = 0;
|
||||
}
|
||||
}
|
||||
pEndString += URI_FIRST_DATA_END_LENGTH;
|
||||
pLook4Word = pEndString;
|
||||
|
||||
/* check if e-mail subject is present */
|
||||
if( !memcmp( pLook4Word, MESSAGE_BEGIN_STRING, MESSAGE_BEGIN_STRING_LENGTH ) )
|
||||
{
|
||||
pEndString += MESSAGE_BEGIN_STRING_LENGTH;
|
||||
/* Retrieve message */
|
||||
memcpy( pSMSStruct->Message, pEndString, PayloadSize - (pEndString - pPayload) );
|
||||
/* add end of string character */
|
||||
pSMSStruct->Message[PayloadSize-(pEndString-pPayload)] = 0;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief This function read the SMS and store data in a structure.
|
||||
* @param pRecordStruct : Pointer on the record structure.
|
||||
* @param pSMSStruct : pointer on the structure to fill.
|
||||
*/
|
||||
static void NDEF_ReadURI_SMS( sRecordInfo_sms *pRecordStruct, sSMSInfo *pSMSStruct )
|
||||
{
|
||||
uint8_t* pPayload;
|
||||
uint32_t PayloadSize;
|
||||
|
||||
PayloadSize = ((uint32_t)(pRecordStruct->PayloadLength3) << 24) | ((uint32_t)(pRecordStruct->PayloadLength2) << 16) |
|
||||
((uint32_t)(pRecordStruct->PayloadLength1) << 8) | pRecordStruct->PayloadLength0;
|
||||
|
||||
/* Read record header */
|
||||
pPayload = (uint8_t*)(pRecordStruct->PayloadBufferAdd);
|
||||
|
||||
if( pRecordStruct->NDEF_Type == URI_SMS_TYPE )
|
||||
NDEF_FillSMSStruct( pPayload , PayloadSize, pSMSStruct );
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/** @defgroup libSMS_Public_Functions
|
||||
* @{
|
||||
* @brief This file is used to manage SMS (stored or loaded in tag)
|
||||
*/
|
||||
|
||||
/**
|
||||
* @brief This function read NDEF and retrieve SMS information if any.
|
||||
* @param pRecordStruct : Pointer on the record structure.
|
||||
* @param pSMSStruct : pointer on the structure to fill.
|
||||
* @retval NDEF_OK : SMS information from NDEF have been retrieve.
|
||||
* @retval NDEF_ERROR : Not able to retrieve SMS information.
|
||||
*/
|
||||
uint16_t NDEF_ReadSMS( sRecordInfo_sms *pRecordStruct, sSMSInfo *pSMSStruct )
|
||||
{
|
||||
uint16_t status = NDEF_ERROR;
|
||||
sRecordInfo_sms *pSPRecordStruct;
|
||||
uint32_t PayloadSize, RecordPosition;
|
||||
uint8_t* pData;
|
||||
|
||||
if( pRecordStruct->NDEF_Type == URI_SMS_TYPE )
|
||||
{
|
||||
NDEF_ReadURI_SMS( pRecordStruct, pSMSStruct );
|
||||
status = NDEF_OK;
|
||||
}
|
||||
else if( pRecordStruct->NDEF_Type == SMARTPOSTER_TYPE )
|
||||
{
|
||||
for( RecordPosition = 0; RecordPosition < pRecordStruct->NbOfRecordInSPPayload; RecordPosition++ )
|
||||
{
|
||||
pSPRecordStruct = pRecordStruct->SPRecordStructAdd[RecordPosition];
|
||||
if( pSPRecordStruct->NDEF_Type == URI_SMS_TYPE )
|
||||
{
|
||||
NDEF_ReadURI_SMS( pSPRecordStruct, pSMSStruct );
|
||||
status = NDEF_OK;
|
||||
}
|
||||
if( pSPRecordStruct->NDEF_Type == TEXT_TYPE )
|
||||
{
|
||||
PayloadSize = ((uint32_t)(pSPRecordStruct->PayloadLength3) << 24) | ((uint32_t)(pSPRecordStruct->PayloadLength2) << 16) |
|
||||
((uint32_t)(pSPRecordStruct->PayloadLength1) << 8) | pSPRecordStruct->PayloadLength0;
|
||||
|
||||
/* The instruction content the UTF-8 language code that is not used here */
|
||||
pData = (uint8_t*)pSPRecordStruct->PayloadBufferAdd;
|
||||
PayloadSize -= *pData + 1; /* remove not usefull data */
|
||||
pData += *pData + 1; /* set pointer on usefull data */
|
||||
|
||||
memcpy( pSMSStruct->Information, pData, PayloadSize );
|
||||
/* add end of string character */
|
||||
pSMSStruct->Information[PayloadSize] = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief This function write the NDEF file with the SMS data given in the structure.
|
||||
* @param pSMSStruct : pointer on structure that contain the SMS information.
|
||||
* @retval NDEF_OK : NDEF file data written in the tag.
|
||||
* @retval NDEF_ERROR : not able to store NDEF in tag.
|
||||
* @retval NDEF_ERROR_MEMORY_INTERNAL : Cannot write to tag.
|
||||
* @retval NDEF_ERROR_NOT_FORMATED : CCFile data not supported or not present.
|
||||
* @retval NDEF_ERROR_MEMORY_TAG : Size not compatible with memory.
|
||||
* @retval NDEF_ERROR_LOCKED : Tag locked, cannot be write.
|
||||
*/
|
||||
uint16_t NDEF_WriteSMS( sSMSInfo *pSMSStruct )
|
||||
{
|
||||
uint16_t status = NDEF_ERROR, Offset = 0;
|
||||
|
||||
NDEF_PrepareSMSMessage( pSMSStruct, &NDEF_Buffer[FIRST_RECORD_OFFSET], &Offset );
|
||||
|
||||
/* Write NDEF */
|
||||
NDEF_Buffer[0] = (Offset & 0xFF00) >> 8;
|
||||
NDEF_Buffer[1] = Offset & 0x00FF;
|
||||
|
||||
status = WriteData( 0x00, Offset + FIRST_RECORD_OFFSET, NDEF_Buffer );
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief This function write the NDEF file with the SMS data given in the structure.
|
||||
* @param pSMSStruct : pointer on structure that contain the SMS information.
|
||||
* @param pNDEFMessage : pointer on the NDEF message.
|
||||
* @param size : to store the size of the NDEF message generated.
|
||||
*/
|
||||
void NDEF_PrepareSMSMessage( sSMSInfo *pSMSStruct, uint8_t *pNDEFMessage, uint16_t *size )
|
||||
{
|
||||
uint16_t Offset = 0;
|
||||
uint32_t smsSize = 0;
|
||||
uint32_t infoSize= 0;
|
||||
uint32_t totalSize = 0;
|
||||
|
||||
/* SMS is an URI but can be included in a smart poster to add text to give instruction to user for instance */
|
||||
|
||||
/* SMS (smart poster) Record Header */
|
||||
/************************************/
|
||||
/* 7 | 6 | 5 | 4 | 3 | 2 1 0 */
|
||||
/*----------------------------------*/
|
||||
/* MB ME CF SR IL TNF */ /* <---- CF=0, IL=0 and SR=1 TNF=1 NFC Forum Well-known type*/
|
||||
/*----------------------------------*/
|
||||
/* TYPE LENGTH */
|
||||
/*----------------------------------*/
|
||||
/* PAYLOAD LENGTH 3 */ /* <---- Used only if SR=0 */
|
||||
/*----------------------------------*/
|
||||
/* PAYLOAD LENGTH 2 */ /* <---- Used only if SR=0 */
|
||||
/*----------------------------------*/
|
||||
/* PAYLOAD LENGTH 1 */ /* <---- Used only if SR=0 */
|
||||
/*----------------------------------*/
|
||||
/* PAYLOAD LENGTH 0 */
|
||||
/*----------------------------------*/
|
||||
/* ID LENGTH */ /* <---- Not Used */
|
||||
/*----------------------------------*/
|
||||
/* TYPE */
|
||||
/*----------------------------------*/
|
||||
/* ID */ /* <---- Not Used */
|
||||
/************************************/
|
||||
|
||||
/* SMS : 1+sms:+tel+1+body=+message */
|
||||
smsSize = 1 + SMS_TYPE_STRING_LENGTH + strlen(pSMSStruct->PhoneNumber) + URI_FIRST_DATA_END_LENGTH +
|
||||
MESSAGE_BEGIN_STRING_LENGTH + strlen(pSMSStruct->Message);
|
||||
|
||||
/* Check if a Smart poster is needed */
|
||||
if( pSMSStruct->Information[0] != '\0' )
|
||||
{
|
||||
/* Info : 1+2+info */
|
||||
infoSize = 1 + ISO_ENGLISH_CODE_STRING_LENGTH + strlen(pSMSStruct->Information);
|
||||
/* Total */
|
||||
totalSize = 4 + smsSize + 4 + infoSize;
|
||||
if( smsSize > 255 ) totalSize += 3; /* Normal Email size */
|
||||
if( infoSize > 255 ) totalSize += 3; /* Normal Info size */
|
||||
|
||||
/* SmartPoster header */
|
||||
if( totalSize > 255 )
|
||||
{
|
||||
pNDEFMessage[Offset++] = 0xC1;
|
||||
pNDEFMessage[Offset++] = SMART_POSTER_TYPE_STRING_LENGTH;
|
||||
pNDEFMessage[Offset++] = (totalSize & 0xFF000000) >> 24;
|
||||
pNDEFMessage[Offset++] = (totalSize & 0x00FF0000) >> 16;
|
||||
pNDEFMessage[Offset++] = (totalSize & 0x0000FF00) >> 8;
|
||||
pNDEFMessage[Offset++] = totalSize & 0x000000FF;
|
||||
}
|
||||
else
|
||||
{
|
||||
pNDEFMessage[Offset++] = 0xD1;
|
||||
pNDEFMessage[Offset++] = SMART_POSTER_TYPE_STRING_LENGTH;
|
||||
pNDEFMessage[Offset++] = (uint8_t)totalSize;
|
||||
}
|
||||
memcpy( &pNDEFMessage[Offset], SMART_POSTER_TYPE_STRING, SMART_POSTER_TYPE_STRING_LENGTH );
|
||||
Offset += SMART_POSTER_TYPE_STRING_LENGTH;
|
||||
}
|
||||
|
||||
/* SMS header */
|
||||
pNDEFMessage[Offset] = 0x81;
|
||||
if( smsSize < 256 ) pNDEFMessage[Offset] |= 0x10; // Set the SR bit
|
||||
if( pSMSStruct->Information[0] == '\0' ) pNDEFMessage[Offset] |= 0x40; // Set the ME bit
|
||||
Offset++;
|
||||
|
||||
pNDEFMessage[Offset++] = URI_TYPE_STRING_LENGTH;
|
||||
if( smsSize > 255 )
|
||||
{
|
||||
pNDEFMessage[Offset++] = (smsSize & 0xFF000000) >> 24;
|
||||
pNDEFMessage[Offset++] = (smsSize & 0x00FF0000) >> 16;
|
||||
pNDEFMessage[Offset++] = (smsSize & 0x0000FF00) >> 8;
|
||||
pNDEFMessage[Offset++] = smsSize & 0x000000FF;
|
||||
}
|
||||
else
|
||||
{
|
||||
pNDEFMessage[Offset++] = (uint8_t)smsSize;
|
||||
}
|
||||
memcpy( &pNDEFMessage[Offset], URI_TYPE_STRING, URI_TYPE_STRING_LENGTH );
|
||||
Offset += URI_TYPE_STRING_LENGTH;
|
||||
|
||||
/* SMS payload */
|
||||
pNDEFMessage[Offset++] = URI_ID_0x00;
|
||||
memcpy( &pNDEFMessage[Offset], SMS_TYPE_STRING, SMS_TYPE_STRING_LENGTH );
|
||||
Offset += SMS_TYPE_STRING_LENGTH;
|
||||
memcpy( &pNDEFMessage[Offset], pSMSStruct->PhoneNumber, strlen(pSMSStruct->PhoneNumber) );
|
||||
Offset += strlen( pSMSStruct->PhoneNumber );
|
||||
memcpy( &pNDEFMessage[Offset], URI_FIRST_DATA_END, URI_FIRST_DATA_END_LENGTH );
|
||||
Offset += URI_FIRST_DATA_END_LENGTH;
|
||||
|
||||
memcpy( &pNDEFMessage[Offset], MESSAGE_BEGIN_STRING, MESSAGE_BEGIN_STRING_LENGTH );
|
||||
Offset += MESSAGE_BEGIN_STRING_LENGTH;
|
||||
memcpy( &pNDEFMessage[Offset], pSMSStruct->Message, strlen(pSMSStruct->Message) );
|
||||
Offset += strlen( pSMSStruct->Message );
|
||||
|
||||
/* Information header */
|
||||
if( pSMSStruct->Information[0] != '\0' )
|
||||
{
|
||||
if( infoSize > 255 )
|
||||
{
|
||||
pNDEFMessage[Offset++] = 0x41;
|
||||
pNDEFMessage[Offset++] = TEXT_TYPE_STRING_LENGTH;
|
||||
pNDEFMessage[Offset++] = (infoSize & 0xFF000000) >> 24;
|
||||
pNDEFMessage[Offset++] = (infoSize & 0x00FF0000) >> 16;
|
||||
pNDEFMessage[Offset++] = (infoSize & 0x0000FF00) >> 8;
|
||||
pNDEFMessage[Offset++] = infoSize & 0x000000FF;
|
||||
}
|
||||
else
|
||||
{
|
||||
pNDEFMessage[Offset++] = 0x51;
|
||||
pNDEFMessage[Offset++] = TEXT_TYPE_STRING_LENGTH;
|
||||
pNDEFMessage[Offset++] = (uint8_t)infoSize;
|
||||
}
|
||||
|
||||
memcpy( &pNDEFMessage[Offset], TEXT_TYPE_STRING, TEXT_TYPE_STRING_LENGTH );
|
||||
Offset += TEXT_TYPE_STRING_LENGTH;
|
||||
pNDEFMessage[Offset++] = ISO_ENGLISH_CODE_STRING_LENGTH; /* UTF-8 with x byte language code */
|
||||
memcpy( &pNDEFMessage[Offset], ISO_ENGLISH_CODE_STRING, ISO_ENGLISH_CODE_STRING_LENGTH );
|
||||
Offset += ISO_ENGLISH_CODE_STRING_LENGTH;
|
||||
|
||||
/* Information payload */
|
||||
memcpy( &pNDEFMessage[Offset], pSMSStruct->Information, strlen(pSMSStruct->Information) );
|
||||
Offset += strlen( pSMSStruct->Information );
|
||||
}
|
||||
|
||||
*size = (uint16_t)(Offset);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
//#ifdef __cplusplus
|
||||
//}
|
||||
//#endif
|
||||
|
||||
/******************* (C) COPYRIGHT 2015 STMicroelectronics *****END OF FILE****/
|
||||
62
src/lib_NDEF_SMS.h
Normal file
62
src/lib_NDEF_SMS.h
Normal file
@@ -0,0 +1,62 @@
|
||||
/**
|
||||
******************************************************************************
|
||||
* @file lib_NDEF_SMS.h
|
||||
* @author MMY Application Team
|
||||
* @version $Revision: 1329 $
|
||||
* @date $Date: 2015-11-05 10:34:25 +0100 (Thu, 05 Nov 2015) $
|
||||
* @brief This file help to manage SMS NDEF file.
|
||||
******************************************************************************
|
||||
* @attention
|
||||
*
|
||||
* <h2><center>© COPYRIGHT 2015 STMicroelectronics</center></h2>
|
||||
*
|
||||
* Licensed under ST MYLIBERTY SOFTWARE LICENSE AGREEMENT (the "License");
|
||||
* You may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at:
|
||||
*
|
||||
* http://www.st.com/myliberty
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied,
|
||||
* AND SPECIFICALLY DISCLAIMING THE IMPLIED WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE, AND NON-INFRINGEMENT.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
******************************************************************************
|
||||
*/
|
||||
|
||||
/* Define to prevent recursive inclusion -------------------------------------*/
|
||||
#ifndef __LIB_NDEF_SMS_H
|
||||
#define __LIB_NDEF_SMS_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/* Includes ------------------------------------------------------------------*/
|
||||
#include "lib_NDEF.h"
|
||||
|
||||
|
||||
typedef struct
|
||||
{
|
||||
char PhoneNumber[16];
|
||||
char Message[400];
|
||||
char Information[400];
|
||||
}sSMSInfo;
|
||||
|
||||
/* Struct defined in lib_NDEF.h */
|
||||
typedef struct sRecordInfo sRecordInfo_sms;
|
||||
|
||||
uint16_t NDEF_ReadSMS( sRecordInfo_sms *pRecordStruct, sSMSInfo *pSMSStruct );
|
||||
uint16_t NDEF_WriteSMS( sSMSInfo *pSMSStruct );
|
||||
void NDEF_PrepareSMSMessage( sSMSInfo *pSMSStruct, uint8_t *pNDEFMessage, uint16_t *size );
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* __LIB_NDEF_SMS_H */
|
||||
|
||||
/******************* (C) COPYRIGHT 2015 STMicroelectronics *****END OF FILE****/
|
||||
141
src/lib_NDEF_Text.cpp
Normal file
141
src/lib_NDEF_Text.cpp
Normal file
@@ -0,0 +1,141 @@
|
||||
/**
|
||||
******************************************************************************
|
||||
* @file lib_NDEF_Text.h
|
||||
* @author MMY Application Team
|
||||
* @version $Revision: 1330 $
|
||||
* @date $Date: 2015-11-05 10:39:11 +0100 (Thu, 05 Nov 2015) $
|
||||
* @brief This file help to manage Text NDEF file.
|
||||
******************************************************************************
|
||||
* @attention
|
||||
*
|
||||
* <h2><center>© COPYRIGHT 2015 STMicroelectronics</center></h2>
|
||||
*
|
||||
* Licensed under ST MYLIBERTY SOFTWARE LICENSE AGREEMENT (the "License");
|
||||
* You may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at:
|
||||
*
|
||||
* http://www.st.com/myliberty
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied,
|
||||
* AND SPECIFICALLY DISCLAIMING THE IMPLIED WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE, AND NON-INFRINGEMENT.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
******************************************************************************
|
||||
*/
|
||||
|
||||
//#ifdef __cplusplus
|
||||
// extern "C" {
|
||||
//#endif
|
||||
|
||||
/* Includes ------------------------------------------------------------------*/
|
||||
#include "lib_NDEF_Text.h"
|
||||
|
||||
/** @addtogroup NFC_libraries
|
||||
* @{
|
||||
* @brief <b>This is the library used to manage the content of the TAG (data)
|
||||
* But also the specific feature of the tag, for instance
|
||||
* password, gpo... </b>
|
||||
*/
|
||||
|
||||
|
||||
/** @addtogroup libNFC_FORUM
|
||||
* @{
|
||||
* @brief This part of the library manage data which follow NFC forum organisation.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @brief This buffer contains the data send/received by TAG
|
||||
*/
|
||||
extern uint8_t NDEF_Buffer [];
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/** @defgroup libEmail_Public_Functions
|
||||
* @{
|
||||
* @brief This file is used to manage Email (stored or loaded in tag)
|
||||
*/
|
||||
|
||||
/**
|
||||
* @brief This function write the text in the TAG.
|
||||
* @param text : text to write.
|
||||
* @retval NDEF_OK : NDEF file data written in the tag.
|
||||
* @retval NDEF_ERROR : not able to store NDEF in tag.
|
||||
* @retval NDEF_ERROR_MEMORY_INTERNAL : Cannot write to tag.
|
||||
* @retval NDEF_ERROR_NOT_FORMATED : CCFile data not supported or not present.
|
||||
* @retval NDEF_ERROR_MEMORY_TAG : Size not compatible with memory.
|
||||
* @retval NDEF_ERROR_LOCKED : Tag locked, cannot be write.
|
||||
*/
|
||||
uint16_t NDEF_WriteText( char *text )
|
||||
{
|
||||
uint16_t status = NDEF_ERROR;
|
||||
uint32_t textSize, Offset = 0;
|
||||
|
||||
NDEF_Buffer[0] = 0;
|
||||
NDEF_Buffer[1] = 0;
|
||||
Offset = FIRST_RECORD_OFFSET;
|
||||
|
||||
/* TEXT : 1+en+message */
|
||||
textSize = 3 + strlen(text);
|
||||
|
||||
/* TEXT header */
|
||||
NDEF_Buffer[Offset] = 0xD1;
|
||||
if( textSize < 256 ) NDEF_Buffer[Offset] |= 0x10; // Set the SR bit
|
||||
Offset++;
|
||||
|
||||
NDEF_Buffer[Offset++] = TEXT_TYPE_STRING_LENGTH;
|
||||
if( textSize > 255 )
|
||||
{
|
||||
NDEF_Buffer[Offset++] = (textSize & 0xFF000000) >> 24;
|
||||
NDEF_Buffer[Offset++] = (textSize & 0x00FF0000) >> 16;
|
||||
NDEF_Buffer[Offset++] = (textSize & 0x0000FF00) >> 8;
|
||||
NDEF_Buffer[Offset++] = textSize & 0x000000FF;
|
||||
}
|
||||
else
|
||||
{
|
||||
NDEF_Buffer[Offset++] = (uint8_t)textSize;
|
||||
}
|
||||
memcpy( &NDEF_Buffer[Offset], TEXT_TYPE_STRING, TEXT_TYPE_STRING_LENGTH );
|
||||
Offset += TEXT_TYPE_STRING_LENGTH;
|
||||
|
||||
/* TEXT payload */
|
||||
NDEF_Buffer[Offset++] = ISO_ENGLISH_CODE_STRING_LENGTH;
|
||||
memcpy( &NDEF_Buffer[Offset], ISO_ENGLISH_CODE_STRING, ISO_ENGLISH_CODE_STRING_LENGTH );
|
||||
Offset += ISO_ENGLISH_CODE_STRING_LENGTH;
|
||||
|
||||
memcpy( &NDEF_Buffer[Offset], text, strlen(text) );
|
||||
Offset += strlen(text);
|
||||
|
||||
Offset -= 2; /* Must not count the 2 byte that represent the NDEF size */
|
||||
NDEF_Buffer[0] = (Offset & 0xFF00) >> 8;
|
||||
NDEF_Buffer[1] = Offset & 0x00FF;
|
||||
|
||||
status = WriteData( 0x00, Offset + 2, NDEF_Buffer );
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
//#ifdef __cplusplus
|
||||
//}
|
||||
//#endif
|
||||
|
||||
/******************* (C) COPYRIGHT 2015 STMicroelectronics *****END OF FILE****/
|
||||
49
src/lib_NDEF_Text.h
Normal file
49
src/lib_NDEF_Text.h
Normal file
@@ -0,0 +1,49 @@
|
||||
/**
|
||||
******************************************************************************
|
||||
* @file lib_NDEF_Text.h
|
||||
* @author MMY Application Team
|
||||
* @version $Revision: 1329 $
|
||||
* @date $Date: 2015-11-05 10:34:25 +0100 (Thu, 05 Nov 2015) $
|
||||
* @brief This file help to manage Text NDEF file.
|
||||
******************************************************************************
|
||||
* @attention
|
||||
*
|
||||
* <h2><center>© COPYRIGHT 2015 STMicroelectronics</center></h2>
|
||||
*
|
||||
* Licensed under ST MYLIBERTY SOFTWARE LICENSE AGREEMENT (the "License");
|
||||
* You may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at:
|
||||
*
|
||||
* http://www.st.com/myliberty
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied,
|
||||
* AND SPECIFICALLY DISCLAIMING THE IMPLIED WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE, AND NON-INFRINGEMENT.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
******************************************************************************
|
||||
*/
|
||||
|
||||
/* Define to prevent recursive inclusion -------------------------------------*/
|
||||
#ifndef __LIB_NDEF_TEXT_H
|
||||
#define __LIB_NDEF_TEXT_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/* Includes ------------------------------------------------------------------*/
|
||||
#include "lib_NDEF.h"
|
||||
|
||||
uint16_t NDEF_WriteText( char *text );
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* __LIB_NDEF_TEXT_H */
|
||||
|
||||
/******************* (C) COPYRIGHT 2015 STMicroelectronics *****END OF FILE****/
|
||||
554
src/lib_NDEF_URI.cpp
Normal file
554
src/lib_NDEF_URI.cpp
Normal file
@@ -0,0 +1,554 @@
|
||||
/**
|
||||
******************************************************************************
|
||||
* @file lib_NDEF_URI.c
|
||||
* @author MMY Application Team
|
||||
* @version $Revision: 1330 $
|
||||
* @date $Date: 2015-11-05 10:39:11 +0100 (Thu, 05 Nov 2015) $
|
||||
* @brief This file help to manage NDEF file that represent URI.
|
||||
******************************************************************************
|
||||
* @attention
|
||||
*
|
||||
* <h2><center>© COPYRIGHT 2015 STMicroelectronics</center></h2>
|
||||
*
|
||||
* Licensed under ST MYLIBERTY SOFTWARE LICENSE AGREEMENT (the "License");
|
||||
* You may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at:
|
||||
*
|
||||
* http://www.st.com/myliberty
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied,
|
||||
* AND SPECIFICALLY DISCLAIMING THE IMPLIED WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE, AND NON-INFRINGEMENT.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
******************************************************************************
|
||||
*/
|
||||
|
||||
//#ifdef __cplusplus
|
||||
// extern "C" {
|
||||
//#endif
|
||||
|
||||
/* Includes ------------------------------------------------------------------*/
|
||||
#include "lib_NDEF_URI.h"
|
||||
|
||||
/** @addtogroup NFC_libraries
|
||||
* @{
|
||||
* @brief <b>This is the library used to manage the content of the TAG (data)
|
||||
* But also the specific feature of the tag, for instance
|
||||
* password, gpo... </b>
|
||||
*/
|
||||
|
||||
|
||||
/** @addtogroup libNFC_FORUM
|
||||
* @{
|
||||
* @brief This part of the library manage data which follow NFC forum organisation.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @brief This buffer contains the data send/received by TAG
|
||||
*/
|
||||
extern uint8_t NDEF_Buffer [];
|
||||
|
||||
/** @defgroup libURI_Private_Functions
|
||||
* @{
|
||||
*/
|
||||
|
||||
static void NDEF_Parse_WellKnowType( sRecordInfo_uri *pRecordStruct, sURI_Info* pURI );
|
||||
|
||||
/**
|
||||
* @brief This function read the URI information and store data in a structure.
|
||||
* @param pRecordStruct : Pointer on the record structure.
|
||||
* @param pURI : pointer on the structure to fill.
|
||||
*/
|
||||
static void NDEF_Parse_WellKnowType( sRecordInfo_uri *pRecordStruct, sURI_Info* pURI )
|
||||
{
|
||||
uint32_t PayloadSize;
|
||||
uint8_t Offset;
|
||||
uint8_t* pPayload;
|
||||
|
||||
pPayload = (uint8_t*)(pRecordStruct->PayloadBufferAdd);
|
||||
|
||||
switch( *pPayload )
|
||||
{
|
||||
case URI_ID_0x01:
|
||||
memcpy( pURI->protocol, URI_ID_0x01_STRING, strlen(URI_ID_0x01_STRING) );
|
||||
Offset = strlen( URI_ID_0x01_STRING );
|
||||
break;
|
||||
|
||||
case URI_ID_0x02:
|
||||
memcpy( pURI->protocol, URI_ID_0x02_STRING, strlen(URI_ID_0x02_STRING) );
|
||||
Offset = strlen( URI_ID_0x02_STRING );
|
||||
break;
|
||||
|
||||
case URI_ID_0x03:
|
||||
memcpy( pURI->protocol, URI_ID_0x03_STRING, strlen(URI_ID_0x03_STRING) );
|
||||
Offset = strlen( URI_ID_0x03_STRING );
|
||||
break;
|
||||
|
||||
case URI_ID_0x04:
|
||||
memcpy( pURI->protocol, URI_ID_0x04_STRING, strlen(URI_ID_0x04_STRING) );
|
||||
Offset = strlen( URI_ID_0x04_STRING );
|
||||
break;
|
||||
|
||||
case URI_ID_0x05:
|
||||
memcpy( pURI->protocol, URI_ID_0x05_STRING, strlen(URI_ID_0x05_STRING) );
|
||||
Offset = strlen( URI_ID_0x05_STRING );
|
||||
break;
|
||||
|
||||
case URI_ID_0x06:
|
||||
memcpy( pURI->protocol, URI_ID_0x06_STRING, strlen(URI_ID_0x06_STRING) );
|
||||
Offset = strlen( URI_ID_0x06_STRING );
|
||||
break;
|
||||
|
||||
case URI_ID_0x07:
|
||||
memcpy( pURI->protocol, URI_ID_0x07_STRING, strlen(URI_ID_0x07_STRING) );
|
||||
Offset = strlen( URI_ID_0x07_STRING );
|
||||
break;
|
||||
|
||||
case URI_ID_0x08:
|
||||
memcpy( pURI->protocol, URI_ID_0x08_STRING, strlen(URI_ID_0x08_STRING) );
|
||||
Offset = strlen( URI_ID_0x08_STRING );
|
||||
break;
|
||||
|
||||
case URI_ID_0x09:
|
||||
memcpy( pURI->protocol, URI_ID_0x09_STRING, strlen(URI_ID_0x09_STRING) );
|
||||
Offset = strlen( URI_ID_0x09_STRING );
|
||||
break;
|
||||
|
||||
case URI_ID_0x0A:
|
||||
memcpy( pURI->protocol, URI_ID_0x0A_STRING, strlen(URI_ID_0x0A_STRING) );
|
||||
Offset = strlen( URI_ID_0x0A_STRING );
|
||||
break;
|
||||
|
||||
case URI_ID_0x0B:
|
||||
memcpy( pURI->protocol, URI_ID_0x0B_STRING, strlen(URI_ID_0x0B_STRING) );
|
||||
Offset = strlen( URI_ID_0x0B_STRING );
|
||||
break;
|
||||
|
||||
case URI_ID_0x0C:
|
||||
memcpy( pURI->protocol, URI_ID_0x0C_STRING, strlen(URI_ID_0x0C_STRING) );
|
||||
Offset = strlen( URI_ID_0x0C_STRING );
|
||||
break;
|
||||
|
||||
case URI_ID_0x0D:
|
||||
memcpy( pURI->protocol, URI_ID_0x0D_STRING, strlen(URI_ID_0x0D_STRING) );
|
||||
Offset = strlen( URI_ID_0x0D_STRING );
|
||||
break;
|
||||
|
||||
case URI_ID_0x0E:
|
||||
memcpy( pURI->protocol, URI_ID_0x0E_STRING, strlen(URI_ID_0x0E_STRING) );
|
||||
Offset = strlen( URI_ID_0x0E_STRING );
|
||||
break;
|
||||
|
||||
case URI_ID_0x0F:
|
||||
memcpy( pURI->protocol, URI_ID_0x0F_STRING, strlen(URI_ID_0x0F_STRING) );
|
||||
Offset = strlen( URI_ID_0x0F_STRING );
|
||||
break;
|
||||
|
||||
case URI_ID_0x10:
|
||||
memcpy( pURI->protocol, URI_ID_0x10_STRING, strlen(URI_ID_0x10_STRING) );
|
||||
Offset = strlen( URI_ID_0x10_STRING );
|
||||
break;
|
||||
|
||||
case URI_ID_0x11:
|
||||
memcpy( pURI->protocol, URI_ID_0x11_STRING, strlen(URI_ID_0x11_STRING) );
|
||||
Offset = strlen( URI_ID_0x11_STRING );
|
||||
break;
|
||||
|
||||
case URI_ID_0x12:
|
||||
memcpy( pURI->protocol, URI_ID_0x12_STRING, strlen(URI_ID_0x12_STRING) );
|
||||
Offset = strlen( URI_ID_0x12_STRING );
|
||||
break;
|
||||
|
||||
case URI_ID_0x13:
|
||||
memcpy( pURI->protocol, URI_ID_0x13_STRING, strlen(URI_ID_0x13_STRING) );
|
||||
Offset = strlen( URI_ID_0x13_STRING );
|
||||
break;
|
||||
|
||||
case URI_ID_0x14:
|
||||
memcpy( pURI->protocol, URI_ID_0x14_STRING, strlen(URI_ID_0x14_STRING) );
|
||||
Offset = strlen( URI_ID_0x14_STRING );
|
||||
break;
|
||||
|
||||
case URI_ID_0x15:
|
||||
memcpy( pURI->protocol, URI_ID_0x15_STRING, strlen(URI_ID_0x15_STRING) );
|
||||
Offset = strlen( URI_ID_0x15_STRING );
|
||||
break;
|
||||
|
||||
case URI_ID_0x16:
|
||||
memcpy( pURI->protocol, URI_ID_0x16_STRING, strlen(URI_ID_0x16_STRING) );
|
||||
Offset = strlen( URI_ID_0x16_STRING );
|
||||
break;
|
||||
|
||||
case URI_ID_0x17:
|
||||
memcpy( pURI->protocol, URI_ID_0x17_STRING, strlen(URI_ID_0x17_STRING) );
|
||||
Offset = strlen( URI_ID_0x17_STRING );
|
||||
break;
|
||||
|
||||
case URI_ID_0x18:
|
||||
memcpy( pURI->protocol, URI_ID_0x18_STRING, strlen(URI_ID_0x18_STRING) );
|
||||
Offset = strlen( URI_ID_0x18_STRING );
|
||||
break;
|
||||
|
||||
case URI_ID_0x19:
|
||||
memcpy( pURI->protocol, URI_ID_0x19_STRING, strlen(URI_ID_0x19_STRING) );
|
||||
Offset = strlen( URI_ID_0x19_STRING );
|
||||
break;
|
||||
|
||||
case URI_ID_0x1A:
|
||||
memcpy( pURI->protocol, URI_ID_0x1A_STRING, strlen(URI_ID_0x1A_STRING) );
|
||||
Offset = strlen( URI_ID_0x1A_STRING );
|
||||
break;
|
||||
|
||||
case URI_ID_0x1B:
|
||||
memcpy( pURI->protocol, URI_ID_0x1B_STRING, strlen(URI_ID_0x1B_STRING) );
|
||||
Offset = strlen( URI_ID_0x1B_STRING );
|
||||
break;
|
||||
|
||||
case URI_ID_0x1C:
|
||||
memcpy( pURI->protocol, URI_ID_0x1C_STRING, strlen(URI_ID_0x1C_STRING) );
|
||||
Offset = strlen( URI_ID_0x1C_STRING );
|
||||
break;
|
||||
|
||||
case URI_ID_0x1D:
|
||||
memcpy( pURI->protocol, URI_ID_0x1D_STRING, strlen(URI_ID_0x1D_STRING) );
|
||||
Offset = strlen( URI_ID_0x1D_STRING );
|
||||
break;
|
||||
|
||||
case URI_ID_0x1E:
|
||||
memcpy( pURI->protocol, URI_ID_0x1E_STRING, strlen(URI_ID_0x1E_STRING) );
|
||||
Offset = strlen( URI_ID_0x1E_STRING );
|
||||
break;
|
||||
|
||||
case URI_ID_0x1F:
|
||||
memcpy( pURI->protocol, URI_ID_0x1F_STRING, strlen(URI_ID_0x1F_STRING) );
|
||||
Offset = strlen( URI_ID_0x1F_STRING );
|
||||
break;
|
||||
|
||||
case URI_ID_0x20:
|
||||
memcpy( pURI->protocol, URI_ID_0x20_STRING, strlen(URI_ID_0x20_STRING) );
|
||||
Offset = strlen( URI_ID_0x20_STRING );
|
||||
break;
|
||||
|
||||
case URI_ID_0x21:
|
||||
memcpy( pURI->protocol, URI_ID_0x21_STRING, strlen(URI_ID_0x21_STRING) );
|
||||
Offset = strlen( URI_ID_0x21_STRING );
|
||||
break;
|
||||
|
||||
case URI_ID_0x22:
|
||||
memcpy( pURI->protocol, URI_ID_0x22_STRING, strlen(URI_ID_0x22_STRING) );
|
||||
Offset = strlen( URI_ID_0x22_STRING );
|
||||
break;
|
||||
|
||||
case URI_ID_0x23:
|
||||
memcpy( pURI->protocol, URI_ID_0x23_STRING, strlen(URI_ID_0x23_STRING) );
|
||||
Offset = strlen( URI_ID_0x23_STRING );
|
||||
break;
|
||||
|
||||
default:
|
||||
Offset = 0;
|
||||
/* Should not happened */
|
||||
break;
|
||||
}
|
||||
/* add end of string character */
|
||||
pURI->protocol[Offset] = '\0';
|
||||
|
||||
pPayload++; /* go after well know byte */
|
||||
|
||||
PayloadSize = ((uint32_t)(pRecordStruct->PayloadLength3) << 24) | ((uint32_t)(pRecordStruct->PayloadLength2) << 16) |
|
||||
((uint32_t)(pRecordStruct->PayloadLength1) << 8) | pRecordStruct->PayloadLength0;
|
||||
|
||||
PayloadSize = PayloadSize - 1; /* remove well know byte */
|
||||
|
||||
memcpy( pURI->URI_Message, pPayload, PayloadSize );
|
||||
/* add end of string character */
|
||||
pURI->URI_Message[PayloadSize] = '\0';
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/** @defgroup libURI_Public_Functions
|
||||
* @{
|
||||
* @brief This file is used to manage URI (stored or loaded in tag)
|
||||
*/
|
||||
|
||||
/**
|
||||
* @brief This function read NDEF and retrieve URI information if any.
|
||||
* @param pRecordStruct : Pointer on the record structure.
|
||||
* @param pURI : pointer on the structure to fill.
|
||||
* @retval NDEF_OK : URI information from NDEF have been retrieved.
|
||||
* @retval NDEF_ERROR : Not able to retrieve URI information.
|
||||
*/
|
||||
uint16_t NDEF_ReadURI( sRecordInfo_uri *pRecordStruct, sURI_Info *pURI )
|
||||
{
|
||||
uint16_t status = NDEF_ERROR;
|
||||
sRecordInfo_uri *pSPRecordStruct;
|
||||
uint32_t PayloadSize, RecordPosition;
|
||||
uint8_t* pData;
|
||||
|
||||
if( pRecordStruct->NDEF_Type == WELL_KNOWN_ABRIDGED_URI_TYPE )
|
||||
{
|
||||
NDEF_Parse_WellKnowType( pRecordStruct, pURI );
|
||||
status = NDEF_OK;
|
||||
}
|
||||
else if( pRecordStruct->NDEF_Type == SMARTPOSTER_TYPE )
|
||||
{
|
||||
for( RecordPosition = 0; RecordPosition < pRecordStruct->NbOfRecordInSPPayload; RecordPosition++ )
|
||||
{
|
||||
pSPRecordStruct = pRecordStruct->SPRecordStructAdd[RecordPosition];
|
||||
if( pSPRecordStruct->NDEF_Type == WELL_KNOWN_ABRIDGED_URI_TYPE )
|
||||
{
|
||||
NDEF_Parse_WellKnowType( pSPRecordStruct, pURI );
|
||||
status = NDEF_OK;
|
||||
}
|
||||
if( pSPRecordStruct->NDEF_Type == TEXT_TYPE )
|
||||
{
|
||||
PayloadSize = ((uint32_t)(pSPRecordStruct->PayloadLength3) << 24) | ((uint32_t)(pSPRecordStruct->PayloadLength2) << 16) |
|
||||
((uint32_t)(pSPRecordStruct->PayloadLength1) << 8) | pSPRecordStruct->PayloadLength0;
|
||||
|
||||
/* The instruction content the UTF-8 language code that is not used here */
|
||||
pData = (uint8_t*)pSPRecordStruct->PayloadBufferAdd;
|
||||
PayloadSize -= *pData + 1; /* remove not usefull data */
|
||||
pData += *pData + 1;
|
||||
|
||||
memcpy( pURI->Information, pData, PayloadSize );
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
status = NDEF_ERROR;
|
||||
}
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief This function prepare the NDEF message with the URI data given in the structure.
|
||||
* @param pURI : pointer on structure that contain the URI information.
|
||||
* @param pNDEFMessage : pointer on the NDEF message.
|
||||
* @param size : to store the size of the NDEF message generated.
|
||||
*/
|
||||
void NDEF_PrepareURIMessage( sURI_Info *pURI, uint8_t *pNDEFMessage, uint16_t *size )
|
||||
{
|
||||
uint32_t uriSize, totalSize, Offset = 0;
|
||||
uint32_t infoSize = 0;
|
||||
char type;
|
||||
|
||||
/* An URI can be included in a smart poster to add text to give instruction to user for instance */
|
||||
|
||||
/* URI (smart poster) Record Header */
|
||||
/************************************/
|
||||
/* 7 | 6 | 5 | 4 | 3 | 2 1 0 */
|
||||
/*----------------------------------*/
|
||||
/* MB ME CF SR IL TNF */ /* <---- CF=0, IL=0 and SR=1 TNF=1 NFC Forum Well-known type*/
|
||||
/*----------------------------------*/
|
||||
/* TYPE LENGTH */
|
||||
/*----------------------------------*/
|
||||
/* PAYLOAD LENGTH 3 */ /* <---- Used only if SR=0 */
|
||||
/*----------------------------------*/
|
||||
/* PAYLOAD LENGTH 2 */ /* <---- Used only if SR=0 */
|
||||
/*----------------------------------*/
|
||||
/* PAYLOAD LENGTH 1 */ /* <---- Used only if SR=0 */
|
||||
/*----------------------------------*/
|
||||
/* PAYLOAD LENGTH 0 */
|
||||
/*----------------------------------*/
|
||||
/* ID LENGTH */ /* <---- Not Used */
|
||||
/*----------------------------------*/
|
||||
/* TYPE */
|
||||
/*----------------------------------*/
|
||||
/* ID */ /* <---- Not Used */
|
||||
/************************************/
|
||||
|
||||
/* We need to know the URI type in order to define if an abreviation is available */
|
||||
type = getUriType( pURI->protocol );
|
||||
|
||||
/* URI : 1+URI for abreviate protocol*/
|
||||
if( type != URI_ID_0x00 )
|
||||
uriSize = 1 + strlen(pURI->URI_Message);
|
||||
else /*: 1+protocol+URI else*/
|
||||
uriSize = 1 + strlen(pURI->protocol) + strlen(pURI->URI_Message);
|
||||
|
||||
/* Check if a Smart poster is needed */
|
||||
if( pURI->Information[0] != '\0' )
|
||||
{
|
||||
/* Info : 1+2+info */
|
||||
infoSize = 1 + ISO_ENGLISH_CODE_STRING_LENGTH + strlen(pURI->Information);
|
||||
/* Total */
|
||||
totalSize = 4 + uriSize + 4 + infoSize;
|
||||
if( uriSize > 255 ) totalSize += 3; /* Normal URI size */
|
||||
if( infoSize > 255 ) totalSize += 3; /* Normal Info size */
|
||||
|
||||
/* SmartPoster header */
|
||||
if( totalSize > 255 )
|
||||
{
|
||||
pNDEFMessage[Offset++] = 0xC1;
|
||||
pNDEFMessage[Offset++] = SMART_POSTER_TYPE_STRING_LENGTH;
|
||||
pNDEFMessage[Offset++] = (totalSize & 0xFF000000) >> 24;
|
||||
pNDEFMessage[Offset++] = (totalSize & 0x00FF0000) >> 16;
|
||||
pNDEFMessage[Offset++] = (totalSize & 0x0000FF00) >> 8;
|
||||
pNDEFMessage[Offset++] = totalSize & 0x000000FF;
|
||||
}
|
||||
else
|
||||
{
|
||||
pNDEFMessage[Offset++] = 0xD1;
|
||||
pNDEFMessage[Offset++] = SMART_POSTER_TYPE_STRING_LENGTH;
|
||||
pNDEFMessage[Offset++] = (uint8_t)totalSize;
|
||||
}
|
||||
memcpy( &pNDEFMessage[Offset], SMART_POSTER_TYPE_STRING, SMART_POSTER_TYPE_STRING_LENGTH );
|
||||
Offset += SMART_POSTER_TYPE_STRING_LENGTH;
|
||||
}
|
||||
|
||||
/* URI header */
|
||||
pNDEFMessage[Offset] = 0x81;
|
||||
if( uriSize < 256 ) pNDEFMessage[Offset] |= 0x10; // Set the SR bit
|
||||
if( pURI->Information[0] == '\0' ) pNDEFMessage[Offset] |= 0x40; // Set the ME bit
|
||||
Offset++;
|
||||
|
||||
pNDEFMessage[Offset++] = URI_TYPE_STRING_LENGTH;
|
||||
if( uriSize > 255 )
|
||||
{
|
||||
pNDEFMessage[Offset++] = (uriSize & 0xFF000000) >> 24;
|
||||
pNDEFMessage[Offset++] = (uriSize & 0x00FF0000) >> 16;
|
||||
pNDEFMessage[Offset++] = (uriSize & 0x0000FF00) >> 8;
|
||||
pNDEFMessage[Offset++] = uriSize & 0x000000FF;
|
||||
}
|
||||
else
|
||||
{
|
||||
pNDEFMessage[Offset++] = (uint8_t)uriSize;
|
||||
}
|
||||
memcpy( &pNDEFMessage[Offset], URI_TYPE_STRING, URI_TYPE_STRING_LENGTH );
|
||||
Offset += URI_TYPE_STRING_LENGTH;
|
||||
|
||||
pNDEFMessage[Offset++] = type;
|
||||
if( type == URI_ID_0x00 ) // No abreviation
|
||||
{
|
||||
memcpy( &pNDEFMessage[Offset], pURI->protocol, strlen(pURI->protocol) );
|
||||
Offset += strlen(pURI->protocol);
|
||||
}
|
||||
|
||||
memcpy( &pNDEFMessage[Offset], pURI->URI_Message, strlen(pURI->URI_Message) );
|
||||
Offset += strlen(pURI->URI_Message);
|
||||
|
||||
/* Information header */
|
||||
if( pURI->Information[0] != '\0' )
|
||||
{
|
||||
if( infoSize > 255 )
|
||||
{
|
||||
pNDEFMessage[Offset++] = 0x41;
|
||||
pNDEFMessage[Offset++] = TEXT_TYPE_STRING_LENGTH;
|
||||
pNDEFMessage[Offset++] = (infoSize & 0xFF000000) >> 24;
|
||||
pNDEFMessage[Offset++] = (infoSize & 0x00FF0000) >> 16;
|
||||
pNDEFMessage[Offset++] = (infoSize & 0x0000FF00) >> 8;
|
||||
pNDEFMessage[Offset++] = infoSize & 0x000000FF;
|
||||
}
|
||||
else
|
||||
{
|
||||
pNDEFMessage[Offset++] = 0x51;
|
||||
pNDEFMessage[Offset++] = TEXT_TYPE_STRING_LENGTH;
|
||||
pNDEFMessage[Offset++] = (uint8_t)infoSize;
|
||||
}
|
||||
|
||||
memcpy( &pNDEFMessage[Offset], TEXT_TYPE_STRING, TEXT_TYPE_STRING_LENGTH );
|
||||
Offset+=TEXT_TYPE_STRING_LENGTH;
|
||||
pNDEFMessage[Offset++] = ISO_ENGLISH_CODE_STRING_LENGTH; /* UTF-8 with x byte language code */
|
||||
memcpy( &pNDEFMessage[Offset], ISO_ENGLISH_CODE_STRING, ISO_ENGLISH_CODE_STRING_LENGTH );
|
||||
Offset += ISO_ENGLISH_CODE_STRING_LENGTH;
|
||||
|
||||
/* Information payload */
|
||||
memcpy( &pNDEFMessage[Offset], pURI->Information, strlen(pURI->Information) );
|
||||
Offset += strlen(pURI->Information);
|
||||
}
|
||||
|
||||
*size = Offset;
|
||||
|
||||
}
|
||||
/**
|
||||
* @brief This function write the NDEF file with the URI data given in the structure.
|
||||
* @param pURI : pointer on structure that contain the URI information.
|
||||
* @retval NDEF_OK : NDEF file data written in the tag.
|
||||
* @retval NDEF_ERROR : not able to store NDEF in tag.
|
||||
* @retval NDEF_ERROR_MEMORY_INTERNAL : Cannot write to tag.
|
||||
* @retval NDEF_ERROR_NOT_FORMATED : CCFile data not supported or not present.
|
||||
* @retval NDEF_ERROR_MEMORY_TAG : Size not compatible with memory.
|
||||
* @retval NDEF_ERROR_LOCKED : Tag locked, cannot be write.
|
||||
*/
|
||||
uint16_t NDEF_WriteURI( sURI_Info *pURI )
|
||||
{
|
||||
uint16_t status = NDEF_ERROR, Offset = 0;
|
||||
|
||||
NDEF_PrepareURIMessage( pURI, &NDEF_Buffer[FIRST_RECORD_OFFSET], &Offset );
|
||||
|
||||
/* Write NDEF */
|
||||
NDEF_Buffer[0] = (Offset & 0xFF00) >> 8;
|
||||
NDEF_Buffer[1] = Offset & 0x00FF;
|
||||
|
||||
status = WriteData( 0x00, Offset + FIRST_RECORD_OFFSET, NDEF_Buffer );
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
char getUriType( char *protocol )
|
||||
{
|
||||
if( !memcmp( protocol, URI_ID_0x01_STRING, strlen(URI_ID_0x01_STRING) ) ) return URI_ID_0x01;
|
||||
else if( !memcmp( protocol, URI_ID_0x02_STRING, strlen(URI_ID_0x02_STRING) ) ) return URI_ID_0x02;
|
||||
else if( !memcmp( protocol, URI_ID_0x03_STRING, strlen(URI_ID_0x03_STRING) ) ) return URI_ID_0x03;
|
||||
else if( !memcmp( protocol, URI_ID_0x04_STRING, strlen(URI_ID_0x04_STRING) ) ) return URI_ID_0x04;
|
||||
else if( !memcmp( protocol, URI_ID_0x05_STRING, strlen(URI_ID_0x05_STRING) ) ) return URI_ID_0x05;
|
||||
else if( !memcmp( protocol, URI_ID_0x06_STRING, strlen(URI_ID_0x06_STRING) ) ) return URI_ID_0x06;
|
||||
else if( !memcmp( protocol, URI_ID_0x07_STRING, strlen(URI_ID_0x07_STRING) ) ) return URI_ID_0x07;
|
||||
else if( !memcmp( protocol, URI_ID_0x08_STRING, strlen(URI_ID_0x08_STRING) ) ) return URI_ID_0x08;
|
||||
else if( !memcmp( protocol, URI_ID_0x09_STRING, strlen(URI_ID_0x09_STRING) ) ) return URI_ID_0x09;
|
||||
else if( !memcmp( protocol, URI_ID_0x0A_STRING, strlen(URI_ID_0x0A_STRING) ) ) return URI_ID_0x0A;
|
||||
else if( !memcmp( protocol, URI_ID_0x0B_STRING, strlen(URI_ID_0x0B_STRING) ) ) return URI_ID_0x0B;
|
||||
else if( !memcmp( protocol, URI_ID_0x0C_STRING, strlen(URI_ID_0x0C_STRING) ) ) return URI_ID_0x0C;
|
||||
else if( !memcmp( protocol, URI_ID_0x0D_STRING, strlen(URI_ID_0x0D_STRING) ) ) return URI_ID_0x0D;
|
||||
else if( !memcmp( protocol, URI_ID_0x0E_STRING, strlen(URI_ID_0x0E_STRING) ) ) return URI_ID_0x0E;
|
||||
else if( !memcmp( protocol, URI_ID_0x0F_STRING, strlen(URI_ID_0x0F_STRING) ) ) return URI_ID_0x0F;
|
||||
else if( !memcmp( protocol, URI_ID_0x10_STRING, strlen(URI_ID_0x10_STRING) ) ) return URI_ID_0x10;
|
||||
else if( !memcmp( protocol, URI_ID_0x11_STRING, strlen(URI_ID_0x11_STRING) ) ) return URI_ID_0x11;
|
||||
else if( !memcmp( protocol, URI_ID_0x12_STRING, strlen(URI_ID_0x12_STRING) ) ) return URI_ID_0x12;
|
||||
else if( !memcmp( protocol, URI_ID_0x13_STRING, strlen(URI_ID_0x13_STRING) ) ) return URI_ID_0x13;
|
||||
else if( !memcmp( protocol, URI_ID_0x14_STRING, strlen(URI_ID_0x14_STRING) ) ) return URI_ID_0x14;
|
||||
else if( !memcmp( protocol, URI_ID_0x15_STRING, strlen(URI_ID_0x15_STRING) ) ) return URI_ID_0x15;
|
||||
else if( !memcmp( protocol, URI_ID_0x16_STRING, strlen(URI_ID_0x16_STRING) ) ) return URI_ID_0x16;
|
||||
else if( !memcmp( protocol, URI_ID_0x17_STRING, strlen(URI_ID_0x17_STRING) ) ) return URI_ID_0x17;
|
||||
else if( !memcmp( protocol, URI_ID_0x18_STRING, strlen(URI_ID_0x18_STRING) ) ) return URI_ID_0x18;
|
||||
else if( !memcmp( protocol, URI_ID_0x19_STRING, strlen(URI_ID_0x19_STRING) ) ) return URI_ID_0x19;
|
||||
else if( !memcmp( protocol, URI_ID_0x1A_STRING, strlen(URI_ID_0x1A_STRING) ) ) return URI_ID_0x1A;
|
||||
else if( !memcmp( protocol, URI_ID_0x1B_STRING, strlen(URI_ID_0x1B_STRING) ) ) return URI_ID_0x1B;
|
||||
else if( !memcmp( protocol, URI_ID_0x1C_STRING, strlen(URI_ID_0x1C_STRING) ) ) return URI_ID_0x1C;
|
||||
else if( !memcmp( protocol, URI_ID_0x1D_STRING, strlen(URI_ID_0x1D_STRING) ) ) return URI_ID_0x1D;
|
||||
else if( !memcmp( protocol, URI_ID_0x1E_STRING, strlen(URI_ID_0x1E_STRING) ) ) return URI_ID_0x1E;
|
||||
else if( !memcmp( protocol, URI_ID_0x1F_STRING, strlen(URI_ID_0x1F_STRING) ) ) return URI_ID_0x1F;
|
||||
else if( !memcmp( protocol, URI_ID_0x20_STRING, strlen(URI_ID_0x20_STRING) ) ) return URI_ID_0x20;
|
||||
else if( !memcmp( protocol, URI_ID_0x21_STRING, strlen(URI_ID_0x21_STRING) ) ) return URI_ID_0x21;
|
||||
else if( !memcmp( protocol, URI_ID_0x22_STRING, strlen(URI_ID_0x22_STRING) ) ) return URI_ID_0x22;
|
||||
else if( !memcmp( protocol, URI_ID_0x23_STRING, strlen(URI_ID_0x23_STRING) ) ) return URI_ID_0x23;
|
||||
else return URI_ID_0x00; // No abreviation for this protocol
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
//#ifdef __cplusplus
|
||||
//}
|
||||
//#endif
|
||||
|
||||
/******************* (C) COPYRIGHT 2015 STMicroelectronics *****END OF FILE****/
|
||||
62
src/lib_NDEF_URI.h
Normal file
62
src/lib_NDEF_URI.h
Normal file
@@ -0,0 +1,62 @@
|
||||
/**
|
||||
******************************************************************************
|
||||
* @file lib_NDEF_URI.h
|
||||
* @author MMY Application Team
|
||||
* @version $Revision: 1329 $
|
||||
* @date $Date: 2015-11-05 10:34:25 +0100 (Thu, 05 Nov 2015) $
|
||||
* @brief This file help to manage URI NDEF file.
|
||||
******************************************************************************
|
||||
* @attention
|
||||
*
|
||||
* <h2><center>© COPYRIGHT 2015 STMicroelectronics</center></h2>
|
||||
*
|
||||
* Licensed under ST MYLIBERTY SOFTWARE LICENSE AGREEMENT (the "License");
|
||||
* You may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at:
|
||||
*
|
||||
* http://www.st.com/myliberty
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied,
|
||||
* AND SPECIFICALLY DISCLAIMING THE IMPLIED WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE, AND NON-INFRINGEMENT.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
******************************************************************************
|
||||
*/
|
||||
|
||||
/* Define to prevent recursive inclusion -------------------------------------*/
|
||||
#ifndef __LIB_NDEF_URI_H
|
||||
#define __LIB_NDEF_URI_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/* Includes ------------------------------------------------------------------*/
|
||||
#include "lib_NDEF.h"
|
||||
|
||||
typedef struct
|
||||
{
|
||||
char protocol[80];
|
||||
char URI_Message[400];
|
||||
char Information[400];
|
||||
}sURI_Info;
|
||||
|
||||
typedef struct sRecordInfo sRecordInfo_uri;
|
||||
|
||||
uint16_t NDEF_ReadURI(sRecordInfo_uri *pRecordStruct, sURI_Info *pURI);
|
||||
uint16_t NDEF_WriteURI(sURI_Info *pURI);
|
||||
|
||||
void NDEF_PrepareURIMessage( sURI_Info *pURI, uint8_t *pNDEFMessage, uint16_t *size );
|
||||
char getUriType( char *protocol );
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* __LIB_NDEF_URI_H */
|
||||
|
||||
/******************* (C) COPYRIGHT 2015 STMicroelectronics *****END OF FILE****/
|
||||
389
src/lib_NDEF_Vcard.cpp
Normal file
389
src/lib_NDEF_Vcard.cpp
Normal file
@@ -0,0 +1,389 @@
|
||||
/**
|
||||
******************************************************************************
|
||||
* @file lib_NDEF_Vcard.c
|
||||
* @author MMY Application Team
|
||||
* @version $Revision: 1330 $
|
||||
* @date $Date: 2015-11-05 10:39:11 +0100 (Thu, 05 Nov 2015) $
|
||||
* @brief This file help to manage NDEF file that represent Vcard.
|
||||
******************************************************************************
|
||||
* @attention
|
||||
*
|
||||
* <h2><center>© COPYRIGHT 2015 STMicroelectronics</center></h2>
|
||||
*
|
||||
* Licensed under ST MYLIBERTY SOFTWARE LICENSE AGREEMENT (the "License");
|
||||
* You may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at:
|
||||
*
|
||||
* http://www.st.com/myliberty
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied,
|
||||
* AND SPECIFICALLY DISCLAIMING THE IMPLIED WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE, AND NON-INFRINGEMENT.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
******************************************************************************
|
||||
*/
|
||||
|
||||
//#ifdef __cplusplus
|
||||
// extern "C" {
|
||||
//#endif
|
||||
|
||||
/* Includes ------------------------------------------------------------------*/
|
||||
#include "lib_NDEF_Vcard.h"
|
||||
|
||||
/** @addtogroup NFC_libraries
|
||||
* @{
|
||||
* @brief <b>This is the library used to manage the content of the TAG (data)
|
||||
* But also the specific feature of the tag, for instance
|
||||
* password, gpo... </b>
|
||||
*/
|
||||
|
||||
|
||||
/** @addtogroup libNFC_FORUM
|
||||
* @{
|
||||
* @brief This part of the library manage data which follow NFC forum organisation.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @brief This buffer contains the data send/received by TAG
|
||||
*/
|
||||
extern uint8_t NDEF_Buffer [];
|
||||
|
||||
/** @defgroup libVcard_Private_Functions
|
||||
* @{
|
||||
*/
|
||||
|
||||
|
||||
static void NDEF_FillVcardStruct( uint8_t* pPayload, uint32_t PayloadSize, char* pKeyWord, uint32_t SizeOfKeyWord, uint8_t* pString );
|
||||
static void NDEF_ExtractVcard( sRecordInfo_vcard *pRecordStruct, sVcardInfo *pVcardStruct );
|
||||
|
||||
/**
|
||||
* @brief This function fill Vcard structure with information of NDEF message.
|
||||
* @param pPayload : pointer on the payload data of the NDEF message.
|
||||
* @param PayloadSize : number of data in the payload.
|
||||
* @param pKeyWord : pointer on the keyword to look for.
|
||||
* @param SizeOfKeyWord : number of byte of the keyword we are looking for.
|
||||
* @param pString : Pointer on the data string to fill.
|
||||
*/
|
||||
static void NDEF_FillVcardStruct( uint8_t* pPayload, uint32_t PayloadSize, char* pKeyWord, uint32_t SizeOfKeyWord, uint8_t* pString )
|
||||
{
|
||||
uint8_t* pLastByteAdd, *pLook4Word, *pEndString;
|
||||
|
||||
/* First character force to NULL in case not matching found */
|
||||
*pString = 0;
|
||||
|
||||
/* Interresting information are stored before picture if any */
|
||||
/* Moreover picture is not used in this demonstration SW */
|
||||
pLastByteAdd = pPayload;
|
||||
while( memcmp( pLastByteAdd, JPEG, JPEG_STRING_SIZE ) && (pLastByteAdd < (pPayload + PayloadSize)) )
|
||||
{
|
||||
pLastByteAdd++;
|
||||
}
|
||||
|
||||
pLook4Word = pPayload;
|
||||
while( memcmp( pLook4Word, pKeyWord, SizeOfKeyWord ) && (pLook4Word < pLastByteAdd) )
|
||||
{
|
||||
pLook4Word++;
|
||||
}
|
||||
|
||||
/* Word found */
|
||||
if( pLook4Word != pLastByteAdd )
|
||||
{
|
||||
pLook4Word += SizeOfKeyWord;
|
||||
pEndString = pLook4Word;
|
||||
while( memcmp( pEndString, LIMIT, LIMIT_STRING_SIZE ) && (pEndString < pLastByteAdd) )
|
||||
{
|
||||
pEndString++;
|
||||
}
|
||||
if( pEndString != pLastByteAdd )
|
||||
{
|
||||
memcpy( pString, pLook4Word, pEndString-pLook4Word );
|
||||
/* add end of string character */
|
||||
pString += pEndString - pLook4Word;
|
||||
*pString = '\0';
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief This function read the Vcard and store data in a structure.
|
||||
* @param pRecordStruct : Pointer on the record structure.
|
||||
* @param pSMSStruct : pointer on the structure to fill.
|
||||
*/
|
||||
static void NDEF_ExtractVcard( sRecordInfo_vcard *pRecordStruct, sVcardInfo *pVcardStruct )
|
||||
{
|
||||
uint32_t PayloadSize;
|
||||
uint8_t* pPayload;
|
||||
|
||||
|
||||
PayloadSize = ((uint32_t)(pRecordStruct->PayloadLength3) << 24) | ((uint32_t)(pRecordStruct->PayloadLength2) << 16) |
|
||||
((uint32_t)(pRecordStruct->PayloadLength1) << 8) | pRecordStruct->PayloadLength0;
|
||||
|
||||
/* Read record header */
|
||||
pPayload = (uint8_t*)(pRecordStruct->PayloadBufferAdd);
|
||||
|
||||
NDEF_FillVcardStruct( pPayload, PayloadSize, VERSION, VERSION_STRING_SIZE, (uint8_t*)(pVcardStruct->Version) );
|
||||
if( !memcmp( pVcardStruct->Version, VCARD_VERSION_2_1, VCARD_VERSION_2_1_SIZE ) )
|
||||
{
|
||||
NDEF_FillVcardStruct( pPayload, PayloadSize, FIRSTNAME, FIRSTNAME_STRING_SIZE, (uint8_t*)(pVcardStruct->FirstName) );
|
||||
NDEF_FillVcardStruct( pPayload, PayloadSize, TITLE, TITLE_STRING_SIZE, (uint8_t*)(pVcardStruct->Title) );
|
||||
NDEF_FillVcardStruct( pPayload, PayloadSize, ORG, ORG_STRING_SIZE, (uint8_t*)(pVcardStruct->Org) );
|
||||
NDEF_FillVcardStruct( pPayload, PayloadSize, HOME_ADDRESS, HOME_ADDRESS_STRING_SIZE, (uint8_t*)(pVcardStruct->HomeAddress) );
|
||||
NDEF_FillVcardStruct( pPayload, PayloadSize, WORK_ADDRESS, WORK_ADDRESS_STRING_SIZE, (uint8_t*)(pVcardStruct->WorkAddress) );
|
||||
NDEF_FillVcardStruct( pPayload, PayloadSize, HOME_TEL, HOME_TEL_STRING_SIZE, (uint8_t*)(pVcardStruct->HomeTel) );
|
||||
NDEF_FillVcardStruct( pPayload, PayloadSize, WORK_TEL, WORK_TEL_STRING_SIZE, (uint8_t*)(pVcardStruct->WorkTel) );
|
||||
NDEF_FillVcardStruct( pPayload, PayloadSize, CELL_TEL, CELL_TEL_STRING_SIZE, (uint8_t*)(pVcardStruct->CellTel) );
|
||||
NDEF_FillVcardStruct( pPayload, PayloadSize, HOME_EMAIL, HOME_EMAIL_STRING_SIZE, (uint8_t*)(pVcardStruct->HomeEmail) );
|
||||
NDEF_FillVcardStruct( pPayload, PayloadSize, WORK_EMAIL, WORK_EMAIL_STRING_SIZE, (uint8_t*)(pVcardStruct->WorkEmail) );
|
||||
}
|
||||
else if( !memcmp( pVcardStruct->Version, VCARD_VERSION_3_0, VCARD_VERSION_3_0_SIZE ) )
|
||||
{
|
||||
/* need to be implemented */
|
||||
}
|
||||
else
|
||||
{
|
||||
/* maybe new version but not supported in this sw */
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/** @defgroup libVcard_Public_Functions
|
||||
* @{
|
||||
* @brief This file is used to manage Vcard (stored or loaded in tag)
|
||||
*/
|
||||
|
||||
/**
|
||||
* @brief This function read NDEF and retrieve Vcard information if any.
|
||||
* @param pRecordStruct : Pointer on the record structure.
|
||||
* @param pVcardStruct : pointer on the structure to fill.
|
||||
* @retval NDEF_OK : Vcard information from NDEF have been retrieved.
|
||||
* @retval NDEF_ERROR : Not able to retrieve Vcard information.
|
||||
*/
|
||||
uint16_t NDEF_ReadVcard( sRecordInfo_vcard *pRecordStruct, sVcardInfo *pVcardStruct )
|
||||
{
|
||||
uint16_t status = NDEF_ERROR;
|
||||
|
||||
if( pRecordStruct->NDEF_Type == VCARD_TYPE )
|
||||
{
|
||||
NDEF_ExtractVcard( pRecordStruct, pVcardStruct );
|
||||
status = NDEF_OK;
|
||||
}
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief This function write the NDEF file with the Vcard data given in the structure.
|
||||
* @param pVcardStruct : pointer on structure that contain the Vcard information.
|
||||
* @retval NDEF_OK : NDEF file data written in the tag.
|
||||
* @retval NDEF_ERROR : not able to store NDEF in tag.
|
||||
* @retval NDEF_ERROR_MEMORY_INTERNAL : Cannot write to tag.
|
||||
* @retval NDEF_ERROR_NOT_FORMATED : CCFile data not supported or not present.
|
||||
* @retval NDEF_ERROR_MEMORY_TAG : Size not compatible with memory.
|
||||
* @retval NDEF_ERROR_LOCKED : Tag locked, cannot be write.
|
||||
*/
|
||||
uint16_t NDEF_WriteVcard( sVcardInfo *pVcardStruct )
|
||||
{
|
||||
uint16_t status = NDEF_ERROR, Offset = 0;
|
||||
|
||||
NDEF_PrepareVcardMessage( pVcardStruct, &NDEF_Buffer[FIRST_RECORD_OFFSET], &Offset );
|
||||
|
||||
/* Write NDEF */
|
||||
NDEF_Buffer[0] = (Offset & 0xFF00) >> 8;
|
||||
NDEF_Buffer[1] = Offset & 0x00FF;
|
||||
|
||||
status = WriteData( 0x00, Offset + FIRST_RECORD_OFFSET, NDEF_Buffer );
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief This function write the NDEF file with the Vcard data given in the structure.
|
||||
* @param pVcardStruct : pointer on structure that contain the Vcard information.
|
||||
* @param pNDEFMessage : pointer on the NDEF message.
|
||||
* @param size : to store the size of the NDEF message generated.
|
||||
*/
|
||||
void NDEF_PrepareVcardMessage( sVcardInfo *pVcardStruct, uint8_t *pNDEFMessage, uint16_t *size )
|
||||
{
|
||||
|
||||
uint32_t PayloadSize = 0;
|
||||
|
||||
/* Vcard Record Header */
|
||||
/************************************/
|
||||
/* 7 | 6 | 5 | 4 | 3 | 2 1 0 */
|
||||
/*----------------------------------*/
|
||||
/* MB ME CF SR IL TNF */ /* <---- CF=0, IL=0 and SR=0 TNF=2 NFC Forum Media type*/
|
||||
/*----------------------------------*/
|
||||
/* TYPE LENGTH */
|
||||
/*----------------------------------*/
|
||||
/* PAYLOAD LENGTH 3 */
|
||||
/*----------------------------------*/
|
||||
/* PAYLOAD LENGTH 2 */
|
||||
/*----------------------------------*/
|
||||
/* PAYLOAD LENGTH 1 */
|
||||
/*----------------------------------*/
|
||||
/* PAYLOAD LENGTH 0 */
|
||||
/*----------------------------------*/
|
||||
/* ID LENGTH */ /* <---- Not Used */
|
||||
/*----------------------------------*/
|
||||
/* TYPE */
|
||||
/*----------------------------------*/
|
||||
/* ID */ /* <---- Not Used */
|
||||
/************************************/
|
||||
|
||||
/* As we don't have embedded a jpeg encoder/decoder in this firmware */
|
||||
/* We have made the choice to manage only string content of the vCard */
|
||||
/* For demonstration purpose in order to fill the 8kB of the M24SR */
|
||||
/* We have embedded a NDEF vCard in the STM32 to be able to fill M24SR */
|
||||
|
||||
/* fill record header */
|
||||
pNDEFMessage[0] = 0xC2; /* Record Flag */
|
||||
pNDEFMessage[1] = VCARD_TYPE_STRING_LENGTH;
|
||||
pNDEFMessage[2] = 0x00; /* Will be filled at the end when payload size is known */
|
||||
pNDEFMessage[3] = 0x00;
|
||||
pNDEFMessage[4] = 0x00;
|
||||
pNDEFMessage[5] = 0x00;
|
||||
memcpy( &pNDEFMessage[6], VCARD_TYPE_STRING, VCARD_TYPE_STRING_LENGTH );
|
||||
|
||||
/* Payload is positionned in the NDEF after record header */
|
||||
PayloadSize = 6 + VCARD_TYPE_STRING_LENGTH;
|
||||
|
||||
/* "BEGIN:VCARD\r\n" */
|
||||
memcpy( &pNDEFMessage[PayloadSize], BEGIN, BEGIN_STRING_SIZE );
|
||||
PayloadSize += BEGIN_STRING_SIZE;
|
||||
memcpy( &pNDEFMessage[PayloadSize], VCARD,VCARD_STRING_SIZE );
|
||||
PayloadSize += VCARD_STRING_SIZE;
|
||||
memcpy( &pNDEFMessage[PayloadSize], LIMIT, LIMIT_STRING_SIZE );
|
||||
PayloadSize += LIMIT_STRING_SIZE;
|
||||
|
||||
/* "VERSION:2.1\r\n" */
|
||||
memcpy( &pNDEFMessage[PayloadSize], VERSION, VERSION_STRING_SIZE );
|
||||
PayloadSize += VERSION_STRING_SIZE;
|
||||
memcpy( &pNDEFMessage[PayloadSize], VCARD_VERSION_2_1, VCARD_VERSION_2_1_SIZE );
|
||||
PayloadSize += VCARD_VERSION_2_1_SIZE;
|
||||
memcpy( &pNDEFMessage[PayloadSize], LIMIT, LIMIT_STRING_SIZE );
|
||||
PayloadSize += LIMIT_STRING_SIZE;
|
||||
|
||||
/* "FN:\r\n" */
|
||||
memcpy( &pNDEFMessage[PayloadSize], FIRSTNAME, FIRSTNAME_STRING_SIZE );
|
||||
PayloadSize += FIRSTNAME_STRING_SIZE;
|
||||
memcpy( &pNDEFMessage[PayloadSize], pVcardStruct->FirstName, strlen(pVcardStruct->FirstName) );
|
||||
PayloadSize += strlen( pVcardStruct->FirstName );
|
||||
memcpy( &pNDEFMessage[PayloadSize], LIMIT, LIMIT_STRING_SIZE );
|
||||
PayloadSize += LIMIT_STRING_SIZE;
|
||||
|
||||
/* "TITLE:\r\n" */
|
||||
memcpy( &pNDEFMessage[PayloadSize], TITLE, TITLE_STRING_SIZE );
|
||||
PayloadSize += TITLE_STRING_SIZE;
|
||||
memcpy( &pNDEFMessage[PayloadSize], pVcardStruct->Title, strlen(pVcardStruct->Title) );
|
||||
PayloadSize += strlen( pVcardStruct->Title );
|
||||
memcpy( &pNDEFMessage[PayloadSize], LIMIT, LIMIT_STRING_SIZE );
|
||||
PayloadSize += LIMIT_STRING_SIZE;
|
||||
|
||||
/* "ORG:\r\n" */
|
||||
memcpy( &pNDEFMessage[PayloadSize], ORG, ORG_STRING_SIZE );
|
||||
PayloadSize += ORG_STRING_SIZE;
|
||||
memcpy( &pNDEFMessage[PayloadSize], pVcardStruct->Org, strlen(pVcardStruct->Org) );
|
||||
PayloadSize += strlen( pVcardStruct->Org );
|
||||
memcpy( &pNDEFMessage[PayloadSize], LIMIT, LIMIT_STRING_SIZE );
|
||||
PayloadSize += LIMIT_STRING_SIZE;
|
||||
|
||||
/* "ADR;HOME:\r\n" */
|
||||
memcpy( &pNDEFMessage[PayloadSize], HOME_ADDRESS, HOME_ADDRESS_STRING_SIZE );
|
||||
PayloadSize += HOME_ADDRESS_STRING_SIZE;
|
||||
memcpy( &pNDEFMessage[PayloadSize], pVcardStruct->HomeAddress, strlen(pVcardStruct->HomeAddress) );
|
||||
PayloadSize += strlen( pVcardStruct->HomeAddress );
|
||||
memcpy( &pNDEFMessage[PayloadSize], LIMIT, LIMIT_STRING_SIZE );
|
||||
PayloadSize += LIMIT_STRING_SIZE;
|
||||
|
||||
/* "ADR;WORK:\r\n" */
|
||||
memcpy( &pNDEFMessage[PayloadSize], WORK_ADDRESS, WORK_ADDRESS_STRING_SIZE );
|
||||
PayloadSize += WORK_ADDRESS_STRING_SIZE;
|
||||
memcpy( &pNDEFMessage[PayloadSize], pVcardStruct->WorkAddress, strlen(pVcardStruct->WorkAddress) );
|
||||
PayloadSize += strlen( pVcardStruct->WorkAddress );
|
||||
memcpy( &pNDEFMessage[PayloadSize], LIMIT, LIMIT_STRING_SIZE );
|
||||
PayloadSize += LIMIT_STRING_SIZE;
|
||||
|
||||
/* "TEL;HOME:\r\n" */
|
||||
memcpy( &pNDEFMessage[PayloadSize], HOME_TEL, HOME_TEL_STRING_SIZE );
|
||||
PayloadSize += HOME_TEL_STRING_SIZE;
|
||||
memcpy( &pNDEFMessage[PayloadSize], pVcardStruct->HomeTel, strlen(pVcardStruct->HomeTel) );
|
||||
PayloadSize += strlen( pVcardStruct->HomeTel );
|
||||
memcpy( &pNDEFMessage[PayloadSize], LIMIT, LIMIT_STRING_SIZE );
|
||||
PayloadSize += LIMIT_STRING_SIZE;
|
||||
|
||||
/* "TEL;WORK:\r\n" */
|
||||
memcpy( &pNDEFMessage[PayloadSize], WORK_TEL, WORK_TEL_STRING_SIZE );
|
||||
PayloadSize += WORK_TEL_STRING_SIZE;
|
||||
memcpy( &pNDEFMessage[PayloadSize], pVcardStruct->WorkTel, strlen(pVcardStruct->WorkTel) );
|
||||
PayloadSize += strlen( pVcardStruct->WorkTel );
|
||||
memcpy( &pNDEFMessage[PayloadSize], LIMIT, LIMIT_STRING_SIZE );
|
||||
PayloadSize += LIMIT_STRING_SIZE;
|
||||
|
||||
/* "TEL;CELL:\r\n" */
|
||||
memcpy( &pNDEFMessage[PayloadSize], CELL_TEL, CELL_TEL_STRING_SIZE );
|
||||
PayloadSize += CELL_TEL_STRING_SIZE;
|
||||
memcpy( &pNDEFMessage[PayloadSize], pVcardStruct->CellTel, strlen(pVcardStruct->CellTel) );
|
||||
PayloadSize += strlen( pVcardStruct->CellTel );
|
||||
memcpy( &pNDEFMessage[PayloadSize], LIMIT, LIMIT_STRING_SIZE );
|
||||
PayloadSize += LIMIT_STRING_SIZE;
|
||||
|
||||
/* "EMAIL;HOME:\r\n" */
|
||||
memcpy( &pNDEFMessage[PayloadSize], HOME_EMAIL, HOME_EMAIL_STRING_SIZE );
|
||||
PayloadSize += HOME_EMAIL_STRING_SIZE;
|
||||
memcpy( &pNDEFMessage[PayloadSize], pVcardStruct->HomeEmail, strlen(pVcardStruct->HomeEmail) );
|
||||
PayloadSize += strlen( pVcardStruct->HomeEmail );
|
||||
memcpy( &pNDEFMessage[PayloadSize], LIMIT, LIMIT_STRING_SIZE );
|
||||
PayloadSize += LIMIT_STRING_SIZE;
|
||||
|
||||
/* "EMAIL;WORK:\r\n" */
|
||||
memcpy( &pNDEFMessage[PayloadSize], WORK_EMAIL, WORK_EMAIL_STRING_SIZE );
|
||||
PayloadSize += WORK_EMAIL_STRING_SIZE;
|
||||
memcpy( &pNDEFMessage[PayloadSize], pVcardStruct->WorkEmail, strlen(pVcardStruct->WorkEmail) );
|
||||
PayloadSize += strlen( pVcardStruct->WorkEmail );
|
||||
memcpy( &pNDEFMessage[PayloadSize], LIMIT, LIMIT_STRING_SIZE );
|
||||
PayloadSize += LIMIT_STRING_SIZE;
|
||||
|
||||
/* "END:VCARD\r\n" */
|
||||
memcpy( &pNDEFMessage[PayloadSize], END, END_STRING_SIZE );
|
||||
PayloadSize += END_STRING_SIZE;
|
||||
memcpy( &pNDEFMessage[PayloadSize], VCARD, VCARD_STRING_SIZE );
|
||||
PayloadSize += VCARD_STRING_SIZE;
|
||||
memcpy( &pNDEFMessage[PayloadSize], LIMIT, LIMIT_STRING_SIZE );
|
||||
PayloadSize += LIMIT_STRING_SIZE;
|
||||
|
||||
*size = (uint16_t)(PayloadSize); /* Must not count the 2 byte that represent the NDEF size */
|
||||
PayloadSize -= 6 + VCARD_TYPE_STRING_LENGTH;
|
||||
|
||||
pNDEFMessage[2] = (PayloadSize & 0xFF000000) >> 24;
|
||||
pNDEFMessage[3] = (PayloadSize & 0x00FF0000) >> 16;
|
||||
pNDEFMessage[4] = (PayloadSize & 0x0000FF00) >> 8;
|
||||
pNDEFMessage[5] = PayloadSize & 0x000000FF;
|
||||
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
//#ifdef __cplusplus
|
||||
//}
|
||||
//#endif
|
||||
|
||||
/******************* (C) COPYRIGHT 2015 STMicroelectronics *****END OF FILE****/
|
||||
114
src/lib_NDEF_Vcard.h
Normal file
114
src/lib_NDEF_Vcard.h
Normal file
@@ -0,0 +1,114 @@
|
||||
/**
|
||||
******************************************************************************
|
||||
* @file lib_NDEF_Vcard.h
|
||||
* @author MMY Application Team
|
||||
* @version $Revision: 1329 $
|
||||
* @date $Date: 2015-11-05 10:34:25 +0100 (Thu, 05 Nov 2015) $
|
||||
* @brief This file help to manage Vcard NDEF file.
|
||||
******************************************************************************
|
||||
* @attention
|
||||
*
|
||||
* <h2><center>© COPYRIGHT 2015 STMicroelectronics</center></h2>
|
||||
*
|
||||
* Licensed under ST MYLIBERTY SOFTWARE LICENSE AGREEMENT (the "License");
|
||||
* You may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at:
|
||||
*
|
||||
* http://www.st.com/myliberty
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied,
|
||||
* AND SPECIFICALLY DISCLAIMING THE IMPLIED WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE, AND NON-INFRINGEMENT.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
******************************************************************************
|
||||
*/
|
||||
|
||||
/* Define to prevent recursive inclusion -------------------------------------*/
|
||||
#ifndef __LIB_NDEF_VCARD_H
|
||||
#define __LIB_NDEF_VCARD_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/* Includes ------------------------------------------------------------------*/
|
||||
#include "lib_NDEF.h"
|
||||
|
||||
|
||||
#define VCARD_VERSION_2_1 "2.1"
|
||||
#define VCARD_VERSION_2_1_SIZE 3
|
||||
|
||||
#define VCARD_VERSION_3_0 "3.0"
|
||||
#define VCARD_VERSION_3_0_SIZE 3
|
||||
|
||||
|
||||
#define BEGIN "BEGIN:"
|
||||
#define VCARD "VCARD"
|
||||
#define VERSION "VERSION:"
|
||||
#define FIRSTNAME "FN:"
|
||||
#define HOME_TEL "TEL;HOME:"
|
||||
#define WORK_TEL "TEL;WORK:"
|
||||
#define CELL_TEL "TEL;CELL:"
|
||||
#define HOME_EMAIL "EMAIL;HOME:"
|
||||
#define WORK_EMAIL "EMAIL;WORK:"
|
||||
#define HOME_ADDRESS "ADR;HOME:"
|
||||
#define WORK_ADDRESS "ADR;WORK:"
|
||||
#define TITLE "TITLE:"
|
||||
#define ORG "ORG:"
|
||||
#define END "END:"
|
||||
#define JPEG "JPEG"
|
||||
|
||||
#define LIMIT "\r\n"
|
||||
|
||||
#define BEGIN_STRING_SIZE 6
|
||||
#define VCARD_STRING_SIZE 5
|
||||
#define VERSION_STRING_SIZE 8
|
||||
#define FIRSTNAME_STRING_SIZE 3
|
||||
#define HOME_TEL_STRING_SIZE 9
|
||||
#define WORK_TEL_STRING_SIZE 9
|
||||
#define CELL_TEL_STRING_SIZE 9
|
||||
#define HOME_EMAIL_STRING_SIZE 11
|
||||
#define WORK_EMAIL_STRING_SIZE 11
|
||||
#define HOME_ADDRESS_STRING_SIZE 9
|
||||
#define WORK_ADDRESS_STRING_SIZE 9
|
||||
#define TITLE_STRING_SIZE 6
|
||||
#define ORG_STRING_SIZE 4
|
||||
#define END_STRING_SIZE 4
|
||||
#define JPEG_STRING_SIZE 4
|
||||
|
||||
#define LIMIT_STRING_SIZE 2
|
||||
|
||||
typedef struct
|
||||
{
|
||||
char Version [10];
|
||||
char FirstName[80];
|
||||
char Title[80];
|
||||
char Org[80];
|
||||
char HomeAddress[80];
|
||||
char WorkAddress[80];
|
||||
char HomeTel[40];
|
||||
char WorkTel[40];
|
||||
char CellTel[40];
|
||||
char HomeEmail[80];
|
||||
char WorkEmail[80];
|
||||
}sVcardInfo;
|
||||
|
||||
/* Struct defined in lib_NDEF.h */
|
||||
typedef struct sRecordInfo sRecordInfo_vcard;
|
||||
|
||||
uint16_t NDEF_ReadVcard( sRecordInfo_vcard *pRecordStruct, sVcardInfo *pVcardStruct );
|
||||
uint16_t NDEF_WriteVcard( sVcardInfo *pVcardStruct );
|
||||
void NDEF_PrepareVcardMessage( sVcardInfo *pVcardStruct, uint8_t *pNDEFMessage, uint16_t *size );
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* __LIB_NDEF_VCARD_H */
|
||||
|
||||
|
||||
/******************* (C) COPYRIGHT 2015 STMicroelectronics *****END OF FILE****/
|
||||
137
src/lib_iso14443A.h
Normal file
137
src/lib_iso14443A.h
Normal file
@@ -0,0 +1,137 @@
|
||||
/**
|
||||
******************************************************************************
|
||||
* @file lib_iso14443A.h
|
||||
* @author MMY Application Team
|
||||
* @version $Revision: 1333 $
|
||||
* @date $Date: 2015-11-05 10:49:42 +0100 (Thu, 05 Nov 2015) $
|
||||
* @brief ISO14443A common constants
|
||||
******************************************************************************
|
||||
* @attention
|
||||
*
|
||||
* <h2><center>© COPYRIGHT 2015 STMicroelectronics</center></h2>
|
||||
*
|
||||
* Licensed under ST MYLIBERTY SOFTWARE LICENSE AGREEMENT (the "License");
|
||||
* You may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at:
|
||||
*
|
||||
* http://www.st.com/myliberty
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied,
|
||||
* AND SPECIFICALLY DISCLAIMING THE IMPLIED WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE, AND NON-INFRINGEMENT.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
******************************************************************************
|
||||
*/
|
||||
|
||||
/* Define to prevent recursive inclusion -------------------------------------------------------*/
|
||||
#ifndef __ISO14443A_H
|
||||
#define __ISO14443A_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include "stdint.h"
|
||||
#include "stdbool.h"
|
||||
|
||||
/* status and error code ---------------------------------------------------------------------- */
|
||||
#define ISO14443A_SUCCESSCODE RESULTOK
|
||||
#define ISO14443A_ERRORCODE_DEFAULT 0x61
|
||||
#define ISO14443A_ERRORCODE_CRC 0x62
|
||||
|
||||
/* Anticollison levels (commands) ------------------------------------------------------------- */
|
||||
#define SEL_CASCADE_LVL_1 0x93
|
||||
#define SEL_CASCADE_LVL_2 0x95
|
||||
#define SEL_CASCADE_LVL_3 0x97
|
||||
#define COMMAND_REQA 0x26
|
||||
#define COMMAND_WUPA 0x52
|
||||
#define COMMAND_SELECT_LV1 0x93
|
||||
#define COMMAND_SELECT_LV2 0x95
|
||||
#define COMMAND_SELECT_LV3 0x97
|
||||
#define COMMAND_HLTA 0x50
|
||||
|
||||
#define COMMAND_RATS 0xE0
|
||||
#define COMMAND_PPS 0xD0
|
||||
#define COMMAND_DESELECT 0xC2
|
||||
#define COMMAND_DESELECTCID 0xCA
|
||||
|
||||
/* Iblock ------------------------------------------------------------------------------------- */
|
||||
#define COMMAND_IBLOCK02 0x02
|
||||
#define COMMAND_IBLOCK03 0x03
|
||||
#define COMMAND_SBLOCK 0xC2
|
||||
#define COMMAND_NACKBLOCK_B2 0xB2
|
||||
#define COMMAND_NACKBLOCK_B3 0xB3
|
||||
#define COMMAND_ACKBLOCK 0xA2
|
||||
|
||||
|
||||
/* numbr of the cascade level ----------------------------------------------------------------- */
|
||||
#define CASCADE_LVL_1 1
|
||||
#define CASCADE_LVL_2 2
|
||||
#define CASCADE_LVL_3 3
|
||||
|
||||
#define ISO14443A_NVM_10 0x10
|
||||
#define ISO14443A_NVM_20 0x20
|
||||
#define ISO14443A_NVM_30 0x30
|
||||
#define ISO14443A_NVM_40 0x40
|
||||
#define ISO14443A_NVM_50 0x50
|
||||
#define ISO14443A_NVM_60 0x60
|
||||
#define ISO14443A_NVM_70 0x70
|
||||
|
||||
/* UID Sizes ---------------------------------------------------------------------------------- */
|
||||
#define ISO14443A_UIDSIZE_UNDEFINED -1
|
||||
#define ISO14443A_UID_PART 3
|
||||
#define ISO14443A_UID_SINGLE_SIZE 4
|
||||
#define ISO14443A_UID_DOUBLE_SIZE 7
|
||||
#define ISO14443A_UID_TRIPLE_SIZE 10
|
||||
|
||||
|
||||
/* Mask used for ATQA ------------------------------------------------------------------------ */
|
||||
#define ISO14443A_UID_MASK 0xC0
|
||||
#define ISO14443A_AC_BIT_FRAME_MASK 0x1F
|
||||
#define ISO14443A_CID_MASK 0x0F
|
||||
#define ISO14443A_FSDI_MASK 0xF0
|
||||
|
||||
/* Size for ISO14443A variables ------------------------------------------------------------- */
|
||||
#define ISO14443A_MAX_NAME_SIZE 50
|
||||
#define ISO14443A_MAX_UID_SIZE 10
|
||||
#define ISO14443A_ATQA_SIZE 2
|
||||
|
||||
/* SAK FLAG --------------------------------------------------------------------------------- */
|
||||
#define SAK_FLAG_ATS_SUPPORTED 0x20
|
||||
#define SAK_FLAG_UID_NOT_COMPLETE 0x04
|
||||
|
||||
|
||||
/* ATQ FLAG */
|
||||
#define ATQ_FLAG_UID_SINGLE_SIZE 0
|
||||
#define ATQ_FLAG_UID_DOUBLE_SIZE 1
|
||||
#define ATQ_FLAG_UID_TRIPLE_SIZE 2
|
||||
|
||||
typedef struct{
|
||||
/* ATQA answer to request of type A*/
|
||||
uint8_t ATQA[ISO14443A_ATQA_SIZE];
|
||||
uint8_t CascadeLevel;
|
||||
/* UID : unique Identification*/
|
||||
uint8_t UIDsize;
|
||||
uint8_t UID[ISO14443A_MAX_UID_SIZE];
|
||||
/* SAK : Select acknowledge*/
|
||||
uint8_t SAK;
|
||||
bool ATSSupported;
|
||||
bool IsDetected;
|
||||
char LogMsg[120];
|
||||
uint8_t CID,
|
||||
FSDI,
|
||||
DRI,
|
||||
NFC_DSI;
|
||||
}ISO14443A_CARD;
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* __ISO14443A_H */
|
||||
|
||||
/******************* (C) COPYRIGHT 2015 STMicroelectronics *****END OF FILE****/
|
||||
993
src/lib_iso14443Apcd.cpp
Normal file
993
src/lib_iso14443Apcd.cpp
Normal file
@@ -0,0 +1,993 @@
|
||||
/**
|
||||
******************************************************************************
|
||||
* @file lib_iso14443Apcd.c
|
||||
* @author MMY Application Team
|
||||
* @version $Revision: 1334 $
|
||||
* @date $Date: 2015-11-05 10:53:37 +0100 (Thu, 05 Nov 2015) $
|
||||
* @brief Manage the iso14443A communication
|
||||
******************************************************************************
|
||||
* @attention
|
||||
*
|
||||
* <h2><center>© COPYRIGHT 2015 STMicroelectronics</center></h2>
|
||||
*
|
||||
* Licensed under ST MYLIBERTY SOFTWARE LICENSE AGREEMENT (the "License");
|
||||
* You may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at:
|
||||
*
|
||||
* http://www.st.com/myliberty
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied,
|
||||
* AND SPECIFICALLY DISCLAIMING THE IMPLIED WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE, AND NON-INFRINGEMENT.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
******************************************************************************
|
||||
*/
|
||||
|
||||
//#ifdef __cplusplus
|
||||
// extern "C" {
|
||||
//#endif
|
||||
|
||||
/* Includes ------------------------------------------------------------------------------ */
|
||||
#include "Arduino.h"
|
||||
#include "lib_iso14443Apcd.h"
|
||||
|
||||
extern PCD_PROTOCOL TechnoSelected;
|
||||
extern IC_VERSION IcVers;
|
||||
|
||||
/* --------------------------------------------------
|
||||
* code templates for ISO14443A protocol
|
||||
* command = Command code | Length | data(Le)
|
||||
* -------------------------------------------------- */
|
||||
#define PCD_TYPEA_TIMERW 0x5A
|
||||
|
||||
/****************** PCD ******************/
|
||||
/* ISO14443A */
|
||||
#define PCD_TYPEA_ARConfigA 0x01
|
||||
#define PCD_TYPEA_ARConfigB 0xDF
|
||||
|
||||
static const uint8_t TOPAZ[] = {SEND_RECEIVE, 0x08, 0x78, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xA8};
|
||||
|
||||
static u8 MultiID[200] = {0};
|
||||
static u8 MultiIDPart2[64] = {0};
|
||||
static u8 RemainingID = 0;
|
||||
|
||||
|
||||
uint16_t FSC = 32;
|
||||
uint16_t FWI = 4; /* Default value */
|
||||
|
||||
|
||||
ISO14443A_CARD ISO14443A_Card;
|
||||
extern uint8_t u95HFBuffer [RFTRANS_95HF_MAX_BUFFER_SIZE+3];
|
||||
|
||||
uint8_t u95HFBufferAntiCol [RFTRANS_95HF_MAX_BUFFER_SIZE+3];
|
||||
|
||||
/* Variables for the different modes */
|
||||
extern DeviceMode_t devicemode;
|
||||
extern TagType_t nfc_tagtype;
|
||||
|
||||
static void ISO14443A_InitStructure( void );
|
||||
static uint16_t FSCIToFSC(uint8_t FSCI);
|
||||
static int8_t ISO14443A_REQA( uint8_t *pDataRead );
|
||||
static int8_t ISO14443A_HLTA( uint8_t *pDataRead );
|
||||
static int8_t ISO14443A_RATS( uint8_t *pDataRead );
|
||||
#if 0
|
||||
static int8_t ISO14443A_PPS( uint8_t *pDataRead );
|
||||
#endif
|
||||
static int8_t ISO14443A_AC( uint8_t *pDataRead, u8 CascadeLevel );
|
||||
static int8_t ISO14443A_ACLevel1 ( uint8_t *pDataRead );
|
||||
static int8_t ISO14443A_ACLevel2 ( uint8_t *pDataRead );
|
||||
static int8_t ISO14443A_ACLevel3 ( uint8_t *pDataRead );
|
||||
static void ISO14443A_CompleteStructure ( uint8_t *pATQA );
|
||||
static int8_t ISO14443A_MultiAnticollision( void );
|
||||
|
||||
|
||||
/** @addtogroup _95HF_Libraries
|
||||
* @{
|
||||
* @brief <b>This is the library used by the whole 95HF family (RX95HF, CR95HF, ST95HF) <br />
|
||||
* You will find ISO libraries ( 14443A, 14443B, 15693, ...) for PICC and PCD <br />
|
||||
* The libraries selected in the project will depend of the application targetted <br />
|
||||
* and the product chosen (RX95HF emulate PICC, CR95HF emulate PCD, ST95HF can do both)</b>
|
||||
*/
|
||||
|
||||
/** @addtogroup PCD
|
||||
* @{
|
||||
* @brief This part of the library enables PCD capabilities of CR95HF & ST95HF.
|
||||
*/
|
||||
|
||||
|
||||
/** @addtogroup ISO14443A_pcd
|
||||
* @{
|
||||
* @brief This part of the library is used to follow ISO14443A.
|
||||
*/
|
||||
|
||||
|
||||
/** @addtogroup lib_iso14443Apcd_Private_Functions
|
||||
* @{
|
||||
*/
|
||||
|
||||
|
||||
/**
|
||||
* @brief Reset the ISO14443A data structure
|
||||
* @param void
|
||||
* @return void
|
||||
*/
|
||||
static void ISO14443A_InitStructure( void )
|
||||
{
|
||||
/* Initializes the data structure used to store results */
|
||||
memset(ISO14443A_Card.ATQA, 0x00, ISO14443A_ATQA_SIZE);
|
||||
memset(ISO14443A_Card.UID , 0x00, ISO14443A_MAX_UID_SIZE);
|
||||
ISO14443A_Card.CascadeLevel = 0;
|
||||
ISO14443A_Card.UIDsize = 0;
|
||||
ISO14443A_Card.ATSSupported = false;
|
||||
ISO14443A_Card.IsDetected = false;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief this functions convert FSCI to FSC
|
||||
* @param FSCI : FSCI value
|
||||
* @return FSC
|
||||
*/
|
||||
static uint16_t FSCIToFSC(uint8_t FSCI)
|
||||
{
|
||||
if (FSCI == 0) return 16;
|
||||
else if (FSCI == 1) return 24;
|
||||
else if (FSCI == 2) return 32;
|
||||
else if (FSCI == 3) return 40;
|
||||
else if (FSCI == 4) return 48;
|
||||
else if (FSCI == 5) return 64;
|
||||
else if (FSCI == 6) return 96;
|
||||
else if (FSCI == 7) return 128;
|
||||
else return 256;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @brief this functions sends the REQA command to the PCD device
|
||||
* @param *pDataRead : Pointer to the PCD response
|
||||
* @return ISO14443A_SUCCESSCODE the function is succesful
|
||||
* @return ISO14443A_ERRORCODE_DEFAULT : an error occured
|
||||
*/
|
||||
static int8_t ISO14443A_REQA( uint8_t *pDataRead )
|
||||
{
|
||||
const uint8_t ReqA[] = { 0x26, 0x07};
|
||||
int8_t status;
|
||||
|
||||
/* sends the command to the PCD device*/
|
||||
errchk(PCD_SendRecv(0x02,ReqA,pDataRead));
|
||||
|
||||
/* retrieves the ATQA response */
|
||||
memcpy(ISO14443A_Card.ATQA, &pDataRead[PCD_DATA_OFFSET], ISO14443A_ATQA_SIZE);
|
||||
/* completes the strucure according to the ATQA response */
|
||||
ISO14443A_CompleteStructure ( ISO14443A_Card.ATQA );
|
||||
|
||||
return ISO14443A_SUCCESSCODE;
|
||||
Error:
|
||||
return ISO14443A_ERRORCODE_DEFAULT;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @brief This functions manage the anticollision
|
||||
* @param *pDataRead : Pointer to the PCD response
|
||||
* @param CascadeLevel : information on the current cascade level
|
||||
* @return ISO14443A_SUCCESSCODE the function is succesful
|
||||
* @return ISO14443A_ERRORCODE_DEFAULT : an error occured
|
||||
*/
|
||||
static int8_t ISO14443A_AC( uint8_t *pDataRead, u8 CascadeLevel )
|
||||
{
|
||||
u8 AnticolParameter [7] = {0x00, ISO14443A_NVM_20, 0x08,0x00,0x00,0x00,0x00};
|
||||
u8 NbResponseByte = 0;
|
||||
u8 NbResponseByteOrigin = 0;
|
||||
u8 Collision = 0;
|
||||
u8 ByteCollisionIndex = 0;
|
||||
u8 BitCollisionIndex = 0;
|
||||
|
||||
u8 RemainingBit = 0;
|
||||
u8 NewByteCollisionIndex = 0;
|
||||
u8 NewBitCollisionIndex = 0;
|
||||
u8 UID[4] = {0x00,0x00,0x00,0x00};
|
||||
int8_t status;
|
||||
|
||||
/* prepare command regarding cascade level on-going */
|
||||
AnticolParameter[0] = CascadeLevel;
|
||||
|
||||
/* sends the command to the PCD device*/
|
||||
errchk(PCD_SendRecv(0x03,AnticolParameter,pDataRead));
|
||||
|
||||
NbResponseByte = pDataRead[1];
|
||||
NbResponseByteOrigin = NbResponseByte;
|
||||
Collision = (pDataRead[NbResponseByte-1] & 0x80);
|
||||
|
||||
ByteCollisionIndex = pDataRead[NbResponseByte];
|
||||
BitCollisionIndex = pDataRead[NbResponseByte+1];
|
||||
|
||||
/* case that should not happend, as occurs because we have miss another collision */
|
||||
if( BitCollisionIndex == 8)
|
||||
{
|
||||
return ISO14443A_ERRORCODE_DEFAULT;
|
||||
}
|
||||
|
||||
/* check for collision (Tag of different UID length at the same time not managed so far) */
|
||||
while( Collision == 0x80)
|
||||
{
|
||||
/* clear collision detection */
|
||||
Collision = 0x00;
|
||||
|
||||
/* send the command to the PCD device*/
|
||||
AnticolParameter[1] = ISO14443A_NVM_20 + ((ByteCollisionIndex) <<4) + (BitCollisionIndex+1);
|
||||
if( ByteCollisionIndex == 0)
|
||||
{
|
||||
AnticolParameter[2] = pDataRead[2] & ((u8)(~(0xFF<<(BitCollisionIndex+1)))); /* ISO said it's better to put collision bit to value 1 */
|
||||
AnticolParameter[3] = (BitCollisionIndex+1) | 0x40; /* add split frame bit */
|
||||
UID [0] = AnticolParameter[2];
|
||||
}
|
||||
else if( ByteCollisionIndex == 1)
|
||||
{
|
||||
AnticolParameter[2] = pDataRead[2];
|
||||
AnticolParameter[3] = pDataRead[3] & ((u8)(~(0xFF<<(BitCollisionIndex+1)))); /* ISO said it's better to put collision bit to value 1 */
|
||||
AnticolParameter[4] = (BitCollisionIndex+1) | 0x40; /* add split frame bit */
|
||||
UID [0] = AnticolParameter[2];
|
||||
UID [1] = AnticolParameter[3];
|
||||
}
|
||||
else if( ByteCollisionIndex == 2)
|
||||
{
|
||||
AnticolParameter[2] = pDataRead[2];
|
||||
AnticolParameter[3] = pDataRead[3];
|
||||
AnticolParameter[4] = pDataRead[4] & ((u8)(~(0xFF<<(BitCollisionIndex+1)))); /* ISO said it's better to put collision bit to value 1 */
|
||||
AnticolParameter[5] = (BitCollisionIndex+1) | 0x40; /* add split frame bit */;
|
||||
UID [0] = AnticolParameter[2];
|
||||
UID [1] = AnticolParameter[3];
|
||||
UID [2] = AnticolParameter[4];
|
||||
}
|
||||
else if( ByteCollisionIndex == 3)
|
||||
{
|
||||
AnticolParameter[2] = pDataRead[2];
|
||||
AnticolParameter[3] = pDataRead[3];
|
||||
AnticolParameter[4] = pDataRead[4];
|
||||
AnticolParameter[5] = pDataRead[5] & ((u8)(~(0xFF<<(BitCollisionIndex+1)))); /* ISO said it's better to put collision bit to value 1 */
|
||||
AnticolParameter[6] = (BitCollisionIndex+1) | 0x40; /* add split frame bit */;
|
||||
UID [0] = AnticolParameter[2];
|
||||
UID [1] = AnticolParameter[3];
|
||||
UID [2] = AnticolParameter[4];
|
||||
UID [3] = AnticolParameter[5];
|
||||
}
|
||||
else
|
||||
return ISO14443A_ERRORCODE_DEFAULT;
|
||||
|
||||
/* send part of the UID */
|
||||
PCD_SendRecv((0x03+ByteCollisionIndex+1),AnticolParameter,pDataRead);
|
||||
|
||||
if(pDataRead[0] != 0x80)
|
||||
return ISO14443A_ERRORCODE_DEFAULT;
|
||||
|
||||
/* check if there is another collision to take into account*/
|
||||
NbResponseByte = pDataRead[1];
|
||||
Collision = (pDataRead[NbResponseByte-1]) & 0x80;
|
||||
|
||||
if ( Collision == 0x80)
|
||||
{
|
||||
NewByteCollisionIndex = pDataRead[NbResponseByte];
|
||||
NewBitCollisionIndex = pDataRead[NbResponseByte+1];
|
||||
}
|
||||
|
||||
/* we can check that non-alignement is the one expected */
|
||||
RemainingBit = 8 - (0x0F & (pDataRead[2+(NbResponseByte-2)-1]));
|
||||
if( RemainingBit == BitCollisionIndex+1)
|
||||
{
|
||||
/* recreate the good UID */
|
||||
if( ByteCollisionIndex == 0)
|
||||
{
|
||||
UID [0] = ((~(0xFF << (BitCollisionIndex+1))) & AnticolParameter[2]) | pDataRead[2] ;
|
||||
UID [1] = pDataRead[3];
|
||||
UID [2] = pDataRead[4];
|
||||
UID [3] = pDataRead[5];
|
||||
}
|
||||
else if( ByteCollisionIndex == 1)
|
||||
{
|
||||
UID [1] = ((~(0xFF << (BitCollisionIndex+1))) & AnticolParameter[3]) | pDataRead[2] ;
|
||||
UID [2] = pDataRead[3];
|
||||
UID [3] = pDataRead[4];
|
||||
}
|
||||
else if( ByteCollisionIndex == 2)
|
||||
{
|
||||
UID [2] = ((~(0xFF << (BitCollisionIndex+1))) & AnticolParameter[4]) | pDataRead[2] ;
|
||||
UID [3] = pDataRead[3];
|
||||
}
|
||||
else if( ByteCollisionIndex == 3)
|
||||
{
|
||||
UID [3] = ((~(0xFF << (BitCollisionIndex+1))) & AnticolParameter[5]) | pDataRead[2] ;
|
||||
}
|
||||
else
|
||||
return ISO14443A_ERRORCODE_DEFAULT;
|
||||
}
|
||||
else
|
||||
return ISO14443A_ERRORCODE_DEFAULT;
|
||||
|
||||
/* prepare the buffer expected by the caller */
|
||||
pDataRead[0] = 0x80;
|
||||
pDataRead[1] = NbResponseByteOrigin;
|
||||
pDataRead[2] = UID [0];
|
||||
pDataRead[3] = UID [1];
|
||||
pDataRead[4] = UID [2];
|
||||
pDataRead[5] = UID [3];
|
||||
pDataRead[6] = UID[0]^UID[1]^UID[2]^UID[3];
|
||||
|
||||
/* if collision was detected restart anticol */
|
||||
if ( Collision == 0x80)
|
||||
{
|
||||
if( ByteCollisionIndex != NewByteCollisionIndex )
|
||||
{
|
||||
ByteCollisionIndex += NewByteCollisionIndex;
|
||||
BitCollisionIndex = NewBitCollisionIndex;
|
||||
}
|
||||
else
|
||||
{
|
||||
ByteCollisionIndex += NewByteCollisionIndex;
|
||||
BitCollisionIndex += (NewBitCollisionIndex+1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return ISO14443A_SUCCESSCODE;
|
||||
Error:
|
||||
return ISO14443A_ERRORCODE_DEFAULT;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief this function carries out the first level of the anticollision
|
||||
* @param *pDataRead : Pointer to the PCD response
|
||||
* @return ISO14443A_SUCCESSCODE the function is succesful
|
||||
* @return ISO14443A_ERRORCODE_DEFAULT : an error occured
|
||||
*/
|
||||
static int8_t ISO14443A_ACLevel1( uint8_t *pDataRead )
|
||||
{
|
||||
uint8_t *pDataToSend = &(u95HFBuffer[PCD_DATA_OFFSET]),
|
||||
Length = 0,
|
||||
BccByte ;
|
||||
int8_t status;
|
||||
|
||||
/* Perform anti-collision */
|
||||
errchk(ISO14443A_AC(pDataRead, SEL_CASCADE_LVL_1));
|
||||
|
||||
/* Saves the UID in the structure */
|
||||
if(ISO14443A_Card.UIDsize == ISO14443A_UID_SINGLE_SIZE)
|
||||
{
|
||||
memcpy( ISO14443A_Card.UID, &pDataRead[PCD_DATA_OFFSET], ISO14443A_UID_SINGLE_SIZE );
|
||||
}
|
||||
else
|
||||
{
|
||||
memcpy(ISO14443A_Card.UID, &pDataRead[PCD_DATA_OFFSET+1], ISO14443A_UID_PART);
|
||||
}
|
||||
|
||||
/* copies the BCC byte of the card response*/
|
||||
BccByte = pDataRead[PCD_DATA_OFFSET + ISO14443A_UID_SINGLE_SIZE ];
|
||||
|
||||
/* Preparing the buffer who contains the SELECT command */
|
||||
pDataToSend[Length ++] = SEL_CASCADE_LVL_1;
|
||||
pDataToSend[Length ++] = ISO14443A_NVM_70;
|
||||
|
||||
/* Inserts the previous reply in the next command */
|
||||
if(ISO14443A_Card.UIDsize == ISO14443A_UID_SINGLE_SIZE)
|
||||
{
|
||||
memcpy(&pDataToSend[Length], ISO14443A_Card.UID, ISO14443A_UID_SINGLE_SIZE );
|
||||
Length += ISO14443A_UID_SINGLE_SIZE ;
|
||||
}
|
||||
else
|
||||
{
|
||||
pDataToSend[Length ++] = 0x88;
|
||||
memcpy(&pDataToSend[Length], ISO14443A_Card.UID, ISO14443A_UID_PART );
|
||||
Length += ISO14443A_UID_PART ;
|
||||
}
|
||||
pDataToSend[Length ++] = BccByte;
|
||||
/* Add the control byte : Append the CRC + 8 bits in first byte (standard frame)*/
|
||||
pDataToSend[Length ++] = PCD_ISO14443A_APPENDCRC | PCD_ISO14443A_A8BITSINFIRSTBYTE;
|
||||
|
||||
errchk(PCD_SendRecv(Length,pDataToSend,pDataRead));
|
||||
|
||||
/* Recovering SAK byte */
|
||||
ISO14443A_Card.SAK = pDataRead[PCD_DATA_OFFSET];
|
||||
|
||||
return ISO14443A_SUCCESSCODE;
|
||||
Error:
|
||||
return ISO14443A_ERRORCODE_DEFAULT;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief this function carries out the second level of the anticollision
|
||||
* @param *pDataRead : Pointer to the PCD response
|
||||
* @return ISO14443A_SUCCESSCODE the function is succesful
|
||||
* @return ISO14443A_ERRORCODE_DEFAULT : an error occured
|
||||
*/
|
||||
static int8_t ISO14443A_ACLevel2( uint8_t *pDataRead )
|
||||
{
|
||||
uint8_t *pDataToSend = &(u95HFBuffer[PCD_DATA_OFFSET]),
|
||||
Length = 0,
|
||||
BccByte ;
|
||||
int8_t status;
|
||||
|
||||
/* Perform anti-collision */
|
||||
errchk(ISO14443A_AC(pDataRead, SEL_CASCADE_LVL_2));
|
||||
//errchk(PCD_SendRecv(0x03,AnnticolParameter,pDataRead));
|
||||
|
||||
/* Copies the UID into the data structure */
|
||||
if(ISO14443A_Card.UIDsize == ISO14443A_UID_DOUBLE_SIZE)
|
||||
{
|
||||
memcpy(&ISO14443A_Card.UID[ISO14443A_UID_PART], &pDataRead[PCD_DATA_OFFSET], ISO14443A_UID_SINGLE_SIZE);
|
||||
}
|
||||
else
|
||||
{
|
||||
memcpy(&ISO14443A_Card.UID[ISO14443A_UID_PART], &pDataRead[PCD_DATA_OFFSET+1], ISO14443A_UID_PART);
|
||||
}
|
||||
|
||||
/* copies the BCC byte of the card response*/
|
||||
BccByte = pDataRead[PCD_DATA_OFFSET + ISO14443A_UID_SINGLE_SIZE ];
|
||||
|
||||
/* Preparing the buffer who contains the SELECT command */
|
||||
pDataToSend[Length ++] = SEL_CASCADE_LVL_2;
|
||||
pDataToSend[Length ++] = ISO14443A_NVM_70;
|
||||
|
||||
/* Copies the UID into the data structure */
|
||||
if(ISO14443A_Card.UIDsize == ISO14443A_UID_DOUBLE_SIZE)
|
||||
{
|
||||
memcpy(&(pDataToSend[Length]),&(ISO14443A_Card.UID[ISO14443A_UID_PART]) , ISO14443A_UID_SINGLE_SIZE);
|
||||
Length += ISO14443A_UID_SINGLE_SIZE ;
|
||||
}
|
||||
else
|
||||
{
|
||||
pDataToSend[Length ++] = 0x88;
|
||||
memcpy(&(pDataToSend[Length]),&(ISO14443A_Card.UID[ISO14443A_UID_PART]) , ISO14443A_UID_PART);
|
||||
Length += ISO14443A_UID_PART ;
|
||||
}
|
||||
pDataToSend[Length ++] = BccByte;
|
||||
/* Add the control byte : Append the CRC + 8 bits in first byte (standard frame)*/
|
||||
pDataToSend[Length ++] = PCD_ISO14443A_APPENDCRC | PCD_ISO14443A_A8BITSINFIRSTBYTE;
|
||||
|
||||
/* emit the select command */
|
||||
errchk(PCD_SendRecv(Length,pDataToSend,pDataRead));
|
||||
|
||||
/* Recovering SAK byte */
|
||||
ISO14443A_Card.SAK = pDataRead[PCD_DATA_OFFSET];
|
||||
|
||||
return ISO14443A_SUCCESSCODE;
|
||||
Error:
|
||||
return ISO14443A_ERRORCODE_DEFAULT;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @brief this function carries out the second level of the anticollision
|
||||
* @param *pDataRead : Pointer to the PCD response
|
||||
* @return ISO14443A_SUCCESSCODE the function is succesful
|
||||
* @return ISO14443A_ERRORCODE_DEFAULT : an error occured
|
||||
*/
|
||||
static int8_t ISO14443A_ACLevel3 ( uint8_t *pDataRead )
|
||||
{
|
||||
uint8_t *pDataToSend = &(u95HFBuffer[PCD_DATA_OFFSET]),
|
||||
Length = 0,
|
||||
BccByte ;
|
||||
int8_t status;
|
||||
|
||||
/* Perform anti-collision */
|
||||
errchk(ISO14443A_AC(pDataRead, SEL_CASCADE_LVL_3));
|
||||
|
||||
/* Copies the UID into the data structure */
|
||||
memcpy(&ISO14443A_Card.UID[ISO14443A_UID_PART], &pDataRead[PCD_DATA_OFFSET], ISO14443A_UID_SINGLE_SIZE);
|
||||
/* copies the BCC byte of the card response*/
|
||||
BccByte = pDataRead[PCD_DATA_OFFSET + ISO14443A_UID_SINGLE_SIZE ];
|
||||
|
||||
/* Preparing the buffer who contains the SELECT command */
|
||||
pDataToSend[Length ++] = SEL_CASCADE_LVL_3;
|
||||
pDataToSend[Length ++] = ISO14443A_NVM_70;
|
||||
|
||||
/* Copies the UID into the data structure */
|
||||
if(ISO14443A_Card.UIDsize == ISO14443A_UID_TRIPLE_SIZE)
|
||||
{
|
||||
memcpy(&(pDataToSend[Length]),&(ISO14443A_Card.UID[ISO14443A_UID_PART]) , ISO14443A_UID_SINGLE_SIZE);
|
||||
Length += ISO14443A_UID_SINGLE_SIZE ;
|
||||
}
|
||||
|
||||
pDataToSend[Length ++] = BccByte;
|
||||
/* Add the control byte : Append the CRC + 8 bits in first byte (standard frame)*/
|
||||
pDataToSend[Length ++] = PCD_ISO14443A_APPENDCRC | PCD_ISO14443A_A8BITSINFIRSTBYTE;
|
||||
|
||||
/* emitthe select command */
|
||||
errchk(PCD_SendRecv(Length,pDataToSend,pDataRead));
|
||||
|
||||
/* Recovering SAK byte */
|
||||
ISO14443A_Card.SAK = pDataRead[PCD_DATA_OFFSET];
|
||||
|
||||
return ISO14443A_SUCCESSCODE;
|
||||
Error:
|
||||
return ISO14443A_ERRORCODE_DEFAULT;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief this functions sends the HLTA command to the PCD device
|
||||
* @param *pDataRead : Pointer to the PCD response
|
||||
* @return ISO14443A_SUCCESSCODE the function is succesful
|
||||
* @return ISO14443A_ERRORCODE_DEFAULT : an error occured
|
||||
*/
|
||||
static int8_t ISO14443A_HLTA( uint8_t *pDataRead )
|
||||
{
|
||||
const uint8_t pdata[]= { 0x50, 0x00, 0x28};
|
||||
|
||||
/* send the command to the PCD device*/
|
||||
PCD_SendRecv(0x03,pdata,pDataRead);
|
||||
|
||||
return ISO14443A_SUCCESSCODE;
|
||||
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @brief this functions emits the RATS command to PICC device
|
||||
* @param *pDataRead : Pointer to the response
|
||||
* @return ISO14443A_SUCCESSCODE the function is succesful
|
||||
* @return ISO14443A_ERRORCODE_DEFAULT : an error occured
|
||||
*/
|
||||
static int8_t ISO14443A_RATS( uint8_t *pDataRead )
|
||||
{
|
||||
int8_t status;
|
||||
uint8_t FSCI;
|
||||
const uint8_t pdata[]= { 0xE0, 0x80, 0x28};
|
||||
|
||||
/* send the command to the PCD device*/
|
||||
errchk(PCD_SendRecv(0x03,pdata,pDataRead));
|
||||
/* check the status byte of the PCD device */
|
||||
errchk(PCD_IsReaderResultCodeOk (SEND_RECEIVE,pDataRead) );
|
||||
/* check the CRC */
|
||||
errchk(PCD_IsCRCOk (PCD_PROTOCOL_ISO14443A,pDataRead) );
|
||||
|
||||
FSCI = pDataRead[3]&0x0F;
|
||||
FSC = FSCIToFSC(FSCI);
|
||||
|
||||
/* Check if FWI is present */
|
||||
if( (pDataRead[3] & 0x20) == 0x20)
|
||||
{
|
||||
if( (pDataRead[3] & 0x10) == 0x10)
|
||||
FWI = (pDataRead[5]&0xF0)>>4;
|
||||
else
|
||||
FWI = (pDataRead[4]&0xF0)>>4;
|
||||
}
|
||||
|
||||
return ISO14443A_SUCCESSCODE;
|
||||
Error:
|
||||
return ISO14443A_ERRORCODE_DEFAULT;
|
||||
}
|
||||
|
||||
#if 0
|
||||
/**
|
||||
* @brief Handles the WAKE_UP command
|
||||
* @param *pDataRead : Pointer to the response
|
||||
* @return ISO14443A_SUCCESSCODE the function is succesful
|
||||
* @return ISO14443A_ERRORCODE_DEFAULT : an error occured
|
||||
*/
|
||||
static int8_t ISO14443A_PPS( uint8_t *pDataRead )
|
||||
{
|
||||
const uint8_t pdata[]= { 0xD0, 0x11, 0x00, 0x28};
|
||||
int8_t status;
|
||||
|
||||
/* sends the command to the PCD device*/
|
||||
errchk(PCD_SendRecv(0x04,pdata,pDataRead));
|
||||
|
||||
/* checks the CRC */
|
||||
errchk(PCD_IsCRCOk (PCD_PROTOCOL_ISO14443A,pDataRead) );
|
||||
|
||||
return ISO14443A_SUCCESSCODE;
|
||||
Error:
|
||||
return ISO14443A_ERRORCODE_DEFAULT;
|
||||
}
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief this function completes the ISO144443 type A structure according to the ATQA response
|
||||
*/
|
||||
static void ISO14443A_CompleteStructure ( uint8_t *pATQA )
|
||||
{
|
||||
|
||||
/* according to FSP ISO 11443-3 the b7&b8 bits of ATQA tag answer is UID size bit frame */
|
||||
/* Recovering the UID size */
|
||||
switch ((ISO14443A_Card.ATQA[0] & ISO14443A_UID_MASK)>>6)
|
||||
{
|
||||
case ATQ_FLAG_UID_SINGLE_SIZE:
|
||||
ISO14443A_Card.UIDsize = ISO14443A_UID_SINGLE_SIZE;
|
||||
ISO14443A_Card.CascadeLevel = CASCADE_LVL_1;
|
||||
break;
|
||||
case ATQ_FLAG_UID_DOUBLE_SIZE:
|
||||
ISO14443A_Card.UIDsize = ISO14443A_UID_DOUBLE_SIZE;
|
||||
ISO14443A_Card.CascadeLevel = CASCADE_LVL_2;
|
||||
break;
|
||||
case ATQ_FLAG_UID_TRIPLE_SIZE:
|
||||
ISO14443A_Card.UIDsize = ISO14443A_UID_TRIPLE_SIZE;
|
||||
ISO14443A_Card.CascadeLevel = CASCADE_LVL_3;
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @brief Checks if a card is in the field
|
||||
* @param None
|
||||
* @return ISO14443A_SUCCESSCODE (Anticollision done) / ISO14443A_ERRORCODE_DEFAULT (Communication issue)
|
||||
*/
|
||||
static int8_t ISO14443A_MultiAnticollision( void )
|
||||
{
|
||||
uint8_t *pDataRead = u95HFBufferAntiCol;
|
||||
int8_t status;
|
||||
|
||||
|
||||
/* Checks if an error occured and execute the Anti-collision level 1*/
|
||||
errchk(ISO14443A_ACLevel1(pDataRead) );
|
||||
|
||||
/* UID Complete ? */
|
||||
if(ISO14443A_Card.SAK & SAK_FLAG_UID_NOT_COMPLETE)
|
||||
{
|
||||
/* Checks if an error occured and execute the Anti-collision level 2*/
|
||||
errchk(ISO14443A_ACLevel2(pDataRead) );
|
||||
}
|
||||
/* UID Complete ? */
|
||||
if(ISO14443A_Card.SAK & SAK_FLAG_UID_NOT_COMPLETE)
|
||||
{
|
||||
/* Checks if an error occured and execute the Anti-collision level 3*/
|
||||
errchk(ISO14443A_ACLevel3(pDataRead) );
|
||||
}
|
||||
|
||||
/* Quiet the founded tag */
|
||||
/* Send a HALT command */
|
||||
errchk(ISO14443A_HLTA(pDataRead) );
|
||||
|
||||
return ISO14443A_SUCCESSCODE;
|
||||
Error:
|
||||
return ISO14443A_ERRORCODE_DEFAULT;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
|
||||
/** @addtogroup lib_iso14443Apcd_Public_Functions
|
||||
* @{
|
||||
*/
|
||||
|
||||
|
||||
/**
|
||||
* @brief this command initializes the PCD device for the IS014443A protocol
|
||||
* @param none
|
||||
* @return ISO14443A_SUCCESSCODE the function is succesful
|
||||
* @return ISO14443A_ERRORCODE_DEFAULT : an error occured
|
||||
*/
|
||||
int8_t ISO14443A_Init(void)
|
||||
{
|
||||
int8_t status;
|
||||
|
||||
ISO14443A_InitStructure( );
|
||||
|
||||
/* sends a protocol Select command to the pcd to configure it */
|
||||
errchk(ISO14443A_ConfigFDTforAnticollision());
|
||||
|
||||
TechnoSelected = PCDPROTOCOL_14443A;
|
||||
|
||||
/* GT min time to respect before sending REQ_A */
|
||||
delay(5);
|
||||
|
||||
return ISO14443A_SUCCESSCODE;
|
||||
Error:
|
||||
return ISO14443A_ERRORCODE_DEFAULT;
|
||||
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @brief Initializes the PCD device for the IS014443A protocol
|
||||
* @param *pDataRead : Pointer to the PCD response
|
||||
* @return ISO14443A_SUCCESSCODE the function is succesful
|
||||
* @return ISO14443A_ERRORCODE_DEFAULT : an error occured
|
||||
*/
|
||||
int8_t TOPAZ_ID( uint8_t *pDataRead)
|
||||
{
|
||||
uint8_t Tag_error_check;
|
||||
|
||||
if(PCD_CheckSendReceive(TOPAZ, pDataRead) != ISO14443A_SUCCESSCODE)
|
||||
return ISO14443A_ERRORCODE_DEFAULT;
|
||||
|
||||
Tag_error_check = pDataRead[RFTRANS_95HF_LENGTH_OFFSET]-1;
|
||||
if((pDataRead[Tag_error_check] & ISO14443A_CRCMASK) == ISO14443A_CRC_ERRORCODE_TYPEA)
|
||||
return ISO14443A_ERRORCODE_CRC;
|
||||
|
||||
if(pDataRead[0] == SENDRECV_RESULTSCODE_OK && pDataRead[1] == 0x04)
|
||||
return ISO14443A_ERRORCODE_DEFAULT;
|
||||
|
||||
devicemode = PCD;
|
||||
if (pDataRead[0] == 0x80)
|
||||
nfc_tagtype = TT1;
|
||||
else
|
||||
return ISO14443A_ERRORCODE_DEFAULT;
|
||||
|
||||
return ISO14443A_SUCCESSCODE;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @brief Checks if a ISO14443A card is in the field
|
||||
* @return ISO14443A_SUCCESSCODE the function is succesful
|
||||
* @return ISO14443A_ERRORCODE_DEFAULT : an error occured
|
||||
*/
|
||||
int8_t ISO14443A_IsPresent( void )
|
||||
{
|
||||
uint8_t *pDataRead = u95HFBuffer;
|
||||
int8_t status;
|
||||
|
||||
errchk(ISO14443A_REQA(pDataRead));
|
||||
|
||||
/* checks the status byte of the PCD device */
|
||||
errchk(PCD_IsReaderResultCodeOk (SEND_RECEIVE,pDataRead) );
|
||||
|
||||
ISO14443A_Card.IsDetected = true;
|
||||
|
||||
return ISO14443A_SUCCESSCODE;
|
||||
Error:
|
||||
return ISO14443A_ERRORCODE_DEFAULT;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* @brief Checks if a card is in the field
|
||||
* @param None
|
||||
* @return ISO14443A_SUCCESSCODE (Anticollision done) / ISO14443A_ERRORCODE_DEFAULT (Communication issue)
|
||||
*/
|
||||
int8_t ISO14443A_Anticollision( void )
|
||||
{
|
||||
uint8_t *pDataRead = u95HFBuffer;
|
||||
int8_t status;
|
||||
|
||||
/* Checks if an error occured and execute the Anti-collision level 1*/
|
||||
errchk(ISO14443A_ACLevel1(pDataRead) );
|
||||
|
||||
/* UID Complete ? */
|
||||
if(ISO14443A_Card.SAK & SAK_FLAG_UID_NOT_COMPLETE)
|
||||
{
|
||||
/* Checks if an error occured and execute the Anti-collision level 2*/
|
||||
errchk(ISO14443A_ACLevel2(pDataRead) );
|
||||
}
|
||||
/* UID Complete ? */
|
||||
if(ISO14443A_Card.SAK & SAK_FLAG_UID_NOT_COMPLETE)
|
||||
{
|
||||
/* Checks if an error occured and execute the Anti-collision level 2*/
|
||||
errchk(ISO14443A_ACLevel3(pDataRead) );
|
||||
}
|
||||
|
||||
/* Checks if the RATS command is supported by the card */
|
||||
if(ISO14443A_Card.SAK & SAK_FLAG_ATS_SUPPORTED)
|
||||
{
|
||||
ISO14443A_ConfigFDTforRATS();
|
||||
|
||||
ISO14443A_Card.ATSSupported = true;
|
||||
errchk(ISO14443A_RATS(pDataRead) );
|
||||
}
|
||||
|
||||
/* Change the FDT to accept APDU */
|
||||
ISO14443A_ConfigFDT(1);
|
||||
|
||||
devicemode = PCD;
|
||||
/* Check the Tag type found */
|
||||
if ((ISO14443A_Card.SAK&0x60) == 0x00) /* TT2 */
|
||||
nfc_tagtype = TT2;
|
||||
else if( (ISO14443A_Card.SAK & 0x20) == 0x20)
|
||||
nfc_tagtype = TT4A;
|
||||
|
||||
return ISO14443A_SUCCESSCODE;
|
||||
Error:
|
||||
return ISO14443A_ERRORCODE_DEFAULT;
|
||||
|
||||
}
|
||||
|
||||
int8_t ISO14443A_ConfigFDTforAnticollision( void)
|
||||
{
|
||||
u8 ProtocolSelectParameters [6] = {0x00, 0x00, 0x00, 0x00, 0x02, 0x02}; /* last 2 bytes since QJE version */
|
||||
u8 WriteRegisterParameters [2] = {PCD_TYPEA_TIMERW, TIMER_WINDOW_UPDATE_CONFIRM_CMD};
|
||||
u8 DemoGainParameters [2] = {PCD_TYPEA_ARConfigA, PCD_TYPEA_ARConfigB};
|
||||
u8 NbParam = 0;
|
||||
uint8_t *pDataRead = u95HFBuffer;
|
||||
int8_t status;
|
||||
|
||||
if( IcVers >= QJE)
|
||||
NbParam = 6;
|
||||
else
|
||||
NbParam = 4;
|
||||
|
||||
errchk(PCD_ProtocolSelect((NbParam+1),PCD_PROTOCOL_ISO14443A,ProtocolSelectParameters,pDataRead));
|
||||
errchk(PCD_WriteRegister ( 0x04,TIMER_WINDOW_REG_ADD,0x00,WriteRegisterParameters,pDataRead));
|
||||
/* in order to adjust the demoduation gain of the PCD which is reseted at each protocol select */
|
||||
errchk(PCD_WriteRegister (0x04,AFE_ANALOG_CONF_REG_SELECTION,0x01,DemoGainParameters,u95HFBuffer));
|
||||
|
||||
return ISO14443A_SUCCESSCODE;
|
||||
Error:
|
||||
return ISO14443A_ERRORCODE_DEFAULT;
|
||||
}
|
||||
|
||||
int8_t ISO14443A_ConfigFDTforRATS( void)
|
||||
{
|
||||
u8 ProtocolSelectParameters [6] = {0x00, 0x00, 0x00, 0x00, 0x03, 0x03}; /* last 2 bytes since QJE version */
|
||||
u8 WriteRegisterParameters [2] = {PCD_TYPEA_TIMERW, TIMER_WINDOW_UPDATE_CONFIRM_CMD};
|
||||
u8 DemoGainParameters [2] = {PCD_TYPEA_ARConfigA, PCD_TYPEA_ARConfigB};
|
||||
u8 NbParam = 0;
|
||||
uint8_t *pDataRead = u95HFBuffer;
|
||||
int8_t status;
|
||||
|
||||
if( IcVers >= QJE)
|
||||
NbParam = 6;
|
||||
else
|
||||
NbParam = 4;
|
||||
|
||||
/* Change the PP:MM parameter to respect RATS timing TS-DP-1.1 13.8.1.1*/
|
||||
/* min to respect */
|
||||
/* FDT PCD = FWTt4at,activation = 71680 (1/fc) */
|
||||
/* (2^PP)*(MM+1)*(DD+128)*32 = 71680 ==> PP = 4 MM=0 DD=12*/
|
||||
/* max to respect not mandatory and as Tag has a FWT activation of 5.2us */
|
||||
/* adding 16.4ms does not make sense ... */
|
||||
/* FDT PCD = FWTt4at,activation + dela(t4at,poll) = 5286us + 16.4ms ~= 21.7ms */
|
||||
/* (2^PP)*(MM+1)*(DD+128)*32 = 21,7 ==> PP = 4 MM=0 DD=12*/
|
||||
ProtocolSelectParameters[1] = 4; // PP
|
||||
ProtocolSelectParameters[2] = 0; // MM
|
||||
ProtocolSelectParameters[3] = 12; // DD
|
||||
errchk(PCD_ProtocolSelect((NbParam+1),PCD_PROTOCOL_ISO14443A,ProtocolSelectParameters,pDataRead));
|
||||
errchk(PCD_WriteRegister ( 0x04,TIMER_WINDOW_REG_ADD,0x00,WriteRegisterParameters,pDataRead));
|
||||
/* in order to adjust the demoduation gain of the PCD which is reseted at each protocol select */
|
||||
errchk(PCD_WriteRegister (0x04,AFE_ANALOG_CONF_REG_SELECTION,0x01,DemoGainParameters,u95HFBuffer));
|
||||
|
||||
return ISO14443A_SUCCESSCODE;
|
||||
Error:
|
||||
return ISO14443A_ERRORCODE_DEFAULT;
|
||||
}
|
||||
|
||||
int8_t ISO14443A_ConfigFDT( uint8_t WTXM)
|
||||
{
|
||||
u8 ProtocolSelectParameters [6] = {0x00, 0x00, 0x00, 0x00, 0x03, 0x03}; /* last 2 bytes since QJE version */
|
||||
u8 WriteRegisterParameters [2] = {PCD_TYPEA_TIMERW, TIMER_WINDOW_UPDATE_CONFIRM_CMD};
|
||||
u8 DemoGainParameters [2] = {PCD_TYPEA_ARConfigA, PCD_TYPEA_ARConfigB};
|
||||
u8 NbParam = 0;
|
||||
uint8_t *pDataRead = u95HFBuffer;
|
||||
int8_t status;
|
||||
|
||||
if( IcVers >= QJE)
|
||||
NbParam = 6;
|
||||
else
|
||||
NbParam = 4;
|
||||
|
||||
/* FWI was updated thanks to ATS, if not the case use default value FWI = 4 TS-DP-1.1 13.6.2.11 */
|
||||
/* FDT PCD = FWT PICC + deltaFWT(t4at) + "deltaT(t4at,poll)" TS-DP-1.1 13.8*/
|
||||
/* If we perform some identification:
|
||||
FDT = (2^PP)*(MM+1)*(DD+128)*32/13.56
|
||||
FDT = (2^(PP))*(1)*(2*DD+256)*16/13.56 + (2^(PP))*(MM)*(2*DD+256)*16/13.56
|
||||
FDT = (256*16/fc)*2^FWI + ((2^FWI) *256*16*1/fc)*MM with PP=FWI and DD=0
|
||||
FDT = (2^FWI)*4096*1/fc + FWT*MM (EQUATION 1)
|
||||
|
||||
I_ With the choice to NOT add deltaT(t4at,poll) = 16,4ms
|
||||
1) In the standard case (No extension time cmd received) we want
|
||||
FDT = FWT + delta FWT(T4AT)
|
||||
FDT = FWT + 49152 (1/fc)
|
||||
|
||||
If we take the rules that we will never set FWI to a value less than 4.
|
||||
(EQUATION 1 comes)
|
||||
FDT = FWT*MM + 65536*1/fc => delta FWT(T4AT) is respected
|
||||
|
||||
As a conclusion with
|
||||
PP=FWI (with FWI>=4)
|
||||
MM=1
|
||||
DD=0
|
||||
we are following the specification.
|
||||
|
||||
2) In the case of extension time request, M will take the WTXM value. */
|
||||
|
||||
if(FWI < 4 )
|
||||
FWI = 4;
|
||||
|
||||
ProtocolSelectParameters[1] = FWI; // PP
|
||||
ProtocolSelectParameters[2] = WTXM; // MM
|
||||
ProtocolSelectParameters[3] = 0; // DD
|
||||
|
||||
errchk(PCD_ProtocolSelect((NbParam+1),PCD_PROTOCOL_ISO14443A,ProtocolSelectParameters,pDataRead));
|
||||
errchk(PCD_WriteRegister ( 0x04,TIMER_WINDOW_REG_ADD,0x00,WriteRegisterParameters,pDataRead));
|
||||
/* in order to adjust the demoduation gain of the PCD which is reseted at each protocol select */
|
||||
errchk(PCD_WriteRegister (0x04,AFE_ANALOG_CONF_REG_SELECTION,0x01,DemoGainParameters,u95HFBuffer));
|
||||
|
||||
return ISO14443A_SUCCESSCODE;
|
||||
Error:
|
||||
return ISO14443A_ERRORCODE_DEFAULT;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Checks if cards are in the field
|
||||
* @param *pNbTag: Number of tag detected
|
||||
* @param *pUIDout: UIDs of detected tags (11 bytes by tag, first byte indicate UID size)
|
||||
* @return ISO14443A_SUCCESSCODE (Anticollision done) / ISO14443A_ERRORCODE_DEFAULT (Communication issue)
|
||||
*/
|
||||
void ISO14443A_MultiTagHunting ( uint8_t *pNbTag, uint8_t *pUIDout )
|
||||
{
|
||||
|
||||
bool exit = false;
|
||||
u8 loop = 0;
|
||||
u8 i = 0;
|
||||
|
||||
RemainingID = 0;
|
||||
*pNbTag = 0;
|
||||
|
||||
delay(5);
|
||||
|
||||
ISO14443A_InitStructure(); /* only initialize structure */
|
||||
|
||||
while( exit == false && loop<= ISO14443A_NB_TAG_MAX )
|
||||
{
|
||||
ISO14443A_InitStructure();
|
||||
if(ISO14443A_IsPresent() == RESULTOK)
|
||||
{
|
||||
delayMicroseconds (50);
|
||||
if(ISO14443A_MultiAnticollision() == RESULTOK)
|
||||
{
|
||||
MultiID[0+((*pNbTag)*11)] = ISO14443A_Card.UIDsize;
|
||||
for(i=0; i<10; i++)
|
||||
{
|
||||
MultiID[(1+i)+((*pNbTag)*11)] = ISO14443A_Card.UID[i];
|
||||
}
|
||||
*pNbTag +=1;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
/* no more tag */
|
||||
exit = true;
|
||||
}
|
||||
loop++;
|
||||
}
|
||||
|
||||
if( *pNbTag <= 5)
|
||||
{
|
||||
memcpy(pUIDout, &MultiID[0], (*pNbTag)*11 );
|
||||
}
|
||||
else
|
||||
{
|
||||
memcpy(pUIDout, &MultiID[0], 5*11 );
|
||||
RemainingID = (*pNbTag-5);
|
||||
memcpy(&MultiIDPart2[0], &MultiID[5*11] , RemainingID*11 );
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
void ISO14443A_MultiTagPart2 ( uint8_t *pNbTag, uint8_t *pUIDout )
|
||||
{
|
||||
memcpy(pUIDout, &MultiIDPart2[0], RemainingID*11);
|
||||
*pNbTag = RemainingID;
|
||||
}
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
//#ifdef __cplusplus
|
||||
//}
|
||||
//#endif
|
||||
|
||||
/******************* (C) COPYRIGHT 2015 STMicroelectronics *****END OF FILE****/
|
||||
129
src/lib_iso14443Apcd.h
Normal file
129
src/lib_iso14443Apcd.h
Normal file
@@ -0,0 +1,129 @@
|
||||
/**
|
||||
******************************************************************************
|
||||
* @file lib_iso14443Apcd.h
|
||||
* @author MMY Application Team
|
||||
* @version $Revision: 1333 $
|
||||
* @date $Date: 2015-11-05 10:49:42 +0100 (Thu, 05 Nov 2015) $
|
||||
* @brief Manage the iso14443A communication
|
||||
******************************************************************************
|
||||
* @attention
|
||||
*
|
||||
* <h2><center>© COPYRIGHT 2015 STMicroelectronics</center></h2>
|
||||
*
|
||||
* Licensed under ST MYLIBERTY SOFTWARE LICENSE AGREEMENT (the "License");
|
||||
* You may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at:
|
||||
*
|
||||
* http://www.st.com/myliberty
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied,
|
||||
* AND SPECIFICALLY DISCLAIMING THE IMPLIED WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE, AND NON-INFRINGEMENT.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
******************************************************************************
|
||||
*/
|
||||
|
||||
/* Define to prevent recursive inclusion -------------------------------------------------------*/
|
||||
#ifndef __ISO14443APCD_H
|
||||
#define __ISO14443APCD_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include "lib_pcd.h"
|
||||
#include "lib_iso14443A.h"
|
||||
|
||||
/* status and error code ---------------------------------------------------------------------- */
|
||||
#define ISO14443A_SUCCESSCODE RESULTOK
|
||||
#define ISO14443A_ERRORCODE_DEFAULT 0x61
|
||||
#define ISO14443A_ERRORCODE_CRC 0x62
|
||||
|
||||
|
||||
/* Anticollison levels (commands) ------------------------------------------------------------- */
|
||||
#define SEL_CASCADE_LVL_1 0x93
|
||||
#define SEL_CASCADE_LVL_2 0x95
|
||||
#define SEL_CASCADE_LVL_3 0x97
|
||||
#define COMMAND_RATS 0xE0
|
||||
#define COMMAND_PPS 0xD0
|
||||
|
||||
/* Iblock ------------------------------------------------------------------------------------- */
|
||||
#define COMMAND_IBLOCK02 0x02
|
||||
#define COMMAND_IBLOCK03 0x03
|
||||
#define COMMAND_SBLOCK 0xC2
|
||||
#define COMMAND_NACKBLOCK 0xB2
|
||||
#define COMMAND_ACKBLOCK 0xA2
|
||||
|
||||
|
||||
/* numbr of the cascade level ----------------------------------------------------------------- */
|
||||
#define CASCADE_LVL_1 1
|
||||
#define CASCADE_LVL_2 2
|
||||
#define CASCADE_LVL_3 3
|
||||
|
||||
#define ISO14443A_NVM_10 0x10
|
||||
#define ISO14443A_NVM_20 0x20
|
||||
#define ISO14443A_NVM_30 0x30
|
||||
#define ISO14443A_NVM_40 0x40
|
||||
#define ISO14443A_NVM_50 0x50
|
||||
#define ISO14443A_NVM_60 0x60
|
||||
#define ISO14443A_NVM_70 0x70
|
||||
|
||||
/* UID Sizes ---------------------------------------------------------------------------------- */
|
||||
#define ISO14443A_UIDSIZE_UNDEFINED -1
|
||||
#define ISO14443A_UID_PART 3
|
||||
#define ISO14443A_UID_SINGLE_SIZE 4
|
||||
#define ISO14443A_UID_DOUBLE_SIZE 7
|
||||
#define ISO14443A_UID_TRIPLE_SIZE 10
|
||||
|
||||
|
||||
/* Mask used for ATQA ------------------------------------------------------------------------ */
|
||||
#define ISO14443A_UID_MASK 0xC0
|
||||
#define ISO14443A_AC_BIT_FRAME_MASK 0x1F
|
||||
#define ISO14443A_CID_MASK 0x0F
|
||||
#define ISO14443A_FSDI_MASK 0xF0
|
||||
|
||||
/* Size for ISO14443A variables ------------------------------------------------------------- */
|
||||
#define ISO14443A_MAX_NAME_SIZE 50
|
||||
#define ISO14443A_MAX_UID_SIZE 10
|
||||
#define ISO14443A_ATQA_SIZE 2
|
||||
|
||||
/* SAK FLAG --------------------------------------------------------------------------------- */
|
||||
#define SAK_FLAG_ATS_SUPPORTED 0x20
|
||||
#define SAK_FLAG_UID_NOT_COMPLETE 0x04
|
||||
|
||||
/* ATQ FLAG */
|
||||
#define ATQ_FLAG_UID_SINGLE_SIZE 0
|
||||
#define ATQ_FLAG_UID_DOUBLE_SIZE 1
|
||||
#define ATQ_FLAG_UID_TRIPLE_SIZE 2
|
||||
|
||||
/* MultiTag Huntig -------------------------------------------------------------------------- */
|
||||
#define ISO14443A_NB_TAG_MAX 10
|
||||
|
||||
/* ---------------------------------------------------------------------------------
|
||||
* --- Local Functions
|
||||
* --------------------------------------------------------------------------------- */
|
||||
void ISO14443A_Reset ( void );
|
||||
int8_t ISO14443A_Init ( void );
|
||||
int8_t ISO14443A_IsPresent ( void );
|
||||
int8_t ISO14443A_Anticollision ( void );
|
||||
int8_t TOPAZ_ID( uint8_t *pDataRead);
|
||||
|
||||
/* To manage dynamicaly FDT */
|
||||
int8_t ISO14443A_ConfigFDTforAnticollision( void);
|
||||
int8_t ISO14443A_ConfigFDTforRATS( void);
|
||||
int8_t ISO14443A_ConfigFDT( uint8_t WTXM);
|
||||
|
||||
void ISO14443A_MultiTagHunting ( uint8_t* pNbTag, uint8_t *pUIDout );
|
||||
void ISO14443A_MultiTagPart2 ( uint8_t *pNbTag, uint8_t *pUIDout );
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* __ISO14443A_H */
|
||||
|
||||
/******************* (C) COPYRIGHT 2015 STMicroelectronics *****END OF FILE****/
|
||||
415
src/lib_iso14443Bpcd.cpp
Normal file
415
src/lib_iso14443Bpcd.cpp
Normal file
@@ -0,0 +1,415 @@
|
||||
/**
|
||||
******************************************************************************
|
||||
* @file lib_iso14443Bpcd.c
|
||||
* @author MMY Application Team
|
||||
* @version $Revision: 1334 $
|
||||
* @date $Date: 2015-11-05 10:53:37 +0100 (Thu, 05 Nov 2015) $
|
||||
* @brief Manage the iso14443B communication
|
||||
******************************************************************************
|
||||
* @attention
|
||||
*
|
||||
* <h2><center>© COPYRIGHT 2015 STMicroelectronics</center></h2>
|
||||
*
|
||||
* Licensed under ST MYLIBERTY SOFTWARE LICENSE AGREEMENT (the "License");
|
||||
* You may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at:
|
||||
*
|
||||
* http://www.st.com/myliberty
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied,
|
||||
* AND SPECIFICALLY DISCLAIMING THE IMPLIED WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE, AND NON-INFRINGEMENT.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
******************************************************************************
|
||||
*/
|
||||
|
||||
//#ifdef __cplusplus
|
||||
// extern "C" {
|
||||
//#endif
|
||||
|
||||
/* Includes ------------------------------------------------------------------------------ */
|
||||
#include "Arduino.h"
|
||||
#include "lib_iso14443Bpcd.h"
|
||||
|
||||
/* ISO14443B */
|
||||
#define PCD_TYPEB_ARConfigA 0x01
|
||||
#define PCD_TYPEB_ARConfigB 0x51
|
||||
|
||||
extern uint8_t u95HFBuffer [RFTRANS_95HF_MAX_BUFFER_SIZE+3];
|
||||
extern IC_VERSION IcVers;
|
||||
|
||||
/* Variables for the different modes */
|
||||
extern DeviceMode_t devicemode;
|
||||
extern TagType_t nfc_tagtype;
|
||||
|
||||
extern PCD_PROTOCOL TechnoSelected;
|
||||
|
||||
/* private variables -----------------------------------------------------------------*/
|
||||
ISO14443B_CARD ISO14443B_Card;
|
||||
|
||||
static void ISO14443B_InitStructure ( void );
|
||||
static void ISO14443B_CompleteStruture ( uint8_t *pDataRead );
|
||||
static int8_t ISO14443B_WriteARConfigB ( void );
|
||||
static int8_t ISO14443B_WriteAndCheckARConfigB ( void );
|
||||
static int8_t ISO14443BReadARConfigB ( uint8_t *pDataRead );
|
||||
|
||||
/** @addtogroup _95HF_Libraries
|
||||
* @{
|
||||
* @brief <b>This is the library used by the whole 95HF family (RX95HF, CR95HF, ST95HF) <br />
|
||||
* You will find ISO libraries ( 14443A, 14443B, 15693, ...) for PICC and PCD <br />
|
||||
* The libraries selected in the project will depend of the application targetted <br />
|
||||
* and the product chosen (RX95HF emulate PICC, CR95HF emulate PCD, ST95HF can do both)</b>
|
||||
*/
|
||||
|
||||
/** @addtogroup PCD
|
||||
* @{
|
||||
* @brief This part of the library enables PCD capabilities of CR95HF & ST95HF.
|
||||
*/
|
||||
|
||||
|
||||
/** @addtogroup ISO14443B_pcd
|
||||
* @{
|
||||
* @brief This part of the library is used to follow ISO14443B.
|
||||
*/
|
||||
|
||||
|
||||
/** @addtogroup lib_iso14443Bpcd_Private_Functions
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* @brief this functions intializes the ISO14443B data structure
|
||||
*/
|
||||
static void ISO14443B_InitStructure(void)
|
||||
{
|
||||
/* Initializes the data structure used to store results */
|
||||
memset(ISO14443B_Card.ATQB , 0x00, ISO14443B_ATQB_SIZE);
|
||||
memset(ISO14443B_Card.PUPI , 0x00, ISO14443B_MAX_PUPI_SIZE);
|
||||
ISO14443B_Card.IsDetected = false;
|
||||
memset(ISO14443B_Card.LogMsg, 0x00, ISO14443B_MAX_LOG_MSG);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @brief this function complete the ISO14443B structure according to the REQB response
|
||||
* @param *pDataRead : Pointer to the PCD response
|
||||
*/
|
||||
static void ISO14443B_CompleteStruture ( uint8_t *pDataRead )
|
||||
{
|
||||
|
||||
memcpy(ISO14443B_Card.ATQB, &pDataRead[PCD_DATA_OFFSET], ISO14443B_ATQB_SIZE);
|
||||
/* retrieves the PUPI field */
|
||||
memcpy (ISO14443B_Card.PUPI, &(pDataRead[PCD_DATA_OFFSET + 1]),ISO14443B_MAX_PUPI_SIZE);
|
||||
/* retrieves the Application data field */
|
||||
memcpy (ISO14443B_Card.ApplicationField,&(pDataRead[PCD_DATA_OFFSET + 1 + 0x04]),0x04);
|
||||
/* retrieves the Application data field */
|
||||
memcpy (ISO14443B_Card.ProtocolInfo, &(pDataRead[PCD_DATA_OFFSET + 1 + 0x04 + 0x04]),0x04);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @brief this function writes the configuration registers according to AFE_SET_ANALOG_CONFIG command
|
||||
* @retval ISO14443B_SUCCESSCODE : the function is successful.
|
||||
* @retval ISO14443B_ERRORCODE_DEFAULT : an error occured
|
||||
*/
|
||||
static int8_t ISO14443B_WriteARConfigB(void)
|
||||
{
|
||||
uint8_t SetAnalogConfigParameter [2] = { PCD_TYPEB_ARConfigA, PCD_TYPEB_ARConfigB };
|
||||
int8_t status;
|
||||
uint8_t *pDataRead = u95HFBuffer;
|
||||
|
||||
errchk(PCD_WriteRegister ( 0x04,AFE_ANALOG_CONF_REG_SELECTION,0x01,SetAnalogConfigParameter,pDataRead));
|
||||
|
||||
return ISO14443B_SUCCESSCODE;
|
||||
Error:
|
||||
return ISO14443B_ERRORCODE_DEFAULT;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief this function reads the configuration registers according to AFE_SET_ANALOG_CONFIG command
|
||||
* @param *pDataRead : Pointer to the PCD response
|
||||
* @retval ISO14443B_SUCCESSCODE : the function is successful.
|
||||
* @retval ISO14443B_ERRORCODE_DEFAULT : an error occured
|
||||
*/
|
||||
static int8_t ISO14443BReadARConfigB (uint8_t *pDataRead )
|
||||
{
|
||||
int8_t status;
|
||||
const uint8_t data = 0x01;
|
||||
|
||||
/* Select the register */
|
||||
errchk(PCD_WriteRegister (0x03,AFE_ANALOG_CONF_REG_SELECTION,0x00,&data,pDataRead));
|
||||
/* Read the ARConfigA and B register */
|
||||
errchk(PCD_ReadRegister ( 0x03,AFE_ANALOG_CONF_REG_SELECTION,0x02,0x01,pDataRead));
|
||||
|
||||
return ISO14443B_SUCCESSCODE;
|
||||
Error:
|
||||
return ISO14443B_ERRORCODE_DEFAULT;
|
||||
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief this function reads ARConfigB registers and check if it matches the requested values(in AFE_SET_ANALOG_CONFIG command)
|
||||
* @retval ISO14443B_SUCCESSCODE : the function is successful.
|
||||
* @retval ISO14443B_ERRORCODE_DEFAULT : an error occured
|
||||
*/
|
||||
static int8_t ISO14443B_WriteAndCheckARConfigB(void)
|
||||
{
|
||||
uint8_t *pDataRead = u95HFBuffer;
|
||||
int8_t status;
|
||||
|
||||
/* Set the Register index to ARConfigB index */
|
||||
errchk(ISO14443B_WriteARConfigB( ));
|
||||
/* Read the register value */
|
||||
/* Set the Register index to ARConfigB index */
|
||||
errchk(ISO14443BReadARConfigB( pDataRead ));
|
||||
/* Check ARConfig value */
|
||||
|
||||
if((pDataRead[PCD_DATA_OFFSET]== PCD_TYPEB_ARConfigA) && (pDataRead[PCD_DATA_OFFSET + 1 ] == PCD_TYPEB_ARConfigB ) )
|
||||
return ISO14443B_SUCCESSCODE;
|
||||
else
|
||||
return ISO14443B_ERRORCODE_DEFAULT;
|
||||
|
||||
Error:
|
||||
return ISO14443B_ERRORCODE_DEFAULT;
|
||||
}
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
|
||||
/** @addtogroup lib_iso14443Bpcd_Public_Functions
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* @brief Initializes the the PCD device for the IS014443B protocol
|
||||
* @retval ISO14443B_SUCCESSCODE : the PCD device is well configured.
|
||||
* @retval ISO14443B_ERRORCODE_DEFAULT : Communication issue.
|
||||
*/
|
||||
int8_t ISO14443B_Init( void )
|
||||
{
|
||||
uint8_t *pDataRead = u95HFBuffer;
|
||||
int8_t status;
|
||||
uint8_t * ProtocolSelectParameters;
|
||||
const uint8_t ProtocolSelectParametersQJC[] = {
|
||||
/* Parameters */
|
||||
PCD_ISO14443B_TRANSMISSION_SPEED_106K |
|
||||
PCD_ISO14443B_RECEPTION_SPEED_106K |
|
||||
PCD_ISO14443B_APPEND_CRC,
|
||||
/* Set FDT */
|
||||
0x02 ,
|
||||
0x00
|
||||
};
|
||||
const uint8_t ProtocolSelectParametersQJE[] = {
|
||||
/* Parameters */
|
||||
PCD_ISO14443B_TRANSMISSION_SPEED_106K |
|
||||
PCD_ISO14443B_RECEPTION_SPEED_106K |
|
||||
PCD_ISO14443B_APPEND_CRC,
|
||||
/* PP MM bytes */
|
||||
0x00,
|
||||
0x1A
|
||||
|
||||
};
|
||||
const uint8_t Length = 0x04;
|
||||
|
||||
if( IcVers < QJE)
|
||||
{
|
||||
ProtocolSelectParameters = (uint8_t*)(ProtocolSelectParametersQJC);
|
||||
}
|
||||
else
|
||||
{
|
||||
ProtocolSelectParameters = (uint8_t*)(ProtocolSelectParametersQJE);
|
||||
}
|
||||
|
||||
ISO14443B_InitStructure( );
|
||||
|
||||
/* sends a protocol Select command to the pcd to configure it */
|
||||
errchk(PCD_ProtocolSelect(Length,PCD_PROTOCOL_ISO14443B,ProtocolSelectParameters,pDataRead));
|
||||
TechnoSelected = PCDPROTOCOL_14443B;
|
||||
/* update the AR register */
|
||||
errchk(ISO14443B_WriteAndCheckARConfigB ());
|
||||
|
||||
/* GT min time to respect before sending REQ_B */
|
||||
delayMicroseconds(5100);
|
||||
|
||||
return ISO14443B_SUCCESSCODE;
|
||||
Error:
|
||||
return ISO14443B_ERRORCODE_DEFAULT;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief this function emits a REQB command to a PICC device
|
||||
* @param *pDataRead : Pointer to the response
|
||||
* @retval ISO14443B_SUCCESSCODE : the function is successful.
|
||||
* @retval ISO14443B_ERRORCODE_DEFAULT : an error occured
|
||||
*/
|
||||
int8_t ISO14443B_ReqB ( uint8_t *pDataRead )
|
||||
{
|
||||
int8_t status;
|
||||
const uint8_t ReqB[] = { /* APf */
|
||||
ISO14443B_ANTICOLLISION_PREFIX_BYTE ,
|
||||
/* AFI */
|
||||
ISO14443B_AFI_ALL_FAMILIES ,
|
||||
/* Parameters */
|
||||
ISO14443B_EXTENDED_ATQB_NOT_SUPPORTED |
|
||||
ISO14443B_REQB_ATTEMPT |
|
||||
ISO14443B_SLOT_MARKER_1
|
||||
};
|
||||
|
||||
/* sends the command to the PCD device*/
|
||||
errchk(PCD_SendRecv(0x03,ReqB,pDataRead));
|
||||
/* Filling of the data structure */
|
||||
ISO14443B_Card.IsDetected = true;
|
||||
/* complete the ISO 14443 type B strucure */
|
||||
ISO14443B_CompleteStruture (pDataRead);
|
||||
|
||||
return ISO14443B_SUCCESSCODE;
|
||||
Error:
|
||||
return ISO14443B_ERRORCODE_DEFAULT;
|
||||
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @brief this function complete the ISO14443B structure according to the AttriB response
|
||||
* @param *pDataRead : Pointer to the PCD response
|
||||
* @retval ISO14443B_SUCCESSCODE : the function is successful.
|
||||
* @retval ISO14443B_ERRORCODE_DEFAULT : an error occured
|
||||
*/
|
||||
int8_t ISO14443B_AttriB( uint8_t *pDataRead )
|
||||
{
|
||||
int8_t status;
|
||||
uint8_t AttriB[ISO14443B_ATQB_SIZE] = {
|
||||
/* Start byte */
|
||||
ATTRIB_FIRST_BYTE ,
|
||||
/* PUPI */
|
||||
0x00 ,
|
||||
/* PUPI */
|
||||
0x00 ,
|
||||
/* PUPI */
|
||||
0x00 ,
|
||||
/* PUPI */
|
||||
0x00 ,
|
||||
/* Parameter 1 */
|
||||
TR0_64_FS |
|
||||
TR1_64_FS |
|
||||
EOF_REQUIRED |
|
||||
SOF_REQUIRED ,
|
||||
/* Parameter 2 */
|
||||
MAX_FRAME_SIZE_256_BYTES |
|
||||
PCD_TO_PICC_106K |
|
||||
PICC_TO_PCD_106K ,
|
||||
/* Parameter 3 */
|
||||
TR2_32_FS |
|
||||
PICC_COMPLIANT_ISO14443_4 ,
|
||||
/* Parameter 4 */
|
||||
CID_0
|
||||
};
|
||||
|
||||
/* copies the PUPI field */
|
||||
memcpy(&AttriB[1], ISO14443B_Card.PUPI, ISO14443B_MAX_PUPI_SIZE);
|
||||
/* sends the command to the PCD device*/
|
||||
errchk(PCD_SendRecv(0x09,AttriB,pDataRead));
|
||||
/* checks the CRC */
|
||||
errchk(PCD_IsCRCOk (PCD_PROTOCOL_ISO14443B,pDataRead) );
|
||||
|
||||
return ISO14443B_SUCCESSCODE;
|
||||
Error:
|
||||
return ISO14443B_ERRORCODE_DEFAULT;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @brief this function checks if a card is in the field
|
||||
* @retval ISO14443B_SUCCESSCODE : the function is successful.
|
||||
* @retval ISO14443B_ERRORCODE_DEFAULT : an error occured
|
||||
*/
|
||||
int8_t ISO14443B_IsPresent( void )
|
||||
{
|
||||
int8_t status;
|
||||
uint8_t *pDataRead = u95HFBuffer;
|
||||
|
||||
/* Init the ISO14443 TypeB communication */
|
||||
errchk(ISO14443B_Init( ));
|
||||
|
||||
/* WakeUp attempt */
|
||||
errchk(ISO14443B_ReqB(pDataRead));
|
||||
|
||||
return ISO14443B_SUCCESSCODE;
|
||||
Error:
|
||||
return ISO14443B_ERRORCODE_DEFAULT;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Anticolision state machine for ISO14443B cards
|
||||
* @param void
|
||||
* @retval ISO14443B_SUCCESSCODE : the function is successful.
|
||||
* @retval ISO14443B_ERRORCODE_DEFAULT : an error occured
|
||||
*/
|
||||
int8_t ISO14443B_Anticollision(void)
|
||||
{
|
||||
int8_t status;
|
||||
uint8_t *pDataRead = u95HFBuffer;
|
||||
const uint8_t ProtocolSelectParameters[] = {PCD_ISO14443B_TRANSMISSION_SPEED_106K|PCD_ISO14443B_RECEPTION_SPEED_106K|PCD_ISO14443B_APPEND_CRC,0x04,0x3E};
|
||||
|
||||
/* ATTRIB attempt */
|
||||
errchk(ISO14443B_AttriB(pDataRead));
|
||||
|
||||
/* Change the PP:MM parameter to accept longer APDU timeout (2^PP)*(MM+1)*(DD+128)*32/13.56 ~= 304ms*/
|
||||
errchk(PCD_ProtocolSelect(0x04,PCD_PROTOCOL_ISO14443B,ProtocolSelectParameters,pDataRead));
|
||||
|
||||
devicemode = PCD;
|
||||
nfc_tagtype = TT4B;
|
||||
|
||||
return ISO14443B_SUCCESSCODE;
|
||||
Error:
|
||||
return ISO14443B_ERRORCODE_DEFAULT;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief this function checks if a card is still in the field
|
||||
* @retval ISO14443B_SUCCESSCODE : the function is successful.
|
||||
* @retval ISO14443B_ERRORCODE_DEFAULT : an error occured
|
||||
*/
|
||||
int8_t ISO14443B_IsCardIntheField(void)
|
||||
{
|
||||
uint8_t *pDataRead = u95HFBuffer;
|
||||
const uint8_t Parameter = 0xB2;
|
||||
int8_t status;
|
||||
|
||||
/* sends the command to the PCD device*/
|
||||
errchk(PCD_SendRecv(0x01,&Parameter,pDataRead));
|
||||
|
||||
return ISO14443B_SUCCESSCODE;
|
||||
Error:
|
||||
return ISO14443B_ERRORCODE_DEFAULT;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
//#ifdef __cplusplus
|
||||
//}
|
||||
//#endif
|
||||
|
||||
/******************* (C) COPYRIGHT 2015 STMicroelectronics *****END OF FILE****/
|
||||
195
src/lib_iso14443Bpcd.h
Normal file
195
src/lib_iso14443Bpcd.h
Normal file
@@ -0,0 +1,195 @@
|
||||
/**
|
||||
******************************************************************************
|
||||
* @file lib_iso14443Bpcd.h
|
||||
* @author MMY Application Team
|
||||
* @version $Revision: 1333 $
|
||||
* @date $Date: 2015-11-05 10:49:42 +0100 (Thu, 05 Nov 2015) $
|
||||
* @brief Manage the iso14443B communication
|
||||
******************************************************************************
|
||||
* @attention
|
||||
*
|
||||
* <h2><center>© COPYRIGHT 2015 STMicroelectronics</center></h2>
|
||||
*
|
||||
* Licensed under ST MYLIBERTY SOFTWARE LICENSE AGREEMENT (the "License");
|
||||
* You may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at:
|
||||
*
|
||||
* http://www.st.com/myliberty
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied,
|
||||
* AND SPECIFICALLY DISCLAIMING THE IMPLIED WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE, AND NON-INFRINGEMENT.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
******************************************************************************
|
||||
*/
|
||||
|
||||
/* Define to prevent recursive inclusion -------------------------------------*/
|
||||
#ifndef __LIB_ISO14443B_H
|
||||
#define __LIB_ISO14443B_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include "lib_pcd.h"
|
||||
|
||||
/* status and error code ---------------------------------------------------------------------- */
|
||||
#define ISO14443B_SUCCESSCODE RESULTOK
|
||||
#define ISO14443B_ERRORCODE_DEFAULT 0x71
|
||||
#define ISO14443B_ERRORCODE_CRC 0x72
|
||||
|
||||
|
||||
/* REQB/WUPB command
|
||||
* ---------------------------------------------------
|
||||
* 1st byte | 2nd byte | 3rd byte | 4th, 5th bytes
|
||||
* ---------------------------------------------------
|
||||
* APf | AFI | PARAM | CRC
|
||||
* ---------------------------------------------------
|
||||
*/
|
||||
#define ISO14443B_ANTICOLLISION_PREFIX_BYTE 0x05
|
||||
#define ISO14443B_REQB 0x05
|
||||
|
||||
#define ISO14443B_AFI_ALL_FAMILIES 0x00 /*Application Family Identifier(AFI)*/
|
||||
|
||||
/* REQB/WUPB PARAM (1 byte)
|
||||
* -------------------------------------------------------------------------------------
|
||||
* RFU(3 bits) | Extended ATQB supported(1 bit) | REQB/WUPB(1 bit) | SLOT MARKER(3 bits)
|
||||
* -------------------------------------------------------------------------------------
|
||||
*/
|
||||
#define ISO14443B_EXTENDED_ATQB_SUPPORTED 1<<4
|
||||
#define ISO14443B_EXTENDED_ATQB_NOT_SUPPORTED 0
|
||||
|
||||
#define ISO14443B_WUPB_ATTEMPT 1<<3
|
||||
#define ISO14443B_REQB_ATTEMPT 0
|
||||
|
||||
#define ISO14443B_SLOT_MARKER_1 0
|
||||
#define ISO14443B_SLOT_MARKER_2 0x01
|
||||
#define ISO14443B_SLOT_MARKER_4 0x02
|
||||
#define ISO14443B_SLOT_MARKER_8 3<<1
|
||||
#define ISO14443B_SLOT_MARKER_16 0x04
|
||||
|
||||
/* ATTRIB command
|
||||
* ---------------------------------------------------------------------------------------------------------------
|
||||
* 1st byte | 2th to 5th bytes | 6th byte | 7th byte | 8th byte | 9th byte | 10th ... 'n'th bytes | (2 bytes)
|
||||
* ---------------------------------------------------------------------------------------------------------------
|
||||
* '1D' | Identifier(PUPI) | PARAM 1 | PARAM 2 | PARAM 3 | PARAM 4 | Higher Layer INF(opt) | CRC
|
||||
* ---------------------------------------------------------------------------------------------------------------
|
||||
*/
|
||||
#define ATTRIB_FIRST_BYTE 0x1D
|
||||
|
||||
/* ATTRIB PARAM 1 (1 byte)
|
||||
* ---------------------------------------------------------------------------------
|
||||
* Minimum TR0(2 bits) | Minimum TR1(2 bits) | EOF(1 bit) | SOF(1 bit) | RFU(2 bits)
|
||||
* ---------------------------------------------------------------------------------
|
||||
*/
|
||||
#define TR0_64_FS 0
|
||||
#define TR0_32_FS 1<<6
|
||||
#define TR0_16_FS 1<<7
|
||||
|
||||
#define TR1_64_FS 0
|
||||
#define TR1_32_FS 1<<4
|
||||
#define TR1_16_FS 1<<5
|
||||
|
||||
#define SOF_REQUIRED 0
|
||||
#define SOF_NOT_REQUIRED 1<<2
|
||||
|
||||
#define EOF_REQUIRED 0
|
||||
#define EOF_NOT_REQUIRED 1<<3
|
||||
|
||||
/* ATTRIB PARAM 2 (1 byte)
|
||||
* -------------------------------------------------------------------------------
|
||||
* PICC TO PCD SPEED(2 bits) | PCD TO PICC SPEED(2 bits) | MAX_FRAME_SIZE(2 bits)
|
||||
* -------------------------------------------------------------------------------
|
||||
*/
|
||||
#define MAX_FRAME_SIZE_16_BYTES 0
|
||||
#define MAX_FRAME_SIZE_24_BYTES 1
|
||||
#define MAX_FRAME_SIZE_32_BYTES 2
|
||||
#define MAX_FRAME_SIZE_40_BYTES 3
|
||||
#define MAX_FRAME_SIZE_48_BYTES 4
|
||||
#define MAX_FRAME_SIZE_64_BYTES 5
|
||||
#define MAX_FRAME_SIZE_96_BYTES 6
|
||||
#define MAX_FRAME_SIZE_128_BYTES 7
|
||||
#define MAX_FRAME_SIZE_256_BYTES 8
|
||||
|
||||
#define PCD_TO_PICC_106K 0
|
||||
#define PCD_TO_PICC_212K 1<<4
|
||||
#define PCD_TO_PICC_424K 1<<5
|
||||
#define PCD_TO_PICC_848K 3<<4
|
||||
|
||||
#define PICC_TO_PCD_106K 0
|
||||
#define PICC_TO_PCD_212K 1<<6
|
||||
#define PICC_TO_PCD_424K 1<<7
|
||||
#define PICC_TO_PCD_848K 3<<6
|
||||
|
||||
/* ATTRIB PARAM 3 (1 byte)
|
||||
* -------------------------------------------------------
|
||||
* RFU(5 bits) | TR2 CODING(2 bits) | PROTOCOL TYPE(1 bit)
|
||||
* -------------------------------------------------------
|
||||
* The least significant byte is used for confirmation of
|
||||
* the protocol type recovered in the ATQB
|
||||
*/
|
||||
#define TR2_32_FS 0
|
||||
#define TR2_128_FS 1<<1
|
||||
#define TR2_256_FS 1<<2
|
||||
#define TR2_512_FS 3<<1
|
||||
|
||||
#define PICC_COMPLIANT_ISO14443_4 1
|
||||
#define PICC_NOT_COMPLIANT_ISO14443_4 0
|
||||
|
||||
/* ATTRIB PARAM 4 (1 byte)
|
||||
* --------------------------
|
||||
* RFU(4 bits) | CID(4 bits)
|
||||
* --------------------------
|
||||
*/
|
||||
#define CID_0 0
|
||||
#define CID_1 1
|
||||
#define CID_2 2
|
||||
#define CID_3 3
|
||||
#define CID_4 4
|
||||
#define CID_5 5
|
||||
#define CID_6 6
|
||||
#define CID_7 7
|
||||
#define CID_8 8
|
||||
#define CID_9 9
|
||||
#define CID_10 10
|
||||
#define CID_11 11
|
||||
#define CID_12 12
|
||||
#define CID_13 13
|
||||
#define CID_14 14
|
||||
|
||||
/* Sizes of ISO14443B variables */
|
||||
#define ISO14443B_ATQB_SIZE 13
|
||||
#define ISO14443B_MAX_PUPI_SIZE 0x04
|
||||
#define ISO14443B_MAX_APPLI_SIZE 0x04
|
||||
#define ISO14443B_MAX_PROTOCOL_SIZE 0x04
|
||||
#define ISO14443B_MAX_LOG_MSG 60
|
||||
|
||||
|
||||
typedef struct{
|
||||
uint8_t ATQB[ISO14443B_ATQB_SIZE];
|
||||
uint8_t PUPI[ISO14443B_MAX_PUPI_SIZE],
|
||||
ApplicationField[ISO14443B_MAX_APPLI_SIZE],
|
||||
ProtocolInfo[ISO14443B_MAX_PROTOCOL_SIZE];
|
||||
bool IsDetected;
|
||||
char LogMsg[ISO14443B_MAX_LOG_MSG];
|
||||
}ISO14443B_CARD;
|
||||
|
||||
|
||||
int8_t ISO14443B_Init ( void );
|
||||
int8_t ISO14443B_ReqB ( uint8_t *pDataRead );
|
||||
int8_t ISO14443B_AttriB ( uint8_t *pDataRead );
|
||||
int8_t ISO14443B_IsPresent ( void );
|
||||
int8_t ISO14443B_IsCardIntheField ( void );
|
||||
int8_t ISO14443B_Anticollision ( void );
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* __ISO14443B_H */
|
||||
|
||||
/******************* (C) COPYRIGHT 2015 STMicroelectronics *****END OF FILE****/
|
||||
1674
src/lib_iso15693pcd.cpp
Normal file
1674
src/lib_iso15693pcd.cpp
Normal file
File diff suppressed because it is too large
Load Diff
318
src/lib_iso15693pcd.h
Normal file
318
src/lib_iso15693pcd.h
Normal file
@@ -0,0 +1,318 @@
|
||||
/**
|
||||
******************************************************************************
|
||||
* @file lib_iso15693pcd.h
|
||||
* @author MMY Application Team
|
||||
* @version $Revision: 1333 $
|
||||
* @date $Date: 2015-11-05 10:49:42 +0100 (Thu, 05 Nov 2015) $
|
||||
* @brief This file provides set of function defined into ISO15693 specification
|
||||
******************************************************************************
|
||||
* @attention
|
||||
*
|
||||
* <h2><center>© COPYRIGHT 2015 STMicroelectronics</center></h2>
|
||||
*
|
||||
* Licensed under ST MYLIBERTY SOFTWARE LICENSE AGREEMENT (the "License");
|
||||
* You may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at:
|
||||
*
|
||||
* http://www.st.com/myliberty
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied,
|
||||
* AND SPECIFICALLY DISCLAIMING THE IMPLIED WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE, AND NON-INFRINGEMENT.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
******************************************************************************
|
||||
*/
|
||||
|
||||
/* Define to prevent recursive inclusion -------------------------------------*/
|
||||
#ifndef __LIB_ISO15693_H
|
||||
#define __LIB_ISO15693_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include "lib_pcd.h"
|
||||
|
||||
#define RFU 0
|
||||
#define ISO15693_PROTOCOL 0x01
|
||||
#define ISO15693_SELECTLENGTH 0x02
|
||||
|
||||
|
||||
/* data rates constants fot select commands -------------------------------------------------- */
|
||||
#define ISO15693_TRANSMISSION_26 0
|
||||
#define ISO15693_TRANSMISSION_53 1
|
||||
#define ISO15693_TRANSMISSION_6 2
|
||||
#define ISO15693_TRANSMISSION_RFU 3
|
||||
// constants fot select commands ------------------------------------------------------------- */
|
||||
#define ISO15693_RESPECT_312 0
|
||||
#define ISO15693_WAIT_FOR_SOF 1
|
||||
/* modulation constants fot select commands -------------------------------------------------- */
|
||||
#define ISO15693_MODULATION_100 0
|
||||
#define ISO15693_MODULATION_10 1
|
||||
/* sub carrier constants fot select commands -------------------------------------------------- */
|
||||
#define ISO15693_SINGLE_SUBCARRIER 0
|
||||
#define ISO15693_DUAL_SUBCARRIER 1
|
||||
/* appendCrc constants fot select commands ---------------------------------------------------- */
|
||||
#define ISO15693_APPENDCRC 1
|
||||
#define ISO15693_DONTAPPENDCRC 0
|
||||
|
||||
#define ISO15693_M24LR64R 0x2C
|
||||
#define ISO15693_M24LR64ER 0x5E
|
||||
#define ISO15693_M24LR16ER 0x4E
|
||||
#define ISO15693_M24LR04ER 0x5A
|
||||
#define ISO15693_LRiS64K 0x44
|
||||
#define ISO15693_LRiS2K 0x28
|
||||
#define ISO15693_LRi2K 0x20
|
||||
#define ISO15693_LRi1K 0x40
|
||||
|
||||
#define ISO15693_LOW_DENSITY 0x00
|
||||
#define ISO15693_HIGH_DENSITY 0x01
|
||||
|
||||
#define ISO15693_NBBYTE_BLOCKLENGTH 4
|
||||
|
||||
/* mask of request flag ----------------------------------------------------------------------- */
|
||||
#define ISO15693_MASK_SUBCARRIERFLAG 0x01
|
||||
#define ISO15693_MASK_DATARATEFLAG 0x02
|
||||
#define ISO15693_MASK_INVENTORYFLAG 0x04
|
||||
#define ISO15693_MASK_PROTEXTFLAG 0x08
|
||||
#define ISO15693_MASK_SELECTORAFIFLAG 0x10
|
||||
#define ISO15693_MASK_ADDRORNBSLOTSFLAG 0x20
|
||||
#define ISO15693_MASK_OPTIONFLAG 0x40
|
||||
#define ISO15693_MASK_RFUFLAG 0x80
|
||||
/* mask of response flag ---------------------------------------------------------------------- */
|
||||
#define ISO15693_RESULTFLAG_STATUSOK 0x00
|
||||
#define ISO15693_MASK_ERRORFLAG 0x01
|
||||
|
||||
/* memmory size information ------------------------------------------------------------------- */
|
||||
#define ISO15693_MEMSIZEMASK_BLOCKSIZE 0x1F00
|
||||
#define ISO15693_MEMSIZEMASK_NBBLOCK 0x00FF
|
||||
#define ISO15693_MEMSIZEOFFSET_BLOCKSIZE 0x08
|
||||
|
||||
|
||||
/* mask for information flags ----------------------------------------------------------------- */
|
||||
#define ISO15693_MASK_DSFIDFLAG 0x01
|
||||
#define ISO15693_MASK_AFIFLAG 0x02
|
||||
#define ISO15693_MASK_MEMSIZEFLAG 0x04
|
||||
#define ISO15693_MASK_ICREFFLAG 0x08
|
||||
|
||||
#define ISO15693_MASK_GETSYSINFOREPLY_MEMSIZE 0x1F
|
||||
|
||||
/* command code ------------------------------------------------------------------------------ */
|
||||
#define ISO15693_CMDCODE_INVENTORY 0x01
|
||||
#define ISO15693_CMDCODE_STAYQUIET 0x02
|
||||
#define ISO15693_CMDCODE_READSINGLEBLOCK 0x20
|
||||
#define ISO15693_CMDCODE_WRITESINGLEBLOCK 0x21
|
||||
#define ISO15693_CMDCODE_LOCKBLOCK 0x22
|
||||
#define ISO15693_CMDCODE_READMULBLOCKS 0x23
|
||||
#define ISO15693_CMDCODE_WRITEMULBLOCKS 0x24
|
||||
#define ISO15693_CMDCODE_SELECT 0x25
|
||||
#define ISO15693_CMDCODE_RESETTOREADY 0x26
|
||||
#define ISO15693_CMDCODE_WRITEAFI 0x27
|
||||
#define ISO15693_CMDCODE_LOCKAFI 0x28
|
||||
#define ISO15693_CMDCODE_WRITEDSFID 0x29
|
||||
#define ISO15693_CMDCODE_LOCKDSFID 0x2A
|
||||
#define ISO15693_CMDCODE_GETSYSINFO 0x2B
|
||||
#define ISO15693_CMDCODE_GETSECURITYINFO 0x2C
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
// request flags ------------------------------------------------------------------------------ */
|
||||
#define ISO15693_REQFLAG_SINGLESUBCARRIER 0
|
||||
#define ISO15693_REQFLAG_TWOSUBCARRIER 1
|
||||
#define ISO15693_REQFLAG_LOWDATARATE 0
|
||||
#define ISO15693_REQFLAG_HIGHDATARATE 1
|
||||
#define ISO15693_REQFLAG_INVENTORYFLAGNOTSET 0
|
||||
#define ISO15693_REQFLAG_INVENTORYFLAGSET 1
|
||||
#define ISO15693_REQFLAG_NOPROTOCOLEXTENSION 0
|
||||
#define ISO15693_REQFLAG_PROTOCOLEXTENSION 1
|
||||
// request flag 5 to 8 definition when inventory flag is not set ----------------------------- */
|
||||
#define ISO15693_REQFLAG_NOTSELECTED 0
|
||||
#define ISO15693_REQFLAG_SELECTED 1
|
||||
#define ISO15693_REQFLAG_NOTADDRESSED 0
|
||||
#define ISO15693_REQFLAG_ADDRESSED 1
|
||||
#define ISO15693_REQFLAG_OPTIONFLAGNOTSET 0
|
||||
#define ISO15693_REQFLAG_OPTIONFLAGSET 1
|
||||
#define ISO15693_REQFLAG_RFUNOTSET 0
|
||||
#define ISO15693_REQFLAG_RFUSET 1
|
||||
// request flag 5 to 8 definition when inventory flag is set -------------------------------- */
|
||||
#define ISO15693_REQFLAG_NOTAFI 0
|
||||
#define ISO15693_REQFLAG_AFI 1
|
||||
#define ISO15693_REQFLAG_16SLOTS 0
|
||||
#define ISO15693_REQFLAG_1SLOT 1
|
||||
|
||||
|
||||
|
||||
// mask for parameter byte (select command) --------------------------------------------------- */
|
||||
#define ISO15693_MASK_APPENDCRC 0x01
|
||||
#define ISO15693_MASK_SUBCARRIER 0x02
|
||||
#define ISO15693_MASK_MODULATION 0x04
|
||||
#define ISO15693_MASK_WAITORSOF 0x08
|
||||
#define ISO15693_MASK_DATARATE 0x30
|
||||
#define ISO15693_MASK_RFU 0xC0
|
||||
// bits offset for parameter byte (select command) -------------------------------------------- */
|
||||
#define ISO15693_OFFSET_APPENDCRC 0x00
|
||||
#define ISO15693_OFFSET_SUBCARRIER 0x01
|
||||
#define ISO15693_OFFSET_MODULATION 0x02
|
||||
#define ISO15693_OFFSET_WAITORSOF 0x03
|
||||
#define ISO15693_OFFSET_DATARATE 0x04
|
||||
#define ISO15693_OFFSET_RFU 0x06
|
||||
|
||||
// byte offset for tag responses -------------------------------------------------------------- */
|
||||
#define ISO15693_OFFSET_FLAGS 0x00
|
||||
#define ISO15693_OFFSET_ERRORCODE 0x01
|
||||
|
||||
#define ISO15693_OFFSET_GETSYSINFOREPLY_NBBLOCK 0x00
|
||||
#define ISO15693_OFFSET_GETSYSINFOREPLY_MEMSIZE 0x01
|
||||
|
||||
#define ISO15693_OFFSET_UID PCD_DATA_OFFSET+0x02
|
||||
|
||||
|
||||
|
||||
#define ISO15693_INVENTORYOFFSET_DSFID 0x01
|
||||
#define ISO15693_INVENTORYOFFSET_UID 0x02
|
||||
#define ISO15693_INVENTORYOFFSET_CRC16 0x05
|
||||
|
||||
#define ISO15693_GETSYSINFOOFFSET_INFOFLAGS 0x01
|
||||
#define ISO15693_GETSYSINFOOFFSET_UID 0x02
|
||||
#define ISO15693_GETSYSINFOOFFSET_DSFID 0x0A
|
||||
|
||||
#define ISO15693_READSINGLEOFFSET_SECURITY 0x01
|
||||
#define ISO15693_GETMULSECURITIOFFSET_SECURITY 0x01
|
||||
|
||||
|
||||
/* number of byte of parameters ------------------------------------------------------------- */
|
||||
#define ISO15693_NBBYTE_UID 0x08
|
||||
#define ISO15693_NBBYTE_CRC16 0x02
|
||||
#define ISO15693_NBBYTE_DSFID 0x01
|
||||
#define ISO15693_NBBYTE_AFI 0x01
|
||||
#define ISO15693_NBBYTE_BLOCKSECURITY 0x01
|
||||
#define ISO15693_NBBYTE_REPLYFLAG 0x01
|
||||
#define ISO15693_NBBYTE_INFOFLAG 0x01
|
||||
#define ISO15693_NBBYTE_MEMORYSIZE 0x02
|
||||
#define ISO15693_NBBYTE_ICREF 0x01
|
||||
#define ISO15693_NBBYTE_REQUESTFLAG 0x01
|
||||
|
||||
#define ISO15693_NBBIT_INVENTORYSCANCHAIN 2+8+8+64
|
||||
#define ISO15693_NBBYTE_INVENTORYSCANCHAIN 11 // =(2+8+8+64) /8 +1
|
||||
#define ISO15693_NBBITS_MASKPARAMETER 64
|
||||
|
||||
/* success and error code --------------------------------------------------------------------- */
|
||||
#define ISO15693_SUCCESSCODE RESULTOK
|
||||
#define ISO15693_ERRORCODE_DEFAULT 0xF1
|
||||
#define ISO15693_ERRORCODE_REQUESTFLAG 0xF2
|
||||
#define ISO15693_ERRORCODE_PARAMETERLENGTH 0xF3
|
||||
#define ISO15693_ERRORCODE_CRCRESIDUE 0xF4
|
||||
#define ISO15693_ERRORCODE_NOTAGFOUND 0xF5
|
||||
|
||||
|
||||
|
||||
/* command length ----------------------------------------------------------------------------- */
|
||||
#define ISO15693_MAXLENGTH_INVENTORY 13 // 8 + 8 + 8 + 64 + 16 = 104bits => 13 bytes
|
||||
#define ISO15693_MAXLENGTH_STAYQUIET 12 // 8 + 8 + 64 + 16 = 96 => 12 bytes
|
||||
#define ISO15693_MAXLENGTH_READSINGLEBLOCK 13 // 8 + 8 + 8 + 64 + 16 = 104bits => 13 bytes
|
||||
#define ISO15693_MAXLENGTH_LOCKSINGLEBLOCK 13 // 8 + 8 + 8 + 64 + 16 = 104bits => 13 bytes
|
||||
#define ISO15693_MAXLENGTH_READMULBLOCK 14 // 8 + 8 + 8 + 64 + 8 + 16 = 112 bits => 14 bytes
|
||||
#define ISO15693_MAXLENGTH_SELECT 12 // 8 + 8 + 64 + 16 = 96 bits => 12 bytes
|
||||
#define ISO15693_MAXLENGTH_RESETTOREADY 12 // 8 + 8 + 64 + 16 = 96 bits => 12 bytes
|
||||
#define ISO15693_MAXLENGTH_WRTITEAFI 13 // 8 + 8 + 8 + 64 + 16 = 104bits => 13 bytes
|
||||
#define ISO15693_MAXLENGTH_WRTITEDSFID 13 // 8 + 8 + 8 + 64 + 16 = 104bits => 13 bytes
|
||||
#define ISO15693_MAXLENGTH_LOCKAFI 12 // 8 + 8 + 64 + 16 = 96 bits => 12 bytes
|
||||
#define ISO15693_MAXLENGTH_LOCKDSFID 12 // 8 + 8 + 64 + 16 = 96 bits => 12 bytes
|
||||
#define ISO15693_MAXLENGTH_GETMULSECURITY 14 // 8 + 8 + 8 + 64 + 8 + 16 = 112 bits => 14 bytes
|
||||
#define ISO15693_MAXLENGTH_GETSYSTEMINFO 12 // 8 + 8 + 64 + 16 = 96 => 12 bytes
|
||||
// reply length
|
||||
#define ISO15693_MAXLENGTH_REPLYINVENTORY 12 // 8 + 8 + 64 + 16 = 96 => 12 bytes
|
||||
#define ISO15693_MAXLENGTH_REPLYSTAYQUIET 4 // No reply
|
||||
#define ISO15693_MAXLENGTH_REPLYREADSINGLEBLOCK MAX_BUFFER_SIZE // 8 + 8 + 8 + 64 + 16 = 104bits => 13 bytes
|
||||
#define ISO15693_MAXLENGTH_REPLYWRITESINGLEBLOCK 4 // 8 + 8 + 16 = 32 bits => 4 bytes
|
||||
#define ISO15693_MAXLENGTH_REPLYLOCKSINGLEBLOCK 4 // 8 + 8 + 16 = 32 bits => 4 bytes
|
||||
#define ISO15693_MAXLENGTH_REPLYREADMULBLOCK MAX_BUFFER_SIZE
|
||||
#define ISO15693_MAXLENGTH_REPLYSELECT 4 // 8 + 8 + 16 = 32 bits => 4 bytes
|
||||
#define ISO15693_MAXLENGTH_REPLYRESETTOREADY 4 // 8 + 8 + 16 = 32 bits => 4 bytes
|
||||
#define ISO15693_MAXLENGTH_REPLYWRTITEAFI 4 // 8 + 8 + 16 = 32 bits => 4 bytes
|
||||
#define ISO15693_MAXLENGTH_REPLYWRTITEDSFID 4 // 8 + 8 + 16 = 32 bits => 4 bytes
|
||||
#define ISO15693_MAXLENGTH_REPLYLOCKAFI 4 // 8 + 8 + 16 = 32 bits => 4 bytes
|
||||
#define ISO15693_MAXLENGTH_REPLYLOCKDSFID 4 // 8 + 8 + 16 = 32 bits => 4 bytes
|
||||
#define ISO15693_MAXLENGTH_REPLYGETMULSECURITY MAX_BUFFER_SIZE
|
||||
#define ISO15693_MAXLENGTH_REPLYGETSYSTEMINFO 15 // 8 + 8 + 64 + 8 + 8 + 8 + 16 = 112 bits => 15 bytes
|
||||
|
||||
|
||||
/* CRC parameters ----------------------------------------------------------------------------- */
|
||||
#define ISO15693_OFFSET_LENGTH PCD_LENGTH_OFFSET
|
||||
#define ISO15693_CRC_MASK 0x02
|
||||
#define ISO15693_CRC_ERROR_CODE 0x02
|
||||
#define ISO15693_COLISION_MASK 0x01
|
||||
#define ISO15693_COLISION_ERROR_CODE 0x01
|
||||
|
||||
#define ISO15693_CRC_MASK_TYPE_A 0x20
|
||||
#define ISO15693_CRC_ERROR_CODE_TYPE_A 0x20
|
||||
|
||||
|
||||
#define ISO15693_MAXLENGTH_BLOCKSIZE 0x32
|
||||
|
||||
typedef struct {
|
||||
int8_t DataRate , // 0 => 26k 1 => 52 k 2 => 6k 3=>RFU
|
||||
WaitOrSOF , // 0 => respect 312 <20>s 1=> wait for SOF
|
||||
ModulationDepth , // 0 => 100% modulation 1=> 10% modulation
|
||||
SubCarrier , // 0 => single 1=> Dual
|
||||
AppendCRC ; // 1=> append 0=> don't append
|
||||
}ISO15693ConfigStruct;
|
||||
|
||||
// CRC 16 constants
|
||||
#define ISO15693_PRELOADCRC16 0xFFFF
|
||||
#define ISO15693_POLYCRC16 0x8408
|
||||
#define ISO15693_MASKCRC16 0x0001
|
||||
#define ISO15693_RESIDUECRC16 0xF0B8
|
||||
|
||||
|
||||
|
||||
/* ---------------------------------------------------------------------------------
|
||||
* --- Local Functions
|
||||
* --------------------------------------------------------------------------------- */
|
||||
|
||||
/* ISO15693 functions --- */
|
||||
|
||||
/* configure the PCD --- */
|
||||
int8_t ISO15693_Init(void);
|
||||
|
||||
/* ISO15693 commands --- */
|
||||
int8_t ISO15693_RunInventory16slots(const uint8_t Flags , const uint8_t AFI,uint8_t *NbTag,uint8_t *pUIDout);
|
||||
int8_t ISO15693_RunAntiCollision(const uint8_t Flags , const uint8_t AFI,uint8_t *NbTag,uint8_t *pUIDout);
|
||||
|
||||
// Get functions
|
||||
int8_t ISO15693_GetUID(uint8_t *UIDout);
|
||||
int8_t ISO15693_GetTagIdentification(uint16_t *Length_Memory_TAG, uint8_t *Tag_Density, uint8_t *IC_Ref_TAG);
|
||||
int8_t ISO15693_GetSystemInfo(const uint8_t Flags, const uint8_t *UIDin ,uint8_t *pResponse);
|
||||
|
||||
// Tag functions
|
||||
uint8_t ISO15693_ReadBytesTagData(uint8_t Tag_Density, uint8_t IC_Ref_Tag, uint8_t *Data_To_Read, uint16_t NbBytes_To_Read, uint16_t FirstBytes_To_Read);
|
||||
uint8_t ISO15693_WriteBytes_TagData(uint8_t Tag_Density, uint8_t *Data_To_Write, uint16_t NbBytes_To_Write, uint16_t FirstBytes_To_Write);
|
||||
|
||||
#ifdef ISO15693_ALLCOMMANDS
|
||||
|
||||
int8_t ISO15693_LockSingleBlock(const uint8_t Flags, const uint8_t *UIDin, const uint8_t BlockNumber,uint8_t *pResponse);
|
||||
|
||||
int8_t ISO15693_Select(const uint8_t Flags, const uint8_t *UIDin, const uint8_t AppendCRC,const uint8_t *CRC16,uint8_t *pResponse);
|
||||
int8_t ISO15693_WriteAFI(const uint8_t Flags, const uint8_t *UIDin,const uint8_t AFIToWrite,uint8_t *pResponse);
|
||||
int8_t ISO15693_LockAFI(const uint8_t Flags, const uint8_t *UIDin, uint8_t *pResponse);
|
||||
int8_t ISO15693_WriteDSFID(const uint8_t Flags, const uint8_t *UIDin,const uint8_t DSFIDToWrite,uint8_t *pResponse);
|
||||
int8_t ISO15693_LockDSFID(const uint8_t Flags, const uint8_t *UIDin, uint8_t *pResponse);
|
||||
int8_t ISO15693_GetMultipleBlockSecutityStatus(const uint8_t Flags, const uint8_t *UIDin, const uint8_t BlockNumber, const uint8_t NbBlocks,uint8_t *pResponse);
|
||||
#endif /* ISO15693_ALLCOMMANDS*/
|
||||
|
||||
|
||||
int8_t ISO15693_SplitInventoryResponse(const uint8_t *ReaderResponse,const uint8_t Length,uint8_t *Flags , uint8_t *DSFIDextract, uint8_t *UIDoutIndex);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* __ISO15693_H */
|
||||
|
||||
/******************* (C) COPYRIGHT 2015 STMicroelectronics *****END OF FILE****/
|
||||
221
src/lib_iso18092pcd.cpp
Normal file
221
src/lib_iso18092pcd.cpp
Normal file
@@ -0,0 +1,221 @@
|
||||
/**
|
||||
******************************************************************************
|
||||
* @file lib_iso18092pcd.c
|
||||
* @author MMY Application Team
|
||||
* @version $Revision: 1334 $
|
||||
* @date $Date: 2015-11-05 10:53:37 +0100 (Thu, 05 Nov 2015) $
|
||||
* @brief Manage the iso18092 communication
|
||||
******************************************************************************
|
||||
* @attention
|
||||
*
|
||||
* <h2><center>© COPYRIGHT 2015 STMicroelectronics</center></h2>
|
||||
*
|
||||
* Licensed under ST MYLIBERTY SOFTWARE LICENSE AGREEMENT (the "License");
|
||||
* You may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at:
|
||||
*
|
||||
* http://www.st.com/myliberty
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied,
|
||||
* AND SPECIFICALLY DISCLAIMING THE IMPLIED WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE, AND NON-INFRINGEMENT.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
******************************************************************************
|
||||
*/
|
||||
|
||||
/* Includes ------------------------------------------------------------------------------ */
|
||||
#include "Arduino.h"
|
||||
#include "lib_iso18092pcd.h"
|
||||
|
||||
/* Felica */
|
||||
#define PCD_TYPEF_ARConfigA 0x01
|
||||
#define PCD_TYPEF_ARConfigB 0x51
|
||||
|
||||
//#ifdef __cplusplus
|
||||
// extern "C" {
|
||||
//#endif
|
||||
|
||||
/* Variables for the different modes */
|
||||
extern DeviceMode_t devicemode;
|
||||
extern TagType_t nfc_tagtype;
|
||||
|
||||
extern PCD_PROTOCOL TechnoSelected;
|
||||
|
||||
FELICA_CARD FELICA_Card;
|
||||
|
||||
static const uint8_t REQC[] = {SEND_RECEIVE ,0x05,0x00,0x12,0xFC,0x01,0x03};
|
||||
|
||||
static int8_t FELICA_Init( uint8_t *pDataRead );
|
||||
static int8_t FELICA_REQC( uint8_t *pDataRead );
|
||||
|
||||
/** @addtogroup _95HF_Libraries
|
||||
* @{
|
||||
* @brief <b>This is the library used by the whole 95HF family (RX95HF, CR95HF, ST95HF) <br />
|
||||
* You will find ISO libraries ( 14443A, 14443B, 15693, ...) for PICC and PCD <br />
|
||||
* The libraries selected in the project will depend of the application targetted <br />
|
||||
* and the product chosen (RX95HF emulate PICC, CR95HF emulate PCD, ST95HF can do both)</b>
|
||||
*/
|
||||
|
||||
/** @addtogroup PCD
|
||||
* @{
|
||||
* @brief This part of the library enables PCD capabilities of CR95HF & ST95HF.
|
||||
*/
|
||||
|
||||
|
||||
/** @addtogroup ISO18092_pcd
|
||||
* @{
|
||||
* @brief This part of the library is used to follow ISO18092.
|
||||
*/
|
||||
|
||||
|
||||
/** @addtogroup lib_iso18092pcd_Private_Functions
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* @brief Initializes the xx95HF for the FELICA protocol
|
||||
* @param void
|
||||
* @return TRUE (if well configured) / FALSE (Communication issue)
|
||||
*/
|
||||
static int8_t FELICA_Init( uint8_t *pDataRead )
|
||||
{
|
||||
int8_t status;
|
||||
u8 ProtocolSelectParameters [4] = {0x51, 0x13, 0x01,0x0D};
|
||||
u8 WriteAmpliGain [2] = {PCD_TYPEF_ARConfigA, PCD_TYPEF_ARConfigB};
|
||||
u8 AutoFDet [2] = {0x02,0xA1};
|
||||
|
||||
|
||||
/* sends a protocol Select command to the pcd to configure it */
|
||||
errchk(PCD_ProtocolSelect(0x05,PCD_PROTOCOL_FELICA,ProtocolSelectParameters,pDataRead));
|
||||
TechnoSelected = PCDPROTOCOL_18092;
|
||||
|
||||
/* in order to adjust the demodulation gain of the PCD*/
|
||||
errchk(PCD_WriteRegister ( 0x04,AFE_ANALOG_CONF_REG_SELECTION,0x01,WriteAmpliGain,pDataRead));
|
||||
|
||||
/* in order to adjust the auto detect of the PCD*/
|
||||
errchk(PCD_WriteRegister ( 0x04,0x0A,0x01,AutoFDet,pDataRead));
|
||||
|
||||
/* GT min time to respect before sending REQ_C */
|
||||
delay(20);
|
||||
delayMicroseconds(400);
|
||||
|
||||
return ISO18092_SUCCESSCODE;
|
||||
Error:
|
||||
return ISO18092_ERRORCODE_DEFAULT;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Handles the REQC command
|
||||
* @param *pDataRead : Pointer on the response
|
||||
* @return TRUE (if CR95HF answered ATQB) / FALSE (No ISO14443B in Field)
|
||||
*/
|
||||
static int8_t FELICA_REQC( uint8_t *pDataRead )
|
||||
{
|
||||
if(PCD_CheckSendReceive(REQC, pDataRead)!= ISO18092_SUCCESSCODE)
|
||||
return ISO18092_ERRORCODE_DEFAULT;
|
||||
|
||||
if (pDataRead[2] != 0x01) // If the answer is not an answer to REQC
|
||||
return ISO18092_ERRORCODE_DEFAULT;
|
||||
else
|
||||
return ISO18092_SUCCESSCODE;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
|
||||
/** @addtogroup lib_iso18092pcd_Public_Functions
|
||||
* @{
|
||||
*/
|
||||
|
||||
void FELICA_Initialization( void )
|
||||
{
|
||||
uint8_t DataRead[MAX_BUFFER_SIZE];
|
||||
|
||||
/* Init the FeliCa communication */
|
||||
FELICA_Init(DataRead);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Checks if a FELICA card is in the field
|
||||
* @param void
|
||||
* @return ISO18092_SUCCESSCODE (A card is present) / ISO18092_ERRORCODE_DEFAULT (No card)
|
||||
*/
|
||||
int8_t FELICA_IsPresent( void )
|
||||
{
|
||||
uint8_t DataRead[MAX_BUFFER_SIZE];
|
||||
|
||||
/* Initializing buffer */
|
||||
memset(DataRead,0,MAX_BUFFER_SIZE);
|
||||
|
||||
/* REQC attempt */
|
||||
if(FELICA_REQC(DataRead) != ISO18092_SUCCESSCODE )
|
||||
return ISO18092_ERRORCODE_DEFAULT;
|
||||
|
||||
/* Filling of the data structure */
|
||||
FELICA_Card.IsDetected = true;
|
||||
memcpy(FELICA_Card.ATQC, &DataRead[PCD_DATA_OFFSET], ATQC_SIZE);
|
||||
memcpy(FELICA_Card.UID , &FELICA_Card.ATQC[1] , UID_SIZE_FELICA);
|
||||
|
||||
devicemode = PCD;
|
||||
nfc_tagtype = TT3;
|
||||
|
||||
/* An ISO14443 card is in the field */
|
||||
return ISO18092_SUCCESSCODE;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Processing of the Anticolision for FELICA cards
|
||||
* @param *message : contains message on the CR95HF replies
|
||||
* @return ISO18092_SUCCESSCODE : the function is succesful
|
||||
*/
|
||||
int8_t FELICA_Anticollision( void )
|
||||
{
|
||||
/* Anticollision process done ! */
|
||||
return ISO18092_SUCCESSCODE;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Checks if a FELICA card is still in the field
|
||||
* @param void
|
||||
* @return ISO18092_SUCCESSCODE : the function is succesful
|
||||
* @return ISO18092_ERRORCODE_DEFAULT : No card in the RF field
|
||||
*/
|
||||
int8_t FELICA_CardTest( void )
|
||||
{
|
||||
uint8_t DummyBuffer[MAX_BUFFER_SIZE];
|
||||
|
||||
if(PCD_CheckSendReceive(REQC, DummyBuffer)!= ISO18092_SUCCESSCODE)
|
||||
return ISO18092_ERRORCODE_DEFAULT;
|
||||
|
||||
return ISO18092_SUCCESSCODE;
|
||||
}
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
//#ifdef __cplusplus
|
||||
//}
|
||||
//#endif
|
||||
|
||||
/******************* (C) COPYRIGHT 2015 STMicroelectronics *****END OF FILE****/
|
||||
77
src/lib_iso18092pcd.h
Normal file
77
src/lib_iso18092pcd.h
Normal file
@@ -0,0 +1,77 @@
|
||||
/**
|
||||
******************************************************************************
|
||||
* @file lib_iso18092pcd.h
|
||||
* @author MMY Application Team
|
||||
* @version $Revision: 1333 $
|
||||
* @date $Date: 2015-11-05 10:49:42 +0100 (Thu, 05 Nov 2015) $
|
||||
* @brief Manage the iso18092 communication
|
||||
******************************************************************************
|
||||
* @attention
|
||||
*
|
||||
* <h2><center>© COPYRIGHT 2015 STMicroelectronics</center></h2>
|
||||
*
|
||||
* Licensed under ST MYLIBERTY SOFTWARE LICENSE AGREEMENT (the "License");
|
||||
* You may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at:
|
||||
*
|
||||
* http://www.st.com/myliberty
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied,
|
||||
* AND SPECIFICALLY DISCLAIMING THE IMPLIED WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE, AND NON-INFRINGEMENT.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
******************************************************************************
|
||||
*/
|
||||
|
||||
|
||||
/* Define to prevent recursive inclusion -------------------------------------*/
|
||||
#ifndef __FELICA_H
|
||||
#define __FELICA_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include "lib_pcd.h"
|
||||
#include "stdbool.h"
|
||||
|
||||
/* -------------------------------------------------------------------------- */
|
||||
#define ATQC_SIZE 0x20
|
||||
#define UID_SIZE_FELICA 8
|
||||
|
||||
/* command code -------------------------------------------------------------- */
|
||||
#define ISO18092_COMMAND_REQC 0x00
|
||||
#define ISO18092_RESPONSE_REQC 0x01
|
||||
|
||||
/* code status -------------------------------------------------------------------------- */
|
||||
#define ISO18092_SUCCESSCODE RESULTOK
|
||||
#define ISO18092_ERRORCODE_DEFAULT 0xC1
|
||||
|
||||
typedef struct{
|
||||
uint8_t ATQC[ATQC_SIZE];
|
||||
uint8_t UID [UID_SIZE_FELICA];
|
||||
bool IsDetected;
|
||||
// char LogMsg[120];
|
||||
}FELICA_CARD;
|
||||
|
||||
//extern FELICA_CARD FELICA_Card;
|
||||
|
||||
/* ---------------------------------------------------------------------------------
|
||||
* --- Local Functions
|
||||
* --------------------------------------------------------------------------------- */
|
||||
void FELICA_Initialization( void );
|
||||
int8_t FELICA_IsPresent ( void );
|
||||
int8_t FELICA_CardTest ( void );
|
||||
int8_t FELICA_Anticollision( void );
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* __FELICA_H */
|
||||
|
||||
/******************* (C) COPYRIGHT 2015 STMicroelectronics *****END OF FILE****/
|
||||
275
src/lib_iso7816pcd.cpp
Normal file
275
src/lib_iso7816pcd.cpp
Normal file
@@ -0,0 +1,275 @@
|
||||
/**
|
||||
******************************************************************************
|
||||
* @file lib_iso7816pcd.c
|
||||
* @author MMY Application Team
|
||||
* @version $Revision: 1334 $
|
||||
* @date $Date: 2015-11-05 10:53:37 +0100 (Thu, 05 Nov 2015) $
|
||||
* @brief Manage the iso 7816 commands
|
||||
******************************************************************************
|
||||
* @attention
|
||||
*
|
||||
* <h2><center>© COPYRIGHT 2015 STMicroelectronics</center></h2>
|
||||
*
|
||||
* Licensed under ST MYLIBERTY SOFTWARE LICENSE AGREEMENT (the "License");
|
||||
* You may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at:
|
||||
*
|
||||
* http://www.st.com/myliberty
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied,
|
||||
* AND SPECIFICALLY DISCLAIMING THE IMPLIED WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE, AND NON-INFRINGEMENT.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
******************************************************************************
|
||||
*/
|
||||
|
||||
//#ifdef __cplusplus
|
||||
// extern "C" {
|
||||
//#endif
|
||||
|
||||
/* Includes ------------------------------------------------------------------------------ */
|
||||
#include "lib_iso7816pcd.h"
|
||||
|
||||
extern TagType_t nfc_tagtype;
|
||||
|
||||
uint8_t bufferSend[MAX_BUFFER_SIZE+3],
|
||||
bufferReceive[MAX_BUFFER_SIZE+3];
|
||||
|
||||
static APDU_Commands APDUcommand ;
|
||||
static APDU_Responce APDUresponse;
|
||||
static uint8_t BlockNumber = 0x02;
|
||||
|
||||
static int8_t ISO7816_SendReceiveAPDU ( uint8_t *pDataReceived );
|
||||
|
||||
/** @addtogroup _95HF_Libraries
|
||||
* @{
|
||||
* @brief <b>This is the library used by the whole 95HF family (RX95HF, CR95HF, ST95HF) <br />
|
||||
* You will find ISO libraries ( 14443A, 14443B, 15693, ...) for PICC and PCD <br />
|
||||
* The libraries selected in the project will depend of the application targetted <br />
|
||||
* and the product chosen (RX95HF emulate PICC, CR95HF emulate PCD, ST95HF can do both)</b>
|
||||
*/
|
||||
|
||||
/** @addtogroup PCD
|
||||
* @{
|
||||
* @brief This part of the library enables PCD capabilities of CR95HF & ST95HF.
|
||||
*/
|
||||
|
||||
|
||||
/** @addtogroup ISO7816_pcd
|
||||
* @{
|
||||
* @brief This part of the library is used to follow ISO7816.
|
||||
*/
|
||||
|
||||
|
||||
/** @addtogroup lib_iso7816pcd_Private_Functions
|
||||
* @{
|
||||
*/
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* @brief this function sends the APDU command to the RF transceiver and returns its response
|
||||
* @return ISO7816_SUCCESSCODE : the function is succesful
|
||||
* @return ISO7816_ERRORCODE_RESPONSE : the function is not succesful. The tag returns an error code
|
||||
* @return ISO7816_ERRORCODE_DEFAULT : the function is not succesful.
|
||||
*/
|
||||
static int8_t ISO7816_SendReceiveAPDU ( uint8_t *pDataReceived )
|
||||
{
|
||||
uint8_t NthByte=0;
|
||||
int8_t status;
|
||||
uint8_t bufferFWI[3];
|
||||
|
||||
bufferSend[NthByte++] = BlockNumber;
|
||||
BlockNumber ^= 0x01;
|
||||
|
||||
// add the class byte
|
||||
bufferSend[NthByte++] = APDUcommand.Header.CLA;
|
||||
// add the command code
|
||||
bufferSend[NthByte++] = APDUcommand.Header.INS;
|
||||
// add the P1 and P2 fields
|
||||
bufferSend[NthByte++] = APDUcommand.Header.P1;
|
||||
bufferSend[NthByte++] = APDUcommand.Header.P2;
|
||||
// add the LC field
|
||||
if (APDUcommand.Body.LC)
|
||||
bufferSend[NthByte++] = APDUcommand.Body.LC;
|
||||
// add the datafield field
|
||||
memcpy(&(bufferSend[NthByte]),APDUcommand.Body.pData,APDUcommand.Body.LC);
|
||||
NthByte += APDUcommand.Body.LC;
|
||||
|
||||
// add the LE field
|
||||
if (APDUcommand.Body.LE || (APDUcommand.Header.P1 == 0x04 && APDUcommand.Header.P2 == 0x00))
|
||||
bufferSend[NthByte++] = APDUcommand.Body.LE;
|
||||
|
||||
// control byte append CRC + 8 bits
|
||||
if( nfc_tagtype == TT4A )
|
||||
bufferSend[NthByte++] = SEND_MASK_APPENDCRC | SEND_MASK_8BITSINFIRSTBYTE;
|
||||
|
||||
// send the command to the RF transceiver
|
||||
errchk(PCD_SendRecv(NthByte,bufferSend,pDataReceived))
|
||||
|
||||
/* Test if a time extension is required */
|
||||
if (pDataReceived[2] == 0xF2)
|
||||
{
|
||||
/* Modify temporarly FDT */
|
||||
ISO14443A_ConfigFDT(pDataReceived[3]);
|
||||
|
||||
/* Send the same buffer in order to accept the time extension */
|
||||
memcpy(bufferFWI,&pDataReceived[2],2);
|
||||
|
||||
if( nfc_tagtype == TT4A )
|
||||
{
|
||||
bufferFWI[2] = SEND_MASK_APPENDCRC | SEND_MASK_8BITSINFIRSTBYTE;
|
||||
PCD_SendRecv(3,bufferFWI, pDataReceived);
|
||||
}
|
||||
else
|
||||
PCD_SendRecv(2,bufferFWI, pDataReceived);
|
||||
|
||||
/* Setback FDT default value */
|
||||
ISO14443A_ConfigFDT(1);
|
||||
}
|
||||
|
||||
if( nfc_tagtype == TT4A )
|
||||
{
|
||||
APDUresponse.SW1 = pDataReceived[pDataReceived[PCD_LENGTH_OFFSET]-5];
|
||||
APDUresponse.SW2 = pDataReceived[pDataReceived[PCD_LENGTH_OFFSET]-4];
|
||||
}
|
||||
else
|
||||
{
|
||||
APDUresponse.SW1 = pDataReceived[pDataReceived[PCD_LENGTH_OFFSET]-3];
|
||||
APDUresponse.SW2 = pDataReceived[pDataReceived[PCD_LENGTH_OFFSET]-2];
|
||||
}
|
||||
|
||||
if (APDUresponse.SW1 == 0x90 && APDUresponse.SW2 == 0x00)
|
||||
return ISO7816_SUCCESSCODE;
|
||||
else
|
||||
return ISO7816_ERRORCODE_RESPONSE;
|
||||
|
||||
Error :
|
||||
return ISO7816_ERRORCODE_DEFAULT;
|
||||
}
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/** @addtogroup lib_iso7816pcd_Public_Functions
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* @brief this function sends the Select command
|
||||
* @param P1byte : P1 value
|
||||
* @param P2byte : P2 value
|
||||
* @param LCbyte : LC value
|
||||
* @param PData : pointer of the File ID
|
||||
* @return ISO7816_SUCCESSCODE : the function is successful and the tag returns a success code
|
||||
* @return ISO7816_ERRORCODE_DEFAULT : the function is not successful
|
||||
*/
|
||||
int8_t ISO7816_SelectFile(const uint8_t P1byte , const uint8_t P2byte , const uint8_t LCbyte ,uint8_t *pDataSel)
|
||||
{
|
||||
// add the class byte
|
||||
APDUcommand.Header.CLA = ISO7816_CLASS_0X00;
|
||||
// add the command code
|
||||
APDUcommand.Header.INS = ISO7816_SELECT_FILE;
|
||||
// add the P1 and P2 fields
|
||||
APDUcommand.Header.P1 = P1byte;
|
||||
APDUcommand.Header.P2 = P2byte;
|
||||
// add the LC field
|
||||
APDUcommand.Body.LC = LCbyte;
|
||||
//add the FileId field
|
||||
memcpy(APDUcommand.Body.pData, pDataSel, APDUcommand.Body.LC);
|
||||
// the LE field is empty
|
||||
APDUcommand.Body.LE = 0x00;
|
||||
|
||||
// Special case for the selectApplication
|
||||
// The block number HAS TO be 0x02
|
||||
if (APDUcommand.Header.P1 == 0x04 && APDUcommand.Header.P2 == 0x00)
|
||||
BlockNumber = 0x02;
|
||||
|
||||
return ISO7816_SendReceiveAPDU ( bufferReceive );
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @brief this function sends a ReadBinary command
|
||||
* @param P1byte : P1 value
|
||||
* @param P2byte : P2 value
|
||||
* @param LEbyte : LE value
|
||||
* @param *pDataRead : Pointer to the data read from the tag
|
||||
* @return ISO7816_SUCCESSCODE : the function is successful and the tag returns a success code
|
||||
* @return ISO7816_ERRORCODE_DEFAULT : the function is not successful
|
||||
*/
|
||||
int8_t ISO7816_ReadBinary(const uint8_t P1byte , const uint8_t P2byte , const uint8_t LEbyte , uint8_t *pDataRead)
|
||||
{
|
||||
// add the class byte
|
||||
APDUcommand.Header.CLA = ISO7816_CLASS_0X00;
|
||||
// add the command code
|
||||
APDUcommand.Header.INS = ISO7816_READ_BINARY;
|
||||
// add the P1 and P2 fields
|
||||
APDUcommand.Header.P1 = P1byte;
|
||||
APDUcommand.Header.P2 = P2byte;
|
||||
// the LC field is empty
|
||||
APDUcommand.Body.LC = 0x00;
|
||||
|
||||
APDUcommand.Body.LE = LEbyte;
|
||||
|
||||
return ISO7816_SendReceiveAPDU ( pDataRead );
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief this function sends the UpdateBinary command.
|
||||
* @param P1byte : P1 value
|
||||
* @param P2byte : P2 value
|
||||
* @param LCbyte : LC value
|
||||
* @param *pData : Pointer to the data to write
|
||||
* @return ISO7816_SUCCESSCODE : the function is successful and the tag returns a success code
|
||||
* @return ISO7816_ERRORCODE_DEFAULT : the function is not successful
|
||||
*/
|
||||
int8_t ISO7816_UpdateBinary(const uint8_t P1byte , const uint8_t P2byte , const uint8_t LCbyte , uint8_t *pData)
|
||||
{
|
||||
|
||||
// add the class byte
|
||||
APDUcommand.Header.CLA = ISO7816_CLASS_0X00;
|
||||
// add the command code
|
||||
APDUcommand.Header.INS = ISO7816_UPDATE_BINARY;
|
||||
// add the P1 and P2 fields
|
||||
APDUcommand.Header.P1 = P1byte;
|
||||
APDUcommand.Header.P2 = P2byte;
|
||||
// add the datafield field
|
||||
APDUcommand.Body.LC = LCbyte;
|
||||
// add data to write
|
||||
memcpy(APDUcommand.Body.pData,pData,APDUcommand.Body.LC);
|
||||
// the LE field is empty
|
||||
APDUcommand.Body.LE = 0x00;
|
||||
|
||||
return ISO7816_SendReceiveAPDU ( bufferReceive );
|
||||
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
//#ifdef __cplusplus
|
||||
//}
|
||||
//#endif
|
||||
|
||||
/******************* (C) COPYRIGHT 2015 STMicroelectronics *****END OF FILE****/
|
||||
110
src/lib_iso7816pcd.h
Normal file
110
src/lib_iso7816pcd.h
Normal file
@@ -0,0 +1,110 @@
|
||||
/**
|
||||
******************************************************************************
|
||||
* @file lib_iso7816pcd.h
|
||||
* @author MMY Application Team
|
||||
* @version $Revision: 1333 $
|
||||
* @date $Date: 2015-11-05 10:49:42 +0100 (Thu, 05 Nov 2015) $
|
||||
* @brief Manage the iso 7816 commands
|
||||
******************************************************************************
|
||||
* @attention
|
||||
*
|
||||
* <h2><center>© COPYRIGHT 2015 STMicroelectronics</center></h2>
|
||||
*
|
||||
* Licensed under ST MYLIBERTY SOFTWARE LICENSE AGREEMENT (the "License");
|
||||
* You may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at:
|
||||
*
|
||||
* http://www.st.com/myliberty
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied,
|
||||
* AND SPECIFICALLY DISCLAIMING THE IMPLIED WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE, AND NON-INFRINGEMENT.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
******************************************************************************
|
||||
*/
|
||||
|
||||
/* Define to prevent recursive inclusion --------------------------------------------------------*/
|
||||
#ifndef __LIB_ISO7816_H
|
||||
#define __LIB_ISO7816_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/* Includes -------------------------------------------------------------------------------------*/
|
||||
#include "lib_iso14443Apcd.h"
|
||||
#include "lib_pcd.h"
|
||||
|
||||
/* status and error code ---------------------------------------------------------------------- */
|
||||
#define ISO7816_SUCCESSCODE RESULTOK
|
||||
#define ISO7816_ERRORCODE_DEFAULT 0x71
|
||||
#define ISO7816_ERRORCODE_RESPONSE 0x72
|
||||
#define ISO7816_ERRORCODE_SENDERRORCODE 0x73
|
||||
|
||||
/* Iblock ------------------------------------------------------------------------------------- */
|
||||
#define ISO7816_IBLOCK02 0x02
|
||||
#define ISO7816_IBLOCK03 0x03
|
||||
|
||||
#define ISO7816_SELECT_FILE 0xA4
|
||||
#define ISO7816_UPDATE_BINARY 0xD6
|
||||
#define ISO7816_READ_BINARY 0xB0
|
||||
|
||||
#define ISO7816_CLASS_0X00 0x00
|
||||
#define ISO7816_CLASS_STM 0xA2
|
||||
|
||||
// offset of the different field of the APDU
|
||||
#define ISO7816_ADPUOFFSET_BLOCK 0x00
|
||||
#define ISO7816_ADPUOFFSET_CLASS ISO7816_ADPUOFFSET_BLOCK + 1
|
||||
#define ISO7816_ADPUOFFSET_INS ISO7816_ADPUOFFSET_BLOCK + 2
|
||||
#define ISO7816_ADPUOFFSET_P1 ISO7816_ADPUOFFSET_BLOCK + 3
|
||||
#define ISO7816_ADPUOFFSET_P2 ISO7816_ADPUOFFSET_BLOCK + 4
|
||||
#define ISO7816_ADPUOFFSET_LC ISO7816_ADPUOFFSET_BLOCK + 5
|
||||
#define ISO7816_ADPUOFFSET_DATA ISO7816_ADPUOFFSET_BLOCK + 6
|
||||
|
||||
/* ADPU-Header command structure ---------------------------------------------*/
|
||||
typedef struct
|
||||
{
|
||||
uint8_t CLA; /* Command class */
|
||||
uint8_t INS; /* Operation code */
|
||||
uint8_t P1; /* Selection Mode */
|
||||
uint8_t P2; /* Selection Option */
|
||||
} Header;
|
||||
|
||||
/* ADPU-Body command structure -----------------------------------------------*/
|
||||
typedef struct
|
||||
{
|
||||
uint8_t LC; /* Data field length */
|
||||
uint8_t pData[256]; /* Command parameters */ // pointer on the transceiver buffer = *(ReaderRecBuf[CR95HF_DATA_OFFSET + ISO7816_ADPUOFFSET_DATA])
|
||||
uint8_t LE; /* Expected length of data to be returned */
|
||||
} Body;
|
||||
|
||||
/* ADPU Command structure ----------------------------------------------------*/
|
||||
typedef struct
|
||||
{
|
||||
Header Header;
|
||||
Body Body;
|
||||
} APDU_Commands;
|
||||
|
||||
/* SC response structure -----------------------------------------------------*/
|
||||
typedef struct
|
||||
{
|
||||
uint8_t SW1; /* Command Processing status */
|
||||
uint8_t SW2; /* Command Processing qualification */
|
||||
} APDU_Responce;
|
||||
|
||||
|
||||
int8_t ISO7816_SelectFile(const uint8_t P1byte , const uint8_t P2byte , const uint8_t LCbyte , uint8_t *PData);
|
||||
int8_t ISO7816_ReadBinary(const uint8_t P1byte , const uint8_t P2byte , const uint8_t LEbyte , uint8_t *pDataRead);
|
||||
int8_t ISO7816_UpdateBinary(const uint8_t P1byte , const uint8_t P2byte , const uint8_t LCbyte , uint8_t *pData);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* __SMARTCARD_H */
|
||||
|
||||
/******************* (C) COPYRIGHT 2015 STMicroelectronics *****END OF FILE****/
|
||||
248
src/lib_nfctype1pcd.cpp
Normal file
248
src/lib_nfctype1pcd.cpp
Normal file
@@ -0,0 +1,248 @@
|
||||
/**
|
||||
******************************************************************************
|
||||
* @file lib_nfctype1pcd.c
|
||||
* @author MMY Application Team
|
||||
* @version $Revision: 1334 $
|
||||
* @date $Date: 2015-11-05 10:53:37 +0100 (Thu, 05 Nov 2015) $
|
||||
* @brief Generates the NFC type1 commands
|
||||
******************************************************************************
|
||||
* @attention
|
||||
*
|
||||
* <h2><center>© COPYRIGHT 2015 STMicroelectronics</center></h2>
|
||||
*
|
||||
* Licensed under ST MYLIBERTY SOFTWARE LICENSE AGREEMENT (the "License");
|
||||
* You may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at:
|
||||
*
|
||||
* http://www.st.com/myliberty
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied,
|
||||
* AND SPECIFICALLY DISCLAIMING THE IMPLIED WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE, AND NON-INFRINGEMENT.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
******************************************************************************
|
||||
*/
|
||||
|
||||
//#ifdef __cplusplus
|
||||
// extern "C" {
|
||||
//#endif
|
||||
|
||||
/* Includes ------------------------------------------------------------------------------ */
|
||||
#include "lib_nfctype1pcd.h"
|
||||
|
||||
extern uint8_t TT1Tag[];
|
||||
extern uint8_t TagUID[];
|
||||
|
||||
static uint8_t PCDNFCT1_ReadAll(uint8_t *pBufferRead);
|
||||
static uint8_t PCDNFCT1_WriteErase(uint8_t address, uint8_t byte);
|
||||
|
||||
/** @addtogroup _95HF_Libraries
|
||||
* @{
|
||||
* @brief <b>This is the library used by the whole 95HF family (RX95HF, CR95HF, ST95HF) <br />
|
||||
* You will find ISO libraries ( 14443A, 14443B, 15693, ...) for PICC and PCD <br />
|
||||
* The libraries selected in the project will depend of the application targetted <br />
|
||||
* and the product chosen (RX95HF emulate PICC, CR95HF emulate PCD, ST95HF can do both)</b>
|
||||
*/
|
||||
|
||||
/** @addtogroup PCD
|
||||
* @{
|
||||
* @brief This part of the library enables PCD capabilities of CR95HF & ST95HF.
|
||||
*/
|
||||
|
||||
|
||||
/** @addtogroup NFC_type1_pcd
|
||||
* @{
|
||||
* @brief This file is used to exchange with NFC FORUM Type1 Tag.
|
||||
*/
|
||||
|
||||
|
||||
/** @addtogroup lib_nfctype1pcd_Private_Functions
|
||||
* @{
|
||||
*/
|
||||
|
||||
|
||||
/**
|
||||
* @brief This function generates the ReadAll command
|
||||
* @param pBufferRead : Pointer on the buffer which will contain the data read
|
||||
* @retval PCDNFCT1_OK : Command success
|
||||
* @retval PCDNFCT1_ERROR : Transmission error
|
||||
*/
|
||||
static uint8_t PCDNFCT1_ReadAll(uint8_t *pBufferRead)
|
||||
{
|
||||
uint8_t buffer[] = {PCDNFCT1_READALL,0x00,0x00,0,0,0,0,PCDNFCT1_TOPAZ_MODE};
|
||||
|
||||
memcpy(&buffer[3], &TagUID[4],4);
|
||||
|
||||
if (PCD_SendRecv(8,buffer, pBufferRead) == PCD_SUCCESSCODE)
|
||||
return PCDNFCT1_OK;
|
||||
else
|
||||
return PCDNFCT1_ERROR;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief This function generates the WriteErase command
|
||||
* @param address : The address of the byte to write
|
||||
* @param byte : The byte to write
|
||||
* @retval PCDNFCT1_OK : Command success
|
||||
* @retval PCDNFCT1_ERROR : Transmission error
|
||||
*/
|
||||
static uint8_t PCDNFCT1_WriteErase(uint8_t address, uint8_t byte)
|
||||
{
|
||||
uint8_t buffer[] = {PCDNFCT1_WRITE_E,0,0,0,0,0,0,PCDNFCT1_TOPAZ_MODE};
|
||||
uint8_t bufferRead[16];
|
||||
|
||||
/* Cannot write protected sector */
|
||||
if (address < 13 || address > 102)
|
||||
return PCDNFCT1_ERROR;
|
||||
|
||||
buffer[1] = address;
|
||||
buffer[2] = byte;
|
||||
memcpy(&buffer[3], &TagUID[4],4);
|
||||
|
||||
if (PCD_SendRecv(8,buffer, bufferRead) == PCD_SUCCESSCODE)
|
||||
return PCDNFCT1_OK;
|
||||
else
|
||||
return PCDNFCT1_ERROR;
|
||||
}
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/** @addtogroup lib_nfctype1pcd_Public_Functions
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* @brief This function reads the NDEF message from a tag type 1 and store result in the TT1Tag buffer
|
||||
* @retval PCDNFCT1_OK : Command success
|
||||
* @retval PCDNFCT1_ERROR : Transmission error
|
||||
*/
|
||||
uint8_t PCDNFCT1_ReadNDEF( void )
|
||||
{
|
||||
uint8_t status;
|
||||
uint8_t buffer[NFCT1_MAX_TAGMEMORY+2];
|
||||
uint16_t NDEFposition = 16, size;
|
||||
|
||||
errchk(PCDNFCT1_ReadAll(buffer));
|
||||
|
||||
if ((buffer[2] & PCDNFCT1_NDEF_CAPABLE_MSK) != 0x10) /* NDEF capable TT1 if H0 = 0x1X */
|
||||
return PCDNFCT1_ERROR_NOT_FORMATED;
|
||||
if (buffer[12] != PCDNFCT1_NDEF_MNB) /* CC file with NDEF info */
|
||||
return PCDNFCT1_ERROR_NOT_FORMATED;
|
||||
if (buffer[14] != 0x0E) /* Check the size (only static memory supported yet)*/
|
||||
return PCDNFCT1_ERROR_MEMORY_INTERNAL;
|
||||
|
||||
// Searching for the first NDEF TLV
|
||||
while (buffer[NDEFposition] != PCDNFCT1_TLV_NDEF)
|
||||
{
|
||||
if (buffer[NDEFposition] == PCDNFCT1_TLV_EMPTY) // Empty TLV
|
||||
NDEFposition++;
|
||||
else if (buffer[NDEFposition] == PCDNFCT1_TLV_LOCK || buffer[NDEFposition] == PCDNFCT1_TLV_MEM) // Lock CTRL TLV or Mem CTRL TLV
|
||||
NDEFposition+=5;
|
||||
else
|
||||
return PCDNFCT1_ERROR; // Other TLV not supported yet (proprietary)
|
||||
if (NDEFposition > NFCT1_MAX_TAGMEMORY)
|
||||
return PCDNFCT1_ERROR; // EOF and no NDEF TLV found
|
||||
}
|
||||
|
||||
// Get the length of the message and copy it
|
||||
if (buffer[NDEFposition+1] == 0xFF) // Long message (cannot happen with static memory...)
|
||||
{
|
||||
size = buffer[NDEFposition+2]<<8|buffer[NDEFposition+3];
|
||||
memcpy(&TT1Tag[16],&buffer[NDEFposition],size+5);
|
||||
}
|
||||
else // Short message
|
||||
{
|
||||
memcpy(&TT1Tag[16],&buffer[NDEFposition],buffer[NDEFposition+1]+3);
|
||||
}
|
||||
|
||||
return PCDNFCT1_OK;
|
||||
Error:
|
||||
return PCDNFCT1_ERROR;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief This function writes the NDEF message to a tag type 1 from the TT1Tag buffer
|
||||
* @retval PCDNFCT1_OK : Command success
|
||||
* @retval PCDNFCT1_ERROR : Transmission error
|
||||
* @retval PCDNFCT1_ERROR_MEMORY : Not enough memory available on the tag
|
||||
*/
|
||||
uint8_t PCDNFCT1_WriteNDEF( void )
|
||||
{
|
||||
uint8_t status;
|
||||
uint8_t buffer[NFCT1_MAX_TAGMEMORY+2];
|
||||
uint16_t NDEFposition = 16, size, i;
|
||||
|
||||
errchk(PCDNFCT1_ReadAll(buffer));
|
||||
|
||||
if ((buffer[2] & PCDNFCT1_NDEF_CAPABLE_MSK) != 0x10) /* NDEF capable TT1 if H0 = 0x1X */
|
||||
return PCDNFCT1_ERROR_NOT_FORMATED;
|
||||
if (buffer[12] != PCDNFCT1_NDEF_MNB) /* CC file with NDEF info */
|
||||
return PCDNFCT1_ERROR_NOT_FORMATED;
|
||||
if (buffer[14] != 0x0E) /* Check the size (only static memory supported yet)*/
|
||||
return PCDNFCT1_ERROR;
|
||||
|
||||
// Searching for the first NDEF TLV
|
||||
while (buffer[NDEFposition] != PCDNFCT1_TLV_NDEF)
|
||||
{
|
||||
if (buffer[NDEFposition] == PCDNFCT1_TLV_EMPTY) // Empty TLV
|
||||
NDEFposition++;
|
||||
else if (buffer[NDEFposition] == PCDNFCT1_TLV_LOCK || buffer[NDEFposition] == PCDNFCT1_TLV_MEM) // Lock CTRL TLV or Mem CTRL TLV
|
||||
NDEFposition+=5;
|
||||
else
|
||||
return PCDNFCT1_ERROR; // Other TLV not supported yet (proprietary)
|
||||
if (NDEFposition > NFCT1_MAX_TAGMEMORY)
|
||||
return PCDNFCT1_ERROR; // EOF and no NDEF TLV found
|
||||
}
|
||||
|
||||
if (TT1Tag[15] == 0xFF)
|
||||
size = (((TT1Tag[16])<<8) | (TT1Tag[17])) + 4;
|
||||
else
|
||||
size = TT1Tag[15]+2;
|
||||
|
||||
if (size > NFCT1_MAX_TAGMEMORY-32)
|
||||
return PCDNFCT1_ERROR_MEMORY_TAG;
|
||||
|
||||
// Invalidate the NDEF message
|
||||
PCDNFCT1_WriteErase(8,PCDNFCT1_NDEF_DISABLE);
|
||||
|
||||
NDEFposition-=3;
|
||||
for(i=15;i<15+size;i++,NDEFposition++)
|
||||
{
|
||||
errchk(PCDNFCT1_WriteErase(NDEFposition,TT1Tag[i]));
|
||||
}
|
||||
|
||||
// Validate the NDEF message
|
||||
PCDNFCT1_WriteErase(8,PCDNFCT1_NDEF_MNB);
|
||||
|
||||
return PCDNFCT1_OK;
|
||||
Error:
|
||||
return PCDNFCT1_ERROR;
|
||||
}
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
//#ifdef __cplusplus
|
||||
//}
|
||||
//#endif
|
||||
|
||||
/******************* (C) COPYRIGHT 2015 STMicroelectronics *****END OF FILE****/
|
||||
75
src/lib_nfctype1pcd.h
Normal file
75
src/lib_nfctype1pcd.h
Normal file
@@ -0,0 +1,75 @@
|
||||
/**
|
||||
******************************************************************************
|
||||
* @file lib_nfctype1pcd.h
|
||||
* @author MMY Application Team
|
||||
* @version $Revision: 1333 $
|
||||
* @date $Date: 2015-11-05 10:49:42 +0100 (Thu, 05 Nov 2015) $
|
||||
* @brief Generates the NFC type1 commands
|
||||
******************************************************************************
|
||||
* @attention
|
||||
*
|
||||
* <h2><center>© COPYRIGHT 2015 STMicroelectronics</center></h2>
|
||||
*
|
||||
* Licensed under ST MYLIBERTY SOFTWARE LICENSE AGREEMENT (the "License");
|
||||
* You may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at:
|
||||
*
|
||||
* http://www.st.com/myliberty
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied,
|
||||
* AND SPECIFICALLY DISCLAIMING THE IMPLIED WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE, AND NON-INFRINGEMENT.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
******************************************************************************
|
||||
*/
|
||||
|
||||
/* Define to prevent recursive inclusion -------------------------------------*/
|
||||
#ifndef _LIB_NFCTYPE1PCD_H
|
||||
#define _LIB_NFCTYPE1PCD_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include "lib_pcd.h"
|
||||
|
||||
/* Error codes */
|
||||
#define PCDNFCT1_OK PCDNFC_OK
|
||||
#define PCDNFCT1_ERROR PCDNFC_ERROR
|
||||
#define PCDNFCT1_ERROR_MEMORY_TAG PCDNFC_ERROR_MEMORY_TAG
|
||||
#define PCDNFCT1_ERROR_MEMORY_INTERNAL PCDNFC_ERROR_MEMORY_INTERNAL
|
||||
#define PCDNFCT1_ERROR_NOT_FORMATED PCDNFC_ERROR_NOT_FORMATED
|
||||
|
||||
/* Command List */
|
||||
#define PCDNFCT1_READALL 0x00
|
||||
#define PCDNFCT1_WRITE_E 0x53
|
||||
|
||||
/* Mask */
|
||||
#define PCDNFCT1_NDEF_CAPABLE_MSK 0xF0
|
||||
|
||||
/* TLV */
|
||||
#define PCDNFCT1_TLV_EMPTY 0x00
|
||||
#define PCDNFCT1_TLV_LOCK 0x01
|
||||
#define PCDNFCT1_TLV_MEM 0x02
|
||||
#define PCDNFCT1_TLV_NDEF 0x03
|
||||
|
||||
#define PCDNFCT1_NDEF_MNB 0xE1
|
||||
#define PCDNFCT1_NDEF_DISABLE 0x00
|
||||
|
||||
#define PCDNFCT1_TOPAZ_MODE 0xA8
|
||||
|
||||
/* Functions */
|
||||
uint8_t PCDNFCT1_ReadNDEF( void );
|
||||
uint8_t PCDNFCT1_WriteNDEF( void );
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* _LIB_NFCTYPE1PCD_H */
|
||||
|
||||
/******************* (C) COPYRIGHT 2015 STMicroelectronics *****END OF FILE****/
|
||||
344
src/lib_nfctype2pcd.cpp
Normal file
344
src/lib_nfctype2pcd.cpp
Normal file
@@ -0,0 +1,344 @@
|
||||
/**
|
||||
******************************************************************************
|
||||
* @file lib_nfctype2pcd.c
|
||||
* @author MMY Application Team
|
||||
* @version $Revision: 1334 $
|
||||
* @date $Date: 2015-11-05 10:53:37 +0100 (Thu, 05 Nov 2015) $
|
||||
* @brief Generates the NFC type2 commands
|
||||
******************************************************************************
|
||||
* @attention
|
||||
*
|
||||
* <h2><center>© COPYRIGHT 2015 STMicroelectronics</center></h2>
|
||||
*
|
||||
* Licensed under ST MYLIBERTY SOFTWARE LICENSE AGREEMENT (the "License");
|
||||
* You may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at:
|
||||
*
|
||||
* http://www.st.com/myliberty
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied,
|
||||
* AND SPECIFICALLY DISCLAIMING THE IMPLIED WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE, AND NON-INFRINGEMENT.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
******************************************************************************
|
||||
*/
|
||||
|
||||
//#ifdef __cplusplus
|
||||
// extern "C" {
|
||||
//#endif
|
||||
|
||||
/* Includes ------------------------------------------------------------------------------ */
|
||||
#include "Arduino.h"
|
||||
#include "lib_nfctype2pcd.h"
|
||||
|
||||
extern uint8_t TT2Tag[];
|
||||
|
||||
static uint8_t PCDNFCT2_Read(uint8_t blocNbr, uint8_t *pBufferRead);
|
||||
static uint8_t PCDNFCT2_Write(uint8_t blocNbr, uint8_t *pBufferWrite);
|
||||
static uint8_t PCDNFCT2_SectorSelect(uint8_t sector);
|
||||
|
||||
/** @addtogroup _95HF_Libraries
|
||||
* @{
|
||||
* @brief <b>This is the library used by the whole 95HF family (RX95HF, CR95HF, ST95HF) <br />
|
||||
* You will find ISO libraries ( 14443A, 14443B, 15693, ...) for PICC and PCD <br />
|
||||
* The libraries selected in the project will depend of the application targetted <br />
|
||||
* and the product chosen (RX95HF emulate PICC, CR95HF emulate PCD, ST95HF can do both)</b>
|
||||
*/
|
||||
|
||||
/** @addtogroup PCD
|
||||
* @{
|
||||
* @brief This part of the library enables PCD capabilities of CR95HF & ST95HF.
|
||||
*/
|
||||
|
||||
|
||||
/** @addtogroup NFC_type2_pcd
|
||||
* @{
|
||||
* @brief This file is used to exchange with NFC FORUM Type2 Tag.
|
||||
*/
|
||||
|
||||
|
||||
/** @addtogroup lib_nfctype2pcd_Private_Functions
|
||||
* @{
|
||||
*/
|
||||
|
||||
|
||||
/**
|
||||
* @brief This function generates the Read command
|
||||
* @param blocNbr : First bloc number
|
||||
* @param pBufferRead : Pointer on the buffer which will contain the data read
|
||||
* @retval PCDNFCT2_OK : Command success
|
||||
* @retval PCDNFCT2_ERROR : Transmission error
|
||||
*/
|
||||
static uint8_t PCDNFCT2_Read(uint8_t blocNbr, uint8_t *pBufferRead)
|
||||
{
|
||||
uint8_t buffer[] = {PCDNFCT2_READ,0,SEND_MASK_APPENDCRC|SEND_MASK_8BITSINFIRSTBYTE};
|
||||
|
||||
buffer[1] = blocNbr;
|
||||
|
||||
if (PCD_SendRecv(3,buffer, pBufferRead) == PCD_SUCCESSCODE)
|
||||
return PCDNFCT2_OK;
|
||||
else
|
||||
return PCDNFCT2_ERROR;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief This function generates the Write command
|
||||
* @param blocNbr : First bloc number
|
||||
* @param pBufferWrite : Pointer on the buffer which contains the data to write
|
||||
* @retval PCDNFCT2_OK : Command success
|
||||
*/
|
||||
static uint8_t PCDNFCT2_Write(uint8_t blocNbr, uint8_t *pBufferWrite)
|
||||
{
|
||||
uint8_t pBufferRead[32];
|
||||
uint8_t buffer[] = {PCDNFCT2_WRITE,0,0,0,0,0,SEND_MASK_APPENDCRC|SEND_MASK_8BITSINFIRSTBYTE};
|
||||
|
||||
buffer[1] = blocNbr;
|
||||
memcpy(&buffer[2], pBufferWrite,4);
|
||||
|
||||
PCD_SendRecv(7,buffer, pBufferRead);
|
||||
return PCDNFCT2_OK;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief This function generates the SectorSelect command
|
||||
* @param sector : Sector number (0/1)
|
||||
* @retval PCDNFCT2_OK : Command success
|
||||
* @retval PCDNFCT2_ERROR : Transmission error
|
||||
*/
|
||||
static uint8_t PCDNFCT2_SectorSelect(uint8_t sector)
|
||||
{
|
||||
uint8_t pBufferRead[32];
|
||||
uint8_t buffer[] = {PCDNFCT2_SECTOR_SEL,0xFF,SEND_MASK_APPENDCRC|SEND_MASK_8BITSINFIRSTBYTE}; // First part
|
||||
uint8_t buffer2[] = {0,0x00,0x00,0x00,SEND_MASK_APPENDCRC|SEND_MASK_8BITSINFIRSTBYTE}; // Second part
|
||||
|
||||
buffer2[0] = sector;
|
||||
|
||||
PCD_SendRecv(3,buffer, pBufferRead);
|
||||
if (pBufferRead[0] == 0x90 && pBufferRead[1] == 0x04 && pBufferRead[2] == 0x0A) // ACK
|
||||
{
|
||||
PCD_SendRecv(5,buffer2, pBufferRead);
|
||||
if (pBufferRead[0] == 0x87 && pBufferRead[1] == 0x00) // Passive ACK = no answer so ST95HF send a timeout
|
||||
return PCDNFCT2_OK;
|
||||
else
|
||||
return PCDNFCT2_ERROR;
|
||||
}
|
||||
else
|
||||
return PCDNFCT2_ERROR;
|
||||
}
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/** @addtogroup lib_nfctype2pcd_Public_Functions
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* @brief This function reads the NDEF message from a tag type 2 and store result in the TT2Tag buffer
|
||||
* @retval PCDNFCT2_OK : Command success
|
||||
* @retval PCDNFCT2_ERROR : Transmission error
|
||||
* @retval PCDNFCT2_ERROR_LOCKED : The tag cannot be read (CC lock)
|
||||
*/
|
||||
uint8_t PCDNFCT2_ReadNDEF( void )
|
||||
{
|
||||
uint8_t status;
|
||||
uint8_t bufferRead[PCDNFCT2_READ_SIZE_BUFFER];
|
||||
uint8_t buffer[NFCT2_MAX_TAGMEMORY];
|
||||
uint16_t size, totalSize, i;
|
||||
uint16_t NDEFposition = 16;
|
||||
|
||||
// Check if CC is present with NDEF capability
|
||||
errchk(PCDNFCT2_Read(0,buffer));
|
||||
if (buffer[14] != PCDNFCT2_NDEF_MNB)
|
||||
return PCDNFCT2_ERROR_NOT_FORMATED;
|
||||
// Check if the tag is not protected
|
||||
if ((buffer[17]&PCDNFCT2_READ_MSK) != 0x00)
|
||||
return PCDNFCT2_ERROR_LOCKED;
|
||||
// Read the size from CC
|
||||
totalSize = buffer[16]*8;
|
||||
|
||||
// Check if there is enough memory available to read the tag
|
||||
if (totalSize > NFCT2_MAX_TAGMEMORY)
|
||||
return PCDNFCT2_ERROR_MEMORY_INTERNAL;
|
||||
|
||||
if (totalSize > PCDNFCT2_SECTOR_SIZE)
|
||||
size = PCDNFCT2_SECTOR_SIZE;
|
||||
else
|
||||
size = totalSize;
|
||||
// Read the whole memory
|
||||
for (i=0;i<size/4;i+=4)
|
||||
{
|
||||
errchk(PCDNFCT2_Read(i,bufferRead));
|
||||
memcpy(&buffer[i*4],&bufferRead[2],PCDNFCT2_READ_SIZE);
|
||||
}
|
||||
// Second sector (if needed)
|
||||
if (totalSize > PCDNFCT2_SECTOR_SIZE)
|
||||
{
|
||||
errchk(PCDNFCT2_SectorSelect(1));
|
||||
size = totalSize-PCDNFCT2_SECTOR_SIZE;
|
||||
for (i=4;i<size/4;i+=4)
|
||||
{
|
||||
errchk(PCDNFCT2_Read(i,bufferRead));
|
||||
memcpy(&buffer[PCDNFCT2_SECTOR_SIZE+i*4],&bufferRead[2],PCDNFCT2_READ_SIZE);
|
||||
}
|
||||
}
|
||||
|
||||
// Searching for the first NDEF TLV
|
||||
while (buffer[NDEFposition] != PCDNFCT2_TLV_NDEF)
|
||||
{
|
||||
if (buffer[NDEFposition] == PCDNFCT2_TLV_EMPTY) // Empty TLV
|
||||
NDEFposition++;
|
||||
else if (buffer[NDEFposition] == PCDNFCT2_TLV_LOCK || buffer[NDEFposition] == PCDNFCT2_TLV_MEM) // Lock CTRL TLV or Mem CTRL TLV
|
||||
NDEFposition+=5;
|
||||
else
|
||||
return PCDNFCT2_ERROR; // Other TLV not supported yet (proprietary)
|
||||
if (NDEFposition > totalSize)
|
||||
return PCDNFCT2_ERROR; // EOF and no NDEF TLV found
|
||||
}
|
||||
|
||||
// Get the length of the message and copy it
|
||||
if (buffer[NDEFposition+1] == 0xFF) // Long message
|
||||
{
|
||||
size = buffer[NDEFposition+2]<<8|buffer[NDEFposition+3];
|
||||
memcpy(&TT2Tag[16],&buffer[NDEFposition],size+5);
|
||||
}
|
||||
else // Short message
|
||||
{
|
||||
memcpy(&TT2Tag[16],&buffer[NDEFposition],buffer[NDEFposition+1]+3);
|
||||
}
|
||||
|
||||
return PCDNFCT2_OK;
|
||||
Error:
|
||||
return PCDNFCT2_ERROR;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief This function writes the NDEF message to a tag type 2 from the TT2Tag buffer
|
||||
* @retval PCDNFCT2_OK : Command success
|
||||
* @retval PCDNFCT2_ERROR : Transmission error
|
||||
* @retval PCDNFCT2_ERROR_LOCKED : The tag cannot be write or read (CC lock)
|
||||
* @retval PCDNFCT2_ERROR_MEMORY : Not enough memory available on the tag
|
||||
*/
|
||||
uint8_t PCDNFCT2_WriteNDEF( void )
|
||||
{
|
||||
uint8_t status;
|
||||
uint8_t bufferRead[PCDNFCT2_READ_SIZE_BUFFER];
|
||||
uint8_t buffer[NFCT2_MAX_TAGMEMORY];
|
||||
uint8_t byteSize;
|
||||
uint16_t size, totalSize, i, firstBloc;
|
||||
uint16_t NDEFposition = 16;
|
||||
|
||||
// Check if CC is present with NDEF capability
|
||||
errchk(PCDNFCT2_Read(0,buffer));
|
||||
if (buffer[14] != PCDNFCT2_NDEF_MNB)
|
||||
return PCDNFCT2_ERROR_NOT_FORMATED;
|
||||
// Check if the tag is not protected for read and write
|
||||
if ((buffer[17]&(PCDNFCT2_READ_MSK|PCDNFCT2_WRITE_MSK)) != 0x00)
|
||||
return PCDNFCT2_ERROR_LOCKED;
|
||||
// Read the size from CC
|
||||
totalSize = buffer[16]*8;
|
||||
// Read the size of message
|
||||
if (TT2Tag[17] == 0xFF) size = TT2Tag[18]<<8|TT2Tag[19];
|
||||
else size = TT2Tag[17];
|
||||
|
||||
// Check if there is enough memory available
|
||||
if (size > totalSize)
|
||||
return PCDNFCT2_ERROR_MEMORY_TAG;
|
||||
|
||||
if (totalSize > PCDNFCT2_SECTOR_SIZE)
|
||||
size = PCDNFCT2_SECTOR_SIZE;
|
||||
else
|
||||
size = totalSize;
|
||||
// Read the whole memory
|
||||
for (i=0;i<size/4;i+=4)
|
||||
{
|
||||
errchk(PCDNFCT2_Read(i,bufferRead));
|
||||
memcpy(&buffer[i*4],&bufferRead[2],PCDNFCT2_READ_SIZE);
|
||||
}
|
||||
// Second sector (if needed)
|
||||
if (totalSize > PCDNFCT2_SECTOR_SIZE)
|
||||
{
|
||||
PCDNFCT2_SectorSelect(1);
|
||||
size = totalSize-PCDNFCT2_SECTOR_SIZE;
|
||||
for (i=4;i<size/4;i+=4)
|
||||
{
|
||||
errchk(PCDNFCT2_Read(i,bufferRead));
|
||||
memcpy(&buffer[PCDNFCT2_SECTOR_SIZE+i*4],&bufferRead[2],PCDNFCT2_READ_SIZE);
|
||||
}
|
||||
}
|
||||
|
||||
// Searching for the first NDEF TLV
|
||||
while (buffer[NDEFposition] != PCDNFCT2_TLV_NDEF)
|
||||
{
|
||||
if (buffer[NDEFposition] == PCDNFCT2_TLV_EMPTY) // Empty TLV
|
||||
NDEFposition++;
|
||||
else if (buffer[NDEFposition] == PCDNFCT2_TLV_LOCK || buffer[NDEFposition] == PCDNFCT2_TLV_MEM) // Lock CTRL TLV or Mem CTRL TLV
|
||||
NDEFposition+=5;
|
||||
else
|
||||
return PCDNFCT2_ERROR; // Other TLV not supported yet (proprietary)
|
||||
if (NDEFposition > totalSize)
|
||||
return PCDNFCT2_ERROR; // EOF and no NDEF TLV found
|
||||
}
|
||||
|
||||
// Write the message
|
||||
if (TT2Tag[17] == 0xFF)
|
||||
size = ((TT2Tag[18]<<8) | (TT2Tag[19])) + 5;
|
||||
else
|
||||
size = TT2Tag[17] +3;
|
||||
|
||||
memcpy(&buffer[NDEFposition],&TT2Tag[16],size);
|
||||
|
||||
// The size has to be 0 for the first write
|
||||
byteSize = TT2Tag[17];
|
||||
buffer[NDEFposition+1] = 0;
|
||||
|
||||
firstBloc = NDEFposition>>2;
|
||||
|
||||
// To be sure to write the first sector
|
||||
if (totalSize > PCDNFCT2_SECTOR_SIZE)
|
||||
{
|
||||
errchk(PCDNFCT2_SectorSelect(0));
|
||||
}
|
||||
// Write all the blocks
|
||||
for (i=firstBloc;i<=(size>>2)+firstBloc;i++)
|
||||
{
|
||||
errchk(PCDNFCT2_Write(i, &buffer[i*4]));
|
||||
// Tag from NXP needs this delay...
|
||||
delay(5);
|
||||
}
|
||||
|
||||
// Write the size (numBloc = (NDEFposition+1)>>2)
|
||||
buffer[NDEFposition+1] = byteSize;
|
||||
errchk(PCDNFCT2_Write(((NDEFposition+1)>>2), &buffer[((NDEFposition+1)>>2)*4]));
|
||||
|
||||
return PCDNFCT2_OK;
|
||||
Error:
|
||||
return PCDNFCT2_ERROR;
|
||||
}
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
//#ifdef __cplusplus
|
||||
//}
|
||||
//#endif
|
||||
|
||||
/******************* (C) COPYRIGHT 2015 STMicroelectronics *****END OF FILE****/
|
||||
85
src/lib_nfctype2pcd.h
Normal file
85
src/lib_nfctype2pcd.h
Normal file
@@ -0,0 +1,85 @@
|
||||
/**
|
||||
******************************************************************************
|
||||
* @file lib_nfctype2pcd.h
|
||||
* @author MMY Application Team
|
||||
* @version $Revision: 1333 $
|
||||
* @date $Date: 2015-11-05 10:49:42 +0100 (Thu, 05 Nov 2015) $
|
||||
* @brief Generates the NFC type2 commands
|
||||
******************************************************************************
|
||||
* @attention
|
||||
*
|
||||
* <h2><center>© COPYRIGHT 2015 STMicroelectronics</center></h2>
|
||||
*
|
||||
* Licensed under ST MYLIBERTY SOFTWARE LICENSE AGREEMENT (the "License");
|
||||
* You may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at:
|
||||
*
|
||||
* http://www.st.com/myliberty
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied,
|
||||
* AND SPECIFICALLY DISCLAIMING THE IMPLIED WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE, AND NON-INFRINGEMENT.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
******************************************************************************
|
||||
*/
|
||||
|
||||
/* Define to prevent recursive inclusion -------------------------------------*/
|
||||
#ifndef _LIB_NFCTYPE2PCD_H
|
||||
#define _LIB_NFCTYPE2PCD_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include "lib_pcd.h"
|
||||
|
||||
/* Error codes */
|
||||
#define PCDNFCT2_OK PCDNFC_OK
|
||||
#define PCDNFCT2_ERROR PCDNFC_ERROR
|
||||
#define PCDNFCT2_ERROR_MEMORY_TAG PCDNFC_ERROR_MEMORY_TAG
|
||||
#define PCDNFCT2_ERROR_MEMORY_INTERNAL PCDNFC_ERROR_MEMORY_INTERNAL
|
||||
#define PCDNFCT2_ERROR_LOCKED PCDNFC_ERROR_LOCKED
|
||||
#define PCDNFCT2_ERROR_NOT_FORMATED PCDNFC_ERROR_NOT_FORMATED
|
||||
|
||||
/* Command List */
|
||||
#define PCDNFCT2_READ 0x30
|
||||
#define PCDNFCT2_WRITE 0xA2
|
||||
#define PCDNFCT2_SECTOR_SEL 0xC2
|
||||
|
||||
/* Size */
|
||||
#define PCDNFCT2_READ_SIZE 16
|
||||
#define PCDNFCT2_READ_SIZE_BUFFER 18
|
||||
#ifndef PCDNFCT2_SECTOR_SIZE
|
||||
// if not defined at application level, let's use 1024 for wider compatibility
|
||||
// it can be reduced to lower values, e.g. 256, but with restrictions :
|
||||
// issue on second sector read
|
||||
#define PCDNFCT2_SECTOR_SIZE 1024
|
||||
#endif
|
||||
|
||||
/* Mask */
|
||||
#define PCDNFCT2_READ_MSK 0xF0
|
||||
#define PCDNFCT2_WRITE_MSK 0x0F
|
||||
|
||||
/* TLV */
|
||||
#define PCDNFCT2_TLV_EMPTY 0x00
|
||||
#define PCDNFCT2_TLV_LOCK 0x01
|
||||
#define PCDNFCT2_TLV_MEM 0x02
|
||||
#define PCDNFCT2_TLV_NDEF 0x03
|
||||
|
||||
#define PCDNFCT2_NDEF_MNB 0xE1
|
||||
|
||||
/* Functions */
|
||||
uint8_t PCDNFCT2_ReadNDEF( void );
|
||||
uint8_t PCDNFCT2_WriteNDEF( void );
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* _LIB_NFCTYPE2PCD_H */
|
||||
|
||||
/******************* (C) COPYRIGHT 2015 STMicroelectronics *****END OF FILE****/
|
||||
349
src/lib_nfctype3pcd.cpp
Normal file
349
src/lib_nfctype3pcd.cpp
Normal file
@@ -0,0 +1,349 @@
|
||||
/**
|
||||
******************************************************************************
|
||||
* @file lib_nfctype3pcd.c
|
||||
* @author MMY Application Team
|
||||
* @version $Revision: 1334 $
|
||||
* @date $Date: 2015-11-05 10:53:37 +0100 (Thu, 05 Nov 2015) $
|
||||
* @brief Generates the NFC type3 commands
|
||||
******************************************************************************
|
||||
* @attention
|
||||
*
|
||||
* <h2><center>© COPYRIGHT 2015 STMicroelectronics</center></h2>
|
||||
*
|
||||
* Licensed under ST MYLIBERTY SOFTWARE LICENSE AGREEMENT (the "License");
|
||||
* You may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at:
|
||||
*
|
||||
* http://www.st.com/myliberty
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied,
|
||||
* AND SPECIFICALLY DISCLAIMING THE IMPLIED WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE, AND NON-INFRINGEMENT.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
******************************************************************************
|
||||
*/
|
||||
|
||||
//#ifdef __cplusplus
|
||||
// extern "C" {
|
||||
//#endif
|
||||
|
||||
/* Includes ------------------------------------------------------------------------------ */
|
||||
#include "lib_nfctype3pcd.h"
|
||||
|
||||
extern FELICA_CARD FELICA_Card;
|
||||
//extern uint8_t TT3Tag[];
|
||||
extern uint8_t *TT3AttribInfo, *TT3NDEFfile;
|
||||
|
||||
static uint8_t PCDNFCT3_ReadAttribInfo(uint8_t *pBufferRead);
|
||||
static uint8_t PCDNFCT3_WriteAttribInfo(uint8_t *pBufferWrite);
|
||||
static uint8_t PCDNFCT3_ReadMessage(const uint32_t NbByteToRead, uint8_t *pBufferRead);
|
||||
static uint8_t PCDNFCT3_WriteMessage(const uint32_t NbByteToWrite, uint8_t *pBufferWrite, uint8_t maxBlocWrite);
|
||||
static void PCDNFCT3_UpdateCheckSum(uint8_t *bufferAttrib);
|
||||
|
||||
/** @addtogroup _95HF_Libraries
|
||||
* @{
|
||||
* @brief <b>This is the library used by the whole 95HF family (RX95HF, CR95HF, ST95HF) <br />
|
||||
* You will find ISO libraries ( 14443A, 14443B, 15693, ...) for PICC and PCD <br />
|
||||
* The libraries selected in the project will depend of the application targetted <br />
|
||||
* and the product chosen (RX95HF emulate PICC, CR95HF emulate PCD, ST95HF can do both)</b>
|
||||
*/
|
||||
|
||||
/** @addtogroup PCD
|
||||
* @{
|
||||
* @brief This part of the library enables PCD capabilities of CR95HF & ST95HF.
|
||||
*/
|
||||
|
||||
|
||||
/** @addtogroup NFC_type3_pcd
|
||||
* @{
|
||||
* @brief This file is used to exchange with NFC FORUM Type3 Tag.
|
||||
*/
|
||||
|
||||
|
||||
/** @addtogroup lib_nfctype3pcd_Private_Functions
|
||||
* @{
|
||||
*/
|
||||
|
||||
|
||||
/**
|
||||
* @brief This function generates the Check command in order to read the AttribInfo field
|
||||
* @param pBufferRead : Pointer on the buffer which will contain the data read
|
||||
* @retval PCDNFCT3_OK : Command success
|
||||
* @retval PCDNFCT3_ERROR : Transmission error
|
||||
*/
|
||||
static uint8_t PCDNFCT3_ReadAttribInfo(uint8_t *pBufferRead)
|
||||
{
|
||||
uint8_t buffer[] = {PCDNFCT3_CHECK,0,0,0,0,0,0,0,0,0x01,PCDNFCT3_CODE_READ_LSB,PCDNFCT3_CODE_READ_MSB,0x01,PCDNFCT3_FIRST_BLOC_MSB,PCDNFCT3_FIRST_BLOC_LSB};
|
||||
|
||||
/* Write UID */
|
||||
memcpy(&buffer[1],FELICA_Card.UID,8);
|
||||
|
||||
if (PCD_SendRecv(15,buffer, pBufferRead) == PCD_SUCCESSCODE)
|
||||
return PCDNFCT3_OK;
|
||||
else
|
||||
return PCDNFCT3_ERROR;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief This function generates the Update command in order to write the AttribInfo field
|
||||
* @param pBufferWrite : Pointer on the buffer which contains the data to write
|
||||
* @retval PCDNFCT3_OK : Command success
|
||||
* @retval PCDNFCT3_ERROR : Transmission error
|
||||
*/
|
||||
static uint8_t PCDNFCT3_WriteAttribInfo(uint8_t *pBufferWrite)
|
||||
{
|
||||
uint8_t buffer[31] = {PCDNFCT3_UPDATE,0,0,0,0,0,0,0,0,0x01,PCDNFCT3_CODE_WRITE_LSB,PCDNFCT3_CODE_WRITE_MSB,0x01,PCDNFCT3_FIRST_BLOC_MSB,PCDNFCT3_FIRST_BLOC_LSB};
|
||||
uint8_t bufferRead[PCDNFCT3_ATTR_SIZE];
|
||||
|
||||
/* Write UID */
|
||||
memcpy(&buffer[1],FELICA_Card.UID,8);
|
||||
/* Write AttribInfo */
|
||||
memcpy(&buffer[15],pBufferWrite,PCDNFCT3_ATTR_SIZE);
|
||||
|
||||
if (PCD_SendRecv(31,buffer, bufferRead) == PCD_SUCCESSCODE)
|
||||
{
|
||||
if (bufferRead[11] == 0 && bufferRead[12] == 0)
|
||||
return PCDNFCT3_OK;
|
||||
else
|
||||
return PCDNFCT3_ERROR; /* Error code in reception frame */
|
||||
}
|
||||
else
|
||||
return PCDNFCT3_ERROR; /* Transmission error */
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief This function generates check commands in order to read all the NDEF message
|
||||
* @param NbByteToRead : Size of the NDEF message to read
|
||||
* @param pBufferRead : Pointer on the buffer which will contain the data read
|
||||
* @retval PCDNFCT3_OK : Command success
|
||||
* @retval PCDNFCT3_ERROR : Transmission error
|
||||
*/
|
||||
static uint8_t PCDNFCT3_ReadMessage(const uint32_t NbByteToRead, uint8_t *pBufferRead)
|
||||
{
|
||||
uint8_t nbBloc,i,j=0,maxBlocRead;
|
||||
uint8_t buffer[48] = {PCDNFCT3_CHECK,0,0,0,0,0,0,0,0,0x01,PCDNFCT3_CODE_READ_LSB,PCDNFCT3_CODE_READ_MSB};
|
||||
uint8_t bufferRead[280];
|
||||
|
||||
memcpy(&buffer[1],FELICA_Card.UID,8);
|
||||
|
||||
/* Check the maximum number of bloc that can be read with one command */
|
||||
maxBlocRead = TT3AttribInfo[1];
|
||||
|
||||
/* Check the total number of bloc to read */
|
||||
nbBloc = (NbByteToRead>>4)+1;
|
||||
|
||||
/* Send as many commands as needed */
|
||||
while (nbBloc > maxBlocRead)
|
||||
{
|
||||
nbBloc-=maxBlocRead;
|
||||
buffer[12] = maxBlocRead;
|
||||
for(i=0;i<maxBlocRead;i++) // 8001,8002,8003...
|
||||
{
|
||||
buffer[13+i*2] = PCDNFCT3_FIRST_BLOC_MSB;
|
||||
buffer[14+i*2] = PCDNFCT3_FIRST_BLOC_LSB+i+1+j*maxBlocRead;
|
||||
}
|
||||
if (PCD_SendRecv(13+maxBlocRead*2,buffer, bufferRead) != PCD_SUCCESSCODE)
|
||||
return PCDNFCT3_ERROR;
|
||||
/* Append the result to the pBufferRead buffer */
|
||||
memcpy(&pBufferRead[j*maxBlocRead*16],&bufferRead[14],maxBlocRead*16);
|
||||
j++;
|
||||
}
|
||||
if (nbBloc != 0) /* If there are blocks remaining */
|
||||
{
|
||||
buffer[12] = nbBloc;
|
||||
for(i=0;i<nbBloc;i++) // 8001,8002,8003...
|
||||
{
|
||||
buffer[13+i*2] = PCDNFCT3_FIRST_BLOC_MSB;
|
||||
buffer[14+i*2] = PCDNFCT3_FIRST_BLOC_LSB+i+1+j*maxBlocRead;
|
||||
}
|
||||
if (PCD_SendRecv(13+nbBloc*2,buffer, bufferRead) != PCD_SUCCESSCODE)
|
||||
return PCDNFCT3_ERROR;
|
||||
/* Append the result to the pBufferRead buffer */
|
||||
memcpy(&pBufferRead[j*maxBlocRead*16],&bufferRead[14],nbBloc*16);
|
||||
}
|
||||
|
||||
return PCDNFCT3_OK;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief This function generates Update commands in order to write all the NDEF message
|
||||
* @param NbByteToWrite : Size of the NDEF message to write
|
||||
* @param pBufferWrite : Pointer on the buffer which contains the data to write
|
||||
* @param maxBlocWrite : Maximum number of blocs that can be write in a single command
|
||||
* @retval PCDNFCT3_OK : Command success
|
||||
* @retval PCDNFCT3_ERROR : Transmission error
|
||||
*/
|
||||
static uint8_t PCDNFCT3_WriteMessage(const uint32_t NbByteToWrite, uint8_t *pBufferWrite, uint8_t maxBlocWrite)
|
||||
{
|
||||
uint8_t nbBloc,i,j=0;
|
||||
uint8_t buffer[280] = {PCDNFCT3_UPDATE,0,0,0,0,0,0,0,0,0x01,PCDNFCT3_CODE_WRITE_LSB,PCDNFCT3_CODE_WRITE_MSB};
|
||||
uint8_t bufferRead[16];
|
||||
|
||||
/* Write UID */
|
||||
memcpy(&buffer[1],FELICA_Card.UID,8);
|
||||
|
||||
/* Check the total number of bloc to write */
|
||||
nbBloc = (NbByteToWrite>>4)+1;
|
||||
|
||||
/* Send as many commands as needed */
|
||||
while (nbBloc > maxBlocWrite)
|
||||
{
|
||||
nbBloc-=maxBlocWrite;
|
||||
buffer[12] = maxBlocWrite;
|
||||
for(i=0;i<maxBlocWrite;i++) // 8001,8002,8003...
|
||||
{
|
||||
buffer[13+i*2] = PCDNFCT3_FIRST_BLOC_MSB;
|
||||
buffer[14+i*2] = PCDNFCT3_FIRST_BLOC_LSB+i+1+j*maxBlocWrite;
|
||||
}
|
||||
memcpy(&buffer[13+maxBlocWrite*2],&pBufferWrite[j*maxBlocWrite*16],maxBlocWrite*16);
|
||||
if (PCD_SendRecv(13+maxBlocWrite*2+16*maxBlocWrite,buffer, bufferRead) != PCD_SUCCESSCODE)
|
||||
return PCDNFCT3_ERROR;
|
||||
if (bufferRead[11] != 0 || bufferRead[12] != 0)
|
||||
return PCDNFCT3_ERROR; /* Error code in reception frame */
|
||||
j++;
|
||||
}
|
||||
if (nbBloc != 0) /* If there are blocks remaining */
|
||||
{
|
||||
buffer[12] = nbBloc;
|
||||
for(i=0;i<nbBloc;i++) // 8001,8002,8003...
|
||||
{
|
||||
buffer[13+i*2] = PCDNFCT3_FIRST_BLOC_MSB;
|
||||
buffer[14+i*2] = PCDNFCT3_FIRST_BLOC_LSB+i+1+j*maxBlocWrite;
|
||||
}
|
||||
memcpy(&buffer[13+nbBloc*2],&pBufferWrite[j*maxBlocWrite*16],nbBloc*16);
|
||||
if (PCD_SendRecv(13+nbBloc*2+16*nbBloc,buffer, bufferRead) != PCD_SUCCESSCODE)
|
||||
return PCDNFCT3_ERROR;
|
||||
if (bufferRead[11] != 0 || bufferRead[12] != 0)
|
||||
return PCDNFCT3_ERROR; /* Error code in reception frame */
|
||||
}
|
||||
|
||||
return PCDNFCT3_OK;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief This function updates the checksum of the AttribInfo field
|
||||
* @param bufferAttrib : Pointer to the memory containing the AttribInfo field
|
||||
*/
|
||||
static void PCDNFCT3_UpdateCheckSum(uint8_t *bufferAttrib)
|
||||
{
|
||||
uint8_t i;
|
||||
uint16_t checkSum = 0;
|
||||
for(i=0;i<14;i++)
|
||||
checkSum+=bufferAttrib[i];
|
||||
bufferAttrib[14] = checkSum>>8;
|
||||
bufferAttrib[15] = checkSum&0x00FF;
|
||||
}
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/** @addtogroup lib_nfctype3pcd_Public_Functions
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* @brief This function reads the NDEF message from a tag type 3 and store result in the TT3Tag buffer
|
||||
* @retval PCDNFCT3_OK : Command success
|
||||
* @retval PCDNFCT3_ERROR : Transmission error
|
||||
* @retval PCDNFCT3_ERROR_LOCKED : The tag cannot be read (AttribInfo lock)
|
||||
*/
|
||||
uint8_t PCDNFCT3_ReadNDEF( void )
|
||||
{
|
||||
uint8_t buffer[32];
|
||||
uint8_t status;
|
||||
uint32_t size;
|
||||
|
||||
/* Read AttribInfo field */
|
||||
errchk(PCDNFCT3_ReadAttribInfo(buffer));
|
||||
memcpy(TT3AttribInfo,&buffer[14],PCDNFCT3_ATTR_SIZE);
|
||||
/* Calculate the size */
|
||||
size = TT3AttribInfo[11]<<16|TT3AttribInfo[12]<<8|TT3AttribInfo[13];
|
||||
|
||||
// Check if there is enough memory available to read the tag
|
||||
if (size > NFCT3_MAX_TAGMEMORY)
|
||||
return PCDNFCT3_ERROR_MEMORY_INTERNAL;
|
||||
|
||||
/* Read the NDEF message */
|
||||
errchk(PCDNFCT3_ReadMessage(size,TT3NDEFfile));
|
||||
|
||||
return PCDNFCT3_OK;
|
||||
Error:
|
||||
return PCDNFCT3_ERROR;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief This function writes the NDEF message to a tag type 3 from the TT3Tag buffer
|
||||
* @retval PCDNFCT3_OK : Command success
|
||||
* @retval PCDNFCT3_ERROR : Transmission error
|
||||
* @retval PCDNFCT3_ERROR_LOCKED : The tag cannot be write (AttribInfo lock)
|
||||
* @retval PCDNFCT3_ERROR_MEMORY : Not enough memory available on the tag
|
||||
*/
|
||||
uint8_t PCDNFCT3_WriteNDEF( void )
|
||||
{
|
||||
uint8_t buffer[32];
|
||||
uint8_t bufferAttrib[16];
|
||||
uint8_t status;
|
||||
uint32_t size, memoryAvailable;
|
||||
|
||||
/* Read AttribInfo field */
|
||||
errchk(PCDNFCT3_ReadAttribInfo(buffer));
|
||||
memcpy(bufferAttrib,&buffer[14],PCDNFCT3_ATTR_SIZE);
|
||||
/* Check if write is available */
|
||||
if(bufferAttrib[10] != 0x01)
|
||||
return PCDNFCT3_ERROR_LOCKED;
|
||||
/* Check if there is enough memory */
|
||||
memoryAvailable = ((bufferAttrib[3]<<8)|bufferAttrib[4]);
|
||||
size = TT3AttribInfo[11]<<16|TT3AttribInfo[12]<<8|TT3AttribInfo[13];
|
||||
if ((size>>4) > memoryAvailable)
|
||||
return PCDNFCT3_ERROR_MEMORY_TAG;
|
||||
|
||||
/* Writing flag set to ON */
|
||||
bufferAttrib[9] = PCDNFCT3_WRITE_ON;
|
||||
/* Update CheckSum */
|
||||
PCDNFCT3_UpdateCheckSum(bufferAttrib);
|
||||
/* Write the AttribInfo */
|
||||
errchk(PCDNFCT3_WriteAttribInfo(bufferAttrib));
|
||||
|
||||
/* Write the message */
|
||||
errchk(PCDNFCT3_WriteMessage(size, TT3NDEFfile,bufferAttrib[2]));
|
||||
|
||||
/* Length */
|
||||
memcpy(&bufferAttrib[11],&TT3AttribInfo[11],3);
|
||||
/* Writing Flag OFF */
|
||||
bufferAttrib[9] = PCDNFCT3_WRITE_OFF;
|
||||
/* CheckSum */
|
||||
PCDNFCT3_UpdateCheckSum(bufferAttrib);
|
||||
/* Write the AttribInfo */
|
||||
errchk(PCDNFCT3_WriteAttribInfo(bufferAttrib));
|
||||
|
||||
return PCDNFCT3_OK;
|
||||
Error:
|
||||
return PCDNFCT3_ERROR;
|
||||
}
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
//#ifdef __cplusplus
|
||||
//}
|
||||
//#endif
|
||||
|
||||
/******************* (C) COPYRIGHT 2015 STMicroelectronics *****END OF FILE****/
|
||||
75
src/lib_nfctype3pcd.h
Normal file
75
src/lib_nfctype3pcd.h
Normal file
@@ -0,0 +1,75 @@
|
||||
/**
|
||||
******************************************************************************
|
||||
* @file lib_nfctype3pcd.h
|
||||
* @author MMY Application Team
|
||||
* @version $Revision: 1333 $
|
||||
* @date $Date: 2015-11-05 10:49:42 +0100 (Thu, 05 Nov 2015) $
|
||||
* @brief Generates the NFC type3 commands
|
||||
******************************************************************************
|
||||
* @attention
|
||||
*
|
||||
* <h2><center>© COPYRIGHT 2015 STMicroelectronics</center></h2>
|
||||
*
|
||||
* Licensed under ST MYLIBERTY SOFTWARE LICENSE AGREEMENT (the "License");
|
||||
* You may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at:
|
||||
*
|
||||
* http://www.st.com/myliberty
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied,
|
||||
* AND SPECIFICALLY DISCLAIMING THE IMPLIED WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE, AND NON-INFRINGEMENT.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
******************************************************************************
|
||||
*/
|
||||
|
||||
/* Define to prevent recursive inclusion -------------------------------------*/
|
||||
#ifndef _LIB_NFCTYPE3PCD_H
|
||||
#define _LIB_NFCTYPE3PCD_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include "lib_iso18092pcd.h"
|
||||
|
||||
#define PCDNFCT3_OK PCDNFC_OK
|
||||
#define PCDNFCT3_ERROR PCDNFC_ERROR
|
||||
#define PCDNFCT3_ERROR_MEMORY_TAG PCDNFC_ERROR_MEMORY_TAG
|
||||
#define PCDNFCT3_ERROR_MEMORY_INTERNAL PCDNFC_ERROR_MEMORY_INTERNAL
|
||||
#define PCDNFCT3_ERROR_LOCKED PCDNFC_ERROR_LOCKED
|
||||
|
||||
/* Command List */
|
||||
#define PCDNFCT3_CHECK 0x06
|
||||
#define PCDNFCT3_UPDATE 0x08
|
||||
|
||||
/* Service code */
|
||||
#define PCDNFCT3_CODE_READ_MSB 0x00
|
||||
#define PCDNFCT3_CODE_READ_LSB 0x0B
|
||||
#define PCDNFCT3_CODE_WRITE_MSB 0x00
|
||||
#define PCDNFCT3_CODE_WRITE_LSB 0x09
|
||||
#define PCDNFCT3_FIRST_BLOC_MSB 0x80
|
||||
#define PCDNFCT3_FIRST_BLOC_LSB 0x00
|
||||
|
||||
/* Flag */
|
||||
#define PCDNFCT3_WRITE_ON 0x0F
|
||||
#define PCDNFCT3_WRITE_OFF 0x00
|
||||
|
||||
/* Size */
|
||||
#define PCDNFCT3_ATTR_SIZE 16
|
||||
|
||||
/* Functions */
|
||||
uint8_t PCDNFCT3_ReadNDEF( void );
|
||||
uint8_t PCDNFCT3_WriteNDEF( void );
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* _LIB_NFCTYPE3PCD_H */
|
||||
|
||||
/******************* (C) COPYRIGHT 2015 STMicroelectronics *****END OF FILE****/
|
||||
348
src/lib_nfctype4pcd.cpp
Normal file
348
src/lib_nfctype4pcd.cpp
Normal file
@@ -0,0 +1,348 @@
|
||||
/**
|
||||
******************************************************************************
|
||||
* @file lib_nfctype4pcd.c
|
||||
* @author MMY Application Team
|
||||
* @version $Revision: 1334 $
|
||||
* @date $Date: 2015-11-05 10:53:37 +0100 (Thu, 05 Nov 2015) $
|
||||
* @brief Generates the NFC type4 commands
|
||||
******************************************************************************
|
||||
* @attention
|
||||
*
|
||||
* <h2><center>© COPYRIGHT 2015 STMicroelectronics</center></h2>
|
||||
*
|
||||
* Licensed under ST MYLIBERTY SOFTWARE LICENSE AGREEMENT (the "License");
|
||||
* You may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at:
|
||||
*
|
||||
* http://www.st.com/myliberty
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied,
|
||||
* AND SPECIFICALLY DISCLAIMING THE IMPLIED WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE, AND NON-INFRINGEMENT.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
******************************************************************************
|
||||
*/
|
||||
|
||||
//#ifdef __cplusplus
|
||||
// extern "C" {
|
||||
//#endif
|
||||
|
||||
/* Includes ------------------------------------------------------------------------------ */
|
||||
#include "lib_nfctype4pcd.h"
|
||||
|
||||
extern uint8_t CardNDEFfileT4A[];
|
||||
extern uint8_t CardNDEFfileT4B[];
|
||||
|
||||
/* Variables for the different modes */
|
||||
//extern DeviceMode_t devicemode;
|
||||
extern TagType_t nfc_tagtype;
|
||||
|
||||
extern uint16_t FSC;
|
||||
|
||||
static int8_t PCDNFCT4_SelectApplication(void);
|
||||
static int8_t PCDNFCT4_SelectCCfile(void);
|
||||
static int8_t PCDNFCT4_SelectNDEFfile(const uint8_t NDEF_ID_MSB, const uint8_t NDEF_ID_LSB);
|
||||
static uint8_t PCDNFCT4_ReadBinary(const uint16_t Offset ,const uint8_t NbByteToRead , uint8_t *pBufferRead);
|
||||
static uint8_t PCDNFCT4_UpdateBinary(const uint16_t Offset ,const uint8_t NbByteToWrite , uint8_t *pBufferWrite);
|
||||
|
||||
/** @addtogroup _95HF_Libraries
|
||||
* @{
|
||||
* @brief <b>This is the library used by the whole 95HF family (RX95HF, CR95HF, ST95HF) <br />
|
||||
* You will find ISO libraries ( 14443A, 14443B, 15693, ...) for PICC and PCD <br />
|
||||
* The libraries selected in the project will depend of the application targetted <br />
|
||||
* and the product chosen (RX95HF emulate PICC, CR95HF emulate PCD, ST95HF can do both)</b>
|
||||
*/
|
||||
|
||||
/** @addtogroup PCD
|
||||
* @{
|
||||
* @brief This part of the library enables PCD capabilities of CR95HF & ST95HF.
|
||||
*/
|
||||
|
||||
|
||||
/** @addtogroup NFC_type4_pcd
|
||||
* @{
|
||||
* @brief This file is used to exchange with NFC FORUM Type4 Tag.
|
||||
*/
|
||||
|
||||
|
||||
/** @addtogroup lib_nfctype4pcd_Private_Functions
|
||||
* @{
|
||||
*/
|
||||
|
||||
|
||||
/**
|
||||
* @brief This function sends the SelectApplication command
|
||||
* @retval PCDNFCT4_OK : Command success
|
||||
* @retval PCDNFCT4_ERROR : Transmission error
|
||||
*/
|
||||
static int8_t PCDNFCT4_SelectApplication(void)
|
||||
{
|
||||
uint8_t P1byte = 0x04,
|
||||
P2byte = 0x00,
|
||||
LCbyte = 0x07,
|
||||
NDEFaplicationField[] = PCDNFCT4_SELECT_APPLI;
|
||||
|
||||
if (ISO7816_SelectFile ( P1byte , P2byte , LCbyte ,NDEFaplicationField ) == ISO7816_SUCCESSCODE)
|
||||
return PCDNFCT4_OK;
|
||||
else
|
||||
return PCDNFCT4_ERROR;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief This function sends the SelectCCfile command
|
||||
* @retval PCDNFCT4_OK : Command success
|
||||
* @retval PCDNFCT4_ERROR : Transmission error
|
||||
*/
|
||||
static int8_t PCDNFCT4_SelectCCfile(void)
|
||||
{
|
||||
uint8_t P1byte = 0x00,
|
||||
P2byte = 0x0C,
|
||||
LCbyte = 0x02,
|
||||
FileId[] = PCDNFCT4_CC_ID;
|
||||
|
||||
if (ISO7816_SelectFile ( P1byte , P2byte , LCbyte ,FileId ) == ISO7816_SUCCESSCODE)
|
||||
return PCDNFCT4_OK;
|
||||
else
|
||||
return PCDNFCT4_ERROR;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief This function sends the SelectNDEF command
|
||||
* @param NDEF_ID_MSB : NDEF identifier most significant bit
|
||||
* @param NDEF_ID_LSB : NDEF identifier least significant bit
|
||||
* @retval PCDNFCT4_OK : Command success
|
||||
* @retval PCDNFCT4_ERROR : Transmission error
|
||||
*/
|
||||
static int8_t PCDNFCT4_SelectNDEFfile(const uint8_t NDEF_ID_MSB, const uint8_t NDEF_ID_LSB)
|
||||
{
|
||||
uint8_t P1byte = 0x00,
|
||||
P2byte = 0x0C,
|
||||
LCbyte = 0x02,
|
||||
FileId[2];
|
||||
|
||||
FileId[0] = NDEF_ID_MSB;
|
||||
FileId[1] = NDEF_ID_LSB;
|
||||
|
||||
if (ISO7816_SelectFile ( P1byte , P2byte , LCbyte ,FileId ) == ISO7816_SUCCESSCODE)
|
||||
return PCDNFCT4_OK;
|
||||
else
|
||||
return PCDNFCT4_ERROR;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief This function sends a read binary command
|
||||
* @param Offset : first byte to read
|
||||
* @param NbByteToRead : number of byte to read
|
||||
* @param pBufferRead : pointer of the buffer read from the tag
|
||||
* @retval PCDNFCT4_OK : Command success
|
||||
* @retval PCDNFCT4_ERROR : Transmission error
|
||||
*/
|
||||
static uint8_t PCDNFCT4_ReadBinary(const uint16_t Offset ,const uint8_t NbByteToRead , uint8_t *pBufferRead)
|
||||
{
|
||||
uint8_t P1byte = GETMSB(Offset),
|
||||
P2byte = GETLSB(Offset),
|
||||
LEbyte = NbByteToRead;
|
||||
|
||||
if (ISO7816_ReadBinary ( P1byte , P2byte , LEbyte ,pBufferRead ) == ISO7816_SUCCESSCODE)
|
||||
return PCDNFCT4_OK;
|
||||
else
|
||||
return PCDNFCT4_ERROR;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief This function sends a update binary command
|
||||
* @param Offset : first byte to write
|
||||
* @param NbByteToWrite : number of byte to write
|
||||
* @param pBufferWrite : pointer of the buffer which contains data to write
|
||||
* @retval PCDNFCT4_OK : Command success
|
||||
* @retval PCDNFCT4_ERROR : Transmission error
|
||||
*/
|
||||
static uint8_t PCDNFCT4_UpdateBinary(const uint16_t Offset ,const uint8_t NbByteToWrite , uint8_t *pBufferWrite)
|
||||
{
|
||||
uint8_t P1byte = GETMSB(Offset),
|
||||
P2byte = GETLSB(Offset),
|
||||
LEbyte = NbByteToWrite;
|
||||
|
||||
if (ISO7816_UpdateBinary ( P1byte , P2byte , LEbyte ,pBufferWrite ) == ISO7816_SUCCESSCODE)
|
||||
return PCDNFCT4_OK;
|
||||
else
|
||||
return PCDNFCT4_ERROR;
|
||||
}
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/** @addtogroup lib_nfctype4pcd_Public_Functions
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* @brief This function reads the NDEF message from a tag type 4 and store result in the CardNDEFfile buffer
|
||||
* @retval PCDNFCT4_OK : Command success
|
||||
* @retval PCDNFCT4_ERROR : Transmission error
|
||||
* @retval PCDNFCT4_ERROR_LOCKED : The tag cannot be read (CCfile lock)
|
||||
*/
|
||||
uint8_t PCDNFCT4_ReadNDEF( void )
|
||||
{
|
||||
uint8_t status, NDEF_ID_MSB, NDEF_ID_LSB;
|
||||
uint8_t limit = 0;
|
||||
uint16_t size, i = 0, MLe;
|
||||
uint8_t buffer[PCDNFCT4_BUFFER_READ];
|
||||
uint8_t *CardNDEFfile;
|
||||
|
||||
// Choose the correct buffer
|
||||
if (nfc_tagtype == TT4A)
|
||||
CardNDEFfile = CardNDEFfileT4A;
|
||||
else
|
||||
CardNDEFfile = CardNDEFfileT4B;
|
||||
|
||||
// SelectAppli
|
||||
errchk(PCDNFCT4_SelectApplication());
|
||||
|
||||
// SelectCC
|
||||
errchk(PCDNFCT4_SelectCCfile());
|
||||
errchk(PCDNFCT4_ReadBinary(0x00, 0x0F, buffer));
|
||||
NDEF_ID_MSB = buffer[12];
|
||||
NDEF_ID_LSB = buffer[13];
|
||||
MLe = MIN((buffer[6]<<8|buffer[7]),0xF6);
|
||||
// Check if read access is allowed
|
||||
if (buffer[16] != PCDNFCT4_ACCESS_ALLOWED)
|
||||
return PCDNFCT4_ERROR_LOCKED;
|
||||
// SelectNDEF
|
||||
errchk(PCDNFCT4_SelectNDEFfile(NDEF_ID_MSB,NDEF_ID_LSB));
|
||||
// Read length
|
||||
errchk(PCDNFCT4_ReadBinary(0x00, 0x02, buffer));
|
||||
size = (((buffer[3])<<8) | (buffer[4])) + 2;
|
||||
|
||||
// Check if there is enough memory available to read the tag
|
||||
if (size > NFCT4_MAX_NDEFMEMORY)
|
||||
return PCDNFCT4_ERROR_MEMORY_INTERNAL;
|
||||
|
||||
/* Mle have a good chance to be bigger than FSC but just in case */
|
||||
/* FSC - PCB, SW1, SW2, CRC1, CRC2 */
|
||||
limit = MIN(MLe,(FSC-5));
|
||||
|
||||
// Read data
|
||||
while (size>limit)
|
||||
{
|
||||
errchk(PCDNFCT4_ReadBinary(i*limit, limit, buffer));
|
||||
memcpy(&CardNDEFfile[i*limit],&buffer[PCD_DATA_OFFSET+1],limit);
|
||||
size -= limit;
|
||||
i++;
|
||||
}
|
||||
if (size > 0)
|
||||
{
|
||||
errchk(PCDNFCT4_ReadBinary(i*limit, size, buffer));
|
||||
memcpy(&CardNDEFfile[i*limit],&buffer[PCD_DATA_OFFSET+1],size);
|
||||
}
|
||||
|
||||
return PCDNFCT4_OK;
|
||||
Error:
|
||||
return PCDNFCT4_ERROR;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief This function writes the NDEF message to a tag type 4 from the CardNDEFfile buffer
|
||||
* @retval PCDNFCT4_OK : Command success
|
||||
* @retval PCDNFCT4_ERROR : Transmission error
|
||||
* @retval PCDNFCT4_ERROR_LOCKED : The tag cannot be write (CCfile lock)
|
||||
* @retval PCDNFCT4_ERROR_MEMORY : Not enough memory available on the tag
|
||||
*/
|
||||
uint8_t PCDNFCT4_WriteNDEF( void )
|
||||
{
|
||||
uint8_t status, NDEF_ID_MSB, NDEF_ID_LSB;
|
||||
uint16_t size, i = 0, MLc, memoryAvailable;
|
||||
uint8_t buffer[32], bufferSize[2];
|
||||
uint8_t *CardNDEFfile;
|
||||
|
||||
// Choose the correct buffer
|
||||
if (nfc_tagtype == TT4A)
|
||||
CardNDEFfile = CardNDEFfileT4A;
|
||||
else
|
||||
CardNDEFfile = CardNDEFfileT4B;
|
||||
|
||||
// SelectAppli
|
||||
errchk(PCDNFCT4_SelectApplication());
|
||||
// SelectCC
|
||||
errchk(PCDNFCT4_SelectCCfile());
|
||||
errchk(PCDNFCT4_ReadBinary(0x00, 0x0F, buffer));
|
||||
NDEF_ID_MSB = buffer[12];
|
||||
NDEF_ID_LSB = buffer[13];
|
||||
// Check if there is enough memory available on the tag
|
||||
memoryAvailable = buffer[14]<<8|buffer[15];
|
||||
size = (((CardNDEFfile[0])<<8) | (CardNDEFfile[1])) + 2;
|
||||
if (size > memoryAvailable)
|
||||
return PCDNFCT4_ERROR_MEMORY_TAG;
|
||||
// Check if write access is allowed
|
||||
if (buffer[17] != PCDNFCT4_ACCESS_ALLOWED)
|
||||
return PCDNFCT4_ERROR_LOCKED;
|
||||
// Chaining not supported yet... and the maximum for ST95HF is 0xF6
|
||||
MLc = MIN((buffer[8]<<8|buffer[9]),0xF6);
|
||||
// SelectNDEF
|
||||
errchk(PCDNFCT4_SelectNDEFfile(NDEF_ID_MSB,NDEF_ID_LSB));
|
||||
// Write NDEF
|
||||
// The size must be 0
|
||||
bufferSize[0] = CardNDEFfile[0]; bufferSize[1] = CardNDEFfile[1];
|
||||
CardNDEFfile[0] = CardNDEFfile[1] = 0;
|
||||
|
||||
while (size>MLc)
|
||||
{
|
||||
status = PCDNFCT4_UpdateBinary(i*MLc, MLc, &CardNDEFfile[i*MLc]);
|
||||
// If an error occur we have to write back the size to the NDEF buffer
|
||||
if (status == PCDNFCT4_ERROR)
|
||||
{
|
||||
CardNDEFfile[0]=bufferSize[0];
|
||||
CardNDEFfile[1]=bufferSize[1];
|
||||
return PCDNFCT4_ERROR;
|
||||
}
|
||||
size -= MLc;
|
||||
i++;
|
||||
}
|
||||
if (size > 0)
|
||||
{
|
||||
status = PCDNFCT4_UpdateBinary(i*MLc, size, &CardNDEFfile[i*MLc]);
|
||||
// If an error occur we have to write back the size to the NDEF buffer
|
||||
if (status == PCDNFCT4_ERROR)
|
||||
{
|
||||
CardNDEFfile[0]=bufferSize[0];
|
||||
CardNDEFfile[1]=bufferSize[1];
|
||||
return PCDNFCT4_ERROR;
|
||||
}
|
||||
}
|
||||
|
||||
// Write the size
|
||||
errchk(PCDNFCT4_UpdateBinary(0,2,bufferSize));
|
||||
|
||||
return PCDNFCT4_OK;
|
||||
Error:
|
||||
return PCDNFCT4_ERROR;
|
||||
}
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
//#ifdef __cplusplus
|
||||
//}
|
||||
//#endif
|
||||
|
||||
/******************* (C) COPYRIGHT 2015 STMicroelectronics *****END OF FILE****/
|
||||
64
src/lib_nfctype4pcd.h
Normal file
64
src/lib_nfctype4pcd.h
Normal file
@@ -0,0 +1,64 @@
|
||||
/**
|
||||
******************************************************************************
|
||||
* @file lib_nfctype4pcd.h
|
||||
* @author MMY Application Team
|
||||
* @version $Revision: 1333 $
|
||||
* @date $Date: 2015-11-05 10:49:42 +0100 (Thu, 05 Nov 2015) $
|
||||
* @brief Generates the NFC type4 commands
|
||||
******************************************************************************
|
||||
* @attention
|
||||
*
|
||||
* <h2><center>© COPYRIGHT 2015 STMicroelectronics</center></h2>
|
||||
*
|
||||
* Licensed under ST MYLIBERTY SOFTWARE LICENSE AGREEMENT (the "License");
|
||||
* You may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at:
|
||||
*
|
||||
* http://www.st.com/myliberty
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied,
|
||||
* AND SPECIFICALLY DISCLAIMING THE IMPLIED WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE, AND NON-INFRINGEMENT.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
******************************************************************************
|
||||
*/
|
||||
|
||||
/* Define to prevent recursive inclusion -------------------------------------*/
|
||||
#ifndef _LIB_NFCTYPE4PCD_H
|
||||
#define _LIB_NFCTYPE4PCD_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include "lib_iso7816pcd.h"
|
||||
|
||||
#define PCDNFCT4_OK PCDNFC_OK
|
||||
#define PCDNFCT4_ERROR PCDNFC_ERROR
|
||||
#define PCDNFCT4_ERROR_MEMORY_TAG PCDNFC_ERROR_MEMORY_TAG
|
||||
#define PCDNFCT4_ERROR_MEMORY_INTERNAL PCDNFC_ERROR_MEMORY_INTERNAL
|
||||
#define PCDNFCT4_ERROR_LOCKED PCDNFC_ERROR_LOCKED
|
||||
|
||||
/* Command List */
|
||||
#define PCDNFCT4_SELECT_APPLI {0xD2,0x76,0x00,0x00,0x85,0x01,0x01,0x00}
|
||||
#define PCDNFCT4_CC_ID {0xE1,0x03}
|
||||
|
||||
/* Size */
|
||||
#define PCDNFCT4_BUFFER_READ 256
|
||||
|
||||
#define PCDNFCT4_ACCESS_ALLOWED 0x00
|
||||
|
||||
uint8_t PCDNFCT4_ReadNDEF(void);
|
||||
uint8_t PCDNFCT4_WriteNDEF( void );
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* _LIB_NFCTYPE4PCD_H */
|
||||
|
||||
/******************* (C) COPYRIGHT 2015 STMicroelectronics *****END OF FILE****/
|
||||
234
src/lib_nfctype5pcd.cpp
Normal file
234
src/lib_nfctype5pcd.cpp
Normal file
@@ -0,0 +1,234 @@
|
||||
/**
|
||||
******************************************************************************
|
||||
* @file lib_nfctype5pcd.c
|
||||
* @author MMY Application Team
|
||||
* @version $Revision: 1334 $
|
||||
* @date $Date: 2015-11-05 10:53:37 +0100 (Thu, 05 Nov 2015) $
|
||||
* @brief Generates the NFC type2 commands
|
||||
******************************************************************************
|
||||
* @attention
|
||||
*
|
||||
* <h2><center>© COPYRIGHT 2015 STMicroelectronics</center></h2>
|
||||
*
|
||||
* Licensed under ST MYLIBERTY SOFTWARE LICENSE AGREEMENT (the "License");
|
||||
* You may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at:
|
||||
*
|
||||
* http://www.st.com/myliberty
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied,
|
||||
* AND SPECIFICALLY DISCLAIMING THE IMPLIED WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE, AND NON-INFRINGEMENT.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
******************************************************************************
|
||||
*/
|
||||
|
||||
//#ifdef __cplusplus
|
||||
// extern "C" {
|
||||
//#endif
|
||||
|
||||
/* Includes ------------------------------------------------------------------------------ */
|
||||
#include "lib_nfctype5pcd.h"
|
||||
|
||||
extern uint8_t TT5Tag[];
|
||||
|
||||
/** @addtogroup _95HF_Libraries
|
||||
* @{
|
||||
* @brief <b>This is the library used by the whole 95HF family (RX95HF, CR95HF, ST95HF) <br />
|
||||
* You will find ISO libraries ( 14443A, 14443B, 15693, ...) for PICC and PCD <br />
|
||||
* The libraries selected in the project will depend of the application targetted <br />
|
||||
* and the product chosen (RX95HF emulate PICC, CR95HF emulate PCD, ST95HF can do both)</b>
|
||||
*/
|
||||
|
||||
/** @addtogroup PCD
|
||||
* @{
|
||||
* @brief This part of the library enables PCD capabilities of CR95HF & ST95HF.
|
||||
*/
|
||||
|
||||
|
||||
/** @addtogroup NFC_type5_pcd
|
||||
* @{
|
||||
* @brief This file is used to exchange with NFC FORUM Type5 Tag.
|
||||
*/
|
||||
|
||||
|
||||
/** @addtogroup lib_nfctype5pcd_Private_Functions
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/** @addtogroup lib_nfctype5pcd_Public_Functions
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* @brief This function reads the NDEF message from a tag type V and store result in the TT5Tag buffer
|
||||
* @retval PCDNFCT5_OK : Command success
|
||||
* @retval PCDNFCT5_ERROR : Transmission error
|
||||
* @retval PCDNFCT5_ERROR_LOCKED : The tag cannot be read (CC lock)
|
||||
*/
|
||||
uint8_t PCDNFCT5_ReadNDEF( void )
|
||||
{
|
||||
uint16_t size;
|
||||
uint8_t tagDensity = ISO15693_HIGH_DENSITY;
|
||||
// Try to determine the density by reading the first sector (128 bytes)
|
||||
if (ISO15693_ReadBytesTagData(ISO15693_HIGH_DENSITY, ISO15693_LRiS64K, TT5Tag, 127, 0) != ISO15693_SUCCESSCODE)
|
||||
{
|
||||
if (ISO15693_ReadBytesTagData(ISO15693_LOW_DENSITY, ISO15693_LRiS64K, TT5Tag, 127, 0) != ISO15693_SUCCESSCODE)
|
||||
return PCDNFCT5_ERROR;
|
||||
tagDensity = ISO15693_LOW_DENSITY;
|
||||
}
|
||||
|
||||
// NDEF capable ?
|
||||
if (TT5Tag[0] != 0xE1)
|
||||
return PCDNFCT5_ERROR_NOT_FORMATED;
|
||||
|
||||
// Check read access
|
||||
if ((TT5Tag[1]&0x0C) != 0)
|
||||
return PCDNFCT5_ERROR_LOCKED;
|
||||
|
||||
// Get the size of the message
|
||||
if (TT5Tag[5] == 0xFF)
|
||||
size = (TT5Tag[6]<<8)|TT5Tag[7];
|
||||
else
|
||||
size = 0x00FF&TT5Tag[5];
|
||||
|
||||
// Check if there is enough memory to read the tag
|
||||
// If CC3 bit3 = 1 the size is higher than 2KB but we don't know the size...
|
||||
if (size+7 > NFCT5_MAX_TAGMEMORY)
|
||||
return PCDNFCT5_ERROR_MEMORY_INTERNAL;
|
||||
|
||||
// Read the rest of the tag if needed
|
||||
if (size > 124)
|
||||
{
|
||||
if (ISO15693_ReadBytesTagData(tagDensity, ISO15693_LRiS64K, &TT5Tag[128], size-128, 128) != ISO15693_SUCCESSCODE)
|
||||
{
|
||||
return PCDNFCT5_ERROR;
|
||||
}
|
||||
}
|
||||
|
||||
return PCDNFCT5_OK;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief This function writes the NDEF message to a tag type V from the TT5Tag buffer
|
||||
* @retval PCDNFCT5_OK : Command success
|
||||
* @retval PCDNFCT5_ERROR : Transmission error
|
||||
* @retval PCDNFCT5_ERROR_LOCKED : The tag cannot be write or read (CC lock)
|
||||
* @retval PCDNFCT5_ERROR_MEMORY : Not enough memory available on the tag
|
||||
*/
|
||||
uint8_t PCDNFCT5_WriteNDEF( void )
|
||||
{
|
||||
uint8_t RepBuffer[30];
|
||||
uint8_t firstSector[140], status;
|
||||
uint16_t size, tagSize;
|
||||
uint8_t tagDensity = ISO15693_HIGH_DENSITY;
|
||||
// Try to determine the density by ready the first sector (128 bytes)
|
||||
if (ISO15693_ReadBytesTagData(ISO15693_HIGH_DENSITY, ISO15693_LRiS64K, firstSector, 127, 0) != ISO15693_SUCCESSCODE)
|
||||
{
|
||||
if (ISO15693_ReadBytesTagData(ISO15693_LOW_DENSITY, ISO15693_LRiS64K, firstSector, 127, 0) != ISO15693_SUCCESSCODE)
|
||||
return PCDNFCT5_ERROR;
|
||||
tagDensity = ISO15693_LOW_DENSITY;
|
||||
}
|
||||
// NDEF capable ?
|
||||
if (firstSector[0] != 0xE1)
|
||||
{
|
||||
/* Create the CC file */
|
||||
// We need the size
|
||||
if (tagDensity == ISO15693_HIGH_DENSITY)
|
||||
ISO15693_GetSystemInfo (0x0A , 0x00, RepBuffer);
|
||||
else
|
||||
ISO15693_GetSystemInfo (0x02 , 0x00, RepBuffer);
|
||||
if (RepBuffer[14] == 0xFF)
|
||||
tagSize = (((RepBuffer[15]<<8)|RepBuffer[14])+1)*(RepBuffer[16]+1);
|
||||
else
|
||||
tagSize = (RepBuffer[14]+1)*(RepBuffer[15]+1);
|
||||
// NDEF capable
|
||||
TT5Tag[0] = 0xE1;
|
||||
// Version + Read/Write allowed
|
||||
TT5Tag[1] = 0x40;
|
||||
// Size
|
||||
if (tagSize > 2040)
|
||||
{
|
||||
// If the size is above 2040 (0xFF) then we have to set the bit3 of CC4
|
||||
TT5Tag[2] = 0xFF;
|
||||
TT5Tag[3] = 0x05;
|
||||
}
|
||||
else
|
||||
{
|
||||
TT5Tag[2] = tagSize/8;
|
||||
TT5Tag[3] = 0x01;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// Copy the CC
|
||||
memcpy(TT5Tag,firstSector,4);
|
||||
|
||||
// Check read and write access
|
||||
if ((TT5Tag[1]&0x0F) != 0)
|
||||
return PCDNFCT5_ERROR_LOCKED;
|
||||
}
|
||||
|
||||
// Get the size of the message to write
|
||||
if (TT5Tag[5] == 0xFF)
|
||||
size = (TT5Tag[6]<<8)|TT5Tag[7];
|
||||
else
|
||||
size = 0x00FF&TT5Tag[5];
|
||||
|
||||
// Check if the memory available on the tag is enough
|
||||
// If CC3 bit3 = 1 the size is higher than 2KB but we don't know the size...
|
||||
if (TT5Tag[2]*8 < size+7 && (TT5Tag[3]&0x04) == 0)
|
||||
return PCDNFCT5_ERROR_MEMORY_TAG;
|
||||
if ((TT5Tag[3]&0x04) != 0) // So we use get system info command
|
||||
{
|
||||
if (tagDensity == ISO15693_HIGH_DENSITY)
|
||||
ISO15693_GetSystemInfo (0x0A , 0x00, RepBuffer);
|
||||
else
|
||||
ISO15693_GetSystemInfo (0x02 , 0x00, RepBuffer);
|
||||
|
||||
if (RepBuffer[14] == 0xFF)
|
||||
tagSize = (((RepBuffer[15]<<8)|RepBuffer[14])+1)*(RepBuffer[16]+1);
|
||||
else
|
||||
tagSize = (RepBuffer[14]+1)*(RepBuffer[15]+1);
|
||||
|
||||
if (tagSize < size+7)
|
||||
return PCDNFCT5_ERROR_MEMORY_TAG;
|
||||
}
|
||||
|
||||
// Write the tag
|
||||
errchk(ISO15693_WriteBytes_TagData(tagDensity, TT5Tag, size+7, 0));
|
||||
|
||||
return PCDNFCT5_OK;
|
||||
Error:
|
||||
return PCDNFCT5_ERROR;
|
||||
}
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
//#ifdef __cplusplus
|
||||
//}
|
||||
//#endif
|
||||
|
||||
/******************* (C) COPYRIGHT 2015 STMicroelectronics *****END OF FILE****/
|
||||
59
src/lib_nfctype5pcd.h
Normal file
59
src/lib_nfctype5pcd.h
Normal file
@@ -0,0 +1,59 @@
|
||||
/**
|
||||
******************************************************************************
|
||||
* @file lib_nfctype5pcd.h
|
||||
* @author MMY Application Team
|
||||
* @version $Revision: 1333 $
|
||||
* @date $Date: 2015-11-05 10:49:42 +0100 (Thu, 05 Nov 2015) $
|
||||
* @brief Generates the NFC type5 commands
|
||||
******************************************************************************
|
||||
* @attention
|
||||
*
|
||||
* <h2><center>© COPYRIGHT 2015 STMicroelectronics</center></h2>
|
||||
*
|
||||
* Licensed under ST MYLIBERTY SOFTWARE LICENSE AGREEMENT (the "License");
|
||||
* You may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at:
|
||||
*
|
||||
* http://www.st.com/myliberty
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied,
|
||||
* AND SPECIFICALLY DISCLAIMING THE IMPLIED WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE, AND NON-INFRINGEMENT.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
******************************************************************************
|
||||
*/
|
||||
|
||||
/* Define to prevent recursive inclusion -------------------------------------*/
|
||||
#ifndef _LIB_NFCTYPE5PCD_H
|
||||
#define _LIB_NFCTYPE5PCD_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include "lib_pcd.h"
|
||||
#include "lib_iso15693pcd.h"
|
||||
|
||||
/* Error codes */
|
||||
#define PCDNFCT5_OK PCDNFC_OK
|
||||
#define PCDNFCT5_ERROR PCDNFC_ERROR
|
||||
#define PCDNFCT5_ERROR_MEMORY_TAG PCDNFC_ERROR_MEMORY_TAG
|
||||
#define PCDNFCT5_ERROR_MEMORY_INTERNAL PCDNFC_ERROR_MEMORY_INTERNAL
|
||||
#define PCDNFCT5_ERROR_LOCKED PCDNFC_ERROR_LOCKED
|
||||
#define PCDNFCT5_ERROR_NOT_FORMATED PCDNFC_ERROR_NOT_FORMATED
|
||||
|
||||
/* Functions */
|
||||
uint8_t PCDNFCT5_ReadNDEF( void );
|
||||
uint8_t PCDNFCT5_WriteNDEF( void );
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* _LIB_NFCTYPE5PCD_H */
|
||||
|
||||
/******************* (C) COPYRIGHT 2015 STMicroelectronics *****END OF FILE****/
|
||||
769
src/lib_pcd.cpp
Normal file
769
src/lib_pcd.cpp
Normal file
@@ -0,0 +1,769 @@
|
||||
/**
|
||||
******************************************************************************
|
||||
* @file lib_pcd.c
|
||||
* @author MMY Application Team
|
||||
* @version $Revision: 1334 $
|
||||
* @date $Date: 2015-11-05 10:53:37 +0100 (Thu, 05 Nov 2015) $
|
||||
* @brief This file provides set of firmware functions to manages the PCD device device.
|
||||
* @brief The commands as defined in the PCD device datasheet
|
||||
******************************************************************************
|
||||
* @attention
|
||||
*
|
||||
* <h2><center>© COPYRIGHT 2015 STMicroelectronics</center></h2>
|
||||
*
|
||||
* Licensed under ST MYLIBERTY SOFTWARE LICENSE AGREEMENT (the "License");
|
||||
* You may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at:
|
||||
*
|
||||
* http://www.st.com/myliberty
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied,
|
||||
* AND SPECIFICALLY DISCLAIMING THE IMPLIED WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE, AND NON-INFRINGEMENT.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
******************************************************************************
|
||||
*/
|
||||
|
||||
//#ifdef __cplusplus
|
||||
// extern "C" {
|
||||
//#endif
|
||||
|
||||
/* Includes ------------------------------------------------------------------------------ */
|
||||
#include "lib_pcd.h"
|
||||
|
||||
extern drv95HF_ConfigStruct drv95HFConfig;
|
||||
extern uint8_t u95HFBuffer [RFTRANS_95HF_MAX_BUFFER_SIZE+3];
|
||||
|
||||
/* Variables for the different modes */
|
||||
//extern DeviceMode_t devicemode;
|
||||
//extern TagType_t nfc_tagtype;
|
||||
extern volatile bool EnableTimeOut;
|
||||
|
||||
static uint8_t IsAnAvailableProtocol (uint8_t Protocol);
|
||||
|
||||
PCD_PROTOCOL TechnoSelected = PCDPROTOCOL_UNKNOWN;
|
||||
|
||||
/** @addtogroup _95HF_Libraries
|
||||
* @{
|
||||
* @brief <b>This is the library used by the whole 95HF family (RX95HF, CR95HF, ST95HF) <br />
|
||||
* You will find ISO libraries ( 14443A, 14443B, 15693, ...) for PICC and PCD <br />
|
||||
* The libraries selected in the project will depend of the application targetted <br />
|
||||
* and the product chosen (RX95HF emulate PICC, CR95HF emulate PCD, ST95HF can do both)</b>
|
||||
*/
|
||||
|
||||
/** @addtogroup PCD
|
||||
* @{
|
||||
* @brief This part of the library enables PCD capabilities of CR95HF & ST95HF.
|
||||
*/
|
||||
|
||||
|
||||
/** @addtogroup PCD_Device
|
||||
* @{
|
||||
* @brief This set of function use the device commands to control both CR95HF & ST95HF <br />
|
||||
* This layer is the bridge beetween the library and the 95HF driver.
|
||||
*/
|
||||
|
||||
|
||||
/** @addtogroup lib_PCD_Private_Functions
|
||||
* @{
|
||||
*/
|
||||
|
||||
static uint32_t PCD_ComputeUARTBaudRate(const uint8_t BaudRateCommandParameter);
|
||||
|
||||
/**
|
||||
* @brief This function computes the UART baud rate according to Baudrate command parameter
|
||||
* @param BaudRateCommandParameter : Baudrate command parameter (1 byte)
|
||||
* @retval the UART baud rate value
|
||||
*/
|
||||
static uint32_t PCD_ComputeUARTBaudRate(const uint8_t BaudRateCommandParameter)
|
||||
{
|
||||
return ((uint32_t)13.56e6/ (2*BaudRateCommandParameter+2));
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief this functions returns PCD_SUCCESSCODE if the protocol is available, otherwise PCD_ERRORCODE_PARAMETER
|
||||
* @param Protocol : RF protocol (ISO 14443 A or 14443 B or 15 693 or Fellica)
|
||||
* @return PCD_SUCCESSCODE : the protocol is available
|
||||
* @return PCD_ERRORCODE_PARAMETER : the protocol isn't available
|
||||
*/
|
||||
static uint8_t IsAnAvailableProtocol (uint8_t Protocol)
|
||||
{
|
||||
switch(Protocol)
|
||||
{
|
||||
case PCD_PROTOCOL_FIELDOFF:
|
||||
return PCD_SUCCESSCODE;
|
||||
case PCD_PROTOCOL_ISO15693:
|
||||
return PCD_SUCCESSCODE;
|
||||
case PCD_PROTOCOL_ISO14443A:
|
||||
return PCD_SUCCESSCODE;
|
||||
case PCD_PROTOCOL_ISO14443B:
|
||||
return PCD_SUCCESSCODE;
|
||||
case PCD_PROTOCOL_FELICA:
|
||||
return PCD_SUCCESSCODE;
|
||||
default: return PCD_ERRORCODE_PARAMETER;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
|
||||
/** @addtogroup lib_PCD_Public_Functions
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* @brief this function send an EOF pulse to a contacless tag
|
||||
* @param pResponse : pointer on the PCD device reply
|
||||
* @retval PCD_SUCCESSCODE : the function is succesful
|
||||
*/
|
||||
int8_t PCD_SendEOF(uint8_t *pResponse)
|
||||
{
|
||||
const uint8_t DataToSend[] = {SEND_RECEIVE ,0x00};
|
||||
|
||||
drv95HF_SendReceive(DataToSend, pResponse);
|
||||
|
||||
return PCD_SUCCESSCODE;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @brief this functions turns the field off
|
||||
* @param none
|
||||
* @retval PCD_SUCCESSCODE : the function is succesful
|
||||
*/
|
||||
void PCD_FieldOff( void )
|
||||
{
|
||||
uint8_t ParametersByte=0x00;
|
||||
uint8_t pResponse[10];
|
||||
|
||||
PCD_ProtocolSelect(0x02, PCD_PROTOCOL_FIELDOFF, &ParametersByte,pResponse);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief this functions turns the field on
|
||||
* @param none
|
||||
* @return none
|
||||
*/
|
||||
void PCD_FieldOn(void)
|
||||
{
|
||||
uint8_t ParametersByte=0x00;
|
||||
uint8_t pResponse[10];
|
||||
|
||||
PCD_ProtocolSelect(0x02, PCD_PROTOCOL_ISO15693, &ParametersByte,pResponse);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief this function send Echo command to the PCD device
|
||||
* @param pResponse : pointer on the PCD device reply
|
||||
* @return PCD_SUCCESSCODE
|
||||
*/
|
||||
int8_t PCD_Echo(uint8_t *pResponse)
|
||||
{
|
||||
const uint8_t command[]= {ECHO};
|
||||
|
||||
drv95HF_SendReceive(command, pResponse);
|
||||
|
||||
return PCD_SUCCESSCODE;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief this function send a ProtocolSeclect command to the PCD device
|
||||
* @param Length : number of byte of protocol select command parameters
|
||||
* @param Protocol : RF protocol (ISO 14443 A or B or 15 693 or Fellica)
|
||||
* @param Parameters: prococol parameters (see reader datasheet)
|
||||
* @param pResponse : pointer on the PCD device response
|
||||
* @return PCD_SUCCESSCODE : the command was succedfully send
|
||||
* @return PCD_ERRORCODE_PARAMETERLENGTH : the Length parameter is erroneous
|
||||
* @return PCD_ERRORCODE_PARAMETER : a parameter is erroneous
|
||||
*/
|
||||
int8_t PCD_ProtocolSelect(const uint8_t Length,const uint8_t Protocol,const uint8_t *Parameters,uint8_t *pResponse)
|
||||
{
|
||||
uint8_t DataToSend[SELECT_BUFFER_SIZE];
|
||||
int8_t status;
|
||||
|
||||
/* check ready to receive Protocol select command */
|
||||
PCD_Echo(u95HFBuffer);
|
||||
|
||||
if (u95HFBuffer[0] != ECHORESPONSE)
|
||||
{
|
||||
/* reset the device */
|
||||
PCD_PORsequence( );
|
||||
}
|
||||
|
||||
/* initialize the result code to 0xFF and length to in case of error */
|
||||
*pResponse = PCD_ERRORCODE_DEFAULT;
|
||||
*(pResponse+1) = 0x00;
|
||||
|
||||
/* check the function parameters */
|
||||
errchk(IsAnAvailableProtocol(Protocol));
|
||||
|
||||
DataToSend[PCD_COMMAND_OFFSET ] = PROTOCOL_SELECT;
|
||||
DataToSend[PCD_LENGTH_OFFSET ] = Length;
|
||||
DataToSend[PCD_DATA_OFFSET ] = Protocol;
|
||||
|
||||
/* DataToSend CodeCmd Length Data */
|
||||
/* Parameters[0] first byte to emmit */
|
||||
memcpy(&(DataToSend[PCD_DATA_OFFSET +1]),Parameters,Length-1);
|
||||
|
||||
/* Send the command the Rf transceiver */
|
||||
drv95HF_SendReceive(DataToSend, pResponse);
|
||||
|
||||
return PCD_SUCCESSCODE;
|
||||
|
||||
Error:
|
||||
return PCD_ERRORCODE_PARAMETER;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @brief this function send a SendRecv command to the PCD device. the command to contacless device is embeded in Parameters.
|
||||
* @param Length : Number of bytes
|
||||
* @param Parameters : data depenps on protocl selected
|
||||
* @param pResponse : pointer on the PCD device response
|
||||
* @return PCD_SUCCESSCODE : the command was succedfully send
|
||||
* @return PCD_ERRORCODE_DEFAULT : the PCD device returned an error code
|
||||
* @return PCD_ERRORCODE_PARAMETERLENGTH : Length parameter is erroneous
|
||||
*/
|
||||
int8_t PCD_SendRecv(const uint8_t Length,const uint8_t *Parameters,uint8_t *pResponse)
|
||||
{
|
||||
uint8_t DataToSend[SENDRECV_BUFFER_SIZE];
|
||||
|
||||
/* initialize the result code to 0xFF and length to 0 */
|
||||
*pResponse = PCD_ERRORCODE_DEFAULT;
|
||||
*(pResponse+1) = 0x00;
|
||||
|
||||
// /* check the function parameters */
|
||||
// if (CHECKVAL (Length,1,255)==false)
|
||||
// return PCD_ERRORCODE_PARAMETERLENGTH;
|
||||
|
||||
DataToSend[PCD_COMMAND_OFFSET ] = SEND_RECEIVE;
|
||||
DataToSend[PCD_LENGTH_OFFSET ] = Length;
|
||||
|
||||
/* DataToSend CodeCmd Length Data*/
|
||||
/* Parameters[0] first byte to emmit */
|
||||
memcpy(&(DataToSend[PCD_DATA_OFFSET]),Parameters,Length);
|
||||
|
||||
/* Send the command the Rf transceiver */
|
||||
drv95HF_SendReceive(DataToSend, pResponse);
|
||||
|
||||
if (PCD_IsReaderResultCodeOk (SEND_RECEIVE,pResponse) != PCD_SUCCESSCODE)
|
||||
{
|
||||
if(*pResponse == PCD_ERRORCODE_NOTAGFOUND)
|
||||
return PCD_ERRORCODE_TIMEOUT;
|
||||
else
|
||||
return PCD_ERRORCODE_DEFAULT;
|
||||
}
|
||||
return PCD_SUCCESSCODE;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief this function send a Idle command to the PCD device
|
||||
* @param Length : Number of bytes
|
||||
* @param Data : pointer on data. Data depends on protocl selected
|
||||
* @param pResponse : pointer on the PCD device response
|
||||
* @return PCD_SUCCESSCODE : the command was succedfully send
|
||||
* @return PCD_ERRORCODE_DEFAULT : the PCD device returned an error code
|
||||
* @return PCD_ERRORCODE_PARAMETERLENGTH : Length parameter is erroneous
|
||||
*/
|
||||
int8_t PCD_Idle(const uint8_t Length, const uint8_t *Data )
|
||||
{
|
||||
uint8_t DataToSend[IDLE_BUFFER_SIZE];
|
||||
|
||||
/* check the function parameters */
|
||||
if (Length != 0x0E)
|
||||
return PCD_ERRORCODE_PARAMETERLENGTH;
|
||||
|
||||
DataToSend[PCD_COMMAND_OFFSET ] = IDLE;
|
||||
DataToSend[PCD_LENGTH_OFFSET ] = Length;
|
||||
|
||||
memcpy(&(DataToSend[PCD_DATA_OFFSET]),Data,Length );
|
||||
|
||||
drv95HF_SendSPICommand(DataToSend);
|
||||
|
||||
return PCD_SUCCESSCODE;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief this function send a RdReg command to the PCD device
|
||||
* @param Length : Number of bytes
|
||||
* @param Address : address of first register to read
|
||||
* @param RegCount : number of register to read
|
||||
* @param Flags : whether to increment address after register read
|
||||
* @param pResponse : pointer on the PCD device response
|
||||
* @return PCD_SUCCESSCODE : the command was succedfully send
|
||||
* @return PCD_ERRORCODE_DEFAULT : the PCD device returned an error code
|
||||
* @return PCD_ERRORCODE_PARAMETERLENGTH : Length parameter is erroneous
|
||||
*/
|
||||
int8_t PCD_ReadRegister(const uint8_t Length,const uint8_t Address,const uint8_t RegCount,const uint8_t Flags,uint8_t *pResponse)
|
||||
{
|
||||
uint8_t DataToSend[RDREG_BUFFER_SIZE];
|
||||
|
||||
|
||||
DataToSend[PCD_COMMAND_OFFSET ] = READ_REGISTER;
|
||||
DataToSend[PCD_LENGTH_OFFSET ] = Length;
|
||||
DataToSend[PCD_DATA_OFFSET ] = Address;
|
||||
DataToSend[PCD_DATA_OFFSET +1 ] = RegCount;
|
||||
DataToSend[PCD_DATA_OFFSET +2 ] = Flags;
|
||||
/* Send the command the Rf transceiver */
|
||||
drv95HF_SendReceive(DataToSend, pResponse);
|
||||
|
||||
if (PCD_IsReaderResultCodeOk (IDLE,pResponse) != PCD_SUCCESSCODE)
|
||||
return PCD_ERRORCODE_DEFAULT;
|
||||
|
||||
return PCD_SUCCESSCODE;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief this function send a WriteRegister command to the PCD device
|
||||
* @param Length : Number of bytes of WrReg parameters
|
||||
* @param Address : address of first register to write
|
||||
* @param pData : pointer data to be write
|
||||
* @param Flags : whether to increment address after register read
|
||||
* @param pResponse : pointer on the PCD device response
|
||||
* @return PCD_SUCCESSCODE : the command was succedfully send
|
||||
* @return PCD_ERRORCODE_PARAMETERLENGTH : Length parameter is erroneous
|
||||
*/
|
||||
int8_t PCD_WriteRegister(const uint8_t Length,const uint8_t Address,const uint8_t Flags,const uint8_t *pData,uint8_t *pResponse)
|
||||
{
|
||||
uint8_t DataToSend[WRREG_BUFFER_SIZE];
|
||||
|
||||
DataToSend[PCD_COMMAND_OFFSET ] = WRITE_REGISTER;
|
||||
DataToSend[PCD_LENGTH_OFFSET ] = Length;
|
||||
DataToSend[PCD_DATA_OFFSET ] = Address;
|
||||
DataToSend[PCD_DATA_OFFSET +1 ] = Flags;
|
||||
|
||||
/* Parameters[0] first byte to emmit */
|
||||
memcpy(&(DataToSend[PCD_DATA_OFFSET + 2]),pData,Length - 2 );
|
||||
|
||||
/* Send the command the Rf transceiver */
|
||||
drv95HF_SendReceive(DataToSend, pResponse);
|
||||
return PCD_SUCCESSCODE;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @brief This function sends POR sequence. It can be use to initialize the PCD device after a POR.
|
||||
* @param none
|
||||
* @return PCD_ERRORCODE_PORERROR : the POR sequence doesn't succeded
|
||||
* @return PCD_SUCCESSCODE : the RF transceiver is ready
|
||||
*/
|
||||
int8_t PCD_PORsequence( void )
|
||||
{
|
||||
uint16_t NthAttempt=0;
|
||||
|
||||
if(drv95HFConfig.uInterface == RFTRANS_95HF_INTERFACE_SPI)
|
||||
{
|
||||
drv95HF_ResetSPI();
|
||||
}
|
||||
|
||||
do{
|
||||
|
||||
/* send an ECHO command and checks the PCD device response */
|
||||
PCD_Echo(u95HFBuffer);
|
||||
if (u95HFBuffer[0]==ECHORESPONSE)
|
||||
return PCD_SUCCESSCODE;
|
||||
|
||||
/* if the SPI interface is selected then send a reset command*/
|
||||
if(drv95HFConfig.uInterface == RFTRANS_95HF_INTERFACE_SPI)
|
||||
{
|
||||
drv95HF_ResetSPI();
|
||||
}
|
||||
|
||||
} while (u95HFBuffer[0]!=ECHORESPONSE && NthAttempt++ <5);
|
||||
|
||||
return PCD_ERRORCODE_PORERROR;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief this function send a command to the PCD device device over SPI or UART bus and receive its response.
|
||||
* @brief the returned value is PCD_SUCCESSCODE
|
||||
* @param *pCommand : pointer on the buffer to send to the the PCD device ( Command | Length | Data)
|
||||
* @param *pResponse : pointer on the the PCD device response ( Command | Length | Data)
|
||||
* @return PCD_SUCCESSCODE : the the PCD device returns an success code
|
||||
* @return PCD_ERRORCODE_DEFAULT : the the PCD device returns an error code
|
||||
*/
|
||||
int8_t PCD_CheckSendReceive(const uint8_t *pCommand, uint8_t *pResponse)
|
||||
{
|
||||
drv95HF_SendReceive(pCommand, pResponse);
|
||||
|
||||
if (PCD_IsReaderResultCodeOk (SEND_RECEIVE,pResponse) != PCD_SUCCESSCODE)
|
||||
return PCD_ERRORCODE_DEFAULT;
|
||||
|
||||
return PCD_SUCCESSCODE;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @brief this function returns PCD_SUCCESSCODE is the reader reply is a succesful code.
|
||||
* @param CmdCode : code command send to the reader
|
||||
* @param ReaderReply : pointer on the PCD device response
|
||||
* @retval PCD_SUCCESSCODE : the CRC is Ok
|
||||
* @retval PCD_NOREPLY_CODE : the CRC is erroenous
|
||||
*/
|
||||
int8_t PCD_IsCRCOk(const uint8_t Protocol ,const uint8_t *pReaderReply)
|
||||
{
|
||||
uint8_t NbByte = pReaderReply[PCD_LENGTH_OFFSET];
|
||||
|
||||
|
||||
switch (Protocol)
|
||||
{
|
||||
case PCD_PROTOCOL_ISO15693:
|
||||
if ( (pReaderReply [PCD_DATA_OFFSET + NbByte - CONTROL_15693_NBBYTE] & CONTROL_15693_CRCMASK) == CONTROL_15693_CRCMASK )
|
||||
{
|
||||
return PCD_ERRORCODE_DEFAULT;
|
||||
}
|
||||
else
|
||||
{
|
||||
return PCD_SUCCESSCODE;
|
||||
}
|
||||
|
||||
case PCD_PROTOCOL_ISO14443A:
|
||||
if ( (pReaderReply [PCD_DATA_OFFSET + NbByte - ISO14443A_NBBYTE] & ISO14443A_CRCMASK) == ISO14443A_CRCMASK )
|
||||
{
|
||||
return PCD_ERRORCODE_DEFAULT;
|
||||
}
|
||||
else
|
||||
{
|
||||
return PCD_SUCCESSCODE;
|
||||
}
|
||||
|
||||
case PCD_PROTOCOL_ISO14443B:
|
||||
if ( (pReaderReply [PCD_DATA_OFFSET + NbByte - CONTROL_14443B_NBBYTE] & CONTROL_14443B_CRCMASK) == CONTROL_14443B_CRCMASK )
|
||||
{
|
||||
return PCD_ERRORCODE_DEFAULT;
|
||||
}
|
||||
else
|
||||
{
|
||||
return PCD_SUCCESSCODE;
|
||||
}
|
||||
|
||||
case PCD_PROTOCOL_FELICA:
|
||||
if ( (pReaderReply [PCD_DATA_OFFSET + NbByte - CONTROL_FELICA_NBBYTE] & CONTROL_FELICA_CRCMASK) == CONTROL_FELICA_CRCMASK )
|
||||
{
|
||||
return PCD_ERRORCODE_DEFAULT;
|
||||
}
|
||||
else
|
||||
{
|
||||
return PCD_SUCCESSCODE;
|
||||
}
|
||||
|
||||
default:
|
||||
return ERRORCODE_GENERIC;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief this function returns PCD_SUCCESSCODE is the reader reply is a succesful code.
|
||||
* @param CmdCode : code command send to the reader
|
||||
* @param ReaderReply : pointer on the PCD device response
|
||||
* @retval PCD_SUCCESSCODE : the PCD device returned a succesful code
|
||||
* @retval PCD_ERRORCODE_DEFAULT : the PCD device didn't return a succesful code
|
||||
* @retval PCD_NOREPLY_CODE : no the PCD device response
|
||||
*/
|
||||
int8_t PCD_IsReaderResultCodeOk(uint8_t CmdCode, const uint8_t *ReaderReply)
|
||||
{
|
||||
|
||||
if (ReaderReply[READERREPLY_STATUSOFFSET] == PCD_ERRORCODE_DEFAULT)
|
||||
return PCD_NOREPLY_CODE;
|
||||
|
||||
switch (CmdCode)
|
||||
{
|
||||
case ECHO:
|
||||
if (ReaderReply[PSEUDOREPLY_OFFSET] == ECHO)
|
||||
return PCD_SUCCESSCODE;
|
||||
else
|
||||
return PCD_ERRORCODE_DEFAULT;
|
||||
|
||||
case IDN:
|
||||
if (ReaderReply[READERREPLY_STATUSOFFSET] == IDN_RESULTSCODE_OK)
|
||||
return PCD_SUCCESSCODE;
|
||||
else
|
||||
return PCD_ERRORCODE_DEFAULT;
|
||||
|
||||
case PROTOCOL_SELECT:
|
||||
switch (ReaderReply[READERREPLY_STATUSOFFSET])
|
||||
{
|
||||
case IDN_RESULTSCODE_OK :
|
||||
return PCD_SUCCESSCODE;
|
||||
|
||||
case PROTOCOLSELECT_ERRORCODE_CMDLENGTH :
|
||||
return PCD_ERRORCODE_DEFAULT;
|
||||
|
||||
case PROTOCOLSELECT_ERRORCODE_INVALID :
|
||||
return PCD_ERRORCODE_DEFAULT;
|
||||
|
||||
default : return PCD_ERRORCODE_DEFAULT;
|
||||
|
||||
}
|
||||
|
||||
case SEND_RECEIVE:
|
||||
switch (ReaderReply[READERREPLY_STATUSOFFSET])
|
||||
{
|
||||
case SENDRECV_RESULTSCODE_OK :
|
||||
if (ReaderReply[READERREPLY_STATUSOFFSET+1] != 0)
|
||||
return PCD_SUCCESSCODE;
|
||||
else
|
||||
return PCD_ERRORCODE_DEFAULT;
|
||||
|
||||
case SENDRECV_RESULTSRESIDUAL :
|
||||
return PCD_SUCCESSCODE;
|
||||
|
||||
case SENDRECV_ERRORCODE_COMERROR :
|
||||
return PCD_ERRORCODE_DEFAULT;
|
||||
|
||||
case SENDRECV_ERRORCODE_FRAMEWAIT :
|
||||
return PCD_ERRORCODE_DEFAULT;
|
||||
|
||||
case SENDRECV_ERRORCODE_SOF :
|
||||
return PCD_ERRORCODE_DEFAULT;
|
||||
|
||||
case SENDRECV_ERRORCODE_OVERFLOW :
|
||||
return PCD_ERRORCODE_DEFAULT;
|
||||
|
||||
case SENDRECV_ERRORCODE_FRAMING :
|
||||
return PCD_ERRORCODE_DEFAULT;
|
||||
|
||||
case SENDRECV_ERRORCODE_EGT :
|
||||
return PCD_ERRORCODE_DEFAULT;
|
||||
|
||||
case SENDRECV_ERRORCODE_LENGTH :
|
||||
return PCD_ERRORCODE_DEFAULT;
|
||||
|
||||
case SENDRECV_ERRORCODE_CRC :
|
||||
return PCD_ERRORCODE_DEFAULT;
|
||||
case SENDRECV_ERRORCODE_RECEPTIONLOST :
|
||||
return PCD_ERRORCODE_DEFAULT;
|
||||
|
||||
default :
|
||||
return PCD_ERRORCODE_DEFAULT;
|
||||
|
||||
}
|
||||
|
||||
case IDLE:
|
||||
switch (ReaderReply[READERREPLY_STATUSOFFSET])
|
||||
{
|
||||
case IDLE_RESULTSCODE_OK :
|
||||
return PCD_SUCCESSCODE;
|
||||
|
||||
case IDLE_ERRORCODE_LENGTH :
|
||||
return PCD_ERRORCODE_DEFAULT;
|
||||
|
||||
default : return PCD_ERRORCODE_DEFAULT;
|
||||
|
||||
}
|
||||
|
||||
case READ_REGISTER:
|
||||
switch (ReaderReply[READERREPLY_STATUSOFFSET])
|
||||
{
|
||||
case READREG_RESULTSCODE_OK :
|
||||
return PCD_SUCCESSCODE;
|
||||
|
||||
case READREG_ERRORCODE_LENGTH :
|
||||
return PCD_ERRORCODE_DEFAULT;
|
||||
|
||||
default : return PCD_ERRORCODE_DEFAULT;
|
||||
|
||||
}
|
||||
|
||||
case WRITE_REGISTER:
|
||||
switch (ReaderReply[READERREPLY_STATUSOFFSET])
|
||||
{
|
||||
case WRITEREG_RESULTSCODE_OK :
|
||||
return PCD_SUCCESSCODE;
|
||||
|
||||
default : return PCD_ERRORCODE_DEFAULT;
|
||||
|
||||
}
|
||||
|
||||
case BAUD_RATE:
|
||||
return PCD_ERRORCODE_DEFAULT;
|
||||
|
||||
default:
|
||||
return ERRORCODE_GENERIC;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief this function perform the calibration to provide the parameter require for tag detection command
|
||||
* @param WU Period : Time allow between 2 tag detections
|
||||
* @param pDacDataH : Value computed for DacDataH (DacDataL = DacDataH <20> 0x10)
|
||||
* @return PCD_SUCCESSCODE : the calibration was successfully performed (DacDataH value is significant)
|
||||
*/
|
||||
int8_t PCD_TagDetectCalibration(const uint8_t Wuperiod, uint8_t *pDacDataH)
|
||||
{
|
||||
uint8_t DataToSend[IDLE_CMD_LENTH+2] = { 0x00, 0x00, 0x03, 0xA1, 0x00, 0xF8, 0x01, 0x18,
|
||||
0x00, 0x00, 0x60, 0x60, 0x00, 0x00, 0x3F, 0x01};
|
||||
uint8_t Response[3] = {0x00};
|
||||
uint8_t AlgoStep[6] = {0x80, 0x40, 0x20, 0x10, 0x08, 0x04};
|
||||
uint8_t i=0;
|
||||
|
||||
/* Insure no tag are present during calibration process */
|
||||
/* During the calibration process, DacDataL is forced to 0x00 and the software successively
|
||||
varies the DacDataH value from its maximum value (0xFE) to its minimum value (0x00) */
|
||||
|
||||
DataToSend[PCD_COMMAND_OFFSET ] = IDLE;
|
||||
DataToSend[PCD_LENGTH_OFFSET ] = IDLE_CMD_LENTH;
|
||||
|
||||
/* modify WU Period according to user input */
|
||||
DataToSend[WU_PERIOD_OFFSET] = Wuperiod;
|
||||
|
||||
/* Start 8-step calibration process */
|
||||
|
||||
/* Step 0: force wake-up event to Tag Detect (set DacDataH = 0x00)
|
||||
With these conditions Wake-Up event must be Tag Detect */
|
||||
|
||||
DataToSend[DACDATAH_OFFSET] = 0x00;
|
||||
drv95HF_SendReceive(DataToSend, Response);
|
||||
|
||||
if( (Response[0] == 0x00) && (Response[1] == 0x01) && (Response[2] == 0x02))
|
||||
{
|
||||
/* Step 1: force Wake-up event to Timeout set DacDataH = 0xFC
|
||||
With these conditions, Wake-Up event must be Timeout */
|
||||
DataToSend[DACDATAH_OFFSET] = 0xFC;
|
||||
drv95HF_SendReceive(DataToSend, Response);
|
||||
if( (Response[0] == 0x00) && (Response[1] == 0x01) && (Response[2] == 0x01))
|
||||
{
|
||||
/* Start loop
|
||||
If previous Wake-up event was Timeout (0x01) we must decrease DacDataH,
|
||||
If it was Tag Detect we must increase DacDataH */
|
||||
for(i=0; i<6; i++)
|
||||
{
|
||||
switch(Response[2])
|
||||
{
|
||||
case 0x01:
|
||||
DataToSend[DACDATAH_OFFSET] -= AlgoStep[i];
|
||||
break;
|
||||
|
||||
case 0x02:
|
||||
DataToSend[DACDATAH_OFFSET] += AlgoStep[i];
|
||||
break;
|
||||
|
||||
default:
|
||||
return PCD_ERRORCODE_DEFAULT;
|
||||
|
||||
}
|
||||
|
||||
drv95HF_SendReceive(DataToSend, Response);
|
||||
}
|
||||
|
||||
/* If last Wake-up event = Tag Detect (0x02), search DacDataRef = last DacDataH value
|
||||
If last Wake-up event = Timeout (0x01), search DacDataRef = last DacDataH value -4 */
|
||||
/* We have founded DacDataRef, DacDataL= DacDataRef <20> Guard and DacDataH= DacDataRef+ Guard
|
||||
where guard = 0x08 (2 DAC steps) */
|
||||
if( (Response[0] == 0x00) && (Response[1] == 0x01) && (Response[2] == 0x01))
|
||||
*pDacDataH = (DataToSend[DACDATAH_OFFSET] -0x04) + 0x08;
|
||||
else
|
||||
*pDacDataH = DataToSend[DACDATAH_OFFSET] + 0x08;
|
||||
|
||||
return PCD_SUCCESSCODE;
|
||||
|
||||
}
|
||||
else
|
||||
return PCD_ERRORCODE_DEFAULT;
|
||||
}
|
||||
else
|
||||
return PCD_ERRORCODE_DEFAULT;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief This function wait for Tag detection to exit
|
||||
* @param WU Source : Condition for exiting this function, Condition that was realized
|
||||
* @param WU Period : Time allow between 2 tag detections
|
||||
* @param DacDataH : value that must have been computed by calling PCD_TagDetectCalibration function
|
||||
* @param NbTrials : number of trial to find tag before time out
|
||||
* @return PCD_SUCCESSCODE : the calibration was succesfully performed (DacDataH value is significant)
|
||||
*/
|
||||
int8_t PCD_WaitforTagDetection(uint8_t *WuSource, const uint8_t WuPeriod, const uint8_t DacDataH, const uint8_t NbTrials)
|
||||
{
|
||||
uint8_t DataToSend[IDLE_CMD_LENTH+2] = { 0x00, 0x00, 0x00, 0x21, 0x00, 0x79, 0x01, 0x18,
|
||||
0x00, 0x20, 0x60, 0x60, 0x00, 0x00, 0x3F, 0x01};
|
||||
uint8_t Response[3] = {0x00};
|
||||
|
||||
DataToSend[PCD_COMMAND_OFFSET ] = IDLE;
|
||||
DataToSend[PCD_LENGTH_OFFSET ] = IDLE_CMD_LENTH;
|
||||
|
||||
/* modify WU Period according to user input */
|
||||
DataToSend[WU_SOURCE_OFFSET] = *WuSource;
|
||||
DataToSend[WU_PERIOD_OFFSET] = WuPeriod;
|
||||
DataToSend[DACDATAL_OFFSET] = DacDataH-0x10;
|
||||
DataToSend[DACDATAH_OFFSET] = DacDataH;
|
||||
DataToSend[NBTRIALS_OFFSET] = NbTrials;
|
||||
|
||||
/* In this case we need to desactivate the drv timeout */
|
||||
EnableTimeOut = false;
|
||||
drv95HF_SendReceive(DataToSend, Response);
|
||||
/* Set back the drv timeout */
|
||||
EnableTimeOut = true;
|
||||
|
||||
if( (Response[0] == 0x00) && (Response[1] == 0x01))
|
||||
{
|
||||
*WuSource = Response[2];
|
||||
return PCD_SUCCESSCODE;
|
||||
}
|
||||
else
|
||||
return PCD_ERRORCODE_DEFAULT;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief this function send a BaudRate command to the PCD device
|
||||
* @param BaudRate : new baudrate
|
||||
* @param pResponse : pseudo reply (shall be 0x55)
|
||||
* @return PCD_SUCCESSCODE : the command was succedfully send
|
||||
*/
|
||||
int8_t PCD_BaudRate(const uint8_t BaudRate,uint8_t *pResponse)
|
||||
{
|
||||
uint8_t DataToSend[BAUDRATE_BUFFER_SIZE];
|
||||
|
||||
DataToSend[PCD_COMMAND_OFFSET ] = BAUD_RATE;
|
||||
DataToSend[PCD_LENGTH_OFFSET ] = BAUDRATE_LENGTH;
|
||||
DataToSend[PCD_DATA_OFFSET ] = BaudRate;
|
||||
/* Send the command the Rf transceiver */
|
||||
drv95HF_SendReceive(DataToSend, pResponse);
|
||||
return PCD_SUCCESSCODE;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief This function run a process to change UARt baud rate. It'll check the baud rate is
|
||||
* @brief compatible with this MCU and configurates MCU and the PCD device baud rate.
|
||||
* @param *pCommand : pointer on the buffer to send to the the PCD device ( Command | Length | Data)
|
||||
* @param *pResponse : pointer on the the PCD device response ( Command | Length | Data)
|
||||
* @retval PCD_SUCCESSCODE : the UART baud rate has been succesfuly changed
|
||||
* @retval PCD_ERRORCODE_UARTDATARATEUNCHANGED : the UART baud rate has not changed
|
||||
* @retval PCD_ERRORCODE_UARTDATARATEPROCESS : command DaubRate was send to the PCD device but the MCU was not able to comunicatewith the PCD device
|
||||
*/
|
||||
int8_t PCD_ChangeUARTBaudRate(const uint8_t *pCommand, uint8_t *pResponse)
|
||||
{
|
||||
return PCD_ERRORCODE_UARTDATARATEUNCHANGED;
|
||||
}
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
//#ifdef __cplusplus
|
||||
//}
|
||||
//#endif
|
||||
|
||||
/******************* (C) COPYRIGHT 2015 STMicroelectronics *****END OF FILE****/
|
||||
269
src/lib_pcd.h
Normal file
269
src/lib_pcd.h
Normal file
@@ -0,0 +1,269 @@
|
||||
/**
|
||||
******************************************************************************
|
||||
* @file lib_pcd.h
|
||||
* @author MMY Application Team
|
||||
* @version $Revision: 1333 $
|
||||
* @date $Date: 2015-11-05 10:49:42 +0100 (Thu, 05 Nov 2015) $
|
||||
* @brief This file provides set of firmware functions to manages PCD device.
|
||||
* @brief The commands as defined in CR95HF datasheet
|
||||
******************************************************************************
|
||||
* @attention
|
||||
*
|
||||
* <h2><center>© COPYRIGHT 2015 STMicroelectronics</center></h2>
|
||||
*
|
||||
* Licensed under ST MYLIBERTY SOFTWARE LICENSE AGREEMENT (the "License");
|
||||
* You may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at:
|
||||
*
|
||||
* http://www.st.com/myliberty
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied,
|
||||
* AND SPECIFICALLY DISCLAIMING THE IMPLIED WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE, AND NON-INFRINGEMENT.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
******************************************************************************
|
||||
*/
|
||||
|
||||
/* Define to prevent recursive inclusion -------------------------------------*/
|
||||
#ifndef _LIB_PCD_H
|
||||
#define _LIB_PCD_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/* Includes ------------------------------------------------------------------*/
|
||||
#include "lib_95HF.h"
|
||||
|
||||
#define PCD_SPI RFTRANS_95HF_SPI
|
||||
|
||||
/* customs command ------------------------------------------------------------------------*/
|
||||
#define PCD_15693ANTICOL 0xA0
|
||||
#define PCD_INVENTORY16SLOTS 0xA1
|
||||
#define PCD_ISWAKEUP 0xA2
|
||||
#define PCD_GOTOTAGDETECTINGSTATE 0xA3
|
||||
#define PCD_CALIBRATETHETAGDETECTION 0xA4
|
||||
|
||||
#define PCD_READCUSTOMTAGMEMORY 0xB0
|
||||
#define PCD_READMCUBUFFER 0xB1
|
||||
#define PCD_GETHARDWAREVERSION 0xB2
|
||||
#define PCD_DOWNLOADSTM32MEM 0xB5
|
||||
#define PCD_READWHOLEMEMORY 0xB6
|
||||
#define PCD_TRANSPARENT 0xB7
|
||||
#define PCD_PULSE_POOLINGREADING 0xB8
|
||||
#define PCD_PULSE_SPINSS 0xB9
|
||||
#define PCD_GETINTERFACEPINSTATE 0xBA
|
||||
#define PCD_SETUSBDISCONNECTSTATE 0xBB
|
||||
#define PCD_GETMCUVERSION 0xBC
|
||||
#define PCD_RESETSEQUENCE 0xBD
|
||||
#define PCD_PULSE_IRQIN 0xBE
|
||||
|
||||
#ifdef USE_MSD_DRIVE
|
||||
#define PCD_COPYTAGTOFILE 0xC1
|
||||
#define PCD_COPYFILETOTAG 0xC2
|
||||
#endif /*USE_MSD_DRIVE*/
|
||||
|
||||
#define PCD_POR 0xC3
|
||||
#define PCD_TAG_TRAKING 0xC4
|
||||
#define PCD_CRYPTO_GENERIC 0xC5
|
||||
#define PCD_NDEF_MESSAGE 0xC6
|
||||
|
||||
#define PCD_MULTITAG 0xD0
|
||||
#define PCD_MULTITAG_EXTENDED 0xD1
|
||||
|
||||
#define SUCCESFUL_SENDS 0x80
|
||||
#define SUCCESFUL_COMMAND 0x00
|
||||
#define SUCCESFUL_COMMAND_0x80 0x80
|
||||
|
||||
/* PCD status and erroc code------------------------------------------------------ */
|
||||
#define PCD_SUCCESSCODE RESULTOK
|
||||
#define PCD_ERRORCODE_DEFAULT 0x21
|
||||
#define PCD_ERRORCODE_PARAMETER 0x22
|
||||
#define PCD_NOREPLY_CODE 0x23
|
||||
#define PCD_ERRORCODE_UARTDATARATEUNCHANGED 0x24
|
||||
#define PCD_ERRORCODE_UARTDATARATEPROCESS 0x25
|
||||
#define PCD_ERRORCODE_PORERROR 0x26
|
||||
#define PCD_ERRORCODE_PARAMETERLENGTH 0x27
|
||||
#define PCD_ERRORCODE_TIMEOUT 0x28
|
||||
|
||||
/* CR95HF polling status --------------------------------------------------------- */
|
||||
#define PCD_IDLERES_LENGTH 0x01
|
||||
#define PCD_WAKEUPSOURCE_TIMEOUT 0x01
|
||||
#define PCD_WAKEUPSOURCE_TAGDETECTING 0x02
|
||||
#define PCD_WAKEUPSOURCE_IRRQINN 0x08
|
||||
|
||||
/* Nb of bytes of reader commands --------------------------------------------------------- */
|
||||
#define SELECT_BUFFER_SIZE 16
|
||||
#define SENDRECV_BUFFER_SIZE 257
|
||||
#define SEND_BUFFER_SIZE 257
|
||||
#define IDLE_BUFFER_SIZE 16
|
||||
#define RDREG_BUFFER_SIZE 5
|
||||
#define WRREG_BUFFER_SIZE 257
|
||||
#define BAUDRATE_BUFFER_SIZE 3
|
||||
#define SUBFREQRES_BUFFER_SIZE 2
|
||||
#define ACFILTER_BUFFER_SIZE 19
|
||||
#define TESTMODE_BUFFER_SIZE 4
|
||||
#define SLEEPMODE_BUFFER_SIZE 4
|
||||
|
||||
/* Nb of bytes of reader response --------------------------------------------------------- */
|
||||
#define PCD_RESPONSEBUFFER_SIZE RFTRANS_95HF_MAX_BUFFER_SIZE
|
||||
|
||||
/* protocol allowed ----------------------------------------------------------------------- */
|
||||
#define PCD_PROTOCOL_FIELDOFF 0x00
|
||||
#define PCD_PROTOCOL_ISO15693 0x01
|
||||
#define PCD_PROTOCOL_ISO14443A 0x02
|
||||
#define PCD_PROTOCOL_ISO14443B 0x03
|
||||
#define PCD_PROTOCOL_FELICA 0x04
|
||||
#define PCD_PROTOCOL_ISO14443_SR 0x05
|
||||
#define PCD_PROTOCOL_TOPAZ 0x06
|
||||
|
||||
|
||||
/* RF transceiver Offset of the command and the response ---------------------------------- */
|
||||
#define PCD_COMMAND_OFFSET RFTRANS_95HF_COMMAND_OFFSET
|
||||
#define PCD_STATUS_OFFSET RFTRANS_95HF_COMMAND_OFFSET
|
||||
#define PCD_LENGTH_OFFSET RFTRANS_95HF_LENGTH_OFFSET
|
||||
#define PCD_DATA_OFFSET RFTRANS_95HF_DATA_OFFSET
|
||||
|
||||
/* Command parameter -------------------------------------------------------------------*/
|
||||
#define SEND_MASK_APPENDCRC 0x20
|
||||
#define SEND_MASK_DONTAPPENDCRC 0x00
|
||||
#define SEND_MASK_8BITSINFIRSTBYTE 0x08
|
||||
|
||||
#define PCD_TRANSPARENTCOMMAND_OFFSET 0x01
|
||||
|
||||
#define ECHOREPLY_OFFSET 0x00
|
||||
|
||||
#define PSEUDOREPLY_OFFSET 0x00
|
||||
#define PSEUDOREPLY_LENGTH 0x01
|
||||
|
||||
#define READERREPLY_STATUSOFFSET 0x00
|
||||
|
||||
#define IDN_RESULTSCODE_OK 0x00
|
||||
|
||||
/* protocol select status --------------------------------------------------------------------- */
|
||||
#define PROTOCOLSELECT_LENGTH 0x02
|
||||
#define PROTOCOLSELECT_RESULTSCODE_OK 0x00
|
||||
#define PROTOCOLSELECT_ERRORCODE_CMDLENGTH 0x82
|
||||
#define PROTOCOLSELECT_ERRORCODE_INVALID 0x83
|
||||
|
||||
/* baud rate command -------------------------------------------------------------------------- */
|
||||
#define BAUDRATE_LENGTH 0x01
|
||||
#define BAUDRATE_DATARATE_DEFAULT 57600
|
||||
|
||||
/* send receive field status ----------------------------------------------------------------- */
|
||||
#define SENDRECV_RESULTSCODE_OK 0x80
|
||||
#define SENDRECV_ERRORCODE_COMERROR 0x86
|
||||
#define SENDRECV_ERRORCODE_FRAMEWAIT 0x87
|
||||
#define SENDRECV_ERRORCODE_SOF 0x88
|
||||
#define SENDRECV_ERRORCODE_OVERFLOW 0x89
|
||||
#define SENDRECV_ERRORCODE_FRAMING 0x8A
|
||||
#define SENDRECV_ERRORCODE_EGT 0x8B
|
||||
#define SENDRECV_ERRORCODE_LENGTH 0x8C
|
||||
#define SENDRECV_ERRORCODE_CRC 0x8D
|
||||
#define SENDRECV_ERRORCODE_RECEPTIONLOST 0x8E
|
||||
#define SENDRECV_RESULTSRESIDUAL 0x90
|
||||
|
||||
#define PCD_ERRORCODE_NOTAGFOUND 0x87
|
||||
|
||||
#define SENDRECV_ERRORCODE_SOFT 0xFF
|
||||
|
||||
/* control byte according to protocol -------------------------------------------------------- */
|
||||
#define CONTROL_MAX_NBBYTE 0x03
|
||||
#define CONTROL_15693_NBBYTE 0x01
|
||||
#define CONTROL_15693_CRCMASK 0x02
|
||||
#define CONTROL_15693_COLISIONMASK 0x01
|
||||
|
||||
#define ISO14443A_NBBYTE 0x03
|
||||
#define ISO14443A_COLISIONMASK 0x80
|
||||
#define ISO14443A_CRCMASK 0x20
|
||||
#define ISO14443A_CRC_ERRORCODE_TYPEA 0x20
|
||||
#define ISO14443A_PARITYMASK 0x10
|
||||
#define ISO14443A_NBSIGNIFICANTBITMASK 0x0F
|
||||
#define ISO14443A_FIRSTCOLISIONBITMASK 0x0F
|
||||
|
||||
#define CONTROL_14443B_NBBYTE 0x01
|
||||
#define CONTROL_14443B_CRCMASK 0x02
|
||||
#define CONTROL_14443B_ERRORCODE 0x02
|
||||
#define CONTROL_14443B_COLISIONMASK 0x01
|
||||
|
||||
#define CONTROL_FELICA_NBBYTE 0x01
|
||||
#define CONTROL_FELICA_CRCMASK 0x02
|
||||
#define CONTROL_FELICA_COLISIONMASK 0x01
|
||||
|
||||
/* Command parameter -------------------------------------------------------------------*/
|
||||
#define PCD_ISO14443A_APPENDCRC 0x20
|
||||
#define PCD_ISO14443A_DONTAPPENDCRC 0x00
|
||||
#define PCD_ISO14443A_A8BITSINFIRSTBYTE 0x08
|
||||
|
||||
/* Speed parameters commom to ISO14443B protocols --------------------------------------*/
|
||||
#define PCD_ISO14443B_TRANSMISSION_SPEED_106K 0x00
|
||||
#define PCD_ISO14443B_TRANSMISSION_SPEED_212K 0x40
|
||||
#define PCD_ISO14443B_TRANSMISSION_SPEED_424K 0x80
|
||||
#define PCD_ISO14443B_TRANSMISSION_SPEED_848K 0xC0
|
||||
|
||||
#define PCD_ISO14443B_RECEPTION_SPEED_106K 0x00
|
||||
#define PCD_ISO14443B_RECEPTION_SPEED_212K 0x10
|
||||
#define PCD_ISO14443B_RECEPTION_SPEED_424K 0x20
|
||||
#define PCD_ISO14443B_RECEPTION_SPEED_848K 0x30
|
||||
|
||||
#define PCD_ISO14443B_APPEND_CRC 0x01
|
||||
|
||||
/* Error codes for Higher level */
|
||||
#define PCDNFC_OK RESULTOK
|
||||
#define PCDNFC_ERROR ERRORCODE_GENERIC
|
||||
#define PCDNFC_ERROR_MEMORY_TAG 2
|
||||
#define PCDNFC_ERROR_MEMORY_INTERNAL 3
|
||||
#define PCDNFC_ERROR_LOCKED 4
|
||||
#define PCDNFC_ERROR_NOT_FORMATED 5
|
||||
|
||||
|
||||
/* protocol selected for the reader -----------------------------------------------*/
|
||||
typedef enum {
|
||||
PCDPROTOCOL_UNKNOWN = 0,
|
||||
PCDPROTOCOL_14443A,
|
||||
PCDPROTOCOL_14443B,
|
||||
PCDPROTOCOL_18092,
|
||||
PCDPROTOCOL_15693,
|
||||
PCDPROTOCOL_NFCDEPA,
|
||||
PCDPROTOCOL_NFCDEPF
|
||||
}PCD_PROTOCOL;
|
||||
|
||||
|
||||
/* Functions ---------------------------------------------------------------- */
|
||||
int8_t PCD_IsReaderResultCodeOk(uint8_t CmdCode,const uint8_t *ReaderReply);
|
||||
int8_t PCD_IsCRCOk(const uint8_t Protocol , const uint8_t *pReaderReply);
|
||||
|
||||
int8_t PCD_CheckSendReceive(const uint8_t *pCommand, uint8_t *pResponse);
|
||||
|
||||
void PCD_FieldOff(void);
|
||||
void PCD_FieldOn(void);
|
||||
|
||||
int8_t PCD_IDN(uint8_t *pResponse);
|
||||
int8_t PCD_Echo(uint8_t *pResponse);
|
||||
int8_t PCD_SendEOF(uint8_t *pResponse);
|
||||
int8_t PCD_ProtocolSelect(const uint8_t Length,const uint8_t Protocol, const uint8_t *Parameters, uint8_t *pResponse);
|
||||
int8_t PCD_SendRecv(const uint8_t Length,const uint8_t *Parameters,uint8_t *pResponse);
|
||||
int8_t PCD_Idle(const uint8_t Length,const uint8_t *Data);
|
||||
int8_t PCD_ReadRegister(const uint8_t Length,const uint8_t Address,const uint8_t RegCount,const uint8_t Flags,uint8_t *pResponse);
|
||||
int8_t PCD_WriteRegister(const uint8_t Length,const uint8_t Address,const uint8_t Flags,const uint8_t *pData,uint8_t *pResponse);
|
||||
|
||||
int8_t PCD_PORsequence(void);
|
||||
void PCD_Receive_SPI_Response(uint8_t *pData);
|
||||
|
||||
int8_t PCD_TagDetectCalibration(const uint8_t Wuperiod,uint8_t *pDacDataH);
|
||||
int8_t PCD_WaitforTagDetection(uint8_t *WuSource, const uint8_t WuPeriod, const uint8_t DacDataH, const uint8_t NbTrials);
|
||||
|
||||
int8_t PCD_BaudRate(const uint8_t BaudRate,uint8_t *pResponse);
|
||||
int8_t PCD_ChangeUARTBaudRate(const uint8_t *pCommand, uint8_t *pResponse);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* _LIB_PCD_H */
|
||||
|
||||
/******************* (C) COPYRIGHT 2015 STMicroelectronics *****END OF FILE****/
|
||||
52
src/lib_wrapper.h
Normal file
52
src/lib_wrapper.h
Normal file
@@ -0,0 +1,52 @@
|
||||
/**
|
||||
******************************************************************************
|
||||
* @file lib_wrapper.h
|
||||
* @author MMY Application Team
|
||||
* @version $Revision: 1329 $
|
||||
* @date $Date: 2015-11-05 10:34:25 +0100 (Thu, 05 Nov 2015) $
|
||||
* @brief This file help to have upper layer independent from HW
|
||||
******************************************************************************
|
||||
* @attention
|
||||
*
|
||||
* <h2><center>© COPYRIGHT 2015 STMicroelectronics</center></h2>
|
||||
*
|
||||
* Licensed under ST MYLIBERTY SOFTWARE LICENSE AGREEMENT (the "License");
|
||||
* You may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at:
|
||||
*
|
||||
* http://www.st.com/myliberty
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied,
|
||||
* AND SPECIFICALLY DISCLAIMING THE IMPLIED WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE, AND NON-INFRINGEMENT.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
******************************************************************************
|
||||
*/
|
||||
|
||||
/* Define to prevent recursive inclusion -------------------------------------*/
|
||||
#ifndef __LIB_WRAPPER_H
|
||||
#define __LIB_WRAPPER_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/* Includes ------------------------------------------------------------------*/
|
||||
#include "common.h"
|
||||
|
||||
|
||||
uint16_t ReadData( uint16_t Offset, uint16_t DataSize, uint8_t* pData );
|
||||
uint16_t WriteData( uint16_t Offset, uint32_t DataSize, uint8_t* pData );
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* __LIB_WRAPPER_H */
|
||||
|
||||
|
||||
/******************* (C) COPYRIGHT 2015 STMicroelectronics *****END OF FILE****/
|
||||
76
src/miscellaneous.h
Normal file
76
src/miscellaneous.h
Normal file
@@ -0,0 +1,76 @@
|
||||
/**
|
||||
******************************************************************************
|
||||
* @file miscellaneous.h
|
||||
* @author MMY Application Team
|
||||
* @version $Revision: 1507 $
|
||||
* @date $Date: 2016-01-08 09:48:35 +0100 (Fri, 08 Jan 2016) $
|
||||
* @brief miscellaneaous functions
|
||||
******************************************************************************
|
||||
* @attention
|
||||
*
|
||||
* <h2><center>© COPYRIGHT 2016 STMicroelectronics</center></h2>
|
||||
*
|
||||
* Licensed under ST MYLIBERTY SOFTWARE LICENSE AGREEMENT (the "License");
|
||||
* You may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at:
|
||||
*
|
||||
* http://www.st.com/myliberty
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied,
|
||||
* AND SPECIFICALLY DISCLAIMING THE IMPLIED WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE, AND NON-INFRINGEMENT.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
******************************************************************************
|
||||
*/
|
||||
|
||||
#ifndef __MISCELLANEOUS_H
|
||||
#define __MISCELLANEOUS_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include "stdint.h"
|
||||
#include "stdbool.h"
|
||||
#include "string.h"
|
||||
|
||||
typedef uint32_t u32;
|
||||
typedef uint16_t u16;
|
||||
typedef uint8_t u8;
|
||||
|
||||
typedef const uint32_t uc32; /*!< Read Only */
|
||||
typedef const uint16_t uc16; /*!< Read Only */
|
||||
typedef const uint8_t uc8; /*!< Read Only */
|
||||
|
||||
|
||||
#define MAX(x,y) ((x > y)? x : y)
|
||||
#define MIN(x,y) ((x < y)? x : y)
|
||||
#define ABS(x) ((x)>0 ? (x) : -(x))
|
||||
#define CHECKVAL(val, min,max) ((val < min || val > max) ? false : true)
|
||||
|
||||
#define GETMSB(val) ((val & 0xFF00 )>>8 )
|
||||
#define GETLSB(val) ( val & 0x00FF )
|
||||
|
||||
#define RESULTOK 0x00
|
||||
#define ERRORCODE_GENERIC 1
|
||||
|
||||
#ifndef errchk
|
||||
#define errchk(fCall) if (status = (fCall), status != RESULTOK) \
|
||||
{goto Error;} else
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* __MISCELLANEOUS_H */
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/******************* (C) COPYRIGHT 2016 STMicroelectronics *****END OF FILE****/
|
||||
Reference in New Issue
Block a user