diff --git a/src/ncp/ncp_host.cpp b/src/ncp/ncp_host.cpp index 84055875bef..dd6fb760076 100644 --- a/src/ncp/ncp_host.cpp +++ b/src/ncp/ncp_host.cpp @@ -49,6 +49,7 @@ namespace Ncp { NcpNetworkProperties::NcpNetworkProperties(void) : mDeviceRole(OT_DEVICE_ROLE_DISABLED) { + memset(&mDatasetActiveTlvs, 0, sizeof(mDatasetActiveTlvs)); } otDeviceRole NcpNetworkProperties::GetDeviceRole(void) const @@ -61,6 +62,18 @@ void NcpNetworkProperties::SetDeviceRole(otDeviceRole aRole) mDeviceRole = aRole; } +void NcpNetworkProperties::SetDatasetActiveTlvs(const otOperationalDatasetTlvs &aActiveOpDatasetTlvs) +{ + mDatasetActiveTlvs.mLength = aActiveOpDatasetTlvs.mLength; + memcpy(mDatasetActiveTlvs.mTlvs, aActiveOpDatasetTlvs.mTlvs, aActiveOpDatasetTlvs.mLength); +} + +void NcpNetworkProperties::GetDatasetActiveTlvs(otOperationalDatasetTlvs &aDatasetTlvs) const +{ + aDatasetTlvs.mLength = mDatasetActiveTlvs.mLength; + memcpy(aDatasetTlvs.mTlvs, mDatasetActiveTlvs.mTlvs, mDatasetActiveTlvs.mLength); +} + // ===================================== NcpHost ====================================== NcpHost::NcpHost(const char *aInterfaceName, bool aDryRun) diff --git a/src/ncp/ncp_host.hpp b/src/ncp/ncp_host.hpp index 6bb18f77d07..c6c54bc2a6d 100644 --- a/src/ncp/ncp_host.hpp +++ b/src/ncp/ncp_host.hpp @@ -58,12 +58,15 @@ class NcpNetworkProperties : virtual public NetworkProperties, public PropsObser // NetworkProperties methods otDeviceRole GetDeviceRole(void) const override; + void GetDatasetActiveTlvs(otOperationalDatasetTlvs &aDatasetTlvs) const override; private: // PropsObserver methods void SetDeviceRole(otDeviceRole aRole) override; + void SetDatasetActiveTlvs(const otOperationalDatasetTlvs &aActiveOpDatasetTlvs) override; - otDeviceRole mDeviceRole; + otDeviceRole mDeviceRole; + otOperationalDatasetTlvs mDatasetActiveTlvs; }; class NcpHost : public MainloopProcessor, public ThreadHost, public NcpNetworkProperties diff --git a/src/ncp/ncp_spinel.cpp b/src/ncp/ncp_spinel.cpp index b9c6b45c71f..586cdd81fc1 100644 --- a/src/ncp/ncp_spinel.cpp +++ b/src/ncp/ncp_spinel.cpp @@ -438,6 +438,12 @@ otbrError NcpSpinel::HandleResponseForPropSet(spinel_tid_t aTid, case SPINEL_PROP_THREAD_ACTIVE_DATASET_TLVS: VerifyOrExit(aKey == SPINEL_PROP_THREAD_ACTIVE_DATASET_TLVS, error = OTBR_ERROR_INVALID_STATE); CallAndClear(mDatasetSetActiveTask, OT_ERROR_NONE); + { + otOperationalDatasetTlvs datasetTlvs; + VerifyOrExit(ParseOperationalDatasetTlvs(aData, aLength, datasetTlvs) == OT_ERROR_NONE, + error = OTBR_ERROR_PARSE); + mPropsObserver->SetDatasetActiveTlvs(datasetTlvs); + } break; case SPINEL_PROP_NET_IF_UP: @@ -725,6 +731,26 @@ otError NcpSpinel::ParseIp6StreamNet(const uint8_t *aBuf, uint8_t aLen, const ui return error; } +otError NcpSpinel::ParseOperationalDatasetTlvs(const uint8_t *aBuf, + uint8_t aLen, + otOperationalDatasetTlvs &aDatasetTlvs) +{ + otError error = OT_ERROR_NONE; + ot::Spinel::Decoder decoder; + const uint8_t *datasetTlvsData; + uint16_t datasetTlvsLen; + + decoder.Init(aBuf, aLen); + SuccessOrExit(error = decoder.ReadData(datasetTlvsData, datasetTlvsLen)); + VerifyOrExit(datasetTlvsLen <= sizeof(aDatasetTlvs.mTlvs), error = OT_ERROR_PARSE); + + memcpy(aDatasetTlvs.mTlvs, datasetTlvsData, datasetTlvsLen); + aDatasetTlvs.mLength = datasetTlvsLen; + +exit: + return error; +} + otDeviceRole NcpSpinel::SpinelRoleToDeviceRole(spinel_net_role_t aRole) { otDeviceRole role = OT_DEVICE_ROLE_DISABLED; diff --git a/src/ncp/ncp_spinel.hpp b/src/ncp/ncp_spinel.hpp index 571a063ab11..8fd9481fee0 100644 --- a/src/ncp/ncp_spinel.hpp +++ b/src/ncp/ncp_spinel.hpp @@ -68,6 +68,13 @@ class PropsObserver */ virtual void SetDeviceRole(otDeviceRole aRole) = 0; + /** + * Updates the active dataset. + * + * @param[in] aActiveOpDatasetTlvs The active dataset tlvs. + */ + virtual void SetDatasetActiveTlvs(const otOperationalDatasetTlvs &aActiveOpDatasetTlvs) = 0; + /** * The destructor. */ @@ -294,6 +301,7 @@ class NcpSpinel : public Netif::Dependencies otError ParseIp6AddressTable(const uint8_t *aBuf, uint16_t aLength, std::vector &aAddressTable); otError ParseIp6MulticastAddresses(const uint8_t *aBuf, uint8_t aLen, std::vector &aAddressList); otError ParseIp6StreamNet(const uint8_t *aBuf, uint8_t aLen, const uint8_t *&aData, uint16_t &aDataLen); + otError ParseOperationalDatasetTlvs(const uint8_t *aBuf, uint8_t aLen, otOperationalDatasetTlvs &aDatasetTlvs); ot::Spinel::SpinelDriver *mSpinelDriver; uint16_t mCmdTidsInUse; ///< Used transaction ids. diff --git a/src/ncp/rcp_host.cpp b/src/ncp/rcp_host.cpp index a7eb6e526da..d41146267db 100644 --- a/src/ncp/rcp_host.cpp +++ b/src/ncp/rcp_host.cpp @@ -78,6 +78,17 @@ otDeviceRole OtNetworkProperties::GetDeviceRole(void) const return otThreadGetDeviceRole(mInstance); } +void OtNetworkProperties::GetDatasetActiveTlvs(otOperationalDatasetTlvs &aDatasetTlvs) const +{ + otError error = otDatasetGetActiveTlvs(mInstance, &aDatasetTlvs); + + if (error != OT_ERROR_NONE) + { + aDatasetTlvs.mLength = 0; + memset(aDatasetTlvs.mTlvs, 0, sizeof(aDatasetTlvs.mTlvs)); + } +} + void OtNetworkProperties::SetInstance(otInstance *aInstance) { mInstance = aInstance; diff --git a/src/ncp/rcp_host.hpp b/src/ncp/rcp_host.hpp index 79f441a16af..aaa6274738d 100644 --- a/src/ncp/rcp_host.hpp +++ b/src/ncp/rcp_host.hpp @@ -73,6 +73,7 @@ class OtNetworkProperties : virtual public NetworkProperties // NetworkProperties methods otDeviceRole GetDeviceRole(void) const override; + void GetDatasetActiveTlvs(otOperationalDatasetTlvs &aDatasetTlvs) const override; // Set the otInstance void SetInstance(otInstance *aInstance); diff --git a/src/ncp/thread_host.hpp b/src/ncp/thread_host.hpp index 30b8e45a03d..6d350b8227e 100644 --- a/src/ncp/thread_host.hpp +++ b/src/ncp/thread_host.hpp @@ -63,6 +63,13 @@ class NetworkProperties */ virtual otDeviceRole GetDeviceRole(void) const = 0; + /** + * Returns the active operational dataset tlvs. + * + * @param[out] aDatasetTlvs A reference to where the Active Operational Dataset will be placed. + */ + virtual void GetDatasetActiveTlvs(otOperationalDatasetTlvs &aDatasetTlvs) const = 0; + /** * The destructor. */