blob: 3d3e192ce6f75c4f52dbdece685b2cad3950bd16 [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::
26 OPAL_NETWORK_SETTINGS;//Maximum size of the boot option parametrs
27constexpr 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,
37 0x00 ,0x01 ,0x06 ,0x04};
38
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{
70 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;
74}__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);
shgoupfd84fbbf2015-12-17 10:05:51 +0800131/* *buf = (char*) malloc(strlen(temp_buf));
132 if (*buf) {
133 strcpy(*buf, temp_buf);
134 }
135*/
136 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
190finish:
191 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),
255 commaDelimtrPos-(equalDelimtrPos+1));
256
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,
265 equalDelimtrPos-commaDelimtrPrevPos,"ipaddress" )) {
266
267 host_config.ipaddress = std::move(value);
268 }
269 else if ( 0 == conf_str.compare(commaDelimtrPrevPos,
270 equalDelimtrPos-commaDelimtrPrevPos,"prefix" )) {
271
272 host_config.prefix = std::move(value);
273 }
274 else if ( 0 == conf_str.compare(commaDelimtrPrevPos,
275 equalDelimtrPos-commaDelimtrPrevPos, "gateway" )) {
276 host_config.gateway = std::move(value);
277 }
278 else if ( 0 == conf_str.compare(commaDelimtrPrevPos,
279 equalDelimtrPos-commaDelimtrPrevPos, "mac" )) {
280 host_config.macaddress = std::move(value);
281 }
282 else if ( 0 == conf_str.compare(commaDelimtrPrevPos,
283 equalDelimtrPos-commaDelimtrPrevPos, "addr_type" )) {
284 host_config.addrType = std::move(value);
285 }
286
287 commaDelimtrPos++;
288 commaDelimtrPrevPos= commaDelimtrPos;
289 }
290}
291
292int getHostNetworkData(get_sys_boot_options_response_t* respptr)
293{
294
295 char *prop = nullptr;
296 int rc = dbus_get_property("network_config",&prop);
297
298 if ( rc < 0 ) {
299 fprintf(stderr, "Dbus get property(boot_flags) failed\
300 for get_sys_boot_options.\n");
301 return rc;
302 }
303
304 std::string conf_str(prop);
305
306 if ( prop ) {
307
308 free(prop);
309 prop = nullptr;
310 }
311
312 /* network_config property Value would be in the form of
313 * ipaddress=1.1.1.1,prefix=16,gateway=2.2.2.2,mac=11:22:33:44:55:66,dhcp=0
314 */
315
316 /* Parsing the string and fill the hostconfig structure with the
317 * values */
318
319 printf ("Configuration String[%s]\n ",conf_str.c_str());
320
321 host_network_config_t host_config;
322
323 // Fill the host_config from the configuration string
324 fillNetworkConfig(host_config,conf_str);
325
326 //Assigning the index as intialByteLength as it is fixed and prefilled.
327 printf ("host_config.macaddress.c_str()=[%s]\n",host_config.macaddress.c_str());
328 do{
329
330 rc = sscanf(host_config.macaddress.c_str(),MAC_ADDRESS_FORMAT,
331 (respptr->data+MAC_OFFSET), (respptr->data+MAC_OFFSET+1),
332 (respptr->data+MAC_OFFSET+2),(respptr->data+MAC_OFFSET+3),
333 (respptr->data+MAC_OFFSET+4), (respptr->data+MAC_OFFSET+5));
334
335
336 if ( rc < 6 ){
337 fprintf(stderr, "sscanf Failed in extracting mac address.\n");
338 rc = -1;
339 break;
340 }
341
342 //Conevrt the dhcp,ipaddress,mask and gateway as hex number
343 respptr->data[MAC_OFFSET+6]=0x00;
344
345 rc = sscanf(host_config.addrType.c_str(),ADDR_TYPE_FORMAT,
346 (respptr->data+ADDRTYPE_OFFSET));
347
348 if ( rc <= 0 ) {
349 fprintf(stderr, "sscanf Failed in extracting address type.\n");
350 rc = -1;
351 break;
352 }
353
354 //ipaddress and gateway would be in IPv4 format
355 rc = inet_pton(AF_INET,host_config.ipaddress.c_str(),
356 (respptr->data+IPADDR_OFFSET));
357
358 if ( rc <= 0 ) {
359 fprintf(stderr, "inet_pton failed during ipaddress coneversion\n");
360 rc = -1;
361 break;
362 }
363
364 rc = sscanf(host_config.prefix.c_str(),PREFIX_FORMAT,
365 (respptr->data+PREFIX_OFFSET));
366
367 if ( rc <= 0 ) {
368 fprintf(stderr, "sscanf failed during prefix extraction.\n");
369 rc = -1;
370 break;
371 }
372
373 rc = inet_pton(AF_INET,host_config.gateway.c_str(),
374 (respptr->data+GATEWAY_OFFSET));
375
376 if ( rc <= 0 ) {
377 fprintf(stderr, "inet_pton failed during gateway conversion.\n");
378 rc = -1;
379 break;
380 }
381
382 }while (0);
383
384 if ( rc ) {
385
386 //PetiBoot-Specific
387 //If sucess then copy the first 9 bytes to the data
388 //else set the respptr to 0
389
390 memcpy(respptr->data,net_conf_initial_bytes,
391 sizeof(net_conf_initial_bytes));
392
393#ifdef _IPMI_DEBUG_
394 printf ("\n===Printing the IPMI Formatted Data========\n");
395
396 for ( uint8_t pos = 0; pos<index; pos++ )
397 printf("%02x ", respptr->data[pos]);
398#endif
399
400 }else {
401
402 memset(respptr->data,0,SIZE_BOOT_OPTION);
403 }
404
405 return rc;
406}
407
408int setHostNetworkData(set_sys_boot_options_t * reqptr)
409{
410 std::string host_network_config;
411 char mac[SIZE_MAC] = {0};
412 char ipAddress[INET_ADDRSTRLEN] = {0};
413 char gateway[INET_ADDRSTRLEN] = {0};
414 char dhcp[SIZE_PREFIX] = {0};
415 char prefix[SIZE_PREFIX] = {0};
416 int rc = 0;
417 uint32_t zeroCookie=0;
418
419 //cookie starts from second byte
420 // version starts from sixth byte
421
422 do {
423
424 // cookie == 0x21 0x70 0x62 0x21
425 if ( memcmp(&(reqptr->data[COOKIE_OFFSET]),
426 (net_conf_initial_bytes+COOKIE_OFFSET),
427 SIZE_COOKIE) != 0 ) {
428 //cookie == 0
429 if ( memcmp(&(reqptr->data[COOKIE_OFFSET]),
430 &zeroCookie,
431 SIZE_COOKIE) == 0 ) {
432 rc = 0;
433 break;
434 }
435 //Invalid cookie
436 fprintf(stderr, "Invalid Cookie\n");
437 rc = -1;
438 break;
439 }
440 // vesion == 0x00 0x01
441 if ( memcmp(&(reqptr->data[VERSION_OFFSET]),
442 (net_conf_initial_bytes+VERSION_OFFSET),
443 SIZE_VERSION) != 0 ) {
444
445 fprintf(stderr, "Invalid Version\n");
446 rc = -1;
447 break;
448 }
449
450 snprintf(mac, SIZE_MAC, MAC_ADDRESS_FORMAT,
451 reqptr->data[MAC_OFFSET],
452 reqptr->data[MAC_OFFSET+1],
453 reqptr->data[MAC_OFFSET+2],
454 reqptr->data[MAC_OFFSET+3],
455 reqptr->data[MAC_OFFSET+4],
456 reqptr->data[MAC_OFFSET+5]);
457
458 snprintf(dhcp,SIZE_PREFIX, ADDR_TYPE_FORMAT, reqptr->data[ADDRTYPE_OFFSET]);
459 //Validating the address type which could be
460 //either static or dynamic
461 if( *(reqptr->data+ADDRTYPE_OFFSET) > 1 ) {
462
463 fprintf(stderr, "Invalid Address Type\n");
464 rc = -1;
465 break;
466
467 }
468
469 snprintf(ipAddress, INET_ADDRSTRLEN, IP_ADDRESS_FORMAT,
470 reqptr->data[IPADDR_OFFSET], reqptr->data[IPADDR_OFFSET+1],
471 reqptr->data[IPADDR_OFFSET+2], reqptr->data[IPADDR_OFFSET+3]);
472
473 //validating prefix
474 if ( *(reqptr->data+PREFIX_OFFSET) > (uint8_t)MAX_PREFIX_VALUE ) {
475
476 fprintf(stderr, "Invalid Prefix\n");
477 rc = -1;
478 break;
479 }
480
481 snprintf(prefix,SIZE_PREFIX,PREFIX_FORMAT, reqptr->data[PREFIX_OFFSET]);
482
483 snprintf(gateway, INET_ADDRSTRLEN,IP_ADDRESS_FORMAT,
484 reqptr->data[GATEWAY_OFFSET], reqptr->data[GATEWAY_OFFSET+1],
485 reqptr->data[GATEWAY_OFFSET+2], reqptr->data[GATEWAY_OFFSET+3]);
486
487
488 }while(0);
489
490 if( !rc )
491 {
492 //Cookie == 0 or it is a valid cookie
493 host_network_config += "ipaddress="+std::string(ipAddress)+",prefix="+
494 std::string(prefix)+",gateway="+std::string(gateway)+
495 ",mac="+std::string(mac)+",addr_type="+std::string(dhcp);
496
497 printf ("Network configuration changed: %s\n",host_network_config.c_str());
498
499 rc = dbus_set_property("network_config",host_network_config.c_str());
500
501 if ( rc < 0 ) {
502 fprintf(stderr, "Dbus set property(network_config)\
503 failed for set_sys_boot_options.\n");
504 rc = -1;
505 }
506
507 }
508 return rc;
509}
510
Adriana Kobylak40814c62015-10-27 15:58:44 -0500511ipmi_ret_t ipmi_chassis_wildcard(ipmi_netfn_t netfn, ipmi_cmd_t cmd,
512 ipmi_request_t request, ipmi_response_t response,
513 ipmi_data_len_t data_len, ipmi_context_t context)
514{
515 printf("Handling CHASSIS WILDCARD Netfn:[0x%X], Cmd:[0x%X]\n",netfn, cmd);
516 // Status code.
Nan Li70aa8d92016-08-29 00:11:10 +0800517 ipmi_ret_t rc = IPMI_CC_INVALID;
Adriana Kobylak40814c62015-10-27 15:58:44 -0500518 *data_len = 0;
519 return rc;
520}
521
Nan Li8d15fb42016-08-16 22:29:40 +0800522ipmi_ret_t ipmi_get_chassis_cap(ipmi_netfn_t netfn, ipmi_cmd_t cmd,
523 ipmi_request_t request, ipmi_response_t response,
524 ipmi_data_len_t data_len, ipmi_context_t context)
525{
526 // sd_bus error
527 ipmi_ret_t rc = IPMI_CC_OK;
528
529 ipmi_chassis_cap_t chassis_cap{};
530
531 *data_len = sizeof(ipmi_chassis_cap_t);
532
533 // TODO: need future work. Get those flag from MRW.
534
535 // capabilities flags
536 // [7..4] - reserved
537 // [3] – 1b = provides power interlock (IPM 1.5)
538 // [2] – 1b = provides Diagnostic Interrupt (FP NMI)
539 // [1] – 1b = provides “Front Panel Lockout” (indicates that the chassis has capabilities
540 // to lock out external power control and reset button or front panel interfaces
541 // and/or detect tampering with those interfaces).
542 // [0] -1b = Chassis provides intrusion (physical security) sensor.
543 // set to default value 0x0.
544 chassis_cap.cap_flags = 0x0;
545
546 // Since we do not have a separate SDR Device/SEL Device/ FRU repository.
547 // The 20h was given as those 5 device addresses.
548 // Chassis FRU info Device Address
549 chassis_cap.fru_info_dev_addr = 0x20;
550
551 // Chassis SDR Device Address
552 chassis_cap.sdr_dev_addr = 0x20;
553
554 // Chassis SEL Device Address
555 chassis_cap.sel_dev_addr = 0x20;
556
557 // Chassis System Management Device Address
558 chassis_cap.system_management_dev_addr = 0x20;
559
560 // Chassis Bridge Device Address.
561 chassis_cap.bridge_dev_addr = 0x20;
562
563 memcpy(response, &chassis_cap, *data_len);
564
565 return rc;
566}
567
Vishwanatha Subbannab12b0c02017-03-07 18:17:19 +0530568//------------------------------------------
569// Calls into Host State Manager Dbus object
570//------------------------------------------
571int initiate_state_transition(State::Host::Transition transition)
vishwa36993272015-11-20 12:43:49 -0600572{
Vishwanatha Subbannab12b0c02017-03-07 18:17:19 +0530573 using namespace phosphor::logging;
574
575 // OpenBMC Host State Manager dbus framework
576 constexpr auto HOST_STATE_MANAGER_ROOT = "/xyz/openbmc_project/state/host0";
577 constexpr auto HOST_STATE_MANAGER_IFACE = "xyz.openbmc_project.State.Host";
578 constexpr auto DBUS_PROPERTY_IFACE = "org.freedesktop.DBus.Properties";
579 constexpr auto PROPERTY = "RequestedHostTransition";
580
vishwa36993272015-11-20 12:43:49 -0600581 // sd_bus error
582 int rc = 0;
Sergey Solomineb9b8142016-08-23 09:07:28 -0500583 char *busname = NULL;
vishwa36993272015-11-20 12:43:49 -0600584
Sergey Solomineb9b8142016-08-23 09:07:28 -0500585 // SD Bus error report mechanism.
586 sd_bus_error bus_error = SD_BUS_ERROR_NULL;
vishwa36993272015-11-20 12:43:49 -0600587
vishwa36993272015-11-20 12:43:49 -0600588 // Gets a hook onto either a SYSTEM or SESSION bus
589 sd_bus *bus_type = ipmid_get_sd_bus_connection();
Vishwanatha Subbannab12b0c02017-03-07 18:17:19 +0530590 rc = mapper_get_service(bus_type, HOST_STATE_MANAGER_ROOT, &busname);
Sergey Solomineb9b8142016-08-23 09:07:28 -0500591 if (rc < 0) {
Vishwanatha Subbannab12b0c02017-03-07 18:17:19 +0530592 log<level::ERR>("Failed to get bus name",
593 entry("ERROR=%s, OBJPATH=%s",
594 strerror(-rc), HOST_STATE_MANAGER_ROOT));
595 return rc;
Sergey Solomineb9b8142016-08-23 09:07:28 -0500596 }
Vishwanatha Subbannab12b0c02017-03-07 18:17:19 +0530597
598 // Convert to string equivalent of the passed in transition enum.
599 auto request = State::convertForMessage(transition);
600
601 rc = sd_bus_call_method(bus_type, // On the system bus
602 busname, // Service to contact
603 HOST_STATE_MANAGER_ROOT, // Object path
604 DBUS_PROPERTY_IFACE, // Interface name
605 "Set", // Method to be called
606 &bus_error, // object to return error
607 nullptr, // Response buffer if any
608 "ssv", // Takes 3 arguments
609 HOST_STATE_MANAGER_IFACE,
610 PROPERTY,
611 "s", request.c_str());
vishwa36993272015-11-20 12:43:49 -0600612 if(rc < 0)
613 {
Vishwanatha Subbannab12b0c02017-03-07 18:17:19 +0530614 log<level::ERR>("Failed to initiate transition",
615 entry("ERROR=%s, REQUEST=%s",
616 bus_error.message, request.c_str()));
vishwa36993272015-11-20 12:43:49 -0600617 }
618 else
619 {
Vishwanatha Subbannab12b0c02017-03-07 18:17:19 +0530620 log<level::INFO>("Transition request initiated successfully");
vishwa36993272015-11-20 12:43:49 -0600621 }
622
623 sd_bus_error_free(&bus_error);
Sergey Solomineb9b8142016-08-23 09:07:28 -0500624 free(busname);
vishwa36993272015-11-20 12:43:49 -0600625
Sergey Solomineb9b8142016-08-23 09:07:28 -0500626 return rc;
vishwa36993272015-11-20 12:43:49 -0600627}
628
Nan Lifdd8ec52016-08-28 03:57:40 +0800629struct hostPowerPolicyTypeMap_t {
630 uint8_t policyNum;
631 char policyName[19];
632};
633
634hostPowerPolicyTypeMap_t g_hostPowerPolicyTypeMap_t[] = {
635
636 {0x00, "LEAVE_OFF"},
637 {0x01, "RESTORE_LAST_STATE"},
638 {0x02, "ALWAYS_POWER_ON"},
639 {0x03, "UNKNOWN"}
640};
641
642uint8_t get_host_power_policy(char *p) {
643
644 hostPowerPolicyTypeMap_t *s = g_hostPowerPolicyTypeMap_t;
645
646 while (s->policyNum != 0x03) {
647 if (!strcmp(s->policyName,p))
648 break;
649 s++;
650 }
651
652 return s->policyNum;
653}
654
655//----------------------------------------------------------------------
656// Get Chassis Status commands
657//----------------------------------------------------------------------
658ipmi_ret_t ipmi_get_chassis_status(ipmi_netfn_t netfn, ipmi_cmd_t cmd,
659 ipmi_request_t request, ipmi_response_t response,
660 ipmi_data_len_t data_len, ipmi_context_t context)
661{
662 const char *objname = "/org/openbmc/control/power0";
663 const char *intf = "org.openbmc.control.Power";
664
665 sd_bus *bus = NULL;
666 sd_bus_message *reply = NULL;
667 int r = 0;
668 int pgood = 0;
669 char *busname = NULL;
670 ipmi_ret_t rc = IPMI_CC_OK;
671 ipmi_get_chassis_status_t chassis_status{};
672
673 char *p = NULL;
674 uint8_t s = 0;
675
676 // Get the system bus where most system services are provided.
677 bus = ipmid_get_sd_bus_connection();
678
679 *data_len = 4;
680
681 r = mapper_get_service(bus, objname, &busname);
682 if (r < 0) {
683 fprintf(stderr, "Failed to get bus name, return value: %s.\n", strerror(-r));
684 rc = IPMI_CC_UNSPECIFIED_ERROR;
685 goto finish;
686 }
687
688 r = sd_bus_get_property(bus, busname, objname, intf, "pgood", NULL, &reply, "i");
689 if (r < 0) {
690 fprintf(stderr, "Failed to call sd_bus_get_property:%d, %s\n", r, strerror(-r));
691 fprintf(stderr, "Bus: %s, Path: %s, Interface: %s\n",
692 busname, objname, intf);
693 rc = IPMI_CC_UNSPECIFIED_ERROR;
694 goto finish;
695 }
696
697 r = sd_bus_message_read(reply, "i", &pgood);
698 if (r < 0) {
699 fprintf(stderr, "Failed to read sensor: %s\n", strerror(-r));
700 rc = IPMI_CC_UNSPECIFIED_ERROR;
701 goto finish;
702 }
703
704 printf("pgood is 0x%02x\n", pgood);
705
706 // Get Power Policy
707 r = dbus_get_property("power_policy",&p);
708
709 if (r < 0) {
710 fprintf(stderr, "Dbus get property(power_policy) failed for get_sys_boot_options.\n");
711 rc = IPMI_CC_UNSPECIFIED_ERROR;
712 } else {
713 s = get_host_power_policy(p);
714 }
715
716 if (p)
717 {
718 free(p);
719 p = NULL;
720 }
721
722 // Current Power State
723 // [7] reserved
724 // [6..5] power restore policy
725 // 00b = chassis stays powered off after AC/mains returns
726 // 01b = after AC returns, power is restored to the state that was
727 // in effect when AC/mains was lost.
728 // 10b = chassis always powers up after AC/mains returns
729 // 11b = unknow
730 // Set to 00b, by observing the hardware behavior.
731 // Do we need to define a dbus property to identify the restore policy?
732
733 // [4] power control fault
734 // 1b = controller attempted to turn system power on or off, but
735 // system did not enter desired state.
736 // Set to 0b, since We don't support it..
737
738 // [3] power fault
739 // 1b = fault detected in main power subsystem.
740 // set to 0b. for we don't support it.
741
742 // [2] 1b = interlock (chassis is presently shut down because a chassis
743 // panel interlock switch is active). (IPMI 1.5)
744 // set to 0b, for we don't support it.
745
746 // [1] power overload
747 // 1b = system shutdown because of power overload condition.
748 // set to 0b, for we don't support it.
749
750 // [0] power is on
751 // 1b = system power is on
752 // 0b = system power is off(soft-off S4/S5, or mechanical off)
753
754 chassis_status.cur_power_state = ((s & 0x3)<<5) | (pgood & 0x1);
755
756 // Last Power Event
757 // [7..5] – reserved
758 // [4] – 1b = last ‘Power is on’ state was entered via IPMI command
759 // [3] – 1b = last power down caused by power fault
760 // [2] – 1b = last power down caused by a power interlock being activated
761 // [1] – 1b = last power down caused by a Power overload
762 // [0] – 1b = AC failed
763 // set to 0x0, for we don't support these fields.
764
765 chassis_status.last_power_event = 0;
766
767 // Misc. Chassis State
768 // [7] – reserved
769 // [6] – 1b = Chassis Identify command and state info supported (Optional)
770 // 0b = Chassis Identify command support unspecified via this command.
771 // (The Get Command Support command , if implemented, would still
772 // indicate support for the Chassis Identify command)
773 // [5..4] – Chassis Identify State. Mandatory when bit[6] =1b, reserved (return
774 // as 00b) otherwise. Returns the present chassis identify state.
775 // Refer to the Chassis Identify command for more info.
776 // 00b = chassis identify state = Off
777 // 01b = chassis identify state = Temporary(timed) On
778 // 10b = chassis identify state = Indefinite On
779 // 11b = reserved
780 // [3] – 1b = Cooling/fan fault detected
781 // [2] – 1b = Drive Fault
782 // [1] – 1b = Front Panel Lockout active (power off and reset via chassis
783 // push-buttons disabled.)
784 // [0] – 1b = Chassis Intrusion active
785 // set to 0, for we don't support them.
786 chassis_status.misc_power_state = 0;
787
788 // Front Panel Button Capabilities and disable/enable status(Optional)
789 // set to 0, for we don't support them.
790 chassis_status.front_panel_button_cap_status = 0;
791
792 // Pack the actual response
793 memcpy(response, &chassis_status, *data_len);
794
795finish:
796 free(busname);
797 reply = sd_bus_message_unref(reply);
798
799 return rc;
800}
Chris Austen7888c4d2015-12-03 15:26:20 -0600801
Vishwanatha Subbanna83b5c1c2017-01-25 18:41:51 +0530802//-------------------------------------------------------------
803// Send a command to SoftPowerOff application to stop any timer
804//-------------------------------------------------------------
805int stop_soft_off_timer()
806{
Vishwanatha Subbanna83b5c1c2017-01-25 18:41:51 +0530807 constexpr auto iface = "org.freedesktop.DBus.Properties";
808 constexpr auto soft_off_iface = "xyz.openbmc_project.Ipmi.Internal."
809 "SoftPowerOff";
810
811 constexpr auto property = "ResponseReceived";
812 constexpr auto value = "xyz.openbmc_project.Ipmi.Internal."
813 "SoftPowerOff.HostResponse.HostShutdown";
814 char *busname = nullptr;
815
816 // Get the system bus where most system services are provided.
817 auto bus = ipmid_get_sd_bus_connection();
818
819 // Get the service name
Vishwanatha Subbannab891a572017-03-31 11:34:48 +0530820 auto r = mapper_get_service(bus, SOFTOFF_OBJPATH, &busname);
Vishwanatha Subbanna83b5c1c2017-01-25 18:41:51 +0530821 if (r < 0) {
822 fprintf(stderr, "Failed to get %s bus name: %s\n",
Vishwanatha Subbannab891a572017-03-31 11:34:48 +0530823 SOFTOFF_OBJPATH, strerror(-r));
Vishwanatha Subbanna83b5c1c2017-01-25 18:41:51 +0530824 return r;
825 }
826
827 // No error object or reply expected.
Vishwanatha Subbannab891a572017-03-31 11:34:48 +0530828 int rc = sd_bus_call_method(bus, busname, SOFTOFF_OBJPATH, iface,
Vishwanatha Subbanna83b5c1c2017-01-25 18:41:51 +0530829 "Set", nullptr, nullptr, "ssv",
830 soft_off_iface, property, "s", value);
831 if (rc < 0)
832 {
833 fprintf(stderr, "Failed to set property in SoftPowerOff object: %s\n",
834 strerror(-rc));
835 }
836 free(busname);
837 return rc;
838}
839
vishwa36993272015-11-20 12:43:49 -0600840//----------------------------------------------------------------------
841// Chassis Control commands
842//----------------------------------------------------------------------
843ipmi_ret_t ipmi_chassis_control(ipmi_netfn_t netfn, ipmi_cmd_t cmd,
844 ipmi_request_t request, ipmi_response_t response,
845 ipmi_data_len_t data_len, ipmi_context_t context)
846{
847 // Error from power off.
848 int rc = 0;
849
850 // No response for this command.
851 *data_len = 0;
852
853 // Catch the actual operaton by peeking into request buffer
854 uint8_t chassis_ctrl_cmd = *(uint8_t *)request;
855 printf("Chassis Control Command: Operation:[0x%X]\n",chassis_ctrl_cmd);
856
857 switch(chassis_ctrl_cmd)
858 {
Vishwanatha Subbannaa66239b2017-03-02 16:54:32 +0530859 case CMD_POWER_ON:
Vishwanatha Subbannab12b0c02017-03-07 18:17:19 +0530860 rc = initiate_state_transition(State::Host::Transition::On);
Vishwanatha Subbannaa66239b2017-03-02 16:54:32 +0530861 break;
vishwa36993272015-11-20 12:43:49 -0600862 case CMD_POWER_OFF:
Vishwanatha Subbanna83b5c1c2017-01-25 18:41:51 +0530863 // Need to Nudge SoftPowerOff application that it needs to stop the
864 // watchdog timer if running.
865 rc = stop_soft_off_timer();
866 if (!rc)
867 {
868 fprintf(stderr, "Error stopping watchdog timer");
869 }
870 // Does not matter if we are able to stop the timer,
871 // just get going and do the hard power off
Vishwanatha Subbannab12b0c02017-03-07 18:17:19 +0530872 rc = initiate_state_transition(State::Host::Transition::Off);
vishwa36993272015-11-20 12:43:49 -0600873 break;
Vishwanatha Subbanna83b5c1c2017-01-25 18:41:51 +0530874
Chris Austen7888c4d2015-12-03 15:26:20 -0600875 case CMD_HARD_RESET:
Vishwanatha Subbannabb5190e2017-03-01 14:53:29 +0530876 case CMD_POWER_CYCLE:
877 // SPEC has a section that says certain implementations can trigger
878 // PowerOn if power is Off when a command to power cycle is
879 // requested
Vishwanatha Subbannab12b0c02017-03-07 18:17:19 +0530880 rc = initiate_state_transition(State::Host::Transition::Reboot);
Chris Austen7888c4d2015-12-03 15:26:20 -0600881 break;
vishwa36993272015-11-20 12:43:49 -0600882 default:
883 {
884 fprintf(stderr, "Invalid Chassis Control command:[0x%X] received\n",chassis_ctrl_cmd);
885 rc = -1;
886 }
887 }
888
889 return ( (rc < 0) ? IPMI_CC_INVALID : IPMI_CC_OK);
890}
891
shgoupfd84fbbf2015-12-17 10:05:51 +0800892struct bootOptionTypeMap_t {
893 uint8_t ipmibootflag;
894 char dbusname[8];
895};
896
897#define INVALID_STRING "Invalid"
898// dbus supports this list of boot devices.
899bootOptionTypeMap_t g_bootOptionTypeMap_t[] = {
900
901 {0x01, "Network"},
902 {0x02, "Disk"},
903 {0x03, "Safe"},
904 {0x05, "CDROM"},
905 {0x06, "Setup"},
906 {0x00, "Default"},
907 {0xFF, INVALID_STRING}
908};
909
910uint8_t get_ipmi_boot_option(char *p) {
911
912 bootOptionTypeMap_t *s = g_bootOptionTypeMap_t;
913
914 while (s->ipmibootflag != 0xFF) {
915 if (!strcmp(s->dbusname,p))
916 break;
917 s++;
918 }
919
920 if (!s->ipmibootflag)
921 printf("Failed to find Sensor Type %s\n", p);
922
923 return s->ipmibootflag;
924}
925
926char* get_boot_option_by_ipmi(uint8_t p) {
927
928 bootOptionTypeMap_t *s = g_bootOptionTypeMap_t;
929
930 while (s->ipmibootflag != 0xFF) {
931
932 if (s->ipmibootflag == p)
933 break;
934
935 s++;
936 }
937
938
939 if (!s->ipmibootflag)
940 printf("Failed to find Sensor Type 0x%x\n", p);
941
942 return s->dbusname;
943}
944
Adriana Kobylak40814c62015-10-27 15:58:44 -0500945ipmi_ret_t ipmi_chassis_get_sys_boot_options(ipmi_netfn_t netfn, ipmi_cmd_t cmd,
946 ipmi_request_t request, ipmi_response_t response,
947 ipmi_data_len_t data_len, ipmi_context_t context)
948{
shgoupfd84fbbf2015-12-17 10:05:51 +0800949 ipmi_ret_t rc = IPMI_CC_PARM_NOT_SUPPORTED;
950 char *p = NULL;
951 get_sys_boot_options_response_t *resp = (get_sys_boot_options_response_t *) response;
952 get_sys_boot_options_t *reqptr = (get_sys_boot_options_t*) request;
953 uint8_t s;
Adriana Kobylak40814c62015-10-27 15:58:44 -0500954
955 printf("IPMI GET_SYS_BOOT_OPTIONS\n");
956
shgoupfd84fbbf2015-12-17 10:05:51 +0800957 memset(resp,0,sizeof(*resp));
958 resp->version = SET_PARM_VERSION;
959 resp->parm = 5;
ratagupta6f6bff2016-04-04 06:20:11 -0500960 resp->data[0] = SET_PARM_BOOT_FLAGS_VALID_ONE_TIME;
Adriana Kobylak40814c62015-10-27 15:58:44 -0500961
Adriana Kobylak40814c62015-10-27 15:58:44 -0500962
shgoupfd84fbbf2015-12-17 10:05:51 +0800963 /*
964 * Parameter #5 means boot flags. Please refer to 28.13 of ipmi doc.
965 * This is the only parameter used by petitboot.
966 */
Ratan Guptafd28dd72016-08-01 04:58:01 -0500967 if ( reqptr->parameter == static_cast<uint8_t>
968 ( BootOptionParameter::BOOT_FLAGS )) {
shgoupfd84fbbf2015-12-17 10:05:51 +0800969
Ratan Guptafd28dd72016-08-01 04:58:01 -0500970 *data_len = static_cast<uint8_t>(BootOptionResponseSize::BOOT_FLAGS);
ratagupta6f6bff2016-04-04 06:20:11 -0500971 /* Get the boot device */
972 int r = dbus_get_property("boot_flags",&p);
shgoupfd84fbbf2015-12-17 10:05:51 +0800973
974 if (r < 0) {
ratagupta6f6bff2016-04-04 06:20:11 -0500975 fprintf(stderr, "Dbus get property(boot_flags) failed for get_sys_boot_options.\n");
shgoupfd84fbbf2015-12-17 10:05:51 +0800976 rc = IPMI_CC_UNSPECIFIED_ERROR;
977
978 } else {
979
980 s = get_ipmi_boot_option(p);
981 resp->data[1] = (s << 2);
982 rc = IPMI_CC_OK;
ratagupta6f6bff2016-04-04 06:20:11 -0500983
shgoupfd84fbbf2015-12-17 10:05:51 +0800984 }
985
ratagupta6f6bff2016-04-04 06:20:11 -0500986 if (p)
987 {
988 free(p);
989 p = NULL;
990 }
991
992 /* Get the boot policy */
993 r = dbus_get_property("boot_policy",&p);
994
995 if (r < 0) {
996 fprintf(stderr, "Dbus get property(boot_policy) failed for get_sys_boot_options.\n");
997 rc = IPMI_CC_UNSPECIFIED_ERROR;
998
999 } else {
1000
Ratan Guptafd28dd72016-08-01 04:58:01 -05001001 printf("BootPolicy is[%s]", p);
ratagupta6f6bff2016-04-04 06:20:11 -05001002 resp->data[0] = (strncmp(p,"ONETIME",strlen("ONETIME"))==0) ?
1003 SET_PARM_BOOT_FLAGS_VALID_ONE_TIME:
1004 SET_PARM_BOOT_FLAGS_VALID_PERMANENT;
1005 rc = IPMI_CC_OK;
1006
1007 }
1008
1009
Ratan Guptafd28dd72016-08-01 04:58:01 -05001010 } else if ( reqptr->parameter == static_cast<uint8_t>
1011 ( BootOptionParameter::OPAL_NETWORK_SETTINGS )) {
1012
1013 *data_len = static_cast<uint8_t>(BootOptionResponseSize::OPAL_NETWORK_SETTINGS);
1014
1015 resp->parm = static_cast<uint8_t>(BootOptionParameter::OPAL_NETWORK_SETTINGS);
1016
1017 int ret = getHostNetworkData(resp);
1018
1019 if (ret < 0) {
1020
1021 fprintf(stderr, "getHostNetworkData failed for get_sys_boot_options.\n");
1022 rc = IPMI_CC_UNSPECIFIED_ERROR;
1023
1024 }else
1025 rc = IPMI_CC_OK;
1026 }
1027
1028 else {
Adriana Kobylak40814c62015-10-27 15:58:44 -05001029 fprintf(stderr, "Unsupported parameter 0x%x\n", reqptr->parameter);
shgoupfd84fbbf2015-12-17 10:05:51 +08001030 }
1031
1032 if (p)
1033 free(p);
1034
Ratan Guptafd28dd72016-08-01 04:58:01 -05001035 if (rc == IPMI_CC_OK)
1036 {
1037 *data_len += 2;
1038 }
1039
shgoupfd84fbbf2015-12-17 10:05:51 +08001040 return rc;
1041}
1042
1043
1044
1045ipmi_ret_t ipmi_chassis_set_sys_boot_options(ipmi_netfn_t netfn, ipmi_cmd_t cmd,
1046 ipmi_request_t request, ipmi_response_t response,
1047 ipmi_data_len_t data_len, ipmi_context_t context)
1048{
1049 ipmi_ret_t rc = IPMI_CC_OK;
1050 char *s;
shgoupfd84fbbf2015-12-17 10:05:51 +08001051 set_sys_boot_options_t *reqptr = (set_sys_boot_options_t *) request;
1052
Ratan Guptafd28dd72016-08-01 04:58:01 -05001053 printf("IPMI SET_SYS_BOOT_OPTIONS reqptr->parameter =[%d]\n",reqptr->parameter);
1054
shgoupfd84fbbf2015-12-17 10:05:51 +08001055 // This IPMI command does not have any resposne data
1056 *data_len = 0;
1057
1058 /* 000101
1059 * Parameter #5 means boot flags. Please refer to 28.13 of ipmi doc.
1060 * This is the only parameter used by petitboot.
1061 */
Ratan Guptafd28dd72016-08-01 04:58:01 -05001062
1063 if (reqptr->parameter == (uint8_t)BootOptionParameter::BOOT_FLAGS) {
shgoupfd84fbbf2015-12-17 10:05:51 +08001064
1065 s = get_boot_option_by_ipmi(((reqptr->data[1] & 0x3C) >> 2));
1066
1067 printf("%d: %s\n", __LINE__, s);
1068 if (!strcmp(s,INVALID_STRING)) {
1069
1070 rc = IPMI_CC_PARM_NOT_SUPPORTED;
1071
1072 } else {
1073
ratagupta6f6bff2016-04-04 06:20:11 -05001074 int r = dbus_set_property("boot_flags",s);
shgoupfd84fbbf2015-12-17 10:05:51 +08001075
1076 if (r < 0) {
ratagupta6f6bff2016-04-04 06:20:11 -05001077 fprintf(stderr, "Dbus set property(boot_flags) failed for set_sys_boot_options.\n");
shgoupfd84fbbf2015-12-17 10:05:51 +08001078 rc = IPMI_CC_UNSPECIFIED_ERROR;
1079 }
1080 }
Ratan Guptafd28dd72016-08-01 04:58:01 -05001081
ratagupta6f6bff2016-04-04 06:20:11 -05001082 /* setting the boot policy */
1083 s = (char *)(((reqptr->data[0] & SET_PARM_BOOT_FLAGS_PERMANENT) ==
Ratan Guptafd28dd72016-08-01 04:58:01 -05001084 SET_PARM_BOOT_FLAGS_PERMANENT) ?"PERMANENT":"ONETIME");
ratagupta6f6bff2016-04-04 06:20:11 -05001085
Ratan Guptafd28dd72016-08-01 04:58:01 -05001086 printf ( "\nBoot Policy is %s",s);
ratagupta6f6bff2016-04-04 06:20:11 -05001087 int r = dbus_set_property("boot_policy",s);
1088
1089 if (r < 0) {
1090 fprintf(stderr, "Dbus set property(boot_policy) failed for set_sys_boot_options.\n");
1091 rc = IPMI_CC_UNSPECIFIED_ERROR;
1092 }
shgoupfd84fbbf2015-12-17 10:05:51 +08001093
Ratan Guptafd28dd72016-08-01 04:58:01 -05001094 } else if (reqptr->parameter ==
1095 (uint8_t)BootOptionParameter::OPAL_NETWORK_SETTINGS) {
1096
1097 int ret = setHostNetworkData(reqptr);
1098 if (ret < 0) {
1099 fprintf(stderr, "setHostNetworkData failed for set_sys_boot_options.\n");
1100 rc = IPMI_CC_UNSPECIFIED_ERROR;
1101 }
1102 }
1103 else {
shgoupfd84fbbf2015-12-17 10:05:51 +08001104 fprintf(stderr, "Unsupported parameter 0x%x\n", reqptr->parameter);
1105 rc = IPMI_CC_PARM_NOT_SUPPORTED;
Adriana Kobylak40814c62015-10-27 15:58:44 -05001106 }
1107
1108 return rc;
1109}
1110
1111void register_netfn_chassis_functions()
1112{
Tom05732372016-09-06 17:21:23 +05301113 // <Wildcard Command>
Adriana Kobylak40814c62015-10-27 15:58:44 -05001114 printf("Registering NetFn:[0x%X], Cmd:[0x%X]\n",NETFUN_CHASSIS, IPMI_CMD_WILDCARD);
Tom05732372016-09-06 17:21:23 +05301115 ipmi_register_callback(NETFUN_CHASSIS, IPMI_CMD_WILDCARD, NULL, ipmi_chassis_wildcard,
1116 PRIVILEGE_USER);
Adriana Kobylak40814c62015-10-27 15:58:44 -05001117
Tom05732372016-09-06 17:21:23 +05301118 // Get Chassis Capabilities
Nan Li8d15fb42016-08-16 22:29:40 +08001119 printf("Registering NetFn:[0x%X], Cmd:[0x%X]\n",NETFUN_CHASSIS, IPMI_CMD_GET_CHASSIS_CAP);
Tom05732372016-09-06 17:21:23 +05301120 ipmi_register_callback(NETFUN_CHASSIS, IPMI_CMD_GET_CHASSIS_CAP, NULL, ipmi_get_chassis_cap,
1121 PRIVILEGE_USER);
Nan Li8d15fb42016-08-16 22:29:40 +08001122
Tom05732372016-09-06 17:21:23 +05301123 // <Get System Boot Options>
Adriana Kobylak40814c62015-10-27 15:58:44 -05001124 printf("Registering NetFn:[0x%X], Cmd:[0x%X]\n",NETFUN_CHASSIS, IPMI_CMD_GET_SYS_BOOT_OPTIONS);
Tom05732372016-09-06 17:21:23 +05301125 ipmi_register_callback(NETFUN_CHASSIS, IPMI_CMD_GET_SYS_BOOT_OPTIONS, NULL,
1126 ipmi_chassis_get_sys_boot_options, PRIVILEGE_OPERATOR);
Adriana Kobylak40814c62015-10-27 15:58:44 -05001127
Tom05732372016-09-06 17:21:23 +05301128 // <Get Chassis Status>
Nan Lifdd8ec52016-08-28 03:57:40 +08001129 printf("Registering NetFn:[0x%X], Cmd:[0x%X]\n",NETFUN_CHASSIS, IPMI_CMD_CHASSIS_STATUS);
Tom05732372016-09-06 17:21:23 +05301130 ipmi_register_callback(NETFUN_CHASSIS, IPMI_CMD_CHASSIS_STATUS, NULL, ipmi_get_chassis_status,
1131 PRIVILEGE_USER);
Nan Lifdd8ec52016-08-28 03:57:40 +08001132
Tom05732372016-09-06 17:21:23 +05301133 // <Chassis Control>
vishwa36993272015-11-20 12:43:49 -06001134 printf("Registering NetFn:[0x%X], Cmd:[0x%X]\n",NETFUN_CHASSIS, IPMI_CMD_CHASSIS_CONTROL);
Tom05732372016-09-06 17:21:23 +05301135 ipmi_register_callback(NETFUN_CHASSIS, IPMI_CMD_CHASSIS_CONTROL, NULL, ipmi_chassis_control,
1136 PRIVILEGE_OPERATOR);
shgoupfd84fbbf2015-12-17 10:05:51 +08001137
Tom05732372016-09-06 17:21:23 +05301138 // <Set System Boot Options>
shgoupfd84fbbf2015-12-17 10:05:51 +08001139 printf("Registering NetFn:[0x%X], Cmd:[0x%X]\n", NETFUN_CHASSIS, IPMI_CMD_SET_SYS_BOOT_OPTIONS);
Tom05732372016-09-06 17:21:23 +05301140 ipmi_register_callback(NETFUN_CHASSIS, IPMI_CMD_SET_SYS_BOOT_OPTIONS, NULL,
1141 ipmi_chassis_set_sys_boot_options, PRIVILEGE_OPERATOR);
vishwa36993272015-11-20 12:43:49 -06001142}