2022-04-28 02:04:02 +02:00

300 lines
7.7 KiB
C

/******************************************************************************
* \attention
*
* <h2><center>&copy; COPYRIGHT 2019 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:
*
* 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.
*
******************************************************************************/
/*
* PROJECT: NDEF firmware
* Revision:
* LANGUAGE: ISO C99
*/
/*! \file
*
* \author
*
* \brief NDEF message
*
*/
/*
******************************************************************************
* INCLUDES
******************************************************************************
*/
#include "platform.h"
#include "st_errno.h"
#include "utils.h"
#include "ndef_record.h"
#include "ndef_message.h"
/*
******************************************************************************
* GLOBAL DEFINES
******************************************************************************
*/
#define NDEF_MAX_RECORD 10U /*!< Maximum number of records */
/*
******************************************************************************
* GLOBAL TYPES
******************************************************************************
*/
/*
******************************************************************************
* LOCAL VARIABLES
******************************************************************************
*/
static uint8_t ndefRecordPoolIndex = 0;
/*
******************************************************************************
* LOCAL FUNCTION PROTOTYPES
******************************************************************************
*/
/*****************************************************************************/
static ndefRecord* ndefAllocRecord(void)
{
static ndefRecord ndefRecordPool[NDEF_MAX_RECORD];
if (ndefRecordPoolIndex >= NDEF_MAX_RECORD)
{
return NULL;
}
return &ndefRecordPool[ndefRecordPoolIndex++];
}
/*
******************************************************************************
* GLOBAL FUNCTIONS
******************************************************************************
*/
/*****************************************************************************/
ReturnCode ndefMessageInit(ndefMessage* message)
{
if (message == NULL)
{
return ERR_PARAM;
}
message->record = NULL;
message->info.length = 0;
message->info.recordCount = 0;
ndefRecordPoolIndex = 0;
return ERR_NONE;
}
/*****************************************************************************/
ReturnCode ndefMessageGetInfo(const ndefMessage* message, ndefMessageInfo* info)
{
ndefRecord* record;
uint32_t length = 0;
uint32_t recordCount = 0;
if ( (message == NULL) || (info == NULL) )
{
return ERR_PARAM;
}
record = message->record;
while (record != NULL)
{
length += ndefRecordGetLength(record);
recordCount++;
record = record->next;
}
info->length = length;
info->recordCount = recordCount;
return ERR_NONE;
}
/*****************************************************************************/
uint32_t ndefMessageGetRecordCount(const ndefMessage* message)
{
ndefMessageInfo info;
if (ndefMessageGetInfo(message, &info) == ERR_NONE)
{
return info.recordCount;
}
return 0;
}
/*****************************************************************************/
ReturnCode ndefMessageAppend(ndefMessage* message, ndefRecord* record)
{
if ( (message == NULL) || (record == NULL) )
{
return ERR_PARAM;
}
/* Clear the Message Begin bit */
ndefHeaderClearMB(record);
/* Record is appended so it is the last in the list, set the Message End bit */
ndefHeaderSetME(record);
record->next = NULL;
if (message->record == NULL)
{
/* Set the Message Begin bit for the first record only */
ndefHeaderSetMB(record);
message->record = record;
}
else
{
ndefRecord* current = message->record;
/* Go through the list of records */
while (current->next != NULL)
{
current = current->next;
}
/* Clear the Message End bit to the record before the one being appended */
ndefHeaderClearME(current);
/* Append to the last record */
current->next = record;
}
message->info.length += ndefRecordGetLength(record);
message->info.recordCount += 1U;
return ERR_NONE;
}
/*****************************************************************************/
ReturnCode ndefMessageDecode(const ndefConstBuffer* bufPayload, ndefMessage* message)
{
ReturnCode err;
uint32_t offset;
if ( (bufPayload == NULL) || (bufPayload->buffer == NULL) || (message == NULL) )
{
return ERR_PARAM;
}
err = ndefMessageInit(message);
if (err != ERR_NONE)
{
return err;
}
offset = 0;
while (offset < bufPayload->length)
{
ndefConstBuffer bufRecord;
ndefRecord* record = ndefAllocRecord();
if (record == NULL)
{
return ERR_NOMEM;
}
bufRecord.buffer = &bufPayload->buffer[offset];
bufRecord.length = bufPayload->length - offset;
err = ndefRecordDecode(&bufRecord, record);
if (err != ERR_NONE)
{
return err;
}
offset += ndefRecordGetLength(record);
err = ndefMessageAppend(message, record);
if (err != ERR_NONE)
{
return err;
}
}
return ERR_NONE;
}
/*****************************************************************************/
ReturnCode ndefMessageEncode(const ndefMessage* message, ndefBuffer* bufPayload)
{
ReturnCode err;
ndefMessageInfo info;
ndefRecord* record;
uint32_t offset;
uint32_t remainingLength;
if ( (message == NULL) || (bufPayload == NULL) || (bufPayload->buffer == NULL) )
{
return ERR_PARAM;
}
err = ndefMessageGetInfo(message, &info);
if ( (err != ERR_NONE) || (bufPayload->length < info.length) )
{
bufPayload->length = info.length;
return ERR_NOMEM;
}
/* Get the first record */
record = ndefMessageGetFirstRecord(message);
offset = 0;
remainingLength = bufPayload->length;
while (record != NULL)
{
ndefBuffer bufRecord;
bufRecord.buffer = &bufPayload->buffer[offset];
bufRecord.length = remainingLength;
err = ndefRecordEncode(record, &bufRecord);
if (err != ERR_NONE)
{
bufPayload->length = info.length;
return err;
}
offset += bufRecord.length;
remainingLength -= bufRecord.length;
record = ndefMessageGetNextRecord(record);
}
bufPayload->length = offset;
return ERR_NONE;
}