| // Copyright 2021 Google LLC |
| // |
| // Licensed under the Apache License, Version 2.0 (the "License"); |
| // you may not use this file except in compliance with the License. |
| // You may obtain a copy of the License at |
| // |
| // http://www.apache.org/licenses/LICENSE-2.0 |
| // |
| // Unless required by applicable law or agreed to in writing, software |
| // distributed under the License is distributed on an "AS IS" BASIS, |
| // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| // See the License for the specific language governing permissions and |
| // limitations under the License. |
| |
| #include <flashupdate/args.hpp> |
| #include <flashupdate/info.hpp> |
| #include <flashupdate/logging.hpp> |
| #include <flashupdate/version.hpp> |
| #include <nlohmann/json.hpp> |
| |
| #include <charconv> |
| #include <format> |
| #include <memory> |
| #include <span> |
| #include <string> |
| |
| namespace flashupdate |
| { |
| namespace info |
| { |
| |
| /** @brief Helper to print debug message or std output |
| * |
| * @param[in] message Main message |
| * @param[in] output Print the message as std output with no debug |
| * message |
| */ |
| static void print(const std::string& message, bool output) |
| { |
| if (!output) |
| { |
| return; |
| } |
| STDLOG("{}", message); |
| } |
| |
| std::string bytesToHex(std::span<const uint8_t> hash) |
| { |
| std::string out; |
| for (uint8_t num : hash) |
| { |
| std::format_to(std::back_inserter(out), "{:02x}", num); |
| } |
| return out; |
| } |
| |
| std::string listStates() |
| { |
| std::string out; |
| for (const auto& [state, _] : info::stringToState) |
| { |
| std::format_to(std::back_inserter(out), " `{}`\n", state); |
| } |
| return out; |
| } |
| |
| std::string printUpdateInfo(const Args& args, struct UpdateInfo info) |
| { |
| nlohmann::json output; |
| if (args.checkStagedVersion) |
| { |
| |
| output["Staged Version"] = info.stage.format(); |
| print(output["Staged Version"], args.cleanOutput); |
| } |
| |
| if (args.checkActiveVersion) |
| { |
| output["Active Version"] = info.active.format(); |
| print(output["Active Version"], args.cleanOutput); |
| } |
| |
| if (args.checkStageState) |
| { |
| auto findState = stateToString.find(info.state); |
| std::string_view state = "CORRUPTED"; |
| if (findState != stateToString.end()) |
| { |
| state = findState->second; |
| } |
| |
| output["Staged State"] = state; |
| print(output["Staged State"], args.cleanOutput); |
| } |
| |
| if (args.checkStagedIndex) |
| { |
| output["Staged Index"] = std::to_string(info.stagingIndex); |
| print(output["Staged Index"], args.cleanOutput); |
| } |
| |
| if (args.otherInfo) |
| { |
| output["Stage CR51 Descriptor Hash"] = |
| bytesToHex(std::span<const uint8_t>(&info.stageDescriptor.hash[0], |
| &info.stageDescriptor.hash[0] + |
| SHA256_DIGEST_LENGTH)); |
| print(output["Stage CR51 Descriptor Hash"], args.cleanOutput); |
| } |
| |
| std::string outputStr = output.dump(); |
| |
| LOG(LogLevel::Notice, "{}", outputStr); |
| return outputStr; |
| } |
| |
| nlohmann::json UpdateInfo::json() |
| { |
| nlohmann::json output; |
| output["Staged Version"] = stage.format(); |
| output["Active Version"] = active.format(); |
| auto findState = stateToString.find(state); |
| if (findState == stateToString.end()) |
| { |
| output["Staged State"] = "CORRUPTED"; |
| } |
| else |
| { |
| output["Staged State"] = findState->second; |
| } |
| output["Staged Index"] = std::to_string(stagingIndex); |
| output["Stage CR51 Descriptor Hash"] = bytesToHex(std::span<const uint8_t>( |
| &stageDescriptor.hash[0], |
| &stageDescriptor.hash[0] + SHA256_DIGEST_LENGTH)); |
| return output; |
| } |
| |
| } // namespace info |
| } // namespace flashupdate |