mirror of
https://github.com/espressif/openthread.git
synced 2026-07-28 22:57:47 +00:00
[spinel] add missing Link Metrics Subject functionality (#7118)
This commit adds the missing Link Metrics configuration of Enh-ACK probing in RCP.
This commit is contained in:
@@ -675,6 +675,32 @@ public:
|
||||
*/
|
||||
otError GetRadioRegion(uint16_t *aRegionCode);
|
||||
|
||||
#if OPENTHREAD_CONFIG_MLE_LINK_METRICS_SUBJECT_ENABLE
|
||||
/**
|
||||
* Enable/disable or update Enhanced-ACK Based Probing in radio for a specific Initiator.
|
||||
*
|
||||
* After Enhanced-ACK Based Probing is configured by a specific Probing Initiator, the Enhanced-ACK sent to that
|
||||
* node should include Vendor-Specific IE containing Link Metrics data. This method informs the radio to start/stop
|
||||
* to collect Link Metrics data and include Vendor-Specific IE that containing the data in Enhanced-ACK sent to that
|
||||
* Probing Initiator.
|
||||
*
|
||||
* @param[in] aLinkMetrics This parameter specifies what metrics to query. Per spec 4.11.3.4.4.6, at most 2
|
||||
* metrics can be specified. The probing would be disabled if @p aLinkMetrics is
|
||||
* bitwise 0.
|
||||
* @param[in] aShortAddress The short address of the Probing Initiator.
|
||||
* @param[in] aExtAddress The extended source address of the Probing Initiator. @p aExtAddress MUST NOT be
|
||||
* nullptr.
|
||||
*
|
||||
* @retval OT_ERROR_NONE Successfully configured the Enhanced-ACK Based Probing.
|
||||
* @retval OT_ERROR_INVALID_ARGS @p aExtAddress is nullptr.
|
||||
* @retval OT_ERROR_NOT_FOUND The Initiator indicated by @p aShortAddress is not found when trying to clear.
|
||||
* @retval OT_ERROR_NO_BUFS No more Initiator can be supported.
|
||||
*/
|
||||
otError ConfigureEnhAckProbing(otLinkMetrics aLinkMetrics,
|
||||
const otShortAddress aShortAddress,
|
||||
const otExtAddress & aExtAddress);
|
||||
#endif
|
||||
|
||||
/**
|
||||
* This method checks whether the spinel interface is radio-only.
|
||||
*
|
||||
|
||||
@@ -2406,5 +2406,41 @@ exit:
|
||||
return error;
|
||||
}
|
||||
|
||||
#if OPENTHREAD_CONFIG_MLE_LINK_METRICS_SUBJECT_ENABLE
|
||||
template <typename InterfaceType, typename ProcessContextType>
|
||||
otError RadioSpinel<InterfaceType, ProcessContextType>::ConfigureEnhAckProbing(otLinkMetrics aLinkMetrics,
|
||||
const otShortAddress aShortAddress,
|
||||
const otExtAddress & aExtAddress)
|
||||
{
|
||||
otError error = OT_ERROR_NONE;
|
||||
uint8_t flags = 0;
|
||||
|
||||
if (aLinkMetrics.mPduCount)
|
||||
{
|
||||
flags |= SPINEL_THREAD_LINK_METRIC_PDU_COUNT;
|
||||
}
|
||||
|
||||
if (aLinkMetrics.mLqi)
|
||||
{
|
||||
flags |= SPINEL_THREAD_LINK_METRIC_LQI;
|
||||
}
|
||||
|
||||
if (aLinkMetrics.mLinkMargin)
|
||||
{
|
||||
flags |= SPINEL_THREAD_LINK_METRIC_LINK_MARGIN;
|
||||
}
|
||||
|
||||
if (aLinkMetrics.mRssi)
|
||||
{
|
||||
flags |= SPINEL_THREAD_LINK_METRIC_RSSI;
|
||||
}
|
||||
|
||||
error = Set(SPINEL_PROP_RCP_ENH_ACK_PROBING, SPINEL_DATATYPE_UINT16_S, SPINEL_DATATYPE_EUI64_S,
|
||||
SPINEL_DATATYPE_UINT8_S, aShortAddress, aExtAddress.m8, flags);
|
||||
|
||||
return error;
|
||||
}
|
||||
#endif
|
||||
|
||||
} // namespace Spinel
|
||||
} // namespace ot
|
||||
|
||||
@@ -1400,6 +1400,7 @@ const char *spinel_prop_key_to_cstr(spinel_prop_key_t prop_key)
|
||||
{SPINEL_PROP_CHILD_SUPERVISION_INTERVAL, "CHILD_SUPERVISION_INTERVAL"},
|
||||
{SPINEL_PROP_CHILD_SUPERVISION_CHECK_TIMEOUT, "CHILD_SUPERVISION_CHECK_TIMEOUT"},
|
||||
{SPINEL_PROP_RCP_VERSION, "RCP_VERSION"},
|
||||
{SPINEL_PROP_RCP_ENH_ACK_PROBING, "ENH_ACK_PROBING"},
|
||||
{SPINEL_PROP_PARENT_RESPONSE_INFO, "PARENT_RESPONSE_INFO"},
|
||||
{SPINEL_PROP_SLAAC_ENABLED, "SLAAC_ENABLED"},
|
||||
{SPINEL_PROP_SUPPORTED_RADIO_LINKS, "SUPPORTED_RADIO_LINKS"},
|
||||
|
||||
+23
-1
@@ -377,7 +377,7 @@
|
||||
* Please see section "Spinel definition compatibility guideline" for more details.
|
||||
*
|
||||
*/
|
||||
#define SPINEL_RCP_API_VERSION 4
|
||||
#define SPINEL_RCP_API_VERSION 5
|
||||
|
||||
/**
|
||||
* @def SPINEL_MIN_HOST_SUPPORTED_RCP_API_VERSION
|
||||
@@ -752,6 +752,7 @@ enum
|
||||
// @ref SPINEL_PROP_THREAD_LINK_METRICS_QUERY_RESULT
|
||||
// @ref SPINEL_PROP_THREAD_LINK_METRICS_MGMT_ENH_ACK
|
||||
// @ref SPINEL_PROP_THREAD_LINK_METRICS_MGMT_FORWARD
|
||||
// @ref SPINEL_PROP_RCP_ENH_ACK_PROBING
|
||||
enum
|
||||
{
|
||||
SPINEL_THREAD_LINK_METRIC_PDU_COUNT = (1 << 0),
|
||||
@@ -4709,6 +4710,27 @@ enum
|
||||
*/
|
||||
SPINEL_PROP_RCP_TIMESTAMP = SPINEL_PROP_RCP_EXT__BEGIN + 2,
|
||||
|
||||
/// Configure Enhanced ACK probing
|
||||
/** Format: `SEC` (Write-only).
|
||||
*
|
||||
* `S`: Short address
|
||||
* `E`: Extended address
|
||||
* `C`: List of requested metric ids encoded as bit fields in single byte
|
||||
*
|
||||
* +---------------+----+
|
||||
* | Metric | Id |
|
||||
* +---------------+----+
|
||||
* | Received PDUs | 0 |
|
||||
* | LQI | 1 |
|
||||
* | Link margin | 2 |
|
||||
* | RSSI | 3 |
|
||||
* +---------------+----+
|
||||
*
|
||||
* Enable/disable or update Enhanced-ACK Based Probing in radio for a specific Initiator.
|
||||
*
|
||||
*/
|
||||
SPINEL_PROP_RCP_ENH_ACK_PROBING = SPINEL_PROP_RCP_EXT__BEGIN + 3,
|
||||
|
||||
SPINEL_PROP_RCP_EXT__END = 0x900,
|
||||
|
||||
SPINEL_PROP_NEST__BEGIN = 0x3BC0,
|
||||
|
||||
@@ -2541,6 +2541,40 @@ exit:
|
||||
}
|
||||
#endif
|
||||
|
||||
#if OPENTHREAD_CONFIG_MLE_LINK_METRICS_INITIATOR_ENABLE || OPENTHREAD_CONFIG_MLE_LINK_METRICS_SUBJECT_ENABLE
|
||||
otError NcpBase::DecodeLinkMetrics(otLinkMetrics *aMetrics, bool aAllowPduCount)
|
||||
{
|
||||
otError error = OT_ERROR_NONE;
|
||||
uint8_t metrics = 0;
|
||||
|
||||
SuccessOrExit(error = mDecoder.ReadUint8(metrics));
|
||||
|
||||
if (metrics & SPINEL_THREAD_LINK_METRIC_PDU_COUNT)
|
||||
{
|
||||
VerifyOrExit(aAllowPduCount, error = OT_ERROR_INVALID_ARGS);
|
||||
aMetrics->mPduCount = true;
|
||||
}
|
||||
|
||||
if (metrics & SPINEL_THREAD_LINK_METRIC_LQI)
|
||||
{
|
||||
aMetrics->mLqi = true;
|
||||
}
|
||||
|
||||
if (metrics & SPINEL_THREAD_LINK_METRIC_LINK_MARGIN)
|
||||
{
|
||||
aMetrics->mLinkMargin = true;
|
||||
}
|
||||
|
||||
if (metrics & SPINEL_THREAD_LINK_METRIC_RSSI)
|
||||
{
|
||||
aMetrics->mRssi = true;
|
||||
}
|
||||
|
||||
exit:
|
||||
return error;
|
||||
}
|
||||
#endif
|
||||
|
||||
} // namespace Ncp
|
||||
} // namespace ot
|
||||
|
||||
|
||||
@@ -389,8 +389,6 @@ protected:
|
||||
#endif
|
||||
|
||||
#if OPENTHREAD_CONFIG_MLE_LINK_METRICS_INITIATOR_ENABLE
|
||||
otError DecodeLinkMetrics(otLinkMetrics *aMetrics, bool aAllowPduCount);
|
||||
|
||||
otError EncodeLinkMetricsValues(const otLinkMetricsValues *aMetricsValues);
|
||||
#endif
|
||||
|
||||
@@ -404,6 +402,10 @@ protected:
|
||||
#endif // OPENTHREAD_CONFIG_UDP_FORWARD_ENABLE
|
||||
#endif // OPENTHREAD_MTD || OPENTHREAD_FTD
|
||||
|
||||
#if OPENTHREAD_CONFIG_MLE_LINK_METRICS_INITIATOR_ENABLE || OPENTHREAD_CONFIG_MLE_LINK_METRICS_SUBJECT_ENABLE
|
||||
otError DecodeLinkMetrics(otLinkMetrics *aMetrics, bool aAllowPduCount);
|
||||
#endif
|
||||
|
||||
otError CommandHandler_NOOP(uint8_t aHeader);
|
||||
otError CommandHandler_RESET(uint8_t aHeader);
|
||||
// Combined command handler for `VALUE_GET`, `VALUE_SET`, `VALUE_INSERT` and `VALUE_REMOVE`.
|
||||
|
||||
@@ -479,7 +479,10 @@ NcpBase::PropertyHandler NcpBase::FindSetPropertyHandler(spinel_prop_key_t aKey)
|
||||
#if OPENTHREAD_RADIO || OPENTHREAD_CONFIG_LINK_RAW_ENABLE
|
||||
OT_NCP_SET_HANDLER_ENTRY(SPINEL_PROP_RCP_MAC_KEY),
|
||||
OT_NCP_SET_HANDLER_ENTRY(SPINEL_PROP_RCP_MAC_FRAME_COUNTER),
|
||||
#if OPENTHREAD_CONFIG_MLE_LINK_METRICS_SUBJECT_ENABLE
|
||||
OT_NCP_SET_HANDLER_ENTRY(SPINEL_PROP_RCP_ENH_ACK_PROBING),
|
||||
#endif
|
||||
#endif // OPENTHREAD_RADIO || OPENTHREAD_CONFIG_LINK_RAW_ENABLE
|
||||
#if OPENTHREAD_MTD || OPENTHREAD_FTD
|
||||
OT_NCP_SET_HANDLER_ENTRY(SPINEL_PROP_UNSOL_UPDATE_FILTER),
|
||||
#if OPENTHREAD_CONFIG_JAM_DETECTION_ENABLE
|
||||
|
||||
@@ -215,38 +215,6 @@ exit:
|
||||
}
|
||||
|
||||
#if OPENTHREAD_CONFIG_MLE_LINK_METRICS_INITIATOR_ENABLE
|
||||
otError NcpBase::DecodeLinkMetrics(otLinkMetrics *aMetrics, bool aAllowPduCount)
|
||||
{
|
||||
otError error = OT_ERROR_NONE;
|
||||
uint8_t metrics = 0;
|
||||
|
||||
SuccessOrExit(error = mDecoder.ReadUint8(metrics));
|
||||
|
||||
if (metrics & SPINEL_THREAD_LINK_METRIC_PDU_COUNT)
|
||||
{
|
||||
VerifyOrExit(aAllowPduCount, error = OT_ERROR_INVALID_ARGS);
|
||||
aMetrics->mPduCount = true;
|
||||
}
|
||||
|
||||
if (metrics & SPINEL_THREAD_LINK_METRIC_LQI)
|
||||
{
|
||||
aMetrics->mLqi = true;
|
||||
}
|
||||
|
||||
if (metrics & SPINEL_THREAD_LINK_METRIC_LINK_MARGIN)
|
||||
{
|
||||
aMetrics->mLinkMargin = true;
|
||||
}
|
||||
|
||||
if (metrics & SPINEL_THREAD_LINK_METRIC_RSSI)
|
||||
{
|
||||
aMetrics->mRssi = true;
|
||||
}
|
||||
|
||||
exit:
|
||||
return error;
|
||||
}
|
||||
|
||||
otError NcpBase::EncodeLinkMetricsValues(const otLinkMetricsValues *aMetricsValues)
|
||||
{
|
||||
otError error = OT_ERROR_NONE;
|
||||
@@ -3155,7 +3123,7 @@ template <> otError NcpBase::HandlePropertySet<SPINEL_PROP_THREAD_LINK_METRICS_Q
|
||||
|
||||
SuccessOrExit(error = mDecoder.ReadIp6Address(address));
|
||||
SuccessOrExit(error = mDecoder.ReadUint8(seriesId));
|
||||
SuccessOrExit(error = DecodeLinkMetrics(&linkMetrics, true));
|
||||
SuccessOrExit(error = DecodeLinkMetrics(&linkMetrics, /* aAllowPduCount */ true));
|
||||
|
||||
error =
|
||||
otLinkMetricsQuery(mInstance, &address, seriesId, &linkMetrics, &NcpBase::HandleLinkMetricsReport_Jump, this);
|
||||
@@ -3190,7 +3158,7 @@ template <> otError NcpBase::HandlePropertySet<SPINEL_PROP_THREAD_LINK_METRICS_M
|
||||
|
||||
SuccessOrExit(error = mDecoder.ReadIp6Address(address));
|
||||
SuccessOrExit(error = mDecoder.ReadUint8(controlFlags));
|
||||
SuccessOrExit(error = DecodeLinkMetrics(&linkMetrics, false));
|
||||
SuccessOrExit(error = DecodeLinkMetrics(&linkMetrics, /* aAllowPduCount */ false));
|
||||
|
||||
error = otLinkMetricsConfigEnhAckProbing(mInstance, &address, static_cast<otLinkMetricsEnhAckFlags>(controlFlags),
|
||||
controlFlags ? &linkMetrics : nullptr,
|
||||
@@ -3214,7 +3182,7 @@ template <> otError NcpBase::HandlePropertySet<SPINEL_PROP_THREAD_LINK_METRICS_M
|
||||
SuccessOrExit(error = mDecoder.ReadUint8(seriesId));
|
||||
SuccessOrExit(error = mDecoder.ReadUint8(types));
|
||||
|
||||
SuccessOrExit(error = DecodeLinkMetrics(&linkMetrics, true));
|
||||
SuccessOrExit(error = DecodeLinkMetrics(&linkMetrics, /* aAllowPduCount */ true));
|
||||
|
||||
if (types & SPINEL_THREAD_FRAME_TYPE_MLE_LINK_PROBE)
|
||||
{
|
||||
|
||||
@@ -512,6 +512,25 @@ exit:
|
||||
return error;
|
||||
}
|
||||
|
||||
#if OPENTHREAD_CONFIG_MLE_LINK_METRICS_SUBJECT_ENABLE
|
||||
template <> otError NcpBase::HandlePropertySet<SPINEL_PROP_RCP_ENH_ACK_PROBING>(void)
|
||||
{
|
||||
otError error = OT_ERROR_NONE;
|
||||
uint16_t shortAddress;
|
||||
const otExtAddress *extAddress;
|
||||
otLinkMetrics linkMetrics = {};
|
||||
|
||||
SuccessOrExit(error = mDecoder.ReadUint16(shortAddress));
|
||||
SuccessOrExit(error = mDecoder.ReadEui64(extAddress));
|
||||
SuccessOrExit(error = DecodeLinkMetrics(&linkMetrics, /* aAllowPduCount */ true));
|
||||
|
||||
error = otPlatRadioConfigureEnhAckProbing(mInstance, linkMetrics, shortAddress, extAddress);
|
||||
|
||||
exit:
|
||||
return error;
|
||||
}
|
||||
#endif
|
||||
|
||||
} // namespace Ncp
|
||||
} // namespace ot
|
||||
|
||||
|
||||
@@ -619,6 +619,18 @@ otError otPlatRadioGetRegion(otInstance *aInstance, uint16_t *aRegionCode)
|
||||
return sRadioSpinel.GetRadioRegion(aRegionCode);
|
||||
}
|
||||
|
||||
#if OPENTHREAD_CONFIG_MLE_LINK_METRICS_SUBJECT_ENABLE
|
||||
otError otPlatRadioConfigureEnhAckProbing(otInstance * aInstance,
|
||||
otLinkMetrics aLinkMetrics,
|
||||
const otShortAddress aShortAddress,
|
||||
const otExtAddress * aExtAddress)
|
||||
{
|
||||
OT_UNUSED_VARIABLE(aInstance);
|
||||
|
||||
return sRadioSpinel.ConfigureEnhAckProbing(aLinkMetrics, aShortAddress, *aExtAddress);
|
||||
}
|
||||
#endif
|
||||
|
||||
otError otPlatRadioReceiveAt(otInstance *aInstance, uint8_t aChannel, uint32_t aStart, uint32_t aDuration)
|
||||
{
|
||||
OT_UNUSED_VARIABLE(aInstance);
|
||||
|
||||
Reference in New Issue
Block a user