u-boot/board/nm/common/bdparser.c

2100 lines
62 KiB
C

/******************************************************************************
* (c) COPYRIGHT 2009-2011 by NetModule AG, Switzerland. All rights reserved.
*
* The program(s) may only be used and/or copied with the written permission
* from NetModule AG or in accordance with the terms and conditions stipulated
* in the agreement contract under which the program(s) have been supplied.
*
* PACKAGE : Board descriptor
*
* ABSTRACT:
* This package implements board descriptor manipulation functions.
*
* HISTORY:
* Date Author Description
* 20091106 rb RFE-FB18392: created
* 20091110 rb Added checksum in header
* 20100121 rs Minor cleanup, const arguments specified
* 20100302 sma RFE-FB18392: created (partition)
* 20100322 th Adaptation WinCE and Win32 (includes/warnings)
* Added get bd info (type and name for standard entries)
* Added scan entries (init and get next)
* Added test scan entries (get entry)
* Added uint64 and partition64
* 20110104 rs General code cleanup (style guide), added new tags/types
* Added bufLen parameter for BD_GetInfo()
* Fixed wrong sizeof type in GetPartition()
* Changed 64 bit type to "long long" from struct
* Added BD_VerifySha1Hmac() function
*****************************************************************************/
/*--- includes --------------------------------------------------------------*/
#include "bdparser.h" /* own header file */
#include <asm/io.h>
/* Platform specific include files */
#ifdef BD_TARGET_WIN32
#include <string.h> /* memcpy, strlen, memset, memcmp */
#endif
#ifdef BD_TARGET_WINCE
#pragma warning(push)
#pragma warning(disable: 4115 4201 4204 4214)
#include <windows.h>
#pragma warning(pop)
#endif
#ifdef BD_TARGET_LINUX
#include <linux/string.h> /* memcpy, strlen, memset, memcmp */
#endif
#ifdef BD_TARGET_UBOOT
#include <common.h> /* memcpy, etc. */
#endif
#ifdef BD_TARGET_VXWORKS
#include "string.h"
// #include "stdlib.h"
// #include "stdio.h"
// #include "ioLib.h"
// #include "vxWorks.h"
#endif
/* Make sure asserts are enabled when unit tests are required */
#if defined(BD_CONF_UNIT_TESTS) && !defined (BD_CONF_WANT_ASSERT)
#error BD_CONF_UNIT_TESTS requires assertions
#endif
/*--- local variables -------------------------------------------------------*/
static const BD_Info bd_info[] = {
{ BD_Serial , BD_Type_String , "serial" },
{ BD_Production_Date , BD_Type_Date , "proddate" },
{ BD_Hw_Ver , BD_Type_UInt8 , "hwver" },
{ BD_Hw_Rel , BD_Type_UInt8 , "hwrel" },
{ BD_Prod_Name , BD_Type_String , "prod_name" },
{ BD_Prod_Variant , BD_Type_UInt16 , "prod_variant" },
{ BD_Prod_Compatibility , BD_Type_String , "prod_compatibility" },
{ BD_Eth_Mac , BD_Type_MAC , "eth_mac" },
{ BD_Ip_Addr , BD_Type_IPV4 , "ip_addr" },
{ BD_Ip_Netmask , BD_Type_IPV4 , "ip_netmask" },
{ BD_Ip_Gateway , BD_Type_IPV4 , "ip_gateway" },
{ BD_Usb_Device_Id , BD_Type_UInt16 , "usb_device_id" },
{ BD_Usb_Vendor_Id , BD_Type_UInt16 , "usb_vendor_id" },
{ BD_Ram_Size , BD_Type_UInt32 , "ram_size" },
{ BD_Ram_Size64 , BD_Type_UInt64 , "ram_size64" },
{ BD_Flash_Size , BD_Type_UInt32 , "flash_size" },
{ BD_Flash_Size64 , BD_Type_UInt64 , "flash_size64" },
{ BD_Eeeprom_Size , BD_Type_UInt32 , "eeprom_size" },
{ BD_Nv_Rram_Size , BD_Type_UInt32 , "nv_ram_size" },
{ BD_Cpu_Base_Clk , BD_Type_UInt32 , "cpu_base_clk" },
{ BD_Cpu_Core_Clk , BD_Type_UInt32 , "cpu_core_clk" },
{ BD_Cpu_Bus_Clk , BD_Type_UInt32 , "cpu_bus_clk" },
{ BD_Ram_Clk , BD_Type_UInt32 , "ram_clk" },
{ BD_Partition , BD_Type_Partition , "partition" },
{ BD_Partition64 , BD_Type_Partition64, "partition64" },
{ BD_Lcd_Type , BD_Type_UInt16 , "lcd_type" },
{ BD_Lcd_Backlight , BD_Type_UInt8 , "lcd_backlight" },
{ BD_Lcd_Contrast , BD_Type_UInt8 , "lcd_contrast" },
{ BD_Touch_Type , BD_Type_UInt16 , "touch_type" },
{ BD_Manufacturer_Id , BD_Type_String , "manufacturer_id" },
{ BD_Hmac_Sha1_4 , BD_Type_HMAC , "hmac-sha1" },
{ BD_Ui_Adapter_Type , BD_Type_UInt16 , "ui_adapter_type" },
{ PD_Dev_Tree , BD_Type_String , "pd_dev_tree" },
/* Guard entry, must be last in array (don't remove) */
{ BD_End , BD_Type_End , 0 },
};
/*--- local functions -------------------------------------------------------*/
static void bd_safeStrCpy( char* pDest, bd_size_t destLen,
const char* pSrc, bd_size_t srcLen )
{
bd_size_t bytesToCopy = 0;
/* Argument check */
BD_ASSERT( pDest != 0 );
BD_ASSERT( destLen >= 1 );
BD_ASSERT( pSrc != 0 );
BD_ASSERT( srcLen <= BD_MAX_ENTRY_LEN );
/* Copy string, truncate if necessary */
if ( srcLen <= (destLen - 1) )
{
/* Whole string fits into supplied buffer */
bytesToCopy = srcLen;
}
else
{
/* Truncate string to buffer size */
bytesToCopy = destLen - 1;
}
if ( bytesToCopy > 0 )
{
memcpy( pDest, pSrc, bytesToCopy );
}
pDest[bytesToCopy] = 0;
}
/*---------------------------------------------------------------------------*/
static bd_uint16_t bd_getUInt16( const void* pBuf )
{
const bd_uint8_t* pui8Buf = 0;
bd_uint16_t value;
BD_ASSERT( pBuf != 0 );
pui8Buf = (const bd_uint8_t*)pBuf;
value = (pui8Buf[0] << 8)
| (pui8Buf[1] << 0);
return value;
}
/*---------------------------------------------------------------------------*/
static bd_uint32_t bd_getUInt32( const void* pBuf )
{
const bd_uint8_t* pui8Buf = 0;
bd_uint32_t value;
BD_ASSERT( pBuf != 0 );
pui8Buf = (const bd_uint8_t*)pBuf;
value = (pui8Buf[0] << 24)
| (pui8Buf[1] << 16)
| (pui8Buf[2] << 8)
| (pui8Buf[3] << 0);
return value;
}
/*---------------------------------------------------------------------------*/
static bd_uint64_t bd_getUInt64( const void* pBuf )
{
const bd_uint8_t* pui8Buf = 0;
bd_uint64_t value;
int i;
BD_ASSERT( pBuf != 0 );
pui8Buf = (const bd_uint8_t*)pBuf;
value = 0;
for (i=0; i<8; i++)
{
value <<= 8;
value |= pui8Buf[i];
}
return value;
}
/*---------------------------------------------------------------------------*/
static bd_bool_t bd_getInfo( bd_uint16_t tag, BD_Type* pType, char* pName, bd_size_t bufLen )
{
bd_bool_t rc = BD_FALSE; /* assume error */
int index;
for ( index = 0; bd_info[index].tag != BD_End; index++ )
{
if ( bd_info[index].tag == tag )
{
BD_ASSERT( bd_info[index].pName != 0 );
/* Found desired entry */
rc = BD_TRUE;
if( pType != 0 )
{
/* Fill in type information */
*pType = bd_info[index].type;
}
if( pName != 0 )
{
/* Fill in tag name */
bd_safeStrCpy( pName, bufLen, bd_info[index].pName, strlen(bd_info[index].pName) );
}
break;
}
}
return rc;
}
/*---------------------------------------------------------------------------*/
static bd_bool_t bd_getNextEntry( const BD_Context* pCtx, BD_Entry* pEntry )
{
bd_bool_t rc = BD_FALSE; /* assume error */
const bd_uint8_t* pTemp = 0;
bd_uint16_t currTag = 0;
bd_uint16_t currLen = 0;
bd_bool_t first = BD_FALSE; /* assume error */
BD_ASSERT( pCtx != 0 );
BD_ASSERT( pEntry != 0 );
/* Make sure we don't read beyond entry is NULL */
if ( pEntry == 0 )
{
return rc;
}
/* Check for last entry*/
if ( pEntry->entry >= pCtx->entries )
{
return rc;
}
/* For the first entry starts with the context buffer else the entry buffer minus header 4 bytes */
if ( ( pEntry->pData == 0 ) )
{
pTemp = pCtx->pData;
first = BD_TRUE;
}
else
{
pTemp = pEntry->pData - 4;
first = BD_FALSE;
}
/* Make sure we don't read beyond data buffer is 0 */
if ( pTemp == 0 )
{
BD_ASSERT(BD_FALSE);
return rc;
}
/* Make sure we don't read beyond data buffer is valid range */
if ( pTemp < pCtx->pData )
{
BD_ASSERT(BD_FALSE);
return rc;
}
/* Make sure we don't read beyond data buffer when getting next tag/len */
if ( (pTemp + 4) > pCtx->pDataEnd )
{
BD_ASSERT(BD_FALSE);
return rc;
}
/* Read tag/length of current entry */
currTag = bd_getUInt16( pTemp + 0 );
currLen = bd_getUInt16( pTemp + 2 );
/* Validate length field */
if ( currLen > BD_MAX_ENTRY_LEN )
{
BD_ASSERT(BD_FALSE);
return rc;
}
/* Must not exceed data buffer */
if ( (pTemp + 4 + currLen) > pCtx->pDataEnd )
{
BD_ASSERT(BD_FALSE);
return rc;
}
if( first==BD_FALSE )
{
/* Advance to next entry */
pTemp += (4 + currLen);
/* Make sure we don't read beyond data buffer when getting next tag/len */
if ( (pTemp + 4) > pCtx->pDataEnd )
{
BD_ASSERT(BD_FALSE);
return rc;
}
/* Read tag/length of current entry */
currTag = bd_getUInt16( pTemp + 0 );
currLen = bd_getUInt16( pTemp + 2 );
/* Validate length field */
if ( currLen > BD_MAX_ENTRY_LEN )
{
BD_ASSERT(BD_FALSE);
return rc;
}
}
/* Fill the entry structure */
pEntry->tag = currTag;
pEntry->len = currLen;
pEntry->entry++;
pEntry->pData = pTemp + 4;
rc = BD_TRUE;
return rc;
}
/*---------------------------------------------------------------------------*/
static const void* bd_findEntry( const BD_Context* pCtx, bd_uint16_t tag,
bd_uint_t index, bd_uint16_t* pLen )
{
const void* pResult = 0;
const bd_uint8_t* pTemp = 0;
bd_uint_t currIndex = 0;
bd_uint_t currEntry = 0;
BD_ASSERT( pCtx != 0 );
BD_ASSERT( pCtx->initialized );
BD_ASSERT( index < pCtx->entries );
/* pLen is allowed to be 0, therefore no check is required. */
if ( pLen != 0 )
{
*pLen = 0;
}
/* Try to find desired entry in data buffer */
pTemp = (const bd_uint8_t*)pCtx->pData;
for (currEntry = 0; currEntry < pCtx->entries; currEntry++)
{
bd_uint16_t currTag = 0;
bd_uint16_t currLen = 0;
/* Make sure we don't read beyond data buffer when getting next tag/len */
if ( (pTemp + 4) > pCtx->pDataEnd )
{
BD_ASSERT(BD_FALSE);
break;
}
/* Read tag/length of current entry */
currTag = bd_getUInt16( pTemp + 0 );
currLen = bd_getUInt16( pTemp + 2 );
/* Validate length field */
if ( currLen > BD_MAX_ENTRY_LEN )
{
BD_ASSERT(BD_FALSE);
break;
}
/* Must not exceed data buffer */
if ( (pTemp + 4 + currLen) > pCtx->pDataEnd )
{
BD_ASSERT(BD_FALSE);
break;
}
if ( currTag == tag )
{
/* Desired entry found */
if ( currIndex == index )
{
/* Desired entry found (tag and index match) */
/* Return pointer to data area of entry */
pResult = pTemp + 4;
if ( pLen != 0 )
{
*pLen = currLen;
}
break;
}
else
{
/* Not yet the entry we wanted, look further */
currIndex++;
}
}
else if ( currTag == 0x0000 )
{
/* Sorry, entry not found -> aborting */
break;
}
/* Advance to next entry */
pTemp += (4 + currLen);
}
return pResult;
}
/*--- global functions ------------------------------------------------------*/
bd_bool_t BD_CheckHeader( BD_Context* pCtx, const void* pHeader )
{
const char* pTemp = 0;
bd_bool_t rc = BD_FALSE; /* assume error */
/* Argument check */
if ( (pCtx == 0)
|| (pHeader == 0)
)
{
return BD_FALSE;
}
/* Initialize context */
pCtx->headerOk = BD_FALSE;
pCtx->initialized = BD_FALSE;
pCtx->size = 0;
pCtx->entries = 0;
pCtx->pData = 0;
pCtx->pDataEnd = 0;
/* Check Identification */
pTemp = (const char*)pHeader;
if ( (pTemp[0] == 'B') && (pTemp[1] == 'D') && (pTemp[2] == 'V') && (pTemp[3] == '1') )
{
bd_uint16_t payloadLen = 0;
bd_uint16_t checksum = 0;
/* Valid ID -> Read payload length */
payloadLen = bd_getUInt16( pTemp+4 );
checksum = bd_getUInt16( pTemp+6 );
/* Validate length, abort on unreasonable values */
if ( payloadLen <= BD_MAX_LENGTH )
{
pCtx->size = payloadLen;
pCtx->checksum = checksum;
pCtx->headerOk = BD_TRUE;
rc = BD_TRUE;
}
else
{
/* Invalid length */
}
}
else
{
/* Unknown identification */
}
return rc;
}
/*---------------------------------------------------------------------------*/
bd_bool_t BD_ImportData( BD_Context* pCtx, const void* pData )
{
const bd_uint8_t* pTemp = 0;
bd_bool_t rc = BD_FALSE; /* assume error */
bd_uint16_t tmpChecksum = 0;
size_t i;
/* Argument check */
if ( (pCtx == 0)
|| (pData == 0)
|| !pCtx->headerOk /* BD_CheckHeader() has not yet been called */
)
{
return BD_FALSE;
}
/* Scan through data, check consistency */
BD_ASSERT( pCtx->size <= BD_MAX_LENGTH );
pCtx->entries = 0;
pCtx->pData = (const bd_uint8_t*)pData;
pCtx->pDataEnd = pCtx->pData + pCtx->size;
pTemp = (const bd_uint8_t*)pCtx->pData;
for (;;)
{
bd_uint16_t tag = 0;
bd_uint16_t len = 0;
/* Make sure we don't read beyond data buffer when getting next tag/len */
if ( (pTemp + 4) > pCtx->pDataEnd )
{
/* @@@ RS: This would be an error */
break;
}
/* Read tag/length of current entry */
tag = bd_getUInt16( pTemp + 0 );
len = bd_getUInt16( pTemp + 2 );
pTemp += 4;
/* Validate length field */
if ( len > BD_MAX_ENTRY_LEN )
{
/* @@@ RS: This would be an error */
break;
}
/* Must not exceed data buffer */
if ( (pTemp + len) > pCtx->pDataEnd )
{
/* @@@ RS: This would be an error */
break;
}
/* Stop if end tag found */
if ( tag == 0x0000 )
{
rc = BD_TRUE;
break;
}
/* Advance to next entry */
pTemp += len;
pCtx->entries++;
}
/* If parsing was Ok and header contained a checksum, verify it */
if ( rc && ( pCtx->checksum != 0 ) )
{
/* Reset pointer to the start of the data/payload buffer */
pTemp = (const bd_uint8_t*)pCtx->pData;
/* Compute running byte checksum */
for (i = 0; i < pCtx->size; i++)
{
tmpChecksum = (bd_uint16_t)( (tmpChecksum + pTemp[i]) & 0xFFFF );
}
if ( tmpChecksum != pCtx->checksum )
{
/* Checksum does not match */
rc = BD_FALSE;
}
}
if ( rc )
{
/* Everything ok */
pCtx->initialized = BD_TRUE;
}
return rc;
}
/*---------------------------------------------------------------------------*/
bd_bool_t BD_ExistsEntry( const BD_Context* pCtx, bd_uint16_t tag, bd_uint_t index )
{
const void* pData = 0; /* pointer to entry data */
bd_bool_t rc = BD_FALSE; /* assume error */
/* Argument check */
if ( (pCtx == 0)
|| !pCtx->initialized
|| (index >= pCtx->entries)
)
{
return BD_FALSE;
}
/* Try to find desired entry */
pData = bd_findEntry( pCtx, tag, index, 0 );
if ( pData != 0 )
{
rc = BD_TRUE;
}
return rc;
}
/*---------------------------------------------------------------------------*/
bd_bool_t BD_GetInfo( bd_uint16_t tag, BD_Type* pType, char *pName, bd_size_t bufLen )
{
/*
* It is allowed to call this function with either pType or pName
* set to 0. In this case the fields will not be filled out
*/
return bd_getInfo( tag, pType, pName, bufLen );
}
/*---------------------------------------------------------------------------*/
bd_bool_t BD_InitEntry( BD_Entry* pEntry )
{
/* Argument check */
if ( pEntry == 0 )
{
return BD_FALSE;
}
memset(pEntry, 0, sizeof(BD_Entry));
return BD_TRUE;
}
/*---------------------------------------------------------------------------*/
bd_bool_t BD_GetNextEntry( const BD_Context* pCtx, BD_Entry* pEntry )
{
/* Argument check */
if ( (pCtx == 0)
|| !pCtx->initialized
|| (pEntry == 0)
)
{
return BD_FALSE;
}
return bd_getNextEntry( pCtx, pEntry );
}
/*---------------------------------------------------------------------------*/
bd_bool_t BD_GetVoid( const BD_Context* pCtx, bd_uint16_t tag,
bd_uint_t index, bd_bool_t* pResult )
{
const void* pData = 0; /* pointer to entry data */
bd_uint16_t len = 0; /* len of entry (should be 2) */
/* Argument check */
if ( (pCtx == 0)
|| (pResult == 0)
|| !pCtx->initialized
|| (index >= pCtx->entries)
)
{
return BD_FALSE;
}
/* Clear result */
*pResult = BD_FALSE;
/* Try to find desired entry */
pData = bd_findEntry( pCtx, tag, index, &len );
/* Void tags necessarily have a length of 0 */
if ( (pData != 0) && (len == 0) )
{
*pResult = BD_TRUE;
}
return BD_TRUE;
}
/*---------------------------------------------------------------------------*/
bd_bool_t BD_GetUInt8( const BD_Context* pCtx, bd_uint16_t tag,
bd_uint_t index, bd_uint8_t* pResult )
{
const void* pData = 0; /* pointer to entry data */
bd_uint16_t len = 0; /* len of entry (should be 2) */
bd_bool_t rc = BD_FALSE; /* assume error */
/* Argument check */
if ( (pCtx == 0)
|| (pResult == 0)
|| !pCtx->initialized
|| (index >= pCtx->entries)
)
{
return BD_FALSE;
}
/* Clear result */
*pResult = 0;
/* Try to find desired entry */
pData = bd_findEntry( pCtx, tag, index, &len );
if ( (pData != 0) && (len == 1) )
{
*pResult = *(bd_uint8_t*)pData;
rc = BD_TRUE;
}
return rc;
}
/*---------------------------------------------------------------------------*/
bd_bool_t BD_GetUInt16( const BD_Context* pCtx, bd_uint16_t tag,
bd_uint_t index, bd_uint16_t* pResult )
{
const void* pData = 0; /* pointer to entry data */
bd_uint16_t len = 0; /* len of entry (should be 2) */
bd_bool_t rc = BD_FALSE; /* assume error */
/* Argument check */
if ( (pCtx == 0)
|| (pResult == 0)
|| !pCtx->initialized
|| (index >= pCtx->entries)
)
{
return BD_FALSE;
}
/* Clear result */
*pResult = 0;
/* Try to find desired entry */
pData = bd_findEntry( pCtx, tag, index, &len );
if ( (pData != 0) && (len == 2) )
{
*pResult = bd_getUInt16( pData );
rc = BD_TRUE;
}
return rc;
}
/*---------------------------------------------------------------------------*/
bd_bool_t BD_GetUInt32( const BD_Context* pCtx, bd_uint16_t tag,
bd_uint_t index, bd_uint32_t* pResult )
{
const void* pData = 0; /* pointer to entry data */
bd_uint16_t len = 0; /* len of entry (should be 4) */
bd_bool_t rc = BD_FALSE; /* assume error */
/* Argument check */
if ( (pCtx == 0)
|| (pResult == 0)
|| !pCtx->initialized
|| (index >= pCtx->entries)
)
{
return BD_FALSE;
}
/* Clear result */
*pResult = 0;
/* Try to find desired entry */
pData = bd_findEntry( pCtx, tag, index, &len );
if ( (pData != 0) && (len == 4) )
{
*pResult = bd_getUInt32( pData );
rc = BD_TRUE;
}
return rc;
}
/*---------------------------------------------------------------------------*/
bd_bool_t BD_GetUInt64( const BD_Context* pCtx, bd_uint16_t tag,
bd_uint_t index, bd_uint64_t* pResult )
{
const void* pData = 0; /* pointer to entry data */
bd_uint16_t len = 0; /* len of entry (should be 4) */
bd_bool_t rc = BD_FALSE; /* assume error */
/* Argument check */
if ( (pCtx == 0)
|| (pResult == 0)
|| !pCtx->initialized
|| (index >= pCtx->entries)
)
{
return BD_FALSE;
}
/* Clear result */
*pResult = 0;
/* Try to find desired entry */
pData = bd_findEntry( pCtx, tag, index, &len );
if ( (pData != 0) && (len == 8) )
{
*pResult = bd_getUInt64( pData );
rc = BD_TRUE;
}
return rc;
}
/*---------------------------------------------------------------------------*/
bd_bool_t BD_GetIPv4( const BD_Context* pCtx, bd_uint16_t tag,
bd_uint_t index, bd_uint32_t* pResult )
{
const void* pData = 0; /* pointer to entry data */
bd_uint16_t len = 0; /* len of entry (should be 4) */
bd_bool_t rc = BD_FALSE; /* assume error */
/* Argument check */
if ( (pCtx == 0)
|| (pResult == 0)
|| !pCtx->initialized
|| (index >= pCtx->entries)
)
{
return BD_FALSE;
}
/* Clear result */
*pResult = 0;
/* Try to find desired entry */
pData = bd_findEntry( pCtx, tag, index, &len );
if ( (pData != 0) && (len == 4) )
{
*pResult = bd_getUInt32( pData );
rc = BD_TRUE;
}
return rc;
}
/*---------------------------------------------------------------------------*/
bd_bool_t BD_GetMAC( const BD_Context* pCtx, bd_uint16_t tag,
bd_uint_t index, bd_uint8_t pResult[6] )
{
const void* pData = 0; /* pointer to entry data */
bd_uint16_t len = 0; /* len of entry (should be 4) */
bd_bool_t rc = BD_FALSE; /* assume error */
/* Argument check */
if ( (pCtx == 0)
|| (pResult == 0)
|| !pCtx->initialized
|| (index >= pCtx->entries)
)
{
return BD_FALSE;
}
/* Clear result */
memset( pResult, 0x00, 6 );
/* Try to find desired entry */
pData = bd_findEntry( pCtx, tag, index, &len );
if ( (pData != 0) && (len == 6) )
{
memcpy( pResult, pData, 6 );
rc = BD_TRUE;
}
return rc;
}
/*---------------------------------------------------------------------------*/
bd_bool_t BD_GetString( const BD_Context* pCtx, bd_uint16_t tag,
bd_uint_t index, char* pResult, bd_size_t bufLen )
{
const void* pData = 0; /* pointer to entry data */
bd_uint16_t len = 0;
bd_bool_t rc = BD_FALSE; /* assume error */
/* Argument check */
if ( (pCtx == 0)
|| (pResult == 0)
|| !pCtx->initialized
|| (index >= pCtx->entries)
|| (bufLen < 1)
)
{
return BD_FALSE;
}
BD_ASSERT( bufLen <= BD_MAX_ENTRY_LEN );
/* Clear result */
pResult[0] = 0;
/* Try to find desired entry */
pData = bd_findEntry( pCtx, tag, index, &len );
if ( pData != 0 )
{
bd_safeStrCpy( pResult, bufLen, pData, len );
rc = BD_TRUE;
}
return rc;
}
/*---------------------------------------------------------------------------*/
bd_bool_t BD_GetBlob( const BD_Context* pCtx, bd_uint16_t tag, bd_uint_t index,
char* pResult, bd_size_t bufLen, bd_size_t* pReadLen)
{
const void* pData = 0; /* pointer to entry data */
bd_uint16_t len = 0; /* len of entry */
bd_bool_t rc = BD_FALSE; /* assume error */
/* Argument check */
if ( (pCtx == 0)
|| (pResult == 0)
|| (pReadLen == 0)
|| !pCtx->initialized
|| (index >= pCtx->entries)
|| (bufLen < 1)
)
{
return BD_FALSE;
}
BD_ASSERT( bufLen <= BD_MAX_ENTRY_LEN );
/* Initialize output value */
*pReadLen = 0;
/* Try to find desired entry */
pData = bd_findEntry( pCtx, tag, index, &len );
if ( (pData != 0) && (len <= bufLen) )
{
/* Copy binary data to user provided buffer */
memcpy( pResult, pData, len );
*pReadLen = len;
rc = BD_TRUE;
}
return rc;
}
/*---------------------------------------------------------------------------*/
bd_bool_t BD_GetPartition( const BD_Context* pCtx, bd_uint16_t tag,
bd_uint_t index, BD_PartitionEntry* pResult )
{
const bd_uint8_t* pData = 0; /* pointer to entry data */
bd_uint16_t len = 0; /* len of entry */
bd_bool_t rc = BD_FALSE; /* assume error */
/* Argument check */
if ( (pCtx == 0)
|| (pResult == 0)
|| !pCtx->initialized
|| (index >= pCtx->entries)
)
{
return BD_FALSE;
}
/* Clear result */
memset( pResult, 0x00, sizeof(BD_PartitionEntry) );
/* Try to find desired entry */
pData = bd_findEntry( pCtx, tag, index, &len );
/* Size must be at least 10 to make sure we have all mandatory fields */
if ( ( pData != 0 ) && ( len >= 10 ) )
{
/* Copy the fix sized fields */
pResult->flags = *pData;
pData++;
pResult->type = *pData;
pData++;
pResult->offset = bd_getUInt32(pData);
pData+=sizeof(bd_uint32_t);
pResult->size = bd_getUInt32(pData);
pData+=sizeof(bd_uint32_t);
/* Copy the partition name */
len -= 10;
bd_safeStrCpy(pResult->name, sizeof(pResult->name), (const char*)pData, len);
rc = BD_TRUE;
}
return rc;
}
/*---------------------------------------------------------------------------*/
bd_bool_t BD_GetPartition64( const BD_Context* pCtx, bd_uint16_t tag,
bd_uint_t index, BD_PartitionEntry64* pResult )
{
const bd_uint8_t* pData = 0; /* pointer to entry data */
bd_uint16_t len = 0; /* len of entry */
bd_bool_t rc = BD_FALSE; /* assume error */
/* Argument check */
if ( (pCtx == 0)
|| (pResult == 0)
|| !pCtx->initialized
|| (index >= pCtx->entries)
)
{
return BD_FALSE;
}
/* Clear result */
memset( pResult, 0x00, sizeof(BD_PartitionEntry64) );
/* Try to find desired entry */
pData = bd_findEntry( pCtx, tag, index, &len );
/* Size must be at least 16 to make sure we have all mandatory fields */
if ( ( pData != 0 ) && (len >= 16) )
{
/* Copy the fix sized fields */
pResult->flags = *pData;
pData++;
pResult->type = *pData;
pData++;
pResult->options = *pData;
pData++;
pData+=5;
pResult->offset = bd_getUInt64(pData);
pData+=sizeof(bd_uint64_t);
pResult->size = bd_getUInt64(pData);
pData+=sizeof(bd_uint64_t);
/* Copy the partition name */
len -= 16;
bd_safeStrCpy(pResult->name, sizeof(pResult->name), (const char*)pData, len);
rc = BD_TRUE;
}
return rc;
}
/*---------------------------------------------------------------------------*/
#ifdef BD_CONF_HAS_HASH
bd_bool_t BD_VerifySha1Hmac( const BD_Context* pCtx, bd_uint16_t tag, bd_uint_t index, const void* pKey, bd_size_t keyLen )
{
const bd_uint8_t* pData = 0; /* pointer to entry data */
bd_uint16_t len = 0; /* len of entry */
bd_uint16_t hashDataLen = 0; /* number of bytes to hash */
const bd_uint8_t* pRefHash;
bd_uint8_t computedHash[160/8];
bd_bool_t rc = BD_FALSE; /* assume error */
/* Argument check */
if ( (pCtx == 0)
|| (pKey == 0)
|| !pCtx->initialized
|| (index >= pCtx->entries)
)
{
return BD_FALSE;
}
BD_ASSERT((keyLen >= 4) && (keyLen <= 256));
/* Try to find desired entry */
pData = bd_findEntry( pCtx, tag, index, &len );
if ( (pData != 0) && (len == 6) )
{
/* Determine amount of data to hash */
hashDataLen = bd_getUInt16(pData);
pData += 2;
BD_ASSERT( hashDataLen < BD_MAX_LENGTH );
/* Remember hash value specified in tag */
pRefHash = pData;
pData += 4;
/* Compute hash over specified range */
BD_SHA1_HASH_FUNC(pKey, keyLen, pData, hashDataLen, computedHash);
/* Compare computed hash value with the one stored in the tag */
if (memcmp(computedHash, pRefHash, 4) == 0)
{
/* Ok -> Hashes match */
rc = BD_TRUE;
}
}
return rc;
}
#endif /* BD_CONF_HAS_HASH */
/*--- unit test -------------------------------------------------------------*/
#ifdef BD_CONF_UNIT_TESTS
static void bd_testHelpers( void )
{
static const bd_uint8_t data[] = { 0x12, 0x34, 0x56, 0x78, 0x9a, 0xbc, 0xde, 0xf0 };
bd_uint64_t t64;
bd_uint32_t t32;
bd_uint16_t t16;
char tempBuf[4];
t16 = bd_getUInt16( data );
BD_ASSERT( t16 == 0x1234 );
t32 = bd_getUInt32( data );
BD_ASSERT( t32 == 0x12345678 );
t64 = bd_getUInt64( data );
BD_ASSERT( t64 == 0x123456789abcdef0ULL );
memset(tempBuf, 0xAA, 4);
bd_safeStrCpy(tempBuf, 4, "xy", 2);
BD_ASSERT(tempBuf[0] == 'x');
BD_ASSERT(tempBuf[1] == 'y');
BD_ASSERT(tempBuf[2] == 0);
memset(tempBuf, 0xAA, 4);
bd_safeStrCpy(tempBuf, 4, "abc", 3);
BD_ASSERT(tempBuf[2] == 'c');
BD_ASSERT(tempBuf[3] == 0);
memset(tempBuf, 0xAA, 4);
bd_safeStrCpy(tempBuf, 4, "bcde", 4);
BD_ASSERT(tempBuf[2] == 'd');
BD_ASSERT(tempBuf[3] == 0);
memset(tempBuf, 0xAA, 4);
bd_safeStrCpy(tempBuf, 4, "defghi", 6);
BD_ASSERT(tempBuf[2] == 'f');
BD_ASSERT(tempBuf[3] == 0);
}
/*---------------------------------------------------------------------------*/
static void bd_testCheckHeader( void )
{
static const bd_uint8_t hdrGood[] = { 'B', 'D', 'V', '1', 0x00, 0x10, 0x00, 0x00 };
static const bd_uint8_t hdrBad1[] = { 'B', 'X', 'Y', 'Z', 0x00, 0x10, 0x00, 0x00 };
static const bd_uint8_t hdrBad2[] = { 'B', 'D', 'V', '1', 0x10, 0x01, 0x00, 0x00 };
BD_Context bdCtx;
bd_bool_t rc;
/* No context, no header */
rc = BD_CheckHeader( 0, 0 );
BD_ASSERT( !rc );
/* No header */
rc = BD_CheckHeader( &bdCtx, 0 );
BD_ASSERT( !rc );
/* No context */
rc = BD_CheckHeader( 0, hdrGood );
BD_ASSERT( !rc );
/* Invalid header (identification) */
rc = BD_CheckHeader( &bdCtx, hdrBad1 );
BD_ASSERT( !rc );
/* Invalid header (length) */
rc = BD_CheckHeader( &bdCtx, hdrBad2 );
BD_ASSERT( !rc );
/* Ok */
rc = BD_CheckHeader( &bdCtx, hdrGood );
BD_ASSERT( rc );
BD_ASSERT( bdCtx.headerOk );
BD_ASSERT( bdCtx.size == 16 );
}
/*---------------------------------------------------------------------------*/
static void bd_testImport( void )
{
static const bd_uint8_t hdr1[] = { 'B', 'D', 'V', '1', 0x00, 0x04, 0x00, 0x00 };
static const bd_uint8_t data1[] = { 0x00, 0x00, 0x00, 0x00 };
static const bd_uint8_t hdr2[] = { 'B', 'D', 'V', '1', 0x00, 13, 0x00, 0x00 };
static const bd_uint8_t data2[] = { 0x00, 0x01, 0x00, 0x05, 'A', 'B', 'C', 'D', 'E', 0x00, 0x00, 0x00, 0x00 };
BD_Context bdCtx;
bd_bool_t rc;
/* Case 0: End tag only */
rc = BD_CheckHeader( &bdCtx, hdr1 );
BD_ASSERT( rc );
rc = BD_ImportData( &bdCtx, data1 );
BD_ASSERT( rc );
BD_ASSERT( bdCtx.initialized );
BD_ASSERT( bdCtx.entries == 0 );
/* Case 1: One string entry, end tag */
rc = BD_CheckHeader( &bdCtx, hdr2 );
BD_ASSERT( rc );
rc = BD_ImportData( &bdCtx, data2 );
BD_ASSERT( rc );
BD_ASSERT( bdCtx.initialized );
BD_ASSERT( bdCtx.entries == 1 );
}
/*---------------------------------------------------------------------------*/
static void bd_testChecksum( void )
{
/* 1 void tag + end tag with valid checksum */
static const bd_uint8_t hdr1[] = { 'B', 'D', 'V', '1', 0x00, 0x08, 0x00, 0x04 };
static const bd_uint8_t data1[] = { 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
/* 1 void tag + end tag with invalid checksum */
static const bd_uint8_t hdr2[] = { 'B', 'D', 'V', '1', 0x00, 0x08, 0x00, 0x02 };
static const bd_uint8_t data2[] = { 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
/* 1 void tag + end tag without checksum */
static const bd_uint8_t hdr3[] = { 'B', 'D', 'V', '1', 0x00, 0x08, 0x00, 0x00 };
static const bd_uint8_t data3[] = { 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
BD_Context bdCtx;
bd_bool_t rc;
/* Case 0: valid checksum */
rc = BD_CheckHeader( &bdCtx, hdr1 );
BD_ASSERT( rc );
rc = BD_ImportData( &bdCtx, data1 );
BD_ASSERT( rc );
BD_ASSERT( bdCtx.initialized );
BD_ASSERT( bdCtx.entries == 1 );
BD_ASSERT( bdCtx.checksum == 0x4 );
/* Case 1: invalid checksum */
rc = BD_CheckHeader( &bdCtx, hdr2 );
BD_ASSERT( rc );
rc = BD_ImportData( &bdCtx, data2 );
BD_ASSERT( !rc );
/* Case 2: no checksum */
rc = BD_CheckHeader( &bdCtx, hdr3 );
BD_ASSERT( rc );
rc = BD_ImportData( &bdCtx, data3 );
BD_ASSERT( rc );
BD_ASSERT( bdCtx.initialized );
BD_ASSERT( bdCtx.entries == 1 );
BD_ASSERT( bdCtx.checksum == 0 );
}
/*---------------------------------------------------------------------------*/
static void bd_testGetUInt( void )
{
static const bd_uint8_t data1[] = { 0x00, 0x01, 0x00, 0x04, 0x12, 0x34, 0x56, 0x78,
0x00, 0x01, 0x00, 0x04, 0xca, 0xfe, 0xba, 0xbe,
0x00, 0x02, 0x00, 0x02, 0x47, 0x11,
0x00, 0x00, 0x00, 0x00 };
static const bd_uint8_t hdr1[] = { 'B', 'D', 'V', '1', 0x00, sizeof(data1), 0x00, 0x00 };
BD_Context bdCtx;
bd_uint32_t result32;
bd_uint16_t result16;
bd_bool_t rc;
/* Initialize */
rc = BD_CheckHeader( &bdCtx, hdr1 );
BD_ASSERT( rc );
rc = BD_ImportData( &bdCtx, data1 );
BD_ASSERT( rc );
BD_ASSERT( bdCtx.entries == 3 );
/* Unknown tag */
rc = BD_ExistsEntry( &bdCtx, 1001, 0 );
BD_ASSERT( !rc );
/* Unknown index */
rc = BD_ExistsEntry( &bdCtx, 1, 2 );
BD_ASSERT( !rc );
/* Ok */
rc = BD_ExistsEntry( &bdCtx, 1, 0 );
BD_ASSERT( rc );
rc = BD_ExistsEntry( &bdCtx, 1, 1 );
BD_ASSERT( rc );
rc = BD_ExistsEntry( &bdCtx, 2, 0 );
BD_ASSERT( rc );
/* No context */
rc = BD_GetUInt32( 0, 1, 0, &result32 );
BD_ASSERT( !rc );
/* No result pointer */
rc = BD_GetUInt32( &bdCtx, 1, 0, 0 );
BD_ASSERT( !rc );
/* Index > number of entries */
rc = BD_GetUInt32( &bdCtx, 1, 3, &result32 );
BD_ASSERT( !rc );
/* Unknown tag */
rc = BD_GetUInt32( &bdCtx, 1001, 0, &result32 );
BD_ASSERT( !rc );
/* Entry with wrong size */
rc = BD_GetUInt32( &bdCtx, 2, 0, &result32 );
BD_ASSERT( !rc );
/* Ok: First entry */
rc = BD_GetUInt32( &bdCtx, 1, 0, &result32 );
BD_ASSERT( rc );
BD_ASSERT( result32 == 0x12345678 );
/* Ok: Second entry */
rc = BD_GetUInt32( &bdCtx, 1, 1, &result32 );
BD_ASSERT( rc );
BD_ASSERT( result32 == 0xcafebabe );
/* Ok: */
rc = BD_GetUInt16( &bdCtx, 2, 0, &result16 );
BD_ASSERT( rc );
BD_ASSERT( result16 == 0x4711 );
}
/*---------------------------------------------------------------------------*/
static void bd_testGetString( void )
{
static const bd_uint8_t data1[] = { 0x00, 0x01, 0x00, 0x05, 'A', 'B', 'C', 'D', 'E', 0x00, 0x00, 0x00, 0x00 };
static const bd_uint8_t hdr1[] = { 'B', 'D', 'V', '1', 0x00, sizeof(data1), 0x00, 0x00 };
BD_Context bdCtx;
char buffer[16];
bd_bool_t rc;
/* Initialize */
rc = BD_CheckHeader( &bdCtx, hdr1 );
BD_ASSERT( rc );
rc = BD_ImportData( &bdCtx, data1 );
BD_ASSERT( rc );
BD_ASSERT( bdCtx.initialized );
BD_ASSERT( bdCtx.entries == 1 );
/* Zero sized buffer */
rc = BD_GetString( &bdCtx, 1, 0, buffer, 0 );
BD_ASSERT(!rc);
/* One byte buffer (terminating 0 only) */
memset(buffer, 0xCC, sizeof(buffer));
rc = BD_GetString( &bdCtx, 1, 0, buffer, 1 );
BD_ASSERT(rc);
BD_ASSERT(buffer[0] == 0);
/* String exactly fits buffer */
memset(buffer, 0xCC, sizeof(buffer));
rc = BD_GetString( &bdCtx, 1, 0, buffer, 6 );
BD_ASSERT(rc);
BD_ASSERT(buffer[4] == 'E');
BD_ASSERT(buffer[5] == 0);
/* Buffer one too short */
memset(buffer, 0xCC, sizeof(buffer));
rc = BD_GetString( &bdCtx, 1, 0, buffer, 5 );
BD_ASSERT(rc);
BD_ASSERT(buffer[3] == 'D');
BD_ASSERT(buffer[4] == 0);
}
/*---------------------------------------------------------------------------*/
static void bd_testGetMAC( void )
{
static const bd_uint8_t data1[] = { 0x00, 0x11, 0x00, 0x06, 0x00, 0xA0, 0xBA, 0x12, 0x34, 0x56,
0x00, 0x00, 0x00, 0x00 };
static const bd_uint8_t hdr1[] = { 'B', 'D', 'V', '1', 0x00, sizeof(data1), 0x00, 0x00 };
BD_Context bdCtx;
bd_uint8_t buffer[6];
bd_bool_t rc;
/* Initialize */
rc = BD_CheckHeader( &bdCtx, hdr1 );
BD_ASSERT( rc );
rc = BD_ImportData( &bdCtx, data1 );
BD_ASSERT( rc );
BD_ASSERT( bdCtx.initialized );
BD_ASSERT( bdCtx.entries == 1 );
/* Non-existing entry */
memset(buffer, 0xCC, sizeof(buffer));
rc = BD_GetMAC( &bdCtx, 1017, 0, buffer );
BD_ASSERT(!rc);
BD_ASSERT(buffer[0] == 0);
BD_ASSERT(buffer[1] == 0);
BD_ASSERT(buffer[2] == 0);
BD_ASSERT(buffer[3] == 0);
BD_ASSERT(buffer[4] == 0);
BD_ASSERT(buffer[5] == 0);
/* Ok */
memset(buffer, 0xCC, sizeof(buffer));
rc = BD_GetMAC( &bdCtx, 17, 0, buffer );
BD_ASSERT(rc);
BD_ASSERT(buffer[0] == 0x00);
BD_ASSERT(buffer[1] == 0xA0);
BD_ASSERT(buffer[2] == 0xBA);
BD_ASSERT(buffer[3] == 0x12);
BD_ASSERT(buffer[4] == 0x34);
BD_ASSERT(buffer[5] == 0x56);
}
/*---------------------------------------------------------------------------*/
static void bd_testGetIPv4( void )
{ /* IP = 192.168.2.1 = 0xC0A80201 */
static const bd_uint8_t data1[] = { 0x00, 0x12, 0x00, 0x04, 0xC0, 0xA8, 0x02, 0x01,
0x00, 0x00, 0x00, 0x00 };
static const bd_uint8_t hdr1[] = { 'B', 'D', 'V', '1', 0x00, sizeof(data1), 0x00, 0x00 };
BD_Context bdCtx;
bd_uint32_t ipAddr;
bd_bool_t rc;
/* Initialize */
rc = BD_CheckHeader( &bdCtx, hdr1 );
BD_ASSERT( rc );
rc = BD_ImportData( &bdCtx, data1 );
BD_ASSERT( rc );
BD_ASSERT( bdCtx.initialized );
BD_ASSERT( bdCtx.entries == 1 );
/* Ok */
ipAddr = 0;
rc = BD_GetIPv4( &bdCtx, 18, 0, &ipAddr );
BD_ASSERT(rc);
BD_ASSERT(ipAddr == 0xC0A80201);
}
/*---------------------------------------------------------------------------*/
static void bd_testGetPartition( void )
{
/* Name with length zero */
static const bd_uint8_t data1[] = { 0x00, 0x18, 0x00, 0x0A, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08,
0x09, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x00 };
static const bd_uint8_t hdr1[] = { 'B', 'D', 'V', '1', 0x00, sizeof(data1), 0x00, 0x00 };
/* Name with length 5 */
static const bd_uint8_t data2[] = { 0x00, 0x18, 0x00, 0x0F, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08,
0x09, 0x0a, 'N', 'a', 'm', 'e', '5', 0x00, 0x00, 0x00, 0x00};
static const bd_uint8_t hdr2[] = { 'B', 'D', 'V', '1', 0x00, sizeof(data2), 0x00, 0x00 };
/* Name with length 16 */
static const bd_uint8_t data3[] = { 0x00, 0x18, 0x00, 0x1A, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08,
0x09, 0x0a, '0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
'a', 'b', 'c', 'd', 'e', 'f', 0x00, 0x00, 0x00, 0x00 };
static const bd_uint8_t hdr3[] = { 'B', 'D', 'V', '1', 0x00, sizeof(data3), 0x00, 0x00 };
/* Name with length 17 */
static const bd_uint8_t data4[] = { 0x00, 0x18, 0x00, 0x1B, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08,
0x09, 0x0a, '0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
'A', 'B', 'C', 'D', 'E', 'F', 'x', 0x00, 0x00, 0x00, 0x00 };
static const bd_uint8_t hdr4[] = { 'B', 'D', 'V', '1', 0x00, sizeof(data4), 0x00, 0x00 };
/* Too short BD */
static const bd_uint8_t data5[] = { 0x00, 0x18, 0x00, 0x09, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08,
0x09, 0x00, 0x00 };
static const bd_uint8_t hdr5[] = { 'B', 'D', 'V', '1', 0x00, sizeof(data5), 0x00, 0x00, 0x00, 0x00 };
BD_Context bdCtx;
BD_PartitionEntry bd_partitionEntry;
bd_bool_t rc;
/* Initialize */
rc = BD_CheckHeader( &bdCtx, hdr1 );
BD_ASSERT( rc );
rc = BD_ImportData( &bdCtx, data1 );
BD_ASSERT( rc );
BD_ASSERT( bdCtx.initialized );
BD_ASSERT( bdCtx.entries == 1 );
/* 0 buffer */
rc = BD_GetPartition( &bdCtx, BD_Partition, 0, 0 );
BD_ASSERT(!rc);
/* Check values */
rc = BD_GetPartition( &bdCtx, BD_Partition, 0, &bd_partitionEntry );
BD_ASSERT(rc);
BD_ASSERT(bd_partitionEntry.flags == 0x01);
BD_ASSERT(bd_partitionEntry.type == 0x02);
BD_ASSERT(bd_partitionEntry.size == 0x0708090a);
BD_ASSERT(bd_partitionEntry.offset == 0x03040506);
/* Check string length is 0 */
BD_ASSERT(bd_partitionEntry.name[0] == 0);
/* Check string length in bd 5 */
rc = BD_CheckHeader( &bdCtx, hdr2 );
BD_ASSERT( rc );
rc = BD_ImportData( &bdCtx, data2 );
BD_ASSERT( rc );
rc = BD_GetPartition( &bdCtx, BD_Partition, 0, &bd_partitionEntry );
BD_ASSERT(rc);
BD_ASSERT(bd_partitionEntry.name[0] == 'N');
BD_ASSERT(bd_partitionEntry.name[4] == '5');
BD_ASSERT(bd_partitionEntry.name[5] == 0);
/* Check string length in bd 16*/
rc = BD_CheckHeader( &bdCtx, hdr3 );
BD_ASSERT( rc );
rc = BD_ImportData( &bdCtx, data3 );
BD_ASSERT( rc );
rc = BD_GetPartition( &bdCtx, BD_Partition, 0, &bd_partitionEntry );
BD_ASSERT(rc);
BD_ASSERT(bd_partitionEntry.name[0] == '0');
BD_ASSERT(bd_partitionEntry.name[15] == 'f');
BD_ASSERT(bd_partitionEntry.name[16] == 0);
/* Check string length in bd 17 */
rc = BD_CheckHeader( &bdCtx, hdr4 );
BD_ASSERT( rc );
rc = BD_ImportData( &bdCtx, data4 );
BD_ASSERT( rc );
rc = BD_GetPartition( &bdCtx, BD_Partition, 0, &bd_partitionEntry );
BD_ASSERT(rc);
BD_ASSERT(bd_partitionEntry.name[0] == '0');
BD_ASSERT(bd_partitionEntry.name[15] == 'F');
BD_ASSERT(bd_partitionEntry.name[16] == 0);
/* BD too short */
rc = BD_CheckHeader( &bdCtx, hdr5 );
BD_ASSERT( rc );
rc = BD_ImportData( &bdCtx, data5 );
BD_ASSERT( !rc );
}
/*---------------------------------------------------------------------------*/
static void bd_testGetEntry( void )
{
#define BD16(var) (bd_uint8_t)(((var) >> 8) & 0x00FF), (bd_uint8_t)(((var) >> 0) & 0x00FF)
typedef struct _BD_IndexTable
{
bd_uint16_t tag; /**< Tag of entry */
bd_uint_t index; /**< Index of entry */
}
BD_IndexTable;
static const bd_uint_t num_entries = 51; // without end tag
static const bd_uint8_t data1[] =
{
// serial[0]: 'Serial'
(bd_uint8_t)(BD_Serial>>8), (bd_uint8_t)(BD_Serial>>0), 0x00, 0x06,
'S', 'e', 'r', 'i', 'a', 'l',
// date[0]: '01.01.2000'
(bd_uint8_t)(BD_Production_Date>>8), (bd_uint8_t)(BD_Production_Date>>0), 0x00, 0x0A,
'0', '1', '.', '0', '1', '.', '2', '0', '0', '0',
// version[0]: 1
(bd_uint8_t)(BD_Hw_Ver>>8), (bd_uint8_t)(BD_Hw_Ver>>0), 0x00, sizeof(bd_uint8_t),
0x01,
// release[0]: 0
(bd_uint8_t)(BD_Hw_Rel>>8), (bd_uint8_t)(BD_Hw_Rel>>0), 0x00, sizeof(bd_uint8_t),
0x00,
// name[0]: 'Product'
(bd_uint8_t)(BD_Prod_Name>>8), (bd_uint8_t)(BD_Prod_Name>>0), 0x00, 0x07,
'P', 'r', 'o', 'd', 'u', 'c', 't',
// variant[0]: 0xF0A5
(bd_uint8_t)(BD_Prod_Variant>>8), (bd_uint8_t)(BD_Prod_Variant>>0), 0x00, sizeof(bd_uint16_t),
0xF0, 0xA5,
// compatibility[0]: 'Comp'
(bd_uint8_t)(BD_Prod_Compatibility>>8), (bd_uint8_t)(BD_Prod_Compatibility>>0), 0x00, 0x04,
'C', 'o', 'm', 'p',
// mac 05:14:23:32:41:50
(bd_uint8_t)(BD_Eth_Mac>>8), (bd_uint8_t)(BD_Eth_Mac>>0), 0x00, 0x06,
0x05, 0x14, 0x23, 0x32, 0x41, 0x50,
// ipv4-addr[0]: 192.168.0.2
(bd_uint8_t)(BD_Ip_Addr>>8), (bd_uint8_t)(BD_Ip_Addr>>0), 0x00, sizeof(bd_uint32_t),
192, 168, 0, 2,
// ipv4-mask[0]: 255.255.255.0
(bd_uint8_t)(BD_Ip_Netmask>>8), (bd_uint8_t)(BD_Ip_Netmask>>0), 0x00, sizeof(bd_uint32_t),
255, 255, 255, 0,
// ipv4-gateway[0]: 192.168.0.1
(bd_uint8_t)(BD_Ip_Gateway>>8), (bd_uint8_t)(BD_Ip_Gateway>>0), 0x00, sizeof(bd_uint32_t),
192, 168, 0, 1,
// ipv4-addr[0]: 172.20.0.2
(bd_uint8_t)(BD_Ip_Addr>>8), (bd_uint8_t)(BD_Ip_Addr>>0), 0x00, sizeof(bd_uint32_t),
172, 20, 0, 2,
// ipv4-mask[0]: 255.255.0.0
(bd_uint8_t)(BD_Ip_Netmask>>8), (bd_uint8_t)(BD_Ip_Netmask>>0), 0x00, sizeof(bd_uint32_t),
255, 255, 0, 0,
// ipv4-gateway[0]: 172.20.0.1
(bd_uint8_t)(BD_Ip_Gateway>>8), (bd_uint8_t)(BD_Ip_Gateway>>0), 0x00, sizeof(bd_uint32_t),
172, 20, 0, 1,
// usbd-pid[0]: 0xAABB
(bd_uint8_t)(BD_Usb_Device_Id>>8), (bd_uint8_t)(BD_Usb_Device_Id>>0), 0x00, sizeof(bd_uint16_t),
0xAA, 0xBB,
// usbd-vid[0]: 0xCCDD
(bd_uint8_t)(BD_Usb_Vendor_Id>>8), (bd_uint8_t)(BD_Usb_Vendor_Id>>0), 0x00, sizeof(bd_uint16_t),
0xCC, 0xDD,
// ram-size[0]: 0xA0A1A2A3
(bd_uint8_t)(BD_Ram_Size>>8), (bd_uint8_t)(BD_Ram_Size>>0), 0x00, sizeof(bd_uint32_t),
0xA0, 0xA1, 0xA2, 0xA3,
// ram-size64[0]: 0xB0B1B2B3B4B5B6B7
(bd_uint8_t)(BD_Ram_Size64>>8), (bd_uint8_t)(BD_Ram_Size64>>0), 0x00, sizeof(bd_uint64_t),
0xB0, 0xB1, 0xB2, 0xB3, 0xB4, 0xB5, 0xB6, 0xB7,
// flash-size[0]: 0x00000000
(bd_uint8_t)(BD_Flash_Size>>8), (bd_uint8_t)(BD_Flash_Size>>0), 0x00, sizeof(bd_uint32_t),
0x00, 0x00, 0x00, 0x00,
// flash-size64[0]: 0x0000000000000000
(bd_uint8_t)(BD_Flash_Size64>>8), (bd_uint8_t)(BD_Flash_Size64>>0), 0x00, sizeof(bd_uint64_t),
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
// e2p-size[0]: 0x00000000
(bd_uint8_t)(BD_Eeeprom_Size>>8), (bd_uint8_t)(BD_Eeeprom_Size>>0), 0x00, sizeof(bd_uint32_t),
0x00, 0x00, 0x00, 0x00,
// nvram-size64[0]: 0x00000000
(bd_uint8_t)(BD_Nv_Rram_Size>>8), (bd_uint8_t)(BD_Nv_Rram_Size>>0), 0x00, sizeof(bd_uint32_t),
0x00, 0x00, 0x00, 0x00,
// cpu-core-clock[0]: 0x00000000
(bd_uint8_t)(BD_Cpu_Base_Clk>>8), (bd_uint8_t)(BD_Cpu_Base_Clk>>0), 0x00, sizeof(bd_uint32_t),
0x00, 0x00, 0x00, 0x00,
// cpu-base-clock[0]: 0x00000000
(bd_uint8_t)(BD_Cpu_Core_Clk>>8), (bd_uint8_t)(BD_Cpu_Core_Clk>>0), 0x00, sizeof(bd_uint32_t),
0x00, 0x00, 0x00, 0x00,
// cpubus-clock[0]: 0x00000000
(bd_uint8_t)(BD_Cpu_Bus_Clk>>8), (bd_uint8_t)(BD_Cpu_Bus_Clk>>0), 0x00, sizeof(bd_uint32_t),
0x00, 0x00, 0x00, 0x00,
// cpuram-clock[0]: 0x00000000
(bd_uint8_t)(BD_Ram_Clk>>8), (bd_uint8_t)(BD_Ram_Clk>>0), 0x00, sizeof(bd_uint32_t),
0x00, 0x00, 0x00, 0x00,
// partition[0]: (len=0x0F) [ACTIVE, BOOTLOADER, offset=0x00010203, size=0x04050607, 'Part0']
(bd_uint8_t)(BD_Partition>>8), (bd_uint8_t)(BD_Partition>>0), 0x00, 0x0F,
BD_Partition_Flags_Active,
BD_Partition_Type_Raw_BootLoader,
0x00, 0x01, 0x02, 0x03,
0x04, 0x05, 0x06, 0x07,
'P', 'a', 'r', 't', '0',
// partition[0]: (len=0x0F) [INACTIVE, YAFFS2, offset=0x00112233, size=0x44556677, 'Part1']
(bd_uint8_t)(BD_Partition>>8), (bd_uint8_t)(BD_Partition>>0), 0x00, 2*sizeof(bd_uint8_t)+2*sizeof(bd_uint32_t)+5,
BD_Partition_Flags_None,
BD_Partition_Type_FS_YAFFS2,
0x00, 0x11, 0x22, 0x33,
0x44, 0x55, 0x66, 0x77,
'P', 'a', 'r', 't', '1',
// partition[0]: (len=0x0F) [ACTIVE, BBT, offset=0xFF00AA55, size=0x00FF55AA, 'Part2']
(bd_uint8_t)(BD_Partition>>8), (bd_uint8_t)(BD_Partition>>0), 0x00, 2*sizeof(bd_uint8_t)+2*sizeof(bd_uint32_t)+5,
BD_Partition_Flags_Active,
BD_Partition_Type_Raw_BBT,
0xFF, 0x00, 0xAA, 0x55,
0x00, 0xFF, 0x55, 0xAA,
'P', 'a', 'r', 't', '2',
// partition64[0]: (len=0x0F) [ACTIVE, BBT, ReadOnly, offset=0x0000FFFF'FF00AA55, size=0000FFFF'0x00FF55AA, 'Part3']
(bd_uint8_t)(BD_Partition64>>8), (bd_uint8_t)(BD_Partition64>>0), 0x00, 8*sizeof(bd_uint8_t)+2*sizeof(bd_uint64_t)+5,
BD_Partition_Flags_Active,
BD_Partition_Type_FS_YAFFS2,
BD_Partition_Opts_ReadOnly,
0,0,0,0,0,
0x00, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0xAA, 0x55,
0x00, 0x00, 0xFF, 0xFF, 0x00, 0xFF, 0x55, 0xAA,
'P', 'a', 'r', 't', '3',
// lcd-type[0]: 0x0000
(bd_uint8_t)(BD_Lcd_Type>>8), (bd_uint8_t)(BD_Lcd_Type>>0), 0x00, sizeof(bd_uint16_t),
0x00, 0x00,
// lcd-backlight[0]: 0x0000
(bd_uint8_t)(BD_Lcd_Backlight>>8), (bd_uint8_t)(BD_Lcd_Backlight>>0), 0x00, sizeof(bd_uint8_t),
0x01,
// lcd-contrast[0]: 0x0000
(bd_uint8_t)(BD_Lcd_Contrast>>8), (bd_uint8_t)(BD_Lcd_Contrast>>0), 0x00, sizeof(bd_uint8_t),
0x7F,
// adapter-type[0]: 0x0000
BD16(BD_Ui_Adapter_Type), 0x00, sizeof(bd_uint16_t),
0x00, 0x00,
// user void[0-15]: -
0x80, 0x00, 0x00, 0x00,
0x80, 0x00, 0x00, 0x00,
0x80, 0x00, 0x00, 0x00,
0x80, 0x00, 0x00, 0x00,
0x80, 0x00, 0x00, 0x00,
0x80, 0x00, 0x00, 0x00,
0x80, 0x00, 0x00, 0x00,
0x80, 0x00, 0x00, 0x00,
0x80, 0x00, 0x00, 0x00,
0x80, 0x00, 0x00, 0x00,
0x80, 0x00, 0x00, 0x00,
0x80, 0x00, 0x00, 0x00,
0x80, 0x00, 0x00, 0x00,
0x80, 0x00, 0x00, 0x00,
0x80, 0x00, 0x00, 0x00,
0x80, 0x00, 0x00, 0x00,
// user row data[0]: 00 01 02 03 04 05 06 07 08 ... 3F
0x80, 0x01, 0x00, 0x40,
0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F,
0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F,
0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27,
0x28, 0x29, 0x2A, 0x2B, 0x2C, 0x2D, 0x2E, 0x2F,
0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37,
0x38, 0x39, 0x3A, 0x3B, 0x3C, 0x3D, 0x3E, 0x3F,
// end
(bd_uint8_t)(BD_End>>8), (bd_uint8_t)(BD_End>>0), 0x00, 0x00,
};
static const bd_uint8_t hdr1[] = { 'B', 'D', 'V', '1', BD16(sizeof(data1)), BD16(0x0000) };
static BD_IndexTable indexTable[BD_MAX_LENGTH/4];
BD_Context bdCtx;
BD_Entry bd_entry;
char name[128];
unsigned char value[BD_MAX_ENTRY_LEN];
bd_uint_t num = 0;
bd_uint_t index = 0;
bd_size_t len = 0;
int i = 0;
BD_Type type = BD_Type_None;
bd_bool_t rc = BD_TRUE;
memset(&bdCtx, 0, sizeof(bdCtx));
memset(&bd_entry, 0, sizeof(bd_entry));
memset(indexTable, 0, sizeof(indexTable));
memset(name, 0, sizeof(name));
memset(value, 0, sizeof(value));
/* initialize */
rc = BD_CheckHeader( &bdCtx, hdr1 );
BD_ASSERT( rc );
rc = BD_ImportData( &bdCtx, data1 );
BD_ASSERT( rc );
BD_ASSERT( bdCtx.initialized );
BD_ASSERT( bdCtx.entries == num_entries );
rc = BD_InitEntry(&bd_entry);
BD_ASSERT( rc );
/* get all bd entries */
while(BD_GetNextEntry(&bdCtx, &bd_entry)==BD_TRUE) {
for(i=0;i<sizeof(indexTable)/sizeof(BD_IndexTable);i++) {
if(indexTable[i].tag == BD_End) {
index = 0;
indexTable[i].tag = bd_entry.tag;
indexTable[i].index = 1;
break;
} else if(indexTable[i].tag == bd_entry.tag) {
index = indexTable[i].index;
indexTable[i].index++;
break;
}
}
rc=BD_GetInfo(bd_entry.tag, &type, name, sizeof(name) );
if(rc == BD_FALSE) {
if(bd_entry.tag == 0x8000) {
type=BD_Type_Void;
rc = BD_TRUE;
} else if(bd_entry.tag == 0x8001) {
type=BD_Type_None;
rc = BD_TRUE;
}
}
BD_ASSERT( rc || ((bd_entry.tag==0) && (bd_entry.len==0)) );
switch(type) {
case BD_Type_End: {
BD_ASSERT( (bd_entry.tag==0) && (bd_entry.len==0) && (index==0) );
} break;
case BD_Type_Void: {
rc = BD_GetVoid (&bdCtx, bd_entry.tag, index, (bd_bool_t *)value);
BD_ASSERT( rc );
if((bd_entry.tag == 0x8000) && (index >= 0) && (index < 16)) {
} else {
BD_ASSERT( BD_FALSE );
}
} break;
case BD_Type_UInt8: {
rc = BD_GetUInt8 (&bdCtx, bd_entry.tag, index, (bd_uint8_t *)value);
BD_ASSERT( rc );
if((bd_entry.tag==BD_Hw_Ver) && (index == 0)) {
BD_ASSERT( *((bd_uint8_t *)value) == 0x01 );
} else if((bd_entry.tag==BD_Hw_Rel) && (index == 0)) {
BD_ASSERT( *((bd_uint8_t *)value) == 0x00 );
} else if((bd_entry.tag==BD_Lcd_Backlight) && (index == 0)) {
BD_ASSERT( *((bd_uint8_t *)value) == 0x01 );
} else if((bd_entry.tag==BD_Lcd_Contrast) && (index == 0)) {
BD_ASSERT( *((bd_uint8_t *)value) == 0x7F );
} else {
BD_ASSERT( BD_FALSE );
}
} break;
case BD_Type_UInt16: {
rc = BD_GetUInt16(&bdCtx, bd_entry.tag, index, (bd_uint16_t *)value);
BD_ASSERT( rc );
if((bd_entry.tag==BD_Prod_Variant) && (index == 0)) {
BD_ASSERT( *((bd_uint16_t *)value) == 0xF0A5 );
} else if((bd_entry.tag==BD_Prod_Variant) && (index == 0)) {
BD_ASSERT( *((bd_uint16_t *)value) == 0xF0A5 );
} else if((bd_entry.tag==BD_Prod_Variant) && (index == 0)) {
BD_ASSERT( *((bd_uint16_t *)value) == 0xF0A5 );
} else if((bd_entry.tag==BD_Usb_Device_Id) && (index == 0)) {
BD_ASSERT( *((bd_uint16_t *)value) == 0xAABB );
} else if((bd_entry.tag==BD_Usb_Vendor_Id) && (index == 0)) {
BD_ASSERT( *((bd_uint16_t *)value) == 0xCCDD );
} else if((bd_entry.tag==BD_Lcd_Type) && (index == 0)) {
BD_ASSERT( *((bd_uint16_t *)value) == 0x0000 );
} else if((bd_entry.tag==BD_Ui_Adapter_Type) && (index == 0)) {
BD_ASSERT( *((bd_uint16_t *)value) == 0x0000 );
} else {
BD_ASSERT( BD_FALSE );
}
} break;
case BD_Type_UInt32: {
rc = BD_GetUInt32(&bdCtx, bd_entry.tag, index, (bd_uint32_t *)value);
BD_ASSERT( rc );
if((bd_entry.tag==BD_Ram_Size) && (index == 0)) {
BD_ASSERT( *((bd_uint32_t *)value) == 0xA0A1A2A3 );
} else if((bd_entry.tag==BD_Flash_Size) && (index == 0)) {
BD_ASSERT( *((bd_uint32_t *)value) == 0x00000000 );
} else if((bd_entry.tag==BD_Eeeprom_Size) && (index == 0)) {
BD_ASSERT( *((bd_uint32_t *)value) == 0x00000000 );
} else if((bd_entry.tag==BD_Nv_Rram_Size) && (index == 0)) {
BD_ASSERT( *((bd_uint32_t *)value) == 0x00000000 );
} else if((bd_entry.tag==BD_Cpu_Base_Clk) && (index == 0)) {
BD_ASSERT( *((bd_uint32_t *)value) == 0x00000000 );
} else if((bd_entry.tag==BD_Cpu_Core_Clk) && (index == 0)) {
BD_ASSERT( *((bd_uint32_t *)value) == 0x00000000 );
} else if((bd_entry.tag==BD_Cpu_Bus_Clk) && (index == 0)) {
BD_ASSERT( *((bd_uint32_t *)value) == 0x00000000 );
} else if((bd_entry.tag==BD_Ram_Clk) && (index == 0)) {
BD_ASSERT( *((bd_uint32_t *)value) == 0x00000000 );
} else {
BD_ASSERT( BD_FALSE );
}
} break;
case BD_Type_UInt64: {
rc = BD_GetUInt64(&bdCtx, bd_entry.tag, index, (bd_uint64_t *)value);
BD_ASSERT( rc );
if((bd_entry.tag==BD_Ram_Size64) && (index == 0)) {
BD_ASSERT( *(bd_uint64_t*)value == 0xB0B1B2B3B4B5B6B7ULL );
} else if((bd_entry.tag==BD_Flash_Size64) && (index == 0)) {
BD_ASSERT( *(bd_uint64_t*)value == 0x0000000000000000ULL );
} else {
BD_ASSERT( BD_FALSE );
}
} break;
case BD_Type_String: {
rc = BD_GetString(&bdCtx, bd_entry.tag, index, (char *)value, bd_entry.len+1);
BD_ASSERT( rc );
if((bd_entry.tag==BD_Prod_Name) && (index == 0)) {
BD_ASSERT( strcmp((char *)value, "Product") == 0 );
} else if((bd_entry.tag==BD_Prod_Compatibility) && (index == 0)) {
BD_ASSERT( strcmp((char *)value, "Comp") == 0 );
} else if((bd_entry.tag==BD_Serial) && (index == 0)) {
BD_ASSERT( strcmp((char *)value, "Serial") == 0 );
} else {
BD_ASSERT( BD_FALSE );
}
} break;
case BD_Type_Date: {
rc = BD_GetString(&bdCtx, bd_entry.tag, index, (char *)value, bd_entry.len+1);
BD_ASSERT( rc );
if((bd_entry.tag==BD_Production_Date) && (index == 0)) {
BD_ASSERT( strcmp((char *)value, "01.01.2000") == 0 );
} else {
BD_ASSERT( BD_FALSE );
}
BD_ASSERT( rc );
} break;
case BD_Type_MAC: {
rc = BD_GetMAC(&bdCtx, bd_entry.tag, index, (bd_uint8_t *)value);
BD_ASSERT( rc );
if((bd_entry.tag==BD_Eth_Mac) && (index == 0)) {
BD_ASSERT( value[0] == 0x05 );
BD_ASSERT( value[1] == 0x14 );
BD_ASSERT( value[2] == 0x23 );
BD_ASSERT( value[3] == 0x32 );
BD_ASSERT( value[4] == 0x41 );
BD_ASSERT( value[5] == 0x50 );
} else {
BD_ASSERT( BD_FALSE );
}
} break;
case BD_Type_IPV4: {
rc = BD_GetIPv4(&bdCtx, bd_entry.tag, index, (bd_uint32_t *)value);
BD_ASSERT( rc );
if((bd_entry.tag==BD_Ip_Addr) && (index == 0)) {
BD_ASSERT( *((bd_uint32_t *)value) == (bd_uint32_t)((192<<24)|(168<<16)|(0<<8)|(2<<0)) );
} else if((bd_entry.tag==BD_Ip_Netmask) && (index == 0)) {
BD_ASSERT( *((bd_uint32_t *)value) == (bd_uint32_t)((255<<24)|(255<<16)|(255<<8)|(0<<0)) );
} else if((bd_entry.tag==BD_Ip_Gateway) && (index == 0)) {
BD_ASSERT( *((bd_uint32_t *)value) == (bd_uint32_t)((192<<24)|(168<<16)|(0<<8)|(1<<0)) );
} else if((bd_entry.tag==BD_Ip_Addr) && (index == 1)) {
BD_ASSERT( *((bd_uint32_t *)value) == (bd_uint32_t)((172<<24)|(20<<16)|(0<<8)|(2<<0)) );
} else if((bd_entry.tag==BD_Ip_Netmask) && (index == 1)) {
BD_ASSERT( *((bd_uint32_t *)value) == (bd_uint32_t)((255<<24)|(255<<16)|(0<<8)|(0<<0)) );
} else if((bd_entry.tag==BD_Ip_Gateway) && (index == 1)) {
BD_ASSERT( *((bd_uint32_t *)value) == (bd_uint32_t)((172<<24)|(20<<16)|(0<<8)|(1<<0)) );
} else {
BD_ASSERT( BD_FALSE );
}
} break;
case BD_Type_Partition: {
BD_PartitionEntry *pPartition=(BD_PartitionEntry *)value;
rc = BD_GetPartition(&bdCtx, bd_entry.tag, index, pPartition);
BD_ASSERT( rc );
if((bd_entry.tag==BD_Partition) && (index == 0)) {
BD_ASSERT( pPartition->flags == BD_Partition_Flags_Active );
BD_ASSERT( pPartition->type == BD_Partition_Type_Raw_BootLoader );
BD_ASSERT( pPartition->offset == 0x00010203 );
BD_ASSERT( pPartition->size == 0x04050607 );
BD_ASSERT( strcmp(pPartition->name, "Part0") == 0 );
} else if((bd_entry.tag==BD_Partition) && (index == 1)) {
BD_ASSERT( pPartition->flags == BD_Partition_Flags_None );
BD_ASSERT( pPartition->type == BD_Partition_Type_FS_YAFFS2 );
BD_ASSERT( pPartition->offset == 0x00112233 );
BD_ASSERT( pPartition->size == 0x44556677 );
BD_ASSERT( strcmp(pPartition->name, "Part1") == 0 );
} else if((bd_entry.tag==BD_Partition) && (index == 2)) {
BD_ASSERT( pPartition->flags == BD_Partition_Flags_Active );
BD_ASSERT( pPartition->type == BD_Partition_Type_Raw_BBT );
BD_ASSERT( pPartition->offset == 0xFF00AA55 );
BD_ASSERT( pPartition->size == 0x00FF55AA );
BD_ASSERT( strcmp(pPartition->name, "Part2") == 0 );
} else {
BD_ASSERT( BD_FALSE );
}
} break;
case BD_Type_Partition64: {
BD_PartitionEntry64 *pPartition64=(BD_PartitionEntry64 *)value;
rc = BD_GetPartition64(&bdCtx, bd_entry.tag, index, pPartition64);
BD_ASSERT( rc );
if((bd_entry.tag==BD_Partition64) && (index == 0)) {
BD_ASSERT( pPartition64->flags == BD_Partition_Flags_Active );
BD_ASSERT( pPartition64->type == BD_Partition_Type_FS_YAFFS2 );
BD_ASSERT( pPartition64->options == BD_Partition_Opts_ReadOnly );
BD_ASSERT( (pPartition64->offset == 0x0000FFFFFF00AA55ULL) );
BD_ASSERT( (pPartition64->size == 0x0000FFFF00FF55AAULL) );
BD_ASSERT( strcmp(pPartition64->name, "Part3") == 0 );
} else {
BD_ASSERT( BD_FALSE );
}
} break;
case BD_Type_None: {
rc = BD_GetBlob(&bdCtx, bd_entry.tag, index, (char *)value, bd_entry.len, &len);
BD_ASSERT( rc );
BD_ASSERT( bd_entry.len == len );
if((bd_entry.tag==0x8001) && (index == 0)) {
BD_ASSERT( len == 0x40 );
for(i=0;i<(int)len;i++) {
BD_ASSERT( ((unsigned char)value[i]) == ((unsigned char)i) );
}
} else {
BD_ASSERT( BD_FALSE );
}
} break;
default: {
BD_ASSERT( rc );
} break;
}
if(type != BD_Type_End) {
num++;
}
}
BD_ASSERT( bdCtx.entries == num );
}
/*---------------------------------------------------------------------------*/
#ifdef BD_CONF_HAS_HASH
static void bd_testHash( void )
{
static bd_uint8_t bdData[] =
{
0x42, 0x44, 0x56, 0x31, 0x00, 0x20, 0x04, 0xBE, 0x00, 0x1F, 0x00, 0x06, 0x00, 0x12, 0x63, 0x1E,
0x22, 0x3D, 0x00, 0x08, 0x00, 0x06, 0x00, 0x11, 0x2B, 0x00, 0xAB, 0xCD, 0x00, 0x09, 0x00, 0x04,
0xAC, 0x1F, 0x0E, 0xFF, 0x00, 0x00, 0x00, 0x00
};
const char key[] = "12345";
const char keyFail[] = "joshua";
BD_Context bdCtx;
bd_bool_t rc;
/* Initialize */
rc = BD_CheckHeader( &bdCtx, bdData );
BD_ASSERT( rc );
rc = BD_ImportData( &bdCtx, bdData+8 );
BD_ASSERT( rc );
/* Verify hashed area of board descriptor */
rc = BD_VerifySha1Hmac( &bdCtx, BD_Hmac_Sha1_4, 0, key, 5);
BD_ASSERT( rc );
/* Try with wrong key -> shall fail */
rc = BD_VerifySha1Hmac( &bdCtx, BD_Hmac_Sha1_4, 0, keyFail, 6);
BD_ASSERT( !rc );
/* Now manipulate a byte in the MAC address .. */
bdData[23]++;
/* .. and test again. This must fail */
rc = BD_VerifySha1Hmac( &bdCtx, BD_Hmac_Sha1_4, 0, key, 5);
BD_ASSERT( !rc );
}
#endif
/*---------------------------------------------------------------------------*/
void BD_UnitTest(void)
{
bd_testHelpers( );
bd_testCheckHeader( );
bd_testImport();
bd_testChecksum();
bd_testGetUInt();
bd_testGetString();
bd_testGetMAC();
bd_testGetIPv4();
bd_testGetPartition();
bd_testGetEntry();
#ifdef BD_CONF_HAS_HASH
bd_testHash();
#endif
}
#endif /* BD_CONF_UNIT_TESTS */
/*--- eof -------------------------------------------------------------------*/