mirror of
https://github.com/espressif/openthread.git
synced 2026-08-21 18:09:52 +00:00
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:
@@ -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
@@ -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;
|
||||
|
||||
@@ -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
@@ -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)
|
||||
|
||||
Reference in New Issue
Block a user