mirror of
https://github.com/espressif/openthread.git
synced 2026-10-07 16:27:35 +00:00
[ncp] add support for SRP client in NCP and spinel (#6062)
This commit adds new spinel definitions for SRP client support (mirroring the public OT APIs of SRP client) and implements get, set, add, and remove handlers in `Ncp` for the new spinel properties.
This commit is contained in:
@@ -2003,6 +2003,46 @@ const char *spinel_prop_key_to_cstr(spinel_prop_key_t prop_key)
|
||||
ret = "NEIGHBOR_TABLE_MULTI_RADIO_INFO";
|
||||
break;
|
||||
|
||||
case SPINEL_PROP_SRP_CLIENT_START:
|
||||
ret = "SRP_CLIENT_START";
|
||||
break;
|
||||
|
||||
case SPINEL_PROP_SRP_CLIENT_LEASE_INTERVAL:
|
||||
ret = "SRP_CLIENT_LEASE_INTERVAL";
|
||||
break;
|
||||
|
||||
case SPINEL_PROP_SRP_CLIENT_KEY_LEASE_INTERVAL:
|
||||
ret = "SRP_CLIENT_KEY_LEASE_INTERVAL";
|
||||
break;
|
||||
|
||||
case SPINEL_PROP_SRP_CLIENT_HOST_INFO:
|
||||
ret = "SRP_CLIENT_HOST_INFO";
|
||||
break;
|
||||
|
||||
case SPINEL_PROP_SRP_CLIENT_HOST_NAME:
|
||||
ret = "SRP_CLIENT_HOST_NAME";
|
||||
break;
|
||||
|
||||
case SPINEL_PROP_SRP_CLIENT_HOST_ADDRESSES:
|
||||
ret = "SRP_CLIENT_HOST_ADDRESSES";
|
||||
break;
|
||||
|
||||
case SPINEL_PROP_SRP_CLIENT_SERVICES:
|
||||
ret = "SRP_CLIENT_SERVICES";
|
||||
break;
|
||||
|
||||
case SPINEL_PROP_SRP_CLIENT_HOST_SERVICES_REMOVE:
|
||||
ret = "SRP_CLIENT_HOST_SERVICES_REMOVE";
|
||||
break;
|
||||
|
||||
case SPINEL_PROP_SRP_CLIENT_HOST_SERVICES_CLEAR:
|
||||
ret = "SRP_CLIENT_HOST_SERVICES_CLEAR";
|
||||
break;
|
||||
|
||||
case SPINEL_PROP_SRP_CLIENT_EVENT:
|
||||
ret = "SRP_CLIENT_EVENT";
|
||||
break;
|
||||
|
||||
case SPINEL_PROP_SERVER_ALLOW_LOCAL_DATA_CHANGE:
|
||||
ret = "SERVER_ALLOW_LOCAL_DATA_CHANGE";
|
||||
break;
|
||||
@@ -2695,6 +2735,10 @@ const char *spinel_capability_to_cstr(spinel_capability_t capability)
|
||||
ret = "MULTI_RADIO";
|
||||
break;
|
||||
|
||||
case SPINEL_CAP_SRP_CLIENT:
|
||||
ret = "SRP_CLIENT";
|
||||
break;
|
||||
|
||||
case SPINEL_CAP_ERROR_RATE_TRACKING:
|
||||
ret = "ERROR_RATE_TRACKING";
|
||||
break;
|
||||
|
||||
@@ -718,6 +718,32 @@ enum
|
||||
SPINEL_RADIO_LINK_TREL_UDP6 = 1,
|
||||
};
|
||||
|
||||
typedef enum
|
||||
{
|
||||
SPINEL_SRP_CLIENT_ITEM_STATE_TO_ADD = 0, // Item to be added/registered.
|
||||
SPINEL_SRP_CLIENT_ITEM_STATE_ADDING = 1, // Item is being added/registered.
|
||||
SPINEL_SRP_CLIENT_ITEM_STATE_TO_REFRESH = 2, // Item to be refreshed (re-register to renew lease).
|
||||
SPINEL_SRP_CLIENT_ITEM_STATE_REFRESHING = 3, // Item is being refreshed.
|
||||
SPINEL_SRP_CLIENT_ITEM_STATE_TO_REMOVE = 4, // Item to be removed.
|
||||
SPINEL_SRP_CLIENT_ITEM_STATE_REMOVING = 5, // Item is being removed.
|
||||
SPINEL_SRP_CLIENT_ITEM_STATE_REGISTERED = 6, // Item is registered with server.
|
||||
SPINEL_SRP_CLIENT_ITEM_STATE_REMOVED = 7, // Item is removed.
|
||||
} spinel_srp_client_item_state_t;
|
||||
|
||||
typedef enum
|
||||
{
|
||||
SPINEL_SRP_CLIENT_ERROR_NONE = 0, // No error.
|
||||
SPINEL_SRP_CLIENT_ERROR_PARSE = 1, // Server unable to interpret due to format error.
|
||||
SPINEL_SRP_CLIENT_ERROR_FAILED = 2, // Server encountered an internal failure.
|
||||
SPINEL_SRP_CLIENT_ERROR_NOT_FOUND = 3, // Name that ought to exist, does not exists.
|
||||
SPINEL_SRP_CLIENT_ERROR_NOT_IMPLEMENTED = 4, // Server does not support the query type.
|
||||
SPINEL_SRP_CLIENT_ERROR_SECURITY = 5, // Service is not authoritative for zone.
|
||||
SPINEL_SRP_CLIENT_ERROR_DUPLICATED = 6, // Some name that ought not to exist, does exist.
|
||||
SPINEL_SRP_CLIENT_ERROR_RESPONSE_TIMEOUT = 7, // Timed out waiting for response from server (client would retry).
|
||||
SPINEL_SRP_CLIENT_ERROR_INVALID_ARGS = 8, // Invalid args (e.g., bad service name or TXT-DATA).
|
||||
SPINEL_SRP_CLIENT_ERROR_NO_BUFS = 9, // No buffer to send the SRP update message.
|
||||
} spinel_srp_client_error_t;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
uint8_t bytes[8];
|
||||
@@ -1153,6 +1179,7 @@ enum
|
||||
SPINEL_CAP_RADIO_COEX = (SPINEL_CAP_OPENTHREAD__BEGIN + 11),
|
||||
SPINEL_CAP_MAC_RETRY_HISTOGRAM = (SPINEL_CAP_OPENTHREAD__BEGIN + 12),
|
||||
SPINEL_CAP_MULTI_RADIO = (SPINEL_CAP_OPENTHREAD__BEGIN + 13),
|
||||
SPINEL_CAP_SRP_CLIENT = (SPINEL_CAP_OPENTHREAD__BEGIN + 14),
|
||||
SPINEL_CAP_OPENTHREAD__END = 640,
|
||||
|
||||
SPINEL_CAP_THREAD__BEGIN = 1024,
|
||||
@@ -3637,6 +3664,143 @@ enum
|
||||
*/
|
||||
SPINEL_PROP_NEIGHBOR_TABLE_MULTI_RADIO_INFO = SPINEL_PROP_OPENTHREAD__BEGIN + 16,
|
||||
|
||||
/// SRP Client Start
|
||||
/** Format: `b(6Sb)` - Write only
|
||||
* Required capability: `SPINEL_CAP_SRP_CLIENT`.
|
||||
*
|
||||
* Writing to this property allows user to start or stop the SRP client operation with a given SRP server.
|
||||
*
|
||||
* Written value format is:
|
||||
*
|
||||
* `b` : TRUE to start the client, FALSE to stop the client.
|
||||
*
|
||||
* When used to start the SRP client, the following fields should also be included:
|
||||
*
|
||||
* `6` : SRP server IPv6 address.
|
||||
* `U` : SRP server port number.
|
||||
* `b` : Boolean to indicate whether or not to emit SRP client events (using `SPINEL_PROP_SRP_CLIENT_EVENT`).
|
||||
*
|
||||
*/
|
||||
SPINEL_PROP_SRP_CLIENT_START = SPINEL_PROP_OPENTHREAD__BEGIN + 17,
|
||||
|
||||
/// SRP Client Lease Interval
|
||||
/** Format: `L` - Read/Write
|
||||
* Required capability: `SPINEL_CAP_SRP_CLIENT`.
|
||||
*
|
||||
* The lease interval used in SRP update requests (in seconds).
|
||||
*
|
||||
*/
|
||||
SPINEL_PROP_SRP_CLIENT_LEASE_INTERVAL = SPINEL_PROP_OPENTHREAD__BEGIN + 18,
|
||||
|
||||
/// SRP Client Key Lease Interval
|
||||
/** Format: `L` - Read/Write
|
||||
* Required capability: `SPINEL_CAP_SRP_CLIENT`.
|
||||
*
|
||||
* The key lease interval used in SRP update requests (in seconds).
|
||||
*
|
||||
*/
|
||||
SPINEL_PROP_SRP_CLIENT_KEY_LEASE_INTERVAL = SPINEL_PROP_OPENTHREAD__BEGIN + 19,
|
||||
|
||||
/// SRP Client Host Info
|
||||
/** Format: `UCt(A(6))` - Read only
|
||||
* Required capability: `SPINEL_CAP_SRP_CLIENT`.
|
||||
*
|
||||
* Format is:
|
||||
*
|
||||
* `U` : The host name.
|
||||
* `C` : The host state (values from `spinel_srp_client_item_state_t`).
|
||||
* `t(A(6))` : Structure containing array of host IPv6 addresses.
|
||||
*
|
||||
*/
|
||||
SPINEL_PROP_SRP_CLIENT_HOST_INFO = SPINEL_PROP_OPENTHREAD__BEGIN + 20,
|
||||
|
||||
/// SRP Client Host Name (label).
|
||||
/** Format: `U` - Read/Write
|
||||
* Required capability: `SPINEL_CAP_SRP_CLIENT`.
|
||||
*
|
||||
*/
|
||||
SPINEL_PROP_SRP_CLIENT_HOST_NAME = SPINEL_PROP_OPENTHREAD__BEGIN + 21,
|
||||
|
||||
/// SRP Client Host Addresses
|
||||
/** Format: `A(6)` - Read/Write
|
||||
* Required capability: `SPINEL_CAP_SRP_CLIENT`.
|
||||
*
|
||||
*/
|
||||
SPINEL_PROP_SRP_CLIENT_HOST_ADDRESSES = SPINEL_PROP_OPENTHREAD__BEGIN + 22,
|
||||
|
||||
/// SRP Client Services
|
||||
/** Format: `A(t(UUSSSd))` - Read/Insert/Remove
|
||||
* Required capability: `SPINEL_CAP_SRP_CLIENT`.
|
||||
*
|
||||
* This property provide a list/array of services. Data per item is
|
||||
*
|
||||
* `U` : The service name labels (e.g., "_chip._udp", not the full domain name.
|
||||
* `U` : The service instance name label (not the full name).
|
||||
* `S` : The service port number.
|
||||
* `S` : The service priority.
|
||||
* `S` : The service weight.
|
||||
*
|
||||
* During remove operation, only service name and service instance name would be used.
|
||||
*
|
||||
*/
|
||||
SPINEL_PROP_SRP_CLIENT_SERVICES = SPINEL_PROP_OPENTHREAD__BEGIN + 23,
|
||||
|
||||
/// SRP Client Host And Services Remove
|
||||
/** Format: `b` : Write only
|
||||
* Required capability: `SPINEL_CAP_SRP_CLIENT`.
|
||||
*
|
||||
* Writing to this property starts the remove process of the host info and all services.
|
||||
* Please see `otSrpClientRemoveHostAndServices()` for more details.
|
||||
*
|
||||
* Format is:
|
||||
*
|
||||
* `b` : A boolean indicating whether or not the host key lease should also be removed.
|
||||
*
|
||||
*/
|
||||
SPINEL_PROP_SRP_CLIENT_HOST_SERVICES_REMOVE = SPINEL_PROP_OPENTHREAD__BEGIN + 24,
|
||||
|
||||
/// SRP Client Host And Services Clear
|
||||
/** Format: Empty : Write only
|
||||
* Required capability: `SPINEL_CAP_SRP_CLIENT`.
|
||||
*
|
||||
* Writing to this property clears all host info and all the services.
|
||||
* Please see `otSrpClientClearHostAndServices()` for more details.
|
||||
*
|
||||
*/
|
||||
SPINEL_PROP_SRP_CLIENT_HOST_SERVICES_CLEAR = SPINEL_PROP_OPENTHREAD__BEGIN + 25,
|
||||
|
||||
/// SRP Client Event
|
||||
/** Format: t() : Asynchronous event only
|
||||
* Required capability: `SPINEL_CAP_SRP_CLIENT`.
|
||||
*
|
||||
* This property is asynchronously emitted when there is an event from SRP client notifying some state changes or
|
||||
* errors.
|
||||
*
|
||||
* The general format of this property is as follows:
|
||||
*
|
||||
* `S` : Error code (see `spinel_srp_client_error_t` enumeration).
|
||||
* `d` : Host info data.
|
||||
* `d` : Active services.
|
||||
* `d` : Removed services.
|
||||
*
|
||||
* The host info data contains:
|
||||
*
|
||||
* `U` : The host name.
|
||||
* `C` : The host state (values from `spinel_srp_client_item_state_t`).
|
||||
* `t(A(6))` : Structure containing array of host IPv6 addresses.
|
||||
*
|
||||
* The active or removed services data is an array of services `A(t(UUSSSd))` with each service format:
|
||||
*
|
||||
* `U` : The service name labels (e.g., "_chip._udp", not the full domain name.
|
||||
* `U` : The service instance name label (not the full name).
|
||||
* `S` : The service port number.
|
||||
* `S` : The service priority.
|
||||
* `S` : The service weight.
|
||||
* `d` : The encoded TXT-DATA.
|
||||
*
|
||||
*/
|
||||
SPINEL_PROP_SRP_CLIENT_EVENT = SPINEL_PROP_OPENTHREAD__BEGIN + 26,
|
||||
|
||||
SPINEL_PROP_OPENTHREAD__END = 0x2000,
|
||||
|
||||
SPINEL_PROP_SERVER__BEGIN = 0xA0,
|
||||
|
||||
@@ -243,6 +243,10 @@ NcpBase::NcpBase(Instance *aInstance)
|
||||
, mOutboundInsecureIpFrameCounter(0)
|
||||
, mDroppedOutboundIpFrameCounter(0)
|
||||
, mDroppedInboundIpFrameCounter(0)
|
||||
#if OPENTHREAD_CONFIG_SRP_CLIENT_ENABLE
|
||||
, mSrpClientNumHostAddresses(0)
|
||||
, mSrpClientCallbackEnabled(false)
|
||||
#endif
|
||||
#endif // OPENTHREAD_MTD || OPENTHREAD_FTD
|
||||
, mFramingErrorCounter(0)
|
||||
, mRxSpinelFrameCounter(0)
|
||||
@@ -281,6 +285,7 @@ NcpBase::NcpBase(Instance *aInstance)
|
||||
#endif
|
||||
otThreadRegisterParentResponseCallback(mInstance, &NcpBase::HandleParentResponseInfo, static_cast<void *>(this));
|
||||
#endif // OPENTHREAD_FTD
|
||||
|
||||
#if OPENTHREAD_CONFIG_LEGACY_ENABLE
|
||||
mLegacyNodeDidJoin = false;
|
||||
mLegacyHandlers = nullptr;
|
||||
@@ -1911,6 +1916,10 @@ template <> otError NcpBase::HandlePropertyGet<SPINEL_PROP_CAPS>(void)
|
||||
SuccessOrExit(error = mEncoder.WriteUintPacked(SPINEL_CAP_MULTI_RADIO));
|
||||
#endif
|
||||
|
||||
#if OPENTHREAD_CONFIG_SRP_CLIENT_ENABLE
|
||||
SuccessOrExit(error = mEncoder.WriteUintPacked(SPINEL_CAP_SRP_CLIENT));
|
||||
#endif
|
||||
|
||||
#endif // OPENTHREAD_MTD || OPENTHREAD_FTD
|
||||
|
||||
exit:
|
||||
|
||||
@@ -50,6 +50,9 @@
|
||||
#if OPENTHREAD_CONFIG_MULTI_RADIO
|
||||
#include <openthread/multi_radio.h>
|
||||
#endif
|
||||
#if OPENTHREAD_CONFIG_SRP_CLIENT_ENABLE
|
||||
#include <openthread/srp_client.h>
|
||||
#endif
|
||||
|
||||
#include "changed_props_set.hpp"
|
||||
#include "common/instance.hpp"
|
||||
@@ -594,6 +597,45 @@ protected:
|
||||
uint32_t mOutboundInsecureIpFrameCounter; // Number of insecure outbound data/IP frames.
|
||||
uint32_t mDroppedOutboundIpFrameCounter; // Number of dropped outbound data/IP frames.
|
||||
uint32_t mDroppedInboundIpFrameCounter; // Number of dropped inbound data/IP frames.
|
||||
|
||||
#if OPENTHREAD_CONFIG_SRP_CLIENT_ENABLE
|
||||
enum : uint8_t
|
||||
{
|
||||
kSrpClientMaxServices = OPENTHREAD_CONFIG_NCP_SRP_CLIENT_MAX_SERVICES,
|
||||
kSrpClientMaxHostAddresses = OPENTHREAD_CONFIG_NCP_SRP_CLIENT_MAX_HOST_ADDRESSES,
|
||||
kSrpClientNameSize = 64,
|
||||
};
|
||||
|
||||
struct SrpClientService
|
||||
{
|
||||
void MarkAsNotInUse(void) { mService.mNext = &mService; }
|
||||
bool IsInUse(void) const { return (mService.mNext != &mService); }
|
||||
|
||||
otSrpClientService mService;
|
||||
char mInstanceName[kSrpClientNameSize];
|
||||
char mServiceName[kSrpClientNameSize];
|
||||
};
|
||||
|
||||
otError EncodeSrpClientHostInfo(const otSrpClientHostInfo &aHostInfo);
|
||||
otError EncodeSrpClientServices(const otSrpClientService *aServices);
|
||||
|
||||
static void HandleSrpClientCallback(otError aError,
|
||||
const otSrpClientHostInfo *aHostInfo,
|
||||
const otSrpClientService * aServices,
|
||||
const otSrpClientService * aRemovedServices,
|
||||
void * aContext);
|
||||
void HandleSrpClientCallback(otError aError,
|
||||
const otSrpClientHostInfo *aHostInfo,
|
||||
const otSrpClientService * aServices,
|
||||
const otSrpClientService * aRemovedServices);
|
||||
|
||||
char mSrpClientHostName[kSrpClientNameSize];
|
||||
SrpClientService mSrpClientServicePool[kSrpClientMaxServices];
|
||||
otIp6Address mSrpClientHostAddresses[kSrpClientMaxHostAddresses];
|
||||
uint8_t mSrpClientNumHostAddresses;
|
||||
bool mSrpClientCallbackEnabled;
|
||||
#endif // OPENTHREAD_CONFIG_SRP_CLIENT_ENABLE
|
||||
|
||||
#if OPENTHREAD_CONFIG_LEGACY_ENABLE
|
||||
const otNcpLegacyHandlers *mLegacyHandlers;
|
||||
uint8_t mLegacyUlaPrefix[OT_NCP_LEGACY_ULA_PREFIX_LENGTH];
|
||||
|
||||
@@ -329,6 +329,15 @@ NcpBase::PropertyHandler NcpBase::FindGetPropertyHandler(spinel_prop_key_t aKey)
|
||||
#if OPENTHREAD_CONFIG_MULTI_RADIO
|
||||
OT_NCP_GET_HANDLER_ENTRY(SPINEL_PROP_NEIGHBOR_TABLE_MULTI_RADIO_INFO),
|
||||
#endif
|
||||
#if OPENTHREAD_CONFIG_SRP_CLIENT_ENABLE
|
||||
OT_NCP_GET_HANDLER_ENTRY(SPINEL_PROP_SRP_CLIENT_LEASE_INTERVAL),
|
||||
OT_NCP_GET_HANDLER_ENTRY(SPINEL_PROP_SRP_CLIENT_KEY_LEASE_INTERVAL),
|
||||
OT_NCP_GET_HANDLER_ENTRY(SPINEL_PROP_SRP_CLIENT_HOST_INFO),
|
||||
OT_NCP_GET_HANDLER_ENTRY(SPINEL_PROP_SRP_CLIENT_HOST_NAME),
|
||||
OT_NCP_GET_HANDLER_ENTRY(SPINEL_PROP_SRP_CLIENT_HOST_ADDRESSES),
|
||||
OT_NCP_GET_HANDLER_ENTRY(SPINEL_PROP_SRP_CLIENT_SERVICES),
|
||||
#endif
|
||||
|
||||
#if OPENTHREAD_CONFIG_LEGACY_ENABLE
|
||||
OT_NCP_GET_HANDLER_ENTRY(SPINEL_PROP_NEST_LEGACY_ULA_PREFIX),
|
||||
OT_NCP_GET_HANDLER_ENTRY(SPINEL_PROP_NEST_LEGACY_LAST_NODE_JOINED),
|
||||
@@ -544,6 +553,15 @@ NcpBase::PropertyHandler NcpBase::FindSetPropertyHandler(spinel_prop_key_t aKey)
|
||||
#if OPENTHREAD_CONFIG_IP6_SLAAC_ENABLE
|
||||
OT_NCP_SET_HANDLER_ENTRY(SPINEL_PROP_SLAAC_ENABLED),
|
||||
#endif
|
||||
#if OPENTHREAD_CONFIG_SRP_CLIENT_ENABLE
|
||||
OT_NCP_SET_HANDLER_ENTRY(SPINEL_PROP_SRP_CLIENT_START),
|
||||
OT_NCP_SET_HANDLER_ENTRY(SPINEL_PROP_SRP_CLIENT_LEASE_INTERVAL),
|
||||
OT_NCP_SET_HANDLER_ENTRY(SPINEL_PROP_SRP_CLIENT_KEY_LEASE_INTERVAL),
|
||||
OT_NCP_SET_HANDLER_ENTRY(SPINEL_PROP_SRP_CLIENT_HOST_NAME),
|
||||
OT_NCP_SET_HANDLER_ENTRY(SPINEL_PROP_SRP_CLIENT_HOST_ADDRESSES),
|
||||
OT_NCP_SET_HANDLER_ENTRY(SPINEL_PROP_SRP_CLIENT_HOST_SERVICES_REMOVE),
|
||||
OT_NCP_SET_HANDLER_ENTRY(SPINEL_PROP_SRP_CLIENT_HOST_SERVICES_CLEAR),
|
||||
#endif
|
||||
#if OPENTHREAD_CONFIG_LEGACY_ENABLE
|
||||
OT_NCP_SET_HANDLER_ENTRY(SPINEL_PROP_NEST_LEGACY_ULA_PREFIX),
|
||||
#endif
|
||||
@@ -602,6 +620,11 @@ NcpBase::PropertyHandler NcpBase::FindInsertPropertyHandler(spinel_prop_key_t aK
|
||||
#endif
|
||||
#if OPENTHREAD_FTD && OPENTHREAD_CONFIG_COMMISSIONER_ENABLE
|
||||
OT_NCP_INSERT_HANDLER_ENTRY(SPINEL_PROP_THREAD_JOINERS),
|
||||
#endif
|
||||
#if OPENTHREAD_FTD || OPENTHREAD_MTD
|
||||
#if OPENTHREAD_CONFIG_SRP_CLIENT_ENABLE
|
||||
OT_NCP_INSERT_HANDLER_ENTRY(SPINEL_PROP_SRP_CLIENT_SERVICES),
|
||||
#endif
|
||||
#endif
|
||||
};
|
||||
|
||||
@@ -650,6 +673,11 @@ NcpBase::PropertyHandler NcpBase::FindRemovePropertyHandler(spinel_prop_key_t aK
|
||||
#endif
|
||||
#if OPENTHREAD_FTD
|
||||
OT_NCP_REMOVE_HANDLER_ENTRY(SPINEL_PROP_THREAD_ACTIVE_ROUTER_IDS),
|
||||
#endif
|
||||
#if OPENTHREAD_FTD || OPENTHREAD_MTD
|
||||
#if OPENTHREAD_CONFIG_SRP_CLIENT_ENABLE
|
||||
OT_NCP_REMOVE_HANDLER_ENTRY(SPINEL_PROP_SRP_CLIENT_SERVICES),
|
||||
#endif
|
||||
#endif
|
||||
};
|
||||
|
||||
|
||||
@@ -64,6 +64,7 @@
|
||||
#include "common/code_utils.hpp"
|
||||
#include "common/debug.hpp"
|
||||
#include "common/instance.hpp"
|
||||
#include "common/string.hpp"
|
||||
#include "net/ip6.hpp"
|
||||
|
||||
#if OPENTHREAD_MTD || OPENTHREAD_FTD
|
||||
@@ -3213,6 +3214,432 @@ exit:
|
||||
}
|
||||
#endif // OPENTHREAD_CONFIG_MULTI_RADIO
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// SRP Client
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
#if OPENTHREAD_CONFIG_SRP_CLIENT_ENABLE
|
||||
|
||||
template <> otError NcpBase::HandlePropertySet<SPINEL_PROP_SRP_CLIENT_START>(void)
|
||||
{
|
||||
otError error = OT_ERROR_NONE;
|
||||
bool start;
|
||||
bool callbackEnabled;
|
||||
otSockAddr serverAddr;
|
||||
|
||||
SuccessOrExit(error = mDecoder.ReadBool(start));
|
||||
|
||||
if (!start)
|
||||
{
|
||||
otSrpClientStop(mInstance);
|
||||
ExitNow();
|
||||
}
|
||||
|
||||
SuccessOrExit(error = mDecoder.ReadIp6Address(serverAddr.mAddress));
|
||||
SuccessOrExit(error = mDecoder.ReadUint16(serverAddr.mPort));
|
||||
SuccessOrExit(error = mDecoder.ReadBool(callbackEnabled));
|
||||
|
||||
SuccessOrExit(error = otSrpClientStart(mInstance, &serverAddr, HandleSrpClientCallback, this));
|
||||
mSrpClientCallbackEnabled = callbackEnabled;
|
||||
|
||||
exit:
|
||||
return error;
|
||||
}
|
||||
|
||||
template <> otError NcpBase::HandlePropertyGet<SPINEL_PROP_SRP_CLIENT_LEASE_INTERVAL>(void)
|
||||
{
|
||||
return mEncoder.WriteUint32(otSrpClientGetLeaseInterval(mInstance));
|
||||
}
|
||||
|
||||
template <> otError NcpBase::HandlePropertySet<SPINEL_PROP_SRP_CLIENT_LEASE_INTERVAL>(void)
|
||||
{
|
||||
otError error;
|
||||
uint32_t interval;
|
||||
|
||||
SuccessOrExit(error = mDecoder.ReadUint32(interval));
|
||||
otSrpClientSetLeaseInterval(mInstance, interval);
|
||||
|
||||
exit:
|
||||
return error;
|
||||
}
|
||||
|
||||
template <> otError NcpBase::HandlePropertyGet<SPINEL_PROP_SRP_CLIENT_KEY_LEASE_INTERVAL>(void)
|
||||
{
|
||||
return mEncoder.WriteUint32(otSrpClientGetKeyLeaseInterval(mInstance));
|
||||
}
|
||||
|
||||
template <> otError NcpBase::HandlePropertySet<SPINEL_PROP_SRP_CLIENT_KEY_LEASE_INTERVAL>(void)
|
||||
{
|
||||
otError error;
|
||||
uint32_t interval;
|
||||
|
||||
SuccessOrExit(error = mDecoder.ReadUint32(interval));
|
||||
otSrpClientSetKeyLeaseInterval(mInstance, interval);
|
||||
|
||||
exit:
|
||||
return error;
|
||||
}
|
||||
|
||||
static spinel_srp_client_item_state_t SrpClientItemStatetoSpinel(otSrpClientItemState aItemState)
|
||||
{
|
||||
spinel_srp_client_item_state_t state = SPINEL_SRP_CLIENT_ITEM_STATE_REMOVED;
|
||||
|
||||
switch (aItemState)
|
||||
{
|
||||
case OT_SRP_CLIENT_ITEM_STATE_TO_ADD:
|
||||
state = SPINEL_SRP_CLIENT_ITEM_STATE_TO_ADD;
|
||||
break;
|
||||
case OT_SRP_CLIENT_ITEM_STATE_ADDING:
|
||||
state = SPINEL_SRP_CLIENT_ITEM_STATE_ADDING;
|
||||
break;
|
||||
case OT_SRP_CLIENT_ITEM_STATE_TO_REFRESH:
|
||||
state = SPINEL_SRP_CLIENT_ITEM_STATE_TO_REFRESH;
|
||||
break;
|
||||
case OT_SRP_CLIENT_ITEM_STATE_REFRESHING:
|
||||
state = SPINEL_SRP_CLIENT_ITEM_STATE_REFRESHING;
|
||||
break;
|
||||
case OT_SRP_CLIENT_ITEM_STATE_TO_REMOVE:
|
||||
state = SPINEL_SRP_CLIENT_ITEM_STATE_TO_REMOVE;
|
||||
break;
|
||||
case OT_SRP_CLIENT_ITEM_STATE_REMOVING:
|
||||
state = SPINEL_SRP_CLIENT_ITEM_STATE_REMOVING;
|
||||
break;
|
||||
case OT_SRP_CLIENT_ITEM_STATE_REGISTERED:
|
||||
state = SPINEL_SRP_CLIENT_ITEM_STATE_REGISTERED;
|
||||
break;
|
||||
case OT_SRP_CLIENT_ITEM_STATE_REMOVED:
|
||||
state = SPINEL_SRP_CLIENT_ITEM_STATE_REMOVED;
|
||||
break;
|
||||
}
|
||||
|
||||
return state;
|
||||
}
|
||||
|
||||
otError NcpBase::EncodeSrpClientHostInfo(const otSrpClientHostInfo &aHostInfo)
|
||||
{
|
||||
otError error;
|
||||
|
||||
SuccessOrExit(error = mEncoder.WriteUtf8(aHostInfo.mName != nullptr ? aHostInfo.mName : ""));
|
||||
SuccessOrExit(error = mEncoder.WriteUint8(SrpClientItemStatetoSpinel(aHostInfo.mState)));
|
||||
|
||||
SuccessOrExit(error = mEncoder.OpenStruct());
|
||||
|
||||
for (uint8_t index = 0; index < aHostInfo.mNumAddresses; index++)
|
||||
{
|
||||
SuccessOrExit(error = mEncoder.WriteIp6Address(aHostInfo.mAddresses[index]));
|
||||
}
|
||||
|
||||
SuccessOrExit(error = mEncoder.CloseStruct());
|
||||
|
||||
exit:
|
||||
return error;
|
||||
}
|
||||
|
||||
template <> otError NcpBase::HandlePropertyGet<SPINEL_PROP_SRP_CLIENT_HOST_INFO>(void)
|
||||
{
|
||||
return EncodeSrpClientHostInfo(*otSrpClientGetHostInfo(mInstance));
|
||||
}
|
||||
|
||||
template <> otError NcpBase::HandlePropertyGet<SPINEL_PROP_SRP_CLIENT_HOST_NAME>(void)
|
||||
{
|
||||
const char *name = otSrpClientGetHostInfo(mInstance)->mName;
|
||||
|
||||
return mEncoder.WriteUtf8(name != nullptr ? name : "");
|
||||
}
|
||||
|
||||
template <> otError NcpBase::HandlePropertySet<SPINEL_PROP_SRP_CLIENT_HOST_NAME>(void)
|
||||
{
|
||||
otError error;
|
||||
const char *name;
|
||||
|
||||
SuccessOrExit(error = mDecoder.ReadUtf8(name));
|
||||
|
||||
VerifyOrExit(StringLength(name, kSrpClientNameSize) < kSrpClientNameSize, error = OT_ERROR_INVALID_ARGS);
|
||||
|
||||
// We first make sure we can set the name, and if so
|
||||
// we copy it to the `mSrpClientHostName` buffer and set
|
||||
// the host name again now with the persisted buffer
|
||||
// This ensures that we do not overwrite a previous
|
||||
// `mSrpClientHostName` when host name cannot be set.
|
||||
|
||||
SuccessOrExit(error = otSrpClientSetHostName(mInstance, name));
|
||||
|
||||
strcpy(mSrpClientHostName, name);
|
||||
error = otSrpClientSetHostName(mInstance, mSrpClientHostName);
|
||||
OT_ASSERT(error == OT_ERROR_NONE);
|
||||
|
||||
exit:
|
||||
return error;
|
||||
}
|
||||
|
||||
template <> otError NcpBase::HandlePropertyGet<SPINEL_PROP_SRP_CLIENT_HOST_ADDRESSES>(void)
|
||||
{
|
||||
otError error = OT_ERROR_NONE;
|
||||
const otSrpClientHostInfo *hostInfo = otSrpClientGetHostInfo(mInstance);
|
||||
|
||||
for (uint8_t index = 0; index < hostInfo->mNumAddresses; index++)
|
||||
{
|
||||
SuccessOrExit(error = mEncoder.WriteIp6Address(hostInfo->mAddresses[index]));
|
||||
}
|
||||
|
||||
exit:
|
||||
return error;
|
||||
}
|
||||
|
||||
template <> otError NcpBase::HandlePropertySet<SPINEL_PROP_SRP_CLIENT_HOST_ADDRESSES>(void)
|
||||
{
|
||||
otError error;
|
||||
otIp6Address addresses[kSrpClientMaxHostAddresses];
|
||||
uint8_t numAddresses = 0;
|
||||
|
||||
while (!mDecoder.IsAllReadInStruct())
|
||||
{
|
||||
VerifyOrExit(numAddresses < kSrpClientMaxHostAddresses, error = OT_ERROR_NO_BUFS);
|
||||
|
||||
SuccessOrExit(error = mDecoder.ReadIp6Address(addresses[numAddresses]));
|
||||
numAddresses++;
|
||||
}
|
||||
|
||||
// We first make sure we can set the addresses, and if so
|
||||
// we copy the address list into `mSrpClientHostAddresses`
|
||||
// and set it again. This ensures that we do not overwrite
|
||||
// a previous list before we know it is safe to set/change
|
||||
// the address list.
|
||||
|
||||
SuccessOrExit(error = otSrpClientSetHostAddresses(mInstance, addresses, numAddresses));
|
||||
|
||||
memcpy(mSrpClientHostAddresses, addresses, sizeof(addresses));
|
||||
mSrpClientNumHostAddresses = numAddresses;
|
||||
|
||||
error = otSrpClientSetHostAddresses(mInstance, mSrpClientHostAddresses, numAddresses);
|
||||
OT_ASSERT(error == OT_ERROR_NONE);
|
||||
|
||||
exit:
|
||||
return error;
|
||||
}
|
||||
|
||||
otError NcpBase::EncodeSrpClientServices(const otSrpClientService *aServices)
|
||||
{
|
||||
otError error = OT_ERROR_NONE;
|
||||
|
||||
for (; aServices != nullptr; aServices = aServices->mNext)
|
||||
{
|
||||
SuccessOrExit(error = mEncoder.OpenStruct());
|
||||
|
||||
SuccessOrExit(error = mEncoder.WriteUtf8(aServices->mName));
|
||||
SuccessOrExit(error = mEncoder.WriteUtf8(aServices->mInstanceName));
|
||||
SuccessOrExit(error = mEncoder.WriteUint16(aServices->mPort));
|
||||
SuccessOrExit(error = mEncoder.WriteUint16(aServices->mPriority));
|
||||
SuccessOrExit(error = mEncoder.WriteUint16(aServices->mWeight));
|
||||
|
||||
SuccessOrExit(error = mEncoder.CloseStruct());
|
||||
}
|
||||
|
||||
exit:
|
||||
return error;
|
||||
}
|
||||
|
||||
template <> otError NcpBase::HandlePropertyGet<SPINEL_PROP_SRP_CLIENT_SERVICES>(void)
|
||||
{
|
||||
return EncodeSrpClientServices(otSrpClientGetServices(mInstance));
|
||||
}
|
||||
|
||||
template <> otError NcpBase::HandlePropertyInsert<SPINEL_PROP_SRP_CLIENT_SERVICES>(void)
|
||||
{
|
||||
otError error = OT_ERROR_NONE;
|
||||
SrpClientService *entry = nullptr;
|
||||
const char * serviceName;
|
||||
const char * instanceName;
|
||||
|
||||
for (SrpClientService &poolEntry : mSrpClientServicePool)
|
||||
{
|
||||
if (!poolEntry.IsInUse())
|
||||
{
|
||||
entry = &poolEntry;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
VerifyOrExit(entry != nullptr, error = OT_ERROR_NO_BUFS);
|
||||
|
||||
SuccessOrExit(error = mDecoder.ReadUtf8(serviceName));
|
||||
VerifyOrExit(StringLength(serviceName, kSrpClientNameSize) < kSrpClientNameSize, error = OT_ERROR_INVALID_ARGS);
|
||||
strcpy(entry->mServiceName, serviceName);
|
||||
entry->mService.mName = entry->mServiceName;
|
||||
|
||||
SuccessOrExit(error = mDecoder.ReadUtf8(instanceName));
|
||||
VerifyOrExit(StringLength(instanceName, kSrpClientNameSize) < kSrpClientNameSize, error = OT_ERROR_INVALID_ARGS);
|
||||
strcpy(entry->mInstanceName, instanceName);
|
||||
entry->mService.mInstanceName = entry->mInstanceName;
|
||||
|
||||
SuccessOrExit(error = mDecoder.ReadUint16(entry->mService.mPort));
|
||||
SuccessOrExit(error = mDecoder.ReadUint16(entry->mService.mPriority));
|
||||
SuccessOrExit(error = mDecoder.ReadUint16(entry->mService.mWeight));
|
||||
|
||||
error = otSrpClientAddService(mInstance, &entry->mService);
|
||||
|
||||
if (error != OT_ERROR_NONE)
|
||||
{
|
||||
entry->MarkAsNotInUse();
|
||||
}
|
||||
|
||||
exit:
|
||||
return error;
|
||||
}
|
||||
|
||||
template <> otError NcpBase::HandlePropertyRemove<SPINEL_PROP_SRP_CLIENT_SERVICES>(void)
|
||||
{
|
||||
otError error = OT_ERROR_NONE;
|
||||
const char *serviceName;
|
||||
const char *instanceName;
|
||||
|
||||
SuccessOrExit(error = mDecoder.ReadUtf8(serviceName));
|
||||
SuccessOrExit(error = mDecoder.ReadUtf8(instanceName));
|
||||
|
||||
for (SrpClientService &poolEntry : mSrpClientServicePool)
|
||||
{
|
||||
if (!poolEntry.IsInUse() || (strcmp(serviceName, poolEntry.mServiceName) != 0) ||
|
||||
(strcmp(instanceName, poolEntry.mInstanceName) != 0))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
error = otSrpClientRemoveService(mInstance, &poolEntry.mService);
|
||||
ExitNow();
|
||||
}
|
||||
|
||||
error = OT_ERROR_NOT_FOUND;
|
||||
|
||||
exit:
|
||||
return error;
|
||||
}
|
||||
|
||||
template <> otError NcpBase::HandlePropertySet<SPINEL_PROP_SRP_CLIENT_HOST_SERVICES_REMOVE>(void)
|
||||
{
|
||||
otError error = OT_ERROR_NONE;
|
||||
bool removeKeyLease;
|
||||
|
||||
SuccessOrExit(error = mDecoder.ReadBool(removeKeyLease));
|
||||
|
||||
error = otSrpClientRemoveHostAndServices(mInstance, removeKeyLease);
|
||||
|
||||
exit:
|
||||
return error;
|
||||
}
|
||||
|
||||
template <> otError NcpBase::HandlePropertySet<SPINEL_PROP_SRP_CLIENT_HOST_SERVICES_CLEAR>(void)
|
||||
{
|
||||
otSrpClientClearHostAndServices(mInstance);
|
||||
|
||||
return OT_ERROR_NONE;
|
||||
}
|
||||
|
||||
static spinel_srp_client_error_t SrpClientErrorToSpinelError(otError aError)
|
||||
{
|
||||
spinel_srp_client_error_t error = SPINEL_SRP_CLIENT_ERROR_FAILED;
|
||||
|
||||
switch (aError)
|
||||
{
|
||||
case OT_ERROR_NONE:
|
||||
error = SPINEL_SRP_CLIENT_ERROR_NONE;
|
||||
break;
|
||||
case OT_ERROR_PARSE:
|
||||
error = SPINEL_SRP_CLIENT_ERROR_PARSE;
|
||||
break;
|
||||
case OT_ERROR_NOT_FOUND:
|
||||
error = SPINEL_SRP_CLIENT_ERROR_NOT_FOUND;
|
||||
break;
|
||||
case OT_ERROR_NOT_IMPLEMENTED:
|
||||
error = SPINEL_SRP_CLIENT_ERROR_NOT_IMPLEMENTED;
|
||||
break;
|
||||
case OT_ERROR_SECURITY:
|
||||
error = SPINEL_SRP_CLIENT_ERROR_SECURITY;
|
||||
break;
|
||||
case OT_ERROR_DUPLICATED:
|
||||
error = SPINEL_SRP_CLIENT_ERROR_DUPLICATED;
|
||||
break;
|
||||
case OT_ERROR_RESPONSE_TIMEOUT:
|
||||
error = SPINEL_SRP_CLIENT_ERROR_RESPONSE_TIMEOUT;
|
||||
break;
|
||||
case OT_ERROR_INVALID_ARGS:
|
||||
error = SPINEL_SRP_CLIENT_ERROR_INVALID_ARGS;
|
||||
break;
|
||||
case OT_ERROR_NO_BUFS:
|
||||
error = SPINEL_SRP_CLIENT_ERROR_NO_BUFS;
|
||||
break;
|
||||
case OT_ERROR_FAILED:
|
||||
default:
|
||||
error = SPINEL_SRP_CLIENT_ERROR_FAILED;
|
||||
break;
|
||||
}
|
||||
|
||||
return error;
|
||||
}
|
||||
|
||||
void NcpBase::HandleSrpClientCallback(otError aError,
|
||||
const otSrpClientHostInfo *aHostInfo,
|
||||
const otSrpClientService * aServices,
|
||||
const otSrpClientService * aRemovedServices,
|
||||
void * aContext)
|
||||
{
|
||||
static_cast<NcpBase *>(aContext)->HandleSrpClientCallback(aError, aHostInfo, aServices, aRemovedServices);
|
||||
}
|
||||
|
||||
void NcpBase::HandleSrpClientCallback(otError aError,
|
||||
const otSrpClientHostInfo *aHostInfo,
|
||||
const otSrpClientService * aServices,
|
||||
const otSrpClientService * aRemovedServices)
|
||||
{
|
||||
otError error = OT_ERROR_NONE;
|
||||
const otSrpClientService *service;
|
||||
const otSrpClientService *next;
|
||||
|
||||
VerifyOrExit(mSrpClientCallbackEnabled);
|
||||
|
||||
SuccessOrExit(error = mEncoder.BeginFrame(SPINEL_HEADER_FLAG | SPINEL_HEADER_IID_0, SPINEL_CMD_PROP_VALUE_IS,
|
||||
SPINEL_PROP_SRP_CLIENT_EVENT));
|
||||
|
||||
SuccessOrExit(error = mEncoder.WriteUint16(SrpClientErrorToSpinelError(aError)));
|
||||
|
||||
SuccessOrExit(error = mEncoder.OpenStruct());
|
||||
SuccessOrExit(error = EncodeSrpClientHostInfo(*aHostInfo));
|
||||
SuccessOrExit(error = mEncoder.CloseStruct());
|
||||
|
||||
SuccessOrExit(error = mEncoder.OpenStruct());
|
||||
SuccessOrExit(error = EncodeSrpClientServices(aServices));
|
||||
SuccessOrExit(error = mEncoder.CloseStruct());
|
||||
|
||||
SuccessOrExit(error = mEncoder.OpenStruct());
|
||||
SuccessOrExit(error = EncodeSrpClientServices(aRemovedServices));
|
||||
SuccessOrExit(error = mEncoder.CloseStruct());
|
||||
|
||||
SuccessOrExit(error = mEncoder.EndFrame());
|
||||
|
||||
exit:
|
||||
|
||||
if (error != OT_ERROR_NONE)
|
||||
{
|
||||
// Emit a NONMEM status if we fail to send the event.
|
||||
mChangedPropsSet.AddLastStatus(SPINEL_STATUS_NOMEM);
|
||||
mUpdateChangedPropsTask.Post();
|
||||
}
|
||||
|
||||
for (service = aRemovedServices; service != nullptr; service = next)
|
||||
{
|
||||
next = service->mNext;
|
||||
|
||||
for (SrpClientService &poolEntry : mSrpClientServicePool)
|
||||
{
|
||||
if (&poolEntry.mService == service)
|
||||
{
|
||||
poolEntry.MarkAsNotInUse();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endif // OPENTHREAD_CONFIG_SRP_CLIENT_ENABLE
|
||||
|
||||
#if OPENTHREAD_CONFIG_LEGACY_ENABLE
|
||||
|
||||
void NcpBase::RegisterLegacyHandlers(const otNcpLegacyHandlers *aHandlers)
|
||||
|
||||
@@ -189,4 +189,28 @@
|
||||
#define OPENTHREAD_ENABLE_NCP_VENDOR_HOOK 0
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @def OPENTHREAD_CONFIG_NCP_SRP_CLIENT_MAX_SERVICES
|
||||
*
|
||||
* The maximum number of service entries supported by SRP client.
|
||||
*
|
||||
* This is only applicable when SRP client is enabled, i.e., OPENTHREAD_CONFIG_SRP_CLIENT_ENABLE is set.
|
||||
*
|
||||
*/
|
||||
#ifndef OPENTHREAD_CONFIG_NCP_SRP_CLIENT_MAX_SERVICES
|
||||
#define OPENTHREAD_CONFIG_NCP_SRP_CLIENT_MAX_SERVICES 2
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @def OPENTHREAD_CONFIG_NCP_SRP_CLIENT_MAX_HOST_ADDRESSES
|
||||
*
|
||||
* The maximum number of host IPv6 address entries supported by SRP client.
|
||||
*
|
||||
* This is only applicable when SRP client is enabled, i.e., OPENTHREAD_CONFIG_SRP_CLIENT_ENABLE is set.
|
||||
*
|
||||
*/
|
||||
#ifndef OPENTHREAD_CONFIG_NCP_SRP_CLIENT_MAX_HOST_ADDRESSES
|
||||
#define OPENTHREAD_CONFIG_NCP_SRP_CLIENT_MAX_HOST_ADDRESSES 2
|
||||
#endif
|
||||
|
||||
#endif // CONFIG_NCP_H_
|
||||
|
||||
Reference in New Issue
Block a user