blob: 8dd30a01e5cc4d433d30c78114d80782377156c2 [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.
Adriana Kobylak30352a62024-04-09 09:25:36 -050062 if (!enabled())
Patrick Williams6a85e8a2021-08-27 08:22:29 -050063 {
64 return true;
65 }
66
67 // Define mslVersion variable and populate in Version format
68 // {major,minor,rev} using parse function.
69
Adriana Kobylak30352a62024-04-09 09:25:36 -050070 std::string msl = getMinimumVersion();
Patrick Williams6a85e8a2021-08-27 08:22:29 -050071 Version mslVersion = {0, 0, 0};
72 parse(msl, mslVersion);
73
74 // Define actualVersion variable and populate in Version format
75 // {major,minor,rev} using parse function.
76 std::string tmpStr{};
77
78 tmpStr = versionManifest;
79 Version actualVersion = {0, 0, 0};
80 parse(versionManifest, actualVersion);
81
82 // Compare actualVersion vs MSL.
83 auto rc = compare(actualVersion, mslVersion);
84 if (rc < 0)
85 {
zamiseck10ec9752022-04-27 12:39:50 -050086 using namespace phosphor::logging;
Adriana Kobylakce82de52024-01-16 13:56:38 -060087 using IncompatibleErr = sdbusplus::error::xyz::openbmc_project::
88 software::version::Incompatible;
zamiseck10ec9752022-04-27 12:39:50 -050089 using Incompatible =
Adriana Kobylakce82de52024-01-16 13:56:38 -060090 xyz::openbmc_project::software::version::Incompatible;
zamiseck10ec9752022-04-27 12:39:50 -050091 std::string purpose =
92 "xyz.openbmc_project.Software.Version.VersionPurpose.BMC";
93
Patrick Williamsc9bb6422021-08-27 06:18:35 -050094 error(
95 "BMC Minimum Ship Level ({MIN_VERSION}) NOT met by {ACTUAL_VERSION}",
96 "MIN_VERSION", msl, "ACTUAL_VERSION", tmpStr, "VERSION_PURPOSE",
97 purpose);
zamiseck10ec9752022-04-27 12:39:50 -050098 report<IncompatibleErr>(Incompatible::MIN_VERSION(msl.c_str()),
99 Incompatible::ACTUAL_VERSION(tmpStr.c_str()),
100 Incompatible::VERSION_PURPOSE(purpose.c_str()));
Patrick Williams6a85e8a2021-08-27 08:22:29 -0500101 return false;
102 }
103
104 return true;
105}
Adriana Kobylak30352a62024-04-09 09:25:36 -0500106
107bool minimum_ship_level::enabled()
108{
109 std::string msl = getMinimumVersion();
110 std::string mslRegex{REGEX_BMC_MSL};
111 if (!msl.empty() && !mslRegex.empty())
112 {
113 return true;
114 }
115 return false;
116}
117
118std::string minimum_ship_level::getMinimumVersion()
119{
120 return BMC_MSL;
121}