| James Feist | c95cb14 | 2018-02-26 10:41:42 -0800 | [diff] [blame] | 1 | /* | 
|  | 2 | // Copyright (c) 2018 Intel Corporation | 
|  | 3 | // | 
|  | 4 | // Licensed under the Apache License, Version 2.0 (the "License"); | 
|  | 5 | // you may not use this file except in compliance with the License. | 
|  | 6 | // You may obtain a copy of the License at | 
|  | 7 | // | 
|  | 8 | //      http://www.apache.org/licenses/LICENSE-2.0 | 
|  | 9 | // | 
|  | 10 | // Unless required by applicable law or agreed to in writing, software | 
|  | 11 | // distributed under the License is distributed on an "AS IS" BASIS, | 
|  | 12 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | 
|  | 13 | // See the License for the specific language governing permissions and | 
|  | 14 | // limitations under the License. | 
|  | 15 | */ | 
|  | 16 |  | 
| Ed Tanous | 072e25d | 2018-12-16 21:45:20 -0800 | [diff] [blame] | 17 | #include "filesystem.hpp" | 
| James Feist | a465ccc | 2019-02-08 12:51:01 -0800 | [diff] [blame] | 18 |  | 
| James Feist | c95cb14 | 2018-02-26 10:41:42 -0800 | [diff] [blame] | 19 | #include <Overlay.hpp> | 
|  | 20 | #include <Utils.hpp> | 
| James Feist | a465ccc | 2019-02-08 12:51:01 -0800 | [diff] [blame] | 21 | #include <boost/algorithm/string/predicate.hpp> | 
|  | 22 | #include <boost/container/flat_map.hpp> | 
|  | 23 | #include <boost/container/flat_set.hpp> | 
|  | 24 | #include <boost/process/child.hpp> | 
|  | 25 | #include <devices.hpp> | 
|  | 26 | #include <iomanip> | 
|  | 27 | #include <iostream> | 
|  | 28 | #include <nlohmann/json.hpp> | 
|  | 29 | #include <regex> | 
|  | 30 | #include <string> | 
| James Feist | c95cb14 | 2018-02-26 10:41:42 -0800 | [diff] [blame] | 31 |  | 
| James Feist | a465ccc | 2019-02-08 12:51:01 -0800 | [diff] [blame] | 32 | constexpr const char* DT_OVERLAY = "/usr/bin/dtoverlay"; | 
|  | 33 | constexpr const char* DTC = "/usr/bin/dtc"; | 
|  | 34 | constexpr const char* OUTPUT_DIR = "/tmp/overlays"; | 
|  | 35 | constexpr const char* TEMPLATE_DIR = PACKAGE_DIR "overlay_templates"; | 
|  | 36 | constexpr const char* TEMPLATE_CHAR = "$"; | 
|  | 37 | constexpr const char* HEX_FORMAT_STR = "0x"; | 
|  | 38 | constexpr const char* PLATFORM = "aspeed,ast2500"; | 
|  | 39 | constexpr const char* I2C_DEVS_DIR = "/sys/bus/i2c/devices"; | 
|  | 40 | constexpr const char* MUX_SYMLINK_DIR = "/dev/i2c-mux"; | 
| James Feist | c95cb14 | 2018-02-26 10:41:42 -0800 | [diff] [blame] | 41 |  | 
|  | 42 | // some drivers need to be unbind / bind to load device tree changes | 
|  | 43 | static const boost::container::flat_map<std::string, std::string> FORCE_PROBES = | 
|  | 44 | {{"IntelFanConnector", "/sys/bus/platform/drivers/aspeed_pwm_tacho"}}; | 
|  | 45 |  | 
| James Feist | c95cb14 | 2018-02-26 10:41:42 -0800 | [diff] [blame] | 46 | std::regex ILLEGAL_NAME_REGEX("[^A-Za-z0-9_]"); | 
|  | 47 |  | 
| James Feist | a465ccc | 2019-02-08 12:51:01 -0800 | [diff] [blame] | 48 | void createOverlay(const std::string& templatePath, | 
|  | 49 | const nlohmann::json& configuration); | 
| James Feist | c95cb14 | 2018-02-26 10:41:42 -0800 | [diff] [blame] | 50 |  | 
|  | 51 | void unloadAllOverlays(void) | 
|  | 52 | { | 
|  | 53 | boost::process::child c(DT_OVERLAY, "-d", OUTPUT_DIR, "-R"); | 
|  | 54 | c.wait(); | 
|  | 55 | } | 
|  | 56 |  | 
|  | 57 | // this is hopefully temporary, but some drivers can't detect changes | 
|  | 58 | // without an unbind and bind so this function must exist for now | 
| James Feist | a465ccc | 2019-02-08 12:51:01 -0800 | [diff] [blame] | 59 | void forceProbe(const std::string& driver) | 
| James Feist | c95cb14 | 2018-02-26 10:41:42 -0800 | [diff] [blame] | 60 | { | 
|  | 61 | std::ofstream driverUnbind(driver + "/unbind"); | 
|  | 62 | std::ofstream driverBind(driver + "/bind"); | 
|  | 63 | if (!driverUnbind.is_open()) | 
|  | 64 | { | 
|  | 65 | std::cerr << "force probe error opening " << driver << "\n"; | 
|  | 66 | return; | 
|  | 67 | } | 
|  | 68 | if (!driverBind.is_open()) | 
|  | 69 | { | 
|  | 70 | driverUnbind.close(); | 
|  | 71 | std::cerr << "force probe error opening " << driver << "\n"; | 
|  | 72 | return; | 
|  | 73 | } | 
|  | 74 |  | 
| Ed Tanous | 072e25d | 2018-12-16 21:45:20 -0800 | [diff] [blame] | 75 | std::filesystem::path pathObj(driver); | 
| James Feist | a465ccc | 2019-02-08 12:51:01 -0800 | [diff] [blame] | 76 | for (auto& p : std::filesystem::directory_iterator(pathObj)) | 
| James Feist | c95cb14 | 2018-02-26 10:41:42 -0800 | [diff] [blame] | 77 | { | 
|  | 78 | // symlinks are object names | 
|  | 79 | if (is_symlink(p)) | 
|  | 80 | { | 
|  | 81 | std::string driverName = p.path().filename(); | 
|  | 82 | driverUnbind << driverName; | 
|  | 83 | driverBind << driverName; | 
|  | 84 | break; | 
|  | 85 | } | 
|  | 86 | } | 
|  | 87 | driverUnbind.close(); | 
|  | 88 | driverBind.close(); | 
|  | 89 | } | 
|  | 90 |  | 
|  | 91 | // helper function to make json types into string | 
| James Feist | a465ccc | 2019-02-08 12:51:01 -0800 | [diff] [blame] | 92 | std::string jsonToString(const nlohmann::json& in) | 
| James Feist | c95cb14 | 2018-02-26 10:41:42 -0800 | [diff] [blame] | 93 | { | 
|  | 94 | if (in.type() == nlohmann::json::value_t::string) | 
|  | 95 | { | 
|  | 96 | return in.get<std::string>(); | 
|  | 97 | } | 
|  | 98 | else if (in.type() == nlohmann::json::value_t::array) | 
|  | 99 | { | 
|  | 100 | // remove brackets and comma from array | 
|  | 101 | std::string array = in.dump(); | 
|  | 102 | array = array.substr(1, array.size() - 2); | 
|  | 103 | boost::replace_all(array, ",", " "); | 
|  | 104 | return array; | 
|  | 105 | } | 
|  | 106 | return in.dump(); | 
|  | 107 | } | 
|  | 108 |  | 
| James Feist | a465ccc | 2019-02-08 12:51:01 -0800 | [diff] [blame] | 109 | void linkMux(const std::string& muxName, size_t bus, size_t address, | 
|  | 110 | const nlohmann::json::array_t& channelNames) | 
| James Feist | c95cb14 | 2018-02-26 10:41:42 -0800 | [diff] [blame] | 111 | { | 
| James Feist | 286babc | 2019-02-07 16:48:28 -0800 | [diff] [blame] | 112 | // create directory first time | 
|  | 113 | static bool createDir = false; | 
|  | 114 | std::error_code ec; | 
|  | 115 | if (!createDir) | 
| James Feist | c95cb14 | 2018-02-26 10:41:42 -0800 | [diff] [blame] | 116 | { | 
| James Feist | 286babc | 2019-02-07 16:48:28 -0800 | [diff] [blame] | 117 | std::filesystem::create_directory(MUX_SYMLINK_DIR, ec); | 
|  | 118 | createDir = true; | 
|  | 119 | } | 
|  | 120 | std::ostringstream hex; | 
|  | 121 | hex << std::hex << std::setfill('0') << std::setw(4) << address; | 
| James Feist | a465ccc | 2019-02-08 12:51:01 -0800 | [diff] [blame] | 122 | const std::string& addressHex = hex.str(); | 
| James Feist | 286babc | 2019-02-07 16:48:28 -0800 | [diff] [blame] | 123 |  | 
|  | 124 | std::filesystem::path devDir(I2C_DEVS_DIR); | 
|  | 125 | devDir /= std::to_string(bus) + "-" + addressHex; | 
|  | 126 |  | 
|  | 127 | size_t channel = 0; | 
|  | 128 | std::string channelName; | 
|  | 129 | std::filesystem::path channelPath = devDir / "channel-0"; | 
|  | 130 | while (is_symlink(channelPath)) | 
|  | 131 | { | 
|  | 132 | if (channel > channelNames.size()) | 
|  | 133 | { | 
|  | 134 | channelName = std::to_string(channel); | 
|  | 135 | } | 
|  | 136 | else | 
|  | 137 | { | 
| James Feist | a465ccc | 2019-02-08 12:51:01 -0800 | [diff] [blame] | 138 | const std::string* ptr = | 
|  | 139 | channelNames[channel].get_ptr<const std::string*>(); | 
| James Feist | 286babc | 2019-02-07 16:48:28 -0800 | [diff] [blame] | 140 | if (ptr == nullptr) | 
|  | 141 | { | 
|  | 142 | channelName = channelNames[channel].dump(); | 
|  | 143 | } | 
|  | 144 | else | 
|  | 145 | { | 
|  | 146 | channelName = *ptr; | 
|  | 147 | } | 
|  | 148 | } | 
|  | 149 | // if configuration has name empty, don't put it in dev | 
| James Feist | 9d74626 | 2019-02-13 15:08:10 -0800 | [diff] [blame] | 150 | if (!channelName.empty()) | 
| James Feist | c95cb14 | 2018-02-26 10:41:42 -0800 | [diff] [blame] | 151 | { | 
| James Feist | 9d74626 | 2019-02-13 15:08:10 -0800 | [diff] [blame] | 152 | std::filesystem::path bus = | 
|  | 153 | std::filesystem::read_symlink(channelPath); | 
|  | 154 | const std::string& busName = bus.filename(); | 
|  | 155 |  | 
|  | 156 | std::string linkDir = MUX_SYMLINK_DIR + std::string("/") + muxName; | 
|  | 157 | if (channel == 0) | 
|  | 158 | { | 
|  | 159 | std::filesystem::create_directory(linkDir, ec); | 
|  | 160 | } | 
|  | 161 | std::filesystem::create_symlink( | 
|  | 162 | "/dev/" + busName, linkDir + std::string("/") + channelName, | 
|  | 163 | ec); | 
|  | 164 |  | 
|  | 165 | if (ec) | 
|  | 166 | { | 
|  | 167 | std::cerr << "Failure creating symlink for " << busName << "\n"; | 
|  | 168 | } | 
| James Feist | c95cb14 | 2018-02-26 10:41:42 -0800 | [diff] [blame] | 169 | } | 
| James Feist | 286babc | 2019-02-07 16:48:28 -0800 | [diff] [blame] | 170 | channel++; | 
|  | 171 | channelPath = devDir / ("channel-" + std::to_string(channel)); | 
|  | 172 | } | 
|  | 173 | if (channel == 0) | 
|  | 174 | { | 
|  | 175 | std::cerr << "Mux missing channels " << devDir << "\n"; | 
| James Feist | c95cb14 | 2018-02-26 10:41:42 -0800 | [diff] [blame] | 176 | } | 
|  | 177 | } | 
|  | 178 |  | 
| James Feist | a465ccc | 2019-02-08 12:51:01 -0800 | [diff] [blame] | 179 | void exportDevice(const std::string& type, | 
|  | 180 | const devices::ExportTemplate& exportTemplate, | 
|  | 181 | const nlohmann::json& configuration) | 
| James Feist | 053a664 | 2018-10-15 13:17:09 -0700 | [diff] [blame] | 182 | { | 
|  | 183 |  | 
|  | 184 | std::string parameters = exportTemplate.parameters; | 
|  | 185 | std::string device = exportTemplate.device; | 
|  | 186 | std::string name = "unknown"; | 
| James Feist | a465ccc | 2019-02-08 12:51:01 -0800 | [diff] [blame] | 187 | const uint64_t* bus = nullptr; | 
|  | 188 | const uint64_t* address = nullptr; | 
|  | 189 | const nlohmann::json::array_t* channels = nullptr; | 
| James Feist | 053a664 | 2018-10-15 13:17:09 -0700 | [diff] [blame] | 190 |  | 
|  | 191 | for (auto keyPair = configuration.begin(); keyPair != configuration.end(); | 
|  | 192 | keyPair++) | 
|  | 193 | { | 
|  | 194 | std::string subsituteString; | 
|  | 195 |  | 
|  | 196 | if (keyPair.key() == "Name" && | 
|  | 197 | keyPair.value().type() == nlohmann::json::value_t::string) | 
|  | 198 | { | 
|  | 199 | subsituteString = std::regex_replace( | 
|  | 200 | keyPair.value().get<std::string>(), ILLEGAL_NAME_REGEX, "_"); | 
|  | 201 | name = subsituteString; | 
|  | 202 | } | 
|  | 203 | else | 
|  | 204 | { | 
|  | 205 | subsituteString = jsonToString(keyPair.value()); | 
|  | 206 | } | 
|  | 207 |  | 
|  | 208 | if (keyPair.key() == "Bus") | 
|  | 209 | { | 
| James Feist | a465ccc | 2019-02-08 12:51:01 -0800 | [diff] [blame] | 210 | bus = keyPair.value().get_ptr<const uint64_t*>(); | 
| James Feist | 053a664 | 2018-10-15 13:17:09 -0700 | [diff] [blame] | 211 | } | 
|  | 212 | else if (keyPair.key() == "Address") | 
|  | 213 | { | 
| James Feist | a465ccc | 2019-02-08 12:51:01 -0800 | [diff] [blame] | 214 | address = keyPair.value().get_ptr<const uint64_t*>(); | 
| James Feist | 053a664 | 2018-10-15 13:17:09 -0700 | [diff] [blame] | 215 | } | 
| James Feist | 286babc | 2019-02-07 16:48:28 -0800 | [diff] [blame] | 216 | else if (keyPair.key() == "ChannelNames") | 
|  | 217 | { | 
|  | 218 | channels = | 
| James Feist | a465ccc | 2019-02-08 12:51:01 -0800 | [diff] [blame] | 219 | keyPair.value().get_ptr<const nlohmann::json::array_t*>(); | 
| James Feist | 286babc | 2019-02-07 16:48:28 -0800 | [diff] [blame] | 220 | } | 
| James Feist | 053a664 | 2018-10-15 13:17:09 -0700 | [diff] [blame] | 221 | boost::replace_all(parameters, TEMPLATE_CHAR + keyPair.key(), | 
|  | 222 | subsituteString); | 
|  | 223 | boost::replace_all(device, TEMPLATE_CHAR + keyPair.key(), | 
|  | 224 | subsituteString); | 
|  | 225 | } | 
|  | 226 |  | 
|  | 227 | // if we found bus and address we can attempt to prevent errors | 
|  | 228 | if (bus != nullptr && address != nullptr) | 
|  | 229 | { | 
|  | 230 | std::ostringstream hex; | 
|  | 231 | hex << std::hex << *address; | 
| James Feist | a465ccc | 2019-02-08 12:51:01 -0800 | [diff] [blame] | 232 | const std::string& addressHex = hex.str(); | 
| James Feist | 053a664 | 2018-10-15 13:17:09 -0700 | [diff] [blame] | 233 | std::string busStr = std::to_string(*bus); | 
|  | 234 |  | 
| Ed Tanous | 072e25d | 2018-12-16 21:45:20 -0800 | [diff] [blame] | 235 | std::filesystem::path devicePath(device); | 
| James Feist | 58b9c26 | 2019-02-12 13:38:45 -0800 | [diff] [blame] | 236 | std::filesystem::path parentPath = devicePath.parent_path(); | 
|  | 237 | if (std::filesystem::is_directory(parentPath)) | 
| James Feist | 053a664 | 2018-10-15 13:17:09 -0700 | [diff] [blame] | 238 | { | 
| James Feist | 58b9c26 | 2019-02-12 13:38:45 -0800 | [diff] [blame] | 239 | for (const auto& path : | 
|  | 240 | std::filesystem::directory_iterator(parentPath)) | 
| James Feist | 053a664 | 2018-10-15 13:17:09 -0700 | [diff] [blame] | 241 | { | 
| James Feist | 58b9c26 | 2019-02-12 13:38:45 -0800 | [diff] [blame] | 242 | if (!std::filesystem::is_directory(path)) | 
|  | 243 | { | 
|  | 244 | continue; | 
|  | 245 | } | 
| James Feist | 053a664 | 2018-10-15 13:17:09 -0700 | [diff] [blame] | 246 |  | 
| James Feist | 58b9c26 | 2019-02-12 13:38:45 -0800 | [diff] [blame] | 247 | const std::string& directoryName = path.path().filename(); | 
|  | 248 | if (boost::starts_with(directoryName, busStr) && | 
|  | 249 | boost::ends_with(directoryName, addressHex)) | 
|  | 250 | { | 
|  | 251 | return; // already exported | 
|  | 252 | } | 
| James Feist | 053a664 | 2018-10-15 13:17:09 -0700 | [diff] [blame] | 253 | } | 
|  | 254 | } | 
|  | 255 | } | 
|  | 256 |  | 
|  | 257 | std::ofstream deviceFile(device); | 
|  | 258 | if (!deviceFile.good()) | 
|  | 259 | { | 
|  | 260 | std::cerr << "Error writing " << device << "\n"; | 
|  | 261 | return; | 
|  | 262 | } | 
|  | 263 | deviceFile << parameters; | 
|  | 264 | deviceFile.close(); | 
| James Feist | 286babc | 2019-02-07 16:48:28 -0800 | [diff] [blame] | 265 | if (boost::ends_with(type, "Mux") && bus && address && channels) | 
|  | 266 | { | 
|  | 267 | linkMux(name, *bus, *address, *channels); | 
|  | 268 | } | 
| James Feist | 053a664 | 2018-10-15 13:17:09 -0700 | [diff] [blame] | 269 | } | 
|  | 270 |  | 
|  | 271 | // this is now deprecated | 
| James Feist | a465ccc | 2019-02-08 12:51:01 -0800 | [diff] [blame] | 272 | void createOverlay(const std::string& templatePath, | 
|  | 273 | const nlohmann::json& configuration) | 
| James Feist | c95cb14 | 2018-02-26 10:41:42 -0800 | [diff] [blame] | 274 | { | 
|  | 275 | std::ifstream templateFile(templatePath); | 
|  | 276 |  | 
|  | 277 | if (!templateFile.is_open()) | 
|  | 278 | { | 
|  | 279 | std::cerr << "createOverlay error opening " << templatePath << "\n"; | 
|  | 280 | return; | 
|  | 281 | } | 
|  | 282 | std::stringstream buff; | 
|  | 283 | buff << templateFile.rdbuf(); | 
|  | 284 | std::string templateStr = buff.str(); | 
|  | 285 | std::string name = "unknown"; | 
| James Feist | d63d18a | 2018-07-19 15:23:45 -0700 | [diff] [blame] | 286 | std::string type = configuration["Type"]; | 
| James Feist | c95cb14 | 2018-02-26 10:41:42 -0800 | [diff] [blame] | 287 | for (auto keyPair = configuration.begin(); keyPair != configuration.end(); | 
|  | 288 | keyPair++) | 
|  | 289 | { | 
|  | 290 | std::string subsituteString; | 
|  | 291 |  | 
|  | 292 | // device tree symbols are in decimal | 
| James Feist | 1e3e698 | 2018-08-03 16:09:28 -0700 | [diff] [blame] | 293 | if (keyPair.key() == "Bus" && | 
| James Feist | c95cb14 | 2018-02-26 10:41:42 -0800 | [diff] [blame] | 294 | keyPair.value().type() == nlohmann::json::value_t::string) | 
|  | 295 | { | 
|  | 296 | unsigned int dec = | 
|  | 297 | std::stoul(keyPair.value().get<std::string>(), nullptr, 16); | 
|  | 298 | subsituteString = std::to_string(dec); | 
|  | 299 | } | 
| James Feist | d63d18a | 2018-07-19 15:23:45 -0700 | [diff] [blame] | 300 | else if (keyPair.key() == "Name" && | 
| James Feist | c95cb14 | 2018-02-26 10:41:42 -0800 | [diff] [blame] | 301 | keyPair.value().type() == nlohmann::json::value_t::string) | 
|  | 302 | { | 
|  | 303 | subsituteString = std::regex_replace( | 
|  | 304 | keyPair.value().get<std::string>(), ILLEGAL_NAME_REGEX, "_"); | 
|  | 305 | name = subsituteString; | 
|  | 306 | } | 
| James Feist | 1e3e698 | 2018-08-03 16:09:28 -0700 | [diff] [blame] | 307 | else if (keyPair.key() == "Address") | 
| Jae Hyun Yoo | 6d1d014 | 2018-07-25 10:07:43 -0700 | [diff] [blame] | 308 | { | 
|  | 309 | if (keyPair.value().type() == nlohmann::json::value_t::string) | 
|  | 310 | { | 
|  | 311 | subsituteString = keyPair.value().get<std::string>(); | 
|  | 312 | subsituteString.erase( | 
|  | 313 | 0, subsituteString.find_first_not_of(HEX_FORMAT_STR)); | 
|  | 314 | } | 
|  | 315 | else | 
|  | 316 | { | 
|  | 317 | std::ostringstream hex; | 
|  | 318 | hex << std::hex << keyPair.value().get<unsigned int>(); | 
|  | 319 | subsituteString = hex.str(); | 
|  | 320 | } | 
|  | 321 | } | 
| James Feist | c95cb14 | 2018-02-26 10:41:42 -0800 | [diff] [blame] | 322 | else | 
|  | 323 | { | 
|  | 324 | subsituteString = jsonToString(keyPair.value()); | 
|  | 325 | } | 
|  | 326 | boost::replace_all(templateStr, TEMPLATE_CHAR + keyPair.key(), | 
|  | 327 | subsituteString); | 
|  | 328 | } | 
|  | 329 | // todo: this is a lame way to fill in platform, but we only | 
|  | 330 | // care about ast2500 right now | 
| James Feist | 1e3e698 | 2018-08-03 16:09:28 -0700 | [diff] [blame] | 331 | boost::replace_all(templateStr, TEMPLATE_CHAR + std::string("Platform"), | 
| James Feist | c95cb14 | 2018-02-26 10:41:42 -0800 | [diff] [blame] | 332 | PLATFORM); | 
|  | 333 | std::string dtsFilename = | 
|  | 334 | std::string(OUTPUT_DIR) + "/" + name + "_" + type + ".dts"; | 
|  | 335 | std::string dtboFilename = | 
|  | 336 | std::string(OUTPUT_DIR) + "/" + name + "_" + type + ".dtbo"; | 
|  | 337 |  | 
|  | 338 | std::ofstream out(dtsFilename); | 
|  | 339 | if (!out.is_open()) | 
|  | 340 | { | 
|  | 341 | std::cerr << "createOverlay error opening " << dtsFilename << "\n"; | 
|  | 342 | return; | 
|  | 343 | } | 
|  | 344 | out << templateStr; | 
|  | 345 | out.close(); | 
|  | 346 |  | 
| James Feist | c95cb14 | 2018-02-26 10:41:42 -0800 | [diff] [blame] | 347 | // compile dtbo and load overlay | 
|  | 348 | boost::process::child c1(DTC, "-@", "-q", "-I", "dts", "-O", "dtb", "-o", | 
|  | 349 | dtboFilename, dtsFilename); | 
|  | 350 | c1.wait(); | 
|  | 351 | if (c1.exit_code()) | 
|  | 352 | { | 
|  | 353 | std::cerr << "DTC error with file " << dtsFilename << "\n"; | 
|  | 354 | return; | 
|  | 355 | } | 
|  | 356 | boost::process::child c2(DT_OVERLAY, "-d", OUTPUT_DIR, name + "_" + type); | 
|  | 357 | c2.wait(); | 
|  | 358 | if (c2.exit_code()) | 
|  | 359 | { | 
|  | 360 | std::cerr << "DTOverlay error with file " << dtboFilename << "\n"; | 
|  | 361 | return; | 
|  | 362 | } | 
|  | 363 | auto findForceProbe = FORCE_PROBES.find(type); | 
|  | 364 | if (findForceProbe != FORCE_PROBES.end()) | 
|  | 365 | { | 
|  | 366 | forceProbe(findForceProbe->second); | 
|  | 367 | } | 
| James Feist | c95cb14 | 2018-02-26 10:41:42 -0800 | [diff] [blame] | 368 | } | 
|  | 369 |  | 
| James Feist | a465ccc | 2019-02-08 12:51:01 -0800 | [diff] [blame] | 370 | bool loadOverlays(const nlohmann::json& systemConfiguration) | 
| James Feist | c95cb14 | 2018-02-26 10:41:42 -0800 | [diff] [blame] | 371 | { | 
|  | 372 |  | 
| Ed Tanous | 072e25d | 2018-12-16 21:45:20 -0800 | [diff] [blame] | 373 | std::vector<std::filesystem::path> paths; | 
|  | 374 | if (!findFiles(std::filesystem::path(TEMPLATE_DIR), | 
| James Feist | a3c180a | 2018-08-09 16:06:04 -0700 | [diff] [blame] | 375 | R"(.*\.template)", paths)) | 
| James Feist | c95cb14 | 2018-02-26 10:41:42 -0800 | [diff] [blame] | 376 | { | 
|  | 377 | std::cerr << "Unable to find any tempate files in " << TEMPLATE_DIR | 
|  | 378 | << "\n"; | 
|  | 379 | return false; | 
|  | 380 | } | 
|  | 381 |  | 
| Ed Tanous | 072e25d | 2018-12-16 21:45:20 -0800 | [diff] [blame] | 382 | std::filesystem::create_directory(OUTPUT_DIR); | 
| James Feist | c95cb14 | 2018-02-26 10:41:42 -0800 | [diff] [blame] | 383 | for (auto entity = systemConfiguration.begin(); | 
|  | 384 | entity != systemConfiguration.end(); entity++) | 
|  | 385 | { | 
| James Feist | 1e3e698 | 2018-08-03 16:09:28 -0700 | [diff] [blame] | 386 | auto findExposes = entity.value().find("Exposes"); | 
| James Feist | c95cb14 | 2018-02-26 10:41:42 -0800 | [diff] [blame] | 387 | if (findExposes == entity.value().end() || | 
|  | 388 | findExposes->type() != nlohmann::json::value_t::array) | 
|  | 389 | { | 
|  | 390 | continue; | 
|  | 391 | } | 
|  | 392 |  | 
| James Feist | a465ccc | 2019-02-08 12:51:01 -0800 | [diff] [blame] | 393 | for (auto& configuration : *findExposes) | 
| James Feist | c95cb14 | 2018-02-26 10:41:42 -0800 | [diff] [blame] | 394 | { | 
| James Feist | 1e3e698 | 2018-08-03 16:09:28 -0700 | [diff] [blame] | 395 | auto findStatus = configuration.find("Status"); | 
| James Feist | c95cb14 | 2018-02-26 10:41:42 -0800 | [diff] [blame] | 396 | // status missing is assumed to be 'okay' | 
|  | 397 | if (findStatus != configuration.end() && *findStatus == "disabled") | 
|  | 398 | { | 
|  | 399 | continue; | 
|  | 400 | } | 
| James Feist | d63d18a | 2018-07-19 15:23:45 -0700 | [diff] [blame] | 401 | auto findType = configuration.find("Type"); | 
| James Feist | c95cb14 | 2018-02-26 10:41:42 -0800 | [diff] [blame] | 402 | if (findType == configuration.end() || | 
|  | 403 | findType->type() != nlohmann::json::value_t::string) | 
|  | 404 | { | 
|  | 405 | continue; | 
|  | 406 | } | 
|  | 407 | std::string type = findType.value().get<std::string>(); | 
| James Feist | ce4367c | 2018-10-16 09:19:57 -0700 | [diff] [blame] | 408 | #if OVERLAYS | 
|  | 409 |  | 
| James Feist | c95cb14 | 2018-02-26 10:41:42 -0800 | [diff] [blame] | 410 | std::string typeFile = type + std::string(".template"); | 
| James Feist | a465ccc | 2019-02-08 12:51:01 -0800 | [diff] [blame] | 411 | for (const auto& path : paths) | 
| James Feist | c95cb14 | 2018-02-26 10:41:42 -0800 | [diff] [blame] | 412 | { | 
|  | 413 | if (path.filename() != typeFile) | 
|  | 414 | { | 
|  | 415 | continue; | 
|  | 416 | } | 
|  | 417 | createOverlay(path.string(), configuration); | 
|  | 418 | break; | 
|  | 419 | } | 
| James Feist | ce4367c | 2018-10-16 09:19:57 -0700 | [diff] [blame] | 420 | #endif | 
| James Feist | 053a664 | 2018-10-15 13:17:09 -0700 | [diff] [blame] | 421 | auto device = devices::exportTemplates.find(type.c_str()); | 
|  | 422 | if (device != devices::exportTemplates.end()) | 
|  | 423 | { | 
| James Feist | 286babc | 2019-02-07 16:48:28 -0800 | [diff] [blame] | 424 | exportDevice(type, device->second, configuration); | 
| James Feist | 053a664 | 2018-10-15 13:17:09 -0700 | [diff] [blame] | 425 | } | 
| James Feist | c95cb14 | 2018-02-26 10:41:42 -0800 | [diff] [blame] | 426 | } | 
|  | 427 | } | 
|  | 428 |  | 
|  | 429 | return true; | 
| Jae Hyun Yoo | 6d1d014 | 2018-07-25 10:07:43 -0700 | [diff] [blame] | 430 | } |