NFC NDEF library

Dependents:   Nucleo_NFC_Example I2C_NFC_Master Print_Entire_Nucleo_NFC01A1_Memory

Fork of lib_NDEF by Enrico Gregoratto

Committer:
EnricoG
Date:
Mon Dec 15 19:41:36 2014 +0000
Revision:
0:3b093bd0819e
Initial commit

Who changed what in which revision?

UserRevisionLine numberNew contents of line
EnricoG 0:3b093bd0819e 1 /**
EnricoG 0:3b093bd0819e 2 ******************************************************************************
EnricoG 0:3b093bd0819e 3 * @file lib_NDEF.c
EnricoG 0:3b093bd0819e 4 * @author MMY Application Team
EnricoG 0:3b093bd0819e 5 * @version V1.0.0
EnricoG 0:3b093bd0819e 6 * @date 20-November-2013
EnricoG 0:3b093bd0819e 7 * @brief This file help to manage NDEF file, to parse and identify them.
EnricoG 0:3b093bd0819e 8 ******************************************************************************
EnricoG 0:3b093bd0819e 9 * @attention
EnricoG 0:3b093bd0819e 10 *
EnricoG 0:3b093bd0819e 11 * <h2><center>&copy; COPYRIGHT 2014 STMicroelectronics</center></h2>
EnricoG 0:3b093bd0819e 12 *
EnricoG 0:3b093bd0819e 13 * Licensed under MMY-ST Liberty SW License Agreement V2, (the "License");
EnricoG 0:3b093bd0819e 14 * You may not use this file except in compliance with the License.
EnricoG 0:3b093bd0819e 15 * You may obtain a copy of the License at:
EnricoG 0:3b093bd0819e 16 *
EnricoG 0:3b093bd0819e 17 * http://www.st.com/software_license_agreement_liberty_v2
EnricoG 0:3b093bd0819e 18 *
EnricoG 0:3b093bd0819e 19 * Unless required by applicable law or agreed to in writing, software
EnricoG 0:3b093bd0819e 20 * distributed under the License is distributed on an "AS IS" BASIS,
EnricoG 0:3b093bd0819e 21 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
EnricoG 0:3b093bd0819e 22 * See the License for the specific language governing permissions and
EnricoG 0:3b093bd0819e 23 * limitations under the License.
EnricoG 0:3b093bd0819e 24 *
EnricoG 0:3b093bd0819e 25 ******************************************************************************
EnricoG 0:3b093bd0819e 26 */
EnricoG 0:3b093bd0819e 27
EnricoG 0:3b093bd0819e 28 /* Includes ------------------------------------------------------------------*/
EnricoG 0:3b093bd0819e 29 #include "lib_NDEF.h"
EnricoG 0:3b093bd0819e 30
EnricoG 0:3b093bd0819e 31 /** @addtogroup NFC_libraries
EnricoG 0:3b093bd0819e 32 * @{
EnricoG 0:3b093bd0819e 33 * @brief <b>This is the library used to manage the content of the TAG (data)
EnricoG 0:3b093bd0819e 34 * But also the specific feature of the tag, for instance
EnricoG 0:3b093bd0819e 35 * password, gpo... </b>
EnricoG 0:3b093bd0819e 36 */
EnricoG 0:3b093bd0819e 37
EnricoG 0:3b093bd0819e 38
EnricoG 0:3b093bd0819e 39 /** @addtogroup libNFC_FORUM
EnricoG 0:3b093bd0819e 40 * @{
EnricoG 0:3b093bd0819e 41 * @brief This part of the library manage data which follow NFC forum organisation.
EnricoG 0:3b093bd0819e 42 */
EnricoG 0:3b093bd0819e 43
EnricoG 0:3b093bd0819e 44 /** @defgroup libNDEF_Private_Functions
EnricoG 0:3b093bd0819e 45 * @{
EnricoG 0:3b093bd0819e 46 */
EnricoG 0:3b093bd0819e 47
EnricoG 0:3b093bd0819e 48
EnricoG 0:3b093bd0819e 49 static uint16_t NDEF_IsNDEFPresent ( void );
EnricoG 0:3b093bd0819e 50 static uint16_t NDEF_ParseRecordHeader ( sRecordInfo *pRecordStruct );
EnricoG 0:3b093bd0819e 51 static void NDEF_ParseWellKnownType ( sRecordInfo *pRecordStruct );
EnricoG 0:3b093bd0819e 52 static void NDEF_ParseMediaType ( sRecordInfo *pRecordStruct );
EnricoG 0:3b093bd0819e 53 static void NDEF_ParseForumExternalType ( sRecordInfo *pRecordStruct );
EnricoG 0:3b093bd0819e 54 static void NDEF_ParseURI(sRecordInfo *pRecordStruct);
EnricoG 0:3b093bd0819e 55 static void NDEF_ParseSP(sRecordInfo *pRecordStruct);
EnricoG 0:3b093bd0819e 56 static uint16_t NDEF_IdentifySPRecord ( sRecordInfo *pRecordStruct, uint8_t* pPayload );
EnricoG 0:3b093bd0819e 57
EnricoG 0:3b093bd0819e 58 /* In case of smart Poster composed with different record, 3 records supported so far */
EnricoG 0:3b093bd0819e 59 sRecordInfo SPRecordStruct1, SPRecordStruct2, SPRecordStruct3;
EnricoG 0:3b093bd0819e 60 uint32_t SPRecordStructAdd[SP_MAX_RECORD] = { (uint32_t)&SPRecordStruct1, (uint32_t)&SPRecordStruct2, (uint32_t)&SPRecordStruct3 };
EnricoG 0:3b093bd0819e 61
EnricoG 0:3b093bd0819e 62 /**
EnricoG 0:3b093bd0819e 63 * @brief This fonction check that the tag contain a NDEF message
EnricoG 0:3b093bd0819e 64 * @param None :
EnricoG 0:3b093bd0819e 65 * @retval SUCCESS : There is a NDEF file stored in tag
EnricoG 0:3b093bd0819e 66 * @retval ERROR : No NDEF in the tag.
EnricoG 0:3b093bd0819e 67 */
EnricoG 0:3b093bd0819e 68 static uint16_t NDEF_IsNDEFPresent ( void )
EnricoG 0:3b093bd0819e 69 {
EnricoG 0:3b093bd0819e 70 uint16_t FileSize;
EnricoG 0:3b093bd0819e 71 uint8_t uM24SR_NDEFHeader [0x2];
EnricoG 0:3b093bd0819e 72
EnricoG 0:3b093bd0819e 73 /* Check NDEF existence */
EnricoG 0:3b093bd0819e 74 ReadData ( NDEF_SIZE_OFFSET , 2 , uM24SR_NDEFHeader);
EnricoG 0:3b093bd0819e 75 FileSize = (uint16_t) ((uM24SR_NDEFHeader[0x00]<<8) | uM24SR_NDEFHeader[0x01]);
EnricoG 0:3b093bd0819e 76
EnricoG 0:3b093bd0819e 77 if( FileSize != 0)
EnricoG 0:3b093bd0819e 78 return SUCCESS;
EnricoG 0:3b093bd0819e 79 else
EnricoG 0:3b093bd0819e 80 return ERROR;
EnricoG 0:3b093bd0819e 81 }
EnricoG 0:3b093bd0819e 82
EnricoG 0:3b093bd0819e 83 /**
EnricoG 0:3b093bd0819e 84 * @brief This fonction identify the type of record
EnricoG 0:3b093bd0819e 85 * @param pRecordStruct : pointer on the record structure to fill
EnricoG 0:3b093bd0819e 86 * @param pPayload : pointer on the payload
EnricoG 0:3b093bd0819e 87 * @retval Status : Status of the operation.
EnricoG 0:3b093bd0819e 88 */
EnricoG 0:3b093bd0819e 89 static uint16_t NDEF_IdentifySPRecord ( sRecordInfo *pRecordStruct, uint8_t* pPayload )
EnricoG 0:3b093bd0819e 90 {
EnricoG 0:3b093bd0819e 91 uint16_t status = ERROR;
EnricoG 0:3b093bd0819e 92 uint16_t SizeOfRecordHeader, TypeNbByte, PayloadLengthField, IDLengthField, IDNbByte;
EnricoG 0:3b093bd0819e 93
EnricoG 0:3b093bd0819e 94 /* Is ID length field present */
EnricoG 0:3b093bd0819e 95 if( (*pPayload)&IL_Mask)
EnricoG 0:3b093bd0819e 96 {
EnricoG 0:3b093bd0819e 97 IDLengthField = ID_LENGTH_FIELD;
EnricoG 0:3b093bd0819e 98 }
EnricoG 0:3b093bd0819e 99 else
EnricoG 0:3b093bd0819e 100 {
EnricoG 0:3b093bd0819e 101 IDLengthField = 0;
EnricoG 0:3b093bd0819e 102 }
EnricoG 0:3b093bd0819e 103
EnricoG 0:3b093bd0819e 104 /* it's a SR */
EnricoG 0:3b093bd0819e 105 if( (*pPayload)&SR_Mask)
EnricoG 0:3b093bd0819e 106 {
EnricoG 0:3b093bd0819e 107 TypeNbByte = pPayload[1];
EnricoG 0:3b093bd0819e 108 PayloadLengthField = 1;
EnricoG 0:3b093bd0819e 109 if( IDLengthField == ID_LENGTH_FIELD)
EnricoG 0:3b093bd0819e 110 IDNbByte = pPayload[3];
EnricoG 0:3b093bd0819e 111 else
EnricoG 0:3b093bd0819e 112 IDNbByte = 0;
EnricoG 0:3b093bd0819e 113 }
EnricoG 0:3b093bd0819e 114 else
EnricoG 0:3b093bd0819e 115 {
EnricoG 0:3b093bd0819e 116 TypeNbByte = pPayload[1];
EnricoG 0:3b093bd0819e 117 PayloadLengthField = 4;
EnricoG 0:3b093bd0819e 118 if( IDLengthField == ID_LENGTH_FIELD)
EnricoG 0:3b093bd0819e 119 IDNbByte = pPayload[6];
EnricoG 0:3b093bd0819e 120 else
EnricoG 0:3b093bd0819e 121 IDNbByte = 0;
EnricoG 0:3b093bd0819e 122 }
EnricoG 0:3b093bd0819e 123
EnricoG 0:3b093bd0819e 124 SizeOfRecordHeader = RECORD_FLAG_FIELD + TYPE_LENGTH_FIELD + PayloadLengthField + IDLengthField + TypeNbByte + IDNbByte;
EnricoG 0:3b093bd0819e 125
EnricoG 0:3b093bd0819e 126 /* it's a SR */
EnricoG 0:3b093bd0819e 127 if( pPayload[0]&SR_Mask)
EnricoG 0:3b093bd0819e 128 {
EnricoG 0:3b093bd0819e 129 pRecordStruct->RecordFlags = pPayload[0];
EnricoG 0:3b093bd0819e 130 pRecordStruct->TypeLength = TypeNbByte;
EnricoG 0:3b093bd0819e 131 pRecordStruct->PayloadLength3 = 0;
EnricoG 0:3b093bd0819e 132 pRecordStruct->PayloadLength2 = 0;
EnricoG 0:3b093bd0819e 133 pRecordStruct->PayloadLength1 = 0;
EnricoG 0:3b093bd0819e 134 pRecordStruct->PayloadLength0 = pPayload[2];
EnricoG 0:3b093bd0819e 135 pRecordStruct->IDLength = IDNbByte;
EnricoG 0:3b093bd0819e 136 memcpy(pRecordStruct->Type, &pPayload[3+IDNbByte] , TypeNbByte);
EnricoG 0:3b093bd0819e 137 memcpy(pRecordStruct->ID, &pPayload[3+IDNbByte+TypeNbByte] , IDNbByte);
EnricoG 0:3b093bd0819e 138 pRecordStruct->PayloadOffset = SizeOfRecordHeader;
EnricoG 0:3b093bd0819e 139 }
EnricoG 0:3b093bd0819e 140 else
EnricoG 0:3b093bd0819e 141 {
EnricoG 0:3b093bd0819e 142 pRecordStruct->RecordFlags = pPayload[0];
EnricoG 0:3b093bd0819e 143 pRecordStruct->TypeLength = TypeNbByte;
EnricoG 0:3b093bd0819e 144 pRecordStruct->PayloadLength3 = pPayload[2];
EnricoG 0:3b093bd0819e 145 pRecordStruct->PayloadLength2 = pPayload[3];
EnricoG 0:3b093bd0819e 146 pRecordStruct->PayloadLength1 = pPayload[4];
EnricoG 0:3b093bd0819e 147 pRecordStruct->PayloadLength0 = pPayload[5];
EnricoG 0:3b093bd0819e 148 pRecordStruct->IDLength = IDNbByte;
EnricoG 0:3b093bd0819e 149 memcpy(pRecordStruct->Type, &pPayload[6+IDNbByte] , TypeNbByte);
EnricoG 0:3b093bd0819e 150 memcpy(pRecordStruct->ID, &pPayload[6+IDNbByte+TypeNbByte] , IDNbByte);
EnricoG 0:3b093bd0819e 151 pRecordStruct->PayloadOffset = SizeOfRecordHeader;
EnricoG 0:3b093bd0819e 152 }
EnricoG 0:3b093bd0819e 153
EnricoG 0:3b093bd0819e 154 pRecordStruct->PayloadBufferAdd = (uint32_t)(pPayload+SizeOfRecordHeader);
EnricoG 0:3b093bd0819e 155
EnricoG 0:3b093bd0819e 156 status = NDEF_ParseRecordHeader(pRecordStruct);
EnricoG 0:3b093bd0819e 157
EnricoG 0:3b093bd0819e 158 return status;
EnricoG 0:3b093bd0819e 159 }
EnricoG 0:3b093bd0819e 160
EnricoG 0:3b093bd0819e 161 /**
EnricoG 0:3b093bd0819e 162 * @brief This fonction parse the record header and dispatch regarding TNF value
EnricoG 0:3b093bd0819e 163 * @param pRecordStruct : pointer on the record structure to fill
EnricoG 0:3b093bd0819e 164 * @retval SUCCESS : record identified and structure filled
EnricoG 0:3b093bd0819e 165 * @retval ERROR : Not supported
EnricoG 0:3b093bd0819e 166 */
EnricoG 0:3b093bd0819e 167 static uint16_t NDEF_ParseRecordHeader ( sRecordInfo *pRecordStruct )
EnricoG 0:3b093bd0819e 168 {
EnricoG 0:3b093bd0819e 169 uint16_t status = SUCCESS;
EnricoG 0:3b093bd0819e 170
EnricoG 0:3b093bd0819e 171 switch( (pRecordStruct->RecordFlags&TNF_Mask))
EnricoG 0:3b093bd0819e 172 {
EnricoG 0:3b093bd0819e 173 case TNF_WellKnown:
EnricoG 0:3b093bd0819e 174 NDEF_ParseWellKnownType ( pRecordStruct );
EnricoG 0:3b093bd0819e 175 break;
EnricoG 0:3b093bd0819e 176
EnricoG 0:3b093bd0819e 177 case TNF_MediaType:
EnricoG 0:3b093bd0819e 178 NDEF_ParseMediaType ( pRecordStruct );
EnricoG 0:3b093bd0819e 179 break;
EnricoG 0:3b093bd0819e 180
EnricoG 0:3b093bd0819e 181 case TNF_NFCForumExternal:
EnricoG 0:3b093bd0819e 182 NDEF_ParseForumExternalType ( pRecordStruct);
EnricoG 0:3b093bd0819e 183 break;
EnricoG 0:3b093bd0819e 184
EnricoG 0:3b093bd0819e 185 default:
EnricoG 0:3b093bd0819e 186 /* currently not supported or unknown*/
EnricoG 0:3b093bd0819e 187 pRecordStruct->NDEF_Type = UNKNOWN_TYPE;
EnricoG 0:3b093bd0819e 188 status = ERROR;
EnricoG 0:3b093bd0819e 189 }
EnricoG 0:3b093bd0819e 190 return status;
EnricoG 0:3b093bd0819e 191 }
EnricoG 0:3b093bd0819e 192
EnricoG 0:3b093bd0819e 193 /**
EnricoG 0:3b093bd0819e 194 * @brief This fonction parse the Well Known type record
EnricoG 0:3b093bd0819e 195 * @param pRecordStruct : pointer on the record structure to fill
EnricoG 0:3b093bd0819e 196 * @retval None
EnricoG 0:3b093bd0819e 197 */
EnricoG 0:3b093bd0819e 198 static void NDEF_ParseWellKnownType ( sRecordInfo *pRecordStruct )
EnricoG 0:3b093bd0819e 199 {
EnricoG 0:3b093bd0819e 200 uint8_t* pPayload;
EnricoG 0:3b093bd0819e 201
EnricoG 0:3b093bd0819e 202 pPayload = (uint8_t*)(pRecordStruct->PayloadBufferAdd);
EnricoG 0:3b093bd0819e 203
EnricoG 0:3b093bd0819e 204 if( !memcmp( &(pRecordStruct->Type), SMART_POSTER_TYPE_STRING, pRecordStruct->TypeLength))
EnricoG 0:3b093bd0819e 205 {
EnricoG 0:3b093bd0819e 206 /* special case where we have to parse others records */
EnricoG 0:3b093bd0819e 207 pRecordStruct->NDEF_Type = SMARTPOSTER_TYPE;
EnricoG 0:3b093bd0819e 208 NDEF_ParseSP(pRecordStruct);
EnricoG 0:3b093bd0819e 209 }
EnricoG 0:3b093bd0819e 210
EnricoG 0:3b093bd0819e 211 else if( !memcmp( &(pRecordStruct->Type), URI_TYPE_STRING, pRecordStruct->TypeLength))
EnricoG 0:3b093bd0819e 212 {
EnricoG 0:3b093bd0819e 213 /* it's an URI Type check if it's an URL or SMS or ... */
EnricoG 0:3b093bd0819e 214 /* check identifier */
EnricoG 0:3b093bd0819e 215 if( *pPayload == URI_ID_0x00)
EnricoG 0:3b093bd0819e 216 {
EnricoG 0:3b093bd0819e 217 NDEF_ParseURI(pRecordStruct);
EnricoG 0:3b093bd0819e 218 }
EnricoG 0:3b093bd0819e 219 else if ( *pPayload > URI_ID_0x00 && *pPayload < URI_RFU )
EnricoG 0:3b093bd0819e 220 {
EnricoG 0:3b093bd0819e 221 /* email special case */
EnricoG 0:3b093bd0819e 222 if ( *pPayload == (uint8_t) URI_ID_0x06)
EnricoG 0:3b093bd0819e 223 {
EnricoG 0:3b093bd0819e 224 pRecordStruct->NDEF_Type = URI_EMAIL_TYPE;
EnricoG 0:3b093bd0819e 225 }
EnricoG 0:3b093bd0819e 226 else
EnricoG 0:3b093bd0819e 227 {
EnricoG 0:3b093bd0819e 228 pRecordStruct->NDEF_Type = WELL_KNOWN_ABRIDGED_URI_TYPE;
EnricoG 0:3b093bd0819e 229 }
EnricoG 0:3b093bd0819e 230 }
EnricoG 0:3b093bd0819e 231 else
EnricoG 0:3b093bd0819e 232 {
EnricoG 0:3b093bd0819e 233 pRecordStruct->NDEF_Type = UNKNOWN_TYPE;
EnricoG 0:3b093bd0819e 234 }
EnricoG 0:3b093bd0819e 235 }
EnricoG 0:3b093bd0819e 236
EnricoG 0:3b093bd0819e 237 else if( !memcmp( &(pRecordStruct->Type), TEXT_TYPE_STRING, pRecordStruct->TypeLength))
EnricoG 0:3b093bd0819e 238 {
EnricoG 0:3b093bd0819e 239 pRecordStruct->NDEF_Type = TEXT_TYPE;
EnricoG 0:3b093bd0819e 240 }
EnricoG 0:3b093bd0819e 241 else
EnricoG 0:3b093bd0819e 242 pRecordStruct->NDEF_Type = UNKNOWN_TYPE;
EnricoG 0:3b093bd0819e 243
EnricoG 0:3b093bd0819e 244 }
EnricoG 0:3b093bd0819e 245
EnricoG 0:3b093bd0819e 246 /**
EnricoG 0:3b093bd0819e 247 * @brief This fonction parse the Media type record
EnricoG 0:3b093bd0819e 248 * @param pRecordStruct : pointer on the record structure to fill
EnricoG 0:3b093bd0819e 249 * @retval None
EnricoG 0:3b093bd0819e 250 */
EnricoG 0:3b093bd0819e 251 static void NDEF_ParseMediaType ( sRecordInfo *pRecordStruct )
EnricoG 0:3b093bd0819e 252 {
EnricoG 0:3b093bd0819e 253 if( !memcmp( &(pRecordStruct->Type), VCARD_TYPE_STRING, pRecordStruct->TypeLength))
EnricoG 0:3b093bd0819e 254 pRecordStruct->NDEF_Type = VCARD_TYPE;
EnricoG 0:3b093bd0819e 255 else if( !memcmp( &(pRecordStruct->Type), XVCARD_TYPE_STRING, pRecordStruct->TypeLength))
EnricoG 0:3b093bd0819e 256 pRecordStruct->NDEF_Type = VCARD_TYPE;
EnricoG 0:3b093bd0819e 257 else
EnricoG 0:3b093bd0819e 258 pRecordStruct->NDEF_Type = UNKNOWN_TYPE;
EnricoG 0:3b093bd0819e 259 }
EnricoG 0:3b093bd0819e 260
EnricoG 0:3b093bd0819e 261 /**
EnricoG 0:3b093bd0819e 262 * @brief This fonction parse the Forum External type record
EnricoG 0:3b093bd0819e 263 * @param pRecordStruct : pointer on the record structure to fill
EnricoG 0:3b093bd0819e 264 * @retval None
EnricoG 0:3b093bd0819e 265 */
EnricoG 0:3b093bd0819e 266 static void NDEF_ParseForumExternalType ( sRecordInfo *pRecordStruct )
EnricoG 0:3b093bd0819e 267 {
EnricoG 0:3b093bd0819e 268 if( !memcmp( &(pRecordStruct->Type), M24SR_DISCOVERY_APP_STRING, pRecordStruct->TypeLength))
EnricoG 0:3b093bd0819e 269 pRecordStruct->NDEF_Type = M24SR_DISCOVERY_APP_TYPE;
EnricoG 0:3b093bd0819e 270 else
EnricoG 0:3b093bd0819e 271 pRecordStruct->NDEF_Type = UNKNOWN_TYPE;
EnricoG 0:3b093bd0819e 272 }
EnricoG 0:3b093bd0819e 273
EnricoG 0:3b093bd0819e 274 /**
EnricoG 0:3b093bd0819e 275 * @brief This fonction parse the URI type record
EnricoG 0:3b093bd0819e 276 * @param pRecordStruct : pointer on the record structure to fill
EnricoG 0:3b093bd0819e 277 * @retval None
EnricoG 0:3b093bd0819e 278 */
EnricoG 0:3b093bd0819e 279 static void NDEF_ParseURI(sRecordInfo *pRecordStruct)
EnricoG 0:3b093bd0819e 280 {
EnricoG 0:3b093bd0819e 281 uint8_t* pPayload;
EnricoG 0:3b093bd0819e 282
EnricoG 0:3b093bd0819e 283 pPayload = (uint8_t*)(pRecordStruct->PayloadBufferAdd);
EnricoG 0:3b093bd0819e 284 pPayload ++; /* to skip URI identifier first URI payload byte */
EnricoG 0:3b093bd0819e 285
EnricoG 0:3b093bd0819e 286 if( !memcmp( pPayload, SMS_TYPE_STRING, strlen(SMS_TYPE_STRING)) )
EnricoG 0:3b093bd0819e 287 {
EnricoG 0:3b093bd0819e 288 pRecordStruct->NDEF_Type = URI_SMS_TYPE;
EnricoG 0:3b093bd0819e 289 }
EnricoG 0:3b093bd0819e 290 else if( !memcmp( pPayload, GEO_TYPE_STRING, strlen(GEO_TYPE_STRING)) )
EnricoG 0:3b093bd0819e 291 {
EnricoG 0:3b093bd0819e 292 pRecordStruct->NDEF_Type = URI_GEO_TYPE;
EnricoG 0:3b093bd0819e 293 }
EnricoG 0:3b093bd0819e 294 else
EnricoG 0:3b093bd0819e 295 pRecordStruct->NDEF_Type = UNKNOWN_TYPE;
EnricoG 0:3b093bd0819e 296
EnricoG 0:3b093bd0819e 297 }
EnricoG 0:3b093bd0819e 298
EnricoG 0:3b093bd0819e 299 /**
EnricoG 0:3b093bd0819e 300 * @brief This fonction parse the Smart Poster
EnricoG 0:3b093bd0819e 301 * @param pRecordStruct : pointer on the record structure to fill
EnricoG 0:3b093bd0819e 302 * @retval None
EnricoG 0:3b093bd0819e 303 */
EnricoG 0:3b093bd0819e 304 static void NDEF_ParseSP(sRecordInfo *pRecordStruct)
EnricoG 0:3b093bd0819e 305 {
EnricoG 0:3b093bd0819e 306 uint8_t* pPayload;
EnricoG 0:3b093bd0819e 307 uint32_t PayloadSize = 0;
EnricoG 0:3b093bd0819e 308 uint32_t SPPayloadSize = 0;
EnricoG 0:3b093bd0819e 309 uint32_t OffsetInSPPayload =0;
EnricoG 0:3b093bd0819e 310 uint32_t RecordPosition = 0;
EnricoG 0:3b093bd0819e 311 sRecordInfo *pSPRecordStruct;
EnricoG 0:3b093bd0819e 312
EnricoG 0:3b093bd0819e 313 /* initialize variable with size of the payload and poiter on data */
EnricoG 0:3b093bd0819e 314 PayloadSize = ((uint32_t)(pRecordStruct->PayloadLength3)<<24) | ((uint32_t)(pRecordStruct->PayloadLength2)<<16) |
EnricoG 0:3b093bd0819e 315 ((uint32_t)(pRecordStruct->PayloadLength1)<<8) | pRecordStruct->PayloadLength0;
EnricoG 0:3b093bd0819e 316
EnricoG 0:3b093bd0819e 317 pPayload = (uint8_t*)(pRecordStruct->PayloadBufferAdd);
EnricoG 0:3b093bd0819e 318
EnricoG 0:3b093bd0819e 319 pSPRecordStruct = (sRecordInfo *)SPRecordStructAdd[0];
EnricoG 0:3b093bd0819e 320
EnricoG 0:3b093bd0819e 321 /* Initailize the number of record find in the SP payload */
EnricoG 0:3b093bd0819e 322 pRecordStruct->NbOfRecordInSPPayload = 0;
EnricoG 0:3b093bd0819e 323
EnricoG 0:3b093bd0819e 324 do
EnricoG 0:3b093bd0819e 325 {
EnricoG 0:3b093bd0819e 326 pSPRecordStruct = (sRecordInfo *)SPRecordStructAdd[RecordPosition];
EnricoG 0:3b093bd0819e 327 /* identify the 1st record in the SP payload */
EnricoG 0:3b093bd0819e 328 if( NDEF_IdentifySPRecord ( pSPRecordStruct, pPayload ))
EnricoG 0:3b093bd0819e 329 {
EnricoG 0:3b093bd0819e 330 /* store add of structure that will contain the other record information */
EnricoG 0:3b093bd0819e 331 pRecordStruct->NbOfRecordInSPPayload ++;
EnricoG 0:3b093bd0819e 332 pRecordStruct->SPRecordStructAdd[RecordPosition] = (uint32_t) pSPRecordStruct;
EnricoG 0:3b093bd0819e 333
EnricoG 0:3b093bd0819e 334 /* After SPRecord + First Record check if we are at the end of NDEF file */
EnricoG 0:3b093bd0819e 335 SPPayloadSize = ((uint32_t)(pSPRecordStruct->PayloadLength3)<<24) | ((uint32_t)(pSPRecordStruct->PayloadLength2)<<16) |
EnricoG 0:3b093bd0819e 336 ((uint32_t)(pSPRecordStruct->PayloadLength1)<<8) | pSPRecordStruct->PayloadLength0;
EnricoG 0:3b093bd0819e 337
EnricoG 0:3b093bd0819e 338 OffsetInSPPayload += pSPRecordStruct->PayloadOffset + SPPayloadSize;
EnricoG 0:3b093bd0819e 339 pPayload += OffsetInSPPayload;
EnricoG 0:3b093bd0819e 340 RecordPosition++;
EnricoG 0:3b093bd0819e 341 }
EnricoG 0:3b093bd0819e 342 }
EnricoG 0:3b093bd0819e 343 while( OffsetInSPPayload < PayloadSize && RecordPosition<SP_MAX_RECORD); /* there is another record */
EnricoG 0:3b093bd0819e 344
EnricoG 0:3b093bd0819e 345 }
EnricoG 0:3b093bd0819e 346
EnricoG 0:3b093bd0819e 347 /**
EnricoG 0:3b093bd0819e 348 * @}
EnricoG 0:3b093bd0819e 349 */
EnricoG 0:3b093bd0819e 350
EnricoG 0:3b093bd0819e 351 /** @defgroup libNDEF_Public_Functions
EnricoG 0:3b093bd0819e 352 * @{
EnricoG 0:3b093bd0819e 353 */
EnricoG 0:3b093bd0819e 354
EnricoG 0:3b093bd0819e 355
EnricoG 0:3b093bd0819e 356 /**
EnricoG 0:3b093bd0819e 357 * @brief This fonction identify the NDEF message stored in tag
EnricoG 0:3b093bd0819e 358 * @param pRecordStruct : Structure to fill with record information
EnricoG 0:3b093bd0819e 359 * @param pNDEF : pointer on the NDEF message data
EnricoG 0:3b093bd0819e 360 * @retval SUCCESS : record struct filled
EnricoG 0:3b093bd0819e 361 * @retval ERROR : record struct not updated
EnricoG 0:3b093bd0819e 362 */
EnricoG 0:3b093bd0819e 363
EnricoG 0:3b093bd0819e 364 uint16_t NDEF_IdentifyNDEF ( sRecordInfo *pRecordStruct, uint8_t* pNDEF )
EnricoG 0:3b093bd0819e 365 {
EnricoG 0:3b093bd0819e 366 uint16_t status = ERROR;
EnricoG 0:3b093bd0819e 367 uint16_t SizeOfRecordHeader, TypeNbByte, PayloadLengthField, IDLengthField, IDNbByte;
EnricoG 0:3b093bd0819e 368 uint32_t PayloadSize;
EnricoG 0:3b093bd0819e 369
EnricoG 0:3b093bd0819e 370 /* check NDEF present */
EnricoG 0:3b093bd0819e 371 if(NDEF_IsNDEFPresent() != SUCCESS)
EnricoG 0:3b093bd0819e 372 {
EnricoG 0:3b093bd0819e 373 return ERROR;
EnricoG 0:3b093bd0819e 374 }
EnricoG 0:3b093bd0819e 375
EnricoG 0:3b093bd0819e 376 /* Analyse record layout */
EnricoG 0:3b093bd0819e 377 ReadData ( FIRST_RECORD_OFFSET , 1 , pNDEF);
EnricoG 0:3b093bd0819e 378
EnricoG 0:3b093bd0819e 379 /* Is ID length field present */
EnricoG 0:3b093bd0819e 380 if( (*pNDEF)&IL_Mask)
EnricoG 0:3b093bd0819e 381 {
EnricoG 0:3b093bd0819e 382 IDLengthField = ID_LENGTH_FIELD;
EnricoG 0:3b093bd0819e 383 }
EnricoG 0:3b093bd0819e 384 else
EnricoG 0:3b093bd0819e 385 {
EnricoG 0:3b093bd0819e 386 IDLengthField = 0;
EnricoG 0:3b093bd0819e 387 }
EnricoG 0:3b093bd0819e 388
EnricoG 0:3b093bd0819e 389 /* it's a SR */
EnricoG 0:3b093bd0819e 390 if( (*pNDEF)&SR_Mask)
EnricoG 0:3b093bd0819e 391 {
EnricoG 0:3b093bd0819e 392 /* Analyse short record layout */
EnricoG 0:3b093bd0819e 393 ReadData ( FIRST_RECORD_OFFSET , 4 , pNDEF);
EnricoG 0:3b093bd0819e 394 TypeNbByte = pNDEF[1];
EnricoG 0:3b093bd0819e 395 PayloadLengthField = 1;
EnricoG 0:3b093bd0819e 396 if( IDLengthField == ID_LENGTH_FIELD)
EnricoG 0:3b093bd0819e 397 IDNbByte = pNDEF[3];
EnricoG 0:3b093bd0819e 398 else
EnricoG 0:3b093bd0819e 399 IDNbByte = 0;
EnricoG 0:3b093bd0819e 400 }
EnricoG 0:3b093bd0819e 401 else
EnricoG 0:3b093bd0819e 402 {
EnricoG 0:3b093bd0819e 403 /* Analyse normal record layout */
EnricoG 0:3b093bd0819e 404 ReadData ( FIRST_RECORD_OFFSET , 7 , pNDEF);
EnricoG 0:3b093bd0819e 405 TypeNbByte = pNDEF[1];
EnricoG 0:3b093bd0819e 406 PayloadLengthField = 4;
EnricoG 0:3b093bd0819e 407 if( IDLengthField == ID_LENGTH_FIELD)
EnricoG 0:3b093bd0819e 408 IDNbByte = pNDEF[6];
EnricoG 0:3b093bd0819e 409 else
EnricoG 0:3b093bd0819e 410 IDNbByte = 0;
EnricoG 0:3b093bd0819e 411 }
EnricoG 0:3b093bd0819e 412
EnricoG 0:3b093bd0819e 413 SizeOfRecordHeader = RECORD_FLAG_FIELD + TYPE_LENGTH_FIELD + PayloadLengthField + IDLengthField + TypeNbByte + IDNbByte;
EnricoG 0:3b093bd0819e 414
EnricoG 0:3b093bd0819e 415 /* Read record header */
EnricoG 0:3b093bd0819e 416 ReadData ( FIRST_RECORD_OFFSET , SizeOfRecordHeader , pNDEF);
EnricoG 0:3b093bd0819e 417 /* it's a SR */
EnricoG 0:3b093bd0819e 418 if( pNDEF[0]&SR_Mask)
EnricoG 0:3b093bd0819e 419 {
EnricoG 0:3b093bd0819e 420 pRecordStruct->RecordFlags = pNDEF[0];
EnricoG 0:3b093bd0819e 421 pRecordStruct->TypeLength = TypeNbByte;
EnricoG 0:3b093bd0819e 422 pRecordStruct->PayloadLength3 = 0;
EnricoG 0:3b093bd0819e 423 pRecordStruct->PayloadLength2 = 0;
EnricoG 0:3b093bd0819e 424 pRecordStruct->PayloadLength1 = 0;
EnricoG 0:3b093bd0819e 425 pRecordStruct->PayloadLength0 = pNDEF[2];
EnricoG 0:3b093bd0819e 426 pRecordStruct->IDLength = IDNbByte;
EnricoG 0:3b093bd0819e 427 memcpy(pRecordStruct->Type, &pNDEF[3+IDNbByte] , TypeNbByte);
EnricoG 0:3b093bd0819e 428 memcpy(pRecordStruct->ID, &pNDEF[3+IDNbByte+TypeNbByte] , IDNbByte);
EnricoG 0:3b093bd0819e 429 pRecordStruct->PayloadOffset = SizeOfRecordHeader;
EnricoG 0:3b093bd0819e 430 }
EnricoG 0:3b093bd0819e 431 else
EnricoG 0:3b093bd0819e 432 {
EnricoG 0:3b093bd0819e 433 pRecordStruct->RecordFlags = pNDEF[0];
EnricoG 0:3b093bd0819e 434 pRecordStruct->TypeLength = TypeNbByte;
EnricoG 0:3b093bd0819e 435 pRecordStruct->PayloadLength3 = pNDEF[2];
EnricoG 0:3b093bd0819e 436 pRecordStruct->PayloadLength2 = pNDEF[3];
EnricoG 0:3b093bd0819e 437 pRecordStruct->PayloadLength1 = pNDEF[4];
EnricoG 0:3b093bd0819e 438 pRecordStruct->PayloadLength0 = pNDEF[5];
EnricoG 0:3b093bd0819e 439 pRecordStruct->IDLength = IDNbByte;
EnricoG 0:3b093bd0819e 440 memcpy(pRecordStruct->Type, &pNDEF[6+IDNbByte] , TypeNbByte);
EnricoG 0:3b093bd0819e 441 memcpy(pRecordStruct->ID, &pNDEF[6+IDNbByte+TypeNbByte] , IDNbByte);
EnricoG 0:3b093bd0819e 442 pRecordStruct->PayloadOffset = SizeOfRecordHeader;
EnricoG 0:3b093bd0819e 443 }
EnricoG 0:3b093bd0819e 444
EnricoG 0:3b093bd0819e 445 PayloadSize = ((uint32_t)(pRecordStruct->PayloadLength3)<<24) | ((uint32_t)(pRecordStruct->PayloadLength2)<<16) |
EnricoG 0:3b093bd0819e 446 ((uint32_t)(pRecordStruct->PayloadLength1)<<8) | pRecordStruct->PayloadLength0;
EnricoG 0:3b093bd0819e 447
EnricoG 0:3b093bd0819e 448 /* read Payload */
EnricoG 0:3b093bd0819e 449 status = ReadData ( (uint16_t)((FIRST_RECORD_OFFSET) + pRecordStruct->PayloadOffset) , PayloadSize , pNDEF);
EnricoG 0:3b093bd0819e 450
EnricoG 0:3b093bd0819e 451 if( status != NDEF_ACTION_COMPLETED)
EnricoG 0:3b093bd0819e 452 return status;
EnricoG 0:3b093bd0819e 453 else
EnricoG 0:3b093bd0819e 454 pRecordStruct->PayloadBufferAdd = (uint32_t)(pNDEF);
EnricoG 0:3b093bd0819e 455
EnricoG 0:3b093bd0819e 456 NDEF_ParseRecordHeader(pRecordStruct);
EnricoG 0:3b093bd0819e 457
EnricoG 0:3b093bd0819e 458 return SUCCESS;
EnricoG 0:3b093bd0819e 459 }
EnricoG 0:3b093bd0819e 460
EnricoG 0:3b093bd0819e 461 /**
EnricoG 0:3b093bd0819e 462 * @brief This fonction read the NDEF content of the TAG
EnricoG 0:3b093bd0819e 463 * @param pNDEF : pointer on the buffer to store NDEF data
EnricoG 0:3b093bd0819e 464 * @retval SUCCESS : NDEF file data retrieve and store in the buffer
EnricoG 0:3b093bd0819e 465 * @retval ERROR : not able to read NDEF
EnricoG 0:3b093bd0819e 466 */
EnricoG 0:3b093bd0819e 467 uint16_t NDEF_ReadNDEF( uint8_t* pNDEF)
EnricoG 0:3b093bd0819e 468 {
EnricoG 0:3b093bd0819e 469 uint16_t status = ERROR;
EnricoG 0:3b093bd0819e 470 uint16_t NDEF_Size = 0;
EnricoG 0:3b093bd0819e 471
EnricoG 0:3b093bd0819e 472 status = ReadData( 0 , 2 , pNDEF);
EnricoG 0:3b093bd0819e 473
EnricoG 0:3b093bd0819e 474 if( status == NDEF_ACTION_COMPLETED)
EnricoG 0:3b093bd0819e 475 {
EnricoG 0:3b093bd0819e 476 NDEF_Size = (uint16_t) (*pNDEF << 8);
EnricoG 0:3b093bd0819e 477 NDEF_Size = NDEF_Size | (uint16_t) (*++pNDEF );
EnricoG 0:3b093bd0819e 478
EnricoG 0:3b093bd0819e 479 status = ReadData( 0 , NDEF_Size+2 , --pNDEF);
EnricoG 0:3b093bd0819e 480 }
EnricoG 0:3b093bd0819e 481
EnricoG 0:3b093bd0819e 482 if( status == NDEF_ACTION_COMPLETED)
EnricoG 0:3b093bd0819e 483 return SUCCESS;
EnricoG 0:3b093bd0819e 484 else
EnricoG 0:3b093bd0819e 485 return ERROR;
EnricoG 0:3b093bd0819e 486
EnricoG 0:3b093bd0819e 487 }
EnricoG 0:3b093bd0819e 488
EnricoG 0:3b093bd0819e 489 /**
EnricoG 0:3b093bd0819e 490 * @brief This fonction write the NDEF in the TAG
EnricoG 0:3b093bd0819e 491 * @param pNDEF : pointer on the buffer containing the NDEF data
EnricoG 0:3b093bd0819e 492 * @retval SUCCESS : NDEF file data written in the tag
EnricoG 0:3b093bd0819e 493 * @retval ERROR : not able to store NDEF in tag
EnricoG 0:3b093bd0819e 494 */
EnricoG 0:3b093bd0819e 495 uint16_t NDEF_WriteNDEF( uint8_t *pNDEF)
EnricoG 0:3b093bd0819e 496 {
EnricoG 0:3b093bd0819e 497 uint16_t status = ERROR;
EnricoG 0:3b093bd0819e 498 uint16_t NDEF_Size = 0;
EnricoG 0:3b093bd0819e 499
EnricoG 0:3b093bd0819e 500 NDEF_Size = (uint16_t) (*pNDEF << 8);
EnricoG 0:3b093bd0819e 501 NDEF_Size = NDEF_Size | (uint16_t) (*++pNDEF );
EnricoG 0:3b093bd0819e 502
EnricoG 0:3b093bd0819e 503 status = WriteData( 0 , NDEF_Size+2 , --pNDEF);
EnricoG 0:3b093bd0819e 504
EnricoG 0:3b093bd0819e 505 if( status == NDEF_ACTION_COMPLETED)
EnricoG 0:3b093bd0819e 506 return SUCCESS;
EnricoG 0:3b093bd0819e 507 else
EnricoG 0:3b093bd0819e 508 return ERROR;
EnricoG 0:3b093bd0819e 509
EnricoG 0:3b093bd0819e 510 }
EnricoG 0:3b093bd0819e 511
EnricoG 0:3b093bd0819e 512
EnricoG 0:3b093bd0819e 513 /**
EnricoG 0:3b093bd0819e 514 * @}
EnricoG 0:3b093bd0819e 515 */
EnricoG 0:3b093bd0819e 516
EnricoG 0:3b093bd0819e 517 /**
EnricoG 0:3b093bd0819e 518 * @}
EnricoG 0:3b093bd0819e 519 */
EnricoG 0:3b093bd0819e 520
EnricoG 0:3b093bd0819e 521 /**
EnricoG 0:3b093bd0819e 522 * @}
EnricoG 0:3b093bd0819e 523 */
EnricoG 0:3b093bd0819e 524
EnricoG 0:3b093bd0819e 525 /******************* (C) COPYRIGHT 2013 STMicroelectronics *****END OF FILE****/
EnricoG 0:3b093bd0819e 526