mirror of
https://github.com/espressif/openthread.git
synced 2026-08-12 05:37:46 +00:00
[mle] add discovery request callback (#5131)
This commit allows notifying the application a discovery request is received, which is useful if the application wants to be more active when a joiner comes.
This commit is contained in:
@@ -53,7 +53,7 @@ extern "C" {
|
||||
* @note This number versions both OpenThread platform and user APIs.
|
||||
*
|
||||
*/
|
||||
#define OPENTHREAD_API_VERSION (22)
|
||||
#define OPENTHREAD_API_VERSION (23)
|
||||
|
||||
/**
|
||||
* @addtogroup api-instance
|
||||
|
||||
@@ -805,6 +805,37 @@ void otThreadRegisterParentResponseCallback(otInstance * aInst
|
||||
otThreadParentResponseCallback aCallback,
|
||||
void * aContext);
|
||||
|
||||
/**
|
||||
* This structure represents the Thread Discovery Request data.
|
||||
*
|
||||
*/
|
||||
typedef struct otThreadDiscoveryRequestInfo
|
||||
{
|
||||
otExtAddress mExtAddress; ///< IEEE 802.15.4 Extended Address of the requester
|
||||
uint8_t mVersion : 4; ///< Thread version.
|
||||
bool mIsJoiner : 1; ///< Whether is from joiner.
|
||||
} otThreadDiscoveryRequestInfo;
|
||||
|
||||
/**
|
||||
* This function pointer is called every time an MLE Discovery Request message is received.
|
||||
*
|
||||
* @param[in] aInfo A pointer to the Discovery Request info data.
|
||||
* @param[in] aContext A pointer to callback application-specific context.
|
||||
*
|
||||
*/
|
||||
typedef void (*otThreadDiscoveryRequestCallback)(const otThreadDiscoveryRequestInfo *aInfo, void *aContext);
|
||||
|
||||
/**
|
||||
* This function sets a callback to receive MLE Discovery Request data.
|
||||
*
|
||||
* @param[in] aInstance A pointer to an OpenThread instance.
|
||||
* @param[in] aCallback A pointer to a function that is called upon receiving an MLE Discovery Request message.
|
||||
* @param[in] aContext A pointer to callback application-specific context.
|
||||
*
|
||||
*/
|
||||
void otThreadSetDiscoveryRequestCallback(otInstance * aInstnace,
|
||||
otThreadDiscoveryRequestCallback aCallback,
|
||||
void * aContext);
|
||||
/**
|
||||
* @}
|
||||
*
|
||||
|
||||
@@ -287,6 +287,9 @@ Interpreter::Interpreter(Instance *aInstance)
|
||||
#if OPENTHREAD_FTD || OPENTHREAD_CONFIG_TMF_NETWORK_DIAG_MTD_ENABLE
|
||||
otThreadSetReceiveDiagnosticGetCallback(mInstance, &Interpreter::HandleDiagnosticGetResponse, this);
|
||||
#endif
|
||||
#if OPENTHREAD_FTD
|
||||
otThreadSetDiscoveryRequestCallback(mInstance, &Interpreter::HandleDiscoveryRequest, this);
|
||||
#endif
|
||||
|
||||
mIcmpHandler.mReceiveCallback = Interpreter::HandleIcmpReceive;
|
||||
mIcmpHandler.mContext = this;
|
||||
@@ -4590,6 +4593,13 @@ void Interpreter::SignalPingReply(const Ip6::Address &aPeerAddress,
|
||||
#endif
|
||||
}
|
||||
|
||||
void Interpreter::HandleDiscoveryRequest(const otThreadDiscoveryRequestInfo &aInfo)
|
||||
{
|
||||
mServer->OutputFormat("~ Discovery Request from ");
|
||||
OutputBytes(aInfo.mExtAddress.m8, sizeof(aInfo.mExtAddress.m8));
|
||||
mServer->OutputFormat(": version=%u,joiner=%d\r\n", aInfo.mVersion, aInfo.mIsJoiner);
|
||||
}
|
||||
|
||||
extern "C" void otCliSetUserCommands(const otCliCommand *aUserCommands, uint8_t aLength)
|
||||
{
|
||||
Server::sServer->GetInterpreter().SetUserCommands(aUserCommands, aLength);
|
||||
|
||||
@@ -429,6 +429,12 @@ private:
|
||||
#endif
|
||||
static Interpreter &GetOwner(OwnerLocator &aOwnerLocator);
|
||||
|
||||
static void HandleDiscoveryRequest(const otThreadDiscoveryRequestInfo *aInfo, void *aContext)
|
||||
{
|
||||
static_cast<Interpreter *>(aContext)->HandleDiscoveryRequest(*aInfo);
|
||||
}
|
||||
void HandleDiscoveryRequest(const otThreadDiscoveryRequestInfo &aInfo);
|
||||
|
||||
static const struct Command sCommands[];
|
||||
const otCliCommand * mUserCommands;
|
||||
uint8_t mUserCommandsLength;
|
||||
|
||||
@@ -383,4 +383,12 @@ void otThreadRegisterNeighborTableCallback(otInstance *aInstance, otNeighborTabl
|
||||
instance.Get<Mle::MleRouter>().RegisterNeighborTableChangedCallback(aCallback);
|
||||
}
|
||||
|
||||
void otThreadSetDiscoveryRequestCallback(otInstance * aInstance,
|
||||
otThreadDiscoveryRequestCallback aCallback,
|
||||
void * aContext)
|
||||
{
|
||||
Instance &instance = *static_cast<Instance *>(aInstance);
|
||||
|
||||
instance.Get<Mle::MleRouter>().SetDiscoveryRequestCallback(aCallback, aContext);
|
||||
}
|
||||
#endif // OPENTHREAD_FTD
|
||||
|
||||
@@ -1616,6 +1616,18 @@ public:
|
||||
return GetLength() <= sizeof(mProvisioningUrl) ? GetLength() : sizeof(mProvisioningUrl);
|
||||
}
|
||||
|
||||
/**
|
||||
* This method indicates whether or not the TLV appears to be well-formed.
|
||||
*
|
||||
* @retval TRUE If the TLV appears to be well-formed.
|
||||
* @retval FALSE If the TLV does not appear to be well-formed.
|
||||
*
|
||||
*/
|
||||
bool IsValid(void) const
|
||||
{
|
||||
return GetType() == kProvisioningUrl && mProvisioningUrl[GetProvisioningUrlLength()] == '\0';
|
||||
}
|
||||
|
||||
/**
|
||||
* This method returns the Provisioning URL value.
|
||||
*
|
||||
|
||||
@@ -88,6 +88,8 @@ MleRouter::MleRouter(Instance &aInstance)
|
||||
#if OPENTHREAD_CONFIG_REFERENCE_DEVICE_ENABLE
|
||||
, mMaxChildIpAddresses(0)
|
||||
#endif
|
||||
, mDiscoveryRequestCallback(nullptr)
|
||||
, mDiscoveryRequestCallbackContext(nullptr)
|
||||
{
|
||||
mDeviceMode.Set(mDeviceMode.Get() | DeviceMode::kModeFullThreadDevice | DeviceMode::kModeFullNetworkData);
|
||||
|
||||
@@ -2860,6 +2862,8 @@ void MleRouter::HandleDiscoveryRequest(const Message &aMessage, const Ip6::Messa
|
||||
|
||||
LogMleMessage("Receive Discovery Request", aMessageInfo.GetPeerAddr());
|
||||
|
||||
discoveryRequest.SetLength(0);
|
||||
|
||||
// only Routers and REEDs respond
|
||||
VerifyOrExit(IsRouterEligible(), error = OT_ERROR_INVALID_STATE);
|
||||
|
||||
@@ -2880,20 +2884,6 @@ void MleRouter::HandleDiscoveryRequest(const Message &aMessage, const Ip6::Messa
|
||||
aMessage.Read(offset, sizeof(discoveryRequest), &discoveryRequest);
|
||||
VerifyOrExit(discoveryRequest.IsValid(), error = OT_ERROR_PARSE);
|
||||
|
||||
if (discoveryRequest.IsJoiner())
|
||||
{
|
||||
#if OPENTHREAD_CONFIG_MLE_STEERING_DATA_SET_OOB_ENABLE
|
||||
if (!mSteeringData.IsEmpty())
|
||||
{
|
||||
break;
|
||||
}
|
||||
else // if steering data is not set out of band, fall back to network data
|
||||
#endif
|
||||
{
|
||||
VerifyOrExit(Get<NetworkData::Leader>().IsJoiningEnabled(), error = OT_ERROR_SECURITY);
|
||||
}
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
case MeshCoP::Tlv::kExtendedPanId:
|
||||
@@ -2909,6 +2899,33 @@ void MleRouter::HandleDiscoveryRequest(const Message &aMessage, const Ip6::Messa
|
||||
offset += sizeof(meshcopTlv) + meshcopTlv.GetLength();
|
||||
}
|
||||
|
||||
if (discoveryRequest.IsValid())
|
||||
{
|
||||
if (mDiscoveryRequestCallback != nullptr)
|
||||
{
|
||||
otThreadDiscoveryRequestInfo info;
|
||||
|
||||
aMessageInfo.GetPeerAddr().GetIid().ConvertToExtAddress(*static_cast<Mac::ExtAddress *>(&info.mExtAddress));
|
||||
info.mVersion = discoveryRequest.GetVersion();
|
||||
info.mIsJoiner = discoveryRequest.IsJoiner();
|
||||
|
||||
mDiscoveryRequestCallback(&info, mDiscoveryRequestCallbackContext);
|
||||
}
|
||||
|
||||
if (discoveryRequest.IsJoiner())
|
||||
{
|
||||
#if OPENTHREAD_CONFIG_MLE_STEERING_DATA_SET_OOB_ENABLE
|
||||
if (!mSteeringData.IsEmpty())
|
||||
{
|
||||
}
|
||||
else // if steering data is not set out of band, fall back to network data
|
||||
#endif
|
||||
{
|
||||
VerifyOrExit(Get<NetworkData::Leader>().IsJoiningEnabled(), error = OT_ERROR_SECURITY);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
error = SendDiscoveryResponse(aMessageInfo.GetPeerAddr(), aMessage.GetPanId());
|
||||
|
||||
exit:
|
||||
|
||||
@@ -490,6 +490,19 @@ public:
|
||||
mNeighborTableChangedCallback = aCallback;
|
||||
}
|
||||
|
||||
/**
|
||||
* This function sets the callback that is called when processing an MLE Discovery Request message.
|
||||
*
|
||||
* @param[in] aCallback A pointer to a function that is called to deliver MLE Discovery Request data.
|
||||
* @param[in] aContext A pointer to application-specific context.
|
||||
*
|
||||
*/
|
||||
void SetDiscoveryRequestCallback(otThreadDiscoveryRequestCallback aCallback, void *aContext)
|
||||
{
|
||||
mDiscoveryRequestCallback = aCallback;
|
||||
mDiscoveryRequestCallbackContext = aContext;
|
||||
}
|
||||
|
||||
/**
|
||||
* This method signals a "neighbor table changed" events (invoking the registered callback function).
|
||||
*
|
||||
@@ -706,6 +719,9 @@ private:
|
||||
#if OPENTHREAD_CONFIG_MLE_STEERING_DATA_SET_OOB_ENABLE
|
||||
MeshCoP::SteeringData mSteeringData;
|
||||
#endif
|
||||
|
||||
otThreadDiscoveryRequestCallback mDiscoveryRequestCallback;
|
||||
void * mDiscoveryRequestCallbackContext;
|
||||
};
|
||||
|
||||
#endif // OPENTHREAD_FTD
|
||||
|
||||
@@ -88,7 +88,16 @@ wait_for "" "Done"
|
||||
send "discover something_invalid\n"
|
||||
expect "Error 7: InvalidArgs"
|
||||
|
||||
set spawn_id $spawn_1
|
||||
expect "version=2,joiner=0"
|
||||
|
||||
set spawn_id $spawn_3
|
||||
send "joiner start 123456\n"
|
||||
set timeout 10
|
||||
expect "NotFound"
|
||||
dispose
|
||||
|
||||
set spawn_id $spawn_1
|
||||
expect "version=2,joiner=1"
|
||||
|
||||
dispose_nodes
|
||||
|
||||
Reference in New Issue
Block a user