diff --git a/include/openthread.h b/include/openthread.h index d6935cfd1..3442379e8 100644 --- a/include/openthread.h +++ b/include/openthread.h @@ -239,23 +239,26 @@ bool otIsSingleton(void); * This function pointer is called during an IEEE 802.15.4 Active Scan when an IEEE 802.15.4 Beacon is received or * the scan completes. * - * @param[in] aResult A valid pointer to the beacon information or NULL when the active scan completes. + * @param[in] aResult A valid pointer to the beacon information or NULL when the active scan completes. + * @param[in] aContext A pointer to application-specific context. * */ -typedef void (*otHandleActiveScanResult)(otActiveScanResult *aResult); +typedef void (*otHandleActiveScanResult)(otActiveScanResult *aResult, void *aContext); /** * This function starts an IEEE 802.15.4 Active Scan * - * @param[in] aScanChannels A bit vector indicating which channels to scan (e.g. OT_CHANNEL_11_MASK). - * @param[in] aScanDuration The time in milliseconds to spend scanning each channel. - * @param[in] aCallback A pointer to a function called on receiving a beacon or scan completes. + * @param[in] aScanChannels A bit vector indicating which channels to scan (e.g. OT_CHANNEL_11_MASK). + * @param[in] aScanDuration The time in milliseconds to spend scanning each channel. + * @param[in] aCallback A pointer to a function called on receiving a beacon or scan completes. + * @param[in] aCallbackContext A pointer to application-specific context. * * @retval kThreadError_None Accepted the Active Scan request. * @retval kThreadError_Busy Already performing an Active Scan. * */ -ThreadError otActiveScan(uint32_t aScanChannels, uint16_t aScanDuration, otHandleActiveScanResult aCallback); +ThreadError otActiveScan(uint32_t aScanChannels, uint16_t aScanDuration, otHandleActiveScanResult aCallback, + void *aCallbackContext); /** * This function indicates whether or not an IEEE 802.15.4 Active Scan is currently in progress. @@ -268,17 +271,18 @@ bool otIsActiveScanInProgress(void); /** * This function starts a Thread Discovery scan. * - * @param[in] aScanChannels A bit vector indicating which channels to scan (e.g. OT_CHANNEL_11_MASK). - * @param[in] aScanDuration The time in milliseconds to spend scanning each channel. - * @param[in] aPanId The PAN ID filter (set to Broadcast PAN to disable filter). - * @param[in] aCallback A pointer to a function called on receiving an MLE Discovery Response or scan completes. + * @param[in] aScanChannels A bit vector indicating which channels to scan (e.g. OT_CHANNEL_11_MASK). + * @param[in] aScanDuration The time in milliseconds to spend scanning each channel. + * @param[in] aPanId The PAN ID filter (set to Broadcast PAN to disable filter). + * @param[in] aCallback A pointer to a function called on receiving an MLE Discovery Response or scan completes. + * @param[in] aCallbackContext A pointer to application-specific context. * * @retval kThreadError_None Accepted the Thread Discovery request. * @retval kThreadError_Busy Already performing an Thread Discovery. * */ ThreadError otDiscover(uint32_t aScanChannels, uint16_t aScanDuration, uint16_t aPanid, - otHandleActiveScanResult aCallback); + otHandleActiveScanResult aCallback, void *aCallbackContext); /** * This function indicates whether or not an MLE Thread Discovery is currently in progress. @@ -1365,19 +1369,21 @@ uint8_t otGetStableNetworkDataVersion(void); * @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. + * @param[in] aFrame A pointer to the received IEEE 802.15.4 frame. + * @param[in] aContext A pointer to application-specific context. * */ -typedef void (*otLinkPcapCallback)(const RadioPacket *aFrame); +typedef void (*otLinkPcapCallback)(const RadioPacket *aFrame, void *aContext); /** * 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. + * @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. + * @param[in] aCallbackContext A pointer to application-specific context. * */ -void otSetLinkPcapCallback(otLinkPcapCallback aPcapCallback); +void otSetLinkPcapCallback(otLinkPcapCallback aPcapCallback, void *aCallbackContext); /** * This function indicates whether or not promiscuous mode is enabled at the link layer. @@ -1621,18 +1627,20 @@ int otWriteMessage(otMessage aMessage, uint16_t aOffset, const void *aBuf, uint1 * This function pointer is called when an IPv6 datagram is received. * * @param[in] aMessage A pointer to the message buffer containing the received IPv6 datagram. + * @param[in] aContext A pointer to application-specific context. * */ -typedef void (*otReceiveIp6DatagramCallback)(otMessage aMessage); +typedef void (*otReceiveIp6DatagramCallback)(otMessage aMessage, void *aContext); /** * This function registers a callback to provide received IPv6 datagrams. * - * @param[in] aCallback A pointer to a function that is called when an IPv6 datagram is received or NULL to disable - * the callback. + * @param[in] aCallback A pointer to a function that is called when an IPv6 datagram is received or + * NULL to disable the callback. + * @param[in] aCallbackContext A pointer to application-specific context. * */ -void otSetReceiveIp6DatagramCallback(otReceiveIp6DatagramCallback aCallback); +void otSetReceiveIp6DatagramCallback(otReceiveIp6DatagramCallback aCallback, void *aCallbackContext); /** * This function sends an IPv6 datagram via the Thread interface. diff --git a/src/cli/cli.cpp b/src/cli/cli.cpp index 5e7b947a8..5e1ade057 100644 --- a/src/cli/cli.cpp +++ b/src/cli/cli.cpp @@ -476,7 +476,7 @@ void Interpreter::ProcessDiscover(int argc, char *argv[]) scanChannels = 1 << value; } - SuccessOrExit(error = otDiscover(scanChannels, 0, OT_PANID_BROADCAST, &HandleActiveScanResult)); + SuccessOrExit(error = otDiscover(scanChannels, 0, OT_PANID_BROADCAST, &HandleActiveScanResult, NULL)); sServer->OutputFormat("| J | Network Name | Extended PAN | PAN | MAC Address | Ch | dBm | LQI |\r\n"); sServer->OutputFormat("+---+------------------+------------------+------+------------------+----+-----+-----+\r\n"); @@ -1510,7 +1510,7 @@ void Interpreter::ProcessScan(int argc, char *argv[]) scanChannels = 1 << value; } - SuccessOrExit(error = otActiveScan(scanChannels, 0, &HandleActiveScanResult)); + SuccessOrExit(error = otActiveScan(scanChannels, 0, &HandleActiveScanResult, NULL)); sServer->OutputFormat("| J | Network Name | Extended PAN | PAN | MAC Address | Ch | dBm | LQI |\r\n"); sServer->OutputFormat("+---+------------------+------------------+------+------------------+----+-----+-----+\r\n"); @@ -1520,7 +1520,7 @@ exit: AppendResult(error); } -void Interpreter::HandleActiveScanResult(otActiveScanResult *aResult) +void Interpreter::HandleActiveScanResult(otActiveScanResult *aResult, void *aContext) { if (aResult == NULL) { @@ -1543,6 +1543,7 @@ void Interpreter::HandleActiveScanResult(otActiveScanResult *aResult) sServer->OutputFormat("| %3d |\r\n", aResult->mLqi); exit: + (void)aContext; return; } diff --git a/src/cli/cli.hpp b/src/cli/cli.hpp index 12cf4daf3..7a2f11757 100644 --- a/src/cli/cli.hpp +++ b/src/cli/cli.hpp @@ -184,7 +184,7 @@ private: static void HandleEchoResponse(void *aContext, Message &aMessage, const Ip6::MessageInfo &aMessageInfo); static void HandlePingTimer(void *aContext); - static void HandleActiveScanResult(otActiveScanResult *aResult); + static void HandleActiveScanResult(otActiveScanResult *aResult, void *aContext); static void HandleNetifStateChanged(uint32_t aFlags, void *aContext); static const struct Command sCommands[]; diff --git a/src/core/mac/mac.cpp b/src/core/mac/mac.cpp index edc61a8b2..be6609b2c 100644 --- a/src/core/mac/mac.cpp +++ b/src/core/mac/mac.cpp @@ -122,6 +122,7 @@ Mac::Mac(ThreadNetif &aThreadNetif): mDataSequence = static_cast(otPlatRandomGet()); mPcapCallback = NULL; + mPcapCallbackContext = NULL; otPlatRadioEnable(); } @@ -860,7 +861,7 @@ void Mac::ReceiveDoneTask(Frame *aFrame, ThreadError aError) if (mPcapCallback) { - mPcapCallback(aFrame); + mPcapCallback(aFrame, mPcapCallbackContext); } aFrame->GetSrcAddr(srcaddr); @@ -1069,9 +1070,10 @@ exit: return error; } -void Mac::SetPcapCallback(otLinkPcapCallback aPcapCallback) +void Mac::SetPcapCallback(otLinkPcapCallback aPcapCallback, void *aCallbackContext) { mPcapCallback = aPcapCallback; + mPcapCallbackContext = aCallbackContext; } bool Mac::IsPromiscuous(void) diff --git a/src/core/mac/mac.hpp b/src/core/mac/mac.hpp index 7498385b7..6b5f81391 100644 --- a/src/core/mac/mac.hpp +++ b/src/core/mac/mac.hpp @@ -419,11 +419,12 @@ public: /** * 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. + * @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. + * @param[in] aCallbackContext A pointer to application-specific context. * */ - void SetPcapCallback(otLinkPcapCallback aPcapCallback); + void SetPcapCallback(otLinkPcapCallback aPcapCallback, void *aCallbackContext); /** * This function indicates whether or not promiscuous mode is enabled at the link layer. @@ -518,6 +519,7 @@ private: void *mActiveScanContext; otLinkPcapCallback mPcapCallback; + void *mPcapCallbackContext; Whitelist mWhitelist; Blacklist mBlacklist; diff --git a/src/core/net/ip6.cpp b/src/core/net/ip6.cpp index f8f4831a1..6b7b7f758 100644 --- a/src/core/net/ip6.cpp +++ b/src/core/net/ip6.cpp @@ -52,6 +52,7 @@ static Mpl *sMpl; static bool sForwardingEnabled; static otReceiveIp6DatagramCallback sReceiveIp6DatagramCallback = NULL; +static void *sReceiveIp6DatagramCallbackContext = NULL; static ThreadError ForwardMessage(Message &message, MessageInfo &messageInfo); @@ -107,9 +108,10 @@ uint16_t Ip6::ComputePseudoheaderChecksum(const Address &src, const Address &dst return checksum; } -void Ip6::SetReceiveDatagramCallback(otReceiveIp6DatagramCallback aCallback) +void Ip6::SetReceiveDatagramCallback(otReceiveIp6DatagramCallback aCallback, void *aCallbackContext) { sReceiveIp6DatagramCallback = aCallback; + sReceiveIp6DatagramCallbackContext = aCallbackContext; } ThreadError AddMplOption(Message &message, Header &header, IpProto nextHeader, uint16_t payloadLength) @@ -331,7 +333,7 @@ void Ip6::ProcessReceiveCallback(Message &aMessage) SuccessOrExit(error = messageCopy->SetLength(aMessage.GetLength())); aMessage.CopyTo(0, 0, aMessage.GetLength(), *messageCopy); - sReceiveIp6DatagramCallback(messageCopy); + sReceiveIp6DatagramCallback(messageCopy, sReceiveIp6DatagramCallbackContext); exit: diff --git a/src/core/net/ip6.hpp b/src/core/net/ip6.hpp index 7af67f8a2..4506a744e 100644 --- a/src/core/net/ip6.hpp +++ b/src/core/net/ip6.hpp @@ -577,11 +577,12 @@ public: /** * This function registers a callback to provide received raw IPv6 datagrams. * - * @param[in] aCallback A pointer to a function that is called when an IPv6 datagram is received or NULL to - * disable the callback. + * @param[in] aCallback A pointer to a function that is called when an IPv6 datagram is received + * or NULL to disable the callback. + * @param[in] aCallbackContext A pointer to application-specific context. * */ - static void SetReceiveDatagramCallback(otReceiveIp6DatagramCallback aCallback); + static void SetReceiveDatagramCallback(otReceiveIp6DatagramCallback aCallback, void *aCallbackContext); /** * This static method enables/disables IPv6 forwarding. diff --git a/src/core/openthread.cpp b/src/core/openthread.cpp index 1c620ba8f..eb4f5a68b 100644 --- a/src/core/openthread.cpp +++ b/src/core/openthread.cpp @@ -65,6 +65,12 @@ static otDEFINE_ALIGNED_VAR(sThreadNetifRaw, sizeof(ThreadNetif), uint64_t); static void HandleActiveScanResult(void *aContext, Mac::Frame *aFrame); static void HandleMleDiscover(otActiveScanResult *aResult, void *aContext); +static otHandleActiveScanResult sActiveScanCallback = NULL; +static void *sActiveScanCallbackContext = NULL; + +static otHandleActiveScanResult sDiscoverCallback = NULL; +static void *sDiscoverCallbackContext = NULL; + void otProcessNextTasklet(void) { TaskletScheduler::RunNextTasklet(); @@ -759,9 +765,9 @@ uint8_t otGetStableNetworkDataVersion(void) return sThreadNetif->GetMle().GetLeaderDataTlv().GetStableDataVersion(); } -void otSetLinkPcapCallback(otLinkPcapCallback aPcapCallback) +void otSetLinkPcapCallback(otLinkPcapCallback aPcapCallback, void *aCallbackContext) { - sThreadNetif->GetMac().SetPcapCallback(aPcapCallback); + sThreadNetif->GetMac().SetPcapCallback(aPcapCallback, aCallbackContext); } bool otIsLinkPromiscuous(void) @@ -929,10 +935,12 @@ bool otIsSingleton(void) return mEnabled && sThreadNetif->GetMle().IsSingleton(); } -ThreadError otActiveScan(uint32_t aScanChannels, uint16_t aScanDuration, otHandleActiveScanResult aCallback) +ThreadError otActiveScan(uint32_t aScanChannels, uint16_t aScanDuration, otHandleActiveScanResult aCallback, + void *aCallbackContext) { - return sThreadNetif->GetMac().ActiveScan(aScanChannels, aScanDuration, &HandleActiveScanResult, - reinterpret_cast(aCallback)); + sActiveScanCallback = aCallback; + sActiveScanCallbackContext = aCallbackContext; + return sThreadNetif->GetMac().ActiveScan(aScanChannels, aScanDuration, &HandleActiveScanResult, NULL); } bool otIsActiveScanInProgress(void) @@ -942,7 +950,6 @@ bool otIsActiveScanInProgress(void) void HandleActiveScanResult(void *aContext, Mac::Frame *aFrame) { - otHandleActiveScanResult handler = reinterpret_cast(aContext); otActiveScanResult result; Mac::Address address; Mac::Beacon *beacon; @@ -952,7 +959,7 @@ void HandleActiveScanResult(void *aContext, Mac::Frame *aFrame) if (aFrame == NULL) { - handler(NULL); + sActiveScanCallback(NULL, sActiveScanCallbackContext); ExitNow(); } @@ -977,17 +984,19 @@ void HandleActiveScanResult(void *aContext, Mac::Frame *aFrame) memcpy(&result.mExtendedPanId, beacon->GetExtendedPanId(), sizeof(result.mExtendedPanId)); } - handler(&result); + sActiveScanCallback(&result, sActiveScanCallbackContext); exit: + (void)aContext; return; } ThreadError otDiscover(uint32_t aScanChannels, uint16_t aScanDuration, uint16_t aPanId, - otHandleActiveScanResult aCallback) + otHandleActiveScanResult aCallback, void *aCallbackContext) { - return sThreadNetif->GetMle().Discover(aScanChannels, aScanDuration, aPanId, &HandleMleDiscover, - reinterpret_cast(aCallback)); + sDiscoverCallback = aCallback; + sDiscoverCallbackContext = aCallbackContext; + return sThreadNetif->GetMle().Discover(aScanChannels, aScanDuration, aPanId, &HandleMleDiscover, NULL); } bool otIsDiscoverInProgress(void) @@ -997,13 +1006,13 @@ bool otIsDiscoverInProgress(void) void HandleMleDiscover(otActiveScanResult *aResult, void *aContext) { - otHandleActiveScanResult handler = reinterpret_cast(aContext); - handler(aResult); + (void)aContext; + sDiscoverCallback(aResult, sDiscoverCallbackContext); } -void otSetReceiveIp6DatagramCallback(otReceiveIp6DatagramCallback aCallback) +void otSetReceiveIp6DatagramCallback(otReceiveIp6DatagramCallback aCallback, void *aCallbackContext) { - Ip6::Ip6::SetReceiveDatagramCallback(aCallback); + Ip6::Ip6::SetReceiveDatagramCallback(aCallback, aCallbackContext); } ThreadError otSendIp6Datagram(otMessage aMessage) diff --git a/src/ncp/ncp_base.cpp b/src/ncp/ncp_base.cpp index 26f189785..13e96b43f 100644 --- a/src/ncp/ncp_base.cpp +++ b/src/ncp/ncp_base.cpp @@ -383,7 +383,7 @@ NcpBase::NcpBase(): assert(sThreadNetif != NULL); otSetStateChangedCallback(&HandleNetifStateChanged, this); - otSetReceiveIp6DatagramCallback(&HandleDatagramFromStack); + otSetReceiveIp6DatagramCallback(&HandleDatagramFromStack, this); otSetIcmpEchoEnabled(false); } @@ -391,9 +391,9 @@ NcpBase::NcpBase(): // MARK: Outbound Datagram Handling // ---------------------------------------------------------------------------- -void NcpBase::HandleDatagramFromStack(otMessage aMessage) +void NcpBase::HandleDatagramFromStack(otMessage aMessage, void *aContext) { - sNcpContext->HandleDatagramFromStack(*static_cast(aMessage)); + reinterpret_cast(aContext)->HandleDatagramFromStack(*static_cast(aMessage)); } void NcpBase::HandleDatagramFromStack(Message &aMessage) @@ -455,14 +455,9 @@ exit: // MARK: Scan Results Glue // ---------------------------------------------------------------------------- -static NcpBase *gActiveScanContextHack = NULL; - -void NcpBase::HandleActiveScanResult_Jump(otActiveScanResult *result) +void NcpBase::HandleActiveScanResult_Jump(otActiveScanResult *result, void *aContext) { - if (gActiveScanContextHack) - { - gActiveScanContextHack->HandleActiveScanResult(result); - } + reinterpret_cast(aContext)->HandleActiveScanResult(result); } void NcpBase::HandleActiveScanResult(otActiveScanResult *result) @@ -2390,12 +2385,12 @@ ThreadError NcpBase::SetPropertyHandler_MAC_SCAN_STATE(uint8_t header, spinel_pr break; case SPINEL_SCAN_STATE_BEACON: - gActiveScanContextHack = this; mShouldSignalEndOfScan = false; errorCode = otActiveScan( mChannelMask, mScanPeriod, - &HandleActiveScanResult_Jump + &HandleActiveScanResult_Jump, + this ); break; diff --git a/src/ncp/ncp_base.hpp b/src/ncp/ncp_base.hpp index 4275760f8..6cd946dfc 100644 --- a/src/ncp/ncp_base.hpp +++ b/src/ncp/ncp_base.hpp @@ -128,14 +128,14 @@ private: /** * Trampoline for HandleDatagramFromStack(). */ - static void HandleDatagramFromStack(otMessage aMessage); + static void HandleDatagramFromStack(otMessage aMessage, void *aContext); void HandleDatagramFromStack(Message &aMessage); /** * Trampoline for HandleActiveScanResult(). */ - static void HandleActiveScanResult_Jump(otActiveScanResult *result); + static void HandleActiveScanResult_Jump(otActiveScanResult *result, void *aContext); void HandleActiveScanResult(otActiveScanResult *result);