[commissioner] add callback for joiner events (#3862)

This commit is contained in:
Jonathan Hui
2019-05-28 18:25:50 -07:00
committed by Jonathan Hui
parent 1abf57dd2f
commit 204d0a91a3
13 changed files with 169 additions and 49 deletions
+1
View File
@@ -3666,6 +3666,7 @@ OTCALL
otCommissionerStart(
_In_ otInstance *aInstance,
_In_ otCommissionerStateCallback aStateCallback,
_In_ otCommissionerJoinerCallback aJoinerCallback,
_In_ void *aContext
)
{
+1 -1
View File
@@ -5367,7 +5367,7 @@ otLwfIoCtl_otCommissionerStart(
UNREFERENCED_PARAMETER(OutBuffer);
*OutBufferLength = 0;
return ThreadErrorToNtstatus(otCommissionerStart(pFilter->otCtx, NULL, NULL));
return ThreadErrorToNtstatus(otCommissionerStart(pFilter->otCtx, NULL, NULL, NULL));
}
_IRQL_requires_max_(PASSIVE_LEVEL)
@@ -999,7 +999,7 @@ OTNODEAPI int32_t OTCALL otNodeCommissionerStart(otNode* aNode)
printf("%d: commissioner start\r\n", aNode->mId);
// TODO: handle commissioner callback
auto error = otCommissionerStart(aNode->mInstance, NULL, NULL);
auto error = otCommissionerStart(aNode->mInstance, NULL, NULL, NULL);
otLogFuncExit();
return error;
+30 -3
View File
@@ -65,6 +65,19 @@ typedef enum otCommissionerState
OT_COMMISSIONER_STATE_ACTIVE = 2, ///< Commissioner role is active.
} otCommissionerState;
/**
* This enumeration defines a Joiner Event on the Commissioner.
*
*/
typedef enum otCommissionerJoinerEvent
{
OT_COMMISSIONER_JOINER_START = 0,
OT_COMMISSIONER_JOINER_CONNECTED = 1,
OT_COMMISSIONER_JOINER_FINALIZE = 2,
OT_COMMISSIONER_JOINER_END = 3,
OT_COMMISSIONER_JOINER_REMOVED = 4,
} otCommissionerJoinerEvent;
#define OT_COMMISSIONING_PASSPHRASE_MIN_SIZE 6 ///< Minimum size of the Commissioning Passphrase
#define OT_COMMISSIONING_PASSPHRASE_MAX_SIZE 255 ///< Maximum size of the Commissioning Passphrase
@@ -108,20 +121,34 @@ typedef struct otCommissioningDataset
*/
typedef void(OTCALL *otCommissionerStateCallback)(otCommissionerState aState, void *aContext);
/**
* This function pointer is called whenever the joiner state changes.
*
* @param[in] aEvent The joiner event type.
* @param[in] aJoinerId A pointer to the Joiner ID.
* @param[in] aContext A pointer to application-specific context.
*
*/
typedef void(OTCALL *otCommissionerJoinerCallback)(otCommissionerJoinerEvent aEvent,
const otExtAddress * aJoinerId,
void * aContext);
/**
* This function enables the Thread Commissioner role.
*
* @param[in] aInstance A pointer to an OpenThread instance.
* @param[in] aStateCallback A pointer to a function that is called when the commissioner state changes.
* @param[in] aJoinerCallback A pointer to a function that is called with a joiner event occurs.
* @param[in] aCallbackContext A pointer to application-specific context.
*
* @retval OT_ERROR_NONE Successfully started the Commissioner role.
* @retval OT_ERROR_INVALID_STATE Commissioner is already started.
*
*/
OTAPI otError OTCALL otCommissionerStart(otInstance * aInstance,
otCommissionerStateCallback aStateCallback,
void * aCallbackContext);
OTAPI otError OTCALL otCommissionerStart(otInstance * aInstance,
otCommissionerStateCallback aStateCallback,
otCommissionerJoinerCallback aJoinerCallback,
void * aCallbackContext);
/**
* This function disables the Thread Commissioner role.
+11 -12
View File
@@ -270,18 +270,17 @@ enum
OT_CHANGED_THREAD_CHILD_REMOVED = 1 << 11, ///< Child was removed
OT_CHANGED_IP6_MULTICAST_SUBSRCRIBED = 1 << 12, ///< Subscribed to a IPv6 multicast address
OT_CHANGED_IP6_MULTICAST_UNSUBSRCRIBED = 1 << 13, ///< Unsubscribed from a IPv6 multicast address
OT_CHANGED_JOINER_STATE = 1 << 14, ///< Joiner state changed
OT_CHANGED_THREAD_CHANNEL = 1 << 15, ///< Thread network channel changed
OT_CHANGED_THREAD_PANID = 1 << 16, ///< Thread network PAN Id changed
OT_CHANGED_THREAD_NETWORK_NAME = 1 << 17, ///< Thread network name changed
OT_CHANGED_THREAD_EXT_PANID = 1 << 18, ///< Thread network extended PAN ID changed
OT_CHANGED_MASTER_KEY = 1 << 19, ///< Master key changed
OT_CHANGED_PSKC = 1 << 20, ///< PSKc changed
OT_CHANGED_SECURITY_POLICY = 1 << 21, ///< Security Policy changed
OT_CHANGED_CHANNEL_MANAGER_NEW_CHANNEL = 1 << 22, ///< Channel Manager new pending Thread channel changed
OT_CHANGED_SUPPORTED_CHANNEL_MASK = 1 << 23, ///< Supported channel mask changed
OT_CHANGED_BORDER_AGENT_STATE = 1 << 24, ///< Border agent state changed
OT_CHANGED_THREAD_NETIF_STATE = 1 << 25, ///< Thread network interface state changed
OT_CHANGED_THREAD_CHANNEL = 1 << 14, ///< Thread network channel changed
OT_CHANGED_THREAD_PANID = 1 << 15, ///< Thread network PAN Id changed
OT_CHANGED_THREAD_NETWORK_NAME = 1 << 16, ///< Thread network name changed
OT_CHANGED_THREAD_EXT_PANID = 1 << 17, ///< Thread network extended PAN ID changed
OT_CHANGED_MASTER_KEY = 1 << 18, ///< Master key changed
OT_CHANGED_PSKC = 1 << 19, ///< PSKc changed
OT_CHANGED_SECURITY_POLICY = 1 << 20, ///< Security Policy changed
OT_CHANGED_CHANNEL_MANAGER_NEW_CHANNEL = 1 << 21, ///< Channel Manager new pending Thread channel changed
OT_CHANGED_SUPPORTED_CHANNEL_MASK = 1 << 22, ///< Supported channel mask changed
OT_CHANGED_BORDER_AGENT_STATE = 1 << 23, ///< Border agent state changed
OT_CHANGED_THREAD_NETIF_STATE = 1 << 24, ///< Thread network interface state changed
};
/**
+37 -1
View File
@@ -317,7 +317,8 @@ otError Commissioner::ProcessStart(int argc, char *argv[])
OT_UNUSED_VARIABLE(argc);
OT_UNUSED_VARIABLE(argv);
return otCommissionerStart(mInterpreter.mInstance, &Commissioner::HandleStateChanged, this);
return otCommissionerStart(mInterpreter.mInstance, &Commissioner::HandleStateChanged,
&Commissioner::HandleJoinerEvent, this);
}
void OTCALL Commissioner::HandleStateChanged(otCommissionerState aState, void *aContext)
@@ -343,6 +344,41 @@ void Commissioner::HandleStateChanged(otCommissionerState aState)
}
}
void OTCALL Commissioner::HandleJoinerEvent(otCommissionerJoinerEvent aEvent,
const otExtAddress * aJoinerId,
void * aContext)
{
static_cast<Commissioner *>(aContext)->HandleJoinerEvent(aEvent, aJoinerId);
}
void Commissioner::HandleJoinerEvent(otCommissionerJoinerEvent aEvent, const otExtAddress *aJoinerId)
{
mInterpreter.mServer->OutputFormat("Commissioner: Joiner ");
switch (aEvent)
{
case OT_COMMISSIONER_JOINER_START:
mInterpreter.mServer->OutputFormat("start ");
break;
case OT_COMMISSIONER_JOINER_CONNECTED:
mInterpreter.mServer->OutputFormat("connect ");
break;
case OT_COMMISSIONER_JOINER_FINALIZE:
mInterpreter.mServer->OutputFormat("finalize ");
break;
case OT_COMMISSIONER_JOINER_END:
mInterpreter.mServer->OutputFormat("end ");
break;
case OT_COMMISSIONER_JOINER_REMOVED:
mInterpreter.mServer->OutputFormat("remove ");
break;
}
mInterpreter.OutputBytes(aJoinerId->m8, sizeof(*aJoinerId));
mInterpreter.mServer->OutputFormat("\r\n");
}
otError Commissioner::ProcessStop(int argc, char *argv[])
{
OT_UNUSED_VARIABLE(argc);
+5
View File
@@ -99,6 +99,11 @@ private:
static void OTCALL HandleStateChanged(otCommissionerState aState, void *aContext);
void HandleStateChanged(otCommissionerState aState);
static void OTCALL HandleJoinerEvent(otCommissionerJoinerEvent aJoinerEvent,
const otExtAddress * aJoinerId,
void * aContext);
void HandleJoinerEvent(otCommissionerJoinerEvent aJoinerEvent, const otExtAddress *aJoinerId);
static void OTCALL HandleEnergyReport(uint32_t aChannelMask,
const uint8_t *aEnergyList,
uint8_t aEnergyListLength,
+7 -2
View File
@@ -40,7 +40,10 @@
using namespace ot;
otError otCommissionerStart(otInstance *aInstance, otCommissionerStateCallback aStateCallback, void *aCallbackContext)
otError otCommissionerStart(otInstance * aInstance,
otCommissionerStateCallback aStateCallback,
otCommissionerJoinerCallback aJoinerCallback,
void * aCallbackContext)
{
otError error = OT_ERROR_DISABLED_FEATURE;
@@ -50,11 +53,13 @@ otError otCommissionerStart(otInstance *aInstance, otCommissionerStateCallback a
#if OPENTHREAD_ENABLE_BORDER_AGENT
SuccessOrExit(error = instance.Get<MeshCoP::BorderAgent>().Stop());
#endif
SuccessOrExit(error = instance.Get<MeshCoP::Commissioner>().Start(aStateCallback, aCallbackContext));
SuccessOrExit(error =
instance.Get<MeshCoP::Commissioner>().Start(aStateCallback, aJoinerCallback, aCallbackContext));
exit:
#else
OT_UNUSED_VARIABLE(aInstance);
OT_UNUSED_VARIABLE(aStateCallback);
OT_UNUSED_VARIABLE(aJoinerCallback);
OT_UNUSED_VARIABLE(aCallbackContext);
#endif
-4
View File
@@ -273,10 +273,6 @@ const char *Notifier::FlagToString(otChangedFlags aFlag) const
retval = "Ip6Mult-";
break;
case OT_CHANGED_JOINER_STATE:
retval = "JoinerState";
break;
case OT_CHANGED_THREAD_CHANNEL:
retval = "Channel";
break;
+62 -19
View File
@@ -71,6 +71,7 @@ Commissioner::Commissioner(Instance &aInstance)
, mEnergyScan(aInstance)
, mPanIdQuery(aInstance)
, mStateCallback(NULL)
, mJoinerCallback(NULL)
, mCallbackContext(NULL)
, mState(OT_COMMISSIONER_STATE_DISABLED)
{
@@ -99,6 +100,14 @@ exit:
return;
}
void Commissioner::SignalJoinerEvent(otCommissionerJoinerEvent aEvent, const Mac::ExtAddress &aJoinerId)
{
if (mJoinerCallback)
{
mJoinerCallback(aEvent, &aJoinerId, mCallbackContext);
}
}
void Commissioner::AddCoapResources(void)
{
Get<Coap::Coap>().AddResource(mRelayReceive);
@@ -113,15 +122,37 @@ void Commissioner::RemoveCoapResources(void)
Get<Coap::CoapSecure>().RemoveResource(mJoinerFinalize);
}
otError Commissioner::Start(otCommissionerStateCallback aStateCallback, void *aCallbackContext)
void Commissioner::HandleCoapsConnected(bool aConnected, void *aContext)
{
static_cast<Commissioner *>(aContext)->HandleCoapsConnected(aConnected);
}
void Commissioner::HandleCoapsConnected(bool aConnected)
{
otCommissionerJoinerEvent event;
Mac::ExtAddress joinerId;
event = aConnected ? OT_COMMISSIONER_JOINER_CONNECTED : OT_COMMISSIONER_JOINER_END;
memcpy(&joinerId, mJoinerIid, sizeof(joinerId));
joinerId.m8[0] ^= 0x2;
SignalJoinerEvent(event, joinerId);
}
otError Commissioner::Start(otCommissionerStateCallback aStateCallback,
otCommissionerJoinerCallback aJoinerCallback,
void * aCallbackContext)
{
otError error = OT_ERROR_NONE;
VerifyOrExit(mState == OT_COMMISSIONER_STATE_DISABLED, error = OT_ERROR_INVALID_STATE);
SuccessOrExit(error = Get<Coap::CoapSecure>().Start(SendRelayTransmit, this));
Get<Coap::CoapSecure>().SetConnectedCallback(&Commissioner::HandleCoapsConnected, this);
mStateCallback = aStateCallback;
mJoinerCallback = aJoinerCallback;
mCallbackContext = aCallbackContext;
mTransmitAttempts = 0;
@@ -276,6 +307,8 @@ otError Commissioner::RemoveJoiner(const Mac::ExtAddress *aEui64, uint32_t aDela
for (size_t i = 0; i < OT_ARRAY_LENGTH(mJoiners); i++)
{
Mac::ExtAddress joinerId;
if (!mJoiners[i].mValid)
{
continue;
@@ -309,24 +342,24 @@ otError Commissioner::RemoveJoiner(const Mac::ExtAddress *aEui64, uint32_t aDela
mJoiners[i].mValid = false;
UpdateJoinerExpirationTimer();
SendCommissionerSet();
if (aEui64)
{
otLogInfoMeshCoP("Removed Joiner (%s)", aEui64->ToString().AsCString());
}
else
{
otLogInfoMeshCoP("Removed Joiner (*)");
}
ComputeJoinerId(mJoiners[i].mEui64, joinerId);
SignalJoinerEvent(OT_COMMISSIONER_JOINER_REMOVED, joinerId);
}
ExitNow(error = OT_ERROR_NONE);
}
exit:
if (error == OT_ERROR_NONE)
{
if (aEui64)
{
otLogInfoMeshCoP("Removed Joiner (%s)", aEui64->ToString().AsCString());
}
else
{
otLogInfoMeshCoP("Removed Joiner (*)");
}
}
return error;
}
@@ -833,7 +866,7 @@ void Commissioner::HandleRelayReceive(Coap::Message &aMessage, const Ip6::Messag
memcpy(mJoinerIid, joinerIid.GetIid(), sizeof(mJoinerIid));
mJoinerIid[0] ^= 0x2;
for (size_t i = 0; i < OT_ARRAY_LENGTH(mJoiners); i++)
for (uint8_t i = 0; i < OT_ARRAY_LENGTH(mJoiners); i++)
{
if (!mJoiners[i].mValid)
{
@@ -847,8 +880,12 @@ void Commissioner::HandleRelayReceive(Coap::Message &aMessage, const Ip6::Messag
error = Get<Coap::CoapSecure>().SetPsk(reinterpret_cast<const uint8_t *>(mJoiners[i].mPsk),
static_cast<uint8_t>(strlen(mJoiners[i].mPsk)));
SuccessOrExit(error);
otLogInfoMeshCoP("found joiner, starting new session");
mJoinerIndex = i;
enableJoiner = true;
otLogInfoMeshCoP("found joiner, starting new session");
SignalJoinerEvent(OT_COMMISSIONER_JOINER_START, joinerId);
break;
}
}
@@ -947,7 +984,7 @@ void Commissioner::SendJoinFinalizeResponse(const Coap::Message &aRequest, State
Ip6::MessageInfo joinerMessageInfo;
MeshCoP::StateTlv stateTlv;
Coap::Message * message;
Mac::ExtAddress extAddr;
Mac::ExtAddress joinerId;
VerifyOrExit((message = NewMeshCoPMessage(Get<Coap::CoapSecure>())) != NULL, error = OT_ERROR_NO_BUFS);
@@ -974,9 +1011,15 @@ void Commissioner::SendJoinFinalizeResponse(const Coap::Message &aRequest, State
SuccessOrExit(error = Get<Coap::CoapSecure>().SendMessage(*message, joinerMessageInfo));
memcpy(extAddr.m8, mJoinerIid, sizeof(extAddr.m8));
extAddr.SetLocal(!extAddr.IsLocal());
RemoveJoiner(&extAddr, kRemoveJoinerDelay); // remove after kRemoveJoinerDelay (seconds)
memcpy(&joinerId, mJoinerIid, sizeof(joinerId));
joinerId.m8[0] ^= 0x2;
SignalJoinerEvent(OT_COMMISSIONER_JOINER_FINALIZE, joinerId);
if (!mJoiners[mJoinerIndex].mAny)
{
// remove after kRemoveJoinerDelay (seconds)
RemoveJoiner(&mJoiners[mJoinerIndex].mEui64, kRemoveJoinerDelay);
}
otLogInfoMeshCoP("sent joiner finalize response");
+12 -3
View File
@@ -69,13 +69,16 @@ public:
* This method starts the Commissioner service.
*
* @param[in] aStateCallback A pointer to a function that is called when the commissioner state changes.
* @param[in] aJoinerCallback A pointer to a function that is called when a joiner event occurs.
* @param[in] aCallbackContext A pointer to application-specific context.
*
* @retval OT_ERROR_NONE Successfully started the Commissioner service.
* @retval OT_ERROR_INVALID_STATE Commissioner is already started.
*
*/
otError Start(otCommissionerStateCallback aStateCallback, void *aCallbackContext);
otError Start(otCommissionerStateCallback aStateCallback,
otCommissionerJoinerCallback aJoinerCallback,
void * aCallbackContext);
/**
* This method stops the Commissioner service.
@@ -288,6 +291,9 @@ private:
otError aResult);
void HandleLeaderKeepAliveResponse(Coap::Message *aMessage, const Ip6::MessageInfo *aMessageInfo, otError aResult);
static void HandleCoapsConnected(bool aConnected, void *aContext);
void HandleCoapsConnected(bool aConnected);
static void HandleRelayReceive(void *aContext, otMessage *aMessage, const otMessageInfo *aMessageInfo);
void HandleRelayReceive(Coap::Message &aMessage, const Ip6::MessageInfo &aMessageInfo);
@@ -307,6 +313,7 @@ private:
otError SendKeepAlive(void);
void SetState(otCommissionerState aState);
void SignalJoinerEvent(otCommissionerJoinerEvent aEvent, const Mac::ExtAddress &aJoinerId);
struct Joiner
{
@@ -321,6 +328,7 @@ private:
uint8_t mJoinerIid[8];
uint16_t mJoinerPort;
uint16_t mJoinerRloc;
uint8_t mJoinerIndex;
TimerMilli mJoinerExpirationTimer;
TimerMilli mTimer;
@@ -339,8 +347,9 @@ private:
ProvisioningUrlTlv mProvisioningUrl;
otCommissionerStateCallback mStateCallback;
void * mCallbackContext;
otCommissionerStateCallback mStateCallback;
otCommissionerJoinerCallback mJoinerCallback;
void * mCallbackContext;
otCommissionerState mState;
};
-1
View File
@@ -83,7 +83,6 @@ void Joiner::SetState(otJoinerState aState)
otLogInfoMeshCoP("JoinerState: %s -> %s", JoinerStateToString(mState), JoinerStateToString(aState));
mState = aState;
Get<Notifier>().Signal(OT_CHANGED_JOINER_STATE);
exit:
return;
+2 -2
View File
@@ -476,7 +476,7 @@ template <> otError NcpBase::HandlePropertySet<SPINEL_PROP_MESHCOP_COMMISSIONER_
break;
case SPINEL_MESHCOP_COMMISSIONER_STATE_ACTIVE:
error = otCommissionerStart(mInstance, NULL, NULL);
error = otCommissionerStart(mInstance, NULL, NULL, NULL);
break;
default:
@@ -742,7 +742,7 @@ otError NcpBase::HandlePropertySet_SPINEL_PROP_THREAD_COMMISSIONER_ENABLED(uint8
}
else
{
error = otCommissionerStart(mInstance, NULL, NULL);
error = otCommissionerStart(mInstance, NULL, NULL, NULL);
}
exit: