| Adriana Kobylak | 40814c6 | 2015-10-27 15:58:44 -0500 | [diff] [blame] | 1 | #include "chassishandler.h" | 
| Patrick Williams | 37af733 | 2016-09-02 21:21:42 -0500 | [diff] [blame] | 2 | #include "host-ipmid/ipmid-api.h" | 
| Adriana Kobylak | 40814c6 | 2015-10-27 15:58:44 -0500 | [diff] [blame] | 3 | #include <stdio.h> | 
| Ratan Gupta | fd28dd7 | 2016-08-01 04:58:01 -0500 | [diff] [blame] | 4 | #include <stdlib.h> | 
| Adriana Kobylak | 40814c6 | 2015-10-27 15:58:44 -0500 | [diff] [blame] | 5 | #include <stdint.h> | 
| Brad Bishop | 3551868 | 2016-07-22 08:35:41 -0400 | [diff] [blame] | 6 | #include <mapper.h> | 
| Ratan Gupta | fd28dd7 | 2016-08-01 04:58:01 -0500 | [diff] [blame] | 7 | #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 Subbanna | b12b0c0 | 2017-03-07 18:17:19 +0530 | [diff] [blame] | 14 | #include <phosphor-logging/log.hpp> | 
 | 15 | #include <xyz/openbmc_project/State/Host/server.hpp> | 
| Vishwanatha Subbanna | b891a57 | 2017-03-31 11:34:48 +0530 | [diff] [blame] | 16 | #include "config.h" | 
| ratagupt | a6f6bff | 2016-04-04 06:20:11 -0500 | [diff] [blame] | 17 |  | 
 | 18 | //Defines | 
| Ratan Gupta | fd28dd7 | 2016-08-01 04:58:01 -0500 | [diff] [blame] | 19 | #define SET_PARM_VERSION                     0x01 | 
 | 20 | #define SET_PARM_BOOT_FLAGS_PERMANENT        0x40 //boot flags data1 7th bit on | 
| ratagupt | a6f6bff | 2016-04-04 06:20:11 -0500 | [diff] [blame] | 21 | #define SET_PARM_BOOT_FLAGS_VALID_ONE_TIME   0x80 //boot flags data1 8th bit on | 
| Ratan Gupta | fd28dd7 | 2016-08-01 04:58:01 -0500 | [diff] [blame] | 22 | #define SET_PARM_BOOT_FLAGS_VALID_PERMANENT  0xC0 //boot flags data1 7 & 8 bit on | 
| ratagupt | a6f6bff | 2016-04-04 06:20:11 -0500 | [diff] [blame] | 23 |  | 
| Ratan Gupta | fd28dd7 | 2016-08-01 04:58:01 -0500 | [diff] [blame] | 24 | constexpr size_t SIZE_MAC  = 18; | 
 | 25 | constexpr size_t SIZE_BOOT_OPTION = (uint8_t)BootOptionResponseSize:: | 
| Andrew Geissler | fca6a4f | 2017-05-30 10:55:39 -0500 | [diff] [blame^] | 26 |         OPAL_NETWORK_SETTINGS;//Maximum size of the boot option parametrs | 
| Ratan Gupta | fd28dd7 | 2016-08-01 04:58:01 -0500 | [diff] [blame] | 27 | constexpr size_t SIZE_PREFIX = 7; | 
 | 28 | constexpr size_t MAX_PREFIX_VALUE = 32; | 
 | 29 | constexpr size_t SIZE_COOKIE = 4; | 
 | 30 | constexpr size_t SIZE_VERSION = 2; | 
 | 31 | constexpr auto   MAC_ADDRESS_FORMAT = "%hhx:%hhx:%hhx:%hhx:%hhx:%hhx"; | 
 | 32 | constexpr auto   IP_ADDRESS_FORMAT = "%d.%d.%d.%d"; | 
| Matthew Barth | 8b47005 | 2016-09-21 10:02:57 -0500 | [diff] [blame] | 33 | constexpr auto   PREFIX_FORMAT = "%hhd"; | 
| Ratan Gupta | fd28dd7 | 2016-08-01 04:58:01 -0500 | [diff] [blame] | 34 | constexpr auto   ADDR_TYPE_FORMAT = "%hhx"; | 
 | 35 | //PetiBoot-Specific | 
 | 36 | static constexpr uint8_t net_conf_initial_bytes[] = {0x80,0x21, 0x70 ,0x62 ,0x21, | 
| Andrew Geissler | fca6a4f | 2017-05-30 10:55:39 -0500 | [diff] [blame^] | 37 |         0x00 ,0x01 ,0x06 ,0x04}; | 
| Ratan Gupta | fd28dd7 | 2016-08-01 04:58:01 -0500 | [diff] [blame] | 38 |  | 
 | 39 | static constexpr size_t COOKIE_OFFSET = 1; | 
 | 40 | static constexpr size_t VERSION_OFFSET = 5; | 
 | 41 | static constexpr size_t MAC_OFFSET = 9; | 
 | 42 | static constexpr size_t ADDRTYPE_OFFSET = 16; | 
 | 43 | static constexpr size_t IPADDR_OFFSET = 17; | 
 | 44 | static constexpr size_t PREFIX_OFFSET = 21; | 
 | 45 | static constexpr size_t GATEWAY_OFFSET = 22; | 
| ratagupt | a6f6bff | 2016-04-04 06:20:11 -0500 | [diff] [blame] | 46 |  | 
 | 47 |  | 
| vishwa | 3699327 | 2015-11-20 12:43:49 -0600 | [diff] [blame] | 48 |  | 
| shgoupf | d84fbbf | 2015-12-17 10:05:51 +0800 | [diff] [blame] | 49 |  | 
| Adriana Kobylak | 40814c6 | 2015-10-27 15:58:44 -0500 | [diff] [blame] | 50 | void register_netfn_chassis_functions() __attribute__((constructor)); | 
 | 51 |  | 
| shgoupf | d84fbbf | 2015-12-17 10:05:51 +0800 | [diff] [blame] | 52 | // Host settings in dbus | 
 | 53 | // Service name should be referenced by connection name got via object mapper | 
 | 54 | const char *settings_object_name  =  "/org/openbmc/settings/host0"; | 
 | 55 | const char *settings_intf_name    =  "org.freedesktop.DBus.Properties"; | 
 | 56 | const char *host_intf_name        =  "org.openbmc.settings.Host"; | 
 | 57 |  | 
| Nan Li | 8d15fb4 | 2016-08-16 22:29:40 +0800 | [diff] [blame] | 58 | typedef 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 Li | fdd8ec5 | 2016-08-28 03:57:40 +0800 | [diff] [blame] | 68 | typedef struct | 
 | 69 | { | 
| Andrew Geissler | fca6a4f | 2017-05-30 10:55:39 -0500 | [diff] [blame^] | 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; | 
| Nan Li | fdd8ec5 | 2016-08-28 03:57:40 +0800 | [diff] [blame] | 74 | }__attribute__((packed)) ipmi_get_chassis_status_t; | 
 | 75 |  | 
