#ifndef FLASH_HPP_
#define FLASH_HPP_
#include "openthread-core-config.h"
#include <stdint.h>
#include <string.h>
#include <openthread/error.h>
#include <openthread/platform/toolchain.h>
#include "common/debug.hpp"
#include "common/locator.hpp"
namespace ot {
class Flash : public InstanceLocator
{
public:
Flash(Instance &aInstance)
: InstanceLocator(aInstance)
{
}
void Init(void);
otError Get(uint16_t aKey, int aIndex, uint8_t *aValue, uint16_t *aValueLength) const;
otError Set(uint16_t aKey, const uint8_t *aValue, uint16_t aValueLength);
otError Add(uint16_t aKey, const uint8_t *aValue, uint16_t aValueLength);
otError Delete(uint16_t aKey, int aIndex);
void Wipe(void);
private:
enum
{
kSwapMarkerSize = 4, };
static const uint32_t sSwapActive = 0xbe5cc5ee;
static const uint32_t sSwapInactive = 0xbe5cc5ec;
OT_TOOL_PACKED_BEGIN
class RecordHeader
{
public:
void Init(uint16_t aKey, bool aFirst)
{
mKey = aKey;
mFlags = kFlagsInit & ~kFlagAddBegin;
if (aFirst)
{
mFlags &= ~kFlagFirst;
}
mLength = 0;
mReserved = 0xffff;
};
uint16_t GetKey(void) const { return mKey; }
void SetKey(uint16_t aKey) { mKey = aKey; }
uint16_t GetLength(void) const { return mLength; }
void SetLength(uint16_t aLength) { mLength = aLength; }
uint16_t GetSize(void) const { return sizeof(*this) + ((mLength + 3) & 0xfffc); }
bool IsValid(void) const { return ((mFlags & (kFlagAddComplete | kFlagDelete)) == kFlagDelete); }
bool IsAddBeginSet(void) const { return (mFlags & kFlagAddBegin) == 0; }
void SetAddBeginFlag(void) { mFlags &= ~kFlagAddBegin; }
bool IsAddCompleteSet(void) const { return (mFlags & kFlagAddComplete) == 0; }
void SetAddCompleteFlag(void) { mFlags &= ~kFlagAddComplete; }
bool IsDeleted(void) const { return (mFlags & kFlagDelete) == 0; }
void SetDeleted(void) { mFlags &= ~kFlagDelete; }
bool IsFirst(void) const { return (mFlags & kFlagFirst) == 0; }
void SetFirst(void) { mFlags &= ~kFlagFirst; }
private:
enum
{
kFlagsInit = 0xffff, kFlagAddBegin = 1 << 0, kFlagAddComplete = 1 << 1, kFlagDelete = 1 << 2, kFlagFirst = 1 << 3, };
uint16_t mKey;
uint16_t mFlags;
uint16_t mLength;
uint16_t mReserved;
} OT_TOOL_PACKED_END;
OT_TOOL_PACKED_BEGIN
class Record : public RecordHeader
{
public:
const uint8_t *GetData(void) const { return mData; }
void SetData(const uint8_t *aData, uint16_t aDataLength)
{
OT_ASSERT(aDataLength <= kMaxDataSize);
memcpy(mData, aData, aDataLength);
SetLength(aDataLength);
}
private:
enum
{
kMaxDataSize = 255,
};
uint8_t mData[kMaxDataSize];
} OT_TOOL_PACKED_END;
otError Add(uint16_t aKey, bool aFirst, const uint8_t *aValue, uint16_t aValueLength);
bool DoesValidRecordExist(uint32_t aOffset, uint16_t aKey) const;
void SanitizeFreeSpace(void);
void Swap(void);
uint32_t mSwapSize;
uint32_t mSwapUsed;
uint8_t mSwapIndex;
};
}
#endif