1*cab87e9cSJagpal Singh Gill #include "config.h"
2*cab87e9cSJagpal Singh Gill
3*cab87e9cSJagpal Singh Gill #include "msl_verify.hpp"
4*cab87e9cSJagpal Singh Gill
5*cab87e9cSJagpal Singh Gill #include "version.hpp"
6*cab87e9cSJagpal Singh Gill
7*cab87e9cSJagpal Singh Gill #include <phosphor-logging/elog-errors.hpp>
8*cab87e9cSJagpal Singh Gill #include <phosphor-logging/elog.hpp>
9*cab87e9cSJagpal Singh Gill #include <phosphor-logging/lg2.hpp>
10*cab87e9cSJagpal Singh Gill #include <xyz/openbmc_project/Software/Version/error.hpp>
11*cab87e9cSJagpal Singh Gill
12*cab87e9cSJagpal Singh Gill #include <regex>
13*cab87e9cSJagpal Singh Gill
14*cab87e9cSJagpal Singh Gill PHOSPHOR_LOG2_USING;
15*cab87e9cSJagpal Singh Gill
compare(const Version & versionToCompare,const Version & mslVersion)16*cab87e9cSJagpal Singh Gill int minimum_ship_level::compare(const Version& versionToCompare,
17*cab87e9cSJagpal Singh Gill const Version& mslVersion)
18*cab87e9cSJagpal Singh Gill {
19*cab87e9cSJagpal Singh Gill if (versionToCompare.major > mslVersion.major)
20*cab87e9cSJagpal Singh Gill {
21*cab87e9cSJagpal Singh Gill return (1);
22*cab87e9cSJagpal Singh Gill }
23*cab87e9cSJagpal Singh Gill if (versionToCompare.major < mslVersion.major)
24*cab87e9cSJagpal Singh Gill {
25*cab87e9cSJagpal Singh Gill return (-1);
26*cab87e9cSJagpal Singh Gill }
27*cab87e9cSJagpal Singh Gill
28*cab87e9cSJagpal Singh Gill if (versionToCompare.minor > mslVersion.minor)
29*cab87e9cSJagpal Singh Gill {
30*cab87e9cSJagpal Singh Gill return (1);
31*cab87e9cSJagpal Singh Gill }
32*cab87e9cSJagpal Singh Gill if (versionToCompare.minor < mslVersion.minor)
33*cab87e9cSJagpal Singh Gill {
34*cab87e9cSJagpal Singh Gill return (-1);
35*cab87e9cSJagpal Singh Gill }
36*cab87e9cSJagpal Singh Gill
37*cab87e9cSJagpal Singh Gill if (versionToCompare.rev > mslVersion.rev)
38*cab87e9cSJagpal Singh Gill {
39*cab87e9cSJagpal Singh Gill return (1);
40*cab87e9cSJagpal Singh Gill }
41*cab87e9cSJagpal Singh Gill if (versionToCompare.rev < mslVersion.rev)
42*cab87e9cSJagpal Singh Gill {
43*cab87e9cSJagpal Singh Gill return (-1);
44*cab87e9cSJagpal Singh Gill }
45*cab87e9cSJagpal Singh Gill
46*cab87e9cSJagpal Singh Gill // Both string are equal and there is no need to make an upgrade return 0.
47*cab87e9cSJagpal Singh Gill return 0;
48*cab87e9cSJagpal Singh Gill }
49*cab87e9cSJagpal Singh Gill
50*cab87e9cSJagpal Singh Gill // parse Function copy inpVersion onto outVersion in Version format
51*cab87e9cSJagpal Singh Gill // {major,minor,rev}.
parse(const std::string & inpVersion,Version & outVersion)52*cab87e9cSJagpal Singh Gill void minimum_ship_level::parse(const std::string& inpVersion,
53*cab87e9cSJagpal Singh Gill Version& outVersion)
54*cab87e9cSJagpal Singh Gill {
55*cab87e9cSJagpal Singh Gill std::smatch match;
56*cab87e9cSJagpal Singh Gill outVersion = {0, 0, 0};
57*cab87e9cSJagpal Singh Gill
58*cab87e9cSJagpal Singh Gill std::regex rx{REGEX_BMC_MSL, std::regex::extended};
59*cab87e9cSJagpal Singh Gill
60*cab87e9cSJagpal Singh Gill if (!std::regex_search(inpVersion, match, rx))
61*cab87e9cSJagpal Singh Gill {
62*cab87e9cSJagpal Singh Gill error("Unable to parse BMC version: {VERSION}", "VERSION", inpVersion);
63*cab87e9cSJagpal Singh Gill return;
64*cab87e9cSJagpal Singh Gill }
65*cab87e9cSJagpal Singh Gill
66*cab87e9cSJagpal Singh Gill outVersion.major = std::stoi(match[2]);
67*cab87e9cSJagpal Singh Gill outVersion.minor = std::stoi(match[3]);
68*cab87e9cSJagpal Singh Gill outVersion.rev = std::stoi(match[4]);
69*cab87e9cSJagpal Singh Gill }
70*cab87e9cSJagpal Singh Gill
verify(const std::string & versionManifest)71*cab87e9cSJagpal Singh Gill bool minimum_ship_level::verify(const std::string& versionManifest)
72*cab87e9cSJagpal Singh Gill {
73*cab87e9cSJagpal Singh Gill // If there is no msl or mslRegex return upgrade is needed.
74*cab87e9cSJagpal Singh Gill if (!enabled())
75*cab87e9cSJagpal Singh Gill {
76*cab87e9cSJagpal Singh Gill return true;
77*cab87e9cSJagpal Singh Gill }
78*cab87e9cSJagpal Singh Gill
79*cab87e9cSJagpal Singh Gill // Define mslVersion variable and populate in Version format
80*cab87e9cSJagpal Singh Gill // {major,minor,rev} using parse function.
81*cab87e9cSJagpal Singh Gill
82*cab87e9cSJagpal Singh Gill std::string msl = getMinimumVersion();
83*cab87e9cSJagpal Singh Gill Version mslVersion = {0, 0, 0};
84*cab87e9cSJagpal Singh Gill parse(msl, mslVersion);
85*cab87e9cSJagpal Singh Gill
86*cab87e9cSJagpal Singh Gill // Define actualVersion variable and populate in Version format
87*cab87e9cSJagpal Singh Gill // {major,minor,rev} using parse function.
88*cab87e9cSJagpal Singh Gill std::string tmpStr{};
89*cab87e9cSJagpal Singh Gill
90*cab87e9cSJagpal Singh Gill tmpStr = versionManifest;
91*cab87e9cSJagpal Singh Gill Version actualVersion = {0, 0, 0};
92*cab87e9cSJagpal Singh Gill parse(versionManifest, actualVersion);
93*cab87e9cSJagpal Singh Gill
94*cab87e9cSJagpal Singh Gill // Compare actualVersion vs MSL.
95*cab87e9cSJagpal Singh Gill auto rc = compare(actualVersion, mslVersion);
96*cab87e9cSJagpal Singh Gill if (rc < 0)
97*cab87e9cSJagpal Singh Gill {
98*cab87e9cSJagpal Singh Gill using namespace phosphor::logging;
99*cab87e9cSJagpal Singh Gill using IncompatibleErr = sdbusplus::error::xyz::openbmc_project::
100*cab87e9cSJagpal Singh Gill software::version::Incompatible;
101*cab87e9cSJagpal Singh Gill using Incompatible =
102*cab87e9cSJagpal Singh Gill xyz::openbmc_project::software::version::Incompatible;
103*cab87e9cSJagpal Singh Gill std::string purpose =
104*cab87e9cSJagpal Singh Gill "xyz.openbmc_project.Software.Version.VersionPurpose.BMC";
105*cab87e9cSJagpal Singh Gill
106*cab87e9cSJagpal Singh Gill error(
107*cab87e9cSJagpal Singh Gill "BMC Minimum Ship Level ({MIN_VERSION}) NOT met by {ACTUAL_VERSION}",
108*cab87e9cSJagpal Singh Gill "MIN_VERSION", msl, "ACTUAL_VERSION", tmpStr, "VERSION_PURPOSE",
109*cab87e9cSJagpal Singh Gill purpose);
110*cab87e9cSJagpal Singh Gill report<IncompatibleErr>(Incompatible::MIN_VERSION(msl.c_str()),
111*cab87e9cSJagpal Singh Gill Incompatible::ACTUAL_VERSION(tmpStr.c_str()),
112*cab87e9cSJagpal Singh Gill Incompatible::VERSION_PURPOSE(purpose.c_str()));
113*cab87e9cSJagpal Singh Gill return false;
114*cab87e9cSJagpal Singh Gill }
115*cab87e9cSJagpal Singh Gill
116*cab87e9cSJagpal Singh Gill return true;
117*cab87e9cSJagpal Singh Gill }
118*cab87e9cSJagpal Singh Gill
enabled()119*cab87e9cSJagpal Singh Gill bool minimum_ship_level::enabled()
120*cab87e9cSJagpal Singh Gill {
121*cab87e9cSJagpal Singh Gill std::string msl = getMinimumVersion();
122*cab87e9cSJagpal Singh Gill std::string mslRegex{REGEX_BMC_MSL};
123*cab87e9cSJagpal Singh Gill return !msl.empty() && !mslRegex.empty();
124*cab87e9cSJagpal Singh Gill }
125*cab87e9cSJagpal Singh Gill
getMinimumVersion()126*cab87e9cSJagpal Singh Gill std::string minimum_ship_level::getMinimumVersion()
127*cab87e9cSJagpal Singh Gill {
128*cab87e9cSJagpal Singh Gill return BMC_MSL;
129*cab87e9cSJagpal Singh Gill }
130