Fix for x86_64 build fail
[platform/upstream/connectedhomeip.git] / src / platform / Linux / ConfigurationManagerImpl.cpp
1 /*
2  *
3  *    Copyright (c) 2020 Project CHIP Authors
4  *    Copyright (c) 2018 Nest Labs, Inc.
5  *    All rights reserved.
6  *
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
10  *
11  *        http://www.apache.org/licenses/LICENSE-2.0
12  *
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.
18  */
19
20 /**
21  *    @file
22  *          Provides the implementation of the Device Layer ConfigurationManager object
23  *          for Linux platforms.
24  */
25
26 #include <platform/internal/CHIPDeviceLayerInternal.h>
27
28 #include <ifaddrs.h>
29 #include <netpacket/packet.h>
30
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>
37
38 namespace chip {
39 namespace DeviceLayer {
40
41 using namespace ::chip::DeviceLayer::Internal;
42
43 /** Singleton instance of the ConfigurationManager implementation object.
44  */
45 ConfigurationManagerImpl ConfigurationManagerImpl::sInstance;
46
47 CHIP_ERROR ConfigurationManagerImpl::_Init()
48 {
49     CHIP_ERROR err;
50     bool failSafeArmed;
51
52     // Force initialization of NVS namespaces if they doesn't already exist.
53     err = EnsureNamespace(kConfigNamespace_ChipFactory);
54     SuccessOrExit(err);
55     err = EnsureNamespace(kConfigNamespace_ChipConfig);
56     SuccessOrExit(err);
57     err = EnsureNamespace(kConfigNamespace_ChipCounters);
58     SuccessOrExit(err);
59
60     // Initialize the generic implementation base class.
61     err = Internal::GenericConfigurationManagerImpl<ConfigurationManagerImpl>::_Init();
62     SuccessOrExit(err);
63
64     // If the fail-safe was armed when the device last shutdown, initiate a factory reset.
65     if (_GetFailSafeArmed(failSafeArmed) == CHIP_NO_ERROR && failSafeArmed)
66     {
67         ChipLogProgress(DeviceLayer, "Detected fail-safe armed on reboot; initiating factory reset");
68         _InitiateFactoryReset();
69     }
70
71     err = CHIP_NO_ERROR;
72
73 exit:
74     return err;
75 }
76
77 CHIP_ERROR ConfigurationManagerImpl::_GetPrimaryWiFiMACAddress(uint8_t * buf)
78 {
79     struct ifaddrs * addresses = NULL;
80     CHIP_ERROR error           = CHIP_NO_ERROR;
81     bool found                 = false;
82
83     VerifyOrExit(getifaddrs(&addresses) == 0, error = CHIP_ERROR_INTERNAL);
84     for (auto addr = addresses; addr != NULL; addr = addr->ifa_next)
85     {
86         if ((addr->ifa_addr) && (addr->ifa_addr->sa_family == AF_PACKET) && strncmp(addr->ifa_name, "lo", IFNAMSIZ) != 0)
87         {
88             struct sockaddr_ll * mac = (struct sockaddr_ll *) addr->ifa_addr;
89             memcpy(buf, mac->sll_addr, mac->sll_halen);
90             found = true;
91             break;
92         }
93     }
94     freeifaddrs(addresses);
95     if (!found)
96     {
97         error = CHIP_ERROR_NO_ENDPOINT;
98     }
99
100 exit:
101     return error;
102 }
103
104 bool ConfigurationManagerImpl::_CanFactoryReset()
105 {
106     // TODO(#742): query the application to determine if factory reset is allowed.
107     return true;
108 }
109
110 void ConfigurationManagerImpl::_InitiateFactoryReset()
111 {
112     PlatformMgr().ScheduleWork(DoFactoryReset);
113 }
114
115 CHIP_ERROR ConfigurationManagerImpl::_ReadPersistedStorageValue(::chip::Platform::PersistedStorage::Key key, uint32_t & value)
116 {
117     PosixConfig::Key configKey{ kConfigNamespace_ChipCounters, key };
118
119     CHIP_ERROR err = ReadConfigValue(configKey, value);
120     if (err == CHIP_DEVICE_ERROR_CONFIG_NOT_FOUND)
121     {
122         err = CHIP_ERROR_PERSISTED_STORAGE_VALUE_NOT_FOUND;
123     }
124     return err;
125 }
126
127 CHIP_ERROR ConfigurationManagerImpl::_WritePersistedStorageValue(::chip::Platform::PersistedStorage::Key key, uint32_t value)
128 {
129     PosixConfig::Key configKey{ kConfigNamespace_ChipCounters, key };
130     return WriteConfigValue(configKey, value);
131 }
132
133 #if CHIP_DEVICE_CONFIG_ENABLE_WIFI_STATION
134 CHIP_ERROR ConfigurationManagerImpl::GetWiFiStationSecurityType(Profiles::NetworkProvisioning::WiFiSecurityType & secType)
135 {
136     CHIP_ERROR err;
137     uint32_t secTypeInt;
138
139     err = ReadConfigValue(kConfigKey_WiFiStationSecType, secTypeInt);
140     if (err == CHIP_NO_ERROR)
141     {
142         secType = (Profiles::NetworkProvisioning::WiFiSecurityType) secTypeInt;
143     }
144     return err;
145 }
146
147 CHIP_ERROR ConfigurationManagerImpl::UpdateWiFiStationSecurityType(Profiles::NetworkProvisioning::WiFiSecurityType secType)
148 {
149     CHIP_ERROR err;
150     Profiles::NetworkProvisioning::WiFiSecurityType curSecType;
151
152     if (secType != Profiles::NetworkProvisioning::kWiFiSecurityType_NotSpecified)
153     {
154         err = GetWiFiStationSecurityType(curSecType);
155         if (err == CHIP_DEVICE_ERROR_CONFIG_NOT_FOUND || (err == CHIP_NO_ERROR && secType != curSecType))
156         {
157             uint32_t secTypeInt = secType;
158             err                 = WriteConfigValue(kConfigKey_WiFiStationSecType, secTypeInt);
159         }
160         SuccessOrExit(err);
161     }
162     else
163     {
164         err = ClearConfigValue(kConfigKey_WiFiStationSecType);
165         SuccessOrExit(err);
166     }
167
168 exit:
169     return err;
170 }
171 #endif // CHIP_DEVICE_CONFIG_ENABLE_WIFI_STATION
172
173 void ConfigurationManagerImpl::DoFactoryReset(intptr_t arg)
174 {
175     CHIP_ERROR err;
176
177     ChipLogProgress(DeviceLayer, "Performing factory reset");
178
179     err = FactoryResetConfig();
180     if (err != CHIP_NO_ERROR)
181     {
182         ChipLogError(DeviceLayer, "FactoryResetConfig() failed: %s", ErrorStr(err));
183     }
184
185 #if CHIP_DEVICE_CONFIG_ENABLE_THREAD
186
187     ChipLogProgress(DeviceLayer, "Clearing Thread provision");
188     ThreadStackMgr().ErasePersistentInfo();
189
190 #endif // CHIP_DEVICE_CONFIG_ENABLE_THREAD
191
192     // Restart the system.
193     ChipLogProgress(DeviceLayer, "System restarting (not implemented)");
194     // TODO(#742): restart CHIP exe
195 }
196
197 } // namespace DeviceLayer
198 } // namespace chip