12d8fa225SAdriana Kobylak #include "config.h"
2f6ed5897SGunnar Mills 
32d8fa225SAdriana Kobylak #include "item_updater.hpp"
4f6ed5897SGunnar Mills 
5f6ed5897SGunnar Mills #include "xyz/openbmc_project/Common/error.hpp"
6f6ed5897SGunnar Mills 
7f6ed5897SGunnar Mills #include <phosphor-logging/elog-errors.hpp>
8f6ed5897SGunnar Mills #include <phosphor-logging/log.hpp>
92d8fa225SAdriana Kobylak 
102d8fa225SAdriana Kobylak namespace openpower
112d8fa225SAdriana Kobylak {
122d8fa225SAdriana Kobylak namespace software
132d8fa225SAdriana Kobylak {
14befe5ce4SAdriana Kobylak namespace updater
152d8fa225SAdriana Kobylak {
1613fc66adSEddie James using namespace sdbusplus::xyz::openbmc_project::Common::Error;
17b66ac3aeSAdriana Kobylak using namespace phosphor::logging;
18b66ac3aeSAdriana Kobylak 
19*f3ce4337SLei YU void ItemUpdater::createActiveAssociation(const std::string& path)
202d8fa225SAdriana Kobylak {
21*f3ce4337SLei YU     assocs.emplace_back(
22*f3ce4337SLei YU         std::make_tuple(ACTIVE_FWD_ASSOCIATION, ACTIVE_REV_ASSOCIATION, path));
23*f3ce4337SLei YU     associations(assocs);
24b66ac3aeSAdriana Kobylak }
25b66ac3aeSAdriana Kobylak 
26*f3ce4337SLei YU void ItemUpdater::updateFunctionalAssociation(const std::string& versionId)
27b66ac3aeSAdriana Kobylak {
28*f3ce4337SLei YU     std::string path = std::string{SOFTWARE_OBJPATH} + '/' + versionId;
29*f3ce4337SLei YU     // remove all functional associations
30*f3ce4337SLei YU     for (auto iter = assocs.begin(); iter != assocs.end();)
312fdb9310SAdriana Kobylak     {
32*f3ce4337SLei YU         if ((std::get<0>(*iter)).compare(FUNCTIONAL_FWD_ASSOCIATION) == 0)
33a8ade7e4SSaqib Khan         {
34*f3ce4337SLei YU             iter = assocs.erase(iter);
35a8ade7e4SSaqib Khan         }
36a8ade7e4SSaqib Khan         else
37a8ade7e4SSaqib Khan         {
38*f3ce4337SLei YU             ++iter;
39a8ade7e4SSaqib Khan         }
40a8ade7e4SSaqib Khan     }
41*f3ce4337SLei YU     assocs.emplace_back(std::make_tuple(FUNCTIONAL_FWD_ASSOCIATION,
42*f3ce4337SLei YU                                         FUNCTIONAL_REV_ASSOCIATION, path));
43*f3ce4337SLei YU     associations(assocs);
449c8adfa3SLeonel Gonzalez }
459c8adfa3SLeonel Gonzalez 
46*f3ce4337SLei YU void ItemUpdater::removeAssociation(const std::string& path)
47dd961b6cSMichael Tritz {
48*f3ce4337SLei YU     for (auto iter = assocs.begin(); iter != assocs.end();)
49*f3ce4337SLei YU     {
50*f3ce4337SLei YU         if ((std::get<2>(*iter)).compare(path) == 0)
51*f3ce4337SLei YU         {
52*f3ce4337SLei YU             iter = assocs.erase(iter);
53*f3ce4337SLei YU             associations(assocs);
54dd961b6cSMichael Tritz         }
55*f3ce4337SLei YU         else
569c8adfa3SLeonel Gonzalez         {
57*f3ce4337SLei YU             ++iter;
58dd961b6cSMichael Tritz         }
599c8adfa3SLeonel Gonzalez     }
60ca9ba069SAdriana Kobylak }
61ca9ba069SAdriana Kobylak 
62*f3ce4337SLei YU bool ItemUpdater::erase(std::string entryId)
63fa7aa12cSMichael Tritz {
64*f3ce4337SLei YU     if (isVersionFunctional(entryId) && isChassisOn())
65ca9ba069SAdriana Kobylak     {
66*f3ce4337SLei YU         log<level::ERR>(("Error: Version " + entryId +
67*f3ce4337SLei YU                          " is currently active and running on the host."
68*f3ce4337SLei YU                          " Unable to remove.")
69*f3ce4337SLei YU                             .c_str());
7013fc66adSEddie James         return false;
7113fc66adSEddie James     }
7213fc66adSEddie James 
73*f3ce4337SLei YU     // Removing entry in versions map
74*f3ce4337SLei YU     auto it = versions.find(entryId);
75*f3ce4337SLei YU     if (it == versions.end())
7613fc66adSEddie James     {
77*f3ce4337SLei YU         log<level::ERR>(("Error: Failed to find version " + entryId +
78*f3ce4337SLei YU                          " in item updater versions map."
79*f3ce4337SLei YU                          " Unable to remove.")
80*f3ce4337SLei YU                             .c_str());
81*f3ce4337SLei YU     }
82*f3ce4337SLei YU     else
83*f3ce4337SLei YU     {
84*f3ce4337SLei YU         versions.erase(entryId);
8513fc66adSEddie James     }
8613fc66adSEddie James 
87*f3ce4337SLei YU     // Removing entry in activations map
88*f3ce4337SLei YU     auto ita = activations.find(entryId);
89*f3ce4337SLei YU     if (ita == activations.end())
9013fc66adSEddie James     {
91*f3ce4337SLei YU         log<level::ERR>(("Error: Failed to find version " + entryId +
92*f3ce4337SLei YU                          " in item updater activations map."
93*f3ce4337SLei YU                          " Unable to remove.")
94*f3ce4337SLei YU                             .c_str());
9513fc66adSEddie James     }
96*f3ce4337SLei YU     else
97*f3ce4337SLei YU     {
98*f3ce4337SLei YU         removeAssociation(ita->second->path);
99*f3ce4337SLei YU         activations.erase(entryId);
100*f3ce4337SLei YU     }
10113fc66adSEddie James     return true;
10213fc66adSEddie James }
10313fc66adSEddie James 
10413fc66adSEddie James bool ItemUpdater::isChassisOn()
10513fc66adSEddie James {
10670dcb63aSAdriana Kobylak     auto mapperCall = bus.new_method_call(MAPPER_BUSNAME, MAPPER_PATH,
10770dcb63aSAdriana Kobylak                                           MAPPER_INTERFACE, "GetObject");
10813fc66adSEddie James 
10913fc66adSEddie James     mapperCall.append(CHASSIS_STATE_PATH,
11013fc66adSEddie James                       std::vector<std::string>({CHASSIS_STATE_OBJ}));
11113fc66adSEddie James     auto mapperResponseMsg = bus.call(mapperCall);
11213fc66adSEddie James     if (mapperResponseMsg.is_method_error())
11313fc66adSEddie James     {
11413fc66adSEddie James         log<level::ERR>("Error in Mapper call");
11513fc66adSEddie James         elog<InternalFailure>();
11613fc66adSEddie James     }
11713fc66adSEddie James     using MapperResponseType = std::map<std::string, std::vector<std::string>>;
11813fc66adSEddie James     MapperResponseType mapperResponse;
11913fc66adSEddie James     mapperResponseMsg.read(mapperResponse);
12013fc66adSEddie James     if (mapperResponse.empty())
12113fc66adSEddie James     {
12213fc66adSEddie James         log<level::ERR>("Invalid Response from mapper");
12313fc66adSEddie James         elog<InternalFailure>();
12413fc66adSEddie James     }
12513fc66adSEddie James 
12613fc66adSEddie James     auto method = bus.new_method_call((mapperResponse.begin()->first).c_str(),
12713fc66adSEddie James                                       CHASSIS_STATE_PATH,
12870dcb63aSAdriana Kobylak                                       SYSTEMD_PROPERTY_INTERFACE, "Get");
12913fc66adSEddie James     method.append(CHASSIS_STATE_OBJ, "CurrentPowerState");
13013fc66adSEddie James     auto response = bus.call(method);
13113fc66adSEddie James     if (response.is_method_error())
13213fc66adSEddie James     {
13313fc66adSEddie James         log<level::ERR>("Error in fetching current Chassis State",
134850d5f6bSGunnar Mills                         entry("MAPPERRESPONSE=%s",
13513fc66adSEddie James                               (mapperResponse.begin()->first).c_str()));
13613fc66adSEddie James         elog<InternalFailure>();
13713fc66adSEddie James     }
13813fc66adSEddie James     sdbusplus::message::variant<std::string> currentChassisState;
13913fc66adSEddie James     response.read(currentChassisState);
14013fc66adSEddie James     auto strParam =
14113fc66adSEddie James         sdbusplus::message::variant_ns::get<std::string>(currentChassisState);
14213fc66adSEddie James     return (strParam != CHASSIS_STATE_OFF);
14313fc66adSEddie James }
14413fc66adSEddie James 
145befe5ce4SAdriana Kobylak } // namespace updater
1462d8fa225SAdriana Kobylak } // namespace software
1472d8fa225SAdriana Kobylak } // namespace openpower
148