121dad047SMiguel Gomez #include "config.h" 221dad047SMiguel Gomez 321dad047SMiguel Gomez #include "msl_verify.hpp" 421dad047SMiguel Gomez 521dad047SMiguel Gomez #include "version.hpp" 621dad047SMiguel Gomez 7*10ec9750Szamiseck #include <phosphor-logging/elog-errors.hpp> 8*10ec9750Szamiseck #include <phosphor-logging/elog.hpp> 9c9bb6425SPatrick Williams #include <phosphor-logging/lg2.hpp> 10*10ec9750Szamiseck #include <xyz/openbmc_project/Software/Version/error.hpp> 1121dad047SMiguel Gomez 1221dad047SMiguel Gomez #include <regex> 1321dad047SMiguel Gomez 14c9bb6425SPatrick Williams PHOSPHOR_LOG2_USING; 1521dad047SMiguel Gomez 1621dad047SMiguel Gomez int minimum_ship_level::compare(const Version& versionToCompare, 1721dad047SMiguel Gomez const Version& mslVersion) 1821dad047SMiguel Gomez { 1921dad047SMiguel Gomez if (versionToCompare.major > mslVersion.major) 2021dad047SMiguel Gomez return (1); 2121dad047SMiguel Gomez if (versionToCompare.major < mslVersion.major) 2221dad047SMiguel Gomez return (-1); 2321dad047SMiguel Gomez 2421dad047SMiguel Gomez if (versionToCompare.minor > mslVersion.minor) 2521dad047SMiguel Gomez return (1); 2621dad047SMiguel Gomez if (versionToCompare.minor < mslVersion.minor) 2721dad047SMiguel Gomez return (-1); 2821dad047SMiguel Gomez 2921dad047SMiguel Gomez if (versionToCompare.rev > mslVersion.rev) 3021dad047SMiguel Gomez return (1); 3121dad047SMiguel Gomez if (versionToCompare.rev < mslVersion.rev) 3221dad047SMiguel Gomez return (-1); 3321dad047SMiguel Gomez 3421dad047SMiguel Gomez // Both string are equal and there is no need to make an upgrade return 0. 3521dad047SMiguel Gomez return 0; 3621dad047SMiguel Gomez } 3721dad047SMiguel Gomez 3821dad047SMiguel Gomez // parse Function copy inpVersion onto outVersion in Version format 3921dad047SMiguel Gomez // {major,minor,rev}. 4021dad047SMiguel Gomez void minimum_ship_level::parse(const std::string& inpVersion, 4121dad047SMiguel Gomez Version& outVersion) 4221dad047SMiguel Gomez { 4321dad047SMiguel Gomez std::smatch match; 4421dad047SMiguel Gomez outVersion = {0, 0, 0}; 4521dad047SMiguel Gomez 4621dad047SMiguel Gomez std::regex rx{REGEX_BMC_MSL, std::regex::extended}; 4721dad047SMiguel Gomez 4821dad047SMiguel Gomez if (!std::regex_search(inpVersion, match, rx)) 4921dad047SMiguel Gomez { 50c9bb6425SPatrick Williams error("Unable to parse BMC version: {VERSION}", "VERSION", inpVersion); 5121dad047SMiguel Gomez return; 5221dad047SMiguel Gomez } 5321dad047SMiguel Gomez 5421dad047SMiguel Gomez outVersion.major = std::stoi(match[2]); 5521dad047SMiguel Gomez outVersion.minor = std::stoi(match[3]); 5621dad047SMiguel Gomez outVersion.rev = std::stoi(match[4]); 5721dad047SMiguel Gomez } 5821dad047SMiguel Gomez 5921dad047SMiguel Gomez bool minimum_ship_level::verify(const std::string& versionManifest) 6021dad047SMiguel Gomez { 6121dad047SMiguel Gomez 6221dad047SMiguel Gomez // If there is no msl or mslRegex return upgrade is needed. 6321dad047SMiguel Gomez std::string msl{BMC_MSL}; 6421dad047SMiguel Gomez std::string mslRegex{REGEX_BMC_MSL}; 6521dad047SMiguel Gomez if (msl.empty() || mslRegex.empty()) 6621dad047SMiguel Gomez { 6721dad047SMiguel Gomez return true; 6821dad047SMiguel Gomez } 6921dad047SMiguel Gomez 7021dad047SMiguel Gomez // Define mslVersion variable and populate in Version format 7121dad047SMiguel Gomez // {major,minor,rev} using parse function. 7221dad047SMiguel Gomez 7321dad047SMiguel Gomez Version mslVersion = {0, 0, 0}; 7421dad047SMiguel Gomez parse(msl, mslVersion); 7521dad047SMiguel Gomez 7621dad047SMiguel Gomez // Define actualVersion variable and populate in Version format 7721dad047SMiguel Gomez // {major,minor,rev} using parse function. 7821dad047SMiguel Gomez std::string tmpStr{}; 7921dad047SMiguel Gomez 8021dad047SMiguel Gomez tmpStr = versionManifest; 8121dad047SMiguel Gomez Version actualVersion = {0, 0, 0}; 8221dad047SMiguel Gomez parse(versionManifest, actualVersion); 8321dad047SMiguel Gomez 8421dad047SMiguel Gomez // Compare actualVersion vs MSL. 8521dad047SMiguel Gomez auto rc = compare(actualVersion, mslVersion); 8621dad047SMiguel Gomez if (rc < 0) 8721dad047SMiguel Gomez { 88*10ec9750Szamiseck using namespace phosphor::logging; 89*10ec9750Szamiseck using IncompatibleErr = sdbusplus::xyz::openbmc_project::Software:: 90*10ec9750Szamiseck Version::Error::Incompatible; 91*10ec9750Szamiseck using Incompatible = 92*10ec9750Szamiseck xyz::openbmc_project::Software::Version::Incompatible; 93*10ec9750Szamiseck std::string purpose = 94*10ec9750Szamiseck "xyz.openbmc_project.Software.Version.VersionPurpose.BMC"; 95*10ec9750Szamiseck 96c9bb6425SPatrick Williams error( 97c9bb6425SPatrick Williams "BMC Minimum Ship Level ({MIN_VERSION}) NOT met by {ACTUAL_VERSION}", 98c9bb6425SPatrick Williams "MIN_VERSION", msl, "ACTUAL_VERSION", tmpStr, "VERSION_PURPOSE", 99c9bb6425SPatrick Williams purpose); 100*10ec9750Szamiseck report<IncompatibleErr>(Incompatible::MIN_VERSION(msl.c_str()), 101*10ec9750Szamiseck Incompatible::ACTUAL_VERSION(tmpStr.c_str()), 102*10ec9750Szamiseck Incompatible::VERSION_PURPOSE(purpose.c_str())); 10321dad047SMiguel Gomez return false; 10421dad047SMiguel Gomez } 10521dad047SMiguel Gomez 10621dad047SMiguel Gomez return true; 10721dad047SMiguel Gomez } 108