blob: c0471085de6c4a4530a49d90465a9c82d9aaa465 [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 Guptacc8feb42017-07-25 21:52:10 +0530295 auto ipObjectInfo = ipmi::getDbusObject(IP_INTERFACE, SETTINGS_ROOT,
296 SETTINGS_MATCH);
297 auto macObjectInfo = ipmi::getDbusObject(MAC_INTERFACE, SETTINGS_ROOT,
298 SETTINGS_MATCH);
Ratan Guptadcb10672017-07-10 10:33:50 +0530299
Ratan Guptacc8feb42017-07-25 21:52:10 +0530300 properties = ipmi::getAllDbusProperties(ipObjectInfo.second,
301 ipObjectInfo.first, IP_INTERFACE);
302 auto variant =
303 ipmi::getDbusProperty(macObjectInfo.second, macObjectInfo.first,
304 MAC_INTERFACE, "MACAddress");
Ratan Guptadcb10672017-07-10 10:33:50 +0530305
Ratan Guptad70f4532017-08-04 02:07:31 +0530306 auto ipAddress = properties["Address"].get<std::string>();
307
308 auto gateway = properties["Gateway"].get<std::string>();
309
310 auto prefix = properties["PrefixLength"].get<uint8_t>();
311
312 uint8_t isStatic = (properties["Origin"].get<std::string>() ==
313 "xyz.openbmc_project.Network.IP.AddressOrigin.Static")
314 ? 1 : 0;
315
Ratan Guptacc8feb42017-07-25 21:52:10 +0530316 auto MACAddress = variant.get<std::string>();
317
Ratan Guptad70f4532017-08-04 02:07:31 +0530318 // it is expected here that we should get the valid data
319 // but we may also get the default values.
320 // Validation of the data is done by settings.
321 //
322 // if mac address is default mac address then
323 // don't send blank override.
324 if ((MACAddress == DEFAULT_MAC_ADDRESS))
325 {
326 memset(respptr->data, 0, SIZE_BOOT_OPTION);
327 rc = -1;
328 return rc;
329 }
330 // if addr is static then ipaddress,gateway,prefix
331 // should not be default one,don't send blank override.
332 if (isStatic)
333 {
334 if((ipAddress == DEFAULT_ADDRESS) ||
335 (gateway == DEFAULT_ADDRESS) ||
336 (!prefix))
337 {
338 memset(respptr->data, 0, SIZE_BOOT_OPTION);
339 rc = -1;
340 return rc;
341 }
342 }
343
Ratan Guptadcb10672017-07-10 10:33:50 +0530344 sscanf(MACAddress.c_str(), MAC_ADDRESS_FORMAT,
345 (respptr->data + MAC_OFFSET),
346 (respptr->data + MAC_OFFSET + 1),
347 (respptr->data + MAC_OFFSET + 2),
348 (respptr->data + MAC_OFFSET + 3),
349 (respptr->data + MAC_OFFSET + 4),
350 (respptr->data + MAC_OFFSET + 5));
351
Ratan Guptadcb10672017-07-10 10:33:50 +0530352 respptr->data[MAC_OFFSET + 6] = 0x00;
353
Ratan Guptad70f4532017-08-04 02:07:31 +0530354 memcpy(respptr->data + ADDRTYPE_OFFSET, &isStatic,
355 sizeof(isStatic));
Ratan Gupta6ec7daa2017-07-15 14:13:01 +0530356
357 uint8_t addressFamily = (properties["Type"].get<std::string>() ==
358 "xyz.openbmc_project.Network.IP.Protocol.IPv4") ?
359 AF_INET : AF_INET6;
360
361 addrSize = (addressFamily == AF_INET) ? IPV4_ADDRESS_SIZE_BYTE :
362 IPV6_ADDRESS_SIZE_BYTE;
Ratan Guptadcb10672017-07-10 10:33:50 +0530363
364 // ipaddress and gateway would be in IPv4 format
Ratan Guptad70f4532017-08-04 02:07:31 +0530365 inet_pton(addressFamily, ipAddress.c_str(),
366 (respptr->data + IPADDR_OFFSET));
Ratan Guptadcb10672017-07-10 10:33:50 +0530367
Ratan Gupta6ec7daa2017-07-15 14:13:01 +0530368 uint8_t prefixOffset = IPADDR_OFFSET + addrSize;
369
370 memcpy(respptr->data + prefixOffset, &prefix, sizeof(prefix));
371
372 uint8_t gatewayOffset = prefixOffset + sizeof(decltype(prefix));
373
Ratan Guptad70f4532017-08-04 02:07:31 +0530374 inet_pton(addressFamily, gateway.c_str(),
375 (respptr->data + gatewayOffset));
Ratan Guptadcb10672017-07-10 10:33:50 +0530376
377 }
378 catch (InternalFailure& e)
379 {
380 commit<InternalFailure>();
381 memset(respptr->data, 0, SIZE_BOOT_OPTION);
382 rc = -1;
Ratan Guptafd28dd72016-08-01 04:58:01 -0500383 return rc;
384 }
385
Ratan Guptadcb10672017-07-10 10:33:50 +0530386 //PetiBoot-Specific
387 //If sucess then copy the first 9 bytes to the data
Ratan Guptadcb10672017-07-10 10:33:50 +0530388 memcpy(respptr->data, net_conf_initial_bytes,
389 sizeof(net_conf_initial_bytes));
Ratan Guptafd28dd72016-08-01 04:58:01 -0500390
Ratan Gupta6ec7daa2017-07-15 14:13:01 +0530391 memcpy(respptr->data + ADDR_SIZE_OFFSET, &addrSize, sizeof(addrSize));
392
Ratan Guptafd28dd72016-08-01 04:58:01 -0500393#ifdef _IPMI_DEBUG_
Ratan Guptadcb10672017-07-10 10:33:50 +0530394 printf("\n===Printing the IPMI Formatted Data========\n");
Ratan Guptafd28dd72016-08-01 04:58:01 -0500395
Ratan Guptadcb10672017-07-10 10:33:50 +0530396 for (uint8_t pos = 0; pos < index; pos++)
397 {
398 printf("%02x ", respptr->data[pos]);
399 }
Ratan Guptafd28dd72016-08-01 04:58:01 -0500400#endif
401
Ratan Guptafd28dd72016-08-01 04:58:01 -0500402 return rc;
403}
404
Ratan Gupta6ec7daa2017-07-15 14:13:01 +0530405/** @brief convert IPv4 and IPv6 addresses from binary to text form.
406 * @param[in] family - IPv4/Ipv6
407 * @param[in] data - req data pointer.
408 * @param[in] offset - offset in the data.
409 * @param[in] addrSize - size of the data which needs to be read from offset.
410 * @returns address in text form.
411 */
412
413std::string getAddrStr(uint8_t family, uint8_t* data,
414 uint8_t offset, uint8_t addrSize)
415{
416 char ipAddr[INET6_ADDRSTRLEN] = {};
417
418 switch(family)
419 {
420 case AF_INET:
421 {
422 struct sockaddr_in addr4 {};
423 memcpy(&addr4.sin_addr.s_addr, &data[offset], addrSize);
424
425 inet_ntop(AF_INET, &addr4.sin_addr,
426 ipAddr, INET_ADDRSTRLEN);
427
428 break;
429 }
430 case AF_INET6:
431 {
432 struct sockaddr_in6 addr6 {};
433 memcpy(&addr6.sin6_addr.s6_addr, &data[offset], addrSize);
434
435 inet_ntop(AF_INET6, &addr6.sin6_addr,
436 ipAddr, INET6_ADDRSTRLEN);
437
438 break;
439 }
440 default:
441 {
442 return {};
443 }
444 }
445
446 return ipAddr;
447}
448
Ratan Guptadcb10672017-07-10 10:33:50 +0530449int setHostNetworkData(set_sys_boot_options_t* reqptr)
Ratan Guptafd28dd72016-08-01 04:58:01 -0500450{
Ratan Guptadcb10672017-07-10 10:33:50 +0530451 using namespace std::string_literals;
Ratan Guptafd28dd72016-08-01 04:58:01 -0500452 std::string host_network_config;
Ratan Guptad70f4532017-08-04 02:07:31 +0530453 char mac[] {"00:00:00:00:00:00"};
Ratan Gupta6ec7daa2017-07-15 14:13:01 +0530454 std::string ipAddress, gateway;
455 char addrOrigin {0};
456 uint8_t addrSize {0};
Ratan Guptadcb10672017-07-10 10:33:50 +0530457 std::string addressOrigin =
Ratan Gupta6ec7daa2017-07-15 14:13:01 +0530458 "xyz.openbmc_project.Network.IP.AddressOrigin.DHCP";
459 std::string addressType =
460 "xyz.openbmc_project.Network.IP.Protocol.IPv4";
Ratan Guptadcb10672017-07-10 10:33:50 +0530461 uint8_t prefix {0};
462 uint32_t zeroCookie = 0;
Ratan Gupta6ec7daa2017-07-15 14:13:01 +0530463 uint8_t family = AF_INET;
Ratan Guptafd28dd72016-08-01 04:58:01 -0500464
465 //cookie starts from second byte
466 // version starts from sixth byte
467
Ratan Guptadcb10672017-07-10 10:33:50 +0530468 try
Ratan Guptafd28dd72016-08-01 04:58:01 -0500469 {
Ratan Guptadcb10672017-07-10 10:33:50 +0530470 do
471 {
472 // cookie == 0x21 0x70 0x62 0x21
473 if (memcmp(&(reqptr->data[COOKIE_OFFSET]),
474 (net_conf_initial_bytes + COOKIE_OFFSET),
475 SIZE_COOKIE) != 0)
476 {
477 //cookie == 0
478 if (memcmp(&(reqptr->data[COOKIE_OFFSET]),
479 &zeroCookie,
480 SIZE_COOKIE) == 0)
481 {
482 // need to zero out the network settings.
483 break;
484 }
485
486 log<level::ERR>("Invalid Cookie");
487 elog<InternalFailure>();
488 }
489
490 // vesion == 0x00 0x01
491 if (memcmp(&(reqptr->data[VERSION_OFFSET]),
492 (net_conf_initial_bytes + VERSION_OFFSET),
493 SIZE_VERSION) != 0)
494 {
495
496 log<level::ERR>("Invalid Version");
497 elog<InternalFailure>();
498 }
499
500 snprintf(mac, SIZE_MAC, MAC_ADDRESS_FORMAT,
501 reqptr->data[MAC_OFFSET],
502 reqptr->data[MAC_OFFSET + 1],
503 reqptr->data[MAC_OFFSET + 2],
504 reqptr->data[MAC_OFFSET + 3],
505 reqptr->data[MAC_OFFSET + 4],
506 reqptr->data[MAC_OFFSET + 5]);
507
Ratan Gupta6ec7daa2017-07-15 14:13:01 +0530508 memcpy(&addrOrigin, &(reqptr->data[ADDRTYPE_OFFSET]),
509 sizeof(decltype(addrOrigin)));
Ratan Guptadcb10672017-07-10 10:33:50 +0530510
Ratan Gupta6ec7daa2017-07-15 14:13:01 +0530511 if (addrOrigin)
Ratan Guptadcb10672017-07-10 10:33:50 +0530512 {
513 addressOrigin =
Ratan Gupta6ec7daa2017-07-15 14:13:01 +0530514 "xyz.openbmc_project.Network.IP.AddressOrigin.Static";
Ratan Guptadcb10672017-07-10 10:33:50 +0530515 }
516
Ratan Gupta6ec7daa2017-07-15 14:13:01 +0530517 // Get the address size
518 memcpy(&addrSize ,&reqptr->data[ADDR_SIZE_OFFSET], sizeof(addrSize));
Ratan Guptadcb10672017-07-10 10:33:50 +0530519
Ratan Gupta6ec7daa2017-07-15 14:13:01 +0530520 uint8_t prefixOffset = IPADDR_OFFSET + addrSize;
Ratan Guptadcb10672017-07-10 10:33:50 +0530521
Ratan Guptad70f4532017-08-04 02:07:31 +0530522 memcpy(&prefix, &(reqptr->data[prefixOffset]),
523 sizeof(decltype(prefix)));
Ratan Guptadcb10672017-07-10 10:33:50 +0530524
Ratan Gupta6ec7daa2017-07-15 14:13:01 +0530525 uint8_t gatewayOffset = prefixOffset + sizeof(decltype(prefix));
526
527 if (addrSize != IPV4_ADDRESS_SIZE_BYTE)
528 {
529 addressType = "xyz.openbmc_project.Network.IP.Protocol.IPv6";
530 family = AF_INET6;
531 }
532
533 ipAddress = getAddrStr(family, reqptr->data, IPADDR_OFFSET, addrSize);
Ratan Guptad70f4532017-08-04 02:07:31 +0530534
Ratan Gupta6ec7daa2017-07-15 14:13:01 +0530535 gateway = getAddrStr(family, reqptr->data, gatewayOffset, addrSize);
536
Ratan Guptadcb10672017-07-10 10:33:50 +0530537 } while(0);
538
Ratan Guptafd28dd72016-08-01 04:58:01 -0500539 //Cookie == 0 or it is a valid cookie
Ratan Guptadcb10672017-07-10 10:33:50 +0530540 host_network_config += "ipaddress="s + ipAddress +
541 ",prefix="s + std::to_string(prefix) + ",gateway="s + gateway +
542 ",mac="s + mac + ",addressOrigin="s + addressOrigin;
Ratan Guptafd28dd72016-08-01 04:58:01 -0500543
Ratan Guptafd28dd72016-08-01 04:58:01 -0500544
Ratan Guptacc8feb42017-07-25 21:52:10 +0530545 auto ipObjectInfo = ipmi::getDbusObject(IP_INTERFACE, SETTINGS_ROOT,
Ratan Guptadcb10672017-07-10 10:33:50 +0530546 SETTINGS_MATCH);
Ratan Guptacc8feb42017-07-25 21:52:10 +0530547 auto macObjectInfo = ipmi::getDbusObject(MAC_INTERFACE, SETTINGS_ROOT,
Ratan Guptadcb10672017-07-10 10:33:50 +0530548 SETTINGS_MATCH);
549 // set the dbus property
Ratan Guptacc8feb42017-07-25 21:52:10 +0530550 ipmi::setDbusProperty(ipObjectInfo.second, ipObjectInfo.first,
Ratan Guptadcb10672017-07-10 10:33:50 +0530551 IP_INTERFACE, "Address", std::string(ipAddress));
Ratan Guptacc8feb42017-07-25 21:52:10 +0530552 ipmi::setDbusProperty(ipObjectInfo.second, ipObjectInfo.first,
Ratan Guptadcb10672017-07-10 10:33:50 +0530553 IP_INTERFACE, "PrefixLength", prefix);
Ratan Guptacc8feb42017-07-25 21:52:10 +0530554 ipmi::setDbusProperty(ipObjectInfo.second, ipObjectInfo.first,
Ratan Guptadcb10672017-07-10 10:33:50 +0530555 IP_INTERFACE, "Origin", addressOrigin);
Ratan Guptacc8feb42017-07-25 21:52:10 +0530556 ipmi::setDbusProperty(ipObjectInfo.second, ipObjectInfo.first,
Ratan Guptadcb10672017-07-10 10:33:50 +0530557 IP_INTERFACE, "Gateway", std::string(gateway));
Ratan Guptacc8feb42017-07-25 21:52:10 +0530558 ipmi::setDbusProperty(ipObjectInfo.second, ipObjectInfo.first,
Ratan Guptadcb10672017-07-10 10:33:50 +0530559 IP_INTERFACE, "Type",
560 std::string("xyz.openbmc_project.Network.IP.Protocol.IPv4"));
Ratan Guptacc8feb42017-07-25 21:52:10 +0530561 ipmi::setDbusProperty(macObjectInfo.second, macObjectInfo.first,
Ratan Guptadcb10672017-07-10 10:33:50 +0530562 MAC_INTERFACE,"MACAddress", std::string(mac));
Ratan Guptafd28dd72016-08-01 04:58:01 -0500563
Ratan Guptad70f4532017-08-04 02:07:31 +0530564 log<level::DEBUG>("Network configuration changed",
565 entry("NETWORKCONFIG=%s", host_network_config.c_str()));
566
Ratan Guptafd28dd72016-08-01 04:58:01 -0500567 }
Ratan Guptadcb10672017-07-10 10:33:50 +0530568 catch (InternalFailure& e)
569 {
570 commit<InternalFailure>();
571 return -1;
572 }
573
574 return 0;
Ratan Guptafd28dd72016-08-01 04:58:01 -0500575}
576
Andrew Geisslerfca6a4f2017-05-30 10:55:39 -0500577ipmi_ret_t ipmi_chassis_wildcard(ipmi_netfn_t netfn, ipmi_cmd_t cmd,
578 ipmi_request_t request,
579 ipmi_response_t response,
580 ipmi_data_len_t data_len,
581 ipmi_context_t context)
Adriana Kobylak40814c62015-10-27 15:58:44 -0500582{
583 printf("Handling CHASSIS WILDCARD Netfn:[0x%X], Cmd:[0x%X]\n",netfn, cmd);
584 // Status code.
Nan Li70aa8d92016-08-29 00:11:10 +0800585 ipmi_ret_t rc = IPMI_CC_INVALID;
Adriana Kobylak40814c62015-10-27 15:58:44 -0500586 *data_len = 0;
587 return rc;
588}
589
Nan Li8d15fb42016-08-16 22:29:40 +0800590ipmi_ret_t ipmi_get_chassis_cap(ipmi_netfn_t netfn, ipmi_cmd_t cmd,
Andrew Geisslerfca6a4f2017-05-30 10:55:39 -0500591 ipmi_request_t request, ipmi_response_t response,
592 ipmi_data_len_t data_len, ipmi_context_t context)
Nan Li8d15fb42016-08-16 22:29:40 +0800593{
594 // sd_bus error
595 ipmi_ret_t rc = IPMI_CC_OK;
596
597 ipmi_chassis_cap_t chassis_cap{};
598
599 *data_len = sizeof(ipmi_chassis_cap_t);
600
601 // TODO: need future work. Get those flag from MRW.
602
603 // capabilities flags
604 // [7..4] - reserved
605 // [3] – 1b = provides power interlock (IPM 1.5)
606 // [2] – 1b = provides Diagnostic Interrupt (FP NMI)
607 // [1] – 1b = provides “Front Panel Lockout” (indicates that the chassis has capabilities
608 // to lock out external power control and reset button or front panel interfaces
609 // and/or detect tampering with those interfaces).
610 // [0] -1b = Chassis provides intrusion (physical security) sensor.
611 // set to default value 0x0.
612 chassis_cap.cap_flags = 0x0;
613
614 // Since we do not have a separate SDR Device/SEL Device/ FRU repository.
615 // The 20h was given as those 5 device addresses.
616 // Chassis FRU info Device Address
617 chassis_cap.fru_info_dev_addr = 0x20;
618
619 // Chassis SDR Device Address
620 chassis_cap.sdr_dev_addr = 0x20;
621
622 // Chassis SEL Device Address
623 chassis_cap.sel_dev_addr = 0x20;
624
625 // Chassis System Management Device Address
626 chassis_cap.system_management_dev_addr = 0x20;
627
628 // Chassis Bridge Device Address.
629 chassis_cap.bridge_dev_addr = 0x20;
630
631 memcpy(response, &chassis_cap, *data_len);
632
633 return rc;
634}
635
Vishwanatha Subbannab12b0c02017-03-07 18:17:19 +0530636//------------------------------------------
637// Calls into Host State Manager Dbus object
638//------------------------------------------
639int initiate_state_transition(State::Host::Transition transition)
vishwa36993272015-11-20 12:43:49 -0600640{
Andrew Geisslerfca6a4f2017-05-30 10:55:39 -0500641 // OpenBMC Host State Manager dbus framework
642 constexpr auto HOST_STATE_MANAGER_ROOT = "/xyz/openbmc_project/state/host0";
643 constexpr auto HOST_STATE_MANAGER_IFACE = "xyz.openbmc_project.State.Host";
644 constexpr auto DBUS_PROPERTY_IFACE = "org.freedesktop.DBus.Properties";
645 constexpr auto PROPERTY = "RequestedHostTransition";
Vishwanatha Subbannab12b0c02017-03-07 18:17:19 +0530646
Andrew Geisslerfca6a4f2017-05-30 10:55:39 -0500647 // sd_bus error
648 int rc = 0;
649 char *busname = NULL;
vishwa36993272015-11-20 12:43:49 -0600650
Andrew Geisslerfca6a4f2017-05-30 10:55:39 -0500651 // SD Bus error report mechanism.
652 sd_bus_error bus_error = SD_BUS_ERROR_NULL;
vishwa36993272015-11-20 12:43:49 -0600653
Andrew Geisslerfca6a4f2017-05-30 10:55:39 -0500654 // Gets a hook onto either a SYSTEM or SESSION bus
655 sd_bus *bus_type = ipmid_get_sd_bus_connection();
656 rc = mapper_get_service(bus_type, HOST_STATE_MANAGER_ROOT, &busname);
657 if (rc < 0)
658 {
659 log<level::ERR>("Failed to get bus name",
660 entry("ERROR=%s, OBJPATH=%s",
661 strerror(-rc), HOST_STATE_MANAGER_ROOT));
662 return rc;
663 }
Vishwanatha Subbannab12b0c02017-03-07 18:17:19 +0530664
Andrew Geisslerfca6a4f2017-05-30 10:55:39 -0500665 // Convert to string equivalent of the passed in transition enum.
666 auto request = State::convertForMessage(transition);
Vishwanatha Subbannab12b0c02017-03-07 18:17:19 +0530667
Andrew Geisslerfca6a4f2017-05-30 10:55:39 -0500668 rc = sd_bus_call_method(bus_type, // On the system bus
669 busname, // Service to contact
670 HOST_STATE_MANAGER_ROOT, // Object path
671 DBUS_PROPERTY_IFACE, // Interface name
672 "Set", // Method to be called
673 &bus_error, // object to return error
674 nullptr, // Response buffer if any
675 "ssv", // Takes 3 arguments
676 HOST_STATE_MANAGER_IFACE,
677 PROPERTY,
678 "s", request.c_str());
679 if(rc < 0)
680 {
681 log<level::ERR>("Failed to initiate transition",
682 entry("ERROR=%s, REQUEST=%s",
683 bus_error.message, request.c_str()));
684 }
685 else
686 {
687 log<level::INFO>("Transition request initiated successfully");
688 }
vishwa36993272015-11-20 12:43:49 -0600689
690 sd_bus_error_free(&bus_error);
Sergey Solomineb9b8142016-08-23 09:07:28 -0500691 free(busname);
vishwa36993272015-11-20 12:43:49 -0600692
Sergey Solomineb9b8142016-08-23 09:07:28 -0500693 return rc;
vishwa36993272015-11-20 12:43:49 -0600694}
695
Deepak Kodihalli18b70d12017-07-21 13:36:33 -0500696namespace power_policy
Andrew Geisslerfca6a4f2017-05-30 10:55:39 -0500697{
Nan Lifdd8ec52016-08-28 03:57:40 +0800698
Deepak Kodihalli18b70d12017-07-21 13:36:33 -0500699using namespace sdbusplus::xyz::openbmc_project::Control::Power::server;
700using IpmiValue = uint8_t;
701using DbusValue = RestorePolicy::Policy;
Nan Lifdd8ec52016-08-28 03:57:40 +0800702
Deepak Kodihalli18b70d12017-07-21 13:36:33 -0500703std::map<DbusValue, IpmiValue> dbusToIpmi =
704{
705 {RestorePolicy::Policy::AlwaysOff, 0x00},
706 {RestorePolicy::Policy::Restore, 0x01},
707 {RestorePolicy::Policy::AlwaysOn, 0x02}
708};
Nan Lifdd8ec52016-08-28 03:57:40 +0800709
Deepak Kodihalli18b70d12017-07-21 13:36:33 -0500710} // namespace power_policy
Nan Lifdd8ec52016-08-28 03:57:40 +0800711
712//----------------------------------------------------------------------
713// Get Chassis Status commands
714//----------------------------------------------------------------------
715ipmi_ret_t ipmi_get_chassis_status(ipmi_netfn_t netfn, ipmi_cmd_t cmd,
Andrew Geisslerfca6a4f2017-05-30 10:55:39 -0500716 ipmi_request_t request,
717 ipmi_response_t response,
718 ipmi_data_len_t data_len,
719 ipmi_context_t context)
Nan Lifdd8ec52016-08-28 03:57:40 +0800720{
721 const char *objname = "/org/openbmc/control/power0";
722 const char *intf = "org.openbmc.control.Power";
723
724 sd_bus *bus = NULL;
725 sd_bus_message *reply = NULL;
726 int r = 0;
727 int pgood = 0;
728 char *busname = NULL;
729 ipmi_ret_t rc = IPMI_CC_OK;
730 ipmi_get_chassis_status_t chassis_status{};
731
Nan Lifdd8ec52016-08-28 03:57:40 +0800732 uint8_t s = 0;
733
Deepak Kodihalli18b70d12017-07-21 13:36:33 -0500734 using namespace chassis::internal;
735 using namespace chassis::internal::cache;
736 using namespace power_policy;
737
738 const auto& powerRestoreSetting = objects.map.at(powerRestoreIntf);
739 auto method =
740 dbus.new_method_call(
741 objects.service(powerRestoreSetting, powerRestoreIntf).c_str(),
742 powerRestoreSetting.c_str(),
Ratan Guptacc8feb42017-07-25 21:52:10 +0530743 ipmi::PROP_INTF,
Deepak Kodihalli18b70d12017-07-21 13:36:33 -0500744 "Get");
745 method.append(powerRestoreIntf, "PowerRestorePolicy");
746 auto resp = dbus.call(method);
747 if (resp.is_method_error())
748 {
749 log<level::ERR>("Error in PowerRestorePolicy Get");
750 report<InternalFailure>();
751 *data_len = 0;
752 return IPMI_CC_UNSPECIFIED_ERROR;
753 }
754 sdbusplus::message::variant<std::string> result;
755 resp.read(result);
756 auto powerRestore =
757 RestorePolicy::convertPolicyFromString(result.get<std::string>());
Nan Lifdd8ec52016-08-28 03:57:40 +0800758
759 *data_len = 4;
760
Tom Joseph63a00512017-08-09 23:39:59 +0530761 bus = ipmid_get_sd_bus_connection();
762
Nan Lifdd8ec52016-08-28 03:57:40 +0800763 r = mapper_get_service(bus, objname, &busname);
764 if (r < 0) {
765 fprintf(stderr, "Failed to get bus name, return value: %s.\n", strerror(-r));
766 rc = IPMI_CC_UNSPECIFIED_ERROR;
767 goto finish;
768 }
769
770 r = sd_bus_get_property(bus, busname, objname, intf, "pgood", NULL, &reply, "i");
771 if (r < 0) {
772 fprintf(stderr, "Failed to call sd_bus_get_property:%d, %s\n", r, strerror(-r));
773 fprintf(stderr, "Bus: %s, Path: %s, Interface: %s\n",
774 busname, objname, intf);
775 rc = IPMI_CC_UNSPECIFIED_ERROR;
776 goto finish;
777 }
778
779 r = sd_bus_message_read(reply, "i", &pgood);
780 if (r < 0) {
781 fprintf(stderr, "Failed to read sensor: %s\n", strerror(-r));
782 rc = IPMI_CC_UNSPECIFIED_ERROR;
783 goto finish;
784 }
785
786 printf("pgood is 0x%02x\n", pgood);
787
Deepak Kodihalli18b70d12017-07-21 13:36:33 -0500788 s = dbusToIpmi.at(powerRestore);
Nan Lifdd8ec52016-08-28 03:57:40 +0800789
790 // Current Power State
791 // [7] reserved
792 // [6..5] power restore policy
793 // 00b = chassis stays powered off after AC/mains returns
794 // 01b = after AC returns, power is restored to the state that was
795 // in effect when AC/mains was lost.
796 // 10b = chassis always powers up after AC/mains returns
797 // 11b = unknow
798 // Set to 00b, by observing the hardware behavior.
799 // Do we need to define a dbus property to identify the restore policy?
800
801 // [4] power control fault
802 // 1b = controller attempted to turn system power on or off, but
803 // system did not enter desired state.
804 // Set to 0b, since We don't support it..
805
806 // [3] power fault
807 // 1b = fault detected in main power subsystem.
808 // set to 0b. for we don't support it.
809
810 // [2] 1b = interlock (chassis is presently shut down because a chassis
811 // panel interlock switch is active). (IPMI 1.5)
812 // set to 0b, for we don't support it.
813
814 // [1] power overload
815 // 1b = system shutdown because of power overload condition.
816 // set to 0b, for we don't support it.
817
818 // [0] power is on
819 // 1b = system power is on
820 // 0b = system power is off(soft-off S4/S5, or mechanical off)
821
822 chassis_status.cur_power_state = ((s & 0x3)<<5) | (pgood & 0x1);
823
824 // Last Power Event
825 // [7..5] – reserved
826 // [4] – 1b = last ‘Power is on’ state was entered via IPMI command
827 // [3] – 1b = last power down caused by power fault
828 // [2] – 1b = last power down caused by a power interlock being activated
829 // [1] – 1b = last power down caused by a Power overload
830 // [0] – 1b = AC failed
831 // set to 0x0, for we don't support these fields.
832
833 chassis_status.last_power_event = 0;
834
835 // Misc. Chassis State
836 // [7] – reserved
837 // [6] – 1b = Chassis Identify command and state info supported (Optional)
838 // 0b = Chassis Identify command support unspecified via this command.
839 // (The Get Command Support command , if implemented, would still
840 // indicate support for the Chassis Identify command)
841 // [5..4] – Chassis Identify State. Mandatory when bit[6] =1b, reserved (return
842 // as 00b) otherwise. Returns the present chassis identify state.
843 // Refer to the Chassis Identify command for more info.
844 // 00b = chassis identify state = Off
845 // 01b = chassis identify state = Temporary(timed) On
846 // 10b = chassis identify state = Indefinite On
847 // 11b = reserved
848 // [3] – 1b = Cooling/fan fault detected
849 // [2] – 1b = Drive Fault
850 // [1] – 1b = Front Panel Lockout active (power off and reset via chassis
851 // push-buttons disabled.)
852 // [0] – 1b = Chassis Intrusion active
853 // set to 0, for we don't support them.
854 chassis_status.misc_power_state = 0;
855
856 // Front Panel Button Capabilities and disable/enable status(Optional)
857 // set to 0, for we don't support them.
858 chassis_status.front_panel_button_cap_status = 0;
859
860 // Pack the actual response
861 memcpy(response, &chassis_status, *data_len);
862
863finish:
864 free(busname);
865 reply = sd_bus_message_unref(reply);
866
867 return rc;
868}
Chris Austen7888c4d2015-12-03 15:26:20 -0600869
Vishwanatha Subbanna83b5c1c2017-01-25 18:41:51 +0530870//-------------------------------------------------------------
871// Send a command to SoftPowerOff application to stop any timer
872//-------------------------------------------------------------
873int stop_soft_off_timer()
874{
Vishwanatha Subbanna83b5c1c2017-01-25 18:41:51 +0530875 constexpr auto iface = "org.freedesktop.DBus.Properties";
876 constexpr auto soft_off_iface = "xyz.openbmc_project.Ipmi.Internal."
Andrew Geisslerfca6a4f2017-05-30 10:55:39 -0500877 "SoftPowerOff";
Vishwanatha Subbanna83b5c1c2017-01-25 18:41:51 +0530878
879 constexpr auto property = "ResponseReceived";
880 constexpr auto value = "xyz.openbmc_project.Ipmi.Internal."
Andrew Geisslerfca6a4f2017-05-30 10:55:39 -0500881 "SoftPowerOff.HostResponse.HostShutdown";
Vishwanatha Subbanna83b5c1c2017-01-25 18:41:51 +0530882
883 // Get the system bus where most system services are provided.
884 auto bus = ipmid_get_sd_bus_connection();
885
886 // Get the service name
Andrew Geissler2b4e4592017-06-08 11:18:35 -0500887 // TODO openbmc/openbmc#1661 - Mapper refactor
888 //
889 // See openbmc/openbmc#1743 for some details but high level summary is that
890 // for now the code will directly call the soft off interface due to a
891 // race condition with mapper usage
892 //
893 //char *busname = nullptr;
894 //auto r = mapper_get_service(bus, SOFTOFF_OBJPATH, &busname);
895 //if (r < 0)
896 //{
897 // fprintf(stderr, "Failed to get %s bus name: %s\n",
898 // SOFTOFF_OBJPATH, strerror(-r));
899 // return r;
900 //}
Vishwanatha Subbanna83b5c1c2017-01-25 18:41:51 +0530901
902 // No error object or reply expected.
Andrew Geissler2b4e4592017-06-08 11:18:35 -0500903 int rc = sd_bus_call_method(bus, SOFTOFF_BUSNAME, SOFTOFF_OBJPATH, iface,
Andrew Geisslerfca6a4f2017-05-30 10:55:39 -0500904 "Set", nullptr, nullptr, "ssv",
905 soft_off_iface, property, "s", value);
Vishwanatha Subbanna83b5c1c2017-01-25 18:41:51 +0530906 if (rc < 0)
907 {
908 fprintf(stderr, "Failed to set property in SoftPowerOff object: %s\n",
909 strerror(-rc));
910 }
Andrew Geisslerfca6a4f2017-05-30 10:55:39 -0500911
Andrew Geissler2b4e4592017-06-08 11:18:35 -0500912 //TODO openbmc/openbmc#1661 - Mapper refactor
913 //free(busname);
Vishwanatha Subbanna83b5c1c2017-01-25 18:41:51 +0530914 return rc;
915}
916
vishwa36993272015-11-20 12:43:49 -0600917//----------------------------------------------------------------------
Andrew Geisslera6e3a302017-05-31 19:34:00 -0500918// Create file to indicate there is no need for softoff notification to host
919//----------------------------------------------------------------------
920void indicate_no_softoff_needed()
921{
922 fs::path path{HOST_INBAND_REQUEST_DIR};
923 if (!fs::is_directory(path))
924 {
925 fs::create_directory(path);
926 }
927
928 // Add the host instance (default 0 for now) to the file name
929 std::string file{HOST_INBAND_REQUEST_FILE};
930 auto size = std::snprintf(nullptr,0,file.c_str(),0);
931 size++; // null
932 std::unique_ptr<char[]> buf(new char[size]);
933 std::snprintf(buf.get(),size,file.c_str(),0);
934
935 // Append file name to directory and create it
936 path /= buf.get();
937 std::ofstream(path.c_str());
938}
939
940//----------------------------------------------------------------------
vishwa36993272015-11-20 12:43:49 -0600941// Chassis Control commands
942//----------------------------------------------------------------------
Andrew Geisslerfca6a4f2017-05-30 10:55:39 -0500943ipmi_ret_t ipmi_chassis_control(ipmi_netfn_t netfn, ipmi_cmd_t cmd,
944 ipmi_request_t request,
945 ipmi_response_t response,
946 ipmi_data_len_t data_len,
947 ipmi_context_t context)
vishwa36993272015-11-20 12:43:49 -0600948{
Andrew Geisslerfca6a4f2017-05-30 10:55:39 -0500949 // Error from power off.
950 int rc = 0;
vishwa36993272015-11-20 12:43:49 -0600951
Andrew Geisslerfca6a4f2017-05-30 10:55:39 -0500952 // No response for this command.
vishwa36993272015-11-20 12:43:49 -0600953 *data_len = 0;
954
Andrew Geisslerfca6a4f2017-05-30 10:55:39 -0500955 // Catch the actual operaton by peeking into request buffer
956 uint8_t chassis_ctrl_cmd = *(uint8_t *)request;
957 printf("Chassis Control Command: Operation:[0x%X]\n",chassis_ctrl_cmd);
vishwa36993272015-11-20 12:43:49 -0600958
Andrew Geisslerfca6a4f2017-05-30 10:55:39 -0500959 switch(chassis_ctrl_cmd)
960 {
961 case CMD_POWER_ON:
962 rc = initiate_state_transition(State::Host::Transition::On);
963 break;
964 case CMD_POWER_OFF:
965 // Need to Nudge SoftPowerOff application that it needs to stop the
966 // watchdog timer if running.
967 rc = stop_soft_off_timer();
Andrew Geisslera6e3a302017-05-31 19:34:00 -0500968 // Only request the Off transition if the soft power off
969 // application is not running
970 if (rc < 0)
Andrew Geisslerfca6a4f2017-05-30 10:55:39 -0500971 {
Andrew Geisslera6e3a302017-05-31 19:34:00 -0500972 log<level::INFO>("Did not find soft off service so request "
973 "Host:Transition:Off");
974
975 // First create a file to indicate to the soft off application
976 // that it should not run since this is a direct user initiated
977 // power off request (i.e. a power off request that is not
978 // originating via a soft power off SMS request)
979 indicate_no_softoff_needed();
980
981 // Now request the shutdown
982 rc = initiate_state_transition(State::Host::Transition::Off);
Andrew Geisslerfca6a4f2017-05-30 10:55:39 -0500983 }
Andrew Geisslera6e3a302017-05-31 19:34:00 -0500984 else
985 {
986 log<level::INFO>("Soft off is running, so let that stop "
987 "the host");
988 }
989
Andrew Geisslerfca6a4f2017-05-30 10:55:39 -0500990 break;
Vishwanatha Subbanna83b5c1c2017-01-25 18:41:51 +0530991
Andrew Geisslerfca6a4f2017-05-30 10:55:39 -0500992 case CMD_HARD_RESET:
993 case CMD_POWER_CYCLE:
994 // SPEC has a section that says certain implementations can trigger
995 // PowerOn if power is Off when a command to power cycle is
996 // requested
Andrew Geisslera6e3a302017-05-31 19:34:00 -0500997
998 // First create a file to indicate to the soft off application
999 // that it should not run since this is a direct user initiated
1000 // power reboot request (i.e. a reboot request that is not
1001 // originating via a soft power off SMS request)
1002 indicate_no_softoff_needed();
1003
Andrew Geisslerfca6a4f2017-05-30 10:55:39 -05001004 rc = initiate_state_transition(State::Host::Transition::Reboot);
1005 break;
1006 default:
1007 {
1008 fprintf(stderr, "Invalid Chassis Control command:[0x%X] received\n",chassis_ctrl_cmd);
1009 rc = -1;
1010 }
1011 }
vishwa36993272015-11-20 12:43:49 -06001012
Andrew Geisslerfca6a4f2017-05-30 10:55:39 -05001013 return ( (rc < 0) ? IPMI_CC_INVALID : IPMI_CC_OK);
vishwa36993272015-11-20 12:43:49 -06001014}
1015
Deepak Kodihalli8cc19362017-07-21 11:18:38 -05001016namespace boot_options
1017{
1018
1019using namespace sdbusplus::xyz::openbmc_project::Control::Boot::server;
1020using IpmiValue = uint8_t;
1021constexpr auto ipmiDefault = 0;
1022
1023std::map<IpmiValue, Source::Sources> sourceIpmiToDbus =
1024{
1025 {0x01, Source::Sources::Network},
1026 {0x02, Source::Sources::Disk},
1027 {0x05, Source::Sources::ExternalMedia},
1028 {ipmiDefault, Source::Sources::Default}
shgoupfd84fbbf2015-12-17 10:05:51 +08001029};
1030
Deepak Kodihalli8cc19362017-07-21 11:18:38 -05001031std::map<IpmiValue, Mode::Modes> modeIpmiToDbus =
1032{
1033 {0x03, Mode::Modes::Safe},
1034 {0x06, Mode::Modes::Setup},
1035 {ipmiDefault, Mode::Modes::Regular}
shgoupfd84fbbf2015-12-17 10:05:51 +08001036};
1037
Deepak Kodihalli8cc19362017-07-21 11:18:38 -05001038std::map<Source::Sources, IpmiValue> sourceDbusToIpmi =
1039{
1040 {Source::Sources::Network, 0x01},
1041 {Source::Sources::Disk, 0x02},
1042 {Source::Sources::ExternalMedia, 0x05},
1043 {Source::Sources::Default, ipmiDefault}
1044};
shgoupfd84fbbf2015-12-17 10:05:51 +08001045
Deepak Kodihalli8cc19362017-07-21 11:18:38 -05001046std::map<Mode::Modes, IpmiValue> modeDbusToIpmi =
1047{
1048 {Mode::Modes::Safe, 0x03},
1049 {Mode::Modes::Setup, 0x06},
1050 {Mode::Modes::Regular, ipmiDefault}
1051};
shgoupfd84fbbf2015-12-17 10:05:51 +08001052
Deepak Kodihalli8cc19362017-07-21 11:18:38 -05001053} // namespace boot_options
shgoupfd84fbbf2015-12-17 10:05:51 +08001054
Andrew Geisslerfca6a4f2017-05-30 10:55:39 -05001055ipmi_ret_t ipmi_chassis_get_sys_boot_options(ipmi_netfn_t netfn, ipmi_cmd_t cmd,
1056 ipmi_request_t request,
1057 ipmi_response_t response,
1058 ipmi_data_len_t data_len,
1059 ipmi_context_t context)
Adriana Kobylak40814c62015-10-27 15:58:44 -05001060{
Deepak Kodihalli8cc19362017-07-21 11:18:38 -05001061 using namespace boot_options;
shgoupfd84fbbf2015-12-17 10:05:51 +08001062 ipmi_ret_t rc = IPMI_CC_PARM_NOT_SUPPORTED;
1063 char *p = NULL;
1064 get_sys_boot_options_response_t *resp = (get_sys_boot_options_response_t *) response;
1065 get_sys_boot_options_t *reqptr = (get_sys_boot_options_t*) request;
Deepak Kodihalli8cc19362017-07-21 11:18:38 -05001066 IpmiValue bootOption = ipmiDefault;
Adriana Kobylak40814c62015-10-27 15:58:44 -05001067
1068 printf("IPMI GET_SYS_BOOT_OPTIONS\n");
1069
shgoupfd84fbbf2015-12-17 10:05:51 +08001070 memset(resp,0,sizeof(*resp));
1071 resp->version = SET_PARM_VERSION;
1072 resp->parm = 5;
ratagupta6f6bff2016-04-04 06:20:11 -05001073 resp->data[0] = SET_PARM_BOOT_FLAGS_VALID_ONE_TIME;
Adriana Kobylak40814c62015-10-27 15:58:44 -05001074
Adriana Kobylak40814c62015-10-27 15:58:44 -05001075
shgoupfd84fbbf2015-12-17 10:05:51 +08001076 /*
1077 * Parameter #5 means boot flags. Please refer to 28.13 of ipmi doc.
1078 * This is the only parameter used by petitboot.
1079 */
Ratan Guptafd28dd72016-08-01 04:58:01 -05001080 if ( reqptr->parameter == static_cast<uint8_t>
Andrew Geisslerfca6a4f2017-05-30 10:55:39 -05001081 ( BootOptionParameter::BOOT_FLAGS )) {
shgoupfd84fbbf2015-12-17 10:05:51 +08001082
Ratan Guptafd28dd72016-08-01 04:58:01 -05001083 *data_len = static_cast<uint8_t>(BootOptionResponseSize::BOOT_FLAGS);
Deepak Kodihalli8cc19362017-07-21 11:18:38 -05001084 using namespace chassis::internal;
1085 using namespace chassis::internal::cache;
shgoupfd84fbbf2015-12-17 10:05:51 +08001086
Deepak Kodihalli8cc19362017-07-21 11:18:38 -05001087 const auto& bootSourceSetting = objects.map.at(bootSourceIntf);
1088 auto method =
1089 dbus.new_method_call(
1090 objects.service(bootSourceSetting, bootSourceIntf).c_str(),
1091 bootSourceSetting.c_str(),
Ratan Guptacc8feb42017-07-25 21:52:10 +05301092 ipmi::PROP_INTF,
Deepak Kodihalli8cc19362017-07-21 11:18:38 -05001093 "Get");
1094 method.append(bootSourceIntf, "BootSource");
1095 auto reply = dbus.call(method);
1096 if (reply.is_method_error())
ratagupta6f6bff2016-04-04 06:20:11 -05001097 {
Deepak Kodihalli8cc19362017-07-21 11:18:38 -05001098 log<level::ERR>("Error in BootSource Get");
1099 report<InternalFailure>();
1100 *data_len = 0;
1101 return IPMI_CC_UNSPECIFIED_ERROR;
ratagupta6f6bff2016-04-04 06:20:11 -05001102 }
Deepak Kodihalli8cc19362017-07-21 11:18:38 -05001103 sdbusplus::message::variant<std::string> result;
1104 reply.read(result);
1105 auto bootSource =
1106 Source::convertSourcesFromString(result.get<std::string>());
1107
1108 const auto& bootModeSetting = objects.map.at(bootModeIntf);
1109 method = dbus.new_method_call(
1110 objects.service(bootModeSetting, bootModeIntf).c_str(),
1111 bootModeSetting.c_str(),
Ratan Guptacc8feb42017-07-25 21:52:10 +05301112 ipmi::PROP_INTF,
Deepak Kodihalli8cc19362017-07-21 11:18:38 -05001113 "Get");
1114 method.append(bootModeIntf, "BootMode");
1115 reply = dbus.call(method);
1116 if (reply.is_method_error())
1117 {
1118 log<level::ERR>("Error in BootMode Get");
1119 report<InternalFailure>();
1120 *data_len = 0;
1121 return IPMI_CC_UNSPECIFIED_ERROR;
1122 }
1123 reply.read(result);
1124 auto bootMode = Mode::convertModesFromString(result.get<std::string>());
1125
1126 bootOption = sourceDbusToIpmi.at(bootSource);
1127 if ((Mode::Modes::Regular == bootMode) &&
1128 (Source::Sources::Default == bootSource))
1129 {
1130 bootOption = ipmiDefault;
1131 }
1132 else if (Source::Sources::Default == bootSource)
1133 {
1134 bootOption = modeDbusToIpmi.at(bootMode);
1135 }
1136 resp->data[1] = (bootOption << 2);
1137 rc = IPMI_CC_OK;
ratagupta6f6bff2016-04-04 06:20:11 -05001138
1139 /* Get the boot policy */
Deepak Kodihalli8cc19362017-07-21 11:18:38 -05001140 int r = dbus_get_property("boot_policy",&p);
ratagupta6f6bff2016-04-04 06:20:11 -05001141
1142 if (r < 0) {
1143 fprintf(stderr, "Dbus get property(boot_policy) failed for get_sys_boot_options.\n");
1144 rc = IPMI_CC_UNSPECIFIED_ERROR;
1145
1146 } else {
1147
George Keishing012d6a42017-06-14 03:06:48 -05001148 printf("BootPolicy is [%s]\n", p);
Andrew Geisslerfca6a4f2017-05-30 10:55:39 -05001149 resp->data[0] = (strncmp(p,"ONETIME",strlen("ONETIME"))==0) ?
1150 SET_PARM_BOOT_FLAGS_VALID_ONE_TIME:
1151 SET_PARM_BOOT_FLAGS_VALID_PERMANENT;
ratagupta6f6bff2016-04-04 06:20:11 -05001152 rc = IPMI_CC_OK;
1153
1154 }
1155
1156
Ratan Guptafd28dd72016-08-01 04:58:01 -05001157 } else if ( reqptr->parameter == static_cast<uint8_t>
Andrew Geisslerfca6a4f2017-05-30 10:55:39 -05001158 ( BootOptionParameter::OPAL_NETWORK_SETTINGS )) {
Ratan Guptafd28dd72016-08-01 04:58:01 -05001159
Andrew Geisslerfca6a4f2017-05-30 10:55:39 -05001160 *data_len = static_cast<uint8_t>(BootOptionResponseSize::OPAL_NETWORK_SETTINGS);
Ratan Guptafd28dd72016-08-01 04:58:01 -05001161
Andrew Geisslerfca6a4f2017-05-30 10:55:39 -05001162 resp->parm = static_cast<uint8_t>(BootOptionParameter::OPAL_NETWORK_SETTINGS);
Ratan Guptafd28dd72016-08-01 04:58:01 -05001163
Andrew Geisslerfca6a4f2017-05-30 10:55:39 -05001164 int ret = getHostNetworkData(resp);
Ratan Guptafd28dd72016-08-01 04:58:01 -05001165
Andrew Geisslerfca6a4f2017-05-30 10:55:39 -05001166 if (ret < 0) {
Ratan Guptafd28dd72016-08-01 04:58:01 -05001167
Andrew Geisslerfca6a4f2017-05-30 10:55:39 -05001168 fprintf(stderr, "getHostNetworkData failed for get_sys_boot_options.\n");
1169 rc = IPMI_CC_UNSPECIFIED_ERROR;
Ratan Guptafd28dd72016-08-01 04:58:01 -05001170
Andrew Geisslerfca6a4f2017-05-30 10:55:39 -05001171 }else
1172 rc = IPMI_CC_OK;
Ratan Guptafd28dd72016-08-01 04:58:01 -05001173 }
1174
1175 else {
Adriana Kobylak40814c62015-10-27 15:58:44 -05001176 fprintf(stderr, "Unsupported parameter 0x%x\n", reqptr->parameter);
shgoupfd84fbbf2015-12-17 10:05:51 +08001177 }
1178
1179 if (p)
1180 free(p);
1181
Ratan Guptafd28dd72016-08-01 04:58:01 -05001182 if (rc == IPMI_CC_OK)
1183 {
1184 *data_len += 2;
1185 }
1186
shgoupfd84fbbf2015-12-17 10:05:51 +08001187 return rc;
1188}
1189
1190
1191
1192ipmi_ret_t ipmi_chassis_set_sys_boot_options(ipmi_netfn_t netfn, ipmi_cmd_t cmd,
Andrew Geisslerfca6a4f2017-05-30 10:55:39 -05001193 ipmi_request_t request,
1194 ipmi_response_t response,
1195 ipmi_data_len_t data_len,
1196 ipmi_context_t context)
shgoupfd84fbbf2015-12-17 10:05:51 +08001197{
Deepak Kodihalli8cc19362017-07-21 11:18:38 -05001198 using namespace boot_options;
shgoupfd84fbbf2015-12-17 10:05:51 +08001199 ipmi_ret_t rc = IPMI_CC_OK;
shgoupfd84fbbf2015-12-17 10:05:51 +08001200 set_sys_boot_options_t *reqptr = (set_sys_boot_options_t *) request;
1201
Ratan Guptafd28dd72016-08-01 04:58:01 -05001202 printf("IPMI SET_SYS_BOOT_OPTIONS reqptr->parameter =[%d]\n",reqptr->parameter);
1203
shgoupfd84fbbf2015-12-17 10:05:51 +08001204 // This IPMI command does not have any resposne data
1205 *data_len = 0;
1206
1207 /* 000101
1208 * Parameter #5 means boot flags. Please refer to 28.13 of ipmi doc.
1209 * This is the only parameter used by petitboot.
1210 */
Ratan Guptafd28dd72016-08-01 04:58:01 -05001211
Deepak Kodihalli8cc19362017-07-21 11:18:38 -05001212 if (reqptr->parameter == (uint8_t)BootOptionParameter::BOOT_FLAGS)
1213 {
1214 IpmiValue bootOption = ((reqptr->data[1] & 0x3C) >> 2);
1215 using namespace chassis::internal;
1216 using namespace chassis::internal::cache;
shgoupfd84fbbf2015-12-17 10:05:51 +08001217
Deepak Kodihalli8cc19362017-07-21 11:18:38 -05001218 auto modeItr = modeIpmiToDbus.find(bootOption);
1219 auto sourceItr = sourceIpmiToDbus.find(bootOption);
1220 if ((ipmiDefault == bootOption) ||
1221 (sourceIpmiToDbus.end() != sourceItr))
1222 {
1223 sdbusplus::message::variant<std::string> property =
1224 convertForMessage(sourceItr->second);
1225 const auto& bootSourceSetting =
1226 objects.map.at(bootSourceIntf);
1227 auto method =
1228 dbus.new_method_call(
1229 objects.service(bootSourceSetting, bootSourceIntf).c_str(),
1230 bootSourceSetting.c_str(),
Ratan Guptacc8feb42017-07-25 21:52:10 +05301231 ipmi::PROP_INTF,
Deepak Kodihalli8cc19362017-07-21 11:18:38 -05001232 "Set");
1233 method.append(bootSourceIntf, "BootSource", property);
1234 auto reply = dbus.call(method);
1235 if (reply.is_method_error())
1236 {
1237 log<level::ERR>("Error in BootSource Set");
1238 report<InternalFailure>();
1239 *data_len = 0;
1240 return IPMI_CC_UNSPECIFIED_ERROR;
1241 }
1242 }
1243 if ((ipmiDefault == bootOption) ||
1244 (modeIpmiToDbus.end() != modeItr))
1245 {
1246 sdbusplus::message::variant<std::string> property =
1247 convertForMessage(modeItr->second);
1248 const auto& bootModeSetting = objects.map.at(bootModeIntf);
1249 auto method =
1250 dbus.new_method_call(
1251 objects.service(bootModeSetting, bootModeIntf).c_str(),
1252 bootModeSetting.c_str(),
Ratan Guptacc8feb42017-07-25 21:52:10 +05301253 ipmi::PROP_INTF,
Deepak Kodihalli8cc19362017-07-21 11:18:38 -05001254 "Set");
1255 method.append(bootModeIntf, "BootMode", property);
1256 auto reply = dbus.call(method);
1257 if (reply.is_method_error())
1258 {
1259 log<level::ERR>("Error in BootMode Set");
1260 report<InternalFailure>();
1261 *data_len = 0;
1262 return IPMI_CC_UNSPECIFIED_ERROR;
shgoupfd84fbbf2015-12-17 10:05:51 +08001263 }
1264 }
Ratan Guptafd28dd72016-08-01 04:58:01 -05001265
ratagupta6f6bff2016-04-04 06:20:11 -05001266 /* setting the boot policy */
Deepak Kodihalli8cc19362017-07-21 11:18:38 -05001267 std::string value =
1268 (char *)(((reqptr->data[0] & SET_PARM_BOOT_FLAGS_PERMANENT) ==
Andrew Geisslerfca6a4f2017-05-30 10:55:39 -05001269 SET_PARM_BOOT_FLAGS_PERMANENT) ?"PERMANENT":"ONETIME");
ratagupta6f6bff2016-04-04 06:20:11 -05001270
Deepak Kodihalli8cc19362017-07-21 11:18:38 -05001271 printf ( "\nBoot Policy is %s",value.c_str());
1272 int r = dbus_set_property("boot_policy",value.c_str());
ratagupta6f6bff2016-04-04 06:20:11 -05001273
1274 if (r < 0) {
1275 fprintf(stderr, "Dbus set property(boot_policy) failed for set_sys_boot_options.\n");
1276 rc = IPMI_CC_UNSPECIFIED_ERROR;
1277 }
shgoupfd84fbbf2015-12-17 10:05:51 +08001278
Andrew Geisslerfca6a4f2017-05-30 10:55:39 -05001279 } else if (reqptr->parameter ==
1280 (uint8_t)BootOptionParameter::OPAL_NETWORK_SETTINGS) {
Ratan Guptafd28dd72016-08-01 04:58:01 -05001281
1282 int ret = setHostNetworkData(reqptr);
1283 if (ret < 0) {
1284 fprintf(stderr, "setHostNetworkData failed for set_sys_boot_options.\n");
1285 rc = IPMI_CC_UNSPECIFIED_ERROR;
1286 }
1287 }
1288 else {
shgoupfd84fbbf2015-12-17 10:05:51 +08001289 fprintf(stderr, "Unsupported parameter 0x%x\n", reqptr->parameter);
1290 rc = IPMI_CC_PARM_NOT_SUPPORTED;
Adriana Kobylak40814c62015-10-27 15:58:44 -05001291 }
1292
1293 return rc;
1294}
1295
1296void register_netfn_chassis_functions()
1297{
Tom05732372016-09-06 17:21:23 +05301298 // <Wildcard Command>
Adriana Kobylak40814c62015-10-27 15:58:44 -05001299 printf("Registering NetFn:[0x%X], Cmd:[0x%X]\n",NETFUN_CHASSIS, IPMI_CMD_WILDCARD);
Tom05732372016-09-06 17:21:23 +05301300 ipmi_register_callback(NETFUN_CHASSIS, IPMI_CMD_WILDCARD, NULL, ipmi_chassis_wildcard,
1301 PRIVILEGE_USER);
Adriana Kobylak40814c62015-10-27 15:58:44 -05001302
Tom05732372016-09-06 17:21:23 +05301303 // Get Chassis Capabilities
Nan Li8d15fb42016-08-16 22:29:40 +08001304 printf("Registering NetFn:[0x%X], Cmd:[0x%X]\n",NETFUN_CHASSIS, IPMI_CMD_GET_CHASSIS_CAP);
Tom05732372016-09-06 17:21:23 +05301305 ipmi_register_callback(NETFUN_CHASSIS, IPMI_CMD_GET_CHASSIS_CAP, NULL, ipmi_get_chassis_cap,
1306 PRIVILEGE_USER);
Nan Li8d15fb42016-08-16 22:29:40 +08001307
Tom05732372016-09-06 17:21:23 +05301308 // <Get System Boot Options>
Adriana Kobylak40814c62015-10-27 15:58:44 -05001309 printf("Registering NetFn:[0x%X], Cmd:[0x%X]\n",NETFUN_CHASSIS, IPMI_CMD_GET_SYS_BOOT_OPTIONS);
Tom05732372016-09-06 17:21:23 +05301310 ipmi_register_callback(NETFUN_CHASSIS, IPMI_CMD_GET_SYS_BOOT_OPTIONS, NULL,
1311 ipmi_chassis_get_sys_boot_options, PRIVILEGE_OPERATOR);
Adriana Kobylak40814c62015-10-27 15:58:44 -05001312
Tom05732372016-09-06 17:21:23 +05301313 // <Get Chassis Status>
Nan Lifdd8ec52016-08-28 03:57:40 +08001314 printf("Registering NetFn:[0x%X], Cmd:[0x%X]\n",NETFUN_CHASSIS, IPMI_CMD_CHASSIS_STATUS);
Tom05732372016-09-06 17:21:23 +05301315 ipmi_register_callback(NETFUN_CHASSIS, IPMI_CMD_CHASSIS_STATUS, NULL, ipmi_get_chassis_status,
1316 PRIVILEGE_USER);
Nan Lifdd8ec52016-08-28 03:57:40 +08001317
Tom05732372016-09-06 17:21:23 +05301318 // <Chassis Control>
vishwa36993272015-11-20 12:43:49 -06001319 printf("Registering NetFn:[0x%X], Cmd:[0x%X]\n",NETFUN_CHASSIS, IPMI_CMD_CHASSIS_CONTROL);
Tom05732372016-09-06 17:21:23 +05301320 ipmi_register_callback(NETFUN_CHASSIS, IPMI_CMD_CHASSIS_CONTROL, NULL, ipmi_chassis_control,
1321 PRIVILEGE_OPERATOR);
shgoupfd84fbbf2015-12-17 10:05:51 +08001322
Tom05732372016-09-06 17:21:23 +05301323 // <Set System Boot Options>
shgoupfd84fbbf2015-12-17 10:05:51 +08001324 printf("Registering NetFn:[0x%X], Cmd:[0x%X]\n", NETFUN_CHASSIS, IPMI_CMD_SET_SYS_BOOT_OPTIONS);
Tom05732372016-09-06 17:21:23 +05301325 ipmi_register_callback(NETFUN_CHASSIS, IPMI_CMD_SET_SYS_BOOT_OPTIONS, NULL,
1326 ipmi_chassis_set_sys_boot_options, PRIVILEGE_OPERATOR);
vishwa36993272015-11-20 12:43:49 -06001327}