blob: e7c8aa24fc90b557986075828c974c589890992b [file] [log] [blame]
// 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