blob: 947c96c0df36e2af58816b1f6e30ef68f3d566a7 [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 Guptacc8feb42017-07-25 21:52:10 +05306#include "utils.hpp"
Ratan Guptadcb10672017-07-10 10:33:50 +05307
Adriana Kobylak40814c62015-10-27 15:58:44 -05008#include <stdio.h>
Ratan Guptafd28dd72016-08-01 04:58:01 -05009#include <stdlib.h>
Adriana Kobylak40814c62015-10-27 15:58:44 -050010#include <stdint.h>
Brad Bishop35518682016-07-22 08:35:41 -040011#include <mapper.h>
Ratan Guptafd28dd72016-08-01 04:58:01 -050012#include <arpa/inet.h>
13#include <netinet/in.h>
14#include <limits.h>
15#include <string.h>
16#include <endian.h>
17#include <sstream>
18#include <array>
Andrew Geisslera6e3a302017-05-31 19:34:00 -050019#include <fstream>
20#include <experimental/filesystem>
Ratan Guptadcb10672017-07-10 10:33:50 +053021#include <string>
Deepak Kodihalli8cc19362017-07-21 11:18:38 -050022#include <map>
Ratan Guptadcb10672017-07-10 10:33:50 +053023
Vishwanatha Subbannab12b0c02017-03-07 18:17:19 +053024#include <phosphor-logging/log.hpp>
Ratan Guptadcb10672017-07-10 10:33:50 +053025#include <phosphor-logging/elog-errors.hpp>
Vishwanatha Subbannab12b0c02017-03-07 18:17:19 +053026#include <xyz/openbmc_project/State/Host/server.hpp>
Ratan Guptadcb10672017-07-10 10:33:50 +053027#include "xyz/openbmc_project/Common/error.hpp"
28
29#include <sdbusplus/bus.hpp>
30#include <sdbusplus/server/object.hpp>
Deepak Kodihalli8cc19362017-07-21 11:18:38 -050031#include <xyz/openbmc_project/Control/Boot/Source/server.hpp>
32#include <xyz/openbmc_project/Control/Boot/Mode/server.hpp>
Deepak Kodihalli18b70d12017-07-21 13:36:33 -050033#include <xyz/openbmc_project/Control/Power/RestorePolicy/server.hpp>
Ratan Guptadcb10672017-07-10 10:33:50 +053034
Vishwanatha Subbannab891a572017-03-31 11:34:48 +053035#include "config.h"
ratagupta6f6bff2016-04-04 06:20:11 -050036
37//Defines
Ratan Guptafd28dd72016-08-01 04:58:01 -050038#define SET_PARM_VERSION 0x01
39#define SET_PARM_BOOT_FLAGS_PERMANENT 0x40 //boot flags data1 7th bit on
ratagupta6f6bff2016-04-04 06:20:11 -050040#define SET_PARM_BOOT_FLAGS_VALID_ONE_TIME 0x80 //boot flags data1 8th bit on
Ratan Guptafd28dd72016-08-01 04:58:01 -050041#define SET_PARM_BOOT_FLAGS_VALID_PERMANENT 0xC0 //boot flags data1 7 & 8 bit on
ratagupta6f6bff2016-04-04 06:20:11 -050042
Ratan Guptafd28dd72016-08-01 04:58:01 -050043constexpr size_t SIZE_MAC = 18;
44constexpr size_t SIZE_BOOT_OPTION = (uint8_t)BootOptionResponseSize::
Andrew Geisslerfca6a4f2017-05-30 10:55:39 -050045 OPAL_NETWORK_SETTINGS;//Maximum size of the boot option parametrs
Ratan Guptafd28dd72016-08-01 04:58:01 -050046constexpr size_t SIZE_PREFIX = 7;
47constexpr size_t MAX_PREFIX_VALUE = 32;
48constexpr size_t SIZE_COOKIE = 4;
49constexpr size_t SIZE_VERSION = 2;
Ratan Guptad70f4532017-08-04 02:07:31 +053050constexpr auto MAC_ADDRESS_FORMAT = "%02hhx:%02hhx:%02hhx:%02hhx:%02hhx:%02hhx";
51constexpr auto IP_ADDRESS_FORMAT = "%u.%u.%u.%u";
Matthew Barth8b470052016-09-21 10:02:57 -050052constexpr auto PREFIX_FORMAT = "%hhd";
Ratan Guptafd28dd72016-08-01 04:58:01 -050053constexpr auto ADDR_TYPE_FORMAT = "%hhx";
Ratan Gupta6ec7daa2017-07-15 14:13:01 +053054constexpr auto IPV4_ADDRESS_SIZE_BYTE = 4;
55constexpr auto IPV6_ADDRESS_SIZE_BYTE = 16;
Ratan Guptad70f4532017-08-04 02:07:31 +053056constexpr auto DEFAULT_MAC_ADDRESS = "00:00:00:00:00:00";
57constexpr auto DEFAULT_ADDRESS = "0.0.0.0";
Ratan Gupta6ec7daa2017-07-15 14:13:01 +053058
Ratan Guptafd28dd72016-08-01 04:58:01 -050059//PetiBoot-Specific
Ratan Gupta6ec7daa2017-07-15 14:13:01 +053060static constexpr uint8_t net_conf_initial_bytes[] = {0x80, 0x21, 0x70, 0x62,
61 0x21, 0x00, 0x01, 0x06};
Ratan Guptafd28dd72016-08-01 04:58:01 -050062
63static constexpr size_t COOKIE_OFFSET = 1;
64static constexpr size_t VERSION_OFFSET = 5;
Ratan Gupta6ec7daa2017-07-15 14:13:01 +053065static constexpr size_t ADDR_SIZE_OFFSET = 8;
Ratan Guptafd28dd72016-08-01 04:58:01 -050066static constexpr size_t MAC_OFFSET = 9;
67static constexpr size_t ADDRTYPE_OFFSET = 16;
68static constexpr size_t IPADDR_OFFSET = 17;
ratagupta6f6bff2016-04-04 06:20:11 -050069
shgoupfd84fbbf2015-12-17 10:05:51 +080070
Adriana Kobylak40814c62015-10-27 15:58:44 -050071void register_netfn_chassis_functions() __attribute__((constructor));
72
shgoupfd84fbbf2015-12-17 10:05:51 +080073// Host settings in dbus
74// Service name should be referenced by connection name got via object mapper
75const char *settings_object_name = "/org/openbmc/settings/host0";
76const char *settings_intf_name = "org.freedesktop.DBus.Properties";
77const char *host_intf_name = "org.openbmc.settings.Host";
78
Ratan Guptadcb10672017-07-10 10:33:50 +053079constexpr auto SETTINGS_ROOT = "/";
80constexpr auto SETTINGS_MATCH = "host0";
Ratan Guptadcb10672017-07-10 10:33:50 +053081
82constexpr auto IP_INTERFACE = "xyz.openbmc_project.Network.IP";
83constexpr auto MAC_INTERFACE = "xyz.openbmc_project.Network.MACAddress";
84
Ratan Guptadcb10672017-07-10 10:33:50 +053085
Nan Li8d15fb42016-08-16 22:29:40 +080086typedef struct
87{
88 uint8_t cap_flags;
89 uint8_t fru_info_dev_addr;
90 uint8_t sdr_dev_addr;
91 uint8_t sel_dev_addr;
92 uint8_t system_management_dev_addr;
93 uint8_t bridge_dev_addr;
94}__attribute__((packed)) ipmi_chassis_cap_t;
95
Nan Lifdd8ec52016-08-28 03:57:40 +080096typedef struct
97{
Andrew Geisslerfca6a4f2017-05-30 10:55:39 -050098 uint8_t cur_power_state;
99 uint8_t last_power_event;
100 uint8_t misc_power_state;
101 uint8_t front_panel_button_cap_status;
Nan Lifdd8ec52016-08-28 03:57:40 +0800102}__attribute__((packed)) ipmi_get_chassis_status_t;
103
Vishwanatha Subbannab12b0c02017-03-07 18:17:19 +0530104// Phosphor Host State manager
105namespace State = sdbusplus::xyz::openbmc_project::State::server;
106
Andrew Geisslera6e3a302017-05-31 19:34:00 -0500107namespace fs = std::experimental::filesystem;
108
Ratan Guptadcb10672017-07-10 10:33:50 +0530109using namespace phosphor::logging;
110using namespace sdbusplus::xyz::openbmc_project::Common::Error;
111
Deepak Kodihalli8cc19362017-07-21 11:18:38 -0500112namespace chassis
113{
114namespace internal
115{
116
117constexpr auto bootModeIntf = "xyz.openbmc_project.Control.Boot.Mode";
118constexpr auto bootSourceIntf = "xyz.openbmc_project.Control.Boot.Source";
Deepak Kodihalli18b70d12017-07-21 13:36:33 -0500119constexpr auto powerRestoreIntf =
120 "xyz.openbmc_project.Control.Power.RestorePolicy";
Deepak Kodihalli8cc19362017-07-21 11:18:38 -0500121sdbusplus::bus::bus dbus(ipmid_get_sd_bus_connection());
122
123namespace cache
124{
125
126settings::Objects objects(dbus,
Deepak Kodihalli18b70d12017-07-21 13:36:33 -0500127 {bootModeIntf, bootSourceIntf, powerRestoreIntf});
Deepak Kodihalli8cc19362017-07-21 11:18:38 -0500128
129} // namespace cache
130} // namespace internal
131} // namespace chassis
132
Ratan Guptadcb10672017-07-10 10:33:50 +0530133//TODO : Can remove the below function as we have
134// new functions which uses sdbusplus.
135//
136// openbmc/openbmc#1489
ratagupta6f6bff2016-04-04 06:20:11 -0500137int dbus_get_property(const char *name, char **buf)
shgoupfd84fbbf2015-12-17 10:05:51 +0800138{
139 sd_bus_error error = SD_BUS_ERROR_NULL;
140 sd_bus_message *m = NULL;
141 sd_bus *bus = NULL;
142 char *temp_buf = NULL;
143 char *connection = NULL;
144 int r;
145
Brad Bishop35518682016-07-22 08:35:41 -0400146 // Get the system bus where most system services are provided.
147 bus = ipmid_get_sd_bus_connection();
shgoupfd84fbbf2015-12-17 10:05:51 +0800148
Brad Bishop35518682016-07-22 08:35:41 -0400149 r = mapper_get_service(bus, settings_object_name, &connection);
shgoupfd84fbbf2015-12-17 10:05:51 +0800150 if (r < 0) {
Brad Bishop819ddd42016-10-05 21:19:19 -0400151 fprintf(stderr, "Failed to get %s connection: %s\n",
152 settings_object_name, strerror(-r));
shgoupfd84fbbf2015-12-17 10:05:51 +0800153 goto finish;
154 }
155
shgoupfd84fbbf2015-12-17 10:05:51 +0800156 /*
157 * Bus, service, object path, interface and method are provided to call
158 * the method.
159 * Signatures and input arguments are provided by the arguments at the
160 * end.
161 */
162 r = sd_bus_call_method(bus,
163 connection, /* service to contact */
164 settings_object_name, /* object path */
165 settings_intf_name, /* interface name */
166 "Get", /* method name */
167 &error, /* object to return error in */
168 &m, /* return message on success */
169 "ss", /* input signature */
170 host_intf_name, /* first argument */
ratagupta6f6bff2016-04-04 06:20:11 -0500171 name); /* second argument */
shgoupfd84fbbf2015-12-17 10:05:51 +0800172
173 if (r < 0) {
174 fprintf(stderr, "Failed to issue method call: %s\n", error.message);
175 goto finish;
176 }
177
178 /*
179 * The output should be parsed exactly the same as the output formatting
180 * specified.
181 */
182 r = sd_bus_message_read(m, "v", "s", &temp_buf);
183 if (r < 0) {
184 fprintf(stderr, "Failed to parse response message: %s\n", strerror(-r));
185 goto finish;
186 }
187
Matthew Barth56181052017-01-23 09:36:29 -0600188 *buf = strdup(temp_buf);
Andrew Geisslerfca6a4f2017-05-30 10:55:39 -0500189 /* *buf = (char*) malloc(strlen(temp_buf));
shgoupfd84fbbf2015-12-17 10:05:51 +0800190 if (*buf) {
191 strcpy(*buf, temp_buf);
192 }
Andrew Geisslerfca6a4f2017-05-30 10:55:39 -0500193 */
shgoupfd84fbbf2015-12-17 10:05:51 +0800194 printf("IPMID boot option property get: {%s}.\n", (char *) temp_buf);
195
196finish:
197 sd_bus_error_free(&error);
198 sd_bus_message_unref(m);
199 free(connection);
200
201 return r;
202}
203
Ratan Guptadcb10672017-07-10 10:33:50 +0530204//TODO : Can remove the below function as we have
205// new functions which uses sdbusplus.
206//
207// openbmc/openbmc#1489
208
ratagupta6f6bff2016-04-04 06:20:11 -0500209int dbus_set_property(const char * name, const char *value)
shgoupfd84fbbf2015-12-17 10:05:51 +0800210{
211 sd_bus_error error = SD_BUS_ERROR_NULL;
212 sd_bus_message *m = NULL;
213 sd_bus *bus = NULL;
214 char *connection = NULL;
215 int r;
216
Brad Bishop35518682016-07-22 08:35:41 -0400217 // Get the system bus where most system services are provided.
218 bus = ipmid_get_sd_bus_connection();
shgoupfd84fbbf2015-12-17 10:05:51 +0800219
Brad Bishop35518682016-07-22 08:35:41 -0400220 r = mapper_get_service(bus, settings_object_name, &connection);
shgoupfd84fbbf2015-12-17 10:05:51 +0800221 if (r < 0) {
Brad Bishop819ddd42016-10-05 21:19:19 -0400222 fprintf(stderr, "Failed to get %s connection: %s\n",
223 settings_object_name, strerror(-r));
shgoupfd84fbbf2015-12-17 10:05:51 +0800224 goto finish;
225 }
226
shgoupfd84fbbf2015-12-17 10:05:51 +0800227 /*
228 * Bus, service, object path, interface and method are provided to call
229 * the method.
230 * Signatures and input arguments are provided by the arguments at the
231 * end.
232 */
233 r = sd_bus_call_method(bus,
234 connection, /* service to contact */
235 settings_object_name, /* object path */
236 settings_intf_name, /* interface name */
237 "Set", /* method name */
238 &error, /* object to return error in */
239 &m, /* return message on success */
240 "ssv", /* input signature */
241 host_intf_name, /* first argument */
ratagupta6f6bff2016-04-04 06:20:11 -0500242 name, /* second argument */
shgoupfd84fbbf2015-12-17 10:05:51 +0800243 "s", /* third argument */
ratagupta6f6bff2016-04-04 06:20:11 -0500244 value); /* fourth argument */
shgoupfd84fbbf2015-12-17 10:05:51 +0800245
246 if (r < 0) {
247 fprintf(stderr, "Failed to issue method call: %s\n", error.message);
248 goto finish;
249 }
250
ratagupta6f6bff2016-04-04 06:20:11 -0500251 printf("IPMID boot option property set: {%s}.\n", value);
shgoupfd84fbbf2015-12-17 10:05:51 +0800252
Andrew Geisslerfca6a4f2017-05-30 10:55:39 -0500253 finish:
shgoupfd84fbbf2015-12-17 10:05:51 +0800254 sd_bus_error_free(&error);
255 sd_bus_message_unref(m);
256 free(connection);
257
258 return r;
259}
260
Adriana Kobylak40814c62015-10-27 15:58:44 -0500261struct get_sys_boot_options_t {
262 uint8_t parameter;
263 uint8_t set;
264 uint8_t block;
265} __attribute__ ((packed));
266
shgoupfd84fbbf2015-12-17 10:05:51 +0800267struct get_sys_boot_options_response_t {
268 uint8_t version;
269 uint8_t parm;
Ratan Guptafd28dd72016-08-01 04:58:01 -0500270 uint8_t data[SIZE_BOOT_OPTION];
shgoupfd84fbbf2015-12-17 10:05:51 +0800271} __attribute__ ((packed));
272
273struct set_sys_boot_options_t {
274 uint8_t parameter;
Ratan Guptafd28dd72016-08-01 04:58:01 -0500275 uint8_t data[SIZE_BOOT_OPTION];
shgoupfd84fbbf2015-12-17 10:05:51 +0800276} __attribute__ ((packed));
277
Ratan Guptafd28dd72016-08-01 04:58:01 -0500278
Ratan Guptadcb10672017-07-10 10:33:50 +0530279int getHostNetworkData(get_sys_boot_options_response_t* respptr)
Ratan Guptafd28dd72016-08-01 04:58:01 -0500280{
Ratan Guptadcb10672017-07-10 10:33:50 +0530281 ipmi::PropertyMap properties;
282 int rc = 0;
Ratan Gupta6ec7daa2017-07-15 14:13:01 +0530283 uint8_t addrSize = IPV4_ADDRESS_SIZE_BYTE;
Ratan Guptafd28dd72016-08-01 04:58:01 -0500284
Ratan Guptadcb10672017-07-10 10:33:50 +0530285 try
286 {
287 //TODO There may be cases where an interface is implemented by multiple
288 // objects,to handle such cases we are interested on that object
289 // which are on interested busname.
290 // Currenlty mapper doesn't give the readable busname(gives busid)
291 // so we can't match with bus name so giving some object specific info
292 // as SETTINGS_MATCH.
293 // Later SETTINGS_MATCH will be replaced with busname.
Ratan Guptafd28dd72016-08-01 04:58:01 -0500294
Ratan Gupta01d4bd12017-08-07 15:53:25 +0530295 sdbusplus::bus::bus bus(ipmid_get_sd_bus_connection());
Ratan Guptadcb10672017-07-10 10:33:50 +0530296
Ratan Gupta01d4bd12017-08-07 15:53:25 +0530297 auto ipObjectInfo = ipmi::getDbusObject(bus, IP_INTERFACE,
298 SETTINGS_ROOT, SETTINGS_MATCH);
299
300 auto macObjectInfo = ipmi::getDbusObject(bus, MAC_INTERFACE,
301 SETTINGS_ROOT, SETTINGS_MATCH);
302
303 properties = ipmi::getAllDbusProperties(bus, ipObjectInfo.second,
304 ipObjectInfo.first, IP_INTERFACE);
Ratan Guptacc8feb42017-07-25 21:52:10 +0530305 auto variant =
Ratan Gupta01d4bd12017-08-07 15:53:25 +0530306 ipmi::getDbusProperty(bus, macObjectInfo.second,
307 macObjectInfo.first,
Ratan Guptacc8feb42017-07-25 21:52:10 +0530308 MAC_INTERFACE, "MACAddress");
Ratan Guptadcb10672017-07-10 10:33:50 +0530309
Ratan Gupta01d4bd12017-08-07 15:53:25 +0530310 auto ipAddress = properties["Address"].get<std::string>();
Ratan Guptad70f4532017-08-04 02:07:31 +0530311
312 auto gateway = properties["Gateway"].get<std::string>();
313
314 auto prefix = properties["PrefixLength"].get<uint8_t>();
315
316 uint8_t isStatic = (properties["Origin"].get<std::string>() ==
317 "xyz.openbmc_project.Network.IP.AddressOrigin.Static")
318 ? 1 : 0;
319
Ratan Guptacc8feb42017-07-25 21:52:10 +0530320 auto MACAddress = variant.get<std::string>();
321
Ratan Guptad70f4532017-08-04 02:07:31 +0530322 // it is expected here that we should get the valid data
323 // but we may also get the default values.
324 // Validation of the data is done by settings.
325 //
326 // if mac address is default mac address then
327 // don't send blank override.
328 if ((MACAddress == DEFAULT_MAC_ADDRESS))
329 {
330 memset(respptr->data, 0, SIZE_BOOT_OPTION);
331 rc = -1;
332 return rc;
333 }
334 // if addr is static then ipaddress,gateway,prefix
335 // should not be default one,don't send blank override.
336 if (isStatic)
337 {
338 if((ipAddress == DEFAULT_ADDRESS) ||
339 (gateway == DEFAULT_ADDRESS) ||
340 (!prefix))
341 {
342 memset(respptr->data, 0, SIZE_BOOT_OPTION);
343 rc = -1;
344 return rc;
345 }
346 }
347
Ratan Guptadcb10672017-07-10 10:33:50 +0530348 sscanf(MACAddress.c_str(), MAC_ADDRESS_FORMAT,
349 (respptr->data + MAC_OFFSET),
350 (respptr->data + MAC_OFFSET + 1),
351 (respptr->data + MAC_OFFSET + 2),
352 (respptr->data + MAC_OFFSET + 3),
353 (respptr->data + MAC_OFFSET + 4),
354 (respptr->data + MAC_OFFSET + 5));
355
Ratan Guptadcb10672017-07-10 10:33:50 +0530356 respptr->data[MAC_OFFSET + 6] = 0x00;
357
Ratan Guptad70f4532017-08-04 02:07:31 +0530358 memcpy(respptr->data + ADDRTYPE_OFFSET, &isStatic,
359 sizeof(isStatic));
Ratan Gupta6ec7daa2017-07-15 14:13:01 +0530360
361 uint8_t addressFamily = (properties["Type"].get<std::string>() ==
362 "xyz.openbmc_project.Network.IP.Protocol.IPv4") ?
363 AF_INET : AF_INET6;
364
365 addrSize = (addressFamily == AF_INET) ? IPV4_ADDRESS_SIZE_BYTE :
366 IPV6_ADDRESS_SIZE_BYTE;
Ratan Guptadcb10672017-07-10 10:33:50 +0530367
368 // ipaddress and gateway would be in IPv4 format
Ratan Guptad70f4532017-08-04 02:07:31 +0530369 inet_pton(addressFamily, ipAddress.c_str(),
370 (respptr->data + IPADDR_OFFSET));
Ratan Guptadcb10672017-07-10 10:33:50 +0530371
Ratan Gupta6ec7daa2017-07-15 14:13:01 +0530372 uint8_t prefixOffset = IPADDR_OFFSET + addrSize;
373
374 memcpy(respptr->data + prefixOffset, &prefix, sizeof(prefix));
375
376 uint8_t gatewayOffset = prefixOffset + sizeof(decltype(prefix));
377
Ratan Guptad70f4532017-08-04 02:07:31 +0530378 inet_pton(addressFamily, gateway.c_str(),
379 (respptr->data + gatewayOffset));
Ratan Guptadcb10672017-07-10 10:33:50 +0530380
381 }
382 catch (InternalFailure& e)
383 {
384 commit<InternalFailure>();
385 memset(respptr->data, 0, SIZE_BOOT_OPTION);
386 rc = -1;
Ratan Guptafd28dd72016-08-01 04:58:01 -0500387 return rc;
388 }
389
Ratan Guptadcb10672017-07-10 10:33:50 +0530390 //PetiBoot-Specific
391 //If sucess then copy the first 9 bytes to the data
Ratan Guptadcb10672017-07-10 10:33:50 +0530392 memcpy(respptr->data, net_conf_initial_bytes,
393 sizeof(net_conf_initial_bytes));
Ratan Guptafd28dd72016-08-01 04:58:01 -0500394
Ratan Gupta6ec7daa2017-07-15 14:13:01 +0530395 memcpy(respptr->data + ADDR_SIZE_OFFSET, &addrSize, sizeof(addrSize));
396
Ratan Guptafd28dd72016-08-01 04:58:01 -0500397#ifdef _IPMI_DEBUG_
Ratan Guptadcb10672017-07-10 10:33:50 +0530398 printf("\n===Printing the IPMI Formatted Data========\n");
Ratan Guptafd28dd72016-08-01 04:58:01 -0500399
Ratan Guptadcb10672017-07-10 10:33:50 +0530400 for (uint8_t pos = 0; pos < index; pos++)
401 {
402 printf("%02x ", respptr->data[pos]);
403 }
Ratan Guptafd28dd72016-08-01 04:58:01 -0500404#endif
405
Ratan Guptafd28dd72016-08-01 04:58:01 -0500406 return rc;
407}
408
Ratan Gupta6ec7daa2017-07-15 14:13:01 +0530409/** @brief convert IPv4 and IPv6 addresses from binary to text form.
410 * @param[in] family - IPv4/Ipv6
411 * @param[in] data - req data pointer.
412 * @param[in] offset - offset in the data.
413 * @param[in] addrSize - size of the data which needs to be read from offset.
414 * @returns address in text form.
415 */
416
417std::string getAddrStr(uint8_t family, uint8_t* data,
418 uint8_t offset, uint8_t addrSize)
419{
420 char ipAddr[INET6_ADDRSTRLEN] = {};
421
422 switch(family)
423 {
424 case AF_INET:
425 {
426 struct sockaddr_in addr4 {};
427 memcpy(&addr4.sin_addr.s_addr, &data[offset], addrSize);
428
429 inet_ntop(AF_INET, &addr4.sin_addr,
430 ipAddr, INET_ADDRSTRLEN);
431
432 break;
433 }
434 case AF_INET6:
435 {
436 struct sockaddr_in6 addr6 {};
437 memcpy(&addr6.sin6_addr.s6_addr, &data[offset], addrSize);
438
439 inet_ntop(AF_INET6, &addr6.sin6_addr,
440 ipAddr, INET6_ADDRSTRLEN);
441
442 break;
443 }
444 default:
445 {
446 return {};
447 }
448 }
449
450 return ipAddr;
451}
452
Ratan Guptadcb10672017-07-10 10:33:50 +0530453int setHostNetworkData(set_sys_boot_options_t* reqptr)
Ratan Guptafd28dd72016-08-01 04:58:01 -0500454{
Ratan Guptadcb10672017-07-10 10:33:50 +0530455 using namespace std::string_literals;
Ratan Guptafd28dd72016-08-01 04:58:01 -0500456 std::string host_network_config;
Ratan Guptad70f4532017-08-04 02:07:31 +0530457 char mac[] {"00:00:00:00:00:00"};
Ratan Gupta6ec7daa2017-07-15 14:13:01 +0530458 std::string ipAddress, gateway;
459 char addrOrigin {0};
460 uint8_t addrSize {0};
Ratan Guptadcb10672017-07-10 10:33:50 +0530461 std::string addressOrigin =
Ratan Gupta6ec7daa2017-07-15 14:13:01 +0530462 "xyz.openbmc_project.Network.IP.AddressOrigin.DHCP";
463 std::string addressType =
464 "xyz.openbmc_project.Network.IP.Protocol.IPv4";
Ratan Guptadcb10672017-07-10 10:33:50 +0530465 uint8_t prefix {0};
466 uint32_t zeroCookie = 0;
Ratan Gupta6ec7daa2017-07-15 14:13:01 +0530467 uint8_t family = AF_INET;
Ratan Guptafd28dd72016-08-01 04:58:01 -0500468
469 //cookie starts from second byte
470 // version starts from sixth byte
471
Ratan Guptadcb10672017-07-10 10:33:50 +0530472 try
Ratan Guptafd28dd72016-08-01 04:58:01 -0500473 {
Ratan Guptadcb10672017-07-10 10:33:50 +0530474 do
475 {
476 // cookie == 0x21 0x70 0x62 0x21
477 if (memcmp(&(reqptr->data[COOKIE_OFFSET]),
478 (net_conf_initial_bytes + COOKIE_OFFSET),
479 SIZE_COOKIE) != 0)
480 {
481 //cookie == 0
482 if (memcmp(&(reqptr->data[COOKIE_OFFSET]),
483 &zeroCookie,
484 SIZE_COOKIE) == 0)
485 {
486 // need to zero out the network settings.
487 break;
488 }
489
490 log<level::ERR>("Invalid Cookie");
491 elog<InternalFailure>();
492 }
493
494 // vesion == 0x00 0x01
495 if (memcmp(&(reqptr->data[VERSION_OFFSET]),
496 (net_conf_initial_bytes + VERSION_OFFSET),
497 SIZE_VERSION) != 0)
498 {
499
500 log<level::ERR>("Invalid Version");
501 elog<InternalFailure>();
502 }
503
504 snprintf(mac, SIZE_MAC, MAC_ADDRESS_FORMAT,
505 reqptr->data[MAC_OFFSET],
506 reqptr->data[MAC_OFFSET + 1],
507 reqptr->data[MAC_OFFSET + 2],
508 reqptr->data[MAC_OFFSET + 3],
509 reqptr->data[MAC_OFFSET + 4],
510 reqptr->data[MAC_OFFSET + 5]);
511
Ratan Gupta6ec7daa2017-07-15 14:13:01 +0530512 memcpy(&addrOrigin, &(reqptr->data[ADDRTYPE_OFFSET]),
513 sizeof(decltype(addrOrigin)));
Ratan Guptadcb10672017-07-10 10:33:50 +0530514
Ratan Gupta6ec7daa2017-07-15 14:13:01 +0530515 if (addrOrigin)
Ratan Guptadcb10672017-07-10 10:33:50 +0530516 {
517 addressOrigin =
Ratan Gupta6ec7daa2017-07-15 14:13:01 +0530518 "xyz.openbmc_project.Network.IP.AddressOrigin.Static";
Ratan Guptadcb10672017-07-10 10:33:50 +0530519 }
520
Ratan Gupta6ec7daa2017-07-15 14:13:01 +0530521 // Get the address size
522 memcpy(&addrSize ,&reqptr->data[ADDR_SIZE_OFFSET], sizeof(addrSize));
Ratan Guptadcb10672017-07-10 10:33:50 +0530523
Ratan Gupta6ec7daa2017-07-15 14:13:01 +0530524 uint8_t prefixOffset = IPADDR_OFFSET + addrSize;
Ratan Guptadcb10672017-07-10 10:33:50 +0530525
Ratan Guptad70f4532017-08-04 02:07:31 +0530526 memcpy(&prefix, &(reqptr->data[prefixOffset]),
527 sizeof(decltype(prefix)));
Ratan Guptadcb10672017-07-10 10:33:50 +0530528
Ratan Gupta6ec7daa2017-07-15 14:13:01 +0530529 uint8_t gatewayOffset = prefixOffset + sizeof(decltype(prefix));
530
531 if (addrSize != IPV4_ADDRESS_SIZE_BYTE)
532 {
533 addressType = "xyz.openbmc_project.Network.IP.Protocol.IPv6";
534 family = AF_INET6;
535 }
536
537 ipAddress = getAddrStr(family, reqptr->data, IPADDR_OFFSET, addrSize);
Ratan Guptad70f4532017-08-04 02:07:31 +0530538
Ratan Gupta6ec7daa2017-07-15 14:13:01 +0530539 gateway = getAddrStr(family, reqptr->data, gatewayOffset, addrSize);
540
Ratan Guptadcb10672017-07-10 10:33:50 +0530541 } while(0);
542
Ratan Guptafd28dd72016-08-01 04:58:01 -0500543 //Cookie == 0 or it is a valid cookie
Ratan Guptadcb10672017-07-10 10:33:50 +0530544 host_network_config += "ipaddress="s + ipAddress +
545 ",prefix="s + std::to_string(prefix) + ",gateway="s + gateway +
546 ",mac="s + mac + ",addressOrigin="s + addressOrigin;
Ratan Guptafd28dd72016-08-01 04:58:01 -0500547
Ratan Guptafd28dd72016-08-01 04:58:01 -0500548
Ratan Gupta01d4bd12017-08-07 15:53:25 +0530549 sdbusplus::bus::bus bus(ipmid_get_sd_bus_connection());
550
551 auto ipObjectInfo = ipmi::getDbusObject(bus, IP_INTERFACE,
552 SETTINGS_ROOT, SETTINGS_MATCH);
553 auto macObjectInfo = ipmi::getDbusObject(bus, MAC_INTERFACE,
554 SETTINGS_ROOT, SETTINGS_MATCH);
Ratan Guptadcb10672017-07-10 10:33:50 +0530555 // set the dbus property
Ratan Gupta01d4bd12017-08-07 15:53:25 +0530556 ipmi::setDbusProperty(bus, ipObjectInfo.second, ipObjectInfo.first,
Ratan Guptadcb10672017-07-10 10:33:50 +0530557 IP_INTERFACE, "Address", std::string(ipAddress));
Ratan Gupta01d4bd12017-08-07 15:53:25 +0530558 ipmi::setDbusProperty(bus, ipObjectInfo.second, ipObjectInfo.first,
Ratan Guptadcb10672017-07-10 10:33:50 +0530559 IP_INTERFACE, "PrefixLength", prefix);
Ratan Gupta01d4bd12017-08-07 15:53:25 +0530560 ipmi::setDbusProperty(bus, ipObjectInfo.second, ipObjectInfo.first,
Ratan Guptadcb10672017-07-10 10:33:50 +0530561 IP_INTERFACE, "Origin", addressOrigin);
Ratan Gupta01d4bd12017-08-07 15:53:25 +0530562 ipmi::setDbusProperty(bus, ipObjectInfo.second, ipObjectInfo.first,
Ratan Guptadcb10672017-07-10 10:33:50 +0530563 IP_INTERFACE, "Gateway", std::string(gateway));
Ratan Gupta01d4bd12017-08-07 15:53:25 +0530564 ipmi::setDbusProperty(bus, ipObjectInfo.second, ipObjectInfo.first,
Ratan Guptadcb10672017-07-10 10:33:50 +0530565 IP_INTERFACE, "Type",
566 std::string("xyz.openbmc_project.Network.IP.Protocol.IPv4"));
Ratan Gupta01d4bd12017-08-07 15:53:25 +0530567 ipmi::setDbusProperty(bus, macObjectInfo.second, macObjectInfo.first,
Ratan Guptadcb10672017-07-10 10:33:50 +0530568 MAC_INTERFACE,"MACAddress", std::string(mac));
Ratan Guptafd28dd72016-08-01 04:58:01 -0500569
Ratan Guptad70f4532017-08-04 02:07:31 +0530570 log<level::DEBUG>("Network configuration changed",
571 entry("NETWORKCONFIG=%s", host_network_config.c_str()));
572
Ratan Guptafd28dd72016-08-01 04:58:01 -0500573 }
Ratan Guptadcb10672017-07-10 10:33:50 +0530574 catch (InternalFailure& e)
575 {
576 commit<InternalFailure>();
577 return -1;
578 }
579
580 return 0;
Ratan Guptafd28dd72016-08-01 04:58:01 -0500581}
582
Andrew Geisslerfca6a4f2017-05-30 10:55:39 -0500583ipmi_ret_t ipmi_chassis_wildcard(ipmi_netfn_t netfn, ipmi_cmd_t cmd,
584 ipmi_request_t request,
585 ipmi_response_t response,
586 ipmi_data_len_t data_len,
587 ipmi_context_t context)
Adriana Kobylak40814c62015-10-27 15:58:44 -0500588{
589 printf("Handling CHASSIS WILDCARD Netfn:[0x%X], Cmd:[0x%X]\n",netfn, cmd);
590 // Status code.
Nan Li70aa8d92016-08-29 00:11:10 +0800591 ipmi_ret_t rc = IPMI_CC_INVALID;
Adriana Kobylak40814c62015-10-27 15:58:44 -0500592 *data_len = 0;
593 return rc;
594}
595
Nan Li8d15fb42016-08-16 22:29:40 +0800596ipmi_ret_t ipmi_get_chassis_cap(ipmi_netfn_t netfn, ipmi_cmd_t cmd,
Andrew Geisslerfca6a4f2017-05-30 10:55:39 -0500597 ipmi_request_t request, ipmi_response_t response,
598 ipmi_data_len_t data_len, ipmi_context_t context)
Nan Li8d15fb42016-08-16 22:29:40 +0800599{
600 // sd_bus error
601 ipmi_ret_t rc = IPMI_CC_OK;
602
603 ipmi_chassis_cap_t chassis_cap{};
604
605 *data_len = sizeof(ipmi_chassis_cap_t);
606
607 // TODO: need future work. Get those flag from MRW.
608
609 // capabilities flags
610 // [7..4] - reserved
611 // [3] – 1b = provides power interlock (IPM 1.5)
612 // [2] – 1b = provides Diagnostic Interrupt (FP NMI)
613 // [1] – 1b = provides “Front Panel Lockout” (indicates that the chassis has capabilities
614 // to lock out external power control and reset button or front panel interfaces
615 // and/or detect tampering with those interfaces).
616 // [0] -1b = Chassis provides intrusion (physical security) sensor.
617 // set to default value 0x0.
618 chassis_cap.cap_flags = 0x0;
619
620 // Since we do not have a separate SDR Device/SEL Device/ FRU repository.
621 // The 20h was given as those 5 device addresses.
622 // Chassis FRU info Device Address
623 chassis_cap.fru_info_dev_addr = 0x20;
624
625 // Chassis SDR Device Address
626 chassis_cap.sdr_dev_addr = 0x20;
627
628 // Chassis SEL Device Address
629 chassis_cap.sel_dev_addr = 0x20;
630
631 // Chassis System Management Device Address
632 chassis_cap.system_management_dev_addr = 0x20;
633
634 // Chassis Bridge Device Address.
635 chassis_cap.bridge_dev_addr = 0x20;
636
637 memcpy(response, &chassis_cap, *data_len);
638
639 return rc;
640}
641
Vishwanatha Subbannab12b0c02017-03-07 18:17:19 +0530642//------------------------------------------
643// Calls into Host State Manager Dbus object
644//------------------------------------------
645int initiate_state_transition(State::Host::Transition transition)
vishwa36993272015-11-20 12:43:49 -0600646{
Andrew Geisslerfca6a4f2017-05-30 10:55:39 -0500647 // OpenBMC Host State Manager dbus framework
648 constexpr auto HOST_STATE_MANAGER_ROOT = "/xyz/openbmc_project/state/host0";
649 constexpr auto HOST_STATE_MANAGER_IFACE = "xyz.openbmc_project.State.Host";
650 constexpr auto DBUS_PROPERTY_IFACE = "org.freedesktop.DBus.Properties";
651 constexpr auto PROPERTY = "RequestedHostTransition";
Vishwanatha Subbannab12b0c02017-03-07 18:17:19 +0530652
Andrew Geisslerfca6a4f2017-05-30 10:55:39 -0500653 // sd_bus error
654 int rc = 0;
655 char *busname = NULL;
vishwa36993272015-11-20 12:43:49 -0600656
Andrew Geisslerfca6a4f2017-05-30 10:55:39 -0500657 // SD Bus error report mechanism.
658 sd_bus_error bus_error = SD_BUS_ERROR_NULL;
vishwa36993272015-11-20 12:43:49 -0600659
Andrew Geisslerfca6a4f2017-05-30 10:55:39 -0500660 // Gets a hook onto either a SYSTEM or SESSION bus
661 sd_bus *bus_type = ipmid_get_sd_bus_connection();
662 rc = mapper_get_service(bus_type, HOST_STATE_MANAGER_ROOT, &busname);
663 if (rc < 0)
664 {
665 log<level::ERR>("Failed to get bus name",
666 entry("ERROR=%s, OBJPATH=%s",
667 strerror(-rc), HOST_STATE_MANAGER_ROOT));
668 return rc;
669 }
Vishwanatha Subbannab12b0c02017-03-07 18:17:19 +0530670
Andrew Geisslerfca6a4f2017-05-30 10:55:39 -0500671 // Convert to string equivalent of the passed in transition enum.
672 auto request = State::convertForMessage(transition);
Vishwanatha Subbannab12b0c02017-03-07 18:17:19 +0530673
Andrew Geisslerfca6a4f2017-05-30 10:55:39 -0500674 rc = sd_bus_call_method(bus_type, // On the system bus
675 busname, // Service to contact
676 HOST_STATE_MANAGER_ROOT, // Object path
677 DBUS_PROPERTY_IFACE, // Interface name
678 "Set", // Method to be called
679 &bus_error, // object to return error
680 nullptr, // Response buffer if any
681 "ssv", // Takes 3 arguments
682 HOST_STATE_MANAGER_IFACE,
683 PROPERTY,
684 "s", request.c_str());
685 if(rc < 0)
686 {
687 log<level::ERR>("Failed to initiate transition",
688 entry("ERROR=%s, REQUEST=%s",
689 bus_error.message, request.c_str()));
690 }
691 else
692 {
693 log<level::INFO>("Transition request initiated successfully");
694 }
vishwa36993272015-11-20 12:43:49 -0600695
696 sd_bus_error_free(&bus_error);
Sergey Solomineb9b8142016-08-23 09:07:28 -0500697 free(busname);
vishwa36993272015-11-20 12:43:49 -0600698
Sergey Solomineb9b8142016-08-23 09:07:28 -0500699 return rc;
vishwa36993272015-11-20 12:43:49 -0600700}
701
Deepak Kodihalli18b70d12017-07-21 13:36:33 -0500702namespace power_policy
Andrew Geisslerfca6a4f2017-05-30 10:55:39 -0500703{
Nan Lifdd8ec52016-08-28 03:57:40 +0800704
Deepak Kodihalli18b70d12017-07-21 13:36:33 -0500705using namespace sdbusplus::xyz::openbmc_project::Control::Power::server;
706using IpmiValue = uint8_t;
707using DbusValue = RestorePolicy::Policy;
Nan Lifdd8ec52016-08-28 03:57:40 +0800708
Deepak Kodihalli18b70d12017-07-21 13:36:33 -0500709std::map<DbusValue, IpmiValue> dbusToIpmi =
710{
711 {RestorePolicy::Policy::AlwaysOff, 0x00},
712 {RestorePolicy::Policy::Restore, 0x01},
713 {RestorePolicy::Policy::AlwaysOn, 0x02}
714};
Nan Lifdd8ec52016-08-28 03:57:40 +0800715
Deepak Kodihalli18b70d12017-07-21 13:36:33 -0500716} // namespace power_policy
Nan Lifdd8ec52016-08-28 03:57:40 +0800717
718//----------------------------------------------------------------------
719// Get Chassis Status commands
720//----------------------------------------------------------------------
721ipmi_ret_t ipmi_get_chassis_status(ipmi_netfn_t netfn, ipmi_cmd_t cmd,
Andrew Geisslerfca6a4f2017-05-30 10:55:39 -0500722 ipmi_request_t request,
723 ipmi_response_t response,
724 ipmi_data_len_t data_len,
725 ipmi_context_t context)
Nan Lifdd8ec52016-08-28 03:57:40 +0800726{
727 const char *objname = "/org/openbmc/control/power0";
728 const char *intf = "org.openbmc.control.Power";
729
730 sd_bus *bus = NULL;
731 sd_bus_message *reply = NULL;
732 int r = 0;
733 int pgood = 0;
734 char *busname = NULL;
735 ipmi_ret_t rc = IPMI_CC_OK;
736 ipmi_get_chassis_status_t chassis_status{};
737
Nan Lifdd8ec52016-08-28 03:57:40 +0800738 uint8_t s = 0;
739
Deepak Kodihalli18b70d12017-07-21 13:36:33 -0500740 using namespace chassis::internal;
741 using namespace chassis::internal::cache;
742 using namespace power_policy;
743
744 const auto& powerRestoreSetting = objects.map.at(powerRestoreIntf);
745 auto method =
746 dbus.new_method_call(
747 objects.service(powerRestoreSetting, powerRestoreIntf).c_str(),
748 powerRestoreSetting.c_str(),
Ratan Guptacc8feb42017-07-25 21:52:10 +0530749 ipmi::PROP_INTF,
Deepak Kodihalli18b70d12017-07-21 13:36:33 -0500750 "Get");
751 method.append(powerRestoreIntf, "PowerRestorePolicy");
752 auto resp = dbus.call(method);
753 if (resp.is_method_error())
754 {
755 log<level::ERR>("Error in PowerRestorePolicy Get");
756 report<InternalFailure>();
757 *data_len = 0;
758 return IPMI_CC_UNSPECIFIED_ERROR;
759 }
760 sdbusplus::message::variant<std::string> result;
761 resp.read(result);
762 auto powerRestore =
763 RestorePolicy::convertPolicyFromString(result.get<std::string>());
Nan Lifdd8ec52016-08-28 03:57:40 +0800764
765 *data_len = 4;
766
Tom Joseph63a00512017-08-09 23:39:59 +0530767 bus = ipmid_get_sd_bus_connection();
768
Nan Lifdd8ec52016-08-28 03:57:40 +0800769 r = mapper_get_service(bus, objname, &busname);
770 if (r < 0) {
771 fprintf(stderr, "Failed to get bus name, return value: %s.\n", strerror(-r));
772 rc = IPMI_CC_UNSPECIFIED_ERROR;
773 goto finish;
774 }
775
776 r = sd_bus_get_property(bus, busname, objname, intf, "pgood", NULL, &reply, "i");
777 if (r < 0) {
778 fprintf(stderr, "Failed to call sd_bus_get_property:%d, %s\n", r, strerror(-r));
779 fprintf(stderr, "Bus: %s, Path: %s, Interface: %s\n",
780 busname, objname, intf);
781 rc = IPMI_CC_UNSPECIFIED_ERROR;
782 goto finish;
783 }
784
785 r = sd_bus_message_read(reply, "i", &pgood);
786 if (r < 0) {
787 fprintf(stderr, "Failed to read sensor: %s\n", strerror(-r));
788 rc = IPMI_CC_UNSPECIFIED_ERROR;
789 goto finish;
790 }
791
792 printf("pgood is 0x%02x\n", pgood);
793
Deepak Kodihalli18b70d12017-07-21 13:36:33 -0500794 s = dbusToIpmi.at(powerRestore);
Nan Lifdd8ec52016-08-28 03:57:40 +0800795
796 // Current Power State
797 // [7] reserved
798 // [6..5] power restore policy
799 // 00b = chassis stays powered off after AC/mains returns
800 // 01b = after AC returns, power is restored to the state that was
801 // in effect when AC/mains was lost.
802 // 10b = chassis always powers up after AC/mains returns
803 // 11b = unknow
804 // Set to 00b, by observing the hardware behavior.
805 // Do we need to define a dbus property to identify the restore policy?
806
807 // [4] power control fault
808 // 1b = controller attempted to turn system power on or off, but
809 // system did not enter desired state.
810 // Set to 0b, since We don't support it..
811
812 // [3] power fault
813 // 1b = fault detected in main power subsystem.
814 // set to 0b. for we don't support it.
815
816 // [2] 1b = interlock (chassis is presently shut down because a chassis
817 // panel interlock switch is active). (IPMI 1.5)
818 // set to 0b, for we don't support it.
819
820 // [1] power overload
821 // 1b = system shutdown because of power overload condition.
822 // set to 0b, for we don't support it.
823
824 // [0] power is on
825 // 1b = system power is on
826 // 0b = system power is off(soft-off S4/S5, or mechanical off)
827
828 chassis_status.cur_power_state = ((s & 0x3)<<5) | (pgood & 0x1);
829
830 // Last Power Event
831 // [7..5] – reserved
832 // [4] – 1b = last ‘Power is on’ state was entered via IPMI command
833 // [3] – 1b = last power down caused by power fault
834 // [2] – 1b = last power down caused by a power interlock being activated
835 // [1] – 1b = last power down caused by a Power overload
836 // [0] – 1b = AC failed
837 // set to 0x0, for we don't support these fields.
838
839 chassis_status.last_power_event = 0;
840
841 // Misc. Chassis State
842 // [7] – reserved
843 // [6] – 1b = Chassis Identify command and state info supported (Optional)
844 // 0b = Chassis Identify command support unspecified via this command.
845 // (The Get Command Support command , if implemented, would still
846 // indicate support for the Chassis Identify command)
847 // [5..4] – Chassis Identify State. Mandatory when bit[6] =1b, reserved (return
848 // as 00b) otherwise. Returns the present chassis identify state.
849 // Refer to the Chassis Identify command for more info.
850 // 00b = chassis identify state = Off
851 // 01b = chassis identify state = Temporary(timed) On
852 // 10b = chassis identify state = Indefinite On
853 // 11b = reserved
854 // [3] – 1b = Cooling/fan fault detected
855 // [2] – 1b = Drive Fault
856 // [1] – 1b = Front Panel Lockout active (power off and reset via chassis
857 // push-buttons disabled.)
858 // [0] – 1b = Chassis Intrusion active
859 // set to 0, for we don't support them.
860 chassis_status.misc_power_state = 0;
861
862 // Front Panel Button Capabilities and disable/enable status(Optional)
863 // set to 0, for we don't support them.
864 chassis_status.front_panel_button_cap_status = 0;
865
866 // Pack the actual response
867 memcpy(response, &chassis_status, *data_len);
868
869finish:
870 free(busname);
871 reply = sd_bus_message_unref(reply);
872
873 return rc;
874}
Chris Austen7888c4d2015-12-03 15:26:20 -0600875
Vishwanatha Subbanna83b5c1c2017-01-25 18:41:51 +0530876//-------------------------------------------------------------
877// Send a command to SoftPowerOff application to stop any timer
878//-------------------------------------------------------------
879int stop_soft_off_timer()
880{
Vishwanatha Subbanna83b5c1c2017-01-25 18:41:51 +0530881 constexpr auto iface = "org.freedesktop.DBus.Properties";
882 constexpr auto soft_off_iface = "xyz.openbmc_project.Ipmi.Internal."
Andrew Geisslerfca6a4f2017-05-30 10:55:39 -0500883 "SoftPowerOff";
Vishwanatha Subbanna83b5c1c2017-01-25 18:41:51 +0530884
885 constexpr auto property = "ResponseReceived";
886 constexpr auto value = "xyz.openbmc_project.Ipmi.Internal."
Andrew Geisslerfca6a4f2017-05-30 10:55:39 -0500887 "SoftPowerOff.HostResponse.HostShutdown";
Vishwanatha Subbanna83b5c1c2017-01-25 18:41:51 +0530888
889 // Get the system bus where most system services are provided.
890 auto bus = ipmid_get_sd_bus_connection();
891
892 // Get the service name
Andrew Geissler2b4e4592017-06-08 11:18:35 -0500893 // TODO openbmc/openbmc#1661 - Mapper refactor
894 //
895 // See openbmc/openbmc#1743 for some details but high level summary is that
896 // for now the code will directly call the soft off interface due to a
897 // race condition with mapper usage
898 //
899 //char *busname = nullptr;
900 //auto r = mapper_get_service(bus, SOFTOFF_OBJPATH, &busname);
901 //if (r < 0)
902 //{
903 // fprintf(stderr, "Failed to get %s bus name: %s\n",
904 // SOFTOFF_OBJPATH, strerror(-r));
905 // return r;
906 //}
Vishwanatha Subbanna83b5c1c2017-01-25 18:41:51 +0530907
908 // No error object or reply expected.
Andrew Geissler2b4e4592017-06-08 11:18:35 -0500909 int rc = sd_bus_call_method(bus, SOFTOFF_BUSNAME, SOFTOFF_OBJPATH, iface,
Andrew Geisslerfca6a4f2017-05-30 10:55:39 -0500910 "Set", nullptr, nullptr, "ssv",
911 soft_off_iface, property, "s", value);
Vishwanatha Subbanna83b5c1c2017-01-25 18:41:51 +0530912 if (rc < 0)
913 {
914 fprintf(stderr, "Failed to set property in SoftPowerOff object: %s\n",
915 strerror(-rc));
916 }
Andrew Geisslerfca6a4f2017-05-30 10:55:39 -0500917
Andrew Geissler2b4e4592017-06-08 11:18:35 -0500918 //TODO openbmc/openbmc#1661 - Mapper refactor
919 //free(busname);
Vishwanatha Subbanna83b5c1c2017-01-25 18:41:51 +0530920 return rc;
921}
922
vishwa36993272015-11-20 12:43:49 -0600923//----------------------------------------------------------------------
Andrew Geisslera6e3a302017-05-31 19:34:00 -0500924// Create file to indicate there is no need for softoff notification to host
925//----------------------------------------------------------------------
926void indicate_no_softoff_needed()
927{
928 fs::path path{HOST_INBAND_REQUEST_DIR};
929 if (!fs::is_directory(path))
930 {
931 fs::create_directory(path);
932 }
933
934 // Add the host instance (default 0 for now) to the file name
935 std::string file{HOST_INBAND_REQUEST_FILE};
936 auto size = std::snprintf(nullptr,0,file.c_str(),0);
937 size++; // null
938 std::unique_ptr<char[]> buf(new char[size]);
939 std::snprintf(buf.get(),size,file.c_str(),0);
940
941 // Append file name to directory and create it
942 path /= buf.get();
943 std::ofstream(path.c_str());
944}
945
946//----------------------------------------------------------------------
vishwa36993272015-11-20 12:43:49 -0600947// Chassis Control commands
948//----------------------------------------------------------------------
Andrew Geisslerfca6a4f2017-05-30 10:55:39 -0500949ipmi_ret_t ipmi_chassis_control(ipmi_netfn_t netfn, ipmi_cmd_t cmd,
950 ipmi_request_t request,
951 ipmi_response_t response,
952 ipmi_data_len_t data_len,
953 ipmi_context_t context)
vishwa36993272015-11-20 12:43:49 -0600954{
Andrew Geisslerfca6a4f2017-05-30 10:55:39 -0500955 // Error from power off.
956 int rc = 0;
vishwa36993272015-11-20 12:43:49 -0600957
Andrew Geisslerfca6a4f2017-05-30 10:55:39 -0500958 // No response for this command.
vishwa36993272015-11-20 12:43:49 -0600959 *data_len = 0;
960
Andrew Geisslerfca6a4f2017-05-30 10:55:39 -0500961 // Catch the actual operaton by peeking into request buffer
962 uint8_t chassis_ctrl_cmd = *(uint8_t *)request;
963 printf("Chassis Control Command: Operation:[0x%X]\n",chassis_ctrl_cmd);
vishwa36993272015-11-20 12:43:49 -0600964
Andrew Geisslerfca6a4f2017-05-30 10:55:39 -0500965 switch(chassis_ctrl_cmd)
966 {
967 case CMD_POWER_ON:
968 rc = initiate_state_transition(State::Host::Transition::On);
969 break;
970 case CMD_POWER_OFF:
971 // Need to Nudge SoftPowerOff application that it needs to stop the
972 // watchdog timer if running.
973 rc = stop_soft_off_timer();
Andrew Geisslera6e3a302017-05-31 19:34:00 -0500974 // Only request the Off transition if the soft power off
975 // application is not running
976 if (rc < 0)
Andrew Geisslerfca6a4f2017-05-30 10:55:39 -0500977 {
Andrew Geisslera6e3a302017-05-31 19:34:00 -0500978 log<level::INFO>("Did not find soft off service so request "
979 "Host:Transition:Off");
980
981 // First create a file to indicate to the soft off application
982 // that it should not run since this is a direct user initiated
983 // power off request (i.e. a power off request that is not
984 // originating via a soft power off SMS request)
985 indicate_no_softoff_needed();
986
987 // Now request the shutdown
988 rc = initiate_state_transition(State::Host::Transition::Off);
Andrew Geisslerfca6a4f2017-05-30 10:55:39 -0500989 }
Andrew Geisslera6e3a302017-05-31 19:34:00 -0500990 else
991 {
992 log<level::INFO>("Soft off is running, so let that stop "
993 "the host");
994 }
995
Andrew Geisslerfca6a4f2017-05-30 10:55:39 -0500996 break;
Vishwanatha Subbanna83b5c1c2017-01-25 18:41:51 +0530997
Andrew Geisslerfca6a4f2017-05-30 10:55:39 -0500998 case CMD_HARD_RESET:
999 case CMD_POWER_CYCLE:
1000 // SPEC has a section that says certain implementations can trigger
1001 // PowerOn if power is Off when a command to power cycle is
1002 // requested
Andrew Geisslera6e3a302017-05-31 19:34:00 -05001003
1004 // First create a file to indicate to the soft off application
1005 // that it should not run since this is a direct user initiated
1006 // power reboot request (i.e. a reboot request that is not
1007 // originating via a soft power off SMS request)
1008 indicate_no_softoff_needed();
1009
Andrew Geisslerfca6a4f2017-05-30 10:55:39 -05001010 rc = initiate_state_transition(State::Host::Transition::Reboot);
1011 break;
1012 default:
1013 {
1014 fprintf(stderr, "Invalid Chassis Control command:[0x%X] received\n",chassis_ctrl_cmd);
1015 rc = -1;
1016 }
1017 }
vishwa36993272015-11-20 12:43:49 -06001018
Andrew Geisslerfca6a4f2017-05-30 10:55:39 -05001019 return ( (rc < 0) ? IPMI_CC_INVALID : IPMI_CC_OK);
vishwa36993272015-11-20 12:43:49 -06001020}
1021
Deepak Kodihalli8cc19362017-07-21 11:18:38 -05001022namespace boot_options
1023{
1024
1025using namespace sdbusplus::xyz::openbmc_project::Control::Boot::server;
1026using IpmiValue = uint8_t;
1027constexpr auto ipmiDefault = 0;
1028
1029std::map<IpmiValue, Source::Sources> sourceIpmiToDbus =
1030{
1031 {0x01, Source::Sources::Network},
1032 {0x02, Source::Sources::Disk},
1033 {0x05, Source::Sources::ExternalMedia},
1034 {ipmiDefault, Source::Sources::Default}
shgoupfd84fbbf2015-12-17 10:05:51 +08001035};
1036
Deepak Kodihalli8cc19362017-07-21 11:18:38 -05001037std::map<IpmiValue, Mode::Modes> modeIpmiToDbus =
1038{
1039 {0x03, Mode::Modes::Safe},
1040 {0x06, Mode::Modes::Setup},
1041 {ipmiDefault, Mode::Modes::Regular}
shgoupfd84fbbf2015-12-17 10:05:51 +08001042};
1043
Deepak Kodihalli8cc19362017-07-21 11:18:38 -05001044std::map<Source::Sources, IpmiValue> sourceDbusToIpmi =
1045{
1046 {Source::Sources::Network, 0x01},
1047 {Source::Sources::Disk, 0x02},
1048 {Source::Sources::ExternalMedia, 0x05},
1049 {Source::Sources::Default, ipmiDefault}
1050};
shgoupfd84fbbf2015-12-17 10:05:51 +08001051
Deepak Kodihalli8cc19362017-07-21 11:18:38 -05001052std::map<Mode::Modes, IpmiValue> modeDbusToIpmi =
1053{
1054 {Mode::Modes::Safe, 0x03},
1055 {Mode::Modes::Setup, 0x06},
1056 {Mode::Modes::Regular, ipmiDefault}
1057};
shgoupfd84fbbf2015-12-17 10:05:51 +08001058
Deepak Kodihalli8cc19362017-07-21 11:18:38 -05001059} // namespace boot_options
shgoupfd84fbbf2015-12-17 10:05:51 +08001060
Andrew Geisslerfca6a4f2017-05-30 10:55:39 -05001061ipmi_ret_t ipmi_chassis_get_sys_boot_options(ipmi_netfn_t netfn, ipmi_cmd_t cmd,
1062 ipmi_request_t request,
1063 ipmi_response_t response,
1064 ipmi_data_len_t data_len,
1065 ipmi_context_t context)
Adriana Kobylak40814c62015-10-27 15:58:44 -05001066{
Deepak Kodihalli8cc19362017-07-21 11:18:38 -05001067 using namespace boot_options;
shgoupfd84fbbf2015-12-17 10:05:51 +08001068 ipmi_ret_t rc = IPMI_CC_PARM_NOT_SUPPORTED;
1069 char *p = NULL;
1070 get_sys_boot_options_response_t *resp = (get_sys_boot_options_response_t *) response;
1071 get_sys_boot_options_t *reqptr = (get_sys_boot_options_t*) request;
Deepak Kodihalli8cc19362017-07-21 11:18:38 -05001072 IpmiValue bootOption = ipmiDefault;
Adriana Kobylak40814c62015-10-27 15:58:44 -05001073
1074 printf("IPMI GET_SYS_BOOT_OPTIONS\n");
1075
shgoupfd84fbbf2015-12-17 10:05:51 +08001076 memset(resp,0,sizeof(*resp));
1077 resp->version = SET_PARM_VERSION;
1078 resp->parm = 5;
ratagupta6f6bff2016-04-04 06:20:11 -05001079 resp->data[0] = SET_PARM_BOOT_FLAGS_VALID_ONE_TIME;
Adriana Kobylak40814c62015-10-27 15:58:44 -05001080
Adriana Kobylak40814c62015-10-27 15:58:44 -05001081
shgoupfd84fbbf2015-12-17 10:05:51 +08001082 /*
1083 * Parameter #5 means boot flags. Please refer to 28.13 of ipmi doc.
1084 * This is the only parameter used by petitboot.
1085 */
Ratan Guptafd28dd72016-08-01 04:58:01 -05001086 if ( reqptr->parameter == static_cast<uint8_t>
Andrew Geisslerfca6a4f2017-05-30 10:55:39 -05001087 ( BootOptionParameter::BOOT_FLAGS )) {
shgoupfd84fbbf2015-12-17 10:05:51 +08001088
Ratan Guptafd28dd72016-08-01 04:58:01 -05001089 *data_len = static_cast<uint8_t>(BootOptionResponseSize::BOOT_FLAGS);
Deepak Kodihalli8cc19362017-07-21 11:18:38 -05001090 using namespace chassis::internal;
1091 using namespace chassis::internal::cache;
shgoupfd84fbbf2015-12-17 10:05:51 +08001092
Deepak Kodihalli8cc19362017-07-21 11:18:38 -05001093 const auto& bootSourceSetting = objects.map.at(bootSourceIntf);
1094 auto method =
1095 dbus.new_method_call(
1096 objects.service(bootSourceSetting, bootSourceIntf).c_str(),
1097 bootSourceSetting.c_str(),
Ratan Guptacc8feb42017-07-25 21:52:10 +05301098 ipmi::PROP_INTF,
Deepak Kodihalli8cc19362017-07-21 11:18:38 -05001099 "Get");
1100 method.append(bootSourceIntf, "BootSource");
1101 auto reply = dbus.call(method);
1102 if (reply.is_method_error())
ratagupta6f6bff2016-04-04 06:20:11 -05001103 {
Deepak Kodihalli8cc19362017-07-21 11:18:38 -05001104 log<level::ERR>("Error in BootSource Get");
1105 report<InternalFailure>();
1106 *data_len = 0;
1107 return IPMI_CC_UNSPECIFIED_ERROR;
ratagupta6f6bff2016-04-04 06:20:11 -05001108 }
Deepak Kodihalli8cc19362017-07-21 11:18:38 -05001109 sdbusplus::message::variant<std::string> result;
1110 reply.read(result);
1111 auto bootSource =
1112 Source::convertSourcesFromString(result.get<std::string>());
1113
1114 const auto& bootModeSetting = objects.map.at(bootModeIntf);
1115 method = dbus.new_method_call(
1116 objects.service(bootModeSetting, bootModeIntf).c_str(),
1117 bootModeSetting.c_str(),
Ratan Guptacc8feb42017-07-25 21:52:10 +05301118 ipmi::PROP_INTF,
Deepak Kodihalli8cc19362017-07-21 11:18:38 -05001119 "Get");
1120 method.append(bootModeIntf, "BootMode");
1121 reply = dbus.call(method);
1122 if (reply.is_method_error())
1123 {
1124 log<level::ERR>("Error in BootMode Get");
1125 report<InternalFailure>();
1126 *data_len = 0;
1127 return IPMI_CC_UNSPECIFIED_ERROR;
1128 }
1129 reply.read(result);
1130 auto bootMode = Mode::convertModesFromString(result.get<std::string>());
1131
1132 bootOption = sourceDbusToIpmi.at(bootSource);
1133 if ((Mode::Modes::Regular == bootMode) &&
1134 (Source::Sources::Default == bootSource))
1135 {
1136 bootOption = ipmiDefault;
1137 }
1138 else if (Source::Sources::Default == bootSource)
1139 {
1140 bootOption = modeDbusToIpmi.at(bootMode);
1141 }
1142 resp->data[1] = (bootOption << 2);
1143 rc = IPMI_CC_OK;
ratagupta6f6bff2016-04-04 06:20:11 -05001144
1145 /* Get the boot policy */
Deepak Kodihalli8cc19362017-07-21 11:18:38 -05001146 int r = dbus_get_property("boot_policy",&p);
ratagupta6f6bff2016-04-04 06:20:11 -05001147
1148 if (r < 0) {
1149 fprintf(stderr, "Dbus get property(boot_policy) failed for get_sys_boot_options.\n");
1150 rc = IPMI_CC_UNSPECIFIED_ERROR;
1151
1152 } else {
1153
George Keishing012d6a42017-06-14 03:06:48 -05001154 printf("BootPolicy is [%s]\n", p);
Andrew Geisslerfca6a4f2017-05-30 10:55:39 -05001155 resp->data[0] = (strncmp(p,"ONETIME",strlen("ONETIME"))==0) ?
1156 SET_PARM_BOOT_FLAGS_VALID_ONE_TIME:
1157 SET_PARM_BOOT_FLAGS_VALID_PERMANENT;
ratagupta6f6bff2016-04-04 06:20:11 -05001158 rc = IPMI_CC_OK;
1159
1160 }
1161
1162
Ratan Guptafd28dd72016-08-01 04:58:01 -05001163 } else if ( reqptr->parameter == static_cast<uint8_t>
Andrew Geisslerfca6a4f2017-05-30 10:55:39 -05001164 ( BootOptionParameter::OPAL_NETWORK_SETTINGS )) {
Ratan Guptafd28dd72016-08-01 04:58:01 -05001165
Andrew Geisslerfca6a4f2017-05-30 10:55:39 -05001166 *data_len = static_cast<uint8_t>(BootOptionResponseSize::OPAL_NETWORK_SETTINGS);
Ratan Guptafd28dd72016-08-01 04:58:01 -05001167
Andrew Geisslerfca6a4f2017-05-30 10:55:39 -05001168 resp->parm = static_cast<uint8_t>(BootOptionParameter::OPAL_NETWORK_SETTINGS);
Ratan Guptafd28dd72016-08-01 04:58:01 -05001169
Andrew Geisslerfca6a4f2017-05-30 10:55:39 -05001170 int ret = getHostNetworkData(resp);
Ratan Guptafd28dd72016-08-01 04:58:01 -05001171
Andrew Geisslerfca6a4f2017-05-30 10:55:39 -05001172 if (ret < 0) {
Ratan Guptafd28dd72016-08-01 04:58:01 -05001173
Andrew Geisslerfca6a4f2017-05-30 10:55:39 -05001174 fprintf(stderr, "getHostNetworkData failed for get_sys_boot_options.\n");
1175 rc = IPMI_CC_UNSPECIFIED_ERROR;
Ratan Guptafd28dd72016-08-01 04:58:01 -05001176
Andrew Geisslerfca6a4f2017-05-30 10:55:39 -05001177 }else
1178 rc = IPMI_CC_OK;
Ratan Guptafd28dd72016-08-01 04:58:01 -05001179 }
1180
1181 else {
Adriana Kobylak40814c62015-10-27 15:58:44 -05001182 fprintf(stderr, "Unsupported parameter 0x%x\n", reqptr->parameter);
shgoupfd84fbbf2015-12-17 10:05:51 +08001183 }
1184
1185 if (p)
1186 free(p);
1187
Ratan Guptafd28dd72016-08-01 04:58:01 -05001188 if (rc == IPMI_CC_OK)
1189 {
1190 *data_len += 2;
1191 }
1192
shgoupfd84fbbf2015-12-17 10:05:51 +08001193 return rc;
1194}
1195
1196
1197
1198ipmi_ret_t ipmi_chassis_set_sys_boot_options(ipmi_netfn_t netfn, ipmi_cmd_t cmd,
Andrew Geisslerfca6a4f2017-05-30 10:55:39 -05001199 ipmi_request_t request,
1200 ipmi_response_t response,
1201 ipmi_data_len_t data_len,
1202 ipmi_context_t context)
shgoupfd84fbbf2015-12-17 10:05:51 +08001203{
Deepak Kodihalli8cc19362017-07-21 11:18:38 -05001204 using namespace boot_options;
shgoupfd84fbbf2015-12-17 10:05:51 +08001205 ipmi_ret_t rc = IPMI_CC_OK;
shgoupfd84fbbf2015-12-17 10:05:51 +08001206 set_sys_boot_options_t *reqptr = (set_sys_boot_options_t *) request;
1207
Ratan Guptafd28dd72016-08-01 04:58:01 -05001208 printf("IPMI SET_SYS_BOOT_OPTIONS reqptr->parameter =[%d]\n",reqptr->parameter);
1209
shgoupfd84fbbf2015-12-17 10:05:51 +08001210 // This IPMI command does not have any resposne data
1211 *data_len = 0;
1212
1213 /* 000101
1214 * Parameter #5 means boot flags. Please refer to 28.13 of ipmi doc.
1215 * This is the only parameter used by petitboot.
1216 */
Ratan Guptafd28dd72016-08-01 04:58:01 -05001217
Deepak Kodihalli8cc19362017-07-21 11:18:38 -05001218 if (reqptr->parameter == (uint8_t)BootOptionParameter::BOOT_FLAGS)
1219 {
1220 IpmiValue bootOption = ((reqptr->data[1] & 0x3C) >> 2);
1221 using namespace chassis::internal;
1222 using namespace chassis::internal::cache;
shgoupfd84fbbf2015-12-17 10:05:51 +08001223
Deepak Kodihalli8cc19362017-07-21 11:18:38 -05001224 auto modeItr = modeIpmiToDbus.find(bootOption);
1225 auto sourceItr = sourceIpmiToDbus.find(bootOption);
1226 if ((ipmiDefault == bootOption) ||
1227 (sourceIpmiToDbus.end() != sourceItr))
1228 {
1229 sdbusplus::message::variant<std::string> property =
1230 convertForMessage(sourceItr->second);
1231 const auto& bootSourceSetting =
1232 objects.map.at(bootSourceIntf);
1233 auto method =
1234 dbus.new_method_call(
1235 objects.service(bootSourceSetting, bootSourceIntf).c_str(),
1236 bootSourceSetting.c_str(),
Ratan Guptacc8feb42017-07-25 21:52:10 +05301237 ipmi::PROP_INTF,
Deepak Kodihalli8cc19362017-07-21 11:18:38 -05001238 "Set");
1239 method.append(bootSourceIntf, "BootSource", property);
1240 auto reply = dbus.call(method);
1241 if (reply.is_method_error())
1242 {
1243 log<level::ERR>("Error in BootSource Set");
1244 report<InternalFailure>();
1245 *data_len = 0;
1246 return IPMI_CC_UNSPECIFIED_ERROR;
1247 }
1248 }
1249 if ((ipmiDefault == bootOption) ||
1250 (modeIpmiToDbus.end() != modeItr))
1251 {
1252 sdbusplus::message::variant<std::string> property =
1253 convertForMessage(modeItr->second);
1254 const auto& bootModeSetting = objects.map.at(bootModeIntf);
1255 auto method =
1256 dbus.new_method_call(
1257 objects.service(bootModeSetting, bootModeIntf).c_str(),
1258 bootModeSetting.c_str(),
Ratan Guptacc8feb42017-07-25 21:52:10 +05301259 ipmi::PROP_INTF,
Deepak Kodihalli8cc19362017-07-21 11:18:38 -05001260 "Set");
1261 method.append(bootModeIntf, "BootMode", property);
1262 auto reply = dbus.call(method);
1263 if (reply.is_method_error())
1264 {
1265 log<level::ERR>("Error in BootMode Set");
1266 report<InternalFailure>();
1267 *data_len = 0;
1268 return IPMI_CC_UNSPECIFIED_ERROR;
shgoupfd84fbbf2015-12-17 10:05:51 +08001269 }
1270 }
Ratan Guptafd28dd72016-08-01 04:58:01 -05001271
ratagupta6f6bff2016-04-04 06:20:11 -05001272 /* setting the boot policy */
Deepak Kodihalli8cc19362017-07-21 11:18:38 -05001273 std::string value =
1274 (char *)(((reqptr->data[0] & SET_PARM_BOOT_FLAGS_PERMANENT) ==
Andrew Geisslerfca6a4f2017-05-30 10:55:39 -05001275 SET_PARM_BOOT_FLAGS_PERMANENT) ?"PERMANENT":"ONETIME");
ratagupta6f6bff2016-04-04 06:20:11 -05001276
Deepak Kodihalli8cc19362017-07-21 11:18:38 -05001277 printf ( "\nBoot Policy is %s",value.c_str());
1278 int r = dbus_set_property("boot_policy",value.c_str());
ratagupta6f6bff2016-04-04 06:20:11 -05001279
1280 if (r < 0) {
1281 fprintf(stderr, "Dbus set property(boot_policy) failed for set_sys_boot_options.\n");
1282 rc = IPMI_CC_UNSPECIFIED_ERROR;
1283 }
shgoupfd84fbbf2015-12-17 10:05:51 +08001284
Andrew Geisslerfca6a4f2017-05-30 10:55:39 -05001285 } else if (reqptr->parameter ==
1286 (uint8_t)BootOptionParameter::OPAL_NETWORK_SETTINGS) {
Ratan Guptafd28dd72016-08-01 04:58:01 -05001287
1288 int ret = setHostNetworkData(reqptr);
1289 if (ret < 0) {
1290 fprintf(stderr, "setHostNetworkData failed for set_sys_boot_options.\n");
1291 rc = IPMI_CC_UNSPECIFIED_ERROR;
1292 }
1293 }
1294 else {
shgoupfd84fbbf2015-12-17 10:05:51 +08001295 fprintf(stderr, "Unsupported parameter 0x%x\n", reqptr->parameter);
1296 rc = IPMI_CC_PARM_NOT_SUPPORTED;
Adriana Kobylak40814c62015-10-27 15:58:44 -05001297 }
1298
1299 return rc;
1300}
1301
1302void register_netfn_chassis_functions()
1303{
Tom05732372016-09-06 17:21:23 +05301304 // <Wildcard Command>
Adriana Kobylak40814c62015-10-27 15:58:44 -05001305 printf("Registering NetFn:[0x%X], Cmd:[0x%X]\n",NETFUN_CHASSIS, IPMI_CMD_WILDCARD);
Tom05732372016-09-06 17:21:23 +05301306 ipmi_register_callback(NETFUN_CHASSIS, IPMI_CMD_WILDCARD, NULL, ipmi_chassis_wildcard,
1307 PRIVILEGE_USER);
Adriana Kobylak40814c62015-10-27 15:58:44 -05001308
Tom05732372016-09-06 17:21:23 +05301309 // Get Chassis Capabilities
Nan Li8d15fb42016-08-16 22:29:40 +08001310 printf("Registering NetFn:[0x%X], Cmd:[0x%X]\n",NETFUN_CHASSIS, IPMI_CMD_GET_CHASSIS_CAP);
Tom05732372016-09-06 17:21:23 +05301311 ipmi_register_callback(NETFUN_CHASSIS, IPMI_CMD_GET_CHASSIS_CAP, NULL, ipmi_get_chassis_cap,
1312 PRIVILEGE_USER);
Nan Li8d15fb42016-08-16 22:29:40 +08001313
Tom05732372016-09-06 17:21:23 +05301314 // <Get System Boot Options>
Adriana Kobylak40814c62015-10-27 15:58:44 -05001315 printf("Registering NetFn:[0x%X], Cmd:[0x%X]\n",NETFUN_CHASSIS, IPMI_CMD_GET_SYS_BOOT_OPTIONS);
Tom05732372016-09-06 17:21:23 +05301316 ipmi_register_callback(NETFUN_CHASSIS, IPMI_CMD_GET_SYS_BOOT_OPTIONS, NULL,
1317 ipmi_chassis_get_sys_boot_options, PRIVILEGE_OPERATOR);
Adriana Kobylak40814c62015-10-27 15:58:44 -05001318
Tom05732372016-09-06 17:21:23 +05301319 // <Get Chassis Status>
Nan Lifdd8ec52016-08-28 03:57:40 +08001320 printf("Registering NetFn:[0x%X], Cmd:[0x%X]\n",NETFUN_CHASSIS, IPMI_CMD_CHASSIS_STATUS);
Tom05732372016-09-06 17:21:23 +05301321 ipmi_register_callback(NETFUN_CHASSIS, IPMI_CMD_CHASSIS_STATUS, NULL, ipmi_get_chassis_status,
1322 PRIVILEGE_USER);
Nan Lifdd8ec52016-08-28 03:57:40 +08001323
Tom05732372016-09-06 17:21:23 +05301324 // <Chassis Control>
vishwa36993272015-11-20 12:43:49 -06001325 printf("Registering NetFn:[0x%X], Cmd:[0x%X]\n",NETFUN_CHASSIS, IPMI_CMD_CHASSIS_CONTROL);
Tom05732372016-09-06 17:21:23 +05301326 ipmi_register_callback(NETFUN_CHASSIS, IPMI_CMD_CHASSIS_CONTROL, NULL, ipmi_chassis_control,
1327 PRIVILEGE_OPERATOR);
shgoupfd84fbbf2015-12-17 10:05:51 +08001328
Tom05732372016-09-06 17:21:23 +05301329 // <Set System Boot Options>
shgoupfd84fbbf2015-12-17 10:05:51 +08001330 printf("Registering NetFn:[0x%X], Cmd:[0x%X]\n", NETFUN_CHASSIS, IPMI_CMD_SET_SYS_BOOT_OPTIONS);
Tom05732372016-09-06 17:21:23 +05301331 ipmi_register_callback(NETFUN_CHASSIS, IPMI_CMD_SET_SYS_BOOT_OPTIONS, NULL,
1332 ipmi_chassis_set_sys_boot_options, PRIVILEGE_OPERATOR);
vishwa36993272015-11-20 12:43:49 -06001333}