mirror of
https://github.com/espressif/openthread.git
synced 2026-08-13 22:27:47 +00:00
[ncp] add support for Joiner Discerner and getting list of joiners (#5137)
This commit adds/updates spinel properties to add Joiner Discerner support on joiner and commissioner side. It also adds support for getting the list of joiners on commissioner by implementing property get handler for spinel property `MESHCOP_COMMISSIONER_JOINERS`.
This commit is contained in:
committed by
Jonathan Hui
parent
c7dc2be7d2
commit
a7415b53a4
@@ -1891,6 +1891,10 @@ const char *spinel_prop_key_to_cstr(spinel_prop_key_t prop_key)
|
||||
ret = "MESHCOP_COMMISSIONER_SESSION_ID";
|
||||
break;
|
||||
|
||||
case SPINEL_PROP_MESHCOP_JOINER_DISCERNER:
|
||||
ret = "MESHCOP_JOINER_DISCERNER";
|
||||
break;
|
||||
|
||||
case SPINEL_PROP_MESHCOP_COMMISSIONER_ANNOUNCE_BEGIN:
|
||||
ret = "MESHCOP_COMMISSIONER_ANNOUNCE_BEGIN";
|
||||
break;
|
||||
|
||||
+38
-5
@@ -3112,15 +3112,22 @@ enum
|
||||
SPINEL_PROP_MESHCOP_COMMISSIONER_STATE = SPINEL_PROP_MESHCOP__BEGIN + 2,
|
||||
|
||||
// Thread Commissioner Joiners
|
||||
/** Format `A(t(E)UL)` - insert or remove only
|
||||
/** Format `A(t(t(E|CX)UL))` - get, insert or remove.
|
||||
*
|
||||
* Required capability: SPINEL_CAP_THREAD_COMMISSIONER
|
||||
*
|
||||
* Data per item is:
|
||||
* Data per array entry is:
|
||||
*
|
||||
* `t(E)` | `t()`: Joiner EUI64. Empty struct indicates any Joiner
|
||||
* `L` : Timeout (in seconds) after which the Joiner is automatically removed
|
||||
* `U` : PSKd
|
||||
* `t()` | `t(E)` | `t(CX)` : Joiner info struct (formatting varies).
|
||||
*
|
||||
* - `t()` or empty struct indicates any joiner.
|
||||
* - `t(E)` specifies the Joiner EUI-64.
|
||||
* - `t(CX) specifies Joiner Discerner, `C` is Discerner length (in bits), and `X` is Discerner value.
|
||||
*
|
||||
* The struct is followed by:
|
||||
*
|
||||
* `L` : Timeout after which to remove Joiner (when written should be in seconds, when read is in milliseconds)
|
||||
* `U` : PSKd
|
||||
*
|
||||
* For CMD_PROP_VALUE_REMOVE the timeout and PSKd are optional.
|
||||
*
|
||||
@@ -3143,6 +3150,32 @@ enum
|
||||
*/
|
||||
SPINEL_PROP_MESHCOP_COMMISSIONER_SESSION_ID = SPINEL_PROP_MESHCOP__BEGIN + 5,
|
||||
|
||||
/// Thread Joiner Discerner
|
||||
/** Format `CX` - Read-write
|
||||
*
|
||||
* Required capability: SPINEL_CAP_THREAD_JOINER
|
||||
*
|
||||
* This property represents a Joiner Discerner.
|
||||
*
|
||||
* The Joiner Discerner is used to calculate the Joiner ID used during commissioning/joining process.
|
||||
*
|
||||
* By default (when a discerner is not provided or cleared), Joiner ID is derived as first 64 bits of the result
|
||||
* of computing SHA-256 over factory-assigned IEEE EUI-64. Note that this is the main behavior expected by Thread
|
||||
* specification.
|
||||
*
|
||||
* Format:
|
||||
*
|
||||
* 'C' : The Joiner Discerner bit length (number of bits).
|
||||
* `X` : The Joiner Discerner value (64-bit unsigned) - Only present/applicable when length is non-zero.
|
||||
*
|
||||
* When writing to this property, the length can be set to zero to clear any previously set Joiner Discerner value.
|
||||
*
|
||||
* When reading this property if there is no currently set Joiner Discerner, zero is returned as the length (with
|
||||
* no value field).
|
||||
*
|
||||
*/
|
||||
SPINEL_PROP_MESHCOP_JOINER_DISCERNER = SPINEL_PROP_MESHCOP__BEGIN + 6,
|
||||
|
||||
SPINEL_PROP_MESHCOP__END = 0x90,
|
||||
|
||||
SPINEL_PROP_MESHCOP_EXT__BEGIN = 0x1800,
|
||||
|
||||
@@ -135,10 +135,14 @@ NcpBase::PropertyHandler NcpBase::FindGetPropertyHandler(spinel_prop_key_t aKey)
|
||||
#if OPENTHREAD_FTD
|
||||
#if OPENTHREAD_CONFIG_COMMISSIONER_ENABLE
|
||||
OT_NCP_GET_HANDLER_ENTRY(SPINEL_PROP_MESHCOP_COMMISSIONER_STATE),
|
||||
OT_NCP_GET_HANDLER_ENTRY(SPINEL_PROP_MESHCOP_COMMISSIONER_JOINERS),
|
||||
OT_NCP_GET_HANDLER_ENTRY(SPINEL_PROP_MESHCOP_COMMISSIONER_PROVISIONING_URL),
|
||||
OT_NCP_GET_HANDLER_ENTRY(SPINEL_PROP_MESHCOP_COMMISSIONER_SESSION_ID),
|
||||
#endif
|
||||
#endif // OPENTHREAD_FTD
|
||||
#if OPENTHREAD_CONFIG_JOINER_ENABLE
|
||||
OT_NCP_GET_HANDLER_ENTRY(SPINEL_PROP_MESHCOP_JOINER_DISCERNER),
|
||||
#endif
|
||||
#if OPENTHREAD_CONFIG_TMF_NETDATA_SERVICE_ENABLE
|
||||
OT_NCP_GET_HANDLER_ENTRY(SPINEL_PROP_SERVER_ALLOW_LOCAL_DATA_CHANGE),
|
||||
OT_NCP_GET_HANDLER_ENTRY(SPINEL_PROP_SERVER_SERVICES),
|
||||
@@ -404,6 +408,9 @@ NcpBase::PropertyHandler NcpBase::FindSetPropertyHandler(spinel_prop_key_t aKey)
|
||||
OT_NCP_SET_HANDLER_ENTRY(SPINEL_PROP_MESHCOP_COMMISSIONER_PROVISIONING_URL),
|
||||
#endif
|
||||
#endif // OPENTHREAD_FTD
|
||||
#if OPENTHREAD_CONFIG_JOINER_ENABLE
|
||||
OT_NCP_SET_HANDLER_ENTRY(SPINEL_PROP_MESHCOP_JOINER_DISCERNER),
|
||||
#endif
|
||||
#if OPENTHREAD_CONFIG_TMF_NETDATA_SERVICE_ENABLE
|
||||
OT_NCP_SET_HANDLER_ENTRY(SPINEL_PROP_SERVER_ALLOW_LOCAL_DATA_CHANGE),
|
||||
#endif
|
||||
|
||||
+87
-14
@@ -538,23 +538,72 @@ exit:
|
||||
return error;
|
||||
}
|
||||
|
||||
template <> otError NcpBase::HandlePropertyGet<SPINEL_PROP_MESHCOP_COMMISSIONER_JOINERS>(void)
|
||||
{
|
||||
otError error = OT_ERROR_NONE;
|
||||
uint16_t iter = 0;
|
||||
otJoinerInfo joinerInfo;
|
||||
|
||||
while (otCommissionerGetNextJoinerInfo(mInstance, &iter, &joinerInfo) == OT_ERROR_NONE)
|
||||
{
|
||||
SuccessOrExit(error = mEncoder.OpenStruct());
|
||||
|
||||
SuccessOrExit(error = mEncoder.OpenStruct()); // Joiner Id (any, EUI64 or a Joiner Discerner) struct
|
||||
|
||||
switch (joinerInfo.mType)
|
||||
{
|
||||
case OT_JOINER_INFO_TYPE_ANY:
|
||||
break;
|
||||
|
||||
case OT_JOINER_INFO_TYPE_EUI64:
|
||||
SuccessOrExit(error = mEncoder.WriteEui64(joinerInfo.mSharedId.mEui64));
|
||||
break;
|
||||
|
||||
case OT_JOINER_INFO_TYPE_DISCERNER:
|
||||
SuccessOrExit(error = mEncoder.WriteUint8(joinerInfo.mSharedId.mDiscerner.mLength));
|
||||
SuccessOrExit(error = mEncoder.WriteUint64(joinerInfo.mSharedId.mDiscerner.mValue));
|
||||
break;
|
||||
}
|
||||
|
||||
SuccessOrExit(error = mEncoder.CloseStruct());
|
||||
|
||||
SuccessOrExit(error = mEncoder.WriteUint32(joinerInfo.mExpirationTime));
|
||||
SuccessOrExit(error = mEncoder.WriteUtf8(joinerInfo.mPskd.m8));
|
||||
|
||||
SuccessOrExit(error = mEncoder.CloseStruct());
|
||||
}
|
||||
|
||||
exit:
|
||||
return error;
|
||||
}
|
||||
|
||||
template <> otError NcpBase::HandlePropertyInsert<SPINEL_PROP_MESHCOP_COMMISSIONER_JOINERS>(void)
|
||||
{
|
||||
otError error = OT_ERROR_NONE;
|
||||
otJoinerDiscerner discerner;
|
||||
bool withDiscerner = false;
|
||||
const otExtAddress *eui64;
|
||||
uint32_t timeout;
|
||||
const char * psk;
|
||||
|
||||
SuccessOrExit(error = mDecoder.OpenStruct());
|
||||
|
||||
if (!mDecoder.IsAllReadInStruct())
|
||||
switch (mDecoder.GetRemainingLengthInStruct())
|
||||
{
|
||||
SuccessOrExit(error = mDecoder.ReadEui64(eui64));
|
||||
}
|
||||
else
|
||||
{
|
||||
// Empty struct indicates any Joiner (no EUI64 is given so nullptr is used.).
|
||||
case 0:
|
||||
// Empty struct indicates any joiner
|
||||
eui64 = nullptr;
|
||||
break;
|
||||
|
||||
case sizeof(spinel_eui64_t):
|
||||
SuccessOrExit(error = mDecoder.ReadEui64(eui64));
|
||||
break;
|
||||
|
||||
default:
|
||||
SuccessOrExit(error = mDecoder.ReadUint8(discerner.mLength));
|
||||
SuccessOrExit(error = mDecoder.ReadUint64(discerner.mValue));
|
||||
withDiscerner = true;
|
||||
break;
|
||||
}
|
||||
|
||||
SuccessOrExit(error = mDecoder.CloseStruct());
|
||||
@@ -562,7 +611,14 @@ template <> otError NcpBase::HandlePropertyInsert<SPINEL_PROP_MESHCOP_COMMISSION
|
||||
SuccessOrExit(error = mDecoder.ReadUint32(timeout));
|
||||
SuccessOrExit(error = mDecoder.ReadUtf8(psk));
|
||||
|
||||
error = otCommissionerAddJoiner(mInstance, eui64, psk, timeout);
|
||||
if (withDiscerner)
|
||||
{
|
||||
error = otCommissionerAddJoinerWithDiscerner(mInstance, &discerner, psk, timeout);
|
||||
}
|
||||
else
|
||||
{
|
||||
error = otCommissionerAddJoiner(mInstance, eui64, psk, timeout);
|
||||
}
|
||||
|
||||
exit:
|
||||
return error;
|
||||
@@ -571,23 +627,40 @@ exit:
|
||||
template <> otError NcpBase::HandlePropertyRemove<SPINEL_PROP_MESHCOP_COMMISSIONER_JOINERS>(void)
|
||||
{
|
||||
otError error = OT_ERROR_NONE;
|
||||
otJoinerDiscerner discerner;
|
||||
bool withDiscerner = false;
|
||||
const otExtAddress *eui64;
|
||||
|
||||
SuccessOrExit(error = mDecoder.OpenStruct());
|
||||
|
||||
if (!mDecoder.IsAllReadInStruct())
|
||||
switch (mDecoder.GetRemainingLengthInStruct())
|
||||
{
|
||||
SuccessOrExit(error = mDecoder.ReadEui64(eui64));
|
||||
}
|
||||
else
|
||||
{
|
||||
// Empty struct indicates any Joiner (no EUI64 is given so nullptr is used.).
|
||||
case 0:
|
||||
// Empty struct indicates any joiner
|
||||
eui64 = nullptr;
|
||||
break;
|
||||
|
||||
case sizeof(spinel_eui64_t):
|
||||
SuccessOrExit(error = mDecoder.ReadEui64(eui64));
|
||||
break;
|
||||
|
||||
default:
|
||||
SuccessOrExit(error = mDecoder.ReadUint8(discerner.mLength));
|
||||
SuccessOrExit(error = mDecoder.ReadUint64(discerner.mValue));
|
||||
withDiscerner = true;
|
||||
break;
|
||||
}
|
||||
|
||||
SuccessOrExit(error = mDecoder.CloseStruct());
|
||||
|
||||
error = otCommissionerRemoveJoiner(mInstance, eui64);
|
||||
if (withDiscerner)
|
||||
{
|
||||
error = otCommissionerRemoveJoinerWithDiscerner(mInstance, &discerner);
|
||||
}
|
||||
else
|
||||
{
|
||||
error = otCommissionerRemoveJoiner(mInstance, eui64);
|
||||
}
|
||||
|
||||
exit:
|
||||
return error;
|
||||
|
||||
@@ -1532,7 +1532,47 @@ exit:
|
||||
return error;
|
||||
}
|
||||
|
||||
#endif
|
||||
template <> otError NcpBase::HandlePropertyGet<SPINEL_PROP_MESHCOP_JOINER_DISCERNER>(void)
|
||||
{
|
||||
otError error;
|
||||
const otJoinerDiscerner *discerner = otJoinerGetDiscerner(mInstance);
|
||||
|
||||
if (discerner == nullptr)
|
||||
{
|
||||
SuccessOrExit(error = mEncoder.WriteUint8(0));
|
||||
}
|
||||
else
|
||||
{
|
||||
SuccessOrExit(error = mEncoder.WriteUint8(discerner->mLength));
|
||||
SuccessOrExit(error = mEncoder.WriteUint64(discerner->mValue));
|
||||
}
|
||||
|
||||
exit:
|
||||
return error;
|
||||
}
|
||||
|
||||
template <> otError NcpBase::HandlePropertySet<SPINEL_PROP_MESHCOP_JOINER_DISCERNER>(void)
|
||||
{
|
||||
otError error = OT_ERROR_NONE;
|
||||
otJoinerDiscerner discerner;
|
||||
|
||||
SuccessOrExit(error = mDecoder.ReadUint8(discerner.mLength));
|
||||
|
||||
if (discerner.mLength == 0)
|
||||
{
|
||||
// Clearing any previously set Joiner Discerner
|
||||
error = otJoinerSetDiscerner(mInstance, nullptr);
|
||||
ExitNow();
|
||||
}
|
||||
|
||||
SuccessOrExit(error = mDecoder.ReadUint64(discerner.mValue));
|
||||
error = otJoinerSetDiscerner(mInstance, &discerner);
|
||||
|
||||
exit:
|
||||
return error;
|
||||
}
|
||||
|
||||
#endif // OPENTHREAD_CONFIG_JOINER_ENABLE
|
||||
|
||||
template <> otError NcpBase::HandlePropertyGet<SPINEL_PROP_IPV6_ML_PREFIX>(void)
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user