blob: 39b2994c9ee3a4d097009f5418fcfda54292e7cc [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>
ratagupta6f6bff2016-04-04 06:20:11 -050016
17//Defines
Ratan Guptafd28dd72016-08-01 04:58:01 -050018#define SET_PARM_VERSION 0x01
19#define SET_PARM_BOOT_FLAGS_PERMANENT 0x40 //boot flags data1 7th bit on
ratagupta6f6bff2016-04-04 06:20:11 -050020#define SET_PARM_BOOT_FLAGS_VALID_ONE_TIME 0x80 //boot flags data1 8th bit on
Ratan Guptafd28dd72016-08-01 04:58:01 -050021#define SET_PARM_BOOT_FLAGS_VALID_PERMANENT 0xC0 //boot flags data1 7 & 8 bit on
ratagupta6f6bff2016-04-04 06:20:11 -050022
Ratan Guptafd28dd72016-08-01 04:58:01 -050023constexpr size_t SIZE_MAC = 18;
24constexpr size_t SIZE_BOOT_OPTION = (uint8_t)BootOptionResponseSize::
25 OPAL_NETWORK_SETTINGS;//Maximum size of the boot option parametrs
26constexpr size_t SIZE_PREFIX = 7;
27constexpr size_t MAX_PREFIX_VALUE = 32;
28constexpr size_t SIZE_COOKIE = 4;
29constexpr size_t SIZE_VERSION = 2;
30constexpr auto MAC_ADDRESS_FORMAT = "%hhx:%hhx:%hhx:%hhx:%hhx:%hhx";
31constexpr auto IP_ADDRESS_FORMAT = "%d.%d.%d.%d";
Matthew Barth8b470052016-09-21 10:02:57 -050032constexpr auto PREFIX_FORMAT = "%hhd";
Ratan Guptafd28dd72016-08-01 04:58:01 -050033constexpr auto ADDR_TYPE_FORMAT = "%hhx";
34//PetiBoot-Specific
35static constexpr uint8_t net_conf_initial_bytes[] = {0x80,0x21, 0x70 ,0x62 ,0x21,
36 0x00 ,0x01 ,0x06 ,0x04};
37
38static constexpr size_t COOKIE_OFFSET = 1;
39static constexpr size_t VERSION_OFFSET = 5;
40static constexpr size_t MAC_OFFSET = 9;
41static constexpr size_t ADDRTYPE_OFFSET = 16;
42static constexpr size_t IPADDR_OFFSET = 17;
43static constexpr size_t PREFIX_OFFSET = 21;
44static constexpr size_t GATEWAY_OFFSET = 22;
ratagupta6f6bff2016-04-04 06:20:11 -050045
46
vishwa36993272015-11-20 12:43:49 -060047
shgoupfd84fbbf2015-12-17 10:05:51 +080048
Adriana Kobylak40814c62015-10-27 15:58:44 -050049void register_netfn_chassis_functions() __attribute__((constructor));
50
shgoupfd84fbbf2015-12-17 10:05:51 +080051// Host settings in dbus
52// Service name should be referenced by connection name got via object mapper
53const char *settings_object_name = "/org/openbmc/settings/host0";
54const char *settings_intf_name = "org.freedesktop.DBus.Properties";
55const char *host_intf_name = "org.openbmc.settings.Host";
56
Nan Li8d15fb42016-08-16 22:29:40 +080057typedef struct
58{
59 uint8_t cap_flags;
60 uint8_t fru_info_dev_addr;
61 uint8_t sdr_dev_addr;
62 uint8_t sel_dev_addr;
63 uint8_t system_management_dev_addr;
64 uint8_t bridge_dev_addr;
65}__attribute__((packed)) ipmi_chassis_cap_t;
66
Nan Lifdd8ec52016-08-28 03:57:40 +080067typedef struct
68{
69 uint8_t cur_power_state;
70 uint8_t last_power_event;
71 uint8_t misc_power_state;
72 uint8_t front_panel_button_cap_status;
73}__attribute__((packed)) ipmi_get_chassis_status_t;
74
Vishwanatha Subbannab12b0c02017-03-07 18:17:19 +053075// Phosphor Host State manager
76namespace State = sdbusplus::xyz::openbmc_project::State::server;
77
ratagupta6f6bff2016-04-04 06:20:11 -050078int dbus_get_property(const char *name, char **buf)
shgoupfd84fbbf2015-12-17 10:05:51 +080079{
80 sd_bus_error error = SD_BUS_ERROR_NULL;
81 sd_bus_message *m = NULL;
82 sd_bus *bus = NULL;
83 char *temp_buf = NULL;
84 char *connection = NULL;
85 int r;
86
Brad Bishop35518682016-07-22 08:35:41 -040087 // Get the system bus where most system services are provided.
88 bus = ipmid_get_sd_bus_connection();
shgoupfd84fbbf2015-12-17 10:05:51 +080089
Brad Bishop35518682016-07-22 08:35:41 -040090 r = mapper_get_service(bus, settings_object_name, &connection);
shgoupfd84fbbf2015-12-17 10:05:51 +080091 if (r < 0) {
Brad Bishop819ddd42016-10-05 21:19:19 -040092 fprintf(stderr, "Failed to get %s connection: %s\n",
93 settings_object_name, strerror(-r));
shgoupfd84fbbf2015-12-17 10:05:51 +080094 goto finish;
95 }
96
shgoupfd84fbbf2015-12-17 10:05:51 +080097 /*
98 * Bus, service, object path, interface and method are provided to call
99 * the method.
100 * Signatures and input arguments are provided by the arguments at the
101 * end.
102 */
103 r = sd_bus_call_method(bus,
104 connection, /* service to contact */
105 settings_object_name, /* object path */
106 settings_intf_name, /* interface name */
107 "Get", /* method name */
108 &error, /* object to return error in */
109 &m, /* return message on success */
110 "ss", /* input signature */
111 host_intf_name, /* first argument */
ratagupta6f6bff2016-04-04 06:20:11 -0500112 name); /* second argument */
shgoupfd84fbbf2015-12-17 10:05:51 +0800113
114 if (r < 0) {
115 fprintf(stderr, "Failed to issue method call: %s\n", error.message);
116 goto finish;
117 }
118
119 /*
120 * The output should be parsed exactly the same as the output formatting
121 * specified.
122 */
123 r = sd_bus_message_read(m, "v", "s", &temp_buf);
124 if (r < 0) {
125 fprintf(stderr, "Failed to parse response message: %s\n", strerror(-r));
126 goto finish;
127 }
128
Matthew Barth56181052017-01-23 09:36:29 -0600129 *buf = strdup(temp_buf);
shgoupfd84fbbf2015-12-17 10:05:51 +0800130/* *buf = (char*) malloc(strlen(temp_buf));
131 if (*buf) {
132 strcpy(*buf, temp_buf);
133 }
134*/
135 printf("IPMID boot option property get: {%s}.\n", (char *) temp_buf);
136
137finish:
138 sd_bus_error_free(&error);
139 sd_bus_message_unref(m);
140 free(connection);
141
142 return r;
143}
144
ratagupta6f6bff2016-04-04 06:20:11 -0500145int dbus_set_property(const char * name, const char *value)
shgoupfd84fbbf2015-12-17 10:05:51 +0800146{
147 sd_bus_error error = SD_BUS_ERROR_NULL;
148 sd_bus_message *m = NULL;
149 sd_bus *bus = NULL;
150 char *connection = NULL;
151 int r;
152
Brad Bishop35518682016-07-22 08:35:41 -0400153 // Get the system bus where most system services are provided.
154 bus = ipmid_get_sd_bus_connection();
shgoupfd84fbbf2015-12-17 10:05:51 +0800155
Brad Bishop35518682016-07-22 08:35:41 -0400156 r = mapper_get_service(bus, settings_object_name, &connection);
shgoupfd84fbbf2015-12-17 10:05:51 +0800157 if (r < 0) {
Brad Bishop819ddd42016-10-05 21:19:19 -0400158 fprintf(stderr, "Failed to get %s connection: %s\n",
159 settings_object_name, strerror(-r));
shgoupfd84fbbf2015-12-17 10:05:51 +0800160 goto finish;
161 }
162
shgoupfd84fbbf2015-12-17 10:05:51 +0800163 /*
164 * Bus, service, object path, interface and method are provided to call
165 * the method.
166 * Signatures and input arguments are provided by the arguments at the
167 * end.
168 */
169 r = sd_bus_call_method(bus,
170 connection, /* service to contact */
171 settings_object_name, /* object path */
172 settings_intf_name, /* interface name */
173 "Set", /* method name */
174 &error, /* object to return error in */
175 &m, /* return message on success */
176 "ssv", /* input signature */
177 host_intf_name, /* first argument */
ratagupta6f6bff2016-04-04 06:20:11 -0500178 name, /* second argument */
shgoupfd84fbbf2015-12-17 10:05:51 +0800179 "s", /* third argument */
ratagupta6f6bff2016-04-04 06:20:11 -0500180 value); /* fourth argument */
shgoupfd84fbbf2015-12-17 10:05:51 +0800181
182 if (r < 0) {
183 fprintf(stderr, "Failed to issue method call: %s\n", error.message);
184 goto finish;
185 }
186
ratagupta6f6bff2016-04-04 06:20:11 -0500187 printf("IPMID boot option property set: {%s}.\n", value);
shgoupfd84fbbf2015-12-17 10:05:51 +0800188
189finish:
190 sd_bus_error_free(&error);
191 sd_bus_message_unref(m);
192 free(connection);
193
194 return r;
195}
196
Adriana Kobylak40814c62015-10-27 15:58:44 -0500197struct get_sys_boot_options_t {
198 uint8_t parameter;
199 uint8_t set;
200 uint8_t block;
201} __attribute__ ((packed));
202
shgoupfd84fbbf2015-12-17 10:05:51 +0800203struct get_sys_boot_options_response_t {
204 uint8_t version;
205 uint8_t parm;
Ratan Guptafd28dd72016-08-01 04:58:01 -0500206 uint8_t data[SIZE_BOOT_OPTION];
shgoupfd84fbbf2015-12-17 10:05:51 +0800207} __attribute__ ((packed));
208
209struct set_sys_boot_options_t {
210 uint8_t parameter;
Ratan Guptafd28dd72016-08-01 04:58:01 -0500211 uint8_t data[SIZE_BOOT_OPTION];
shgoupfd84fbbf2015-12-17 10:05:51 +0800212} __attribute__ ((packed));
213
Ratan Guptafd28dd72016-08-01 04:58:01 -0500214struct host_network_config_t {
215 std::string ipaddress;
216 std::string prefix;
217 std::string gateway;
218 std::string macaddress;
219 std::string addrType;
220
221 host_network_config_t()=default;
222};
223
224void fillNetworkConfig( host_network_config_t & host_config ,
225 const std::string& conf_str ) {
226
227 constexpr auto COMMA_DELIMITER = ",";
228 constexpr auto EQUAL_DELIMITER = "=";
229 size_t commaDelimtrPos = 0;
230 size_t equalDelimtrPos = 0,commaDelimtrPrevPos = 0;
231 std::string value;
232 while ( commaDelimtrPos < conf_str.length() ) {
233
234 commaDelimtrPos = conf_str.find(COMMA_DELIMITER,commaDelimtrPos);
235 //This condition is to extract the last
236 //Substring as we will not be having the delimeter
237 //at end. std::string::npos is -1
238
239 if ( commaDelimtrPos == std::string::npos ) {
240 commaDelimtrPos = conf_str.length();
241 }
242
243 equalDelimtrPos = conf_str.find (EQUAL_DELIMITER,commaDelimtrPrevPos);
244
245 //foo,ipaddress=1234
246 if ( equalDelimtrPos == std::string::npos ) {
247
248 commaDelimtrPos++;
249 commaDelimtrPrevPos= commaDelimtrPos;
250 continue;
251 }
252
253 value = conf_str.substr((equalDelimtrPos+1),
254 commaDelimtrPos-(equalDelimtrPos+1));
255
256#ifdef _IPMI_DEBUG_
257 printf ("Name=[%s],Value=[%s],commaDelimtrPos=[%d],\
258 commaDelimtrPrevPos=[%d],equalDelimtrPos=[%d]\n",
259 name.c_str(),value.c_str(),commaDelimtrPos,
260 commaDelimtrPrevPos,equalDelimtrPos);
261#endif
262
263 if ( 0 == conf_str.compare(commaDelimtrPrevPos,
264 equalDelimtrPos-commaDelimtrPrevPos,"ipaddress" )) {
265
266 host_config.ipaddress = std::move(value);
267 }
268 else if ( 0 == conf_str.compare(commaDelimtrPrevPos,
269 equalDelimtrPos-commaDelimtrPrevPos,"prefix" )) {
270
271 host_config.prefix = std::move(value);
272 }
273 else if ( 0 == conf_str.compare(commaDelimtrPrevPos,
274 equalDelimtrPos-commaDelimtrPrevPos, "gateway" )) {
275 host_config.gateway = std::move(value);
276 }
277 else if ( 0 == conf_str.compare(commaDelimtrPrevPos,
278 equalDelimtrPos-commaDelimtrPrevPos, "mac" )) {
279 host_config.macaddress = std::move(value);
280 }
281 else if ( 0 == conf_str.compare(commaDelimtrPrevPos,
282 equalDelimtrPos-commaDelimtrPrevPos, "addr_type" )) {
283 host_config.addrType = std::move(value);
284 }
285
286 commaDelimtrPos++;
287 commaDelimtrPrevPos= commaDelimtrPos;
288 }
289}
290
291int getHostNetworkData(get_sys_boot_options_response_t* respptr)
292{
293
294 char *prop = nullptr;
295 int rc = dbus_get_property("network_config",&prop);
296
297 if ( rc < 0 ) {
298 fprintf(stderr, "Dbus get property(boot_flags) failed\
299 for get_sys_boot_options.\n");
300 return rc;
301 }
302
303 std::string conf_str(prop);
304
305 if ( prop ) {
306
307 free(prop);
308 prop = nullptr;
309 }
310
311 /* network_config property Value would be in the form of
312 * ipaddress=1.1.1.1,prefix=16,gateway=2.2.2.2,mac=11:22:33:44:55:66,dhcp=0
313 */
314
315 /* Parsing the string and fill the hostconfig structure with the
316 * values */
317
318 printf ("Configuration String[%s]\n ",conf_str.c_str());
319
320 host_network_config_t host_config;
321
322 // Fill the host_config from the configuration string
323 fillNetworkConfig(host_config,conf_str);
324
325 //Assigning the index as intialByteLength as it is fixed and prefilled.
326 printf ("host_config.macaddress.c_str()=[%s]\n",host_config.macaddress.c_str());
327 do{
328
329 rc = sscanf(host_config.macaddress.c_str(),MAC_ADDRESS_FORMAT,
330 (respptr->data+MAC_OFFSET), (respptr->data+MAC_OFFSET+1),
331 (respptr->data+MAC_OFFSET+2),(respptr->data+MAC_OFFSET+3),
332 (respptr->data+MAC_OFFSET+4), (respptr->data+MAC_OFFSET+5));
333
334
335 if ( rc < 6 ){
336 fprintf(stderr, "sscanf Failed in extracting mac address.\n");
337 rc = -1;
338 break;
339 }
340
341 //Conevrt the dhcp,ipaddress,mask and gateway as hex number
342 respptr->data[MAC_OFFSET+6]=0x00;
343
344 rc = sscanf(host_config.addrType.c_str(),ADDR_TYPE_FORMAT,
345 (respptr->data+ADDRTYPE_OFFSET));
346
347 if ( rc <= 0 ) {
348 fprintf(stderr, "sscanf Failed in extracting address type.\n");
349 rc = -1;
350 break;
351 }
352
353 //ipaddress and gateway would be in IPv4 format
354 rc = inet_pton(AF_INET,host_config.ipaddress.c_str(),
355 (respptr->data+IPADDR_OFFSET));
356
357 if ( rc <= 0 ) {
358 fprintf(stderr, "inet_pton failed during ipaddress coneversion\n");
359 rc = -1;
360 break;
361 }
362
363 rc = sscanf(host_config.prefix.c_str(),PREFIX_FORMAT,
364 (respptr->data+PREFIX_OFFSET));
365
366 if ( rc <= 0 ) {
367 fprintf(stderr, "sscanf failed during prefix extraction.\n");
368 rc = -1;
369 break;
370 }
371
372 rc = inet_pton(AF_INET,host_config.gateway.c_str(),
373 (respptr->data+GATEWAY_OFFSET));
374
375 if ( rc <= 0 ) {
376 fprintf(stderr, "inet_pton failed during gateway conversion.\n");
377 rc = -1;
378 break;
379 }
380
381 }while (0);
382
383 if ( rc ) {
384
385 //PetiBoot-Specific
386 //If sucess then copy the first 9 bytes to the data
387 //else set the respptr to 0
388
389 memcpy(respptr->data,net_conf_initial_bytes,
390 sizeof(net_conf_initial_bytes));
391
392#ifdef _IPMI_DEBUG_
393 printf ("\n===Printing the IPMI Formatted Data========\n");
394
395 for ( uint8_t pos = 0; pos<index; pos++ )
396 printf("%02x ", respptr->data[pos]);
397#endif
398
399 }else {
400
401 memset(respptr->data,0,SIZE_BOOT_OPTION);
402 }
403
404 return rc;
405}
406
407int setHostNetworkData(set_sys_boot_options_t * reqptr)
408{
409 std::string host_network_config;
410 char mac[SIZE_MAC] = {0};
411 char ipAddress[INET_ADDRSTRLEN] = {0};
412 char gateway[INET_ADDRSTRLEN] = {0};
413 char dhcp[SIZE_PREFIX] = {0};
414 char prefix[SIZE_PREFIX] = {0};
415 int rc = 0;
416 uint32_t zeroCookie=0;
417
418 //cookie starts from second byte
419 // version starts from sixth byte
420
421 do {
422
423 // cookie == 0x21 0x70 0x62 0x21
424 if ( memcmp(&(reqptr->data[COOKIE_OFFSET]),
425 (net_conf_initial_bytes+COOKIE_OFFSET),
426 SIZE_COOKIE) != 0 ) {
427 //cookie == 0
428 if ( memcmp(&(reqptr->data[COOKIE_OFFSET]),
429 &zeroCookie,
430 SIZE_COOKIE) == 0 ) {
431 rc = 0;
432 break;
433 }
434 //Invalid cookie
435 fprintf(stderr, "Invalid Cookie\n");
436 rc = -1;
437 break;
438 }
439 // vesion == 0x00 0x01
440 if ( memcmp(&(reqptr->data[VERSION_OFFSET]),
441 (net_conf_initial_bytes+VERSION_OFFSET),
442 SIZE_VERSION) != 0 ) {
443
444 fprintf(stderr, "Invalid Version\n");
445 rc = -1;
446 break;
447 }
448
449 snprintf(mac, SIZE_MAC, MAC_ADDRESS_FORMAT,
450 reqptr->data[MAC_OFFSET],
451 reqptr->data[MAC_OFFSET+1],
452 reqptr->data[MAC_OFFSET+2],
453 reqptr->data[MAC_OFFSET+3],
454 reqptr->data[MAC_OFFSET+4],
455 reqptr->data[MAC_OFFSET+5]);
456
457 snprintf(dhcp,SIZE_PREFIX, ADDR_TYPE_FORMAT, reqptr->data[ADDRTYPE_OFFSET]);
458 //Validating the address type which could be
459 //either static or dynamic
460 if( *(reqptr->data+ADDRTYPE_OFFSET) > 1 ) {
461
462 fprintf(stderr, "Invalid Address Type\n");
463 rc = -1;
464 break;
465
466 }
467
468 snprintf(ipAddress, INET_ADDRSTRLEN, IP_ADDRESS_FORMAT,
469 reqptr->data[IPADDR_OFFSET], reqptr->data[IPADDR_OFFSET+1],
470 reqptr->data[IPADDR_OFFSET+2], reqptr->data[IPADDR_OFFSET+3]);
471
472 //validating prefix
473 if ( *(reqptr->data+PREFIX_OFFSET) > (uint8_t)MAX_PREFIX_VALUE ) {
474
475 fprintf(stderr, "Invalid Prefix\n");
476 rc = -1;
477 break;
478 }
479
480 snprintf(prefix,SIZE_PREFIX,PREFIX_FORMAT, reqptr->data[PREFIX_OFFSET]);
481
482 snprintf(gateway, INET_ADDRSTRLEN,IP_ADDRESS_FORMAT,
483 reqptr->data[GATEWAY_OFFSET], reqptr->data[GATEWAY_OFFSET+1],
484 reqptr->data[GATEWAY_OFFSET+2], reqptr->data[GATEWAY_OFFSET+3]);
485
486
487 }while(0);
488
489 if( !rc )
490 {
491 //Cookie == 0 or it is a valid cookie
492 host_network_config += "ipaddress="+std::string(ipAddress)+",prefix="+
493 std::string(prefix)+",gateway="+std::string(gateway)+
494 ",mac="+std::string(mac)+",addr_type="+std::string(dhcp);
495
496 printf ("Network configuration changed: %s\n",host_network_config.c_str());
497
498 rc = dbus_set_property("network_config",host_network_config.c_str());
499
500 if ( rc < 0 ) {
501 fprintf(stderr, "Dbus set property(network_config)\
502 failed for set_sys_boot_options.\n");
503 rc = -1;
504 }
505
506 }
507 return rc;
508}
509
Adriana Kobylak40814c62015-10-27 15:58:44 -0500510ipmi_ret_t ipmi_chassis_wildcard(ipmi_netfn_t netfn, ipmi_cmd_t cmd,
511 ipmi_request_t request, ipmi_response_t response,
512 ipmi_data_len_t data_len, ipmi_context_t context)
513{
514 printf("Handling CHASSIS WILDCARD Netfn:[0x%X], Cmd:[0x%X]\n",netfn, cmd);
515 // Status code.
Nan Li70aa8d92016-08-29 00:11:10 +0800516 ipmi_ret_t rc = IPMI_CC_INVALID;
Adriana Kobylak40814c62015-10-27 15:58:44 -0500517 *data_len = 0;
518 return rc;
519}
520
Nan Li8d15fb42016-08-16 22:29:40 +0800521ipmi_ret_t ipmi_get_chassis_cap(ipmi_netfn_t netfn, ipmi_cmd_t cmd,
522 ipmi_request_t request, ipmi_response_t response,
523 ipmi_data_len_t data_len, ipmi_context_t context)
524{
525 // sd_bus error
526 ipmi_ret_t rc = IPMI_CC_OK;
527
528 ipmi_chassis_cap_t chassis_cap{};
529
530 *data_len = sizeof(ipmi_chassis_cap_t);
531
532 // TODO: need future work. Get those flag from MRW.
533
534 // capabilities flags
535 // [7..4] - reserved
536 // [3] – 1b = provides power interlock (IPM 1.5)
537 // [2] – 1b = provides Diagnostic Interrupt (FP NMI)
538 // [1] – 1b = provides “Front Panel Lockout” (indicates that the chassis has capabilities
539 // to lock out external power control and reset button or front panel interfaces
540 // and/or detect tampering with those interfaces).
541 // [0] -1b = Chassis provides intrusion (physical security) sensor.
542 // set to default value 0x0.
543 chassis_cap.cap_flags = 0x0;
544
545 // Since we do not have a separate SDR Device/SEL Device/ FRU repository.
546 // The 20h was given as those 5 device addresses.
547 // Chassis FRU info Device Address
548 chassis_cap.fru_info_dev_addr = 0x20;
549
550 // Chassis SDR Device Address
551 chassis_cap.sdr_dev_addr = 0x20;
552
553 // Chassis SEL Device Address
554 chassis_cap.sel_dev_addr = 0x20;
555
556 // Chassis System Management Device Address
557 chassis_cap.system_management_dev_addr = 0x20;
558
559 // Chassis Bridge Device Address.
560 chassis_cap.bridge_dev_addr = 0x20;
561
562 memcpy(response, &chassis_cap, *data_len);
563
564 return rc;
565}
566
Vishwanatha Subbannab12b0c02017-03-07 18:17:19 +0530567//------------------------------------------
568// Calls into Host State Manager Dbus object
569//------------------------------------------
570int initiate_state_transition(State::Host::Transition transition)
vishwa36993272015-11-20 12:43:49 -0600571{
Vishwanatha Subbannab12b0c02017-03-07 18:17:19 +0530572 using namespace phosphor::logging;
573
574 // OpenBMC Host State Manager dbus framework
575 constexpr auto HOST_STATE_MANAGER_ROOT = "/xyz/openbmc_project/state/host0";
576 constexpr auto HOST_STATE_MANAGER_IFACE = "xyz.openbmc_project.State.Host";
577 constexpr auto DBUS_PROPERTY_IFACE = "org.freedesktop.DBus.Properties";
578 constexpr auto PROPERTY = "RequestedHostTransition";
579
vishwa36993272015-11-20 12:43:49 -0600580 // sd_bus error
581 int rc = 0;
Sergey Solomineb9b8142016-08-23 09:07:28 -0500582 char *busname = NULL;
vishwa36993272015-11-20 12:43:49 -0600583
Sergey Solomineb9b8142016-08-23 09:07:28 -0500584 // SD Bus error report mechanism.
585 sd_bus_error bus_error = SD_BUS_ERROR_NULL;
vishwa36993272015-11-20 12:43:49 -0600586
vishwa36993272015-11-20 12:43:49 -0600587 // Gets a hook onto either a SYSTEM or SESSION bus
588 sd_bus *bus_type = ipmid_get_sd_bus_connection();
Vishwanatha Subbannab12b0c02017-03-07 18:17:19 +0530589 rc = mapper_get_service(bus_type, HOST_STATE_MANAGER_ROOT, &busname);
Sergey Solomineb9b8142016-08-23 09:07:28 -0500590 if (rc < 0) {
Vishwanatha Subbannab12b0c02017-03-07 18:17:19 +0530591 log<level::ERR>("Failed to get bus name",
592 entry("ERROR=%s, OBJPATH=%s",
593 strerror(-rc), HOST_STATE_MANAGER_ROOT));
594 return rc;
Sergey Solomineb9b8142016-08-23 09:07:28 -0500595 }
Vishwanatha Subbannab12b0c02017-03-07 18:17:19 +0530596
597 // Convert to string equivalent of the passed in transition enum.
598 auto request = State::convertForMessage(transition);
599
600 rc = sd_bus_call_method(bus_type, // On the system bus
601 busname, // Service to contact
602 HOST_STATE_MANAGER_ROOT, // Object path
603 DBUS_PROPERTY_IFACE, // Interface name
604 "Set", // Method to be called
605 &bus_error, // object to return error
606 nullptr, // Response buffer if any
607 "ssv", // Takes 3 arguments
608 HOST_STATE_MANAGER_IFACE,
609 PROPERTY,
610 "s", request.c_str());
vishwa36993272015-11-20 12:43:49 -0600611 if(rc < 0)
612 {
Vishwanatha Subbannab12b0c02017-03-07 18:17:19 +0530613 log<level::ERR>("Failed to initiate transition",
614 entry("ERROR=%s, REQUEST=%s",
615 bus_error.message, request.c_str()));
vishwa36993272015-11-20 12:43:49 -0600616 }
617 else
618 {
Vishwanatha Subbannab12b0c02017-03-07 18:17:19 +0530619 log<level::INFO>("Transition request initiated successfully");
vishwa36993272015-11-20 12:43:49 -0600620 }
621
622 sd_bus_error_free(&bus_error);
Sergey Solomineb9b8142016-08-23 09:07:28 -0500623 free(busname);
vishwa36993272015-11-20 12:43:49 -0600624
Sergey Solomineb9b8142016-08-23 09:07:28 -0500625 return rc;
vishwa36993272015-11-20 12:43:49 -0600626}
627
Nan Lifdd8ec52016-08-28 03:57:40 +0800628struct hostPowerPolicyTypeMap_t {
629 uint8_t policyNum;
630 char policyName[19];
631};
632
633hostPowerPolicyTypeMap_t g_hostPowerPolicyTypeMap_t[] = {
634
635 {0x00, "LEAVE_OFF"},
636 {0x01, "RESTORE_LAST_STATE"},
637 {0x02, "ALWAYS_POWER_ON"},
638 {0x03, "UNKNOWN"}
639};
640
641uint8_t get_host_power_policy(char *p) {
642
643 hostPowerPolicyTypeMap_t *s = g_hostPowerPolicyTypeMap_t;
644
645 while (s->policyNum != 0x03) {
646 if (!strcmp(s->policyName,p))
647 break;
648 s++;
649 }
650
651 return s->policyNum;
652}
653
654//----------------------------------------------------------------------
655// Get Chassis Status commands
656//----------------------------------------------------------------------
657ipmi_ret_t ipmi_get_chassis_status(ipmi_netfn_t netfn, ipmi_cmd_t cmd,
658 ipmi_request_t request, ipmi_response_t response,
659 ipmi_data_len_t data_len, ipmi_context_t context)
660{
661 const char *objname = "/org/openbmc/control/power0";
662 const char *intf = "org.openbmc.control.Power";
663
664 sd_bus *bus = NULL;
665 sd_bus_message *reply = NULL;
666 int r = 0;
667 int pgood = 0;
668 char *busname = NULL;
669 ipmi_ret_t rc = IPMI_CC_OK;
670 ipmi_get_chassis_status_t chassis_status{};
671
672 char *p = NULL;
673 uint8_t s = 0;
674
675 // Get the system bus where most system services are provided.
676 bus = ipmid_get_sd_bus_connection();
677
678 *data_len = 4;
679
680 r = mapper_get_service(bus, objname, &busname);
681 if (r < 0) {
682 fprintf(stderr, "Failed to get bus name, return value: %s.\n", strerror(-r));
683 rc = IPMI_CC_UNSPECIFIED_ERROR;
684 goto finish;
685 }
686
687 r = sd_bus_get_property(bus, busname, objname, intf, "pgood", NULL, &reply, "i");
688 if (r < 0) {
689 fprintf(stderr, "Failed to call sd_bus_get_property:%d, %s\n", r, strerror(-r));
690 fprintf(stderr, "Bus: %s, Path: %s, Interface: %s\n",
691 busname, objname, intf);
692 rc = IPMI_CC_UNSPECIFIED_ERROR;
693 goto finish;
694 }
695
696 r = sd_bus_message_read(reply, "i", &pgood);
697 if (r < 0) {
698 fprintf(stderr, "Failed to read sensor: %s\n", strerror(-r));
699 rc = IPMI_CC_UNSPECIFIED_ERROR;
700 goto finish;
701 }
702
703 printf("pgood is 0x%02x\n", pgood);
704
705 // Get Power Policy
706 r = dbus_get_property("power_policy",&p);
707
708 if (r < 0) {
709 fprintf(stderr, "Dbus get property(power_policy) failed for get_sys_boot_options.\n");
710 rc = IPMI_CC_UNSPECIFIED_ERROR;
711 } else {
712 s = get_host_power_policy(p);
713 }
714
715 if (p)
716 {
717 free(p);
718 p = NULL;
719 }
720
721 // Current Power State
722 // [7] reserved
723 // [6..5] power restore policy
724 // 00b = chassis stays powered off after AC/mains returns
725 // 01b = after AC returns, power is restored to the state that was
726 // in effect when AC/mains was lost.
727 // 10b = chassis always powers up after AC/mains returns
728 // 11b = unknow
729 // Set to 00b, by observing the hardware behavior.
730 // Do we need to define a dbus property to identify the restore policy?
731
732 // [4] power control fault
733 // 1b = controller attempted to turn system power on or off, but
734 // system did not enter desired state.
735 // Set to 0b, since We don't support it..
736
737 // [3] power fault
738 // 1b = fault detected in main power subsystem.
739 // set to 0b. for we don't support it.
740
741 // [2] 1b = interlock (chassis is presently shut down because a chassis
742 // panel interlock switch is active). (IPMI 1.5)
743 // set to 0b, for we don't support it.
744
745 // [1] power overload
746 // 1b = system shutdown because of power overload condition.
747 // set to 0b, for we don't support it.
748
749 // [0] power is on
750 // 1b = system power is on
751 // 0b = system power is off(soft-off S4/S5, or mechanical off)
752
753 chassis_status.cur_power_state = ((s & 0x3)<<5) | (pgood & 0x1);
754
755 // Last Power Event
756 // [7..5] – reserved
757 // [4] – 1b = last ‘Power is on’ state was entered via IPMI command
758 // [3] – 1b = last power down caused by power fault
759 // [2] – 1b = last power down caused by a power interlock being activated
760 // [1] – 1b = last power down caused by a Power overload
761 // [0] – 1b = AC failed
762 // set to 0x0, for we don't support these fields.
763
764 chassis_status.last_power_event = 0;
765
766 // Misc. Chassis State
767 // [7] – reserved
768 // [6] – 1b = Chassis Identify command and state info supported (Optional)
769 // 0b = Chassis Identify command support unspecified via this command.
770 // (The Get Command Support command , if implemented, would still
771 // indicate support for the Chassis Identify command)
772 // [5..4] – Chassis Identify State. Mandatory when bit[6] =1b, reserved (return
773 // as 00b) otherwise. Returns the present chassis identify state.
774 // Refer to the Chassis Identify command for more info.
775 // 00b = chassis identify state = Off
776 // 01b = chassis identify state = Temporary(timed) On
777 // 10b = chassis identify state = Indefinite On
778 // 11b = reserved
779 // [3] – 1b = Cooling/fan fault detected
780 // [2] – 1b = Drive Fault
781 // [1] – 1b = Front Panel Lockout active (power off and reset via chassis
782 // push-buttons disabled.)
783 // [0] – 1b = Chassis Intrusion active
784 // set to 0, for we don't support them.
785 chassis_status.misc_power_state = 0;
786
787 // Front Panel Button Capabilities and disable/enable status(Optional)
788 // set to 0, for we don't support them.
789 chassis_status.front_panel_button_cap_status = 0;
790
791 // Pack the actual response
792 memcpy(response, &chassis_status, *data_len);
793
794finish:
795 free(busname);
796 reply = sd_bus_message_unref(reply);
797
798 return rc;
799}
Chris Austen7888c4d2015-12-03 15:26:20 -0600800
Vishwanatha Subbanna83b5c1c2017-01-25 18:41:51 +0530801//-------------------------------------------------------------
802// Send a command to SoftPowerOff application to stop any timer
803//-------------------------------------------------------------
804int stop_soft_off_timer()
805{
806 constexpr auto objname = "/xyz/openbmc_project/ipmi/internal/"
807 "softpoweroff";
808 constexpr auto iface = "org.freedesktop.DBus.Properties";
809 constexpr auto soft_off_iface = "xyz.openbmc_project.Ipmi.Internal."
810 "SoftPowerOff";
811
812 constexpr auto property = "ResponseReceived";
813 constexpr auto value = "xyz.openbmc_project.Ipmi.Internal."
814 "SoftPowerOff.HostResponse.HostShutdown";
815 char *busname = nullptr;
816
817 // Get the system bus where most system services are provided.
818 auto bus = ipmid_get_sd_bus_connection();
819
820 // Get the service name
821 auto r = mapper_get_service(bus, objname, &busname);
822 if (r < 0) {
823 fprintf(stderr, "Failed to get %s bus name: %s\n",
824 objname, strerror(-r));
825 return r;
826 }
827
828 // No error object or reply expected.
829 int rc = sd_bus_call_method(bus, busname, objname, iface,
830 "Set", nullptr, nullptr, "ssv",
831 soft_off_iface, property, "s", value);
832 if (rc < 0)
833 {
834 fprintf(stderr, "Failed to set property in SoftPowerOff object: %s\n",
835 strerror(-rc));
836 }
837 free(busname);
838 return rc;
839}
840
vishwa36993272015-11-20 12:43:49 -0600841//----------------------------------------------------------------------
842// Chassis Control commands
843//----------------------------------------------------------------------
844ipmi_ret_t ipmi_chassis_control(ipmi_netfn_t netfn, ipmi_cmd_t cmd,
845 ipmi_request_t request, ipmi_response_t response,
846 ipmi_data_len_t data_len, ipmi_context_t context)
847{
848 // Error from power off.
849 int rc = 0;
850
851 // No response for this command.
852 *data_len = 0;
853
854 // Catch the actual operaton by peeking into request buffer
855 uint8_t chassis_ctrl_cmd = *(uint8_t *)request;
856 printf("Chassis Control Command: Operation:[0x%X]\n",chassis_ctrl_cmd);
857
858 switch(chassis_ctrl_cmd)
859 {
Vishwanatha Subbannaa66239b2017-03-02 16:54:32 +0530860 case CMD_POWER_ON:
Vishwanatha Subbannab12b0c02017-03-07 18:17:19 +0530861 rc = initiate_state_transition(State::Host::Transition::On);
Vishwanatha Subbannaa66239b2017-03-02 16:54:32 +0530862 break;
vishwa36993272015-11-20 12:43:49 -0600863 case CMD_POWER_OFF:
Vishwanatha Subbanna83b5c1c2017-01-25 18:41:51 +0530864 // Need to Nudge SoftPowerOff application that it needs to stop the
865 // watchdog timer if running.
866 rc = stop_soft_off_timer();
867 if (!rc)
868 {
869 fprintf(stderr, "Error stopping watchdog timer");
870 }
871 // Does not matter if we are able to stop the timer,
872 // just get going and do the hard power off
Vishwanatha Subbannab12b0c02017-03-07 18:17:19 +0530873 rc = initiate_state_transition(State::Host::Transition::Off);
vishwa36993272015-11-20 12:43:49 -0600874 break;
Vishwanatha Subbanna83b5c1c2017-01-25 18:41:51 +0530875
Chris Austen7888c4d2015-12-03 15:26:20 -0600876 case CMD_HARD_RESET:
Vishwanatha Subbannabb5190e2017-03-01 14:53:29 +0530877 case CMD_POWER_CYCLE:
878 // SPEC has a section that says certain implementations can trigger
879 // PowerOn if power is Off when a command to power cycle is
880 // requested
Vishwanatha Subbannab12b0c02017-03-07 18:17:19 +0530881 rc = initiate_state_transition(State::Host::Transition::Reboot);
Chris Austen7888c4d2015-12-03 15:26:20 -0600882 break;
vishwa36993272015-11-20 12:43:49 -0600883 default:
884 {
885 fprintf(stderr, "Invalid Chassis Control command:[0x%X] received\n",chassis_ctrl_cmd);
886 rc = -1;
887 }
888 }
889
890 return ( (rc < 0) ? IPMI_CC_INVALID : IPMI_CC_OK);
891}
892
shgoupfd84fbbf2015-12-17 10:05:51 +0800893struct bootOptionTypeMap_t {
894 uint8_t ipmibootflag;
895 char dbusname[8];
896};
897
898#define INVALID_STRING "Invalid"
899// dbus supports this list of boot devices.
900bootOptionTypeMap_t g_bootOptionTypeMap_t[] = {
901
902 {0x01, "Network"},
903 {0x02, "Disk"},
904 {0x03, "Safe"},
905 {0x05, "CDROM"},
906 {0x06, "Setup"},
907 {0x00, "Default"},
908 {0xFF, INVALID_STRING}
909};
910
911uint8_t get_ipmi_boot_option(char *p) {
912
913 bootOptionTypeMap_t *s = g_bootOptionTypeMap_t;
914
915 while (s->ipmibootflag != 0xFF) {
916 if (!strcmp(s->dbusname,p))
917 break;
918 s++;
919 }
920
921 if (!s->ipmibootflag)
922 printf("Failed to find Sensor Type %s\n", p);
923
924 return s->ipmibootflag;
925}
926
927char* get_boot_option_by_ipmi(uint8_t p) {
928
929 bootOptionTypeMap_t *s = g_bootOptionTypeMap_t;
930
931 while (s->ipmibootflag != 0xFF) {
932
933 if (s->ipmibootflag == p)
934 break;
935
936 s++;
937 }
938
939
940 if (!s->ipmibootflag)
941 printf("Failed to find Sensor Type 0x%x\n", p);
942
943 return s->dbusname;
944}
945
Adriana Kobylak40814c62015-10-27 15:58:44 -0500946ipmi_ret_t ipmi_chassis_get_sys_boot_options(ipmi_netfn_t netfn, ipmi_cmd_t cmd,
947 ipmi_request_t request, ipmi_response_t response,
948 ipmi_data_len_t data_len, ipmi_context_t context)
949{
shgoupfd84fbbf2015-12-17 10:05:51 +0800950 ipmi_ret_t rc = IPMI_CC_PARM_NOT_SUPPORTED;
951 char *p = NULL;
952 get_sys_boot_options_response_t *resp = (get_sys_boot_options_response_t *) response;
953 get_sys_boot_options_t *reqptr = (get_sys_boot_options_t*) request;
954 uint8_t s;
Adriana Kobylak40814c62015-10-27 15:58:44 -0500955
956 printf("IPMI GET_SYS_BOOT_OPTIONS\n");
957
shgoupfd84fbbf2015-12-17 10:05:51 +0800958 memset(resp,0,sizeof(*resp));
959 resp->version = SET_PARM_VERSION;
960 resp->parm = 5;
ratagupta6f6bff2016-04-04 06:20:11 -0500961 resp->data[0] = SET_PARM_BOOT_FLAGS_VALID_ONE_TIME;
Adriana Kobylak40814c62015-10-27 15:58:44 -0500962
Adriana Kobylak40814c62015-10-27 15:58:44 -0500963
shgoupfd84fbbf2015-12-17 10:05:51 +0800964 /*
965 * Parameter #5 means boot flags. Please refer to 28.13 of ipmi doc.
966 * This is the only parameter used by petitboot.
967 */
Ratan Guptafd28dd72016-08-01 04:58:01 -0500968 if ( reqptr->parameter == static_cast<uint8_t>
969 ( BootOptionParameter::BOOT_FLAGS )) {
shgoupfd84fbbf2015-12-17 10:05:51 +0800970
Ratan Guptafd28dd72016-08-01 04:58:01 -0500971 *data_len = static_cast<uint8_t>(BootOptionResponseSize::BOOT_FLAGS);
ratagupta6f6bff2016-04-04 06:20:11 -0500972 /* Get the boot device */
973 int r = dbus_get_property("boot_flags",&p);
shgoupfd84fbbf2015-12-17 10:05:51 +0800974
975 if (r < 0) {
ratagupta6f6bff2016-04-04 06:20:11 -0500976 fprintf(stderr, "Dbus get property(boot_flags) failed for get_sys_boot_options.\n");
shgoupfd84fbbf2015-12-17 10:05:51 +0800977 rc = IPMI_CC_UNSPECIFIED_ERROR;
978
979 } else {
980
981 s = get_ipmi_boot_option(p);
982 resp->data[1] = (s << 2);
983 rc = IPMI_CC_OK;
ratagupta6f6bff2016-04-04 06:20:11 -0500984
shgoupfd84fbbf2015-12-17 10:05:51 +0800985 }
986
ratagupta6f6bff2016-04-04 06:20:11 -0500987 if (p)
988 {
989 free(p);
990 p = NULL;
991 }
992
993 /* Get the boot policy */
994 r = dbus_get_property("boot_policy",&p);
995
996 if (r < 0) {
997 fprintf(stderr, "Dbus get property(boot_policy) failed for get_sys_boot_options.\n");
998 rc = IPMI_CC_UNSPECIFIED_ERROR;
999
1000 } else {
1001
Ratan Guptafd28dd72016-08-01 04:58:01 -05001002 printf("BootPolicy is[%s]", p);
ratagupta6f6bff2016-04-04 06:20:11 -05001003 resp->data[0] = (strncmp(p,"ONETIME",strlen("ONETIME"))==0) ?
1004 SET_PARM_BOOT_FLAGS_VALID_ONE_TIME:
1005 SET_PARM_BOOT_FLAGS_VALID_PERMANENT;
1006 rc = IPMI_CC_OK;
1007
1008 }
1009
1010
Ratan Guptafd28dd72016-08-01 04:58:01 -05001011 } else if ( reqptr->parameter == static_cast<uint8_t>
1012 ( BootOptionParameter::OPAL_NETWORK_SETTINGS )) {
1013
1014 *data_len = static_cast<uint8_t>(BootOptionResponseSize::OPAL_NETWORK_SETTINGS);
1015
1016 resp->parm = static_cast<uint8_t>(BootOptionParameter::OPAL_NETWORK_SETTINGS);
1017
1018 int ret = getHostNetworkData(resp);
1019
1020 if (ret < 0) {
1021
1022 fprintf(stderr, "getHostNetworkData failed for get_sys_boot_options.\n");
1023 rc = IPMI_CC_UNSPECIFIED_ERROR;
1024
1025 }else
1026 rc = IPMI_CC_OK;
1027 }
1028
1029 else {
Adriana Kobylak40814c62015-10-27 15:58:44 -05001030 fprintf(stderr, "Unsupported parameter 0x%x\n", reqptr->parameter);
shgoupfd84fbbf2015-12-17 10:05:51 +08001031 }
1032
1033 if (p)
1034 free(p);
1035
Ratan Guptafd28dd72016-08-01 04:58:01 -05001036 if (rc == IPMI_CC_OK)
1037 {
1038 *data_len += 2;
1039 }
1040
shgoupfd84fbbf2015-12-17 10:05:51 +08001041 return rc;
1042}
1043
1044
1045
1046ipmi_ret_t ipmi_chassis_set_sys_boot_options(ipmi_netfn_t netfn, ipmi_cmd_t cmd,
1047 ipmi_request_t request, ipmi_response_t response,
1048 ipmi_data_len_t data_len, ipmi_context_t context)
1049{
1050 ipmi_ret_t rc = IPMI_CC_OK;
1051 char *s;
shgoupfd84fbbf2015-12-17 10:05:51 +08001052 set_sys_boot_options_t *reqptr = (set_sys_boot_options_t *) request;
1053
Ratan Guptafd28dd72016-08-01 04:58:01 -05001054 printf("IPMI SET_SYS_BOOT_OPTIONS reqptr->parameter =[%d]\n",reqptr->parameter);
1055
shgoupfd84fbbf2015-12-17 10:05:51 +08001056 // This IPMI command does not have any resposne data
1057 *data_len = 0;
1058
1059 /* 000101
1060 * Parameter #5 means boot flags. Please refer to 28.13 of ipmi doc.
1061 * This is the only parameter used by petitboot.
1062 */
Ratan Guptafd28dd72016-08-01 04:58:01 -05001063
1064 if (reqptr->parameter == (uint8_t)BootOptionParameter::BOOT_FLAGS) {
shgoupfd84fbbf2015-12-17 10:05:51 +08001065
1066 s = get_boot_option_by_ipmi(((reqptr->data[1] & 0x3C) >> 2));
1067
1068 printf("%d: %s\n", __LINE__, s);
1069 if (!strcmp(s,INVALID_STRING)) {
1070
1071 rc = IPMI_CC_PARM_NOT_SUPPORTED;
1072
1073 } else {
1074
ratagupta6f6bff2016-04-04 06:20:11 -05001075 int r = dbus_set_property("boot_flags",s);
shgoupfd84fbbf2015-12-17 10:05:51 +08001076
1077 if (r < 0) {
ratagupta6f6bff2016-04-04 06:20:11 -05001078 fprintf(stderr, "Dbus set property(boot_flags) failed for set_sys_boot_options.\n");
shgoupfd84fbbf2015-12-17 10:05:51 +08001079 rc = IPMI_CC_UNSPECIFIED_ERROR;
1080 }
1081 }
Ratan Guptafd28dd72016-08-01 04:58:01 -05001082
ratagupta6f6bff2016-04-04 06:20:11 -05001083 /* setting the boot policy */
1084 s = (char *)(((reqptr->data[0] & SET_PARM_BOOT_FLAGS_PERMANENT) ==
Ratan Guptafd28dd72016-08-01 04:58:01 -05001085 SET_PARM_BOOT_FLAGS_PERMANENT) ?"PERMANENT":"ONETIME");
ratagupta6f6bff2016-04-04 06:20:11 -05001086
Ratan Guptafd28dd72016-08-01 04:58:01 -05001087 printf ( "\nBoot Policy is %s",s);
ratagupta6f6bff2016-04-04 06:20:11 -05001088 int r = dbus_set_property("boot_policy",s);
1089
1090 if (r < 0) {
1091 fprintf(stderr, "Dbus set property(boot_policy) failed for set_sys_boot_options.\n");
1092 rc = IPMI_CC_UNSPECIFIED_ERROR;
1093 }
shgoupfd84fbbf2015-12-17 10:05:51 +08001094
Ratan Guptafd28dd72016-08-01 04:58:01 -05001095 } else if (reqptr->parameter ==
1096 (uint8_t)BootOptionParameter::OPAL_NETWORK_SETTINGS) {
1097
1098 int ret = setHostNetworkData(reqptr);
1099 if (ret < 0) {
1100 fprintf(stderr, "setHostNetworkData failed for set_sys_boot_options.\n");
1101 rc = IPMI_CC_UNSPECIFIED_ERROR;
1102 }
1103 }
1104 else {
shgoupfd84fbbf2015-12-17 10:05:51 +08001105 fprintf(stderr, "Unsupported parameter 0x%x\n", reqptr->parameter);
1106 rc = IPMI_CC_PARM_NOT_SUPPORTED;
Adriana Kobylak40814c62015-10-27 15:58:44 -05001107 }
1108
1109 return rc;
1110}
1111
1112void register_netfn_chassis_functions()
1113{
Tom05732372016-09-06 17:21:23 +05301114 // <Wildcard Command>
Adriana Kobylak40814c62015-10-27 15:58:44 -05001115 printf("Registering NetFn:[0x%X], Cmd:[0x%X]\n",NETFUN_CHASSIS, IPMI_CMD_WILDCARD);
Tom05732372016-09-06 17:21:23 +05301116 ipmi_register_callback(NETFUN_CHASSIS, IPMI_CMD_WILDCARD, NULL, ipmi_chassis_wildcard,
1117 PRIVILEGE_USER);
Adriana Kobylak40814c62015-10-27 15:58:44 -05001118
Tom05732372016-09-06 17:21:23 +05301119 // Get Chassis Capabilities
Nan Li8d15fb42016-08-16 22:29:40 +08001120 printf("Registering NetFn:[0x%X], Cmd:[0x%X]\n",NETFUN_CHASSIS, IPMI_CMD_GET_CHASSIS_CAP);
Tom05732372016-09-06 17:21:23 +05301121 ipmi_register_callback(NETFUN_CHASSIS, IPMI_CMD_GET_CHASSIS_CAP, NULL, ipmi_get_chassis_cap,
1122 PRIVILEGE_USER);
Nan Li8d15fb42016-08-16 22:29:40 +08001123
Tom05732372016-09-06 17:21:23 +05301124 // <Get System Boot Options>
Adriana Kobylak40814c62015-10-27 15:58:44 -05001125 printf("Registering NetFn:[0x%X], Cmd:[0x%X]\n",NETFUN_CHASSIS, IPMI_CMD_GET_SYS_BOOT_OPTIONS);
Tom05732372016-09-06 17:21:23 +05301126 ipmi_register_callback(NETFUN_CHASSIS, IPMI_CMD_GET_SYS_BOOT_OPTIONS, NULL,
1127 ipmi_chassis_get_sys_boot_options, PRIVILEGE_OPERATOR);
Adriana Kobylak40814c62015-10-27 15:58:44 -05001128
Tom05732372016-09-06 17:21:23 +05301129 // <Get Chassis Status>
Nan Lifdd8ec52016-08-28 03:57:40 +08001130 printf("Registering NetFn:[0x%X], Cmd:[0x%X]\n",NETFUN_CHASSIS, IPMI_CMD_CHASSIS_STATUS);
Tom05732372016-09-06 17:21:23 +05301131 ipmi_register_callback(NETFUN_CHASSIS, IPMI_CMD_CHASSIS_STATUS, NULL, ipmi_get_chassis_status,
1132 PRIVILEGE_USER);
Nan Lifdd8ec52016-08-28 03:57:40 +08001133
Tom05732372016-09-06 17:21:23 +05301134 // <Chassis Control>
vishwa36993272015-11-20 12:43:49 -06001135 printf("Registering NetFn:[0x%X], Cmd:[0x%X]\n",NETFUN_CHASSIS, IPMI_CMD_CHASSIS_CONTROL);
Tom05732372016-09-06 17:21:23 +05301136 ipmi_register_callback(NETFUN_CHASSIS, IPMI_CMD_CHASSIS_CONTROL, NULL, ipmi_chassis_control,
1137 PRIVILEGE_OPERATOR);
shgoupfd84fbbf2015-12-17 10:05:51 +08001138
Tom05732372016-09-06 17:21:23 +05301139 // <Set System Boot Options>
shgoupfd84fbbf2015-12-17 10:05:51 +08001140 printf("Registering NetFn:[0x%X], Cmd:[0x%X]\n", NETFUN_CHASSIS, IPMI_CMD_SET_SYS_BOOT_OPTIONS);
Tom05732372016-09-06 17:21:23 +05301141 ipmi_register_callback(NETFUN_CHASSIS, IPMI_CMD_SET_SYS_BOOT_OPTIONS, NULL,
1142 ipmi_chassis_set_sys_boot_options, PRIVILEGE_OPERATOR);
vishwa36993272015-11-20 12:43:49 -06001143}