Include timestamp TLV (#564)

* Include timestamp TLV
* Keep one copy of timestamp
This commit is contained in:
Lu Wang
2016-09-14 21:13:43 -07:00
committed by Jonathan Hui
parent 8831217615
commit 5c28c02e40
8 changed files with 120 additions and 73 deletions
+10 -4
View File
@@ -320,7 +320,6 @@ ThreadError JoinerRouter::SendJoinerEntrust(const Ip6::MessageInfo &aMessageInfo
MeshLocalPrefixTlv meshLocalPrefix;
ExtendedPanIdTlv extendedPanId;
NetworkNameTlv networkName;
ActiveTimestampTlv activeTimestamp;
Tlv *tlv;
VerifyOrExit((message = mSocket.NewMessage(0)) != NULL, error = kThreadError_NoBufs);
@@ -353,9 +352,16 @@ ThreadError JoinerRouter::SendJoinerEntrust(const Ip6::MessageInfo &aMessageInfo
networkName.SetNetworkName(mNetif.GetMac().GetNetworkName());
SuccessOrExit(error = message->Append(&networkName, sizeof(Tlv) + networkName.GetLength()));
activeTimestamp.Init();
*static_cast<Timestamp *>(&activeTimestamp) = mNetif.GetActiveDataset().GetNetwork().GetTimestamp();
SuccessOrExit(error = message->Append(&activeTimestamp, sizeof(activeTimestamp)));
if ((tlv = mNetif.GetActiveDataset().GetNetwork().Get(Tlv::kActiveTimestamp)) != NULL)
{
SuccessOrExit(error = message->Append(tlv, sizeof(Tlv) + tlv->GetLength()));
}
else
{
ActiveTimestampTlv activeTimestamp;
activeTimestamp.Init();
SuccessOrExit(error = message->Append(&activeTimestamp, sizeof(activeTimestamp)));
}
if ((tlv = mNetif.GetActiveDataset().GetNetwork().Get(Tlv::kChannelMask)) != NULL)
{
+55 -29
View File
@@ -41,15 +41,14 @@
namespace Thread {
namespace MeshCoP {
Dataset::Dataset(void) :
Dataset::Dataset(const Tlv::Type aType) :
mType(aType),
mLength(0)
{
mTimestamp.Init();
}
void Dataset::Clear(void)
{
mTimestamp.Init();
mLength = 0;
}
@@ -110,6 +109,8 @@ void Dataset::Get(otOperationalDataset &aDataset)
const ActiveTimestampTlv *tlv = static_cast<const ActiveTimestampTlv *>(cur);
aDataset.mActiveTimestamp = tlv->GetSeconds();
aDataset.mIsActiveTimestampSet = true;
GetTimestamp();
break;
}
@@ -228,30 +229,36 @@ void Dataset::Get(otOperationalDataset &aDataset)
}
}
ThreadError Dataset::Set(const otOperationalDataset &aDataset, bool aActive)
ThreadError Dataset::Set(const otOperationalDataset &aDataset)
{
ThreadError error = kThreadError_None;
MeshCoP::ActiveTimestampTlv activeTimestampTlv;
VerifyOrExit(aDataset.mIsActiveTimestampSet, error = kThreadError_InvalidArgs);
if (aActive)
activeTimestampTlv.Init();
activeTimestampTlv.SetSeconds(aDataset.mActiveTimestamp);
activeTimestampTlv.SetTicks(0);
Set(activeTimestampTlv);
if (mType == Tlv::kPendingTimestamp)
{
mTimestamp.SetSeconds(aDataset.mActiveTimestamp);
mTimestamp.SetTicks(0);
mTimestamp.SetAuthoritative(false);
}
else
{
MeshCoP::ActiveTimestampTlv tlv;
MeshCoP::PendingTimestampTlv pendingTimestampTlv;
VerifyOrExit(aDataset.mIsPendingTimestampSet, error = kThreadError_InvalidArgs);
mTimestamp.SetSeconds(aDataset.mPendingTimestamp);
mTimestamp.SetTicks(0);
mTimestamp.SetAuthoritative(false);
tlv.Init();
tlv.SetSeconds(aDataset.mActiveTimestamp);
Set(tlv);
pendingTimestampTlv.Init();
pendingTimestampTlv.SetSeconds(aDataset.mPendingTimestamp);
pendingTimestampTlv.SetTicks(0);
Set(pendingTimestampTlv);
if (aDataset.mIsDelaySet)
{
MeshCoP::DelayTimerTlv tlv;
tlv.Init();
tlv.SetDelayTimer(aDataset.mDelay);
Set(tlv);
}
}
if (aDataset.mIsChannelSet)
@@ -287,14 +294,6 @@ ThreadError Dataset::Set(const otOperationalDataset &aDataset, bool aActive)
Set(channelMask.tlv);
}
if (aDataset.mIsDelaySet)
{
MeshCoP::DelayTimerTlv tlv;
tlv.Init();
tlv.SetDelayTimer(aDataset.mDelay);
Set(tlv);
}
if (aDataset.mIsExtendedPanIdSet)
{
MeshCoP::ExtendedPanIdTlv tlv;
@@ -356,14 +355,41 @@ exit:
return error;
}
const Timestamp &Dataset::GetTimestamp(void) const
const Timestamp *Dataset::GetTimestamp(void) const
{
return mTimestamp;
const Timestamp *timestamp = NULL;
if (mType == Tlv::kActiveTimestamp)
{
const ActiveTimestampTlv *tlv = static_cast<const ActiveTimestampTlv *>(Get(mType));
VerifyOrExit(tlv != NULL, ;);
timestamp = static_cast<const Timestamp *>(tlv);
}
else
{
const PendingTimestampTlv *tlv = static_cast<const PendingTimestampTlv *>(Get(mType));
VerifyOrExit(tlv != NULL, ;);
timestamp = static_cast<const Timestamp *>(tlv);
}
exit:
return timestamp;
}
void Dataset::SetTimestamp(const Timestamp &aTimestamp)
{
mTimestamp = aTimestamp;
OT_TOOL_PACKED_BEGIN
struct
{
Tlv tlv;
Timestamp timestamp;
} OT_TOOL_PACKED_END timestampTlv;
timestampTlv.tlv.SetType(mType);
timestampTlv.tlv.SetLength(sizeof(Timestamp));
timestampTlv.timestamp = aTimestamp;
Set(timestampTlv.tlv);
}
ThreadError Dataset::Set(const Tlv &aTlv)
+9 -7
View File
@@ -52,8 +52,10 @@ public:
/**
* This constructor initializes the object.
*
* @param[in] aType The type of the dataset, active or pending.
*
*/
Dataset(void);
Dataset(const Tlv::Type aType);
/**
* This method clears the Dataset.
@@ -102,10 +104,10 @@ public:
/**
* This method returns a reference to the Timestamp.
*
* @returns A reference to the Timestamp.
* @returns A pointer to the Timestamp.
*
*/
const Timestamp &GetTimestamp(void) const;
const Timestamp *GetTimestamp(void) const;
/**
* This method sets the Timestamp value.
@@ -126,16 +128,16 @@ public:
ThreadError Set(const Message &aMessage, uint16_t aOffset, uint8_t aLength);
ThreadError Set(const otOperationalDataset &aDataset, bool aActive);
ThreadError Set(const otOperationalDataset &aDataset);
void Remove(Tlv::Type aType);
private:
void Remove(uint8_t *aStart, uint8_t aLength);
Timestamp mTimestamp; ///< Active or Pending Timestamp
uint8_t mTlvs[kMaxSize]; ///< The Dataset buffer
uint8_t mLength; ///< The number of valid bytes in @var mTlvs
Tlv::Type mType; ///< Active or Pending
uint8_t mTlvs[kMaxSize]; ///< The Dataset buffer
uint8_t mLength; ///< The number of valid bytes in @var mTlvs
};
} // namespace MeshCoP
+23 -22
View File
@@ -49,7 +49,10 @@
namespace Thread {
namespace MeshCoP {
DatasetManager::DatasetManager(ThreadNetif &aThreadNetif, const char *aUriSet, const char *aUriGet):
DatasetManager::DatasetManager(ThreadNetif &aThreadNetif, const Tlv::Type aType, const char *aUriSet,
const char *aUriGet):
mLocal(aType),
mNetwork(aType),
mMle(aThreadNetif.GetMle()),
mNetif(aThreadNetif),
mNetworkDataLeader(aThreadNetif.GetNetworkDataLeader()),
@@ -71,7 +74,8 @@ ThreadError DatasetManager::Set(const Dataset &aDataset, uint8_t &aFlags)
aFlags = 0;
VerifyOrExit(mNetwork.GetTimestamp().Compare(aDataset.GetTimestamp()) > 0, error = kThreadError_InvalidArgs);
VerifyOrExit((mNetwork.GetTimestamp() == NULL) || (aDataset.GetTimestamp() &&
mNetwork.GetTimestamp()->Compare(*aDataset.GetTimestamp()) > 0), error = kThreadError_InvalidArgs);
mLocal = aDataset;
aFlags |= kFlagLocalUpdated;
@@ -102,6 +106,7 @@ ThreadError DatasetManager::Set(const Timestamp &aTimestamp, const Message &aMes
uint16_t aOffset, uint8_t aLength, uint8_t &aFlags)
{
ThreadError error = kThreadError_None;
const Timestamp *timestamp;
int compare;
aFlags = 0;
@@ -110,7 +115,8 @@ ThreadError DatasetManager::Set(const Timestamp &aTimestamp, const Message &aMes
mNetwork.SetTimestamp(aTimestamp);
aFlags |= kFlagNetworkUpdated;
compare = mLocal.GetTimestamp().Compare(aTimestamp);
timestamp = mLocal.GetTimestamp();
compare = (timestamp == NULL) ? 1 : timestamp->Compare(aTimestamp);
if (compare > 0)
{
@@ -141,7 +147,8 @@ void DatasetManager::HandleTimer(void *aContext)
void DatasetManager::HandleTimer(void)
{
VerifyOrExit(mMle.IsAttached() && mNetwork.GetTimestamp().Compare(mLocal.GetTimestamp()) > 0, ;);
VerifyOrExit(mMle.IsAttached() && ((mNetwork.GetTimestamp() == NULL) ||
(mLocal.GetTimestamp() && mNetwork.GetTimestamp()->Compare(*mLocal.GetTimestamp()) > 0)), ;);
VerifyOrExit(mLocal.Get(Tlv::kDelayTimer) != NULL, ;);
Register();
@@ -158,7 +165,6 @@ ThreadError DatasetManager::Register(void)
Message *message;
Ip6::Address leader;
Ip6::MessageInfo messageInfo;
ActiveTimestampTlv timestamp;
mSocket.Open(&HandleUdpReceive, this);
@@ -179,10 +185,6 @@ ThreadError DatasetManager::Register(void)
VerifyOrExit((message = mSocket.NewMessage(0)) != NULL, error = kThreadError_NoBufs);
SuccessOrExit(error = message->Append(header.GetBytes(), header.GetLength()));
timestamp.Init();
*static_cast<Timestamp *>(&timestamp) = mLocal.GetTimestamp();
SuccessOrExit(error = message->Append(&timestamp, sizeof(timestamp)));
SuccessOrExit(error = message->Append(mLocal.GetBytes(), mLocal.GetSize()));
mMle.GetLeaderAddress(leader);
@@ -262,7 +264,8 @@ void DatasetManager::HandleSet(Coap::Header &aHeader, Message &aMessage, const I
}
// verify the request includes a timestamp that is ahead of the locally stored value
VerifyOrExit(offset < aMessage.GetLength() && mLocal.GetTimestamp().Compare(timestamp) > 0, state = StateTlv::kReject);
VerifyOrExit(offset < aMessage.GetLength() && (mLocal.GetTimestamp() == NULL ||
mLocal.GetTimestamp()->Compare(timestamp) > 0), state = StateTlv::kReject);
mLocal.Set(aMessage, aMessage.GetOffset(), static_cast<uint8_t>(aMessage.GetLength() - aMessage.GetOffset()));
mNetwork = mLocal;
@@ -568,7 +571,7 @@ exit:
}
ActiveDataset::ActiveDataset(ThreadNetif &aThreadNetif):
DatasetManager(aThreadNetif, OPENTHREAD_URI_ACTIVE_SET, OPENTHREAD_URI_ACTIVE_GET)
DatasetManager(aThreadNetif, Tlv::kActiveTimestamp, OPENTHREAD_URI_ACTIVE_SET, OPENTHREAD_URI_ACTIVE_GET)
{
}
@@ -576,8 +579,6 @@ void ActiveDataset::Get(otOperationalDataset &aDataset)
{
memset(&aDataset, 0, sizeof(aDataset));
mLocal.Get(aDataset);
aDataset.mActiveTimestamp = mLocal.GetTimestamp().GetSeconds();
aDataset.mIsActiveTimestampSet = true;
}
ThreadError ActiveDataset::Set(const Dataset &aDataset)
@@ -595,9 +596,9 @@ exit:
ThreadError ActiveDataset::Set(const otOperationalDataset &aDataset)
{
ThreadError error = kThreadError_None;
Dataset dataset;
Dataset dataset(Tlv::kActiveTimestamp);
SuccessOrExit(error = dataset.Set(aDataset, true));
SuccessOrExit(error = dataset.Set(aDataset));
SuccessOrExit(error = Set(dataset));
exit:
@@ -688,7 +689,7 @@ ThreadError ActiveDataset::ApplyConfiguration(void)
}
PendingDataset::PendingDataset(ThreadNetif &aThreadNetif):
DatasetManager(aThreadNetif, OPENTHREAD_URI_PENDING_SET, OPENTHREAD_URI_PENDING_GET),
DatasetManager(aThreadNetif, Tlv::kPendingTimestamp, OPENTHREAD_URI_PENDING_SET, OPENTHREAD_URI_PENDING_GET),
mTimer(aThreadNetif.GetIp6().mTimerScheduler, HandleTimer, this)
{
}
@@ -697,8 +698,6 @@ void PendingDataset::Get(otOperationalDataset &aDataset)
{
memset(&aDataset, 0, sizeof(aDataset));
mLocal.Get(aDataset);
aDataset.mPendingTimestamp = mLocal.GetTimestamp().GetSeconds();
aDataset.mIsPendingTimestampSet = true;
}
ThreadError PendingDataset::Set(const Dataset &aDataset)
@@ -716,9 +715,9 @@ exit:
ThreadError PendingDataset::Set(const otOperationalDataset &aDataset)
{
ThreadError error = kThreadError_None;
Dataset dataset;
Dataset dataset(Tlv::kPendingTimestamp);
SuccessOrExit(error = dataset.Set(aDataset, false));
SuccessOrExit(error = dataset.Set(aDataset));
SuccessOrExit(error = Set(dataset));
exit:
@@ -766,7 +765,8 @@ void PendingDataset::ResetDelayTimer(uint8_t aFlags)
mNetworkTime = Timer::GetNow();
// if partition is up to date and delay timer already expired
if ((mNetwork.GetTimestamp().Compare(mLocal.GetTimestamp()) == 0) &&
if ((mNetwork.GetTimestamp() && mLocal.GetTimestamp() &&
(mNetwork.GetTimestamp()->Compare(*mLocal.GetTimestamp())) == 0) &&
(delayTimer = static_cast<DelayTimerTlv *>(mLocal.Get(Tlv::kDelayTimer))) != NULL &&
(delayTimer->GetDelayTimer() == 0))
{
@@ -828,7 +828,8 @@ void PendingDataset::HandleTimer(void)
// update only if one of the following is true
// 1) not attached
// 2) partition's pending dataset is up to date
VerifyOrExit(!mMle.IsAttached() || mNetwork.GetTimestamp().Compare(mLocal.GetTimestamp()) == 0, ;);
VerifyOrExit((!mMle.IsAttached() || (mNetwork.GetTimestamp() &&
(mNetwork.GetTimestamp()->Compare(*mLocal.GetTimestamp()))) == 0), ;);
mLocal.Remove(Tlv::kDelayTimer);
+1 -1
View File
@@ -69,7 +69,7 @@ protected:
kFlagNetworkUpdated = 1 << 1,
};
DatasetManager(ThreadNetif &aThreadNetif, const char *aUriSet, const char *aUriGet);
DatasetManager(ThreadNetif &aThreadNetif, const Tlv::Type aType, const char *aUriSet, const char *aUriGet);
ThreadError Set(const Dataset &aDataset, uint8_t &aFlags);
+8
View File
@@ -134,6 +134,14 @@ public:
*/
uint8_t *GetValue() { return reinterpret_cast<uint8_t *>(this) + sizeof(Tlv); }
/**
* This method returns a pointer to the Value.
*
* @returns A pointer to the value.
*
*/
const uint8_t *GetValue() const { return reinterpret_cast<const uint8_t *>(this) + sizeof(Tlv); }
/**
* This method returns a pointer to the next TLV.
*
+6 -6
View File
@@ -896,12 +896,12 @@ ThreadError Mle::AppendActiveTimestamp(Message &aMessage)
{
ThreadError error;
ActiveTimestampTlv timestampTlv;
const MeshCoP::Timestamp &timestamp(mNetif.GetActiveDataset().GetNetwork().GetTimestamp());
const MeshCoP::Timestamp *timestamp(mNetif.GetActiveDataset().GetNetwork().GetTimestamp());
VerifyOrExit(timestamp.GetSeconds() != 0, error = kThreadError_None);
VerifyOrExit(timestamp && timestamp->GetSeconds() != 0, error = kThreadError_None);
timestampTlv.Init();
*static_cast<MeshCoP::Timestamp *>(&timestampTlv) = timestamp;
*static_cast<MeshCoP::Timestamp *>(&timestampTlv) = *timestamp;
error = aMessage.Append(&timestampTlv, sizeof(timestampTlv));
exit:
@@ -912,12 +912,12 @@ ThreadError Mle::AppendPendingTimestamp(Message &aMessage)
{
ThreadError error;
PendingTimestampTlv timestampTlv;
const MeshCoP::Timestamp &timestamp(mNetif.GetPendingDataset().GetNetwork().GetTimestamp());
const MeshCoP::Timestamp *timestamp(mNetif.GetPendingDataset().GetNetwork().GetTimestamp());
VerifyOrExit(timestamp.GetSeconds() != 0, error = kThreadError_None);
VerifyOrExit(timestamp && timestamp->GetSeconds() != 0, error = kThreadError_None);
timestampTlv.Init();
*static_cast<MeshCoP::Timestamp *>(&timestampTlv) = timestamp;
*static_cast<MeshCoP::Timestamp *>(&timestampTlv) = *timestamp;
error = aMessage.Append(&timestampTlv, sizeof(timestampTlv));
exit:
+8 -4
View File
@@ -1950,13 +1950,15 @@ ThreadError MleRouter::HandleChildIdRequest(const Message &aMessage, const Ip6::
numTlvs = tlvRequest.GetLength();
if (activeTimestamp.GetLength() == 0 ||
mNetif.GetActiveDataset().GetNetwork().GetTimestamp().Compare(activeTimestamp) != 0)
mNetif.GetActiveDataset().GetNetwork().GetTimestamp() == NULL ||
mNetif.GetActiveDataset().GetNetwork().GetTimestamp()->Compare(activeTimestamp) != 0)
{
child->mRequestTlvs[numTlvs++] = Tlv::kActiveDataset;
}
if (pendingTimestamp.GetLength() == 0 ||
mNetif.GetPendingDataset().GetNetwork().GetTimestamp().Compare(pendingTimestamp) != 0)
mNetif.GetPendingDataset().GetNetwork().GetTimestamp() == NULL ||
mNetif.GetPendingDataset().GetNetwork().GetTimestamp()->Compare(pendingTimestamp) != 0)
{
child->mRequestTlvs[numTlvs++] = Tlv::kPendingDataset;
}
@@ -2100,13 +2102,15 @@ ThreadError MleRouter::HandleDataRequest(const Message &aMessage, const Ip6::Mes
numTlvs = tlvRequest.GetLength();
if (activeTimestamp.GetLength() == 0 ||
mNetif.GetActiveDataset().GetNetwork().GetTimestamp().Compare(activeTimestamp) != 0)
mNetif.GetActiveDataset().GetNetwork().GetTimestamp() == NULL ||
mNetif.GetActiveDataset().GetNetwork().GetTimestamp()->Compare(activeTimestamp) != 0)
{
tlvs[numTlvs++] = Tlv::kActiveDataset;
}
if (pendingTimestamp.GetLength() == 0 ||
mNetif.GetPendingDataset().GetNetwork().GetTimestamp().Compare(pendingTimestamp) != 0)
mNetif.GetPendingDataset().GetNetwork().GetTimestamp() == NULL ||
mNetif.GetPendingDataset().GetNetwork().GetTimestamp()->Compare(pendingTimestamp) != 0)
{
tlvs[numTlvs++] = Tlv::kPendingDataset;
}