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 : #pragma once
19 :
20 : #include <app/icd/server/ICDServerConfig.h>
21 : #if CHIP_CONFIG_ENABLE_ICD_SERVER
22 : #include <app/icd/server/ICDManager.h> // nogncheck
23 : #endif
24 : #include <app/icd/server/ICDStateObserver.h>
25 : #include <app/server/CommissioningModeProvider.h>
26 : #include <credentials/FabricTable.h>
27 : #include <lib/core/CHIPError.h>
28 : #include <lib/core/Optional.h>
29 : #include <lib/dnssd/Advertiser.h>
30 : #include <platform/CHIPDeviceLayer.h>
31 : #include <stddef.h>
32 : #include <system/TimeSource.h>
33 :
34 : namespace chip {
35 : namespace app {
36 :
37 : class DLL_EXPORT DnssdServer : public ICDStateObserver
38 : {
39 : public:
40 : static constexpr System::Clock::Timestamp kTimeoutCleared = System::Clock::kZero;
41 :
42 : /// Provides the system-wide implementation of the service advertiser
43 29 : static DnssdServer & Instance()
44 : {
45 29 : static DnssdServer instance;
46 29 : return instance;
47 : }
48 :
49 : /// Sets the secure Matter port
50 1 : void SetSecuredPort(uint16_t port) { mSecuredPort = port; }
51 :
52 : /// Gets the secure Matter port
53 7 : uint16_t GetSecuredPort() const { return mSecuredPort; }
54 :
55 : /// Sets the unsecure Matter port
56 1 : void SetUnsecuredPort(uint16_t port) { mUnsecuredPort = port; }
57 :
58 : /// Gets the unsecure Matter port
59 0 : uint16_t GetUnsecuredPort() const { return mUnsecuredPort; }
60 :
61 : /// Sets the interface id used for advertising
62 1 : void SetInterfaceId(Inet::InterfaceId interfaceId) { mInterfaceId = interfaceId; }
63 :
64 : /// Gets the interface id used for advertising
65 7 : Inet::InterfaceId GetInterfaceId() { return mInterfaceId; }
66 :
67 : //
68 : // Set the fabric table the DnssdServer should use for operational
69 : // advertising. This must be set before StartServer() is called for the
70 : // first time.
71 : //
72 1 : void SetFabricTable(FabricTable * table)
73 : {
74 1 : VerifyOrDie(table != nullptr);
75 1 : mFabricTable = table;
76 1 : }
77 :
78 : // Set the commissioning mode provider to use. Null provider will mean we
79 : // assume the commissioning mode is kDisabled.
80 2 : void SetCommissioningModeProvider(CommissioningModeProvider * provider) { mCommissioningModeProvider = provider; }
81 :
82 : #if CHIP_DEVICE_CONFIG_ENABLE_EXTENDED_DISCOVERY
83 : /// Sets the extended discovery timeout. Value will be persisted across reboots
84 : void SetExtendedDiscoveryTimeoutSecs(int32_t secs);
85 :
86 : /// Callback from Extended Discovery Expiration timer
87 : /// Checks if extended discovery has expired and if so,
88 : /// stops commissionable node advertising
89 : /// Extended Discovery Expiration refers here to commissionable node advertising when NOT in commissioning mode
90 : void OnExtendedDiscoveryExpiration(System::Layer * aSystemLayer, void * aAppState);
91 : #endif // CHIP_DEVICE_CONFIG_ENABLE_EXTENDED_DISCOVERY
92 :
93 : #if CHIP_CONFIG_ENABLE_ICD_SERVER
94 : template <class AdvertisingParams>
95 : void AddICDKeyToAdvertisement(AdvertisingParams & advParams);
96 :
97 : void SetICDManager(ICDManager * manager) { mICDManager = manager; };
98 : #endif
99 :
100 : /// Start operational advertising
101 : CHIP_ERROR AdvertiseOperational();
102 :
103 : /// (Re-)starts the Dnssd server, using the commissioning mode from our
104 : /// commissioning mode provider.
105 : void StartServer();
106 :
107 : /// (Re-)starts the Dnssd server, using the provided commissioning mode.
108 : void StartServer(Dnssd::CommissioningMode mode);
109 :
110 : //// Stop the Dnssd server. After this call, SetFabricTable must be called
111 : //// again before calling StartServer().
112 : void StopServer();
113 :
114 : CHIP_ERROR GenerateRotatingDeviceId(char rotatingDeviceIdHexBuffer[], size_t rotatingDeviceIdHexBufferSize);
115 :
116 : /// Generates the (random) instance name that a CHIP device is to use for pre-commissioning DNS-SD
117 : CHIP_ERROR GetCommissionableInstanceName(char * buffer, size_t bufferLen);
118 :
119 : /**
120 : * @brief Overrides configuration so that commissionable advertisement will use an
121 : * ephemeral discriminator such as one set for ECM. If the Optional has no
122 : * value, the default basic discriminator is used as usual.
123 : *
124 : * @param[in] discriminator Ephemeral discriminator to override if it HasValue(), otherwise reverts
125 : * to default.
126 : * @return CHIP_NO_ERROR on success or CHIP_ERROR_INVALID_ARGUMENT on invalid value
127 : */
128 : CHIP_ERROR SetEphemeralDiscriminator(Optional<uint16_t> discriminator);
129 :
130 : /**
131 : * @brief When the ICD changes operating mode, the dnssd server needs to restart its DNS-SD advertising to update the TXT keys.
132 : */
133 : void OnICDModeChange() override;
134 :
135 : /**
136 : * @brief dnssd server has no action to do on this ICD event. Do nothing.
137 : */
138 0 : void OnEnterActiveMode() override{};
139 :
140 : /**
141 : * @brief dnssd server has no action to do on this ICD event. Do nothing.
142 : */
143 0 : void OnTransitionToIdle() override{};
144 :
145 : /**
146 : * @brief dnssd server has no action to do on this ICD event. Do nothing.
147 : */
148 0 : void OnEnterIdleMode() override{};
149 :
150 : private:
151 : /// Overloaded utility method for commissioner and commissionable advertisement
152 : /// This method is used for both commissioner discovery and commissionable node discovery since
153 : /// they share many fields.
154 : /// commissionableNode = true : advertise commissionable node
155 : /// commissionableNode = false : advertise commissioner
156 : CHIP_ERROR Advertise(bool commissionableNode, chip::Dnssd::CommissioningMode mode);
157 :
158 : /// Set MDNS commissioner advertisement
159 : CHIP_ERROR AdvertiseCommissioner();
160 :
161 : /// Set MDNS commissionable node advertisement
162 : CHIP_ERROR AdvertiseCommissionableNode(chip::Dnssd::CommissioningMode mode);
163 :
164 : // Our randomly-generated fallback "MAC address", in case we don't have a real one.
165 : uint8_t mFallbackMAC[chip::DeviceLayer::ConfigurationManager::kPrimaryMACAddressLength] = { 0 };
166 :
167 : void GetPrimaryOrFallbackMACAddress(chip::MutableByteSpan mac);
168 :
169 : //
170 : // Check if we have any valid operational credentials present in the fabric table and return true
171 : // if we do.
172 : //
173 : bool HaveOperationalCredentials();
174 :
175 : FabricTable * mFabricTable = nullptr;
176 : CommissioningModeProvider * mCommissioningModeProvider = nullptr;
177 :
178 : #if CHIP_CONFIG_ENABLE_ICD_SERVER
179 : ICDManager * mICDManager = nullptr;
180 : #endif // CHIP_CONFIG_ENABLE_ICD_SERVER
181 :
182 : uint16_t mSecuredPort = CHIP_PORT;
183 : uint16_t mUnsecuredPort = CHIP_UDC_PORT;
184 : Inet::InterfaceId mInterfaceId = Inet::InterfaceId::Null();
185 :
186 : // Ephemeral discriminator to use instead of the default if set
187 : Optional<uint16_t> mEphemeralDiscriminator;
188 :
189 : #if CHIP_DEVICE_CONFIG_ENABLE_EXTENDED_DISCOVERY
190 : Time::TimeSource<Time::Source::kSystem> mTimeSource;
191 :
192 : /// Get the current extended discovery timeout (set by
193 : /// SetExtendedDiscoveryTimeoutSecs, or the configuration default if not set).
194 : int32_t GetExtendedDiscoveryTimeoutSecs();
195 :
196 : /// schedule next extended discovery expiration
197 : CHIP_ERROR ScheduleExtendedDiscoveryExpiration();
198 :
199 : // mExtendedDiscoveryExpiration, if not set to kTimeoutCleared, is used to
200 : // indicate that we should be advertising extended discovery right now.
201 : System::Clock::Timestamp mExtendedDiscoveryExpiration = kTimeoutCleared;
202 : Optional<int32_t> mExtendedDiscoveryTimeoutSecs = NullOptional;
203 :
204 : // The commissioning mode we are advertising right now. Used to detect when
205 : // we need to start extended discovery advertisement. We start this off as
206 : // kEnabledBasic, so that when we first start up we do extended discovery
207 : // advertisement if we don't enter commissioning mode.
208 : Dnssd::CommissioningMode mCurrentCommissioningMode = Dnssd::CommissioningMode::kEnabledBasic;
209 : #endif // CHIP_DEVICE_CONFIG_ENABLE_EXTENDED_DISCOVERY
210 : };
211 :
212 : } // namespace app
213 : } // namespace chip
|