diff --git a/configure.ac b/configure.ac index 4a0c6b076..8ba43a168 100644 --- a/configure.ac +++ b/configure.ac @@ -908,10 +908,8 @@ PLATFORM_INFO=${with_platform_info} AC_MSG_RESULT(${PLATFORM_INFO}) -if test "$PLATFORM_INFO" != "none"; then - AC_SUBST(PLATFORM_INFO) - AC_DEFINE_UNQUOTED([PLATFORM_INFO],["${PLATFORM_INFO}"],[OpenThread platform information]) -fi +AC_SUBST(PLATFORM_INFO) +AC_DEFINE_UNQUOTED([PLATFORM_INFO],["${PLATFORM_INFO}"],[OpenThread platform information]) # # Tools diff --git a/examples/drivers/windows/include/otLwfIoctl.h b/examples/drivers/windows/include/otLwfIoctl.h index a9675807b..94d09a91e 100644 --- a/examples/drivers/windows/include/otLwfIoctl.h +++ b/examples/drivers/windows/include/otLwfIoctl.h @@ -509,12 +509,20 @@ typedef enum _OTLWF_NOTIF_TYPE OTLWF_CTL_CODE(168, METHOD_BUFFERED, FILE_WRITE_DATA) // GUID - InterfaceGuid -#define OPENTHREAD_PSK_MAX_LENGTH 32 -#define OPENTHREAD_PROV_URL_MAX_LENGTH 64 +#define OPENTHREAD_PSK_MAX_LENGTH 32 +#define OPENTHREAD_PROV_URL_MAX_LENGTH 64 +#define OPENTHREAD_VENDOR_NAME_MAX_LENGTH 32 +#define OPENTHREAD_VENDOR_MODEL_MAX_LENGTH 32 +#define OPENTHREAD_VENDOR_SW_VERSION_MAX_LENGTH 16 +#define OPENTHREAD_VENDOR_DATA_MAX_LENGTH 64 typedef struct otCommissionConfig { uint8_t PSKd[OPENTHREAD_PSK_MAX_LENGTH + 1]; uint8_t ProvisioningUrl[OPENTHREAD_PROV_URL_MAX_LENGTH + 1]; + uint8_t VendorName[OPENTHREAD_VENDOR_NAME_MAX_LENGTH + 1]; + uint8_t VendorModel[OPENTHREAD_VENDOR_MODEL_MAX_LENGTH + 1]; + uint8_t VendorSwVersion[OPENTHREAD_VENDOR_SW_VERSION_MAX_LENGTH + 1]; + uint8_t VendorData[OPENTHREAD_VENDOR_DATA_MAX_LENGTH + 1]; } otCommissionConfig; #define IOCTL_OTLWF_OT_JOINER_START \ diff --git a/examples/drivers/windows/otApi/otApi.cpp b/examples/drivers/windows/otApi/otApi.cpp index f80da531c..41ee80dfc 100644 --- a/examples/drivers/windows/otApi/otApi.cpp +++ b/examples/drivers/windows/otApi/otApi.cpp @@ -3491,6 +3491,10 @@ otJoinerStart( _In_ otInstance *aInstance, const char *aPSKd, const char *aProvisioningUrl, + const char *aVendorName, + const char *aVendorModel, + const char *aVendorSwVersion, + const char *aVendorData, _In_ otJoinerCallback aCallback, _In_ void *aCallbackContext ) @@ -3501,15 +3505,27 @@ otJoinerStart( size_t aPSKdLength = strlen(aPSKd); size_t aProvisioningUrlLength = aProvisioningUrl == nullptr ? 0 : strlen(aProvisioningUrl); + size_t aVendorNameLength = aVendorName == nullptr ? 0 : strlen(aVendorName); + size_t aVendorModelLength = aVendorModel == nullptr ? 0 : strlen(aVendorModel); + size_t aVendorSwVersionLength = aVendorSwVersion == nullptr ? 0 : strlen(aVendorSwVersion); + size_t aVendorDataLength = aVendorData == nullptr ? 0 : strlen(aVendorData); if (aPSKdLength > OPENTHREAD_PSK_MAX_LENGTH || - aProvisioningUrlLength > OPENTHREAD_PROV_URL_MAX_LENGTH) + aProvisioningUrlLength > OPENTHREAD_PROV_URL_MAX_LENGTH || + aVendorNameLength > OPENTHREAD_VENDOR_NAME_MAX_LENGTH || + aVendorModelLength > OPENTHREAD_VENDOR_MODEL_MAX_LENGTH || + aVendorSwVersionLength > OPENTHREAD_VENDOR_SW_VERSION_MAX_LENGTH || + aVendorDataLength > OPENTHREAD_VENDOR_DATA_MAX_LENGTH) { return kThreadError_InvalidArgs; } memcpy_s(config.PSKd, sizeof(config.PSKd), aPSKd, aPSKdLength); memcpy_s(config.ProvisioningUrl, sizeof(config.ProvisioningUrl), aProvisioningUrl, aProvisioningUrlLength); + memcpy_s(config.VendorName, sizeof(config.VendorName), aVendorName, aVendorNameLength); + memcpy_s(config.VendorModel, sizeof(config.VendorModel), aVendorModel, aVendorModelLength); + memcpy_s(config.VendorSwVersion, sizeof(config.VendorSwVersion), aVendorSwVersion, aVendorSwVersionLength); + memcpy_s(config.VendorData, sizeof(config.VendorData), aVendorData, aVendorDataLength); return DwordToThreadError(SetIOCTL(aInstance, IOCTL_OTLWF_OT_JOINER_START, (const otCommissionConfig*)&config)); } diff --git a/examples/drivers/windows/otLwf/iocontrol.c b/examples/drivers/windows/otLwf/iocontrol.c index d4d6ae185..075194980 100644 --- a/examples/drivers/windows/otLwf/iocontrol.c +++ b/examples/drivers/windows/otLwf/iocontrol.c @@ -5275,6 +5275,10 @@ otLwfIoCtl_otJoinerStart( pFilter->otCtx, (const char*)aConfig->PSKd, (const char*)aConfig->ProvisioningUrl, + (const char*)aConfig->VendorName, + (const char*)aConfig->VendorModel, + (const char*)aConfig->VendorSwVersion, + (const char*)aConfig->VendorData, NULL, // TODO: handle the joiner completion callback NULL) ); diff --git a/examples/drivers/windows/otNodeApi/otNodeApi.cpp b/examples/drivers/windows/otNodeApi/otNodeApi.cpp index 9f8dd6eab..5c1a349e6 100644 --- a/examples/drivers/windows/otNodeApi/otNodeApi.cpp +++ b/examples/drivers/windows/otNodeApi/otNodeApi.cpp @@ -951,7 +951,7 @@ OTNODEAPI int32_t OTCALL otNodeJoinerStart(otNode* aNode, const char *aPSKd, con printf("%d: joiner start %s %s\r\n", aNode->mId, aPSKd, aProvisioningUrl); // TODO: handle the joiner completion callback - auto error = otJoinerStart(aNode->mInstance, aPSKd, aProvisioningUrl, NULL, NULL); + auto error = otJoinerStart(aNode->mInstance, aPSKd, aProvisioningUrl, NULL, NULL, NULL, NULL, NULL, NULL); otLogFuncExit(); return error; diff --git a/include/commissioning/joiner.h b/include/commissioning/joiner.h index 7a4c4ab9b..b7edcd72c 100644 --- a/include/commissioning/joiner.h +++ b/include/commissioning/joiner.h @@ -66,6 +66,10 @@ typedef void (OTCALL *otJoinerCallback)(ThreadError aError, void *aContext); * @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). + * @param[in] aVendorName A pointer to the Vendor Name (must be static). + * @param[in] aVendorModel A pointer to the Vendor Model (must be static). + * @param[in] aVendorSwVersion A pointer to the Vendor SW Version (must be static). + * @param[in] aVendorData A pointer to the Vendor Data (must be static). * @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. * @@ -74,6 +78,8 @@ typedef void (OTCALL *otJoinerCallback)(ThreadError aError, void *aContext); * */ OTAPI ThreadError OTCALL otJoinerStart(otInstance *aInstance, const char *aPSKd, const char *aProvisioningUrl, + const char *aVendorName, const char *aVendorModel, + const char *aVendorSwVersion, const char *aVendordata, otJoinerCallback aCallback, void *aContext); /** diff --git a/include/openthread-types.h b/include/openthread-types.h index 4ac2ac6bf..849ee48cc 100644 --- a/include/openthread-types.h +++ b/include/openthread-types.h @@ -477,36 +477,41 @@ typedef struct otCommissioningDataset */ typedef enum otMeshcopTlvType { - OT_MESHCOP_TLV_CHANNEL = 0, ///< meshcop Channel TLV - OT_MESHCOP_TLV_PANID = 1, ///< meshcop Pan Id TLV - OT_MESHCOP_TLV_EXTPANID = 2, ///< meshcop Extended Pan Id TLV - OT_MESHCOP_TLV_NETWORKNAME = 3, ///< meshcop Network Name TLV - OT_MESHCOP_TLV_PSKC = 4, ///< meshcop PSKc TLV - OT_MESHCOP_TLV_MASTERKEY = 5, ///< meshcop Network Master Key TLV - OT_MESHCOP_TLV_MESHLOCALPREFIX = 7, ///< meshcop Mesh Local Prefix TLV - OT_MESHCOP_TLV_STEERING_DATA = 8, ///< meshcop Steering Data TLV - OT_MESHCOP_TLV_BORDER_AGENT_RLOC = 9, ///< meshcop Border Agent Locator TLV - OT_MESHCOP_TLV_COMMISSIONER_ID = 10, ///< meshcop Commissioner ID TLV - OT_MESHCOP_TLV_COMM_SESSION_ID = 11, ///< meshcop Commissioner Session ID TLV - OT_MESHCOP_TLV_SECURITYPOLICY = 12, ///< meshcop Security Policy TLV - OT_MESHCOP_TLV_GET = 13, ///< meshcop Get TLV - OT_MESHCOP_TLV_ACTIVETIMESTAMP = 14, ///< meshcop Active Timestamp TLV - OT_MESHCOP_TLV_STATE = 16, ///< meshcop State TLV - OT_MESHCOP_TLV_JOINER_DTLS = 17, ///< meshcop Joiner DTLS Encapsulation TLV - OT_MESHCOP_TLV_JOINER_UDP_PORT = 18, ///< meshcop Joiner UDP Port TLV - 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 - OT_MESHCOP_TLV_COUNT = 54, ///< meshcop Count TLV - OT_MESHCOP_TLV_PERIOD = 55, ///< meshcop Period TLV - OT_MESHCOP_TLV_SCAN_DURATION = 56, ///< meshcop Scan Duration TLV - OT_MESHCOP_TLV_ENERGY_LIST = 57, ///< meshcop Energy List TLV - OT_MESHCOP_TLV_DISCOVERYREQUEST = 128, ///< meshcop Discovery Request TLV - OT_MESHCOP_TLV_DISCOVERYRESPONSE = 129, ///< meshcop Discovery Response TLV + OT_MESHCOP_TLV_CHANNEL = 0, ///< meshcop Channel TLV + OT_MESHCOP_TLV_PANID = 1, ///< meshcop Pan Id TLV + OT_MESHCOP_TLV_EXTPANID = 2, ///< meshcop Extended Pan Id TLV + OT_MESHCOP_TLV_NETWORKNAME = 3, ///< meshcop Network Name TLV + OT_MESHCOP_TLV_PSKC = 4, ///< meshcop PSKc TLV + OT_MESHCOP_TLV_MASTERKEY = 5, ///< meshcop Network Master Key TLV + OT_MESHCOP_TLV_MESHLOCALPREFIX = 7, ///< meshcop Mesh Local Prefix TLV + OT_MESHCOP_TLV_STEERING_DATA = 8, ///< meshcop Steering Data TLV + OT_MESHCOP_TLV_BORDER_AGENT_RLOC = 9, ///< meshcop Border Agent Locator TLV + OT_MESHCOP_TLV_COMMISSIONER_ID = 10, ///< meshcop Commissioner ID TLV + OT_MESHCOP_TLV_COMM_SESSION_ID = 11, ///< meshcop Commissioner Session ID TLV + OT_MESHCOP_TLV_SECURITYPOLICY = 12, ///< meshcop Security Policy TLV + OT_MESHCOP_TLV_GET = 13, ///< meshcop Get TLV + OT_MESHCOP_TLV_ACTIVETIMESTAMP = 14, ///< meshcop Active Timestamp TLV + OT_MESHCOP_TLV_STATE = 16, ///< meshcop State TLV + OT_MESHCOP_TLV_JOINER_DTLS = 17, ///< meshcop Joiner DTLS Encapsulation TLV + OT_MESHCOP_TLV_JOINER_UDP_PORT = 18, ///< meshcop Joiner UDP Port TLV + 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_VENDOR_NAME_TLV = 33, ///< meshcop Vendor Name TLV + OT_MESHCOP_TLV_VENDOR_MODEL_TLV = 34, ///< meshcop Vendor Model TLV + OT_MESHCOP_TLV_VENDOR_SW_VERSION_TLV = 35, ///< meshcop Vendor SW Version TLV + OT_MESHCOP_TLV_VENDOR_DATA_TLV = 36, ///< meshcop Vendor Data TLV + OT_MESHCOP_TLV_VENDOR_STACK_VERSION_TLV = 37, ///< meshcop Vendor Stack Version 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 + OT_MESHCOP_TLV_COUNT = 54, ///< meshcop Count TLV + OT_MESHCOP_TLV_PERIOD = 55, ///< meshcop Period TLV + OT_MESHCOP_TLV_SCAN_DURATION = 56, ///< meshcop Scan Duration TLV + OT_MESHCOP_TLV_ENERGY_LIST = 57, ///< meshcop Energy List TLV + OT_MESHCOP_TLV_DISCOVERYREQUEST = 128, ///< meshcop Discovery Request TLV + OT_MESHCOP_TLV_DISCOVERYRESPONSE = 129, ///< meshcop Discovery Response TLV } otMeshcopTlvType; /** diff --git a/src/cli/cli.cpp b/src/cli/cli.cpp index 6e288c4eb..d12c94a30 100644 --- a/src/cli/cli.cpp +++ b/src/cli/cli.cpp @@ -2439,7 +2439,9 @@ void Interpreter::ProcessJoiner(int argc, char *argv[]) const char *provisioningUrl; VerifyOrExit(argc > 1, error = kThreadError_Parse); provisioningUrl = (argc > 2) ? argv[2] : NULL; - otJoinerStart(mInstance, argv[1], provisioningUrl, &Interpreter::s_HandleJoinerCallback, this); + otJoinerStart(mInstance, argv[1], provisioningUrl, + PACKAGE_NAME, PLATFORM_INFO, PACKAGE_VERSION, NULL, + &Interpreter::s_HandleJoinerCallback, this); } else if (strcmp(argv[0], "stop") == 0) { diff --git a/src/core/meshcop/joiner.cpp b/src/core/meshcop/joiner.cpp index 762bae458..ec42c1cf5 100644 --- a/src/core/meshcop/joiner.cpp +++ b/src/core/meshcop/joiner.cpp @@ -66,6 +66,10 @@ Joiner::Joiner(ThreadNetif &aNetif): mJoinerRouterChannel(0), mJoinerRouterPanId(0), mJoinerUdpPort(0), + mVendorName(NULL), + mVendorModel(NULL), + mVendorSwVersion(NULL), + mVendorData(NULL), mTimer(aNetif.GetIp6().mTimerScheduler, &Joiner::HandleTimer, this), mJoinerEntrust(OPENTHREAD_URI_JOINER_ENTRUST, &Joiner::HandleJoinerEntrust, this), mCoapServer(aNetif.GetCoapServer()), @@ -75,7 +79,9 @@ Joiner::Joiner(ThreadNetif &aNetif): mCoapServer.AddResource(mJoinerEntrust); } -ThreadError Joiner::Start(const char *aPSKd, const char *aProvisioningUrl, otJoinerCallback aCallback, void *aContext) +ThreadError Joiner::Start(const char *aPSKd, const char *aProvisioningUrl, + const char *aVendorName, const char *aVendorModel, const char *aVendorSwVersion, + const char *aVendorData, otJoinerCallback aCallback, void *aContext) { ThreadError error; Mac::ExtAddress extAddress; @@ -96,6 +102,10 @@ ThreadError Joiner::Start(const char *aPSKd, const char *aProvisioningUrl, otJoi mJoinerRouterPanId = Mac::kPanIdBroadcast; SuccessOrExit(error = mNetif.GetMle().Discover(0, 0, mNetif.GetMac().GetPanId(), HandleDiscoverResult, this)); + mVendorName = aVendorName; + mVendorModel = aVendorModel; + mVendorSwVersion = aVendorSwVersion; + mVendorData = aVendorData; mCallback = aCallback; mContext = aContext; mState = kStateDiscover; @@ -240,7 +250,10 @@ void Joiner::SendJoinerFinalize(void) ThreadError error = kThreadError_None; Message *message = NULL; StateTlv stateTlv; - uint8_t length; + VendorNameTlv vendorNameTlv; + VendorModelTlv vendorModelTlv; + VendorSwVersionTlv vendorSwVersionTlv; + VendorStackVersionTlv vendorStackVersionTlv; otLogFuncEntry(); @@ -254,11 +267,37 @@ void Joiner::SendJoinerFinalize(void) stateTlv.SetState(MeshCoP::StateTlv::kAccept); SuccessOrExit(error = message->Append(&stateTlv, sizeof(stateTlv))); - length = mSecureCoapClient.GetDtls().mProvisioningUrl.GetLength(); + vendorNameTlv.Init(); + vendorNameTlv.SetVendorName(mVendorName); + SuccessOrExit(error = message->Append(&vendorNameTlv, vendorNameTlv.GetSize())); - if (length > 0) + vendorModelTlv.Init(); + vendorModelTlv.SetVendorModel(mVendorModel); + SuccessOrExit(error = message->Append(&vendorModelTlv, vendorModelTlv.GetSize())); + + vendorSwVersionTlv.Init(); + vendorSwVersionTlv.SetVendorSwVersion(mVendorSwVersion); + SuccessOrExit(error = message->Append(&vendorSwVersionTlv, vendorSwVersionTlv.GetSize())); + + vendorStackVersionTlv.Init(); + vendorStackVersionTlv.SetOui(OPENTHREAD_CONFIG_STACK_VENDOR_OUI); + vendorStackVersionTlv.SetMajor(OPENTHREAD_CONFIG_STACK_VERSION_MAJOR); + vendorStackVersionTlv.SetMinor(OPENTHREAD_CONFIG_STACK_VERSION_MINOR); + vendorStackVersionTlv.SetRevision(OPENTHREAD_CONFIG_STACK_VERSION_REV); + SuccessOrExit(error = message->Append(&vendorStackVersionTlv, vendorStackVersionTlv.GetSize())); + + if (mVendorData != NULL) { - SuccessOrExit(error = message->Append(&mSecureCoapClient.GetDtls().mProvisioningUrl, length + sizeof(Tlv))); + VendorDataTlv vendorDataTlv; + vendorDataTlv.Init(); + vendorDataTlv.SetVendorData(mVendorData); + SuccessOrExit(error = message->Append(&vendorDataTlv, vendorDataTlv.GetSize())); + } + + if (mSecureCoapClient.GetDtls().mProvisioningUrl.GetLength() > 0) + { + SuccessOrExit(error = message->Append(&mSecureCoapClient.GetDtls().mProvisioningUrl, + mSecureCoapClient.GetDtls().mProvisioningUrl.GetSize())); } #if OPENTHREAD_ENABLE_CERT_LOG diff --git a/src/core/meshcop/joiner.hpp b/src/core/meshcop/joiner.hpp index cdc0a70c8..7ffd8ee75 100644 --- a/src/core/meshcop/joiner.hpp +++ b/src/core/meshcop/joiner.hpp @@ -67,13 +67,20 @@ public: * * @param[in] aPSKd A pointer to the PSKd. * @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] aVendorModel A pointer to the Vendor Model (must be static). + * @param[in] aVendorSwVersion A pointer to the Vendor SW Version (must be static). + * @param[in] aVendorData A pointer to the Vendor Data (must be static). * @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. * * @retval kThreadError_None Successfully started the Joiner service. * */ - ThreadError Start(const char *aPSKd, const char *aProvisioningUrl, otJoinerCallback aCallback, void *aContext); + ThreadError Start(const char *aPSKd, const char *aProvisioningUrl, + const char *aVendorName, const char *aVendorModel, + const char *aVendorSwVersion, const char *aVendorData, + otJoinerCallback aCallback, void *aContext); /** * This method stops the Joiner service. @@ -132,6 +139,11 @@ private: uint16_t mJoinerUdpPort; Mac::ExtAddress mJoinerRouter; + const char *mVendorName; + const char *mVendorModel; + const char *mVendorSwVersion; + const char *mVendorData; + Timer mTimer; Coap::Resource mJoinerEntrust; Coap::Server &mCoapServer; diff --git a/src/core/meshcop/tlvs.hpp b/src/core/meshcop/tlvs.hpp index 4c9a6c6e6..50f24fbe0 100644 --- a/src/core/meshcop/tlvs.hpp +++ b/src/core/meshcop/tlvs.hpp @@ -63,36 +63,41 @@ public: */ enum Type { - kChannel = OT_MESHCOP_TLV_CHANNEL, ///< Channel TLV - kPanId = OT_MESHCOP_TLV_PANID, ///< PAN ID TLV - kExtendedPanId = OT_MESHCOP_TLV_EXTPANID, ///< Extended PAN ID TLV - kNetworkName = OT_MESHCOP_TLV_NETWORKNAME, ///< Newtork Name TLV - kPSKc = OT_MESHCOP_TLV_PSKC, ///< PSKc TLV - kNetworkMasterKey = OT_MESHCOP_TLV_MASTERKEY, ///< Network Master Key TLV - kMeshLocalPrefix = OT_MESHCOP_TLV_MESHLOCALPREFIX, ///< Mesh Local Prefix TLV - kSteeringData = OT_MESHCOP_TLV_STEERING_DATA, ///< Steering Data TLV - kBorderAgentLocator = OT_MESHCOP_TLV_BORDER_AGENT_RLOC, ///< Border Agent Locator TLV - kCommissionerId = OT_MESHCOP_TLV_COMMISSIONER_ID, ///< Commissioner ID TLV - kCommissionerSessionId = OT_MESHCOP_TLV_COMM_SESSION_ID, ///< Commissioner Session ID TLV - kSecurityPolicy = OT_MESHCOP_TLV_SECURITYPOLICY, ///< Security Policy TLV - kGet = OT_MESHCOP_TLV_GET, ///< Get TLV - kActiveTimestamp = OT_MESHCOP_TLV_ACTIVETIMESTAMP, ///< Active Timestamp TLV - kState = OT_MESHCOP_TLV_STATE, ///< State TLV - kJoinerDtlsEncapsulation = OT_MESHCOP_TLV_JOINER_DTLS, ///< Joiner DTLS Encapsulation TLV - kJoinerUdpPort = OT_MESHCOP_TLV_JOINER_UDP_PORT, ///< Joiner UDP Port TLV - 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 - kCount = OT_MESHCOP_TLV_COUNT, ///< Count TLV - kPeriod = OT_MESHCOP_TLV_PERIOD, ///< Period TLV - kScanDuration = OT_MESHCOP_TLV_SCAN_DURATION, ///< Scan Duration TLV - kEnergyList = OT_MESHCOP_TLV_ENERGY_LIST, ///< Energy List TLV - kDiscoveryRequest = OT_MESHCOP_TLV_DISCOVERYREQUEST, ///< Discovery Request TLV - kDiscoveryResponse = OT_MESHCOP_TLV_DISCOVERYRESPONSE, ///< Discovery Response TLV + kChannel = OT_MESHCOP_TLV_CHANNEL, ///< Channel TLV + kPanId = OT_MESHCOP_TLV_PANID, ///< PAN ID TLV + kExtendedPanId = OT_MESHCOP_TLV_EXTPANID, ///< Extended PAN ID TLV + kNetworkName = OT_MESHCOP_TLV_NETWORKNAME, ///< Newtork Name TLV + kPSKc = OT_MESHCOP_TLV_PSKC, ///< PSKc TLV + kNetworkMasterKey = OT_MESHCOP_TLV_MASTERKEY, ///< Network Master Key TLV + kMeshLocalPrefix = OT_MESHCOP_TLV_MESHLOCALPREFIX, ///< Mesh Local Prefix TLV + kSteeringData = OT_MESHCOP_TLV_STEERING_DATA, ///< Steering Data TLV + kBorderAgentLocator = OT_MESHCOP_TLV_BORDER_AGENT_RLOC, ///< Border Agent Locator TLV + kCommissionerId = OT_MESHCOP_TLV_COMMISSIONER_ID, ///< Commissioner ID TLV + kCommissionerSessionId = OT_MESHCOP_TLV_COMM_SESSION_ID, ///< Commissioner Session ID TLV + kSecurityPolicy = OT_MESHCOP_TLV_SECURITYPOLICY, ///< Security Policy TLV + kGet = OT_MESHCOP_TLV_GET, ///< Get TLV + kActiveTimestamp = OT_MESHCOP_TLV_ACTIVETIMESTAMP, ///< Active Timestamp TLV + kState = OT_MESHCOP_TLV_STATE, ///< State TLV + kJoinerDtlsEncapsulation = OT_MESHCOP_TLV_JOINER_DTLS, ///< Joiner DTLS Encapsulation TLV + kJoinerUdpPort = OT_MESHCOP_TLV_JOINER_UDP_PORT, ///< Joiner UDP Port TLV + 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 + kVendorName = OT_MESHCOP_TLV_VENDOR_NAME_TLV, ///< meshcop Vendor Name TLV + kVendorModel = OT_MESHCOP_TLV_VENDOR_MODEL_TLV, ///< meshcop Vendor Model TLV + kVendorSwVersion = OT_MESHCOP_TLV_VENDOR_SW_VERSION_TLV, ///< meshcop Vendor SW Version TLV + kVendorData = OT_MESHCOP_TLV_VENDOR_DATA_TLV, ///< meshcop Vendor Data TLV + kVendorStackVersion = OT_MESHCOP_TLV_VENDOR_STACK_VERSION_TLV, ///< meshcop Vendor Stack Version 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 + kCount = OT_MESHCOP_TLV_COUNT, ///< Count TLV + kPeriod = OT_MESHCOP_TLV_PERIOD, ///< Period TLV + kScanDuration = OT_MESHCOP_TLV_SCAN_DURATION, ///< Scan Duration TLV + kEnergyList = OT_MESHCOP_TLV_ENERGY_LIST, ///< Energy List TLV + kDiscoveryRequest = OT_MESHCOP_TLV_DISCOVERYREQUEST, ///< Discovery Request TLV + kDiscoveryResponse = OT_MESHCOP_TLV_DISCOVERYRESPONSE, ///< Discovery Response TLV }; /** @@ -1461,6 +1466,390 @@ private: char mProvisioningUrl[kMaxLength]; } OT_TOOL_PACKED_END; +/** + * This class implements Vendor Name TLV generation and parsing. + * + */ +OT_TOOL_PACKED_BEGIN +class VendorNameTlv: public Tlv +{ +public: + /** + * This method initializes the TLV. + * + */ + void Init(void) { SetType(kVendorName); 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 Vendor Name value. + * + * @returns The Vendor Name value. + * + */ + const char *GetVendorName(void) const { return mVendorName; } + + /** + * This method sets the Vendor Name value. + * + * @param[in] aVendorName A pointer to the Vendor Name value. + * + */ + ThreadError SetVendorName(const char *aVendorName) { + ThreadError error = kThreadError_None; + size_t len = (aVendorName == NULL) ? 0 : strnlen(aVendorName, sizeof(mVendorName) + 1); + + VerifyOrExit(len <= sizeof(mVendorName), error = kThreadError_InvalidArgs); + SetLength(static_cast(len)); + + if (len > 0) { + memcpy(mVendorName, aVendorName, len); + } + +exit: + return error; + } + +private: + enum + { + kMaxLength = 32, + }; + + char mVendorName[kMaxLength]; +} OT_TOOL_PACKED_END; + +/** + * This class implements Vendor Model TLV generation and parsing. + * + */ +OT_TOOL_PACKED_BEGIN +class VendorModelTlv: public Tlv +{ +public: + /** + * This method initializes the TLV. + * + */ + void Init(void) { SetType(kVendorModel); 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 Vendor Model value. + * + * @returns The Vendor Model value. + * + */ + const char *GetVendorModel(void) const { return mVendorModel; } + + /** + * This method sets the Vendor Model value. + * + * @param[in] aVendorModel A pointer to the Vendor Model value. + * + */ + ThreadError SetVendorModel(const char *aVendorModel) { + ThreadError error = kThreadError_None; + size_t len = (aVendorModel == NULL) ? 0 : strnlen(aVendorModel, sizeof(mVendorModel) + 1); + + VerifyOrExit(len <= sizeof(mVendorModel), error = kThreadError_InvalidArgs); + SetLength(static_cast(len)); + + if (len > 0) { + memcpy(mVendorModel, aVendorModel, len); + } + +exit: + return error; + } + +private: + enum + { + kMaxLength = 32, + }; + + char mVendorModel[kMaxLength]; +} OT_TOOL_PACKED_END; + +/** + * This class implements Vendor SW Version TLV generation and parsing. + * + */ +OT_TOOL_PACKED_BEGIN +class VendorSwVersionTlv: public Tlv +{ +public: + /** + * This method initializes the TLV. + * + */ + void Init(void) { SetType(kVendorSwVersion); 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 Vendor SW Version value. + * + * @returns The Vendor SW Version value. + * + */ + const char *GetVendorSwVersion(void) const { return mVendorSwVersion; } + + /** + * This method sets the Vendor SW Version value. + * + * @param[in] aVendorSwVersion A pointer to the Vendor SW Version value. + * + */ + ThreadError SetVendorSwVersion(const char *aVendorSwVersion) { + ThreadError error = kThreadError_None; + size_t len = (aVendorSwVersion == NULL) ? 0 : strnlen(aVendorSwVersion, sizeof(mVendorSwVersion) + 1); + + VerifyOrExit(len <= sizeof(mVendorSwVersion), error = kThreadError_InvalidArgs); + SetLength(static_cast(len)); + + if (len > 0) { + memcpy(mVendorSwVersion, aVendorSwVersion, len); + } + +exit: + return error; + } + +private: + enum + { + kMaxLength = 16, + }; + + char mVendorSwVersion[kMaxLength]; +} OT_TOOL_PACKED_END; + +/** + * This class implements Vendor Data TLV generation and parsing. + * + */ +OT_TOOL_PACKED_BEGIN +class VendorDataTlv: public Tlv +{ +public: + /** + * This method initializes the TLV. + * + */ + void Init(void) { SetType(kVendorData); 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 Vendor Data value. + * + * @returns The Vendor Data value. + * + */ + const char *GetVendorData(void) const { return mVendorData; } + + /** + * This method sets the Vendor Data value. + * + * @param[in] aVendorData A pointer to the Vendor Data value. + * + */ + ThreadError SetVendorData(const char *aVendorData) { + ThreadError error = kThreadError_None; + size_t len = (aVendorData == NULL) ? 0 : strnlen(aVendorData, sizeof(mVendorData) + 1); + + VerifyOrExit(len <= sizeof(mVendorData), error = kThreadError_InvalidArgs); + SetLength(static_cast(len)); + + if (len > 0) { + memcpy(mVendorData, aVendorData, len); + } + +exit: + return error; + } + +private: + enum + { + kMaxLength = 64, + }; + + char mVendorData[kMaxLength]; +} OT_TOOL_PACKED_END; + +/** + * This class implements Vendor Stack Version TLV generation and parsing. + * + */ +OT_TOOL_PACKED_BEGIN +class VendorStackVersionTlv: public Tlv +{ +public: + /** + * This method initializes the TLV. + * + */ + void Init(void) { SetType(kVendorStackVersion); SetLength(sizeof(*this) - sizeof(Tlv)); } + + /** + * 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 Stack Vendor OUI value. + * + * @returns The Vendor Stack Vendor OUI value. + * + */ + uint32_t GetOui(void) const { + return (static_cast(mOui[0]) << 16) | (static_cast(mOui[1]) << 8) | static_cast(mOui[2]); + } + + /** + * This method returns the Stack Vendor OUI value. + * + * @param[in] aOui The Vendor Stack Vendor OUI value. + * + */ + void SetOui(uint32_t aOui) { + mOui[0] = (aOui >> 16) & 0xff; + mOui[1] = (aOui >> 8) & 0xff; + mOui[2] = aOui & 0xff; + } + + /** + * This method returns the Build value. + * + * @returns The Build value. + * + */ + uint16_t GetBuild(void) const { return (HostSwap16(mBuildRevision) & kBuildMask) >> kBuildOffset; } + + /** + * This method sets the Build value. + * + * @param[in] aBuild The Build value. + * + */ + void SetBuild(uint16_t aBuild) { + mBuildRevision = HostSwap16((HostSwap16(mBuildRevision) & ~kBuildMask) | + ((aBuild << kBuildOffset) & kBuildMask)); + } + + /** + * This method returns the Revision value. + * + * @returns The Revision value. + * + */ + uint8_t GetRevision(void) const { return (HostSwap16(mBuildRevision) & kRevMask) >> kRevOffset; } + + /** + * This method sets the Revision value. + * + * @param[in] aRevision The Revision value. + * + */ + void SetRevision(uint8_t aRevision) { + mBuildRevision = HostSwap16((HostSwap16(mBuildRevision) & ~kRevMask) | ((aRevision << kRevOffset) & kRevMask)); + } + + /** + * This method returns the Minor value. + * + * @returns The Minor value. + * + */ + uint8_t GetMinor(void) const { return (mMinorMajor & kMinorMask) >> kMinorOffset; } + + /** + * This method sets the Minor value. + * + * @param[in] aMinor The Minor value. + * + */ + void SetMinor(uint8_t aMinor) { + mMinorMajor = (mMinorMajor & ~kMinorMask) | ((aMinor << kMinorOffset) & kMinorMask); + } + + /** + * This method returns the Major value. + * + * @returns The Major value. + * + */ + uint8_t GetMajor(void) const { return (mMinorMajor & kMajorMask) >> kMajorOffset; } + + /** + * This method sets the Major value. + * + * @param[in] aMajor The Major value. + * + */ + void SetMajor(uint8_t aMajor) { + mMinorMajor = (mMinorMajor & ~kMajorMask) | ((aMajor << kMajorOffset) & kMajorMask); + } + +private: + uint8_t mOui[3]; + + enum + { + kBuildOffset = 4, + kBuildMask = 0xfff << kBuildOffset, + kRevOffset = 0, + kRevMask = 0xf << kBuildOffset, + }; + uint16_t mBuildRevision; + + enum + { + kMinorOffset = 4, + kMinorMask = 0xf << kMinorOffset, + kMajorOffset = 0, + kMajorMask = 0xf << kMajorOffset, + }; + uint8_t mMinorMajor; +} OT_TOOL_PACKED_END; + /** * This class implements Discovery Request TLV generation and parsing. * diff --git a/src/core/openthread-core-default-config.h b/src/core/openthread-core-default-config.h index b562da614..f2ab3a8e9 100644 --- a/src/core/openthread-core-default-config.h +++ b/src/core/openthread-core-default-config.h @@ -35,6 +35,46 @@ #ifndef OPENTHREAD_CORE_DEFAULT_CONFIG_H_ #define OPENTHREAD_CORE_DEFAULT_CONFIG_H_ +/** + * @def OPENTHREAD_CONFIG_STACK_VENDOR_OUI + * + * The Organizationally Unique Identifier for the Thread stack. + * + */ +#ifndef OPENTHREAD_CONFIG_STACK_VENDOR_OUI +#define OPENTHREAD_CONFIG_STACK_VENDOR_OUI 0x18b430 +#endif // OPENTHREAD_CONFIG_STACK_VENDOR_OUI + +/** + * @def OPENTHREAD_CONFIG_STACK_VERSION_REV + * + * The Stack Version Revision for the Thread stack. + * + */ +#ifndef OPENTHREAD_CONFIG_STACK_VERSION_REV +#define OPENTHREAD_CONFIG_STACK_VERSION_REV 0 +#endif // OPENTHREAD_CONFIG_STACK_VERSION_REV + +/** + * @def OPENTHREAD_CONFIG_STACK_VERSION_MAJOR + * + * The Stack Version Major for the Thread stack. + * + */ +#ifndef OPENTHREAD_CONFIG_STACK_VERSION_MAJOR +#define OPENTHREAD_CONFIG_STACK_VERSION_MAJOR 0 +#endif // OPENTHREAD_CONFIG_STACK_VERSION_MAJOR + +/** + * @def OPENTHREAD_CONFIG_STACK_VERSION_MINOR + * + * The Stack Version Minor for the Thread stack. + * + */ +#ifndef OPENTHREAD_CONFIG_STACK_VERSION_MINOR +#define OPENTHREAD_CONFIG_STACK_VERSION_MINOR 1 +#endif // OPENTHREAD_CONFIG_STACK_VERSION_MINOR + /** * @def OPENTHREAD_CONFIG_NUM_MESSAGE_BUFFERS * diff --git a/src/core/openthread.cpp b/src/core/openthread.cpp index 1c9536168..84efb7f22 100644 --- a/src/core/openthread.cpp +++ b/src/core/openthread.cpp @@ -1748,9 +1748,13 @@ uint16_t otCommissionerGetSessionId(otInstance *aInstance) #if OPENTHREAD_ENABLE_JOINER ThreadError otJoinerStart(otInstance *aInstance, const char *aPSKd, const char *aProvisioningUrl, + const char *aVendorName, const char *aVendorModel, + const char *aVendorSwVersion, const char *aVendorData, otJoinerCallback aCallback, void *aContext) { - return aInstance->mThreadNetif.GetJoiner().Start(aPSKd, aProvisioningUrl, aCallback, aContext); + return aInstance->mThreadNetif.GetJoiner().Start(aPSKd, aProvisioningUrl, + aVendorName, aVendorModel, aVendorSwVersion, aVendorData, + aCallback, aContext); } ThreadError otJoinerStop(otInstance *aInstance)