mirror of
https://github.com/espressif/openthread.git
synced 2026-08-25 11:49:51 +00:00
[meshcop-tlvs] simplify and enhance ChannelMaskTlv (#9675)
This commit simplifies `ChannelMaskTlv` generation and parsing. Notably, it ensures that when we read this TLV from a `Message` the TLV value format is validated. The changes include: - `Entry` class representing a channel page entry is now defined as a `private` nested class within `ChannelMaskTlv`. - A shared `EntriesData::Parse()` method is added that validates and parses the entries in the TLV, whether the TLV value resides in a buffer (e.g., within `Dataset`) or in a `Message`. - `ChannelMaskTlv::AppendTo()` method is added to construct entries from a given combined channel mask (for all pages) and append the `ChannelMaskTlv` to a given `Message`. - `Radio::kSupportedChannelPages` is changed to an array (containing all supported pages) instead of mask. - Helper functions added in `Radio`, `SupportsChannelPage()` to verify if a channel page is supported by the radio, and `ChannelMaskForPage()` to obtain the supported channel mask for a given page.
This commit is contained in:
@@ -60,10 +60,9 @@ Error AnnounceBeginClient::SendRequest(uint32_t aChannelMask,
|
||||
uint16_t aPeriod,
|
||||
const Ip6::Address &aAddress)
|
||||
{
|
||||
Error error = kErrorNone;
|
||||
MeshCoP::ChannelMaskTlv channelMask;
|
||||
Tmf::MessageInfo messageInfo(GetInstance());
|
||||
Coap::Message *message = nullptr;
|
||||
Error error = kErrorNone;
|
||||
Tmf::MessageInfo messageInfo(GetInstance());
|
||||
Coap::Message *message = nullptr;
|
||||
|
||||
VerifyOrExit(Get<MeshCoP::Commissioner>().IsActive(), error = kErrorInvalidState);
|
||||
VerifyOrExit((message = Get<Tmf::Agent>().NewPriorityMessage()) != nullptr, error = kErrorNoBufs);
|
||||
@@ -74,9 +73,7 @@ Error AnnounceBeginClient::SendRequest(uint32_t aChannelMask,
|
||||
SuccessOrExit(
|
||||
error = Tlv::Append<MeshCoP::CommissionerSessionIdTlv>(*message, Get<MeshCoP::Commissioner>().GetSessionId()));
|
||||
|
||||
channelMask.Init();
|
||||
channelMask.SetChannelMask(aChannelMask);
|
||||
SuccessOrExit(error = channelMask.AppendTo(*message));
|
||||
SuccessOrExit(error = MeshCoP::ChannelMaskTlv::AppendTo(*message, aChannelMask));
|
||||
|
||||
SuccessOrExit(error = Tlv::Append<MeshCoP::CountTlv>(*message, aCount));
|
||||
SuccessOrExit(error = Tlv::Append<MeshCoP::PeriodTlv>(*message, aPeriod));
|
||||
|
||||
@@ -199,9 +199,9 @@ void Dataset::ConvertTo(Info &aDatasetInfo) const
|
||||
|
||||
case Tlv::kChannelMask:
|
||||
{
|
||||
uint32_t mask = As<ChannelMaskTlv>(cur)->GetChannelMask();
|
||||
uint32_t mask;
|
||||
|
||||
if (mask != 0)
|
||||
if (As<ChannelMaskTlv>(cur)->ReadChannelMask(mask) == kErrorNone)
|
||||
{
|
||||
aDatasetInfo.SetChannelMask(mask);
|
||||
}
|
||||
@@ -312,10 +312,10 @@ Error Dataset::SetFrom(const Info &aDatasetInfo)
|
||||
|
||||
if (aDatasetInfo.IsChannelMaskPresent())
|
||||
{
|
||||
ChannelMaskTlv tlv;
|
||||
tlv.Init();
|
||||
tlv.SetChannelMask(aDatasetInfo.GetChannelMask());
|
||||
IgnoreError(WriteTlv(tlv));
|
||||
ChannelMaskTlv::Value value;
|
||||
|
||||
ChannelMaskTlv::PrepareValue(value, aDatasetInfo.GetChannelMask());
|
||||
IgnoreError(WriteTlv(Tlv::kChannelMask, value.mData, value.mLength));
|
||||
}
|
||||
|
||||
if (aDatasetInfo.IsExtendedPanIdPresent())
|
||||
|
||||
@@ -228,7 +228,7 @@ Error DatasetManager::GetChannelMask(Mac::ChannelMask &aChannelMask) const
|
||||
|
||||
channelMaskTlv = As<ChannelMaskTlv>(dataset.FindTlv(Tlv::kChannelMask));
|
||||
VerifyOrExit(channelMaskTlv != nullptr, error = kErrorNotFound);
|
||||
VerifyOrExit((mask = channelMaskTlv->GetChannelMask()) != 0);
|
||||
SuccessOrExit(channelMaskTlv->ReadChannelMask(mask));
|
||||
|
||||
aChannelMask.SetMask(mask & Get<Mac::Mac>().GetSupportedChannelMask().GetMask());
|
||||
|
||||
|
||||
@@ -319,10 +319,10 @@ Error ActiveDatasetManager::GenerateLocal(void)
|
||||
|
||||
if (!dataset.Contains<ChannelMaskTlv>())
|
||||
{
|
||||
ChannelMaskTlv tlv;
|
||||
tlv.Init();
|
||||
tlv.SetChannelMask(Get<Mac::Mac>().GetSupportedChannelMask().GetMask());
|
||||
IgnoreError(dataset.WriteTlv(tlv));
|
||||
ChannelMaskTlv::Value value;
|
||||
|
||||
ChannelMaskTlv::PrepareValue(value, Get<Mac::Mac>().GetSupportedChannelMask().GetMask());
|
||||
IgnoreError(dataset.WriteTlv(Tlv::kChannelMask, value.mData, value.mLength));
|
||||
}
|
||||
|
||||
if (!dataset.Contains<ExtendedPanIdTlv>())
|
||||
|
||||
@@ -66,10 +66,9 @@ Error EnergyScanClient::SendQuery(uint32_t aChannelMas
|
||||
otCommissionerEnergyReportCallback aCallback,
|
||||
void *aContext)
|
||||
{
|
||||
Error error = kErrorNone;
|
||||
MeshCoP::ChannelMaskTlv channelMask;
|
||||
Tmf::MessageInfo messageInfo(GetInstance());
|
||||
Coap::Message *message = nullptr;
|
||||
Error error = kErrorNone;
|
||||
Tmf::MessageInfo messageInfo(GetInstance());
|
||||
Coap::Message *message = nullptr;
|
||||
|
||||
VerifyOrExit(Get<MeshCoP::Commissioner>().IsActive(), error = kErrorInvalidState);
|
||||
VerifyOrExit((message = Get<Tmf::Agent>().NewPriorityMessage()) != nullptr, error = kErrorNoBufs);
|
||||
@@ -80,9 +79,7 @@ Error EnergyScanClient::SendQuery(uint32_t aChannelMas
|
||||
SuccessOrExit(
|
||||
error = Tlv::Append<MeshCoP::CommissionerSessionIdTlv>(*message, Get<MeshCoP::Commissioner>().GetSessionId()));
|
||||
|
||||
channelMask.Init();
|
||||
channelMask.SetChannelMask(aChannelMask);
|
||||
SuccessOrExit(error = channelMask.AppendTo(*message));
|
||||
SuccessOrExit(error = MeshCoP::ChannelMaskTlv::AppendTo(*message, aChannelMask));
|
||||
|
||||
SuccessOrExit(error = Tlv::Append<MeshCoP::CountTlv>(*message, aCount));
|
||||
SuccessOrExit(error = Tlv::Append<MeshCoP::PeriodTlv>(*message, aPeriod));
|
||||
@@ -110,7 +107,7 @@ void EnergyScanClient::HandleTmf<kUriEnergyReport>(Coap::Message &aMessage, cons
|
||||
|
||||
LogInfo("Received %s", UriToString<kUriEnergyReport>());
|
||||
|
||||
VerifyOrExit((mask = MeshCoP::ChannelMaskTlv::GetChannelMask(aMessage)) != 0);
|
||||
SuccessOrExit(MeshCoP::ChannelMaskTlv::FindIn(aMessage, mask));
|
||||
|
||||
SuccessOrExit(MeshCoP::Tlv::FindTlv(aMessage, MeshCoP::Tlv::kEnergyList, sizeof(energyListTlv), energyListTlv));
|
||||
|
||||
|
||||
+107
-158
@@ -158,191 +158,140 @@ const char *StateTlv::StateToString(State aState)
|
||||
return aState == kReject ? kStateStrings[2] : kStateStrings[aState];
|
||||
}
|
||||
|
||||
bool ChannelMaskBaseTlv::IsValid(void) const
|
||||
bool ChannelMaskTlv::IsValid(void) const
|
||||
{
|
||||
const ChannelMaskEntryBase *cur = GetFirstEntry();
|
||||
const ChannelMaskEntryBase *end = reinterpret_cast<const ChannelMaskEntryBase *>(GetNext());
|
||||
bool ret = false;
|
||||
uint32_t channelMask;
|
||||
|
||||
VerifyOrExit(cur != nullptr);
|
||||
|
||||
while (cur < end)
|
||||
{
|
||||
uint8_t channelPage;
|
||||
|
||||
VerifyOrExit((cur + 1) <= end && cur->GetNext() <= end);
|
||||
|
||||
channelPage = cur->GetChannelPage();
|
||||
|
||||
#if OPENTHREAD_CONFIG_PLATFORM_RADIO_PROPRIETARY_SUPPORT
|
||||
if (channelPage == OPENTHREAD_CONFIG_PLATFORM_RADIO_PROPRIETARY_CHANNEL_PAGE)
|
||||
#else
|
||||
if ((channelPage == OT_RADIO_CHANNEL_PAGE_0) || (channelPage == OT_RADIO_CHANNEL_PAGE_2))
|
||||
#endif
|
||||
{
|
||||
VerifyOrExit(static_cast<const ChannelMaskEntry *>(cur)->IsValid());
|
||||
}
|
||||
|
||||
cur = cur->GetNext();
|
||||
}
|
||||
|
||||
ret = true;
|
||||
|
||||
exit:
|
||||
return ret;
|
||||
return (ReadChannelMask(channelMask) == kErrorNone);
|
||||
}
|
||||
|
||||
const ChannelMaskEntryBase *ChannelMaskBaseTlv::GetFirstEntry(void) const
|
||||
Error ChannelMaskTlv::ReadChannelMask(uint32_t &aChannelMask) const
|
||||
{
|
||||
const ChannelMaskEntryBase *entry = nullptr;
|
||||
EntriesData entriesData;
|
||||
|
||||
VerifyOrExit(GetLength() >= sizeof(ChannelMaskEntryBase));
|
||||
entriesData.Clear();
|
||||
entriesData.mData = &mEntriesStart;
|
||||
entriesData.mLength = GetLength();
|
||||
|
||||
entry = reinterpret_cast<const ChannelMaskEntryBase *>(GetValue());
|
||||
VerifyOrExit(GetLength() >= entry->GetEntrySize(), entry = nullptr);
|
||||
|
||||
exit:
|
||||
return entry;
|
||||
return entriesData.Parse(aChannelMask);
|
||||
}
|
||||
|
||||
ChannelMaskEntryBase *ChannelMaskBaseTlv::GetFirstEntry(void) { return AsNonConst(AsConst(this)->GetFirstEntry()); }
|
||||
|
||||
void ChannelMaskTlv::SetChannelMask(uint32_t aChannelMask)
|
||||
Error ChannelMaskTlv::FindIn(const Message &aMessage, uint32_t &aChannelMask)
|
||||
{
|
||||
uint8_t length = 0;
|
||||
ChannelMaskEntry *entry;
|
||||
Error error;
|
||||
EntriesData entriesData;
|
||||
|
||||
entry = static_cast<ChannelMaskEntry *>(GetFirstEntry());
|
||||
entriesData.Clear();
|
||||
entriesData.mMessage = &aMessage;
|
||||
|
||||
#if OPENTHREAD_CONFIG_RADIO_915MHZ_OQPSK_SUPPORT
|
||||
if (aChannelMask & OT_RADIO_915MHZ_OQPSK_CHANNEL_MASK)
|
||||
{
|
||||
OT_ASSERT(entry != nullptr);
|
||||
entry->Init();
|
||||
entry->SetChannelPage(OT_RADIO_CHANNEL_PAGE_2);
|
||||
entry->SetMask(aChannelMask & OT_RADIO_915MHZ_OQPSK_CHANNEL_MASK);
|
||||
|
||||
length += sizeof(ChannelMaskEntry);
|
||||
|
||||
entry = static_cast<ChannelMaskEntry *>(entry->GetNext());
|
||||
}
|
||||
#endif
|
||||
|
||||
#if OPENTHREAD_CONFIG_RADIO_2P4GHZ_OQPSK_SUPPORT
|
||||
if (aChannelMask & OT_RADIO_2P4GHZ_OQPSK_CHANNEL_MASK)
|
||||
{
|
||||
OT_ASSERT(entry != nullptr);
|
||||
entry->Init();
|
||||
entry->SetChannelPage(OT_RADIO_CHANNEL_PAGE_0);
|
||||
entry->SetMask(aChannelMask & OT_RADIO_2P4GHZ_OQPSK_CHANNEL_MASK);
|
||||
|
||||
length += sizeof(ChannelMaskEntry);
|
||||
}
|
||||
#endif
|
||||
|
||||
#if OPENTHREAD_CONFIG_PLATFORM_RADIO_PROPRIETARY_SUPPORT
|
||||
if (aChannelMask & OPENTHREAD_CONFIG_PLATFORM_RADIO_PROPRIETARY_CHANNEL_MASK)
|
||||
{
|
||||
OT_ASSERT(entry != nullptr);
|
||||
entry->Init();
|
||||
entry->SetChannelPage(OPENTHREAD_CONFIG_PLATFORM_RADIO_PROPRIETARY_CHANNEL_PAGE);
|
||||
entry->SetMask(aChannelMask & OPENTHREAD_CONFIG_PLATFORM_RADIO_PROPRIETARY_CHANNEL_MASK);
|
||||
|
||||
length += sizeof(ChannelMaskEntry);
|
||||
}
|
||||
#endif
|
||||
|
||||
SetLength(length);
|
||||
}
|
||||
|
||||
uint32_t ChannelMaskTlv::GetChannelMask(void) const
|
||||
{
|
||||
const ChannelMaskEntryBase *cur = GetFirstEntry();
|
||||
const ChannelMaskEntryBase *end = reinterpret_cast<const ChannelMaskEntryBase *>(GetNext());
|
||||
uint32_t mask = 0;
|
||||
|
||||
VerifyOrExit(cur != nullptr);
|
||||
|
||||
while (cur < end)
|
||||
{
|
||||
uint8_t channelPage;
|
||||
|
||||
VerifyOrExit((cur + 1) <= end && cur->GetNext() <= end);
|
||||
|
||||
channelPage = cur->GetChannelPage();
|
||||
|
||||
#if OPENTHREAD_CONFIG_RADIO_915MHZ_OQPSK_SUPPORT
|
||||
if (channelPage == OT_RADIO_CHANNEL_PAGE_2)
|
||||
{
|
||||
mask |= static_cast<const ChannelMaskEntry *>(cur)->GetMask() & OT_RADIO_915MHZ_OQPSK_CHANNEL_MASK;
|
||||
}
|
||||
#endif
|
||||
|
||||
#if OPENTHREAD_CONFIG_RADIO_2P4GHZ_OQPSK_SUPPORT
|
||||
if (channelPage == OT_RADIO_CHANNEL_PAGE_0)
|
||||
{
|
||||
mask |= static_cast<const ChannelMaskEntry *>(cur)->GetMask() & OT_RADIO_2P4GHZ_OQPSK_CHANNEL_MASK;
|
||||
}
|
||||
#endif
|
||||
|
||||
#if OPENTHREAD_CONFIG_PLATFORM_RADIO_PROPRIETARY_SUPPORT
|
||||
if (channelPage == OPENTHREAD_CONFIG_PLATFORM_RADIO_PROPRIETARY_CHANNEL_PAGE)
|
||||
{
|
||||
mask |= static_cast<const ChannelMaskEntry *>(cur)->GetMask() &
|
||||
OPENTHREAD_CONFIG_PLATFORM_RADIO_PROPRIETARY_CHANNEL_MASK;
|
||||
}
|
||||
#endif
|
||||
|
||||
cur = cur->GetNext();
|
||||
}
|
||||
SuccessOrExit(error = FindTlvValueOffset(aMessage, Tlv::kChannelMask, entriesData.mOffset, entriesData.mLength));
|
||||
error = entriesData.Parse(aChannelMask);
|
||||
|
||||
exit:
|
||||
return mask;
|
||||
return error;
|
||||
}
|
||||
|
||||
uint32_t ChannelMaskTlv::GetChannelMask(const Message &aMessage)
|
||||
Error ChannelMaskTlv::EntriesData::Parse(uint32_t &aChannelMask)
|
||||
{
|
||||
uint32_t mask = 0;
|
||||
uint16_t offset;
|
||||
uint16_t end;
|
||||
// Validates and parses the Channel Mask TLV entries for each
|
||||
// channel page and if successful updates `aChannelMask` to
|
||||
// return the combined mask for all channel pages supported by
|
||||
// radio. The entries can be either contained in `mMessage` from
|
||||
// `mOffset` (when `mMessage` is non-null) or be in a buffer
|
||||
// `mData`. `mLength` gives the number of bytes for all entries.
|
||||
|
||||
SuccessOrExit(FindTlvValueStartEndOffsets(aMessage, kChannelMask, offset, end));
|
||||
Error error = kErrorParse;
|
||||
Entry readEntry;
|
||||
const Entry *entry;
|
||||
uint16_t size;
|
||||
|
||||
while (offset + sizeof(ChannelMaskEntryBase) <= end)
|
||||
aChannelMask = 0;
|
||||
|
||||
VerifyOrExit(mLength > 0); // At least one entry.
|
||||
|
||||
while (mLength > 0)
|
||||
{
|
||||
ChannelMaskEntry entry;
|
||||
VerifyOrExit(mLength > kEntryHeaderSize);
|
||||
|
||||
IgnoreError(aMessage.Read(offset, entry));
|
||||
VerifyOrExit(offset + entry.GetEntrySize() <= end);
|
||||
|
||||
switch (entry.GetChannelPage())
|
||||
if (mMessage != nullptr)
|
||||
{
|
||||
#if OPENTHREAD_CONFIG_RADIO_2P4GHZ_OQPSK_SUPPORT
|
||||
case OT_RADIO_CHANNEL_PAGE_0:
|
||||
IgnoreError(aMessage.Read(offset, entry));
|
||||
mask |= entry.GetMask() & OT_RADIO_2P4GHZ_OQPSK_CHANNEL_MASK;
|
||||
break;
|
||||
#endif
|
||||
// We first read the entry's header only and after
|
||||
// validating the entry and that the entry's channel page
|
||||
// is supported by radio, we read the full `Entry`.
|
||||
|
||||
#if OPENTHREAD_CONFIG_RADIO_915MHZ_OQPSK_SUPPORT
|
||||
case OT_RADIO_CHANNEL_PAGE_2:
|
||||
IgnoreError(aMessage.Read(offset, entry));
|
||||
mask |= entry.GetMask() & OT_RADIO_915MHZ_OQPSK_CHANNEL_MASK;
|
||||
break;
|
||||
#endif
|
||||
|
||||
#if OPENTHREAD_CONFIG_PLATFORM_RADIO_PROPRIETARY_SUPPORT
|
||||
case OPENTHREAD_CONFIG_PLATFORM_RADIO_PROPRIETARY_CHANNEL_PAGE:
|
||||
IgnoreError(aMessage.Read(offset, entry));
|
||||
mask |= entry.GetMask() & OPENTHREAD_CONFIG_PLATFORM_RADIO_PROPRIETARY_CHANNEL_MASK;
|
||||
break;
|
||||
#endif
|
||||
mMessage->ReadBytes(mOffset, &readEntry, kEntryHeaderSize);
|
||||
entry = &readEntry;
|
||||
}
|
||||
else
|
||||
{
|
||||
entry = reinterpret_cast<const Entry *>(mData);
|
||||
}
|
||||
|
||||
size = kEntryHeaderSize + entry->GetMaskLength();
|
||||
|
||||
VerifyOrExit(size <= mLength);
|
||||
|
||||
if (Radio::SupportsChannelPage(entry->GetChannelPage()))
|
||||
{
|
||||
// Currently supported channel pages all use `uint32_t`
|
||||
// channel mask.
|
||||
|
||||
VerifyOrExit(entry->GetMaskLength() == kMaskLength);
|
||||
|
||||
if (mMessage != nullptr)
|
||||
{
|
||||
IgnoreError(mMessage->Read(mOffset, readEntry));
|
||||
}
|
||||
|
||||
aChannelMask |= (entry->GetMask() & Radio::ChannelMaskForPage(entry->GetChannelPage()));
|
||||
}
|
||||
|
||||
mLength -= size;
|
||||
|
||||
if (mMessage != nullptr)
|
||||
{
|
||||
mOffset += size;
|
||||
}
|
||||
else
|
||||
{
|
||||
mData += size;
|
||||
}
|
||||
offset += entry.GetEntrySize();
|
||||
}
|
||||
|
||||
error = kErrorNone;
|
||||
|
||||
exit:
|
||||
return mask;
|
||||
return error;
|
||||
}
|
||||
|
||||
void ChannelMaskTlv::PrepareValue(Value &aValue, uint32_t aChannelMask)
|
||||
{
|
||||
Entry *entry = reinterpret_cast<Entry *>(aValue.mData);
|
||||
|
||||
aValue.mLength = 0;
|
||||
|
||||
for (uint8_t page : Radio::kSupportedChannelPages)
|
||||
{
|
||||
uint32_t mask = (Radio::ChannelMaskForPage(page) & aChannelMask);
|
||||
|
||||
if (mask != 0)
|
||||
{
|
||||
entry->SetChannelPage(page);
|
||||
entry->SetMaskLength(kMaskLength);
|
||||
entry->SetMask(mask);
|
||||
|
||||
aValue.mLength += sizeof(Entry);
|
||||
entry++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Error ChannelMaskTlv::AppendTo(Message &aMessage, uint32_t aChannelMask)
|
||||
{
|
||||
Value value;
|
||||
|
||||
PrepareValue(value, aChannelMask);
|
||||
return Tlv::Append<ChannelMaskTlv>(aMessage, value.mData, value.mLength);
|
||||
}
|
||||
|
||||
} // namespace MeshCoP
|
||||
|
||||
@@ -613,258 +613,121 @@ typedef SimpleTlvInfo<Tlv::kPendingTimestamp, Timestamp> PendingTimestampTlv;
|
||||
*/
|
||||
typedef UintTlvInfo<Tlv::kDelayTimer, uint32_t> DelayTimerTlv;
|
||||
|
||||
// forward declare ChannelMaskTlv
|
||||
class ChannelMaskTlv;
|
||||
|
||||
/**
|
||||
* Implements Channel Mask Entry generation and parsing.
|
||||
*
|
||||
*/
|
||||
OT_TOOL_PACKED_BEGIN
|
||||
class ChannelMaskEntryBase
|
||||
{
|
||||
public:
|
||||
/**
|
||||
* Gets the ChannelPage value.
|
||||
*
|
||||
* @returns The ChannelPage value.
|
||||
*
|
||||
*/
|
||||
uint8_t GetChannelPage(void) const { return mChannelPage; }
|
||||
|
||||
/**
|
||||
* Sets the ChannelPage value.
|
||||
*
|
||||
* @param[in] aChannelPage The ChannelPage value.
|
||||
*
|
||||
*/
|
||||
void SetChannelPage(uint8_t aChannelPage) { mChannelPage = aChannelPage; }
|
||||
|
||||
/**
|
||||
* Gets the MaskLength value.
|
||||
*
|
||||
* @returns The MaskLength value.
|
||||
*
|
||||
*/
|
||||
uint8_t GetMaskLength(void) const { return mMaskLength; }
|
||||
|
||||
/**
|
||||
* Sets the MaskLength value.
|
||||
*
|
||||
* @param[in] aMaskLength The MaskLength value.
|
||||
*
|
||||
*/
|
||||
void SetMaskLength(uint8_t aMaskLength) { mMaskLength = aMaskLength; }
|
||||
|
||||
/**
|
||||
* Returns the total size of this Channel Mask Entry including the mask.
|
||||
*
|
||||
* @returns The total size of this entry (number of bytes).
|
||||
*
|
||||
*/
|
||||
uint16_t GetEntrySize(void) const { return sizeof(ChannelMaskEntryBase) + mMaskLength; }
|
||||
|
||||
/**
|
||||
* Clears the bit corresponding to @p aChannel in ChannelMask.
|
||||
*
|
||||
* @param[in] aChannel The channel in ChannelMask to clear.
|
||||
*
|
||||
*/
|
||||
void ClearChannel(uint8_t aChannel)
|
||||
{
|
||||
uint8_t *mask = reinterpret_cast<uint8_t *>(this) + sizeof(*this);
|
||||
mask[aChannel / 8] &= ~(0x80 >> (aChannel % 8));
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the bit corresponding to @p aChannel in ChannelMask.
|
||||
*
|
||||
* @param[in] aChannel The channel in ChannelMask to set.
|
||||
*
|
||||
*/
|
||||
void SetChannel(uint8_t aChannel)
|
||||
{
|
||||
uint8_t *mask = reinterpret_cast<uint8_t *>(this) + sizeof(*this);
|
||||
mask[aChannel / 8] |= 0x80 >> (aChannel % 8);
|
||||
}
|
||||
|
||||
/**
|
||||
* Indicates whether or not the bit corresponding to @p aChannel in ChannelMask is set.
|
||||
*
|
||||
* @param[in] aChannel The channel in ChannelMask to get.
|
||||
*
|
||||
*/
|
||||
bool IsChannelSet(uint8_t aChannel) const
|
||||
{
|
||||
const uint8_t *mask = reinterpret_cast<const uint8_t *>(this) + sizeof(*this);
|
||||
return (aChannel < (mMaskLength * 8)) ? ((mask[aChannel / 8] & (0x80 >> (aChannel % 8))) != 0) : false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the next Channel Mask Entry in a Channel Mask TLV.
|
||||
*
|
||||
* @returns A pointer to next Channel Mask Entry.
|
||||
*
|
||||
*/
|
||||
const ChannelMaskEntryBase *GetNext(void) const
|
||||
{
|
||||
return reinterpret_cast<const ChannelMaskEntryBase *>(reinterpret_cast<const uint8_t *>(this) + GetEntrySize());
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the next Channel Mask Entry in a Channel Mask TLV.
|
||||
*
|
||||
* @returns A pointer to next Channel Mask Entry.
|
||||
*
|
||||
*/
|
||||
ChannelMaskEntryBase *GetNext(void) { return AsNonConst(AsConst(this)->GetNext()); }
|
||||
|
||||
private:
|
||||
uint8_t mChannelPage;
|
||||
uint8_t mMaskLength;
|
||||
} OT_TOOL_PACKED_END;
|
||||
|
||||
/**
|
||||
* Implements Channel Mask Entry Page 0 generation and parsing.
|
||||
*
|
||||
*/
|
||||
OT_TOOL_PACKED_BEGIN
|
||||
class ChannelMaskEntry : public ChannelMaskEntryBase
|
||||
{
|
||||
public:
|
||||
/**
|
||||
* Initializes the entry.
|
||||
*
|
||||
*/
|
||||
void Init(void)
|
||||
{
|
||||
SetChannelPage(0);
|
||||
SetMaskLength(sizeof(mMask));
|
||||
}
|
||||
|
||||
/**
|
||||
* Indicates whether or not the entry appears to be well-formed.
|
||||
*
|
||||
* @retval TRUE If the entry appears to be well-formed.
|
||||
* @retval FALSE If the entry does not appear to be well-formed.
|
||||
*
|
||||
*/
|
||||
bool IsValid(void) const { return GetMaskLength() == sizeof(mMask); }
|
||||
|
||||
/**
|
||||
* Returns the Channel Mask value as a `uint32_t` bit mask.
|
||||
*
|
||||
* @returns The Channel Mask value.
|
||||
*
|
||||
*/
|
||||
uint32_t GetMask(void) const { return Reverse32(BigEndian::HostSwap32(mMask)); }
|
||||
|
||||
/**
|
||||
* Sets the Channel Mask value.
|
||||
*
|
||||
* @param[in] aMask The Channel Mask value.
|
||||
*
|
||||
*/
|
||||
void SetMask(uint32_t aMask) { mMask = BigEndian::HostSwap32(Reverse32(aMask)); }
|
||||
|
||||
private:
|
||||
uint32_t mMask;
|
||||
} OT_TOOL_PACKED_END;
|
||||
|
||||
/**
|
||||
* Implements Channel Mask TLV generation and parsing.
|
||||
*
|
||||
*/
|
||||
OT_TOOL_PACKED_BEGIN
|
||||
class ChannelMaskBaseTlv : public Tlv, public TlvInfo<Tlv::kChannelMask>
|
||||
class ChannelMaskTlv : public Tlv, public TlvInfo<Tlv::kChannelMask>
|
||||
{
|
||||
static constexpr uint8_t kEntryHeaderSize = 2; // Two bytes: mChannelPage and mMaskLength
|
||||
static constexpr uint8_t kEntrySize = kEntryHeaderSize + sizeof(uint32_t);
|
||||
|
||||
public:
|
||||
/**
|
||||
* Initializes the TLV.
|
||||
* Represents Channel Mask TLV value to append.
|
||||
*
|
||||
*/
|
||||
void Init(void)
|
||||
struct Value
|
||||
{
|
||||
SetType(kChannelMask);
|
||||
SetLength(sizeof(*this) - sizeof(Tlv));
|
||||
}
|
||||
static constexpr uint16_t kMaxLength = (kEntrySize * Radio::kNumChannelPages); ///< Max value length.
|
||||
|
||||
uint8_t mData[kMaxLength]; ///< Array to store TLV value (encoded as one or more Channel Mask TLV Entry)
|
||||
uint8_t mLength; ///< Value length in bytes.
|
||||
};
|
||||
|
||||
ChannelMaskTlv(void) = delete;
|
||||
|
||||
/**
|
||||
* Indicates whether or not the TLV appears to be well-formed.
|
||||
* Parses the Channel Mask TLV value and validates that all the included entries are well-formed.
|
||||
*
|
||||
* @retval TRUE If the TLV appears to be well-formed.
|
||||
* @retval FALSE If the TLV does not appear to be well-formed.
|
||||
* @returns TRUE if the TLV is well-formed, FALSE otherwise.
|
||||
*
|
||||
*/
|
||||
bool IsValid(void) const;
|
||||
|
||||
/**
|
||||
* Gets the first Channel Mask Entry in the Channel Mask TLV.
|
||||
* Parses and retrieves the combined channel mask for all supported channel pages from entries in the TLV.
|
||||
*
|
||||
* @returns A pointer to first Channel Mask Entry or `nullptr` if not found.
|
||||
* @param[out] aChannelMask A reference to return the channel mask.
|
||||
*
|
||||
* @retval kErrorNone Successfully parsed the TLV value, @p aChannelMask is updated.
|
||||
* @retval kErrorParse TLV value is not well-formed.
|
||||
*
|
||||
*/
|
||||
const ChannelMaskEntryBase *GetFirstEntry(void) const;
|
||||
Error ReadChannelMask(uint32_t &aChannelMask) const;
|
||||
|
||||
/**
|
||||
* Gets the first Channel Mask Entry in the Channel Mask TLV.
|
||||
* Searches within a given message for Channel Mask TLV, parses and validates the TLV value and returns the
|
||||
* combined channel mask for all supported channel pages included in the TLV.
|
||||
*
|
||||
* @returns A pointer to first Channel Mask Entry or `nullptr` if not found.
|
||||
* @param[in] aMessage The message to search in.
|
||||
* @param[out] aChannelMask A reference to return the channel mask.
|
||||
*
|
||||
* @retval kErrorNone Found the TLV, successfully parsed its value, @p aChannelMask is updated.
|
||||
* @retval kErrorNotFound No Channel Mask TLV found in the @p aMessage.
|
||||
* @retval kErrorParse Found the TLV, but failed to parse it.
|
||||
*
|
||||
*/
|
||||
ChannelMaskEntryBase *GetFirstEntry(void);
|
||||
} OT_TOOL_PACKED_END;
|
||||
|
||||
/**
|
||||
* Implements Channel Mask TLV generation and parsing.
|
||||
*
|
||||
*/
|
||||
OT_TOOL_PACKED_BEGIN
|
||||
class ChannelMaskTlv : public ChannelMaskBaseTlv
|
||||
{
|
||||
public:
|
||||
/**
|
||||
* Initializes the TLV.
|
||||
*
|
||||
*/
|
||||
void Init(void)
|
||||
{
|
||||
SetType(kChannelMask);
|
||||
SetLength(sizeof(*this) - sizeof(Tlv));
|
||||
memset(mEntries, 0, sizeof(mEntries));
|
||||
}
|
||||
static Error FindIn(const Message &aMessage, uint32_t &aChannelMask);
|
||||
|
||||
/**
|
||||
* Sets the Channel Mask Entries.
|
||||
* Prepares Channel Mask TLV value for appending/writing.
|
||||
*
|
||||
* @param[in] aChannelMask The Channel Mask value.
|
||||
* @param[out] aValue A reference to `Value` structure to populate.
|
||||
* @param[in] aChannelMask The combined channel mask for all supported channel pages.
|
||||
*
|
||||
*/
|
||||
void SetChannelMask(uint32_t aChannelMask);
|
||||
static void PrepareValue(Value &aValue, uint32_t aChannelMask);
|
||||
|
||||
/**
|
||||
* Returns the Channel Mask value as a `uint32_t` bit mask.
|
||||
* Prepares a Channel Mask TLV value and appends the TLV to a given message.
|
||||
*
|
||||
* @returns The Channel Mask or 0 if not found.
|
||||
* @param[in] aMessage The message to append to.
|
||||
* @param[in] aChannelMask The combined channel mask for all supported channel pages.
|
||||
*
|
||||
* @retval kErrorNone Successfully prepared the Channel Mask TLV and appended it to @p aMessage.
|
||||
* @retval kErrorNoBufs Insufficient available buffers to grow the message.
|
||||
*
|
||||
*/
|
||||
uint32_t GetChannelMask(void) const;
|
||||
|
||||
/**
|
||||
* Reads message and returns the Channel Mask value as a `uint32_t` bit mask.
|
||||
*
|
||||
* @param[in] aMessage A reference to the message.
|
||||
*
|
||||
* @returns The Channel Mask or 0 if not found.
|
||||
*
|
||||
*/
|
||||
static uint32_t GetChannelMask(const Message &aMessage);
|
||||
static Error AppendTo(Message &aMessage, uint32_t aChannelMask);
|
||||
|
||||
private:
|
||||
static constexpr uint8_t kNumMaskEntries = Radio::kNumChannelPages;
|
||||
static constexpr uint8_t kMaskLength = sizeof(uint32_t);
|
||||
|
||||
ChannelMaskEntry mEntries[kNumMaskEntries];
|
||||
} OT_TOOL_PACKED_END;
|
||||
OT_TOOL_PACKED_BEGIN
|
||||
class Entry
|
||||
{
|
||||
public:
|
||||
uint8_t GetChannelPage(void) const { return mChannelPage; }
|
||||
void SetChannelPage(uint8_t aChannelPage) { mChannelPage = aChannelPage; }
|
||||
uint8_t GetMaskLength(void) const { return mMaskLength; }
|
||||
void SetMaskLength(uint8_t aMaskLength) { mMaskLength = aMaskLength; }
|
||||
uint32_t GetMask(void) const { return Reverse32(BigEndian::HostSwap32(mMask)); }
|
||||
void SetMask(uint32_t aMask) { mMask = BigEndian::HostSwap32(Reverse32(aMask)); }
|
||||
|
||||
private:
|
||||
uint8_t mChannelPage;
|
||||
uint8_t mMaskLength;
|
||||
uint32_t mMask;
|
||||
} OT_TOOL_PACKED_END;
|
||||
|
||||
struct EntriesData : public Clearable<EntriesData>
|
||||
{
|
||||
// Represents received Channel Mask TLV Entries data which
|
||||
// is either contained in `mData` buffer, or in `mMessage`
|
||||
// at `mOffset`.
|
||||
|
||||
Error Parse(uint32_t &aChannelMask);
|
||||
|
||||
const uint8_t *mData;
|
||||
const Message *mMessage;
|
||||
uint16_t mOffset;
|
||||
uint16_t mLength;
|
||||
};
|
||||
|
||||
uint8_t mEntriesStart;
|
||||
} OT_TOOL_PACKED_BEGIN;
|
||||
|
||||
/**
|
||||
* Implements Energy List TLV generation and parsing.
|
||||
|
||||
@@ -62,10 +62,9 @@ Error PanIdQueryClient::SendQuery(uint16_t aPanId,
|
||||
otCommissionerPanIdConflictCallback aCallback,
|
||||
void *aContext)
|
||||
{
|
||||
Error error = kErrorNone;
|
||||
MeshCoP::ChannelMaskTlv channelMask;
|
||||
Tmf::MessageInfo messageInfo(GetInstance());
|
||||
Coap::Message *message = nullptr;
|
||||
Error error = kErrorNone;
|
||||
Tmf::MessageInfo messageInfo(GetInstance());
|
||||
Coap::Message *message = nullptr;
|
||||
|
||||
VerifyOrExit(Get<MeshCoP::Commissioner>().IsActive(), error = kErrorInvalidState);
|
||||
VerifyOrExit((message = Get<Tmf::Agent>().NewPriorityMessage()) != nullptr, error = kErrorNoBufs);
|
||||
@@ -76,9 +75,7 @@ Error PanIdQueryClient::SendQuery(uint16_t aPanId,
|
||||
SuccessOrExit(
|
||||
error = Tlv::Append<MeshCoP::CommissionerSessionIdTlv>(*message, Get<MeshCoP::Commissioner>().GetSessionId()));
|
||||
|
||||
channelMask.Init();
|
||||
channelMask.SetChannelMask(aChannelMask);
|
||||
SuccessOrExit(error = channelMask.AppendTo(*message));
|
||||
SuccessOrExit(error = MeshCoP::ChannelMaskTlv::AppendTo(*message, aChannelMask));
|
||||
|
||||
SuccessOrExit(error = Tlv::Append<MeshCoP::PanIdTlv>(*message, aPanId));
|
||||
|
||||
@@ -106,7 +103,7 @@ void PanIdQueryClient::HandleTmf<kUriPanIdConflict>(Coap::Message &aMessage, con
|
||||
|
||||
SuccessOrExit(Tlv::Find<MeshCoP::PanIdTlv>(aMessage, panId));
|
||||
|
||||
VerifyOrExit((mask = MeshCoP::ChannelMaskTlv::GetChannelMask(aMessage)) != 0);
|
||||
SuccessOrExit(MeshCoP::ChannelMaskTlv::FindIn(aMessage, mask));
|
||||
|
||||
mCallback.InvokeIfSet(panId, mask);
|
||||
|
||||
|
||||
@@ -36,6 +36,18 @@
|
||||
|
||||
namespace ot {
|
||||
|
||||
const uint8_t Radio::kSupportedChannelPages[kNumChannelPages] = {
|
||||
#if OPENTHREAD_CONFIG_RADIO_2P4GHZ_OQPSK_SUPPORT
|
||||
kChannelPage0,
|
||||
#endif
|
||||
#if OPENTHREAD_CONFIG_RADIO_915MHZ_OQPSK_SUPPORT
|
||||
kChannelPage2,
|
||||
#endif
|
||||
#if OPENTHREAD_CONFIG_PLATFORM_RADIO_PROPRIETARY_SUPPORT
|
||||
OPENTHREAD_CONFIG_PLATFORM_RADIO_PROPRIETARY_CHANNEL_PAGE,
|
||||
#endif
|
||||
};
|
||||
|
||||
#if OPENTHREAD_RADIO
|
||||
void Radio::Init(void)
|
||||
{
|
||||
|
||||
+75
-18
@@ -136,33 +136,33 @@ public:
|
||||
static constexpr uint32_t kSymbolTime = OT_RADIO_SYMBOL_TIME;
|
||||
static constexpr uint8_t kSymbolsPerOctet = OT_RADIO_SYMBOLS_PER_OCTET;
|
||||
static constexpr uint32_t kPhyUsPerByte = kSymbolsPerOctet * kSymbolTime;
|
||||
static constexpr uint8_t kChannelPage0 = OT_RADIO_CHANNEL_PAGE_0;
|
||||
static constexpr uint8_t kChannelPage2 = OT_RADIO_CHANNEL_PAGE_2;
|
||||
#if (OPENTHREAD_CONFIG_RADIO_2P4GHZ_OQPSK_SUPPORT && OPENTHREAD_CONFIG_RADIO_915MHZ_OQPSK_SUPPORT)
|
||||
static constexpr uint16_t kNumChannelPages = 2;
|
||||
static constexpr uint32_t kSupportedChannels =
|
||||
OT_RADIO_915MHZ_OQPSK_CHANNEL_MASK | OT_RADIO_2P4GHZ_OQPSK_CHANNEL_MASK;
|
||||
static constexpr uint8_t kChannelMin = OT_RADIO_915MHZ_OQPSK_CHANNEL_MIN;
|
||||
static constexpr uint8_t kChannelMax = OT_RADIO_2P4GHZ_OQPSK_CHANNEL_MAX;
|
||||
static constexpr uint32_t kSupportedChannelPages = OT_RADIO_CHANNEL_PAGE_0_MASK | OT_RADIO_CHANNEL_PAGE_2_MASK;
|
||||
static constexpr uint8_t kChannelMin = OT_RADIO_915MHZ_OQPSK_CHANNEL_MIN;
|
||||
static constexpr uint8_t kChannelMax = OT_RADIO_2P4GHZ_OQPSK_CHANNEL_MAX;
|
||||
#elif OPENTHREAD_CONFIG_RADIO_915MHZ_OQPSK_SUPPORT
|
||||
static constexpr uint16_t kNumChannelPages = 1;
|
||||
static constexpr uint32_t kSupportedChannels = OT_RADIO_915MHZ_OQPSK_CHANNEL_MASK;
|
||||
static constexpr uint8_t kChannelMin = OT_RADIO_915MHZ_OQPSK_CHANNEL_MIN;
|
||||
static constexpr uint8_t kChannelMax = OT_RADIO_915MHZ_OQPSK_CHANNEL_MAX;
|
||||
static constexpr uint32_t kSupportedChannelPages = OT_RADIO_CHANNEL_PAGE_2_MASK;
|
||||
static constexpr uint16_t kNumChannelPages = 1;
|
||||
static constexpr uint32_t kSupportedChannels = OT_RADIO_915MHZ_OQPSK_CHANNEL_MASK;
|
||||
static constexpr uint8_t kChannelMin = OT_RADIO_915MHZ_OQPSK_CHANNEL_MIN;
|
||||
static constexpr uint8_t kChannelMax = OT_RADIO_915MHZ_OQPSK_CHANNEL_MAX;
|
||||
#elif OPENTHREAD_CONFIG_RADIO_2P4GHZ_OQPSK_SUPPORT
|
||||
static constexpr uint16_t kNumChannelPages = 1;
|
||||
static constexpr uint32_t kSupportedChannels = OT_RADIO_2P4GHZ_OQPSK_CHANNEL_MASK;
|
||||
static constexpr uint8_t kChannelMin = OT_RADIO_2P4GHZ_OQPSK_CHANNEL_MIN;
|
||||
static constexpr uint8_t kChannelMax = OT_RADIO_2P4GHZ_OQPSK_CHANNEL_MAX;
|
||||
static constexpr uint32_t kSupportedChannelPages = OT_RADIO_CHANNEL_PAGE_0_MASK;
|
||||
static constexpr uint16_t kNumChannelPages = 1;
|
||||
static constexpr uint32_t kSupportedChannels = OT_RADIO_2P4GHZ_OQPSK_CHANNEL_MASK;
|
||||
static constexpr uint8_t kChannelMin = OT_RADIO_2P4GHZ_OQPSK_CHANNEL_MIN;
|
||||
static constexpr uint8_t kChannelMax = OT_RADIO_2P4GHZ_OQPSK_CHANNEL_MAX;
|
||||
#elif OPENTHREAD_CONFIG_PLATFORM_RADIO_PROPRIETARY_SUPPORT
|
||||
static constexpr uint16_t kNumChannelPages = 1;
|
||||
static constexpr uint32_t kSupportedChannels = OPENTHREAD_CONFIG_PLATFORM_RADIO_PROPRIETARY_CHANNEL_MASK;
|
||||
static constexpr uint8_t kChannelMin = OPENTHREAD_CONFIG_PLATFORM_RADIO_PROPRIETARY_CHANNEL_MIN;
|
||||
static constexpr uint8_t kChannelMax = OPENTHREAD_CONFIG_PLATFORM_RADIO_PROPRIETARY_CHANNEL_MAX;
|
||||
static constexpr uint32_t kSupportedChannelPages = (1 << OPENTHREAD_CONFIG_PLATFORM_RADIO_PROPRIETARY_CHANNEL_PAGE);
|
||||
static constexpr uint16_t kNumChannelPages = 1;
|
||||
static constexpr uint32_t kSupportedChannels = OPENTHREAD_CONFIG_PLATFORM_RADIO_PROPRIETARY_CHANNEL_MASK;
|
||||
static constexpr uint8_t kChannelMin = OPENTHREAD_CONFIG_PLATFORM_RADIO_PROPRIETARY_CHANNEL_MIN;
|
||||
static constexpr uint8_t kChannelMax = OPENTHREAD_CONFIG_PLATFORM_RADIO_PROPRIETARY_CHANNEL_MAX;
|
||||
#endif
|
||||
|
||||
static const uint8_t kSupportedChannelPages[kNumChannelPages];
|
||||
|
||||
static constexpr int8_t kInvalidRssi = OT_RADIO_RSSI_INVALID; ///< Invalid RSSI value.
|
||||
|
||||
static constexpr int8_t kDefaultReceiveSensitivity = -110; ///< Default receive sensitivity (in dBm).
|
||||
@@ -771,6 +771,63 @@ public:
|
||||
*/
|
||||
Error GetRegion(uint16_t &aRegionCode) const { return otPlatRadioGetRegion(GetInstancePtr(), &aRegionCode); }
|
||||
|
||||
/**
|
||||
* Indicates whether a given channel page is supported based on the current configurations.
|
||||
*
|
||||
* @param[in] aChannelPage The channel page to check.
|
||||
*
|
||||
* @retval TRUE The @p aChannelPage is supported by radio.
|
||||
* @retval FALASE The @p aChannelPage is not supported by radio.
|
||||
*
|
||||
*/
|
||||
static constexpr bool SupportsChannelPage(uint8_t aChannelPage)
|
||||
{
|
||||
#if OPENTHREAD_CONFIG_RADIO_2P4GHZ_OQPSK_SUPPORT && OPENTHREAD_CONFIG_RADIO_915MHZ_OQPSK_SUPPORT
|
||||
return (aChannelPage == kChannelPage0) || (aChannelPage == kChannelPage2);
|
||||
#elif OPENTHREAD_CONFIG_RADIO_2P4GHZ_OQPSK_SUPPORT
|
||||
return (aChannelPage == kChannelPage0);
|
||||
#elif OPENTHREAD_CONFIG_RADIO_915MHZ_OQPSK_SUPPORT
|
||||
return (aChannelPage == kChannelPage2);
|
||||
#elif OPENTHREAD_CONFIG_PLATFORM_RADIO_PROPRIETARY_SUPPORT
|
||||
return (aChannelPage == OPENTHREAD_CONFIG_PLATFORM_RADIO_PROPRIETARY_CHANNEL_PAGE);
|
||||
#endif
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the channel mask for a given channel page if supported by the radio.
|
||||
*
|
||||
* @param[in] aChannelPage The channel page.
|
||||
*
|
||||
* @returns The channel mask for @p aChannelPage if page is supported by the radio, otherwise zero.
|
||||
*
|
||||
*/
|
||||
static uint32_t ChannelMaskForPage(uint8_t aChannelPage)
|
||||
{
|
||||
uint32_t mask = 0;
|
||||
|
||||
#if OPENTHREAD_CONFIG_RADIO_2P4GHZ_OQPSK_SUPPORT
|
||||
if (aChannelPage == kChannelPage0)
|
||||
{
|
||||
mask = OT_RADIO_2P4GHZ_OQPSK_CHANNEL_MASK;
|
||||
}
|
||||
#endif
|
||||
|
||||
#if OPENTHREAD_CONFIG_RADIO_915MHZ_OQPSK_SUPPORT
|
||||
if (aChannelPage == kChannelPage1)
|
||||
{
|
||||
mask = OT_RADIO_915MHZ_OQPSK_CHANNEL_MASK;
|
||||
}
|
||||
#endif
|
||||
|
||||
#if OPENTHREAD_CONFIG_PLATFORM_RADIO_PROPRIETARY_SUPPORT
|
||||
if (aChannelPage == OPENTHREAD_CONFIG_PLATFORM_RADIO_PROPRIETARY_CHANNEL_PAGE)
|
||||
{
|
||||
mask = OPENTHREAD_CONFIG_PLATFORM_RADIO_PROPRIETARY_CHANNEL_MASK;
|
||||
}
|
||||
#endif
|
||||
return mask;
|
||||
}
|
||||
|
||||
private:
|
||||
otInstance *GetInstancePtr(void) const { return reinterpret_cast<otInstance *>(&InstanceLocator::GetInstance()); }
|
||||
|
||||
|
||||
@@ -71,7 +71,7 @@ void AnnounceBeginServer::HandleTmf<kUriAnnounceBegin>(Coap::Message &aMessage,
|
||||
uint16_t period;
|
||||
|
||||
VerifyOrExit(aMessage.IsPostRequest());
|
||||
VerifyOrExit((mask = MeshCoP::ChannelMaskTlv::GetChannelMask(aMessage)) != 0);
|
||||
SuccessOrExit(MeshCoP::ChannelMaskTlv::FindIn(aMessage, mask));
|
||||
|
||||
SuccessOrExit(Tlv::Find<MeshCoP::CountTlv>(aMessage, count));
|
||||
SuccessOrExit(Tlv::Find<MeshCoP::PeriodTlv>(aMessage, period));
|
||||
|
||||
@@ -63,12 +63,11 @@ EnergyScanServer::EnergyScanServer(Instance &aInstance)
|
||||
template <>
|
||||
void EnergyScanServer::HandleTmf<kUriEnergyScan>(Coap::Message &aMessage, const Ip6::MessageInfo &aMessageInfo)
|
||||
{
|
||||
uint8_t count;
|
||||
uint16_t period;
|
||||
uint16_t scanDuration;
|
||||
uint32_t mask;
|
||||
MeshCoP::Tlv tlv;
|
||||
MeshCoP::ChannelMaskTlv channelMaskTlv;
|
||||
uint8_t count;
|
||||
uint16_t period;
|
||||
uint16_t scanDuration;
|
||||
uint32_t mask;
|
||||
MeshCoP::Tlv tlv;
|
||||
|
||||
VerifyOrExit(aMessage.IsPostRequest());
|
||||
|
||||
@@ -76,15 +75,13 @@ void EnergyScanServer::HandleTmf<kUriEnergyScan>(Coap::Message &aMessage, const
|
||||
SuccessOrExit(Tlv::Find<MeshCoP::PeriodTlv>(aMessage, period));
|
||||
SuccessOrExit(Tlv::Find<MeshCoP::ScanDurationTlv>(aMessage, scanDuration));
|
||||
|
||||
VerifyOrExit((mask = MeshCoP::ChannelMaskTlv::GetChannelMask(aMessage)) != 0);
|
||||
SuccessOrExit(MeshCoP::ChannelMaskTlv::FindIn(aMessage, mask));
|
||||
|
||||
FreeMessage(mReportMessage);
|
||||
mReportMessage = Get<Tmf::Agent>().NewPriorityConfirmablePostMessage(kUriEnergyReport);
|
||||
VerifyOrExit(mReportMessage != nullptr);
|
||||
|
||||
channelMaskTlv.Init();
|
||||
channelMaskTlv.SetChannelMask(mask);
|
||||
SuccessOrExit(channelMaskTlv.AppendTo(*mReportMessage));
|
||||
SuccessOrExit(MeshCoP::ChannelMaskTlv::AppendTo(*mReportMessage, mask));
|
||||
|
||||
tlv.SetType(MeshCoP::Tlv::kEnergyList);
|
||||
SuccessOrExit(mReportMessage->Append(tlv));
|
||||
|
||||
@@ -125,8 +125,7 @@ bool ChannelTlvValue::IsValid(void) const
|
||||
bool isValid = false;
|
||||
uint16_t channel;
|
||||
|
||||
VerifyOrExit(mChannelPage < BitSizeOf(uint32_t));
|
||||
VerifyOrExit((1U << mChannelPage) & Radio::kSupportedChannelPages);
|
||||
VerifyOrExit(Radio::SupportsChannelPage(mChannelPage));
|
||||
|
||||
channel = GetChannel();
|
||||
VerifyOrExit((Radio::kChannelMin <= channel) && (channel <= Radio::kChannelMax));
|
||||
|
||||
@@ -322,12 +322,9 @@ Error Server::AppendDiagTlv(uint8_t aTlvType, Message &aMessage)
|
||||
|
||||
tlv.Init();
|
||||
|
||||
for (uint8_t page = 0; page < static_cast<uint8_t>(BitSizeOf(Radio::kSupportedChannelPages)); page++)
|
||||
for (uint8_t page : Radio::kSupportedChannelPages)
|
||||
{
|
||||
if (Radio::kSupportedChannelPages & (1 << page))
|
||||
{
|
||||
tlv.GetChannelPages()[length++] = page;
|
||||
}
|
||||
tlv.GetChannelPages()[length++] = page;
|
||||
}
|
||||
|
||||
tlv.SetLength(length);
|
||||
|
||||
@@ -64,7 +64,7 @@ void PanIdQueryServer::HandleTmf<kUriPanIdQuery>(Coap::Message &aMessage, const
|
||||
uint32_t mask;
|
||||
|
||||
VerifyOrExit(aMessage.IsPostRequest());
|
||||
VerifyOrExit((mask = MeshCoP::ChannelMaskTlv::GetChannelMask(aMessage)) != 0);
|
||||
SuccessOrExit(MeshCoP::ChannelMaskTlv::FindIn(aMessage, mask));
|
||||
|
||||
SuccessOrExit(Tlv::Find<MeshCoP::PanIdTlv>(aMessage, panId));
|
||||
|
||||
@@ -105,17 +105,14 @@ void PanIdQueryServer::HandleScanResult(Mac::ActiveScanResult *aScanResult)
|
||||
|
||||
void PanIdQueryServer::SendConflict(void)
|
||||
{
|
||||
Error error = kErrorNone;
|
||||
MeshCoP::ChannelMaskTlv channelMask;
|
||||
Tmf::MessageInfo messageInfo(GetInstance());
|
||||
Coap::Message *message;
|
||||
Error error = kErrorNone;
|
||||
Tmf::MessageInfo messageInfo(GetInstance());
|
||||
Coap::Message *message;
|
||||
|
||||
message = Get<Tmf::Agent>().NewPriorityConfirmablePostMessage(kUriPanIdConflict);
|
||||
VerifyOrExit(message != nullptr, error = kErrorNoBufs);
|
||||
|
||||
channelMask.Init();
|
||||
channelMask.SetChannelMask(mChannelMask);
|
||||
SuccessOrExit(error = channelMask.AppendTo(*message));
|
||||
SuccessOrExit(error = MeshCoP::ChannelMaskTlv::AppendTo(*message, mChannelMask));
|
||||
|
||||
SuccessOrExit(error = Tlv::Append<MeshCoP::PanIdTlv>(*message, mPanId));
|
||||
|
||||
|
||||
Reference in New Issue
Block a user