Skip to content

Commit 67622dd

Browse files
[ncp] bridge DNSSD TXT and address resolvers over Spinel
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 - Fix DecodeDnssdHost for multiple address entries
1 parent 522a665 commit 67622dd

11 files changed

Lines changed: 924 additions & 36 deletions

src/lib/spinel/spinel.c

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1423,6 +1423,12 @@ const char *spinel_prop_key_to_cstr(spinel_prop_key_t prop_key)
14231423
{SPINEL_PROP_DNSSD_BROWSE_RESULT, "DNSSD_BROWSE_RESULT"},
14241424
{SPINEL_PROP_DNSSD_SRV_RESOLVER, "DNSSD_SRV_RESOLVER"},
14251425
{SPINEL_PROP_DNSSD_SRV_RESULT, "DNSSD_SRV_RESULT"},
1426+
{SPINEL_PROP_DNSSD_TXT_RESOLVER, "DNSSD_TXT_RESOLVER"},
1427+
{SPINEL_PROP_DNSSD_TXT_RESULT, "DNSSD_TXT_RESULT"},
1428+
{SPINEL_PROP_DNSSD_IP6_ADDRESS_RESOLVER, "DNSSD_IP6_ADDRESS_RESOLVER"},
1429+
{SPINEL_PROP_DNSSD_IP6_ADDRESS_RESULT, "DNSSD_IP6_ADDRESS_RESULT"},
1430+
{SPINEL_PROP_DNSSD_IP4_ADDRESS_RESOLVER, "DNSSD_IP4_ADDRESS_RESOLVER"},
1431+
{SPINEL_PROP_DNSSD_IP4_ADDRESS_RESULT, "DNSSD_IP4_ADDRESS_RESULT"},
14261432
{SPINEL_PROP_BORDER_AGENT_MESHCOP_SERVICE_STATE, "BORDER_AGENT_MESHCOP_SERVICE_STATE"},
14271433
{SPINEL_PROP_BORDER_AGENT_EPHEMERAL_KEY_STATE, "SPINEL_PROP_BORDER_AGENT_EPHEMERAL_KEY_STATE"},
14281434
{SPINEL_PROP_BORDER_AGENT_EPHEMERAL_KEY_ENABLE, "SPINEL_PROP_BORDER_AGENT_EPHEMERAL_KEY_ENABLE"},

src/lib/spinel/spinel.h

Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4961,6 +4961,63 @@ enum
49614961
*/
49624962
SPINEL_PROP_DNSSD_SRV_RESULT = SPINEL_PROP_DNSSD__BEGIN + 9,
49634963

4964+
/// DNS-SD TXT Resolver
4965+
/**
4966+
* Format: `UULD`: Inserted/Removed
4967+
*
4968+
* `U`: The service instance label.
4969+
* `U`: The service type.
4970+
* `L`: The infrastructure network interface index.
4971+
* `D`: The context of the request (pointer to `otPlatDnssdTxtCallback`).
4972+
*/
4973+
SPINEL_PROP_DNSSD_TXT_RESOLVER = SPINEL_PROP_DNSSD__BEGIN + 10,
4974+
4975+
/// DNS-SD TXT Resolution Result
4976+
/**
4977+
* Format: `UUdLLD`: Set
4978+
*
4979+
* `U`: Service instance label.
4980+
* `U`: Service type.
4981+
* `d`: Encoded TXT data bytes (empty if removed).
4982+
* `L`: TTL in seconds (zero indicates removal).
4983+
* `L`: Infrastructure interface index.
4984+
* `D`: Callback context (`sizeof(otPlatDnssdTxtCallback)`).
4985+
*/
4986+
SPINEL_PROP_DNSSD_TXT_RESULT = SPINEL_PROP_DNSSD__BEGIN + 11,
4987+
4988+
/// DNS-SD IPv6 Address Resolver
4989+
/**
4990+
* Format: `ULD`: Inserted/Removed
4991+
*
4992+
* `U`: Host name (no domain).
4993+
* `L`: Infrastructure interface index.
4994+
* `D`: Callback context (`sizeof(otPlatDnssdAddressCallback)`).
4995+
*/
4996+
SPINEL_PROP_DNSSD_IP6_ADDRESS_RESOLVER = SPINEL_PROP_DNSSD__BEGIN + 12,
4997+
4998+
/// DNS-SD IPv6 Address Resolution Result
4999+
/**
5000+
* Format: `ULt(A(6L))D`: Set
5001+
*
5002+
* `U`: Host name.
5003+
* `L`: Infrastructure interface index.
5004+
* `t(A(6L))`: Struct containing an array of IPv6 addresses, each followed by a TTL as uint32_t.
5005+
* `D`: Callback context (`sizeof(otPlatDnssdAddressCallback)`).
5006+
*/
5007+
SPINEL_PROP_DNSSD_IP6_ADDRESS_RESULT = SPINEL_PROP_DNSSD__BEGIN + 13,
5008+
5009+
/// DNS-SD IPv4 Address Resolver
5010+
/**
5011+
* Format: `ULD`: Inserted/Removed (same as IPv6 resolver; IPv4 uses IPv4-mapped IPv6 in results).
5012+
*/
5013+
SPINEL_PROP_DNSSD_IP4_ADDRESS_RESOLVER = SPINEL_PROP_DNSSD__BEGIN + 14,
5014+
5015+
/// DNS-SD IPv4 Address Resolution Result
5016+
/**
5017+
* Format: Same as `SPINEL_PROP_DNSSD_IP6_ADDRESS_RESULT`.
5018+
*/
5019+
SPINEL_PROP_DNSSD_IP4_ADDRESS_RESULT = SPINEL_PROP_DNSSD__BEGIN + 15,
5020+
49645021
SPINEL_PROP_DNSSD__END = 0x950,
49655022

