xref: /openbmc/phosphor-bmc-code-mgmt/bmc/msl_verify.cpp (revision cab87e9cdeeb3e166d6d577511f6be4dc7721aca)
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