blob: e9980fbae5b5022dfe9b40d7887e6cfb431ff098 [file] [log] [blame]
Adriana Kobylak40814c62015-10-27 15:58:44 -05001#include "chassishandler.h"
Patrick Williams37af7332016-09-02 21:21:42 -05002#include "host-ipmid/ipmid-api.h"
Ratan Guptadcb10672017-07-10 10:33:50 +05303#include "types.hpp"
Deepak Kodihalli8cc19362017-07-21 11:18:38 -05004#include "ipmid.hpp"
5#include "settings.hpp"
Ratan Guptadcb10672017-07-10 10:33:50 +05306
Adriana Kobylak40814c62015-10-27 15:58:44 -05007#include <stdio.h>
Ratan Guptafd28dd72016-08-01 04:58:01 -05008#include <stdlib.h>
Adriana Kobylak40814c62015-10-27 15:58:44 -05009#include <stdint.h>
Brad Bishop35518682016-07-22 08:35:41 -040010#include <mapper.h>
Ratan Guptafd28dd72016-08-01 04:58:01 -050011#include <arpa/inet.h>
12#include <netinet/in.h>
13#include <limits.h>
14#include <string.h>
15#include <endian.h>
16#include <sstream>
17#include <array>
Andrew Geisslera6e3a302017-05-31 19:34:00 -050018#include <fstream>
19#include <experimental/filesystem>
Ratan Guptadcb10672017-07-10 10:33:50 +053020#include <string>
Deepak Kodihalli8cc19362017-07-21 11:18:38 -050021#include <map>
Ratan Guptadcb10672017-07-10 10:33:50 +053022
Vishwanatha Subbannab12b0c02017-03-07 18:17:19 +053023#include <phosphor-logging/log.hpp>
Ratan Guptadcb10672017-07-10 10:33:50 +053024#include <phosphor-logging/elog-errors.hpp>
Vishwanatha Subbannab12b0c02017-03-07 18:17:19 +053025#include <xyz/openbmc_project/State/Host/server.hpp>
Ratan Guptadcb10672017-07-10 10:33:50 +053026#include "xyz/openbmc_project/Common/error.hpp"
27
28#include <sdbusplus/bus.hpp>
29#include <sdbusplus/server/object.hpp>
Deepak Kodihalli8cc19362017-07-21 11:18:38 -050030#include <xyz/openbmc_project/Control/Boot/Source/server.hpp>
31#include <xyz/openbmc_project/Control/Boot/Mode/server.hpp>
Deepak Kodihalli18b70d12017-07-21 13:36:33 -050032#include <xyz/openbmc_project/Control/Power/RestorePolicy/server.hpp>
Ratan Guptadcb10672017-07-10 10:33:50 +053033
Vishwanatha Subbannab891a572017-03-31 11:34:48 +053034#include "config.h"
ratagupta6f6bff2016-04-04 06:20:11 -050035
36//Defines
Ratan Guptafd28dd72016-08-01 04:58:01 -050037#define SET_PARM_VERSION 0x01
38#define SET_PARM_BOOT_FLAGS_PERMANENT 0x40 //boot flags data1 7th bit on
ratagupta6f6bff2016-04-04 06:20:11 -050039#define SET_PARM_BOOT_FLAGS_VALID_ONE_TIME 0x80 //boot flags data1 8th bit on
Ratan Guptafd28dd72016-08-01 04:58:01 -050040#define SET_PARM_BOOT_FLAGS_VALID_PERMANENT 0xC0 //boot flags data1 7 & 8 bit on
ratagupta6f6bff2016-04-04 06:20:11 -050041
Ratan Guptafd28dd72016-08-01 04:58:01 -050042constexpr size_t SIZE_MAC = 18;
43constexpr size_t SIZE_BOOT_OPTION = (uint8_t)BootOptionResponseSize::
Andrew Geisslerfca6a4f2017-05-30 10:55:39 -050044 OPAL_NETWORK_SETTINGS;//Maximum size of the boot option parametrs
Ratan Guptafd28dd72016-08-01 04:58:01 -050045constexpr size_t SIZE_PREFIX = 7;
46constexpr size_t MAX_PREFIX_VALUE = 32;
47constexpr size_t SIZE_COOKIE = 4;
48constexpr size_t SIZE_VERSION = 2;
Ratan Guptad70f4532017-08-04 02:07:31 +053049constexpr auto MAC_ADDRESS_FORMAT = "%02hhx:%02hhx:%02hhx:%02hhx:%02hhx:%02hhx";
50constexpr auto IP_ADDRESS_FORMAT = "%u.%u.%u.%u";
Matthew Barth8b470052016-09-21 10:02:57 -050051constexpr auto PREFIX_FORMAT = "%hhd";
Ratan Guptafd28dd72016-08-01 04:58:01 -050052constexpr auto ADDR_TYPE_FORMAT = "%hhx";
Ratan Gupta6ec7daa2017-07-15 14:13:01 +053053constexpr auto IPV4_ADDRESS_SIZE_BYTE = 4;
54constexpr auto IPV6_ADDRESS_SIZE_BYTE = 16;
Ratan Guptad70f4532017-08-04 02:07:31 +053055constexpr auto DEFAULT_MAC_ADDRESS = "00:00:00:00:00:00";
56constexpr auto DEFAULT_ADDRESS = "0.0.0.0";
Ratan Gupta6ec7daa2017-07-15 14:13:01 +053057
Ratan Guptafd28dd72016-08-01 04:58:01 -050058//PetiBoot-Specific
Ratan Gupta6ec7daa2017-07-15 14:13:01 +053059static constexpr uint8_t net_conf_initial_bytes[] = {0x80, 0x21, 0x70, 0x62,
60 0x21, 0x00, 0x01, 0x06};
Ratan Guptafd28dd72016-08-01 04:58:01 -050061
62static constexpr size_t COOKIE_OFFSET = 1;
63static constexpr size_t VERSION_OFFSET = 5;
Ratan Gupta6ec7daa2017-07-15 14:13:01 +053064static constexpr size_t ADDR_SIZE_OFFSET = 8;
Ratan Guptafd28dd72016-08-01 04:58:01 -050065static constexpr size_t MAC_OFFSET = 9;
66static constexpr size_t ADDRTYPE_OFFSET = 16;
67static constexpr size_t IPADDR_OFFSET = 17;
ratagupta6f6bff2016-04-04 06:20:11 -050068
shgoupfd84fbbf2015-12-17 10:05:51 +080069
Adriana Kobylak40814c62015-10-27 15:58:44 -050070void register_netfn_chassis_functions() __attribute__((constructor));
71
shgoupfd84fbbf2015-12-17 10:05:51 +080072// Host settings in dbus
73// Service name should be referenced by connection name got via object mapper
74const char *settings_object_name = "/org/openbmc/settings/host0";
75const char *settings_intf_name = "org.freedesktop.DBus.Properties";
76const char *host_intf_name = "org.openbmc.settings.Host";
77
Ratan Guptadcb10672017-07-10 10:33:50 +053078constexpr auto MAPPER_BUS_NAME = "xyz.openbmc_project.ObjectMapper";
79constexpr auto MAPPER_OBJ = "/xyz/openbmc_project/object_mapper";
80constexpr auto MAPPER_INTF = "xyz.openbmc_project.ObjectMapper";
81
82constexpr auto SETTINGS_ROOT = "/";
83constexpr auto SETTINGS_MATCH = "host0";
84constexpr auto PROP_INTF = "org.freedesktop.DBus.Properties";
85
86constexpr auto IP_INTERFACE = "xyz.openbmc_project.Network.IP";
87constexpr auto MAC_INTERFACE = "xyz.openbmc_project.Network.MACAddress";
88
89constexpr auto METHOD_GET = "Get";
90constexpr auto METHOD_GET_ALL = "GetAll";
91constexpr auto METHOD_SET = "Set";
92
Nan Li8d15fb42016-08-16 22:29:40 +080093typedef struct
94{
95 uint8_t cap_flags;
96 uint8_t fru_info_dev_addr;
97 uint8_t sdr_dev_addr;
98 uint8_t sel_dev_addr;
99 uint8_t system_management_dev_addr;
100 uint8_t bridge_dev_addr;
101}__attribute__((packed)) ipmi_chassis_cap_t;
102
Nan Lifdd8ec52016-08-28 03:57:40 +0800103typedef struct
104{
Andrew Geisslerfca6a4f2017-05-30 10:55:39 -0500105 uint8_t cur_power_state;
106 uint8_t last_power_event;
107 uint8_t misc_power_state;
108 uint8_t front_panel_button_cap_status;
Nan Lifdd8ec52016-08-28 03:57:40 +0800109}__attribute__((packed)) ipmi_get_chassis_status_t;
110
Vishwanatha Subbannab12b0c02017-03-07 18:17:19 +0530111// Phosphor Host State manager
112namespace State = sdbusplus::xyz::openbmc_project::State::server;
113
Andrew Geisslera6e3a302017-05-31 19:34:00 -0500114namespace fs = std::experimental::filesystem;
115
Ratan Guptadcb10672017-07-10 10:33:50 +0530116using namespace phosphor::logging;
117using namespace sdbusplus::xyz::openbmc_project::Common::Error;
118
Deepak Kodihalli8cc19362017-07-21 11:18:38 -0500119namespace chassis
120{
121namespace internal
122{
123
124constexpr auto bootModeIntf = "xyz.openbmc_project.Control.Boot.Mode";
125constexpr auto bootSourceIntf = "xyz.openbmc_project.Control.Boot.Source";
Deepak Kodihalli18b70d12017-07-21 13:36:33 -0500126constexpr auto powerRestoreIntf =
127 "xyz.openbmc_project.Control.Power.RestorePolicy";
Deepak Kodihalli8cc19362017-07-21 11:18:38 -0500128sdbusplus::bus::bus dbus(ipmid_get_sd_bus_connection());
129
130namespace cache
131{
132
133settings::Objects objects(dbus,
Deepak Kodihalli18b70d12017-07-21 13:36:33 -0500134 {bootModeIntf, bootSourceIntf, powerRestoreIntf});
Deepak Kodihalli8cc19362017-07-21 11:18:38 -0500135
136} // namespace cache
137} // namespace internal
138} // namespace chassis
139
Ratan Guptadcb10672017-07-10 10:33:50 +0530140/** @brief Gets the dbus object info implementing the given interface
141 * from the given subtree.
142 * @param[in] interface - Dbus interface.
143 * @param[in] serviceRoot - subtree from where the search should start.
144 * @param[in] match - identifier for object.
145 * @return On success returns the object having objectpath and servicename.
146 */
147
148//TODO There may be cases where an interface is implemented by multiple
149// objects,to handle such cases we are interested on that object
150// which are on interested busname.
151// Currently mapper doesn't give the readable busname(gives busid) so we can't
152// use busname to find the object,will do later once the support is there.
153
154ipmi::DbusObjectInfo getDbusObject(const std::string& interface,
155 const std::string& serviceRoot = SETTINGS_ROOT,
156 const std::string& match = "")
157{
158 std::vector<std::string>interfaces;
159 interfaces.emplace_back(interface);
160
161 auto bus = sdbusplus::bus::new_default();
162 auto depth = 0;
163
164 auto mapperCall = bus.new_method_call(MAPPER_BUS_NAME,
165 MAPPER_OBJ,
166 MAPPER_INTF,
167 "GetSubTree");
168
169 mapperCall.append(serviceRoot);
170 mapperCall.append(depth);
171 mapperCall.append(interfaces);
172
173 auto mapperReply = bus.call(mapperCall);
174 if (mapperReply.is_method_error())
175 {
176 log<level::ERR>("Error in mapper call");
177 elog<InternalFailure>();
178 }
179
180 ipmi::ObjectTree objectTree;
181 mapperReply.read(objectTree);
182
183 if (objectTree.empty())
184 {
185 log<level::ERR>("No Object have impelmented the interface",
186 entry("INTERFACE=%s", interface.c_str()));
187 elog<InternalFailure>();
188 }
189
190 ipmi::DbusObjectInfo objectInfo;
191
192 // if match is empty then return the first object
193 if(match == "")
194 {
195 objectInfo = make_pair(objectTree.begin()->first,
196 objectTree.begin()->second.begin()->first);
197 return objectInfo;
198 }
199
200 // else search the match string in the object path
201 auto objectFound = false;
202 for (auto& object : objectTree)
203 {
204 if(object.first.find(match)!= std::string::npos)
205 {
206 objectFound = true;
207 objectInfo = make_pair(object.first, object.second.begin()->first);
208 break;
209 }
210 }
211
212 if(!objectFound)
213 {
214 log<level::ERR>("Failed to find object which matches",
215 entry("MATCH=%s",match.c_str()));
216 elog<InternalFailure>();
217 }
218 return objectInfo;
219
220}
221
222/** @brief Gets the value associated with the given object
223 * and the interface.
224 * @param[in] service - Dbus service name.
225 * @param[in] objPath - Dbus object path.
226 * @param[in] interface - Dbus interface.
227 * @param[in] property - name of the property.
228 * @return On success returns the value of the property.
229 */
230std::string getDbusProperty(const std::string& service,
231 const std::string& objPath,
232 const std::string& interface,
233 const std::string& property)
234{
235
236 sdbusplus::message::variant<std::string> name;
237
238 auto bus = sdbusplus::bus::new_default();
239
240 auto method = bus.new_method_call(
241 service.c_str(),
242 objPath.c_str(),
243 PROP_INTF,
244 METHOD_GET);
245
246 method.append(interface, property);
247
248 auto reply = bus.call(method);
249
250 if (reply.is_method_error())
251 {
252 log<level::ERR>("Failed to get property",
253 entry("PROPERTY=%s", property.c_str()),
254 entry("PATH=%s", objPath.c_str()),
255 entry("INTERFACE=%s", interface.c_str()));
256 elog<InternalFailure>();
257 }
258
259 reply.read(name);
260
261 return name.get<std::string>();
262}
263
264/** @brief Gets all the properties associated with the given object
265 * and the interface.
266 * @param[in] service - Dbus service name.
267 * @param[in] objPath - Dbus object path.
268 * @param[in] interface - Dbus interface.
269 * @return On success returns the map of name value pair.
270 */
271ipmi::PropertyMap getAllDbusProperties(const std::string& service,
272 const std::string& objPath,
273 const std::string& interface)
274{
275 ipmi::PropertyMap properties;
276 auto bus = sdbusplus::bus::new_default();
277
278 auto method = bus.new_method_call(
279 service.c_str(),
280 objPath.c_str(),
281 PROP_INTF,
282 METHOD_GET_ALL);
283
284 method.append(interface);
285
286 auto reply = bus.call(method);
287
288 if (reply.is_method_error())
289 {
290 log<level::ERR>("Failed to get all properties",
291 entry("PATH=%s", objPath.c_str()),
292 entry("INTERFACE=%s", interface.c_str()));
293 elog<InternalFailure>();
294 }
295
296 reply.read(properties);
297 return properties;
298}
299
300/** @brief Sets the property value of the given object.
301 * @param[in] service - Dbus service name.
302 * @param[in] objPath - Dbus object path.
303 * @param[in] interface - Dbus interface.
304 * @param[in] property - name of the property.
305 * @param[in] value - value which needs to be set.
306 */
307void setDbusProperty(const std::string& service,
308 const std::string& objPath,
309 const std::string& interface,
310 const std::string& property,
311 const ipmi::Value& value)
312{
313 auto bus = sdbusplus::bus::new_default();
314
315 auto method = bus.new_method_call(
316 service.c_str(),
317 objPath.c_str(),
318 PROP_INTF,
319 METHOD_SET);
320
321 method.append(interface);
322 method.append(property, value);
323
324 if (!bus.call(method))
325 {
326 log<level::ERR>("Failed to set property",
327 entry("PROPERTY=%s", property.c_str()),
328 entry("PATH=%s",objPath.c_str()),
329 entry("INTERFACE=%s",interface.c_str()));
330 elog<InternalFailure>();
331 }
332
333}
334
335//TODO : Can remove the below function as we have
336// new functions which uses sdbusplus.
337//
338// openbmc/openbmc#1489
ratagupta6f6bff2016-04-04 06:20:11 -0500339int dbus_get_property(const char *name, char **buf)
shgoupfd84fbbf2015-12-17 10:05:51 +0800340{
341 sd_bus_error error = SD_BUS_ERROR_NULL;
342 sd_bus_message *m = NULL;
343 sd_bus *bus = NULL;
344 char *temp_buf = NULL;
345 char *connection = NULL;
346 int r;
347
Brad Bishop35518682016-07-22 08:35:41 -0400348 // Get the system bus where most system services are provided.
349 bus = ipmid_get_sd_bus_connection();
shgoupfd84fbbf2015-12-17 10:05:51 +0800350
Brad Bishop35518682016-07-22 08:35:41 -0400351 r = mapper_get_service(bus, settings_object_name, &connection);
shgoupfd84fbbf2015-12-17 10:05:51 +0800352 if (r < 0) {
Brad Bishop819ddd42016-10-05 21:19:19 -0400353 fprintf(stderr, "Failed to get %s connection: %s\n",
354 settings_object_name, strerror(-r));
shgoupfd84fbbf2015-12-17 10:05:51 +0800355 goto finish;
356 }
357
shgoupfd84fbbf2015-12-17 10:05:51 +0800358 /*
359 * Bus, service, object path, interface and method are provided to call
360 * the method.
361 * Signatures and input arguments are provided by the arguments at the
362 * end.
363 */
364 r = sd_bus_call_method(bus,
365 connection, /* service to contact */
366 settings_object_name, /* object path */
367 settings_intf_name, /* interface name */
368 "Get", /* method name */
369 &error, /* object to return error in */
370 &m, /* return message on success */
371 "ss", /* input signature */
372 host_intf_name, /* first argument */
ratagupta6f6bff2016-04-04 06:20:11 -0500373 name); /* second argument */
shgoupfd84fbbf2015-12-17 10:05:51 +0800374
375 if (r < 0) {
376 fprintf(stderr, "Failed to issue method call: %s\n", error.message);
377 goto finish;
378 }
379
380 /*
381 * The output should be parsed exactly the same as the output formatting
382 * specified.
383 */
384 r = sd_bus_message_read(m, "v", "s", &temp_buf);
385 if (r < 0) {
386 fprintf(stderr, "Failed to parse response message: %s\n", strerror(-r));
387 goto finish;
388 }
389
Matthew Barth56181052017-01-23 09:36:29 -0600390 *buf = strdup(temp_buf);
Andrew Geisslerfca6a4f2017-05-30 10:55:39 -0500391 /* *buf = (char*) malloc(strlen(temp_buf));
shgoupfd84fbbf2015-12-17 10:05:51 +0800392 if (*buf) {
393 strcpy(*buf, temp_buf);
394 }
Andrew Geisslerfca6a4f2017-05-30 10:55:39 -0500395 */
shgoupfd84fbbf2015-12-17 10:05:51 +0800396 printf("IPMID boot option property get: {%s}.\n", (char *) temp_buf);
397
398finish:
399 sd_bus_error_free(&error);
400 sd_bus_message_unref(m);
401 free(connection);
402
403 return r;
404}
405
Ratan Guptadcb10672017-07-10 10:33:50 +0530406//TODO : Can remove the below function as we have
407// new functions which uses sdbusplus.
408//
409// openbmc/openbmc#1489
410
ratagupta6f6bff2016-04-04 06:20:11 -0500411int dbus_set_property(const char * name, const char *value)
shgoupfd84fbbf2015-12-17 10:05:51 +0800412{
413 sd_bus_error error = SD_BUS_ERROR_NULL;
414 sd_bus_message *m = NULL;
415 sd_bus *bus = NULL;
416 char *connection = NULL;
417 int r;
418
Brad Bishop35518682016-07-22 08:35:41 -0400419 // Get the system bus where most system services are provided.
420 bus = ipmid_get_sd_bus_connection();
shgoupfd84fbbf2015-12-17 10:05:51 +0800421
Brad Bishop35518682016-07-22 08:35:41 -0400422 r = mapper_get_service(bus, settings_object_name, &connection);
shgoupfd84fbbf2015-12-17 10:05:51 +0800423 if (r < 0) {
Brad Bishop819ddd42016-10-05 21:19:19 -0400424 fprintf(stderr, "Failed to get %s connection: %s\n",
425 settings_object_name, strerror(-r));
shgoupfd84fbbf2015-12-17 10:05:51 +0800426 goto finish;
427 }
428
shgoupfd84fbbf2015-12-17 10:05:51 +0800429 /*
430 * Bus, service, object path, interface and method are provided to call
431 * the method.
432 * Signatures and input arguments are provided by the arguments at the
433 * end.
434 */
435 r = sd_bus_call_method(bus,
436 connection, /* service to contact */
437 settings_object_name, /* object path */
438 settings_intf_name, /* interface name */
439 "Set", /* method name */
440 &error, /* object to return error in */
441 &m, /* return message on success */
442 "ssv", /* input signature */
443 host_intf_name, /* first argument */
ratagupta6f6bff2016-04-04 06:20:11 -0500444 name, /* second argument */
shgoupfd84fbbf2015-12-17 10:05:51 +0800445 "s", /* third argument */
ratagupta6f6bff2016-04-04 06:20:11 -0500446 value); /* fourth argument */
shgoupfd84fbbf2015-12-17 10:05:51 +0800447
448 if (r < 0) {
449 fprintf(stderr, "Failed to issue method call: %s\n", error.message);
450 goto finish;
451 }
452
ratagupta6f6bff2016-04-04 06:20:11 -0500453 printf("IPMID boot option property set: {%s}.\n", value);
shgoupfd84fbbf2015-12-17 10:05:51 +0800454
Andrew Geisslerfca6a4f2017-05-30 10:55:39 -0500455 finish:
shgoupfd84fbbf2015-12-17 10:05:51 +0800456 sd_bus_error_free(&error);
457 sd_bus_message_unref(m);
458 free(connection);
459
460 return r;
461}
462
Adriana Kobylak40814c62015-10-27 15:58:44 -0500463struct get_sys_boot_options_t {
464 uint8_t parameter;
465 uint8_t set;
466 uint8_t block;
467} __attribute__ ((packed));
468
shgoupfd84fbbf2015-12-17 10:05:51 +0800469struct get_sys_boot_options_response_t {
470 uint8_t version;
471 uint8_t parm;
Ratan Guptafd28dd72016-08-01 04:58:01 -0500472 uint8_t data[SIZE_BOOT_OPTION];
shgoupfd84fbbf2015-12-17 10:05:51 +0800473} __attribute__ ((packed));
474
475struct set_sys_boot_options_t {
476 uint8_t parameter;
Ratan Guptafd28dd72016-08-01 04:58:01 -0500477 uint8_t data[SIZE_BOOT_OPTION];
shgoupfd84fbbf2015-12-17 10:05:51 +0800478} __attribute__ ((packed));
479
Ratan Guptafd28dd72016-08-01 04:58:01 -0500480
Ratan Guptadcb10672017-07-10 10:33:50 +0530481int getHostNetworkData(get_sys_boot_options_response_t* respptr)
Ratan Guptafd28dd72016-08-01 04:58:01 -0500482{
Ratan Guptadcb10672017-07-10 10:33:50 +0530483 ipmi::PropertyMap properties;
484 int rc = 0;
Ratan Gupta6ec7daa2017-07-15 14:13:01 +0530485 uint8_t addrSize = IPV4_ADDRESS_SIZE_BYTE;
Ratan Guptafd28dd72016-08-01 04:58:01 -0500486
Ratan Guptadcb10672017-07-10 10:33:50 +0530487 try
488 {
489 //TODO There may be cases where an interface is implemented by multiple
490 // objects,to handle such cases we are interested on that object
491 // which are on interested busname.
492 // Currenlty mapper doesn't give the readable busname(gives busid)
493 // so we can't match with bus name so giving some object specific info
494 // as SETTINGS_MATCH.
495 // Later SETTINGS_MATCH will be replaced with busname.
Ratan Guptafd28dd72016-08-01 04:58:01 -0500496
Ratan Guptadcb10672017-07-10 10:33:50 +0530497 auto ipObjectInfo = getDbusObject(IP_INTERFACE, SETTINGS_ROOT,
498 SETTINGS_MATCH);
499 auto macObjectInfo = getDbusObject(MAC_INTERFACE, SETTINGS_ROOT,
500 SETTINGS_MATCH);
501
502 properties = getAllDbusProperties(ipObjectInfo.second,
503 ipObjectInfo.first, IP_INTERFACE);
504 auto MACAddress =
505 getDbusProperty(macObjectInfo.second, macObjectInfo.first,
506 MAC_INTERFACE, "MACAddress");
507
Ratan Guptad70f4532017-08-04 02:07:31 +0530508 auto ipAddress = properties["Address"].get<std::string>();
509
510 auto gateway = properties["Gateway"].get<std::string>();
511
512 auto prefix = properties["PrefixLength"].get<uint8_t>();
513
514 uint8_t isStatic = (properties["Origin"].get<std::string>() ==
515 "xyz.openbmc_project.Network.IP.AddressOrigin.Static")
516 ? 1 : 0;
517
518 // it is expected here that we should get the valid data
519 // but we may also get the default values.
520 // Validation of the data is done by settings.
521 //
522 // if mac address is default mac address then
523 // don't send blank override.
524 if ((MACAddress == DEFAULT_MAC_ADDRESS))
525 {
526 memset(respptr->data, 0, SIZE_BOOT_OPTION);
527 rc = -1;
528 return rc;
529 }
530 // if addr is static then ipaddress,gateway,prefix
531 // should not be default one,don't send blank override.
532 if (isStatic)
533 {
534 if((ipAddress == DEFAULT_ADDRESS) ||
535 (gateway == DEFAULT_ADDRESS) ||
536 (!prefix))
537 {
538 memset(respptr->data, 0, SIZE_BOOT_OPTION);
539 rc = -1;
540 return rc;
541 }
542 }
543
Ratan Guptadcb10672017-07-10 10:33:50 +0530544 sscanf(MACAddress.c_str(), MAC_ADDRESS_FORMAT,
545 (respptr->data + MAC_OFFSET),
546 (respptr->data + MAC_OFFSET + 1),
547 (respptr->data + MAC_OFFSET + 2),
548 (respptr->data + MAC_OFFSET + 3),
549 (respptr->data + MAC_OFFSET + 4),
550 (respptr->data + MAC_OFFSET + 5));
551
Ratan Guptadcb10672017-07-10 10:33:50 +0530552 respptr->data[MAC_OFFSET + 6] = 0x00;
553
Ratan Guptad70f4532017-08-04 02:07:31 +0530554 memcpy(respptr->data + ADDRTYPE_OFFSET, &isStatic,
555 sizeof(isStatic));
Ratan Gupta6ec7daa2017-07-15 14:13:01 +0530556
557 uint8_t addressFamily = (properties["Type"].get<std::string>() ==
558 "xyz.openbmc_project.Network.IP.Protocol.IPv4") ?
559 AF_INET : AF_INET6;
560
561 addrSize = (addressFamily == AF_INET) ? IPV4_ADDRESS_SIZE_BYTE :
562 IPV6_ADDRESS_SIZE_BYTE;
Ratan Guptadcb10672017-07-10 10:33:50 +0530563
564 // ipaddress and gateway would be in IPv4 format
Ratan Guptad70f4532017-08-04 02:07:31 +0530565 inet_pton(addressFamily, ipAddress.c_str(),
566 (respptr->data + IPADDR_OFFSET));
Ratan Guptadcb10672017-07-10 10:33:50 +0530567
Ratan Gupta6ec7daa2017-07-15 14:13:01 +0530568 uint8_t prefixOffset = IPADDR_OFFSET + addrSize;
569
570 memcpy(respptr->data + prefixOffset, &prefix, sizeof(prefix));
571
572 uint8_t gatewayOffset = prefixOffset + sizeof(decltype(prefix));
573
Ratan Guptad70f4532017-08-04 02:07:31 +0530574 inet_pton(addressFamily, gateway.c_str(),
575 (respptr->data + gatewayOffset));
Ratan Guptadcb10672017-07-10 10:33:50 +0530576
577 }
578 catch (InternalFailure& e)
579 {
580 commit<InternalFailure>();
581 memset(respptr->data, 0, SIZE_BOOT_OPTION);
582 rc = -1;
Ratan Guptafd28dd72016-08-01 04:58:01 -0500583 return rc;
584 }
585
Ratan Guptadcb10672017-07-10 10:33:50 +0530586 //PetiBoot-Specific
587 //If sucess then copy the first 9 bytes to the data
Ratan Guptadcb10672017-07-10 10:33:50 +0530588 memcpy(respptr->data, net_conf_initial_bytes,
589 sizeof(net_conf_initial_bytes));
Ratan Guptafd28dd72016-08-01 04:58:01 -0500590
Ratan Gupta6ec7daa2017-07-15 14:13:01 +0530591 memcpy(respptr->data + ADDR_SIZE_OFFSET, &addrSize, sizeof(addrSize));
592
Ratan Guptafd28dd72016-08-01 04:58:01 -0500593#ifdef _IPMI_DEBUG_
Ratan Guptadcb10672017-07-10 10:33:50 +0530594 printf("\n===Printing the IPMI Formatted Data========\n");
Ratan Guptafd28dd72016-08-01 04:58:01 -0500595
Ratan Guptadcb10672017-07-10 10:33:50 +0530596 for (uint8_t pos = 0; pos < index; pos++)
597 {
598 printf("%02x ", respptr->data[pos]);
599 }
Ratan Guptafd28dd72016-08-01 04:58:01 -0500600#endif
601
Ratan Guptafd28dd72016-08-01 04:58:01 -0500602 return rc;
603}
604
Ratan Gupta6ec7daa2017-07-15 14:13:01 +0530605/** @brief convert IPv4 and IPv6 addresses from binary to text form.
606 * @param[in] family - IPv4/Ipv6
607 * @param[in] data - req data pointer.
608 * @param[in] offset - offset in the data.
609 * @param[in] addrSize - size of the data which needs to be read from offset.
610 * @returns address in text form.
611 */
612
613std::string getAddrStr(uint8_t family, uint8_t* data,
614 uint8_t offset, uint8_t addrSize)
615{
616 char ipAddr[INET6_ADDRSTRLEN] = {};
617
618 switch(family)
619 {
620 case AF_INET:
621 {
622 struct sockaddr_in addr4 {};
623 memcpy(&addr4.sin_addr.s_addr, &data[offset], addrSize);
624
625 inet_ntop(AF_INET, &addr4.sin_addr,
626 ipAddr, INET_ADDRSTRLEN);
627
628 break;
629 }
630 case AF_INET6:
631 {
632 struct sockaddr_in6 addr6 {};
633 memcpy(&addr6.sin6_addr.s6_addr, &data[offset], addrSize);
634
635 inet_ntop(AF_INET6, &addr6.sin6_addr,
636 ipAddr, INET6_ADDRSTRLEN);
637
638 break;
639 }
640 default:
641 {
642 return {};
643 }
644 }
645
646 return ipAddr;
647}
648
Ratan Guptadcb10672017-07-10 10:33:50 +0530649int setHostNetworkData(set_sys_boot_options_t* reqptr)
Ratan Guptafd28dd72016-08-01 04:58:01 -0500650{
Ratan Guptadcb10672017-07-10 10:33:50 +0530651 using namespace std::string_literals;
Ratan Guptafd28dd72016-08-01 04:58:01 -0500652 std::string host_network_config;
Ratan Guptad70f4532017-08-04 02:07:31 +0530653 char mac[] {"00:00:00:00:00:00"};
Ratan Gupta6ec7daa2017-07-15 14:13:01 +0530654 std::string ipAddress, gateway;
655 char addrOrigin {0};
656 uint8_t addrSize {0};
Ratan Guptadcb10672017-07-10 10:33:50 +0530657 std::string addressOrigin =
Ratan Gupta6ec7daa2017-07-15 14:13:01 +0530658 "xyz.openbmc_project.Network.IP.AddressOrigin.DHCP";
659 std::string addressType =
660 "xyz.openbmc_project.Network.IP.Protocol.IPv4";
Ratan Guptadcb10672017-07-10 10:33:50 +0530661 uint8_t prefix {0};
662 uint32_t zeroCookie = 0;
Ratan Gupta6ec7daa2017-07-15 14:13:01 +0530663 uint8_t family = AF_INET;
Ratan Guptafd28dd72016-08-01 04:58:01 -0500664
665 //cookie starts from second byte
666 // version starts from sixth byte
667
Ratan Guptadcb10672017-07-10 10:33:50 +0530668 try
Ratan Guptafd28dd72016-08-01 04:58:01 -0500669 {
Ratan Guptadcb10672017-07-10 10:33:50 +0530670 do
671 {
672 // cookie == 0x21 0x70 0x62 0x21
673 if (memcmp(&(reqptr->data[COOKIE_OFFSET]),
674 (net_conf_initial_bytes + COOKIE_OFFSET),
675 SIZE_COOKIE) != 0)
676 {
677 //cookie == 0
678 if (memcmp(&(reqptr->data[COOKIE_OFFSET]),
679 &zeroCookie,
680 SIZE_COOKIE) == 0)
681 {
682 // need to zero out the network settings.
683 break;
684 }
685
686 log<level::ERR>("Invalid Cookie");
687 elog<InternalFailure>();
688 }
689
690 // vesion == 0x00 0x01
691 if (memcmp(&(reqptr->data[VERSION_OFFSET]),
692 (net_conf_initial_bytes + VERSION_OFFSET),
693 SIZE_VERSION) != 0)
694 {
695
696 log<level::ERR>("Invalid Version");
697 elog<InternalFailure>();
698 }
699
700 snprintf(mac, SIZE_MAC, MAC_ADDRESS_FORMAT,
701 reqptr->data[MAC_OFFSET],
702 reqptr->data[MAC_OFFSET + 1],
703 reqptr->data[MAC_OFFSET + 2],
704 reqptr->data[MAC_OFFSET + 3],
705 reqptr->data[MAC_OFFSET + 4],
706 reqptr->data[MAC_OFFSET + 5]);
707
Ratan Gupta6ec7daa2017-07-15 14:13:01 +0530708 memcpy(&addrOrigin, &(reqptr->data[ADDRTYPE_OFFSET]),
709 sizeof(decltype(addrOrigin)));
Ratan Guptadcb10672017-07-10 10:33:50 +0530710
Ratan Gupta6ec7daa2017-07-15 14:13:01 +0530711 if (addrOrigin)
Ratan Guptadcb10672017-07-10 10:33:50 +0530712 {
713 addressOrigin =
Ratan Gupta6ec7daa2017-07-15 14:13:01 +0530714 "xyz.openbmc_project.Network.IP.AddressOrigin.Static";
Ratan Guptadcb10672017-07-10 10:33:50 +0530715 }
716
Ratan Gupta6ec7daa2017-07-15 14:13:01 +0530717 // Get the address size
718 memcpy(&addrSize ,&reqptr->data[ADDR_SIZE_OFFSET], sizeof(addrSize));
Ratan Guptadcb10672017-07-10 10:33:50 +0530719
Ratan Gupta6ec7daa2017-07-15 14:13:01 +0530720 uint8_t prefixOffset = IPADDR_OFFSET + addrSize;
Ratan Guptadcb10672017-07-10 10:33:50 +0530721
Ratan Guptad70f4532017-08-04 02:07:31 +0530722 memcpy(&prefix, &(reqptr->data[prefixOffset]),
723 sizeof(decltype(prefix)));
Ratan Guptadcb10672017-07-10 10:33:50 +0530724
Ratan Gupta6ec7daa2017-07-15 14:13:01 +0530725 uint8_t gatewayOffset = prefixOffset + sizeof(decltype(prefix));
726
727 if (addrSize != IPV4_ADDRESS_SIZE_BYTE)
728 {
729 addressType = "xyz.openbmc_project.Network.IP.Protocol.IPv6";
730 family = AF_INET6;
731 }
732
733 ipAddress = getAddrStr(family, reqptr->data, IPADDR_OFFSET, addrSize);
Ratan Guptad70f4532017-08-04 02:07:31 +0530734
Ratan Gupta6ec7daa2017-07-15 14:13:01 +0530735 gateway = getAddrStr(family, reqptr->data, gatewayOffset, addrSize);
736
Ratan Guptadcb10672017-07-10 10:33:50 +0530737 } while(0);
738
Ratan Guptafd28dd72016-08-01 04:58:01 -0500739 //Cookie == 0 or it is a valid cookie
Ratan Guptadcb10672017-07-10 10:33:50 +0530740 host_network_config += "ipaddress="s + ipAddress +
741 ",prefix="s + std::to_string(prefix) + ",gateway="s + gateway +
742 ",mac="s + mac + ",addressOrigin="s + addressOrigin;
Ratan Guptafd28dd72016-08-01 04:58:01 -0500743
Ratan Guptafd28dd72016-08-01 04:58:01 -0500744
Ratan Guptadcb10672017-07-10 10:33:50 +0530745 auto ipObjectInfo = getDbusObject(IP_INTERFACE, SETTINGS_ROOT,
746 SETTINGS_MATCH);
747 auto macObjectInfo = getDbusObject(MAC_INTERFACE, SETTINGS_ROOT,
748 SETTINGS_MATCH);
749 // set the dbus property
750 setDbusProperty(ipObjectInfo.second, ipObjectInfo.first,
751 IP_INTERFACE, "Address", std::string(ipAddress));
752 setDbusProperty(ipObjectInfo.second, ipObjectInfo.first,
753 IP_INTERFACE, "PrefixLength", prefix);
754 setDbusProperty(ipObjectInfo.second, ipObjectInfo.first,
755 IP_INTERFACE, "Origin", addressOrigin);
756 setDbusProperty(ipObjectInfo.second, ipObjectInfo.first,
757 IP_INTERFACE, "Gateway", std::string(gateway));
758 setDbusProperty(ipObjectInfo.second, ipObjectInfo.first,
759 IP_INTERFACE, "Type",
760 std::string("xyz.openbmc_project.Network.IP.Protocol.IPv4"));
761 setDbusProperty(macObjectInfo.second, macObjectInfo.first,
762 MAC_INTERFACE,"MACAddress", std::string(mac));
Ratan Guptafd28dd72016-08-01 04:58:01 -0500763
Ratan Guptad70f4532017-08-04 02:07:31 +0530764 log<level::DEBUG>("Network configuration changed",
765 entry("NETWORKCONFIG=%s", host_network_config.c_str()));
766
Ratan Guptafd28dd72016-08-01 04:58:01 -0500767 }
Ratan Guptadcb10672017-07-10 10:33:50 +0530768 catch (InternalFailure& e)
769 {
770 commit<InternalFailure>();
771 return -1;
772 }
773
774 return 0;
Ratan Guptafd28dd72016-08-01 04:58:01 -0500775}
776
Andrew Geisslerfca6a4f2017-05-30 10:55:39 -0500777ipmi_ret_t ipmi_chassis_wildcard(ipmi_netfn_t netfn, ipmi_cmd_t cmd,
778 ipmi_request_t request,
779 ipmi_response_t response,
780 ipmi_data_len_t data_len,
781 ipmi_context_t context)
Adriana Kobylak40814c62015-10-27 15:58:44 -0500782{
783 printf("Handling CHASSIS WILDCARD Netfn:[0x%X], Cmd:[0x%X]\n",netfn, cmd);
784 // Status code.
Nan Li70aa8d92016-08-29 00:11:10 +0800785 ipmi_ret_t rc = IPMI_CC_INVALID;
Adriana Kobylak40814c62015-10-27 15:58:44 -0500786 *data_len = 0;
787 return rc;
788}
789
Nan Li8d15fb42016-08-16 22:29:40 +0800790ipmi_ret_t ipmi_get_chassis_cap(ipmi_netfn_t netfn, ipmi_cmd_t cmd,
Andrew Geisslerfca6a4f2017-05-30 10:55:39 -0500791 ipmi_request_t request, ipmi_response_t response,
792 ipmi_data_len_t data_len, ipmi_context_t context)
Nan Li8d15fb42016-08-16 22:29:40 +0800793{
794 // sd_bus error
795 ipmi_ret_t rc = IPMI_CC_OK;
796
797 ipmi_chassis_cap_t chassis_cap{};
798
799 *data_len = sizeof(ipmi_chassis_cap_t);
800
801 // TODO: need future work. Get those flag from MRW.
802
803 // capabilities flags
804 // [7..4] - reserved
805 // [3] – 1b = provides power interlock (IPM 1.5)
806 // [2] – 1b = provides Diagnostic Interrupt (FP NMI)
807 // [1] – 1b = provides “Front Panel Lockout” (indicates that the chassis has capabilities
808 // to lock out external power control and reset button or front panel interfaces
809 // and/or detect tampering with those interfaces).
810 // [0] -1b = Chassis provides intrusion (physical security) sensor.
811 // set to default value 0x0.
812 chassis_cap.cap_flags = 0x0;
813
814 // Since we do not have a separate SDR Device/SEL Device/ FRU repository.
815 // The 20h was given as those 5 device addresses.
816 // Chassis FRU info Device Address
817 chassis_cap.fru_info_dev_addr = 0x20;
818
819 // Chassis SDR Device Address
820 chassis_cap.sdr_dev_addr = 0x20;
821
822 // Chassis SEL Device Address
823 chassis_cap.sel_dev_addr = 0x20;
824
825 // Chassis System Management Device Address
826 chassis_cap.system_management_dev_addr = 0x20;
827
828 // Chassis Bridge Device Address.
829 chassis_cap.bridge_dev_addr = 0x20;
830
831 memcpy(response, &chassis_cap, *data_len);
832
833 return rc;
834}
835
Vishwanatha Subbannab12b0c02017-03-07 18:17:19 +0530836//------------------------------------------
837// Calls into Host State Manager Dbus object
838//------------------------------------------
839int initiate_state_transition(State::Host::Transition transition)
vishwa36993272015-11-20 12:43:49 -0600840{
Andrew Geisslerfca6a4f2017-05-30 10:55:39 -0500841 // OpenBMC Host State Manager dbus framework
842 constexpr auto HOST_STATE_MANAGER_ROOT = "/xyz/openbmc_project/state/host0";
843 constexpr auto HOST_STATE_MANAGER_IFACE = "xyz.openbmc_project.State.Host";
844 constexpr auto DBUS_PROPERTY_IFACE = "org.freedesktop.DBus.Properties";
845 constexpr auto PROPERTY = "RequestedHostTransition";
Vishwanatha Subbannab12b0c02017-03-07 18:17:19 +0530846
Andrew Geisslerfca6a4f2017-05-30 10:55:39 -0500847 // sd_bus error
848 int rc = 0;
849 char *busname = NULL;
vishwa36993272015-11-20 12:43:49 -0600850
Andrew Geisslerfca6a4f2017-05-30 10:55:39 -0500851 // SD Bus error report mechanism.
852 sd_bus_error bus_error = SD_BUS_ERROR_NULL;
vishwa36993272015-11-20 12:43:49 -0600853
Andrew Geisslerfca6a4f2017-05-30 10:55:39 -0500854 // Gets a hook onto either a SYSTEM or SESSION bus
855 sd_bus *bus_type = ipmid_get_sd_bus_connection();
856 rc = mapper_get_service(bus_type, HOST_STATE_MANAGER_ROOT, &busname);
857 if (rc < 0)
858 {
859 log<level::ERR>("Failed to get bus name",
860 entry("ERROR=%s, OBJPATH=%s",
861 strerror(-rc), HOST_STATE_MANAGER_ROOT));
862 return rc;
863 }
Vishwanatha Subbannab12b0c02017-03-07 18:17:19 +0530864
Andrew Geisslerfca6a4f2017-05-30 10:55:39 -0500865 // Convert to string equivalent of the passed in transition enum.
866 auto request = State::convertForMessage(transition);
Vishwanatha Subbannab12b0c02017-03-07 18:17:19 +0530867
Andrew Geisslerfca6a4f2017-05-30 10:55:39 -0500868 rc = sd_bus_call_method(bus_type, // On the system bus
869 busname, // Service to contact
870 HOST_STATE_MANAGER_ROOT, // Object path
871 DBUS_PROPERTY_IFACE, // Interface name
872 "Set", // Method to be called
873 &bus_error, // object to return error
874 nullptr, // Response buffer if any
875 "ssv", // Takes 3 arguments
876 HOST_STATE_MANAGER_IFACE,
877 PROPERTY,
878 "s", request.c_str());
879 if(rc < 0)
880 {
881 log<level::ERR>("Failed to initiate transition",
882 entry("ERROR=%s, REQUEST=%s",
883 bus_error.message, request.c_str()));
884 }
885 else
886 {
887 log<level::INFO>("Transition request initiated successfully");
888 }
vishwa36993272015-11-20 12:43:49 -0600889
890 sd_bus_error_free(&bus_error);
Sergey Solomineb9b8142016-08-23 09:07:28 -0500891 free(busname);
vishwa36993272015-11-20 12:43:49 -0600892
Sergey Solomineb9b8142016-08-23 09:07:28 -0500893 return rc;
vishwa36993272015-11-20 12:43:49 -0600894}
895
Deepak Kodihalli18b70d12017-07-21 13:36:33 -0500896namespace power_policy
Andrew Geisslerfca6a4f2017-05-30 10:55:39 -0500897{
Nan Lifdd8ec52016-08-28 03:57:40 +0800898
Deepak Kodihalli18b70d12017-07-21 13:36:33 -0500899using namespace sdbusplus::xyz::openbmc_project::Control::Power::server;
900using IpmiValue = uint8_t;
901using DbusValue = RestorePolicy::Policy;
Nan Lifdd8ec52016-08-28 03:57:40 +0800902
Deepak Kodihalli18b70d12017-07-21 13:36:33 -0500903std::map<DbusValue, IpmiValue> dbusToIpmi =
904{
905 {RestorePolicy::Policy::AlwaysOff, 0x00},
906 {RestorePolicy::Policy::Restore, 0x01},
907 {RestorePolicy::Policy::AlwaysOn, 0x02}
908};
Nan Lifdd8ec52016-08-28 03:57:40 +0800909
Deepak Kodihalli18b70d12017-07-21 13:36:33 -0500910} // namespace power_policy
Nan Lifdd8ec52016-08-28 03:57:40 +0800911
912//----------------------------------------------------------------------
913// Get Chassis Status commands
914//----------------------------------------------------------------------
915ipmi_ret_t ipmi_get_chassis_status(ipmi_netfn_t netfn, ipmi_cmd_t cmd,
Andrew Geisslerfca6a4f2017-05-30 10:55:39 -0500916 ipmi_request_t request,
917 ipmi_response_t response,
918 ipmi_data_len_t data_len,
919 ipmi_context_t context)
Nan Lifdd8ec52016-08-28 03:57:40 +0800920{
921 const char *objname = "/org/openbmc/control/power0";
922 const char *intf = "org.openbmc.control.Power";
923
924 sd_bus *bus = NULL;
925 sd_bus_message *reply = NULL;
926 int r = 0;
927 int pgood = 0;
928 char *busname = NULL;
929 ipmi_ret_t rc = IPMI_CC_OK;
930 ipmi_get_chassis_status_t chassis_status{};
931
Nan Lifdd8ec52016-08-28 03:57:40 +0800932 uint8_t s = 0;
933
Deepak Kodihalli18b70d12017-07-21 13:36:33 -0500934 using namespace chassis::internal;
935 using namespace chassis::internal::cache;
936 using namespace power_policy;
937
938 const auto& powerRestoreSetting = objects.map.at(powerRestoreIntf);
939 auto method =
940 dbus.new_method_call(
941 objects.service(powerRestoreSetting, powerRestoreIntf).c_str(),
942 powerRestoreSetting.c_str(),
943 PROP_INTF,
944 "Get");
945 method.append(powerRestoreIntf, "PowerRestorePolicy");
946 auto resp = dbus.call(method);
947 if (resp.is_method_error())
948 {
949 log<level::ERR>("Error in PowerRestorePolicy Get");
950 report<InternalFailure>();
951 *data_len = 0;
952 return IPMI_CC_UNSPECIFIED_ERROR;
953 }
954 sdbusplus::message::variant<std::string> result;
955 resp.read(result);
956 auto powerRestore =
957 RestorePolicy::convertPolicyFromString(result.get<std::string>());
Nan Lifdd8ec52016-08-28 03:57:40 +0800958
959 *data_len = 4;
960
Tom Joseph63a00512017-08-09 23:39:59 +0530961 bus = ipmid_get_sd_bus_connection();
962
Nan Lifdd8ec52016-08-28 03:57:40 +0800963 r = mapper_get_service(bus, objname, &busname);
964 if (r < 0) {
965 fprintf(stderr, "Failed to get bus name, return value: %s.\n", strerror(-r));
966 rc = IPMI_CC_UNSPECIFIED_ERROR;
967 goto finish;
968 }
969
970 r = sd_bus_get_property(bus, busname, objname, intf, "pgood", NULL, &reply, "i");
971 if (r < 0) {
972 fprintf(stderr, "Failed to call sd_bus_get_property:%d, %s\n", r, strerror(-r));
973 fprintf(stderr, "Bus: %s, Path: %s, Interface: %s\n",
974 busname, objname, intf);
975 rc = IPMI_CC_UNSPECIFIED_ERROR;
976 goto finish;
977 }
978
979 r = sd_bus_message_read(reply, "i", &pgood);
980 if (r < 0) {
981 fprintf(stderr, "Failed to read sensor: %s\n", strerror(-r));
982 rc = IPMI_CC_UNSPECIFIED_ERROR;
983 goto finish;
984 }
985
986 printf("pgood is 0x%02x\n", pgood);
987
Deepak Kodihalli18b70d12017-07-21 13:36:33 -0500988 s = dbusToIpmi.at(powerRestore);
Nan Lifdd8ec52016-08-28 03:57:40 +0800989
990 // Current Power State
991 // [7] reserved
992 // [6..5] power restore policy
993 // 00b = chassis stays powered off after AC/mains returns
994 // 01b = after AC returns, power is restored to the state that was
995 // in effect when AC/mains was lost.
996 // 10b = chassis always powers up after AC/mains returns
997 // 11b = unknow
998 // Set to 00b, by observing the hardware behavior.
999 // Do we need to define a dbus property to identify the restore policy?
1000
1001 // [4] power control fault
1002 // 1b = controller attempted to turn system power on or off, but
1003 // system did not enter desired state.
1004 // Set to 0b, since We don't support it..
1005
1006 // [3] power fault
1007 // 1b = fault detected in main power subsystem.
1008 // set to 0b. for we don't support it.
1009
1010 // [2] 1b = interlock (chassis is presently shut down because a chassis
1011 // panel interlock switch is active). (IPMI 1.5)
1012 // set to 0b, for we don't support it.
1013
1014 // [1] power overload
1015 // 1b = system shutdown because of power overload condition.
1016 // set to 0b, for we don't support it.
1017
1018 // [0] power is on
1019 // 1b = system power is on
1020 // 0b = system power is off(soft-off S4/S5, or mechanical off)
1021
1022 chassis_status.cur_power_state = ((s & 0x3)<<5) | (pgood & 0x1);
1023
1024 // Last Power Event
1025 // [7..5] – reserved
1026 // [4] – 1b = last ‘Power is on’ state was entered via IPMI command
1027 // [3] – 1b = last power down caused by power fault
1028 // [2] – 1b = last power down caused by a power interlock being activated
1029 // [1] – 1b = last power down caused by a Power overload
1030 // [0] – 1b = AC failed
1031 // set to 0x0, for we don't support these fields.
1032
1033 chassis_status.last_power_event = 0;
1034
1035 // Misc. Chassis State
1036 // [7] – reserved
1037 // [6] – 1b = Chassis Identify command and state info supported (Optional)
1038 // 0b = Chassis Identify command support unspecified via this command.
1039 // (The Get Command Support command , if implemented, would still
1040 // indicate support for the Chassis Identify command)
1041 // [5..4] – Chassis Identify State. Mandatory when bit[6] =1b, reserved (return
1042 // as 00b) otherwise. Returns the present chassis identify state.
1043 // Refer to the Chassis Identify command for more info.
1044 // 00b = chassis identify state = Off
1045 // 01b = chassis identify state = Temporary(timed) On
1046 // 10b = chassis identify state = Indefinite On
1047 // 11b = reserved
1048 // [3] – 1b = Cooling/fan fault detected
1049 // [2] – 1b = Drive Fault
1050 // [1] – 1b = Front Panel Lockout active (power off and reset via chassis
1051 // push-buttons disabled.)
1052 // [0] – 1b = Chassis Intrusion active
1053 // set to 0, for we don't support them.
1054 chassis_status.misc_power_state = 0;
1055
1056 // Front Panel Button Capabilities and disable/enable status(Optional)
1057 // set to 0, for we don't support them.
1058 chassis_status.front_panel_button_cap_status = 0;
1059
1060 // Pack the actual response
1061 memcpy(response, &chassis_status, *data_len);
1062
1063finish:
1064 free(busname);
1065 reply = sd_bus_message_unref(reply);
1066
1067 return rc;
1068}
Chris Austen7888c4d2015-12-03 15:26:20 -06001069
Vishwanatha Subbanna83b5c1c2017-01-25 18:41:51 +05301070//-------------------------------------------------------------
1071// Send a command to SoftPowerOff application to stop any timer
1072//-------------------------------------------------------------
1073int stop_soft_off_timer()
1074{
Vishwanatha Subbanna83b5c1c2017-01-25 18:41:51 +05301075 constexpr auto iface = "org.freedesktop.DBus.Properties";
1076 constexpr auto soft_off_iface = "xyz.openbmc_project.Ipmi.Internal."
Andrew Geisslerfca6a4f2017-05-30 10:55:39 -05001077 "SoftPowerOff";
Vishwanatha Subbanna83b5c1c2017-01-25 18:41:51 +05301078
1079 constexpr auto property = "ResponseReceived";
1080 constexpr auto value = "xyz.openbmc_project.Ipmi.Internal."
Andrew Geisslerfca6a4f2017-05-30 10:55:39 -05001081 "SoftPowerOff.HostResponse.HostShutdown";
Vishwanatha Subbanna83b5c1c2017-01-25 18:41:51 +05301082
1083 // Get the system bus where most system services are provided.
1084 auto bus = ipmid_get_sd_bus_connection();
1085
1086 // Get the service name
Andrew Geissler2b4e4592017-06-08 11:18:35 -05001087 // TODO openbmc/openbmc#1661 - Mapper refactor
1088 //
1089 // See openbmc/openbmc#1743 for some details but high level summary is that
1090 // for now the code will directly call the soft off interface due to a
1091 // race condition with mapper usage
1092 //
1093 //char *busname = nullptr;
1094 //auto r = mapper_get_service(bus, SOFTOFF_OBJPATH, &busname);
1095 //if (r < 0)
1096 //{
1097 // fprintf(stderr, "Failed to get %s bus name: %s\n",
1098 // SOFTOFF_OBJPATH, strerror(-r));
1099 // return r;
1100 //}
Vishwanatha Subbanna83b5c1c2017-01-25 18:41:51 +05301101
1102 // No error object or reply expected.
Andrew Geissler2b4e4592017-06-08 11:18:35 -05001103 int rc = sd_bus_call_method(bus, SOFTOFF_BUSNAME, SOFTOFF_OBJPATH, iface,
Andrew Geisslerfca6a4f2017-05-30 10:55:39 -05001104 "Set", nullptr, nullptr, "ssv",
1105 soft_off_iface, property, "s", value);
Vishwanatha Subbanna83b5c1c2017-01-25 18:41:51 +05301106 if (rc < 0)
1107 {
1108 fprintf(stderr, "Failed to set property in SoftPowerOff object: %s\n",
1109 strerror(-rc));
1110 }
Andrew Geisslerfca6a4f2017-05-30 10:55:39 -05001111
Andrew Geissler2b4e4592017-06-08 11:18:35 -05001112 //TODO openbmc/openbmc#1661 - Mapper refactor
1113 //free(busname);
Vishwanatha Subbanna83b5c1c2017-01-25 18:41:51 +05301114 return rc;
1115}
1116
vishwa36993272015-11-20 12:43:49 -06001117//----------------------------------------------------------------------
Andrew Geisslera6e3a302017-05-31 19:34:00 -05001118// Create file to indicate there is no need for softoff notification to host
1119//----------------------------------------------------------------------
1120void indicate_no_softoff_needed()
1121{
1122 fs::path path{HOST_INBAND_REQUEST_DIR};
1123 if (!fs::is_directory(path))
1124 {
1125 fs::create_directory(path);
1126 }
1127
1128 // Add the host instance (default 0 for now) to the file name
1129 std::string file{HOST_INBAND_REQUEST_FILE};
1130 auto size = std::snprintf(nullptr,0,file.c_str(),0);
1131 size++; // null
1132 std::unique_ptr<char[]> buf(new char[size]);
1133 std::snprintf(buf.get(),size,file.c_str(),0);
1134
1135 // Append file name to directory and create it
1136 path /= buf.get();
1137 std::ofstream(path.c_str());
1138}
1139
1140//----------------------------------------------------------------------
vishwa36993272015-11-20 12:43:49 -06001141// Chassis Control commands
1142//----------------------------------------------------------------------
Andrew Geisslerfca6a4f2017-05-30 10:55:39 -05001143ipmi_ret_t ipmi_chassis_control(ipmi_netfn_t netfn, ipmi_cmd_t cmd,
1144 ipmi_request_t request,
1145 ipmi_response_t response,
1146 ipmi_data_len_t data_len,
1147 ipmi_context_t context)
vishwa36993272015-11-20 12:43:49 -06001148{
Andrew Geisslerfca6a4f2017-05-30 10:55:39 -05001149 // Error from power off.
1150 int rc = 0;
vishwa36993272015-11-20 12:43:49 -06001151
Andrew Geisslerfca6a4f2017-05-30 10:55:39 -05001152 // No response for this command.
vishwa36993272015-11-20 12:43:49 -06001153 *data_len = 0;
1154
Andrew Geisslerfca6a4f2017-05-30 10:55:39 -05001155 // Catch the actual operaton by peeking into request buffer
1156 uint8_t chassis_ctrl_cmd = *(uint8_t *)request;
1157 printf("Chassis Control Command: Operation:[0x%X]\n",chassis_ctrl_cmd);
vishwa36993272015-11-20 12:43:49 -06001158
Andrew Geisslerfca6a4f2017-05-30 10:55:39 -05001159 switch(chassis_ctrl_cmd)
1160 {
1161 case CMD_POWER_ON:
1162 rc = initiate_state_transition(State::Host::Transition::On);
1163 break;
1164 case CMD_POWER_OFF:
1165 // Need to Nudge SoftPowerOff application that it needs to stop the
1166 // watchdog timer if running.
1167 rc = stop_soft_off_timer();
Andrew Geisslera6e3a302017-05-31 19:34:00 -05001168 // Only request the Off transition if the soft power off
1169 // application is not running
1170 if (rc < 0)
Andrew Geisslerfca6a4f2017-05-30 10:55:39 -05001171 {
Andrew Geisslera6e3a302017-05-31 19:34:00 -05001172 log<level::INFO>("Did not find soft off service so request "
1173 "Host:Transition:Off");
1174
1175 // First create a file to indicate to the soft off application
1176 // that it should not run since this is a direct user initiated
1177 // power off request (i.e. a power off request that is not
1178 // originating via a soft power off SMS request)
1179 indicate_no_softoff_needed();
1180
1181 // Now request the shutdown
1182 rc = initiate_state_transition(State::Host::Transition::Off);
Andrew Geisslerfca6a4f2017-05-30 10:55:39 -05001183 }
Andrew Geisslera6e3a302017-05-31 19:34:00 -05001184 else
1185 {
1186 log<level::INFO>("Soft off is running, so let that stop "
1187 "the host");
1188 }
1189
Andrew Geisslerfca6a4f2017-05-30 10:55:39 -05001190 break;
Vishwanatha Subbanna83b5c1c2017-01-25 18:41:51 +05301191
Andrew Geisslerfca6a4f2017-05-30 10:55:39 -05001192 case CMD_HARD_RESET:
1193 case CMD_POWER_CYCLE:
1194 // SPEC has a section that says certain implementations can trigger
1195 // PowerOn if power is Off when a command to power cycle is
1196 // requested
Andrew Geisslera6e3a302017-05-31 19:34:00 -05001197
1198 // First create a file to indicate to the soft off application
1199 // that it should not run since this is a direct user initiated
1200 // power reboot request (i.e. a reboot request that is not
1201 // originating via a soft power off SMS request)
1202 indicate_no_softoff_needed();
1203
Andrew Geisslerfca6a4f2017-05-30 10:55:39 -05001204 rc = initiate_state_transition(State::Host::Transition::Reboot);
1205 break;
1206 default:
1207 {
1208 fprintf(stderr, "Invalid Chassis Control command:[0x%X] received\n",chassis_ctrl_cmd);
1209 rc = -1;
1210 }
1211 }
vishwa36993272015-11-20 12:43:49 -06001212
Andrew Geisslerfca6a4f2017-05-30 10:55:39 -05001213 return ( (rc < 0) ? IPMI_CC_INVALID : IPMI_CC_OK);
vishwa36993272015-11-20 12:43:49 -06001214}
1215
Deepak Kodihalli8cc19362017-07-21 11:18:38 -05001216namespace boot_options
1217{
1218
1219using namespace sdbusplus::xyz::openbmc_project::Control::Boot::server;
1220using IpmiValue = uint8_t;
1221constexpr auto ipmiDefault = 0;
1222
1223std::map<IpmiValue, Source::Sources> sourceIpmiToDbus =
1224{
1225 {0x01, Source::Sources::Network},
1226 {0x02, Source::Sources::Disk},
1227 {0x05, Source::Sources::ExternalMedia},
1228 {ipmiDefault, Source::Sources::Default}
shgoupfd84fbbf2015-12-17 10:05:51 +08001229};
1230
Deepak Kodihalli8cc19362017-07-21 11:18:38 -05001231std::map<IpmiValue, Mode::Modes> modeIpmiToDbus =
1232{
1233 {0x03, Mode::Modes::Safe},
1234 {0x06, Mode::Modes::Setup},
1235 {ipmiDefault, Mode::Modes::Regular}
shgoupfd84fbbf2015-12-17 10:05:51 +08001236};
1237
Deepak Kodihalli8cc19362017-07-21 11:18:38 -05001238std::map<Source::Sources, IpmiValue> sourceDbusToIpmi =
1239{
1240 {Source::Sources::Network, 0x01},
1241 {Source::Sources::Disk, 0x02},
1242 {Source::Sources::ExternalMedia, 0x05},
1243 {Source::Sources::Default, ipmiDefault}
1244};
shgoupfd84fbbf2015-12-17 10:05:51 +08001245
Deepak Kodihalli8cc19362017-07-21 11:18:38 -05001246std::map<Mode::Modes, IpmiValue> modeDbusToIpmi =
1247{
1248 {Mode::Modes::Safe, 0x03},
1249 {Mode::Modes::Setup, 0x06},
1250 {Mode::Modes::Regular, ipmiDefault}
1251};
shgoupfd84fbbf2015-12-17 10:05:51 +08001252
Deepak Kodihalli8cc19362017-07-21 11:18:38 -05001253} // namespace boot_options
shgoupfd84fbbf2015-12-17 10:05:51 +08001254
Andrew Geisslerfca6a4f2017-05-30 10:55:39 -05001255ipmi_ret_t ipmi_chassis_get_sys_boot_options(ipmi_netfn_t netfn, ipmi_cmd_t cmd,
1256 ipmi_request_t request,
1257 ipmi_response_t response,
1258 ipmi_data_len_t data_len,
1259 ipmi_context_t context)
Adriana Kobylak40814c62015-10-27 15:58:44 -05001260{
Deepak Kodihalli8cc19362017-07-21 11:18:38 -05001261 using namespace boot_options;
shgoupfd84fbbf2015-12-17 10:05:51 +08001262 ipmi_ret_t rc = IPMI_CC_PARM_NOT_SUPPORTED;
1263 char *p = NULL;
1264 get_sys_boot_options_response_t *resp = (get_sys_boot_options_response_t *) response;
1265 get_sys_boot_options_t *reqptr = (get_sys_boot_options_t*) request;
Deepak Kodihalli8cc19362017-07-21 11:18:38 -05001266 IpmiValue bootOption = ipmiDefault;
Adriana Kobylak40814c62015-10-27 15:58:44 -05001267
1268 printf("IPMI GET_SYS_BOOT_OPTIONS\n");
1269
shgoupfd84fbbf2015-12-17 10:05:51 +08001270 memset(resp,0,sizeof(*resp));
1271 resp->version = SET_PARM_VERSION;
1272 resp->parm = 5;
ratagupta6f6bff2016-04-04 06:20:11 -05001273 resp->data[0] = SET_PARM_BOOT_FLAGS_VALID_ONE_TIME;
Adriana Kobylak40814c62015-10-27 15:58:44 -05001274
Adriana Kobylak40814c62015-10-27 15:58:44 -05001275
shgoupfd84fbbf2015-12-17 10:05:51 +08001276 /*
1277 * Parameter #5 means boot flags. Please refer to 28.13 of ipmi doc.
1278 * This is the only parameter used by petitboot.
1279 */
Ratan Guptafd28dd72016-08-01 04:58:01 -05001280 if ( reqptr->parameter == static_cast<uint8_t>
Andrew Geisslerfca6a4f2017-05-30 10:55:39 -05001281 ( BootOptionParameter::BOOT_FLAGS )) {
shgoupfd84fbbf2015-12-17 10:05:51 +08001282
Ratan Guptafd28dd72016-08-01 04:58:01 -05001283 *data_len = static_cast<uint8_t>(BootOptionResponseSize::BOOT_FLAGS);
Deepak Kodihalli8cc19362017-07-21 11:18:38 -05001284 using namespace chassis::internal;
1285 using namespace chassis::internal::cache;
shgoupfd84fbbf2015-12-17 10:05:51 +08001286
Deepak Kodihalli8cc19362017-07-21 11:18:38 -05001287 const auto& bootSourceSetting = objects.map.at(bootSourceIntf);
1288 auto method =
1289 dbus.new_method_call(
1290 objects.service(bootSourceSetting, bootSourceIntf).c_str(),
1291 bootSourceSetting.c_str(),
1292 PROP_INTF,
1293 "Get");
1294 method.append(bootSourceIntf, "BootSource");
1295 auto reply = dbus.call(method);
1296 if (reply.is_method_error())
ratagupta6f6bff2016-04-04 06:20:11 -05001297 {
Deepak Kodihalli8cc19362017-07-21 11:18:38 -05001298 log<level::ERR>("Error in BootSource Get");
1299 report<InternalFailure>();
1300 *data_len = 0;
1301 return IPMI_CC_UNSPECIFIED_ERROR;
ratagupta6f6bff2016-04-04 06:20:11 -05001302 }
Deepak Kodihalli8cc19362017-07-21 11:18:38 -05001303 sdbusplus::message::variant<std::string> result;
1304 reply.read(result);
1305 auto bootSource =
1306 Source::convertSourcesFromString(result.get<std::string>());
1307
1308 const auto& bootModeSetting = objects.map.at(bootModeIntf);
1309 method = dbus.new_method_call(
1310 objects.service(bootModeSetting, bootModeIntf).c_str(),
1311 bootModeSetting.c_str(),
1312 PROP_INTF,
1313 "Get");
1314 method.append(bootModeIntf, "BootMode");
1315 reply = dbus.call(method);
1316 if (reply.is_method_error())
1317 {
1318 log<level::ERR>("Error in BootMode Get");
1319 report<InternalFailure>();
1320 *data_len = 0;
1321 return IPMI_CC_UNSPECIFIED_ERROR;
1322 }
1323 reply.read(result);
1324 auto bootMode = Mode::convertModesFromString(result.get<std::string>());
1325
1326 bootOption = sourceDbusToIpmi.at(bootSource);
1327 if ((Mode::Modes::Regular == bootMode) &&
1328 (Source::Sources::Default == bootSource))
1329 {
1330 bootOption = ipmiDefault;
1331 }
1332 else if (Source::Sources::Default == bootSource)
1333 {
1334 bootOption = modeDbusToIpmi.at(bootMode);
1335 }
1336 resp->data[1] = (bootOption << 2);
1337 rc = IPMI_CC_OK;
ratagupta6f6bff2016-04-04 06:20:11 -05001338
1339 /* Get the boot policy */
Deepak Kodihalli8cc19362017-07-21 11:18:38 -05001340 int r = dbus_get_property("boot_policy",&p);
ratagupta6f6bff2016-04-04 06:20:11 -05001341
1342 if (r < 0) {
1343 fprintf(stderr, "Dbus get property(boot_policy) failed for get_sys_boot_options.\n");
1344 rc = IPMI_CC_UNSPECIFIED_ERROR;
1345
1346 } else {
1347
George Keishing012d6a42017-06-14 03:06:48 -05001348 printf("BootPolicy is [%s]\n", p);
Andrew Geisslerfca6a4f2017-05-30 10:55:39 -05001349 resp->data[0] = (strncmp(p,"ONETIME",strlen("ONETIME"))==0) ?
1350 SET_PARM_BOOT_FLAGS_VALID_ONE_TIME:
1351 SET_PARM_BOOT_FLAGS_VALID_PERMANENT;
ratagupta6f6bff2016-04-04 06:20:11 -05001352 rc = IPMI_CC_OK;
1353
1354 }
1355
1356
Ratan Guptafd28dd72016-08-01 04:58:01 -05001357 } else if ( reqptr->parameter == static_cast<uint8_t>
Andrew Geisslerfca6a4f2017-05-30 10:55:39 -05001358 ( BootOptionParameter::OPAL_NETWORK_SETTINGS )) {
Ratan Guptafd28dd72016-08-01 04:58:01 -05001359
Andrew Geisslerfca6a4f2017-05-30 10:55:39 -05001360 *data_len = static_cast<uint8_t>(BootOptionResponseSize::OPAL_NETWORK_SETTINGS);
Ratan Guptafd28dd72016-08-01 04:58:01 -05001361
Andrew Geisslerfca6a4f2017-05-30 10:55:39 -05001362 resp->parm = static_cast<uint8_t>(BootOptionParameter::OPAL_NETWORK_SETTINGS);
Ratan Guptafd28dd72016-08-01 04:58:01 -05001363
Andrew Geisslerfca6a4f2017-05-30 10:55:39 -05001364 int ret = getHostNetworkData(resp);
Ratan Guptafd28dd72016-08-01 04:58:01 -05001365
Andrew Geisslerfca6a4f2017-05-30 10:55:39 -05001366 if (ret < 0) {
Ratan Guptafd28dd72016-08-01 04:58:01 -05001367
Andrew Geisslerfca6a4f2017-05-30 10:55:39 -05001368 fprintf(stderr, "getHostNetworkData failed for get_sys_boot_options.\n");
1369 rc = IPMI_CC_UNSPECIFIED_ERROR;
Ratan Guptafd28dd72016-08-01 04:58:01 -05001370
Andrew Geisslerfca6a4f2017-05-30 10:55:39 -05001371 }else
1372 rc = IPMI_CC_OK;
Ratan Guptafd28dd72016-08-01 04:58:01 -05001373 }
1374
1375 else {
Adriana Kobylak40814c62015-10-27 15:58:44 -05001376 fprintf(stderr, "Unsupported parameter 0x%x\n", reqptr->parameter);
shgoupfd84fbbf2015-12-17 10:05:51 +08001377 }
1378
1379 if (p)
1380 free(p);
1381
Ratan Guptafd28dd72016-08-01 04:58:01 -05001382 if (rc == IPMI_CC_OK)
1383 {
1384 *data_len += 2;
1385 }
1386
shgoupfd84fbbf2015-12-17 10:05:51 +08001387 return rc;
1388}
1389
1390
1391
1392ipmi_ret_t ipmi_chassis_set_sys_boot_options(ipmi_netfn_t netfn, ipmi_cmd_t cmd,
Andrew Geisslerfca6a4f2017-05-30 10:55:39 -05001393 ipmi_request_t request,
1394 ipmi_response_t response,
1395 ipmi_data_len_t data_len,
1396 ipmi_context_t context)
shgoupfd84fbbf2015-12-17 10:05:51 +08001397{
Deepak Kodihalli8cc19362017-07-21 11:18:38 -05001398 using namespace boot_options;
shgoupfd84fbbf2015-12-17 10:05:51 +08001399 ipmi_ret_t rc = IPMI_CC_OK;
shgoupfd84fbbf2015-12-17 10:05:51 +08001400 set_sys_boot_options_t *reqptr = (set_sys_boot_options_t *) request;
1401
Ratan Guptafd28dd72016-08-01 04:58:01 -05001402 printf("IPMI SET_SYS_BOOT_OPTIONS reqptr->parameter =[%d]\n",reqptr->parameter);
1403
shgoupfd84fbbf2015-12-17 10:05:51 +08001404 // This IPMI command does not have any resposne data
1405 *data_len = 0;
1406
1407 /* 000101
1408 * Parameter #5 means boot flags. Please refer to 28.13 of ipmi doc.
1409 * This is the only parameter used by petitboot.
1410 */
Ratan Guptafd28dd72016-08-01 04:58:01 -05001411
Deepak Kodihalli8cc19362017-07-21 11:18:38 -05001412 if (reqptr->parameter == (uint8_t)BootOptionParameter::BOOT_FLAGS)
1413 {
1414 IpmiValue bootOption = ((reqptr->data[1] & 0x3C) >> 2);
1415 using namespace chassis::internal;
1416 using namespace chassis::internal::cache;
shgoupfd84fbbf2015-12-17 10:05:51 +08001417
Deepak Kodihalli8cc19362017-07-21 11:18:38 -05001418 auto modeItr = modeIpmiToDbus.find(bootOption);
1419 auto sourceItr = sourceIpmiToDbus.find(bootOption);
1420 if ((ipmiDefault == bootOption) ||
1421 (sourceIpmiToDbus.end() != sourceItr))
1422 {
1423 sdbusplus::message::variant<std::string> property =
1424 convertForMessage(sourceItr->second);
1425 const auto& bootSourceSetting =
1426 objects.map.at(bootSourceIntf);
1427 auto method =
1428 dbus.new_method_call(
1429 objects.service(bootSourceSetting, bootSourceIntf).c_str(),
1430 bootSourceSetting.c_str(),
1431 PROP_INTF,
1432 "Set");
1433 method.append(bootSourceIntf, "BootSource", property);
1434 auto reply = dbus.call(method);
1435 if (reply.is_method_error())
1436 {
1437 log<level::ERR>("Error in BootSource Set");
1438 report<InternalFailure>();
1439 *data_len = 0;
1440 return IPMI_CC_UNSPECIFIED_ERROR;
1441 }
1442 }
1443 if ((ipmiDefault == bootOption) ||
1444 (modeIpmiToDbus.end() != modeItr))
1445 {
1446 sdbusplus::message::variant<std::string> property =
1447 convertForMessage(modeItr->second);
1448 const auto& bootModeSetting = objects.map.at(bootModeIntf);
1449 auto method =
1450 dbus.new_method_call(
1451 objects.service(bootModeSetting, bootModeIntf).c_str(),
1452 bootModeSetting.c_str(),
1453 PROP_INTF,
1454 "Set");
1455 method.append(bootModeIntf, "BootMode", property);
1456 auto reply = dbus.call(method);
1457 if (reply.is_method_error())
1458 {
1459 log<level::ERR>("Error in BootMode Set");
1460 report<InternalFailure>();
1461 *data_len = 0;
1462 return IPMI_CC_UNSPECIFIED_ERROR;
shgoupfd84fbbf2015-12-17 10:05:51 +08001463 }
1464 }
Ratan Guptafd28dd72016-08-01 04:58:01 -05001465
ratagupta6f6bff2016-04-04 06:20:11 -05001466 /* setting the boot policy */
Deepak Kodihalli8cc19362017-07-21 11:18:38 -05001467 std::string value =
1468 (char *)(((reqptr->data[0] & SET_PARM_BOOT_FLAGS_PERMANENT) ==
Andrew Geisslerfca6a4f2017-05-30 10:55:39 -05001469 SET_PARM_BOOT_FLAGS_PERMANENT) ?"PERMANENT":"ONETIME");
ratagupta6f6bff2016-04-04 06:20:11 -05001470
Deepak Kodihalli8cc19362017-07-21 11:18:38 -05001471 printf ( "\nBoot Policy is %s",value.c_str());
1472 int r = dbus_set_property("boot_policy",value.c_str());
ratagupta6f6bff2016-04-04 06:20:11 -05001473
1474 if (r < 0) {
1475 fprintf(stderr, "Dbus set property(boot_policy) failed for set_sys_boot_options.\n");
1476 rc = IPMI_CC_UNSPECIFIED_ERROR;
1477 }
shgoupfd84fbbf2015-12-17 10:05:51 +08001478
Andrew Geisslerfca6a4f2017-05-30 10:55:39 -05001479 } else if (reqptr->parameter ==
1480 (uint8_t)BootOptionParameter::OPAL_NETWORK_SETTINGS) {
Ratan Guptafd28dd72016-08-01 04:58:01 -05001481
1482 int ret = setHostNetworkData(reqptr);
1483 if (ret < 0) {
1484 fprintf(stderr, "setHostNetworkData failed for set_sys_boot_options.\n");
1485 rc = IPMI_CC_UNSPECIFIED_ERROR;
1486 }
1487 }
1488 else {
shgoupfd84fbbf2015-12-17 10:05:51 +08001489 fprintf(stderr, "Unsupported parameter 0x%x\n", reqptr->parameter);
1490 rc = IPMI_CC_PARM_NOT_SUPPORTED;
Adriana Kobylak40814c62015-10-27 15:58:44 -05001491 }
1492
1493 return rc;
1494}
1495
1496void register_netfn_chassis_functions()
1497{
Tom05732372016-09-06 17:21:23 +05301498 // <Wildcard Command>
Adriana Kobylak40814c62015-10-27 15:58:44 -05001499 printf("Registering NetFn:[0x%X], Cmd:[0x%X]\n",NETFUN_CHASSIS, IPMI_CMD_WILDCARD);
Tom05732372016-09-06 17:21:23 +05301500 ipmi_register_callback(NETFUN_CHASSIS, IPMI_CMD_WILDCARD, NULL, ipmi_chassis_wildcard,
1501 PRIVILEGE_USER);
Adriana Kobylak40814c62015-10-27 15:58:44 -05001502
Tom05732372016-09-06 17:21:23 +05301503 // Get Chassis Capabilities
Nan Li8d15fb42016-08-16 22:29:40 +08001504 printf("Registering NetFn:[0x%X], Cmd:[0x%X]\n",NETFUN_CHASSIS, IPMI_CMD_GET_CHASSIS_CAP);
Tom05732372016-09-06 17:21:23 +05301505 ipmi_register_callback(NETFUN_CHASSIS, IPMI_CMD_GET_CHASSIS_CAP, NULL, ipmi_get_chassis_cap,
1506 PRIVILEGE_USER);
Nan Li8d15fb42016-08-16 22:29:40 +08001507
Tom05732372016-09-06 17:21:23 +05301508 // <Get System Boot Options>
Adriana Kobylak40814c62015-10-27 15:58:44 -05001509 printf("Registering NetFn:[0x%X], Cmd:[0x%X]\n",NETFUN_CHASSIS, IPMI_CMD_GET_SYS_BOOT_OPTIONS);
Tom05732372016-09-06 17:21:23 +05301510 ipmi_register_callback(NETFUN_CHASSIS, IPMI_CMD_GET_SYS_BOOT_OPTIONS, NULL,
1511 ipmi_chassis_get_sys_boot_options, PRIVILEGE_OPERATOR);
Adriana Kobylak40814c62015-10-27 15:58:44 -05001512
Tom05732372016-09-06 17:21:23 +05301513 // <Get Chassis Status>
Nan Lifdd8ec52016-08-28 03:57:40 +08001514 printf("Registering NetFn:[0x%X], Cmd:[0x%X]\n",NETFUN_CHASSIS, IPMI_CMD_CHASSIS_STATUS);
Tom05732372016-09-06 17:21:23 +05301515 ipmi_register_callback(NETFUN_CHASSIS, IPMI_CMD_CHASSIS_STATUS, NULL, ipmi_get_chassis_status,
1516 PRIVILEGE_USER);
Nan Lifdd8ec52016-08-28 03:57:40 +08001517
Tom05732372016-09-06 17:21:23 +05301518 // <Chassis Control>
vishwa36993272015-11-20 12:43:49 -06001519 printf("Registering NetFn:[0x%X], Cmd:[0x%X]\n",NETFUN_CHASSIS, IPMI_CMD_CHASSIS_CONTROL);
Tom05732372016-09-06 17:21:23 +05301520 ipmi_register_callback(NETFUN_CHASSIS, IPMI_CMD_CHASSIS_CONTROL, NULL, ipmi_chassis_control,
1521 PRIVILEGE_OPERATOR);
shgoupfd84fbbf2015-12-17 10:05:51 +08001522
Tom05732372016-09-06 17:21:23 +05301523 // <Set System Boot Options>
shgoupfd84fbbf2015-12-17 10:05:51 +08001524 printf("Registering NetFn:[0x%X], Cmd:[0x%X]\n", NETFUN_CHASSIS, IPMI_CMD_SET_SYS_BOOT_OPTIONS);
Tom05732372016-09-06 17:21:23 +05301525 ipmi_register_callback(NETFUN_CHASSIS, IPMI_CMD_SET_SYS_BOOT_OPTIONS, NULL,
1526 ipmi_chassis_set_sys_boot_options, PRIVILEGE_OPERATOR);
vishwa36993272015-11-20 12:43:49 -06001527}