Fork for the GitHub
lib_NDEF_Vcard.cpp
- Committer:
- DiegoOstuni
- Date:
- 2019-11-14
- Revision:
- 0:de13951f30f6
File content as of revision 0:de13951f30f6:
/** ****************************************************************************** * @file lib_NDEF_Vcard.c * @author MMY Application Team * @version $Revision: 3210 $ * @date $Date: 2016-12-05 15:37:48 +0100 (Mon, 05 Dec 2016) $ * @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. * ****************************************************************************** */ /* Includes ------------------------------------------------------------------*/ #include "lib_NDEF_Vcard.h" /** @addtogroup lib_NDEF_Vcard * @ingroup libNDEF * @{ * @brief This part of the library manage the data which follow NFC forum organisation. */ /* This buffer contains the data sent/received by TAG */ extern uint8_t NDEF_Buffer []; static void NDEF_FillVcardStruct( uint8_t* pPayload, uint32_t PayloadSize, char* pKeyWord, uint32_t SizeOfKeyWord, uint8_t* pString ); static void NDEF_ExtractVcard( sRecordInfo_t *pRecordStruct, sVcardInfo *pVcardStruct ); /** * @brief This function extracts a Vcard particular property from a vCard. * @param pPayload Pointer on the vCard payload data of the vCard record. * @param PayloadSize Number of bytes in the vCard payload. * @param pKeyWord Pointer on the vCard property keyword to look for. * @param SizeOfKeyWord Number of bytes of the vCard property keyword we are looking for. * @param pString Pointer on a string used to return the vCard property read. */ 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 reads a Vcard record and stores data in a `sVcardInfo` structure. * @param pRecordStruct Pointer on the vCard record structure. * @param pVcardStruct Pointer on the `sCardInfo` structure to fill. */ static void NDEF_ExtractVcard( sRecordInfo_t *pRecordStruct, sVcardInfo *pVcardStruct ) { uint32_t PayloadSize; uint8_t* pPayload; PayloadSize = pRecordStruct->PayloadLength; /* 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, GEN_ADDRESS, strlen(GEN_ADDRESS), (uint8_t*)(pVcardStruct->Address) ); 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, GEN_EMAIL, strlen(GEN_EMAIL), (uint8_t*)(pVcardStruct->Email) ); 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 */ } } /** * @brief This function reads a Vcard record and stores data in a `sVcardInfo` structure. * @param pRecordStruct Pointer on the vCard record structure. * @param pVcardStruct Pointer on the `sCardInfo` structure to fill. * @retval NDEF_OK The Vcard information has been retrieved. * @retval NDEF_ERROR Not able to retrieve the Vcard information. */ uint16_t NDEF_ReadVcard( sRecordInfo_t *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 writes a NDEF message to the NFC tag with the Vcard data given in a `sVcardInfo` structure. * @param pVcardStruct Pointer on a `sVcardInfo` structure containing the Vcard information. * @retval NDEF_OK NDEF file data written in the tag. * @retval NDEF_ERROR Not able to store the 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, I2C* mi2cChannel ) { uint16_t status = NDEF_ERROR, Offset = 0; NDEF_PrepareVcardMessage( pVcardStruct, NDEF_Buffer, &Offset ); status = NfcTag_WriteNDEF( Offset , NDEF_Buffer, mi2cChannel ); return status; } /** * @brief This function computes the size of a Vcard record from the data given in the `sVcardInfo` structure. * @param pVcardStruct Pointer on a `sVcardInfo` structure containing the Vcard information. * @return vCard record data size in bytes (excluding record metadata). */ uint32_t NDEF_GetVcardLength( sVcardInfo *pVcardStruct) { uint32_t PayloadSize = 0; /* "BEGIN:VCARD\r\n" */ PayloadSize += BEGIN_STRING_SIZE; PayloadSize += VCARD_STRING_SIZE; PayloadSize += LIMIT_STRING_SIZE; /* "VERSION:2.1\r\n" */ PayloadSize += VERSION_STRING_SIZE; PayloadSize += VCARD_VERSION_2_1_SIZE; PayloadSize += LIMIT_STRING_SIZE; /* "N:\r\n" */ if(*pVcardStruct->Name != '\0') { PayloadSize += VCARD_NAME_STRING_SIZE; PayloadSize += strlen( pVcardStruct->Name ); PayloadSize += LIMIT_STRING_SIZE; } /* "FN:\r\n" */ if(*pVcardStruct->FirstName != '\0') { PayloadSize += FIRSTNAME_STRING_SIZE; PayloadSize += strlen( pVcardStruct->FirstName ); PayloadSize += LIMIT_STRING_SIZE; } if(*pVcardStruct->Title != '\0') { /* "TITLE:\r\n" */ PayloadSize += TITLE_STRING_SIZE; PayloadSize += strlen( pVcardStruct->Title ); PayloadSize += LIMIT_STRING_SIZE; } if(*pVcardStruct->Org != '\0') { /* "ORG:\r\n" */ PayloadSize += ORG_STRING_SIZE; PayloadSize += strlen( pVcardStruct->Org ); PayloadSize += LIMIT_STRING_SIZE; } if(*pVcardStruct->Url != '\0') { /* "URL:\r\n" */ PayloadSize += URL_STRING_SIZE; PayloadSize += strlen( pVcardStruct->Url ); PayloadSize += LIMIT_STRING_SIZE; } if(*pVcardStruct->HomeAddress != '\0') { /* "ADR;HOME:\r\n" */ PayloadSize += HOME_ADDRESS_STRING_SIZE; PayloadSize += strlen( pVcardStruct->HomeAddress ); PayloadSize += LIMIT_STRING_SIZE; } if(*pVcardStruct->WorkAddress != '\0') { /* "ADR;WORK:\r\n" */ PayloadSize += WORK_ADDRESS_STRING_SIZE; PayloadSize += strlen( pVcardStruct->WorkAddress ); PayloadSize += LIMIT_STRING_SIZE; } if(*pVcardStruct->HomeTel != '\0') { /* "TEL;HOME:\r\n" */ PayloadSize += HOME_TEL_STRING_SIZE; PayloadSize += strlen( pVcardStruct->HomeTel ); PayloadSize += LIMIT_STRING_SIZE; } if(*pVcardStruct->WorkTel != '\0') { /* "TEL;WORK:\r\n" */ PayloadSize += WORK_TEL_STRING_SIZE; PayloadSize += strlen( pVcardStruct->WorkTel ); PayloadSize += LIMIT_STRING_SIZE; } if(*pVcardStruct->CellTel != '\0') { /* "TEL;CELL:\r\n" */ PayloadSize += CELL_TEL_STRING_SIZE; PayloadSize += strlen( pVcardStruct->CellTel ); PayloadSize += LIMIT_STRING_SIZE; } if(*pVcardStruct->HomeEmail != '\0') { /* "EMAIL;HOME:\r\n" */ PayloadSize += HOME_EMAIL_STRING_SIZE; PayloadSize += strlen( pVcardStruct->HomeEmail ); PayloadSize += LIMIT_STRING_SIZE; } if(*pVcardStruct->WorkEmail != '\0') { /* "EMAIL;WORK:\r\n" */ PayloadSize += WORK_EMAIL_STRING_SIZE; PayloadSize += strlen( pVcardStruct->WorkEmail ); PayloadSize += LIMIT_STRING_SIZE; } /* "END:VCARD\r\n" */ PayloadSize += END_STRING_SIZE; PayloadSize += VCARD_STRING_SIZE; /* PayloadSize += LIMIT_STRING_SIZE;*/ return PayloadSize; } /** * @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 */ uint32_t length = NDEF_GetVcardLength(pVcardStruct); if(length >= 0xFF) { pNDEFMessage[0] = 0xC2; /* Record Flag */ pNDEFMessage[1] = XVCARD_TYPE_STRING_LENGTH; pNDEFMessage[5] = length & 0xff; pNDEFMessage[4] = (length>>8) & 0xff; pNDEFMessage[3] = (length>>16) & 0xff; pNDEFMessage[2] = length>>24; memcpy( &pNDEFMessage[6], XVCARD_TYPE_STRING, XVCARD_TYPE_STRING_LENGTH ); /* Payload is positionned in the NDEF after record header */ PayloadSize = 6 + XVCARD_TYPE_STRING_LENGTH; } else { pNDEFMessage[0] = 0xD2; /* Record Flag */ pNDEFMessage[1] = XVCARD_TYPE_STRING_LENGTH; pNDEFMessage[2] = length; memcpy( &pNDEFMessage[3], XVCARD_TYPE_STRING, XVCARD_TYPE_STRING_LENGTH ); /* Payload is positionned in the NDEF after record header */ PayloadSize = 3 + XVCARD_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; /* "N:\r\n" */ if(*pVcardStruct->Name != '\0') { memcpy( &pNDEFMessage[PayloadSize], VCARD_NAME, VCARD_NAME_STRING_SIZE ); PayloadSize += VCARD_NAME_STRING_SIZE; memcpy( &pNDEFMessage[PayloadSize], pVcardStruct->Name, strlen(pVcardStruct->Name) ); PayloadSize += strlen( pVcardStruct->Name ); memcpy( &pNDEFMessage[PayloadSize], LIMIT, LIMIT_STRING_SIZE ); PayloadSize += LIMIT_STRING_SIZE; } /* "FN:\r\n" */ if(*pVcardStruct->FirstName != '\0') { 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; } if(*pVcardStruct->HomeTel != '\0') { /* "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; } if(*pVcardStruct->WorkTel != '\0') { /* "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; } if(*pVcardStruct->CellTel != '\0') { /* "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; } if(*pVcardStruct->HomeEmail != '\0') { /* "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; } if(*pVcardStruct->WorkEmail != '\0') { /* "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; } if(*pVcardStruct->HomeAddress != '\0') { /* "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; } if(*pVcardStruct->WorkAddress != '\0') { /* "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; } if(*pVcardStruct->Org != '\0') { /* "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; } if(*pVcardStruct->Title != '\0') { /* "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; } if(*pVcardStruct->Url != '\0') { /* "URL:\r\n" */ memcpy( &pNDEFMessage[PayloadSize], URL, URL_STRING_SIZE ); PayloadSize += URL_STRING_SIZE; memcpy( &pNDEFMessage[PayloadSize], pVcardStruct->Url, strlen(pVcardStruct->Url) ); PayloadSize += strlen( pVcardStruct->Url ); 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; */ } /** * @brief This function extracts binary data from a base64 representation. * @param input64 : pointer on the input data in base64. * @param binary : returned binary data. * @return Updated pointer on the input64 buffer (normal increment is 4 base64 char for 3 bytes of binary data, but special char are ignored) */ static uint8_t* from_base64(uint8_t *input64, uint32_t* binary) { /* Read 4 base64 character & translate them into 3 bytes binary */ *binary = 0; uint8_t base64_6bits; int i = 0; while(i<4) { if((*input64 >= 'A') && (*input64 <= 'Z')) { base64_6bits = *(input64++) - 'A'; } else if ((*input64 >= 'a') && (*input64 <= 'z')) { base64_6bits = *(input64++) - 'a' + 26; } else if ((*input64 >= '0') && (*input64 <= '9')) { base64_6bits = *(input64++) - '0' + 52; } else if (*input64 == '+') { base64_6bits = 62; input64++; } else if (*input64 == '/') { base64_6bits = 63; input64++; } else if (*input64 == '=') { base64_6bits = 0; input64++; } else { input64++; continue; } *binary |= base64_6bits << (6*(3-i)); i++; } *binary = ((*binary & 0xFF0000)>>16) | ((*binary & 0xFF)<<16) | (*binary & 0xFF00); return input64; } /** * @brief This function return the picture stored in a VCARD. * @param pPayload : pointer on the payload data of the NDEF message. * @param PayloadSize : number of data in the payload. * @param pPict : Pointer on the dpicture buffer (must be big enough to contain the picture - warning: no check is done in the function). */ int NDEF_getVcardPicture( uint8_t* pPayload, uint32_t PayloadSize, uint8_t* pPict ) { uint8_t* pSrcPict; /* Let's find the picture */ pSrcPict = pPayload; while( memcmp( pSrcPict, JPEG, JPEG_STRING_SIZE ) && (pSrcPict < (pPayload + PayloadSize)) ) { pSrcPict++; } while( (*pSrcPict != ':') && (pSrcPict < (pPayload + PayloadSize)) ) { pSrcPict++; } /* Picture start at next char */ pSrcPict++; /* Word found */ while( memcmp( pSrcPict, LIMIT, LIMIT_STRING_SIZE ) && (pSrcPict < (pPayload + PayloadSize) ) ) { uint32_t binary24; pSrcPict = from_base64(pSrcPict, &binary24); /* copy the 3 bytes read from the base64 data */ memcpy( pPict, &binary24, 3); pPict += 3; /* Ignore any line breaks */ while (*pSrcPict == 0x0A) { pSrcPict++; } } if(pSrcPict >= (pPayload + PayloadSize)) { /* problem when parsing the picture */ return 1; } else { /* picture found */ return 0; } } /** * @} */ /******************* (C) COPYRIGHT 2015 STMicroelectronics *****END OF FILE****/