Fork for the GitHub

Committer:
DiegoOstuni
Date:
Thu Nov 14 10:34:11 2019 +0000
Revision:
0:de13951f30f6
Add files

Who changed what in which revision?

UserRevisionLine numberNew contents of line
DiegoOstuni 0:de13951f30f6 1 /**
DiegoOstuni 0:de13951f30f6 2 ******************************************************************************
DiegoOstuni 0:de13951f30f6 3 * @file lib_NDEF.c
DiegoOstuni 0:de13951f30f6 4 * @author MMY Application Team
DiegoOstuni 0:de13951f30f6 5 * @version $Revision: 3210 $
DiegoOstuni 0:de13951f30f6 6 * @date $Date: 2016-12-05 15:37:48 +0100 (Mon, 05 Dec 2016) $
DiegoOstuni 0:de13951f30f6 7 * @brief This file help to manage NDEF file, to parse and identify them.
DiegoOstuni 0:de13951f30f6 8 ******************************************************************************
DiegoOstuni 0:de13951f30f6 9 * @attention
DiegoOstuni 0:de13951f30f6 10 *
DiegoOstuni 0:de13951f30f6 11 * <h2><center>&copy; COPYRIGHT 2015 STMicroelectronics</center></h2>
DiegoOstuni 0:de13951f30f6 12 *
DiegoOstuni 0:de13951f30f6 13 * Licensed under ST MYLIBERTY SOFTWARE LICENSE AGREEMENT (the "License");
DiegoOstuni 0:de13951f30f6 14 * You may not use this file except in compliance with the License.
DiegoOstuni 0:de13951f30f6 15 * You may obtain a copy of the License at:
DiegoOstuni 0:de13951f30f6 16 *
DiegoOstuni 0:de13951f30f6 17 * http://www.st.com/myliberty
DiegoOstuni 0:de13951f30f6 18 *
DiegoOstuni 0:de13951f30f6 19 * Unless required by applicable law or agreed to in writing, software
DiegoOstuni 0:de13951f30f6 20 * distributed under the License is distributed on an "AS IS" BASIS,
DiegoOstuni 0:de13951f30f6 21 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied,
DiegoOstuni 0:de13951f30f6 22 * AND SPECIFICALLY DISCLAIMING THE IMPLIED WARRANTIES OF MERCHANTABILITY,
DiegoOstuni 0:de13951f30f6 23 * FITNESS FOR A PARTICULAR PURPOSE, AND NON-INFRINGEMENT.
DiegoOstuni 0:de13951f30f6 24 * See the License for the specific language governing permissions and
DiegoOstuni 0:de13951f30f6 25 * limitations under the License.
DiegoOstuni 0:de13951f30f6 26 *
DiegoOstuni 0:de13951f30f6 27 ******************************************************************************
DiegoOstuni 0:de13951f30f6 28 */
DiegoOstuni 0:de13951f30f6 29
DiegoOstuni 0:de13951f30f6 30 /* Includes ------------------------------------------------------------------*/
DiegoOstuni 0:de13951f30f6 31 #include "lib_NDEF.h"
DiegoOstuni 0:de13951f30f6 32 #include "lib_NDEF_Bluetooth.h"
DiegoOstuni 0:de13951f30f6 33 #include "lib_NDEF_Handover.h"
DiegoOstuni 0:de13951f30f6 34 #include "lib_NDEF_Wifi.h"
DiegoOstuni 0:de13951f30f6 35 #include "mbed.h"
DiegoOstuni 0:de13951f30f6 36
DiegoOstuni 0:de13951f30f6 37 /** @addtogroup NFC_libraries
DiegoOstuni 0:de13951f30f6 38 * @{
DiegoOstuni 0:de13951f30f6 39 * @brief <b>This is the library used to manage the content of the TAG (data)
DiegoOstuni 0:de13951f30f6 40 * But also the specific feature of the tag, for instance
DiegoOstuni 0:de13951f30f6 41 * password, gpo... </b>
DiegoOstuni 0:de13951f30f6 42 */
DiegoOstuni 0:de13951f30f6 43
DiegoOstuni 0:de13951f30f6 44
DiegoOstuni 0:de13951f30f6 45 /** @addtogroup libNFC_FORUM
DiegoOstuni 0:de13951f30f6 46 * @{
DiegoOstuni 0:de13951f30f6 47 * @brief This part of the library manage data which follow NFC forum organisation.
DiegoOstuni 0:de13951f30f6 48 */
DiegoOstuni 0:de13951f30f6 49
DiegoOstuni 0:de13951f30f6 50 /** @defgroup libNDEF_Private_Functions
DiegoOstuni 0:de13951f30f6 51 * @{
DiegoOstuni 0:de13951f30f6 52 */
DiegoOstuni 0:de13951f30f6 53
DiegoOstuni 0:de13951f30f6 54
DiegoOstuni 0:de13951f30f6 55 static uint16_t NDEF_IsNDEFPresent( I2C* mi2cChannel );
DiegoOstuni 0:de13951f30f6 56 static uint16_t NDEF_ParseRecordHeader( sRecordInfo_t *pRecordStruct );
DiegoOstuni 0:de13951f30f6 57 static void NDEF_ParseWellKnownType( sRecordInfo_t *pRecordStruct );
DiegoOstuni 0:de13951f30f6 58 static void NDEF_ParseMediaType( sRecordInfo_t *pRecordStruct );
DiegoOstuni 0:de13951f30f6 59 static void NDEF_ParseForumExternalType( sRecordInfo_t *pRecordStruct );
DiegoOstuni 0:de13951f30f6 60 static void NDEF_ParseURI( sRecordInfo_t *pRecordStruct );
DiegoOstuni 0:de13951f30f6 61 static void NDEF_ParseSP( sRecordInfo_t *pRecordStruct );
DiegoOstuni 0:de13951f30f6 62 static uint16_t NDEF_IdentifySPRecord( sRecordInfo_t *pRecordStruct, uint8_t* pPayload );
DiegoOstuni 0:de13951f30f6 63
DiegoOstuni 0:de13951f30f6 64 /** @brief This buffer is used to store the data sent/received by the TAG. */
DiegoOstuni 0:de13951f30f6 65 uint8_t NDEF_Buffer [NDEF_MAX_SIZE];
DiegoOstuni 0:de13951f30f6 66 /** @brief Size of the buffer used to build the NDEF messages. */
DiegoOstuni 0:de13951f30f6 67 uint32_t NDEF_Buffer_size = NDEF_MAX_SIZE;
DiegoOstuni 0:de13951f30f6 68 /** @brief This buffer is used when it's required to prepare a record before adding it to the NDEF_Buffer. */
DiegoOstuni 0:de13951f30f6 69 uint8_t NDEF_Record_Buffer [NDEF_RECORD_MAX_SIZE];
DiegoOstuni 0:de13951f30f6 70 /** @brief Size of the buffer used when a record has to be prepared. */
DiegoOstuni 0:de13951f30f6 71 uint32_t NDEF_Record_Buffer_size = NDEF_RECORD_MAX_SIZE;
DiegoOstuni 0:de13951f30f6 72
DiegoOstuni 0:de13951f30f6 73 /* In case of smart Poster composed with different record, 3 records supported so far */
DiegoOstuni 0:de13951f30f6 74 sRecordInfo_t SPRecordStruct1, SPRecordStruct2, SPRecordStruct3, SPRecordStruct4;
DiegoOstuni 0:de13951f30f6 75 sRecordInfo_t *SPRecordStructAdd[SP_MAX_RECORD] = { &SPRecordStruct1, &SPRecordStruct2, &SPRecordStruct3, &SPRecordStruct4 };
DiegoOstuni 0:de13951f30f6 76
DiegoOstuni 0:de13951f30f6 77 /**
DiegoOstuni 0:de13951f30f6 78 * @brief This function checks that the tag contain a NDEF message.
DiegoOstuni 0:de13951f30f6 79 * @retval NDEF_OK : There is a NDEF file stored in tag.
DiegoOstuni 0:de13951f30f6 80 * @retval NDEF_ERROR : No NDEF in the tag.
DiegoOstuni 0:de13951f30f6 81 */
DiegoOstuni 0:de13951f30f6 82 static uint16_t NDEF_IsNDEFPresent( I2C* mi2cChannel )
DiegoOstuni 0:de13951f30f6 83 {
DiegoOstuni 0:de13951f30f6 84 uint16_t FileSize;
DiegoOstuni 0:de13951f30f6 85
DiegoOstuni 0:de13951f30f6 86 /* Check NDEF existence */
DiegoOstuni 0:de13951f30f6 87 NfcTag_GetLength(&FileSize, mi2cChannel);
DiegoOstuni 0:de13951f30f6 88
DiegoOstuni 0:de13951f30f6 89 if( FileSize != 0 )
DiegoOstuni 0:de13951f30f6 90 return NDEF_OK;
DiegoOstuni 0:de13951f30f6 91 else
DiegoOstuni 0:de13951f30f6 92 return NDEF_ERROR;
DiegoOstuni 0:de13951f30f6 93 }
DiegoOstuni 0:de13951f30f6 94
DiegoOstuni 0:de13951f30f6 95 /**
DiegoOstuni 0:de13951f30f6 96 * @brief This function identify the type of record.
DiegoOstuni 0:de13951f30f6 97 * @param pRecordStruct : pointer on the record structure to fill.
DiegoOstuni 0:de13951f30f6 98 * @param pPayload : pointer on the payload.
DiegoOstuni 0:de13951f30f6 99 * @retval Status : Status of the operation.
DiegoOstuni 0:de13951f30f6 100 */
DiegoOstuni 0:de13951f30f6 101 static uint16_t NDEF_IdentifySPRecord( sRecordInfo_t *pRecordStruct, uint8_t* pPayload )
DiegoOstuni 0:de13951f30f6 102 {
DiegoOstuni 0:de13951f30f6 103 uint16_t status = NDEF_ERROR;
DiegoOstuni 0:de13951f30f6 104 uint16_t SizeOfRecordHeader, TypeNbByte, PayloadLengthField, IDLengthField, IDNbByte;
DiegoOstuni 0:de13951f30f6 105
DiegoOstuni 0:de13951f30f6 106 /* Is ID length field present */
DiegoOstuni 0:de13951f30f6 107 if( (*pPayload) & IL_Mask )
DiegoOstuni 0:de13951f30f6 108 {
DiegoOstuni 0:de13951f30f6 109 IDLengthField = ID_LENGTH_FIELD;
DiegoOstuni 0:de13951f30f6 110 }
DiegoOstuni 0:de13951f30f6 111 else
DiegoOstuni 0:de13951f30f6 112 {
DiegoOstuni 0:de13951f30f6 113 IDLengthField = 0;
DiegoOstuni 0:de13951f30f6 114 }
DiegoOstuni 0:de13951f30f6 115
DiegoOstuni 0:de13951f30f6 116 /* it's a SR */
DiegoOstuni 0:de13951f30f6 117 if( (*pPayload) & SR_Mask )
DiegoOstuni 0:de13951f30f6 118 {
DiegoOstuni 0:de13951f30f6 119 TypeNbByte = pPayload[1];
DiegoOstuni 0:de13951f30f6 120 PayloadLengthField = 1;
DiegoOstuni 0:de13951f30f6 121 if( IDLengthField == ID_LENGTH_FIELD )
DiegoOstuni 0:de13951f30f6 122 IDNbByte = pPayload[3];
DiegoOstuni 0:de13951f30f6 123 else
DiegoOstuni 0:de13951f30f6 124 IDNbByte = 0;
DiegoOstuni 0:de13951f30f6 125 }
DiegoOstuni 0:de13951f30f6 126 else
DiegoOstuni 0:de13951f30f6 127 {
DiegoOstuni 0:de13951f30f6 128 TypeNbByte = pPayload[1];
DiegoOstuni 0:de13951f30f6 129 PayloadLengthField = 4;
DiegoOstuni 0:de13951f30f6 130 if( IDLengthField == ID_LENGTH_FIELD )
DiegoOstuni 0:de13951f30f6 131 IDNbByte = pPayload[6];
DiegoOstuni 0:de13951f30f6 132 else
DiegoOstuni 0:de13951f30f6 133 IDNbByte = 0;
DiegoOstuni 0:de13951f30f6 134 }
DiegoOstuni 0:de13951f30f6 135
DiegoOstuni 0:de13951f30f6 136 SizeOfRecordHeader = RECORD_FLAG_FIELD + TYPE_LENGTH_FIELD + PayloadLengthField + IDLengthField + TypeNbByte + IDNbByte;
DiegoOstuni 0:de13951f30f6 137
DiegoOstuni 0:de13951f30f6 138 /* it's a SR */
DiegoOstuni 0:de13951f30f6 139 if( pPayload[0] & SR_Mask )
DiegoOstuni 0:de13951f30f6 140 {
DiegoOstuni 0:de13951f30f6 141 pRecordStruct->RecordFlags = pPayload[0];
DiegoOstuni 0:de13951f30f6 142 pRecordStruct->TypeLength = TypeNbByte;
DiegoOstuni 0:de13951f30f6 143 pRecordStruct->PayloadLength = pPayload[2];
DiegoOstuni 0:de13951f30f6 144 pRecordStruct->IDLength = IDNbByte;
DiegoOstuni 0:de13951f30f6 145 memcpy( pRecordStruct->Type, &pPayload[3+IDNbByte], TypeNbByte );
DiegoOstuni 0:de13951f30f6 146 memcpy( pRecordStruct->ID, &pPayload[3+IDNbByte+TypeNbByte], IDNbByte );
DiegoOstuni 0:de13951f30f6 147 pRecordStruct->PayloadOffset = SizeOfRecordHeader;
DiegoOstuni 0:de13951f30f6 148 }
DiegoOstuni 0:de13951f30f6 149 else
DiegoOstuni 0:de13951f30f6 150 {
DiegoOstuni 0:de13951f30f6 151 pRecordStruct->RecordFlags = pPayload[0];
DiegoOstuni 0:de13951f30f6 152 pRecordStruct->TypeLength = TypeNbByte;
DiegoOstuni 0:de13951f30f6 153 pRecordStruct->PayloadLength = ( ((uint32_t)pPayload[2]) << 24 ) |
DiegoOstuni 0:de13951f30f6 154 ( ((uint32_t)pPayload[3]) << 16 ) |
DiegoOstuni 0:de13951f30f6 155 ( ((uint32_t)pPayload[4]) << 8 )
DiegoOstuni 0:de13951f30f6 156 | pPayload[5] ;
DiegoOstuni 0:de13951f30f6 157 pRecordStruct->IDLength = IDNbByte;
DiegoOstuni 0:de13951f30f6 158 memcpy( pRecordStruct->Type, &pPayload[6+IDNbByte], TypeNbByte );
DiegoOstuni 0:de13951f30f6 159 memcpy( pRecordStruct->ID, &pPayload[6+IDNbByte+TypeNbByte], IDNbByte );
DiegoOstuni 0:de13951f30f6 160 pRecordStruct->PayloadOffset = SizeOfRecordHeader;
DiegoOstuni 0:de13951f30f6 161 }
DiegoOstuni 0:de13951f30f6 162
DiegoOstuni 0:de13951f30f6 163 pRecordStruct->PayloadBufferAdd = pPayload + SizeOfRecordHeader ;
DiegoOstuni 0:de13951f30f6 164
DiegoOstuni 0:de13951f30f6 165 status = NDEF_ParseRecordHeader( pRecordStruct );
DiegoOstuni 0:de13951f30f6 166
DiegoOstuni 0:de13951f30f6 167 return status;
DiegoOstuni 0:de13951f30f6 168 }
DiegoOstuni 0:de13951f30f6 169
DiegoOstuni 0:de13951f30f6 170 /**
DiegoOstuni 0:de13951f30f6 171 * @brief This function parse the record header and dispatch regarding TNF value.
DiegoOstuni 0:de13951f30f6 172 * @param pRecordStruct : pointer on the record structure to fill.
DiegoOstuni 0:de13951f30f6 173 * @retval NDEF_OK : record identified and structure filled.
DiegoOstuni 0:de13951f30f6 174 * @retval NDEF_ERROR : Not supported.
DiegoOstuni 0:de13951f30f6 175 */
DiegoOstuni 0:de13951f30f6 176 static uint16_t NDEF_ParseRecordHeader( sRecordInfo_t *pRecordStruct )
DiegoOstuni 0:de13951f30f6 177 {
DiegoOstuni 0:de13951f30f6 178 uint16_t status = NDEF_OK;
DiegoOstuni 0:de13951f30f6 179
DiegoOstuni 0:de13951f30f6 180 switch( (pRecordStruct->RecordFlags & TNF_Mask) )
DiegoOstuni 0:de13951f30f6 181 {
DiegoOstuni 0:de13951f30f6 182 case TNF_WellKnown:
DiegoOstuni 0:de13951f30f6 183 NDEF_ParseWellKnownType( pRecordStruct );
DiegoOstuni 0:de13951f30f6 184 break;
DiegoOstuni 0:de13951f30f6 185
DiegoOstuni 0:de13951f30f6 186 case TNF_MediaType:
DiegoOstuni 0:de13951f30f6 187 NDEF_ParseMediaType( pRecordStruct );
DiegoOstuni 0:de13951f30f6 188 break;
DiegoOstuni 0:de13951f30f6 189
DiegoOstuni 0:de13951f30f6 190 case TNF_NFCForumExternal:
DiegoOstuni 0:de13951f30f6 191 NDEF_ParseForumExternalType( pRecordStruct);
DiegoOstuni 0:de13951f30f6 192 break;
DiegoOstuni 0:de13951f30f6 193
DiegoOstuni 0:de13951f30f6 194 default:
DiegoOstuni 0:de13951f30f6 195 /* currently not supported or unknown*/
DiegoOstuni 0:de13951f30f6 196 pRecordStruct->NDEF_Type = UNKNOWN_TYPE;
DiegoOstuni 0:de13951f30f6 197 status = NDEF_ERROR;
DiegoOstuni 0:de13951f30f6 198 }
DiegoOstuni 0:de13951f30f6 199 return status;
DiegoOstuni 0:de13951f30f6 200 }
DiegoOstuni 0:de13951f30f6 201
DiegoOstuni 0:de13951f30f6 202 /**
DiegoOstuni 0:de13951f30f6 203 * @brief This function parse the Well Known type record.
DiegoOstuni 0:de13951f30f6 204 * @param pRecordStruct : pointer on the record structure to fill.
DiegoOstuni 0:de13951f30f6 205 */
DiegoOstuni 0:de13951f30f6 206 static void NDEF_ParseWellKnownType( sRecordInfo_t *pRecordStruct )
DiegoOstuni 0:de13951f30f6 207 {
DiegoOstuni 0:de13951f30f6 208 uint8_t* pPayload;
DiegoOstuni 0:de13951f30f6 209
DiegoOstuni 0:de13951f30f6 210 pPayload = (uint8_t*)( pRecordStruct->PayloadBufferAdd );
DiegoOstuni 0:de13951f30f6 211
DiegoOstuni 0:de13951f30f6 212 if( !memcmp( &(pRecordStruct->Type), SMART_POSTER_TYPE_STRING, pRecordStruct->TypeLength ) )
DiegoOstuni 0:de13951f30f6 213 {
DiegoOstuni 0:de13951f30f6 214 /* special case where we have to parse others records */
DiegoOstuni 0:de13951f30f6 215 pRecordStruct->NDEF_Type = SMARTPOSTER_TYPE;
DiegoOstuni 0:de13951f30f6 216 NDEF_ParseSP( pRecordStruct );
DiegoOstuni 0:de13951f30f6 217 }
DiegoOstuni 0:de13951f30f6 218
DiegoOstuni 0:de13951f30f6 219 else if( !memcmp( &(pRecordStruct->Type), URI_TYPE_STRING, pRecordStruct->TypeLength ) )
DiegoOstuni 0:de13951f30f6 220 {
DiegoOstuni 0:de13951f30f6 221 /* it's an URI Type check if it's an URL or SMS or ... */
DiegoOstuni 0:de13951f30f6 222 /* check identifier */
DiegoOstuni 0:de13951f30f6 223 if( *pPayload == URI_ID_0x00 )
DiegoOstuni 0:de13951f30f6 224 {
DiegoOstuni 0:de13951f30f6 225 NDEF_ParseURI( pRecordStruct );
DiegoOstuni 0:de13951f30f6 226 }
DiegoOstuni 0:de13951f30f6 227 else if( (*pPayload > URI_ID_0x00) && (*pPayload < URI_RFU) )
DiegoOstuni 0:de13951f30f6 228 {
DiegoOstuni 0:de13951f30f6 229 /* email special case */
DiegoOstuni 0:de13951f30f6 230 if( *pPayload == (uint8_t) URI_ID_0x06 )
DiegoOstuni 0:de13951f30f6 231 {
DiegoOstuni 0:de13951f30f6 232 pRecordStruct->NDEF_Type = URI_EMAIL_TYPE;
DiegoOstuni 0:de13951f30f6 233 }
DiegoOstuni 0:de13951f30f6 234 else
DiegoOstuni 0:de13951f30f6 235 {
DiegoOstuni 0:de13951f30f6 236 pRecordStruct->NDEF_Type = WELL_KNOWN_ABRIDGED_URI_TYPE;
DiegoOstuni 0:de13951f30f6 237 }
DiegoOstuni 0:de13951f30f6 238 }
DiegoOstuni 0:de13951f30f6 239 else
DiegoOstuni 0:de13951f30f6 240 {
DiegoOstuni 0:de13951f30f6 241 pRecordStruct->NDEF_Type = UNKNOWN_TYPE;
DiegoOstuni 0:de13951f30f6 242 }
DiegoOstuni 0:de13951f30f6 243 }
DiegoOstuni 0:de13951f30f6 244
DiegoOstuni 0:de13951f30f6 245 else if( !memcmp( &(pRecordStruct->Type), TEXT_TYPE_STRING, pRecordStruct->TypeLength ) )
DiegoOstuni 0:de13951f30f6 246 {
DiegoOstuni 0:de13951f30f6 247 pRecordStruct->NDEF_Type = TEXT_TYPE;
DiegoOstuni 0:de13951f30f6 248 } else if ((!memcmp( &(pRecordStruct->Type), NDEF_HANDOVER_SELECT_TYPE_STR, pRecordStruct->TypeLength )) ||
DiegoOstuni 0:de13951f30f6 249 (!memcmp( &(pRecordStruct->Type), NDEF_HANDOVER_REQUEST_TYPE_STR, pRecordStruct->TypeLength ) ))
DiegoOstuni 0:de13951f30f6 250 {
DiegoOstuni 0:de13951f30f6 251 pRecordStruct->NDEF_Type = HANDOVER_TYPE;
DiegoOstuni 0:de13951f30f6 252 }
DiegoOstuni 0:de13951f30f6 253 else
DiegoOstuni 0:de13951f30f6 254 pRecordStruct->NDEF_Type = UNKNOWN_TYPE;
DiegoOstuni 0:de13951f30f6 255 }
DiegoOstuni 0:de13951f30f6 256
DiegoOstuni 0:de13951f30f6 257 /**
DiegoOstuni 0:de13951f30f6 258 * @brief This function parse the Media type record.
DiegoOstuni 0:de13951f30f6 259 * @param pRecordStruct : pointer on the record structure to fill.
DiegoOstuni 0:de13951f30f6 260 */
DiegoOstuni 0:de13951f30f6 261 static void NDEF_ParseMediaType( sRecordInfo_t *pRecordStruct )
DiegoOstuni 0:de13951f30f6 262 {
DiegoOstuni 0:de13951f30f6 263 if( !memcmp( &(pRecordStruct->Type), VCARD_TYPE_STRING, pRecordStruct->TypeLength ) )
DiegoOstuni 0:de13951f30f6 264 pRecordStruct->NDEF_Type = VCARD_TYPE;
DiegoOstuni 0:de13951f30f6 265 else if( !memcmp( &(pRecordStruct->Type), XVCARD_TYPE_STRING, pRecordStruct->TypeLength ) )
DiegoOstuni 0:de13951f30f6 266 pRecordStruct->NDEF_Type = VCARD_TYPE;
DiegoOstuni 0:de13951f30f6 267 else if( !memcmp( &(pRecordStruct->Type), XVCARD2_TYPE_STRING, pRecordStruct->TypeLength ) )
DiegoOstuni 0:de13951f30f6 268 pRecordStruct->NDEF_Type = VCARD_TYPE;
DiegoOstuni 0:de13951f30f6 269 else if (!memcmp(&pRecordStruct->Type, NDEF_BLUETOOTH_BREDR_MIME_TYPE, pRecordStruct->TypeLength))
DiegoOstuni 0:de13951f30f6 270 pRecordStruct->NDEF_Type = BT_TYPE;
DiegoOstuni 0:de13951f30f6 271 else if (!memcmp(&pRecordStruct->Type, NDEF_BLUETOOTH_BLE_MIME_TYPE, pRecordStruct->TypeLength))
DiegoOstuni 0:de13951f30f6 272 pRecordStruct->NDEF_Type = BLE_TYPE;
DiegoOstuni 0:de13951f30f6 273 else if (!memcmp(&pRecordStruct->Type, WIFITOKEN_TYPE_STRING, pRecordStruct->TypeLength))
DiegoOstuni 0:de13951f30f6 274 pRecordStruct->NDEF_Type = URI_WIFITOKEN_TYPE;
DiegoOstuni 0:de13951f30f6 275 else
DiegoOstuni 0:de13951f30f6 276 pRecordStruct->NDEF_Type = UNKNOWN_TYPE;
DiegoOstuni 0:de13951f30f6 277 }
DiegoOstuni 0:de13951f30f6 278
DiegoOstuni 0:de13951f30f6 279 /**
DiegoOstuni 0:de13951f30f6 280 * @brief This function parse the Forum External type record.
DiegoOstuni 0:de13951f30f6 281 * @param pRecordStruct : pointer on the record structure to fill.
DiegoOstuni 0:de13951f30f6 282 */
DiegoOstuni 0:de13951f30f6 283 static void NDEF_ParseForumExternalType( sRecordInfo_t *pRecordStruct )
DiegoOstuni 0:de13951f30f6 284 {
DiegoOstuni 0:de13951f30f6 285 if( !memcmp( &(pRecordStruct->Type), M24SR_DISCOVERY_APP_STRING, pRecordStruct->TypeLength ) )
DiegoOstuni 0:de13951f30f6 286 pRecordStruct->NDEF_Type = M24SR_DISCOVERY_APP_TYPE;
DiegoOstuni 0:de13951f30f6 287 else
DiegoOstuni 0:de13951f30f6 288 pRecordStruct->NDEF_Type = UNKNOWN_TYPE;
DiegoOstuni 0:de13951f30f6 289 }
DiegoOstuni 0:de13951f30f6 290
DiegoOstuni 0:de13951f30f6 291 /**
DiegoOstuni 0:de13951f30f6 292 * @brief This function parse the URI type record.
DiegoOstuni 0:de13951f30f6 293 * @param pRecordStruct : pointer on the record structure to fill.
DiegoOstuni 0:de13951f30f6 294 */
DiegoOstuni 0:de13951f30f6 295 static void NDEF_ParseURI( sRecordInfo_t *pRecordStruct )
DiegoOstuni 0:de13951f30f6 296 {
DiegoOstuni 0:de13951f30f6 297 uint8_t* pPayload;
DiegoOstuni 0:de13951f30f6 298
DiegoOstuni 0:de13951f30f6 299 pPayload = (uint8_t*)( pRecordStruct->PayloadBufferAdd );
DiegoOstuni 0:de13951f30f6 300 pPayload++; /* to skip URI identifier first URI payload byte */
DiegoOstuni 0:de13951f30f6 301
DiegoOstuni 0:de13951f30f6 302 if( !memcmp( pPayload, SMS_TYPE_STRING, strlen(SMS_TYPE_STRING) ) )
DiegoOstuni 0:de13951f30f6 303 {
DiegoOstuni 0:de13951f30f6 304 pRecordStruct->NDEF_Type = URI_SMS_TYPE;
DiegoOstuni 0:de13951f30f6 305 }
DiegoOstuni 0:de13951f30f6 306 else if( !memcmp( pPayload, GEO_TYPE_STRING, strlen(GEO_TYPE_STRING) ) )
DiegoOstuni 0:de13951f30f6 307 {
DiegoOstuni 0:de13951f30f6 308 pRecordStruct->NDEF_Type = URI_GEO_TYPE;
DiegoOstuni 0:de13951f30f6 309 }
DiegoOstuni 0:de13951f30f6 310 else
DiegoOstuni 0:de13951f30f6 311 pRecordStruct->NDEF_Type = UNKNOWN_TYPE;
DiegoOstuni 0:de13951f30f6 312 }
DiegoOstuni 0:de13951f30f6 313
DiegoOstuni 0:de13951f30f6 314 /**
DiegoOstuni 0:de13951f30f6 315 * @brief This function parse the Smart Poster.
DiegoOstuni 0:de13951f30f6 316 * @param pRecordStruct : pointer on the record structure to fill.
DiegoOstuni 0:de13951f30f6 317 */
DiegoOstuni 0:de13951f30f6 318 static void NDEF_ParseSP( sRecordInfo_t *pRecordStruct )
DiegoOstuni 0:de13951f30f6 319 {
DiegoOstuni 0:de13951f30f6 320 uint8_t* pPayload;
DiegoOstuni 0:de13951f30f6 321 uint32_t PayloadSize = 0;
DiegoOstuni 0:de13951f30f6 322 uint32_t SPPayloadSize = 0;
DiegoOstuni 0:de13951f30f6 323 uint32_t OffsetInSPPayload = 0;
DiegoOstuni 0:de13951f30f6 324 uint32_t RecordPosition = 0;
DiegoOstuni 0:de13951f30f6 325 sRecordInfo_t *pSPRecordStruct;
DiegoOstuni 0:de13951f30f6 326
DiegoOstuni 0:de13951f30f6 327 /* initialize variable with size of the payload and poiter on data */
DiegoOstuni 0:de13951f30f6 328 PayloadSize = pRecordStruct->PayloadLength;
DiegoOstuni 0:de13951f30f6 329
DiegoOstuni 0:de13951f30f6 330 pPayload = (uint8_t*)( pRecordStruct->PayloadBufferAdd );
DiegoOstuni 0:de13951f30f6 331
DiegoOstuni 0:de13951f30f6 332 pSPRecordStruct = SPRecordStructAdd[0];
DiegoOstuni 0:de13951f30f6 333
DiegoOstuni 0:de13951f30f6 334 /* Initailize the number of record find in the SP payload */
DiegoOstuni 0:de13951f30f6 335 pRecordStruct->NbOfRecordInSPPayload = 0;
DiegoOstuni 0:de13951f30f6 336
DiegoOstuni 0:de13951f30f6 337 do
DiegoOstuni 0:de13951f30f6 338 {
DiegoOstuni 0:de13951f30f6 339 pSPRecordStruct = SPRecordStructAdd[RecordPosition];
DiegoOstuni 0:de13951f30f6 340 /* identify the record in the SP payload */
DiegoOstuni 0:de13951f30f6 341 if( NDEF_IdentifySPRecord( pSPRecordStruct, pPayload ) == NDEF_OK )
DiegoOstuni 0:de13951f30f6 342 {
DiegoOstuni 0:de13951f30f6 343 /* store add of structure that will contain the other record information */
DiegoOstuni 0:de13951f30f6 344 pRecordStruct->NbOfRecordInSPPayload++;
DiegoOstuni 0:de13951f30f6 345 pRecordStruct->SPRecordStructAdd[RecordPosition] = pSPRecordStruct;
DiegoOstuni 0:de13951f30f6 346
DiegoOstuni 0:de13951f30f6 347 /* After SPRecord + First Record check if we are at the end of NDEF file */
DiegoOstuni 0:de13951f30f6 348 SPPayloadSize = pSPRecordStruct->PayloadLength;
DiegoOstuni 0:de13951f30f6 349
DiegoOstuni 0:de13951f30f6 350 OffsetInSPPayload += pSPRecordStruct->PayloadOffset + SPPayloadSize;
DiegoOstuni 0:de13951f30f6 351 pPayload += OffsetInSPPayload;
DiegoOstuni 0:de13951f30f6 352 }
DiegoOstuni 0:de13951f30f6 353 else /* Recommended Action Record for example */
DiegoOstuni 0:de13951f30f6 354 {
DiegoOstuni 0:de13951f30f6 355 SPPayloadSize = 0;
DiegoOstuni 0:de13951f30f6 356 }
DiegoOstuni 0:de13951f30f6 357 RecordPosition++;
DiegoOstuni 0:de13951f30f6 358 }
DiegoOstuni 0:de13951f30f6 359 while( (OffsetInSPPayload < PayloadSize) && RecordPosition<SP_MAX_RECORD); /* there is another record */
DiegoOstuni 0:de13951f30f6 360 }
DiegoOstuni 0:de13951f30f6 361
DiegoOstuni 0:de13951f30f6 362 /**
DiegoOstuni 0:de13951f30f6 363 * @}
DiegoOstuni 0:de13951f30f6 364 */
DiegoOstuni 0:de13951f30f6 365
DiegoOstuni 0:de13951f30f6 366 /** @defgroup libNDEF_Public_Functions
DiegoOstuni 0:de13951f30f6 367 * @{
DiegoOstuni 0:de13951f30f6 368 */
DiegoOstuni 0:de13951f30f6 369
DiegoOstuni 0:de13951f30f6 370
DiegoOstuni 0:de13951f30f6 371 /**
DiegoOstuni 0:de13951f30f6 372 * @brief This function identify the NDEF message stored in tag.
DiegoOstuni 0:de13951f30f6 373 * @param pRecordStruct : Structure to fill with record information.
DiegoOstuni 0:de13951f30f6 374 * @param pNDEF : pointer on the NDEF message data.
DiegoOstuni 0:de13951f30f6 375 * @retval NDEF_OK : record struct filled.
DiegoOstuni 0:de13951f30f6 376 * @retval NDEF_ERROR : record struct not updated.
DiegoOstuni 0:de13951f30f6 377 */
DiegoOstuni 0:de13951f30f6 378 uint16_t NDEF_IdentifyNDEF( sRecordInfo_t *pRecordStruct, uint8_t* pNDEF, I2C* mi2cChannel )
DiegoOstuni 0:de13951f30f6 379 {
DiegoOstuni 0:de13951f30f6 380 uint16_t SizeOfRecordHeader, TypeNbByte, PayloadLengthField, IDLengthField, IDNbByte;
DiegoOstuni 0:de13951f30f6 381
DiegoOstuni 0:de13951f30f6 382 /* check NDEF present */
DiegoOstuni 0:de13951f30f6 383 if( NDEF_IsNDEFPresent(mi2cChannel) != NDEF_OK )
DiegoOstuni 0:de13951f30f6 384 {
DiegoOstuni 0:de13951f30f6 385 return NDEF_ERROR;
DiegoOstuni 0:de13951f30f6 386 }
DiegoOstuni 0:de13951f30f6 387
DiegoOstuni 0:de13951f30f6 388 /* Read the NDEF file */
DiegoOstuni 0:de13951f30f6 389 NfcTag_ReadNDEF( pNDEF, mi2cChannel );
DiegoOstuni 0:de13951f30f6 390
DiegoOstuni 0:de13951f30f6 391 /* Is ID length field present */
DiegoOstuni 0:de13951f30f6 392 if( (*pNDEF) & IL_Mask )
DiegoOstuni 0:de13951f30f6 393 {
DiegoOstuni 0:de13951f30f6 394 IDLengthField = ID_LENGTH_FIELD;
DiegoOstuni 0:de13951f30f6 395 }
DiegoOstuni 0:de13951f30f6 396 else
DiegoOstuni 0:de13951f30f6 397 {
DiegoOstuni 0:de13951f30f6 398 IDLengthField = 0;
DiegoOstuni 0:de13951f30f6 399 }
DiegoOstuni 0:de13951f30f6 400
DiegoOstuni 0:de13951f30f6 401 /* it's a SR */
DiegoOstuni 0:de13951f30f6 402 if( (*pNDEF) & SR_Mask )
DiegoOstuni 0:de13951f30f6 403 {
DiegoOstuni 0:de13951f30f6 404 /* Analyse short record layout */
DiegoOstuni 0:de13951f30f6 405 TypeNbByte = pNDEF[1];
DiegoOstuni 0:de13951f30f6 406 PayloadLengthField = 1;
DiegoOstuni 0:de13951f30f6 407 if( IDLengthField == ID_LENGTH_FIELD )
DiegoOstuni 0:de13951f30f6 408 IDNbByte = pNDEF[3];
DiegoOstuni 0:de13951f30f6 409 else
DiegoOstuni 0:de13951f30f6 410 IDNbByte = 0;
DiegoOstuni 0:de13951f30f6 411 }
DiegoOstuni 0:de13951f30f6 412 else
DiegoOstuni 0:de13951f30f6 413 {
DiegoOstuni 0:de13951f30f6 414 /* Analyse normal record layout */
DiegoOstuni 0:de13951f30f6 415 TypeNbByte = pNDEF[1];
DiegoOstuni 0:de13951f30f6 416 PayloadLengthField = 4;
DiegoOstuni 0:de13951f30f6 417 if( IDLengthField == ID_LENGTH_FIELD )
DiegoOstuni 0:de13951f30f6 418 IDNbByte = pNDEF[6];
DiegoOstuni 0:de13951f30f6 419 else
DiegoOstuni 0:de13951f30f6 420 IDNbByte = 0;
DiegoOstuni 0:de13951f30f6 421 }
DiegoOstuni 0:de13951f30f6 422
DiegoOstuni 0:de13951f30f6 423 SizeOfRecordHeader = RECORD_FLAG_FIELD + TYPE_LENGTH_FIELD + PayloadLengthField + IDLengthField + TypeNbByte + IDNbByte;
DiegoOstuni 0:de13951f30f6 424
DiegoOstuni 0:de13951f30f6 425 /* Read record header */
DiegoOstuni 0:de13951f30f6 426 /* it's a SR */
DiegoOstuni 0:de13951f30f6 427 if( pNDEF[0] & SR_Mask )
DiegoOstuni 0:de13951f30f6 428 {
DiegoOstuni 0:de13951f30f6 429 pRecordStruct->RecordFlags = pNDEF[0];
DiegoOstuni 0:de13951f30f6 430 pRecordStruct->TypeLength = TypeNbByte;
DiegoOstuni 0:de13951f30f6 431 pRecordStruct->PayloadLength = pNDEF[2];
DiegoOstuni 0:de13951f30f6 432 pRecordStruct->IDLength = IDNbByte;
DiegoOstuni 0:de13951f30f6 433 memcpy( pRecordStruct->Type, &pNDEF[3+IDNbByte], TypeNbByte );
DiegoOstuni 0:de13951f30f6 434 memcpy( pRecordStruct->ID, &pNDEF[3+IDNbByte+TypeNbByte], IDNbByte );
DiegoOstuni 0:de13951f30f6 435 pRecordStruct->PayloadOffset = SizeOfRecordHeader;
DiegoOstuni 0:de13951f30f6 436 }
DiegoOstuni 0:de13951f30f6 437 else
DiegoOstuni 0:de13951f30f6 438 {
DiegoOstuni 0:de13951f30f6 439 pRecordStruct->RecordFlags = pNDEF[0];
DiegoOstuni 0:de13951f30f6 440 pRecordStruct->TypeLength = TypeNbByte;
DiegoOstuni 0:de13951f30f6 441 pRecordStruct->PayloadLength = ( ((uint32_t)pNDEF[2]) << 24 ) |
DiegoOstuni 0:de13951f30f6 442 ( ((uint32_t)pNDEF[3]) << 16 ) |
DiegoOstuni 0:de13951f30f6 443 ( ((uint32_t)pNDEF[4]) << 8 )
DiegoOstuni 0:de13951f30f6 444 | pNDEF[5] ;
DiegoOstuni 0:de13951f30f6 445 pRecordStruct->IDLength = IDNbByte;
DiegoOstuni 0:de13951f30f6 446 memcpy( pRecordStruct->Type, &pNDEF[6+IDNbByte], TypeNbByte );
DiegoOstuni 0:de13951f30f6 447 memcpy( pRecordStruct->ID, &pNDEF[6+IDNbByte+TypeNbByte], IDNbByte );
DiegoOstuni 0:de13951f30f6 448 pRecordStruct->PayloadOffset = SizeOfRecordHeader;
DiegoOstuni 0:de13951f30f6 449 }
DiegoOstuni 0:de13951f30f6 450
DiegoOstuni 0:de13951f30f6 451 pRecordStruct->PayloadBufferAdd = pNDEF;
DiegoOstuni 0:de13951f30f6 452
DiegoOstuni 0:de13951f30f6 453 NDEF_ParseRecordHeader( pRecordStruct );
DiegoOstuni 0:de13951f30f6 454
DiegoOstuni 0:de13951f30f6 455 return NDEF_OK;
DiegoOstuni 0:de13951f30f6 456 }
DiegoOstuni 0:de13951f30f6 457
DiegoOstuni 0:de13951f30f6 458 /**
DiegoOstuni 0:de13951f30f6 459 * @brief This function read the NDEF content of the TAG.
DiegoOstuni 0:de13951f30f6 460 * @param pNDEF : pointer on the buffer to store NDEF data.
DiegoOstuni 0:de13951f30f6 461 * @retval NDEF_OK : NDEF file data retrieve and store in the buffer.
DiegoOstuni 0:de13951f30f6 462 * @retval NDEF_ERROR : not able to read NDEF from tag.
DiegoOstuni 0:de13951f30f6 463 * @retval NDEF_ERROR_MEMORY_INTERNAL : Cannot read tag.
DiegoOstuni 0:de13951f30f6 464 * @retval NDEF_ERROR_NOT_FORMATED : CCFile data not supported or not present.
DiegoOstuni 0:de13951f30f6 465 * @retval NDEF_ERROR_MEMORY_TAG : Size not compatible with memory.
DiegoOstuni 0:de13951f30f6 466 * @retval NDEF_ERROR_LOCKED : Tag locked, cannot be read.
DiegoOstuni 0:de13951f30f6 467 */
DiegoOstuni 0:de13951f30f6 468 uint16_t NDEF_ReadNDEF( uint8_t* pNDEF, I2C* mi2cChannel )
DiegoOstuni 0:de13951f30f6 469 {
DiegoOstuni 0:de13951f30f6 470 return NfcTag_ReadNDEF( pNDEF, mi2cChannel );
DiegoOstuni 0:de13951f30f6 471 }
DiegoOstuni 0:de13951f30f6 472
DiegoOstuni 0:de13951f30f6 473
DiegoOstuni 0:de13951f30f6 474
DiegoOstuni 0:de13951f30f6 475 /**
DiegoOstuni 0:de13951f30f6 476 * @brief This function read the NDEF size of the TAG.
DiegoOstuni 0:de13951f30f6 477 * @param Size : pointer to a 16-bit Size (in bytes) to be returned.
DiegoOstuni 0:de13951f30f6 478 * @retval NDEF_OK : NDEF file data retrieve and store in the buffer.
DiegoOstuni 0:de13951f30f6 479 * @retval NDEF_ERROR : not able to read NDEF from tag.
DiegoOstuni 0:de13951f30f6 480 * @retval NDEF_ERROR_MEMORY_INTERNAL : Cannot read tag.
DiegoOstuni 0:de13951f30f6 481 * @retval NDEF_ERROR_NOT_FORMATED : CCFile data not supported or not present.
DiegoOstuni 0:de13951f30f6 482 * @retval NDEF_ERROR_MEMORY_TAG : Size not compatible with memory.
DiegoOstuni 0:de13951f30f6 483 * @retval NDEF_ERROR_LOCKED : Tag locked, cannot be read.
DiegoOstuni 0:de13951f30f6 484 */
DiegoOstuni 0:de13951f30f6 485 uint16_t NDEF_getNDEFSize(uint16_t* Size, I2C* mi2cChannel)
DiegoOstuni 0:de13951f30f6 486 {
DiegoOstuni 0:de13951f30f6 487 return NfcTag_GetLength(Size, mi2cChannel);
DiegoOstuni 0:de13951f30f6 488 }
DiegoOstuni 0:de13951f30f6 489 /**
DiegoOstuni 0:de13951f30f6 490 * @brief This function write the NDEF in the TAG.
DiegoOstuni 0:de13951f30f6 491 * @param pNDEF : pointer on the buffer containing the NDEF data.
DiegoOstuni 0:de13951f30f6 492 * @retval NDEF_OK : NDEF file data written in the tag.
DiegoOstuni 0:de13951f30f6 493 * @retval NDEF_ERROR : not able to store NDEF in tag.
DiegoOstuni 0:de13951f30f6 494 * @retval NDEF_ERROR_MEMORY_INTERNAL : Cannot write to tag.
DiegoOstuni 0:de13951f30f6 495 * @retval NDEF_ERROR_NOT_FORMATED : CCFile data not supported or not present.
DiegoOstuni 0:de13951f30f6 496 * @retval NDEF_ERROR_MEMORY_TAG : Size not compatible with memory.
DiegoOstuni 0:de13951f30f6 497 * @retval NDEF_ERROR_LOCKED : Tag locked, cannot be write.
DiegoOstuni 0:de13951f30f6 498 */
DiegoOstuni 0:de13951f30f6 499 uint16_t NDEF_WriteNDEF( uint16_t NDEF_Size, uint8_t *pNDEF, I2C* mi2cChannel )
DiegoOstuni 0:de13951f30f6 500 {
DiegoOstuni 0:de13951f30f6 501 return NfcTag_WriteNDEF( NDEF_Size, pNDEF, mi2cChannel );
DiegoOstuni 0:de13951f30f6 502
DiegoOstuni 0:de13951f30f6 503 }
DiegoOstuni 0:de13951f30f6 504
DiegoOstuni 0:de13951f30f6 505 /**
DiegoOstuni 0:de13951f30f6 506 * @brief This function append the record to an the NDEF in the TAG.
DiegoOstuni 0:de13951f30f6 507 * @param pRecord : pointer on the record with data to be written.
DiegoOstuni 0:de13951f30f6 508 * @retval NDEF_OK : NDEF file data written in the tag.
DiegoOstuni 0:de13951f30f6 509 * @retval NDEF_ERROR : not able to store NDEF in tag.
DiegoOstuni 0:de13951f30f6 510 * @retval NDEF_ERROR_MEMORY_INTERNAL : Cannot write to tag.
DiegoOstuni 0:de13951f30f6 511 * @retval NDEF_ERROR_NOT_FORMATED : CCFile data not supported or not present.
DiegoOstuni 0:de13951f30f6 512 * @retval NDEF_ERROR_MEMORY_TAG : Size not compatible with memory.
DiegoOstuni 0:de13951f30f6 513 * @retval NDEF_ERROR_LOCKED : Tag locked, cannot be write.
DiegoOstuni 0:de13951f30f6 514 */
DiegoOstuni 0:de13951f30f6 515 uint16_t NDEF_AppendRecord(sRecordInfo_t *Record, I2C* mi2cChannel )
DiegoOstuni 0:de13951f30f6 516 {
DiegoOstuni 0:de13951f30f6 517 uint16_t status;
DiegoOstuni 0:de13951f30f6 518 uint16_t NDEF_Size = 0;
DiegoOstuni 0:de13951f30f6 519 uint8_t* pData = NDEF_Buffer;
DiegoOstuni 0:de13951f30f6 520
DiegoOstuni 0:de13951f30f6 521 status = NDEF_getNDEFSize(&NDEF_Size, mi2cChannel);
DiegoOstuni 0:de13951f30f6 522 if(status != NDEF_OK) return status ;
DiegoOstuni 0:de13951f30f6 523
DiegoOstuni 0:de13951f30f6 524 if(NDEF_Size != 0)
DiegoOstuni 0:de13951f30f6 525 {
DiegoOstuni 0:de13951f30f6 526 // There are already records in the NDEF
DiegoOstuni 0:de13951f30f6 527 Record->RecordFlags &= ~MB_Mask;
DiegoOstuni 0:de13951f30f6 528
DiegoOstuni 0:de13951f30f6 529 status = NfcTag_ReadNDEF(pData, mi2cChannel);
DiegoOstuni 0:de13951f30f6 530 if(status != NDEF_OK) return status ;
DiegoOstuni 0:de13951f30f6 531
DiegoOstuni 0:de13951f30f6 532 uint8_t* pNdefRecord;
DiegoOstuni 0:de13951f30f6 533 sRecordInfo_t LastRecord;
DiegoOstuni 0:de13951f30f6 534 do {
DiegoOstuni 0:de13951f30f6 535 pNdefRecord = pData;
DiegoOstuni 0:de13951f30f6 536 NDEF_IdentifyBuffer(&LastRecord,pData);
DiegoOstuni 0:de13951f30f6 537 pData += LastRecord.PayloadOffset + LastRecord.PayloadLength;
DiegoOstuni 0:de13951f30f6 538 // TO DO: add a security condition to avoid infinite loop if NDEF file is corrupted
DiegoOstuni 0:de13951f30f6 539 } while(!(LastRecord.RecordFlags & ME_Mask));
DiegoOstuni 0:de13951f30f6 540 LastRecord.RecordFlags &= ~ME_Mask;
DiegoOstuni 0:de13951f30f6 541 *pNdefRecord = LastRecord.RecordFlags;
DiegoOstuni 0:de13951f30f6 542 } else {
DiegoOstuni 0:de13951f30f6 543 // This will be the first message in memory
DiegoOstuni 0:de13951f30f6 544 Record->RecordFlags |= MB_Mask;
DiegoOstuni 0:de13951f30f6 545 }
DiegoOstuni 0:de13951f30f6 546 Record->RecordFlags |= ME_Mask;
DiegoOstuni 0:de13951f30f6 547 uint32_t RecordLength = NDEF_WriteRecord(Record,pData, mi2cChannel);
DiegoOstuni 0:de13951f30f6 548
DiegoOstuni 0:de13951f30f6 549
DiegoOstuni 0:de13951f30f6 550 return NfcTag_WriteNDEF( NDEF_Size + RecordLength, NDEF_Buffer, mi2cChannel );
DiegoOstuni 0:de13951f30f6 551
DiegoOstuni 0:de13951f30f6 552 }
DiegoOstuni 0:de13951f30f6 553
DiegoOstuni 0:de13951f30f6 554
DiegoOstuni 0:de13951f30f6 555
DiegoOstuni 0:de13951f30f6 556 /**
DiegoOstuni 0:de13951f30f6 557 * @brief This function identify the NDEF message stored in tag.
DiegoOstuni 0:de13951f30f6 558 * @param pRecordStruct : Structure to fill with record information.
DiegoOstuni 0:de13951f30f6 559 * @param pNDEF : pointer on the NDEF message data.
DiegoOstuni 0:de13951f30f6 560 * @retval NDEF_OK : record struct filled.
DiegoOstuni 0:de13951f30f6 561 * @retval NDEF_ERROR : record struct not updated.
DiegoOstuni 0:de13951f30f6 562 */
DiegoOstuni 0:de13951f30f6 563 uint16_t NDEF_IdentifyBuffer( sRecordInfo_t *pRecordStruct, uint8_t* pNDEF )
DiegoOstuni 0:de13951f30f6 564 {
DiegoOstuni 0:de13951f30f6 565 uint16_t SizeOfRecordHeader, TypeNbByte, PayloadLengthField, IDLengthField, IDNbByte;
DiegoOstuni 0:de13951f30f6 566
DiegoOstuni 0:de13951f30f6 567 /* Is ID length field present */
DiegoOstuni 0:de13951f30f6 568 if( (*pNDEF) & IL_Mask )
DiegoOstuni 0:de13951f30f6 569 {
DiegoOstuni 0:de13951f30f6 570 IDLengthField = ID_LENGTH_FIELD;
DiegoOstuni 0:de13951f30f6 571 }
DiegoOstuni 0:de13951f30f6 572 else
DiegoOstuni 0:de13951f30f6 573 {
DiegoOstuni 0:de13951f30f6 574 IDLengthField = 0;
DiegoOstuni 0:de13951f30f6 575 }
DiegoOstuni 0:de13951f30f6 576
DiegoOstuni 0:de13951f30f6 577 /* it's a SR */
DiegoOstuni 0:de13951f30f6 578 if( (*pNDEF) & SR_Mask )
DiegoOstuni 0:de13951f30f6 579 {
DiegoOstuni 0:de13951f30f6 580 /* Analyse short record layout */
DiegoOstuni 0:de13951f30f6 581 TypeNbByte = pNDEF[1];
DiegoOstuni 0:de13951f30f6 582 PayloadLengthField = 1;
DiegoOstuni 0:de13951f30f6 583 if( IDLengthField == ID_LENGTH_FIELD )
DiegoOstuni 0:de13951f30f6 584 IDNbByte = pNDEF[3];
DiegoOstuni 0:de13951f30f6 585 else
DiegoOstuni 0:de13951f30f6 586 IDNbByte = 0;
DiegoOstuni 0:de13951f30f6 587 }
DiegoOstuni 0:de13951f30f6 588 else
DiegoOstuni 0:de13951f30f6 589 {
DiegoOstuni 0:de13951f30f6 590 /* Analyse normal record layout */
DiegoOstuni 0:de13951f30f6 591 TypeNbByte = pNDEF[1];
DiegoOstuni 0:de13951f30f6 592 PayloadLengthField = 4;
DiegoOstuni 0:de13951f30f6 593 if( IDLengthField == ID_LENGTH_FIELD )
DiegoOstuni 0:de13951f30f6 594 IDNbByte = pNDEF[6];
DiegoOstuni 0:de13951f30f6 595 else
DiegoOstuni 0:de13951f30f6 596 IDNbByte = 0;
DiegoOstuni 0:de13951f30f6 597 }
DiegoOstuni 0:de13951f30f6 598
DiegoOstuni 0:de13951f30f6 599 SizeOfRecordHeader = RECORD_FLAG_FIELD + TYPE_LENGTH_FIELD + PayloadLengthField + IDLengthField + TypeNbByte + IDNbByte;
DiegoOstuni 0:de13951f30f6 600
DiegoOstuni 0:de13951f30f6 601 /* it's a SR */
DiegoOstuni 0:de13951f30f6 602 if( pNDEF[0] & SR_Mask )
DiegoOstuni 0:de13951f30f6 603 {
DiegoOstuni 0:de13951f30f6 604 pRecordStruct->RecordFlags = pNDEF[0];
DiegoOstuni 0:de13951f30f6 605 pRecordStruct->TypeLength = TypeNbByte;
DiegoOstuni 0:de13951f30f6 606 pRecordStruct->PayloadLength = pNDEF[2];
DiegoOstuni 0:de13951f30f6 607 pRecordStruct->IDLength = IDNbByte;
DiegoOstuni 0:de13951f30f6 608 memcpy( pRecordStruct->Type, &pNDEF[3+IDLengthField], TypeNbByte );
DiegoOstuni 0:de13951f30f6 609 memcpy( pRecordStruct->ID, &pNDEF[3+IDLengthField+TypeNbByte], IDNbByte );
DiegoOstuni 0:de13951f30f6 610 pRecordStruct->PayloadOffset = SizeOfRecordHeader;
DiegoOstuni 0:de13951f30f6 611 }
DiegoOstuni 0:de13951f30f6 612 else
DiegoOstuni 0:de13951f30f6 613 {
DiegoOstuni 0:de13951f30f6 614 pRecordStruct->RecordFlags = pNDEF[0];
DiegoOstuni 0:de13951f30f6 615 pRecordStruct->TypeLength = TypeNbByte;
DiegoOstuni 0:de13951f30f6 616 pRecordStruct->PayloadLength = ( ((uint32_t)pNDEF[2]) << 24 ) |
DiegoOstuni 0:de13951f30f6 617 ( ((uint32_t)pNDEF[3]) << 16 ) |
DiegoOstuni 0:de13951f30f6 618 ( ((uint32_t)pNDEF[4]) << 8 )
DiegoOstuni 0:de13951f30f6 619 | pNDEF[5] ;
DiegoOstuni 0:de13951f30f6 620 pRecordStruct->IDLength = IDNbByte;
DiegoOstuni 0:de13951f30f6 621 memcpy( pRecordStruct->Type, &pNDEF[6+IDNbByte], TypeNbByte );
DiegoOstuni 0:de13951f30f6 622 memcpy( pRecordStruct->ID, &pNDEF[6+IDNbByte+TypeNbByte], IDNbByte );
DiegoOstuni 0:de13951f30f6 623 pRecordStruct->PayloadOffset = SizeOfRecordHeader;
DiegoOstuni 0:de13951f30f6 624 }
DiegoOstuni 0:de13951f30f6 625
DiegoOstuni 0:de13951f30f6 626 pRecordStruct->PayloadBufferAdd = &pNDEF[pRecordStruct->PayloadOffset];
DiegoOstuni 0:de13951f30f6 627
DiegoOstuni 0:de13951f30f6 628 NDEF_ParseRecordHeader( pRecordStruct );
DiegoOstuni 0:de13951f30f6 629
DiegoOstuni 0:de13951f30f6 630 return NDEF_OK;
DiegoOstuni 0:de13951f30f6 631 }
DiegoOstuni 0:de13951f30f6 632
DiegoOstuni 0:de13951f30f6 633 /**
DiegoOstuni 0:de13951f30f6 634 * @brief This function writes a record into a NDEF buffer. (update SR flag if required)
DiegoOstuni 0:de13951f30f6 635 * @param pRecord : Structure with record information to be written.
DiegoOstuni 0:de13951f30f6 636 * @param pNDEF : pointer on the NDEF buffer.
DiegoOstuni 0:de13951f30f6 637 * @retval Length : Length of the written data (in bytes)
DiegoOstuni 0:de13951f30f6 638 */
DiegoOstuni 0:de13951f30f6 639 uint32_t NDEF_WriteRecord( sRecordInfo_t *pRecord, uint8_t* pNDEF, I2C* mi2cChannel )
DiegoOstuni 0:de13951f30f6 640 {
DiegoOstuni 0:de13951f30f6 641 /************************************/
DiegoOstuni 0:de13951f30f6 642 /* 7 | 6 | 5 | 4 | 3 | 2 1 0 */
DiegoOstuni 0:de13951f30f6 643 /*----------------------------------*/
DiegoOstuni 0:de13951f30f6 644 /* MB ME CF SR IL TNF */
DiegoOstuni 0:de13951f30f6 645 /*----------------------------------*/
DiegoOstuni 0:de13951f30f6 646 /* TYPE LENGTH */
DiegoOstuni 0:de13951f30f6 647 /*----------------------------------*/
DiegoOstuni 0:de13951f30f6 648 /* PAYLOAD LENGTH 3 */
DiegoOstuni 0:de13951f30f6 649 /*----------------------------------*/
DiegoOstuni 0:de13951f30f6 650 /* PAYLOAD LENGTH 2 */
DiegoOstuni 0:de13951f30f6 651 /*----------------------------------*/
DiegoOstuni 0:de13951f30f6 652 /* PAYLOAD LENGTH 1 */
DiegoOstuni 0:de13951f30f6 653 /*----------------------------------*/
DiegoOstuni 0:de13951f30f6 654 /* PAYLOAD LENGTH 0 */
DiegoOstuni 0:de13951f30f6 655 /*----------------------------------*/
DiegoOstuni 0:de13951f30f6 656 /* ID LENGTH */
DiegoOstuni 0:de13951f30f6 657 /*----------------------------------*/
DiegoOstuni 0:de13951f30f6 658 /* TYPE */
DiegoOstuni 0:de13951f30f6 659 /*----------------------------------*/
DiegoOstuni 0:de13951f30f6 660 /* ID */
DiegoOstuni 0:de13951f30f6 661 /*----------------------------------*/
DiegoOstuni 0:de13951f30f6 662 /* PAYLOAD */
DiegoOstuni 0:de13951f30f6 663 /************************************/
DiegoOstuni 0:de13951f30f6 664 uint8_t * start = pNDEF;
DiegoOstuni 0:de13951f30f6 665
DiegoOstuni 0:de13951f30f6 666 // start by considering payload length
DiegoOstuni 0:de13951f30f6 667 if(pRecord->PayloadLength <= 0xFF)
DiegoOstuni 0:de13951f30f6 668 pRecord->RecordFlags |= SR_Mask;
DiegoOstuni 0:de13951f30f6 669 else
DiegoOstuni 0:de13951f30f6 670 pRecord->RecordFlags &= ~SR_Mask;
DiegoOstuni 0:de13951f30f6 671
DiegoOstuni 0:de13951f30f6 672 // Then start writing!
DiegoOstuni 0:de13951f30f6 673 *pNDEF++ = pRecord->RecordFlags;
DiegoOstuni 0:de13951f30f6 674
DiegoOstuni 0:de13951f30f6 675 *pNDEF++ = pRecord->TypeLength;
DiegoOstuni 0:de13951f30f6 676
DiegoOstuni 0:de13951f30f6 677 if (!(pRecord->RecordFlags & SR_Mask))
DiegoOstuni 0:de13951f30f6 678 {
DiegoOstuni 0:de13951f30f6 679 *pNDEF++ = (pRecord->PayloadLength >> 24) & 0xFF;
DiegoOstuni 0:de13951f30f6 680 *pNDEF++ = (pRecord->PayloadLength >> 16) & 0xFF ;
DiegoOstuni 0:de13951f30f6 681 *pNDEF++ = (pRecord->PayloadLength >> 8) & 0xFF;
DiegoOstuni 0:de13951f30f6 682 }
DiegoOstuni 0:de13951f30f6 683 *pNDEF++ = (pRecord->PayloadLength) & 0xFF;
DiegoOstuni 0:de13951f30f6 684
DiegoOstuni 0:de13951f30f6 685 if(pRecord->RecordFlags & IL_Mask)
DiegoOstuni 0:de13951f30f6 686 *pNDEF++ = (pRecord->IDLength);
DiegoOstuni 0:de13951f30f6 687
DiegoOstuni 0:de13951f30f6 688 memcpy(pNDEF,pRecord->Type,pRecord->TypeLength);
DiegoOstuni 0:de13951f30f6 689 pNDEF += pRecord->TypeLength;
DiegoOstuni 0:de13951f30f6 690
DiegoOstuni 0:de13951f30f6 691 if(pRecord->RecordFlags & IL_Mask)
DiegoOstuni 0:de13951f30f6 692 {
DiegoOstuni 0:de13951f30f6 693 memcpy(pNDEF,pRecord->ID,pRecord->IDLength);
DiegoOstuni 0:de13951f30f6 694 pNDEF += pRecord->IDLength;
DiegoOstuni 0:de13951f30f6 695 }
DiegoOstuni 0:de13951f30f6 696
DiegoOstuni 0:de13951f30f6 697 memcpy(pNDEF,pRecord->PayloadBufferAdd,pRecord->PayloadLength);
DiegoOstuni 0:de13951f30f6 698 pNDEF += pRecord->PayloadLength;
DiegoOstuni 0:de13951f30f6 699
DiegoOstuni 0:de13951f30f6 700 return (pNDEF - start);
DiegoOstuni 0:de13951f30f6 701 }
DiegoOstuni 0:de13951f30f6 702
DiegoOstuni 0:de13951f30f6 703 /**
DiegoOstuni 0:de13951f30f6 704 * @brief This function return the length a record data (update SR flag if required)
DiegoOstuni 0:de13951f30f6 705 * @param pRecord : Structure with record information
DiegoOstuni 0:de13951f30f6 706 * @retval Length : Length of the data (in bytes)
DiegoOstuni 0:de13951f30f6 707 */
DiegoOstuni 0:de13951f30f6 708 uint32_t NDEF_GetRecordLength( sRecordInfo_t *pRecord )
DiegoOstuni 0:de13951f30f6 709 {
DiegoOstuni 0:de13951f30f6 710 // start by considering payload length
DiegoOstuni 0:de13951f30f6 711 if(pRecord->PayloadLength <= 0xFF)
DiegoOstuni 0:de13951f30f6 712 pRecord->RecordFlags |= SR_Mask;
DiegoOstuni 0:de13951f30f6 713 else
DiegoOstuni 0:de13951f30f6 714 pRecord->RecordFlags &= ~SR_Mask;
DiegoOstuni 0:de13951f30f6 715
DiegoOstuni 0:de13951f30f6 716 // Then compute the length
DiegoOstuni 0:de13951f30f6 717 uint32_t length = 1 + // Flags
DiegoOstuni 0:de13951f30f6 718 1 + // Type length
DiegoOstuni 0:de13951f30f6 719 ((pRecord->RecordFlags & SR_Mask)? 1 : 4) + // Payload length
DiegoOstuni 0:de13951f30f6 720 ((pRecord->RecordFlags & IL_Mask)? 1 : 0) + // ID length
DiegoOstuni 0:de13951f30f6 721 pRecord->TypeLength + // Type
DiegoOstuni 0:de13951f30f6 722 ((pRecord->RecordFlags & IL_Mask)? pRecord->IDLength : 0) + // ID
DiegoOstuni 0:de13951f30f6 723 pRecord->PayloadLength; // Payload;
DiegoOstuni 0:de13951f30f6 724
DiegoOstuni 0:de13951f30f6 725 return length;
DiegoOstuni 0:de13951f30f6 726 }
DiegoOstuni 0:de13951f30f6 727
DiegoOstuni 0:de13951f30f6 728 /**
DiegoOstuni 0:de13951f30f6 729 * @brief This function clears the NDEF file
DiegoOstuni 0:de13951f30f6 730 * @retval NDEF Status
DiegoOstuni 0:de13951f30f6 731 */
DiegoOstuni 0:de13951f30f6 732 uint16_t NDEF_ClearNDEF(I2C* mi2cChannel)
DiegoOstuni 0:de13951f30f6 733 {
DiegoOstuni 0:de13951f30f6 734 return NDEF_WriteNDEF(0 , NULL, mi2cChannel);
DiegoOstuni 0:de13951f30f6 735 }
DiegoOstuni 0:de13951f30f6 736
DiegoOstuni 0:de13951f30f6 737 /**
DiegoOstuni 0:de13951f30f6 738 * @}
DiegoOstuni 0:de13951f30f6 739 */
DiegoOstuni 0:de13951f30f6 740
DiegoOstuni 0:de13951f30f6 741 /**
DiegoOstuni 0:de13951f30f6 742 * @}
DiegoOstuni 0:de13951f30f6 743 */
DiegoOstuni 0:de13951f30f6 744
DiegoOstuni 0:de13951f30f6 745 /**
DiegoOstuni 0:de13951f30f6 746 * @}
DiegoOstuni 0:de13951f30f6 747 */
DiegoOstuni 0:de13951f30f6 748
DiegoOstuni 0:de13951f30f6 749 /******************* (C) COPYRIGHT 2015 STMicroelectronics *****END OF FILE****/