mirror of
https://github.com/espressif/openthread.git
synced 2026-08-14 14:47:46 +00:00
[ncp] add Thread Dataset related spinel properties and their get/set handlers in NCP (#2327)
This commit adds new spinel properties related to Thread Operational Dataset and implements the corresponding get/set handlers for the new properties in `NcpBase`.
This commit is contained in:
committed by
Jonathan Hui
parent
a68e0b3f9f
commit
4e060e4dd3
@@ -352,3 +352,164 @@ Data per item is:
|
||||
* `C`: Link Quality Out
|
||||
* `C`: Age (seconds since last heard)
|
||||
* `b`: Link established with Router ID or not.
|
||||
|
||||
### PROP 5400: SPINEL_PROP_THREAD_ACTIVE_DATASET (#prop-thread-active-dataset)
|
||||
|
||||
* Type: Read-Write
|
||||
* Packing-Encoding: `A(t(iD))`
|
||||
|
||||
This property provides access to current Thread Active Operational Dataset.
|
||||
A Thread device maintains the Operational Dataset that it has stored locally
|
||||
and the one currently in use by the partition to which it is attached. This
|
||||
property corresponds to the locally stored Dataset on the device.
|
||||
|
||||
Operational Dataset consists of a set of supported properties (e.g., channel,
|
||||
master key, network name, PAN id, etc). Note that not all supported properties
|
||||
may be present (have a value) in a Dataset.
|
||||
|
||||
The Dataset value is encoded as an array of structures containing pairs of
|
||||
property key (as `i`) followed by the property value (as `D`). The property
|
||||
value must follow the format associated with the corresponding spinel
|
||||
property.
|
||||
|
||||
On write, any unknown/unsupported property keys must be ignored.
|
||||
|
||||
The following properties can be included in a Dataset list:
|
||||
|
||||
* SPINEL_PROP_DATASET_ACTIVE_TIMESTAMP
|
||||
* SPINEL_PROP_PHY_CHAN
|
||||
* SPINEL_PROP_PHY_CHAN_SUPPORTED (Channel Mask Page 0)
|
||||
* SPINEL_PROP_NET_MASTER_KEY
|
||||
* SPINEL_PROP_NET_NETWORK_NAME
|
||||
* SPINEL_PROP_NET_XPANID
|
||||
* SPINEL_PROP_MAC_15_4_PANID
|
||||
* SPINEL_PROP_IPV6_ML_PREFIX
|
||||
* SPINEL_PROP_NET_PSKC
|
||||
* SPINEL_PROP_DATASET_SECURITY_POLICY
|
||||
|
||||
### PROP 5401: SPINEL_PROP_THREAD_PENDING_DATASET (#prop-thread-pending-dataset)
|
||||
|
||||
* Type: Read-Write
|
||||
* Packing-Encoding: `A(t(iD))`
|
||||
|
||||
This property provide access to current Thread Pending Operational Dataset
|
||||
locally stored on the device.
|
||||
|
||||
The formatting of this property follows the same rules as in
|
||||
SPINEL_PROP_THREAD_ACTIVE_DATASET.
|
||||
|
||||
In addition supported properties in SPINEL_PROP_THREAD_ACTIVE_DATASET, the
|
||||
following properties can also be included in the Pending Dataset:
|
||||
|
||||
* SPINEL_PROP_DATASET_PENDING_TIMESTAMP
|
||||
* SPINEL_PROP_DATASET_DELAY_TIMER
|
||||
|
||||
### PROP 5402: SPINEL_PROP_THREAD_MGMT_ACTIVE_DATASET (#prop-thread-mgmt-active-dataset)
|
||||
|
||||
* Type: Write only
|
||||
* Packing-Encoding: `A(t(iD))`
|
||||
|
||||
The formatting of this property follows the same rules as in
|
||||
SPINEL_PROP_THREAD_ACTIVE_DATASET.
|
||||
|
||||
This is write-only property. When written, it triggers a MGMT_ACTIVE_SET meshcop
|
||||
command to be sent to the leader with the given Dataset. The spinel frame response
|
||||
should be a `LAST_STATUS` with the status of the transmission of MGMT_ACTIVE_SET
|
||||
command.
|
||||
|
||||
In addition to supported properties in SPINEL_PROP_THREAD_ACTIVE_DATASET, the
|
||||
following property can be included in the Dataset (to allow for custom raw
|
||||
TLVs):
|
||||
|
||||
* SPINEL_PROP_DATASET_RAW_TLVS
|
||||
|
||||
### PROP 5403: SPINEL_PROP_THREAD_MGMT_PENDING_DATASET (#prop-thread-mgmt-pending-dataset)
|
||||
|
||||
* Type: Write only
|
||||
* Packing-Encoding: `A(t(iD))`
|
||||
|
||||
This property is similar to SPINEL_PROP_THREAD_PENDING_DATASET and follows the
|
||||
same format and rules.
|
||||
|
||||
In addition to supported properties in SPINEL_PROP_THREAD_PENDING_DATASET, the
|
||||
following property can be included the Dataset (to allow for custom raw TLVs to
|
||||
be provided):
|
||||
|
||||
* SPINEL_PROP_DATASET_RAW_TLVS
|
||||
|
||||
### PROP 5404: SPINEL_PROP_DATASET_ACTIVE_TIMESTAMP (#prop-dataset-active-timestamps)
|
||||
|
||||
* Type: No direct read or write
|
||||
* Packing-Encoding: `X`
|
||||
|
||||
This property represents the Active Timestamp field in a Thread Operational
|
||||
Dataset.
|
||||
|
||||
This can only be included in one of the Dataset related properties below:
|
||||
|
||||
* SPINEL_PROP_THREAD_ACTIVE_DATASET
|
||||
* SPINEL_PROP_THREAD_PENDING_DATASET
|
||||
* SPINEL_PROP_THREAD_MGMT_ACTIVE_DATASET
|
||||
* SPINEL_PROP_THREAD_MGMT_PENDING_DATASET
|
||||
|
||||
### PROP 5405: SPINEL_PROP_DATASET_PENDING_TIMESTAMP (#prop-dataset-pending-timestamps)
|
||||
|
||||
* Type: No direct read or write
|
||||
* Packing-Encoding: `X`
|
||||
|
||||
This property represents the Pending Timestamp field in a Thread Operational
|
||||
Dataset.
|
||||
|
||||
It can only be included in one of the Pending Dataset properties:
|
||||
|
||||
* SPINEL_PROP_THREAD_PENDING_DATASET
|
||||
* SPINEL_PROP_THREAD_MGMT_PENDING_DATASET
|
||||
|
||||
|
||||
### PROP 5406: SPINEL_PROP_DATASET_DELAY_TIMER (#prop-dataset-delay-timer)
|
||||
|
||||
* Type: No direct read or write
|
||||
* Packing-Encoding: `L`
|
||||
|
||||
This property represents the Delay Timer field in a Thread Operational Dataset.
|
||||
Delay timer (in ms) specifies the time renaming until Thread devices overwrite
|
||||
the value in the Active Operational Dataset with the corresponding values in the
|
||||
Pending Operational Dataset.
|
||||
|
||||
It can only be included in one of the Pending Dataset properties:
|
||||
|
||||
* SPINEL_PROP_THREAD_PENDING_DATASET
|
||||
* SPINEL_PROP_THREAD_MGMT_PENDING_DATASET
|
||||
|
||||
### PROP 5407: SPINEL_PROP_DATASET_SECURITY_POLICY (#prop-dataset-security-policy)
|
||||
|
||||
* Type: No direct read or write
|
||||
* Packing-Encoding: `SC`
|
||||
|
||||
This property represents the Security Policy field in a Thread Operational
|
||||
Dataset.
|
||||
|
||||
The content is:
|
||||
|
||||
* `S` : Key Rotation Time (in units of hour)
|
||||
* `C` : Security Policy Flags (as specified in Thread 1.1 Section 8.10.1.15)
|
||||
|
||||
It can only be included in one of the Dataset related properties below:
|
||||
|
||||
* SPINEL_PROP_THREAD_ACTIVE_DATASET
|
||||
* SPINEL_PROP_THREAD_PENDING_DATASET
|
||||
* SPINEL_PROP_THREAD_MGMT_ACTIVE_DATASET
|
||||
* SPINEL_PROP_THREAD_MGMT_PENDING_DATASET
|
||||
|
||||
### PROP 5408: SPINEL_PROP_DATASET_RAW_TLVS (#prop-dataset-raw-tlvs)
|
||||
|
||||
* Type: No direct read or write
|
||||
* Packing-Encoding: `D`
|
||||
|
||||
This property defines extra raw TLVs that can be added to an Operational
|
||||
DataSet.
|
||||
|
||||
It can only be included in one of the following Dataset properties:
|
||||
|
||||
* SPINEL_PROP_THREAD_MGMT_ACTIVE_DATASET
|
||||
* SPINEL_PROP_THREAD_MGMT_PENDING_DATASET
|
||||
|
||||
@@ -136,6 +136,8 @@ const NcpBase::PropertyHandlerEntry NcpBase::mGetPropertyHandlerTable[] =
|
||||
NCP_GET_PROP_HANDLER_ENTRY(THREAD_NETWORK_DATA),
|
||||
NCP_GET_PROP_HANDLER_ENTRY(THREAD_STABLE_NETWORK_DATA),
|
||||
#endif
|
||||
NCP_GET_PROP_HANDLER_ENTRY(THREAD_ACTIVE_DATASET),
|
||||
NCP_GET_PROP_HANDLER_ENTRY(THREAD_PENDING_DATASET),
|
||||
NCP_GET_PROP_HANDLER_ENTRY(IPV6_ADDRESS_TABLE),
|
||||
NCP_GET_PROP_HANDLER_ENTRY(IPV6_ICMP_PING_OFFLOAD),
|
||||
NCP_GET_PROP_HANDLER_ENTRY(IPV6_LL_ADDR),
|
||||
@@ -310,6 +312,10 @@ const NcpBase::PropertyHandlerEntry NcpBase::mSetPropertyHandlerTable[] =
|
||||
NCP_SET_PROP_HANDLER_ENTRY(THREAD_TMF_PROXY_ENABLED),
|
||||
NCP_SET_PROP_HANDLER_ENTRY(THREAD_TMF_PROXY_STREAM),
|
||||
#endif
|
||||
NCP_SET_PROP_HANDLER_ENTRY(THREAD_ACTIVE_DATASET),
|
||||
NCP_SET_PROP_HANDLER_ENTRY(THREAD_PENDING_DATASET),
|
||||
NCP_SET_PROP_HANDLER_ENTRY(THREAD_MGMT_ACTIVE_DATASET),
|
||||
NCP_SET_PROP_HANDLER_ENTRY(THREAD_MGMT_PENDING_DATASET),
|
||||
#endif // #if OPENTHREAD_FTD
|
||||
};
|
||||
|
||||
|
||||
@@ -243,10 +243,12 @@ private:
|
||||
static void SendDoneTask(void *aContext);
|
||||
void SendDoneTask(void);
|
||||
|
||||
otError GetPropertyHandler_ChannelMaskHelper(uint32_t channel_mask);
|
||||
otError EncodeChannelMask(uint32_t channel_mask);
|
||||
otError EncodeOperationalDataset(const otOperationalDataset &aDataset);
|
||||
|
||||
#if OPENTHREAD_FTD
|
||||
otError EncodeChildInfo(const otChildInfo &aChildInfo);
|
||||
otError DecodeOperationalDataset(otOperationalDataset &aDataset, const uint8_t **aTlvs, uint8_t *aTlvsLength);
|
||||
#endif
|
||||
|
||||
#endif // OPENTHREAD_MTD || OPENTHREAD_FTD
|
||||
@@ -488,6 +490,8 @@ private:
|
||||
NCP_SET_PROP_HANDLER(THREAD_DISCOVERY_SCAN_ENABLE_FILTERING);
|
||||
NCP_GET_PROP_HANDLER(THREAD_DISCOVERY_SCAN_PANID);
|
||||
NCP_SET_PROP_HANDLER(THREAD_DISCOVERY_SCAN_PANID);
|
||||
NCP_GET_PROP_HANDLER(THREAD_ACTIVE_DATASET);
|
||||
NCP_GET_PROP_HANDLER(THREAD_PENDING_DATASET);
|
||||
|
||||
NCP_GET_PROP_HANDLER(CNTR_TX_PKT_TOTAL);
|
||||
NCP_GET_PROP_HANDLER(CNTR_TX_PKT_ACK_REQ);
|
||||
@@ -598,6 +602,10 @@ private:
|
||||
NCP_SET_PROP_HANDLER(THREAD_TMF_PROXY_STREAM);
|
||||
#endif
|
||||
NCP_REMOVE_PROP_HANDLER(THREAD_ACTIVE_ROUTER_IDS);
|
||||
NCP_SET_PROP_HANDLER(THREAD_ACTIVE_DATASET);
|
||||
NCP_SET_PROP_HANDLER(THREAD_PENDING_DATASET);
|
||||
NCP_SET_PROP_HANDLER(THREAD_MGMT_ACTIVE_DATASET);
|
||||
NCP_SET_PROP_HANDLER(THREAD_MGMT_PENDING_DATASET);
|
||||
|
||||
#endif // OPENTHREAD_FTD
|
||||
|
||||
|
||||
@@ -32,6 +32,7 @@
|
||||
|
||||
#include "ncp_base.hpp"
|
||||
|
||||
#include <openthread/dataset_ftd.h>
|
||||
#include <openthread/diag.h>
|
||||
#include <openthread/icmp6.h>
|
||||
#include <openthread/ncp.h>
|
||||
@@ -39,6 +40,7 @@
|
||||
#include <openthread/platform/misc.h>
|
||||
#include <openthread/platform/radio.h>
|
||||
#include <openthread/thread_ftd.h>
|
||||
|
||||
#if OPENTHREAD_ENABLE_TMF_PROXY
|
||||
#include <openthread/tmf_proxy.h>
|
||||
#endif
|
||||
@@ -592,6 +594,230 @@ exit:
|
||||
}
|
||||
#endif // OPENTHREAD_ENABLE_TMF_PROXY
|
||||
|
||||
otError NcpBase::DecodeOperationalDataset(otOperationalDataset &aDataset, const uint8_t **aTlvs, uint8_t *aTlvsLength)
|
||||
{
|
||||
otError error = OT_ERROR_NONE;
|
||||
|
||||
memset(&aDataset, 0, sizeof(otOperationalDataset));
|
||||
|
||||
if (aTlvs != NULL)
|
||||
{
|
||||
*aTlvs = NULL;
|
||||
}
|
||||
|
||||
if (aTlvsLength != NULL)
|
||||
{
|
||||
*aTlvsLength = 0;
|
||||
}
|
||||
|
||||
while (!mDecoder.IsAllReadInStruct())
|
||||
{
|
||||
unsigned int propKey;
|
||||
|
||||
SuccessOrExit(error = mDecoder.OpenStruct());
|
||||
SuccessOrExit(error = mDecoder.ReadUintPacked(propKey));
|
||||
|
||||
switch (static_cast<spinel_prop_key_t>(propKey))
|
||||
{
|
||||
case SPINEL_PROP_DATASET_ACTIVE_TIMESTAMP:
|
||||
SuccessOrExit(error = mDecoder.ReadUint64(aDataset.mActiveTimestamp));
|
||||
aDataset.mIsActiveTimestampSet = true;
|
||||
break;
|
||||
|
||||
case SPINEL_PROP_DATASET_PENDING_TIMESTAMP:
|
||||
SuccessOrExit(error = mDecoder.ReadUint64(aDataset.mPendingTimestamp));
|
||||
aDataset.mIsPendingTimestampSet = true;
|
||||
break;
|
||||
|
||||
case SPINEL_PROP_NET_MASTER_KEY:
|
||||
{
|
||||
const uint8_t *key;
|
||||
uint16_t len;
|
||||
|
||||
SuccessOrExit(error = mDecoder.ReadData(key, len));
|
||||
VerifyOrExit(len == OT_MASTER_KEY_SIZE, error = OT_ERROR_INVALID_ARGS);
|
||||
memcpy(aDataset.mMasterKey.m8, key, len);
|
||||
aDataset.mIsMasterKeySet = true;
|
||||
break;
|
||||
}
|
||||
|
||||
case SPINEL_PROP_NET_NETWORK_NAME:
|
||||
{
|
||||
const char *name;
|
||||
size_t len;
|
||||
|
||||
SuccessOrExit(error = mDecoder.ReadUtf8(name));
|
||||
len = strlen(name);
|
||||
VerifyOrExit(len <= OT_NETWORK_NAME_MAX_SIZE, error = OT_ERROR_INVALID_ARGS);
|
||||
memcpy(aDataset.mNetworkName.m8, name, len + 1);
|
||||
aDataset.mIsNetworkNameSet = true;
|
||||
break;
|
||||
}
|
||||
|
||||
case SPINEL_PROP_NET_XPANID:
|
||||
{
|
||||
const uint8_t *xpanid;
|
||||
uint16_t len;
|
||||
|
||||
SuccessOrExit(error = mDecoder.ReadData(xpanid, len));
|
||||
VerifyOrExit(len == OT_EXT_PAN_ID_SIZE, error = OT_ERROR_INVALID_ARGS);
|
||||
memcpy(aDataset.mExtendedPanId.m8, xpanid, len);
|
||||
aDataset.mIsExtendedPanIdSet = true;
|
||||
break;
|
||||
}
|
||||
|
||||
case SPINEL_PROP_IPV6_ML_PREFIX:
|
||||
{
|
||||
const otIp6Address *addr;
|
||||
uint8_t prefixLen;
|
||||
|
||||
SuccessOrExit(error = mDecoder.ReadIp6Address(addr));
|
||||
SuccessOrExit(error = mDecoder.ReadUint8(prefixLen));
|
||||
VerifyOrExit(prefixLen == 64, error = OT_ERROR_INVALID_ARGS);
|
||||
memcpy(aDataset.mMeshLocalPrefix.m8, addr, OT_MESH_LOCAL_PREFIX_SIZE);
|
||||
aDataset.mIsMeshLocalPrefixSet = true;
|
||||
break;
|
||||
}
|
||||
|
||||
case SPINEL_PROP_DATASET_DELAY_TIMER:
|
||||
SuccessOrExit(error = mDecoder.ReadUint32(aDataset.mDelay));
|
||||
aDataset.mIsDelaySet = true;
|
||||
break;
|
||||
|
||||
case SPINEL_PROP_MAC_15_4_PANID:
|
||||
SuccessOrExit(error = mDecoder.ReadUint16(aDataset.mPanId));
|
||||
aDataset.mIsPanIdSet = true;
|
||||
break;
|
||||
|
||||
case SPINEL_PROP_PHY_CHAN:
|
||||
{
|
||||
uint8_t channel;
|
||||
|
||||
SuccessOrExit(error = mDecoder.ReadUint8(channel));
|
||||
aDataset.mChannel = channel;
|
||||
aDataset.mIsChannelSet = true;
|
||||
break;
|
||||
}
|
||||
|
||||
case SPINEL_PROP_NET_PSKC:
|
||||
{
|
||||
const uint8_t *psk;
|
||||
uint16_t len;
|
||||
|
||||
SuccessOrExit(error = mDecoder.ReadData(psk, len));
|
||||
VerifyOrExit(len == OT_PSKC_MAX_SIZE, error = OT_ERROR_INVALID_ARGS);
|
||||
memcpy(aDataset.mPSKc.m8, psk, OT_PSKC_MAX_SIZE);
|
||||
aDataset.mIsPSKcSet = true;
|
||||
break;
|
||||
}
|
||||
|
||||
case SPINEL_PROP_DATASET_SECURITY_POLICY:
|
||||
SuccessOrExit(error = mDecoder.ReadUint16(aDataset.mSecurityPolicy.mRotationTime));
|
||||
SuccessOrExit(error = mDecoder.ReadUint8(aDataset.mSecurityPolicy.mFlags));
|
||||
aDataset.mIsSecurityPolicySet = true;
|
||||
break;
|
||||
|
||||
case SPINEL_PROP_PHY_CHAN_SUPPORTED:
|
||||
{
|
||||
uint8_t channel;
|
||||
|
||||
aDataset.mChannelMaskPage0 = 0;
|
||||
|
||||
while (!mDecoder.IsAllReadInStruct())
|
||||
{
|
||||
SuccessOrExit(error = mDecoder.ReadUint8(channel));
|
||||
VerifyOrExit(channel <= 31, error = OT_ERROR_INVALID_ARGS);
|
||||
aDataset.mChannelMaskPage0 |= (1U << channel);
|
||||
}
|
||||
|
||||
aDataset.mIsChannelMaskPage0Set = true;
|
||||
}
|
||||
|
||||
case SPINEL_PROP_DATASET_RAW_TLVS:
|
||||
{
|
||||
const uint8_t *tlvs;
|
||||
uint16_t len;
|
||||
|
||||
SuccessOrExit(error = mDecoder.ReadData(tlvs, len));
|
||||
VerifyOrExit(len <= 255, error = OT_ERROR_INVALID_ARGS);
|
||||
|
||||
if (aTlvs != NULL)
|
||||
{
|
||||
*aTlvs = tlvs;
|
||||
}
|
||||
|
||||
if (aTlvsLength != NULL)
|
||||
{
|
||||
*aTlvsLength = static_cast<uint8_t>(len);
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
SuccessOrExit(error = mDecoder.CloseStruct());
|
||||
}
|
||||
|
||||
exit:
|
||||
return error;
|
||||
}
|
||||
|
||||
otError NcpBase::SetPropertyHandler_THREAD_ACTIVE_DATASET(void)
|
||||
{
|
||||
otError error = OT_ERROR_NONE;
|
||||
otOperationalDataset dataset;
|
||||
|
||||
SuccessOrExit(error = DecodeOperationalDataset(dataset, NULL, NULL));
|
||||
error = otDatasetSetActive(mInstance, &dataset);
|
||||
|
||||
exit:
|
||||
return error;
|
||||
}
|
||||
|
||||
otError NcpBase::SetPropertyHandler_THREAD_PENDING_DATASET(void)
|
||||
{
|
||||
otError error = OT_ERROR_NONE;
|
||||
otOperationalDataset dataset;
|
||||
|
||||
SuccessOrExit(error = DecodeOperationalDataset(dataset, NULL, NULL));
|
||||
error = otDatasetSetPending(mInstance, &dataset);
|
||||
|
||||
exit:
|
||||
return error;
|
||||
}
|
||||
|
||||
otError NcpBase::SetPropertyHandler_THREAD_MGMT_ACTIVE_DATASET(void)
|
||||
{
|
||||
otError error = OT_ERROR_NONE;
|
||||
otOperationalDataset dataset;
|
||||
const uint8_t *extraTlvs;
|
||||
uint8_t extraTlvsLength;
|
||||
|
||||
SuccessOrExit(error = DecodeOperationalDataset(dataset, &extraTlvs, &extraTlvsLength));
|
||||
error = otDatasetSendMgmtActiveSet(mInstance, &dataset, extraTlvs, extraTlvsLength);
|
||||
|
||||
exit:
|
||||
return error;
|
||||
|
||||
}
|
||||
|
||||
otError NcpBase::SetPropertyHandler_THREAD_MGMT_PENDING_DATASET(void)
|
||||
{
|
||||
otError error = OT_ERROR_NONE;
|
||||
otOperationalDataset dataset;
|
||||
const uint8_t *extraTlvs;
|
||||
uint8_t extraTlvsLength;
|
||||
|
||||
SuccessOrExit(error = DecodeOperationalDataset(dataset, &extraTlvs, &extraTlvsLength));
|
||||
error = otDatasetSendMgmtPendingSet(mInstance, &dataset, extraTlvs, extraTlvsLength);
|
||||
|
||||
exit:
|
||||
return error;
|
||||
}
|
||||
|
||||
} // namespace Ncp
|
||||
} // namespace ot
|
||||
|
||||
|
||||
+136
-3
@@ -217,7 +217,7 @@ otError NcpBase::GetPropertyHandler_PHY_FREQ(void)
|
||||
|
||||
otError NcpBase::GetPropertyHandler_PHY_CHAN_SUPPORTED(void)
|
||||
{
|
||||
return GetPropertyHandler_ChannelMaskHelper(mSupportedChannelMask);
|
||||
return EncodeChannelMask(mSupportedChannelMask);
|
||||
}
|
||||
|
||||
otError NcpBase::GetPropertyHandler_PHY_RSSI(void)
|
||||
@@ -844,6 +844,139 @@ otError NcpBase::SetPropertyHandler_THREAD_DISCOVERY_SCAN_PANID(void)
|
||||
return mDecoder.ReadUint16(mDiscoveryScanPanId);
|
||||
}
|
||||
|
||||
otError NcpBase::EncodeOperationalDataset(const otOperationalDataset &aDataset)
|
||||
{
|
||||
otError error = OT_ERROR_NONE;
|
||||
|
||||
if (aDataset.mIsActiveTimestampSet)
|
||||
{
|
||||
SuccessOrExit(mEncoder.OpenStruct());
|
||||
SuccessOrExit(mEncoder.WriteUintPacked(SPINEL_PROP_DATASET_ACTIVE_TIMESTAMP));
|
||||
SuccessOrExit(mEncoder.WriteUint64(aDataset.mActiveTimestamp));
|
||||
SuccessOrExit(mEncoder.CloseStruct());
|
||||
}
|
||||
|
||||
if (aDataset.mIsPendingTimestampSet)
|
||||
{
|
||||
SuccessOrExit(mEncoder.OpenStruct());
|
||||
SuccessOrExit(mEncoder.WriteUintPacked(SPINEL_PROP_DATASET_PENDING_TIMESTAMP));
|
||||
SuccessOrExit(mEncoder.WriteUint64(aDataset.mPendingTimestamp));
|
||||
SuccessOrExit(mEncoder.CloseStruct());
|
||||
}
|
||||
|
||||
if (aDataset.mIsMasterKeySet)
|
||||
{
|
||||
SuccessOrExit(mEncoder.OpenStruct());
|
||||
SuccessOrExit(mEncoder.WriteUintPacked(SPINEL_PROP_NET_MASTER_KEY));
|
||||
SuccessOrExit(mEncoder.WriteData(aDataset.mMasterKey.m8, OT_MASTER_KEY_SIZE));
|
||||
SuccessOrExit(mEncoder.CloseStruct());
|
||||
}
|
||||
|
||||
if (aDataset.mIsNetworkNameSet)
|
||||
{
|
||||
SuccessOrExit(mEncoder.OpenStruct());
|
||||
SuccessOrExit(mEncoder.WriteUintPacked(SPINEL_PROP_NET_NETWORK_NAME));
|
||||
SuccessOrExit(mEncoder.WriteUtf8(aDataset.mNetworkName.m8));
|
||||
SuccessOrExit(mEncoder.CloseStruct());
|
||||
}
|
||||
|
||||
if (aDataset.mIsExtendedPanIdSet)
|
||||
{
|
||||
SuccessOrExit(mEncoder.OpenStruct());
|
||||
SuccessOrExit(mEncoder.WriteUintPacked(SPINEL_PROP_NET_XPANID));
|
||||
SuccessOrExit(mEncoder.WriteData(aDataset.mExtendedPanId.m8, OT_EXT_PAN_ID_SIZE));
|
||||
SuccessOrExit(mEncoder.CloseStruct());
|
||||
}
|
||||
|
||||
if (aDataset.mIsMeshLocalPrefixSet)
|
||||
{
|
||||
otIp6Address addr;
|
||||
|
||||
memcpy(addr.mFields.m8, aDataset.mMeshLocalPrefix.m8, 8);
|
||||
memset(addr.mFields.m8 + 8, 0, 8); // Zero out the last 8 bytes.
|
||||
|
||||
SuccessOrExit(mEncoder.OpenStruct());
|
||||
SuccessOrExit(mEncoder.WriteUintPacked(SPINEL_PROP_IPV6_ML_PREFIX));
|
||||
SuccessOrExit(error = mEncoder.WriteIp6Address(addr)); // Mesh local prefix
|
||||
SuccessOrExit(error = mEncoder.WriteUint8(64)); // Prefix length (in bits)
|
||||
SuccessOrExit(mEncoder.CloseStruct());
|
||||
}
|
||||
|
||||
if (aDataset.mIsDelaySet)
|
||||
{
|
||||
SuccessOrExit(mEncoder.OpenStruct());
|
||||
SuccessOrExit(mEncoder.WriteUintPacked(SPINEL_PROP_DATASET_DELAY_TIMER));
|
||||
SuccessOrExit(mEncoder.WriteUint32(aDataset.mDelay));
|
||||
SuccessOrExit(mEncoder.CloseStruct());
|
||||
}
|
||||
|
||||
if (aDataset.mIsPanIdSet)
|
||||
{
|
||||
SuccessOrExit(mEncoder.OpenStruct());
|
||||
SuccessOrExit(mEncoder.WriteUintPacked(SPINEL_PROP_MAC_15_4_PANID));
|
||||
SuccessOrExit(mEncoder.WriteUint16(aDataset.mPanId));
|
||||
SuccessOrExit(mEncoder.CloseStruct());
|
||||
}
|
||||
|
||||
if (aDataset.mIsChannelSet)
|
||||
{
|
||||
SuccessOrExit(mEncoder.OpenStruct());
|
||||
SuccessOrExit(mEncoder.WriteUintPacked(SPINEL_PROP_PHY_CHAN));
|
||||
|
||||
// The channel is stored in Dataset as `uint16_t` (to accommodate
|
||||
// larger number of channels in sub-GHz band), however the current
|
||||
// definition of `SPINEL_PROP_PHY_CHAN` property limits the channel
|
||||
// to a `uint8_t`.
|
||||
|
||||
SuccessOrExit(mEncoder.WriteUint8(static_cast<uint8_t>(aDataset.mChannel)));
|
||||
SuccessOrExit(mEncoder.CloseStruct());
|
||||
}
|
||||
|
||||
if (aDataset.mIsPSKcSet)
|
||||
{
|
||||
SuccessOrExit(mEncoder.OpenStruct());
|
||||
SuccessOrExit(mEncoder.WriteUintPacked(SPINEL_PROP_NET_PSKC));
|
||||
SuccessOrExit(mEncoder.WriteData(aDataset.mPSKc.m8, sizeof(spinel_net_pskc_t)));
|
||||
SuccessOrExit(mEncoder.CloseStruct());
|
||||
}
|
||||
|
||||
if (aDataset.mIsSecurityPolicySet)
|
||||
{
|
||||
SuccessOrExit(mEncoder.OpenStruct());
|
||||
SuccessOrExit(mEncoder.WriteUintPacked(SPINEL_PROP_DATASET_SECURITY_POLICY));
|
||||
SuccessOrExit(mEncoder.WriteUint16(aDataset.mSecurityPolicy.mRotationTime));
|
||||
SuccessOrExit(mEncoder.WriteUint8(aDataset.mSecurityPolicy.mFlags));
|
||||
SuccessOrExit(mEncoder.CloseStruct());
|
||||
}
|
||||
|
||||
if (aDataset.mIsChannelMaskPage0Set)
|
||||
{
|
||||
SuccessOrExit(mEncoder.OpenStruct());
|
||||
SuccessOrExit(mEncoder.WriteUintPacked(SPINEL_PROP_PHY_CHAN_SUPPORTED));
|
||||
SuccessOrExit(EncodeChannelMask(aDataset.mChannelMaskPage0));
|
||||
SuccessOrExit(mEncoder.CloseStruct());
|
||||
}
|
||||
|
||||
exit:
|
||||
return error;
|
||||
}
|
||||
|
||||
otError NcpBase::GetPropertyHandler_THREAD_ACTIVE_DATASET(void)
|
||||
{
|
||||
otOperationalDataset dataset;
|
||||
|
||||
IgnoreReturnValue(otDatasetGetActive(mInstance, &dataset));
|
||||
return EncodeOperationalDataset(dataset);
|
||||
}
|
||||
|
||||
otError NcpBase::GetPropertyHandler_THREAD_PENDING_DATASET(void)
|
||||
{
|
||||
otOperationalDataset dataset;
|
||||
|
||||
IgnoreReturnValue(otDatasetGetPending(mInstance, &dataset));
|
||||
return EncodeOperationalDataset(dataset);
|
||||
}
|
||||
|
||||
otError NcpBase::GetPropertyHandler_IPV6_ML_PREFIX(void)
|
||||
{
|
||||
otError error = OT_ERROR_NONE;
|
||||
@@ -2254,7 +2387,7 @@ otError NcpBase::GetPropertyHandler_NEST_LEGACY_LAST_NODE_JOINED(void)
|
||||
}
|
||||
#endif // OPENTHREAD_ENABLE_LEGACY
|
||||
|
||||
otError NcpBase::GetPropertyHandler_ChannelMaskHelper(uint32_t aChannelMask)
|
||||
otError NcpBase::EncodeChannelMask(uint32_t aChannelMask)
|
||||
{
|
||||
otError error = OT_ERROR_NONE;
|
||||
|
||||
@@ -2273,7 +2406,7 @@ exit:
|
||||
|
||||
otError NcpBase::GetPropertyHandler_MAC_SCAN_MASK(void)
|
||||
{
|
||||
return GetPropertyHandler_ChannelMaskHelper(mChannelMask);
|
||||
return EncodeChannelMask(mChannelMask);
|
||||
}
|
||||
|
||||
otError NcpBase::SetPropertyHandler_MAC_SCAN_MASK(void)
|
||||
|
||||
@@ -1473,6 +1473,42 @@ spinel_prop_key_to_cstr(spinel_prop_key_t prop_key)
|
||||
ret = "PROP_THREAD_ROUTER_TABLE";
|
||||
break;
|
||||
|
||||
case SPINEL_PROP_THREAD_ACTIVE_DATASET:
|
||||
ret = "PROP_THREAD_ACTIVE_DATASET";
|
||||
break;
|
||||
|
||||
case SPINEL_PROP_THREAD_PENDING_DATASET:
|
||||
ret = "PROP_THREAD_PENDING_DATASET";
|
||||
break;
|
||||
|
||||
case SPINEL_PROP_THREAD_MGMT_ACTIVE_DATASET:
|
||||
ret = "PROP_THREAD_MGMT_ACTIVE_DATASET";
|
||||
break;
|
||||
|
||||
case SPINEL_PROP_THREAD_MGMT_PENDING_DATASET:
|
||||
ret = "PROP_THREAD_MGMT_PENDING_DATASET";
|
||||
break;
|
||||
|
||||
case SPINEL_PROP_DATASET_ACTIVE_TIMESTAMP:
|
||||
ret = "PROP_DATASET_ACTIVE_TIMESTAMP";
|
||||
break;
|
||||
|
||||
case SPINEL_PROP_DATASET_PENDING_TIMESTAMP:
|
||||
ret = "PROP_DATASET_PENDING_TIMESTAMP";
|
||||
break;
|
||||
|
||||
case SPINEL_PROP_DATASET_DELAY_TIMER:
|
||||
ret = "PROP_DATASET_DELAY_TIMER";
|
||||
break;
|
||||
|
||||
case SPINEL_PROP_DATASET_SECURITY_POLICY:
|
||||
ret = "PROP_DATASET_SECURITY_POLICY";
|
||||
break;
|
||||
|
||||
case SPINEL_PROP_DATASET_RAW_TLVS:
|
||||
ret = "PROP_DATASET_RAW_TLVS";
|
||||
break;
|
||||
|
||||
case SPINEL_PROP_IPV6_LL_ADDR:
|
||||
ret = "PROP_IPV6_LL_ADDR";
|
||||
break;
|
||||
|
||||
+149
-1
@@ -1011,7 +1011,7 @@ typedef enum
|
||||
SPINEL_PROP_THREAD_STEERING_DATA = SPINEL_PROP_THREAD_EXT__BEGIN + 22,
|
||||
|
||||
/// Thread Router Table.
|
||||
/** Format: `A(t(ESCCCCCCb)`.
|
||||
/** Format: `A(t(ESCCCCCCb)` - Read only
|
||||
*
|
||||
* Data per item is:
|
||||
*
|
||||
@@ -1028,6 +1028,154 @@ typedef enum
|
||||
*/
|
||||
SPINEL_PROP_THREAD_ROUTER_TABLE = SPINEL_PROP_THREAD_EXT__BEGIN + 23,
|
||||
|
||||
/// Thread Active Operational Dataset
|
||||
/** Format: `A(t(iD))` - Read-Write
|
||||
*
|
||||
* This property provides access to current Thread Active Operational Dataset. A Thread device maintains the
|
||||
* Operational Dataset that it has stored locally and the one currently in use by the partition to which it is
|
||||
* attached. This property corresponds to the locally stored Dataset on the device.
|
||||
*
|
||||
* Operational Dataset consists of a set of supported properties (e.g., channel, master key, network name, PAN id,
|
||||
* etc). Note that not all supported properties may be present (have a value) in a Dataset.
|
||||
*
|
||||
* The Dataset value is encoded as an array of structs containing pairs of property key (as `i`) followed by the
|
||||
* property value (as `D`). The property value must follow the format associated with the corresponding property.
|
||||
*
|
||||
* On write, any unknown/unsupported property keys must be ignored.
|
||||
*
|
||||
* The following properties can be included in a Dataset list:
|
||||
*
|
||||
* SPINEL_PROP_DATASET_ACTIVE_TIMESTAMP
|
||||
* SPINEL_PROP_PHY_CHAN
|
||||
* SPINEL_PROP_PHY_CHAN_SUPPORTED (Channel Mask Page 0)
|
||||
* SPINEL_PROP_NET_MASTER_KEY
|
||||
* SPINEL_PROP_NET_NETWORK_NAME
|
||||
* SPINEL_PROP_NET_XPANID
|
||||
* SPINEL_PROP_MAC_15_4_PANID
|
||||
* SPINEL_PROP_IPV6_ML_PREFIX
|
||||
* SPINEL_PROP_NET_PSKC
|
||||
* SPINEL_PROP_DATASET_SECURITY_POLICY
|
||||
*
|
||||
*/
|
||||
SPINEL_PROP_THREAD_ACTIVE_DATASET = SPINEL_PROP_THREAD_EXT__BEGIN + 24,
|
||||
|
||||
/// Thread Pending Operational Dataset
|
||||
/** Format: `A(t(iD))` - Read-Write
|
||||
*
|
||||
* This property provide access to current locally stored Pending Operational Dataset.
|
||||
*
|
||||
* The formatting of this property follows the same rules as in SPINEL_PROP_THREAD_ACTIVE_DATASET.
|
||||
*
|
||||
* In addition supported properties in SPINEL_PROP_THREAD_ACTIVE_DATASET, the following properties can also
|
||||
* be included in the Pending Dataset:
|
||||
*
|
||||
* SPINEL_PROP_DATASET_PENDING_TIMESTAMP
|
||||
* SPINEL_PROP_DATASET_DELAY_TIMER
|
||||
*
|
||||
*/
|
||||
SPINEL_PROP_THREAD_PENDING_DATASET = SPINEL_PROP_THREAD_EXT__BEGIN + 25,
|
||||
|
||||
/// Thread Active Operational Dataset (MGMT send)
|
||||
/** Format: `A(t(iD))` - Write only
|
||||
*
|
||||
* The formatting of this property follows the same rules as in SPINEL_PROP_THREAD_ACTIVE_DATASET.
|
||||
*
|
||||
* This is write-only property. When written, it triggers a MGMT_ACTIVE_SET meshcop command to be sent to leader
|
||||
* with the given Dataset. The spinel frame response should be a `LAST_STATUS` with the status of the transmission
|
||||
* of MGMT_ACTIVE_SET command.
|
||||
*
|
||||
* In addition to supported properties in SPINEL_PROP_THREAD_ACTIVE_DATASET, the following property can be
|
||||
* included in the Dataset (to allow for custom raw TLVs):
|
||||
*
|
||||
* SPINEL_PROP_DATASET_RAW_TLVS
|
||||
*
|
||||
*/
|
||||
SPINEL_PROP_THREAD_MGMT_ACTIVE_DATASET
|
||||
= SPINEL_PROP_THREAD_EXT__BEGIN + 26,
|
||||
|
||||
/// Thread Pending Operational Dataset (MGMT send)
|
||||
/** Format: `A(t(iD))` - Write only
|
||||
*
|
||||
* This property is similar to SPINEL_PROP_THREAD_PENDING_DATASET and follows the same format and rules.
|
||||
*
|
||||
* In addition to supported properties in SPINEL_PROP_THREAD_PENDING_DATASET, the following property can be
|
||||
* included the Dataset (to allow for custom raw TLVs to be provided).
|
||||
*
|
||||
* SPINEL_PROP_DATASET_RAW_TLVS
|
||||
*
|
||||
*/
|
||||
SPINEL_PROP_THREAD_MGMT_PENDING_DATASET
|
||||
= SPINEL_PROP_THREAD_EXT__BEGIN + 27,
|
||||
|
||||
/// Operational Dataset Active Timestamp
|
||||
/** Format: `X` - No direct read or write
|
||||
*
|
||||
* It can only be included in one of the Dataset related properties below:
|
||||
*
|
||||
* SPINEL_PROP_THREAD_ACTIVE_DATASET
|
||||
* SPINEL_PROP_THREAD_PENDING_DATASET
|
||||
* SPINEL_PROP_THREAD_MGMT_ACTIVE_DATASET
|
||||
* SPINEL_PROP_THREAD_MGMT_PENDING_DATASET
|
||||
*
|
||||
*/
|
||||
SPINEL_PROP_DATASET_ACTIVE_TIMESTAMP
|
||||
= SPINEL_PROP_THREAD_EXT__BEGIN + 28,
|
||||
|
||||
/// Operational Dataset Pending Timestamp
|
||||
/** Format: `X` - No direct read or write
|
||||
*
|
||||
* It can only be included in one of the Pending Dataset properties:
|
||||
*
|
||||
* SPINEL_PROP_THREAD_PENDING_DATASET
|
||||
* SPINEL_PROP_THREAD_MGMT_PENDING_DATASET
|
||||
*
|
||||
*/
|
||||
SPINEL_PROP_DATASET_PENDING_TIMESTAMP
|
||||
= SPINEL_PROP_THREAD_EXT__BEGIN + 29,
|
||||
|
||||
/// Operational Dataset Delay Timer
|
||||
/** Format: `L` - No direct read or write
|
||||
*
|
||||
* Delay timer (in ms) specifies the time renaming until Thread devices overwrite the value in the Active
|
||||
* Operational Dataset with the corresponding values in the Pending Operational Dataset.
|
||||
*
|
||||
* It can only be included in one of the Pending Dataset properties:
|
||||
*
|
||||
* SPINEL_PROP_THREAD_PENDING_DATASET
|
||||
* SPINEL_PROP_THREAD_MGMT_PENDING_DATASET
|
||||
*
|
||||
*/
|
||||
SPINEL_PROP_DATASET_DELAY_TIMER = SPINEL_PROP_THREAD_EXT__BEGIN + 30,
|
||||
|
||||
/// Operational Dataset Security Policy
|
||||
/** Format: `SC` - No direct read or write
|
||||
*
|
||||
* It can only be included in one of the Dataset related properties below:
|
||||
*
|
||||
* SPINEL_PROP_THREAD_ACTIVE_DATASET
|
||||
* SPINEL_PROP_THREAD_PENDING_DATASET
|
||||
* SPINEL_PROP_THREAD_MGMT_ACTIVE_DATASET
|
||||
* SPINEL_PROP_THREAD_MGMT_PENDING_DATASET
|
||||
*
|
||||
* Content is
|
||||
* `S` : Key Rotation Time (in units of hour)
|
||||
* `C` : Security Policy Flags (as specified in Thread 1.1 Section 8.10.1.15)
|
||||
*
|
||||
*/
|
||||
SPINEL_PROP_DATASET_SECURITY_POLICY = SPINEL_PROP_THREAD_EXT__BEGIN + 31,
|
||||
|
||||
/// Operational Dataset Additional Raw TLVs
|
||||
/** Format: `D` - No direct read or write
|
||||
*
|
||||
* This property defines extra raw TLVs that can be added to an Operational DataSet.
|
||||
*
|
||||
* It can only be included in one of the following Dataset properties:
|
||||
*
|
||||
* SPINEL_PROP_THREAD_MGMT_ACTIVE_DATASET
|
||||
* SPINEL_PROP_THREAD_MGMT_PENDING_DATASET
|
||||
*
|
||||
*/
|
||||
SPINEL_PROP_DATASET_RAW_TLVS = SPINEL_PROP_THREAD_EXT__BEGIN + 32,
|
||||
SPINEL_PROP_THREAD_EXT__END = 0x1600,
|
||||
|
||||
SPINEL_PROP_IPV6__BEGIN = 0x60,
|
||||
|
||||
Reference in New Issue
Block a user