Add Channel Mask TLV CLI support (#549)

- Add a new Dataset::Set method to support variable TLV data payload. This is mainly for Channel Mask TLV
- Add CLI to support Channel Mask TLV
This commit is contained in:
Lu Wang
2016-09-13 20:55:11 -07:00
committed by Jonathan Hui
parent 84079beb3a
commit fb823f4f72
4 changed files with 100 additions and 22 deletions
+30 -22
View File
@@ -215,6 +215,12 @@ enum
OT_SECURITY_POLICY_BEACONS = 1 << 3, ///< Beacons enabled
};
/**
* This type represents Channel Mask Page 0.
*
*/
typedef uint32_t otChannelMaskPage0;
/**
* This type represents the IEEE 802.15.4 PAN ID.
*
@@ -340,29 +346,31 @@ typedef struct otEnergyScanResult
*/
typedef struct otOperationalDataset
{
uint64_t mActiveTimestamp; ///< Active Timestamp
uint64_t mPendingTimestamp; ///< Pending Timestamp
otMasterKey mMasterKey; ///< Network Master Key
otNetworkName mNetworkName; ///< Network Name
otExtendedPanId mExtendedPanId; ///< Extended PAN ID
otMeshLocalPrefix mMeshLocalPrefix; ///< Mesh Local Prefix
uint32_t mDelay; ///< Delay Timer
otPanId mPanId; ///< PAN ID
uint16_t mChannel; ///< Channel
otPSKc mPSKc; ///< PSKc
otSecurityPolicy mSecurityPolicy; ///< Security Policy
uint64_t mActiveTimestamp; ///< Active Timestamp
uint64_t mPendingTimestamp; ///< Pending Timestamp
otMasterKey mMasterKey; ///< Network Master Key
otNetworkName mNetworkName; ///< Network Name
otExtendedPanId mExtendedPanId; ///< Extended PAN ID
otMeshLocalPrefix mMeshLocalPrefix; ///< Mesh Local Prefix
uint32_t mDelay; ///< Delay Timer
otPanId mPanId; ///< PAN ID
uint16_t mChannel; ///< Channel
otPSKc mPSKc; ///< PSKc
otSecurityPolicy mSecurityPolicy; ///< Security Policy
otChannelMaskPage0 mChannelMaskPage0; ///< Channel Mask Page 0
bool mIsActiveTimestampSet : 1; ///< TRUE if Active Timestamp is set, FALSE otherwise.
bool mIsPendingTimestampSet : 1; ///< TRUE if Pending Timestamp is set, FALSE otherwise.
bool mIsMasterKeySet : 1; ///< TRUE if Network Master Key is set, FALSE otherwise.
bool mIsNetworkNameSet : 1; ///< TRUE if Network Name is set, FALSE otherwise.
bool mIsExtendedPanIdSet : 1; ///< TRUE if Extended PAN ID is set, FALSE otherwise.
bool mIsMeshLocalPrefixSet : 1; ///< TRUE if Mesh Local Prefix is set, FALSE otherwise.
bool mIsDelaySet : 1; ///< TRUE if Delay Timer is set, FALSE otherwise.
bool mIsPanIdSet : 1; ///< TRUE if PAN ID is set, FALSE otherwise.
bool mIsChannelSet : 1; ///< TRUE if Channel is set, FALSE otherwise.
bool mIsPSKcSet : 1; ///< TRUE if PSKc is set, FALSE otherwise.
bool mIsSecurityPolicySet : 1; ///< TRUE if Security Policy is set, FALSE otherwise.
bool mIsActiveTimestampSet : 1; ///< TRUE if Active Timestamp is set, FALSE otherwise.
bool mIsPendingTimestampSet : 1; ///< TRUE if Pending Timestamp is set, FALSE otherwise.
bool mIsMasterKeySet : 1; ///< TRUE if Network Master Key is set, FALSE otherwise.
bool mIsNetworkNameSet : 1; ///< TRUE if Network Name is set, FALSE otherwise.
bool mIsExtendedPanIdSet : 1; ///< TRUE if Extended PAN ID is set, FALSE otherwise.
bool mIsMeshLocalPrefixSet : 1; ///< TRUE if Mesh Local Prefix is set, FALSE otherwise.
bool mIsDelaySet : 1; ///< TRUE if Delay Timer is set, FALSE otherwise.
bool mIsPanIdSet : 1; ///< TRUE if PAN ID is set, FALSE otherwise.
bool mIsChannelSet : 1; ///< TRUE if Channel is set, FALSE otherwise.
bool mIsPSKcSet : 1; ///< TRUE if PSKc is set, FALSE otherwise.
bool mIsSecurityPolicySet : 1; ///< TRUE if Security Policy is set, FALSE otherwise.
bool mIsChannelMaskPage0Set : 1; ///< TRUE if Channel Mask Page 0 is set, FALSE otherwise.
} otOperationalDataset;
/**
+21
View File
@@ -55,6 +55,7 @@ const DatasetCommand Dataset::sCommands[] =
{ "active", &ProcessActive },
{ "activetimestamp", &ProcessActiveTimestamp },
{ "channel", &ProcessChannel },
{ "channelmask", &ProcessChannelMask },
{ "clear", &ProcessClear },
{ "commit", &ProcessCommit },
{ "delay", &ProcessDelay },
@@ -99,6 +100,11 @@ ThreadError Dataset::Print(otOperationalDataset &aDataset)
sServer->OutputFormat("Channel: %d\r\n", aDataset.mChannel);
}
if (aDataset.mIsChannelMaskPage0Set)
{
sServer->OutputFormat("Channel Mask Page 0: %x\r\n", aDataset.mChannelMaskPage0);
}
if (aDataset.mIsDelaySet)
{
sServer->OutputFormat("Delay: %d\r\n", aDataset.mDelay);
@@ -261,6 +267,21 @@ exit:
return error;
}
ThreadError Dataset::ProcessChannelMask(otInstance *aInstance, int argc, char *argv[])
{
ThreadError error = kThreadError_None;
long value;
VerifyOrExit(argc > 0, error = kThreadError_Parse);
SuccessOrExit(error = Interpreter::ParseLong(argv[0], value));
sDataset.mChannelMaskPage0 = static_cast<uint32_t>(value);
sDataset.mIsChannelMaskPage0Set = true;
(void)aInstance;
exit:
return error;
}
ThreadError Dataset::ProcessClear(otInstance *aInstance, int argc, char *argv[])
{
memset(&sDataset, 0, sizeof(sDataset));
+1
View File
@@ -77,6 +77,7 @@ private:
static ThreadError ProcessActive(otInstance *aInstance, int argc, char *argv[]);
static ThreadError ProcessActiveTimestamp(otInstance *aInstance, int argc, char *argv[]);
static ThreadError ProcessChannel(otInstance *aInstance, int argc, char *argv[]);
static ThreadError ProcessChannelMask(otInstance *aInstance, int argc, char *argv[]);
static ThreadError ProcessClear(otInstance *aInstance, int argc, char *argv[]);
static ThreadError ProcessCommit(otInstance *aInstance, int argc, char *argv[]);
static ThreadError ProcessDelay(otInstance *aInstance, int argc, char *argv[]);
+48
View File
@@ -121,6 +121,30 @@ void Dataset::Get(otOperationalDataset &aDataset)
break;
}
case Tlv::kChannelMask:
{
uint8_t length = cur->GetLength();
const uint8_t *entry = reinterpret_cast<const uint8_t *>(cur) + sizeof(Tlv);
const uint8_t *entryEnd = entry + length;
while (entry < entryEnd)
{
if (reinterpret_cast<const ChannelMaskEntry *>(entry)->GetChannelPage() == 0)
{
uint8_t i = sizeof(ChannelMaskEntry);
aDataset.mChannelMaskPage0 = static_cast<uint32_t>(entry[i] | (entry[i + 1] << 8) |
(entry[i + 2] << 16) | (entry[i + 3] << 24));
aDataset.mIsChannelMaskPage0Set = true;
break;
}
entry += (reinterpret_cast<const ChannelMaskEntry *>(entry)->GetMaskLength() +
sizeof(ChannelMaskEntry));
}
break;
}
case Tlv::kDelayTimer:
{
const DelayTimerTlv *tlv = static_cast<const DelayTimerTlv *>(cur);
@@ -239,6 +263,30 @@ ThreadError Dataset::Set(const otOperationalDataset &aDataset, bool aActive)
Set(tlv);
}
if (aDataset.mIsChannelMaskPage0Set)
{
OT_TOOL_PACKED_BEGIN
struct
{
MeshCoP::ChannelMaskTlv tlv;
MeshCoP::ChannelMaskEntry entry;
uint8_t mask[sizeof(aDataset.mChannelMaskPage0)];
} OT_TOOL_PACKED_END channelMask;
channelMask.tlv.Init();
channelMask.tlv.SetLength(sizeof(MeshCoP::ChannelMaskEntry) + sizeof(aDataset.mChannelMaskPage0));
channelMask.entry.SetChannelPage(0);
channelMask.entry.SetMaskLength(sizeof(aDataset.mChannelMaskPage0));
for (uint8_t index = 0; index < sizeof(aDataset.mChannelMaskPage0); index++)
{
channelMask.mask[index] = (aDataset.mChannelMaskPage0 >> (8 * index)) & 0xff;
}
Set(channelMask.tlv);
}
if (aDataset.mIsDelaySet)
{
MeshCoP::DelayTimerTlv tlv;