mirror of
https://github.com/espressif/openthread.git
synced 2026-09-11 11:40:06 +00:00
[spinel] add spinel property to send mgmt set dataset in TLVs format (#10587)
This commit adds a new spinel property `SPINEL_PROP_THREAD_MGMT_SET_PENDING_DATASET_TLVS` to do network migration operation on NCP. The existing property `SPINEL_PROP_THREAD_MGMT_SET_PENDING_DATASET` cannot be used for two reasons: 1. It uses a structured format instead of raw TLVs format. 2. The set handler of `SPINEL_PROP_THREAD_MGMT_SET_PENDING_DATASET` doesn't call `otDatasetSendMgmtPendingSet` with a callback. On NCP, we want to know the result of the MGMT_SET operation. (accepted, rejected or timeout) This new property works similarly as `SPINEL_PROP_NET_LEAVE_GRACEFULLY` added in https://github.com/openthread/openthread/pull/10337 1. Host sets the property to NCP. 2. NCP will give an immediate response on the result of `otDatasetSendMgmtPendingSet`. - If succeeded, NCP will respond an empty property `SPINEL_PROP_THREAD_MGMT_SET_PENDING_DATASET_TLVS` - If failed, NCP will respond a LAST_STATUS of the error info. 3. When the callback of `otDatasetSendMgmtPendingSet` is called, NCP will send a notification of `SPINEL_PROP_THREAD_MGMT_SET_PENDING_DATASET_TLVS` to the host to notify the result of the operation.
This commit is contained in:
@@ -1363,6 +1363,7 @@ const char *spinel_prop_key_to_cstr(spinel_prop_key_t prop_key)
|
||||
{SPINEL_PROP_THREAD_BACKBONE_ROUTER_LOCAL_REGISTER, "THREAD_BACKBONE_ROUTER_LOCAL_REGISTER"},
|
||||
{SPINEL_PROP_THREAD_BACKBONE_ROUTER_LOCAL_REGISTRATION_JITTER,
|
||||
"THREAD_BACKBONE_ROUTER_LOCAL_REGISTRATION_JITTER"},
|
||||
{SPINEL_PROP_THREAD_MGMT_SET_PENDING_DATASET_TLVS, "THREAD_MGMT_SET_PENDING_DATASET_TLVS"},
|
||||
{SPINEL_PROP_MESHCOP_JOINER_STATE, "MESHCOP_JOINER_STATE"},
|
||||
{SPINEL_PROP_MESHCOP_JOINER_COMMISSIONING, "MESHCOP_JOINER_COMMISSIONING"},
|
||||
{SPINEL_PROP_IPV6_LL_ADDR, "IPV6_LL_ADDR"},
|
||||
|
||||
@@ -3412,6 +3412,25 @@ enum
|
||||
*/
|
||||
SPINEL_PROP_THREAD_PENDING_DATASET_TLVS = SPINEL_PROP_THREAD_EXT__BEGIN + 61,
|
||||
|
||||
/// Send MGMT_SET Thread Pending Operational Dataset (in TLV format).
|
||||
/** Format: `D` - Write only
|
||||
*
|
||||
* This is write-only property. When written, it triggers a MGMT_PENDING_SET meshcop command to be sent to leader
|
||||
* with the given Dataset.
|
||||
*
|
||||
* When setting this property, the spinel frame response will be:
|
||||
* 1. A `LAST_STATUS` with the status of the transmission of MGMT_PENDING_SET command if it fails.
|
||||
* 2. A `SPINEL_PROP_THREAD_MGMT_SET_PENDING_DATASET_TLVS` with no content.
|
||||
*
|
||||
* On response reception or timeout, another notification will be sent to the host:
|
||||
* A `SPINEL_PROP_THREAD_MGMT_SET_PENDING_DATASET_TLVS` with a spinel_status_t indicating
|
||||
* the result of MGMT_SET_PENDING.
|
||||
*
|
||||
* On write, any unknown/unsupported TLVs must be ignored.
|
||||
*
|
||||
*/
|
||||
SPINEL_PROP_THREAD_MGMT_SET_PENDING_DATASET_TLVS = SPINEL_PROP_THREAD_EXT__BEGIN + 62,
|
||||
|
||||
SPINEL_PROP_THREAD_EXT__END = 0x1600,
|
||||
|
||||
SPINEL_PROP_IPV6__BEGIN = 0x60,
|
||||
|
||||
@@ -92,6 +92,7 @@ const ChangedPropsSet::Entry ChangedPropsSet::mSupportedProps[] = {
|
||||
{SPINEL_PROP_THREAD_NETWORK_TIME, SPINEL_STATUS_OK, false},
|
||||
#endif
|
||||
{SPINEL_PROP_PARENT_RESPONSE_INFO, SPINEL_STATUS_OK, true},
|
||||
{SPINEL_PROP_THREAD_MGMT_SET_PENDING_DATASET_TLVS, SPINEL_STATUS_OK, false},
|
||||
};
|
||||
|
||||
uint8_t ChangedPropsSet::GetNumEntries(void) const
|
||||
|
||||
@@ -315,6 +315,7 @@ NcpBase::NcpBase(Instance *aInstance)
|
||||
, mRxSpinelOutOfOrderTidCounter(0)
|
||||
, mTxSpinelFrameCounter(0)
|
||||
, mDidInitialUpdates(false)
|
||||
, mDatasetSendMgmtPendingSetResult(SPINEL_STATUS_OK)
|
||||
, mLogTimestampBase(0)
|
||||
#if OPENTHREAD_CONFIG_DIAG_ENABLE
|
||||
, mDiagOutput(nullptr)
|
||||
|
||||
@@ -624,6 +624,10 @@ protected:
|
||||
|
||||
void ThreadDetachGracefullyHandler(void);
|
||||
|
||||
static void DatasetSendMgmtPendingSetHandler(otError aResult, void *aContext);
|
||||
|
||||
void DatasetSendMgmtPendingSetHandler(otError aResult);
|
||||
|
||||
protected:
|
||||
static NcpBase *sNcpInstance;
|
||||
static spinel_status_t ThreadErrorToSpinelStatus(otError aError);
|
||||
@@ -738,6 +742,8 @@ protected:
|
||||
|
||||
bool mDidInitialUpdates;
|
||||
|
||||
spinel_status_t mDatasetSendMgmtPendingSetResult;
|
||||
|
||||
uint64_t mLogTimestampBase; // Timestamp base used for logging
|
||||
|
||||
#if OPENTHREAD_CONFIG_DIAG_ENABLE
|
||||
|
||||
@@ -336,6 +336,7 @@ NcpBase::PropertyHandler NcpBase::FindGetPropertyHandler(spinel_prop_key_t aKey)
|
||||
#endif
|
||||
OT_NCP_GET_HANDLER_ENTRY(SPINEL_PROP_THREAD_ACTIVE_DATASET_TLVS),
|
||||
OT_NCP_GET_HANDLER_ENTRY(SPINEL_PROP_THREAD_PENDING_DATASET_TLVS),
|
||||
OT_NCP_GET_HANDLER_ENTRY(SPINEL_PROP_THREAD_MGMT_SET_PENDING_DATASET_TLVS),
|
||||
#if OPENTHREAD_CONFIG_CHANNEL_MANAGER_ENABLE
|
||||
OT_NCP_GET_HANDLER_ENTRY(SPINEL_PROP_CHANNEL_MANAGER_NEW_CHANNEL),
|
||||
OT_NCP_GET_HANDLER_ENTRY(SPINEL_PROP_CHANNEL_MANAGER_DELAY),
|
||||
@@ -607,6 +608,7 @@ NcpBase::PropertyHandler NcpBase::FindSetPropertyHandler(spinel_prop_key_t aKey)
|
||||
#endif
|
||||
OT_NCP_SET_HANDLER_ENTRY(SPINEL_PROP_THREAD_ACTIVE_DATASET_TLVS),
|
||||
OT_NCP_SET_HANDLER_ENTRY(SPINEL_PROP_THREAD_PENDING_DATASET_TLVS),
|
||||
OT_NCP_SET_HANDLER_ENTRY(SPINEL_PROP_THREAD_MGMT_SET_PENDING_DATASET_TLVS),
|
||||
#if OPENTHREAD_CONFIG_COMMISSIONER_ENABLE
|
||||
OT_NCP_SET_HANDLER_ENTRY(SPINEL_PROP_MESHCOP_COMMISSIONER_ANNOUNCE_BEGIN),
|
||||
OT_NCP_SET_HANDLER_ENTRY(SPINEL_PROP_MESHCOP_COMMISSIONER_ENERGY_SCAN),
|
||||
|
||||
@@ -1739,6 +1739,42 @@ exit:
|
||||
return error;
|
||||
}
|
||||
|
||||
void NcpBase::DatasetSendMgmtPendingSetHandler(otError aResult, void *aContext)
|
||||
{
|
||||
static_cast<NcpBase *>(aContext)->DatasetSendMgmtPendingSetHandler(aResult);
|
||||
}
|
||||
|
||||
void NcpBase::DatasetSendMgmtPendingSetHandler(otError aResult)
|
||||
{
|
||||
mDatasetSendMgmtPendingSetResult = ThreadErrorToSpinelStatus(aResult);
|
||||
mChangedPropsSet.AddProperty(SPINEL_PROP_THREAD_MGMT_SET_PENDING_DATASET_TLVS);
|
||||
mUpdateChangedPropsTask.Post();
|
||||
}
|
||||
|
||||
template <> otError NcpBase::HandlePropertyGet<SPINEL_PROP_THREAD_MGMT_SET_PENDING_DATASET_TLVS>(void)
|
||||
{
|
||||
return mEncoder.WriteUint32(mDatasetSendMgmtPendingSetResult);
|
||||
}
|
||||
|
||||
template <> otError NcpBase::HandlePropertySet<SPINEL_PROP_THREAD_MGMT_SET_PENDING_DATASET_TLVS>(void)
|
||||
{
|
||||
otError error = OT_ERROR_NONE;
|
||||
otOperationalDataset emptyDataset;
|
||||
const uint8_t *data;
|
||||
uint16_t len;
|
||||
|
||||
memset(&emptyDataset, 0, sizeof(emptyDataset));
|
||||
|
||||
SuccessOrExit(error = mDecoder.ReadData(data, len));
|
||||
VerifyOrExit(len < OT_OPERATIONAL_DATASET_MAX_LENGTH, error = OT_ERROR_PARSE);
|
||||
|
||||
error = otDatasetSendMgmtPendingSet(mInstance, &emptyDataset, data, static_cast<uint8_t>(len),
|
||||
DatasetSendMgmtPendingSetHandler, this);
|
||||
|
||||
exit:
|
||||
return error;
|
||||
}
|
||||
|
||||
template <> otError NcpBase::HandlePropertySet<SPINEL_PROP_THREAD_MGMT_GET_ACTIVE_DATASET>(void)
|
||||
{
|
||||
otError error = OT_ERROR_NONE;
|
||||
|
||||
Reference in New Issue
Block a user