[dataset] use full Timestamp TLV value in otOperationalDataset (#7739)

The `otOperationalDataset#mActiveTimestamp` should represent the full
Active Timestamp TLV value but not only the seconds. The same for
`otOperationalDataset#mPendingTimestamp`.
This commit is contained in:
Kangping
2022-06-03 10:59:16 -07:00
committed by GitHub
parent c8556dfd66
commit 5daca7c684
12 changed files with 150 additions and 52 deletions
+13 -2
View File
@@ -213,6 +213,17 @@ typedef struct otOperationalDatasetComponents
bool mIsChannelMaskPresent : 1; ///< TRUE if Channel Mask is present, FALSE otherwise.
} otOperationalDatasetComponents;
/**
* This structure represents a Thread Dataset timestamp component.
*
*/
typedef struct otTimestamp
{
uint64_t mSeconds;
uint16_t mTicks;
bool mAuthoritative;
} otTimestamp;
/**
* This structure represents an Active or Pending Operational Dataset.
*
@@ -221,8 +232,8 @@ typedef struct otOperationalDatasetComponents
*/
typedef struct otOperationalDataset
{
uint64_t mActiveTimestamp; ///< Active Timestamp
uint64_t mPendingTimestamp; ///< Pending Timestamp
otTimestamp mActiveTimestamp; ///< Active Timestamp
otTimestamp mPendingTimestamp; ///< Pending Timestamp
otNetworkKey mNetworkKey; ///< Network Key
otNetworkName mNetworkName; ///< Network Name
otExtendedPanId mExtendedPanId; ///< Extended PAN ID
+1 -1
View File
@@ -53,7 +53,7 @@ extern "C" {
* @note This number versions both OpenThread platform and user APIs.
*
*/
#define OPENTHREAD_API_VERSION (218)
#define OPENTHREAD_API_VERSION (219)
/**
* @addtogroup api-instance
+4 -4
View File
@@ -196,7 +196,7 @@ Done
Usage: `dataset activetimestamp [timestamp]`
Get active timestamp.
Get active timestamp seconds.
```bash
> dataset activetimestamp
@@ -204,7 +204,7 @@ Get active timestamp.
Done
```
Set active timestamp.
Set active timestamp seconds.
```bash
> dataset activetimestamp 123456789
@@ -457,7 +457,7 @@ Done
Usage: `dataset pendingtimestamp [timestamp]`
Get pending timestamp.
Get pending timestamp seconds.
```bash
> dataset pendingtimestamp
@@ -465,7 +465,7 @@ Get pending timestamp.
Done
```
Set pending timestamp.
Set pending timestamp seconds.
```bash
> dataset pendingtimestamp 123456789
+16 -8
View File
@@ -51,12 +51,12 @@ otError Dataset::Print(otOperationalDataset &aDataset)
{
if (aDataset.mComponents.mIsPendingTimestampPresent)
{
OutputLine("Pending Timestamp: %lu", aDataset.mPendingTimestamp);
OutputLine("Pending Timestamp: %lu", aDataset.mPendingTimestamp.mSeconds);
}
if (aDataset.mComponents.mIsActiveTimestampPresent)
{
OutputLine("Active Timestamp: %lu", aDataset.mActiveTimestamp);
OutputLine("Active Timestamp: %lu", aDataset.mActiveTimestamp.mSeconds);
}
if (aDataset.mComponents.mIsChannelPresent)
@@ -205,12 +205,14 @@ template <> otError Dataset::Process<Cmd("activetimestamp")>(Arg aArgs[])
{
if (sDataset.mComponents.mIsActiveTimestampPresent)
{
OutputLine("%lu", sDataset.mActiveTimestamp);
OutputLine("%lu", sDataset.mActiveTimestamp.mSeconds);
}
}
else
{
SuccessOrExit(error = aArgs[0].ParseAsUint64(sDataset.mActiveTimestamp));
SuccessOrExit(error = aArgs[0].ParseAsUint64(sDataset.mActiveTimestamp.mSeconds));
sDataset.mActiveTimestamp.mTicks = 0;
sDataset.mActiveTimestamp.mAuthoritative = false;
sDataset.mComponents.mIsActiveTimestampPresent = true;
}
@@ -423,12 +425,14 @@ template <> otError Dataset::Process<Cmd("pendingtimestamp")>(Arg aArgs[])
{
if (sDataset.mComponents.mIsPendingTimestampPresent)
{
OutputLine("%lu", sDataset.mPendingTimestamp);
OutputLine("%lu", sDataset.mPendingTimestamp.mSeconds);
}
}
else
{
SuccessOrExit(error = aArgs[0].ParseAsUint64(sDataset.mPendingTimestamp));
SuccessOrExit(error = aArgs[0].ParseAsUint64(sDataset.mPendingTimestamp.mSeconds));
sDataset.mPendingTimestamp.mTicks = 0;
sDataset.mPendingTimestamp.mAuthoritative = false;
sDataset.mComponents.mIsPendingTimestampPresent = true;
}
@@ -450,14 +454,18 @@ template <> otError Dataset::Process<Cmd("mgmtsetcommand")>(Arg aArgs[])
if (*arg == "activetimestamp")
{
arg++;
SuccessOrExit(error = arg->ParseAsUint64(dataset.mActiveTimestamp.mSeconds));
dataset.mActiveTimestamp.mTicks = 0;
dataset.mActiveTimestamp.mAuthoritative = false;
dataset.mComponents.mIsActiveTimestampPresent = true;
SuccessOrExit(error = arg->ParseAsUint64(dataset.mActiveTimestamp));
}
else if (*arg == "pendingtimestamp")
{
arg++;
SuccessOrExit(error = arg->ParseAsUint64(dataset.mPendingTimestamp.mSeconds));
dataset.mPendingTimestamp.mTicks = 0;
dataset.mPendingTimestamp.mAuthoritative = false;
dataset.mComponents.mIsPendingTimestampPresent = true;
SuccessOrExit(error = arg->ParseAsUint64(dataset.mPendingTimestamp));
}
else if (*arg == "networkkey")
{
+15 -14
View File
@@ -43,6 +43,7 @@
#include "common/log.hpp"
#include "mac/mac_types.hpp"
#include "meshcop/meshcop_tlvs.hpp"
#include "meshcop/timestamp.hpp"
#include "thread/mle_tlvs.hpp"
namespace ot {
@@ -69,10 +70,12 @@ Error Dataset::Info::GenerateRandom(Instance &aInstance)
Clear();
mActiveTimestamp = 1;
mChannel = preferredChannels.ChooseRandomChannel();
mChannelMask = supportedChannels.GetMask();
mPanId = Mac::GenerateRandomPanId();
mActiveTimestamp.mSeconds = 1;
mActiveTimestamp.mTicks = 0;
mActiveTimestamp.mAuthoritative = false;
mChannel = preferredChannels.ChooseRandomChannel();
mChannelMask = supportedChannels.GetMask();
mPanId = Mac::GenerateRandomPanId();
AsCoreType(&mSecurityPolicy).SetToDefault();
SuccessOrExit(error = AsCoreType(&mNetworkKey).GenerateRandom());
@@ -193,7 +196,7 @@ void Dataset::ConvertTo(Info &aDatasetInfo) const
switch (cur->GetType())
{
case Tlv::kActiveTimestamp:
aDatasetInfo.SetActiveTimestamp(As<ActiveTimestampTlv>(cur)->GetTimestamp().GetSeconds());
aDatasetInfo.SetActiveTimestamp(As<ActiveTimestampTlv>(cur)->GetTimestamp());
break;
case Tlv::kChannel:
@@ -237,7 +240,7 @@ void Dataset::ConvertTo(Info &aDatasetInfo) const
break;
case Tlv::kPendingTimestamp:
aDatasetInfo.SetPendingTimestamp(As<PendingTimestampTlv>(cur)->GetTimestamp().GetSeconds());
aDatasetInfo.SetPendingTimestamp(As<PendingTimestampTlv>(cur)->GetTimestamp());
break;
case Tlv::kPskc:
@@ -286,20 +289,18 @@ Error Dataset::SetFrom(const Info &aDatasetInfo)
if (aDatasetInfo.IsActiveTimestampPresent())
{
Timestamp timestamp;
Timestamp activeTimestamp;
timestamp.Clear();
timestamp.SetSeconds(aDatasetInfo.GetActiveTimestamp());
IgnoreError(SetTlv(Tlv::kActiveTimestamp, timestamp));
aDatasetInfo.GetActiveTimestamp(activeTimestamp);
IgnoreError(SetTlv(Tlv::kActiveTimestamp, activeTimestamp));
}
if (aDatasetInfo.IsPendingTimestampPresent())
{
Timestamp timestamp;
Timestamp pendingTimestamp;
timestamp.Clear();
timestamp.SetSeconds(aDatasetInfo.GetPendingTimestamp());
IgnoreError(SetTlv(Tlv::kPendingTimestamp, timestamp));
aDatasetInfo.GetPendingTimestamp(pendingTimestamp);
IgnoreError(SetTlv(Tlv::kPendingTimestamp, pendingTimestamp));
}
if (aDatasetInfo.IsDelayPresent())
+6 -6
View File
@@ -203,7 +203,7 @@ public:
* @returns The Active Timestamp in the Dataset.
*
*/
uint64_t GetActiveTimestamp(void) const { return mActiveTimestamp; }
void GetActiveTimestamp(Timestamp &aTimestamp) const { aTimestamp.SetFromTimestamp(mActiveTimestamp); }
/**
* This method sets the Active Timestamp in the Dataset.
@@ -211,9 +211,9 @@ public:
* @param[in] aTimestamp A Timestamp value.
*
*/
void SetActiveTimestamp(uint64_t aTimestamp)
void SetActiveTimestamp(const Timestamp &aTimestamp)
{
mActiveTimestamp = aTimestamp;
aTimestamp.ConvertTo(mActiveTimestamp);
mComponents.mIsActiveTimestampPresent = true;
}
@@ -234,7 +234,7 @@ public:
* @returns The Pending Timestamp in the Dataset.
*
*/
uint64_t GetPendingTimestamp(void) const { return mPendingTimestamp; }
void GetPendingTimestamp(Timestamp &aTimestamp) const { aTimestamp.SetFromTimestamp(mPendingTimestamp); }
/**
* This method sets the Pending Timestamp in the Dataset.
@@ -242,9 +242,9 @@ public:
* @param[in] aTimestamp A Timestamp value.
*
*/
void SetPendingTimestamp(uint64_t aTimestamp)
void SetPendingTimestamp(const Timestamp &aTimestamp)
{
mPendingTimestamp = aTimestamp;
aTimestamp.ConvertTo(mPendingTimestamp);
mComponents.mIsPendingTimestampPresent = true;
}
+11 -2
View File
@@ -41,6 +41,7 @@
#include "common/locator_getters.hpp"
#include "common/log.hpp"
#include "common/random.hpp"
#include "meshcop/timestamp.hpp"
namespace ot {
namespace MeshCoP {
@@ -193,9 +194,17 @@ void DatasetUpdater::HandleNotifierEvents(Events aEvents)
{
Finish(kErrorNone);
}
else if (requestedDataset.GetActiveTimestamp() <= dataset.GetActiveTimestamp())
else
{
Finish(kErrorAlready);
Timestamp requestedDatasetTimestamp;
Timestamp activeDatasetTimestamp;
requestedDataset.GetActiveTimestamp(requestedDatasetTimestamp);
dataset.GetActiveTimestamp(activeDatasetTimestamp);
if (Timestamp::Compare(requestedDatasetTimestamp, activeDatasetTimestamp) <= 0)
{
Finish(kErrorAlready);
}
}
}
+43 -9
View File
@@ -38,13 +38,23 @@
namespace ot {
namespace MeshCoP {
void Timestamp::ConvertTo(otTimestamp &aTimestamp) const
{
aTimestamp.mSeconds = GetSeconds();
aTimestamp.mTicks = GetTicks();
aTimestamp.mAuthoritative = GetAuthoritative();
}
void Timestamp::SetFromTimestamp(const otTimestamp &aTimestamp)
{
SetSeconds(aTimestamp.mSeconds);
SetTicks(aTimestamp.mTicks);
SetAuthoritative(aTimestamp.mAuthoritative);
}
int Timestamp::Compare(const Timestamp *aFirst, const Timestamp *aSecond)
{
int rval;
uint64_t firstSeconds;
uint64_t secondSeconds;
uint16_t firstTicks;
uint16_t secondTicks;
int rval;
if (aFirst == nullptr)
{
@@ -62,22 +72,46 @@ int Timestamp::Compare(const Timestamp *aFirst, const Timestamp *aSecond)
// Both are non-null.
firstSeconds = aFirst->GetSeconds();
secondSeconds = aSecond->GetSeconds();
rval = Compare(*aFirst, *aSecond);
exit:
return rval;
}
int Timestamp::Compare(const Timestamp &aFirst, const Timestamp &aSecond)
{
int rval;
uint64_t firstSeconds;
uint64_t secondSeconds;
uint16_t firstTicks;
uint16_t secondTicks;
bool firstAuthoritative;
bool secondAuthoritative;
firstSeconds = aFirst.GetSeconds();
secondSeconds = aSecond.GetSeconds();
if (firstSeconds != secondSeconds)
{
ExitNow(rval = (firstSeconds > secondSeconds) ? 1 : -1);
}
firstTicks = aFirst->GetTicks();
secondTicks = aSecond->GetTicks();
firstTicks = aFirst.GetTicks();
secondTicks = aSecond.GetTicks();
if (firstTicks != secondTicks)
{
ExitNow(rval = (firstTicks > secondTicks) ? 1 : -1);
}
firstAuthoritative = aFirst.GetAuthoritative();
secondAuthoritative = aSecond.GetAuthoritative();
if (firstAuthoritative != secondAuthoritative)
{
ExitNow(rval = firstAuthoritative ? 1 : -1);
}
rval = 0;
exit:
+26
View File
@@ -39,6 +39,7 @@
#include <string.h>
#include <openthread/dataset.h>
#include <openthread/platform/toolchain.h>
#include "common/clearable.hpp"
@@ -59,6 +60,18 @@ OT_TOOL_PACKED_BEGIN
class Timestamp : public Clearable<Timestamp>
{
public:
/**
* This method converts the timestamp to `otTimestamp`.
*
*/
void ConvertTo(otTimestamp &aTimestamp) const;
/**
* This method sets the timestamp from `otTimestamp`.
*
*/
void SetFromTimestamp(const otTimestamp &aTimestamp);
/**
* This method returns the Seconds value.
*
@@ -143,6 +156,19 @@ public:
*/
static int Compare(const Timestamp *aFirst, const Timestamp *aSecond);
/**
* This static method compares two timestamps.
*
* @param[in] aFirst A reference to the first timestamp to compare.
* @param[in] aSecond A reference to the second timestamp to compare.
*
* @retval -1 if @p aFirst is less than @p aSecond (`aFirst < aSecond`).
* @retval 0 if @p aFirst is equal to @p aSecond (`aFirst == aSecond`).
* @retval 1 if @p aFirst is greater than @p aSecond (`aFirst > aSecond`).
*
*/
static int Compare(const Timestamp &aFirst, const Timestamp &aSecond);
private:
static constexpr uint8_t kTicksOffset = 1;
static constexpr uint16_t kTicksMask = 0x7fff << kTicksOffset;
+1 -1
View File
@@ -752,7 +752,7 @@ otError RadioSpinel<InterfaceType, ProcessContextType>::ThreadDatasetHandler(con
* Initially set Active Timestamp to 0. This is to allow the node to join the network
* yet retrieve the full Active Dataset from a neighboring device if one exists.
*/
opDataset.mActiveTimestamp = 0;
memset(&opDataset.mActiveTimestamp, 0, sizeof(opDataset.mActiveTimestamp));
opDataset.mComponents.mIsActiveTimestampPresent = true;
SuccessOrExit(error = dataset.SetFrom(static_cast<MeshCoP::Dataset::Info &>(opDataset)));
+12 -4
View File
@@ -1228,17 +1228,21 @@ otError NcpBase::EncodeOperationalDataset(const otOperationalDataset &aDataset)
if (aDataset.mComponents.mIsActiveTimestampPresent)
{
const otTimestamp &activeTimestamp = aDataset.mActiveTimestamp;
SuccessOrExit(error = mEncoder.OpenStruct());
SuccessOrExit(error = mEncoder.WriteUintPacked(SPINEL_PROP_DATASET_ACTIVE_TIMESTAMP));
SuccessOrExit(error = mEncoder.WriteUint64(aDataset.mActiveTimestamp));
SuccessOrExit(error = mEncoder.WriteUint64(activeTimestamp.mSeconds));
SuccessOrExit(error = mEncoder.CloseStruct());
}
if (aDataset.mComponents.mIsPendingTimestampPresent)
{
const otTimestamp &pendingTimestamp = aDataset.mPendingTimestamp;
SuccessOrExit(error = mEncoder.OpenStruct());
SuccessOrExit(error = mEncoder.WriteUintPacked(SPINEL_PROP_DATASET_PENDING_TIMESTAMP));
SuccessOrExit(error = mEncoder.WriteUint64(aDataset.mPendingTimestamp));
SuccessOrExit(error = mEncoder.WriteUint64(pendingTimestamp.mSeconds));
SuccessOrExit(error = mEncoder.CloseStruct());
}
@@ -1400,7 +1404,9 @@ otError NcpBase::DecodeOperationalDataset(otOperationalDataset &aDataset,
if (!aAllowEmptyValues || !mDecoder.IsAllReadInStruct())
{
SuccessOrExit(error = mDecoder.ReadUint64(aDataset.mActiveTimestamp));
SuccessOrExit(error = mDecoder.ReadUint64(aDataset.mActiveTimestamp.mSeconds));
aDataset.mActiveTimestamp.mTicks = 0;
aDataset.mActiveTimestamp.mAuthoritative = false;
}
aDataset.mComponents.mIsActiveTimestampPresent = true;
@@ -1410,7 +1416,9 @@ otError NcpBase::DecodeOperationalDataset(otOperationalDataset &aDataset,
if (!aAllowEmptyValues || !mDecoder.IsAllReadInStruct())
{
SuccessOrExit(error = mDecoder.ReadUint64(aDataset.mPendingTimestamp));
SuccessOrExit(error = mDecoder.ReadUint64(aDataset.mPendingTimestamp.mSeconds));
aDataset.mPendingTimestamp.mTicks = 0;
aDataset.mPendingTimestamp.mAuthoritative = false;
}
aDataset.mComponents.mIsPendingTimestampPresent = true;
+2 -1
View File
@@ -139,7 +139,7 @@ void TestTimestamp(void)
VerifyOrQuit(MeshCoP::Timestamp::Compare(&t1, &t2) == 0);
t1.SetAuthoritative(true);
VerifyOrQuit(MeshCoP::Timestamp::Compare(&t1, &t2) == 0);
VerifyOrQuit(MeshCoP::Timestamp::Compare(&t1, &t2) > 0);
t1.SetSeconds(1);
VerifyOrQuit(t1.GetSeconds() == 1);
@@ -147,6 +147,7 @@ void TestTimestamp(void)
VerifyOrQuit(MeshCoP::Timestamp::Compare(&t2, &t1) < 0);
t2.SetSeconds(1);
t2.SetAuthoritative(true);
VerifyOrQuit(MeshCoP::Timestamp::Compare(&t1, &t2) == 0);
printf("TestTimestamp() passed\n");