49665023
SPINEL_PROP_BORDER_AGENT__BEGIN = 0x950,

src/lib/spinel/spinel_prop_codec.cpp

Lines changed: 175 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -125,20 +125,22 @@ otError DecodeDnssdHost(Decoder &aDecoder,
125125
SuccessOrExit(error = aDecoder.ReadUtf8(aHost.mHostName));
126126
SuccessOrExit(error = aDecoder.ReadUint16(aHost.mAddressesLength));
127127

128-
if (aHost.mAddressesLength == 0)
129-
{
130-
aHost.mAddresses = nullptr;
131-
}
132-
else
128+
if (aHost.mAddressesLength > 0)
133129
{
130+
const otIp6Address *address = nullptr;
131+
134132
SuccessOrExit(error = aDecoder.ReadIp6Address(aHost.mAddresses));
135133

136134
for (uint16_t i = 1; i < aHost.mAddressesLength; i++)
137135
{
138-
const otIp6Address *address;
139-
140136
SuccessOrExit(error = aDecoder.ReadIp6Address(address));
141137
}
138+
139+
OT_UNUSED_VARIABLE(address);
140+
}
141+
else
142+
{
143+
aHost.mAddresses = nullptr;
142144
}
143145

144146
SuccessOrExit(error = aDecoder.ReadUint32(aRequestId));
@@ -393,5 +395,171 @@ otError DecodeDnssdSrvResult(Decoder &aDecoder,
393395
return error;
394396
}
395397

398+
template <>
399+
otError EncodeDnssdDiscovery<otPlatDnssdTxtResolver>(Encoder &aEncoder, const otPlatDnssdTxtResolver &aDiscovery)
400+
{
401+
otError error = OT_ERROR_NONE;
402+
403+
SuccessOrExit(error = aEncoder.WriteUtf8(aDiscovery.mServiceInstance));
404+
SuccessOrExit(error = aEncoder.WriteUtf8(aDiscovery.mServiceType));
405+
SuccessOrExit(error = aEncoder.WriteUint32(aDiscovery.mInfraIfIndex));
406+
SuccessOrExit(error = aEncoder.WriteData(reinterpret_cast<const uint8_t *>(&aDiscovery.mCallback),
407+
sizeof(aDiscovery.mCallback)));
408+
409+
exit:
410+
return error;
411+
}
412+
413+
template <>
414+
otError EncodeDnssdDiscovery<otPlatDnssdAddressResolver>(Encoder &aEncoder,
415+
const otPlatDnssdAddressResolver &aDiscovery)
416+
{
417+
otError error = OT_ERROR_NONE;
418+
419+
SuccessOrExit(error = aEncoder.WriteUtf8(aDiscovery.mHostName));
420+
SuccessOrExit(error = aEncoder.WriteUint32(aDiscovery.mInfraIfIndex));
421+
SuccessOrExit(error = aEncoder.WriteData(reinterpret_cast<const uint8_t *>(&aDiscovery.mCallback),
422+
sizeof(aDiscovery.mCallback)));
423+
424+
exit:
425+
return error;
426+
}
427+
428+
otError EncodeDnssdTxtResult(Encoder &aEncoder,
429+
const otPlatDnssdTxtResult &aTxtResult,
430+
const uint8_t *aCallbackData,
431+
uint16_t aCallbackDataLen)
432+
{
433+
otError error = OT_ERROR_NONE;
434+
435+
SuccessOrExit(error = aEncoder.WriteUtf8(aTxtResult.mServiceInstance));
436+
SuccessOrExit(error = aEncoder.WriteUtf8(aTxtResult.mServiceType));
437+
if (aTxtResult.mTxtData != nullptr && aTxtResult.mTxtDataLength > 0)
438+
{
439+
SuccessOrExit(error = aEncoder.WriteDataWithLen(aTxtResult.mTxtData, aTxtResult.mTxtDataLength));
440+
}
441+
else
442+
{
443+
SuccessOrExit(error = aEncoder.WriteDataWithLen(nullptr, 0));
444+
}
445+
SuccessOrExit(error = aEncoder.WriteUint32(aTxtResult.mTtl));
446+
SuccessOrExit(error = aEncoder.WriteUint32(aTxtResult.mInfraIfIndex));
447+
SuccessOrExit(error = aEncoder.WriteData(aCallbackData, aCallbackDataLen));
448+
449+
exit:
450+
return error;
451+
}
452+
453+
otError DecodeDnssdTxtResolver(Decoder &aDecoder,
454+
otPlatDnssdTxtResolver &aTxtResolver,
455+
const uint8_t *&aCallbackData,
456+
uint16_t &aCallbackDataLen)
457+
{
458+
otError error = OT_ERROR_NONE;
459+
460+
SuccessOrExit(error = aDecoder.ReadUtf8(aTxtResolver.mServiceInstance));
461+
SuccessOrExit(error = aDecoder.ReadUtf8(aTxtResolver.mServiceType));
462+
SuccessOrExit(error = aDecoder.ReadUint32(aTxtResolver.mInfraIfIndex));
463+
SuccessOrExit(error = aDecoder.ReadData(aCallbackData, aCallbackDataLen));
464+
465+
exit:
466+
return error;
467+
}
468+
469+
otError DecodeDnssdTxtResult(Decoder &aDecoder,
470+
otPlatDnssdTxtResult &aTxtResult,
471+
const uint8_t *&aCallbackData,
472+
uint16_t &aCallbackDataLen)
473+
{
474+
otError error = OT_ERROR_NONE;
475+
476+
SuccessOrExit(error = aDecoder.ReadUtf8(aTxtResult.mServiceInstance));
477+
SuccessOrExit(error = aDecoder.ReadUtf8(aTxtResult.mServiceType));
478+
SuccessOrExit(error = aDecoder.ReadDataWithLen(aTxtResult.mTxtData, aTxtResult.mTxtDataLength));
479+
480+
if (aTxtResult.mTxtDataLength == 0)
481+
{
482+
aTxtResult.mTxtData = nullptr;
483+
}
484+
485+
SuccessOrExit(error = aDecoder.ReadUint32(aTxtResult.mTtl));
486+
SuccessOrExit(error = aDecoder.ReadUint32(aTxtResult.mInfraIfIndex));
487+
SuccessOrExit(error = aDecoder.ReadData(aCallbackData, aCallbackDataLen));
488+
489+
exit:
490+
return error;
491+
}
492+
493+
otError EncodeDnssdAddressResult(Encoder &aEncoder,
494+
const otPlatDnssdAddressResult &aAddressResult,
495+
const uint8_t *aCallbackData,
496+
uint16_t aCallbackDataLen)
497+
{
498+
otError error = OT_ERROR_NONE;
499+
500+
SuccessOrExit(error = aEncoder.WriteUtf8(aAddressResult.mHostName));
501+
SuccessOrExit(error = aEncoder.WriteUint32(aAddressResult.mInfraIfIndex));
502+
SuccessOrExit(error = aEncoder.OpenStruct());
503+
504+
for (uint16_t i = 0; i < aAddressResult.mAddressesLength; i++)
505+
{
506+
SuccessOrExit(error = aEncoder.WriteIp6Address(aAddressResult.mAddresses[i].mAddress));
507+
SuccessOrExit(error = aEncoder.WriteUint32(aAddressResult.mAddresses[i].mTtl));
508+
}
509+
510+
SuccessOrExit(error = aEncoder.CloseStruct());
511+
SuccessOrExit(error = aEncoder.WriteData(aCallbackData, aCallbackDataLen));
512+
513+
exit:
514+
return error;
515+
}
516+
517+
otError DecodeDnssdAddressResolver(Decoder &aDecoder,
518+
otPlatDnssdAddressResolver &aAddressResolver,
519+
const uint8_t *&aCallbackData,
520+
uint16_t &aCallbackDataLen)
521+
{
522+
otError error = OT_ERROR_NONE;
523+
524+
SuccessOrExit(error = aDecoder.ReadUtf8(aAddressResolver.mHostName));
525+
SuccessOrExit(error = aDecoder.ReadUint32(aAddressResolver.mInfraIfIndex));
526+
SuccessOrExit(error = aDecoder.ReadData(aCallbackData, aCallbackDataLen));
527+
528+
exit:
529+
return error;
530+
}
531+
532+
otError DecodeDnssdAddressResult(Decoder &aDecoder,
533+
otPlatDnssdAddressResult &aAddressResult,
534+
otPlatDnssdAddressAndTtl *aAddressArray,
535+
uint16_t aMaxAddresses,
536+
const uint8_t *&aCallbackData,
537+
uint16_t &aCallbackDataLen)
538+
{
539+
otError error = OT_ERROR_NONE;
540+
uint16_t count = 0;
541+
542+
SuccessOrExit(error = aDecoder.ReadUtf8(aAddressResult.mHostName));
543+
SuccessOrExit(error = aDecoder.ReadUint32(aAddressResult.mInfraIfIndex));
544+
SuccessOrExit(error = aDecoder.OpenStruct());
545+
546+
while (!aDecoder.IsAllReadInStruct())
547+
{
548+
VerifyOrExit(count < aMaxAddresses, error = OT_ERROR_PARSE);
549+
SuccessOrExit(error = aDecoder.ReadIp6Address(aAddressArray[count].mAddress));
550+
SuccessOrExit(error = aDecoder.ReadUint32(aAddressArray[count].mTtl));
551+
count++;
552+
}
553+
554+
SuccessOrExit(error = aDecoder.CloseStruct());
555+
556+
aAddressResult.mAddresses = (count > 0) ? aAddressArray : nullptr;
557+
aAddressResult.mAddressesLength = count;
558+
SuccessOrExit(error = aDecoder.ReadData(aCallbackData, aCallbackDataLen));
559+
560+
exit:
561+
return error;
562+
}
563+
396564
} // namespace Spinel
397565
} // namespace ot

