mirror of
https://github.com/espressif/openthread.git
synced 2026-06-06 05:24:51 +00:00
[mac] adds the wake-up identifier to the Connection IE (#11907)
The P2P peer can be woken up using the wake-up identifier. The wake-up identifier is included in the Connection IE. This commit implements methods to the Connection IE and Frame to process wake-up identifier.
This commit is contained in:
+27
-12
@@ -299,11 +299,12 @@ exit:
|
||||
#if OPENTHREAD_CONFIG_WAKEUP_COORDINATOR_ENABLE || OPENTHREAD_CONFIG_WAKEUP_END_DEVICE_ENABLE
|
||||
bool Frame::IsWakeupFrame(void) const
|
||||
{
|
||||
const uint16_t fcf = GetFrameControlField();
|
||||
bool result = false;
|
||||
uint8_t keyIdMode;
|
||||
uint8_t firstIeIndex;
|
||||
Address srcAddress;
|
||||
const uint16_t fcf = GetFrameControlField();
|
||||
bool result = false;
|
||||
uint8_t keyIdMode;
|
||||
uint8_t firstIeIndex;
|
||||
Address srcAddress;
|
||||
const ConnectionIe *connectionIe;
|
||||
|
||||
// Wake-up frame is a Multipurpose frame without Ack Request...
|
||||
VerifyOrExit((fcf & kFcfFrameTypeMask) == kTypeMultipurpose);
|
||||
@@ -319,12 +320,12 @@ bool Frame::IsWakeupFrame(void) const
|
||||
|
||||
// ... that has Rendezvous Time IE and Connection IE...
|
||||
VerifyOrExit(GetRendezvousTimeIe() != nullptr);
|
||||
VerifyOrExit(GetConnectionIe() != nullptr);
|
||||
VerifyOrExit((connectionIe = GetConnectionIe()) != nullptr);
|
||||
|
||||
// ... but no other IEs nor payload.
|
||||
firstIeIndex = FindHeaderIeIndex();
|
||||
VerifyOrExit(mPsdu + firstIeIndex + sizeof(HeaderIe) + RendezvousTimeIe::kIeContentSize + sizeof(HeaderIe) +
|
||||
ConnectionIe::kIeContentSize ==
|
||||
connectionIe->GetHeaderIe()->GetLength() ==
|
||||
GetFooter());
|
||||
|
||||
result = true;
|
||||
@@ -1505,26 +1506,39 @@ exit:
|
||||
#endif // OPENTHREAD_CONFIG_THREAD_VERSION >= OT_THREAD_VERSION_1_2
|
||||
|
||||
#if OPENTHREAD_CONFIG_WAKEUP_COORDINATOR_ENABLE
|
||||
Error TxFrame::GenerateWakeupFrame(PanId aPanId, const Address &aDest, const Address &aSource)
|
||||
Error TxFrame::GenerateWakeupFrame(PanId aPanId, const WakeupRequest &aWakeupRequest, const Address &aSource)
|
||||
{
|
||||
Error error = kErrorNone;
|
||||
uint16_t fcf;
|
||||
uint8_t secCtl;
|
||||
uint8_t wakeupIdLength;
|
||||
FrameBuilder builder;
|
||||
Address dest;
|
||||
|
||||
fcf = kTypeMultipurpose | kMpFcfLongFrame | kMpFcfPanidPresent | kMpFcfSecurityEnabled | kMpFcfSequenceSuppression |
|
||||
kMpFcfIePresent;
|
||||
|
||||
VerifyOrExit(!aDest.IsNone() && !aSource.IsNone(), error = kErrorInvalidArgs);
|
||||
VerifyOrExit(!aSource.IsNone(), error = kErrorInvalidArgs);
|
||||
|
||||
fcf |= DetermineFcfAddrType(aDest, kMpFcfDstAddrShift);
|
||||
if (aWakeupRequest.IsWakeupByExtAddress())
|
||||
{
|
||||
wakeupIdLength = 0;
|
||||
dest.SetExtended(aWakeupRequest.GetExtAddress());
|
||||
}
|
||||
else
|
||||
{
|
||||
wakeupIdLength = GetWakeupIdLength(aWakeupRequest.GetWakeupId());
|
||||
dest.SetNone();
|
||||
}
|
||||
|
||||
fcf |= DetermineFcfAddrType(dest, kMpFcfDstAddrShift);
|
||||
fcf |= DetermineFcfAddrType(aSource, kMpFcfSrcAddrShift);
|
||||
|
||||
builder.Init(mPsdu, GetMtu());
|
||||
|
||||
IgnoreError(builder.AppendLittleEndianUint16(fcf));
|
||||
IgnoreError(builder.AppendLittleEndianUint16(aPanId));
|
||||
IgnoreError(builder.AppendMacAddress(aDest));
|
||||
IgnoreError(builder.AppendMacAddress(dest));
|
||||
IgnoreError(builder.AppendMacAddress(aSource));
|
||||
|
||||
secCtl = kKeyIdMode2 | kSecurityEncMic32;
|
||||
@@ -1534,8 +1548,9 @@ Error TxFrame::GenerateWakeupFrame(PanId aPanId, const Address &aDest, const Add
|
||||
builder.Append<HeaderIe>()->Init(RendezvousTimeIe::kHeaderIeId, sizeof(RendezvousTimeIe));
|
||||
builder.Append<RendezvousTimeIe>();
|
||||
|
||||
builder.Append<HeaderIe>()->Init(ConnectionIe::kHeaderIeId, sizeof(ConnectionIe));
|
||||
builder.Append<HeaderIe>()->Init(ConnectionIe::kHeaderIeId, sizeof(ConnectionIe) + wakeupIdLength);
|
||||
builder.Append<ConnectionIe>()->Init();
|
||||
builder.AppendLength(wakeupIdLength);
|
||||
|
||||
builder.AppendLength(CalculateMicSize(secCtl) + GetFcsSize());
|
||||
|
||||
|
||||
@@ -1322,14 +1322,14 @@ public:
|
||||
/**
|
||||
* Generate IEE 802.15.4 Wake-up frame.
|
||||
*
|
||||
* @param[in] aPanId A destination PAN identifier
|
||||
* @param[in] aDest A destination address (short or extended)
|
||||
* @param[in] aSource A source address (short or extended)
|
||||
* @param[in] aPanId A destination PAN identifier
|
||||
* @param[in] aWakeupRequest A const reference to the wake-up request.
|
||||
* @param[in] aSource A source address (short or extended)
|
||||
*
|
||||
* @retval kErrorNone Successfully generated Wake-up frame.
|
||||
* @retval kErrorInvalidArgs @p aDest or @p aSource have incorrect type.
|
||||
*/
|
||||
Error GenerateWakeupFrame(PanId aPanId, const Address &aDest, const Address &aSource);
|
||||
Error GenerateWakeupFrame(PanId aPanId, const WakeupRequest &aWakeupRequest, const Address &aSource);
|
||||
#endif
|
||||
|
||||
#if OPENTHREAD_CONFIG_THREAD_VERSION >= OT_THREAD_VERSION_1_2
|
||||
|
||||
@@ -43,5 +43,41 @@ void HeaderIe::Init(uint16_t aId, uint8_t aLen)
|
||||
SetLength(aLen);
|
||||
}
|
||||
|
||||
#if OPENTHREAD_CONFIG_WAKEUP_COORDINATOR_ENABLE || OPENTHREAD_CONFIG_WAKEUP_END_DEVICE_ENABLE
|
||||
Error ConnectionIe::SetWakeupId(WakeupId aWakeupId)
|
||||
{
|
||||
Error error = kErrorNone;
|
||||
const HeaderIe *headerIe = GetHeaderIe();
|
||||
uint8_t wakeupIdLength = GetWakeupIdLength(aWakeupId);
|
||||
|
||||
VerifyOrExit(headerIe->GetLength() > sizeof(ConnectionIe), error = kErrorParse);
|
||||
VerifyOrExit(headerIe->GetLength() - sizeof(ConnectionIe) == wakeupIdLength, error = kErrorParse);
|
||||
aWakeupId = LittleEndian::HostSwap64(aWakeupId);
|
||||
memcpy(GetWakeupIdData(), reinterpret_cast<uint8_t *>(&aWakeupId), wakeupIdLength);
|
||||
|
||||
exit:
|
||||
return error;
|
||||
}
|
||||
|
||||
Error ConnectionIe::GetWakeupId(WakeupId &aWakeupId) const
|
||||
{
|
||||
Error error = kErrorNone;
|
||||
const HeaderIe *headerIe = GetHeaderIe();
|
||||
uint8_t wakeupIdLength;
|
||||
|
||||
VerifyOrExit(headerIe->GetLength() > sizeof(ConnectionIe), error = kErrorParse);
|
||||
|
||||
wakeupIdLength = headerIe->GetLength() - sizeof(ConnectionIe);
|
||||
VerifyOrExit(wakeupIdLength <= sizeof(WakeupId), error = kErrorParse);
|
||||
|
||||
aWakeupId = 0;
|
||||
memcpy(reinterpret_cast<uint8_t *>(&aWakeupId), GetWakeupIdData(), wakeupIdLength);
|
||||
aWakeupId = LittleEndian::HostSwap64(aWakeupId);
|
||||
|
||||
exit:
|
||||
return error;
|
||||
}
|
||||
#endif // OPENTHREAD_CONFIG_WAKEUP_COORDINATOR_ENABLE || OPENTHREAD_CONFIG_WAKEUP_END_DEVICE_ENABLE
|
||||
|
||||
} // namespace Mac
|
||||
} // namespace ot
|
||||
|
||||
@@ -377,11 +377,44 @@ public:
|
||||
*/
|
||||
void SetRetryCount(uint8_t aRetryCount) { WriteBits<uint8_t, kRetryCountMask>(mConnectionWindow, aRetryCount); }
|
||||
|
||||
/**
|
||||
* Sets the Wake-up Identifier.
|
||||
*
|
||||
* @param[in] aWakeupId The Wake-up Identifier.
|
||||
*
|
||||
* @retval kErrorNone Successfully set the Wake-up Identifier.
|
||||
* @retval kErrorParse The length of the given Wake-up Identifier didn't match the reserved length.
|
||||
*/
|
||||
Error SetWakeupId(WakeupId aWakeupId);
|
||||
|
||||
/**
|
||||
* Gets the Wake-up Identifier.
|
||||
*
|
||||
* @param[out] aWakeupId A reference to the Wake-up Identifier.
|
||||
*
|
||||
* @retval kErrorNone Successfully got the Wake-up Identifier.
|
||||
* @retval kErrorParse Failed to parse the Wake-up Identifier from the Connection IE.
|
||||
*/
|
||||
Error GetWakeupId(WakeupId &aWakeupId) const;
|
||||
|
||||
/**
|
||||
* Gets the pointer to the HeaderIe of this ConnectionIe.
|
||||
*
|
||||
* @returns A pointer to the HeaderIe.
|
||||
*/
|
||||
const HeaderIe *GetHeaderIe(void) const
|
||||
{
|
||||
return reinterpret_cast<const HeaderIe *>(reinterpret_cast<const uint8_t *>(this) - sizeof(HeaderIe));
|
||||
}
|
||||
|
||||
private:
|
||||
static constexpr uint8_t kRetryIntervalOffset = 4;
|
||||
static constexpr uint8_t kRetryIntervalMask = 0x3 << kRetryIntervalOffset;
|
||||
static constexpr uint8_t kRetryCountMask = 0xf;
|
||||
|
||||
const uint8_t *GetWakeupIdData(void) const { return reinterpret_cast<const uint8_t *>(this) + sizeof(*this); }
|
||||
uint8_t *GetWakeupIdData(void) { return reinterpret_cast<uint8_t *>(this) + sizeof(*this); }
|
||||
|
||||
uint8_t mConnectionWindow;
|
||||
} OT_TOOL_PACKED_END;
|
||||
#endif // OPENTHREAD_CONFIG_WAKEUP_COORDINATOR_ENABLE || OPENTHREAD_CONFIG_WAKEUP_END_DEVICE_ENABLE
|
||||
|
||||
@@ -35,6 +35,7 @@
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
#include "common/bit_utils.hpp"
|
||||
#include "common/code_utils.hpp"
|
||||
#include "common/random.hpp"
|
||||
#include "common/string.hpp"
|
||||
@@ -404,6 +405,27 @@ bool KeyMaterial::operator==(const KeyMaterial &aOther) const
|
||||
#endif
|
||||
}
|
||||
|
||||
#if OPENTHREAD_CONFIG_WAKEUP_COORDINATOR_ENABLE || OPENTHREAD_CONFIG_WAKEUP_END_DEVICE_ENABLE
|
||||
uint8_t GetWakeupIdLength(WakeupId aWakeupId)
|
||||
{
|
||||
uint8_t zeroBytesCount = 0;
|
||||
|
||||
for (int i = static_cast<int>(sizeof(WakeupId)) - 1; i >= 1; --i)
|
||||
{
|
||||
if (((aWakeupId >> (i * kBitsPerByte)) & 0xFF) == 0)
|
||||
{
|
||||
zeroBytesCount++;
|
||||
}
|
||||
else
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return sizeof(WakeupId) - zeroBytesCount;
|
||||
}
|
||||
#endif
|
||||
|
||||
#if OPENTHREAD_CONFIG_WAKEUP_COORDINATOR_ENABLE
|
||||
void WakeupRequest::SetExtAddress(const ExtAddress &aExtAddress)
|
||||
{
|
||||
|
||||
@@ -81,6 +81,11 @@ typedef otShortAddress ShortAddress;
|
||||
constexpr ShortAddress kShortAddrBroadcast = OT_RADIO_BROADCAST_SHORT_ADDR; ///< Broadcast Short Address.
|
||||
constexpr ShortAddress kShortAddrInvalid = OT_RADIO_INVALID_SHORT_ADDR; ///< Invalid Short Address.
|
||||
|
||||
/**
|
||||
* Represents the wake-up identifier.
|
||||
*/
|
||||
typedef otWakeupId WakeupId;
|
||||
|
||||
/**
|
||||
* Generates a random IEEE 802.15.4 PAN ID.
|
||||
*
|
||||
@@ -960,6 +965,19 @@ private:
|
||||
uint8_t mUncertainty;
|
||||
};
|
||||
|
||||
#if OPENTHREAD_CONFIG_WAKEUP_COORDINATOR_ENABLE || OPENTHREAD_CONFIG_WAKEUP_END_DEVICE_ENABLE
|
||||
/**
|
||||
* Gets the length of the wake-up identifier.
|
||||
*
|
||||
* The length is the number of bytes remaining after removing the most significant zero bytes.
|
||||
*
|
||||
* @param[in] aWakeupId The wake-up identifier.
|
||||
*
|
||||
* @returns The length of the @p aWakeupId.
|
||||
*/
|
||||
uint8_t GetWakeupIdLength(WakeupId aWakeupId);
|
||||
#endif
|
||||
|
||||
#if OPENTHREAD_CONFIG_WAKEUP_COORDINATOR_ENABLE
|
||||
/**
|
||||
* Represents a wake-up request.
|
||||
@@ -1004,6 +1022,28 @@ public:
|
||||
*/
|
||||
ExtAddress &GetExtAddress(void);
|
||||
|
||||
/**
|
||||
* Gets the Wake-up Identifier of the wake-up request.
|
||||
*
|
||||
* MUST be used only if the wake-up request type is `kTypeWakeupId` or `kTypeGroupWakeupId`.
|
||||
*
|
||||
* @returns The Wake-up Identifier.
|
||||
*/
|
||||
WakeupId GetWakeupId(void) const { return mShared.mWakeupId; }
|
||||
|
||||
/**
|
||||
* Sets the wake-up request with the Wake-up Identifier.
|
||||
*
|
||||
* The type is also updated to indicate that the wake-up request type is `kTypeWakeupId`.
|
||||
*
|
||||
* @param[in] aWakeupId A Wake-up Identifier.
|
||||
*/
|
||||
void SetWakeupId(WakeupId aWakeupId)
|
||||
{
|
||||
SetType(kTypeWakeupId);
|
||||
mShared.mWakeupId = aWakeupId;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the wake-up request type.
|
||||
*
|
||||
|
||||
@@ -80,7 +80,6 @@ void WakeupTxScheduler::RequestWakeupFrameTransmission(void) { Get<Mac::Mac>().R
|
||||
Mac::TxFrame *WakeupTxScheduler::PrepareWakeupFrame(Mac::TxFrames &aTxFrames)
|
||||
{
|
||||
Mac::TxFrame *frame = nullptr;
|
||||
Mac::Address target;
|
||||
Mac::Address source;
|
||||
uint32_t radioTxDelay;
|
||||
uint32_t rendezvousTimeUs;
|
||||
@@ -89,7 +88,6 @@ Mac::TxFrame *WakeupTxScheduler::PrepareWakeupFrame(Mac::TxFrames &aTxFrames)
|
||||
|
||||
VerifyOrExit(mIsRunning);
|
||||
|
||||
target.SetExtended(mWakeupRequest.GetExtAddress());
|
||||
source.SetExtended(Get<Mac::Mac>().GetExtAddress());
|
||||
VerifyOrExit(mTxTimeUs >= nowUs);
|
||||
radioTxDelay = mTxTimeUs - nowUs;
|
||||
@@ -100,7 +98,8 @@ Mac::TxFrame *WakeupTxScheduler::PrepareWakeupFrame(Mac::TxFrames &aTxFrames)
|
||||
frame = &aTxFrames.GetTxFrame();
|
||||
#endif
|
||||
|
||||
VerifyOrExit(frame->GenerateWakeupFrame(Get<Mac::Mac>().GetPanId(), target, source) == kErrorNone, frame = nullptr);
|
||||
VerifyOrExit(frame->GenerateWakeupFrame(Get<Mac::Mac>().GetPanId(), mWakeupRequest, source) == kErrorNone,
|
||||
frame = nullptr);
|
||||
frame->SetTxDelayBaseTime(static_cast<uint32_t>(Get<Radio>().GetNow()));
|
||||
frame->SetTxDelay(radioTxDelay);
|
||||
frame->SetCsmaCaEnabled(kWakeupFrameTxCca);
|
||||
|
||||
@@ -785,6 +785,7 @@ void TestMacFrameAckGeneration(void)
|
||||
#if OPENTHREAD_CONFIG_WAKEUP_COORDINATOR_ENABLE
|
||||
constexpr uint16_t kMpFcfLongFrame = 1 << 3;
|
||||
constexpr uint16_t kMpFcfDstAddrShift = 4;
|
||||
constexpr uint16_t kMpFcfDstAddrNone = 0 << kMpFcfDstAddrShift;
|
||||
constexpr uint16_t kMpFcfDstAddrExt = 3 << kMpFcfDstAddrShift;
|
||||
constexpr uint16_t kMpFcfSrcAddrShift = 6;
|
||||
constexpr uint16_t kMpFcfSrcAddrShort = 2 << kMpFcfSrcAddrShift;
|
||||
@@ -797,9 +798,10 @@ constexpr uint16_t kMpFcfIePresent = 1 << 15;
|
||||
|
||||
void TestMacWakeupFrameGeneration(void)
|
||||
{
|
||||
constexpr static uint8_t kSrcExtaddr[] = {0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08};
|
||||
constexpr static uint8_t kDstExtaddr[] = {0xf0, 0xe1, 0xd2, 0xc3, 0xb4, 0xa5, 0x96, 0x87};
|
||||
constexpr static uint8_t kKeySource[] = {0, 0, 0, 0x1c};
|
||||
constexpr static Mac::WakeupId kWakeupId = 0x1020;
|
||||
constexpr static uint8_t kSrcExtaddr[] = {0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08};
|
||||
constexpr static uint8_t kDstExtaddr[] = {0xf0, 0xe1, 0xd2, 0xc3, 0xb4, 0xa5, 0x96, 0x87};
|
||||
constexpr static uint8_t kKeySource[] = {0, 0, 0, 0x1c};
|
||||
|
||||
constexpr static uint8_t kWakeupPsdu[] = {
|
||||
// Frame Control
|
||||
@@ -818,10 +820,28 @@ void TestMacWakeupFrameGeneration(void)
|
||||
// Connection IE
|
||||
0x05, 0x00, 0x9b, 0xb8, 0xea, 0x01, 0x1c};
|
||||
|
||||
constexpr static uint8_t kWakeupPsdu2[] = {
|
||||
// Frame Control
|
||||
Mac::Frame::kTypeMultipurpose | kMpFcfLongFrame | kMpFcfDstAddrNone | kMpFcfSrcAddrExt,
|
||||
(kMpFcfPanidPresent | kMpFcfSecurityEnabled | kMpFcfSequenceSuppression | kMpFcfIePresent) >> 8,
|
||||
// PAN ID
|
||||
0xce, 0xfa,
|
||||
// No Destination Address
|
||||
// Source Address
|
||||
0x08, 0x07, 0x06, 0x05, 0x04, 0x03, 0x02, 0x01,
|
||||
// Security Header
|
||||
Mac::Frame::kKeyIdMode2 | Mac::Frame::kSecurityEncMic32, 0xfc, 0xfc, 0xfc, 0xfc, 0x00, 0x00, 0x00, 0x1c, 0x1d,
|
||||
// Rendezvous Time IE
|
||||
0x82, 0x0e, 0xcd, 0xab,
|
||||
// Connection IE
|
||||
0x07, 0x00, 0x9b, 0xb8, 0xea, 0x01, 0x1c, 0x20, 0x10};
|
||||
|
||||
uint8_t psdu[OT_RADIO_FRAME_MAX_SIZE];
|
||||
Mac::Address src;
|
||||
Mac::Address dst;
|
||||
Mac::Address addr;
|
||||
Mac::WakeupId wakeupId;
|
||||
Mac::WakeupRequest wakeupRequest;
|
||||
Mac::TxFrame txFrame;
|
||||
Mac::Frame rxFrame;
|
||||
Mac::ConnectionIe *connectionIe;
|
||||
@@ -830,11 +850,12 @@ void TestMacWakeupFrameGeneration(void)
|
||||
|
||||
src.SetExtended(kSrcExtaddr);
|
||||
dst.SetExtended(kDstExtaddr);
|
||||
wakeupRequest.SetExtAddress(dst.GetExtended());
|
||||
txFrame.mPsdu = psdu;
|
||||
txFrame.mLength = 0;
|
||||
txFrame.mRadioType = 0;
|
||||
|
||||
SuccessOrQuit(txFrame.GenerateWakeupFrame(0xface, dst, src));
|
||||
SuccessOrQuit(txFrame.GenerateWakeupFrame(0xface, wakeupRequest, src));
|
||||
|
||||
// Validate that the frame satisfies the wake-up frame definition
|
||||
VerifyOrQuit(txFrame.GetType() == Mac::Frame::kTypeMultipurpose);
|
||||
@@ -855,10 +876,12 @@ void TestMacWakeupFrameGeneration(void)
|
||||
connectionIe = txFrame.GetConnectionIe();
|
||||
connectionIe->SetRetryInterval(1);
|
||||
connectionIe->SetRetryCount(12);
|
||||
VerifyOrQuit(connectionIe->SetWakeupId(kWakeupId) == kErrorParse);
|
||||
|
||||
VerifyOrQuit(txFrame.GetRendezvousTimeIe()->GetRendezvousTime() == 0xabcd);
|
||||
VerifyOrQuit(connectionIe->GetRetryInterval() == 1);
|
||||
VerifyOrQuit(connectionIe->GetRetryCount() == 12);
|
||||
VerifyOrQuit(connectionIe->GetWakeupId(wakeupId) == kErrorParse);
|
||||
VerifyOrQuit(txFrame.GetLength() == sizeof(kWakeupPsdu) + txFrame.GetFooterLength());
|
||||
VerifyOrQuit(memcmp(psdu, kWakeupPsdu, sizeof(kWakeupPsdu)) == 0);
|
||||
|
||||
@@ -869,6 +892,53 @@ void TestMacWakeupFrameGeneration(void)
|
||||
|
||||
SuccessOrQuit(rxFrame.ValidatePsdu());
|
||||
VerifyOrQuit(rxFrame.IsWakeupFrame());
|
||||
|
||||
// Validate the wake-up frame using the wake-up identifier.
|
||||
src.SetExtended(kSrcExtaddr);
|
||||
wakeupRequest.SetWakeupId(kWakeupId);
|
||||
txFrame.mPsdu = psdu;
|
||||
txFrame.mLength = 0;
|
||||
txFrame.mRadioType = 0;
|
||||
|
||||
SuccessOrQuit(txFrame.GenerateWakeupFrame(0xface, wakeupRequest, src));
|
||||
|
||||
// Validate that the frame satisfies the wake-up frame definition
|
||||
VerifyOrQuit(txFrame.GetType() == Mac::Frame::kTypeMultipurpose);
|
||||
VerifyOrQuit(!txFrame.GetAckRequest());
|
||||
VerifyOrQuit(txFrame.GetRendezvousTimeIe() != nullptr);
|
||||
VerifyOrQuit(txFrame.GetConnectionIe() != nullptr);
|
||||
VerifyOrQuit(txFrame.GetPayloadLength() == 0);
|
||||
SuccessOrQuit(txFrame.GetSrcAddr(addr));
|
||||
VerifyOrQuit(CompareAddresses(src, addr));
|
||||
SuccessOrQuit(txFrame.GetDstAddr(addr));
|
||||
VerifyOrQuit(addr.IsNone());
|
||||
|
||||
// Initialize remaining fields and check if the frame has the expected contents
|
||||
txFrame.SetFrameCounter(0xfcfcfcfc);
|
||||
txFrame.SetKeySource(kKeySource);
|
||||
txFrame.SetKeyId(0x1d);
|
||||
txFrame.GetRendezvousTimeIe()->SetRendezvousTime(0xabcd);
|
||||
connectionIe = txFrame.GetConnectionIe();
|
||||
connectionIe->SetRetryInterval(1);
|
||||
connectionIe->SetRetryCount(12);
|
||||
SuccessOrQuit(connectionIe->SetWakeupId(kWakeupId));
|
||||
|
||||
VerifyOrQuit(txFrame.GetRendezvousTimeIe()->GetRendezvousTime() == 0xabcd);
|
||||
VerifyOrQuit(connectionIe->GetRetryInterval() == 1);
|
||||
VerifyOrQuit(connectionIe->GetRetryCount() == 12);
|
||||
SuccessOrQuit(connectionIe->GetWakeupId(wakeupId));
|
||||
VerifyOrQuit(wakeupId == kWakeupId);
|
||||
VerifyOrQuit(wakeupRequest.GetWakeupId() == kWakeupId);
|
||||
VerifyOrQuit(txFrame.GetLength() == sizeof(kWakeupPsdu2) + txFrame.GetFooterLength());
|
||||
VerifyOrQuit(memcmp(psdu, kWakeupPsdu2, sizeof(kWakeupPsdu2)) == 0);
|
||||
|
||||
// Initialize RX Frame with the same PSDU and check if it's recognized as wake-up frame
|
||||
rxFrame.mPsdu = psdu;
|
||||
rxFrame.mLength = txFrame.GetLength();
|
||||
rxFrame.mRadioType = 0;
|
||||
|
||||
SuccessOrQuit(rxFrame.ValidatePsdu());
|
||||
VerifyOrQuit(rxFrame.IsWakeupFrame());
|
||||
}
|
||||
|
||||
void TestMacWakeupFrameDetectionNegative(void)
|
||||
|
||||
Reference in New Issue
Block a user