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