blob: cdcf143b210cfd665218528acdab5ab6c0daa71c [file] [log] [blame]
Sampa Misraaea5dde2020-08-31 08:33:47 -05001#include "inband_code_update.hpp"
2
Sagar Srinivas78a225a2020-08-27 00:52:20 -05003#include "libpldm/entity.h"
4
5#include "libpldmresponder/pdr.hpp"
Sampa Misraaea5dde2020-08-31 08:33:47 -05006#include "oem_ibm_handler.hpp"
7#include "xyz/openbmc_project/Common/error.hpp"
8
9#include <sdbusplus/server.hpp>
10#include <xyz/openbmc_project/Dump/NewDump/server.hpp>
11
12#include <exception>
13
14namespace pldm
15{
Sampa Misraaea5dde2020-08-31 08:33:47 -050016namespace responder
17{
18using namespace oem_ibm_platform;
19
20std::string CodeUpdate::fetchCurrentBootSide()
21{
22 return currBootSide;
23}
24
25std::string CodeUpdate::fetchNextBootSide()
26{
27 return nextBootSide;
28}
29
30int CodeUpdate::setCurrentBootSide(const std::string& currSide)
31{
32 currBootSide = currSide;
33 return PLDM_SUCCESS;
34}
35
36int CodeUpdate::setNextBootSide(const std::string& nextSide)
37{
38 nextBootSide = nextSide;
39 std::string objPath{};
40 if (nextBootSide == currBootSide)
41 {
42 objPath = runningVersion;
43 }
44 else
45 {
46 objPath = nonRunningVersion;
47 }
48 if (objPath.empty())
49 {
50 std::cerr << "no nonRunningVersion present \n";
51 return PLDM_PLATFORM_INVALID_STATE_VALUE;
52 }
53
54 pldm::utils::DBusMapping dbusMapping{objPath, redundancyIntf, "Priority",
55 "uint8_t"};
56 uint8_t val = 0;
57 pldm::utils::PropertyValue value = static_cast<uint8_t>(val);
58 try
59 {
60 dBusIntf->setDbusProperty(dbusMapping, value);
61 }
62 catch (const std::exception& e)
63 {
64 std::cerr << "failed to set the next boot side to " << objPath.c_str()
65 << " ERROR=" << e.what() << "\n";
66 return PLDM_ERROR;
67 }
68 return PLDM_SUCCESS;
69}
70
71void CodeUpdate::setVersions()
72{
73 static constexpr auto mapperService = "xyz.openbmc_project.ObjectMapper";
74 static constexpr auto functionalObjPath =
75 "/xyz/openbmc_project/software/functional";
76 static constexpr auto activeObjPath =
77 "/xyz/openbmc_project/software/active";
78 static constexpr auto propIntf = "org.freedesktop.DBus.Properties";
79
80 auto& bus = dBusIntf->getBus();
Sampa Misraaea5dde2020-08-31 08:33:47 -050081 try
82 {
83 auto method = bus.new_method_call(mapperService, functionalObjPath,
84 propIntf, "Get");
85 method.append("xyz.openbmc_project.Association", "endpoints");
86 std::variant<std::vector<std::string>> paths;
87
88 auto reply = bus.call(method);
89 reply.read(paths);
90
91 runningVersion = std::get<std::vector<std::string>>(paths)[0];
92
93 auto method1 =
94 bus.new_method_call(mapperService, activeObjPath, propIntf, "Get");
95 method1.append("xyz.openbmc_project.Association", "endpoints");
96
97 auto reply1 = bus.call(method1);
98 reply1.read(paths);
99 for (const auto& path : std::get<std::vector<std::string>>(paths))
100 {
101 if (path != runningVersion)
102 {
103 nonRunningVersion = path;
104 break;
105 }
106 }
107 }
108 catch (const std::exception& e)
109 {
110 std::cerr << "failed to make a d-bus call to Object Mapper "
111 "Association, ERROR="
112 << e.what() << "\n";
113 return;
114 }
115
116 using namespace sdbusplus::bus::match::rules;
117 captureNextBootSideChange.push_back(
118 std::make_unique<sdbusplus::bus::match::match>(
119 pldm::utils::DBusHandler::getBus(),
120 propertiesChanged(runningVersion, redundancyIntf),
121 [this](sdbusplus::message::message& msg) {
122 DbusChangedProps props;
123 std::string iface;
124 msg.read(iface, props);
125 processPriorityChangeNotification(props);
126 }));
127 fwUpdateMatcher = std::make_unique<sdbusplus::bus::match::match>(
128 pldm::utils::DBusHandler::getBus(),
129 "interface='org.freedesktop.DBus.ObjectManager',type='signal',"
130 "member='InterfacesAdded',path='/xyz/openbmc_project/software'",
131 [this](sdbusplus::message::message& msg) {
132 DBusInterfaceAdded interfaces;
133 sdbusplus::message::object_path path;
134 msg.read(path, interfaces);
135 for (auto& interface : interfaces)
136 {
137 if (interface.first ==
138 "xyz.openbmc_project.Software.Activation")
139 {
140 newImageId = path.str;
141 break;
142 }
143 }
144 });
145}
146
147void CodeUpdate::processPriorityChangeNotification(
148 const DbusChangedProps& chProperties)
149{
150 static constexpr auto propName = "Priority";
151 const auto it = chProperties.find(propName);
152 if (it == chProperties.end())
153 {
154 return;
155 }
156 uint8_t newVal = std::get<uint8_t>(it->second);
157 nextBootSide = (newVal == 0) ? currBootSide
158 : ((currBootSide == Tside) ? Pside : Tside);
159}
160
161void CodeUpdate::setOemPlatformHandler(
162 pldm::responder::oem_platform::Handler* handler)
163{
164 oemPlatformHandler = handler;
165}
166
167uint8_t fetchBootSide(uint16_t entityInstance, CodeUpdate* codeUpdate)
168{
169 uint8_t sensorOpState = tSideNum;
Sampa Misraaea5dde2020-08-31 08:33:47 -0500170 if (entityInstance == 0)
171 {
172 auto currSide = codeUpdate->fetchCurrentBootSide();
173 if (currSide == Pside)
174 {
175 sensorOpState = pSideNum;
176 }
177 }
178 else if (entityInstance == 1)
179 {
180 auto nextSide = codeUpdate->fetchNextBootSide();
181 if (nextSide == Pside)
182 {
183 sensorOpState = pSideNum;
184 }
185 }
186 else
187 {
188 sensorOpState = PLDM_SENSOR_UNKNOWN;
189 }
190
191 return sensorOpState;
192}
193
194int setBootSide(uint16_t entityInstance, uint8_t currState,
195 const std::vector<set_effecter_state_field>& stateField,
196 CodeUpdate* codeUpdate)
197{
198 int rc = PLDM_SUCCESS;
199 auto side = (stateField[currState].effecter_state == pSideNum) ? "P" : "T";
200
201 if (entityInstance == 0)
202 {
203 rc = codeUpdate->setCurrentBootSide(side);
204 }
205 else if (entityInstance == 1)
206 {
207 rc = codeUpdate->setNextBootSide(side);
208 }
209 else
210 {
211 rc = PLDM_PLATFORM_INVALID_STATE_VALUE;
212 }
213 return rc;
214}
215
216} // namespace responder
217} // namespace pldm