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