| Vishwanatha Subbanna | b12b0c0 | 2017-03-07 18:17:19 +0530 | [diff] [blame] | 76 | // Phosphor Host State manager | 
 | 77 | namespace State = sdbusplus::xyz::openbmc_project::State::server; | 
 | 78 |  | 
| ratagupt | a6f6bff | 2016-04-04 06:20:11 -0500 | [diff] [blame] | 79 | int dbus_get_property(const char *name, char **buf) | 
| shgoupf | d84fbbf | 2015-12-17 10:05:51 +0800 | [diff] [blame] | 80 | { | 
 | 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 Bishop | 3551868 | 2016-07-22 08:35:41 -0400 | [diff] [blame] | 88 |     // Get the system bus where most system services are provided. | 
 | 89 |     bus = ipmid_get_sd_bus_connection(); | 
| shgoupf | d84fbbf | 2015-12-17 10:05:51 +0800 | [diff] [blame] | 90 |  | 
| Brad Bishop | 3551868 | 2016-07-22 08:35:41 -0400 | [diff] [blame] | 91 |     r = mapper_get_service(bus, settings_object_name, &connection); | 
| shgoupf | d84fbbf | 2015-12-17 10:05:51 +0800 | [diff] [blame] | 92 |     if (r < 0) { | 
| Brad Bishop | 819ddd4 | 2016-10-05 21:19:19 -0400 | [diff] [blame] | 93 |         fprintf(stderr, "Failed to get %s connection: %s\n", | 
 | 94 |                 settings_object_name, strerror(-r)); | 
| shgoupf | d84fbbf | 2015-12-17 10:05:51 +0800 | [diff] [blame] | 95 |         goto finish; | 
 | 96 |     } | 
 | 97 |  | 
| shgoupf | d84fbbf | 2015-12-17 10:05:51 +0800 | [diff] [blame] | 98 |     /* | 
 | 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 */ | 
| ratagupt | a6f6bff | 2016-04-04 06:20:11 -0500 | [diff] [blame] | 113 |                            name);                                      /* second argument */ | 
| shgoupf | d84fbbf | 2015-12-17 10:05:51 +0800 | [diff] [blame] | 114 |  | 
 | 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 Barth | 5618105 | 2017-01-23 09:36:29 -0600 | [diff] [blame] | 130 |     *buf = strdup(temp_buf); | 
| Andrew Geissler | fca6a4f | 2017-05-30 10:55:39 -0500 | [diff] [blame^] | 131 |     /*    *buf = (char*) malloc(strlen(temp_buf)); | 
| shgoupf | d84fbbf | 2015-12-17 10:05:51 +0800 | [diff] [blame] | 132 |     if (*buf) { | 
 | 133 |         strcpy(*buf, temp_buf); | 
 | 134 |     } | 
| Andrew Geissler | fca6a4f | 2017-05-30 10:55:39 -0500 | [diff] [blame^] | 135 |      */ | 
| shgoupf | d84fbbf | 2015-12-17 10:05:51 +0800 | [diff] [blame] | 136 |     printf("IPMID boot option property get: {%s}.\n", (char *) temp_buf); | 
 | 137 |  | 
 | 138 | finish: | 
 | 139 |     sd_bus_error_free(&error); | 
 | 140 |     sd_bus_message_unref(m); | 
 | 141 |     free(connection); | 
 | 142 |  | 
 | 143 |     return r; | 
 | 144 | } | 
 | 145 |  | 
| ratagupt | a6f6bff | 2016-04-04 06:20:11 -0500 | [diff] [blame] | 146 | int dbus_set_property(const char * name, const char *value) | 
| shgoupf | d84fbbf | 2015-12-17 10:05:51 +0800 | [diff] [blame] | 147 | { | 
 | 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 Bishop | 3551868 | 2016-07-22 08:35:41 -0400 | [diff] [blame] | 154 |     // Get the system bus where most system services are provided. | 
 | 155 |     bus = ipmid_get_sd_bus_connection(); | 
| shgoupf | d84fbbf | 2015-12-17 10:05:51 +0800 | [diff] [blame] | 156 |  | 
| Brad Bishop | 3551868 | 2016-07-22 08:35:41 -0400 | [diff] [blame] | 157 |     r = mapper_get_service(bus, settings_object_name, &connection); | 
| shgoupf | d84fbbf | 2015-12-17 10:05:51 +0800 | [diff] [blame] | 158 |     if (r < 0) { | 
| Brad Bishop | 819ddd4 | 2016-10-05 21:19:19 -0400 | [diff] [blame] | 159 |         fprintf(stderr, "Failed to get %s connection: %s\n", | 
 | 160 |                 settings_object_name, strerror(-r)); | 
| shgoupf | d84fbbf | 2015-12-17 10:05:51 +0800 | [diff] [blame] | 161 |         goto finish; | 
 | 162 |     } | 
 | 163 |  | 
| shgoupf | d84fbbf | 2015-12-17 10:05:51 +0800 | [diff] [blame] | 164 |     /* | 
 | 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 */ | 
| ratagupt | a6f6bff | 2016-04-04 06:20:11 -0500 | [diff] [blame] | 179 |                            name,                                       /* second argument */ | 
| shgoupf | d84fbbf | 2015-12-17 10:05:51 +0800 | [diff] [blame] | 180 |                            "s",                                        /* third argument */ | 
| ratagupt | a6f6bff | 2016-04-04 06:20:11 -0500 | [diff] [blame] | 181 |                            value);                                     /* fourth argument */ | 
| shgoupf | d84fbbf | 2015-12-17 10:05:51 +0800 | [diff] [blame] | 182 |  | 
 | 183 |     if (r < 0) { | 
 | 184 |         fprintf(stderr, "Failed to issue method call: %s\n", error.message); | 
 | 185 |         goto finish; | 
 | 186 |     } | 
 | 187 |  | 
| ratagupt | a6f6bff | 2016-04-04 06:20:11 -0500 | [diff] [blame] | 188 |     printf("IPMID boot option property set: {%s}.\n", value); | 
| shgoupf | d84fbbf | 2015-12-17 10:05:51 +0800 | [diff] [blame] | 189 |  | 
| Andrew Geissler | fca6a4f | 2017-05-30 10:55:39 -0500 | [diff] [blame^] | 190 |     finish: | 
| shgoupf | d84fbbf | 2015-12-17 10:05:51 +0800 | [diff] [blame] | 191 |     sd_bus_error_free(&error); | 
 | 192 |     sd_bus_message_unref(m); | 
 | 193 |     free(connection); | 
 | 194 |  | 
 | 195 |     return r; | 
 | 196 | } | 
 | 197 |  | 
| Adriana Kobylak | 40814c6 | 2015-10-27 15:58:44 -0500 | [diff] [blame] | 198 | struct get_sys_boot_options_t { | 
 | 199 |     uint8_t parameter; | 
 | 200 |     uint8_t set; | 
 | 201 |     uint8_t block; | 
 | 202 | }  __attribute__ ((packed)); | 
 | 203 |  | 
