mirror of
https://github.com/espressif/openthread.git
synced 2026-09-15 13:40:06 +00:00
[ncp] bridge DNSSD TXT and address resolvers over Spinel (#13311)
Discovery Proxy on NCP needs TXT and host address resolution from the host OTBR, but only browse and SRV resolvers were wired through Spinel. Add the missing properties, codecs, and NCP handlers so the platform DNSSD stubs forward resolver start/stop and deliver results back. - Add SPINEL_PROP_DNSSD_TXT_* and IP4/IP6 address resolver/result props - Encode/decode TXT and address discovery in spinel_prop_codec - Handle resolver insert/remove and result SET in ncp_base_ftd - Wire otPlatDnssd*Txt/Address* stubs in ncp/platform/dnssd.cpp
This commit is contained in:
@@ -1423,6 +1423,12 @@ const char *spinel_prop_key_to_cstr(spinel_prop_key_t prop_key)
|
||||
{SPINEL_PROP_DNSSD_BROWSE_RESULT, "DNSSD_BROWSE_RESULT"},
|
||||
{SPINEL_PROP_DNSSD_SRV_RESOLVER, "DNSSD_SRV_RESOLVER"},
|
||||
{SPINEL_PROP_DNSSD_SRV_RESULT, "DNSSD_SRV_RESULT"},
|
||||
{SPINEL_PROP_DNSSD_TXT_RESOLVER, "DNSSD_TXT_RESOLVER"},
|
||||
{SPINEL_PROP_DNSSD_TXT_RESULT, "DNSSD_TXT_RESULT"},
|
||||
{SPINEL_PROP_DNSSD_IP6_ADDRESS_RESOLVER, "DNSSD_IP6_ADDRESS_RESOLVER"},
|
||||
{SPINEL_PROP_DNSSD_IP6_ADDRESS_RESULT, "DNSSD_IP6_ADDRESS_RESULT"},
|
||||
{SPINEL_PROP_DNSSD_IP4_ADDRESS_RESOLVER, "DNSSD_IP4_ADDRESS_RESOLVER"},
|
||||
{SPINEL_PROP_DNSSD_IP4_ADDRESS_RESULT, "DNSSD_IP4_ADDRESS_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"},
|
||||
|
||||
@@ -4961,6 +4961,63 @@ enum
|
||||
*/
|
||||
SPINEL_PROP_DNSSD_SRV_RESULT = SPINEL_PROP_DNSSD__BEGIN + 9,
|
||||
|
||||
/// DNS-SD TXT Resolver
|
||||
/**
|
||||
* Format: `UULD`: Inserted/Removed
|
||||
*
|
||||
* `U`: The service instance label.
|
||||
* `U`: The service type.
|
||||
* `L`: The infrastructure network interface index.
|
||||
* `D`: The context of the request (pointer to `otPlatDnssdTxtCallback`).
|
||||
*/
|
||||
SPINEL_PROP_DNSSD_TXT_RESOLVER = SPINEL_PROP_DNSSD__BEGIN + 10,
|
||||
|
||||
/// DNS-SD TXT Resolution Result
|
||||
/**
|
||||
* Format: `UUdLLD`: Set
|
||||
*
|
||||
* `U`: Service instance label.
|
||||
* `U`: Service type.
|
||||
* `d`: Encoded TXT data bytes (empty if removed).
|
||||
* `L`: TTL in seconds (zero indicates removal).
|
||||
* `L`: Infrastructure interface index.
|
||||
* `D`: Callback context (`sizeof(otPlatDnssdTxtCallback)`).
|
||||
*/
|
||||
SPINEL_PROP_DNSSD_TXT_RESULT = SPINEL_PROP_DNSSD__BEGIN + 11,
|
||||
|
||||
/// DNS-SD IPv6 Address Resolver
|
||||
/**
|
||||
* Format: `ULD`: Inserted/Removed
|
||||
*
|
||||
* `U`: Host name (no domain).
|
||||
* `L`: Infrastructure interface index.
|
||||
* `D`: Callback context (`sizeof(otPlatDnssdAddressCallback)`).
|
||||
*/
|
||||
SPINEL_PROP_DNSSD_IP6_ADDRESS_RESOLVER = SPINEL_PROP_DNSSD__BEGIN + 12,
|
||||
|
||||
/// DNS-SD IPv6 Address Resolution Result
|
||||
/**
|
||||
* Format: `ULt(A(6L))D`: Set
|
||||
*
|
||||
* `U`: Host name.
|
||||
* `L`: Infrastructure interface index.
|
||||
* `t(A(6L))`: Struct containing an array of IPv6 addresses, each followed by a TTL as `uint32_t`.
|
||||
* `D`: Callback context (`sizeof(otPlatDnssdAddressCallback)`).
|
||||
*/
|
||||
SPINEL_PROP_DNSSD_IP6_ADDRESS_RESULT = SPINEL_PROP_DNSSD__BEGIN + 13,
|
||||
|
||||
/// DNS-SD IPv4 Address Resolver
|
||||
/**
|
||||
* Format: `ULD`: Inserted/Removed (same as IPv6 resolver; IPv4 uses IPv4-mapped IPv6 in results).
|
||||
*/
|
||||
SPINEL_PROP_DNSSD_IP4_ADDRESS_RESOLVER = SPINEL_PROP_DNSSD__BEGIN + 14,
|
||||
|
||||
/// DNS-SD IPv4 Address Resolution Result
|
||||
/**
|
||||
* Format: Same as `SPINEL_PROP_DNSSD_IP6_ADDRESS_RESULT`.
|
||||
*/
|
||||
SPINEL_PROP_DNSSD_IP4_ADDRESS_RESULT = SPINEL_PROP_DNSSD__BEGIN + 15,
|
||||
|
||||
SPINEL_PROP_DNSSD__END = 0x950,
|
||||
|
||||
SPINEL_PROP_BORDER_AGENT__BEGIN = 0x950,
|
||||
|
||||
@@ -393,5 +393,170 @@ exit:
|
||||
return error;
|
||||
}
|
||||
|
||||
template <>
|
||||
otError EncodeDnssdDiscovery<otPlatDnssdTxtResolver>(Encoder &aEncoder, const otPlatDnssdTxtResolver &aDiscovery)
|
||||
{
|
||||
otError error = OT_ERROR_NONE;
|
||||
|
||||
SuccessOrExit(error = aEncoder.WriteUtf8(aDiscovery.mServiceInstance));
|
||||
SuccessOrExit(error = aEncoder.WriteUtf8(aDiscovery.mServiceType));
|
||||
SuccessOrExit(error = aEncoder.WriteUint32(aDiscovery.mInfraIfIndex));
|
||||
SuccessOrExit(error = aEncoder.WriteData(reinterpret_cast<const uint8_t *>(&aDiscovery.mCallback),
|
||||
sizeof(aDiscovery.mCallback)));
|
||||
|
||||
exit:
|
||||
return error;
|
||||
}
|
||||
|
||||
template <>
|
||||
otError EncodeDnssdDiscovery<otPlatDnssdAddressResolver>(Encoder &aEncoder,
|
||||
const otPlatDnssdAddressResolver &aDiscovery)
|
||||
{
|
||||
otError error = OT_ERROR_NONE;
|
||||
|
||||
SuccessOrExit(error = aEncoder.WriteUtf8(aDiscovery.mHostName));
|
||||
SuccessOrExit(error = aEncoder.WriteUint32(aDiscovery.mInfraIfIndex));
|
||||
SuccessOrExit(error = aEncoder.WriteData(reinterpret_cast<const uint8_t *>(&aDiscovery.mCallback),
|
||||
sizeof(aDiscovery.mCallback)));
|
||||
|
||||
exit:
|
||||
return error;
|
||||
}
|
||||
|
||||
otError EncodeDnssdTxtResult(Encoder &aEncoder,
|
||||
const otPlatDnssdTxtResult &aTxtResult,
|
||||
const uint8_t *aCallbackData,
|
||||
uint16_t aCallbackDataLen)
|
||||
{
|
||||
otError error = OT_ERROR_NONE;
|
||||
|
||||
SuccessOrExit(error = aEncoder.WriteUtf8(aTxtResult.mServiceInstance));
|
||||
SuccessOrExit(error = aEncoder.WriteUtf8(aTxtResult.mServiceType));
|
||||
if (aTxtResult.mTxtData != nullptr && aTxtResult.mTxtDataLength > 0)
|
||||
{
|
||||
SuccessOrExit(error = aEncoder.WriteDataWithLen(aTxtResult.mTxtData, aTxtResult.mTxtDataLength));
|
||||
}
|
||||
else
|
||||
{
|
||||
SuccessOrExit(error = aEncoder.WriteDataWithLen(nullptr, 0));
|
||||
}
|
||||
SuccessOrExit(error = aEncoder.WriteUint32(aTxtResult.mTtl));
|
||||
SuccessOrExit(error = aEncoder.WriteUint32(aTxtResult.mInfraIfIndex));
|
||||
SuccessOrExit(error = aEncoder.WriteData(aCallbackData, aCallbackDataLen));
|
||||
|
||||
exit:
|
||||
return error;
|
||||
}
|
||||
|
||||
otError DecodeDnssdTxtResolver(Decoder &aDecoder,
|
||||
otPlatDnssdTxtResolver &aTxtResolver,
|
||||
const uint8_t *&aCallbackData,
|
||||
uint16_t &aCallbackDataLen)
|
||||
{
|
||||
otError error = OT_ERROR_NONE;
|
||||
|
||||
SuccessOrExit(error = aDecoder.ReadUtf8(aTxtResolver.mServiceInstance));
|
||||
SuccessOrExit(error = aDecoder.ReadUtf8(aTxtResolver.mServiceType));
|
||||
SuccessOrExit(error = aDecoder.ReadUint32(aTxtResolver.mInfraIfIndex));
|
||||
SuccessOrExit(error = aDecoder.ReadData(aCallbackData, aCallbackDataLen));
|
||||
|
||||
exit:
|
||||
return error;
|
||||
}
|
||||
|
||||
otError DecodeDnssdTxtResult(Decoder &aDecoder,
|
||||
otPlatDnssdTxtResult &aTxtResult,
|
||||
const uint8_t *&aCallbackData,
|
||||
uint16_t &aCallbackDataLen)
|
||||
{
|
||||
otError error = OT_ERROR_NONE;
|
||||
|
||||
SuccessOrExit(error = aDecoder.ReadUtf8(aTxtResult.mServiceInstance));
|
||||
SuccessOrExit(error = aDecoder.ReadUtf8(aTxtResult.mServiceType));
|
||||
SuccessOrExit(error = aDecoder.ReadDataWithLen(aTxtResult.mTxtData, aTxtResult.mTxtDataLength));
|
||||
|
||||
if (aTxtResult.mTxtDataLength == 0)
|
||||
{
|
||||
aTxtResult.mTxtData = nullptr;
|
||||
}
|
||||
|
||||
SuccessOrExit(error = aDecoder.ReadUint32(aTxtResult.mTtl));
|
||||
SuccessOrExit(error = aDecoder.ReadUint32(aTxtResult.mInfraIfIndex));
|
||||
SuccessOrExit(error = aDecoder.ReadData(aCallbackData, aCallbackDataLen));
|
||||
|
||||
exit:
|
||||
return error;
|
||||
}
|
||||
|
||||
otError EncodeDnssdAddressResult(Encoder &aEncoder,
|
||||
const otPlatDnssdAddressResult &aAddressResult,
|
||||
const uint8_t *aCallbackData,
|
||||
uint16_t aCallbackDataLen)
|
||||
{
|
||||
otError error = OT_ERROR_NONE;
|
||||
|
||||
SuccessOrExit(error = aEncoder.WriteUtf8(aAddressResult.mHostName));
|
||||
SuccessOrExit(error = aEncoder.WriteUint32(aAddressResult.mInfraIfIndex));
|
||||
SuccessOrExit(error = aEncoder.OpenStruct());
|
||||
|
||||
for (uint16_t i = 0; i < aAddressResult.mAddressesLength; i++)
|
||||
{
|
||||
SuccessOrExit(error = aEncoder.WriteIp6Address(aAddressResult.mAddresses[i].mAddress));
|
||||
SuccessOrExit(error = aEncoder.WriteUint32(aAddressResult.mAddresses[i].mTtl));
|
||||
}
|
||||
|
||||
SuccessOrExit(error = aEncoder.CloseStruct());
|
||||
SuccessOrExit(error = aEncoder.WriteData(aCallbackData, aCallbackDataLen));
|
||||
|
||||
exit:
|
||||
return error;
|
||||
}
|
||||
|
||||
otError DecodeDnssdAddressResolver(Decoder &aDecoder,
|
||||
otPlatDnssdAddressResolver &aAddressResolver,
|
||||
const uint8_t *&aCallbackData,
|
||||
uint16_t &aCallbackDataLen)
|
||||
{
|
||||
otError error = OT_ERROR_NONE;
|
||||
|
||||
SuccessOrExit(error = aDecoder.ReadUtf8(aAddressResolver.mHostName));
|
||||
SuccessOrExit(error = aDecoder.ReadUint32(aAddressResolver.mInfraIfIndex));
|
||||
SuccessOrExit(error = aDecoder.ReadData(aCallbackData, aCallbackDataLen));
|
||||
|
||||
exit:
|
||||
return error;
|
||||
}
|
||||
|
||||
otError DecodeDnssdAddressResult(Decoder &aDecoder,
|
||||
otPlatDnssdAddressResult &aAddressResult,
|
||||
otPlatDnssdAddressAndTtl *aAddressArray,
|
||||
uint16_t aAddressArraySize,
|
||||
const uint8_t *&aCallbackData,
|
||||
uint16_t &aCallbackDataLen)
|
||||
{
|
||||
otError error = OT_ERROR_NONE;
|
||||
uint16_t count = 0;
|
||||
|
||||
SuccessOrExit(error = aDecoder.ReadUtf8(aAddressResult.mHostName));
|
||||
SuccessOrExit(error = aDecoder.ReadUint32(aAddressResult.mInfraIfIndex));
|
||||
SuccessOrExit(error = aDecoder.OpenStruct());
|
||||
|
||||
while ((count < aAddressArraySize) && !aDecoder.IsAllReadInStruct())
|
||||
{
|
||||
SuccessOrExit(error = aDecoder.ReadIp6Address(aAddressArray[count].mAddress));
|
||||
SuccessOrExit(error = aDecoder.ReadUint32(aAddressArray[count].mTtl));
|
||||
count++;
|
||||
}
|
||||
|
||||
SuccessOrExit(error = aDecoder.CloseStruct());
|
||||
|
||||
aAddressResult.mAddresses = (count > 0) ? aAddressArray : nullptr;
|
||||
aAddressResult.mAddressesLength = count;
|
||||
SuccessOrExit(error = aDecoder.ReadData(aCallbackData, aCallbackDataLen));
|
||||
|
||||
exit:
|
||||
return error;
|
||||
}
|
||||
|
||||
} // namespace Spinel
|
||||
} // namespace ot
|
||||
|
||||
@@ -100,6 +100,32 @@ otError EncodeDnssdSrvResult(Encoder &aEncoder,
|
||||
const uint8_t *aCallbackData,
|
||||
uint16_t aCallbackDataLen);
|
||||
|
||||
/**
|
||||
* Use Spinel::Encode to encode a Dnssd TXT result.
|
||||
*
|
||||
* @param[in] aEncoder A reference to the encoder object.
|
||||
* @param[in] aTxtResult A reference to the TXT result.
|
||||
* @param[in] aCallbackData A pointer to the callback data.
|
||||
* @param[in] aCallbackDataLen The data length.
|
||||
*/
|
||||
otError EncodeDnssdTxtResult(Encoder &aEncoder,
|
||||
const otPlatDnssdTxtResult &aTxtResult,
|
||||
const uint8_t *aCallbackData,
|
||||
uint16_t aCallbackDataLen);
|
||||
|
||||
/**
|
||||
* Use Spinel::Encode to encode a Dnssd Address result.
|
||||
*
|
||||
* @param[in] aEncoder A reference to the encoder object.
|
||||
* @param[in] aAddressResult A reference to the Address result.
|
||||
* @param[in] aCallbackData A pointer to the callback data.
|
||||
* @param[in] aCallbackDataLen The data length.
|
||||
*/
|
||||
otError EncodeDnssdAddressResult(Encoder &aEncoder,
|
||||
const otPlatDnssdAddressResult &aAddressResult,
|
||||
const uint8_t *aCallbackData,
|
||||
uint16_t aCallbackDataLen);
|
||||
|
||||
/**
|
||||
* Use Spinel::Decoder to decode a SPINEL_PROP_DNSSD_HOST message to a otPlatDnssdHost.
|
||||
*
|
||||
@@ -210,6 +236,71 @@ otError DecodeDnssdSrvResult(Decoder &aDecoder,
|
||||
otPlatDnssdSrvResult &aSrvResult,
|
||||
const uint8_t *&aCallbackData,
|
||||
uint16_t &aCallbackDataLen);
|
||||
|
||||
/**
|
||||
* Use Spinel::Decoder to decode a SPINEL_PROP_DNSSD_TXT_RESOLVER message to a otPlatDnssdTxtResolver.
|
||||
*
|
||||
* @param[in] aDecoder A reference to the decoder object.
|
||||
* @param[out] aTxtResolver A reference to the TXT resolver.
|
||||
* @param[out] aCallbackData A reference to the pointer to the callback data.
|
||||
* @param[out] aCallbackDataLen A reference to the callback data length.
|
||||
*/
|
||||
otError DecodeDnssdTxtResolver(Decoder &aDecoder,
|
||||
otPlatDnssdTxtResolver &aTxtResolver,
|
||||
const uint8_t *&aCallbackData,
|
||||
uint16_t &aCallbackDataLen);
|
||||
|
||||
/**
|
||||
* Use Spinel::Decoder to decode a SPINEL_PROP_DNSSD_TXT_RESULT message to a otPlatDnssdTxtResult.
|
||||
*
|
||||
* @param[in] aDecoder A reference to the decoder object.
|
||||
* @param[out] aTxtResult A reference to the TXT result.
|
||||
* @param[out] aCallbackData A reference to the pointer to the callback data.
|
||||
* @param[out] aCallbackDataLen A reference to the callback data length.
|
||||
*/
|
||||
otError DecodeDnssdTxtResult(Decoder &aDecoder,
|
||||
otPlatDnssdTxtResult &aTxtResult,
|
||||
const uint8_t *&aCallbackData,
|
||||
uint16_t &aCallbackDataLen);
|
||||
|
||||
/**
|
||||
* Use Spinel::Decoder to decode a SPINEL_PROP_DNSSD_IP6_ADDRESS_RESOLVER message to a otPlatDnssdAddressResolver.
|
||||
*
|
||||
* @param[in] aDecoder A reference to the decoder object.
|
||||
* @param[out] aAddressResolver A reference to the Address resolver.
|
||||
* @param[out] aCallbackData A reference to the pointer to the callback data.
|
||||
* @param[out] aCallbackDataLen A reference to the callback data length.
|
||||
*/
|
||||
otError DecodeDnssdAddressResolver(Decoder &aDecoder,
|
||||
otPlatDnssdAddressResolver &aAddressResolver,
|
||||
const uint8_t *&aCallbackData,
|
||||
uint16_t &aCallbackDataLen);
|
||||
|
||||
/**
|
||||
* Use Spinel::Decoder to decode a SPINEL_PROP_DNSSD_IP6_ADDRESS_RESULT message to a otPlatDnssdAddressResult.
|
||||
*
|
||||
* Also used for `SPINEL_PROP_DNSSD_IP4_ADDRESS_RESULT` (same wire format, IPv4 uses IPv4-mapped IPv6 address).
|
||||
*
|
||||
* Entries are read from the struct until it is exhausted or @p aAddressArray is full. If the
|
||||
* struct contains more entries than @p aAddressArraySize, the extra entries are silently ignored and
|
||||
* `mAddressesLength` reports the number actually copied.
|
||||
*
|
||||
* @param[in] aDecoder A reference to the decoder object.
|
||||
* @param[out] aAddressResult A reference to the Address result.
|
||||
* @param[out] aAddressArray Caller-provided storage to copy address and TTL entries.
|
||||
* @param[in] aAddressArraySize The maximum number of entries that fit in @p aAddressArray.
|
||||
* @param[out] aCallbackData A reference to the pointer to the callback data.
|
||||
* @param[out] aCallbackDataLen A reference to the callback data length.
|
||||
*
|
||||
* @retval OT_ERROR_NONE Successfully decoded the address result.
|
||||
* @retval OT_ERROR_PARSE Malformed frame.
|
||||
*/
|
||||
otError DecodeDnssdAddressResult(Decoder &aDecoder,
|
||||
otPlatDnssdAddressResult &aAddressResult,
|
||||
otPlatDnssdAddressAndTtl *aAddressArray,
|
||||
uint16_t aAddressArraySize,
|
||||
const uint8_t *&aCallbackData,
|
||||
uint16_t &aCallbackDataLen);
|
||||
} // namespace Spinel
|
||||
} // namespace ot
|
||||
|
||||
|
||||
+104
-5
@@ -338,6 +338,48 @@ public:
|
||||
*/
|
||||
void DnssdStopSrvResolver(const otPlatDnssdSrvResolver *aResolver);
|
||||
|
||||
/**
|
||||
* Starts a TXT resolver.
|
||||
*
|
||||
* @param[in] aResolver The resolver to be started.
|
||||
*/
|
||||
void DnssdStartTxtResolver(const otPlatDnssdTxtResolver *aResolver);
|
||||
|
||||
/**
|
||||
* Stops a TXT resolver.
|
||||
*
|
||||
* @param[in] aResolver The resolver to be stopped.
|
||||
*/
|
||||
void DnssdStopTxtResolver(const otPlatDnssdTxtResolver *aResolver);
|
||||
|
||||
/**
|
||||
* Starts an IPv6 address resolver.
|
||||
*
|
||||
* @param[in] aResolver The resolver to be started.
|
||||
*/
|
||||
void DnssdStartIp6AddressResolver(const otPlatDnssdAddressResolver *aResolver);
|
||||
|
||||
/**
|
||||
* Stops an IPv6 address resolver.
|
||||
*
|
||||
* @param[in] aResolver The resolver to be stopped.
|
||||
*/
|
||||
void DnssdStopIp6AddressResolver(const otPlatDnssdAddressResolver *aResolver);
|
||||
|
||||
/**
|
||||
* Starts an IPv4 address resolver.
|
||||
*
|
||||
* @param[in] aResolver The resolver to be started.
|
||||
*/
|
||||
void DnssdStartIp4AddressResolver(const otPlatDnssdAddressResolver *aResolver);
|
||||
|
||||
/**
|
||||
* Stops an IPv4 address resolver.
|
||||
*
|
||||
* @param[in] aResolver The resolver to be stopped.
|
||||
*/
|
||||
void DnssdStopIp4AddressResolver(const otPlatDnssdAddressResolver *aResolver);
|
||||
|
||||
/**
|
||||
* Gets the Dnssd state.
|
||||
*
|
||||
@@ -585,6 +627,7 @@ protected:
|
||||
uint16_t aSockPort,
|
||||
void *aContext);
|
||||
void HandleUdpForwardStream(otMessage *aMessage, uint16_t aPeerPort, otIp6Address &aPeerAddr, uint16_t aPort);
|
||||
|
||||
#endif // OPENTHREAD_CONFIG_UDP_FORWARD_ENABLE
|
||||
#endif // OPENTHREAD_MTD || OPENTHREAD_FTD
|
||||
|
||||
@@ -883,6 +926,11 @@ protected:
|
||||
|
||||
#if OPENTHREAD_CONFIG_NCP_DNSSD_ENABLE && OPENTHREAD_CONFIG_PLATFORM_DNSSD_ENABLE
|
||||
|
||||
static constexpr uint16_t kDnssdMaxAddressResultEntries = OPENTHREAD_CONFIG_NCP_DNSSD_MAX_ADDRESS_RESULT_ENTRIES;
|
||||
|
||||
static_assert(kDnssdMaxAddressResultEntries >= 1,
|
||||
"OPENTHREAD_CONFIG_NCP_DNSSD_MAX_ADDRESS_RESULT_ENTRIES must be >= 1");
|
||||
|
||||
template <typename DnssdObjType> struct DnssdDiscoveryPropKeyFor;
|
||||
|
||||
template <typename DnssdObjType>
|
||||
@@ -903,7 +951,7 @@ protected:
|
||||
SuccessOrExit(error = mEncoder.EndFrame());
|
||||
|
||||
exit:
|
||||
if (error != OT_ERROR_NONE)
|
||||
if (error != OT_ERROR_NONE && aCallback != nullptr)
|
||||
{
|
||||
aCallback(mInstance, aRequestId, error);
|
||||
}
|
||||
@@ -912,10 +960,14 @@ protected:
|
||||
/**
|
||||
* Template for making service discovery.
|
||||
*
|
||||
* DnssdDiscoveryType can be: otPlatDnssdBrowser, otPlatDnssdSrvResolver, otPlatDnssdTxtResolver,
|
||||
* otPlatDnssdAddressResolver and otPlatDnssdRecordQuerier.
|
||||
* `DnssdDiscoveryType` can be `otPlatDnssdBrowser`, `otPlatDnssdSrvResolver`, `otPlatDnssdTxtResolver`,
|
||||
* or `otPlatDnssdAddressResolver`.
|
||||
*
|
||||
* Use the 2-parameter overload for browser/SRV/TXT resolvers (one C type, one Spinel property).
|
||||
* For address resolvers (one C type, two Spinel properties), pass the Spinel property key explicitly.
|
||||
*/
|
||||
template <typename DnssdDiscoveryType> void DnssdUpdateDiscovery(const DnssdDiscoveryType *aDiscovery, bool aStart)
|
||||
template <typename DnssdDiscoveryType>
|
||||
void DnssdUpdateDiscovery(const DnssdDiscoveryType *aDiscovery, bool aStart, spinel_prop_key_t aPropKey)
|
||||
{
|
||||
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;
|
||||
@@ -923,7 +975,7 @@ protected:
|
||||
VerifyOrExit(aDiscovery != nullptr);
|
||||
VerifyOrExit(mDnssdState == OT_PLAT_DNSSD_READY);
|
||||
|
||||
SuccessOrExit(mEncoder.BeginFrame(header, cmd, DnssdDiscoveryPropKeyFor<DnssdDiscoveryType>::Key));
|
||||
SuccessOrExit(mEncoder.BeginFrame(header, cmd, aPropKey));
|
||||
SuccessOrExit(Spinel::EncodeDnssdDiscovery(mEncoder, *aDiscovery));
|
||||
SuccessOrExit(mEncoder.EndFrame());
|
||||
|
||||
@@ -931,6 +983,48 @@ protected:
|
||||
return;
|
||||
}
|
||||
|
||||
template <typename DnssdDiscoveryType> void DnssdUpdateDiscovery(const DnssdDiscoveryType *aDiscovery, bool aStart)
|
||||
{
|
||||
DnssdUpdateDiscovery(aDiscovery, aStart, DnssdDiscoveryPropKeyFor<DnssdDiscoveryType>::Key);
|
||||
}
|
||||
|
||||
/**
|
||||
* Handles `SPINEL_PROP_DNSSD_IP6_ADDRESS_RESULT` and `SPINEL_PROP_DNSSD_IP4_ADDRESS_RESULT` property sets.
|
||||
*/
|
||||
otError HandleDnssdAddressResultPropertySet(void);
|
||||
|
||||
/**
|
||||
* Invokes a DNS-SD result callback recovered from Spinel callback context.
|
||||
*
|
||||
* @tparam ResultType The DNS-SD result type (e.g. `otPlatDnssdTxtResult`).
|
||||
*
|
||||
* @param[in] aResult The decoded result to pass to the callback.
|
||||
* @param[in] aContext Pointer to the serialized callback context.
|
||||
* @param[in] aContextLen Length of @p aContext in bytes.
|
||||
*
|
||||
* @retval OT_ERROR_NONE Callback invoked (or skipped if null).
|
||||
* @retval OT_ERROR_PARSE Context length does not match callback pointer size.
|
||||
*/
|
||||
template <typename ResultType>
|
||||
otError InvokeDnssdResultCallback(const ResultType &aResult, const uint8_t *aContext, uint16_t aContextLen)
|
||||
{
|
||||
typedef void (*Callback)(otInstance *aInstance, const ResultType *aResult);
|
||||
|
||||
otError error = OT_ERROR_NONE;
|
||||
Callback callback = nullptr;
|
||||
|
||||
VerifyOrExit(aContextLen == sizeof(Callback), error = OT_ERROR_PARSE);
|
||||
memcpy(&callback, aContext, aContextLen);
|
||||
|
||||
if (callback != nullptr)
|
||||
{
|
||||
callback(mInstance, &aResult);
|
||||
}
|
||||
|
||||
exit:
|
||||
return error;
|
||||
}
|
||||
|
||||
otPlatDnssdState mDnssdState;
|
||||
#endif // OPENTHREAD_CONFIG_NCP_DNSSD_ENABLE && OPENTHREAD_CONFIG_PLATFORM_DNSSD_ENABLE
|
||||
|
||||
@@ -965,6 +1059,11 @@ template <> struct NcpBase::DnssdDiscoveryPropKeyFor<otPlatDnssdSrvResolver>
|
||||
{
|
||||
static constexpr spinel_prop_key_t Key = SPINEL_PROP_DNSSD_SRV_RESOLVER;
|
||||
};
|
||||
|
||||
template <> struct NcpBase::DnssdDiscoveryPropKeyFor<otPlatDnssdTxtResolver>
|
||||
{
|
||||
static constexpr spinel_prop_key_t Key = SPINEL_PROP_DNSSD_TXT_RESOLVER;
|
||||
};
|
||||
#endif
|
||||
|
||||
} // namespace Ncp
|
||||
|
||||
@@ -546,6 +546,9 @@ NcpBase::PropertyHandler NcpBase::FindSetPropertyHandler(spinel_prop_key_t aKey)
|
||||
OT_NCP_SET_HANDLER_ENTRY(SPINEL_PROP_DNSSD_REQUEST_RESULT),
|
||||
OT_NCP_SET_HANDLER_ENTRY(SPINEL_PROP_DNSSD_BROWSE_RESULT),
|
||||
OT_NCP_SET_HANDLER_ENTRY(SPINEL_PROP_DNSSD_SRV_RESULT),
|
||||
OT_NCP_SET_HANDLER_ENTRY(SPINEL_PROP_DNSSD_TXT_RESULT),
|
||||
OT_NCP_SET_HANDLER_ENTRY(SPINEL_PROP_DNSSD_IP6_ADDRESS_RESULT),
|
||||
OT_NCP_SET_HANDLER_ENTRY(SPINEL_PROP_DNSSD_IP4_ADDRESS_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),
|
||||
|
||||
+85
-18
@@ -1707,6 +1707,36 @@ void NcpBase::DnssdStopSrvResolver(const otPlatDnssdSrvResolver *aResolver)
|
||||
DnssdUpdateDiscovery(aResolver, /* aStart */ false);
|
||||
}
|
||||
|
||||
void NcpBase::DnssdStartTxtResolver(const otPlatDnssdTxtResolver *aResolver)
|
||||
{
|
||||
DnssdUpdateDiscovery(aResolver, /* aStart */ true);
|
||||
}
|
||||
|
||||
void NcpBase::DnssdStopTxtResolver(const otPlatDnssdTxtResolver *aResolver)
|
||||
{
|
||||
DnssdUpdateDiscovery(aResolver, /* aStart */ false);
|
||||
}
|
||||
|
||||
void NcpBase::DnssdStartIp6AddressResolver(const otPlatDnssdAddressResolver *aResolver)
|
||||
{
|
||||
DnssdUpdateDiscovery(aResolver, /* aStart */ true, SPINEL_PROP_DNSSD_IP6_ADDRESS_RESOLVER);
|
||||
}
|
||||
|
||||
void NcpBase::DnssdStopIp6AddressResolver(const otPlatDnssdAddressResolver *aResolver)
|
||||
{
|
||||
DnssdUpdateDiscovery(aResolver, /* aStart */ false, SPINEL_PROP_DNSSD_IP6_ADDRESS_RESOLVER);
|
||||
}
|
||||
|
||||
void NcpBase::DnssdStartIp4AddressResolver(const otPlatDnssdAddressResolver *aResolver)
|
||||
{
|
||||
DnssdUpdateDiscovery(aResolver, /* aStart */ true, SPINEL_PROP_DNSSD_IP4_ADDRESS_RESOLVER);
|
||||
}
|
||||
|
||||
void NcpBase::DnssdStopIp4AddressResolver(const otPlatDnssdAddressResolver *aResolver)
|
||||
{
|
||||
DnssdUpdateDiscovery(aResolver, /* aStart */ false, SPINEL_PROP_DNSSD_IP4_ADDRESS_RESOLVER);
|
||||
}
|
||||
|
||||
otPlatDnssdState NcpBase::DnssdGetState(void) { return mDnssdState; }
|
||||
|
||||
template <> otError NcpBase::HandlePropertySet<SPINEL_PROP_DNSSD_STATE>(void)
|
||||
@@ -1739,8 +1769,11 @@ template <> otError NcpBase::HandlePropertySet<SPINEL_PROP_DNSSD_REQUEST_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));
|
||||
memcpy(&callback, context, contextLen);
|
||||
if (callback != nullptr)
|
||||
{
|
||||
callback(mInstance, requestId, static_cast<otError>(result));
|
||||
}
|
||||
|
||||
exit:
|
||||
return error;
|
||||
@@ -1748,16 +1781,13 @@ exit:
|
||||
|
||||
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;
|
||||
otError error = OT_ERROR_NONE;
|
||||
otPlatDnssdBrowseResult browseResult;
|
||||
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);
|
||||
SuccessOrExit(error = InvokeDnssdResultCallback(browseResult, context, contextLen));
|
||||
|
||||
exit:
|
||||
return error;
|
||||
@@ -1765,16 +1795,53 @@ exit:
|
||||
|
||||
template <> otError NcpBase::HandlePropertySet<SPINEL_PROP_DNSSD_SRV_RESULT>(void)
|
||||
{
|
||||
otError error = OT_ERROR_NONE;
|
||||
otPlatDnssdSrvResult srvResult;
|
||||
otPlatDnssdSrvCallback callback = nullptr;
|
||||
const uint8_t *context;
|
||||
uint16_t contextLen;
|
||||
otError error = OT_ERROR_NONE;
|
||||
otPlatDnssdSrvResult srvResult;
|
||||
const uint8_t *context;
|
||||
uint16_t contextLen;
|
||||
|
||||
SuccessOrExit(error = DecodeDnssdSrvResult(mDecoder, srvResult, context, contextLen));
|
||||
VerifyOrExit(contextLen == sizeof(otPlatDnssdSrvCallback), error = OT_ERROR_PARSE);
|
||||
callback = *reinterpret_cast<const otPlatDnssdSrvCallback *>(context);
|
||||
callback(mInstance, &srvResult);
|
||||
SuccessOrExit(error = InvokeDnssdResultCallback(srvResult, context, contextLen));
|
||||
|
||||
exit:
|
||||
return error;
|
||||
}
|
||||
|
||||
template <> otError NcpBase::HandlePropertySet<SPINEL_PROP_DNSSD_TXT_RESULT>(void)
|
||||
{
|
||||
otError error = OT_ERROR_NONE;
|
||||
otPlatDnssdTxtResult txtResult;
|
||||
const uint8_t *context;
|
||||
uint16_t contextLen;
|
||||
|
||||
SuccessOrExit(error = DecodeDnssdTxtResult(mDecoder, txtResult, context, contextLen));
|
||||
SuccessOrExit(error = InvokeDnssdResultCallback(txtResult, context, contextLen));
|
||||
|
||||
exit:
|
||||
return error;
|
||||
}
|
||||
|
||||
template <> otError NcpBase::HandlePropertySet<SPINEL_PROP_DNSSD_IP6_ADDRESS_RESULT>(void)
|
||||
{
|
||||
return HandleDnssdAddressResultPropertySet();
|
||||
}
|
||||
|
||||
template <> otError NcpBase::HandlePropertySet<SPINEL_PROP_DNSSD_IP4_ADDRESS_RESULT>(void)
|
||||
{
|
||||
return HandleDnssdAddressResultPropertySet();
|
||||
}
|
||||
|
||||
otError NcpBase::HandleDnssdAddressResultPropertySet(void)
|
||||
{
|
||||
otError error = OT_ERROR_NONE;
|
||||
otPlatDnssdAddressResult addrResult;
|
||||
otPlatDnssdAddressAndTtl addrArray[kDnssdMaxAddressResultEntries];
|
||||
const uint8_t *context;
|
||||
uint16_t contextLen;
|
||||
|
||||
SuccessOrExit(error = DecodeDnssdAddressResult(mDecoder, addrResult, addrArray, kDnssdMaxAddressResultEntries,
|
||||
context, contextLen));
|
||||
SuccessOrExit(error = InvokeDnssdResultCallback(addrResult, context, contextLen));
|
||||
|
||||
exit:
|
||||
return error;
|
||||
|
||||
@@ -185,6 +185,23 @@
|
||||
#define OPENTHREAD_CONFIG_NCP_DNSSD_ENABLE 0
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @def OPENTHREAD_CONFIG_NCP_DNSSD_MAX_ADDRESS_RESULT_ENTRIES
|
||||
*
|
||||
* The maximum number of `otPlatDnssdAddressAndTtl` entries the NCP decodes from a single
|
||||
* `SPINEL_PROP_DNSSD_IP6_ADDRESS_RESULT` or `SPINEL_PROP_DNSSD_IP4_ADDRESS_RESULT` property update.
|
||||
*
|
||||
* Each entry is stored on the stack while handling the property; increase this only if the host may
|
||||
* send larger address lists and the platform can afford the extra stack usage.
|
||||
*
|
||||
* Must be at least 1. If the Spinel address array contains more entries than this limit, the NCP
|
||||
* reports the first `OPENTHREAD_CONFIG_NCP_DNSSD_MAX_ADDRESS_RESULT_ENTRIES` entries and ignores
|
||||
* the rest.
|
||||
*/
|
||||
#ifndef OPENTHREAD_CONFIG_NCP_DNSSD_MAX_ADDRESS_RESULT_ENTRIES
|
||||
#define OPENTHREAD_CONFIG_NCP_DNSSD_MAX_ADDRESS_RESULT_ENTRIES 32
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @def OPENTHREAD_CONFIG_NCP_CLI_STREAM_ENABLE
|
||||
*
|
||||
|
||||
@@ -136,37 +136,37 @@ void otPlatDnssdStopSrvResolver(otInstance *aInstance, const otPlatDnssdSrvResol
|
||||
void otPlatDnssdStartTxtResolver(otInstance *aInstance, const otPlatDnssdTxtResolver *aResolver)
|
||||
{
|
||||
OT_UNUSED_VARIABLE(aInstance);
|
||||
OT_UNUSED_VARIABLE(aResolver);
|
||||
ot::Ncp::NcpBase::GetNcpInstance()->DnssdStartTxtResolver(aResolver);
|
||||
}
|
||||
|
||||
void otPlatDnssdStopTxtResolver(otInstance *aInstance, const otPlatDnssdTxtResolver *aResolver)
|
||||
{
|
||||
OT_UNUSED_VARIABLE(aInstance);
|
||||
OT_UNUSED_VARIABLE(aResolver);
|
||||
ot::Ncp::NcpBase::GetNcpInstance()->DnssdStopTxtResolver(aResolver);
|
||||
}
|
||||
|
||||
void otPlatDnssdStartIp6AddressResolver(otInstance *aInstance, const otPlatDnssdAddressResolver *aResolver)
|
||||
{
|
||||
OT_UNUSED_VARIABLE(aInstance);
|
||||
OT_UNUSED_VARIABLE(aResolver);
|
||||
ot::Ncp::NcpBase::GetNcpInstance()->DnssdStartIp6AddressResolver(aResolver);
|
||||
}
|
||||
|
||||
void otPlatDnssdStopIp6AddressResolver(otInstance *aInstance, const otPlatDnssdAddressResolver *aResolver)
|
||||
{
|
||||
OT_UNUSED_VARIABLE(aInstance);
|
||||
OT_UNUSED_VARIABLE(aResolver);
|
||||
ot::Ncp::NcpBase::GetNcpInstance()->DnssdStopIp6AddressResolver(aResolver);
|
||||
}
|
||||
|
||||
void otPlatDnssdStartIp4AddressResolver(otInstance *aInstance, const otPlatDnssdAddressResolver *aResolver)
|
||||
{
|
||||
OT_UNUSED_VARIABLE(aInstance);
|
||||
OT_UNUSED_VARIABLE(aResolver);
|
||||
ot::Ncp::NcpBase::GetNcpInstance()->DnssdStartIp4AddressResolver(aResolver);
|
||||
}
|
||||
|
||||
void otPlatDnssdStopIp4AddressResolver(otInstance *aInstance, const otPlatDnssdAddressResolver *aResolver)
|
||||
{
|
||||
OT_UNUSED_VARIABLE(aInstance);
|
||||
OT_UNUSED_VARIABLE(aResolver);
|
||||
ot::Ncp::NcpBase::GetNcpInstance()->DnssdStopIp4AddressResolver(aResolver);
|
||||
}
|
||||
|
||||
void otPlatDnssdStartRecordQuerier(otInstance *aInstance, const otPlatDnssdRecordQuerier *aQuerier)
|
||||
|
||||
@@ -316,6 +316,152 @@ void TestNcpDnssdSrvResolve(void)
|
||||
VerifyOrQuit(sDnssdSrvCallbackInvoked);
|
||||
}
|
||||
|
||||
static bool sDnssdTxtCallbackInvoked = false;
|
||||
|
||||
static const uint8_t kTestTxtData[] = {0x01, 0x02, 0x03};
|
||||
|
||||
static void TestDnssdTxtCallback(otInstance *aInstance, const otPlatDnssdTxtResult *aResult)
|
||||
{
|
||||
OT_UNUSED_VARIABLE(aInstance);
|
||||
|
||||
VerifyOrQuit(strcmp(aResult->mServiceInstance, "GAT-X303 #1") == 0);
|
||||
VerifyOrQuit(strcmp(aResult->mServiceType, "_ms._tcp") == 0);
|
||||
VerifyOrQuit(aResult->mTxtDataLength == sizeof(kTestTxtData));
|
||||
VerifyOrQuit(aResult->mTxtData != nullptr);
|
||||
VerifyOrQuit(memcmp(aResult->mTxtData, kTestTxtData, sizeof(kTestTxtData)) == 0);
|
||||
VerifyOrQuit(aResult->mTtl == 90);
|
||||
VerifyOrQuit(aResult->mInfraIfIndex == 1);
|
||||
|
||||
sDnssdTxtCallbackInvoked = true;
|
||||
}
|
||||
|
||||
static otError GenerateSpinelDnssdTxtResultFrame(const otPlatDnssdTxtResult &aTxtResult, uint8_t *aBuf, uint16_t &aLen)
|
||||
{
|
||||
otError error = OT_ERROR_NONE;
|
||||
uint8_t buf[kMaxSpinelBufferSize];
|
||||
Spinel::Buffer ncpBuffer(buf, kMaxSpinelBufferSize);
|
||||
Spinel::Encoder encoder(ncpBuffer);
|
||||
otPlatDnssdTxtCallback callback = &TestDnssdTxtCallback;
|
||||
|
||||
uint8_t header = SPINEL_HEADER_FLAG | 0 /* Iid */ | 1 /* Tid */;
|
||||
SuccessOrExit(error = encoder.BeginFrame(header, SPINEL_CMD_PROP_VALUE_SET, SPINEL_PROP_DNSSD_TXT_RESULT));
|
||||
SuccessOrExit(error = EncodeDnssdTxtResult(encoder, aTxtResult, 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 TestNcpDnssdTxtResolve(void)
|
||||
{
|
||||
Instance *instance = static_cast<Instance *>(testInitInstance());
|
||||
Ncp::NcpBase ncpBase(instance);
|
||||
uint8_t recvBuf[kMaxSpinelBufferSize];
|
||||
uint16_t recvLen;
|
||||
otPlatDnssdTxtResolver resolver;
|
||||
otPlatDnssdTxtResult txtResult;
|
||||
|
||||
resolver.mServiceInstance = "GAT-X303 #1";
|
||||
resolver.mServiceType = "_ms._tcp";
|
||||
resolver.mInfraIfIndex = 1;
|
||||
resolver.mCallback = TestDnssdTxtCallback;
|
||||
|
||||
otPlatDnssdStartTxtResolver(instance, &resolver);
|
||||
|
||||
txtResult.mServiceInstance = "GAT-X303 #1";
|
||||
txtResult.mServiceType = "_ms._tcp";
|
||||
txtResult.mTxtData = kTestTxtData;
|
||||
txtResult.mTxtDataLength = sizeof(kTestTxtData);
|
||||
txtResult.mTtl = 90;
|
||||
txtResult.mInfraIfIndex = 1;
|
||||
|
||||
SuccessOrQuit(GenerateSpinelDnssdTxtResultFrame(txtResult, recvBuf, recvLen));
|
||||
|
||||
ncpBase.HandleReceive(recvBuf, recvLen);
|
||||
|
||||
VerifyOrQuit(sDnssdTxtCallbackInvoked);
|
||||
}
|
||||
|
||||
static bool sDnssdAddressCallbackInvoked = false;
|
||||
|
||||
static void TestDnssdAddressCallback(otInstance *aInstance, const otPlatDnssdAddressResult *aResult)
|
||||
{
|
||||
OT_UNUSED_VARIABLE(aInstance);
|
||||
|
||||
VerifyOrQuit(strcmp(aResult->mHostName, "my-host") == 0);
|
||||
VerifyOrQuit(aResult->mInfraIfIndex == 3);
|
||||
VerifyOrQuit(aResult->mAddressesLength == 2);
|
||||
VerifyOrQuit(aResult->mAddresses != nullptr);
|
||||
VerifyOrQuit(aResult->mAddresses[0].mTtl == 60);
|
||||
VerifyOrQuit(aResult->mAddresses[1].mTtl == 120);
|
||||
VerifyOrQuit(aResult->mAddresses[0].mAddress.mFields.m8[0] == 0x11);
|
||||
VerifyOrQuit(aResult->mAddresses[1].mAddress.mFields.m8[0] == 0x22);
|
||||
|
||||
sDnssdAddressCallbackInvoked = true;
|
||||
}
|
||||
|
||||
static otError GenerateSpinelDnssdAddressResultFrame(const otPlatDnssdAddressResult &aAddressResult,
|
||||
uint8_t *aBuf,
|
||||
uint16_t &aLen)
|
||||
{
|
||||
otError error = OT_ERROR_NONE;
|
||||
uint8_t buf[kMaxSpinelBufferSize];
|
||||
Spinel::Buffer ncpBuffer(buf, kMaxSpinelBufferSize);
|
||||
Spinel::Encoder encoder(ncpBuffer);
|
||||
otPlatDnssdAddressCallback callback = &TestDnssdAddressCallback;
|
||||
|
||||
uint8_t header = SPINEL_HEADER_FLAG | 0 /* Iid */ | 1 /* Tid */;
|
||||
SuccessOrExit(error = encoder.BeginFrame(header, SPINEL_CMD_PROP_VALUE_SET, SPINEL_PROP_DNSSD_IP6_ADDRESS_RESULT));
|
||||
SuccessOrExit(error = EncodeDnssdAddressResult(encoder, aAddressResult,
|
||||
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 TestNcpDnssdAddressResolve(void)
|
||||
{
|
||||
Instance *instance = static_cast<Instance *>(testInitInstance());
|
||||
Ncp::NcpBase ncpBase(instance);
|
||||
uint8_t recvBuf[kMaxSpinelBufferSize];
|
||||
uint16_t recvLen;
|
||||
otPlatDnssdAddressResolver resolver;
|
||||
otPlatDnssdAddressResult addrResult;
|
||||
otPlatDnssdAddressAndTtl addrArray[2];
|
||||
|
||||
resolver.mHostName = "my-host";
|
||||
resolver.mInfraIfIndex = 3;
|
||||
resolver.mCallback = TestDnssdAddressCallback;
|
||||
|
||||
otPlatDnssdStartIp6AddressResolver(instance, &resolver);
|
||||
|
||||
memset(&addrArray[0].mAddress, 0x11, sizeof(addrArray[0].mAddress));
|
||||
addrArray[0].mTtl = 60;
|
||||
memset(&addrArray[1].mAddress, 0x22, sizeof(addrArray[1].mAddress));
|
||||
addrArray[1].mTtl = 120;
|
||||
|
||||
addrResult.mHostName = "my-host";
|
||||
addrResult.mInfraIfIndex = 3;
|
||||
addrResult.mAddresses = addrArray;
|
||||
addrResult.mAddressesLength = 2;
|
||||
|
||||
SuccessOrQuit(GenerateSpinelDnssdAddressResultFrame(addrResult, recvBuf, recvLen));
|
||||
|
||||
ncpBase.HandleReceive(recvBuf, recvLen);
|
||||
|
||||
VerifyOrQuit(sDnssdAddressCallbackInvoked);
|
||||
}
|
||||
|
||||
} // namespace ot
|
||||
|
||||
#endif // OPENTHREAD_CONFIG_NCP_DNSSD_ENABLE && OPENTHREAD_CONFIG_PLATFORM_DNSSD_ENABLE
|
||||
@@ -327,6 +473,8 @@ int main(void)
|
||||
ot::TestNcpDnssdRegistrations();
|
||||
ot::TestNcpDnssdBrowse();
|
||||
ot::TestNcpDnssdSrvResolve();
|
||||
ot::TestNcpDnssdTxtResolve();
|
||||
ot::TestNcpDnssdAddressResolve();
|
||||
#endif
|
||||
printf("All tests passed\n");
|
||||
return 0;
|
||||
|
||||
@@ -29,6 +29,7 @@
|
||||
#include <string.h>
|
||||
|
||||
#include "test_util.hpp"
|
||||
#include "common/code_utils.hpp"
|
||||
#include "lib/spinel/spinel_prop_codec.hpp"
|
||||
|
||||
namespace ot {
|
||||
@@ -53,6 +54,18 @@ static void FakeDnssdSrvCallback(otInstance *aInstance, const otPlatDnssdSrvResu
|
||||
OT_UNUSED_VARIABLE(aResult);
|
||||
}
|
||||
|
||||
static void FakeDnssdTxtCallback(otInstance *aInstance, const otPlatDnssdTxtResult *aResult)
|
||||
{
|
||||
OT_UNUSED_VARIABLE(aInstance);
|
||||
OT_UNUSED_VARIABLE(aResult);
|
||||
}
|
||||
|
||||
static void FakeDnssdAddressCallback(otInstance *aInstance, const otPlatDnssdAddressResult *aResult)
|
||||
{
|
||||
OT_UNUSED_VARIABLE(aInstance);
|
||||
OT_UNUSED_VARIABLE(aResult);
|
||||
}
|
||||
|
||||
static constexpr uint16_t kMaxSpinelBufferSize = 2048;
|
||||
|
||||
void TestDnssd(void)
|
||||
@@ -454,6 +467,306 @@ void TestDnssdSrvResult(void)
|
||||
VerifyOrQuit(*reinterpret_cast<const otPlatDnssdSrvCallback *>(callbackData) == FakeDnssdSrvCallback);
|
||||
}
|
||||
|
||||
void TestDnssdTxtResolver(void)
|
||||
{
|
||||
uint8_t buf[kMaxSpinelBufferSize];
|
||||
uint16_t len;
|
||||
Spinel::Buffer ncpBuffer(buf, kMaxSpinelBufferSize);
|
||||
Spinel::Encoder encoder(ncpBuffer);
|
||||
Spinel::Decoder decoder;
|
||||
uint8_t header;
|
||||
unsigned int command;
|
||||
unsigned int propKey;
|
||||
otError error = OT_ERROR_NONE;
|
||||
|
||||
otPlatDnssdTxtResolver txtResolverEncode;
|
||||
otPlatDnssdTxtResolver txtResolverDecode;
|
||||
const uint8_t *callbackData;
|
||||
uint16_t callbackDataLen;
|
||||
|
||||
txtResolverEncode.mServiceInstance = "svc1";
|
||||
txtResolverEncode.mServiceType = "_t._udp";
|
||||
txtResolverEncode.mInfraIfIndex = 2;
|
||||
txtResolverEncode.mCallback = FakeDnssdTxtCallback;
|
||||
|
||||
ncpBuffer.Clear();
|
||||
SuccessOrQuit(
|
||||
error = encoder.BeginFrame(SPINEL_HEADER_FLAG, SPINEL_CMD_PROP_VALUE_INSERTED, SPINEL_PROP_DNSSD_TXT_RESOLVER));
|
||||
SuccessOrQuit(error = EncodeDnssdDiscovery(encoder, txtResolverEncode));
|
||||
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));
|
||||
SuccessOrQuit(error = decoder.ReadUintPacked(command));
|
||||
SuccessOrQuit(error = decoder.ReadUintPacked(propKey));
|
||||
SuccessOrQuit(error = DecodeDnssdTxtResolver(decoder, txtResolverDecode, callbackData, callbackDataLen));
|
||||
VerifyOrQuit(strcmp(txtResolverDecode.mServiceInstance, txtResolverEncode.mServiceInstance) == 0);
|
||||
VerifyOrQuit(strcmp(txtResolverDecode.mServiceType, txtResolverEncode.mServiceType) == 0);
|
||||
VerifyOrQuit(txtResolverDecode.mInfraIfIndex == txtResolverEncode.mInfraIfIndex);
|
||||
VerifyOrQuit(callbackDataLen == sizeof(otPlatDnssdTxtCallback));
|
||||
VerifyOrQuit(*reinterpret_cast<const otPlatDnssdTxtCallback *>(callbackData) == FakeDnssdTxtCallback);
|
||||
}
|
||||
|
||||
void TestDnssdTxtResult(void)
|
||||
{
|
||||
uint8_t buf[kMaxSpinelBufferSize];
|
||||
uint16_t len;
|
||||
Spinel::Buffer ncpBuffer(buf, kMaxSpinelBufferSize);
|
||||
Spinel::Encoder encoder(ncpBuffer);
|
||||
Spinel::Decoder decoder;
|
||||
uint8_t header;
|
||||
unsigned int command;
|
||||
unsigned int propKey;
|
||||
otError error = OT_ERROR_NONE;
|
||||
|
||||
const uint8_t kTxt[] = {0x01, 0x02, 0x03};
|
||||
otPlatDnssdTxtResult txtResultEncode;
|
||||
otPlatDnssdTxtResult txtResultDecode;
|
||||
const uint8_t *callbackData;
|
||||
uint16_t callbackDataLen;
|
||||
otPlatDnssdTxtCallback callback = FakeDnssdTxtCallback;
|
||||
|
||||
txtResultEncode.mServiceInstance = "svc1";
|
||||
txtResultEncode.mServiceType = "_t._udp";
|
||||
txtResultEncode.mTxtData = kTxt;
|
||||
txtResultEncode.mTxtDataLength = sizeof(kTxt);
|
||||
txtResultEncode.mTtl = 60;
|
||||
txtResultEncode.mInfraIfIndex = 3;
|
||||
|
||||
ncpBuffer.Clear();
|
||||
SuccessOrQuit(error =
|
||||
encoder.BeginFrame(SPINEL_HEADER_FLAG, SPINEL_CMD_PROP_VALUE_SET, SPINEL_PROP_DNSSD_TXT_RESULT));
|
||||
SuccessOrQuit(error = EncodeDnssdTxtResult(encoder, txtResultEncode, 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));
|
||||
SuccessOrQuit(error = decoder.ReadUintPacked(command));
|
||||
SuccessOrQuit(error = decoder.ReadUintPacked(propKey));
|
||||
SuccessOrQuit(error = DecodeDnssdTxtResult(decoder, txtResultDecode, callbackData, callbackDataLen));
|
||||
VerifyOrQuit(strcmp(txtResultDecode.mServiceInstance, txtResultEncode.mServiceInstance) == 0);
|
||||
VerifyOrQuit(strcmp(txtResultDecode.mServiceType, txtResultEncode.mServiceType) == 0);
|
||||
VerifyOrQuit(txtResultDecode.mTxtDataLength == txtResultEncode.mTxtDataLength);
|
||||
VerifyOrQuit(memcmp(txtResultDecode.mTxtData, txtResultEncode.mTxtData, txtResultDecode.mTxtDataLength) == 0);
|
||||
VerifyOrQuit(txtResultDecode.mTtl == txtResultEncode.mTtl);
|
||||
VerifyOrQuit(txtResultDecode.mInfraIfIndex == txtResultEncode.mInfraIfIndex);
|
||||
VerifyOrQuit(callbackDataLen == sizeof(otPlatDnssdTxtCallback));
|
||||
VerifyOrQuit(*reinterpret_cast<const otPlatDnssdTxtCallback *>(callbackData) == FakeDnssdTxtCallback);
|
||||
|
||||
// Empty TXT payload (removed entry or zero-length record).
|
||||
txtResultEncode.mTxtDataLength = 0;
|
||||
txtResultEncode.mTxtData = nullptr;
|
||||
txtResultEncode.mTtl = 0;
|
||||
|
||||
ncpBuffer.Clear();
|
||||
SuccessOrQuit(error =
|
||||
encoder.BeginFrame(SPINEL_HEADER_FLAG, SPINEL_CMD_PROP_VALUE_SET, SPINEL_PROP_DNSSD_TXT_RESULT));
|
||||
SuccessOrQuit(error = EncodeDnssdTxtResult(encoder, txtResultEncode, 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));
|
||||
SuccessOrQuit(error = decoder.ReadUintPacked(command));
|
||||
SuccessOrQuit(error = decoder.ReadUintPacked(propKey));
|
||||
SuccessOrQuit(error = DecodeDnssdTxtResult(decoder, txtResultDecode, callbackData, callbackDataLen));
|
||||
VerifyOrQuit(strcmp(txtResultDecode.mServiceInstance, txtResultEncode.mServiceInstance) == 0);
|
||||
VerifyOrQuit(strcmp(txtResultDecode.mServiceType, txtResultEncode.mServiceType) == 0);
|
||||
VerifyOrQuit(txtResultDecode.mTxtDataLength == 0);
|
||||
VerifyOrQuit(txtResultDecode.mTxtData == nullptr);
|
||||
VerifyOrQuit(txtResultDecode.mTtl == 0);
|
||||
VerifyOrQuit(txtResultDecode.mInfraIfIndex == txtResultEncode.mInfraIfIndex);
|
||||
VerifyOrQuit(callbackDataLen == sizeof(otPlatDnssdTxtCallback));
|
||||
VerifyOrQuit(*reinterpret_cast<const otPlatDnssdTxtCallback *>(callbackData) == FakeDnssdTxtCallback);
|
||||
}
|
||||
|
||||
void TestDnssdAddressResolver(void)
|
||||
{
|
||||
uint8_t buf[kMaxSpinelBufferSize];
|
||||
uint16_t len;
|
||||
Spinel::Buffer ncpBuffer(buf, kMaxSpinelBufferSize);
|
||||
Spinel::Encoder encoder(ncpBuffer);
|
||||
Spinel::Decoder decoder;
|
||||
uint8_t header;
|
||||
unsigned int command;
|
||||
unsigned int propKey;
|
||||
otError error = OT_ERROR_NONE;
|
||||
otPlatDnssdAddressResolver addrEncode;
|
||||
otPlatDnssdAddressResolver addrDecode;
|
||||
const uint8_t *callbackData;
|
||||
uint16_t callbackDataLen;
|
||||
|
||||
addrEncode.mHostName = "host1";
|
||||
addrEncode.mInfraIfIndex = 4;
|
||||
addrEncode.mCallback = FakeDnssdAddressCallback;
|
||||
|
||||
ncpBuffer.Clear();
|
||||
SuccessOrQuit(error = encoder.BeginFrame(SPINEL_HEADER_FLAG, SPINEL_CMD_PROP_VALUE_INSERTED,
|
||||
SPINEL_PROP_DNSSD_IP6_ADDRESS_RESOLVER));
|
||||
SuccessOrQuit(error = EncodeDnssdDiscovery(encoder, addrEncode));
|
||||
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));
|
||||
SuccessOrQuit(error = decoder.ReadUintPacked(command));
|
||||
SuccessOrQuit(error = decoder.ReadUintPacked(propKey));
|
||||
SuccessOrQuit(error = DecodeDnssdAddressResolver(decoder, addrDecode, callbackData, callbackDataLen));
|
||||
VerifyOrQuit(strcmp(addrDecode.mHostName, addrEncode.mHostName) == 0);
|
||||
VerifyOrQuit(addrDecode.mInfraIfIndex == addrEncode.mInfraIfIndex);
|
||||
VerifyOrQuit(callbackDataLen == sizeof(otPlatDnssdAddressCallback));
|
||||
VerifyOrQuit(*reinterpret_cast<const otPlatDnssdAddressCallback *>(callbackData) == FakeDnssdAddressCallback);
|
||||
}
|
||||
|
||||
void TestDnssdAddressResult(void)
|
||||
{
|
||||
uint8_t buf[kMaxSpinelBufferSize];
|
||||
uint16_t len;
|
||||
Spinel::Buffer ncpBuffer(buf, kMaxSpinelBufferSize);
|
||||
Spinel::Encoder encoder(ncpBuffer);
|
||||
Spinel::Decoder decoder;
|
||||
uint8_t header;
|
||||
unsigned int command;
|
||||
unsigned int propKey;
|
||||
otError error = OT_ERROR_NONE;
|
||||
otPlatDnssdAddressResult addrResultEncode;
|
||||
otPlatDnssdAddressResult addrResultDecode;
|
||||
otPlatDnssdAddressAndTtl addrArrayEncode[1];
|
||||
otPlatDnssdAddressAndTtl addrArrayDecode[4];
|
||||
const uint8_t *callbackData;
|
||||
uint16_t callbackDataLen;
|
||||
otPlatDnssdAddressCallback callback = FakeDnssdAddressCallback;
|
||||
|
||||
memset(&addrArrayEncode[0].mAddress, 0xab, sizeof(addrArrayEncode[0].mAddress));
|
||||
addrArrayEncode[0].mTtl = 30;
|
||||
|
||||
addrResultEncode.mHostName = "host2";
|
||||
addrResultEncode.mAddresses = addrArrayEncode;
|
||||
addrResultEncode.mAddressesLength = 1;
|
||||
addrResultEncode.mInfraIfIndex = 5;
|
||||
|
||||
ncpBuffer.Clear();
|
||||
SuccessOrQuit(error = encoder.BeginFrame(SPINEL_HEADER_FLAG, SPINEL_CMD_PROP_VALUE_SET,
|
||||
SPINEL_PROP_DNSSD_IP6_ADDRESS_RESULT));
|
||||
SuccessOrQuit(error = EncodeDnssdAddressResult(encoder, addrResultEncode,
|
||||
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));
|
||||
SuccessOrQuit(error = decoder.ReadUintPacked(command));
|
||||
SuccessOrQuit(error = decoder.ReadUintPacked(propKey));
|
||||
SuccessOrQuit(error = DecodeDnssdAddressResult(decoder, addrResultDecode, addrArrayDecode,
|
||||
OT_ARRAY_LENGTH(addrArrayDecode), callbackData, callbackDataLen));
|
||||
VerifyOrQuit(strcmp(addrResultDecode.mHostName, addrResultEncode.mHostName) == 0);
|
||||
VerifyOrQuit(addrResultDecode.mInfraIfIndex == addrResultEncode.mInfraIfIndex);
|
||||
VerifyOrQuit(addrResultDecode.mAddressesLength == 1);
|
||||
VerifyOrQuit(addrResultDecode.mAddresses[0].mTtl == addrArrayEncode[0].mTtl);
|
||||
VerifyOrQuit(memcmp(&addrResultDecode.mAddresses[0].mAddress, &addrArrayEncode[0].mAddress, sizeof(otIp6Address)) ==
|
||||
0);
|
||||
VerifyOrQuit(callbackDataLen == sizeof(otPlatDnssdAddressCallback));
|
||||
VerifyOrQuit(*reinterpret_cast<const otPlatDnssdAddressCallback *>(callbackData) == FakeDnssdAddressCallback);
|
||||
|
||||
// Empty address result (removed entry or zero-entry record).
|
||||
addrResultEncode.mAddressesLength = 0;
|
||||
addrResultEncode.mAddresses = nullptr;
|
||||
|
||||
ncpBuffer.Clear();
|
||||
SuccessOrQuit(error = encoder.BeginFrame(SPINEL_HEADER_FLAG, SPINEL_CMD_PROP_VALUE_SET,
|
||||
SPINEL_PROP_DNSSD_IP6_ADDRESS_RESULT));
|
||||
SuccessOrQuit(error = EncodeDnssdAddressResult(encoder, addrResultEncode,
|
||||
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));
|
||||
SuccessOrQuit(error = decoder.ReadUintPacked(command));
|
||||
SuccessOrQuit(error = decoder.ReadUintPacked(propKey));
|
||||
SuccessOrQuit(error = DecodeDnssdAddressResult(decoder, addrResultDecode, addrArrayDecode,
|
||||
OT_ARRAY_LENGTH(addrArrayDecode), callbackData, callbackDataLen));
|
||||
VerifyOrQuit(strcmp(addrResultDecode.mHostName, addrResultEncode.mHostName) == 0);
|
||||
VerifyOrQuit(addrResultDecode.mInfraIfIndex == addrResultEncode.mInfraIfIndex);
|
||||
VerifyOrQuit(addrResultDecode.mAddressesLength == 0);
|
||||
VerifyOrQuit(addrResultDecode.mAddresses == nullptr);
|
||||
VerifyOrQuit(callbackDataLen == sizeof(otPlatDnssdAddressCallback));
|
||||
VerifyOrQuit(*reinterpret_cast<const otPlatDnssdAddressCallback *>(callbackData) == FakeDnssdAddressCallback);
|
||||
|
||||
// Multi-entry address result (`t(A(6L))` with more than one entry).
|
||||
{
|
||||
otPlatDnssdAddressAndTtl multiAddrs[2];
|
||||
|
||||
memset(&multiAddrs[0].mAddress, 0x11, sizeof(multiAddrs[0].mAddress));
|
||||
multiAddrs[0].mTtl = 60;
|
||||
memset(&multiAddrs[1].mAddress, 0x22, sizeof(multiAddrs[1].mAddress));
|
||||
multiAddrs[1].mTtl = 120;
|
||||
|
||||
addrResultEncode.mAddresses = multiAddrs;
|
||||
addrResultEncode.mAddressesLength = 2;
|
||||
|
||||
ncpBuffer.Clear();
|
||||
SuccessOrQuit(error = encoder.BeginFrame(SPINEL_HEADER_FLAG, SPINEL_CMD_PROP_VALUE_SET,
|
||||
SPINEL_PROP_DNSSD_IP6_ADDRESS_RESULT));
|
||||
SuccessOrQuit(error = EncodeDnssdAddressResult(encoder, addrResultEncode,
|
||||
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));
|
||||
SuccessOrQuit(error = decoder.ReadUintPacked(command));
|
||||
SuccessOrQuit(error = decoder.ReadUintPacked(propKey));
|
||||
SuccessOrQuit(error =
|
||||
DecodeDnssdAddressResult(decoder, addrResultDecode, addrArrayDecode,
|
||||
OT_ARRAY_LENGTH(addrArrayDecode), callbackData, callbackDataLen));
|
||||
VerifyOrQuit(addrResultDecode.mAddressesLength == 2);
|
||||
VerifyOrQuit(addrResultDecode.mAddresses[0].mTtl == multiAddrs[0].mTtl);
|
||||
VerifyOrQuit(addrResultDecode.mAddresses[1].mTtl == multiAddrs[1].mTtl);
|
||||
VerifyOrQuit(memcmp(&addrResultDecode.mAddresses[0].mAddress, &multiAddrs[0].mAddress, sizeof(otIp6Address)) ==
|
||||
0);
|
||||
VerifyOrQuit(memcmp(&addrResultDecode.mAddresses[1].mAddress, &multiAddrs[1].mAddress, sizeof(otIp6Address)) ==
|
||||
0);
|
||||
VerifyOrQuit(callbackDataLen == sizeof(otPlatDnssdAddressCallback));
|
||||
VerifyOrQuit(*reinterpret_cast<const otPlatDnssdAddressCallback *>(callbackData) == FakeDnssdAddressCallback);
|
||||
|
||||
// Over-max: more entries than the caller buffer. The first entries are reported, the rest are
|
||||
// ignored, and the callback context after the struct is still decoded correctly.
|
||||
decoder.Init(buf, len);
|
||||
SuccessOrQuit(error = decoder.ReadUint8(header));
|
||||
SuccessOrQuit(error = decoder.ReadUintPacked(command));
|
||||
SuccessOrQuit(error = decoder.ReadUintPacked(propKey));
|
||||
SuccessOrQuit(error = DecodeDnssdAddressResult(decoder, addrResultDecode, addrArrayDecode,
|
||||
/* aAddressArraySize */ 1, callbackData, callbackDataLen));
|
||||
VerifyOrQuit(strcmp(addrResultDecode.mHostName, addrResultEncode.mHostName) == 0);
|
||||
VerifyOrQuit(addrResultDecode.mInfraIfIndex == addrResultEncode.mInfraIfIndex);
|
||||
VerifyOrQuit(addrResultDecode.mAddressesLength == 1);
|
||||
VerifyOrQuit(addrResultDecode.mAddresses[0].mTtl == multiAddrs[0].mTtl);
|
||||
VerifyOrQuit(memcmp(&addrResultDecode.mAddresses[0].mAddress, &multiAddrs[0].mAddress, sizeof(otIp6Address)) ==
|
||||
0);
|
||||
VerifyOrQuit(callbackDataLen == sizeof(otPlatDnssdAddressCallback));
|
||||
VerifyOrQuit(*reinterpret_cast<const otPlatDnssdAddressCallback *>(callbackData) == FakeDnssdAddressCallback);
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace Spinel
|
||||
} // namespace ot
|
||||
|
||||
@@ -464,6 +777,10 @@ int main(void)
|
||||
ot::Spinel::TestDnssdBrowserResult();
|
||||
ot::Spinel::TestDnssdSrvResolver();
|
||||
ot::Spinel::TestDnssdSrvResult();
|
||||
ot::Spinel::TestDnssdTxtResolver();
|
||||
ot::Spinel::TestDnssdTxtResult();
|
||||
ot::Spinel::TestDnssdAddressResolver();
|
||||
ot::Spinel::TestDnssdAddressResult();
|
||||
printf("\nAll tests passed.\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user