Adriana Kobylak | 40814c6 | 2015-10-27 15:58:44 -0500 | [diff] [blame] | 1 | #include "chassishandler.h" |
| 2 | #include "ipmid-api.h" |
| 3 | #include <stdio.h> |
| 4 | #include <string.h> |
| 5 | #include <stdint.h> |
| 6 | |
vishwa | 3699327 | 2015-11-20 12:43:49 -0600 | [diff] [blame] | 7 | // OpenBMC Chassis Manager dbus framework |
| 8 | const char *chassis_bus_name = "org.openbmc.control.Chassis"; |
| 9 | const char *chassis_object_name = "/org/openbmc/control/chassis0"; |
| 10 | const char *chassis_intf_name = "org.openbmc.control.Chassis"; |
| 11 | |
Adriana Kobylak | 40814c6 | 2015-10-27 15:58:44 -0500 | [diff] [blame] | 12 | void register_netfn_chassis_functions() __attribute__((constructor)); |
| 13 | |
| 14 | struct get_sys_boot_options_t { |
| 15 | uint8_t parameter; |
| 16 | uint8_t set; |
| 17 | uint8_t block; |
| 18 | } __attribute__ ((packed)); |
| 19 | |
| 20 | ipmi_ret_t ipmi_chassis_wildcard(ipmi_netfn_t netfn, ipmi_cmd_t cmd, |
| 21 | ipmi_request_t request, ipmi_response_t response, |
| 22 | ipmi_data_len_t data_len, ipmi_context_t context) |
| 23 | { |
| 24 | printf("Handling CHASSIS WILDCARD Netfn:[0x%X], Cmd:[0x%X]\n",netfn, cmd); |
| 25 | // Status code. |
| 26 | ipmi_ret_t rc = IPMI_CC_OK; |
| 27 | *data_len = 0; |
| 28 | return rc; |
| 29 | } |
| 30 | |
vishwa | 3699327 | 2015-11-20 12:43:49 -0600 | [diff] [blame] | 31 | //------------------------------------------------------------ |
| 32 | // Calls into Chassis Control Dbus object to do the power off |
| 33 | //------------------------------------------------------------ |
| 34 | int ipmi_chassis_power_off() |
| 35 | { |
| 36 | // sd_bus error |
| 37 | int rc = 0; |
| 38 | |
| 39 | // SD Bus error report mechanism. |
| 40 | sd_bus_error bus_error = SD_BUS_ERROR_NULL; |
| 41 | |
| 42 | // Response from the call. Although there is no response for this call, |
| 43 | // obligated to mention this to make compiler happy. |
| 44 | sd_bus_message *response = NULL; |
| 45 | |
| 46 | // Gets a hook onto either a SYSTEM or SESSION bus |
| 47 | sd_bus *bus_type = ipmid_get_sd_bus_connection(); |
| 48 | |
| 49 | rc = sd_bus_call_method(bus_type, // On the System Bus |
| 50 | chassis_bus_name, // Service to contact |
| 51 | chassis_object_name, // Object path |
| 52 | chassis_intf_name, // Interface name |
| 53 | "powerOff", // Method to be called |
| 54 | &bus_error, // object to return error |
| 55 | &response, // Response buffer if any |
| 56 | NULL); // No input arguments |
| 57 | if(rc < 0) |
| 58 | { |
| 59 | fprintf(stderr,"ERROR initiating Power Off:[%s]\n",bus_error.message); |
| 60 | } |
| 61 | else |
| 62 | { |
| 63 | printf("Chassis Power Off initiated successfully\n"); |
| 64 | } |
| 65 | |
| 66 | sd_bus_error_free(&bus_error); |
| 67 | sd_bus_message_unref(response); |
| 68 | |
| 69 | return rc; |
| 70 | } |
| 71 | |
| 72 | //---------------------------------------------------------------------- |
| 73 | // Chassis Control commands |
| 74 | //---------------------------------------------------------------------- |
| 75 | ipmi_ret_t ipmi_chassis_control(ipmi_netfn_t netfn, ipmi_cmd_t cmd, |
| 76 | ipmi_request_t request, ipmi_response_t response, |
| 77 | ipmi_data_len_t data_len, ipmi_context_t context) |
| 78 | { |
| 79 | // Error from power off. |
| 80 | int rc = 0; |
| 81 | |
| 82 | // No response for this command. |
| 83 | *data_len = 0; |
| 84 | |
| 85 | // Catch the actual operaton by peeking into request buffer |
| 86 | uint8_t chassis_ctrl_cmd = *(uint8_t *)request; |
| 87 | printf("Chassis Control Command: Operation:[0x%X]\n",chassis_ctrl_cmd); |
| 88 | |
| 89 | switch(chassis_ctrl_cmd) |
| 90 | { |
| 91 | case CMD_POWER_OFF: |
| 92 | case CMD_HARD_RESET: |
| 93 | { |
| 94 | rc = ipmi_chassis_power_off(); |
| 95 | break; |
| 96 | } |
| 97 | default: |
| 98 | { |
| 99 | fprintf(stderr, "Invalid Chassis Control command:[0x%X] received\n",chassis_ctrl_cmd); |
| 100 | rc = -1; |
| 101 | } |
| 102 | } |
| 103 | |
| 104 | return ( (rc < 0) ? IPMI_CC_INVALID : IPMI_CC_OK); |
| 105 | } |
| 106 | |
Adriana Kobylak | 40814c6 | 2015-10-27 15:58:44 -0500 | [diff] [blame] | 107 | ipmi_ret_t ipmi_chassis_get_sys_boot_options(ipmi_netfn_t netfn, ipmi_cmd_t cmd, |
| 108 | ipmi_request_t request, ipmi_response_t response, |
| 109 | ipmi_data_len_t data_len, ipmi_context_t context) |
| 110 | { |
| 111 | ipmi_ret_t rc = IPMI_CC_OK; |
| 112 | *data_len = 0; |
| 113 | |
| 114 | printf("IPMI GET_SYS_BOOT_OPTIONS\n"); |
| 115 | |
| 116 | get_sys_boot_options_t *reqptr = (get_sys_boot_options_t*) request; |
| 117 | |
| 118 | // TODO Return default values to OPAL until dbus interface is available |
| 119 | |
| 120 | if (reqptr->parameter == 5) // Parameter #5 |
| 121 | { |
| 122 | uint8_t buf[] = {0x1,0x5,80,0,0,0,0}; |
| 123 | *data_len = sizeof(buf); |
| 124 | memcpy(response, &buf, *data_len); |
| 125 | } |
| 126 | else |
| 127 | { |
| 128 | fprintf(stderr, "Unsupported parameter 0x%x\n", reqptr->parameter); |
| 129 | return IPMI_CC_PARM_NOT_SUPPORTED; |
| 130 | } |
| 131 | |
| 132 | return rc; |
| 133 | } |
| 134 | |
| 135 | void register_netfn_chassis_functions() |
| 136 | { |
| 137 | printf("Registering NetFn:[0x%X], Cmd:[0x%X]\n",NETFUN_CHASSIS, IPMI_CMD_WILDCARD); |
| 138 | ipmi_register_callback(NETFUN_CHASSIS, IPMI_CMD_WILDCARD, NULL, ipmi_chassis_wildcard); |
| 139 | |
| 140 | printf("Registering NetFn:[0x%X], Cmd:[0x%X]\n",NETFUN_CHASSIS, IPMI_CMD_GET_SYS_BOOT_OPTIONS); |
| 141 | ipmi_register_callback(NETFUN_CHASSIS, IPMI_CMD_GET_SYS_BOOT_OPTIONS, NULL, ipmi_chassis_get_sys_boot_options); |
Adriana Kobylak | 40814c6 | 2015-10-27 15:58:44 -0500 | [diff] [blame] | 142 | |
vishwa | 3699327 | 2015-11-20 12:43:49 -0600 | [diff] [blame] | 143 | printf("Registering NetFn:[0x%X], Cmd:[0x%X]\n",NETFUN_CHASSIS, IPMI_CMD_CHASSIS_CONTROL); |
| 144 | ipmi_register_callback(NETFUN_CHASSIS, IPMI_CMD_CHASSIS_CONTROL, NULL, ipmi_chassis_control); |
| 145 | } |