mirror of
https://github.com/espressif/openthread.git
synced 2026-08-11 21:27:46 +00:00
[ncp] implement ncp platform dnssd discovery methods (#12068)
This commit implements `otPlatDnssdStartBrowser` and `otPlatDnssdStopBrowser` to support service discovery on NCP. The platform APIs are intended to be used by `ServiceDiscovery::Server::DiscoveryProxy` for discovery functionality. This commit only supports browser for now and will suppport Srv/Txt/Address resolver in other commits to avoid this commit from being too large. This commit contains these changes: * Add new spinel property for starting / stopping service browser * Implement encoding/decoding of the new property * Add unit test for encoding/decoding * Implement ncp version of dnssd platform API `otPlatDnssdStartBrowser` and `otPlatDnssdStopBrowser` * Add property handler to get browser result on NCP side * Add unit test to verify that the browser callback is correctly invoked after getting browser result.
This commit is contained in:
@@ -1419,6 +1419,8 @@ const char *spinel_prop_key_to_cstr(spinel_prop_key_t prop_key)
|
||||
{SPINEL_PROP_DNSSD_HOST, "DNSSD_HOST"},
|
||||
{SPINEL_PROP_DNSSD_SERVICE, "DNSSD_SERVICE"},
|
||||
{SPINEL_PROP_DNSSD_KEY_RECORD, "DNSSD_KEY_RECORD"},
|
||||
{SPINEL_PROP_DNSSD_BROWSER, "DNSSD_BROWSER"},
|
||||
{SPINEL_PROP_DNSSD_BROWSE_RESULT, "DNSSD_BROWSE_RESULT"},
|
||||
{SPINEL_PROP_BORDER_AGENT_MESHCOP_SERVICE_STATE, "BORDER_AGENT_MESHCOP_SERVICE_STATE"},
|
||||
{SPINEL_PROP_BORDER_AGENT_EPHEMERAL_KEY_STATE, "SPINEL_PROP_BORDER_AGENT_EPHEMERAL_KEY_STATE"},
|
||||
{SPINEL_PROP_BORDER_AGENT_EPHEMERAL_KEY_ENABLE, "SPINEL_PROP_BORDER_AGENT_EPHEMERAL_KEY_ENABLE"},
|
||||
|
||||
@@ -4897,6 +4897,34 @@ enum
|
||||
*/
|
||||
SPINEL_PROP_DNSSD_KEY_RECORD = SPINEL_PROP_DNSSD__BEGIN + 5,
|
||||
|
||||
/// DNS-SD Service Browser
|
||||
/**
|
||||
* Format : Inserted/Removed
|
||||
*
|
||||
* `U` : The service type (e.g., "_mt._udp"). MUST NOT include domain name.
|
||||
* `t(U)` : The sub-type label if browsing for sub-type, empty otherwise.
|
||||
* `L` : The infrastructure network interface index to browse the service.
|
||||
* `D` : The context of the request. A pointer to the browse callback to receive the result.
|
||||
*
|
||||
* NCP uses this property to browse services.
|
||||
*/
|
||||
SPINEL_PROP_DNSSD_BROWSER = SPINEL_PROP_DNSSD__BEGIN + 6,
|
||||
|
||||
/// DNS-SD Service Browser Result
|
||||
/**
|
||||
* Format : Set
|
||||
*
|
||||
* `U` : The service type (e.g., "_mt._udp"). MUST NOT include domain name.
|
||||
* `t(U)` : The sub-type label if browsing for sub-type, empty otherwise.
|
||||
* `U` : Service instance label.
|
||||
* `L` : TTL in seconds. Zero TTL indicates that service is removed.
|
||||
* `L` : The infrastructure network interface index.
|
||||
* `D` : The context of the request. A pointer to the browse callback to receive the result.
|
||||
*
|
||||
* Host uses this property to send the result of the browser to NCP.
|
||||
*/
|
||||
SPINEL_PROP_DNSSD_BROWSE_RESULT = SPINEL_PROP_DNSSD__BEGIN + 7,
|
||||
|
||||
SPINEL_PROP_DNSSD__END = 0x950,
|
||||
|
||||
SPINEL_PROP_BORDER_AGENT__BEGIN = 0x950,
|
||||
|
||||
@@ -196,5 +196,99 @@ exit:
|
||||
return error;
|
||||
}
|
||||
|
||||
template <> otError EncodeDnssdDiscovery<otPlatDnssdBrowser>(Encoder &aEncoder, const otPlatDnssdBrowser &aDiscovery)
|
||||
{
|
||||
otError error = OT_ERROR_NONE;
|
||||
|
||||
SuccessOrExit(error = aEncoder.WriteUtf8(aDiscovery.mServiceType));
|
||||
SuccessOrExit(error = aEncoder.OpenStruct());
|
||||
if (aDiscovery.mSubTypeLabel != nullptr)
|
||||
{
|
||||
SuccessOrExit(error = aEncoder.WriteUtf8(aDiscovery.mSubTypeLabel));
|
||||
}
|
||||
SuccessOrExit(error = aEncoder.CloseStruct());
|
||||
SuccessOrExit(error = aEncoder.WriteUint32(aDiscovery.mInfraIfIndex));
|
||||
SuccessOrExit(error = aEncoder.WriteData(reinterpret_cast<const uint8_t *>(&aDiscovery.mCallback),
|
||||
sizeof(aDiscovery.mCallback)));
|
||||
|
||||
exit:
|
||||
return error;
|
||||
}
|
||||
|
||||
otError EncodeDnssdBrowseResult(Encoder &aEncoder,
|
||||
const otPlatDnssdBrowseResult &aBrowseResult,
|
||||
const uint8_t *aCallbackData,
|
||||
uint16_t aCallbackDataLen)
|
||||
{
|
||||
otError error = OT_ERROR_NONE;
|
||||
|
||||
SuccessOrExit(error = aEncoder.WriteUtf8(aBrowseResult.mServiceType));
|
||||
SuccessOrExit(error = aEncoder.OpenStruct());
|
||||
if (aBrowseResult.mSubTypeLabel != nullptr)
|
||||
{
|
||||
SuccessOrExit(error = aEncoder.WriteUtf8(aBrowseResult.mSubTypeLabel));
|
||||
}
|
||||
SuccessOrExit(error = aEncoder.CloseStruct());
|
||||
SuccessOrExit(error = aEncoder.WriteUtf8(aBrowseResult.mServiceInstance));
|
||||
SuccessOrExit(error = aEncoder.WriteUint32(aBrowseResult.mTtl));
|
||||
SuccessOrExit(error = aEncoder.WriteUint32(aBrowseResult.mInfraIfIndex));
|
||||
SuccessOrExit(error = aEncoder.WriteData(aCallbackData, aCallbackDataLen));
|
||||
|
||||
exit:
|
||||
return error;
|
||||
}
|
||||
|
||||
otError DecodeDnssdBrowser(Decoder &aDecoder,
|
||||
otPlatDnssdBrowser &aBrowser,
|
||||
const uint8_t *&aCallbackData,
|
||||
uint16_t &aCallbackDataLen)
|
||||
{
|
||||
otError error = OT_ERROR_NONE;
|
||||
|
||||
SuccessOrExit(error = aDecoder.ReadUtf8(aBrowser.mServiceType));
|
||||
SuccessOrExit(error = aDecoder.OpenStruct());
|
||||
if (!aDecoder.IsAllReadInStruct())
|
||||
{
|
||||
SuccessOrExit(error = aDecoder.ReadUtf8(aBrowser.mSubTypeLabel));
|
||||
}
|
||||
else
|
||||
{
|
||||
aBrowser.mSubTypeLabel = nullptr;
|
||||
}
|
||||
SuccessOrExit(error = aDecoder.CloseStruct());
|
||||
SuccessOrExit(error = aDecoder.ReadUint32(aBrowser.mInfraIfIndex));
|
||||
SuccessOrExit(error = aDecoder.ReadData(aCallbackData, aCallbackDataLen));
|
||||
|
||||
exit:
|
||||
return error;
|
||||
}
|
||||
|
||||
otError DecodeDnssdBrowseResult(Decoder &aDecoder,
|
||||
otPlatDnssdBrowseResult &aBrowseResult,
|
||||
const uint8_t *&aCallbackData,
|
||||
uint16_t &aCallbackDataLen)
|
||||
{
|
||||
otError error = OT_ERROR_NONE;
|
||||
|
||||
SuccessOrExit(error = aDecoder.ReadUtf8(aBrowseResult.mServiceType));
|
||||
SuccessOrExit(error = aDecoder.OpenStruct());
|
||||
if (!aDecoder.IsAllReadInStruct())
|
||||
{
|
||||
SuccessOrExit(error = aDecoder.ReadUtf8(aBrowseResult.mSubTypeLabel));
|
||||
}
|
||||
else
|
||||
{
|
||||
aBrowseResult.mSubTypeLabel = nullptr;
|
||||
}
|
||||
SuccessOrExit(error = aDecoder.CloseStruct());
|
||||
SuccessOrExit(error = aDecoder.ReadUtf8(aBrowseResult.mServiceInstance));
|
||||
SuccessOrExit(error = aDecoder.ReadUint32(aBrowseResult.mTtl));
|
||||
SuccessOrExit(error = aDecoder.ReadUint32(aBrowseResult.mInfraIfIndex));
|
||||
SuccessOrExit(error = aDecoder.ReadData(aCallbackData, aCallbackDataLen));
|
||||
|
||||
exit:
|
||||
return error;
|
||||
}
|
||||
|
||||
} // namespace Spinel
|
||||
} // namespace ot
|
||||
|
||||
@@ -58,6 +58,35 @@ otError EncodeDnssd(Encoder &aEncoder,
|
||||
otPlatDnssdRequestId aRequestId,
|
||||
otPlatDnssdRegisterCallback aCallback);
|
||||
|
||||
/**
|
||||
* Use Spinel::Encode to encode a Dnssd Discovery.
|
||||
*
|
||||
* DnssdDiscoveryType can be: otPlatDnssdBrowser, otPlatDnssdSrvResolver, otPlatDnssdTxtResolver,
|
||||
* otPlatDnssdAddressResolver and otPlatDnssdRecordQuerier.
|
||||
*
|
||||
* A Spinel header and command MUST have been encoded by the encoder.
|
||||
*
|
||||
* @param[in] aEncoder A reference to the encoder object.
|
||||
* @param[in] aDiscovery A reference to the dnssd discovery object.
|
||||
*/
|
||||
template <typename DnssdDiscoveryType>
|
||||
otError EncodeDnssdDiscovery(Encoder &aEncoder, const DnssdDiscoveryType &aDiscovery);
|
||||
|
||||
/**
|
||||
* Use Spinel::Encode to encode a Dnssd Browser result.
|
||||
*
|
||||
* A Spinel header and command MUST have been encoded by the encoder.
|
||||
*
|
||||
* @param[in] aEncoder A reference to the encoder object.
|
||||
* @param[in] aBrowseResult A reference to the browse result object.
|
||||
* @param[in] aCallbackData A pointer to the callback data.
|
||||
* @param[in] aCallbackDataLen The data length.
|
||||
*/
|
||||
otError EncodeDnssdBrowseResult(Encoder &aEncoder,
|
||||
const otPlatDnssdBrowseResult &aBrowseResult,
|
||||
const uint8_t *aCallbackData,
|
||||
uint16_t aCallbackDataLen);
|
||||
|
||||
/**
|
||||
* Use Spinel::Decoder to decode a SPINEL_PROP_DNSSD_HOST message to a otPlatDnssdHost.
|
||||
*
|
||||
@@ -113,6 +142,36 @@ otError DecodeDnssdKey(Decoder &aDecoder,
|
||||
const uint8_t *&aCallbackData,
|
||||
uint16_t &aCallbackDataLen);
|
||||
|
||||
/**
|
||||
* Use Spinel::Decoder to decode a SPINEL_PROP_DNSSD_BROWSER message to a otPlatDnssdBrowser.
|
||||
*
|
||||
* The decoder MUST have read the header, command and property key of the frame.
|
||||
*
|
||||
* @param[in] aDecoder A reference to the decoder object.
|
||||
* @param[out] aBrowser A reference to the dnssd browser.
|
||||
* @param[out] aCallbackData A reference to the pointer to the callback data.
|
||||
* @param[out] aCallbackDataLen A reference to the callback data length.
|
||||
*/
|
||||
otError DecodeDnssdBrowser(Decoder &aDecoder,
|
||||
otPlatDnssdBrowser &aBrowser,
|
||||
const uint8_t *&aCallbackData,
|
||||
uint16_t &aCallbackDataLen);
|
||||
|
||||
/**
|
||||
* Use Spinel::Decoder to decode a Dnssd Browser result.
|
||||
*
|
||||
* The decoder MUST have read the header, command and property key of the frame.
|
||||
*
|
||||
* @param[in] aDecoder A reference to the decoder object.
|
||||
* @param[out] aBrowseResult A reference to the browse result.
|
||||
* @param[out] aCallbackData A reference to the pointer to the callback data.
|
||||
* @param[out] aCallbackDataLen A reference to the callback data length.
|
||||
*/
|
||||
otError DecodeDnssdBrowseResult(Decoder &aDecoder,
|
||||
otPlatDnssdBrowseResult &aBrowseResult,
|
||||
const uint8_t *&aCallbackData,
|
||||
uint16_t &aCallbackDataLen);
|
||||
|
||||
} // namespace Spinel
|
||||
} // namespace ot
|
||||
|
||||
|
||||
+46
-1
@@ -310,13 +310,27 @@ public:
|
||||
otPlatDnssdRequestId aRequestId,
|
||||
otPlatDnssdRegisterCallback aCallback);
|
||||
|
||||
/**
|
||||
* Starts a service browser.
|
||||
*
|
||||
* @param[in] aBrowser The browser to be started.
|
||||
*/
|
||||
void DnssdStartBrowser(const otPlatDnssdBrowser *aBrowser);
|
||||
|
||||
/**
|
||||
* Stops a service browser.
|
||||
*
|
||||
* @param[in] aBrowser The browser to be stopped.
|
||||
*/
|
||||
void DnssdStopBrowser(const otPlatDnssdBrowser *aBrowser);
|
||||
|
||||
/**
|
||||
* Gets the Dnssd state.
|
||||
*
|
||||
* Returns the platform dnssd state.
|
||||
*/
|
||||
otPlatDnssdState DnssdGetState(void);
|
||||
#endif
|
||||
#endif // OPENTHREAD_FTD && OPENTHREAD_CONFIG_NCP_DNSSD_ENABLE && OPENTHREAD_CONFIG_PLATFORM_DNSSD_ENABLE
|
||||
|
||||
protected:
|
||||
static constexpr uint8_t kBitsPerByte = 8; ///< Number of bits in a byte.
|
||||
@@ -851,6 +865,8 @@ protected:
|
||||
|
||||
#if OPENTHREAD_CONFIG_NCP_DNSSD_ENABLE && OPENTHREAD_CONFIG_PLATFORM_DNSSD_ENABLE
|
||||
|
||||
template <typename DnssdObjType> struct DnssdDiscoveryPropKeyFor;
|
||||
|
||||
template <typename DnssdObjType>
|
||||
void DnssdUpdate(const DnssdObjType *aObj,
|
||||
otPlatDnssdRequestId aRequestId,
|
||||
@@ -875,6 +891,28 @@ protected:
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Template for making service discovery.
|
||||
*
|
||||
* DnssdDiscoveryType can be: otPlatDnssdBrowser, otPlatDnssdSrvResolver, otPlatDnssdTxtResolver,
|
||||
* otPlatDnssdAddressResolver and otPlatDnssdRecordQuerier.
|
||||
*/
|
||||
template <typename DnssdDiscoveryType> void DnssdUpdateDiscovery(const DnssdDiscoveryType *aDiscovery, bool aStart)
|
||||
{
|
||||
uint8_t header = SPINEL_HEADER_FLAG | SPINEL_HEADER_TX_NOTIFICATION_IID;
|
||||
spinel_command_t cmd = aStart ? SPINEL_CMD_PROP_VALUE_INSERTED : SPINEL_CMD_PROP_VALUE_REMOVED;
|
||||
|
||||
VerifyOrExit(aDiscovery != nullptr);
|
||||
VerifyOrExit(mDnssdState == OT_PLAT_DNSSD_READY);
|
||||
|
||||
SuccessOrExit(mEncoder.BeginFrame(header, cmd, DnssdDiscoveryPropKeyFor<DnssdDiscoveryType>::Key));
|
||||
SuccessOrExit(Spinel::EncodeDnssdDiscovery(mEncoder, *aDiscovery));
|
||||
SuccessOrExit(mEncoder.EndFrame());
|
||||
|
||||
exit:
|
||||
return;
|
||||
}
|
||||
|
||||
otPlatDnssdState mDnssdState;
|
||||
#endif // OPENTHREAD_CONFIG_NCP_DNSSD_ENABLE && OPENTHREAD_CONFIG_PLATFORM_DNSSD_ENABLE
|
||||
|
||||
@@ -899,6 +937,13 @@ protected:
|
||||
#endif
|
||||
};
|
||||
|
||||
#if OPENTHREAD_FTD && OPENTHREAD_CONFIG_NCP_DNSSD_ENABLE && OPENTHREAD_CONFIG_PLATFORM_DNSSD_ENABLE
|
||||
template <> struct NcpBase::DnssdDiscoveryPropKeyFor<otPlatDnssdBrowser>
|
||||
{
|
||||
static constexpr spinel_prop_key_t Key = SPINEL_PROP_DNSSD_BROWSER;
|
||||
};
|
||||
#endif
|
||||
|
||||
} // namespace Ncp
|
||||
} // namespace ot
|
||||
|
||||
|
||||
@@ -545,6 +545,7 @@ NcpBase::PropertyHandler NcpBase::FindSetPropertyHandler(spinel_prop_key_t aKey)
|
||||
#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),
|
||||
OT_NCP_SET_HANDLER_ENTRY(SPINEL_PROP_DNSSD_BROWSE_RESULT),
|
||||
#endif
|
||||
#if OPENTHREAD_CONFIG_BORDER_AGENT_ENABLE && OPENTHREAD_CONFIG_BORDER_AGENT_EPHEMERAL_KEY_ENABLE
|
||||
OT_NCP_SET_HANDLER_ENTRY(SPINEL_PROP_BORDER_AGENT_EPHEMERAL_KEY_ENABLE),
|
||||
|
||||
@@ -1692,6 +1692,16 @@ void NcpBase::DnssdUnregisterKey(const otPlatDnssdKey *aKey,
|
||||
DnssdUpdate(aKey, aRequestId, aCallback, /* aRegister */ false);
|
||||
}
|
||||
|
||||
void NcpBase::DnssdStartBrowser(const otPlatDnssdBrowser *aBrowser)
|
||||
{
|
||||
DnssdUpdateDiscovery(aBrowser, /* aStart */ true);
|
||||
}
|
||||
|
||||
void NcpBase::DnssdStopBrowser(const otPlatDnssdBrowser *aBrowser)
|
||||
{
|
||||
DnssdUpdateDiscovery(aBrowser, /* aStart */ false);
|
||||
}
|
||||
|
||||
otPlatDnssdState NcpBase::DnssdGetState(void) { return mDnssdState; }
|
||||
|
||||
template <> otError NcpBase::HandlePropertySet<SPINEL_PROP_DNSSD_STATE>(void)
|
||||
@@ -1731,6 +1741,23 @@ exit:
|
||||
return error;
|
||||
}
|
||||
|
||||
template <> otError NcpBase::HandlePropertySet<SPINEL_PROP_DNSSD_BROWSE_RESULT>(void)
|
||||
{
|
||||
otError error = OT_ERROR_NONE;
|
||||
otPlatDnssdBrowseResult browseResult;
|
||||
otPlatDnssdBrowseCallback callback = nullptr;
|
||||
const uint8_t *context;
|
||||
uint16_t contextLen;
|
||||
|
||||
SuccessOrExit(error = DecodeDnssdBrowseResult(mDecoder, browseResult, context, contextLen));
|
||||
VerifyOrExit(contextLen == sizeof(otPlatDnssdBrowseCallback), error = OT_ERROR_PARSE);
|
||||
callback = *reinterpret_cast<const otPlatDnssdBrowseCallback *>(context);
|
||||
callback(mInstance, &browseResult);
|
||||
|
||||
exit:
|
||||
return error;
|
||||
}
|
||||
|
||||
#endif // OPENTHREAD_CONFIG_NCP_DNSSD_ENABLE && OPENTHREAD_CONFIG_PLATFORM_DNSSD_ENABLE
|
||||
|
||||
#if OPENTHREAD_CONFIG_BORDER_AGENT_ENABLE
|
||||
|
||||
@@ -108,13 +108,17 @@ void otPlatDnssdUnregisterKey(otInstance *aInstance,
|
||||
void otPlatDnssdStartBrowser(otInstance *aInstance, const otPlatDnssdBrowser *aBrowser)
|
||||
{
|
||||
OT_UNUSED_VARIABLE(aInstance);
|
||||
OT_UNUSED_VARIABLE(aBrowser);
|
||||
ot::Ncp::NcpBase *ncp = ot::Ncp::NcpBase::GetNcpInstance();
|
||||
|
||||
ncp->DnssdStartBrowser(aBrowser);
|
||||
}
|
||||
|
||||
void otPlatDnssdStopBrowser(otInstance *aInstance, const otPlatDnssdBrowser *aBrowser)
|
||||
{
|
||||
OT_UNUSED_VARIABLE(aInstance);
|
||||
OT_UNUSED_VARIABLE(aBrowser);
|
||||
ot::Ncp::NcpBase *ncp = ot::Ncp::NcpBase::GetNcpInstance();
|
||||
|
||||
ncp->DnssdStopBrowser(aBrowser);
|
||||
}
|
||||
|
||||
void otPlatDnssdStartSrvResolver(otInstance *aInstance, const otPlatDnssdSrvResolver *aResolver)
|
||||
|
||||
@@ -178,6 +178,72 @@ void TestNcpDnssdRegistrations(void)
|
||||
VerifyOrQuit(sError == OT_ERROR_NONE);
|
||||
}
|
||||
|
||||
static bool sDnssdBrowseCallbackInvoked = false;
|
||||
|
||||
static void TestDnssdBrowseCallback(otInstance *aInstance, const otPlatDnssdBrowseResult *aResult)
|
||||
{
|
||||
VerifyOrQuit(strcmp(aResult->mServiceType, "_ms._tcp") == 0);
|
||||
VerifyOrQuit(strcmp(aResult->mSubTypeLabel, "_battery") == 0);
|
||||
VerifyOrQuit(strcmp(aResult->mServiceInstance, "GAT-X105 #1") == 0);
|
||||
VerifyOrQuit(aResult->mTtl == 12345);
|
||||
VerifyOrQuit(aResult->mInfraIfIndex == 2);
|
||||
|
||||
sDnssdBrowseCallbackInvoked = true;
|
||||
}
|
||||
|
||||
static otError GenerateSpinelDnssdBrowseResultFrame(const otPlatDnssdBrowseResult &aBrowseResult,
|
||||
uint8_t *aBuf,
|
||||
uint16_t &aLen)
|
||||
{
|
||||
otError error = OT_ERROR_NONE;
|
||||
uint8_t buf[kMaxSpinelBufferSize];
|
||||
Spinel::Buffer ncpBuffer(buf, kMaxSpinelBufferSize);
|
||||
Spinel::Encoder encoder(ncpBuffer);
|
||||
otPlatDnssdBrowseCallback callback = &TestDnssdBrowseCallback;
|
||||
|
||||
uint8_t header = SPINEL_HEADER_FLAG | 0 /* Iid */ | 1 /* Tid */;
|
||||
SuccessOrExit(error = encoder.BeginFrame(header, SPINEL_CMD_PROP_VALUE_SET, SPINEL_PROP_DNSSD_BROWSE_RESULT));
|
||||
SuccessOrExit(error = EncodeDnssdBrowseResult(encoder, aBrowseResult, 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 TestNcpDnssdBrowse(void)
|
||||
{
|
||||
Instance *instance = static_cast<Instance *>(testInitInstance());
|
||||
Ncp::NcpBase ncpBase(instance);
|
||||
uint8_t recvBuf[kMaxSpinelBufferSize];
|
||||
uint16_t recvLen;
|
||||
otPlatDnssdBrowser browser;
|
||||
otPlatDnssdBrowseResult browseResult;
|
||||
|
||||
browser.mServiceType = "_ms._tcp";
|
||||
browser.mSubTypeLabel = "_battery";
|
||||
browser.mInfraIfIndex = 2;
|
||||
browser.mCallback = TestDnssdBrowseCallback;
|
||||
|
||||
otPlatDnssdStartBrowser(instance, &browser);
|
||||
|
||||
browseResult.mServiceType = "_ms._tcp";
|
||||
browseResult.mSubTypeLabel = "_battery";
|
||||
browseResult.mServiceInstance = "GAT-X105 #1";
|
||||
browseResult.mTtl = 12345;
|
||||
browseResult.mInfraIfIndex = 2;
|
||||
|
||||
SuccessOrQuit(GenerateSpinelDnssdBrowseResultFrame(browseResult, recvBuf, recvLen));
|
||||
|
||||
ncpBase.HandleReceive(recvBuf, recvLen);
|
||||
|
||||
VerifyOrQuit(sDnssdBrowseCallbackInvoked);
|
||||
}
|
||||
|
||||
} // namespace ot
|
||||
|
||||
#endif // OPENTHREAD_CONFIG_NCP_DNSSD_ENABLE && OPENTHREAD_CONFIG_PLATFORM_DNSSD_ENABLE
|
||||
@@ -187,6 +253,7 @@ int main(void)
|
||||
#if OPENTHREAD_CONFIG_NCP_DNSSD_ENABLE && OPENTHREAD_CONFIG_PLATFORM_DNSSD_ENABLE
|
||||
ot::TestNcpDnssdGetState();
|
||||
ot::TestNcpDnssdRegistrations();
|
||||
ot::TestNcpDnssdBrowse();
|
||||
#endif
|
||||
printf("All tests passed\n");
|
||||
return 0;
|
||||
|
||||
@@ -41,6 +41,12 @@ static void DnssdFakeCallback(otInstance *aInstance, otPlatDnssdRequestId aReque
|
||||
OT_UNUSED_VARIABLE(aError);
|
||||
}
|
||||
|
||||
static void FakeDnssdBrowseCallback(otInstance *aInstance, const otPlatDnssdBrowseResult *aResult)
|
||||
{
|
||||
OT_UNUSED_VARIABLE(aInstance);
|
||||
OT_UNUSED_VARIABLE(aResult);
|
||||
}
|
||||
|
||||
void TestDnssd(void)
|
||||
{
|
||||
constexpr uint16_t kMaxSpinelBufferSize = 2048;
|
||||
@@ -178,6 +184,75 @@ void TestDnssd(void)
|
||||
VerifyOrQuit(requestId == 3);
|
||||
VerifyOrQuit(callbackDataLen == sizeof(otPlatDnssdRegisterCallback));
|
||||
VerifyOrQuit(*reinterpret_cast<const otPlatDnssdRegisterCallback *>(callbackData) == DnssdFakeCallback);
|
||||
|
||||
// Test Dnssd Browser encoding and decoding
|
||||
otPlatDnssdBrowser dnssdBrowserEncode;
|
||||
otPlatDnssdBrowser dnssdBrowserDecode;
|
||||
|
||||
dnssdBrowserEncode.mServiceType = "_meshcop._udp";
|
||||
dnssdBrowserEncode.mSubTypeLabel = nullptr;
|
||||
dnssdBrowserEncode.mInfraIfIndex = 1;
|
||||
dnssdBrowserEncode.mCallback = FakeDnssdBrowseCallback;
|
||||
|
||||
ncpBuffer.Clear();
|
||||
SuccessOrQuit(
|
||||
error = encoder.BeginFrame(SPINEL_HEADER_FLAG, SPINEL_CMD_PROP_VALUE_INSERTED, SPINEL_PROP_DNSSD_BROWSER));
|
||||
SuccessOrQuit(error = EncodeDnssdDiscovery(encoder, dnssdBrowserEncode));
|
||||
SuccessOrQuit(error = encoder.EndFrame());
|
||||
SuccessOrQuit(ncpBuffer.OutFrameBegin());
|
||||
len = ncpBuffer.OutFrameGetLength();
|
||||
VerifyOrQuit(ncpBuffer.OutFrameRead(len, buf) == len);
|
||||
|
||||
decoder.Init(buf, len);
|
||||
SuccessOrQuit(error = decoder.ReadUint8(header));
|
||||
VerifyOrQuit(header == SPINEL_HEADER_FLAG);
|
||||
SuccessOrQuit(error = decoder.ReadUintPacked(command));
|
||||
VerifyOrQuit(command == SPINEL_CMD_PROP_VALUE_INSERTED);
|
||||
SuccessOrQuit(error = decoder.ReadUintPacked(propKey));
|
||||
VerifyOrQuit(static_cast<spinel_prop_key_t>(propKey) == SPINEL_PROP_DNSSD_BROWSER);
|
||||
SuccessOrQuit(error = DecodeDnssdBrowser(decoder, dnssdBrowserDecode, callbackData, callbackDataLen));
|
||||
VerifyOrQuit(strcmp(dnssdBrowserDecode.mServiceType, dnssdBrowserEncode.mServiceType) == 0);
|
||||
VerifyOrQuit(dnssdBrowserDecode.mSubTypeLabel == dnssdBrowserEncode.mSubTypeLabel);
|
||||
VerifyOrQuit(dnssdBrowserDecode.mInfraIfIndex == dnssdBrowserEncode.mInfraIfIndex);
|
||||
VerifyOrQuit(callbackDataLen == sizeof(otPlatDnssdBrowseCallback));
|
||||
VerifyOrQuit(*reinterpret_cast<const otPlatDnssdBrowseCallback *>(callbackData) == FakeDnssdBrowseCallback);
|
||||
|
||||
// Test Dnssd Browser Result encoding and decoding
|
||||
otPlatDnssdBrowseResult dnssdBrowseResultEncode;
|
||||
otPlatDnssdBrowseResult dnssdBrowseResultDecode;
|
||||
|
||||
dnssdBrowseResultEncode.mServiceType = "_ms._tcp";
|
||||
dnssdBrowseResultEncode.mSubTypeLabel = "_nuclear";
|
||||
dnssdBrowseResultEncode.mServiceInstance = "ZGMF-X09A #1";
|
||||
dnssdBrowseResultEncode.mTtl = 1999;
|
||||
dnssdBrowseResultEncode.mInfraIfIndex = 1;
|
||||
|
||||
otPlatDnssdBrowseCallback callback = &FakeDnssdBrowseCallback;
|
||||
|
||||
ncpBuffer.Clear();
|
||||
SuccessOrQuit(
|
||||
error = encoder.BeginFrame(SPINEL_HEADER_FLAG, SPINEL_CMD_PROP_VALUE_SET, SPINEL_PROP_DNSSD_BROWSE_RESULT));
|
||||
SuccessOrQuit(error = EncodeDnssdBrowseResult(encoder, dnssdBrowseResultEncode,
|
||||
reinterpret_cast<const uint8_t *>(&callback), sizeof(callback)));
|
||||
SuccessOrQuit(error = encoder.EndFrame());
|
||||
SuccessOrQuit(ncpBuffer.OutFrameBegin());
|
||||
len = ncpBuffer.OutFrameGetLength();
|
||||
VerifyOrQuit(ncpBuffer.OutFrameRead(len, buf) == len);
|
||||
|
||||
decoder.Init(buf, len);
|
||||
SuccessOrQuit(error = decoder.ReadUint8(header));
|
||||
VerifyOrQuit(header == SPINEL_HEADER_FLAG);
|
||||
SuccessOrQuit(error = decoder.ReadUintPacked(command));
|
||||
VerifyOrQuit(command == SPINEL_CMD_PROP_VALUE_SET);
|
||||
SuccessOrQuit(error = decoder.ReadUintPacked(propKey));
|
||||
VerifyOrQuit(static_cast<spinel_prop_key_t>(propKey) == SPINEL_PROP_DNSSD_BROWSE_RESULT);
|
||||
SuccessOrQuit(error = DecodeDnssdBrowseResult(decoder, dnssdBrowseResultDecode, callbackData, callbackDataLen));
|
||||
VerifyOrQuit(strcmp(dnssdBrowseResultDecode.mServiceType, dnssdBrowseResultEncode.mServiceType) == 0);
|
||||
VerifyOrQuit(strcmp(dnssdBrowseResultDecode.mSubTypeLabel, dnssdBrowseResultEncode.mSubTypeLabel) == 0);
|
||||
VerifyOrQuit(strcmp(dnssdBrowseResultDecode.mServiceInstance, dnssdBrowseResultEncode.mServiceInstance) == 0);
|
||||
VerifyOrQuit(dnssdBrowseResultDecode.mInfraIfIndex == dnssdBrowseResultEncode.mInfraIfIndex);
|
||||
VerifyOrQuit(callbackDataLen == sizeof(otPlatDnssdBrowseCallback));
|
||||
VerifyOrQuit(*reinterpret_cast<const otPlatDnssdBrowseCallback *>(callbackData) == FakeDnssdBrowseCallback);
|
||||
}
|
||||
|
||||
} // namespace Spinel
|
||||
|
||||
Reference in New Issue
Block a user