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 30 : static DnssdServer & Instance()
44 : {
45 30 : static DnssdServer instance;
46 30 : 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 : #if INET_CONFIG_ENABLE_TCP_ENDPOINT
101 1 : void SetTCPServerEnabled(bool serverEnabled) { mTCPServerEnabled = serverEnabled; };
102 : #endif // INET_CONFIG_ENABLE_TCP_ENDPOINT
103 :
104 : /// Start operational advertising
105 : CHIP_ERROR AdvertiseOperational();
106 :
107 : /// (Re-)starts the Dnssd server, using the commissioning mode from our
108 : /// commissioning mode provider.
109 : void StartServer();
110 :
111 : /// (Re-)starts the Dnssd server, using the provided commissioning mode.
112 : void StartServer(Dnssd::CommissioningMode mode);
113 :
114 : //// Stop the Dnssd server. After this call, SetFabricTable must be called
115 : //// again before calling StartServer().
116 : void StopServer();
117 :
118 : CHIP_ERROR GenerateRotatingDeviceId(char rotatingDeviceIdHexBuffer[], size_t rotatingDeviceIdHexBufferSize);
119 :
120 : /// Generates the (random) instance name that a CHIP device is to use for pre-commissioning DNS-SD
121 : CHIP_ERROR GetCommissionableInstanceName(char * buffer, size_t bufferLen);
122 :
123 : /**
124 : * @brief Overrides configuration so that commissionable advertisement will use an
125 : * ephemeral discriminator such as one set for ECM. If the Optional has no
126 : * value, the default basic discriminator is used as usual.
127 : *
128 : * @param[in] discriminator Ephemeral discriminator to override if it HasValue(), otherwise reverts
129 : * to default.
130 : * @return CHIP_NO_ERROR on success or CHIP_ERROR_INVALID_ARGUMENT on invalid value
131 : */
132 : CHIP_ERROR SetEphemeralDiscriminator(Optional<uint16_t> discriminator);
133 :
134 : /**
135 : * @brief When the ICD changes operating mode, the dnssd server needs to restart its DNS-SD advertising to update the TXT keys.
136 : */
137 : void OnICDModeChange() override;
138 :
139 : /**
140 : * @brief dnssd server has no action to do on this ICD event. Do nothing.
141 : */
142 0 : void OnEnterActiveMode() override{};
143 :
144 : /**
145 : * @brief dnssd server has no action to do on this ICD event. Do nothing.
146 : */
147 0 : void OnTransitionToIdle() override{};
148 :
149 : /**
150 : * @brief dnssd server has no action to do on this ICD event. Do nothing.
151 : */
152 0 : void OnEnterIdleMode() override{};
153 :
154 : private:
155 : /// Overloaded utility method for commissioner and commissionable advertisement
156 : /// This method is used for both commissioner discovery and commissionable node discovery since
157 : /// they share many fields.
158 : /// commissionableNode = true : advertise commissionable node
159 : /// commissionableNode = false : advertise commissioner
160 : CHIP_ERROR Advertise(bool commissionableNode, chip::Dnssd::CommissioningMode mode);
161 :
162 : /// Set MDNS commissioner advertisement
163 : CHIP_ERROR AdvertiseCommissioner();
164 :
165 : /// Set MDNS commissionable node advertisement
166 : CHIP_ERROR AdvertiseCommissionableNode(chip::Dnssd::CommissioningMode mode);
167 :
168 : // Our randomly-generated fallback "MAC address", in case we don't have a real one.
169 : uint8_t mFallbackMAC[chip::DeviceLayer::ConfigurationManager::kPrimaryMACAddressLength] = { 0 };
170 :
171 : void GetPrimaryOrFallbackMACAddress(MutableByteSpan & mac);
172 :
173 : //
174 : // Check if we have any valid operational credentials present in the fabric table and return true
175 : // if we do.
176 : //
177 : bool HaveOperationalCredentials();
178 :
179 : FabricTable * mFabricTable = nullptr;
180 : CommissioningModeProvider * mCommissioningModeProvider = nullptr;
181 :
182 : #if CHIP_CONFIG_ENABLE_ICD_SERVER
183 : ICDManager * mICDManager = nullptr;
184 : #endif // CHIP_CONFIG_ENABLE_ICD_SERVER
185 :
186 : #if INET_CONFIG_ENABLE_TCP_ENDPOINT
187 : bool mTCPServerEnabled = true;
188 : #endif // INET_CONFIG_ENABLE_TCP_ENDPOINT
189 :
190 : uint16_t mSecuredPort = CHIP_PORT;
191 : uint16_t mUnsecuredPort = CHIP_UDC_PORT;
192 : Inet::InterfaceId mInterfaceId = Inet::InterfaceId::Null();
193 :
194 : // Ephemeral discriminator to use instead of the default if set
195 : Optional<uint16_t> mEphemeralDiscriminator;
196 :
197 : #if CHIP_DEVICE_CONFIG_ENABLE_EXTENDED_DISCOVERY
198 : Time::TimeSource<Time::Source::kSystem> mTimeSource;
199 :
200 : /// Get the current extended discovery timeout (set by
201 : /// SetExtendedDiscoveryTimeoutSecs, or the configuration default if not set).
202 : int32_t GetExtendedDiscoveryTimeoutSecs();
203 :
204 : /// schedule next extended discovery expiration
205 : CHIP_ERROR ScheduleExtendedDiscoveryExpiration();
206 :
207 : // mExtendedDiscoveryExpiration, if not set to kTimeoutCleared, is used to
208 : // indicate that we should be advertising extended discovery right now.
209 : System::Clock::Timestamp mExtendedDiscoveryExpiration = kTimeoutCleared;
210 : Optional<int32_t> mExtendedDiscoveryTimeoutSecs = NullOptional;
211 :
212 : // The commissioning mode we are advertising right now. Used to detect when
213 : // we need to start extended discovery advertisement. We start this off as
214 : // kEnabledBasic, so that when we first start up we do extended discovery
215 : // advertisement if we don't enter commissioning mode.
216 : Dnssd::CommissioningMode mCurrentCommissioningMode = Dnssd::CommissioningMode::kEnabledBasic;
217 : #endif // CHIP_DEVICE_CONFIG_ENABLE_EXTENDED_DISCOVERY
218 : };
219 :
220 : } // namespace app
221 : } // namespace chip
|