[joiner] remove static requirement for vendor parameters in Start() (#3748)

This commit updates the `Joiner` class implementation to remove the
requirement for `Start()` vendor related parameters (vendor name,
model, sw version, data) to be static (string). This is done without
requiring the `Joiner` class to use member variables to store/copy
the strings by preparing the "Joiner Finalize" message early on (note
that these parameters are included in this message) and keeping track
of the dynamically allocated `Coap::Message` pointer instead.
This commit is contained in:
Abtin Keshavarzian
2019-04-11 10:11:59 -07:00
committed by Jonathan Hui
parent eab62dd699
commit b1ac8a4f19
3 changed files with 78 additions and 52 deletions
+4 -4
View File
@@ -84,10 +84,10 @@ typedef void(OTCALL *otJoinerCallback)(otError aError, void *aContext);
* @param[in] aInstance A pointer to an OpenThread instance. * @param[in] aInstance A pointer to an OpenThread instance.
* @param[in] aPSKd A pointer to the PSKd. * @param[in] aPSKd A pointer to the PSKd.
* @param[in] aProvisioningUrl A pointer to the Provisioning URL (may be NULL). * @param[in] aProvisioningUrl A pointer to the Provisioning URL (may be NULL).
* @param[in] aVendorName A pointer to the Vendor Name (must be static). * @param[in] aVendorName A pointer to the Vendor Name (may be NULL).
* @param[in] aVendorModel A pointer to the Vendor Model (must be static). * @param[in] aVendorModel A pointer to the Vendor Model (may be NULL).
* @param[in] aVendorSwVersion A pointer to the Vendor SW Version (must be static). * @param[in] aVendorSwVersion A pointer to the Vendor SW Version (may be NULL).
* @param[in] aVendorData A pointer to the Vendor Data (must be static). * @param[in] aVendorData A pointer to the Vendor Data (may be NULL).
* @param[in] aCallback A pointer to a function that is called when the join operation completes. * @param[in] aCallback A pointer to a function that is called when the join operation completes.
* @param[in] aContext A pointer to application-specific context. * @param[in] aContext A pointer to application-specific context.
* *
+62 -40
View File
@@ -63,10 +63,7 @@ Joiner::Joiner(Instance &aInstance)
, mCallback(NULL) , mCallback(NULL)
, mContext(NULL) , mContext(NULL)
, mJoinerRouterIndex(0) , mJoinerRouterIndex(0)
, mVendorName(NULL) , mFinalizeMessage(NULL)
, mVendorModel(NULL)
, mVendorSwVersion(NULL)
, mVendorData(NULL)
, mTimer(aInstance, &Joiner::HandleTimer, this) , mTimer(aInstance, &Joiner::HandleTimer, this)
, mJoinerEntrust(OT_URI_PATH_JOINER_ENTRUST, &Joiner::HandleJoinerEntrust, this) , mJoinerEntrust(OT_URI_PATH_JOINER_ENTRUST, &Joiner::HandleJoinerEntrust, this)
{ {
@@ -116,22 +113,20 @@ otError Joiner::Start(const char * aPSKd,
SuccessOrExit(error = Get<Coap::CoapSecure>().Start(kJoinerUdpPort)); SuccessOrExit(error = Get<Coap::CoapSecure>().Start(kJoinerUdpPort));
SuccessOrExit(error = Get<Coap::CoapSecure>().SetPsk(reinterpret_cast<const uint8_t *>(aPSKd), SuccessOrExit(error = Get<Coap::CoapSecure>().SetPsk(reinterpret_cast<const uint8_t *>(aPSKd),
static_cast<uint8_t>(strlen(aPSKd)))); static_cast<uint8_t>(strlen(aPSKd))));
SuccessOrExit(error = Get<Coap::CoapSecure>().GetDtls().mProvisioningUrl.SetProvisioningUrl(aProvisioningUrl));
for (JoinerRouter *router = &mJoinerRouters[0]; router < OT_ARRAY_END(mJoinerRouters); router++) for (JoinerRouter *router = &mJoinerRouters[0]; router < OT_ARRAY_END(mJoinerRouters); router++)
{ {
router->mPriority = 0; // Priority zero means entry is not in-use. router->mPriority = 0; // Priority zero means entry is not in-use.
} }
SuccessOrExit(error = PrepareJoinerFinalizeMessage(aProvisioningUrl, aVendorName, aVendorModel, aVendorSwVersion,
aVendorData));
SuccessOrExit(error = Get<Mle::MleRouter>().Discover(Mac::ChannelMask(0), Get<Mac::Mac>().GetPanId(), SuccessOrExit(error = Get<Mle::MleRouter>().Discover(Mac::ChannelMask(0), Get<Mac::Mac>().GetPanId(),
/* aJoiner */ true, /* aEnableFiltering */ true, /* aJoiner */ true, /* aEnableFiltering */ true,
HandleDiscoverResult, this)); HandleDiscoverResult, this));
mVendorName = aVendorName; mCallback = aCallback;
mVendorModel = aVendorModel; mContext = aContext;
mVendorSwVersion = aVendorSwVersion;
mVendorData = aVendorData;
mCallback = aCallback;
mContext = aContext;
SetState(OT_JOINER_STATE_DISCOVER); SetState(OT_JOINER_STATE_DISCOVER);
@@ -139,6 +134,7 @@ exit:
if (error != OT_ERROR_NONE) if (error != OT_ERROR_NONE)
{ {
otLogInfoMeshCoP("Error %s while starting joiner", otThreadErrorToString(error)); otLogInfoMeshCoP("Error %s while starting joiner", otThreadErrorToString(error));
FreeJoinerFinalizeMessage();
} }
return error; return error;
@@ -172,6 +168,7 @@ void Joiner::Finish(otError aError)
case OT_JOINER_STATE_DISCOVER: case OT_JOINER_STATE_DISCOVER:
Get<Coap::CoapSecure>().Stop(); Get<Coap::CoapSecure>().Stop();
FreeJoinerFinalizeMessage();
break; break;
} }
@@ -388,74 +385,99 @@ exit:
return; return;
} }
void Joiner::SendJoinerFinalize(void) otError Joiner::PrepareJoinerFinalizeMessage(const char *aProvisioningUrl,
const char *aVendorName,
const char *aVendorModel,
const char *aVendorSwVersion,
const char *aVendorData)
{ {
otError error = OT_ERROR_NONE; otError error = OT_ERROR_NONE;
Coap::Message * message = NULL;
StateTlv stateTlv; StateTlv stateTlv;
VendorNameTlv vendorNameTlv; VendorNameTlv vendorNameTlv;
VendorModelTlv vendorModelTlv; VendorModelTlv vendorModelTlv;
VendorSwVersionTlv vendorSwVersionTlv; VendorSwVersionTlv vendorSwVersionTlv;
VendorStackVersionTlv vendorStackVersionTlv; VendorStackVersionTlv vendorStackVersionTlv;
ProvisioningUrlTlv provisioningUrlTlv;
VerifyOrExit((message = NewMeshCoPMessage(Get<Coap::CoapSecure>())) != NULL, error = OT_ERROR_NO_BUFS); VerifyOrExit((mFinalizeMessage = NewMeshCoPMessage(Get<Coap::CoapSecure>())) != NULL, error = OT_ERROR_NO_BUFS);
message->Init(OT_COAP_TYPE_CONFIRMABLE, OT_COAP_CODE_POST); mFinalizeMessage->Init(OT_COAP_TYPE_CONFIRMABLE, OT_COAP_CODE_POST);
message->AppendUriPathOptions(OT_URI_PATH_JOINER_FINALIZE); mFinalizeMessage->AppendUriPathOptions(OT_URI_PATH_JOINER_FINALIZE);
message->SetPayloadMarker(); mFinalizeMessage->SetPayloadMarker();
message->SetOffset(message->GetLength()); mFinalizeMessage->SetOffset(mFinalizeMessage->GetLength());
stateTlv.Init(); stateTlv.Init();
stateTlv.SetState(MeshCoP::StateTlv::kAccept); stateTlv.SetState(MeshCoP::StateTlv::kAccept);
SuccessOrExit(error = message->Append(&stateTlv, sizeof(stateTlv))); SuccessOrExit(error = mFinalizeMessage->Append(&stateTlv, sizeof(stateTlv)));
vendorNameTlv.Init(); vendorNameTlv.Init();
vendorNameTlv.SetVendorName(mVendorName); vendorNameTlv.SetVendorName(aVendorName);
SuccessOrExit(error = message->Append(&vendorNameTlv, vendorNameTlv.GetSize())); SuccessOrExit(error = mFinalizeMessage->Append(&vendorNameTlv, vendorNameTlv.GetSize()));
vendorModelTlv.Init(); vendorModelTlv.Init();
vendorModelTlv.SetVendorModel(mVendorModel); vendorModelTlv.SetVendorModel(aVendorModel);
SuccessOrExit(error = message->Append(&vendorModelTlv, vendorModelTlv.GetSize())); SuccessOrExit(error = mFinalizeMessage->Append(&vendorModelTlv, vendorModelTlv.GetSize()));
vendorSwVersionTlv.Init(); vendorSwVersionTlv.Init();
vendorSwVersionTlv.SetVendorSwVersion(mVendorSwVersion); vendorSwVersionTlv.SetVendorSwVersion(aVendorSwVersion);
SuccessOrExit(error = message->Append(&vendorSwVersionTlv, vendorSwVersionTlv.GetSize())); SuccessOrExit(error = mFinalizeMessage->Append(&vendorSwVersionTlv, vendorSwVersionTlv.GetSize()));
vendorStackVersionTlv.Init(); vendorStackVersionTlv.Init();
vendorStackVersionTlv.SetOui(OPENTHREAD_CONFIG_STACK_VENDOR_OUI); vendorStackVersionTlv.SetOui(OPENTHREAD_CONFIG_STACK_VENDOR_OUI);
vendorStackVersionTlv.SetMajor(OPENTHREAD_CONFIG_STACK_VERSION_MAJOR); vendorStackVersionTlv.SetMajor(OPENTHREAD_CONFIG_STACK_VERSION_MAJOR);
vendorStackVersionTlv.SetMinor(OPENTHREAD_CONFIG_STACK_VERSION_MINOR); vendorStackVersionTlv.SetMinor(OPENTHREAD_CONFIG_STACK_VERSION_MINOR);
vendorStackVersionTlv.SetRevision(OPENTHREAD_CONFIG_STACK_VERSION_REV); vendorStackVersionTlv.SetRevision(OPENTHREAD_CONFIG_STACK_VERSION_REV);
SuccessOrExit(error = message->Append(&vendorStackVersionTlv, vendorStackVersionTlv.GetSize())); SuccessOrExit(error = mFinalizeMessage->Append(&vendorStackVersionTlv, vendorStackVersionTlv.GetSize()));
if (mVendorData != NULL) if (aVendorData != NULL)
{ {
VendorDataTlv vendorDataTlv; VendorDataTlv vendorDataTlv;
vendorDataTlv.Init(); vendorDataTlv.Init();
vendorDataTlv.SetVendorData(mVendorData); vendorDataTlv.SetVendorData(aVendorData);
SuccessOrExit(error = message->Append(&vendorDataTlv, vendorDataTlv.GetSize())); SuccessOrExit(error = mFinalizeMessage->Append(&vendorDataTlv, vendorDataTlv.GetSize()));
} }
if (Get<Coap::CoapSecure>().GetDtls().mProvisioningUrl.GetLength() > 0) provisioningUrlTlv.Init();
provisioningUrlTlv.SetProvisioningUrl(aProvisioningUrl);
if (provisioningUrlTlv.GetLength() > 0)
{ {
SuccessOrExit(error = message->Append(&Get<Coap::CoapSecure>().GetDtls().mProvisioningUrl, SuccessOrExit(error = mFinalizeMessage->Append(&provisioningUrlTlv, provisioningUrlTlv.GetSize()));
Get<Coap::CoapSecure>().GetDtls().mProvisioningUrl.GetSize()));
} }
exit:
if (error != OT_ERROR_NONE)
{
FreeJoinerFinalizeMessage();
}
return error;
}
void Joiner::FreeJoinerFinalizeMessage(void)
{
if (mFinalizeMessage != NULL)
{
mFinalizeMessage->Free();
mFinalizeMessage = NULL;
}
}
void Joiner::SendJoinerFinalize(void)
{
assert(mFinalizeMessage != NULL);
#if OPENTHREAD_ENABLE_CERT_LOG #if OPENTHREAD_ENABLE_CERT_LOG
LogCertMessage("[THCI] direction=send | type=JOIN_FIN.req |", *message); LogCertMessage("[THCI] direction=send | type=JOIN_FIN.req |", *mFinalizeMessage);
#endif #endif
SuccessOrExit(error = Get<Coap::CoapSecure>().SendMessage(*message, Joiner::HandleJoinerFinalizeResponse, this)); SuccessOrExit(Get<Coap::CoapSecure>().SendMessage(*mFinalizeMessage, Joiner::HandleJoinerFinalizeResponse, this));
mFinalizeMessage = NULL;
otLogInfoMeshCoP("Joiner sent finalize"); otLogInfoMeshCoP("Joiner sent finalize");
exit: exit:
return;
if (error != OT_ERROR_NONE && message != NULL)
{
message->Free();
}
} }
void Joiner::HandleJoinerFinalizeResponse(void * aContext, void Joiner::HandleJoinerFinalizeResponse(void * aContext,
+12 -8
View File
@@ -68,10 +68,10 @@ public:
* *
* @param[in] aPSKd A pointer to the PSKd. * @param[in] aPSKd A pointer to the PSKd.
* @param[in] aProvisioningUrl A pointer to the Provisioning URL (may be NULL). * @param[in] aProvisioningUrl A pointer to the Provisioning URL (may be NULL).
* @param[in] aVendorName A pointer to the Vendor Name (must be static). * @param[in] aVendorName A pointer to the Vendor Name (may be NULL).
* @param[in] aVendorModel A pointer to the Vendor Model (must be static). * @param[in] aVendorModel A pointer to the Vendor Model (may be NULL).
* @param[in] aVendorSwVersion A pointer to the Vendor SW Version (must be static). * @param[in] aVendorSwVersion A pointer to the Vendor SW Version (may be NULL).
* @param[in] aVendorData A pointer to the Vendor Data (must be static). * @param[in] aVendorData A pointer to the Vendor Data (may be NULL).
* @param[in] aCallback A pointer to a function that is called when the join operation completes. * @param[in] aCallback A pointer to a function that is called when the join operation completes.
* @param[in] aContext A pointer to application-specific context. * @param[in] aContext A pointer to application-specific context.
* *
@@ -152,6 +152,13 @@ private:
otError Connect(JoinerRouter &aRouter); otError Connect(JoinerRouter &aRouter);
void Finish(otError aError); void Finish(otError aError);
uint8_t CalculatePriority(int8_t aRssi, bool aSteeringDataAllowsAny); uint8_t CalculatePriority(int8_t aRssi, bool aSteeringDataAllowsAny);
otError PrepareJoinerFinalizeMessage(const char *aProvisioningUrl,
const char *aVendorName,
const char *aVendorModel,
const char *aVendorSwVersion,
const char *aVendorData);
void FreeJoinerFinalizeMessage(void);
void SendJoinerFinalize(void); void SendJoinerFinalize(void);
void SendJoinerEntrustResponse(const Coap::Message &aRequest, const Ip6::MessageInfo &aRequestInfo); void SendJoinerEntrustResponse(const Coap::Message &aRequest, const Ip6::MessageInfo &aRequestInfo);
@@ -167,10 +174,7 @@ private:
JoinerRouter mJoinerRouters[OPENTHREAD_CONFIG_MAX_JOINER_ROUTER_ENTRIES]; JoinerRouter mJoinerRouters[OPENTHREAD_CONFIG_MAX_JOINER_ROUTER_ENTRIES];
uint16_t mJoinerRouterIndex; uint16_t mJoinerRouterIndex;
const char *mVendorName; Coap::Message *mFinalizeMessage;
const char *mVendorModel;
const char *mVendorSwVersion;
const char *mVendorData;
TimerMilli mTimer; TimerMilli mTimer;
Coap::Resource mJoinerEntrust; Coap::Resource mJoinerEntrust;