| shgoupf | d84fbbf | 2015-12-17 10:05:51 +0800 | [diff] [blame] | 204 | struct get_sys_boot_options_response_t { | 
 | 205 |     uint8_t version; | 
 | 206 |     uint8_t parm; | 
| Ratan Gupta | fd28dd7 | 2016-08-01 04:58:01 -0500 | [diff] [blame] | 207 |     uint8_t data[SIZE_BOOT_OPTION]; | 
| shgoupf | d84fbbf | 2015-12-17 10:05:51 +0800 | [diff] [blame] | 208 | }  __attribute__ ((packed)); | 
 | 209 |  | 
 | 210 | struct set_sys_boot_options_t { | 
 | 211 |     uint8_t parameter; | 
| Ratan Gupta | fd28dd7 | 2016-08-01 04:58:01 -0500 | [diff] [blame] | 212 |     uint8_t data[SIZE_BOOT_OPTION]; | 
| shgoupf | d84fbbf | 2015-12-17 10:05:51 +0800 | [diff] [blame] | 213 | }  __attribute__ ((packed)); | 
 | 214 |  | 
| Ratan Gupta | fd28dd7 | 2016-08-01 04:58:01 -0500 | [diff] [blame] | 215 | struct 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 |  | 
 | 225 | void 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 Geissler | fca6a4f | 2017-05-30 10:55:39 -0500 | [diff] [blame^] | 255 |                                 commaDelimtrPos-(equalDelimtrPos+1)); | 
| Ratan Gupta | fd28dd7 | 2016-08-01 04:58:01 -0500 | [diff] [blame] | 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, | 
| Andrew Geissler | fca6a4f | 2017-05-30 10:55:39 -0500 | [diff] [blame^] | 265 |                                    equalDelimtrPos-commaDelimtrPrevPos, | 
 | 266 |                                    "ipaddress" )) { | 
 | 267 |             host_config.ipaddress = std::move(value); | 
| Ratan Gupta | fd28dd7 | 2016-08-01 04:58:01 -0500 | [diff] [blame] | 268 |         } | 
 | 269 |         else if ( 0 == conf_str.compare(commaDelimtrPrevPos, | 
| Andrew Geissler | fca6a4f | 2017-05-30 10:55:39 -0500 | [diff] [blame^] | 270 |                                         equalDelimtrPos-commaDelimtrPrevPos, | 
 | 271 |                                         "prefix" )) { | 
 | 272 |             host_config.prefix = std::move(value); | 
| Ratan Gupta | fd28dd7 | 2016-08-01 04:58:01 -0500 | [diff] [blame] | 273 |         } | 
 | 274 |         else if ( 0 == conf_str.compare(commaDelimtrPrevPos, | 
| Andrew Geissler | fca6a4f | 2017-05-30 10:55:39 -0500 | [diff] [blame^] | 275 |                                         equalDelimtrPos-commaDelimtrPrevPos, | 
 | 276 |                                         "gateway" )) { | 
| Ratan Gupta | fd28dd7 | 2016-08-01 04:58:01 -0500 | [diff] [blame] | 277 |             host_config.gateway = std::move(value); | 
 | 278 |         } | 
 | 279 |         else if ( 0 == conf_str.compare(commaDelimtrPrevPos, | 
| Andrew Geissler | fca6a4f | 2017-05-30 10:55:39 -0500 | [diff] [blame^] | 280 |                                         equalDelimtrPos-commaDelimtrPrevPos, | 
 | 281 |                                         "mac" )) { | 
| Ratan Gupta | fd28dd7 | 2016-08-01 04:58:01 -0500 | [diff] [blame] | 282 |             host_config.macaddress = std::move(value); | 
 | 283 |         } | 
 | 284 |         else if ( 0 == conf_str.compare(commaDelimtrPrevPos, | 
| Andrew Geissler | fca6a4f | 2017-05-30 10:55:39 -0500 | [diff] [blame^] | 285 |                                         equalDelimtrPos-commaDelimtrPrevPos, | 
 | 286 |                                         "addr_type" )) { | 
| Ratan Gupta | fd28dd7 | 2016-08-01 04:58:01 -0500 | [diff] [blame] | 287 |             host_config.addrType = std::move(value); | 
 | 288 |         } | 
 | 289 |  | 
 | 290 |         commaDelimtrPos++; | 
 | 291 |         commaDelimtrPrevPos= commaDelimtrPos; | 
 | 292 |     } | 
 | 293 | } | 
 | 294 |  | 
 | 295 | int  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 Geissler | fca6a4f | 2017-05-30 10:55:39 -0500 | [diff] [blame^] | 334 |                     (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 Gupta | fd28dd7 | 2016-08-01 04:58:01 -0500 | [diff] [blame] | 337 |  | 
 | 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 Geissler | fca6a4f | 2017-05-30 10:55:39 -0500 | [diff] [blame^] | 349 |                     (respptr->data+ADDRTYPE_OFFSET)); | 
| Ratan Gupta | fd28dd7 | 2016-08-01 04:58:01 -0500 | [diff] [blame] | 350 |  | 
 | 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 Geissler | fca6a4f | 2017-05-30 10:55:39 -0500 | [diff] [blame^] | 359 |                        (respptr->data+IPADDR_OFFSET)); | 
| Ratan Gupta | fd28dd7 | 2016-08-01 04:58:01 -0500 | [diff] [blame] | 360 |  | 
 | 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 Geissler | fca6a4f | 2017-05-30 10:55:39 -0500 | [diff] [blame^] | 368 |                     (respptr->data+PREFIX_OFFSET)); | 
| Ratan Gupta | fd28dd7 | 2016-08-01 04:58:01 -0500 | [diff] [blame] | 369 |  | 
 | 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 Geissler | fca6a4f | 2017-05-30 10:55:39 -0500 | [diff] [blame^] | 377 |                        (respptr->data+GATEWAY_OFFSET)); | 
| Ratan Gupta | fd28dd7 | 2016-08-01 04:58:01 -0500 | [diff] [blame] | 378 |  | 
 | 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 Geissler | fca6a4f | 2017-05-30 10:55:39 -0500 | [diff] [blame^] | 394 |                sizeof(net_conf_initial_bytes)); | 
| Ratan Gupta | fd28dd7 | 2016-08-01 04:58:01 -0500 | [diff] [blame] | 395 |  | 
 | 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 |  | 
 | 411 | int 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 Geissler | fca6a4f | 2017-05-30 10:55:39 -0500 | [diff] [blame^] | 433 |                          &zeroCookie, | 
 | 434 |                          SIZE_COOKIE) == 0 ) { | 
| Ratan Gupta | fd28dd7 | 2016-08-01 04:58:01 -0500 | [diff] [blame] | 435 |                 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 Geissler | fca6a4f | 2017-05-30 10:55:39 -0500 | [diff] [blame^] | 454 |                  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 Gupta | fd28dd7 | 2016-08-01 04:58:01 -0500 | [diff] [blame] | 460 |  | 
 | 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 Geissler | fca6a4f | 2017-05-30 10:55:39 -0500 | [diff] [blame^] | 473 |                  reqptr->data[IPADDR_OFFSET], reqptr->data[IPADDR_OFFSET+1], | 
 | 474 |                  reqptr->data[IPADDR_OFFSET+2], reqptr->data[IPADDR_OFFSET+3]); | 
