3 * Copyright (c) 2020 Project CHIP Authors
4 * Copyright (c) 2018 Nest Labs, Inc.
7 * Licensed under the Apache License, Version 2.0 (the "License");
8 * you may not use this file except in compliance with the License.
9 * You may obtain a copy of the License at
11 * http://www.apache.org/licenses/LICENSE-2.0
13 * Unless required by applicable law or agreed to in writing, software
14 * distributed under the License is distributed on an "AS IS" BASIS,
15 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 * See the License for the specific language governing permissions and
17 * limitations under the License.
22 * Provides the implementation of the Device Layer ConfigurationManager object
23 * for Linux platforms.
26 #include <platform/internal/CHIPDeviceLayerInternal.h>
29 #include <netpacket/packet.h>
31 #include <core/CHIPVendorIdentifiers.hpp>
32 #include <platform/ConfigurationManager.h>
33 #include <platform/Linux/PosixConfig.h>
34 #include <platform/internal/GenericConfigurationManagerImpl.cpp>
35 #include <support/CodeUtils.h>
36 #include <support/logging/CHIPLogging.h>
39 namespace DeviceLayer {
41 using namespace ::chip::DeviceLayer::Internal;
43 /** Singleton instance of the ConfigurationManager implementation object.
45 ConfigurationManagerImpl ConfigurationManagerImpl::sInstance;
47 CHIP_ERROR ConfigurationManagerImpl::_Init()
52 // Force initialization of NVS namespaces if they doesn't already exist.
53 err = EnsureNamespace(kConfigNamespace_ChipFactory);
55 err = EnsureNamespace(kConfigNamespace_ChipConfig);
57 err = EnsureNamespace(kConfigNamespace_ChipCounters);
60 // Initialize the generic implementation base class.
61 err = Internal::GenericConfigurationManagerImpl<ConfigurationManagerImpl>::_Init();
64 // If the fail-safe was armed when the device last shutdown, initiate a factory reset.
65 if (_GetFailSafeArmed(failSafeArmed) == CHIP_NO_ERROR && failSafeArmed)
67 ChipLogProgress(DeviceLayer, "Detected fail-safe armed on reboot; initiating factory reset");
68 _InitiateFactoryReset();
77 CHIP_ERROR ConfigurationManagerImpl::_GetPrimaryWiFiMACAddress(uint8_t * buf)
79 struct ifaddrs * addresses = NULL;
80 CHIP_ERROR error = CHIP_NO_ERROR;
83 VerifyOrExit(getifaddrs(&addresses) == 0, error = CHIP_ERROR_INTERNAL);
84 for (auto addr = addresses; addr != NULL; addr = addr->ifa_next)
86 if ((addr->ifa_addr) && (addr->ifa_addr->sa_family == AF_PACKET) && strncmp(addr->ifa_name, "lo", IFNAMSIZ) != 0)
88 struct sockaddr_ll * mac = (struct sockaddr_ll *) addr->ifa_addr;
89 memcpy(buf, mac->sll_addr, mac->sll_halen);
94 freeifaddrs(addresses);
97 error = CHIP_ERROR_NO_ENDPOINT;
104 bool ConfigurationManagerImpl::_CanFactoryReset()
106 // TODO(#742): query the application to determine if factory reset is allowed.
110 void ConfigurationManagerImpl::_InitiateFactoryReset()
112 PlatformMgr().ScheduleWork(DoFactoryReset);
115 CHIP_ERROR ConfigurationManagerImpl::_ReadPersistedStorageValue(::chip::Platform::PersistedStorage::Key key, uint32_t & value)
117 PosixConfig::Key configKey{ kConfigNamespace_ChipCounters, key };
119 CHIP_ERROR err = ReadConfigValue(configKey, value);
120 if (err == CHIP_DEVICE_ERROR_CONFIG_NOT_FOUND)
122 err = CHIP_ERROR_PERSISTED_STORAGE_VALUE_NOT_FOUND;
127 CHIP_ERROR ConfigurationManagerImpl::_WritePersistedStorageValue(::chip::Platform::PersistedStorage::Key key, uint32_t value)
129 PosixConfig::Key configKey{ kConfigNamespace_ChipCounters, key };
130 return WriteConfigValue(configKey, value);
133 #if CHIP_DEVICE_CONFIG_ENABLE_WIFI_STATION
134 CHIP_ERROR ConfigurationManagerImpl::GetWiFiStationSecurityType(Profiles::NetworkProvisioning::WiFiSecurityType & secType)
139 err = ReadConfigValue(kConfigKey_WiFiStationSecType, secTypeInt);
140 if (err == CHIP_NO_ERROR)
142 secType = (Profiles::NetworkProvisioning::WiFiSecurityType) secTypeInt;
147 CHIP_ERROR ConfigurationManagerImpl::UpdateWiFiStationSecurityType(Profiles::NetworkProvisioning::WiFiSecurityType secType)
150 Profiles::NetworkProvisioning::WiFiSecurityType curSecType;
152 if (secType != Profiles::NetworkProvisioning::kWiFiSecurityType_NotSpecified)
154 err = GetWiFiStationSecurityType(curSecType);
155 if (err == CHIP_DEVICE_ERROR_CONFIG_NOT_FOUND || (err == CHIP_NO_ERROR && secType != curSecType))
157 uint32_t secTypeInt = secType;
158 err = WriteConfigValue(kConfigKey_WiFiStationSecType, secTypeInt);
164 err = ClearConfigValue(kConfigKey_WiFiStationSecType);
171 #endif // CHIP_DEVICE_CONFIG_ENABLE_WIFI_STATION
173 void ConfigurationManagerImpl::DoFactoryReset(intptr_t arg)
177 ChipLogProgress(DeviceLayer, "Performing factory reset");
179 err = FactoryResetConfig();
180 if (err != CHIP_NO_ERROR)
182 ChipLogError(DeviceLayer, "FactoryResetConfig() failed: %s", ErrorStr(err));
185 #if CHIP_DEVICE_CONFIG_ENABLE_THREAD
187 ChipLogProgress(DeviceLayer, "Clearing Thread provision");
188 ThreadStackMgr().ErasePersistentInfo();
190 #endif // CHIP_DEVICE_CONFIG_ENABLE_THREAD
192 // Restart the system.
193 ChipLogProgress(DeviceLayer, "System restarting (not implemented)");
194 // TODO(#742): restart CHIP exe
197 } // namespace DeviceLayer