Skip to content

Commit d792574

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 5f03f0e commit d792574

10 files changed

Lines changed: 728 additions & 15 deletions

File tree

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
@@ -4959,6 +4959,63 @@ enum
49594959
*/
49604960
SPINEL_PROP_DNSSD_SRV_RESULT = SPINEL_PROP_DNSSD__BEGIN + 9,
49614961

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

49645021
SPINEL_PROP_BORDER_AGENT__BEGIN = 0x950,

src/lib/spinel/spinel_prop_codec.cpp

Lines changed: 173 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -124,7 +124,25 @@ otError DecodeDnssdHost(Decoder &aDecoder,
124124

125125
SuccessOrExit(error = aDecoder.ReadUtf8(aHost.mHostName));
126126
SuccessOrExit(error = aDecoder.ReadUint16(aHost.mAddressesLength));
127-
SuccessOrExit(error = aDecoder.ReadIp6Address(aHost.mAddresses));
127+
128+
if (aHost.mAddressesLength > 0)
129+
{
130+
const otIp6Address *address = nullptr;
131+
132+
SuccessOrExit(error = aDecoder.ReadIp6Address(aHost.mAddresses));
133+
134+
for (uint16_t i = 1; i < aHost.mAddressesLength; i++)
135+
{
136+
SuccessOrExit(error = aDecoder.ReadIp6Address(address));
137+
}
138+
139+
OT_UNUSED_VARIABLE(address);
140+
}
141+
else
142+
{
143+
aHost.mAddresses = nullptr;
144+
}
145+
128146
SuccessOrExit(error = aDecoder.ReadUint32(aRequestId));
129147
SuccessOrExit(error = aDecoder.ReadData(aCallbackData, aCallbackDataLen));
130148

@@ -377,5 +395,159 @@ otError DecodeDnssdSrvResult(Decoder &aDecoder,
377395
return error;
378396
}
379397

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+
SuccessOrExit(error = aDecoder.ReadUint32(aTxtResult.mTtl));
480+
SuccessOrExit(error = aDecoder.ReadUint32(aTxtResult.mInfraIfIndex));
481+
SuccessOrExit(error = aDecoder.ReadData(aCallbackData, aCallbackDataLen));
482+
483+
exit:
484+
return error;
485+
}
486+
487+
otError EncodeDnssdAddressResult(Encoder &aEncoder,
488+
const otPlatDnssdAddressResult &aAddressResult,
489+
const uint8_t *aCallbackData,
490+
uint16_t aCallbackDataLen)
491+
{
492+
otError error = OT_ERROR_NONE;
493+
494+
SuccessOrExit(error = aEncoder.WriteUtf8(aAddressResult.mHostName));
495+
SuccessOrExit(error = aEncoder.WriteUint32(aAddressResult.mInfraIfIndex));
496+
SuccessOrExit(error = aEncoder.WriteUint16(aAddressResult.mAddressesLength));
497+
for (uint16_t i = 0; i < aAddressResult.mAddressesLength; i++)
498+
{
499+
SuccessOrExit(error = aEncoder.WriteIp6Address(aAddressResult.mAddresses[i].mAddress));
500+
SuccessOrExit(error = aEncoder.WriteUint32(aAddressResult.mAddresses[i].mTtl));
501+
}
502+
SuccessOrExit(error = aEncoder.WriteData(aCallbackData, aCallbackDataLen));
503+
504+
exit:
505+
return error;
506+
}
507+
508+
otError DecodeDnssdAddressResolver(Decoder &aDecoder,
509+
otPlatDnssdAddressResolver &aAddressResolver,
510+
const uint8_t *&aCallbackData,
511+
uint16_t &aCallbackDataLen)
512+
{
513+
otError error = OT_ERROR_NONE;
514+
515+
SuccessOrExit(error = aDecoder.ReadUtf8(aAddressResolver.mHostName));
516+
SuccessOrExit(error = aDecoder.ReadUint32(aAddressResolver.mInfraIfIndex));
517+
SuccessOrExit(error = aDecoder.ReadData(aCallbackData, aCallbackDataLen));
518+
519+
exit:
520+
return error;
521+
}
522+
523+
otError DecodeDnssdAddressResult(Decoder &aDecoder,
524+
otPlatDnssdAddressResult &aAddressResult,
525+
otPlatDnssdAddressAndTtl *aAddressArray,
526+
uint16_t aMaxAddresses,
527+
const uint8_t *&aCallbackData,
528+
uint16_t &aCallbackDataLen)
529+
{
530+
otError error = OT_ERROR_NONE;
531+
uint16_t count;
532+
533+
SuccessOrExit(error = aDecoder.ReadUtf8(aAddressResult.mHostName));
534+
SuccessOrExit(error = aDecoder.ReadUint32(aAddressResult.mInfraIfIndex));
535+
SuccessOrExit(error = aDecoder.ReadUint16(count));
536+
VerifyOrExit(count <= aMaxAddresses, error = OT_ERROR_PARSE);
537+
538+
for (uint16_t i = 0; i < count; i++)
539+
{
540+
SuccessOrExit(error = aDecoder.ReadIp6Address(aAddressArray[i].mAddress));
541+
SuccessOrExit(error = aDecoder.ReadUint32(aAddressArray[i].mTtl));
542+
}
543+
544+
aAddressResult.mAddresses = (count > 0) ? aAddressArray : nullptr;
545+
aAddressResult.mAddressesLength = count;
546+
SuccessOrExit(error = aDecoder.ReadData(aCallbackData, aCallbackDataLen));
547+
548+
exit:
549+
return error;
550+
}
551+
380552
} // namespace Spinel
381553
} // namespace ot