| Ratan Gupta | fd28dd7 | 2016-08-01 04:58:01 -0500 | [diff] [blame] | 475 |  | 
 | 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 Geissler | fca6a4f | 2017-05-30 10:55:39 -0500 | [diff] [blame^] | 487 |                  reqptr->data[GATEWAY_OFFSET], | 
 | 488 |                  reqptr->data[GATEWAY_OFFSET+1], | 
 | 489 |                  reqptr->data[GATEWAY_OFFSET+2], | 
 | 490 |                  reqptr->data[GATEWAY_OFFSET+3]); | 
| Ratan Gupta | fd28dd7 | 2016-08-01 04:58:01 -0500 | [diff] [blame] | 491 |  | 
 | 492 |  | 
 | 493 |     }while(0); | 
 | 494 |  | 
 | 495 |     if( !rc ) | 
 | 496 |     { | 
 | 497 |         //Cookie == 0 or it is a valid cookie | 
| Andrew Geissler | fca6a4f | 2017-05-30 10:55:39 -0500 | [diff] [blame^] | 498 |         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 Gupta | fd28dd7 | 2016-08-01 04:58:01 -0500 | [diff] [blame] | 501 |  | 
 | 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 Geissler | fca6a4f | 2017-05-30 10:55:39 -0500 | [diff] [blame^] | 516 | ipmi_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 Kobylak | 40814c6 | 2015-10-27 15:58:44 -0500 | [diff] [blame] | 521 | { | 
 | 522 |     printf("Handling CHASSIS WILDCARD Netfn:[0x%X], Cmd:[0x%X]\n",netfn, cmd); | 
 | 523 |     // Status code. | 
| Nan Li | 70aa8d9 | 2016-08-29 00:11:10 +0800 | [diff] [blame] | 524 |     ipmi_ret_t rc = IPMI_CC_INVALID; | 
| Adriana Kobylak | 40814c6 | 2015-10-27 15:58:44 -0500 | [diff] [blame] | 525 |     *data_len = 0; | 
 | 526 |     return rc; | 
 | 527 | } | 
 | 528 |  | 
| Nan Li | 8d15fb4 | 2016-08-16 22:29:40 +0800 | [diff] [blame] | 529 | ipmi_ret_t ipmi_get_chassis_cap(ipmi_netfn_t netfn, ipmi_cmd_t cmd, | 
| Andrew Geissler | fca6a4f | 2017-05-30 10:55:39 -0500 | [diff] [blame^] | 530 |                                 ipmi_request_t request, ipmi_response_t response, | 
 | 531 |                                 ipmi_data_len_t data_len, ipmi_context_t context) | 
| Nan Li | 8d15fb4 | 2016-08-16 22:29:40 +0800 | [diff] [blame] | 532 | { | 
 | 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 Subbanna | b12b0c0 | 2017-03-07 18:17:19 +0530 | [diff] [blame] | 575 | //------------------------------------------ | 
 | 576 | // Calls into Host State Manager Dbus object | 
 | 577 | //------------------------------------------ | 
 | 578 | int initiate_state_transition(State::Host::Transition transition) | 
| vishwa | 3699327 | 2015-11-20 12:43:49 -0600 | [diff] [blame] | 579 | { | 
| Andrew Geissler | fca6a4f | 2017-05-30 10:55:39 -0500 | [diff] [blame^] | 580 |     using namespace phosphor::logging; | 
| Vishwanatha Subbanna | b12b0c0 | 2017-03-07 18:17:19 +0530 | [diff] [blame] | 581 |  | 
| Andrew Geissler | fca6a4f | 2017-05-30 10:55:39 -0500 | [diff] [blame^] | 582 |     // 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 Subbanna | b12b0c0 | 2017-03-07 18:17:19 +0530 | [diff] [blame] | 587 |  | 
| Andrew Geissler | fca6a4f | 2017-05-30 10:55:39 -0500 | [diff] [blame^] | 588 |     // sd_bus error | 
 | 589 |     int rc = 0; | 
 | 590 |     char  *busname = NULL; | 
| vishwa | 3699327 | 2015-11-20 12:43:49 -0600 | [diff] [blame] | 591 |  | 
| Andrew Geissler | fca6a4f | 2017-05-30 10:55:39 -0500 | [diff] [blame^] | 592 |     // SD Bus error report mechanism. | 
 | 593 |     sd_bus_error bus_error = SD_BUS_ERROR_NULL; | 
| vishwa | 3699327 | 2015-11-20 12:43:49 -0600 | [diff] [blame] | 594 |  | 
| Andrew Geissler | fca6a4f | 2017-05-30 10:55:39 -0500 | [diff] [blame^] | 595 |     // 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 Subbanna | b12b0c0 | 2017-03-07 18:17:19 +0530 | [diff] [blame] | 605 |  | 
| Andrew Geissler | fca6a4f | 2017-05-30 10:55:39 -0500 | [diff] [blame^] | 606 |     // Convert to string equivalent of the passed in transition enum. | 
 | 607 |     auto request = State::convertForMessage(transition); | 
| Vishwanatha Subbanna | b12b0c0 | 2017-03-07 18:17:19 +0530 | [diff] [blame] | 608 |  | 
| Andrew Geissler | fca6a4f | 2017-05-30 10:55:39 -0500 | [diff] [blame^] | 609 |     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 |     } | 
| vishwa | 3699327 | 2015-11-20 12:43:49 -0600 | [diff] [blame] | 630 |  | 
 | 631 |     sd_bus_error_free(&bus_error); | 
| Sergey Solomin | eb9b814 | 2016-08-23 09:07:28 -0500 | [diff] [blame] | 632 |     free(busname); | 
| vishwa | 3699327 | 2015-11-20 12:43:49 -0600 | [diff] [blame] | 633 |  | 
| Sergey Solomin | eb9b814 | 2016-08-23 09:07:28 -0500 | [diff] [blame] | 634 |     return rc; | 
| vishwa | 3699327 | 2015-11-20 12:43:49 -0600 | [diff] [blame] | 635 | } | 
 | 636 |  | 
| Andrew Geissler | fca6a4f | 2017-05-30 10:55:39 -0500 | [diff] [blame^] | 637 | struct hostPowerPolicyTypeMap_t | 
 | 638 | { | 
| Nan Li | fdd8ec5 | 2016-08-28 03:57:40 +0800 | [diff] [blame] | 639 |     uint8_t policyNum; | 
 | 640 |     char    policyName[19]; | 
 | 641 | }; | 
 | 642 |  | 
 | 643 | hostPowerPolicyTypeMap_t g_hostPowerPolicyTypeMap_t[] = { | 
 | 644 |  | 
| Andrew Geissler | fca6a4f | 2017-05-30 10:55:39 -0500 | [diff] [blame^] | 645 |         {0x00, "LEAVE_OFF"}, | 
 | 646 |         {0x01, "RESTORE_LAST_STATE"}, | 
 | 647 |         {0x02, "ALWAYS_POWER_ON"}, | 
 | 648 |         {0x03, "UNKNOWN"} | 
| Nan Li | fdd8ec5 | 2016-08-28 03:57:40 +0800 | [diff] [blame] | 649 | }; | 
 | 650 |  | 
| Andrew Geissler | fca6a4f | 2017-05-30 10:55:39 -0500 | [diff] [blame^] | 651 | uint8_t get_host_power_policy(char *p) | 
 | 652 | { | 
| Nan Li | fdd8ec5 | 2016-08-28 03:57:40 +0800 | [diff] [blame] | 653 |  | 
 | 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 | //---------------------------------------------------------------------- | 
 | 668 | ipmi_ret_t ipmi_get_chassis_status(ipmi_netfn_t netfn, ipmi_cmd_t cmd, | 
| Andrew Geissler | fca6a4f | 2017-05-30 10:55:39 -0500 | [diff] [blame^] | 669 |                                    ipmi_request_t request, | 
 | 670 |                                    ipmi_response_t response, | 
 | 671 |                                    ipmi_data_len_t data_len, | 
 | 672 |                                    ipmi_context_t context) | 
| Nan Li | fdd8ec5 | 2016-08-28 03:57:40 +0800 | [diff] [blame] | 673 | { | 
 | 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 Geissler | fca6a4f | 2017-05-30 10:55:39 -0500 | [diff] [blame^] | 730 |         free(p); | 
 | 731 |         p = NULL; | 
| Nan Li | fdd8ec5 | 2016-08-28 03:57:40 +0800 | [diff] [blame] | 732 |     } | 
 | 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 |  | 
 | 807 | finish: | 
 | 808 |     free(busname); | 
 | 809 |     reply = sd_bus_message_unref(reply); | 
 | 810 |  | 
 | 811 |     return rc; | 
 | 812 | } | 
| Chris Austen | 7888c4d | 2015-12-03 15:26:20 -0600 | [diff] [blame] | 813 |  | 
| Vishwanatha Subbanna | 83b5c1c | 2017-01-25 18:41:51 +0530 | [diff] [blame] | 814 | //------------------------------------------------------------- | 
 | 815 | // Send a command to SoftPowerOff application to stop any timer | 
 | 816 | //------------------------------------------------------------- | 
 | 817 | int stop_soft_off_timer() | 
 | 818 | { | 
| Vishwanatha Subbanna | 83b5c1c | 2017-01-25 18:41:51 +0530 | [diff] [blame] | 819 |     constexpr auto iface            = "org.freedesktop.DBus.Properties"; | 
 | 820 |     constexpr auto soft_off_iface   = "xyz.openbmc_project.Ipmi.Internal." | 
| Andrew Geissler | fca6a4f | 2017-05-30 10:55:39 -0500 | [diff] [blame^] | 821 |             "SoftPowerOff"; | 
| Vishwanatha Subbanna | 83b5c1c | 2017-01-25 18:41:51 +0530 | [diff] [blame] | 822 |  | 
 | 823 |     constexpr auto property         = "ResponseReceived"; | 
 | 824 |     constexpr auto value            = "xyz.openbmc_project.Ipmi.Internal." | 
| Andrew Geissler | fca6a4f | 2017-05-30 10:55:39 -0500 | [diff] [blame^] | 825 |             "SoftPowerOff.HostResponse.HostShutdown"; | 
| Vishwanatha Subbanna | 83b5c1c | 2017-01-25 18:41:51 +0530 | [diff] [blame] | 826 |     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 Subbanna | b891a57 | 2017-03-31 11:34:48 +0530 | [diff] [blame] | 832 |     auto r = mapper_get_service(bus, SOFTOFF_OBJPATH, &busname); | 
| Andrew Geissler | fca6a4f | 2017-05-30 10:55:39 -0500 | [diff] [blame^] | 833 |     if (r < 0) | 
 | 834 |     { | 
| Vishwanatha Subbanna | 83b5c1c | 2017-01-25 18:41:51 +0530 | [diff] [blame] | 835 |         fprintf(stderr, "Failed to get %s bus name: %s\n", | 
| Vishwanatha Subbanna | b891a57 | 2017-03-31 11:34:48 +0530 | [diff] [blame] | 836 |                 SOFTOFF_OBJPATH, strerror(-r)); | 
| Vishwanatha Subbanna | 83b5c1c | 2017-01-25 18:41:51 +0530 | [diff] [blame] | 837 |         return r; | 
 | 838 |     } | 
 | 839 |  | 
 | 840 |     // No error object or reply expected. | 
| Vishwanatha Subbanna | b891a57 | 2017-03-31 11:34:48 +0530 | [diff] [blame] | 841 |     int rc = sd_bus_call_method(bus, busname, SOFTOFF_OBJPATH, iface, | 
| Andrew Geissler | fca6a4f | 2017-05-30 10:55:39 -0500 | [diff] [blame^] | 842 |                                 "Set", nullptr, nullptr, "ssv", | 
 | 843 |                                 soft_off_iface, property, "s", value); | 
| Vishwanatha Subbanna | 83b5c1c | 2017-01-25 18:41:51 +0530 | [diff] [blame] | 844 |     if (rc < 0) | 
 | 845 |     { | 
 | 846 |         fprintf(stderr, "Failed to set property in SoftPowerOff object: %s\n", | 
 | 847 |                 strerror(-rc)); | 
 | 848 |     } | 
| Andrew Geissler | fca6a4f | 2017-05-30 10:55:39 -0500 | [diff] [blame^] | 849 |  | 
| Vishwanatha Subbanna | 83b5c1c | 2017-01-25 18:41:51 +0530 | [diff] [blame] | 850 |     free(busname); | 
 | 851 |     return rc; | 
 | 852 | } | 
 | 853 |  | 
| vishwa | 3699327 | 2015-11-20 12:43:49 -0600 | [diff] [blame] | 854 | //---------------------------------------------------------------------- | 
 | 855 | // Chassis Control commands | 
 | 856 | //---------------------------------------------------------------------- | 
| Andrew Geissler | fca6a4f | 2017-05-30 10:55:39 -0500 | [diff] [blame^] | 857 | ipmi_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) | 
| vishwa | 3699327 | 2015-11-20 12:43:49 -0600 | [diff] [blame] | 862 | { | 
| Andrew Geissler | fca6a4f | 2017-05-30 10:55:39 -0500 | [diff] [blame^] | 863 |     // Error from power off. | 
 | 864 |     int rc = 0; | 
| vishwa | 3699327 | 2015-11-20 12:43:49 -0600 | [diff] [blame] | 865 |  | 
| Andrew Geissler | fca6a4f | 2017-05-30 10:55:39 -0500 | [diff] [blame^] | 866 |     // No response for this command. | 
| vishwa | 3699327 | 2015-11-20 12:43:49 -0600 | [diff] [blame] | 867 |     *data_len = 0; | 
 | 868 |  | 
| Andrew Geissler | fca6a4f | 2017-05-30 10:55:39 -0500 | [diff] [blame^] | 869 |     // 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); | 
| vishwa | 3699327 | 2015-11-20 12:43:49 -0600 | [diff] [blame] | 872 |  | 
| Andrew Geissler | fca6a4f | 2017-05-30 10:55:39 -0500 | [diff] [blame^] | 873 |     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 Subbanna | 83b5c1c | 2017-01-25 18:41:51 +0530 | [diff] [blame] | 890 |  | 
| Andrew Geissler | fca6a4f | 2017-05-30 10:55:39 -0500 | [diff] [blame^] | 891 |         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 |     } | 
| vishwa | 3699327 | 2015-11-20 12:43:49 -0600 | [diff] [blame] | 904 |  | 
| Andrew Geissler | fca6a4f | 2017-05-30 10:55:39 -0500 | [diff] [blame^] | 905 |     return ( (rc < 0) ? IPMI_CC_INVALID : IPMI_CC_OK); | 
| vishwa | 3699327 | 2015-11-20 12:43:49 -0600 | [diff] [blame] | 906 | } | 
 | 907 |  | 