src/lib/spinel/spinel_prop_codec.hpp

Lines changed: 84 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -100,6 +100,32 @@ otError EncodeDnssdSrvResult(Encoder &aEncoder,
100100
const uint8_t *aCallbackData,
101101
uint16_t aCallbackDataLen);
102102

103+
/**
104+
* Use Spinel::Encode to encode a Dnssd TXT result.
105+
*
106+
* @param[in] aEncoder A reference to the encoder object.
107+
* @param[in] aTxtResult A reference to the TXT result.
108+
* @param[in] aCallbackData A pointer to the callback data.
109+
* @param[in] aCallbackDataLen The data length.
110+
*/
111+
otError EncodeDnssdTxtResult(Encoder &aEncoder,
112+
const otPlatDnssdTxtResult &aTxtResult,
113+
const uint8_t *aCallbackData,
114+
uint16_t aCallbackDataLen);
115+
116+
/**
117+
* Use Spinel::Encode to encode a Dnssd Address result.
118+
*
119+
* @param[in] aEncoder A reference to the encoder object.
120+
* @param[in] aAddressResult A reference to the Address result.
121+
* @param[in] aCallbackData A pointer to the callback data.
122+
* @param[in] aCallbackDataLen The data length.
123+
*/
124+
otError EncodeDnssdAddressResult(Encoder &aEncoder,
125+
const otPlatDnssdAddressResult &aAddressResult,
126+
const uint8_t *aCallbackData,
127+
uint16_t aCallbackDataLen);
128+
103129
/**
104130
* Use Spinel::Decoder to decode a SPINEL_PROP_DNSSD_HOST message to a otPlatDnssdHost.
105131
*
@@ -210,6 +236,64 @@ otError DecodeDnssdSrvResult(Decoder &aDecoder,
210236
otPlatDnssdSrvResult &aSrvResult,
211237
const uint8_t *&aCallbackData,
212238
uint16_t &aCallbackDataLen);
239+
240+
/**
241+
* Use Spinel::Decoder to decode a SPINEL_PROP_DNSSD_TXT_RESOLVER message to a otPlatDnssdTxtResolver.
242+
*
243+
* @param[in] aDecoder A reference to the decoder object.
244+
* @param[out] aTxtResolver A reference to the TXT resolver.
245+
* @param[out] aCallbackData A reference to the pointer to the callback data.
246+
* @param[out] aCallbackDataLen A reference to the callback data length.
247+
*/
248+
otError DecodeDnssdTxtResolver(Decoder &aDecoder,
249+
otPlatDnssdTxtResolver &aTxtResolver,
250+
const uint8_t *&aCallbackData,
251+
uint16_t &aCallbackDataLen);
252+
253+
/**
254+
* Use Spinel::Decoder to decode a SPINEL_PROP_DNSSD_TXT_RESULT message to a otPlatDnssdTxtResult.
255+
*
256+
* @param[in] aDecoder A reference to the decoder object.
257+
* @param[out] aTxtResult A reference to the TXT result.
258+
* @param[out] aCallbackData A reference to the pointer to the callback data.
259+
* @param[out] aCallbackDataLen A reference to the callback data length.
260+
*/
261+
otError DecodeDnssdTxtResult(Decoder &aDecoder,
262+
otPlatDnssdTxtResult &aTxtResult,
263+
const uint8_t *&aCallbackData,
264+
uint16_t &aCallbackDataLen);
265+
266+
/**
267+
* Use Spinel::Decoder to decode a SPINEL_PROP_DNSSD_IP6_ADDRESS_RESOLVER message to a otPlatDnssdAddressResolver.
268+
*
269+
* @param[in] aDecoder A reference to the decoder object.
270+
* @param[out] aAddressResolver A reference to the Address resolver.
271+
* @param[out] aCallbackData A reference to the pointer to the callback data.
272+
* @param[out] aCallbackDataLen A reference to the callback data length.
273+
*/
274+
otError DecodeDnssdAddressResolver(Decoder &aDecoder,
275+
otPlatDnssdAddressResolver &aAddressResolver,
276+
const uint8_t *&aCallbackData,
277+
uint16_t &aCallbackDataLen);
278+
279+
/**
280+
* Use Spinel::Decoder to decode a SPINEL_PROP_DNSSD_IP6_ADDRESS_RESULT message to a otPlatDnssdAddressResult.
281+
*
282+
* Also used for `SPINEL_PROP_DNSSD_IP4_ADDRESS_RESULT` (same wire format IPv4 uses IPv4-mapped IPv6 address).
283+
*
284+
* @param[in] aDecoder A reference to the decoder object.
285+
* @param[out] aAddressResult A reference to the Address result.
286+
* @param[out] aAddressArray Caller-provided storage to copy address and TTL entries.
287+
* @param[in] aMaxAddresses The maximum number of addresses.
288+
* @param[out] aCallbackData A reference to the pointer to the callback data.
289+
* @param[out] aCallbackDataLen A reference to the callback data length.
290+
*/
291+
otError DecodeDnssdAddressResult(Decoder &aDecoder,
292+
otPlatDnssdAddressResult &aAddressResult,
293+
otPlatDnssdAddressAndTtl *aAddressArray,
294+
uint16_t aMaxAddresses,
295+
const uint8_t *&aCallbackData,
296+
uint16_t &aCallbackDataLen);
213297
} // namespace Spinel
214298
} // namespace ot
215299

0 commit comments

Comments
 (0)