[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:
Yakun Xu
2020-08-11 10:22:10 -07:00
committed by GitHub
parent 644e0a30f7
commit 66dcbac15d
9 changed files with 124 additions and 15 deletions
+1 -1
View File
@@ -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
+31
View File
@@ -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);
/**
* @}
*
+10
View File
@@ -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);
+6
View File
@@ -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;
+8
View File
@@ -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
+12
View File
@@ -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.
*
+31 -14
View File
@@ -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:
+16
View File
@@ -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