blob: 1a69cdbc3a88361dd881deb5e1fad14e948d69b6 [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;
49constexpr auto MAC_ADDRESS_FORMAT = "%hhx:%hhx:%hhx:%hhx:%hhx:%hhx";
50constexpr auto IP_ADDRESS_FORMAT = "%d.%d.%d.%d";
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;
55
Ratan Guptafd28dd72016-08-01 04:58:01 -050056//PetiBoot-Specific
Ratan Gupta6ec7daa2017-07-15 14:13:01 +053057static constexpr uint8_t net_conf_initial_bytes[] = {0x80, 0x21, 0x70, 0x62,
58 0x21, 0x00, 0x01, 0x06};
Ratan Guptafd28dd72016-08-01 04:58:01 -050059
60static constexpr size_t COOKIE_OFFSET = 1;
61static constexpr size_t VERSION_OFFSET = 5;
Ratan Gupta6ec7daa2017-07-15 14:13:01 +053062static constexpr size_t ADDR_SIZE_OFFSET = 8;
Ratan Guptafd28dd72016-08-01 04:58:01 -050063static constexpr size_t MAC_OFFSET = 9;
64static constexpr size_t ADDRTYPE_OFFSET = 16;
65static constexpr size_t IPADDR_OFFSET = 17;
ratagupta6f6bff2016-04-04 06:20:11 -050066
shgoupfd84fbbf2015-12-17 10:05:51 +080067
Adriana Kobylak40814c62015-10-27 15:58:44 -050068void register_netfn_chassis_functions() __attribute__((constructor));
69
shgoupfd84fbbf2015-12-17 10:05:51 +080070// Host settings in dbus
71// Service name should be referenced by connection name got via object mapper
72const char *settings_object_name = "/org/openbmc/settings/host0";
73const char *settings_intf_name = "org.freedesktop.DBus.Properties";
74const char *host_intf_name = "org.openbmc.settings.Host";
75
Ratan Guptadcb10672017-07-10 10:33:50 +053076constexpr auto MAPPER_BUS_NAME = "xyz.openbmc_project.ObjectMapper";
77constexpr auto MAPPER_OBJ = "/xyz/openbmc_project/object_mapper";
78constexpr auto MAPPER_INTF = "xyz.openbmc_project.ObjectMapper";
79
80constexpr auto SETTINGS_ROOT = "/";
81constexpr auto SETTINGS_MATCH = "host0";
82constexpr auto PROP_INTF = "org.freedesktop.DBus.Properties";
83
84constexpr auto IP_INTERFACE = "xyz.openbmc_project.Network.IP";
85constexpr auto MAC_INTERFACE = "xyz.openbmc_project.Network.MACAddress";
86
87constexpr auto METHOD_GET = "Get";
88constexpr auto METHOD_GET_ALL = "GetAll";
89constexpr auto METHOD_SET = "Set";
90
Nan Li8d15fb42016-08-16 22:29:40 +080091typedef struct
92{
93 uint8_t cap_flags;
94 uint8_t fru_info_dev_addr;
95 uint8_t sdr_dev_addr;
96 uint8_t sel_dev_addr;
97 uint8_t system_management_dev_addr;
98 uint8_t bridge_dev_addr;
99}__attribute__((packed)) ipmi_chassis_cap_t;
100
Nan Lifdd8ec52016-08-28 03:57:40 +0800101typedef struct
102{
Andrew Geisslerfca6a4f2017-05-30 10:55:39 -0500103 uint8_t cur_power_state;
104 uint8_t last_power_event;
105 uint8_t misc_power_state;
106 uint8_t front_panel_button_cap_status;
Nan Lifdd8ec52016-08-28 03:57:40 +0800107}__attribute__((packed)) ipmi_get_chassis_status_t;
108
Vishwanatha Subbannab12b0c02017-03-07 18:17:19 +0530109// Phosphor Host State manager
110namespace State = sdbusplus::xyz::openbmc_project::State::server;
111
Andrew Geisslera6e3a302017-05-31 19:34:00 -0500112namespace fs = std::experimental::filesystem;
113
Ratan Guptadcb10672017-07-10 10:33:50 +0530114using namespace phosphor::logging;
115using namespace sdbusplus::xyz::openbmc_project::Common::Error;
116
Deepak Kodihalli8cc19362017-07-21 11:18:38 -0500117namespace chassis
118{
119namespace internal
120{
121
122constexpr auto bootModeIntf = "xyz.openbmc_project.Control.Boot.Mode";
123constexpr auto bootSourceIntf = "xyz.openbmc_project.Control.Boot.Source";
Deepak Kodihalli18b70d12017-07-21 13:36:33 -0500124constexpr auto powerRestoreIntf =
125 "xyz.openbmc_project.Control.Power.RestorePolicy";
Deepak Kodihalli8cc19362017-07-21 11:18:38 -0500126sdbusplus::bus::bus dbus(ipmid_get_sd_bus_connection());
127
128namespace cache
129{
130
131settings::Objects objects(dbus,
Deepak Kodihalli18b70d12017-07-21 13:36:33 -0500132 {bootModeIntf, bootSourceIntf, powerRestoreIntf});
Deepak Kodihalli8cc19362017-07-21 11:18:38 -0500133
134} // namespace cache
135} // namespace internal
136} // namespace chassis
137
Ratan Guptadcb10672017-07-10 10:33:50 +0530138/** @brief Gets the dbus object info implementing the given interface
139 * from the given subtree.
140 * @param[in] interface - Dbus interface.
141 * @param[in] serviceRoot - subtree from where the search should start.
142 * @param[in] match - identifier for object.
143 * @return On success returns the object having objectpath and servicename.
144 */
145
146//TODO There may be cases where an interface is implemented by multiple
147// objects,to handle such cases we are interested on that object
148// which are on interested busname.
149// Currently mapper doesn't give the readable busname(gives busid) so we can't
150// use busname to find the object,will do later once the support is there.
151
152ipmi::DbusObjectInfo getDbusObject(const std::string& interface,
153 const std::string& serviceRoot = SETTINGS_ROOT,
154 const std::string& match = "")
155{
156 std::vector<std::string>interfaces;
157 interfaces.emplace_back(interface);
158
159 auto bus = sdbusplus::bus::new_default();
160 auto depth = 0;
161
162 auto mapperCall = bus.new_method_call(MAPPER_BUS_NAME,
163 MAPPER_OBJ,
164 MAPPER_INTF,
165 "GetSubTree");
166
167 mapperCall.append(serviceRoot);
168 mapperCall.append(depth);
169 mapperCall.append(interfaces);
170
171 auto mapperReply = bus.call(mapperCall);
172 if (mapperReply.is_method_error())
173 {
174 log<level::ERR>("Error in mapper call");
175 elog<InternalFailure>();
176 }
177
178 ipmi::ObjectTree objectTree;
179 mapperReply.read(objectTree);
180
181 if (objectTree.empty())
182 {
183 log<level::ERR>("No Object have impelmented the interface",
184 entry("INTERFACE=%s", interface.c_str()));
185 elog<InternalFailure>();
186 }
187
188 ipmi::DbusObjectInfo objectInfo;
189
190 // if match is empty then return the first object
191 if(match == "")
192 {
193 objectInfo = make_pair(objectTree.begin()->first,
194 objectTree.begin()->second.begin()->first);
195 return objectInfo;
196 }
197
198 // else search the match string in the object path
199 auto objectFound = false;
200 for (auto& object : objectTree)
201 {
202 if(object.first.find(match)!= std::string::npos)
203 {
204 objectFound = true;
205 objectInfo = make_pair(object.first, object.second.begin()->first);
206 break;
207 }
208 }
209
210 if(!objectFound)
211 {
212 log<level::ERR>("Failed to find object which matches",
213 entry("MATCH=%s",match.c_str()));
214 elog<InternalFailure>();
215 }
216 return objectInfo;
217
218}
219
220/** @brief Gets the value associated with the given object
221 * and the interface.
222 * @param[in] service - Dbus service name.
223 * @param[in] objPath - Dbus object path.
224 * @param[in] interface - Dbus interface.
225 * @param[in] property - name of the property.
226 * @return On success returns the value of the property.
227 */
228std::string getDbusProperty(const std::string& service,
229 const std::string& objPath,
230 const std::string& interface,
231 const std::string& property)
232{
233
234 sdbusplus::message::variant<std::string> name;
235
236 auto bus = sdbusplus::bus::new_default();
237
238 auto method = bus.new_method_call(
239 service.c_str(),
240 objPath.c_str(),
241 PROP_INTF,
242 METHOD_GET);
243
244 method.append(interface, property);
245
246 auto reply = bus.call(method);
247
248 if (reply.is_method_error())
249 {
250 log<level::ERR>("Failed to get property",
251 entry("PROPERTY=%s", property.c_str()),
252 entry("PATH=%s", objPath.c_str()),
253 entry("INTERFACE=%s", interface.c_str()));
254 elog<InternalFailure>();
255 }
256
257 reply.read(name);
258
259 return name.get<std::string>();
260}
261
262/** @brief Gets all the properties associated with the given object
263 * and the interface.
264 * @param[in] service - Dbus service name.
265 * @param[in] objPath - Dbus object path.
266 * @param[in] interface - Dbus interface.
267 * @return On success returns the map of name value pair.
268 */
269ipmi::PropertyMap getAllDbusProperties(const std::string& service,
270 const std::string& objPath,
271 const std::string& interface)
272{
273 ipmi::PropertyMap properties;
274 auto bus = sdbusplus::bus::new_default();
275
276 auto method = bus.new_method_call(
277 service.c_str(),
278 objPath.c_str(),
279 PROP_INTF,
280 METHOD_GET_ALL);
281
282 method.append(interface);
283
284 auto reply = bus.call(method);
285
286 if (reply.is_method_error())
287 {
288 log<level::ERR>("Failed to get all properties",
289 entry("PATH=%s", objPath.c_str()),
290 entry("INTERFACE=%s", interface.c_str()));
291 elog<InternalFailure>();
292 }
293
294 reply.read(properties);
295 return properties;
296}
297
298/** @brief Sets the property value of the given object.
299 * @param[in] service - Dbus service name.
300 * @param[in] objPath - Dbus object path.
301 * @param[in] interface - Dbus interface.
302 * @param[in] property - name of the property.
303 * @param[in] value - value which needs to be set.
304 */
305void setDbusProperty(const std::string& service,
306 const std::string& objPath,
307 const std::string& interface,
308 const std::string& property,
309 const ipmi::Value& value)
310{
311 auto bus = sdbusplus::bus::new_default();
312
313 auto method = bus.new_method_call(
314 service.c_str(),
315 objPath.c_str(),
316 PROP_INTF,
317 METHOD_SET);
318
319 method.append(interface);
320 method.append(property, value);
321
322 if (!bus.call(method))
323 {
324 log<level::ERR>("Failed to set property",
325 entry("PROPERTY=%s", property.c_str()),
326 entry("PATH=%s",objPath.c_str()),
327 entry("INTERFACE=%s",interface.c_str()));
328 elog<InternalFailure>();
329 }
330
331}
332
333//TODO : Can remove the below function as we have
334// new functions which uses sdbusplus.
335//
336// openbmc/openbmc#1489
ratagupta6f6bff2016-04-04 06:20:11 -0500337int dbus_get_property(const char *name, char **buf)
shgoupfd84fbbf2015-12-17 10:05:51 +0800338{
339 sd_bus_error error = SD_BUS_ERROR_NULL;
340 sd_bus_message *m = NULL;
341 sd_bus *bus = NULL;
342 char *temp_buf = NULL;
343 char *connection = NULL;
344 int r;
345
Brad Bishop35518682016-07-22 08:35:41 -0400346 // Get the system bus where most system services are provided.
347 bus = ipmid_get_sd_bus_connection();
shgoupfd84fbbf2015-12-17 10:05:51 +0800348
Brad Bishop35518682016-07-22 08:35:41 -0400349 r = mapper_get_service(bus, settings_object_name, &connection);
shgoupfd84fbbf2015-12-17 10:05:51 +0800350 if (r < 0) {
Brad Bishop819ddd42016-10-05 21:19:19 -0400351 fprintf(stderr, "Failed to get %s connection: %s\n",
352 settings_object_name, strerror(-r));
shgoupfd84fbbf2015-12-17 10:05:51 +0800353 goto finish;
354 }
355
shgoupfd84fbbf2015-12-17 10:05:51 +0800356 /*
357 * Bus, service, object path, interface and method are provided to call
358 * the method.
359 * Signatures and input arguments are provided by the arguments at the
360 * end.
361 */
362 r = sd_bus_call_method(bus,
363 connection, /* service to contact */
364 settings_object_name, /* object path */
365 settings_intf_name, /* interface name */
366 "Get", /* method name */
367 &error, /* object to return error in */
368 &m, /* return message on success */
369 "ss", /* input signature */
370 host_intf_name, /* first argument */
ratagupta6f6bff2016-04-04 06:20:11 -0500371 name); /* second argument */
shgoupfd84fbbf2015-12-17 10:05:51 +0800372
373 if (r < 0) {
374 fprintf(stderr, "Failed to issue method call: %s\n", error.message);
375 goto finish;
376 }
377
378 /*
379 * The output should be parsed exactly the same as the output formatting
380 * specified.
381 */
382 r = sd_bus_message_read(m, "v", "s", &temp_buf);
383 if (r < 0) {
384 fprintf(stderr, "Failed to parse response message: %s\n", strerror(-r));
385 goto finish;
386 }
387
Matthew Barth56181052017-01-23 09:36:29 -0600388 *buf = strdup(temp_buf);
Andrew Geisslerfca6a4f2017-05-30 10:55:39 -0500389 /* *buf = (char*) malloc(strlen(temp_buf));
shgoupfd84fbbf2015-12-17 10:05:51 +0800390 if (*buf) {
391 strcpy(*buf, temp_buf);
392 }
Andrew Geisslerfca6a4f2017-05-30 10:55:39 -0500393 */
shgoupfd84fbbf2015-12-17 10:05:51 +0800394 printf("IPMID boot option property get: {%s}.\n", (char *) temp_buf);
395
396finish:
397 sd_bus_error_free(&error);
398 sd_bus_message_unref(m);
399 free(connection);
400
401 return r;
402}
403
Ratan Guptadcb10672017-07-10 10:33:50 +0530404//TODO : Can remove the below function as we have
405// new functions which uses sdbusplus.
406//
407// openbmc/openbmc#1489
408
ratagupta6f6bff2016-04-04 06:20:11 -0500409int dbus_set_property(const char * name, const char *value)
shgoupfd84fbbf2015-12-17 10:05:51 +0800410{
411 sd_bus_error error = SD_BUS_ERROR_NULL;
412 sd_bus_message *m = NULL;
413 sd_bus *bus = NULL;
414 char *connection = NULL;
415 int r;
416
Brad Bishop35518682016-07-22 08:35:41 -0400417 // Get the system bus where most system services are provided.
418 bus = ipmid_get_sd_bus_connection();
shgoupfd84fbbf2015-12-17 10:05:51 +0800419
Brad Bishop35518682016-07-22 08:35:41 -0400420 r = mapper_get_service(bus, settings_object_name, &connection);
shgoupfd84fbbf2015-12-17 10:05:51 +0800421 if (r < 0) {
Brad Bishop819ddd42016-10-05 21:19:19 -0400422 fprintf(stderr, "Failed to get %s connection: %s\n",
423 settings_object_name, strerror(-r));
shgoupfd84fbbf2015-12-17 10:05:51 +0800424 goto finish;
425 }
426
shgoupfd84fbbf2015-12-17 10:05:51 +0800427 /*
428 * Bus, service, object path, interface and method are provided to call
429 * the method.
430 * Signatures and input arguments are provided by the arguments at the
431 * end.
432 */
433 r = sd_bus_call_method(bus,
434 connection, /* service to contact */
435 settings_object_name, /* object path */
436 settings_intf_name, /* interface name */
437 "Set", /* method name */
438 &error, /* object to return error in */
439 &m, /* return message on success */
440 "ssv", /* input signature */
441 host_intf_name, /* first argument */
ratagupta6f6bff2016-04-04 06:20:11 -0500442 name, /* second argument */
shgoupfd84fbbf2015-12-17 10:05:51 +0800443 "s", /* third argument */
ratagupta6f6bff2016-04-04 06:20:11 -0500444 value); /* fourth argument */
shgoupfd84fbbf2015-12-17 10:05:51 +0800445
446 if (r < 0) {
447 fprintf(stderr, "Failed to issue method call: %s\n", error.message);
448 goto finish;
449 }
450
ratagupta6f6bff2016-04-04 06:20:11 -0500451 printf("IPMID boot option property set: {%s}.\n", value);
shgoupfd84fbbf2015-12-17 10:05:51 +0800452
Andrew Geisslerfca6a4f2017-05-30 10:55:39 -0500453 finish:
shgoupfd84fbbf2015-12-17 10:05:51 +0800454 sd_bus_error_free(&error);
455 sd_bus_message_unref(m);
456 free(connection);
457
458 return r;
459}
460
Adriana Kobylak40814c62015-10-27 15:58:44 -0500461struct get_sys_boot_options_t {
462 uint8_t parameter;
463 uint8_t set;
464 uint8_t block;
465} __attribute__ ((packed));
466
shgoupfd84fbbf2015-12-17 10:05:51 +0800467struct get_sys_boot_options_response_t {
468 uint8_t version;
469 uint8_t parm;
Ratan Guptafd28dd72016-08-01 04:58:01 -0500470 uint8_t data[SIZE_BOOT_OPTION];
shgoupfd84fbbf2015-12-17 10:05:51 +0800471} __attribute__ ((packed));
472
473struct set_sys_boot_options_t {
474 uint8_t parameter;
Ratan Guptafd28dd72016-08-01 04:58:01 -0500475 uint8_t data[SIZE_BOOT_OPTION];
shgoupfd84fbbf2015-12-17 10:05:51 +0800476} __attribute__ ((packed));
477
Ratan Guptafd28dd72016-08-01 04:58:01 -0500478
Ratan Guptadcb10672017-07-10 10:33:50 +0530479int getHostNetworkData(get_sys_boot_options_response_t* respptr)
Ratan Guptafd28dd72016-08-01 04:58:01 -0500480{
Ratan Guptadcb10672017-07-10 10:33:50 +0530481 ipmi::PropertyMap properties;
482 int rc = 0;
Ratan Gupta6ec7daa2017-07-15 14:13:01 +0530483 uint8_t addrSize = IPV4_ADDRESS_SIZE_BYTE;
Ratan Guptafd28dd72016-08-01 04:58:01 -0500484
Ratan Guptadcb10672017-07-10 10:33:50 +0530485 try
486 {
487 //TODO There may be cases where an interface is implemented by multiple
488 // objects,to handle such cases we are interested on that object
489 // which are on interested busname.
490 // Currenlty mapper doesn't give the readable busname(gives busid)
491 // so we can't match with bus name so giving some object specific info
492 // as SETTINGS_MATCH.
493 // Later SETTINGS_MATCH will be replaced with busname.
Ratan Guptafd28dd72016-08-01 04:58:01 -0500494
Ratan Guptadcb10672017-07-10 10:33:50 +0530495 auto ipObjectInfo = getDbusObject(IP_INTERFACE, SETTINGS_ROOT,
496 SETTINGS_MATCH);
497 auto macObjectInfo = getDbusObject(MAC_INTERFACE, SETTINGS_ROOT,
498 SETTINGS_MATCH);
499
500 properties = getAllDbusProperties(ipObjectInfo.second,
501 ipObjectInfo.first, IP_INTERFACE);
502 auto MACAddress =
503 getDbusProperty(macObjectInfo.second, macObjectInfo.first,
504 MAC_INTERFACE, "MACAddress");
505
506 sscanf(MACAddress.c_str(), MAC_ADDRESS_FORMAT,
507 (respptr->data + MAC_OFFSET),
508 (respptr->data + MAC_OFFSET + 1),
509 (respptr->data + MAC_OFFSET + 2),
510 (respptr->data + MAC_OFFSET + 3),
511 (respptr->data + MAC_OFFSET + 4),
512 (respptr->data + MAC_OFFSET + 5));
513
514
515 respptr->data[MAC_OFFSET + 6] = 0x00;
516
Ratan Gupta6ec7daa2017-07-15 14:13:01 +0530517 uint8_t addrOrigin = (properties["Origin"].get<std::string>() ==
Ratan Guptadcb10672017-07-10 10:33:50 +0530518 "xyz.openbmc_project.Network.IP.AddressOrigin.Static") ? 1 : 0;
519
Ratan Gupta6ec7daa2017-07-15 14:13:01 +0530520 memcpy(respptr->data + ADDRTYPE_OFFSET, &addrOrigin,
521 sizeof(addrOrigin));
522
523 uint8_t addressFamily = (properties["Type"].get<std::string>() ==
524 "xyz.openbmc_project.Network.IP.Protocol.IPv4") ?
525 AF_INET : AF_INET6;
526
527 addrSize = (addressFamily == AF_INET) ? IPV4_ADDRESS_SIZE_BYTE :
528 IPV6_ADDRESS_SIZE_BYTE;
Ratan Guptadcb10672017-07-10 10:33:50 +0530529
530 // ipaddress and gateway would be in IPv4 format
531
Ratan Gupta6ec7daa2017-07-15 14:13:01 +0530532 inet_pton(addressFamily,
533 properties["Address"].get<std::string>().c_str(),
Ratan Guptadcb10672017-07-10 10:33:50 +0530534 (respptr->data + IPADDR_OFFSET));
535
536 uint8_t prefix = properties["PrefixLength"].get<uint8_t>();
Ratan Guptadcb10672017-07-10 10:33:50 +0530537
Ratan Gupta6ec7daa2017-07-15 14:13:01 +0530538 uint8_t prefixOffset = IPADDR_OFFSET + addrSize;
539
540 memcpy(respptr->data + prefixOffset, &prefix, sizeof(prefix));
541
542 uint8_t gatewayOffset = prefixOffset + sizeof(decltype(prefix));
543
544 inet_pton(addressFamily,
545 properties["Gateway"].get<std::string>().c_str(),
546 (respptr->data + gatewayOffset));
Ratan Guptadcb10672017-07-10 10:33:50 +0530547
548 }
549 catch (InternalFailure& e)
550 {
551 commit<InternalFailure>();
552 memset(respptr->data, 0, SIZE_BOOT_OPTION);
553 rc = -1;
Ratan Guptafd28dd72016-08-01 04:58:01 -0500554 return rc;
555 }
556
Ratan Guptadcb10672017-07-10 10:33:50 +0530557 //PetiBoot-Specific
558 //If sucess then copy the first 9 bytes to the data
Ratan Guptadcb10672017-07-10 10:33:50 +0530559 memcpy(respptr->data, net_conf_initial_bytes,
560 sizeof(net_conf_initial_bytes));
Ratan Guptafd28dd72016-08-01 04:58:01 -0500561
Ratan Gupta6ec7daa2017-07-15 14:13:01 +0530562 memcpy(respptr->data + ADDR_SIZE_OFFSET, &addrSize, sizeof(addrSize));
563
Ratan Guptafd28dd72016-08-01 04:58:01 -0500564#ifdef _IPMI_DEBUG_
Ratan Guptadcb10672017-07-10 10:33:50 +0530565 printf("\n===Printing the IPMI Formatted Data========\n");
Ratan Guptafd28dd72016-08-01 04:58:01 -0500566
Ratan Guptadcb10672017-07-10 10:33:50 +0530567 for (uint8_t pos = 0; pos < index; pos++)
568 {
569 printf("%02x ", respptr->data[pos]);
570 }
Ratan Guptafd28dd72016-08-01 04:58:01 -0500571#endif
572
Ratan Guptafd28dd72016-08-01 04:58:01 -0500573 return rc;
574}
575
Ratan Gupta6ec7daa2017-07-15 14:13:01 +0530576/** @brief convert IPv4 and IPv6 addresses from binary to text form.
577 * @param[in] family - IPv4/Ipv6
578 * @param[in] data - req data pointer.
579 * @param[in] offset - offset in the data.
580 * @param[in] addrSize - size of the data which needs to be read from offset.
581 * @returns address in text form.
582 */
583
584std::string getAddrStr(uint8_t family, uint8_t* data,
585 uint8_t offset, uint8_t addrSize)
586{
587 char ipAddr[INET6_ADDRSTRLEN] = {};
588
589 switch(family)
590 {
591 case AF_INET:
592 {
593 struct sockaddr_in addr4 {};
594 memcpy(&addr4.sin_addr.s_addr, &data[offset], addrSize);
595
596 inet_ntop(AF_INET, &addr4.sin_addr,
597 ipAddr, INET_ADDRSTRLEN);
598
599 break;
600 }
601 case AF_INET6:
602 {
603 struct sockaddr_in6 addr6 {};
604 memcpy(&addr6.sin6_addr.s6_addr, &data[offset], addrSize);
605
606 inet_ntop(AF_INET6, &addr6.sin6_addr,
607 ipAddr, INET6_ADDRSTRLEN);
608
609 break;
610 }
611 default:
612 {
613 return {};
614 }
615 }
616
617 return ipAddr;
618}
619
Ratan Guptadcb10672017-07-10 10:33:50 +0530620int setHostNetworkData(set_sys_boot_options_t* reqptr)
Ratan Guptafd28dd72016-08-01 04:58:01 -0500621{
Ratan Guptadcb10672017-07-10 10:33:50 +0530622 using namespace std::string_literals;
Ratan Guptafd28dd72016-08-01 04:58:01 -0500623 std::string host_network_config;
624 char mac[SIZE_MAC] = {0};
Ratan Gupta6ec7daa2017-07-15 14:13:01 +0530625 std::string ipAddress, gateway;
626 char addrOrigin {0};
627 uint8_t addrSize {0};
Ratan Guptadcb10672017-07-10 10:33:50 +0530628 std::string addressOrigin =
Ratan Gupta6ec7daa2017-07-15 14:13:01 +0530629 "xyz.openbmc_project.Network.IP.AddressOrigin.DHCP";
630 std::string addressType =
631 "xyz.openbmc_project.Network.IP.Protocol.IPv4";
Ratan Guptadcb10672017-07-10 10:33:50 +0530632 uint8_t prefix {0};
633 uint32_t zeroCookie = 0;
Ratan Gupta6ec7daa2017-07-15 14:13:01 +0530634 uint8_t family = AF_INET;
Ratan Guptafd28dd72016-08-01 04:58:01 -0500635
636 //cookie starts from second byte
637 // version starts from sixth byte
638
Ratan Guptadcb10672017-07-10 10:33:50 +0530639 try
Ratan Guptafd28dd72016-08-01 04:58:01 -0500640 {
Ratan Guptadcb10672017-07-10 10:33:50 +0530641 do
642 {
643 // cookie == 0x21 0x70 0x62 0x21
644 if (memcmp(&(reqptr->data[COOKIE_OFFSET]),
645 (net_conf_initial_bytes + COOKIE_OFFSET),
646 SIZE_COOKIE) != 0)
647 {
648 //cookie == 0
649 if (memcmp(&(reqptr->data[COOKIE_OFFSET]),
650 &zeroCookie,
651 SIZE_COOKIE) == 0)
652 {
653 // need to zero out the network settings.
654 break;
655 }
656
657 log<level::ERR>("Invalid Cookie");
658 elog<InternalFailure>();
659 }
660
661 // vesion == 0x00 0x01
662 if (memcmp(&(reqptr->data[VERSION_OFFSET]),
663 (net_conf_initial_bytes + VERSION_OFFSET),
664 SIZE_VERSION) != 0)
665 {
666
667 log<level::ERR>("Invalid Version");
668 elog<InternalFailure>();
669 }
670
671 snprintf(mac, SIZE_MAC, MAC_ADDRESS_FORMAT,
672 reqptr->data[MAC_OFFSET],
673 reqptr->data[MAC_OFFSET + 1],
674 reqptr->data[MAC_OFFSET + 2],
675 reqptr->data[MAC_OFFSET + 3],
676 reqptr->data[MAC_OFFSET + 4],
677 reqptr->data[MAC_OFFSET + 5]);
678
Ratan Gupta6ec7daa2017-07-15 14:13:01 +0530679 memcpy(&addrOrigin, &(reqptr->data[ADDRTYPE_OFFSET]),
680 sizeof(decltype(addrOrigin)));
Ratan Guptadcb10672017-07-10 10:33:50 +0530681
Ratan Gupta6ec7daa2017-07-15 14:13:01 +0530682 if (addrOrigin)
Ratan Guptadcb10672017-07-10 10:33:50 +0530683 {
684 addressOrigin =
Ratan Gupta6ec7daa2017-07-15 14:13:01 +0530685 "xyz.openbmc_project.Network.IP.AddressOrigin.Static";
Ratan Guptadcb10672017-07-10 10:33:50 +0530686 }
687
Ratan Gupta6ec7daa2017-07-15 14:13:01 +0530688 // Get the address size
689 memcpy(&addrSize ,&reqptr->data[ADDR_SIZE_OFFSET], sizeof(addrSize));
Ratan Guptadcb10672017-07-10 10:33:50 +0530690
Ratan Gupta6ec7daa2017-07-15 14:13:01 +0530691 uint8_t prefixOffset = IPADDR_OFFSET + addrSize;
Ratan Guptadcb10672017-07-10 10:33:50 +0530692
Ratan Gupta6ec7daa2017-07-15 14:13:01 +0530693 memcpy(&prefix, &(reqptr->data[prefixOffset]), sizeof(decltype(prefix)));
Ratan Guptadcb10672017-07-10 10:33:50 +0530694
Ratan Gupta6ec7daa2017-07-15 14:13:01 +0530695 uint8_t gatewayOffset = prefixOffset + sizeof(decltype(prefix));
696
697 if (addrSize != IPV4_ADDRESS_SIZE_BYTE)
698 {
699 addressType = "xyz.openbmc_project.Network.IP.Protocol.IPv6";
700 family = AF_INET6;
701 }
702
703 ipAddress = getAddrStr(family, reqptr->data, IPADDR_OFFSET, addrSize);
704 gateway = getAddrStr(family, reqptr->data, gatewayOffset, addrSize);
705
Ratan Guptadcb10672017-07-10 10:33:50 +0530706 } while(0);
707
Ratan Guptafd28dd72016-08-01 04:58:01 -0500708 //Cookie == 0 or it is a valid cookie
Ratan Guptadcb10672017-07-10 10:33:50 +0530709 host_network_config += "ipaddress="s + ipAddress +
710 ",prefix="s + std::to_string(prefix) + ",gateway="s + gateway +
711 ",mac="s + mac + ",addressOrigin="s + addressOrigin;
Ratan Guptafd28dd72016-08-01 04:58:01 -0500712
Ratan Guptadcb10672017-07-10 10:33:50 +0530713 log<level::DEBUG>("Network configuration changed",
714 entry("NETWORKCONFIG=%s", host_network_config.c_str()));
Ratan Guptafd28dd72016-08-01 04:58:01 -0500715
Ratan Guptadcb10672017-07-10 10:33:50 +0530716 auto ipObjectInfo = getDbusObject(IP_INTERFACE, SETTINGS_ROOT,
717 SETTINGS_MATCH);
718 auto macObjectInfo = getDbusObject(MAC_INTERFACE, SETTINGS_ROOT,
719 SETTINGS_MATCH);
720 // set the dbus property
721 setDbusProperty(ipObjectInfo.second, ipObjectInfo.first,
722 IP_INTERFACE, "Address", std::string(ipAddress));
723 setDbusProperty(ipObjectInfo.second, ipObjectInfo.first,
724 IP_INTERFACE, "PrefixLength", prefix);
725 setDbusProperty(ipObjectInfo.second, ipObjectInfo.first,
726 IP_INTERFACE, "Origin", addressOrigin);
727 setDbusProperty(ipObjectInfo.second, ipObjectInfo.first,
728 IP_INTERFACE, "Gateway", std::string(gateway));
729 setDbusProperty(ipObjectInfo.second, ipObjectInfo.first,
730 IP_INTERFACE, "Type",
731 std::string("xyz.openbmc_project.Network.IP.Protocol.IPv4"));
732 setDbusProperty(macObjectInfo.second, macObjectInfo.first,
733 MAC_INTERFACE,"MACAddress", std::string(mac));
Ratan Guptafd28dd72016-08-01 04:58:01 -0500734
735 }
Ratan Guptadcb10672017-07-10 10:33:50 +0530736 catch (InternalFailure& e)
737 {
738 commit<InternalFailure>();
739 return -1;
740 }
741
742 return 0;
Ratan Guptafd28dd72016-08-01 04:58:01 -0500743}
744
Andrew Geisslerfca6a4f2017-05-30 10:55:39 -0500745ipmi_ret_t ipmi_chassis_wildcard(ipmi_netfn_t netfn, ipmi_cmd_t cmd,
746 ipmi_request_t request,
747 ipmi_response_t response,
748 ipmi_data_len_t data_len,
749 ipmi_context_t context)
Adriana Kobylak40814c62015-10-27 15:58:44 -0500750{
751 printf("Handling CHASSIS WILDCARD Netfn:[0x%X], Cmd:[0x%X]\n",netfn, cmd);
752 // Status code.
Nan Li70aa8d92016-08-29 00:11:10 +0800753 ipmi_ret_t rc = IPMI_CC_INVALID;
Adriana Kobylak40814c62015-10-27 15:58:44 -0500754 *data_len = 0;
755 return rc;
756}
757
Nan Li8d15fb42016-08-16 22:29:40 +0800758ipmi_ret_t ipmi_get_chassis_cap(ipmi_netfn_t netfn, ipmi_cmd_t cmd,
Andrew Geisslerfca6a4f2017-05-30 10:55:39 -0500759 ipmi_request_t request, ipmi_response_t response,
760 ipmi_data_len_t data_len, ipmi_context_t context)
Nan Li8d15fb42016-08-16 22:29:40 +0800761{
762 // sd_bus error
763 ipmi_ret_t rc = IPMI_CC_OK;
764
765 ipmi_chassis_cap_t chassis_cap{};
766
767 *data_len = sizeof(ipmi_chassis_cap_t);
768
769 // TODO: need future work. Get those flag from MRW.
770
771 // capabilities flags
772 // [7..4] - reserved
773 // [3] – 1b = provides power interlock (IPM 1.5)
774 // [2] – 1b = provides Diagnostic Interrupt (FP NMI)
775 // [1] – 1b = provides “Front Panel Lockout” (indicates that the chassis has capabilities
776 // to lock out external power control and reset button or front panel interfaces
777 // and/or detect tampering with those interfaces).
778 // [0] -1b = Chassis provides intrusion (physical security) sensor.
779 // set to default value 0x0.
780 chassis_cap.cap_flags = 0x0;
781
782 // Since we do not have a separate SDR Device/SEL Device/ FRU repository.
783 // The 20h was given as those 5 device addresses.
784 // Chassis FRU info Device Address
785 chassis_cap.fru_info_dev_addr = 0x20;
786
787 // Chassis SDR Device Address
788 chassis_cap.sdr_dev_addr = 0x20;
789
790 // Chassis SEL Device Address
791 chassis_cap.sel_dev_addr = 0x20;
792
793 // Chassis System Management Device Address
794 chassis_cap.system_management_dev_addr = 0x20;
795
796 // Chassis Bridge Device Address.
797 chassis_cap.bridge_dev_addr = 0x20;
798
799 memcpy(response, &chassis_cap, *data_len);
800
801 return rc;
802}
803
Vishwanatha Subbannab12b0c02017-03-07 18:17:19 +0530804//------------------------------------------
805// Calls into Host State Manager Dbus object
806//------------------------------------------
807int initiate_state_transition(State::Host::Transition transition)
vishwa36993272015-11-20 12:43:49 -0600808{
Andrew Geisslerfca6a4f2017-05-30 10:55:39 -0500809 // OpenBMC Host State Manager dbus framework
810 constexpr auto HOST_STATE_MANAGER_ROOT = "/xyz/openbmc_project/state/host0";
811 constexpr auto HOST_STATE_MANAGER_IFACE = "xyz.openbmc_project.State.Host";
812 constexpr auto DBUS_PROPERTY_IFACE = "org.freedesktop.DBus.Properties";
813 constexpr auto PROPERTY = "RequestedHostTransition";
Vishwanatha Subbannab12b0c02017-03-07 18:17:19 +0530814
Andrew Geisslerfca6a4f2017-05-30 10:55:39 -0500815 // sd_bus error
816 int rc = 0;
817 char *busname = NULL;
vishwa36993272015-11-20 12:43:49 -0600818
Andrew Geisslerfca6a4f2017-05-30 10:55:39 -0500819 // SD Bus error report mechanism.
820 sd_bus_error bus_error = SD_BUS_ERROR_NULL;
vishwa36993272015-11-20 12:43:49 -0600821
Andrew Geisslerfca6a4f2017-05-30 10:55:39 -0500822 // Gets a hook onto either a SYSTEM or SESSION bus
823 sd_bus *bus_type = ipmid_get_sd_bus_connection();
824 rc = mapper_get_service(bus_type, HOST_STATE_MANAGER_ROOT, &busname);
825 if (rc < 0)
826 {
827 log<level::ERR>("Failed to get bus name",
828 entry("ERROR=%s, OBJPATH=%s",
829 strerror(-rc), HOST_STATE_MANAGER_ROOT));
830 return rc;
831 }
Vishwanatha Subbannab12b0c02017-03-07 18:17:19 +0530832
Andrew Geisslerfca6a4f2017-05-30 10:55:39 -0500833 // Convert to string equivalent of the passed in transition enum.
834 auto request = State::convertForMessage(transition);
Vishwanatha Subbannab12b0c02017-03-07 18:17:19 +0530835
Andrew Geisslerfca6a4f2017-05-30 10:55:39 -0500836 rc = sd_bus_call_method(bus_type, // On the system bus
837 busname, // Service to contact
838 HOST_STATE_MANAGER_ROOT, // Object path
839 DBUS_PROPERTY_IFACE, // Interface name
840 "Set", // Method to be called
841 &bus_error, // object to return error
842 nullptr, // Response buffer if any
843 "ssv", // Takes 3 arguments
844 HOST_STATE_MANAGER_IFACE,
845 PROPERTY,
846 "s", request.c_str());
847 if(rc < 0)
848 {
849 log<level::ERR>("Failed to initiate transition",
850 entry("ERROR=%s, REQUEST=%s",
851 bus_error.message, request.c_str()));
852 }
853 else
854 {
855 log<level::INFO>("Transition request initiated successfully");
856 }
vishwa36993272015-11-20 12:43:49 -0600857
858 sd_bus_error_free(&bus_error);
Sergey Solomineb9b8142016-08-23 09:07:28 -0500859 free(busname);
vishwa36993272015-11-20 12:43:49 -0600860
Sergey Solomineb9b8142016-08-23 09:07:28 -0500861 return rc;
vishwa36993272015-11-20 12:43:49 -0600862}
863
Deepak Kodihalli18b70d12017-07-21 13:36:33 -0500864namespace power_policy
Andrew Geisslerfca6a4f2017-05-30 10:55:39 -0500865{
Nan Lifdd8ec52016-08-28 03:57:40 +0800866
Deepak Kodihalli18b70d12017-07-21 13:36:33 -0500867using namespace sdbusplus::xyz::openbmc_project::Control::Power::server;
868using IpmiValue = uint8_t;
869using DbusValue = RestorePolicy::Policy;
Nan Lifdd8ec52016-08-28 03:57:40 +0800870
Deepak Kodihalli18b70d12017-07-21 13:36:33 -0500871std::map<DbusValue, IpmiValue> dbusToIpmi =
872{
873 {RestorePolicy::Policy::AlwaysOff, 0x00},
874 {RestorePolicy::Policy::Restore, 0x01},
875 {RestorePolicy::Policy::AlwaysOn, 0x02}
876};
Nan Lifdd8ec52016-08-28 03:57:40 +0800877
Deepak Kodihalli18b70d12017-07-21 13:36:33 -0500878} // namespace power_policy
Nan Lifdd8ec52016-08-28 03:57:40 +0800879
880//----------------------------------------------------------------------
881// Get Chassis Status commands
882//----------------------------------------------------------------------
883ipmi_ret_t ipmi_get_chassis_status(ipmi_netfn_t netfn, ipmi_cmd_t cmd,
Andrew Geisslerfca6a4f2017-05-30 10:55:39 -0500884 ipmi_request_t request,
885 ipmi_response_t response,
886 ipmi_data_len_t data_len,
887 ipmi_context_t context)
Nan Lifdd8ec52016-08-28 03:57:40 +0800888{
889 const char *objname = "/org/openbmc/control/power0";
890 const char *intf = "org.openbmc.control.Power";
891
892 sd_bus *bus = NULL;
893 sd_bus_message *reply = NULL;
894 int r = 0;
895 int pgood = 0;
896 char *busname = NULL;
897 ipmi_ret_t rc = IPMI_CC_OK;
898 ipmi_get_chassis_status_t chassis_status{};
899
Nan Lifdd8ec52016-08-28 03:57:40 +0800900 uint8_t s = 0;
901
Deepak Kodihalli18b70d12017-07-21 13:36:33 -0500902 using namespace chassis::internal;
903 using namespace chassis::internal::cache;
904 using namespace power_policy;
905
906 const auto& powerRestoreSetting = objects.map.at(powerRestoreIntf);
907 auto method =
908 dbus.new_method_call(
909 objects.service(powerRestoreSetting, powerRestoreIntf).c_str(),
910 powerRestoreSetting.c_str(),
911 PROP_INTF,
912 "Get");
913 method.append(powerRestoreIntf, "PowerRestorePolicy");
914 auto resp = dbus.call(method);
915 if (resp.is_method_error())
916 {
917 log<level::ERR>("Error in PowerRestorePolicy Get");
918 report<InternalFailure>();
919 *data_len = 0;
920 return IPMI_CC_UNSPECIFIED_ERROR;
921 }
922 sdbusplus::message::variant<std::string> result;
923 resp.read(result);
924 auto powerRestore =
925 RestorePolicy::convertPolicyFromString(result.get<std::string>());
Nan Lifdd8ec52016-08-28 03:57:40 +0800926
927 *data_len = 4;
928
929 r = mapper_get_service(bus, objname, &busname);
930 if (r < 0) {
931 fprintf(stderr, "Failed to get bus name, return value: %s.\n", strerror(-r));
932 rc = IPMI_CC_UNSPECIFIED_ERROR;
933 goto finish;
934 }
935
936 r = sd_bus_get_property(bus, busname, objname, intf, "pgood", NULL, &reply, "i");
937 if (r < 0) {
938 fprintf(stderr, "Failed to call sd_bus_get_property:%d, %s\n", r, strerror(-r));
939 fprintf(stderr, "Bus: %s, Path: %s, Interface: %s\n",
940 busname, objname, intf);
941 rc = IPMI_CC_UNSPECIFIED_ERROR;
942 goto finish;
943 }
944
945 r = sd_bus_message_read(reply, "i", &pgood);
946 if (r < 0) {
947 fprintf(stderr, "Failed to read sensor: %s\n", strerror(-r));
948 rc = IPMI_CC_UNSPECIFIED_ERROR;
949 goto finish;
950 }
951
952 printf("pgood is 0x%02x\n", pgood);
953
Deepak Kodihalli18b70d12017-07-21 13:36:33 -0500954 s = dbusToIpmi.at(powerRestore);
Nan Lifdd8ec52016-08-28 03:57:40 +0800955
956 // Current Power State
957 // [7] reserved
958 // [6..5] power restore policy
959 // 00b = chassis stays powered off after AC/mains returns
960 // 01b = after AC returns, power is restored to the state that was
961 // in effect when AC/mains was lost.
962 // 10b = chassis always powers up after AC/mains returns
963 // 11b = unknow
964 // Set to 00b, by observing the hardware behavior.
965 // Do we need to define a dbus property to identify the restore policy?
966
967 // [4] power control fault
968 // 1b = controller attempted to turn system power on or off, but
969 // system did not enter desired state.
970 // Set to 0b, since We don't support it..
971
972 // [3] power fault
973 // 1b = fault detected in main power subsystem.
974 // set to 0b. for we don't support it.
975
976 // [2] 1b = interlock (chassis is presently shut down because a chassis
977 // panel interlock switch is active). (IPMI 1.5)
978 // set to 0b, for we don't support it.
979
980 // [1] power overload
981 // 1b = system shutdown because of power overload condition.
982 // set to 0b, for we don't support it.
983
984 // [0] power is on
985 // 1b = system power is on
986 // 0b = system power is off(soft-off S4/S5, or mechanical off)
987
988 chassis_status.cur_power_state = ((s & 0x3)<<5) | (pgood & 0x1);
989
990 // Last Power Event
991 // [7..5] – reserved
992 // [4] – 1b = last ‘Power is on’ state was entered via IPMI command
993 // [3] – 1b = last power down caused by power fault
994 // [2] – 1b = last power down caused by a power interlock being activated
995 // [1] – 1b = last power down caused by a Power overload
996 // [0] – 1b = AC failed
997 // set to 0x0, for we don't support these fields.
998
999 chassis_status.last_power_event = 0;
1000
1001 // Misc. Chassis State
1002 // [7] – reserved
1003 // [6] – 1b = Chassis Identify command and state info supported (Optional)
1004 // 0b = Chassis Identify command support unspecified via this command.
1005 // (The Get Command Support command , if implemented, would still
1006 // indicate support for the Chassis Identify command)
1007 // [5..4] – Chassis Identify State. Mandatory when bit[6] =1b, reserved (return
1008 // as 00b) otherwise. Returns the present chassis identify state.
1009 // Refer to the Chassis Identify command for more info.
1010 // 00b = chassis identify state = Off
1011 // 01b = chassis identify state = Temporary(timed) On
1012 // 10b = chassis identify state = Indefinite On
1013 // 11b = reserved
1014 // [3] – 1b = Cooling/fan fault detected
1015 // [2] – 1b = Drive Fault
1016 // [1] – 1b = Front Panel Lockout active (power off and reset via chassis
1017 // push-buttons disabled.)
1018 // [0] – 1b = Chassis Intrusion active
1019 // set to 0, for we don't support them.
1020 chassis_status.misc_power_state = 0;
1021
1022 // Front Panel Button Capabilities and disable/enable status(Optional)
1023 // set to 0, for we don't support them.
1024 chassis_status.front_panel_button_cap_status = 0;
1025
1026 // Pack the actual response
1027 memcpy(response, &chassis_status, *data_len);
1028
1029finish:
1030 free(busname);
1031 reply = sd_bus_message_unref(reply);
1032
1033 return rc;
1034}
Chris Austen7888c4d2015-12-03 15:26:20 -06001035
Vishwanatha Subbanna83b5c1c2017-01-25 18:41:51 +05301036//-------------------------------------------------------------
1037// Send a command to SoftPowerOff application to stop any timer
1038//-------------------------------------------------------------
1039int stop_soft_off_timer()
1040{
Vishwanatha Subbanna83b5c1c2017-01-25 18:41:51 +05301041 constexpr auto iface = "org.freedesktop.DBus.Properties";
1042 constexpr auto soft_off_iface = "xyz.openbmc_project.Ipmi.Internal."
Andrew Geisslerfca6a4f2017-05-30 10:55:39 -05001043 "SoftPowerOff";
Vishwanatha Subbanna83b5c1c2017-01-25 18:41:51 +05301044
1045 constexpr auto property = "ResponseReceived";
1046 constexpr auto value = "xyz.openbmc_project.Ipmi.Internal."
Andrew Geisslerfca6a4f2017-05-30 10:55:39 -05001047 "SoftPowerOff.HostResponse.HostShutdown";
Vishwanatha Subbanna83b5c1c2017-01-25 18:41:51 +05301048
1049 // Get the system bus where most system services are provided.
1050 auto bus = ipmid_get_sd_bus_connection();
1051
1052 // Get the service name
Andrew Geissler2b4e4592017-06-08 11:18:35 -05001053 // TODO openbmc/openbmc#1661 - Mapper refactor
1054 //
1055 // See openbmc/openbmc#1743 for some details but high level summary is that
1056 // for now the code will directly call the soft off interface due to a
1057 // race condition with mapper usage
1058 //
1059 //char *busname = nullptr;
1060 //auto r = mapper_get_service(bus, SOFTOFF_OBJPATH, &busname);
1061 //if (r < 0)
1062 //{
1063 // fprintf(stderr, "Failed to get %s bus name: %s\n",
1064 // SOFTOFF_OBJPATH, strerror(-r));
1065 // return r;
1066 //}
Vishwanatha Subbanna83b5c1c2017-01-25 18:41:51 +05301067
1068 // No error object or reply expected.
Andrew Geissler2b4e4592017-06-08 11:18:35 -05001069 int rc = sd_bus_call_method(bus, SOFTOFF_BUSNAME, SOFTOFF_OBJPATH, iface,
Andrew Geisslerfca6a4f2017-05-30 10:55:39 -05001070 "Set", nullptr, nullptr, "ssv",
1071 soft_off_iface, property, "s", value);
Vishwanatha Subbanna83b5c1c2017-01-25 18:41:51 +05301072 if (rc < 0)
1073 {
1074 fprintf(stderr, "Failed to set property in SoftPowerOff object: %s\n",
1075 strerror(-rc));
1076 }
Andrew Geisslerfca6a4f2017-05-30 10:55:39 -05001077
Andrew Geissler2b4e4592017-06-08 11:18:35 -05001078 //TODO openbmc/openbmc#1661 - Mapper refactor
1079 //free(busname);
Vishwanatha Subbanna83b5c1c2017-01-25 18:41:51 +05301080 return rc;
1081}
1082
vishwa36993272015-11-20 12:43:49 -06001083//----------------------------------------------------------------------
Andrew Geisslera6e3a302017-05-31 19:34:00 -05001084// Create file to indicate there is no need for softoff notification to host
1085//----------------------------------------------------------------------
1086void indicate_no_softoff_needed()
1087{
1088 fs::path path{HOST_INBAND_REQUEST_DIR};
1089 if (!fs::is_directory(path))
1090 {
1091 fs::create_directory(path);
1092 }
1093
1094 // Add the host instance (default 0 for now) to the file name
1095 std::string file{HOST_INBAND_REQUEST_FILE};
1096 auto size = std::snprintf(nullptr,0,file.c_str(),0);
1097 size++; // null
1098 std::unique_ptr<char[]> buf(new char[size]);
1099 std::snprintf(buf.get(),size,file.c_str(),0);
1100
1101 // Append file name to directory and create it
1102 path /= buf.get();
1103 std::ofstream(path.c_str());
1104}
1105
1106//----------------------------------------------------------------------
vishwa36993272015-11-20 12:43:49 -06001107// Chassis Control commands
1108//----------------------------------------------------------------------
Andrew Geisslerfca6a4f2017-05-30 10:55:39 -05001109ipmi_ret_t ipmi_chassis_control(ipmi_netfn_t netfn, ipmi_cmd_t cmd,
1110 ipmi_request_t request,
1111 ipmi_response_t response,
1112 ipmi_data_len_t data_len,
1113 ipmi_context_t context)
vishwa36993272015-11-20 12:43:49 -06001114{
Andrew Geisslerfca6a4f2017-05-30 10:55:39 -05001115 // Error from power off.
1116 int rc = 0;
vishwa36993272015-11-20 12:43:49 -06001117
Andrew Geisslerfca6a4f2017-05-30 10:55:39 -05001118 // No response for this command.
vishwa36993272015-11-20 12:43:49 -06001119 *data_len = 0;
1120
Andrew Geisslerfca6a4f2017-05-30 10:55:39 -05001121 // Catch the actual operaton by peeking into request buffer
1122 uint8_t chassis_ctrl_cmd = *(uint8_t *)request;
1123 printf("Chassis Control Command: Operation:[0x%X]\n",chassis_ctrl_cmd);
vishwa36993272015-11-20 12:43:49 -06001124
Andrew Geisslerfca6a4f2017-05-30 10:55:39 -05001125 switch(chassis_ctrl_cmd)
1126 {
1127 case CMD_POWER_ON:
1128 rc = initiate_state_transition(State::Host::Transition::On);
1129 break;
1130 case CMD_POWER_OFF:
1131 // Need to Nudge SoftPowerOff application that it needs to stop the
1132 // watchdog timer if running.
1133 rc = stop_soft_off_timer();
Andrew Geisslera6e3a302017-05-31 19:34:00 -05001134 // Only request the Off transition if the soft power off
1135 // application is not running
1136 if (rc < 0)
Andrew Geisslerfca6a4f2017-05-30 10:55:39 -05001137 {
Andrew Geisslera6e3a302017-05-31 19:34:00 -05001138 log<level::INFO>("Did not find soft off service so request "
1139 "Host:Transition:Off");
1140
1141 // First create a file to indicate to the soft off application
1142 // that it should not run since this is a direct user initiated
1143 // power off request (i.e. a power off request that is not
1144 // originating via a soft power off SMS request)
1145 indicate_no_softoff_needed();
1146
1147 // Now request the shutdown
1148 rc = initiate_state_transition(State::Host::Transition::Off);
Andrew Geisslerfca6a4f2017-05-30 10:55:39 -05001149 }
Andrew Geisslera6e3a302017-05-31 19:34:00 -05001150 else
1151 {
1152 log<level::INFO>("Soft off is running, so let that stop "
1153 "the host");
1154 }
1155
Andrew Geisslerfca6a4f2017-05-30 10:55:39 -05001156 break;
Vishwanatha Subbanna83b5c1c2017-01-25 18:41:51 +05301157
Andrew Geisslerfca6a4f2017-05-30 10:55:39 -05001158 case CMD_HARD_RESET:
1159 case CMD_POWER_CYCLE:
1160 // SPEC has a section that says certain implementations can trigger
1161 // PowerOn if power is Off when a command to power cycle is
1162 // requested
Andrew Geisslera6e3a302017-05-31 19:34:00 -05001163
1164 // First create a file to indicate to the soft off application
1165 // that it should not run since this is a direct user initiated
1166 // power reboot request (i.e. a reboot request that is not
1167 // originating via a soft power off SMS request)
1168 indicate_no_softoff_needed();
1169
Andrew Geisslerfca6a4f2017-05-30 10:55:39 -05001170 rc = initiate_state_transition(State::Host::Transition::Reboot);
1171 break;
1172 default:
1173 {
1174 fprintf(stderr, "Invalid Chassis Control command:[0x%X] received\n",chassis_ctrl_cmd);
1175 rc = -1;
1176 }
1177 }
vishwa36993272015-11-20 12:43:49 -06001178
Andrew Geisslerfca6a4f2017-05-30 10:55:39 -05001179 return ( (rc < 0) ? IPMI_CC_INVALID : IPMI_CC_OK);
vishwa36993272015-11-20 12:43:49 -06001180}
1181
Deepak Kodihalli8cc19362017-07-21 11:18:38 -05001182namespace boot_options
1183{
1184
1185using namespace sdbusplus::xyz::openbmc_project::Control::Boot::server;
1186using IpmiValue = uint8_t;
1187constexpr auto ipmiDefault = 0;
1188
1189std::map<IpmiValue, Source::Sources> sourceIpmiToDbus =
1190{
1191 {0x01, Source::Sources::Network},
1192 {0x02, Source::Sources::Disk},
1193 {0x05, Source::Sources::ExternalMedia},
1194 {ipmiDefault, Source::Sources::Default}
shgoupfd84fbbf2015-12-17 10:05:51 +08001195};
1196
Deepak Kodihalli8cc19362017-07-21 11:18:38 -05001197std::map<IpmiValue, Mode::Modes> modeIpmiToDbus =
1198{
1199 {0x03, Mode::Modes::Safe},
1200 {0x06, Mode::Modes::Setup},
1201 {ipmiDefault, Mode::Modes::Regular}
shgoupfd84fbbf2015-12-17 10:05:51 +08001202};
1203
Deepak Kodihalli8cc19362017-07-21 11:18:38 -05001204std::map<Source::Sources, IpmiValue> sourceDbusToIpmi =
1205{
1206 {Source::Sources::Network, 0x01},
1207 {Source::Sources::Disk, 0x02},
1208 {Source::Sources::ExternalMedia, 0x05},
1209 {Source::Sources::Default, ipmiDefault}
1210};
shgoupfd84fbbf2015-12-17 10:05:51 +08001211
Deepak Kodihalli8cc19362017-07-21 11:18:38 -05001212std::map<Mode::Modes, IpmiValue> modeDbusToIpmi =
1213{
1214 {Mode::Modes::Safe, 0x03},
1215 {Mode::Modes::Setup, 0x06},
1216 {Mode::Modes::Regular, ipmiDefault}
1217};
shgoupfd84fbbf2015-12-17 10:05:51 +08001218
Deepak Kodihalli8cc19362017-07-21 11:18:38 -05001219} // namespace boot_options
shgoupfd84fbbf2015-12-17 10:05:51 +08001220
Andrew Geisslerfca6a4f2017-05-30 10:55:39 -05001221ipmi_ret_t ipmi_chassis_get_sys_boot_options(ipmi_netfn_t netfn, ipmi_cmd_t cmd,
1222 ipmi_request_t request,
1223 ipmi_response_t response,
1224 ipmi_data_len_t data_len,
1225 ipmi_context_t context)
Adriana Kobylak40814c62015-10-27 15:58:44 -05001226{
Deepak Kodihalli8cc19362017-07-21 11:18:38 -05001227 using namespace boot_options;
shgoupfd84fbbf2015-12-17 10:05:51 +08001228 ipmi_ret_t rc = IPMI_CC_PARM_NOT_SUPPORTED;
1229 char *p = NULL;
1230 get_sys_boot_options_response_t *resp = (get_sys_boot_options_response_t *) response;
1231 get_sys_boot_options_t *reqptr = (get_sys_boot_options_t*) request;
Deepak Kodihalli8cc19362017-07-21 11:18:38 -05001232 IpmiValue bootOption = ipmiDefault;
Adriana Kobylak40814c62015-10-27 15:58:44 -05001233
1234 printf("IPMI GET_SYS_BOOT_OPTIONS\n");
1235
shgoupfd84fbbf2015-12-17 10:05:51 +08001236 memset(resp,0,sizeof(*resp));
1237 resp->version = SET_PARM_VERSION;
1238 resp->parm = 5;
ratagupta6f6bff2016-04-04 06:20:11 -05001239 resp->data[0] = SET_PARM_BOOT_FLAGS_VALID_ONE_TIME;
Adriana Kobylak40814c62015-10-27 15:58:44 -05001240
Adriana Kobylak40814c62015-10-27 15:58:44 -05001241
shgoupfd84fbbf2015-12-17 10:05:51 +08001242 /*
1243 * Parameter #5 means boot flags. Please refer to 28.13 of ipmi doc.
1244 * This is the only parameter used by petitboot.
1245 */
Ratan Guptafd28dd72016-08-01 04:58:01 -05001246 if ( reqptr->parameter == static_cast<uint8_t>
Andrew Geisslerfca6a4f2017-05-30 10:55:39 -05001247 ( BootOptionParameter::BOOT_FLAGS )) {
shgoupfd84fbbf2015-12-17 10:05:51 +08001248
Ratan Guptafd28dd72016-08-01 04:58:01 -05001249 *data_len = static_cast<uint8_t>(BootOptionResponseSize::BOOT_FLAGS);
Deepak Kodihalli8cc19362017-07-21 11:18:38 -05001250 using namespace chassis::internal;
1251 using namespace chassis::internal::cache;
shgoupfd84fbbf2015-12-17 10:05:51 +08001252
Deepak Kodihalli8cc19362017-07-21 11:18:38 -05001253 const auto& bootSourceSetting = objects.map.at(bootSourceIntf);
1254 auto method =
1255 dbus.new_method_call(
1256 objects.service(bootSourceSetting, bootSourceIntf).c_str(),
1257 bootSourceSetting.c_str(),
1258 PROP_INTF,
1259 "Get");
1260 method.append(bootSourceIntf, "BootSource");
1261 auto reply = dbus.call(method);
1262 if (reply.is_method_error())
ratagupta6f6bff2016-04-04 06:20:11 -05001263 {
Deepak Kodihalli8cc19362017-07-21 11:18:38 -05001264 log<level::ERR>("Error in BootSource Get");
1265 report<InternalFailure>();
1266 *data_len = 0;
1267 return IPMI_CC_UNSPECIFIED_ERROR;
ratagupta6f6bff2016-04-04 06:20:11 -05001268 }
Deepak Kodihalli8cc19362017-07-21 11:18:38 -05001269 sdbusplus::message::variant<std::string> result;
1270 reply.read(result);
1271 auto bootSource =
1272 Source::convertSourcesFromString(result.get<std::string>());
1273
1274 const auto& bootModeSetting = objects.map.at(bootModeIntf);
1275 method = dbus.new_method_call(
1276 objects.service(bootModeSetting, bootModeIntf).c_str(),
1277 bootModeSetting.c_str(),
1278 PROP_INTF,
1279 "Get");
1280 method.append(bootModeIntf, "BootMode");
1281 reply = dbus.call(method);
1282 if (reply.is_method_error())
1283 {
1284 log<level::ERR>("Error in BootMode Get");
1285 report<InternalFailure>();
1286 *data_len = 0;
1287 return IPMI_CC_UNSPECIFIED_ERROR;
1288 }
1289 reply.read(result);
1290 auto bootMode = Mode::convertModesFromString(result.get<std::string>());
1291
1292 bootOption = sourceDbusToIpmi.at(bootSource);
1293 if ((Mode::Modes::Regular == bootMode) &&
1294 (Source::Sources::Default == bootSource))
1295 {
1296 bootOption = ipmiDefault;
1297 }
1298 else if (Source::Sources::Default == bootSource)
1299 {
1300 bootOption = modeDbusToIpmi.at(bootMode);
1301 }
1302 resp->data[1] = (bootOption << 2);
1303 rc = IPMI_CC_OK;
ratagupta6f6bff2016-04-04 06:20:11 -05001304
1305 /* Get the boot policy */
Deepak Kodihalli8cc19362017-07-21 11:18:38 -05001306 int r = dbus_get_property("boot_policy",&p);
ratagupta6f6bff2016-04-04 06:20:11 -05001307
1308 if (r < 0) {
1309 fprintf(stderr, "Dbus get property(boot_policy) failed for get_sys_boot_options.\n");
1310 rc = IPMI_CC_UNSPECIFIED_ERROR;
1311
1312 } else {
1313
George Keishing012d6a42017-06-14 03:06:48 -05001314 printf("BootPolicy is [%s]\n", p);
Andrew Geisslerfca6a4f2017-05-30 10:55:39 -05001315 resp->data[0] = (strncmp(p,"ONETIME",strlen("ONETIME"))==0) ?
1316 SET_PARM_BOOT_FLAGS_VALID_ONE_TIME:
1317 SET_PARM_BOOT_FLAGS_VALID_PERMANENT;
ratagupta6f6bff2016-04-04 06:20:11 -05001318 rc = IPMI_CC_OK;
1319
1320 }
1321
1322
Ratan Guptafd28dd72016-08-01 04:58:01 -05001323 } else if ( reqptr->parameter == static_cast<uint8_t>
Andrew Geisslerfca6a4f2017-05-30 10:55:39 -05001324 ( BootOptionParameter::OPAL_NETWORK_SETTINGS )) {
Ratan Guptafd28dd72016-08-01 04:58:01 -05001325
Andrew Geisslerfca6a4f2017-05-30 10:55:39 -05001326 *data_len = static_cast<uint8_t>(BootOptionResponseSize::OPAL_NETWORK_SETTINGS);
Ratan Guptafd28dd72016-08-01 04:58:01 -05001327
Andrew Geisslerfca6a4f2017-05-30 10:55:39 -05001328 resp->parm = static_cast<uint8_t>(BootOptionParameter::OPAL_NETWORK_SETTINGS);
Ratan Guptafd28dd72016-08-01 04:58:01 -05001329
Andrew Geisslerfca6a4f2017-05-30 10:55:39 -05001330 int ret = getHostNetworkData(resp);
Ratan Guptafd28dd72016-08-01 04:58:01 -05001331
Andrew Geisslerfca6a4f2017-05-30 10:55:39 -05001332 if (ret < 0) {
Ratan Guptafd28dd72016-08-01 04:58:01 -05001333
Andrew Geisslerfca6a4f2017-05-30 10:55:39 -05001334 fprintf(stderr, "getHostNetworkData failed for get_sys_boot_options.\n");
1335 rc = IPMI_CC_UNSPECIFIED_ERROR;
Ratan Guptafd28dd72016-08-01 04:58:01 -05001336
Andrew Geisslerfca6a4f2017-05-30 10:55:39 -05001337 }else
1338 rc = IPMI_CC_OK;
Ratan Guptafd28dd72016-08-01 04:58:01 -05001339 }
1340
1341 else {
Adriana Kobylak40814c62015-10-27 15:58:44 -05001342 fprintf(stderr, "Unsupported parameter 0x%x\n", reqptr->parameter);
shgoupfd84fbbf2015-12-17 10:05:51 +08001343 }
1344
1345 if (p)
1346 free(p);
1347
Ratan Guptafd28dd72016-08-01 04:58:01 -05001348 if (rc == IPMI_CC_OK)
1349 {
1350 *data_len += 2;
1351 }
1352
shgoupfd84fbbf2015-12-17 10:05:51 +08001353 return rc;
1354}
1355
1356
1357
1358ipmi_ret_t ipmi_chassis_set_sys_boot_options(ipmi_netfn_t netfn, ipmi_cmd_t cmd,
Andrew Geisslerfca6a4f2017-05-30 10:55:39 -05001359 ipmi_request_t request,
1360 ipmi_response_t response,
1361 ipmi_data_len_t data_len,
1362 ipmi_context_t context)
shgoupfd84fbbf2015-12-17 10:05:51 +08001363{
Deepak Kodihalli8cc19362017-07-21 11:18:38 -05001364 using namespace boot_options;
shgoupfd84fbbf2015-12-17 10:05:51 +08001365 ipmi_ret_t rc = IPMI_CC_OK;
shgoupfd84fbbf2015-12-17 10:05:51 +08001366 set_sys_boot_options_t *reqptr = (set_sys_boot_options_t *) request;
1367
Ratan Guptafd28dd72016-08-01 04:58:01 -05001368 printf("IPMI SET_SYS_BOOT_OPTIONS reqptr->parameter =[%d]\n",reqptr->parameter);
1369
shgoupfd84fbbf2015-12-17 10:05:51 +08001370 // This IPMI command does not have any resposne data
1371 *data_len = 0;
1372
1373 /* 000101
1374 * Parameter #5 means boot flags. Please refer to 28.13 of ipmi doc.
1375 * This is the only parameter used by petitboot.
1376 */
Ratan Guptafd28dd72016-08-01 04:58:01 -05001377
Deepak Kodihalli8cc19362017-07-21 11:18:38 -05001378 if (reqptr->parameter == (uint8_t)BootOptionParameter::BOOT_FLAGS)
1379 {
1380 IpmiValue bootOption = ((reqptr->data[1] & 0x3C) >> 2);
1381 using namespace chassis::internal;
1382 using namespace chassis::internal::cache;
shgoupfd84fbbf2015-12-17 10:05:51 +08001383
Deepak Kodihalli8cc19362017-07-21 11:18:38 -05001384 auto modeItr = modeIpmiToDbus.find(bootOption);
1385 auto sourceItr = sourceIpmiToDbus.find(bootOption);
1386 if ((ipmiDefault == bootOption) ||
1387 (sourceIpmiToDbus.end() != sourceItr))
1388 {
1389 sdbusplus::message::variant<std::string> property =
1390 convertForMessage(sourceItr->second);
1391 const auto& bootSourceSetting =
1392 objects.map.at(bootSourceIntf);
1393 auto method =
1394 dbus.new_method_call(
1395 objects.service(bootSourceSetting, bootSourceIntf).c_str(),
1396 bootSourceSetting.c_str(),
1397 PROP_INTF,
1398 "Set");
1399 method.append(bootSourceIntf, "BootSource", property);
1400 auto reply = dbus.call(method);
1401 if (reply.is_method_error())
1402 {
1403 log<level::ERR>("Error in BootSource Set");
1404 report<InternalFailure>();
1405 *data_len = 0;
1406 return IPMI_CC_UNSPECIFIED_ERROR;
1407 }
1408 }
1409 if ((ipmiDefault == bootOption) ||
1410 (modeIpmiToDbus.end() != modeItr))
1411 {
1412 sdbusplus::message::variant<std::string> property =
1413 convertForMessage(modeItr->second);
1414 const auto& bootModeSetting = objects.map.at(bootModeIntf);
1415 auto method =
1416 dbus.new_method_call(
1417 objects.service(bootModeSetting, bootModeIntf).c_str(),
1418 bootModeSetting.c_str(),
1419 PROP_INTF,
1420 "Set");
1421 method.append(bootModeIntf, "BootMode", property);
1422 auto reply = dbus.call(method);
1423 if (reply.is_method_error())
1424 {
1425 log<level::ERR>("Error in BootMode Set");
1426 report<InternalFailure>();
1427 *data_len = 0;
1428 return IPMI_CC_UNSPECIFIED_ERROR;
shgoupfd84fbbf2015-12-17 10:05:51 +08001429 }
1430 }
Ratan Guptafd28dd72016-08-01 04:58:01 -05001431
ratagupta6f6bff2016-04-04 06:20:11 -05001432 /* setting the boot policy */
Deepak Kodihalli8cc19362017-07-21 11:18:38 -05001433 std::string value =
1434 (char *)(((reqptr->data[0] & SET_PARM_BOOT_FLAGS_PERMANENT) ==
Andrew Geisslerfca6a4f2017-05-30 10:55:39 -05001435 SET_PARM_BOOT_FLAGS_PERMANENT) ?"PERMANENT":"ONETIME");
ratagupta6f6bff2016-04-04 06:20:11 -05001436
Deepak Kodihalli8cc19362017-07-21 11:18:38 -05001437 printf ( "\nBoot Policy is %s",value.c_str());
1438 int r = dbus_set_property("boot_policy",value.c_str());
ratagupta6f6bff2016-04-04 06:20:11 -05001439
1440 if (r < 0) {
1441 fprintf(stderr, "Dbus set property(boot_policy) failed for set_sys_boot_options.\n");
1442 rc = IPMI_CC_UNSPECIFIED_ERROR;
1443 }
shgoupfd84fbbf2015-12-17 10:05:51 +08001444
Andrew Geisslerfca6a4f2017-05-30 10:55:39 -05001445 } else if (reqptr->parameter ==
1446 (uint8_t)BootOptionParameter::OPAL_NETWORK_SETTINGS) {
Ratan Guptafd28dd72016-08-01 04:58:01 -05001447
1448 int ret = setHostNetworkData(reqptr);
1449 if (ret < 0) {
1450 fprintf(stderr, "setHostNetworkData failed for set_sys_boot_options.\n");
1451 rc = IPMI_CC_UNSPECIFIED_ERROR;
1452 }
1453 }
1454 else {
shgoupfd84fbbf2015-12-17 10:05:51 +08001455 fprintf(stderr, "Unsupported parameter 0x%x\n", reqptr->parameter);
1456 rc = IPMI_CC_PARM_NOT_SUPPORTED;
Adriana Kobylak40814c62015-10-27 15:58:44 -05001457 }
1458
1459 return rc;
1460}
1461
1462void register_netfn_chassis_functions()
1463{
Tom05732372016-09-06 17:21:23 +05301464 // <Wildcard Command>
Adriana Kobylak40814c62015-10-27 15:58:44 -05001465 printf("Registering NetFn:[0x%X], Cmd:[0x%X]\n",NETFUN_CHASSIS, IPMI_CMD_WILDCARD);
Tom05732372016-09-06 17:21:23 +05301466 ipmi_register_callback(NETFUN_CHASSIS, IPMI_CMD_WILDCARD, NULL, ipmi_chassis_wildcard,
1467 PRIVILEGE_USER);
Adriana Kobylak40814c62015-10-27 15:58:44 -05001468
Tom05732372016-09-06 17:21:23 +05301469 // Get Chassis Capabilities
Nan Li8d15fb42016-08-16 22:29:40 +08001470 printf("Registering NetFn:[0x%X], Cmd:[0x%X]\n",NETFUN_CHASSIS, IPMI_CMD_GET_CHASSIS_CAP);
Tom05732372016-09-06 17:21:23 +05301471 ipmi_register_callback(NETFUN_CHASSIS, IPMI_CMD_GET_CHASSIS_CAP, NULL, ipmi_get_chassis_cap,
1472 PRIVILEGE_USER);
Nan Li8d15fb42016-08-16 22:29:40 +08001473
Tom05732372016-09-06 17:21:23 +05301474 // <Get System Boot Options>
Adriana Kobylak40814c62015-10-27 15:58:44 -05001475 printf("Registering NetFn:[0x%X], Cmd:[0x%X]\n",NETFUN_CHASSIS, IPMI_CMD_GET_SYS_BOOT_OPTIONS);
Tom05732372016-09-06 17:21:23 +05301476 ipmi_register_callback(NETFUN_CHASSIS, IPMI_CMD_GET_SYS_BOOT_OPTIONS, NULL,
1477 ipmi_chassis_get_sys_boot_options, PRIVILEGE_OPERATOR);
Adriana Kobylak40814c62015-10-27 15:58:44 -05001478
Tom05732372016-09-06 17:21:23 +05301479 // <Get Chassis Status>
Nan Lifdd8ec52016-08-28 03:57:40 +08001480 printf("Registering NetFn:[0x%X], Cmd:[0x%X]\n",NETFUN_CHASSIS, IPMI_CMD_CHASSIS_STATUS);
Tom05732372016-09-06 17:21:23 +05301481 ipmi_register_callback(NETFUN_CHASSIS, IPMI_CMD_CHASSIS_STATUS, NULL, ipmi_get_chassis_status,
1482 PRIVILEGE_USER);
Nan Lifdd8ec52016-08-28 03:57:40 +08001483
Tom05732372016-09-06 17:21:23 +05301484 // <Chassis Control>
vishwa36993272015-11-20 12:43:49 -06001485 printf("Registering NetFn:[0x%X], Cmd:[0x%X]\n",NETFUN_CHASSIS, IPMI_CMD_CHASSIS_CONTROL);
Tom05732372016-09-06 17:21:23 +05301486 ipmi_register_callback(NETFUN_CHASSIS, IPMI_CMD_CHASSIS_CONTROL, NULL, ipmi_chassis_control,
1487 PRIVILEGE_OPERATOR);
shgoupfd84fbbf2015-12-17 10:05:51 +08001488
Tom05732372016-09-06 17:21:23 +05301489 // <Set System Boot Options>
shgoupfd84fbbf2015-12-17 10:05:51 +08001490 printf("Registering NetFn:[0x%X], Cmd:[0x%X]\n", NETFUN_CHASSIS, IPMI_CMD_SET_SYS_BOOT_OPTIONS);
Tom05732372016-09-06 17:21:23 +05301491 ipmi_register_callback(NETFUN_CHASSIS, IPMI_CMD_SET_SYS_BOOT_OPTIONS, NULL,
1492 ipmi_chassis_set_sys_boot_options, PRIVILEGE_OPERATOR);
vishwa36993272015-11-20 12:43:49 -06001493}