Add ability to capture all received IEEE 802.15.4 frames. (#120)

* Add API to register a callback for providing received IEEE 802.15.4 frames.
* Add API to enable/disable promiscuous mode.
This commit is contained in:
Jonathan Hui
2016-06-11 12:44:40 -07:00
committed by GitHub
parent 012fe7ebee
commit 87e9508232
4 changed files with 139 additions and 4 deletions
+45
View File
@@ -39,6 +39,7 @@
#include <stdbool.h>
#include <openthread-types.h>
#include <platform/radio.h>
#ifdef __cplusplus
extern "C" {
@@ -856,6 +857,50 @@ uint8_t otGetRouterIdSequence(void);
*/
uint8_t otGetStableNetworkDataVersion(void);
/**
* This function pointer is called when an IEEE 802.15.4 frame is received.
*
* @note This callback is called after FCS processing and @p aFrame may not contain the actual FCS that was received.
*
* @note This callback is called before IEEE 802.15.4 security processing and mSecurityValid in @p aFrame will
* always be false.
*
* @param[in] aFrame A pointer to the received IEEE 802.15.4 frame.
*
*/
typedef void (*otLinkPcapCallback)(const RadioPacket *aFrame);
/**
* This function registers a callback to provide received raw IEEE 802.15.4 frames.
*
* @param[in] aPcapCallback A pointer to a function that is called when receiving an IEEE 802.15.4 link frame or
* NULL to disable the callback.
*
*/
void otSetLinkPcapCallback(otLinkPcapCallback aPcapCallback);
/**
* This function indicates whether or not promiscuous mode is enabled at the link layer.
*
* @retval true Promiscuous mode is enabled.
* @retval false Promiscuous mode is not enabled.
*
*/
bool otIsLinkPromiscuous(void);
/**
* This function enables or disables the link layer promiscuous mode.
*
* @note Promiscuous mode may only be enabled when the Thread interface is disabled.
*
* @param[in] aPromiscuous true to enable promiscuous mode, or false otherwise.
*
* @retval kThreadError_None Successfully enabled promiscuous mode.
* @retval kThreadError_Busy Could not enable promiscuous mode because the Thread interface is enabled.
*
*/
ThreadError otSetLinkPromiscuous(bool aPromiscuous);
/**
* @}
*
+32 -3
View File
@@ -79,7 +79,7 @@ Mac::Mac(ThreadNetif &aThreadNetif):
mState = kStateIdle;
mRxOnWhenIdle = true;
mRxOnWhenIdle = false;
mCsmaAttempts = 0;
mTransmitAttempts = 0;
mTransmitBeacon = false;
@@ -114,6 +114,8 @@ Mac::Mac(ThreadNetif &aThreadNetif):
mBeaconSequence = otPlatRandomGet();
mDataSequence = otPlatRandomGet();
mPcapCallback = NULL;
otPlatRadioEnable();
}
@@ -155,7 +157,6 @@ bool Mac::IsActiveScanInProgress(void)
return (mState == kStateActiveScan) || mActiveScanRequest;
}
ThreadError Mac::RegisterReceiver(Receiver &aReceiver)
{
assert(mReceiveTail != &aReceiver && aReceiver.mNext == NULL);
@@ -293,7 +294,7 @@ void Mac::NextOperation(void)
break;
default:
if (mRxOnWhenIdle || mReceiveTimer.IsRunning())
if (mRxOnWhenIdle || mReceiveTimer.IsRunning() || otPlatRadioGetPromiscuous())
{
otPlatRadioReceive(mChannel);
}
@@ -752,6 +753,13 @@ void Mac::ReceiveDoneTask(Frame *aFrame, ThreadError aError)
VerifyOrExit(aError == kThreadError_None && aFrame != NULL, ;);
aFrame->mSecurityValid = false;
if (mPcapCallback)
{
mPcapCallback(aFrame);
}
aFrame->GetSrcAddr(srcaddr);
neighbor = mMle.GetNeighbor(srcaddr);
@@ -868,6 +876,27 @@ exit:
return error;
}
void Mac::SetPcapCallback(otLinkPcapCallback aPcapCallback)
{
mPcapCallback = aPcapCallback;
}
bool Mac::IsPromiscuous(void)
{
return otPlatRadioGetPromiscuous();
}
void Mac::SetPromiscuous(bool aPromiscuous)
{
otPlatRadioSetPromiscuous(aPromiscuous);
SuccessOrExit(otPlatRadioIdle());
NextOperation();
exit:
return;
}
Whitelist &Mac::GetWhitelist(void)
{
return mWhitelist;
+30
View File
@@ -391,6 +391,34 @@ public:
*/
bool IsActiveScanInProgress(void);
/**
* This function registers a callback to provide received raw IEEE 802.15.4 frames.
*
* @param[in] aPcapCallback A pointer to a function that is called when receiving an IEEE 802.15.4 link frame or
* NULL to disable the callback.
*
*/
void SetPcapCallback(otLinkPcapCallback aPcapCallback);
/**
* This function indicates whether or not promiscuous mode is enabled at the link layer.
*
* @retval true Promiscuous mode is enabled.
* @retval false Promiscuous mode is not enabled.
*
*/
bool IsPromiscuous(void);
/**
* This function enables or disables the link layer promiscuous mode.
*
* Promiscuous mode keeps the receiver enabled, overriding the value of mRxOnWhenIdle.
*
* @param[in] aPromiscuous true to enable promiscuous mode, or false otherwise.
*
*/
void SetPromiscuous(bool aPromiscuous);
private:
void GenerateNonce(const ExtAddress &aAddress, uint32_t aFrameCounter, uint8_t aSecurityLevel, uint8_t *aNonce);
void NextOperation(void);
@@ -453,6 +481,8 @@ private:
ActiveScanHandler mActiveScanHandler;
void *mActiveScanContext;
otLinkPcapCallback mPcapCallback;
Whitelist mWhitelist;
};
+32 -1
View File
@@ -492,6 +492,29 @@ uint8_t otGetStableNetworkDataVersion(void)
return sThreadNetif->GetMle().GetLeaderDataTlv().GetStableDataVersion();
}
void otSetLinkPcapCallback(otLinkPcapCallback aPcapCallback)
{
sThreadNetif->GetMac().SetPcapCallback(aPcapCallback);
}
bool otIsLinkPromiscuous(void)
{
return sThreadNetif->GetMac().IsPromiscuous();
}
ThreadError otSetLinkPromiscuous(bool aPromiscuous)
{
ThreadError error = kThreadError_None;
// cannot enable IEEE 802.15.4 promiscuous mode if the Thread interface is enabled
VerifyOrExit(sThreadNetif->IsUp() == false, error = kThreadError_Busy);
sThreadNetif->GetMac().SetPromiscuous(aPromiscuous);
exit:
return error;
}
bool otIsIp6AddressEqual(const otIp6Address *a, const otIp6Address *b)
{
return *static_cast<const Ip6::Address *>(a) == *static_cast<const Ip6::Address *>(b);
@@ -519,7 +542,15 @@ ThreadError otRemoveUnicastAddress(otNetifAddress *address)
ThreadError otEnable(void)
{
return sThreadNetif->Up();
ThreadError error = kThreadError_None;
// cannot enable the Thread stack if IEEE 802.15.4 promiscuous mode is enabled
VerifyOrExit(otPlatRadioGetPromiscuous() == false, error = kThreadError_Busy);
SuccessOrExit(error = sThreadNetif->Up());
exit:
return error;
}
ThreadError otDisable(void)