blob: 049ac9a171fe9b84712b6d4f48d2fca7a67f98ca [file] [log] [blame]
Patrick Williams6a85e8a2021-08-27 08:22:29 -05001#include "config.h"
2
3#include "msl_verify.hpp"
4
5#include "version.hpp"
6
zamiseck10ec9752022-04-27 12:39:50 -05007#include <phosphor-logging/elog-errors.hpp>
8#include <phosphor-logging/elog.hpp>
Patrick Williamsc9bb6422021-08-27 06:18:35 -05009#include <phosphor-logging/lg2.hpp>
zamiseck10ec9752022-04-27 12:39:50 -050010#include <xyz/openbmc_project/Software/Version/error.hpp>
Patrick Williams6a85e8a2021-08-27 08:22:29 -050011
12#include <regex>
13
Patrick Williamsc9bb6422021-08-27 06:18:35 -050014PHOSPHOR_LOG2_USING;
Patrick Williams6a85e8a2021-08-27 08:22:29 -050015
16int minimum_ship_level::compare(const Version& versionToCompare,
17 const Version& mslVersion)
18{
19 if (versionToCompare.major > mslVersion.major)
20 return (1);
21 if (versionToCompare.major < mslVersion.major)
22 return (-1);
23
24 if (versionToCompare.minor > mslVersion.minor)
25 return (1);
26 if (versionToCompare.minor < mslVersion.minor)
27 return (-1);
28
29 if (versionToCompare.rev > mslVersion.rev)
30 return (1);
31 if (versionToCompare.rev < mslVersion.rev)
32 return (-1);
33
34 // Both string are equal and there is no need to make an upgrade return 0.
35 return 0;
36}
37
38// parse Function copy inpVersion onto outVersion in Version format
39// {major,minor,rev}.
40void minimum_ship_level::parse(const std::string& inpVersion,
41 Version& outVersion)
42{
43 std::smatch match;
44 outVersion = {0, 0, 0};
45
46 std::regex rx{REGEX_BMC_MSL, std::regex::extended};
47
48 if (!std::regex_search(inpVersion, match, rx))
49 {
Patrick Williamsc9bb6422021-08-27 06:18:35 -050050 error("Unable to parse BMC version: {VERSION}", "VERSION", inpVersion);
Patrick Williams6a85e8a2021-08-27 08:22:29 -050051 return;
52 }
53
54 outVersion.major = std::stoi(match[2]);
55 outVersion.minor = std::stoi(match[3]);
56 outVersion.rev = std::stoi(match[4]);
57}
58
59bool minimum_ship_level::verify(const std::string& versionManifest)
60{
Patrick Williams6a85e8a2021-08-27 08:22:29 -050061 // If there is no msl or mslRegex return upgrade is needed.
62 std::string msl{BMC_MSL};
63 std::string mslRegex{REGEX_BMC_MSL};
64 if (msl.empty() || mslRegex.empty())
65 {
66 return true;
67 }
68
69 // Define mslVersion variable and populate in Version format
70 // {major,minor,rev} using parse function.
71
72 Version mslVersion = {0, 0, 0};
73 parse(msl, mslVersion);
74
75 // Define actualVersion variable and populate in Version format
76 // {major,minor,rev} using parse function.
77 std::string tmpStr{};
78
79 tmpStr = versionManifest;
80 Version actualVersion = {0, 0, 0};
81 parse(versionManifest, actualVersion);
82
83 // Compare actualVersion vs MSL.
84 auto rc = compare(actualVersion, mslVersion);
85 if (rc < 0)
86 {
zamiseck10ec9752022-04-27 12:39:50 -050087 using namespace phosphor::logging;
88 using IncompatibleErr = sdbusplus::xyz::openbmc_project::Software::
89 Version::Error::Incompatible;
90 using Incompatible =
91 xyz::openbmc_project::Software::Version::Incompatible;
92 std::string purpose =
93 "xyz.openbmc_project.Software.Version.VersionPurpose.BMC";
94
Patrick Williamsc9bb6422021-08-27 06:18:35 -050095 error(
96 "BMC Minimum Ship Level ({MIN_VERSION}) NOT met by {ACTUAL_VERSION}",
97 "MIN_VERSION", msl, "ACTUAL_VERSION", tmpStr, "VERSION_PURPOSE",
98 purpose);
zamiseck10ec9752022-04-27 12:39:50 -050099 report<IncompatibleErr>(Incompatible::MIN_VERSION(msl.c_str()),
100 Incompatible::ACTUAL_VERSION(tmpStr.c_str()),
101 Incompatible::VERSION_PURPOSE(purpose.c_str()));
Patrick Williams6a85e8a2021-08-27 08:22:29 -0500102 return false;
103 }
104
105 return true;
106}