[ncp] implement ncp version of otPlatDnssdRegisterHost (#10893)

This commit implements ncp version of otPlatDnssdRegisterHost.
1. move the position of `SPINEL_PROP_DNSSD_STATE` in `spinel.h`
   because it was by mistake put within the range of
   `SPINEL_PROP_SRP_SERVER`. The value is unchanged.
2. A template method `DnssdUpdate` is added because the same process
   works also for DNSSD service and key record which will be added in
   following PRs.
This commit is contained in:
Li Cao
2024-11-07 09:46:59 +01:00
committed by GitHub
parent e43120d903
commit d0998beca4
7 changed files with 206 additions and 17 deletions
+2
View File
@@ -1414,6 +1414,8 @@ const char *spinel_prop_key_to_cstr(spinel_prop_key_t prop_key)
{SPINEL_PROP_SRP_SERVER_ENABLED, "SPINEL_PROP_SRP_SERVER_ENABLED"},
{SPINEL_PROP_SRP_SERVER_AUTO_ENABLE_MODE, "SPINEL_PROP_SRP_SERVER_AUTO_ENABLE_MODE"},
{SPINEL_PROP_DNSSD_STATE, "DNSSD_STATE"},
{SPINEL_PROP_DNSSD_REQUEST_RESULT, "DNSSD_REQUEST_RESULT"},
{SPINEL_PROP_DNSSD_HOST, "DNSSD_HOST"},
{SPINEL_PROP_PARENT_RESPONSE_INFO, "PARENT_RESPONSE_INFO"},
{SPINEL_PROP_SLAAC_ENABLED, "SLAAC_ENABLED"},
{SPINEL_PROP_SUPPORTED_RADIO_LINKS, "SUPPORTED_RADIO_LINKS"},
+35 -11
View File
@@ -4785,17 +4785,6 @@ enum
SPINEL_PROP_SRP_SERVER__BEGIN = 0x920,
SPINEL_PROP_DNSSD__BEGIN = 0x930,
/// Dnssd State
/** Format `b`: Write-only
*
* `C`: The dnssd state.
*/
SPINEL_PROP_DNSSD_STATE = SPINEL_PROP_DNSSD__BEGIN + 1,
SPINEL_PROP_DNSSD__END = 0x950,
/// SRP server state.
/** Format `b`
* Type: Read-Write
@@ -4814,6 +4803,41 @@ enum
SPINEL_PROP_SRP_SERVER__END = 0x930,
SPINEL_PROP_DNSSD__BEGIN = 0x930,
/// Dnssd State
/** Format `C`: Write-only
*
* `C`: The dnssd state.
*/
SPINEL_PROP_DNSSD_STATE = SPINEL_PROP_DNSSD__BEGIN + 1,
/// Dnssd Request Result
/** Format `CLD`: Write
*
* `C` : The result of the request. A unsigned int8 corresponds to otError.
* `L` : The Dnssd Request ID.
* `D` : The context of the request. (A pointer to the callback for the request)
*
* Host uses this property to notify the NCP of the result of NCP's DNS-SD request.
*/
SPINEL_PROP_DNSSD_REQUEST_RESULT = SPINEL_PROP_DNSSD__BEGIN + 2,
/// DNS-SD Host
/** Format `USA(6)LD`: Inserted/Removed
*
* `U` : The host name.
* `S` : The count of IPv6 addresses.
* `A(6)` : The IPv6 addresses of the host.
* `L` : The Dnssd Request ID.
* `D` : The context of the request. (A pointer to the callback for the request)
*
* NCP uses this property to register/unregister a DNS-SD host.
*/
SPINEL_PROP_DNSSD_HOST = SPINEL_PROP_DNSSD__BEGIN + 3,
SPINEL_PROP_DNSSD__END = 0x950,
SPINEL_PROP_NEST__BEGIN = 0x3BC0,
SPINEL_PROP_NEST_STREAM_MFG = SPINEL_PROP_NEST__BEGIN + 0,
+51
View File
@@ -53,6 +53,7 @@
#if OPENTHREAD_CONFIG_SRP_CLIENT_ENABLE
#include <openthread/srp_client.h>
#endif
#include <openthread/platform/dnssd.h>
#include "changed_props_set.hpp"
#include "common/tasklet.hpp"
@@ -245,6 +246,28 @@ public:
uint16_t aBufferLength);
#if OPENTHREAD_FTD && OPENTHREAD_CONFIG_NCP_DNSSD_ENABLE && OPENTHREAD_CONFIG_PLATFORM_DNSSD_ENABLE
/**
* Registers or updates a host on the infrastructure network's DNS-SD module (on host).
*
* @param[in] aHost Information about the host to register.
* @param[in] aRequestId The ID associated with this request.
* @param[in] aCallback The callback function pointer to report the outcome (may be NULL if no callback needed).
*/
void DnssdRegisterHost(const otPlatDnssdHost *aHost,
otPlatDnssdRequestId aRequestId,
otPlatDnssdRegisterCallback aCallback);
/**
* Unregisters a host on the infrastructure network's DNS-SD module (on host).
*
* @param[in] aHost Information about the host to register.
* @param[in] aRequestId The ID associated with this request.
* @param[in] aCallback The callback function pointer to report the outcome (may be NULL if no callback needed).
*/
void DnssdUnregisterHost(const otPlatDnssdHost *aHost,
otPlatDnssdRequestId aRequestId,
otPlatDnssdRegisterCallback aCallback);
/**
* Gets the Dnssd state.
*
@@ -780,6 +803,34 @@ protected:
#endif
#if OPENTHREAD_CONFIG_NCP_DNSSD_ENABLE && OPENTHREAD_CONFIG_PLATFORM_DNSSD_ENABLE
template <typename DnssdObjType>
void DnssdUpdate(const DnssdObjType *Obj,
otPlatDnssdRequestId aRequestId,
otPlatDnssdRegisterCallback aCallback,
bool aRegister)
{
otError error = OT_ERROR_NONE;
uint8_t header = SPINEL_HEADER_FLAG | SPINEL_HEADER_TX_NOTIFICATION_IID;
spinel_command_t cmd = aRegister ? SPINEL_CMD_PROP_VALUE_INSERTED : SPINEL_CMD_PROP_VALUE_REMOVED;
VerifyOrExit(mDnssdState == OT_PLAT_DNSSD_READY, error = OT_ERROR_INVALID_STATE);
SuccessOrExit(error = mEncoder.BeginFrame(header, cmd));
SuccessOrExit(error = EncodeDnssd(Obj));
SuccessOrExit(error = mEncoder.WriteUint32(aRequestId));
SuccessOrExit(error = mEncoder.WriteData(reinterpret_cast<const uint8_t *>(&aCallback), sizeof(aCallback)));
SuccessOrExit(error = mEncoder.EndFrame());
exit:
if (error != OT_ERROR_NONE)
{
aCallback(mInstance, aRequestId, error);
}
}
template <typename DnssdObjType> otError EncodeDnssd(const DnssdObjType *aObj);
otPlatDnssdState mDnssdState;
#endif
#endif
+1
View File
@@ -537,6 +537,7 @@ NcpBase::PropertyHandler NcpBase::FindSetPropertyHandler(spinel_prop_key_t aKey)
#endif
#if OPENTHREAD_CONFIG_PLATFORM_DNSSD_ENABLE && OPENTHREAD_CONFIG_NCP_DNSSD_ENABLE
OT_NCP_SET_HANDLER_ENTRY(SPINEL_PROP_DNSSD_STATE),
OT_NCP_SET_HANDLER_ENTRY(SPINEL_PROP_DNSSD_REQUEST_RESULT),
#endif
#endif // OPENTHREAD_FTD
#if OPENTHREAD_MTD || OPENTHREAD_FTD
+50
View File
@@ -1566,6 +1566,36 @@ exit:
#if OPENTHREAD_CONFIG_NCP_DNSSD_ENABLE && OPENTHREAD_CONFIG_PLATFORM_DNSSD_ENABLE
template <> otError NcpBase::EncodeDnssd<otPlatDnssdHost>(const otPlatDnssdHost *aHost)
{
otError error = OT_ERROR_NONE;
SuccessOrExit(error = mEncoder.WriteUintPacked(SPINEL_PROP_DNSSD_HOST));
SuccessOrExit(error = mEncoder.WriteUtf8(aHost->mHostName == nullptr ? "" : aHost->mHostName));
SuccessOrExit(error = mEncoder.WriteUint16(aHost->mAddressesLength));
for (uint8_t i = 0; i < aHost->mAddressesLength; i++)
{
SuccessOrExit(error = mEncoder.WriteIp6Address(aHost->mAddresses[i]));
}
exit:
return error;
}
void NcpBase::DnssdRegisterHost(const otPlatDnssdHost *aHost,
otPlatDnssdRequestId aRequestId,
otPlatDnssdRegisterCallback aCallback)
{
DnssdUpdate(aHost, aRequestId, aCallback, /* aRegister */ true);
}
void NcpBase::DnssdUnregisterHost(const otPlatDnssdHost *aHost,
otPlatDnssdRequestId aRequestId,
otPlatDnssdRegisterCallback aCallback)
{
DnssdUpdate(aHost, aRequestId, aCallback, /* aRegister */ false);
}
otPlatDnssdState NcpBase::DnssdGetState(void) { return mDnssdState; }
template <> otError NcpBase::HandlePropertySet<SPINEL_PROP_DNSSD_STATE>(void)
@@ -1585,6 +1615,26 @@ exit:
return error;
}
template <> otError NcpBase::HandlePropertySet<SPINEL_PROP_DNSSD_REQUEST_RESULT>(void)
{
otError error = OT_ERROR_NONE;
otPlatDnssdRequestId requestId;
uint8_t result;
otPlatDnssdRegisterCallback callback = nullptr;
const uint8_t *context;
uint16_t contextLen;
SuccessOrExit(error = mDecoder.ReadUint8(result));
SuccessOrExit(error = mDecoder.ReadUint32(requestId));
SuccessOrExit(error = mDecoder.ReadData(context, contextLen));
VerifyOrExit(contextLen == sizeof(otPlatDnssdRegisterCallback), error = OT_ERROR_PARSE);
callback = *reinterpret_cast<const otPlatDnssdRegisterCallback *>(context);
callback(mInstance, requestId, static_cast<otError>(result));
exit:
return error;
}
#endif // OPENTHREAD_CONFIG_NCP_DNSSD_ENABLE && OPENTHREAD_CONFIG_PLATFORM_DNSSD_ENABLE
} // namespace Ncp
+6 -6
View File
@@ -67,9 +67,9 @@ void otPlatDnssdRegisterHost(otInstance *aInstance,
otPlatDnssdRegisterCallback aCallback)
{
OT_UNUSED_VARIABLE(aInstance);
OT_UNUSED_VARIABLE(aHost);
OT_UNUSED_VARIABLE(aRequestId);
OT_UNUSED_VARIABLE(aCallback);
ot::Ncp::NcpBase *ncp = ot::Ncp::NcpBase::GetNcpInstance();
ncp->DnssdRegisterHost(aHost, aRequestId, aCallback);
}
void otPlatDnssdUnregisterHost(otInstance *aInstance,
@@ -78,9 +78,9 @@ void otPlatDnssdUnregisterHost(otInstance *aInstance,
otPlatDnssdRegisterCallback aCallback)
{
OT_UNUSED_VARIABLE(aInstance);
OT_UNUSED_VARIABLE(aHost);
OT_UNUSED_VARIABLE(aRequestId);
OT_UNUSED_VARIABLE(aCallback);
ot::Ncp::NcpBase *ncp = ot::Ncp::NcpBase::GetNcpInstance();
ncp->DnssdUnregisterHost(aHost, aRequestId, aCallback);
}
void otPlatDnssdRegisterKey(otInstance *aInstance,
+61
View File
@@ -42,6 +42,8 @@
namespace ot {
constexpr uint16_t kMaxSpinelBufferSize = 2048;
static uint32_t sRequestId;
static uint8_t sError;
static otError GenerateSpinelDnssdSetStateFrame(otPlatDnssdState aState, uint8_t *aBuf, uint16_t &aLen)
{
@@ -63,6 +65,35 @@ exit:
return error;
}
static void TestPlatDnssdRegisterCallback(otInstance *aInstance, otPlatDnssdRequestId aRequestId, otError aError)
{
sRequestId = aRequestId;
sError = aError;
}
static otError GenerateSpinelDnssdRequestResultFrame(uint32_t aRequestId, otError aError, uint8_t *aBuf, uint16_t &aLen)
{
otError error = OT_ERROR_NONE;
uint8_t buf[kMaxSpinelBufferSize];
Spinel::Buffer ncpBuffer(buf, kMaxSpinelBufferSize);
Spinel::Encoder encoder(ncpBuffer);
otPlatDnssdRegisterCallback callback = &TestPlatDnssdRegisterCallback;
uint8_t header = SPINEL_HEADER_FLAG | 0 /* Iid */ | 1 /* Tid */;
SuccessOrExit(error = encoder.BeginFrame(header, SPINEL_CMD_PROP_VALUE_SET, SPINEL_PROP_DNSSD_REQUEST_RESULT));
SuccessOrExit(error = encoder.WriteUint8(aError));
SuccessOrExit(error = encoder.WriteUint32(aRequestId));
SuccessOrExit(error = encoder.WriteData(reinterpret_cast<const uint8_t *>(&callback), sizeof(callback)));
SuccessOrExit(error = encoder.EndFrame());
SuccessOrExit(ncpBuffer.OutFrameBegin());
aLen = ncpBuffer.OutFrameGetLength();
VerifyOrExit(ncpBuffer.OutFrameRead(aLen, aBuf) == aLen, error = OT_ERROR_FAILED);
exit:
return error;
}
void TestNcpDnssdGetState(void)
{
Instance *instance = static_cast<Instance *>(testInitInstance());
@@ -81,6 +112,35 @@ void TestNcpDnssdGetState(void)
VerifyOrQuit(dnssdState == OT_PLAT_DNSSD_READY);
}
void TestNcpDnssdRegistrations(void)
{
Instance *instance = static_cast<Instance *>(testInitInstance());
Ncp::NcpBase ncpBase(instance);
uint8_t recvBuf[kMaxSpinelBufferSize];
uint16_t recvLen;
otPlatDnssdHost dnssdHost;
sRequestId = 0; // Use 0 to indicate `sRequestId` hasn't been set.
// Register a dnssd host when the dnssd state is DISABLED
dnssdHost.mHostName = "ot-test";
dnssdHost.mAddressesLength = 0;
otPlatDnssdRegisterHost(instance, &dnssdHost, 1 /* aRequestId */, TestPlatDnssdRegisterCallback);
VerifyOrQuit(sRequestId == 1);
VerifyOrQuit(sError == OT_ERROR_INVALID_STATE);
// Set the dnssd state to READY
SuccessOrQuit(GenerateSpinelDnssdSetStateFrame(OT_PLAT_DNSSD_READY, recvBuf, recvLen));
ncpBase.HandleReceive(recvBuf, recvLen);
otPlatDnssdUnregisterHost(instance, &dnssdHost, 2 /* aRequestId */, TestPlatDnssdRegisterCallback);
SuccessOrQuit(GenerateSpinelDnssdRequestResultFrame(2 /* aRequestId */, OT_ERROR_NOT_FOUND, recvBuf, recvLen));
ncpBase.HandleReceive(recvBuf, recvLen);
VerifyOrQuit(sRequestId == 2);
VerifyOrQuit(sError == OT_ERROR_NOT_FOUND);
}
} // namespace ot
#endif // OPENTHREAD_CONFIG_NCP_DNSSD_ENABLE && OPENTHREAD_CONFIG_PLATFORM_DNSSD_ENABLE
@@ -89,6 +149,7 @@ int main(void)
{
#if OPENTHREAD_CONFIG_NCP_DNSSD_ENABLE && OPENTHREAD_CONFIG_PLATFORM_DNSSD_ENABLE
ot::TestNcpDnssdGetState();
ot::TestNcpDnssdRegistrations();
#endif
printf("All tests passed\n");
return 0;