135e83f3eSSaqib Khan #include <fstream>
2ec1b41c4SGunnar Mills #include <string>
32ce7da29SGunnar Mills #include <phosphor-logging/log.hpp>
4ec1b41c4SGunnar Mills #include "config.h"
52ce7da29SGunnar Mills #include "item_updater.hpp"
62ce7da29SGunnar Mills #include "xyz/openbmc_project/Software/Version/server.hpp"
735e83f3eSSaqib Khan #include <experimental/filesystem>
8705f1bfcSSaqib Khan #include "version.hpp"
9ec1b41c4SGunnar Mills 
10ec1b41c4SGunnar Mills namespace phosphor
11ec1b41c4SGunnar Mills {
12ec1b41c4SGunnar Mills namespace software
13ec1b41c4SGunnar Mills {
14ec1b41c4SGunnar Mills namespace updater
15ec1b41c4SGunnar Mills {
16ec1b41c4SGunnar Mills 
172ce7da29SGunnar Mills // When you see server:: you know we're referencing our base class
182ce7da29SGunnar Mills namespace server = sdbusplus::xyz::openbmc_project::Software::server;
192ce7da29SGunnar Mills 
202ce7da29SGunnar Mills using namespace phosphor::logging;
2135e83f3eSSaqib Khan namespace fs = std::experimental::filesystem;
2235e83f3eSSaqib Khan 
2335e83f3eSSaqib Khan constexpr auto bmcImage = "image-rofs";
242ce7da29SGunnar Mills 
25e75d10f5SPatrick Williams void ItemUpdater::createActivation(sdbusplus::message::message& msg)
26ec1b41c4SGunnar Mills {
272ce7da29SGunnar Mills     sdbusplus::message::object_path objPath;
28705f1bfcSSaqib Khan     auto purpose = server::Version::VersionPurpose::Unknown;
29705f1bfcSSaqib Khan     std::string version;
302ce7da29SGunnar Mills     std::map<std::string,
312ce7da29SGunnar Mills              std::map<std::string,
322ce7da29SGunnar Mills                       sdbusplus::message::variant<std::string>>> interfaces;
33e75d10f5SPatrick Williams     msg.read(objPath, interfaces);
342ce7da29SGunnar Mills     std::string path(std::move(objPath));
352ce7da29SGunnar Mills 
362ce7da29SGunnar Mills     for (const auto& intf : interfaces)
372ce7da29SGunnar Mills     {
38705f1bfcSSaqib Khan         if (intf.first == VERSION_IFACE)
392ce7da29SGunnar Mills         {
402ce7da29SGunnar Mills             for (const auto& property : intf.second)
412ce7da29SGunnar Mills             {
42705f1bfcSSaqib Khan                 if (property.first == "Purpose")
432ce7da29SGunnar Mills                 {
44705f1bfcSSaqib Khan                     std::string str = sdbusplus::message::variant_ns::
45705f1bfcSSaqib Khan                         get<std::string>(property.second);
46705f1bfcSSaqib Khan                     purpose = server::Version::
47705f1bfcSSaqib Khan                         convertVersionPurposeFromString(str);
48705f1bfcSSaqib Khan                 }
49705f1bfcSSaqib Khan                 else if (property.first == "Version")
50705f1bfcSSaqib Khan                 {
51705f1bfcSSaqib Khan                     version = sdbusplus::message::variant_ns::
52705f1bfcSSaqib Khan                         get<std::string>(property.second);
53705f1bfcSSaqib Khan                 }
54705f1bfcSSaqib Khan             }
55705f1bfcSSaqib Khan         }
56705f1bfcSSaqib Khan     }
57705f1bfcSSaqib Khan     if (version.empty() ||
58705f1bfcSSaqib Khan         (purpose != server::Version::VersionPurpose::BMC &&
59705f1bfcSSaqib Khan         purpose != server::Version::VersionPurpose::System))
602ce7da29SGunnar Mills     {
61e75d10f5SPatrick Williams         return;
622ce7da29SGunnar Mills     }
632ce7da29SGunnar Mills 
642ce7da29SGunnar Mills     // Version id is the last item in the path
652ce7da29SGunnar Mills     auto pos = path.rfind("/");
662ce7da29SGunnar Mills     if (pos == std::string::npos)
672ce7da29SGunnar Mills     {
682ce7da29SGunnar Mills         log<level::ERR>("No version id found in object path",
692ce7da29SGunnar Mills                         entry("OBJPATH=%s", path));
70e75d10f5SPatrick Williams         return;
712ce7da29SGunnar Mills     }
722ce7da29SGunnar Mills 
732ce7da29SGunnar Mills     auto versionId = path.substr(pos + 1);
742ce7da29SGunnar Mills 
75e75d10f5SPatrick Williams     if (activations.find(versionId) == activations.end())
762ce7da29SGunnar Mills     {
7735e83f3eSSaqib Khan         // Determine the Activation state by processing the given image dir.
7835e83f3eSSaqib Khan         auto activationState = server::Activation::Activations::Invalid;
7935e83f3eSSaqib Khan         ItemUpdater::ActivationStatus result = ItemUpdater::
8035e83f3eSSaqib Khan                      validateSquashFSImage(versionId);
8135e83f3eSSaqib Khan         if (result == ItemUpdater::ActivationStatus::ready)
8235e83f3eSSaqib Khan         {
8335e83f3eSSaqib Khan             activationState = server::Activation::Activations::Ready;
8435e83f3eSSaqib Khan         }
8535e83f3eSSaqib Khan         else if (result == ItemUpdater::ActivationStatus::active)
8635e83f3eSSaqib Khan         {
8735e83f3eSSaqib Khan             activationState = server::Activation::Activations::Active;
8835e83f3eSSaqib Khan         }
8935e83f3eSSaqib Khan         activations.insert(std::make_pair(
902ce7da29SGunnar Mills                                versionId,
91ec1b41c4SGunnar Mills                                std::make_unique<Activation>(
9235e83f3eSSaqib Khan                                         bus,
9335e83f3eSSaqib Khan                                         path,
9435e83f3eSSaqib Khan                                         versionId,
9535e83f3eSSaqib Khan                                         activationState)));
96705f1bfcSSaqib Khan         versions.insert(std::make_pair(
97705f1bfcSSaqib Khan                             versionId,
98705f1bfcSSaqib Khan                             std::make_unique<phosphor::software::
99705f1bfcSSaqib Khan                                 manager::Version>(
100705f1bfcSSaqib Khan                                 bus,
101705f1bfcSSaqib Khan                                 path,
102705f1bfcSSaqib Khan                                 version,
103705f1bfcSSaqib Khan                                 purpose,
104705f1bfcSSaqib Khan                                 "")));
1052ce7da29SGunnar Mills     }
106e75d10f5SPatrick Williams     return;
107ec1b41c4SGunnar Mills }
108ec1b41c4SGunnar Mills 
109*ba239881SSaqib Khan void ItemUpdater::processBMCImage()
110*ba239881SSaqib Khan {
111*ba239881SSaqib Khan     auto purpose = server::Version::VersionPurpose::BMC;
112*ba239881SSaqib Khan     auto version = phosphor::software::manager::Version::getBMCVersion();
113*ba239881SSaqib Khan     auto id = phosphor::software::manager::Version::getId(version);
114*ba239881SSaqib Khan     auto path =  std::string{SOFTWARE_OBJPATH} + '/' + id;
115*ba239881SSaqib Khan     activations.insert(std::make_pair(
116*ba239881SSaqib Khan                            id,
117*ba239881SSaqib Khan                            std::make_unique<Activation>(
118*ba239881SSaqib Khan                                bus,
119*ba239881SSaqib Khan                                path,
120*ba239881SSaqib Khan                                id,
121*ba239881SSaqib Khan                                server::Activation::Activations::Active)));
122*ba239881SSaqib Khan     versions.insert(std::make_pair(
123*ba239881SSaqib Khan                         id,
124*ba239881SSaqib Khan                         std::make_unique<phosphor::software::
125*ba239881SSaqib Khan                              manager::Version>(
126*ba239881SSaqib Khan                              bus,
127*ba239881SSaqib Khan                              path,
128*ba239881SSaqib Khan                              version,
129*ba239881SSaqib Khan                              purpose,
130*ba239881SSaqib Khan                              "")));
131*ba239881SSaqib Khan     return;
132*ba239881SSaqib Khan }
133*ba239881SSaqib Khan 
13435e83f3eSSaqib Khan ItemUpdater::ActivationStatus ItemUpdater::validateSquashFSImage(
13535e83f3eSSaqib Khan              const std::string& versionId)
13635e83f3eSSaqib Khan {
13735e83f3eSSaqib Khan 
13835e83f3eSSaqib Khan     // TODO openbmc/openbmc#1715 Check the Common.FilePath to
13935e83f3eSSaqib Khan     //      determine the active image.
14035e83f3eSSaqib Khan     fs::path imageDirPath(IMG_UPLOAD_DIR);
14135e83f3eSSaqib Khan     imageDirPath /= versionId;
14235e83f3eSSaqib Khan     if (!fs::is_directory(imageDirPath))
14335e83f3eSSaqib Khan     {
14435e83f3eSSaqib Khan         return ItemUpdater::ActivationStatus::active;
14535e83f3eSSaqib Khan     }
14635e83f3eSSaqib Khan 
14735e83f3eSSaqib Khan     fs::path file(imageDirPath);
14835e83f3eSSaqib Khan     file /= bmcImage;
14935e83f3eSSaqib Khan     std::ifstream efile(file.c_str());
15035e83f3eSSaqib Khan 
15135e83f3eSSaqib Khan     if (efile.good() == 1)
15235e83f3eSSaqib Khan     {
15335e83f3eSSaqib Khan         return ItemUpdater::ActivationStatus::ready;
15435e83f3eSSaqib Khan     }
15535e83f3eSSaqib Khan     else
15635e83f3eSSaqib Khan     {
15735e83f3eSSaqib Khan         log<level::ERR>("Failed to find the SquashFS image.");
15835e83f3eSSaqib Khan         return ItemUpdater::ActivationStatus::invalid;
15935e83f3eSSaqib Khan     }
16035e83f3eSSaqib Khan }
16135e83f3eSSaqib Khan 
162ec1b41c4SGunnar Mills } // namespace updater
163ec1b41c4SGunnar Mills } // namespace software
164ec1b41c4SGunnar Mills } // namespace phosphor
165