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