| shgoupf | d84fbbf | 2015-12-17 10:05:51 +0800 | [diff] [blame] | 908 | struct 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. | 
 | 915 | bootOptionTypeMap_t g_bootOptionTypeMap_t[] = { | 
 | 916 |  | 
| Andrew Geissler | fca6a4f | 2017-05-30 10:55:39 -0500 | [diff] [blame^] | 917 |         {0x01, "Network"}, | 
 | 918 |         {0x02, "Disk"}, | 
 | 919 |         {0x03, "Safe"}, | 
 | 920 |         {0x05, "CDROM"}, | 
 | 921 |         {0x06, "Setup"}, | 
 | 922 |         {0x00, "Default"}, | 
 | 923 |         {0xFF, INVALID_STRING} | 
| shgoupf | d84fbbf | 2015-12-17 10:05:51 +0800 | [diff] [blame] | 924 | }; | 
 | 925 |  | 
 | 926 | uint8_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 |  | 
 | 942 | char* 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 Geissler | fca6a4f | 2017-05-30 10:55:39 -0500 | [diff] [blame^] | 961 | ipmi_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 Kobylak | 40814c6 | 2015-10-27 15:58:44 -0500 | [diff] [blame] | 966 | { | 
| shgoupf | d84fbbf | 2015-12-17 10:05:51 +0800 | [diff] [blame] | 967 |     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 Kobylak | 40814c6 | 2015-10-27 15:58:44 -0500 | [diff] [blame] | 972 |  | 
 | 973 |     printf("IPMI GET_SYS_BOOT_OPTIONS\n"); | 
 | 974 |  | 
| shgoupf | d84fbbf | 2015-12-17 10:05:51 +0800 | [diff] [blame] | 975 |     memset(resp,0,sizeof(*resp)); | 
 | 976 |     resp->version   = SET_PARM_VERSION; | 
 | 977 |     resp->parm      = 5; | 
| ratagupt | a6f6bff | 2016-04-04 06:20:11 -0500 | [diff] [blame] | 978 |     resp->data[0]   = SET_PARM_BOOT_FLAGS_VALID_ONE_TIME; | 
| Adriana Kobylak | 40814c6 | 2015-10-27 15:58:44 -0500 | [diff] [blame] | 979 |  | 
| Adriana Kobylak | 40814c6 | 2015-10-27 15:58:44 -0500 | [diff] [blame] | 980 |  | 
| shgoupf | d84fbbf | 2015-12-17 10:05:51 +0800 | [diff] [blame] | 981 |     /* | 
 | 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 Gupta | fd28dd7 | 2016-08-01 04:58:01 -0500 | [diff] [blame] | 985 |     if ( reqptr->parameter == static_cast<uint8_t> | 
| Andrew Geissler | fca6a4f | 2017-05-30 10:55:39 -0500 | [diff] [blame^] | 986 |     ( BootOptionParameter::BOOT_FLAGS )) { | 
| shgoupf | d84fbbf | 2015-12-17 10:05:51 +0800 | [diff] [blame] | 987 |  | 
| Ratan Gupta | fd28dd7 | 2016-08-01 04:58:01 -0500 | [diff] [blame] | 988 |         *data_len = static_cast<uint8_t>(BootOptionResponseSize::BOOT_FLAGS); | 
| ratagupt | a6f6bff | 2016-04-04 06:20:11 -0500 | [diff] [blame] | 989 |         /* Get the boot device */ | 
 | 990 |         int r = dbus_get_property("boot_flags",&p); | 
| shgoupf | d84fbbf | 2015-12-17 10:05:51 +0800 | [diff] [blame] | 991 |  | 
 | 992 |         if (r < 0) { | 
| ratagupt | a6f6bff | 2016-04-04 06:20:11 -0500 | [diff] [blame] | 993 |             fprintf(stderr, "Dbus get property(boot_flags) failed for get_sys_boot_options.\n"); | 
| shgoupf | d84fbbf | 2015-12-17 10:05:51 +0800 | [diff] [blame] | 994 |             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; | 
| ratagupt | a6f6bff | 2016-04-04 06:20:11 -0500 | [diff] [blame] | 1001 |  | 
| shgoupf | d84fbbf | 2015-12-17 10:05:51 +0800 | [diff] [blame] | 1002 |         } | 
 | 1003 |  | 
| ratagupt | a6f6bff | 2016-04-04 06:20:11 -0500 | [diff] [blame] | 1004 |         if (p) | 
 | 1005 |         { | 
| Andrew Geissler | fca6a4f | 2017-05-30 10:55:39 -0500 | [diff] [blame^] | 1006 |             free(p); | 
 | 1007 |             p = NULL; | 
| ratagupt | a6f6bff | 2016-04-04 06:20:11 -0500 | [diff] [blame] | 1008 |         } | 
 | 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 Gupta | fd28dd7 | 2016-08-01 04:58:01 -0500 | [diff] [blame] | 1019 |             printf("BootPolicy is[%s]", p); | 
| Andrew Geissler | fca6a4f | 2017-05-30 10:55:39 -0500 | [diff] [blame^] | 1020 |             resp->data[0] = (strncmp(p,"ONETIME",strlen("ONETIME"))==0) ? | 
 | 1021 |                     SET_PARM_BOOT_FLAGS_VALID_ONE_TIME: | 
 | 1022 |                     SET_PARM_BOOT_FLAGS_VALID_PERMANENT; | 
| ratagupt | a6f6bff | 2016-04-04 06:20:11 -0500 | [diff] [blame] | 1023 |             rc = IPMI_CC_OK; | 
 | 1024 |  | 
 | 1025 |         } | 
 | 1026 |  | 
 | 1027 |  | 
