3 * Copyright (c) 2021 Project CHIP Authors
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
9 * http://www.apache.org/licenses/LICENSE-2.0
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.
22 #include <core/Optional.h>
23 #include <mdns/Advertiser.h>
24 #include <platform/CHIPDeviceLayer.h>
25 #include <platform/ConfigurationManager.h>
26 #include <support/ReturnMacros.h>
27 #include <support/logging/CHIPLogging.h>
28 #include <transport/AdminPairingTable.h>
29 #include <transport/PASESession.h>
39 NodeId GetCurrentNodeId()
41 // TODO: once operational credentials are implemented, node ID should be read from them
42 if (!DeviceLayer::ConfigurationMgr().IsFullyProvisioned())
44 ChipLogError(Discovery, "Device not fully provisioned. Node ID unknown.");
45 return chip::kTestDeviceNodeId;
48 // Admin pairings should have been persisted and should be loadable
50 // TODO: once multi-admin is decided, figure out if a single node id
51 // is sufficient or if we need multi-node-id advertisement. Existing
52 // mdns advertises a single node id as parameter.
54 // Search for one admin pairing and use its node id.
55 auto pairing = GetGlobalAdminPairingTable().cbegin();
56 if (pairing != GetGlobalAdminPairingTable().cend())
58 ChipLogProgress(Discovery, "Found admin paring for admin %" PRIX64 ", node %" PRIX64, pairing->GetAdminId(),
59 pairing->GetNodeId());
60 return pairing->GetNodeId();
63 ChipLogError(Discovery, "Failed to find a valid admin pairing. Node ID unknown");
64 return chip::kTestDeviceNodeId;
69 /// Set MDNS operational advertisement
70 CHIP_ERROR AdvertiseOperational()
74 if (DeviceLayer::ConfigurationMgr().GetFabricId(fabricId) != CHIP_NO_ERROR)
76 ChipLogError(Discovery, "Fabric ID not known. Using a default");
77 fabricId = 5544332211;
80 const auto advertiseParameters = chip::Mdns::OperationalAdvertisingParameters()
81 .SetFabricId(fabricId)
82 .SetNodeId(GetCurrentNodeId())
86 auto & mdnsAdvertiser = chip::Mdns::ServiceAdvertiser::Instance();
88 ReturnErrorOnFailure(mdnsAdvertiser.Advertise(advertiseParameters));
90 return mdnsAdvertiser.Start(&chip::DeviceLayer::InetLayer, chip::Mdns::kMdnsPort);
93 /// Set MDNS commisioning advertisement
94 CHIP_ERROR AdvertiseCommisioning()
97 auto advertiseParameters = chip::Mdns::CommissionAdvertisingParameters().SetPort(CHIP_PORT).EnableIpV4(true);
100 if (DeviceLayer::ConfigurationMgr().GetVendorId(value) != CHIP_NO_ERROR)
102 ChipLogProgress(Discovery, "Vendor ID not known");
106 advertiseParameters.SetVendorId(chip::Optional<uint16_t>::Value(value));
109 if (DeviceLayer::ConfigurationMgr().GetProductId(value) != CHIP_NO_ERROR)
111 ChipLogProgress(Discovery, "Product ID not known");
115 advertiseParameters.SetProductId(chip::Optional<uint16_t>::Value(value));
118 if (DeviceLayer::ConfigurationMgr().GetSetupDiscriminator(value) != CHIP_NO_ERROR)
120 ChipLogError(Discovery, "Setup discriminator not known. Using a default.");
123 advertiseParameters.SetShortDiscriminator(static_cast<uint8_t>(value & 0xFF)).SetLongDiscrimininator(value);
125 auto & mdnsAdvertiser = chip::Mdns::ServiceAdvertiser::Instance();
127 ReturnErrorOnFailure(mdnsAdvertiser.Advertise(advertiseParameters));
129 return mdnsAdvertiser.Start(&chip::DeviceLayer::InetLayer, chip::Mdns::kMdnsPort);
132 /// (Re-)starts the minmdns server
135 CHIP_ERROR err = chip::Mdns::ServiceAdvertiser::Instance().Start(&chip::DeviceLayer::InetLayer, chip::Mdns::kMdnsPort);
137 // TODO: advertise this only when really operational once we support both
138 // operational and commisioning advertising is supported.
139 if (DeviceLayer::ConfigurationMgr().IsFullyProvisioned())
141 err = app::Mdns::AdvertiseOperational();
145 // TODO: Thread devices are not able to advertise using mDNS before being provisioned,
146 // so configuraton should be added to enable commissioning advertising based on supported
147 // Rendezvous methods.
148 #if !CHIP_DEVICE_CONFIG_ENABLE_THREAD
149 err = app::Mdns::AdvertiseCommisioning();
153 if (err != CHIP_NO_ERROR)
155 ChipLogError(Discovery, "Failed to start mDNS server: %s", chip::ErrorStr(err));