libNDEF library for the STMicroelectronics X-NUCLEO-NFC04A1

Dependents:   mbed-os-nfc04a1 Wiagro-Lanza34-XDot

Revision:
0:de13951f30f6
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/lib_NDEF_SMS.cpp	Thu Nov 14 10:34:11 2019 +0000
@@ -0,0 +1,370 @@
+/**
+  ******************************************************************************
+  * @file    lib_NDEF_SMS.c
+  * @author  MMY Application Team
+  * @version $Revision: 2702 $
+  * @date    $Date: 2016-07-13 18:45:05 +0200 (Wed, 13 Jul 2016) $
+  * @brief   This file help to manage NDEF file that represent SMS.
+ ******************************************************************************
+  * @attention
+  *
+  * <h2><center>&copy; 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_SMS.h"
+
+
+/** @addtogroup NFC_libraries
+  * @{
+  * @brief  <b>This is the library used to manage the content of the TAG (data)
+  *          But also the specific feature of the tag, for instance
+  *          password, gpo... </b>
+  */
+
+
+/** @addtogroup libNFC_FORUM
+  * @{
+  *	@brief  This part of the library manage data which follow NFC forum organisation.
+  */
+
+/**
+ * @brief  This buffer contains the data send/received by TAG
+ */
+extern uint8_t NDEF_Buffer [];
+
+/** @defgroup libSMS_Private_Functions
+  * @{
+  */
+
+static void NDEF_FillSMSStruct( uint8_t* pPayload, uint32_t PayloadSize, sSMSInfo *pSMSStruct );
+static void NDEF_ReadURI_SMS( sRecordInfo_t *pRecordStruct, sSMSInfo *pSMSStruct );
+
+/**
+  * @brief  This function fill SMS structure with information of NDEF message.
+  * @param  pPayload : pointer on the payload data of the NDEF message.
+  * @param  PayloadSize : number of data in the payload.
+  * @param  pSMSStruct : pointer on the structure to fill.
+  */
+static void NDEF_FillSMSStruct( uint8_t* pPayload, uint32_t PayloadSize, sSMSInfo *pSMSStruct )
+{
+  uint8_t* pLastByteAdd, *pLook4Word, *pEndString;
+  char* pKeyWord;
+  uint32_t SizeOfKeyWord;
+  pEndString = 0;
+
+  pKeyWord = SMS_TYPE_STRING;
+  SizeOfKeyWord = SMS_TYPE_STRING_LENGTH;
+
+  /* First character force to NULL in case not matching found */
+  *pSMSStruct->PhoneNumber = 0;
+  *pSMSStruct->Message = 0;
+
+  /* Interesting information are stored before picture if any */
+  /* Moreover picture is not used in this demonstration SW */
+  pLastByteAdd = (uint8_t*)(pPayload + PayloadSize);
+
+  pLook4Word = pPayload;
+  while( memcmp( pLook4Word, pKeyWord, SizeOfKeyWord ) && (pLook4Word < pLastByteAdd) )
+  {
+    pLook4Word++;
+  }
+
+  /* Retrieve phone number */
+  if( pLook4Word != pLastByteAdd )
+  {
+    pLook4Word += SizeOfKeyWord;
+    pEndString = pLook4Word;
+    while( memcmp( pEndString, URI_FIRST_DATA_END, URI_FIRST_DATA_END_LENGTH ) && (pEndString < pLastByteAdd) )
+    {
+      pEndString++;
+    }
+    if( pEndString != pLastByteAdd )
+    {
+      memcpy( pSMSStruct->PhoneNumber, pLook4Word, pEndString-pLook4Word );
+      /* add end of string character */
+      pSMSStruct->PhoneNumber[pEndString-pLook4Word] = 0;
+    }
+  }
+  pEndString += URI_FIRST_DATA_END_LENGTH;
+  pLook4Word = pEndString;
+
+  /* check if e-mail subject is present */
+  if( !memcmp( pLook4Word, MESSAGE_BEGIN_STRING, MESSAGE_BEGIN_STRING_LENGTH ) )
+  {
+    pEndString += MESSAGE_BEGIN_STRING_LENGTH;
+    /* Retrieve message */
+    memcpy( pSMSStruct->Message, pEndString, PayloadSize - (pEndString - pPayload) );
+    /* add end of string character */
+    pSMSStruct->Message[PayloadSize-(pEndString-pPayload)] = 0;
+  }
+}
+
+/**
+  * @brief  This function read the SMS and store data in a structure.
+  * @param  pRecordStruct : Pointer on the record structure.
+  * @param  pSMSStruct : pointer on the structure to fill.
+  */
+static void NDEF_ReadURI_SMS( sRecordInfo_t *pRecordStruct, sSMSInfo *pSMSStruct )
+{
+  uint8_t* pPayload;
+  uint32_t PayloadSize;
+
+  PayloadSize = pRecordStruct->PayloadLength;
+
+  /* Read record header */
+  pPayload = (uint8_t*)(pRecordStruct->PayloadBufferAdd);
+
+  if( pRecordStruct->NDEF_Type == URI_SMS_TYPE )
+    NDEF_FillSMSStruct( pPayload , PayloadSize, pSMSStruct );
+
+}
+
+/**
+  * @}
+  */
+
+/** @defgroup libSMS_Public_Functions
+  * @{
+  * @brief  This file is used to manage SMS (stored or loaded in tag)
+  */ 
+
+/**
+  * @brief  This function read NDEF and retrieve SMS information if any.
+  * @param  pRecordStruct : Pointer on the record structure.
+  * @param  pSMSStruct : pointer on the structure to fill.
+  * @retval NDEF_OK : SMS information from NDEF have been retrieve.
+  * @retval NDEF_ERROR : Not able to retrieve SMS information.
+  */
+uint16_t NDEF_ReadSMS( sRecordInfo_t *pRecordStruct, sSMSInfo *pSMSStruct )
+{
+  uint16_t status = NDEF_ERROR;
+  sRecordInfo_t *pSPRecordStruct;
+  uint32_t PayloadSize, RecordPosition;
+  uint8_t* pData;
+
+  if( pRecordStruct->NDEF_Type == URI_SMS_TYPE )
+  {
+    NDEF_ReadURI_SMS( pRecordStruct, pSMSStruct );
+    status = NDEF_OK;
+  }
+  else if( pRecordStruct->NDEF_Type == SMARTPOSTER_TYPE )
+  {
+    for( RecordPosition = 0; RecordPosition < pRecordStruct->NbOfRecordInSPPayload; RecordPosition++ )
+    {
+      pSPRecordStruct = pRecordStruct->SPRecordStructAdd[RecordPosition];
+      if( pSPRecordStruct->NDEF_Type == URI_SMS_TYPE )
+      {
+        NDEF_ReadURI_SMS( pSPRecordStruct, pSMSStruct );
+        status = NDEF_OK;
+      }
+      if( pSPRecordStruct->NDEF_Type == TEXT_TYPE )
+      {
+        PayloadSize = pSPRecordStruct->PayloadLength;
+
+        /* The instruction content the UTF-8 language code that is not used here */
+        pData = (uint8_t*)pSPRecordStruct->PayloadBufferAdd;
+        PayloadSize -= *pData + 1; /* remove not usefull data */
+        pData += *pData + 1; /* set pointer on usefull data */
+
+        memcpy( pSMSStruct->Information, pData, PayloadSize );
+        /* add end of string character */
+        pSMSStruct->Information[PayloadSize] = 0;
+      }
+    }
+  }
+
+  return status;
+}
+
+/**
+  * @brief  This function write the NDEF file with the SMS data given in the structure.
+  * @param  pSMSStruct : pointer on structure that contain the SMS information.
+  * @retval NDEF_OK : NDEF file data written in the tag.
+  * @retval NDEF_ERROR : not able to store NDEF in tag.
+  * @retval NDEF_ERROR_MEMORY_INTERNAL : Cannot write to tag.
+  * @retval NDEF_ERROR_NOT_FORMATED : CCFile data not supported or not present.
+  * @retval NDEF_ERROR_MEMORY_TAG : Size not compatible with memory.
+  * @retval NDEF_ERROR_LOCKED : Tag locked, cannot be write.
+  */
+uint16_t NDEF_WriteSMS( sSMSInfo *pSMSStruct, I2C* mi2cChannel )
+{
+  uint16_t status = NDEF_ERROR, Offset = 0;
+
+  NDEF_PrepareSMSMessage( pSMSStruct, NDEF_Buffer, &Offset );
+
+  status = NfcTag_WriteNDEF( Offset , NDEF_Buffer, mi2cChannel );
+
+  return status;
+}
+
+/**
+  * @brief  This function write the NDEF file with the SMS data given in the structure.
+  * @param  pSMSStruct : pointer on structure that contain the SMS information.
+  * @param  pNDEFMessage : pointer on the NDEF message.
+  * @param  size : to store the size of the NDEF message generated.
+  */
+void NDEF_PrepareSMSMessage( sSMSInfo *pSMSStruct, uint8_t *pNDEFMessage, uint16_t *size )
+{
+  uint16_t Offset = 0;
+  uint32_t smsSize = 0;
+  uint32_t infoSize= 0;
+  uint32_t totalSize = 0;
+
+  /* SMS is an URI but can be included in a smart poster to add text to give instruction to user for instance */
+
+  /* SMS (smart poster) Record Header */
+/************************************/
+/*  7 |  6 |  5 |  4 |  3 | 2  1  0 */
+/*----------------------------------*/
+/* MB   ME   CF   SR   IL    TNF    */  /* <---- CF=0, IL=0 and SR=1 TNF=1 NFC Forum Well-known type*/
+/*----------------------------------*/
+/*          TYPE LENGTH             */
+/*----------------------------------*/
+/*        PAYLOAD LENGTH 3          */  /* <---- Used only if SR=0 */
+/*----------------------------------*/
+/*        PAYLOAD LENGTH 2          */  /* <---- Used only if SR=0 */
+/*----------------------------------*/
+/*        PAYLOAD LENGTH 1          */  /* <---- Used only if SR=0 */
+/*----------------------------------*/
+/*        PAYLOAD LENGTH 0          */
+/*----------------------------------*/
+/*          ID LENGTH               */  /* <---- Not Used  */
+/*----------------------------------*/
+/*              TYPE                */
+/*----------------------------------*/
+/*               ID                 */  /* <---- Not Used  */
+/************************************/
+
+  /* SMS : 1+sms:+tel+1+body=+message */
+  smsSize = 1 + SMS_TYPE_STRING_LENGTH + strlen(pSMSStruct->PhoneNumber) + URI_FIRST_DATA_END_LENGTH + 
+            MESSAGE_BEGIN_STRING_LENGTH + strlen(pSMSStruct->Message);
+
+  /* Check if a Smart poster is needed */
+  if( pSMSStruct->Information[0] != '\0' )
+  {
+    /* Info : 1+2+info */
+    infoSize = 1 + ISO_ENGLISH_CODE_STRING_LENGTH + strlen(pSMSStruct->Information);
+    /* Total */
+    totalSize = 4 + smsSize + 4 + infoSize;
+    if( smsSize > 255 ) totalSize += 3; /* Normal Email size */
+    if( infoSize > 255 ) totalSize += 3;  /* Normal Info size */
+
+    /* SmartPoster header */
+    if( totalSize > 255 )
+    {
+      pNDEFMessage[Offset++] = 0xC1;
+      pNDEFMessage[Offset++] = SMART_POSTER_TYPE_STRING_LENGTH;
+      pNDEFMessage[Offset++] = (totalSize & 0xFF000000) >> 24;
+      pNDEFMessage[Offset++] = (totalSize & 0x00FF0000) >> 16;
+      pNDEFMessage[Offset++] = (totalSize & 0x0000FF00) >> 8;
+      pNDEFMessage[Offset++] = totalSize & 0x000000FF;
+    }
+    else
+    {
+      pNDEFMessage[Offset++] = 0xD1;
+      pNDEFMessage[Offset++] = SMART_POSTER_TYPE_STRING_LENGTH;
+      pNDEFMessage[Offset++] = (uint8_t)totalSize;
+    }
+    memcpy( &pNDEFMessage[Offset], SMART_POSTER_TYPE_STRING, SMART_POSTER_TYPE_STRING_LENGTH );
+    Offset += SMART_POSTER_TYPE_STRING_LENGTH;
+  }
+
+  /* SMS header */
+  pNDEFMessage[Offset] = 0x81;
+  if( smsSize < 256 ) pNDEFMessage[Offset] |= 0x10;                      // Set the SR bit
+  if( pSMSStruct->Information[0] == '\0' ) pNDEFMessage[Offset] |= 0x40; // Set the ME bit
+  Offset++;
+
+  pNDEFMessage[Offset++] = URI_TYPE_STRING_LENGTH;
+  if( smsSize > 255 )
+  {
+    pNDEFMessage[Offset++] = (smsSize & 0xFF000000) >> 24;
+    pNDEFMessage[Offset++] = (smsSize & 0x00FF0000) >> 16;
+    pNDEFMessage[Offset++] = (smsSize & 0x0000FF00) >> 8;
+    pNDEFMessage[Offset++] = smsSize & 0x000000FF;
+  }
+  else
+  {
+    pNDEFMessage[Offset++] = (uint8_t)smsSize;
+  }
+  memcpy( &pNDEFMessage[Offset], URI_TYPE_STRING, URI_TYPE_STRING_LENGTH );
+  Offset += URI_TYPE_STRING_LENGTH;
+
+  /* SMS payload */
+  pNDEFMessage[Offset++] = URI_ID_0x00;
+  memcpy( &pNDEFMessage[Offset], SMS_TYPE_STRING, SMS_TYPE_STRING_LENGTH );
+  Offset += SMS_TYPE_STRING_LENGTH;
+  memcpy( &pNDEFMessage[Offset], pSMSStruct->PhoneNumber, strlen(pSMSStruct->PhoneNumber) );
+  Offset += strlen( pSMSStruct->PhoneNumber );
+  memcpy( &pNDEFMessage[Offset], URI_FIRST_DATA_END, URI_FIRST_DATA_END_LENGTH );
+  Offset += URI_FIRST_DATA_END_LENGTH;
+
+  memcpy( &pNDEFMessage[Offset], MESSAGE_BEGIN_STRING, MESSAGE_BEGIN_STRING_LENGTH );
+  Offset += MESSAGE_BEGIN_STRING_LENGTH;
+  memcpy( &pNDEFMessage[Offset], pSMSStruct->Message, strlen(pSMSStruct->Message) );
+  Offset += strlen( pSMSStruct->Message );
+
+  /* Information header */
+  if( pSMSStruct->Information[0] != '\0' )
+  {
+    if( infoSize > 255 )
+    {
+      pNDEFMessage[Offset++] = 0x41;
+      pNDEFMessage[Offset++] = TEXT_TYPE_STRING_LENGTH;
+      pNDEFMessage[Offset++] = (infoSize & 0xFF000000) >> 24;
+      pNDEFMessage[Offset++] = (infoSize & 0x00FF0000) >> 16;
+      pNDEFMessage[Offset++] = (infoSize & 0x0000FF00) >> 8;
+      pNDEFMessage[Offset++] = infoSize & 0x000000FF;
+    }
+    else
+    {
+      pNDEFMessage[Offset++] = 0x51;
+      pNDEFMessage[Offset++] = TEXT_TYPE_STRING_LENGTH;
+      pNDEFMessage[Offset++] = (uint8_t)infoSize;
+    }
+
+    memcpy( &pNDEFMessage[Offset], TEXT_TYPE_STRING, TEXT_TYPE_STRING_LENGTH );
+    Offset += TEXT_TYPE_STRING_LENGTH;
+    pNDEFMessage[Offset++] = ISO_ENGLISH_CODE_STRING_LENGTH; /* UTF-8 with x byte language code */
+    memcpy( &pNDEFMessage[Offset], ISO_ENGLISH_CODE_STRING, ISO_ENGLISH_CODE_STRING_LENGTH );
+    Offset += ISO_ENGLISH_CODE_STRING_LENGTH;
+
+    /* Information payload */
+    memcpy( &pNDEFMessage[Offset], pSMSStruct->Information, strlen(pSMSStruct->Information) );
+    Offset += strlen( pSMSStruct->Information );
+  }
+
+  *size = (uint16_t)(Offset);
+}
+
+
+/**
+  * @}
+  */
+
+/**
+  * @}
+  */
+
+/**
+  * @}
+  */
+
+/******************* (C) COPYRIGHT 2015 STMicroelectronics *****END OF FILE****/