| Ratan Gupta | fd28dd7 | 2016-08-01 04:58:01 -0500 | [diff] [blame] | 1028 |     } else if ( reqptr->parameter == static_cast<uint8_t> | 
| Andrew Geissler | fca6a4f | 2017-05-30 10:55:39 -0500 | [diff] [blame^] | 1029 |     ( BootOptionParameter::OPAL_NETWORK_SETTINGS )) { | 
| Ratan Gupta | fd28dd7 | 2016-08-01 04:58:01 -0500 | [diff] [blame] | 1030 |  | 
| Andrew Geissler | fca6a4f | 2017-05-30 10:55:39 -0500 | [diff] [blame^] | 1031 |         *data_len = static_cast<uint8_t>(BootOptionResponseSize::OPAL_NETWORK_SETTINGS); | 
| Ratan Gupta | fd28dd7 | 2016-08-01 04:58:01 -0500 | [diff] [blame] | 1032 |  | 
| Andrew Geissler | fca6a4f | 2017-05-30 10:55:39 -0500 | [diff] [blame^] | 1033 |         resp->parm = static_cast<uint8_t>(BootOptionParameter::OPAL_NETWORK_SETTINGS); | 
| Ratan Gupta | fd28dd7 | 2016-08-01 04:58:01 -0500 | [diff] [blame] | 1034 |  | 
| Andrew Geissler | fca6a4f | 2017-05-30 10:55:39 -0500 | [diff] [blame^] | 1035 |         int ret = getHostNetworkData(resp); | 
| Ratan Gupta | fd28dd7 | 2016-08-01 04:58:01 -0500 | [diff] [blame] | 1036 |  | 
| Andrew Geissler | fca6a4f | 2017-05-30 10:55:39 -0500 | [diff] [blame^] | 1037 |         if (ret < 0) { | 
| Ratan Gupta | fd28dd7 | 2016-08-01 04:58:01 -0500 | [diff] [blame] | 1038 |  | 
| Andrew Geissler | fca6a4f | 2017-05-30 10:55:39 -0500 | [diff] [blame^] | 1039 |             fprintf(stderr, "getHostNetworkData failed for get_sys_boot_options.\n"); | 
 | 1040 |             rc = IPMI_CC_UNSPECIFIED_ERROR; | 
| Ratan Gupta | fd28dd7 | 2016-08-01 04:58:01 -0500 | [diff] [blame] | 1041 |  | 
| Andrew Geissler | fca6a4f | 2017-05-30 10:55:39 -0500 | [diff] [blame^] | 1042 |         }else | 
 | 1043 |             rc = IPMI_CC_OK; | 
| Ratan Gupta | fd28dd7 | 2016-08-01 04:58:01 -0500 | [diff] [blame] | 1044 |     } | 
 | 1045 |  | 
 | 1046 |     else { | 
| Adriana Kobylak | 40814c6 | 2015-10-27 15:58:44 -0500 | [diff] [blame] | 1047 |         fprintf(stderr, "Unsupported parameter 0x%x\n", reqptr->parameter); | 
| shgoupf | d84fbbf | 2015-12-17 10:05:51 +0800 | [diff] [blame] | 1048 |     } | 
 | 1049 |  | 
 | 1050 |     if (p) | 
 | 1051 |         free(p); | 
 | 1052 |  | 
