Implement Provisioning URL TLV. (#646)

This commit is contained in:
Jonathan Hui
2016-09-21 10:51:09 -07:00
committed by GitHub
parent 4b51be41b5
commit b26e022491
12 changed files with 149 additions and 32 deletions
+5 -4
View File
@@ -49,14 +49,15 @@ extern "C" {
/**
* This function enables the Thread Commissioner role.
*
* @param[in] aInstance A pointer to an OpenThread instance.
* @param[in] aPSKd A pointer to the PSKd.
* @param[in] aInstance A pointer to an OpenThread instance.
* @param[in] aPSKd A pointer to the PSKd.
* @param[in] aProvisioningUrl A pointer to the Provisioning URL (may be NULL).
*
* @retval kThreadError_None Successfully started the Commissioner role.
* @retval kThreadError_InvalidArgs @p aPSKd is invalid.
* @retval kThreadError_InvalidArgs @p aPSKd or @p aProvisioningUrl is invalid.
*
*/
ThreadError otCommissionerStart(otInstance *aInstance, const char *aPSKd);
ThreadError otCommissionerStart(otInstance *aInstance, const char *aPSKd, const char *aProvisioningUrl);
/**
* This function disables the Thread Commissioner role.
+5 -4
View File
@@ -49,14 +49,15 @@ extern "C" {
/**
* This function enables the Thread Joiner role.
*
* @param[in] aInstance A pointer to an OpenThread instance.
* @param[in] aPSKd A pointer to the PSKd.
* @param[in] aInstance A pointer to an OpenThread instance.
* @param[in] aPSKd A pointer to the PSKd.
* @param[in] aProvisioningUrl A pointer to the Provisioning URL (may be NULL).
*
* @retval kThreadError_None Successfully started the Commissioner role.
* @retval kThreadError_InvalidArgs @p aPSKd is invalid.
* @retval kThreadError_InvalidArgs @p aPSKd or @p aProvisioningUrl is invalid.
*
*/
ThreadError otJoinerStart(otInstance *aInstance, const char *aPSKd);
ThreadError otJoinerStart(otInstance *aInstance, const char *aPSKd, const char *aProvisioningUrl);
/**
* This function disables the Thread Joiner role.
+1
View File
@@ -402,6 +402,7 @@ typedef enum otMeshcopTlvType
OT_MESHCOP_TLV_JOINER_IID = 19, ///< meshcop Joiner IID TLV
OT_MESHCOP_TLV_JOINER_RLOC = 20, ///< meshcop Joiner Router Locator TLV
OT_MESHCOP_TLV_JOINER_ROUTER_KEK = 21, ///< meshcop Joiner Router KEK TLV
OT_MESHCOP_TLV_PROVISIONING_URL = 32, ///< meshcop Provisioning URL TLV
OT_MESHCOP_TLV_PENDINGTIMESTAMP = 51, ///< meshcop Pending Timestamp TLV
OT_MESHCOP_TLV_DELAYTIMER = 52, ///< meshcop Delay Timer TLV
OT_MESHCOP_TLV_CHANNELMASK = 53, ///< meshcop Channel Mask TLV
+6 -2
View File
@@ -1912,8 +1912,10 @@ void Interpreter::ProcessCommissioner(int argc, char *argv[])
if (strcmp(argv[0], "start") == 0)
{
const char *provisioningUrl;
VerifyOrExit(argc > 1, error = kThreadError_Parse);
otCommissionerStart(mInstance, argv[1]);
provisioningUrl = argc > 2 ? argv[2] : NULL;
otCommissionerStart(mInstance, argv[1], provisioningUrl);
}
else if (strcmp(argv[0], "stop") == 0)
{
@@ -2022,8 +2024,10 @@ void Interpreter::ProcessJoiner(int argc, char *argv[])
if (strcmp(argv[0], "start") == 0)
{
const char *provisioningUrl;
VerifyOrExit(argc > 1, error = kThreadError_Parse);
otJoinerStart(mInstance, argv[1]);
provisioningUrl = (argc > 2) ? argv[2] : NULL;
otJoinerStart(mInstance, argv[1], provisioningUrl);
}
else if (strcmp(argv[0], "stop") == 0)
{
+31 -8
View File
@@ -65,7 +65,7 @@ Commissioner::Commissioner(ThreadNetif &aThreadNetif):
aThreadNetif.GetCoapServer().AddResource(mRelayReceive);
}
ThreadError Commissioner::Start(const char *aPSKd)
ThreadError Commissioner::Start(const char *aPSKd, const char *aProvisioningUrl)
{
ThreadError error = kThreadError_None;
@@ -73,6 +73,7 @@ ThreadError Commissioner::Start(const char *aPSKd)
SuccessOrExit(error = mNetif.GetDtls().SetPsk(reinterpret_cast<const uint8_t *>(aPSKd),
static_cast<uint8_t>(strlen(aPSKd))));
SuccessOrExit(error = mNetif.GetDtls().mProvisioningUrl.SetProvisioningUrl(aProvisioningUrl));
SuccessOrExit(error = mSocket.Open(HandleUdpReceive, this));
mState = kStatePetition;
SendPetition();
@@ -429,18 +430,21 @@ exit:
void Commissioner::ReceiveJoinerFinalize(uint8_t *buf, uint16_t length)
{
Message *message;
Message *message = NULL;
Coap::Header header;
char uriPath[16];
char *curUriPath = uriPath;
const Coap::Header::Option *coapOption;
StateTlv::State state = StateTlv::kAccept;
ProvisioningUrlTlv provisioningUrl;
otLogInfoMeshCoP("receive joiner finalize 1\r\n");
VerifyOrExit((message = mNetif.GetIp6().mMessagePool.New(Message::kTypeIp6, 0)) != NULL, ;);
SuccessOrExit(message->Append(buf, length));
SuccessOrExit(header.FromMessage(*message));
message->SetOffset(header.GetLength());
SuccessOrExit(message->SetOffset(header.GetLength()));
coapOption = header.GetCurrentOption();
@@ -465,15 +469,34 @@ void Commissioner::ReceiveJoinerFinalize(uint8_t *buf, uint16_t length)
coapOption = header.GetNextOption();
}
curUriPath[-1] = '\0';
if (curUriPath > uriPath)
{
curUriPath[-1] = '\0';
}
SendJoinFinalizeResponse(header);
VerifyOrExit(strcmp(uriPath, OPENTHREAD_URI_JOINER_FINALIZE) == 0,);
if (Tlv::GetTlv(*message, Tlv::kProvisioningUrl, sizeof(provisioningUrl), provisioningUrl) == kThreadError_None)
{
if (provisioningUrl.GetLength() != mNetif.GetDtls().mProvisioningUrl.GetLength() ||
memcmp(provisioningUrl.GetProvisioningUrl(), mNetif.GetDtls().mProvisioningUrl.GetProvisioningUrl(),
provisioningUrl.GetLength()) != 0)
{
state = StateTlv::kReject;
}
}
SendJoinFinalizeResponse(header, state);
exit:
return;
if (message != NULL)
{
message->Free();
}
}
void Commissioner::SendJoinFinalizeResponse(const Coap::Header &aRequestHeader)
void Commissioner::SendJoinFinalizeResponse(const Coap::Header &aRequestHeader, StateTlv::State aState)
{
Coap::Header responseHeader;
MeshCoP::StateTlv *stateTlv;
@@ -491,7 +514,7 @@ void Commissioner::SendJoinFinalizeResponse(const Coap::Header &aRequestHeader)
stateTlv = reinterpret_cast<MeshCoP::StateTlv *>(cur);
stateTlv->Init();
stateTlv->SetState(MeshCoP::StateTlv::kAccept);
stateTlv->SetState(aState);
cur += sizeof(*stateTlv);
mSendKek = true;
+4 -3
View File
@@ -61,12 +61,13 @@ public:
/**
* This method starts the Commissioner service.
*
* @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).
*
* @retval kThreadError_None Successfully started the Commissioner service.
*
*/
ThreadError Start(const char *aPSKd);
ThreadError Start(const char *aPSKd, const char *aProvisioningUrl);
/**
* This method stops the Commissioner service.
@@ -108,7 +109,7 @@ private:
void HandleUdpTransmit(void);
void ReceiveJoinerFinalize(uint8_t *buf, uint16_t length);
void SendJoinFinalizeResponse(const Coap::Header &aRequestHeader);
void SendJoinFinalizeResponse(const Coap::Header &aRequestHeader, StateTlv::State aState);
ThreadError SendPetition(void);
ThreadError SendKeepAlive(void);
+1
View File
@@ -54,6 +54,7 @@ Dtls::Dtls(ThreadNetif &aNetif):
mTimerSet(false),
mNetif(aNetif)
{
mProvisioningUrl.Init();
}
ThreadError Dtls::Start(bool aClient, ReceiveHandler aReceiveHandler, SendHandler aSendHandler, void *aContext)
+7
View File
@@ -38,6 +38,7 @@
#include <common/message.hpp>
#include <common/timer.hpp>
#include <crypto/sha256.hpp>
#include <thread/meshcop_tlvs.hpp>
#include <mbedtls/ssl.h>
#include <mbedtls/entropy.h>
@@ -158,6 +159,12 @@ public:
*/
ThreadError Receive(Message &aMessage, uint16_t aOffset, uint16_t aLength);
/**
* The provisioning URL is placed here so that both the Commissioner and Joiner can share the same object.
*
*/
ProvisioningUrlTlv mProvisioningUrl;
private:
enum
{
+25 -5
View File
@@ -64,7 +64,7 @@ Joiner::Joiner(ThreadNetif &aNetif):
mNetif.GetCoapServer().AddResource(mJoinerEntrust);
}
ThreadError Joiner::Start(const char *aPSKd)
ThreadError Joiner::Start(const char *aPSKd, const char *aProvisioningUrl)
{
ThreadError error;
Mac::ExtAddress extAddress;
@@ -76,6 +76,7 @@ ThreadError Joiner::Start(const char *aPSKd)
SuccessOrExit(error = mNetif.GetDtls().SetPsk(reinterpret_cast<const uint8_t *>(aPSKd),
static_cast<uint8_t>(strlen(aPSKd))));
SuccessOrExit(error = mNetif.GetDtls().mProvisioningUrl.SetProvisioningUrl(aProvisioningUrl));
SuccessOrExit(error = mNetif.GetMle().Discover(0, 0, mNetif.GetMac().GetPanId(), HandleDiscoverResult, this));
exit:
@@ -215,7 +216,8 @@ exit:
void Joiner::SendJoinerFinalize(void)
{
Coap::Header header;
MeshCoP::StateTlv *stateTlv;
StateTlv *stateTlv;
uint8_t length;
uint8_t buf[128];
uint8_t *cur = buf;
@@ -234,6 +236,15 @@ void Joiner::SendJoinerFinalize(void)
stateTlv->SetState(MeshCoP::StateTlv::kAccept);
cur += sizeof(*stateTlv);
length = mNetif.GetDtls().mProvisioningUrl.GetLength();
if (length > 0)
{
length += sizeof(Tlv);
memcpy(cur, &mNetif.GetDtls().mProvisioningUrl, length);
cur += length;
}
mNetif.GetDtls().Send(buf, static_cast<uint16_t>(cur - buf));
otLogInfoMeshCoP("Sent joiner finalize\r\n");
@@ -241,24 +252,33 @@ void Joiner::SendJoinerFinalize(void)
void Joiner::ReceiveJoinerFinalizeResponse(uint8_t *buf, uint16_t length)
{
Message *message;
Message *message = NULL;
Coap::Header header;
StateTlv state;
VerifyOrExit((message = mNetif.GetIp6().mMessagePool.New(Message::kTypeIp6, 0)) != NULL, ;);
SuccessOrExit(message->Append(buf, length));
SuccessOrExit(header.FromMessage(*message));
SuccessOrExit(message->SetOffset(header.GetLength()));
VerifyOrExit(header.GetType() == Coap::Header::kTypeAcknowledgment &&
header.GetCode() == Coap::Header::kCodeChanged &&
header.GetMessageId() == 0 &&
header.GetTokenLength() == 0, ;);
otLogInfoMeshCoP("received joiner finalize response\r\n");
SuccessOrExit(Tlv::GetTlv(*message, Tlv::kState, sizeof(state), state));
VerifyOrExit(state.IsValid(), ;);
otLogInfoMeshCoP("received joiner finalize response %d\r\n", static_cast<uint8_t>(state.GetState()));
Close();
exit:
return;
if (message != NULL)
{
message->Free();
}
}
void Joiner::HandleJoinerEntrust(void *aContext, Coap::Header &aHeader,
+3 -2
View File
@@ -63,12 +63,13 @@ public:
/**
* This method starts the Joiner service.
*
* @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).
*
* @retval kThreadError_None Successfully started the Joiner service.
*
*/
ThreadError Start(const char *aPSKd);
ThreadError Start(const char *aPSKd, const char *aProvisioningUrl);
/**
* This method stops the Joiner service.
+4 -4
View File
@@ -1339,9 +1339,9 @@ ThreadError otSendPendingSet(otInstance *, const otOperationalDataset *aDataset,
#if OPENTHREAD_ENABLE_COMMISSIONER
#include <commissioning/commissioner.h>
ThreadError otCommissionerStart(otInstance *, const char *aPSKd)
ThreadError otCommissionerStart(otInstance *, const char *aPSKd, const char *aProvisioningUrl)
{
return sThreadNetif->GetCommissioner().Start(aPSKd);
return sThreadNetif->GetCommissioner().Start(aPSKd, aProvisioningUrl);
}
ThreadError otCommissionerStop(otInstance *)
@@ -1369,9 +1369,9 @@ ThreadError otCommissionerPanIdQuery(otInstance *, uint16_t aPanId, uint32_t aCh
#endif // OPENTHREAD_ENABLE_COMMISSIONER
#if OPENTHREAD_ENABLE_JOINER
ThreadError otJoinerStart(otInstance *, const char *aPSKd)
ThreadError otJoinerStart(otInstance *, const char *aPSKd, const char *aProvisioningUrl)
{
return sThreadNetif->GetJoiner().Start(aPSKd);
return sThreadNetif->GetJoiner().Start(aPSKd, aProvisioningUrl);
}
ThreadError otJoinerStop(otInstance *)
+57
View File
@@ -81,6 +81,7 @@ public:
kJoinerIid = OT_MESHCOP_TLV_JOINER_IID, ///< Joiner IID TLV
kJoinerRouterLocator = OT_MESHCOP_TLV_JOINER_RLOC, ///< Joiner Router Locator TLV
kJoinerRouterKek = OT_MESHCOP_TLV_JOINER_ROUTER_KEK, ///< Joiner Router KEK TLV
kProvisioningUrl = OT_MESHCOP_TLV_PROVISIONING_URL, ///< Provisioning URL TLV
kPendingTimestamp = OT_MESHCOP_TLV_PENDINGTIMESTAMP, ///< Pending Timestamp TLV
kDelayTimer = OT_MESHCOP_TLV_DELAYTIMER, ///< Delay Timer TLV
kChannelMask = OT_MESHCOP_TLV_CHANNELMASK, ///< Channel Mask TLV
@@ -1491,6 +1492,62 @@ public:
bool IsValid(void) const { return true; }
} OT_TOOL_PACKED_END;
/**
* This class implements Provisioning URL TLV generation and parsing.
*
*/
OT_TOOL_PACKED_BEGIN
class ProvisioningUrlTlv: public Tlv
{
public:
/**
* This method initializes the TLV.
*
*/
void Init(void) { SetType(kProvisioningUrl); SetLength(0); }
/**
* 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 GetLength() <= sizeof(*this) - sizeof(Tlv); }
/**
* This method returns the Provisioning URL value.
*
* @returns The Provisioning URL value.
*
*/
const char *GetProvisioningUrl(void) const { return mProvisioningUrl; }
/**
* This method sets the Provisioning URL value.
*
* @param[in] aProvisioningUrl A pointer to the Provisioning URL value.
*
*/
ThreadError SetProvisioningUrl(const char *aProvisioningUrl) {
ThreadError error = kThreadError_None;
size_t len = aProvisioningUrl ? strnlen(aProvisioningUrl, kMaxLength + 1) : 0;
SetLength(static_cast<uint8_t>(len));
VerifyOrExit(len <= kMaxLength, error = kThreadError_InvalidArgs);
memcpy(mProvisioningUrl, aProvisioningUrl, len);
exit:
return error;
}
private:
enum
{
kMaxLength = 64,
};
char mProvisioningUrl[kMaxLength];
} OT_TOOL_PACKED_END;
/**
* This class implements Discovery Request TLV generation and parsing.
*