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