| Ratan Gupta | fd28dd7 | 2016-08-01 04:58:01 -0500 | [diff] [blame] | 1053 |     if (rc == IPMI_CC_OK) | 
 | 1054 |     { | 
 | 1055 |         *data_len += 2; | 
 | 1056 |     } | 
 | 1057 |  | 
| shgoupf | d84fbbf | 2015-12-17 10:05:51 +0800 | [diff] [blame] | 1058 |     return rc; | 
 | 1059 | } | 
 | 1060 |  | 
 | 1061 |  | 
 | 1062 |  | 
 | 1063 | ipmi_ret_t ipmi_chassis_set_sys_boot_options(ipmi_netfn_t netfn, ipmi_cmd_t cmd, | 
| Andrew Geissler | fca6a4f | 2017-05-30 10:55:39 -0500 | [diff] [blame^] | 1064 |                                              ipmi_request_t request, | 
 | 1065 |                                              ipmi_response_t response, | 
 | 1066 |                                              ipmi_data_len_t data_len, | 
 | 1067 |                                              ipmi_context_t context) | 
| shgoupf | d84fbbf | 2015-12-17 10:05:51 +0800 | [diff] [blame] | 1068 | { | 
 | 1069 |     ipmi_ret_t rc = IPMI_CC_OK; | 
 | 1070 |     char *s; | 
| shgoupf | d84fbbf | 2015-12-17 10:05:51 +0800 | [diff] [blame] | 1071 |     set_sys_boot_options_t *reqptr = (set_sys_boot_options_t *) request; | 
 | 1072 |  | 
| Ratan Gupta | fd28dd7 | 2016-08-01 04:58:01 -0500 | [diff] [blame] | 1073 |     printf("IPMI SET_SYS_BOOT_OPTIONS reqptr->parameter =[%d]\n",reqptr->parameter); | 
 | 1074 |  | 
| shgoupf | d84fbbf | 2015-12-17 10:05:51 +0800 | [diff] [blame] | 1075 |     // 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 Gupta | fd28dd7 | 2016-08-01 04:58:01 -0500 | [diff] [blame] | 1082 |  | 
 | 1083 |     if (reqptr->parameter == (uint8_t)BootOptionParameter::BOOT_FLAGS) { | 
| shgoupf | d84fbbf | 2015-12-17 10:05:51 +0800 | [diff] [blame] | 1084 |  | 
 | 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 |  | 
| ratagupt | a6f6bff | 2016-04-04 06:20:11 -0500 | [diff] [blame] | 1094 |             int r = dbus_set_property("boot_flags",s); | 
| shgoupf | d84fbbf | 2015-12-17 10:05:51 +0800 | [diff] [blame] | 1095 |  | 
 | 1096 |             if (r < 0) { | 
| ratagupt | a6f6bff | 2016-04-04 06:20:11 -0500 | [diff] [blame] | 1097 |                 fprintf(stderr, "Dbus set property(boot_flags) failed for set_sys_boot_options.\n"); | 
| shgoupf | d84fbbf | 2015-12-17 10:05:51 +0800 | [diff] [blame] | 1098 |                 rc = IPMI_CC_UNSPECIFIED_ERROR; | 
 | 1099 |             } | 
 | 1100 |         } | 
| Ratan Gupta | fd28dd7 | 2016-08-01 04:58:01 -0500 | [diff] [blame] | 1101 |  | 
| ratagupt | a6f6bff | 2016-04-04 06:20:11 -0500 | [diff] [blame] | 1102 |         /* setting the boot policy */ | 
| Andrew Geissler | fca6a4f | 2017-05-30 10:55:39 -0500 | [diff] [blame^] | 1103 |         s = (char *)(((reqptr->data[0] & SET_PARM_BOOT_FLAGS_PERMANENT) == | 
 | 1104 |                 SET_PARM_BOOT_FLAGS_PERMANENT) ?"PERMANENT":"ONETIME"); | 
| ratagupt | a6f6bff | 2016-04-04 06:20:11 -0500 | [diff] [blame] | 1105 |  | 
| Ratan Gupta | fd28dd7 | 2016-08-01 04:58:01 -0500 | [diff] [blame] | 1106 |         printf ( "\nBoot Policy is %s",s); | 
| ratagupt | a6f6bff | 2016-04-04 06:20:11 -0500 | [diff] [blame] | 1107 |         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 |         } | 
| shgoupf | d84fbbf | 2015-12-17 10:05:51 +0800 | [diff] [blame] | 1113 |  | 
| Andrew Geissler | fca6a4f | 2017-05-30 10:55:39 -0500 | [diff] [blame^] | 1114 |     } else if (reqptr->parameter == | 
 | 1115 |             (uint8_t)BootOptionParameter::OPAL_NETWORK_SETTINGS) { | 
| Ratan Gupta | fd28dd7 | 2016-08-01 04:58:01 -0500 | [diff] [blame] | 1116 |  | 
 | 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 { | 
| shgoupf | d84fbbf | 2015-12-17 10:05:51 +0800 | [diff] [blame] | 1124 |         fprintf(stderr, "Unsupported parameter 0x%x\n", reqptr->parameter); | 
 | 1125 |         rc = IPMI_CC_PARM_NOT_SUPPORTED; | 
| Adriana Kobylak | 40814c6 | 2015-10-27 15:58:44 -0500 | [diff] [blame] | 1126 |     } | 
 | 1127 |  | 
 | 1128 |     return rc; | 
 | 1129 | } | 
 | 1130 |  | 
 | 1131 | void register_netfn_chassis_functions() | 
 | 1132 | { | 
| Tom | 0573237 | 2016-09-06 17:21:23 +0530 | [diff] [blame] | 1133 |     // <Wildcard Command> | 
| Adriana Kobylak | 40814c6 | 2015-10-27 15:58:44 -0500 | [diff] [blame] | 1134 |     printf("Registering NetFn:[0x%X], Cmd:[0x%X]\n",NETFUN_CHASSIS, IPMI_CMD_WILDCARD); | 
| Tom | 0573237 | 2016-09-06 17:21:23 +0530 | [diff] [blame] | 1135 |     ipmi_register_callback(NETFUN_CHASSIS, IPMI_CMD_WILDCARD, NULL, ipmi_chassis_wildcard, | 
 | 1136 |                            PRIVILEGE_USER); | 
| Adriana Kobylak | 40814c6 | 2015-10-27 15:58:44 -0500 | [diff] [blame] | 1137 |  | 
| Tom | 0573237 | 2016-09-06 17:21:23 +0530 | [diff] [blame] | 1138 |     // Get Chassis Capabilities | 
| Nan Li | 8d15fb4 | 2016-08-16 22:29:40 +0800 | [diff] [blame] | 1139 |     printf("Registering NetFn:[0x%X], Cmd:[0x%X]\n",NETFUN_CHASSIS, IPMI_CMD_GET_CHASSIS_CAP); | 
| Tom | 0573237 | 2016-09-06 17:21:23 +0530 | [diff] [blame] | 1140 |     ipmi_register_callback(NETFUN_CHASSIS, IPMI_CMD_GET_CHASSIS_CAP, NULL, ipmi_get_chassis_cap, | 
 | 1141 |                            PRIVILEGE_USER); | 
| Nan Li | 8d15fb4 | 2016-08-16 22:29:40 +0800 | [diff] [blame] | 1142 |  | 
| Tom | 0573237 | 2016-09-06 17:21:23 +0530 | [diff] [blame] | 1143 |     // <Get System Boot Options> | 
| Adriana Kobylak | 40814c6 | 2015-10-27 15:58:44 -0500 | [diff] [blame] | 1144 |     printf("Registering NetFn:[0x%X], Cmd:[0x%X]\n",NETFUN_CHASSIS, IPMI_CMD_GET_SYS_BOOT_OPTIONS); | 
| Tom | 0573237 | 2016-09-06 17:21:23 +0530 | [diff] [blame] | 1145 |     ipmi_register_callback(NETFUN_CHASSIS, IPMI_CMD_GET_SYS_BOOT_OPTIONS, NULL, | 
 | 1146 |                            ipmi_chassis_get_sys_boot_options, PRIVILEGE_OPERATOR); | 
| Adriana Kobylak | 40814c6 | 2015-10-27 15:58:44 -0500 | [diff] [blame] | 1147 |  | 
| Tom | 0573237 | 2016-09-06 17:21:23 +0530 | [diff] [blame] | 1148 |     // <Get Chassis Status> | 
| Nan Li | fdd8ec5 | 2016-08-28 03:57:40 +0800 | [diff] [blame] | 1149 |     printf("Registering NetFn:[0x%X], Cmd:[0x%X]\n",NETFUN_CHASSIS, IPMI_CMD_CHASSIS_STATUS); | 
| Tom | 0573237 | 2016-09-06 17:21:23 +0530 | [diff] [blame] | 1150 |     ipmi_register_callback(NETFUN_CHASSIS, IPMI_CMD_CHASSIS_STATUS, NULL, ipmi_get_chassis_status, | 
 | 1151 |                            PRIVILEGE_USER); | 
| Nan Li | fdd8ec5 | 2016-08-28 03:57:40 +0800 | [diff] [blame] | 1152 |  | 
| Tom | 0573237 | 2016-09-06 17:21:23 +0530 | [diff] [blame] | 1153 |     // <Chassis Control> | 
| vishwa | 3699327 | 2015-11-20 12:43:49 -0600 | [diff] [blame] | 1154 |     printf("Registering NetFn:[0x%X], Cmd:[0x%X]\n",NETFUN_CHASSIS, IPMI_CMD_CHASSIS_CONTROL); | 
| Tom | 0573237 | 2016-09-06 17:21:23 +0530 | [diff] [blame] | 1155 |     ipmi_register_callback(NETFUN_CHASSIS, IPMI_CMD_CHASSIS_CONTROL, NULL, ipmi_chassis_control, | 
 | 1156 |                            PRIVILEGE_OPERATOR); | 
| shgoupf | d84fbbf | 2015-12-17 10:05:51 +0800 | [diff] [blame] | 1157 |  | 
| Tom | 0573237 | 2016-09-06 17:21:23 +0530 | [diff] [blame] | 1158 |     // <Set System Boot Options> | 
| shgoupf | d84fbbf | 2015-12-17 10:05:51 +0800 | [diff] [blame] | 1159 |     printf("Registering NetFn:[0x%X], Cmd:[0x%X]\n", NETFUN_CHASSIS, IPMI_CMD_SET_SYS_BOOT_OPTIONS); | 
| Tom | 0573237 | 2016-09-06 17:21:23 +0530 | [diff] [blame] | 1160 |     ipmi_register_callback(NETFUN_CHASSIS, IPMI_CMD_SET_SYS_BOOT_OPTIONS, NULL, | 
 | 1161 |                            ipmi_chassis_set_sys_boot_options, PRIVILEGE_OPERATOR); | 
| vishwa | 3699327 | 2015-11-20 12:43:49 -0600 | [diff] [blame] | 1162 | } |