src/lib/spinel/spinel_prop_codec.hpp

Lines changed: 84 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -210,6 +210,90 @@ otError DecodeDnssdSrvResult(Decoder &aDecoder,
210210
otPlatDnssdSrvResult &aSrvResult,
211211
const uint8_t *&aCallbackData,
212212
uint16_t &aCallbackDataLen);
213+
214+
/**
215+
* Use Spinel::Encode to encode a Dnssd TXT result.
216+
*
217+
* @param[in] aEncoder A reference to the encoder object.
218+
* @param[in] aTxtResult A reference to the TXT result.
219+
* @param[in] aCallbackData A pointer to the callback data.
220+
* @param[in] aCallbackDataLen The data length.
221+
*/
222+
otError EncodeDnssdTxtResult(Encoder &aEncoder,
223+
const otPlatDnssdTxtResult &aTxtResult,
224+
const uint8_t *aCallbackData,
225+
uint16_t aCallbackDataLen);
226+
227+
/**
228+
* Use Spinel::Decoder to decode a SPINEL_PROP_DNSSD_TXT_RESOLVER message to a otPlatDnssdTxtResolver.
229+
*
230+
* @param[in] aDecoder A reference to the decoder object.
231+
* @param[out] aTxtResolver A reference to the TXT resolver.
232+
* @param[out] aCallbackData A reference to the pointer to the callback data.
233+
* @param[out] aCallbackDataLen A reference to the callback data length.
234+
*/
235+
otError DecodeDnssdTxtResolver(Decoder &aDecoder,
236+
otPlatDnssdTxtResolver &aTxtResolver,
237+
const uint8_t *&aCallbackData,
238+
uint16_t &aCallbackDataLen);
239+
240+
/**
241+
* Use Spinel::Decoder to decode a SPINEL_PROP_DNSSD_TXT_RESULT message to a otPlatDnssdTxtResult.
242+
*
243+
* @param[in] aDecoder A reference to the decoder object.
244+
* @param[out] aTxtResult A reference to the TXT result.
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 DecodeDnssdTxtResult(Decoder &aDecoder,
249+
otPlatDnssdTxtResult &aTxtResult,
250+
const uint8_t *&aCallbackData,
251+
uint16_t &aCallbackDataLen);
252+
253+
/**
254+
* Use Spinel::Encode to encode a Dnssd Address result.
255+
*
256+
* @param[in] aEncoder A reference to the encoder object.
257+
* @param[in] aAddressResult A reference to the Address result.
258+
* @param[in] aCallbackData A pointer to the callback data.
259+
* @param[in] aCallbackDataLen The data length.
260+
*/
261+
otError EncodeDnssdAddressResult(Encoder &aEncoder,
262+
const otPlatDnssdAddressResult &aAddressResult,
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)