Line data Source code
1 : /*
2 : *
3 : * Copyright (c) 2021 Project CHIP Authors
4 : *
5 : * Licensed under the Apache License, Version 2.0 (the "License");
6 : * you may not use this file except in compliance with the License.
7 : * You may obtain a copy of the License at
8 : *
9 : * http://www.apache.org/licenses/LICENSE-2.0
10 : *
11 : * Unless required by applicable law or agreed to in writing, software
12 : * distributed under the License is distributed on an "AS IS" BASIS,
13 : * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 : * See the License for the specific language governing permissions and
15 : * limitations under the License.
16 : */
17 :
18 : #include <app/server/Dnssd.h>
19 :
20 : #include <app-common/zap-generated/cluster-enums.h>
21 : #include <inttypes.h>
22 : #include <lib/core/Optional.h>
23 : #include <lib/dnssd/Advertiser.h>
24 : #include <lib/dnssd/ServiceNaming.h>
25 : #include <lib/support/DefaultStorageKeyAllocator.h>
26 : #include <lib/support/Span.h>
27 : #include <lib/support/logging/CHIPLogging.h>
28 : #include <messaging/ReliableMessageProtocolConfig.h>
29 : #include <platform/CHIPDeviceLayer.h>
30 : #include <platform/CommissionableDataProvider.h>
31 : #include <platform/ConfigurationManager.h>
32 : #include <platform/DeviceInstanceInfoProvider.h>
33 : #include <protocols/secure_channel/PASESession.h>
34 : #if CHIP_ENABLE_ROTATING_DEVICE_ID && defined(CHIP_DEVICE_CONFIG_ROTATING_DEVICE_ID_UNIQUE_ID)
35 : #include <setup_payload/AdditionalDataPayloadGenerator.h>
36 : #endif
37 : #include <credentials/FabricTable.h>
38 : #include <setup_payload/SetupPayload.h>
39 : #include <system/TimeSource.h>
40 :
41 : #include <algorithm>
42 :
43 : using namespace chip;
44 : using namespace chip::DeviceLayer;
45 :
46 : namespace chip {
47 : namespace app {
48 : namespace {
49 :
50 2 : void OnPlatformEvent(const DeviceLayer::ChipDeviceEvent * event)
51 : {
52 2 : switch (event->Type)
53 : {
54 1 : case DeviceLayer::DeviceEventType::kDnssdInitialized:
55 : case DeviceLayer::DeviceEventType::kDnssdRestartNeeded:
56 1 : app::DnssdServer::Instance().StartServer();
57 1 : break;
58 1 : default:
59 1 : break;
60 : }
61 2 : }
62 :
63 2 : void OnPlatformEventWrapper(const DeviceLayer::ChipDeviceEvent * event, intptr_t arg)
64 : {
65 : (void) arg;
66 2 : OnPlatformEvent(event);
67 2 : }
68 :
69 : } // namespace
70 :
71 : constexpr System::Clock::Timestamp DnssdServer::kTimeoutCleared;
72 :
73 7 : bool DnssdServer::HaveOperationalCredentials()
74 : {
75 7 : VerifyOrDie(mFabricTable != nullptr);
76 :
77 : // Look for any fabric info that has a useful operational identity.
78 7 : return mFabricTable->FabricCount() != 0;
79 : }
80 :
81 : #if CHIP_DEVICE_CONFIG_ENABLE_EXTENDED_DISCOVERY
82 :
83 : void DnssdServer::SetExtendedDiscoveryTimeoutSecs(int32_t secs)
84 : {
85 : ChipLogDetail(Discovery, "Setting extended discovery timeout to %" PRId32 "s", secs);
86 : mExtendedDiscoveryTimeoutSecs = MakeOptional(secs);
87 :
88 : if (mExtendedDiscoveryExpiration != kTimeoutCleared &&
89 : mExtendedDiscoveryExpiration > mTimeSource.GetMonotonicTimestamp() + System::Clock::Seconds32(secs))
90 : {
91 : // Reset our timer to the new (shorter) timeout.
92 : ScheduleExtendedDiscoveryExpiration();
93 : }
94 : }
95 :
96 : int32_t DnssdServer::GetExtendedDiscoveryTimeoutSecs()
97 : {
98 : return mExtendedDiscoveryTimeoutSecs.ValueOr(CHIP_DEVICE_CONFIG_EXTENDED_DISCOVERY_TIMEOUT_SECS);
99 : }
100 :
101 : /// Callback from Extended Discovery Expiration timer
102 : void HandleExtendedDiscoveryExpiration(System::Layer * aSystemLayer, void * aAppState)
103 : {
104 : DnssdServer::Instance().OnExtendedDiscoveryExpiration(aSystemLayer, aAppState);
105 : }
106 :
107 : void DnssdServer::OnExtendedDiscoveryExpiration(System::Layer * aSystemLayer, void * aAppState)
108 : {
109 : ChipLogDetail(Discovery, "Extended discovery timed out");
110 :
111 : mExtendedDiscoveryExpiration = kTimeoutCleared;
112 :
113 : // Reset our advertising, now that we have flagged ourselves as possibly not
114 : // needing extended discovery anymore.
115 : StartServer();
116 : }
117 :
118 : CHIP_ERROR DnssdServer::ScheduleExtendedDiscoveryExpiration()
119 : {
120 : int32_t extendedDiscoveryTimeoutSecs = GetExtendedDiscoveryTimeoutSecs();
121 : if (extendedDiscoveryTimeoutSecs == CHIP_DEVICE_CONFIG_DISCOVERY_NO_TIMEOUT)
122 : {
123 : return CHIP_NO_ERROR;
124 : }
125 : ChipLogDetail(Discovery, "Scheduling extended discovery timeout in %" PRId32 "s", extendedDiscoveryTimeoutSecs);
126 :
127 : mExtendedDiscoveryExpiration = mTimeSource.GetMonotonicTimestamp() + System::Clock::Seconds32(extendedDiscoveryTimeoutSecs);
128 :
129 : return DeviceLayer::SystemLayer().StartTimer(System::Clock::Seconds32(extendedDiscoveryTimeoutSecs),
130 : HandleExtendedDiscoveryExpiration, nullptr);
131 : }
132 : #endif // CHIP_DEVICE_CONFIG_ENABLE_EXTENDED_DISCOVERY
133 :
134 0 : CHIP_ERROR DnssdServer::GetCommissionableInstanceName(char * buffer, size_t bufferLen)
135 : {
136 0 : auto & mdnsAdvertiser = chip::Dnssd::ServiceAdvertiser::Instance();
137 0 : return mdnsAdvertiser.GetCommissionableInstanceName(buffer, bufferLen);
138 : }
139 :
140 11 : CHIP_ERROR DnssdServer::SetEphemeralDiscriminator(Optional<uint16_t> discriminator)
141 : {
142 11 : VerifyOrReturnError(discriminator.ValueOr(0) <= kMaxDiscriminatorValue, CHIP_ERROR_INVALID_ARGUMENT);
143 11 : mEphemeralDiscriminator = discriminator;
144 :
145 11 : return CHIP_NO_ERROR;
146 : }
147 :
148 : #if CHIP_CONFIG_ENABLE_ICD_SERVER
149 : template <class AdvertisingParams>
150 : void DnssdServer::AddICDKeyToAdvertisement(AdvertisingParams & advParams)
151 : {
152 : VerifyOrDieWithMsg(mICDManager != nullptr, Discovery,
153 : "Invalid pointer to the ICDManager which is required for the LIT operating mode");
154 :
155 : Dnssd::ICDModeAdvertise ICDModeToAdvertise = Dnssd::ICDModeAdvertise::kNone;
156 : // Only advertise the ICD key if the device can operate as a LIT
157 : if (mICDManager->SupportsFeature(Clusters::IcdManagement::Feature::kLongIdleTimeSupport))
158 : {
159 : if (mICDManager->GetICDMode() == ICDConfigurationData::ICDMode::LIT)
160 : {
161 : ICDModeToAdvertise = Dnssd::ICDModeAdvertise::kLIT;
162 : }
163 : else
164 : {
165 : ICDModeToAdvertise = Dnssd::ICDModeAdvertise::kSIT;
166 : }
167 : }
168 :
169 : advParams.SetICDModeToAdvertise(ICDModeToAdvertise);
170 : }
171 : #endif
172 :
173 7 : void DnssdServer::GetPrimaryOrFallbackMACAddress(MutableByteSpan & mac)
174 : {
175 7 : if (ConfigurationMgr().GetPrimaryMACAddress(mac) != CHIP_NO_ERROR)
176 : {
177 : // Only generate a fallback "MAC" once, so we don't keep constantly changing our host name.
178 0 : if (std::all_of(std::begin(mFallbackMAC), std::end(mFallbackMAC), [](uint8_t v) { return v == 0; }))
179 : {
180 0 : ChipLogError(Discovery, "Failed to get primary mac address of device. Generating a random one.");
181 0 : Crypto::DRBG_get_bytes(mFallbackMAC, sizeof(mFallbackMAC));
182 : }
183 0 : VerifyOrDie(mac.size() == sizeof(mFallbackMAC)); // kPrimaryMACAddressLength
184 0 : memcpy(mac.data(), mFallbackMAC, sizeof(mFallbackMAC));
185 : }
186 7 : }
187 :
188 : /// Set MDNS operational advertisement
189 12 : CHIP_ERROR DnssdServer::AdvertiseOperational()
190 : {
191 12 : VerifyOrReturnError(mFabricTable != nullptr, CHIP_ERROR_INCORRECT_STATE);
192 :
193 12 : for (const FabricInfo & fabricInfo : *mFabricTable)
194 : {
195 0 : if (!fabricInfo.ShouldAdvertiseIdentity())
196 : {
197 0 : continue;
198 : }
199 :
200 : uint8_t macBuffer[DeviceLayer::ConfigurationManager::kPrimaryMACAddressLength];
201 0 : MutableByteSpan mac(macBuffer);
202 0 : GetPrimaryOrFallbackMACAddress(mac);
203 :
204 0 : auto advertiseParameters = chip::Dnssd::OperationalAdvertisingParameters()
205 0 : .SetPeerId(fabricInfo.GetPeerId())
206 0 : .SetMac(mac)
207 0 : .SetPort(GetSecuredPort())
208 0 : .SetInterfaceId(GetInterfaceId())
209 0 : .SetLocalMRPConfig(GetLocalMRPConfig().std_optional())
210 0 : .EnableIpV4(true);
211 :
212 : #if CHIP_CONFIG_ENABLE_ICD_SERVER
213 : AddICDKeyToAdvertisement(advertiseParameters);
214 : #endif
215 :
216 : #if INET_CONFIG_ENABLE_TCP_ENDPOINT
217 0 : advertiseParameters.SetTCPSupportModes(mTCPServerEnabled ? chip::Dnssd::TCPModeAdvertise::kTCPClientServer
218 : : chip::Dnssd::TCPModeAdvertise::kTCPClient);
219 : #endif
220 0 : auto & mdnsAdvertiser = chip::Dnssd::ServiceAdvertiser::Instance();
221 :
222 0 : ChipLogProgress(Discovery, "Advertise operational node " ChipLogFormatX64 "-" ChipLogFormatX64,
223 : ChipLogValueX64(advertiseParameters.GetPeerId().GetCompressedFabricId()),
224 : ChipLogValueX64(advertiseParameters.GetPeerId().GetNodeId()));
225 : // Should we keep trying to advertise the other operational
226 : // identities on failure?
227 0 : ReturnErrorOnFailure(mdnsAdvertiser.Advertise(advertiseParameters));
228 : }
229 12 : return CHIP_NO_ERROR;
230 : }
231 :
232 7 : CHIP_ERROR DnssdServer::Advertise(bool commissionableNode, chip::Dnssd::CommissioningMode mode)
233 : {
234 7 : auto advertiseParameters = chip::Dnssd::CommissionAdvertisingParameters()
235 7 : .SetPort(commissionableNode ? GetSecuredPort() : GetUnsecuredPort())
236 7 : .SetInterfaceId(GetInterfaceId())
237 7 : .EnableIpV4(true);
238 7 : advertiseParameters.SetCommissionAdvertiseMode(commissionableNode ? chip::Dnssd::CommssionAdvertiseMode::kCommissionableNode
239 : : chip::Dnssd::CommssionAdvertiseMode::kCommissioner);
240 :
241 7 : advertiseParameters.SetCommissioningMode(mode);
242 :
243 : char pairingInst[chip::Dnssd::kKeyPairingInstructionMaxLength + 1];
244 :
245 : uint8_t macBuffer[DeviceLayer::ConfigurationManager::kPrimaryMACAddressLength];
246 7 : MutableByteSpan mac(macBuffer);
247 7 : GetPrimaryOrFallbackMACAddress(mac);
248 7 : advertiseParameters.SetMac(mac);
249 :
250 : uint16_t value;
251 : uint32_t val32;
252 7 : if (DeviceLayer::GetDeviceInstanceInfoProvider()->GetVendorId(value) != CHIP_NO_ERROR)
253 : {
254 0 : ChipLogDetail(Discovery, "Vendor ID not known");
255 : }
256 : else
257 : {
258 7 : advertiseParameters.SetVendorId(std::make_optional<uint16_t>(value));
259 : }
260 :
261 7 : if (DeviceLayer::GetDeviceInstanceInfoProvider()->GetProductId(value) != CHIP_NO_ERROR)
262 : {
263 0 : ChipLogDetail(Discovery, "Product ID not known");
264 : }
265 : else
266 : {
267 7 : advertiseParameters.SetProductId(std::make_optional<uint16_t>(value));
268 : }
269 :
270 7 : if (DeviceLayer::ConfigurationMgr().IsCommissionableDeviceTypeEnabled() &&
271 7 : DeviceLayer::ConfigurationMgr().GetDeviceTypeId(val32) == CHIP_NO_ERROR)
272 : {
273 0 : advertiseParameters.SetDeviceType(std::make_optional<uint32_t>(val32));
274 : }
275 :
276 : char deviceName[chip::Dnssd::kKeyDeviceNameMaxLength + 1];
277 7 : if (DeviceLayer::ConfigurationMgr().IsCommissionableDeviceNameEnabled() &&
278 7 : DeviceLayer::ConfigurationMgr().GetCommissionableDeviceName(deviceName, sizeof(deviceName)) == CHIP_NO_ERROR)
279 : {
280 0 : advertiseParameters.SetDeviceName(std::make_optional<const char *>(deviceName));
281 : }
282 :
283 7 : advertiseParameters.SetLocalMRPConfig(GetLocalMRPConfig().std_optional());
284 :
285 : #if CHIP_CONFIG_ENABLE_ICD_SERVER
286 : AddICDKeyToAdvertisement(advertiseParameters);
287 : #endif
288 :
289 7 : if (commissionableNode)
290 : {
291 7 : uint16_t discriminator = 0;
292 7 : CHIP_ERROR error = DeviceLayer::GetCommissionableDataProvider()->GetSetupDiscriminator(discriminator);
293 7 : if (error != CHIP_NO_ERROR)
294 : {
295 0 : ChipLogError(Discovery,
296 : "Setup discriminator read error (%" CHIP_ERROR_FORMAT ")! Critical error, will not be commissionable.",
297 : error.Format());
298 0 : return error;
299 : }
300 :
301 : // Override discriminator with temporary one if one is set
302 7 : discriminator = mEphemeralDiscriminator.ValueOr(discriminator);
303 :
304 7 : advertiseParameters.SetShortDiscriminator(static_cast<uint8_t>((discriminator >> 8) & 0x0F))
305 7 : .SetLongDiscriminator(discriminator);
306 :
307 : #if CHIP_ENABLE_ROTATING_DEVICE_ID && defined(CHIP_DEVICE_CONFIG_ROTATING_DEVICE_ID_UNIQUE_ID)
308 : char rotatingDeviceIdHexBuffer[RotatingDeviceId::kHexMaxLength];
309 : ReturnErrorOnFailure(GenerateRotatingDeviceId(rotatingDeviceIdHexBuffer, MATTER_ARRAY_SIZE(rotatingDeviceIdHexBuffer)));
310 : advertiseParameters.SetRotatingDeviceId(std::make_optional<const char *>(rotatingDeviceIdHexBuffer));
311 : #endif
312 :
313 7 : if (!HaveOperationalCredentials())
314 : {
315 7 : if (DeviceLayer::ConfigurationMgr().GetInitialPairingHint(value) != CHIP_NO_ERROR)
316 : {
317 0 : ChipLogDetail(Discovery, "DNS-SD Pairing Hint not set");
318 : }
319 : else
320 : {
321 7 : advertiseParameters.SetPairingHint(std::make_optional<uint16_t>(value));
322 : }
323 :
324 7 : if (DeviceLayer::ConfigurationMgr().GetInitialPairingInstruction(pairingInst, sizeof(pairingInst)) != CHIP_NO_ERROR)
325 : {
326 0 : ChipLogDetail(Discovery, "DNS-SD Pairing Instruction not set");
327 : }
328 : else
329 : {
330 7 : advertiseParameters.SetPairingInstruction(std::make_optional<const char *>(pairingInst));
331 : }
332 : }
333 : else
334 : {
335 0 : if (DeviceLayer::ConfigurationMgr().GetSecondaryPairingHint(value) != CHIP_NO_ERROR)
336 : {
337 0 : ChipLogDetail(Discovery, "DNS-SD Pairing Hint not set");
338 : }
339 : else
340 : {
341 0 : advertiseParameters.SetPairingHint(std::make_optional<uint16_t>(value));
342 : }
343 :
344 0 : if (DeviceLayer::ConfigurationMgr().GetSecondaryPairingInstruction(pairingInst, sizeof(pairingInst)) != CHIP_NO_ERROR)
345 : {
346 0 : ChipLogDetail(Discovery, "DNS-SD Pairing Instruction not set");
347 : }
348 : else
349 : {
350 0 : advertiseParameters.SetPairingInstruction(std::make_optional<const char *>(pairingInst));
351 : }
352 : }
353 : }
354 : #if CHIP_DEVICE_CONFIG_ENABLE_COMMISSIONER_PASSCODE
355 : else
356 : {
357 : advertiseParameters.SetCommissionerPasscodeSupported(std::make_optional<bool>(true));
358 : }
359 : #endif
360 :
361 7 : auto & mdnsAdvertiser = chip::Dnssd::ServiceAdvertiser::Instance();
362 :
363 7 : ChipLogProgress(Discovery, "Advertise commission parameter vendorID=%u productID=%u discriminator=%04u/%02u cm=%u cp=%u",
364 : advertiseParameters.GetVendorId().value_or(0), advertiseParameters.GetProductId().value_or(0),
365 : advertiseParameters.GetLongDiscriminator(), advertiseParameters.GetShortDiscriminator(),
366 : to_underlying(advertiseParameters.GetCommissioningMode()),
367 : advertiseParameters.GetCommissionerPasscodeSupported().value_or(false) ? 1 : 0);
368 7 : return mdnsAdvertiser.Advertise(advertiseParameters);
369 : }
370 :
371 0 : CHIP_ERROR DnssdServer::AdvertiseCommissioner()
372 : {
373 0 : return Advertise(false /* commissionableNode */, chip::Dnssd::CommissioningMode::kDisabled);
374 : }
375 :
376 7 : CHIP_ERROR DnssdServer::AdvertiseCommissionableNode(chip::Dnssd::CommissioningMode mode)
377 : {
378 : #if CHIP_DEVICE_CONFIG_ENABLE_EXTENDED_DISCOVERY
379 : mCurrentCommissioningMode = mode;
380 : if (mode != Dnssd::CommissioningMode::kDisabled)
381 : {
382 : // We're not doing extended discovery right now.
383 : DeviceLayer::SystemLayer().CancelTimer(HandleExtendedDiscoveryExpiration, nullptr);
384 : mExtendedDiscoveryExpiration = kTimeoutCleared;
385 : }
386 : #endif // CHIP_DEVICE_CONFIG_ENABLE_EXTENDED_DISCOVERY
387 :
388 7 : return Advertise(true /* commissionableNode */, mode);
389 : }
390 :
391 12 : void DnssdServer::StartServer()
392 : {
393 12 : Dnssd::CommissioningMode mode = Dnssd::CommissioningMode::kDisabled;
394 12 : if (mCommissioningModeProvider)
395 : {
396 12 : mode = mCommissioningModeProvider->GetCommissioningMode();
397 : }
398 12 : return StartServer(mode);
399 : }
400 :
401 0 : void DnssdServer::StopServer()
402 : {
403 : // Make sure we don't hold on to a dangling fabric table pointer.
404 0 : mFabricTable = nullptr;
405 :
406 0 : DeviceLayer::PlatformMgr().RemoveEventHandler(OnPlatformEventWrapper, 0);
407 :
408 : #if CHIP_DEVICE_CONFIG_ENABLE_EXTENDED_DISCOVERY
409 : if (mExtendedDiscoveryExpiration != kTimeoutCleared)
410 : {
411 : DeviceLayer::SystemLayer().CancelTimer(HandleExtendedDiscoveryExpiration, nullptr);
412 : mExtendedDiscoveryExpiration = kTimeoutCleared;
413 : }
414 : #endif // CHIP_DEVICE_CONFIG_ENABLE_EXTENDED_DISCOVERY
415 :
416 0 : if (Dnssd::ServiceAdvertiser::Instance().IsInitialized())
417 : {
418 0 : auto err = Dnssd::ServiceAdvertiser::Instance().RemoveServices();
419 0 : if (err != CHIP_NO_ERROR)
420 : {
421 0 : ChipLogError(Discovery, "Failed to remove advertised services: %" CHIP_ERROR_FORMAT, err.Format());
422 : }
423 :
424 0 : Dnssd::ServiceAdvertiser::Instance().Shutdown();
425 : }
426 0 : }
427 :
428 12 : void DnssdServer::StartServer(Dnssd::CommissioningMode mode)
429 : {
430 12 : ChipLogProgress(Discovery, "Updating services using commissioning mode %d", static_cast<int>(mode));
431 :
432 12 : DeviceLayer::PlatformMgr().AddEventHandler(OnPlatformEventWrapper, 0);
433 :
434 12 : CHIP_ERROR err = Dnssd::ServiceAdvertiser::Instance().Init(chip::DeviceLayer::UDPEndPointManager());
435 12 : if (err != CHIP_NO_ERROR)
436 : {
437 0 : ChipLogError(Discovery, "Failed to initialize advertiser: %" CHIP_ERROR_FORMAT, err.Format());
438 : }
439 :
440 12 : err = Dnssd::ServiceAdvertiser::Instance().RemoveServices();
441 12 : if (err != CHIP_NO_ERROR)
442 : {
443 0 : ChipLogError(Discovery, "Failed to remove advertised services: %" CHIP_ERROR_FORMAT, err.Format());
444 : }
445 :
446 12 : err = AdvertiseOperational();
447 12 : if (err != CHIP_NO_ERROR)
448 : {
449 0 : ChipLogError(Discovery, "Failed to advertise operational node: %" CHIP_ERROR_FORMAT, err.Format());
450 : }
451 :
452 12 : if (mode != Dnssd::CommissioningMode::kDisabled)
453 : {
454 7 : err = AdvertiseCommissionableNode(mode);
455 7 : if (err != CHIP_NO_ERROR)
456 : {
457 0 : ChipLogError(Discovery, "Failed to advertise commissionable node: %" CHIP_ERROR_FORMAT, err.Format());
458 : }
459 : }
460 : #if CHIP_DEVICE_CONFIG_ENABLE_EXTENDED_DISCOVERY
461 : else if (GetExtendedDiscoveryTimeoutSecs() != CHIP_DEVICE_CONFIG_DISCOVERY_DISABLED)
462 : {
463 : bool alwaysAdvertiseExtended = (GetExtendedDiscoveryTimeoutSecs() == CHIP_DEVICE_CONFIG_DISCOVERY_NO_TIMEOUT);
464 : // We do extended discovery advertising in three cases:
465 : // 1) We don't have a timeout for extended discovery.
466 : // 2) We are transitioning out of commissioning mode (basic or enhanced)
467 : // and should therefore start extended discovery.
468 : // 3) We are resetting advertising while we are in the middle of an
469 : // existing extended discovery advertising period.
470 : if (alwaysAdvertiseExtended || mCurrentCommissioningMode != Dnssd::CommissioningMode::kDisabled ||
471 : mExtendedDiscoveryExpiration != kTimeoutCleared)
472 : {
473 : err = AdvertiseCommissionableNode(mode);
474 : if (err != CHIP_NO_ERROR)
475 : {
476 : ChipLogError(Discovery, "Failed to advertise extended commissionable node: %" CHIP_ERROR_FORMAT, err.Format());
477 : }
478 : if (mExtendedDiscoveryExpiration == kTimeoutCleared)
479 : {
480 : // set timeout
481 : ScheduleExtendedDiscoveryExpiration();
482 : }
483 : }
484 : }
485 : #endif // CHIP_DEVICE_CONFIG_ENABLE_EXTENDED_DISCOVERY
486 :
487 : #if CHIP_DEVICE_CONFIG_ENABLE_COMMISSIONER_DISCOVERY
488 : err = AdvertiseCommissioner();
489 : if (err != CHIP_NO_ERROR)
490 : {
491 : ChipLogError(Discovery, "Failed to advertise commissioner: %" CHIP_ERROR_FORMAT, err.Format());
492 : }
493 : #endif // CHIP_DEVICE_CONFIG_ENABLE_COMMISSIONER_DISCOVERY
494 :
495 12 : err = Dnssd::ServiceAdvertiser::Instance().FinalizeServiceUpdate();
496 12 : if (err != CHIP_NO_ERROR)
497 : {
498 0 : ChipLogError(Discovery, "Failed to finalize service update: %" CHIP_ERROR_FORMAT, err.Format());
499 : }
500 12 : }
501 :
502 : #if CHIP_ENABLE_ROTATING_DEVICE_ID && defined(CHIP_DEVICE_CONFIG_ROTATING_DEVICE_ID_UNIQUE_ID)
503 : CHIP_ERROR DnssdServer::GenerateRotatingDeviceId(char rotatingDeviceIdHexBuffer[], size_t rotatingDeviceIdHexBufferSize)
504 : {
505 : AdditionalDataPayloadGeneratorParams additionalDataPayloadParams;
506 : uint8_t rotatingDeviceIdUniqueId[chip::DeviceLayer::ConfigurationManager::kRotatingDeviceIDUniqueIDLength];
507 : MutableByteSpan rotatingDeviceIdUniqueIdSpan(rotatingDeviceIdUniqueId);
508 : size_t rotatingDeviceIdValueOutputSize = 0;
509 :
510 : ReturnErrorOnFailure(
511 : chip::DeviceLayer::GetDeviceInstanceInfoProvider()->GetRotatingDeviceIdUniqueId(rotatingDeviceIdUniqueIdSpan));
512 : ReturnErrorOnFailure(
513 : chip::DeviceLayer::ConfigurationMgr().GetLifetimeCounter(additionalDataPayloadParams.rotatingDeviceIdLifetimeCounter));
514 : additionalDataPayloadParams.rotatingDeviceIdUniqueId = rotatingDeviceIdUniqueIdSpan;
515 :
516 : return AdditionalDataPayloadGenerator().generateRotatingDeviceIdAsHexString(
517 : additionalDataPayloadParams, rotatingDeviceIdHexBuffer, rotatingDeviceIdHexBufferSize, rotatingDeviceIdValueOutputSize);
518 : }
519 : #endif
520 :
521 0 : void DnssdServer::OnICDModeChange()
522 : {
523 : // ICDMode changed, restart DNS-SD advertising, because SII and ICD key are affected by this change.
524 : // StartServer will take care of setting the operational and commissionable advertisements
525 0 : StartServer();
526 0 : }
527 :
528 : } // namespace app
529 : } // namespace chip
|