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 : if (mICDManager == nullptr)
153 : {
154 : ChipLogError(Discovery, "Invalid pointer to the ICDManager which is required for adding Dnssd advertisement key");
155 : return;
156 : }
157 :
158 : Dnssd::ICDModeAdvertise ICDModeToAdvertise = Dnssd::ICDModeAdvertise::kNone;
159 : // Only advertise the ICD key if the device can operate as a LIT
160 : if (mICDManager->SupportsFeature(Clusters::IcdManagement::Feature::kLongIdleTimeSupport))
161 : {
162 : if (mICDManager->GetICDMode() == ICDConfigurationData::ICDMode::LIT)
163 : {
164 : ICDModeToAdvertise = Dnssd::ICDModeAdvertise::kLIT;
165 : }
166 : else
167 : {
168 : ICDModeToAdvertise = Dnssd::ICDModeAdvertise::kSIT;
169 : }
170 : }
171 :
172 : advParams.SetICDModeToAdvertise(ICDModeToAdvertise);
173 : }
174 : #endif
175 :
176 7 : void DnssdServer::GetPrimaryOrFallbackMACAddress(MutableByteSpan & mac)
177 : {
178 7 : if (ConfigurationMgr().GetPrimaryMACAddress(mac) != CHIP_NO_ERROR)
179 : {
180 : // Only generate a fallback "MAC" once, so we don't keep constantly changing our host name.
181 0 : if (std::all_of(std::begin(mFallbackMAC), std::end(mFallbackMAC), [](uint8_t v) { return v == 0; }))
182 : {
183 0 : ChipLogError(Discovery, "Failed to get primary mac address of device. Generating a random one.");
184 0 : Crypto::DRBG_get_bytes(mFallbackMAC, sizeof(mFallbackMAC));
185 : }
186 0 : VerifyOrDie(mac.size() == sizeof(mFallbackMAC)); // kPrimaryMACAddressLength
187 0 : memcpy(mac.data(), mFallbackMAC, sizeof(mFallbackMAC));
188 : }
189 7 : }
190 :
191 : /// Set MDNS operational advertisement
192 12 : CHIP_ERROR DnssdServer::AdvertiseOperational()
193 : {
194 12 : VerifyOrReturnError(mFabricTable != nullptr, CHIP_ERROR_INCORRECT_STATE);
195 :
196 12 : for (const FabricInfo & fabricInfo : *mFabricTable)
197 : {
198 0 : if (!fabricInfo.ShouldAdvertiseIdentity())
199 : {
200 0 : continue;
201 : }
202 :
203 : uint8_t macBuffer[DeviceLayer::ConfigurationManager::kPrimaryMACAddressLength];
204 0 : MutableByteSpan mac(macBuffer);
205 0 : GetPrimaryOrFallbackMACAddress(mac);
206 :
207 0 : auto advertiseParameters = chip::Dnssd::OperationalAdvertisingParameters()
208 0 : .SetPeerId(fabricInfo.GetPeerId())
209 0 : .SetMac(mac)
210 0 : .SetPort(GetSecuredPort())
211 0 : .SetInterfaceId(GetInterfaceId())
212 0 : .SetLocalMRPConfig(GetLocalMRPConfig().std_optional())
213 0 : .EnableIpV4(SecuredIPv4PortMatchesIPv6Port());
214 :
215 : #if CHIP_CONFIG_ENABLE_ICD_SERVER
216 : AddICDKeyToAdvertisement(advertiseParameters);
217 : #endif
218 :
219 : #if INET_CONFIG_ENABLE_TCP_ENDPOINT
220 0 : advertiseParameters.SetTCPSupportModes(mTCPServerEnabled ? chip::Dnssd::TCPModeAdvertise::kTCPClientServer
221 : : chip::Dnssd::TCPModeAdvertise::kTCPClient);
222 : #endif
223 0 : auto & mdnsAdvertiser = chip::Dnssd::ServiceAdvertiser::Instance();
224 :
225 0 : ChipLogProgress(Discovery, "Advertise operational node " ChipLogFormatX64 "-" ChipLogFormatX64,
226 : ChipLogValueX64(advertiseParameters.GetPeerId().GetCompressedFabricId()),
227 : ChipLogValueX64(advertiseParameters.GetPeerId().GetNodeId()));
228 : // Should we keep trying to advertise the other operational
229 : // identities on failure?
230 0 : ReturnErrorOnFailure(mdnsAdvertiser.Advertise(advertiseParameters));
231 : }
232 12 : return CHIP_NO_ERROR;
233 : }
234 :
235 7 : CHIP_ERROR DnssdServer::Advertise(bool commissionableNode, chip::Dnssd::CommissioningMode mode)
236 : {
237 7 : auto advertiseParameters = chip::Dnssd::CommissionAdvertisingParameters()
238 7 : .SetPort(commissionableNode ? GetSecuredPort() : GetUnsecuredPort())
239 7 : .SetInterfaceId(GetInterfaceId())
240 7 : .EnableIpV4(!commissionableNode || SecuredIPv4PortMatchesIPv6Port());
241 7 : advertiseParameters.SetCommissionAdvertiseMode(commissionableNode ? chip::Dnssd::CommssionAdvertiseMode::kCommissionableNode
242 : : chip::Dnssd::CommssionAdvertiseMode::kCommissioner);
243 :
244 7 : advertiseParameters.SetCommissioningMode(mode);
245 :
246 : char pairingInst[chip::Dnssd::kKeyPairingInstructionMaxLength + 1];
247 :
248 : uint8_t macBuffer[DeviceLayer::ConfigurationManager::kPrimaryMACAddressLength];
249 7 : MutableByteSpan mac(macBuffer);
250 7 : GetPrimaryOrFallbackMACAddress(mac);
251 7 : advertiseParameters.SetMac(mac);
252 :
253 : uint16_t value;
254 : uint32_t val32;
255 7 : if (DeviceLayer::GetDeviceInstanceInfoProvider()->GetVendorId(value) != CHIP_NO_ERROR)
256 : {
257 0 : ChipLogDetail(Discovery, "Vendor ID not known");
258 : }
259 : else
260 : {
261 7 : advertiseParameters.SetVendorId(std::make_optional<uint16_t>(value));
262 : }
263 :
264 7 : if (DeviceLayer::GetDeviceInstanceInfoProvider()->GetProductId(value) != CHIP_NO_ERROR)
265 : {
266 0 : ChipLogDetail(Discovery, "Product ID not known");
267 : }
268 : else
269 : {
270 7 : advertiseParameters.SetProductId(std::make_optional<uint16_t>(value));
271 : }
272 :
273 7 : if (DeviceLayer::ConfigurationMgr().IsCommissionableDeviceTypeEnabled() &&
274 7 : DeviceLayer::ConfigurationMgr().GetDeviceTypeId(val32) == CHIP_NO_ERROR)
275 : {
276 0 : advertiseParameters.SetDeviceType(std::make_optional<uint32_t>(val32));
277 : }
278 :
279 : char deviceName[chip::Dnssd::kKeyDeviceNameMaxLength + 1];
280 7 : if (DeviceLayer::ConfigurationMgr().IsCommissionableDeviceNameEnabled() &&
281 7 : DeviceLayer::ConfigurationMgr().GetCommissionableDeviceName(deviceName, sizeof(deviceName)) == CHIP_NO_ERROR)
282 : {
283 0 : advertiseParameters.SetDeviceName(std::make_optional<const char *>(deviceName));
284 : }
285 :
286 7 : advertiseParameters.SetLocalMRPConfig(GetLocalMRPConfig().std_optional());
287 :
288 : #if CHIP_CONFIG_ENABLE_ICD_SERVER
289 : AddICDKeyToAdvertisement(advertiseParameters);
290 : #endif
291 :
292 7 : if (commissionableNode)
293 : {
294 7 : uint16_t discriminator = 0;
295 7 : CHIP_ERROR error = DeviceLayer::GetCommissionableDataProvider()->GetSetupDiscriminator(discriminator);
296 7 : if (error != CHIP_NO_ERROR)
297 : {
298 0 : ChipLogError(Discovery,
299 : "Setup discriminator read error (%" CHIP_ERROR_FORMAT ")! Critical error, will not be commissionable.",
300 : error.Format());
301 0 : return error;
302 : }
303 :
304 : // Override discriminator with temporary one if one is set
305 7 : discriminator = mEphemeralDiscriminator.ValueOr(discriminator);
306 :
307 7 : advertiseParameters.SetShortDiscriminator(static_cast<uint8_t>((discriminator >> 8) & 0x0F))
308 7 : .SetLongDiscriminator(discriminator);
309 :
310 : #if CHIP_ENABLE_ROTATING_DEVICE_ID && defined(CHIP_DEVICE_CONFIG_ROTATING_DEVICE_ID_UNIQUE_ID)
311 : char rotatingDeviceIdHexBuffer[RotatingDeviceId::kHexMaxLength];
312 : ReturnErrorOnFailure(GenerateRotatingDeviceId(rotatingDeviceIdHexBuffer, MATTER_ARRAY_SIZE(rotatingDeviceIdHexBuffer)));
313 : advertiseParameters.SetRotatingDeviceId(std::make_optional<const char *>(rotatingDeviceIdHexBuffer));
314 : #endif
315 :
316 7 : if (!HaveOperationalCredentials())
317 : {
318 7 : if (DeviceLayer::ConfigurationMgr().GetInitialPairingHint(value) != CHIP_NO_ERROR)
319 : {
320 0 : ChipLogDetail(Discovery, "DNS-SD Pairing Hint not set");
321 : }
322 : else
323 : {
324 7 : advertiseParameters.SetPairingHint(std::make_optional<uint16_t>(value));
325 : }
326 :
327 7 : if (DeviceLayer::ConfigurationMgr().GetInitialPairingInstruction(pairingInst, sizeof(pairingInst)) != CHIP_NO_ERROR)
328 : {
329 0 : ChipLogDetail(Discovery, "DNS-SD Pairing Instruction not set");
330 : }
331 : else
332 : {
333 7 : advertiseParameters.SetPairingInstruction(std::make_optional<const char *>(pairingInst));
334 : }
335 : }
336 : else
337 : {
338 0 : if (DeviceLayer::ConfigurationMgr().GetSecondaryPairingHint(value) != CHIP_NO_ERROR)
339 : {
340 0 : ChipLogDetail(Discovery, "DNS-SD Pairing Hint not set");
341 : }
342 : else
343 : {
344 0 : advertiseParameters.SetPairingHint(std::make_optional<uint16_t>(value));
345 : }
346 :
347 0 : if (DeviceLayer::ConfigurationMgr().GetSecondaryPairingInstruction(pairingInst, sizeof(pairingInst)) != CHIP_NO_ERROR)
348 : {
349 0 : ChipLogDetail(Discovery, "DNS-SD Pairing Instruction not set");
350 : }
351 : else
352 : {
353 0 : advertiseParameters.SetPairingInstruction(std::make_optional<const char *>(pairingInst));
354 : }
355 : }
356 : }
357 : #if CHIP_DEVICE_CONFIG_ENABLE_COMMISSIONER_PASSCODE
358 : else
359 : {
360 : advertiseParameters.SetCommissionerPasscodeSupported(std::make_optional<bool>(true));
361 : }
362 : #endif
363 :
364 7 : auto & mdnsAdvertiser = chip::Dnssd::ServiceAdvertiser::Instance();
365 :
366 7 : ChipLogProgress(Discovery, "Advertise commission parameter vendorID=%u productID=%u discriminator=%04u/%02u cm=%u cp=%u",
367 : advertiseParameters.GetVendorId().value_or(0), advertiseParameters.GetProductId().value_or(0),
368 : advertiseParameters.GetLongDiscriminator(), advertiseParameters.GetShortDiscriminator(),
369 : to_underlying(advertiseParameters.GetCommissioningMode()),
370 : advertiseParameters.GetCommissionerPasscodeSupported().value_or(false) ? 1 : 0);
371 7 : return mdnsAdvertiser.Advertise(advertiseParameters);
372 : }
373 :
374 0 : CHIP_ERROR DnssdServer::AdvertiseCommissioner()
375 : {
376 0 : return Advertise(false /* commissionableNode */, chip::Dnssd::CommissioningMode::kDisabled);
377 : }
378 :
379 7 : CHIP_ERROR DnssdServer::AdvertiseCommissionableNode(chip::Dnssd::CommissioningMode mode)
380 : {
381 : #if CHIP_DEVICE_CONFIG_ENABLE_EXTENDED_DISCOVERY
382 : mCurrentCommissioningMode = mode;
383 : if (mode != Dnssd::CommissioningMode::kDisabled)
384 : {
385 : // We're not doing extended discovery right now.
386 : DeviceLayer::SystemLayer().CancelTimer(HandleExtendedDiscoveryExpiration, nullptr);
387 : mExtendedDiscoveryExpiration = kTimeoutCleared;
388 : }
389 : #endif // CHIP_DEVICE_CONFIG_ENABLE_EXTENDED_DISCOVERY
390 :
391 7 : return Advertise(true /* commissionableNode */, mode);
392 : }
393 :
394 12 : void DnssdServer::StartServer()
395 : {
396 12 : Dnssd::CommissioningMode mode = Dnssd::CommissioningMode::kDisabled;
397 12 : if (mCommissioningModeProvider)
398 : {
399 12 : mode = mCommissioningModeProvider->GetCommissioningMode();
400 : }
401 12 : return StartServer(mode);
402 : }
403 :
404 0 : void DnssdServer::StopServer()
405 : {
406 : // Make sure we don't hold on to a dangling fabric table pointer.
407 0 : mFabricTable = nullptr;
408 :
409 0 : DeviceLayer::PlatformMgr().RemoveEventHandler(OnPlatformEventWrapper, 0);
410 :
411 : #if CHIP_DEVICE_CONFIG_ENABLE_EXTENDED_DISCOVERY
412 : if (mExtendedDiscoveryExpiration != kTimeoutCleared)
413 : {
414 : DeviceLayer::SystemLayer().CancelTimer(HandleExtendedDiscoveryExpiration, nullptr);
415 : mExtendedDiscoveryExpiration = kTimeoutCleared;
416 : }
417 : #endif // CHIP_DEVICE_CONFIG_ENABLE_EXTENDED_DISCOVERY
418 :
419 0 : if (Dnssd::ServiceAdvertiser::Instance().IsInitialized())
420 : {
421 0 : auto err = Dnssd::ServiceAdvertiser::Instance().RemoveServices();
422 0 : if (err != CHIP_NO_ERROR)
423 : {
424 0 : ChipLogError(Discovery, "Failed to remove advertised services: %" CHIP_ERROR_FORMAT, err.Format());
425 : }
426 :
427 0 : Dnssd::ServiceAdvertiser::Instance().Shutdown();
428 : }
429 0 : }
430 :
431 12 : void DnssdServer::StartServer(Dnssd::CommissioningMode mode)
432 : {
433 12 : ChipLogProgress(Discovery, "Updating services using commissioning mode %d", static_cast<int>(mode));
434 :
435 12 : DeviceLayer::PlatformMgr().AddEventHandler(OnPlatformEventWrapper, 0);
436 :
437 12 : CHIP_ERROR err = Dnssd::ServiceAdvertiser::Instance().Init(chip::DeviceLayer::UDPEndPointManager());
438 12 : if (err != CHIP_NO_ERROR)
439 : {
440 0 : ChipLogError(Discovery, "Failed to initialize advertiser: %" CHIP_ERROR_FORMAT, err.Format());
441 : }
442 :
443 12 : err = Dnssd::ServiceAdvertiser::Instance().RemoveServices();
444 12 : if (err != CHIP_NO_ERROR)
445 : {
446 0 : ChipLogError(Discovery, "Failed to remove advertised services: %" CHIP_ERROR_FORMAT, err.Format());
447 : }
448 :
449 12 : err = AdvertiseOperational();
450 12 : if (err != CHIP_NO_ERROR)
451 : {
452 0 : ChipLogError(Discovery, "Failed to advertise operational node: %" CHIP_ERROR_FORMAT, err.Format());
453 : }
454 :
455 12 : if (mode != Dnssd::CommissioningMode::kDisabled)
456 : {
457 7 : err = AdvertiseCommissionableNode(mode);
458 7 : if (err != CHIP_NO_ERROR)
459 : {
460 0 : ChipLogError(Discovery, "Failed to advertise commissionable node: %" CHIP_ERROR_FORMAT, err.Format());
461 : }
462 : }
463 : #if CHIP_DEVICE_CONFIG_ENABLE_EXTENDED_DISCOVERY
464 : else if (GetExtendedDiscoveryTimeoutSecs() != CHIP_DEVICE_CONFIG_DISCOVERY_DISABLED)
465 : {
466 : bool alwaysAdvertiseExtended = (GetExtendedDiscoveryTimeoutSecs() == CHIP_DEVICE_CONFIG_DISCOVERY_NO_TIMEOUT);
467 : // We do extended discovery advertising in three cases:
468 : // 1) We don't have a timeout for extended discovery.
469 : // 2) We are transitioning out of commissioning mode (basic or enhanced)
470 : // and should therefore start extended discovery.
471 : // 3) We are resetting advertising while we are in the middle of an
472 : // existing extended discovery advertising period.
473 : if (alwaysAdvertiseExtended || mCurrentCommissioningMode != Dnssd::CommissioningMode::kDisabled ||
474 : mExtendedDiscoveryExpiration != kTimeoutCleared)
475 : {
476 : err = AdvertiseCommissionableNode(mode);
477 : if (err != CHIP_NO_ERROR)
478 : {
479 : ChipLogError(Discovery, "Failed to advertise extended commissionable node: %" CHIP_ERROR_FORMAT, err.Format());
480 : }
481 : if (mExtendedDiscoveryExpiration == kTimeoutCleared)
482 : {
483 : // set timeout
484 : ScheduleExtendedDiscoveryExpiration();
485 : }
486 : }
487 : }
488 : #endif // CHIP_DEVICE_CONFIG_ENABLE_EXTENDED_DISCOVERY
489 :
490 : #if CHIP_DEVICE_CONFIG_ENABLE_COMMISSIONER_DISCOVERY
491 : err = AdvertiseCommissioner();
492 : if (err != CHIP_NO_ERROR)
493 : {
494 : ChipLogError(Discovery, "Failed to advertise commissioner: %" CHIP_ERROR_FORMAT, err.Format());
495 : }
496 : #endif // CHIP_DEVICE_CONFIG_ENABLE_COMMISSIONER_DISCOVERY
497 :
498 12 : err = Dnssd::ServiceAdvertiser::Instance().FinalizeServiceUpdate();
499 12 : if (err != CHIP_NO_ERROR)
500 : {
501 0 : ChipLogError(Discovery, "Failed to finalize service update: %" CHIP_ERROR_FORMAT, err.Format());
502 : }
503 12 : }
504 :
505 : #if CHIP_ENABLE_ROTATING_DEVICE_ID && defined(CHIP_DEVICE_CONFIG_ROTATING_DEVICE_ID_UNIQUE_ID)
506 : CHIP_ERROR DnssdServer::GenerateRotatingDeviceId(char rotatingDeviceIdHexBuffer[], size_t rotatingDeviceIdHexBufferSize)
507 : {
508 : AdditionalDataPayloadGeneratorParams additionalDataPayloadParams;
509 : uint8_t rotatingDeviceIdUniqueId[chip::DeviceLayer::ConfigurationManager::kRotatingDeviceIDUniqueIDLength];
510 : MutableByteSpan rotatingDeviceIdUniqueIdSpan(rotatingDeviceIdUniqueId);
511 : size_t rotatingDeviceIdValueOutputSize = 0;
512 :
513 : ReturnErrorOnFailure(
514 : chip::DeviceLayer::GetDeviceInstanceInfoProvider()->GetRotatingDeviceIdUniqueId(rotatingDeviceIdUniqueIdSpan));
515 : ReturnErrorOnFailure(
516 : chip::DeviceLayer::ConfigurationMgr().GetLifetimeCounter(additionalDataPayloadParams.rotatingDeviceIdLifetimeCounter));
517 : additionalDataPayloadParams.rotatingDeviceIdUniqueId = rotatingDeviceIdUniqueIdSpan;
518 :
519 : return AdditionalDataPayloadGenerator().generateRotatingDeviceIdAsHexString(
520 : additionalDataPayloadParams, rotatingDeviceIdHexBuffer, rotatingDeviceIdHexBufferSize, rotatingDeviceIdValueOutputSize);
521 : }
522 : #endif
523 :
524 0 : void DnssdServer::OnICDModeChange()
525 : {
526 : // ICDMode changed, restart DNS-SD advertising, because SII and ICD key are affected by this change.
527 : // StartServer will take care of setting the operational and commissionable advertisements
528 0 : StartServer();
529 0 : }
530 :
531 : } // namespace app
532 : } // namespace chip
|