blob: ef5647c7721ef4d0e92836f451acc466f551c832 [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"
Adriana Kobylak40814c62015-10-27 15:58:44 -05003#include <stdio.h>
Ratan Guptafd28dd72016-08-01 04:58:01 -05004#include <stdlib.h>
Adriana Kobylak40814c62015-10-27 15:58:44 -05005#include <stdint.h>
Brad Bishop35518682016-07-22 08:35:41 -04006#include <mapper.h>
Ratan Guptafd28dd72016-08-01 04:58:01 -05007#include <arpa/inet.h>
8#include <netinet/in.h>
9#include <limits.h>
10#include <string.h>
11#include <endian.h>
12#include <sstream>
13#include <array>
Vishwanatha Subbannab12b0c02017-03-07 18:17:19 +053014#include <phosphor-logging/log.hpp>
15#include <xyz/openbmc_project/State/Host/server.hpp>
Vishwanatha Subbannab891a572017-03-31 11:34:48 +053016#include "config.h"
ratagupta6f6bff2016-04-04 06:20:11 -050017
18//Defines
Ratan Guptafd28dd72016-08-01 04:58:01 -050019#define SET_PARM_VERSION 0x01
20#define SET_PARM_BOOT_FLAGS_PERMANENT 0x40 //boot flags data1 7th bit on
ratagupta6f6bff2016-04-04 06:20:11 -050021#define SET_PARM_BOOT_FLAGS_VALID_ONE_TIME 0x80 //boot flags data1 8th bit on
Ratan Guptafd28dd72016-08-01 04:58:01 -050022#define SET_PARM_BOOT_FLAGS_VALID_PERMANENT 0xC0 //boot flags data1 7 & 8 bit on
ratagupta6f6bff2016-04-04 06:20:11 -050023
Ratan Guptafd28dd72016-08-01 04:58:01 -050024constexpr size_t SIZE_MAC = 18;
25constexpr size_t SIZE_BOOT_OPTION = (uint8_t)BootOptionResponseSize::
Andrew Geisslerfca6a4f2017-05-30 10:55:39 -050026 OPAL_NETWORK_SETTINGS;//Maximum size of the boot option parametrs
Ratan Guptafd28dd72016-08-01 04:58:01 -050027constexpr size_t SIZE_PREFIX = 7;
28constexpr size_t MAX_PREFIX_VALUE = 32;
29constexpr size_t SIZE_COOKIE = 4;
30constexpr size_t SIZE_VERSION = 2;
31constexpr auto MAC_ADDRESS_FORMAT = "%hhx:%hhx:%hhx:%hhx:%hhx:%hhx";
32constexpr auto IP_ADDRESS_FORMAT = "%d.%d.%d.%d";
Matthew Barth8b470052016-09-21 10:02:57 -050033constexpr auto PREFIX_FORMAT = "%hhd";
Ratan Guptafd28dd72016-08-01 04:58:01 -050034constexpr auto ADDR_TYPE_FORMAT = "%hhx";
35//PetiBoot-Specific
36static constexpr uint8_t net_conf_initial_bytes[] = {0x80,0x21, 0x70 ,0x62 ,0x21,
Andrew Geisslerfca6a4f2017-05-30 10:55:39 -050037 0x00 ,0x01 ,0x06 ,0x04};
Ratan Guptafd28dd72016-08-01 04:58:01 -050038
39static constexpr size_t COOKIE_OFFSET = 1;
40static constexpr size_t VERSION_OFFSET = 5;
41static constexpr size_t MAC_OFFSET = 9;
42static constexpr size_t ADDRTYPE_OFFSET = 16;
43static constexpr size_t IPADDR_OFFSET = 17;
44static constexpr size_t PREFIX_OFFSET = 21;
45static constexpr size_t GATEWAY_OFFSET = 22;
ratagupta6f6bff2016-04-04 06:20:11 -050046
47
vishwa36993272015-11-20 12:43:49 -060048
shgoupfd84fbbf2015-12-17 10:05:51 +080049
Adriana Kobylak40814c62015-10-27 15:58:44 -050050void register_netfn_chassis_functions() __attribute__((constructor));
51
shgoupfd84fbbf2015-12-17 10:05:51 +080052// Host settings in dbus
53// Service name should be referenced by connection name got via object mapper
54const char *settings_object_name = "/org/openbmc/settings/host0";
55const char *settings_intf_name = "org.freedesktop.DBus.Properties";
56const char *host_intf_name = "org.openbmc.settings.Host";
57
Nan Li8d15fb42016-08-16 22:29:40 +080058typedef struct
59{
60 uint8_t cap_flags;
61 uint8_t fru_info_dev_addr;
62 uint8_t sdr_dev_addr;
63 uint8_t sel_dev_addr;
64 uint8_t system_management_dev_addr;
65 uint8_t bridge_dev_addr;
66}__attribute__((packed)) ipmi_chassis_cap_t;
67
Nan Lifdd8ec52016-08-28 03:57:40 +080068typedef struct
69{
Andrew Geisslerfca6a4f2017-05-30 10:55:39 -050070 uint8_t cur_power_state;
71 uint8_t last_power_event;
72 uint8_t misc_power_state;
73 uint8_t front_panel_button_cap_status;
Nan Lifdd8ec52016-08-28 03:57:40 +080074}__attribute__((packed)) ipmi_get_chassis_status_t;
75
Vishwanatha Subbannab12b0c02017-03-07 18:17:19 +053076// Phosphor Host State manager
77namespace State = sdbusplus::xyz::openbmc_project::State::server;
78
ratagupta6f6bff2016-04-04 06:20:11 -050079int dbus_get_property(const char *name, char **buf)
shgoupfd84fbbf2015-12-17 10:05:51 +080080{
81 sd_bus_error error = SD_BUS_ERROR_NULL;
82 sd_bus_message *m = NULL;
83 sd_bus *bus = NULL;
84 char *temp_buf = NULL;
85 char *connection = NULL;
86 int r;
87
Brad Bishop35518682016-07-22 08:35:41 -040088 // Get the system bus where most system services are provided.
89 bus = ipmid_get_sd_bus_connection();
shgoupfd84fbbf2015-12-17 10:05:51 +080090
Brad Bishop35518682016-07-22 08:35:41 -040091 r = mapper_get_service(bus, settings_object_name, &connection);
shgoupfd84fbbf2015-12-17 10:05:51 +080092 if (r < 0) {
Brad Bishop819ddd42016-10-05 21:19:19 -040093 fprintf(stderr, "Failed to get %s connection: %s\n",
94 settings_object_name, strerror(-r));
shgoupfd84fbbf2015-12-17 10:05:51 +080095 goto finish;
96 }
97
shgoupfd84fbbf2015-12-17 10:05:51 +080098 /*
99 * Bus, service, object path, interface and method are provided to call
100 * the method.
101 * Signatures and input arguments are provided by the arguments at the
102 * end.
103 */
104 r = sd_bus_call_method(bus,
105 connection, /* service to contact */
106 settings_object_name, /* object path */
107 settings_intf_name, /* interface name */
108 "Get", /* method name */
109 &error, /* object to return error in */
110 &m, /* return message on success */
111 "ss", /* input signature */
112 host_intf_name, /* first argument */
ratagupta6f6bff2016-04-04 06:20:11 -0500113 name); /* second argument */
shgoupfd84fbbf2015-12-17 10:05:51 +0800114
115 if (r < 0) {
116 fprintf(stderr, "Failed to issue method call: %s\n", error.message);
117 goto finish;
118 }
119
120 /*
121 * The output should be parsed exactly the same as the output formatting
122 * specified.
123 */
124 r = sd_bus_message_read(m, "v", "s", &temp_buf);
125 if (r < 0) {
126 fprintf(stderr, "Failed to parse response message: %s\n", strerror(-r));
127 goto finish;
128 }
129
Matthew Barth56181052017-01-23 09:36:29 -0600130 *buf = strdup(temp_buf);
Andrew Geisslerfca6a4f2017-05-30 10:55:39 -0500131 /* *buf = (char*) malloc(strlen(temp_buf));
shgoupfd84fbbf2015-12-17 10:05:51 +0800132 if (*buf) {
133 strcpy(*buf, temp_buf);
134 }
Andrew Geisslerfca6a4f2017-05-30 10:55:39 -0500135 */
shgoupfd84fbbf2015-12-17 10:05:51 +0800136 printf("IPMID boot option property get: {%s}.\n", (char *) temp_buf);
137
138finish:
139 sd_bus_error_free(&error);
140 sd_bus_message_unref(m);
141 free(connection);
142
143 return r;
144}
145
ratagupta6f6bff2016-04-04 06:20:11 -0500146int dbus_set_property(const char * name, const char *value)
shgoupfd84fbbf2015-12-17 10:05:51 +0800147{
148 sd_bus_error error = SD_BUS_ERROR_NULL;
149 sd_bus_message *m = NULL;
150 sd_bus *bus = NULL;
151 char *connection = NULL;
152 int r;
153
Brad Bishop35518682016-07-22 08:35:41 -0400154 // Get the system bus where most system services are provided.
155 bus = ipmid_get_sd_bus_connection();
shgoupfd84fbbf2015-12-17 10:05:51 +0800156
Brad Bishop35518682016-07-22 08:35:41 -0400157 r = mapper_get_service(bus, settings_object_name, &connection);
shgoupfd84fbbf2015-12-17 10:05:51 +0800158 if (r < 0) {
Brad Bishop819ddd42016-10-05 21:19:19 -0400159 fprintf(stderr, "Failed to get %s connection: %s\n",
160 settings_object_name, strerror(-r));
shgoupfd84fbbf2015-12-17 10:05:51 +0800161 goto finish;
162 }
163
shgoupfd84fbbf2015-12-17 10:05:51 +0800164 /*
165 * Bus, service, object path, interface and method are provided to call
166 * the method.
167 * Signatures and input arguments are provided by the arguments at the
168 * end.
169 */
170 r = sd_bus_call_method(bus,
171 connection, /* service to contact */
172 settings_object_name, /* object path */
173 settings_intf_name, /* interface name */
174 "Set", /* method name */
175 &error, /* object to return error in */
176 &m, /* return message on success */
177 "ssv", /* input signature */
178 host_intf_name, /* first argument */
ratagupta6f6bff2016-04-04 06:20:11 -0500179 name, /* second argument */
shgoupfd84fbbf2015-12-17 10:05:51 +0800180 "s", /* third argument */
ratagupta6f6bff2016-04-04 06:20:11 -0500181 value); /* fourth argument */
shgoupfd84fbbf2015-12-17 10:05:51 +0800182
183 if (r < 0) {
184 fprintf(stderr, "Failed to issue method call: %s\n", error.message);
185 goto finish;
186 }
187
ratagupta6f6bff2016-04-04 06:20:11 -0500188 printf("IPMID boot option property set: {%s}.\n", value);
shgoupfd84fbbf2015-12-17 10:05:51 +0800189
Andrew Geisslerfca6a4f2017-05-30 10:55:39 -0500190 finish:
shgoupfd84fbbf2015-12-17 10:05:51 +0800191 sd_bus_error_free(&error);
192 sd_bus_message_unref(m);
193 free(connection);
194
195 return r;
196}
197
Adriana Kobylak40814c62015-10-27 15:58:44 -0500198struct get_sys_boot_options_t {
199 uint8_t parameter;
200 uint8_t set;
201 uint8_t block;
202} __attribute__ ((packed));
203
shgoupfd84fbbf2015-12-17 10:05:51 +0800204struct get_sys_boot_options_response_t {
205 uint8_t version;
206 uint8_t parm;
Ratan Guptafd28dd72016-08-01 04:58:01 -0500207 uint8_t data[SIZE_BOOT_OPTION];
shgoupfd84fbbf2015-12-17 10:05:51 +0800208} __attribute__ ((packed));
209
210struct set_sys_boot_options_t {
211 uint8_t parameter;
Ratan Guptafd28dd72016-08-01 04:58:01 -0500212 uint8_t data[SIZE_BOOT_OPTION];
shgoupfd84fbbf2015-12-17 10:05:51 +0800213} __attribute__ ((packed));
214
Ratan Guptafd28dd72016-08-01 04:58:01 -0500215struct host_network_config_t {
216 std::string ipaddress;
217 std::string prefix;
218 std::string gateway;
219 std::string macaddress;
220 std::string addrType;
221
222 host_network_config_t()=default;
223};
224
225void fillNetworkConfig( host_network_config_t & host_config ,
226 const std::string& conf_str ) {
227
228 constexpr auto COMMA_DELIMITER = ",";
229 constexpr auto EQUAL_DELIMITER = "=";
230 size_t commaDelimtrPos = 0;
231 size_t equalDelimtrPos = 0,commaDelimtrPrevPos = 0;
232 std::string value;
233 while ( commaDelimtrPos < conf_str.length() ) {
234
235 commaDelimtrPos = conf_str.find(COMMA_DELIMITER,commaDelimtrPos);
236 //This condition is to extract the last
237 //Substring as we will not be having the delimeter
238 //at end. std::string::npos is -1
239
240 if ( commaDelimtrPos == std::string::npos ) {
241 commaDelimtrPos = conf_str.length();
242 }
243
244 equalDelimtrPos = conf_str.find (EQUAL_DELIMITER,commaDelimtrPrevPos);
245
246 //foo,ipaddress=1234
247 if ( equalDelimtrPos == std::string::npos ) {
248
249 commaDelimtrPos++;
250 commaDelimtrPrevPos= commaDelimtrPos;
251 continue;
252 }
253
254 value = conf_str.substr((equalDelimtrPos+1),
Andrew Geisslerfca6a4f2017-05-30 10:55:39 -0500255 commaDelimtrPos-(equalDelimtrPos+1));
Ratan Guptafd28dd72016-08-01 04:58:01 -0500256
257#ifdef _IPMI_DEBUG_
258 printf ("Name=[%s],Value=[%s],commaDelimtrPos=[%d],\
259 commaDelimtrPrevPos=[%d],equalDelimtrPos=[%d]\n",
260 name.c_str(),value.c_str(),commaDelimtrPos,
261 commaDelimtrPrevPos,equalDelimtrPos);
262#endif
263
264 if ( 0 == conf_str.compare(commaDelimtrPrevPos,
Andrew Geisslerfca6a4f2017-05-30 10:55:39 -0500265 equalDelimtrPos-commaDelimtrPrevPos,
266 "ipaddress" )) {
267 host_config.ipaddress = std::move(value);
Ratan Guptafd28dd72016-08-01 04:58:01 -0500268 }
269 else if ( 0 == conf_str.compare(commaDelimtrPrevPos,
Andrew Geisslerfca6a4f2017-05-30 10:55:39 -0500270 equalDelimtrPos-commaDelimtrPrevPos,
271 "prefix" )) {
272 host_config.prefix = std::move(value);
Ratan Guptafd28dd72016-08-01 04:58:01 -0500273 }
274 else if ( 0 == conf_str.compare(commaDelimtrPrevPos,
Andrew Geisslerfca6a4f2017-05-30 10:55:39 -0500275 equalDelimtrPos-commaDelimtrPrevPos,
276 "gateway" )) {
Ratan Guptafd28dd72016-08-01 04:58:01 -0500277 host_config.gateway = std::move(value);
278 }
279 else if ( 0 == conf_str.compare(commaDelimtrPrevPos,
Andrew Geisslerfca6a4f2017-05-30 10:55:39 -0500280 equalDelimtrPos-commaDelimtrPrevPos,
281 "mac" )) {
Ratan Guptafd28dd72016-08-01 04:58:01 -0500282 host_config.macaddress = std::move(value);
283 }
284 else if ( 0 == conf_str.compare(commaDelimtrPrevPos,
Andrew Geisslerfca6a4f2017-05-30 10:55:39 -0500285 equalDelimtrPos-commaDelimtrPrevPos,
286 "addr_type" )) {
Ratan Guptafd28dd72016-08-01 04:58:01 -0500287 host_config.addrType = std::move(value);
288 }
289
290 commaDelimtrPos++;
291 commaDelimtrPrevPos= commaDelimtrPos;
292 }
293}
294
295int getHostNetworkData(get_sys_boot_options_response_t* respptr)
296{
297
298 char *prop = nullptr;
299 int rc = dbus_get_property("network_config",&prop);
300
301 if ( rc < 0 ) {
302 fprintf(stderr, "Dbus get property(boot_flags) failed\
303 for get_sys_boot_options.\n");
304 return rc;
305 }
306
307 std::string conf_str(prop);
308
309 if ( prop ) {
310
311 free(prop);
312 prop = nullptr;
313 }
314
315 /* network_config property Value would be in the form of
316 * ipaddress=1.1.1.1,prefix=16,gateway=2.2.2.2,mac=11:22:33:44:55:66,dhcp=0
317 */
318
319 /* Parsing the string and fill the hostconfig structure with the
320 * values */
321
322 printf ("Configuration String[%s]\n ",conf_str.c_str());
323
324 host_network_config_t host_config;
325
326 // Fill the host_config from the configuration string
327 fillNetworkConfig(host_config,conf_str);
328
329 //Assigning the index as intialByteLength as it is fixed and prefilled.
330 printf ("host_config.macaddress.c_str()=[%s]\n",host_config.macaddress.c_str());
331 do{
332
333 rc = sscanf(host_config.macaddress.c_str(),MAC_ADDRESS_FORMAT,
Andrew Geisslerfca6a4f2017-05-30 10:55:39 -0500334 (respptr->data+MAC_OFFSET), (respptr->data+MAC_OFFSET+1),
335 (respptr->data+MAC_OFFSET+2),(respptr->data+MAC_OFFSET+3),
336 (respptr->data+MAC_OFFSET+4), (respptr->data+MAC_OFFSET+5));
Ratan Guptafd28dd72016-08-01 04:58:01 -0500337
338
339 if ( rc < 6 ){
340 fprintf(stderr, "sscanf Failed in extracting mac address.\n");
341 rc = -1;
342 break;
343 }
344
345 //Conevrt the dhcp,ipaddress,mask and gateway as hex number
346 respptr->data[MAC_OFFSET+6]=0x00;
347
348 rc = sscanf(host_config.addrType.c_str(),ADDR_TYPE_FORMAT,
Andrew Geisslerfca6a4f2017-05-30 10:55:39 -0500349 (respptr->data+ADDRTYPE_OFFSET));
Ratan Guptafd28dd72016-08-01 04:58:01 -0500350
351 if ( rc <= 0 ) {
352 fprintf(stderr, "sscanf Failed in extracting address type.\n");
353 rc = -1;
354 break;
355 }
356
357 //ipaddress and gateway would be in IPv4 format
358 rc = inet_pton(AF_INET,host_config.ipaddress.c_str(),
Andrew Geisslerfca6a4f2017-05-30 10:55:39 -0500359 (respptr->data+IPADDR_OFFSET));
Ratan Guptafd28dd72016-08-01 04:58:01 -0500360
361 if ( rc <= 0 ) {
362 fprintf(stderr, "inet_pton failed during ipaddress coneversion\n");
363 rc = -1;
364 break;
365 }
366
367 rc = sscanf(host_config.prefix.c_str(),PREFIX_FORMAT,
Andrew Geisslerfca6a4f2017-05-30 10:55:39 -0500368 (respptr->data+PREFIX_OFFSET));
Ratan Guptafd28dd72016-08-01 04:58:01 -0500369
370 if ( rc <= 0 ) {
371 fprintf(stderr, "sscanf failed during prefix extraction.\n");
372 rc = -1;
373 break;
374 }
375
376 rc = inet_pton(AF_INET,host_config.gateway.c_str(),
Andrew Geisslerfca6a4f2017-05-30 10:55:39 -0500377 (respptr->data+GATEWAY_OFFSET));
Ratan Guptafd28dd72016-08-01 04:58:01 -0500378
379 if ( rc <= 0 ) {
380 fprintf(stderr, "inet_pton failed during gateway conversion.\n");
381 rc = -1;
382 break;
383 }
384
385 }while (0);
386
387 if ( rc ) {
388
389 //PetiBoot-Specific
390 //If sucess then copy the first 9 bytes to the data
391 //else set the respptr to 0
392
393 memcpy(respptr->data,net_conf_initial_bytes,
Andrew Geisslerfca6a4f2017-05-30 10:55:39 -0500394 sizeof(net_conf_initial_bytes));
Ratan Guptafd28dd72016-08-01 04:58:01 -0500395
396#ifdef _IPMI_DEBUG_
397 printf ("\n===Printing the IPMI Formatted Data========\n");
398
399 for ( uint8_t pos = 0; pos<index; pos++ )
400 printf("%02x ", respptr->data[pos]);
401#endif
402
403 }else {
404
405 memset(respptr->data,0,SIZE_BOOT_OPTION);
406 }
407
408 return rc;
409}
410
411int setHostNetworkData(set_sys_boot_options_t * reqptr)
412{
413 std::string host_network_config;
414 char mac[SIZE_MAC] = {0};
415 char ipAddress[INET_ADDRSTRLEN] = {0};
416 char gateway[INET_ADDRSTRLEN] = {0};
417 char dhcp[SIZE_PREFIX] = {0};
418 char prefix[SIZE_PREFIX] = {0};
419 int rc = 0;
420 uint32_t zeroCookie=0;
421
422 //cookie starts from second byte
423 // version starts from sixth byte
424
425 do {
426
427 // cookie == 0x21 0x70 0x62 0x21
428 if ( memcmp(&(reqptr->data[COOKIE_OFFSET]),
429 (net_conf_initial_bytes+COOKIE_OFFSET),
430 SIZE_COOKIE) != 0 ) {
431 //cookie == 0
432 if ( memcmp(&(reqptr->data[COOKIE_OFFSET]),
Andrew Geisslerfca6a4f2017-05-30 10:55:39 -0500433 &zeroCookie,
434 SIZE_COOKIE) == 0 ) {
Ratan Guptafd28dd72016-08-01 04:58:01 -0500435 rc = 0;
436 break;
437 }
438 //Invalid cookie
439 fprintf(stderr, "Invalid Cookie\n");
440 rc = -1;
441 break;
442 }
443 // vesion == 0x00 0x01
444 if ( memcmp(&(reqptr->data[VERSION_OFFSET]),
445 (net_conf_initial_bytes+VERSION_OFFSET),
446 SIZE_VERSION) != 0 ) {
447
448 fprintf(stderr, "Invalid Version\n");
449 rc = -1;
450 break;
451 }
452
453 snprintf(mac, SIZE_MAC, MAC_ADDRESS_FORMAT,
Andrew Geisslerfca6a4f2017-05-30 10:55:39 -0500454 reqptr->data[MAC_OFFSET],
455 reqptr->data[MAC_OFFSET+1],
456 reqptr->data[MAC_OFFSET+2],
457 reqptr->data[MAC_OFFSET+3],
458 reqptr->data[MAC_OFFSET+4],
459 reqptr->data[MAC_OFFSET+5]);
Ratan Guptafd28dd72016-08-01 04:58:01 -0500460
461 snprintf(dhcp,SIZE_PREFIX, ADDR_TYPE_FORMAT, reqptr->data[ADDRTYPE_OFFSET]);
462 //Validating the address type which could be
463 //either static or dynamic
464 if( *(reqptr->data+ADDRTYPE_OFFSET) > 1 ) {
465
466 fprintf(stderr, "Invalid Address Type\n");
467 rc = -1;
468 break;
469
470 }
471
472 snprintf(ipAddress, INET_ADDRSTRLEN, IP_ADDRESS_FORMAT,
Andrew Geisslerfca6a4f2017-05-30 10:55:39 -0500473 reqptr->data[IPADDR_OFFSET], reqptr->data[IPADDR_OFFSET+1],
474 reqptr->data[IPADDR_OFFSET+2], reqptr->data[IPADDR_OFFSET+3]);
Ratan Guptafd28dd72016-08-01 04:58:01 -0500475
476 //validating prefix
477 if ( *(reqptr->data+PREFIX_OFFSET) > (uint8_t)MAX_PREFIX_VALUE ) {
478
479 fprintf(stderr, "Invalid Prefix\n");
480 rc = -1;
481 break;
482 }
483
484 snprintf(prefix,SIZE_PREFIX,PREFIX_FORMAT, reqptr->data[PREFIX_OFFSET]);
485
486 snprintf(gateway, INET_ADDRSTRLEN,IP_ADDRESS_FORMAT,
Andrew Geisslerfca6a4f2017-05-30 10:55:39 -0500487 reqptr->data[GATEWAY_OFFSET],
488 reqptr->data[GATEWAY_OFFSET+1],
489 reqptr->data[GATEWAY_OFFSET+2],
490 reqptr->data[GATEWAY_OFFSET+3]);
Ratan Guptafd28dd72016-08-01 04:58:01 -0500491
492
493 }while(0);
494
495 if( !rc )
496 {
497 //Cookie == 0 or it is a valid cookie
Andrew Geisslerfca6a4f2017-05-30 10:55:39 -0500498 host_network_config += "ipaddress="+std::string(ipAddress)+",prefix="+
499 std::string(prefix)+",gateway="+std::string(gateway)+
500 ",mac="+std::string(mac)+",addr_type="+std::string(dhcp);
Ratan Guptafd28dd72016-08-01 04:58:01 -0500501
502 printf ("Network configuration changed: %s\n",host_network_config.c_str());
503
504 rc = dbus_set_property("network_config",host_network_config.c_str());
505
506 if ( rc < 0 ) {
507 fprintf(stderr, "Dbus set property(network_config)\
508 failed for set_sys_boot_options.\n");
509 rc = -1;
510 }
511
512 }
513 return rc;
514}
515
Andrew Geisslerfca6a4f2017-05-30 10:55:39 -0500516ipmi_ret_t ipmi_chassis_wildcard(ipmi_netfn_t netfn, ipmi_cmd_t cmd,
517 ipmi_request_t request,
518 ipmi_response_t response,
519 ipmi_data_len_t data_len,
520 ipmi_context_t context)
Adriana Kobylak40814c62015-10-27 15:58:44 -0500521{
522 printf("Handling CHASSIS WILDCARD Netfn:[0x%X], Cmd:[0x%X]\n",netfn, cmd);
523 // Status code.
Nan Li70aa8d92016-08-29 00:11:10 +0800524 ipmi_ret_t rc = IPMI_CC_INVALID;
Adriana Kobylak40814c62015-10-27 15:58:44 -0500525 *data_len = 0;
526 return rc;
527}
528
Nan Li8d15fb42016-08-16 22:29:40 +0800529ipmi_ret_t ipmi_get_chassis_cap(ipmi_netfn_t netfn, ipmi_cmd_t cmd,
Andrew Geisslerfca6a4f2017-05-30 10:55:39 -0500530 ipmi_request_t request, ipmi_response_t response,
531 ipmi_data_len_t data_len, ipmi_context_t context)
Nan Li8d15fb42016-08-16 22:29:40 +0800532{
533 // sd_bus error
534 ipmi_ret_t rc = IPMI_CC_OK;
535
536 ipmi_chassis_cap_t chassis_cap{};
537
538 *data_len = sizeof(ipmi_chassis_cap_t);
539
540 // TODO: need future work. Get those flag from MRW.
541
542 // capabilities flags
543 // [7..4] - reserved
544 // [3] – 1b = provides power interlock (IPM 1.5)
545 // [2] – 1b = provides Diagnostic Interrupt (FP NMI)
546 // [1] – 1b = provides “Front Panel Lockout” (indicates that the chassis has capabilities
547 // to lock out external power control and reset button or front panel interfaces
548 // and/or detect tampering with those interfaces).
549 // [0] -1b = Chassis provides intrusion (physical security) sensor.
550 // set to default value 0x0.
551 chassis_cap.cap_flags = 0x0;
552
553 // Since we do not have a separate SDR Device/SEL Device/ FRU repository.
554 // The 20h was given as those 5 device addresses.
555 // Chassis FRU info Device Address
556 chassis_cap.fru_info_dev_addr = 0x20;
557
558 // Chassis SDR Device Address
559 chassis_cap.sdr_dev_addr = 0x20;
560
561 // Chassis SEL Device Address
562 chassis_cap.sel_dev_addr = 0x20;
563
564 // Chassis System Management Device Address
565 chassis_cap.system_management_dev_addr = 0x20;
566
567 // Chassis Bridge Device Address.
568 chassis_cap.bridge_dev_addr = 0x20;
569
570 memcpy(response, &chassis_cap, *data_len);
571
572 return rc;
573}
574
Vishwanatha Subbannab12b0c02017-03-07 18:17:19 +0530575//------------------------------------------
576// Calls into Host State Manager Dbus object
577//------------------------------------------
578int initiate_state_transition(State::Host::Transition transition)
vishwa36993272015-11-20 12:43:49 -0600579{
Andrew Geisslerfca6a4f2017-05-30 10:55:39 -0500580 using namespace phosphor::logging;
Vishwanatha Subbannab12b0c02017-03-07 18:17:19 +0530581
Andrew Geisslerfca6a4f2017-05-30 10:55:39 -0500582 // OpenBMC Host State Manager dbus framework
583 constexpr auto HOST_STATE_MANAGER_ROOT = "/xyz/openbmc_project/state/host0";
584 constexpr auto HOST_STATE_MANAGER_IFACE = "xyz.openbmc_project.State.Host";
585 constexpr auto DBUS_PROPERTY_IFACE = "org.freedesktop.DBus.Properties";
586 constexpr auto PROPERTY = "RequestedHostTransition";
Vishwanatha Subbannab12b0c02017-03-07 18:17:19 +0530587
Andrew Geisslerfca6a4f2017-05-30 10:55:39 -0500588 // sd_bus error
589 int rc = 0;
590 char *busname = NULL;
vishwa36993272015-11-20 12:43:49 -0600591
Andrew Geisslerfca6a4f2017-05-30 10:55:39 -0500592 // SD Bus error report mechanism.
593 sd_bus_error bus_error = SD_BUS_ERROR_NULL;
vishwa36993272015-11-20 12:43:49 -0600594
Andrew Geisslerfca6a4f2017-05-30 10:55:39 -0500595 // Gets a hook onto either a SYSTEM or SESSION bus
596 sd_bus *bus_type = ipmid_get_sd_bus_connection();
597 rc = mapper_get_service(bus_type, HOST_STATE_MANAGER_ROOT, &busname);
598 if (rc < 0)
599 {
600 log<level::ERR>("Failed to get bus name",
601 entry("ERROR=%s, OBJPATH=%s",
602 strerror(-rc), HOST_STATE_MANAGER_ROOT));
603 return rc;
604 }
Vishwanatha Subbannab12b0c02017-03-07 18:17:19 +0530605
Andrew Geisslerfca6a4f2017-05-30 10:55:39 -0500606 // Convert to string equivalent of the passed in transition enum.
607 auto request = State::convertForMessage(transition);
Vishwanatha Subbannab12b0c02017-03-07 18:17:19 +0530608
Andrew Geisslerfca6a4f2017-05-30 10:55:39 -0500609 rc = sd_bus_call_method(bus_type, // On the system bus
610 busname, // Service to contact
611 HOST_STATE_MANAGER_ROOT, // Object path
612 DBUS_PROPERTY_IFACE, // Interface name
613 "Set", // Method to be called
614 &bus_error, // object to return error
615 nullptr, // Response buffer if any
616 "ssv", // Takes 3 arguments
617 HOST_STATE_MANAGER_IFACE,
618 PROPERTY,
619 "s", request.c_str());
620 if(rc < 0)
621 {
622 log<level::ERR>("Failed to initiate transition",
623 entry("ERROR=%s, REQUEST=%s",
624 bus_error.message, request.c_str()));
625 }
626 else
627 {
628 log<level::INFO>("Transition request initiated successfully");
629 }
vishwa36993272015-11-20 12:43:49 -0600630
631 sd_bus_error_free(&bus_error);
Sergey Solomineb9b8142016-08-23 09:07:28 -0500632 free(busname);
vishwa36993272015-11-20 12:43:49 -0600633
Sergey Solomineb9b8142016-08-23 09:07:28 -0500634 return rc;
vishwa36993272015-11-20 12:43:49 -0600635}
636
Andrew Geisslerfca6a4f2017-05-30 10:55:39 -0500637struct hostPowerPolicyTypeMap_t
638{
Nan Lifdd8ec52016-08-28 03:57:40 +0800639 uint8_t policyNum;
640 char policyName[19];
641};
642
643hostPowerPolicyTypeMap_t g_hostPowerPolicyTypeMap_t[] = {
644
Andrew Geisslerfca6a4f2017-05-30 10:55:39 -0500645 {0x00, "LEAVE_OFF"},
646 {0x01, "RESTORE_LAST_STATE"},
647 {0x02, "ALWAYS_POWER_ON"},
648 {0x03, "UNKNOWN"}
Nan Lifdd8ec52016-08-28 03:57:40 +0800649};
650
Andrew Geisslerfca6a4f2017-05-30 10:55:39 -0500651uint8_t get_host_power_policy(char *p)
652{
Nan Lifdd8ec52016-08-28 03:57:40 +0800653
654 hostPowerPolicyTypeMap_t *s = g_hostPowerPolicyTypeMap_t;
655
656 while (s->policyNum != 0x03) {
657 if (!strcmp(s->policyName,p))
658 break;
659 s++;
660 }
661
662 return s->policyNum;
663}
664
665//----------------------------------------------------------------------
666// Get Chassis Status commands
667//----------------------------------------------------------------------
668ipmi_ret_t ipmi_get_chassis_status(ipmi_netfn_t netfn, ipmi_cmd_t cmd,
Andrew Geisslerfca6a4f2017-05-30 10:55:39 -0500669 ipmi_request_t request,
670 ipmi_response_t response,
671 ipmi_data_len_t data_len,
672 ipmi_context_t context)
Nan Lifdd8ec52016-08-28 03:57:40 +0800673{
674 const char *objname = "/org/openbmc/control/power0";
675 const char *intf = "org.openbmc.control.Power";
676
677 sd_bus *bus = NULL;
678 sd_bus_message *reply = NULL;
679 int r = 0;
680 int pgood = 0;
681 char *busname = NULL;
682 ipmi_ret_t rc = IPMI_CC_OK;
683 ipmi_get_chassis_status_t chassis_status{};
684
685 char *p = NULL;
686 uint8_t s = 0;
687
688 // Get the system bus where most system services are provided.
689 bus = ipmid_get_sd_bus_connection();
690
691 *data_len = 4;
692
693 r = mapper_get_service(bus, objname, &busname);
694 if (r < 0) {
695 fprintf(stderr, "Failed to get bus name, return value: %s.\n", strerror(-r));
696 rc = IPMI_CC_UNSPECIFIED_ERROR;
697 goto finish;
698 }
699
700 r = sd_bus_get_property(bus, busname, objname, intf, "pgood", NULL, &reply, "i");
701 if (r < 0) {
702 fprintf(stderr, "Failed to call sd_bus_get_property:%d, %s\n", r, strerror(-r));
703 fprintf(stderr, "Bus: %s, Path: %s, Interface: %s\n",
704 busname, objname, intf);
705 rc = IPMI_CC_UNSPECIFIED_ERROR;
706 goto finish;
707 }
708
709 r = sd_bus_message_read(reply, "i", &pgood);
710 if (r < 0) {
711 fprintf(stderr, "Failed to read sensor: %s\n", strerror(-r));
712 rc = IPMI_CC_UNSPECIFIED_ERROR;
713 goto finish;
714 }
715
716 printf("pgood is 0x%02x\n", pgood);
717
718 // Get Power Policy
719 r = dbus_get_property("power_policy",&p);
720
721 if (r < 0) {
722 fprintf(stderr, "Dbus get property(power_policy) failed for get_sys_boot_options.\n");
723 rc = IPMI_CC_UNSPECIFIED_ERROR;
724 } else {
725 s = get_host_power_policy(p);
726 }
727
728 if (p)
729 {
Andrew Geisslerfca6a4f2017-05-30 10:55:39 -0500730 free(p);
731 p = NULL;
Nan Lifdd8ec52016-08-28 03:57:40 +0800732 }
733
734 // Current Power State
735 // [7] reserved
736 // [6..5] power restore policy
737 // 00b = chassis stays powered off after AC/mains returns
738 // 01b = after AC returns, power is restored to the state that was
739 // in effect when AC/mains was lost.
740 // 10b = chassis always powers up after AC/mains returns
741 // 11b = unknow
742 // Set to 00b, by observing the hardware behavior.
743 // Do we need to define a dbus property to identify the restore policy?
744
745 // [4] power control fault
746 // 1b = controller attempted to turn system power on or off, but
747 // system did not enter desired state.
748 // Set to 0b, since We don't support it..
749
750 // [3] power fault
751 // 1b = fault detected in main power subsystem.
752 // set to 0b. for we don't support it.
753
754 // [2] 1b = interlock (chassis is presently shut down because a chassis
755 // panel interlock switch is active). (IPMI 1.5)
756 // set to 0b, for we don't support it.
757
758 // [1] power overload
759 // 1b = system shutdown because of power overload condition.
760 // set to 0b, for we don't support it.
761
762 // [0] power is on
763 // 1b = system power is on
764 // 0b = system power is off(soft-off S4/S5, or mechanical off)
765
766 chassis_status.cur_power_state = ((s & 0x3)<<5) | (pgood & 0x1);
767
768 // Last Power Event
769 // [7..5] – reserved
770 // [4] – 1b = last ‘Power is on’ state was entered via IPMI command
771 // [3] – 1b = last power down caused by power fault
772 // [2] – 1b = last power down caused by a power interlock being activated
773 // [1] – 1b = last power down caused by a Power overload
774 // [0] – 1b = AC failed
775 // set to 0x0, for we don't support these fields.
776
777 chassis_status.last_power_event = 0;
778
779 // Misc. Chassis State
780 // [7] – reserved
781 // [6] – 1b = Chassis Identify command and state info supported (Optional)
782 // 0b = Chassis Identify command support unspecified via this command.
783 // (The Get Command Support command , if implemented, would still
784 // indicate support for the Chassis Identify command)
785 // [5..4] – Chassis Identify State. Mandatory when bit[6] =1b, reserved (return
786 // as 00b) otherwise. Returns the present chassis identify state.
787 // Refer to the Chassis Identify command for more info.
788 // 00b = chassis identify state = Off
789 // 01b = chassis identify state = Temporary(timed) On
790 // 10b = chassis identify state = Indefinite On
791 // 11b = reserved
792 // [3] – 1b = Cooling/fan fault detected
793 // [2] – 1b = Drive Fault
794 // [1] – 1b = Front Panel Lockout active (power off and reset via chassis
795 // push-buttons disabled.)
796 // [0] – 1b = Chassis Intrusion active
797 // set to 0, for we don't support them.
798 chassis_status.misc_power_state = 0;
799
800 // Front Panel Button Capabilities and disable/enable status(Optional)
801 // set to 0, for we don't support them.
802 chassis_status.front_panel_button_cap_status = 0;
803
804 // Pack the actual response
805 memcpy(response, &chassis_status, *data_len);
806
807finish:
808 free(busname);
809 reply = sd_bus_message_unref(reply);
810
811 return rc;
812}
Chris Austen7888c4d2015-12-03 15:26:20 -0600813
Vishwanatha Subbanna83b5c1c2017-01-25 18:41:51 +0530814//-------------------------------------------------------------
815// Send a command to SoftPowerOff application to stop any timer
816//-------------------------------------------------------------
817int stop_soft_off_timer()
818{
Vishwanatha Subbanna83b5c1c2017-01-25 18:41:51 +0530819 constexpr auto iface = "org.freedesktop.DBus.Properties";
820 constexpr auto soft_off_iface = "xyz.openbmc_project.Ipmi.Internal."
Andrew Geisslerfca6a4f2017-05-30 10:55:39 -0500821 "SoftPowerOff";
Vishwanatha Subbanna83b5c1c2017-01-25 18:41:51 +0530822
823 constexpr auto property = "ResponseReceived";
824 constexpr auto value = "xyz.openbmc_project.Ipmi.Internal."
Andrew Geisslerfca6a4f2017-05-30 10:55:39 -0500825 "SoftPowerOff.HostResponse.HostShutdown";
Vishwanatha Subbanna83b5c1c2017-01-25 18:41:51 +0530826 char *busname = nullptr;
827
828 // Get the system bus where most system services are provided.
829 auto bus = ipmid_get_sd_bus_connection();
830
831 // Get the service name
Vishwanatha Subbannab891a572017-03-31 11:34:48 +0530832 auto r = mapper_get_service(bus, SOFTOFF_OBJPATH, &busname);
Andrew Geisslerfca6a4f2017-05-30 10:55:39 -0500833 if (r < 0)
834 {
Vishwanatha Subbanna83b5c1c2017-01-25 18:41:51 +0530835 fprintf(stderr, "Failed to get %s bus name: %s\n",
Vishwanatha Subbannab891a572017-03-31 11:34:48 +0530836 SOFTOFF_OBJPATH, strerror(-r));
Vishwanatha Subbanna83b5c1c2017-01-25 18:41:51 +0530837 return r;
838 }
839
840 // No error object or reply expected.
Vishwanatha Subbannab891a572017-03-31 11:34:48 +0530841 int rc = sd_bus_call_method(bus, busname, SOFTOFF_OBJPATH, iface,
Andrew Geisslerfca6a4f2017-05-30 10:55:39 -0500842 "Set", nullptr, nullptr, "ssv",
843 soft_off_iface, property, "s", value);
Vishwanatha Subbanna83b5c1c2017-01-25 18:41:51 +0530844 if (rc < 0)
845 {
846 fprintf(stderr, "Failed to set property in SoftPowerOff object: %s\n",
847 strerror(-rc));
848 }
Andrew Geisslerfca6a4f2017-05-30 10:55:39 -0500849
Vishwanatha Subbanna83b5c1c2017-01-25 18:41:51 +0530850 free(busname);
851 return rc;
852}
853
vishwa36993272015-11-20 12:43:49 -0600854//----------------------------------------------------------------------
855// Chassis Control commands
856//----------------------------------------------------------------------
Andrew Geisslerfca6a4f2017-05-30 10:55:39 -0500857ipmi_ret_t ipmi_chassis_control(ipmi_netfn_t netfn, ipmi_cmd_t cmd,
858 ipmi_request_t request,
859 ipmi_response_t response,
860 ipmi_data_len_t data_len,
861 ipmi_context_t context)
vishwa36993272015-11-20 12:43:49 -0600862{
Andrew Geisslerfca6a4f2017-05-30 10:55:39 -0500863 // Error from power off.
864 int rc = 0;
vishwa36993272015-11-20 12:43:49 -0600865
Andrew Geisslerfca6a4f2017-05-30 10:55:39 -0500866 // No response for this command.
vishwa36993272015-11-20 12:43:49 -0600867 *data_len = 0;
868
Andrew Geisslerfca6a4f2017-05-30 10:55:39 -0500869 // Catch the actual operaton by peeking into request buffer
870 uint8_t chassis_ctrl_cmd = *(uint8_t *)request;
871 printf("Chassis Control Command: Operation:[0x%X]\n",chassis_ctrl_cmd);
vishwa36993272015-11-20 12:43:49 -0600872
Andrew Geisslerfca6a4f2017-05-30 10:55:39 -0500873 switch(chassis_ctrl_cmd)
874 {
875 case CMD_POWER_ON:
876 rc = initiate_state_transition(State::Host::Transition::On);
877 break;
878 case CMD_POWER_OFF:
879 // Need to Nudge SoftPowerOff application that it needs to stop the
880 // watchdog timer if running.
881 rc = stop_soft_off_timer();
882 if (!rc)
883 {
884 fprintf(stderr, "Error stopping watchdog timer");
885 }
886 // Does not matter if we are able to stop the timer,
887 // just get going and do the hard power off
888 rc = initiate_state_transition(State::Host::Transition::Off);
889 break;
Vishwanatha Subbanna83b5c1c2017-01-25 18:41:51 +0530890
Andrew Geisslerfca6a4f2017-05-30 10:55:39 -0500891 case CMD_HARD_RESET:
892 case CMD_POWER_CYCLE:
893 // SPEC has a section that says certain implementations can trigger
894 // PowerOn if power is Off when a command to power cycle is
895 // requested
896 rc = initiate_state_transition(State::Host::Transition::Reboot);
897 break;
898 default:
899 {
900 fprintf(stderr, "Invalid Chassis Control command:[0x%X] received\n",chassis_ctrl_cmd);
901 rc = -1;
902 }
903 }
vishwa36993272015-11-20 12:43:49 -0600904
Andrew Geisslerfca6a4f2017-05-30 10:55:39 -0500905 return ( (rc < 0) ? IPMI_CC_INVALID : IPMI_CC_OK);
vishwa36993272015-11-20 12:43:49 -0600906}
907
shgoupfd84fbbf2015-12-17 10:05:51 +0800908struct bootOptionTypeMap_t {
909 uint8_t ipmibootflag;
910 char dbusname[8];
911};
912
913#define INVALID_STRING "Invalid"
914// dbus supports this list of boot devices.
915bootOptionTypeMap_t g_bootOptionTypeMap_t[] = {
916
Andrew Geisslerfca6a4f2017-05-30 10:55:39 -0500917 {0x01, "Network"},
918 {0x02, "Disk"},
919 {0x03, "Safe"},
920 {0x05, "CDROM"},
921 {0x06, "Setup"},
922 {0x00, "Default"},
923 {0xFF, INVALID_STRING}
shgoupfd84fbbf2015-12-17 10:05:51 +0800924};
925
926uint8_t get_ipmi_boot_option(char *p) {
927
928 bootOptionTypeMap_t *s = g_bootOptionTypeMap_t;
929
930 while (s->ipmibootflag != 0xFF) {
931 if (!strcmp(s->dbusname,p))
932 break;
933 s++;
934 }
935
936 if (!s->ipmibootflag)
937 printf("Failed to find Sensor Type %s\n", p);
938
939 return s->ipmibootflag;
940}
941
942char* get_boot_option_by_ipmi(uint8_t p) {
943
944 bootOptionTypeMap_t *s = g_bootOptionTypeMap_t;
945
946 while (s->ipmibootflag != 0xFF) {
947
948 if (s->ipmibootflag == p)
949 break;
950
951 s++;
952 }
953
954
955 if (!s->ipmibootflag)
956 printf("Failed to find Sensor Type 0x%x\n", p);
957
958 return s->dbusname;
959}
960
Andrew Geisslerfca6a4f2017-05-30 10:55:39 -0500961ipmi_ret_t ipmi_chassis_get_sys_boot_options(ipmi_netfn_t netfn, ipmi_cmd_t cmd,
962 ipmi_request_t request,
963 ipmi_response_t response,
964 ipmi_data_len_t data_len,
965 ipmi_context_t context)
Adriana Kobylak40814c62015-10-27 15:58:44 -0500966{
shgoupfd84fbbf2015-12-17 10:05:51 +0800967 ipmi_ret_t rc = IPMI_CC_PARM_NOT_SUPPORTED;
968 char *p = NULL;
969 get_sys_boot_options_response_t *resp = (get_sys_boot_options_response_t *) response;
970 get_sys_boot_options_t *reqptr = (get_sys_boot_options_t*) request;
971 uint8_t s;
Adriana Kobylak40814c62015-10-27 15:58:44 -0500972
973 printf("IPMI GET_SYS_BOOT_OPTIONS\n");
974
shgoupfd84fbbf2015-12-17 10:05:51 +0800975 memset(resp,0,sizeof(*resp));
976 resp->version = SET_PARM_VERSION;
977 resp->parm = 5;
ratagupta6f6bff2016-04-04 06:20:11 -0500978 resp->data[0] = SET_PARM_BOOT_FLAGS_VALID_ONE_TIME;
Adriana Kobylak40814c62015-10-27 15:58:44 -0500979
Adriana Kobylak40814c62015-10-27 15:58:44 -0500980
shgoupfd84fbbf2015-12-17 10:05:51 +0800981 /*
982 * Parameter #5 means boot flags. Please refer to 28.13 of ipmi doc.
983 * This is the only parameter used by petitboot.
984 */
Ratan Guptafd28dd72016-08-01 04:58:01 -0500985 if ( reqptr->parameter == static_cast<uint8_t>
Andrew Geisslerfca6a4f2017-05-30 10:55:39 -0500986 ( BootOptionParameter::BOOT_FLAGS )) {
shgoupfd84fbbf2015-12-17 10:05:51 +0800987
Ratan Guptafd28dd72016-08-01 04:58:01 -0500988 *data_len = static_cast<uint8_t>(BootOptionResponseSize::BOOT_FLAGS);
ratagupta6f6bff2016-04-04 06:20:11 -0500989 /* Get the boot device */
990 int r = dbus_get_property("boot_flags",&p);
shgoupfd84fbbf2015-12-17 10:05:51 +0800991
992 if (r < 0) {
ratagupta6f6bff2016-04-04 06:20:11 -0500993 fprintf(stderr, "Dbus get property(boot_flags) failed for get_sys_boot_options.\n");
shgoupfd84fbbf2015-12-17 10:05:51 +0800994 rc = IPMI_CC_UNSPECIFIED_ERROR;
995
996 } else {
997
998 s = get_ipmi_boot_option(p);
999 resp->data[1] = (s << 2);
1000 rc = IPMI_CC_OK;
ratagupta6f6bff2016-04-04 06:20:11 -05001001
shgoupfd84fbbf2015-12-17 10:05:51 +08001002 }
1003
ratagupta6f6bff2016-04-04 06:20:11 -05001004 if (p)
1005 {
Andrew Geisslerfca6a4f2017-05-30 10:55:39 -05001006 free(p);
1007 p = NULL;
ratagupta6f6bff2016-04-04 06:20:11 -05001008 }
1009
1010 /* Get the boot policy */
1011 r = dbus_get_property("boot_policy",&p);
1012
1013 if (r < 0) {
1014 fprintf(stderr, "Dbus get property(boot_policy) failed for get_sys_boot_options.\n");
1015 rc = IPMI_CC_UNSPECIFIED_ERROR;
1016
1017 } else {
1018
Ratan Guptafd28dd72016-08-01 04:58:01 -05001019 printf("BootPolicy is[%s]", p);
Andrew Geisslerfca6a4f2017-05-30 10:55:39 -05001020 resp->data[0] = (strncmp(p,"ONETIME",strlen("ONETIME"))==0) ?
1021 SET_PARM_BOOT_FLAGS_VALID_ONE_TIME:
1022 SET_PARM_BOOT_FLAGS_VALID_PERMANENT;
ratagupta6f6bff2016-04-04 06:20:11 -05001023 rc = IPMI_CC_OK;
1024
1025 }
1026
1027
Ratan Guptafd28dd72016-08-01 04:58:01 -05001028 } else if ( reqptr->parameter == static_cast<uint8_t>
Andrew Geisslerfca6a4f2017-05-30 10:55:39 -05001029 ( BootOptionParameter::OPAL_NETWORK_SETTINGS )) {
Ratan Guptafd28dd72016-08-01 04:58:01 -05001030
Andrew Geisslerfca6a4f2017-05-30 10:55:39 -05001031 *data_len = static_cast<uint8_t>(BootOptionResponseSize::OPAL_NETWORK_SETTINGS);
Ratan Guptafd28dd72016-08-01 04:58:01 -05001032
Andrew Geisslerfca6a4f2017-05-30 10:55:39 -05001033 resp->parm = static_cast<uint8_t>(BootOptionParameter::OPAL_NETWORK_SETTINGS);
Ratan Guptafd28dd72016-08-01 04:58:01 -05001034
Andrew Geisslerfca6a4f2017-05-30 10:55:39 -05001035 int ret = getHostNetworkData(resp);
Ratan Guptafd28dd72016-08-01 04:58:01 -05001036
Andrew Geisslerfca6a4f2017-05-30 10:55:39 -05001037 if (ret < 0) {
Ratan Guptafd28dd72016-08-01 04:58:01 -05001038
Andrew Geisslerfca6a4f2017-05-30 10:55:39 -05001039 fprintf(stderr, "getHostNetworkData failed for get_sys_boot_options.\n");
1040 rc = IPMI_CC_UNSPECIFIED_ERROR;
Ratan Guptafd28dd72016-08-01 04:58:01 -05001041
Andrew Geisslerfca6a4f2017-05-30 10:55:39 -05001042 }else
1043 rc = IPMI_CC_OK;
Ratan Guptafd28dd72016-08-01 04:58:01 -05001044 }
1045
1046 else {
Adriana Kobylak40814c62015-10-27 15:58:44 -05001047 fprintf(stderr, "Unsupported parameter 0x%x\n", reqptr->parameter);
shgoupfd84fbbf2015-12-17 10:05:51 +08001048 }
1049
1050 if (p)
1051 free(p);
1052
Ratan Guptafd28dd72016-08-01 04:58:01 -05001053 if (rc == IPMI_CC_OK)
1054 {
1055 *data_len += 2;
1056 }
1057
shgoupfd84fbbf2015-12-17 10:05:51 +08001058 return rc;
1059}
1060
1061
1062
1063ipmi_ret_t ipmi_chassis_set_sys_boot_options(ipmi_netfn_t netfn, ipmi_cmd_t cmd,
Andrew Geisslerfca6a4f2017-05-30 10:55:39 -05001064 ipmi_request_t request,
1065 ipmi_response_t response,
1066 ipmi_data_len_t data_len,
1067 ipmi_context_t context)
shgoupfd84fbbf2015-12-17 10:05:51 +08001068{
1069 ipmi_ret_t rc = IPMI_CC_OK;
1070 char *s;
shgoupfd84fbbf2015-12-17 10:05:51 +08001071 set_sys_boot_options_t *reqptr = (set_sys_boot_options_t *) request;
1072
Ratan Guptafd28dd72016-08-01 04:58:01 -05001073 printf("IPMI SET_SYS_BOOT_OPTIONS reqptr->parameter =[%d]\n",reqptr->parameter);
1074
shgoupfd84fbbf2015-12-17 10:05:51 +08001075 // This IPMI command does not have any resposne data
1076 *data_len = 0;
1077
1078 /* 000101
1079 * Parameter #5 means boot flags. Please refer to 28.13 of ipmi doc.
1080 * This is the only parameter used by petitboot.
1081 */
Ratan Guptafd28dd72016-08-01 04:58:01 -05001082
1083 if (reqptr->parameter == (uint8_t)BootOptionParameter::BOOT_FLAGS) {
shgoupfd84fbbf2015-12-17 10:05:51 +08001084
1085 s = get_boot_option_by_ipmi(((reqptr->data[1] & 0x3C) >> 2));
1086
1087 printf("%d: %s\n", __LINE__, s);
1088 if (!strcmp(s,INVALID_STRING)) {
1089
1090 rc = IPMI_CC_PARM_NOT_SUPPORTED;
1091
1092 } else {
1093
ratagupta6f6bff2016-04-04 06:20:11 -05001094 int r = dbus_set_property("boot_flags",s);
shgoupfd84fbbf2015-12-17 10:05:51 +08001095
1096 if (r < 0) {
ratagupta6f6bff2016-04-04 06:20:11 -05001097 fprintf(stderr, "Dbus set property(boot_flags) failed for set_sys_boot_options.\n");
shgoupfd84fbbf2015-12-17 10:05:51 +08001098 rc = IPMI_CC_UNSPECIFIED_ERROR;
1099 }
1100 }
Ratan Guptafd28dd72016-08-01 04:58:01 -05001101
ratagupta6f6bff2016-04-04 06:20:11 -05001102 /* setting the boot policy */
Andrew Geisslerfca6a4f2017-05-30 10:55:39 -05001103 s = (char *)(((reqptr->data[0] & SET_PARM_BOOT_FLAGS_PERMANENT) ==
1104 SET_PARM_BOOT_FLAGS_PERMANENT) ?"PERMANENT":"ONETIME");
ratagupta6f6bff2016-04-04 06:20:11 -05001105
Ratan Guptafd28dd72016-08-01 04:58:01 -05001106 printf ( "\nBoot Policy is %s",s);
ratagupta6f6bff2016-04-04 06:20:11 -05001107 int r = dbus_set_property("boot_policy",s);
1108
1109 if (r < 0) {
1110 fprintf(stderr, "Dbus set property(boot_policy) failed for set_sys_boot_options.\n");
1111 rc = IPMI_CC_UNSPECIFIED_ERROR;
1112 }
shgoupfd84fbbf2015-12-17 10:05:51 +08001113
Andrew Geisslerfca6a4f2017-05-30 10:55:39 -05001114 } else if (reqptr->parameter ==
1115 (uint8_t)BootOptionParameter::OPAL_NETWORK_SETTINGS) {
Ratan Guptafd28dd72016-08-01 04:58:01 -05001116
1117 int ret = setHostNetworkData(reqptr);
1118 if (ret < 0) {
1119 fprintf(stderr, "setHostNetworkData failed for set_sys_boot_options.\n");
1120 rc = IPMI_CC_UNSPECIFIED_ERROR;
1121 }
1122 }
1123 else {
shgoupfd84fbbf2015-12-17 10:05:51 +08001124 fprintf(stderr, "Unsupported parameter 0x%x\n", reqptr->parameter);
1125 rc = IPMI_CC_PARM_NOT_SUPPORTED;
Adriana Kobylak40814c62015-10-27 15:58:44 -05001126 }
1127
1128 return rc;
1129}
1130
1131void register_netfn_chassis_functions()
1132{
Tom05732372016-09-06 17:21:23 +05301133 // <Wildcard Command>
Adriana Kobylak40814c62015-10-27 15:58:44 -05001134 printf("Registering NetFn:[0x%X], Cmd:[0x%X]\n",NETFUN_CHASSIS, IPMI_CMD_WILDCARD);
Tom05732372016-09-06 17:21:23 +05301135 ipmi_register_callback(NETFUN_CHASSIS, IPMI_CMD_WILDCARD, NULL, ipmi_chassis_wildcard,
1136 PRIVILEGE_USER);
Adriana Kobylak40814c62015-10-27 15:58:44 -05001137
Tom05732372016-09-06 17:21:23 +05301138 // Get Chassis Capabilities
Nan Li8d15fb42016-08-16 22:29:40 +08001139 printf("Registering NetFn:[0x%X], Cmd:[0x%X]\n",NETFUN_CHASSIS, IPMI_CMD_GET_CHASSIS_CAP);
Tom05732372016-09-06 17:21:23 +05301140 ipmi_register_callback(NETFUN_CHASSIS, IPMI_CMD_GET_CHASSIS_CAP, NULL, ipmi_get_chassis_cap,
1141 PRIVILEGE_USER);
Nan Li8d15fb42016-08-16 22:29:40 +08001142
Tom05732372016-09-06 17:21:23 +05301143 // <Get System Boot Options>
Adriana Kobylak40814c62015-10-27 15:58:44 -05001144 printf("Registering NetFn:[0x%X], Cmd:[0x%X]\n",NETFUN_CHASSIS, IPMI_CMD_GET_SYS_BOOT_OPTIONS);
Tom05732372016-09-06 17:21:23 +05301145 ipmi_register_callback(NETFUN_CHASSIS, IPMI_CMD_GET_SYS_BOOT_OPTIONS, NULL,
1146 ipmi_chassis_get_sys_boot_options, PRIVILEGE_OPERATOR);
Adriana Kobylak40814c62015-10-27 15:58:44 -05001147
Tom05732372016-09-06 17:21:23 +05301148 // <Get Chassis Status>
Nan Lifdd8ec52016-08-28 03:57:40 +08001149 printf("Registering NetFn:[0x%X], Cmd:[0x%X]\n",NETFUN_CHASSIS, IPMI_CMD_CHASSIS_STATUS);
Tom05732372016-09-06 17:21:23 +05301150 ipmi_register_callback(NETFUN_CHASSIS, IPMI_CMD_CHASSIS_STATUS, NULL, ipmi_get_chassis_status,
1151 PRIVILEGE_USER);
Nan Lifdd8ec52016-08-28 03:57:40 +08001152
Tom05732372016-09-06 17:21:23 +05301153 // <Chassis Control>
vishwa36993272015-11-20 12:43:49 -06001154 printf("Registering NetFn:[0x%X], Cmd:[0x%X]\n",NETFUN_CHASSIS, IPMI_CMD_CHASSIS_CONTROL);
Tom05732372016-09-06 17:21:23 +05301155 ipmi_register_callback(NETFUN_CHASSIS, IPMI_CMD_CHASSIS_CONTROL, NULL, ipmi_chassis_control,
1156 PRIVILEGE_OPERATOR);
shgoupfd84fbbf2015-12-17 10:05:51 +08001157
Tom05732372016-09-06 17:21:23 +05301158 // <Set System Boot Options>
shgoupfd84fbbf2015-12-17 10:05:51 +08001159 printf("Registering NetFn:[0x%X], Cmd:[0x%X]\n", NETFUN_CHASSIS, IPMI_CMD_SET_SYS_BOOT_OPTIONS);
Tom05732372016-09-06 17:21:23 +05301160 ipmi_register_callback(NETFUN_CHASSIS, IPMI_CMD_SET_SYS_BOOT_OPTIONS, NULL,
1161 ipmi_chassis_set_sys_boot_options, PRIVILEGE_OPERATOR);
vishwa36993272015-11-20 12:43:49 -06001162}