| Patrick Venture | 46470a3 | 2018-09-07 19:26:25 -0700 | [diff] [blame] | 1 | #include "apphandler.hpp" | 
| Patrick Venture | 0b02be9 | 2018-08-31 11:55:55 -0700 | [diff] [blame] | 2 |  | 
| Xo Wang | f542e8b | 2017-08-09 15:34:16 -0700 | [diff] [blame] | 3 | #include "app/channel.hpp" | 
 | 4 | #include "app/watchdog.hpp" | 
 | 5 | #include "ipmid.hpp" | 
| Xo Wang | f542e8b | 2017-08-09 15:34:16 -0700 | [diff] [blame] | 6 | #include "sys_info_param.hpp" | 
 | 7 | #include "transporthandler.hpp" | 
 | 8 | #include "types.hpp" | 
 | 9 | #include "utils.hpp" | 
 | 10 |  | 
| Patrick Venture | 0b02be9 | 2018-08-31 11:55:55 -0700 | [diff] [blame] | 11 | #include <arpa/inet.h> | 
| Patrick Venture | 46470a3 | 2018-09-07 19:26:25 -0700 | [diff] [blame] | 12 | #include <host-ipmid/ipmid-api.h> | 
| Xo Wang | 8765133 | 2017-08-11 10:17:59 -0700 | [diff] [blame] | 13 | #include <limits.h> | 
| Patrick Venture | 0b02be9 | 2018-08-31 11:55:55 -0700 | [diff] [blame] | 14 | #include <mapper.h> | 
| Patrick Venture | 0b02be9 | 2018-08-31 11:55:55 -0700 | [diff] [blame] | 15 | #include <systemd/sd-bus.h> | 
| Xo Wang | 8765133 | 2017-08-11 10:17:59 -0700 | [diff] [blame] | 16 | #include <unistd.h> | 
| Patrick Venture | 0b02be9 | 2018-08-31 11:55:55 -0700 | [diff] [blame] | 17 |  | 
| Patrick Venture | 3a5071a | 2018-09-12 13:27:42 -0700 | [diff] [blame] | 18 | #include <algorithm> | 
 | 19 | #include <array> | 
 | 20 | #include <cstddef> | 
 | 21 | #include <fstream> | 
 | 22 | #include <memory> | 
| Patrick Venture | 46470a3 | 2018-09-07 19:26:25 -0700 | [diff] [blame] | 23 | #include <nlohmann/json.hpp> | 
| Patrick Venture | 3a5071a | 2018-09-12 13:27:42 -0700 | [diff] [blame] | 24 | #include <phosphor-logging/elog-errors.hpp> | 
 | 25 | #include <phosphor-logging/log.hpp> | 
 | 26 | #include <string> | 
 | 27 | #include <tuple> | 
 | 28 | #include <vector> | 
 | 29 | #include <xyz/openbmc_project/Common/error.hpp> | 
 | 30 | #include <xyz/openbmc_project/Software/Activation/server.hpp> | 
 | 31 | #include <xyz/openbmc_project/Software/Version/server.hpp> | 
 | 32 | #include <xyz/openbmc_project/State/BMC/server.hpp> | 
| Ratan Gupta | b8e9955 | 2017-07-27 07:07:48 +0530 | [diff] [blame] | 33 |  | 
| Vernon Mauery | 185b9f8 | 2018-07-20 10:52:36 -0700 | [diff] [blame] | 34 | #if __has_include(<filesystem>) | 
 | 35 | #include <filesystem> | 
 | 36 | #elif __has_include(<experimental/filesystem>) | 
 | 37 | #include <experimental/filesystem> | 
| Patrick Venture | 0b02be9 | 2018-08-31 11:55:55 -0700 | [diff] [blame] | 38 | namespace std | 
 | 39 | { | 
 | 40 | // splice experimental::filesystem into std | 
 | 41 | namespace filesystem = std::experimental::filesystem; | 
 | 42 | } // namespace std | 
| Vernon Mauery | 185b9f8 | 2018-07-20 10:52:36 -0700 | [diff] [blame] | 43 | #else | 
| Patrick Venture | 0b02be9 | 2018-08-31 11:55:55 -0700 | [diff] [blame] | 44 | #error filesystem not available | 
| Vernon Mauery | 185b9f8 | 2018-07-20 10:52:36 -0700 | [diff] [blame] | 45 | #endif | 
| Ratan Gupta | 62736ec | 2017-09-02 12:02:47 +0530 | [diff] [blame] | 46 |  | 
| Patrick Venture | 0b02be9 | 2018-08-31 11:55:55 -0700 | [diff] [blame] | 47 | extern sd_bus* bus; | 
| vishwabmc | ba0bd5f | 2015-09-30 16:50:23 +0530 | [diff] [blame] | 48 |  | 
| Alexander Amelkin | ba19c18 | 2018-09-04 15:49:36 +0300 | [diff] [blame] | 49 | constexpr auto bmc_state_interface = "xyz.openbmc_project.State.BMC"; | 
 | 50 | constexpr auto bmc_state_property = "CurrentBMCState"; | 
| Marri Devender Rao | 5e007a5 | 2018-01-08 06:18:36 -0600 | [diff] [blame] | 51 | constexpr auto bmc_interface = "xyz.openbmc_project.Inventory.Item.Bmc"; | 
 | 52 | constexpr auto bmc_guid_interface = "xyz.openbmc_project.Common.UUID"; | 
 | 53 | constexpr auto bmc_guid_property = "UUID"; | 
 | 54 | constexpr auto bmc_guid_len = 16; | 
 | 55 |  | 
| Nagaraju Goruganti | 744398d | 2018-02-20 09:52:00 -0600 | [diff] [blame] | 56 | static constexpr auto redundancyIntf = | 
 | 57 |     "xyz.openbmc_project.Software.RedundancyPriority"; | 
| Patrick Venture | 0b02be9 | 2018-08-31 11:55:55 -0700 | [diff] [blame] | 58 | static constexpr auto versionIntf = "xyz.openbmc_project.Software.Version"; | 
| Nagaraju Goruganti | 744398d | 2018-02-20 09:52:00 -0600 | [diff] [blame] | 59 | static constexpr auto activationIntf = | 
 | 60 |     "xyz.openbmc_project.Software.Activation"; | 
 | 61 | static constexpr auto softwareRoot = "/xyz/openbmc_project/software"; | 
 | 62 |  | 
| Chris Austen | 6caf28b | 2015-10-13 12:40:40 -0500 | [diff] [blame] | 63 | void register_netfn_app_functions() __attribute__((constructor)); | 
| vishwabmc | ba0bd5f | 2015-09-30 16:50:23 +0530 | [diff] [blame] | 64 |  | 
| Ratan Gupta | b8e9955 | 2017-07-27 07:07:48 +0530 | [diff] [blame] | 65 | using namespace phosphor::logging; | 
 | 66 | using namespace sdbusplus::xyz::openbmc_project::Common::Error; | 
| Nagaraju Goruganti | 744398d | 2018-02-20 09:52:00 -0600 | [diff] [blame] | 67 | using Version = sdbusplus::xyz::openbmc_project::Software::server::Version; | 
 | 68 | using Activation = | 
 | 69 |     sdbusplus::xyz::openbmc_project::Software::server::Activation; | 
| Alexander Amelkin | ba19c18 | 2018-09-04 15:49:36 +0300 | [diff] [blame] | 70 | using BMC = sdbusplus::xyz::openbmc_project::State::server::BMC; | 
| Vernon Mauery | 185b9f8 | 2018-07-20 10:52:36 -0700 | [diff] [blame] | 71 | namespace fs = std::filesystem; | 
| Ratan Gupta | b8e9955 | 2017-07-27 07:07:48 +0530 | [diff] [blame] | 72 |  | 
| Nan Li | ee0cb90 | 2016-07-11 15:38:03 +0800 | [diff] [blame] | 73 | // Offset in get device id command. | 
 | 74 | typedef struct | 
 | 75 | { | 
| Patrick Venture | 0b02be9 | 2018-08-31 11:55:55 -0700 | [diff] [blame] | 76 |     uint8_t id; | 
 | 77 |     uint8_t revision; | 
 | 78 |     uint8_t fw[2]; | 
 | 79 |     uint8_t ipmi_ver; | 
 | 80 |     uint8_t addn_dev_support; | 
 | 81 |     uint8_t manuf_id[3]; | 
 | 82 |     uint8_t prod_id[2]; | 
 | 83 |     uint8_t aux[4]; | 
 | 84 | } __attribute__((packed)) ipmi_device_id_t; | 
| Chris Austen | 7303bdc | 2016-04-17 11:50:54 -0500 | [diff] [blame] | 85 |  | 
| Nagaraju Goruganti | 744398d | 2018-02-20 09:52:00 -0600 | [diff] [blame] | 86 | /** | 
 | 87 |  * @brief Returns the Version info from primary s/w object | 
 | 88 |  * | 
 | 89 |  * Get the Version info from the active s/w object which is having high | 
 | 90 |  * "Priority" value(a smaller number is a higher priority) and "Purpose" | 
 | 91 |  * is "BMC" from the list of all s/w objects those are implementing | 
 | 92 |  * RedundancyPriority interface from the given softwareRoot path. | 
 | 93 |  * | 
 | 94 |  * @return On success returns the Version info from primary s/w object. | 
 | 95 |  * | 
 | 96 |  */ | 
 | 97 | std::string getActiveSoftwareVersionInfo() | 
 | 98 | { | 
 | 99 |     sdbusplus::bus::bus bus{ipmid_get_sd_bus_connection()}; | 
 | 100 |  | 
 | 101 |     std::string revision{}; | 
| Patrick Venture | 0b02be9 | 2018-08-31 11:55:55 -0700 | [diff] [blame] | 102 |     auto objectTree = | 
 | 103 |         ipmi::getAllDbusObjects(bus, softwareRoot, redundancyIntf, ""); | 
| Nagaraju Goruganti | 744398d | 2018-02-20 09:52:00 -0600 | [diff] [blame] | 104 |     if (objectTree.empty()) | 
 | 105 |     { | 
 | 106 |         log<level::ERR>("No Obj has implemented the s/w redundancy interface", | 
 | 107 |                         entry("INTERFACE=%s", redundancyIntf)); | 
 | 108 |         elog<InternalFailure>(); | 
 | 109 |     } | 
 | 110 |  | 
 | 111 |     auto objectFound = false; | 
 | 112 |     for (auto& softObject : objectTree) | 
 | 113 |     { | 
 | 114 |         auto service = ipmi::getService(bus, redundancyIntf, softObject.first); | 
 | 115 |         auto objValueTree = ipmi::getManagedObjects(bus, service, softwareRoot); | 
 | 116 |  | 
 | 117 |         auto minPriority = 0xFF; | 
 | 118 |         for (const auto& objIter : objValueTree) | 
 | 119 |         { | 
 | 120 |             try | 
 | 121 |             { | 
 | 122 |                 auto& intfMap = objIter.second; | 
 | 123 |                 auto& redundancyPriorityProps = intfMap.at(redundancyIntf); | 
 | 124 |                 auto& versionProps = intfMap.at(versionIntf); | 
 | 125 |                 auto& activationProps = intfMap.at(activationIntf); | 
 | 126 |                 auto priority = | 
 | 127 |                     redundancyPriorityProps.at("Priority").get<uint8_t>(); | 
 | 128 |                 auto purpose = versionProps.at("Purpose").get<std::string>(); | 
 | 129 |                 auto activation = | 
 | 130 |                     activationProps.at("Activation").get<std::string>(); | 
 | 131 |                 auto version = versionProps.at("Version").get<std::string>(); | 
 | 132 |                 if ((Version::convertVersionPurposeFromString(purpose) == | 
 | 133 |                      Version::VersionPurpose::BMC) && | 
 | 134 |                     (Activation::convertActivationsFromString(activation) == | 
 | 135 |                      Activation::Activations::Active)) | 
 | 136 |                 { | 
 | 137 |                     if (priority < minPriority) | 
 | 138 |                     { | 
 | 139 |                         minPriority = priority; | 
 | 140 |                         objectFound = true; | 
 | 141 |                         revision = std::move(version); | 
 | 142 |                     } | 
 | 143 |                 } | 
 | 144 |             } | 
 | 145 |             catch (const std::exception& e) | 
 | 146 |             { | 
 | 147 |                 log<level::ERR>(e.what()); | 
 | 148 |             } | 
 | 149 |         } | 
 | 150 |     } | 
 | 151 |  | 
 | 152 |     if (!objectFound) | 
 | 153 |     { | 
 | 154 |         log<level::ERR>("Could not found an BMC software Object"); | 
 | 155 |         elog<InternalFailure>(); | 
 | 156 |     } | 
 | 157 |  | 
 | 158 |     return revision; | 
 | 159 | } | 
 | 160 |  | 
| Alexander Amelkin | ba19c18 | 2018-09-04 15:49:36 +0300 | [diff] [blame] | 161 | bool getCurrentBmcState() | 
 | 162 | { | 
 | 163 |     sdbusplus::bus::bus bus{ipmid_get_sd_bus_connection()}; | 
 | 164 |  | 
 | 165 |     // Get the Inventory object implementing the BMC interface | 
 | 166 |     ipmi::DbusObjectInfo bmcObject = | 
 | 167 |         ipmi::getDbusObject(bus, bmc_state_interface); | 
 | 168 |     auto variant = | 
 | 169 |         ipmi::getDbusProperty(bus, bmcObject.second, bmcObject.first, | 
 | 170 |                               bmc_state_interface, bmc_state_property); | 
 | 171 |  | 
 | 172 |     return variant.is<std::string>() && | 
 | 173 |            BMC::convertBMCStateFromString(variant.get<std::string>()) == | 
 | 174 |                BMC::BMCState::Ready; | 
 | 175 | } | 
 | 176 |  | 
| Adriana Kobylak | 3a552e1 | 2015-10-19 16:11:00 -0500 | [diff] [blame] | 177 | ipmi_ret_t ipmi_app_set_acpi_power_state(ipmi_netfn_t netfn, ipmi_cmd_t cmd, | 
| Patrick Venture | 0b02be9 | 2018-08-31 11:55:55 -0700 | [diff] [blame] | 178 |                                          ipmi_request_t request, | 
 | 179 |                                          ipmi_response_t response, | 
 | 180 |                                          ipmi_data_len_t data_len, | 
 | 181 |                                          ipmi_context_t context) | 
| Chris Austen | 6caf28b | 2015-10-13 12:40:40 -0500 | [diff] [blame] | 182 | { | 
 | 183 |     ipmi_ret_t rc = IPMI_CC_OK; | 
 | 184 |     *data_len = 0; | 
 | 185 |  | 
| Aditya Saripalli | 5fb1460 | 2017-11-09 14:46:27 +0530 | [diff] [blame] | 186 |     log<level::DEBUG>("IPMI SET ACPI STATE Ignoring for now\n"); | 
| Chris Austen | 6caf28b | 2015-10-13 12:40:40 -0500 | [diff] [blame] | 187 |     return rc; | 
 | 188 | } | 
 | 189 |  | 
| Chris Austen | 7303bdc | 2016-04-17 11:50:54 -0500 | [diff] [blame] | 190 | typedef struct | 
 | 191 | { | 
 | 192 |     char major; | 
 | 193 |     char minor; | 
| Chris Austen | 176c965 | 2016-04-30 16:32:17 -0500 | [diff] [blame] | 194 |     uint16_t d[2]; | 
| Chris Austen | 7303bdc | 2016-04-17 11:50:54 -0500 | [diff] [blame] | 195 | } rev_t; | 
 | 196 |  | 
| Dinesh Chinari | 2b7e07d | 2017-11-08 15:38:50 -0600 | [diff] [blame] | 197 | /* Currently supports the vx.x-x-[-x] and v1.x.x-x-[-x] format. It will     */ | 
 | 198 | /* return -1 if not in those formats, this routine knows how to parse       */ | 
| Chris Austen | 7303bdc | 2016-04-17 11:50:54 -0500 | [diff] [blame] | 199 | /* version = v0.6-19-gf363f61-dirty                                         */ | 
 | 200 | /*            ^ ^ ^^          ^                                             */ | 
 | 201 | /*            | |  |----------|-- additional details                        */ | 
 | 202 | /*            | |---------------- Minor                                     */ | 
 | 203 | /*            |------------------ Major                                     */ | 
| Dinesh Chinari | 2b7e07d | 2017-11-08 15:38:50 -0600 | [diff] [blame] | 204 | /* and version = v1.99.10-113-g65edf7d-r3-0-g9e4f715                        */ | 
 | 205 | /*                ^ ^  ^^ ^                                                 */ | 
 | 206 | /*                | |  |--|---------- additional details                    */ | 
 | 207 | /*                | |---------------- Minor                                 */ | 
 | 208 | /*                |------------------ Major                                 */ | 
| Chris Austen | 7303bdc | 2016-04-17 11:50:54 -0500 | [diff] [blame] | 209 | /* Additional details : If the option group exists it will force Auxiliary  */ | 
 | 210 | /* Firmware Revision Information 4th byte to 1 indicating the build was     */ | 
 | 211 | /* derived with additional edits                                            */ | 
| Patrick Venture | 0b02be9 | 2018-08-31 11:55:55 -0700 | [diff] [blame] | 212 | int convert_version(const char* p, rev_t* rev) | 
| Chris Austen | 7303bdc | 2016-04-17 11:50:54 -0500 | [diff] [blame] | 213 | { | 
| Dinesh Chinari | 2b7e07d | 2017-11-08 15:38:50 -0600 | [diff] [blame] | 214 |     std::string s(p); | 
 | 215 |     std::string token; | 
| Chris Austen | 176c965 | 2016-04-30 16:32:17 -0500 | [diff] [blame] | 216 |     uint16_t commits; | 
| Chris Austen | 7303bdc | 2016-04-17 11:50:54 -0500 | [diff] [blame] | 217 |  | 
| Patrick Venture | 0b02be9 | 2018-08-31 11:55:55 -0700 | [diff] [blame] | 218 |     auto location = s.find_first_of('v'); | 
| Dinesh Chinari | 2b7e07d | 2017-11-08 15:38:50 -0600 | [diff] [blame] | 219 |     if (location != std::string::npos) | 
 | 220 |     { | 
| Patrick Venture | 0b02be9 | 2018-08-31 11:55:55 -0700 | [diff] [blame] | 221 |         s = s.substr(location + 1); | 
| Chris Austen | 176c965 | 2016-04-30 16:32:17 -0500 | [diff] [blame] | 222 |     } | 
| Chris Austen | 7303bdc | 2016-04-17 11:50:54 -0500 | [diff] [blame] | 223 |  | 
| Dinesh Chinari | 2b7e07d | 2017-11-08 15:38:50 -0600 | [diff] [blame] | 224 |     if (!s.empty()) | 
 | 225 |     { | 
 | 226 |         location = s.find_first_of("."); | 
 | 227 |         if (location != std::string::npos) | 
 | 228 |         { | 
| Patrick Venture | 0b02be9 | 2018-08-31 11:55:55 -0700 | [diff] [blame] | 229 |             rev->major = | 
 | 230 |                 static_cast<char>(std::stoi(s.substr(0, location), 0, 16)); | 
 | 231 |             token = s.substr(location + 1); | 
| Dinesh Chinari | 2b7e07d | 2017-11-08 15:38:50 -0600 | [diff] [blame] | 232 |         } | 
| Chris Austen | 176c965 | 2016-04-30 16:32:17 -0500 | [diff] [blame] | 233 |  | 
| Dinesh Chinari | 2b7e07d | 2017-11-08 15:38:50 -0600 | [diff] [blame] | 234 |         if (!token.empty()) | 
 | 235 |         { | 
 | 236 |             location = token.find_first_of(".-"); | 
 | 237 |             if (location != std::string::npos) | 
 | 238 |             { | 
| Patrick Venture | d211702 | 2018-02-06 08:54:37 -0800 | [diff] [blame] | 239 |                 rev->minor = static_cast<char>( | 
| Patrick Venture | 0b02be9 | 2018-08-31 11:55:55 -0700 | [diff] [blame] | 240 |                     std::stoi(token.substr(0, location), 0, 16)); | 
 | 241 |                 token = token.substr(location + 1); | 
| Dinesh Chinari | 2b7e07d | 2017-11-08 15:38:50 -0600 | [diff] [blame] | 242 |             } | 
 | 243 |         } | 
| Chris Austen | 7303bdc | 2016-04-17 11:50:54 -0500 | [diff] [blame] | 244 |  | 
| Dinesh Chinari | 2b7e07d | 2017-11-08 15:38:50 -0600 | [diff] [blame] | 245 |         // Capture the number of commits on top of the minor tag. | 
 | 246 |         // I'm using BE format like the ipmi spec asked for | 
 | 247 |         location = token.find_first_of(".-"); | 
 | 248 |         if (!token.empty()) | 
 | 249 |         { | 
 | 250 |             commits = std::stoi(token.substr(0, location), 0, 16); | 
| Patrick Venture | 0b02be9 | 2018-08-31 11:55:55 -0700 | [diff] [blame] | 251 |             rev->d[0] = (commits >> 8) | (commits << 8); | 
| Dinesh Chinari | 2b7e07d | 2017-11-08 15:38:50 -0600 | [diff] [blame] | 252 |  | 
 | 253 |             // commit number we skip | 
 | 254 |             location = token.find_first_of(".-"); | 
 | 255 |             if (location != std::string::npos) | 
 | 256 |             { | 
| Patrick Venture | 0b02be9 | 2018-08-31 11:55:55 -0700 | [diff] [blame] | 257 |                 token = token.substr(location + 1); | 
| Dinesh Chinari | 2b7e07d | 2017-11-08 15:38:50 -0600 | [diff] [blame] | 258 |             } | 
 | 259 |         } | 
| Patrick Venture | 0b02be9 | 2018-08-31 11:55:55 -0700 | [diff] [blame] | 260 |         else | 
 | 261 |         { | 
| Dinesh Chinari | 2b7e07d | 2017-11-08 15:38:50 -0600 | [diff] [blame] | 262 |             rev->d[0] = 0; | 
 | 263 |         } | 
 | 264 |  | 
 | 265 |         if (location != std::string::npos) | 
 | 266 |         { | 
| Patrick Venture | 0b02be9 | 2018-08-31 11:55:55 -0700 | [diff] [blame] | 267 |             token = token.substr(location + 1); | 
| Dinesh Chinari | 2b7e07d | 2017-11-08 15:38:50 -0600 | [diff] [blame] | 268 |         } | 
 | 269 |  | 
 | 270 |         // Any value of the optional parameter forces it to 1 | 
 | 271 |         location = token.find_first_of(".-"); | 
 | 272 |         if (location != std::string::npos) | 
 | 273 |         { | 
| Patrick Venture | 0b02be9 | 2018-08-31 11:55:55 -0700 | [diff] [blame] | 274 |             token = token.substr(location + 1); | 
| Dinesh Chinari | 2b7e07d | 2017-11-08 15:38:50 -0600 | [diff] [blame] | 275 |         } | 
 | 276 |         commits = (!token.empty()) ? 1 : 0; | 
 | 277 |  | 
| Patrick Venture | 0b02be9 | 2018-08-31 11:55:55 -0700 | [diff] [blame] | 278 |         // We do this operation to get this displayed in least significant bytes | 
 | 279 |         // of ipmitool device id command. | 
 | 280 |         rev->d[1] = (commits >> 8) | (commits << 8); | 
| Dinesh Chinari | 2b7e07d | 2017-11-08 15:38:50 -0600 | [diff] [blame] | 281 |     } | 
 | 282 |  | 
| Chris Austen | 7303bdc | 2016-04-17 11:50:54 -0500 | [diff] [blame] | 283 |     return 0; | 
 | 284 | } | 
 | 285 |  | 
| Adriana Kobylak | 3a552e1 | 2015-10-19 16:11:00 -0500 | [diff] [blame] | 286 | ipmi_ret_t ipmi_app_get_device_id(ipmi_netfn_t netfn, ipmi_cmd_t cmd, | 
| Patrick Venture | 0b02be9 | 2018-08-31 11:55:55 -0700 | [diff] [blame] | 287 |                                   ipmi_request_t request, | 
 | 288 |                                   ipmi_response_t response, | 
 | 289 |                                   ipmi_data_len_t data_len, | 
 | 290 |                                   ipmi_context_t context) | 
| Chris Austen | 6caf28b | 2015-10-13 12:40:40 -0500 | [diff] [blame] | 291 | { | 
 | 292 |     ipmi_ret_t rc = IPMI_CC_OK; | 
| Nagaraju Goruganti | 744398d | 2018-02-20 09:52:00 -0600 | [diff] [blame] | 293 |     int r = -1; | 
| Chris Austen | 7303bdc | 2016-04-17 11:50:54 -0500 | [diff] [blame] | 294 |     rev_t rev = {0}; | 
| David Cobbley | a1adb07 | 2017-11-21 15:58:13 -0800 | [diff] [blame] | 295 |     static ipmi_device_id_t dev_id{}; | 
 | 296 |     static bool dev_id_initialized = false; | 
 | 297 |     const char* filename = "/usr/share/ipmi-providers/dev_id.json"; | 
| Alexander Amelkin | ba19c18 | 2018-09-04 15:49:36 +0300 | [diff] [blame] | 298 |     constexpr auto ipmiDevIdStateShift = 7; | 
 | 299 |     constexpr auto ipmiDevIdFw1Mask = ~(1 << ipmiDevIdStateShift); | 
| Chris Austen | 6caf28b | 2015-10-13 12:40:40 -0500 | [diff] [blame] | 300 |  | 
 | 301 |     // Data length | 
| Chris Austen | 7303bdc | 2016-04-17 11:50:54 -0500 | [diff] [blame] | 302 |     *data_len = sizeof(dev_id); | 
 | 303 |  | 
| David Cobbley | a1adb07 | 2017-11-21 15:58:13 -0800 | [diff] [blame] | 304 |     if (!dev_id_initialized) | 
 | 305 |     { | 
| Nagaraju Goruganti | 744398d | 2018-02-20 09:52:00 -0600 | [diff] [blame] | 306 |         try | 
 | 307 |         { | 
 | 308 |             auto version = getActiveSoftwareVersionInfo(); | 
 | 309 |             r = convert_version(version.c_str(), &rev); | 
| David Cobbley | a1adb07 | 2017-11-21 15:58:13 -0800 | [diff] [blame] | 310 |         } | 
| Nagaraju Goruganti | 744398d | 2018-02-20 09:52:00 -0600 | [diff] [blame] | 311 |         catch (const std::exception& e) | 
 | 312 |         { | 
 | 313 |             log<level::ERR>(e.what()); | 
 | 314 |         } | 
| Nan Li | ee0cb90 | 2016-07-11 15:38:03 +0800 | [diff] [blame] | 315 |  | 
| Patrick Venture | 0b02be9 | 2018-08-31 11:55:55 -0700 | [diff] [blame] | 316 |         if (r >= 0) | 
 | 317 |         { | 
| Nagaraju Goruganti | 744398d | 2018-02-20 09:52:00 -0600 | [diff] [blame] | 318 |             // bit7 identifies if the device is available | 
 | 319 |             // 0=normal operation | 
 | 320 |             // 1=device firmware, SDR update, | 
 | 321 |             // or self-initialization in progress. | 
| Alexander Amelkin | ba19c18 | 2018-09-04 15:49:36 +0300 | [diff] [blame] | 322 |             // The availability may change in run time, so mask here | 
 | 323 |             // and initialize later. | 
 | 324 |             dev_id.fw[0] = rev.major & ipmiDevIdFw1Mask; | 
| Nagaraju Goruganti | 744398d | 2018-02-20 09:52:00 -0600 | [diff] [blame] | 325 |  | 
 | 326 |             rev.minor = (rev.minor > 99 ? 99 : rev.minor); | 
 | 327 |             dev_id.fw[1] = rev.minor % 10 + (rev.minor / 10) * 16; | 
| Patrick Venture | b51bf9c | 2018-09-10 15:53:14 -0700 | [diff] [blame] | 328 |             std::memcpy(&dev_id.aux, rev.d, 4); | 
| David Cobbley | a1adb07 | 2017-11-21 15:58:13 -0800 | [diff] [blame] | 329 |         } | 
| Nan Li | ee0cb90 | 2016-07-11 15:38:03 +0800 | [diff] [blame] | 330 |  | 
| David Cobbley | a1adb07 | 2017-11-21 15:58:13 -0800 | [diff] [blame] | 331 |         // IPMI Spec version 2.0 | 
 | 332 |         dev_id.ipmi_ver = 2; | 
| Adriana Kobylak | 0e91264 | 2016-06-22 16:54:39 -0500 | [diff] [blame] | 333 |  | 
| David Cobbley | a1adb07 | 2017-11-21 15:58:13 -0800 | [diff] [blame] | 334 |         std::ifstream dev_id_file(filename); | 
 | 335 |         if (dev_id_file.is_open()) | 
 | 336 |         { | 
 | 337 |             auto data = nlohmann::json::parse(dev_id_file, nullptr, false); | 
 | 338 |             if (!data.is_discarded()) | 
 | 339 |             { | 
 | 340 |                 dev_id.id = data.value("id", 0); | 
 | 341 |                 dev_id.revision = data.value("revision", 0); | 
 | 342 |                 dev_id.addn_dev_support = data.value("addn_dev_support", 0); | 
 | 343 |                 dev_id.manuf_id[2] = data.value("manuf_id", 0) >> 16; | 
 | 344 |                 dev_id.manuf_id[1] = data.value("manuf_id", 0) >> 8; | 
 | 345 |                 dev_id.manuf_id[0] = data.value("manuf_id", 0); | 
 | 346 |                 dev_id.prod_id[1] = data.value("prod_id", 0) >> 8; | 
 | 347 |                 dev_id.prod_id[0] = data.value("prod_id", 0); | 
| Tom Joseph | af8a098 | 2018-03-09 07:54:02 -0600 | [diff] [blame] | 348 |                 dev_id.aux[3] = data.value("aux", 0); | 
 | 349 |                 dev_id.aux[2] = data.value("aux", 0) >> 8; | 
 | 350 |                 dev_id.aux[1] = data.value("aux", 0) >> 16; | 
 | 351 |                 dev_id.aux[0] = data.value("aux", 0) >> 24; | 
| David Cobbley | a1adb07 | 2017-11-21 15:58:13 -0800 | [diff] [blame] | 352 |  | 
| Patrick Venture | 0b02be9 | 2018-08-31 11:55:55 -0700 | [diff] [blame] | 353 |                 // Don't read the file every time if successful | 
| David Cobbley | a1adb07 | 2017-11-21 15:58:13 -0800 | [diff] [blame] | 354 |                 dev_id_initialized = true; | 
 | 355 |             } | 
 | 356 |             else | 
 | 357 |             { | 
 | 358 |                 log<level::ERR>("Device ID JSON parser failure"); | 
 | 359 |                 rc = IPMI_CC_UNSPECIFIED_ERROR; | 
 | 360 |             } | 
 | 361 |         } | 
 | 362 |         else | 
 | 363 |         { | 
 | 364 |             log<level::ERR>("Device ID file not found"); | 
 | 365 |             rc = IPMI_CC_UNSPECIFIED_ERROR; | 
| Chris Austen | 7303bdc | 2016-04-17 11:50:54 -0500 | [diff] [blame] | 366 |         } | 
 | 367 |     } | 
| Chris Austen | 6caf28b | 2015-10-13 12:40:40 -0500 | [diff] [blame] | 368 |  | 
| Alexander Amelkin | ba19c18 | 2018-09-04 15:49:36 +0300 | [diff] [blame] | 369 |     // Set availability to the actual current BMC state | 
 | 370 |     dev_id.fw[0] &= ipmiDevIdFw1Mask; | 
 | 371 |     if (!getCurrentBmcState()) | 
 | 372 |     { | 
 | 373 |         dev_id.fw[0] |= (1 << ipmiDevIdStateShift); | 
 | 374 |     } | 
 | 375 |  | 
| Chris Austen | 6caf28b | 2015-10-13 12:40:40 -0500 | [diff] [blame] | 376 |     // Pack the actual response | 
| Patrick Venture | b51bf9c | 2018-09-10 15:53:14 -0700 | [diff] [blame] | 377 |     std::memcpy(response, &dev_id, *data_len); | 
| Nagaraju Goruganti | 744398d | 2018-02-20 09:52:00 -0600 | [diff] [blame] | 378 |  | 
| Chris Austen | 6caf28b | 2015-10-13 12:40:40 -0500 | [diff] [blame] | 379 |     return rc; | 
 | 380 | } | 
 | 381 |  | 
| Nan Li | 41fa24a | 2016-11-10 20:12:37 +0800 | [diff] [blame] | 382 | ipmi_ret_t ipmi_app_get_self_test_results(ipmi_netfn_t netfn, ipmi_cmd_t cmd, | 
| Patrick Venture | 0b02be9 | 2018-08-31 11:55:55 -0700 | [diff] [blame] | 383 |                                           ipmi_request_t request, | 
 | 384 |                                           ipmi_response_t response, | 
 | 385 |                                           ipmi_data_len_t data_len, | 
 | 386 |                                           ipmi_context_t context) | 
| Nan Li | 41fa24a | 2016-11-10 20:12:37 +0800 | [diff] [blame] | 387 | { | 
 | 388 |     ipmi_ret_t rc = IPMI_CC_OK; | 
 | 389 |  | 
 | 390 |     // Byte 2: | 
 | 391 |     //  55h - No error. | 
| Gunnar Mills | 8991dd6 | 2017-10-25 17:11:29 -0500 | [diff] [blame] | 392 |     //  56h - Self Test function not implemented in this controller. | 
| Nan Li | 41fa24a | 2016-11-10 20:12:37 +0800 | [diff] [blame] | 393 |     //  57h - Corrupted or inaccesssible data or devices. | 
 | 394 |     //  58h - Fatal hardware error. | 
 | 395 |     //  FFh - reserved. | 
 | 396 |     //  all other: Device-specific 'internal failure'. | 
 | 397 |     //  Byte 3: | 
 | 398 |     //      For byte 2 = 55h, 56h, FFh:     00h | 
 | 399 |     //      For byte 2 = 58h, all other:    Device-specific | 
 | 400 |     //      For byte 2 = 57h:   self-test error bitfield. | 
 | 401 |     //      Note: returning 57h does not imply that all test were run. | 
 | 402 |     //      [7] 1b = Cannot access SEL device. | 
 | 403 |     //      [6] 1b = Cannot access SDR Repository. | 
 | 404 |     //      [5] 1b = Cannot access BMC FRU device. | 
 | 405 |     //      [4] 1b = IPMB signal lines do not respond. | 
 | 406 |     //      [3] 1b = SDR Repository empty. | 
 | 407 |     //      [2] 1b = Internal Use Area of BMC FRU corrupted. | 
 | 408 |     //      [1] 1b = controller update 'boot block' firmware corrupted. | 
 | 409 |     //      [0] 1b = controller operational firmware corrupted. | 
 | 410 |  | 
 | 411 |     char selftestresults[2] = {0}; | 
 | 412 |  | 
 | 413 |     *data_len = 2; | 
 | 414 |  | 
 | 415 |     selftestresults[0] = 0x56; | 
 | 416 |     selftestresults[1] = 0; | 
 | 417 |  | 
| Patrick Venture | b51bf9c | 2018-09-10 15:53:14 -0700 | [diff] [blame] | 418 |     std::memcpy(response, selftestresults, *data_len); | 
| Nan Li | 41fa24a | 2016-11-10 20:12:37 +0800 | [diff] [blame] | 419 |  | 
 | 420 |     return rc; | 
 | 421 | } | 
 | 422 |  | 
| Adriana Kobylak | d100ee5 | 2015-10-20 17:02:37 -0500 | [diff] [blame] | 423 | ipmi_ret_t ipmi_app_get_device_guid(ipmi_netfn_t netfn, ipmi_cmd_t cmd, | 
| Patrick Venture | 0b02be9 | 2018-08-31 11:55:55 -0700 | [diff] [blame] | 424 |                                     ipmi_request_t request, | 
 | 425 |                                     ipmi_response_t response, | 
 | 426 |                                     ipmi_data_len_t data_len, | 
 | 427 |                                     ipmi_context_t context) | 
| Adriana Kobylak | d100ee5 | 2015-10-20 17:02:37 -0500 | [diff] [blame] | 428 | { | 
| Patrick Venture | 0b02be9 | 2018-08-31 11:55:55 -0700 | [diff] [blame] | 429 |     const char* objname = "/org/openbmc/control/chassis0"; | 
 | 430 |     const char* iface = "org.freedesktop.DBus.Properties"; | 
 | 431 |     const char* chassis_iface = "org.openbmc.control.Chassis"; | 
 | 432 |     sd_bus_message* reply = NULL; | 
| Adriana Kobylak | d100ee5 | 2015-10-20 17:02:37 -0500 | [diff] [blame] | 433 |     sd_bus_error error = SD_BUS_ERROR_NULL; | 
 | 434 |     int r = 0; | 
| Patrick Venture | 0b02be9 | 2018-08-31 11:55:55 -0700 | [diff] [blame] | 435 |     char* uuid = NULL; | 
 | 436 |     char* busname = NULL; | 
| Adriana Kobylak | d100ee5 | 2015-10-20 17:02:37 -0500 | [diff] [blame] | 437 |  | 
| Adriana Kobylak | d100ee5 | 2015-10-20 17:02:37 -0500 | [diff] [blame] | 438 |     // UUID is in RFC4122 format. Ex: 61a39523-78f2-11e5-9862-e6402cfc3223 | 
| Patrick Venture | d211702 | 2018-02-06 08:54:37 -0800 | [diff] [blame] | 439 |     // Per IPMI Spec 2.0 need to convert to 16 hex bytes and reverse the byte | 
 | 440 |     // order | 
| Adriana Kobylak | d100ee5 | 2015-10-20 17:02:37 -0500 | [diff] [blame] | 441 |     // Ex: 0x2332fc2c40e66298e511f2782395a361 | 
 | 442 |  | 
| Patrick Venture | 0b02be9 | 2018-08-31 11:55:55 -0700 | [diff] [blame] | 443 |     const int resp_size = 16;     // Response is 16 hex bytes per IPMI Spec | 
| Adriana Kobylak | d100ee5 | 2015-10-20 17:02:37 -0500 | [diff] [blame] | 444 |     uint8_t resp_uuid[resp_size]; // Array to hold the formatted response | 
| Patrick Venture | d211702 | 2018-02-06 08:54:37 -0800 | [diff] [blame] | 445 |     // Point resp end of array to save in reverse order | 
| Patrick Venture | 0b02be9 | 2018-08-31 11:55:55 -0700 | [diff] [blame] | 446 |     int resp_loc = resp_size - 1; | 
| Adriana Kobylak | d100ee5 | 2015-10-20 17:02:37 -0500 | [diff] [blame] | 447 |     int i = 0; | 
| Patrick Venture | 0b02be9 | 2018-08-31 11:55:55 -0700 | [diff] [blame] | 448 |     char* tokptr = NULL; | 
 | 449 |     char* id_octet = NULL; | 
| Emily Shaffer | edb8bb0 | 2018-09-27 14:50:15 -0700 | [diff] [blame^] | 450 |     size_t total_uuid_size = 0; | 
 | 451 |     // 1 byte of resp is built from 2 chars of uuid. | 
 | 452 |     constexpr size_t max_uuid_size = 2 * resp_size; | 
| vishwa | 1eaea4f | 2016-02-26 11:57:40 -0600 | [diff] [blame] | 453 |  | 
 | 454 |     // Status code. | 
 | 455 |     ipmi_ret_t rc = IPMI_CC_OK; | 
 | 456 |     *data_len = 0; | 
 | 457 |  | 
| vishwa | 1eaea4f | 2016-02-26 11:57:40 -0600 | [diff] [blame] | 458 |     // Call Get properties method with the interface and property name | 
| Sergey Solomin | eb9b814 | 2016-08-23 09:07:28 -0500 | [diff] [blame] | 459 |     r = mapper_get_service(bus, objname, &busname); | 
| Patrick Venture | 0b02be9 | 2018-08-31 11:55:55 -0700 | [diff] [blame] | 460 |     if (r < 0) | 
 | 461 |     { | 
 | 462 |         log<level::ERR>("Failed to get bus name", entry("BUS=%s", objname), | 
| Aditya Saripalli | 5fb1460 | 2017-11-09 14:46:27 +0530 | [diff] [blame] | 463 |                         entry("ERRNO=0x%X", -r)); | 
| Sergey Solomin | eb9b814 | 2016-08-23 09:07:28 -0500 | [diff] [blame] | 464 |         goto finish; | 
 | 465 |     } | 
| Patrick Venture | 0b02be9 | 2018-08-31 11:55:55 -0700 | [diff] [blame] | 466 |     r = sd_bus_call_method(bus, busname, objname, iface, "Get", &error, &reply, | 
 | 467 |                            "ss", chassis_iface, "uuid"); | 
| vishwa | 1eaea4f | 2016-02-26 11:57:40 -0600 | [diff] [blame] | 468 |     if (r < 0) | 
 | 469 |     { | 
| Patrick Venture | 0b02be9 | 2018-08-31 11:55:55 -0700 | [diff] [blame] | 470 |         log<level::ERR>("Failed to call Get Method", entry("ERRNO=0x%X", -r)); | 
| vishwa | 1eaea4f | 2016-02-26 11:57:40 -0600 | [diff] [blame] | 471 |         rc = IPMI_CC_UNSPECIFIED_ERROR; | 
 | 472 |         goto finish; | 
 | 473 |     } | 
 | 474 |  | 
 | 475 |     r = sd_bus_message_read(reply, "v", "s", &uuid); | 
 | 476 |     if (r < 0 || uuid == NULL) | 
 | 477 |     { | 
| Patrick Venture | 0b02be9 | 2018-08-31 11:55:55 -0700 | [diff] [blame] | 478 |         log<level::ERR>("Failed to get a response", entry("ERRNO=0x%X", -r)); | 
| vishwa | 1eaea4f | 2016-02-26 11:57:40 -0600 | [diff] [blame] | 479 |         rc = IPMI_CC_RESPONSE_ERROR; | 
 | 480 |         goto finish; | 
 | 481 |     } | 
| Adriana Kobylak | d100ee5 | 2015-10-20 17:02:37 -0500 | [diff] [blame] | 482 |  | 
 | 483 |     // Traverse the UUID | 
| Patrick Venture | d211702 | 2018-02-06 08:54:37 -0800 | [diff] [blame] | 484 |     // Get the UUID octects separated by dash | 
 | 485 |     id_octet = strtok_r(uuid, "-", &tokptr); | 
| Adriana Kobylak | d100ee5 | 2015-10-20 17:02:37 -0500 | [diff] [blame] | 486 |  | 
 | 487 |     if (id_octet == NULL) | 
| vishwa | 1eaea4f | 2016-02-26 11:57:40 -0600 | [diff] [blame] | 488 |     { | 
 | 489 |         // Error | 
| Patrick Venture | 0b02be9 | 2018-08-31 11:55:55 -0700 | [diff] [blame] | 490 |         log<level::ERR>("Unexpected UUID format", entry("UUID=%s", uuid)); | 
| vishwa | 1eaea4f | 2016-02-26 11:57:40 -0600 | [diff] [blame] | 491 |         rc = IPMI_CC_RESPONSE_ERROR; | 
 | 492 |         goto finish; | 
| Adriana Kobylak | d100ee5 | 2015-10-20 17:02:37 -0500 | [diff] [blame] | 493 |     } | 
 | 494 |  | 
 | 495 |     while (id_octet != NULL) | 
 | 496 |     { | 
 | 497 |         // Calculate the octet string size since it varies | 
 | 498 |         // Divide it by 2 for the array size since 1 byte is built from 2 chars | 
| Patrick Venture | 0b02be9 | 2018-08-31 11:55:55 -0700 | [diff] [blame] | 499 |         int tmp_size = strlen(id_octet) / 2; | 
| Adriana Kobylak | d100ee5 | 2015-10-20 17:02:37 -0500 | [diff] [blame] | 500 |  | 
| Emily Shaffer | edb8bb0 | 2018-09-27 14:50:15 -0700 | [diff] [blame^] | 501 |         // Check if total UUID size has been exceeded | 
 | 502 |         if ((total_uuid_size += strlen(id_octet)) > max_uuid_size) | 
 | 503 |         { | 
 | 504 |             // Error - UUID too long to store | 
 | 505 |             log<level::ERR>("UUID too long", entry("UUID=%s", uuid)); | 
 | 506 |             rc = IPMI_CC_RESPONSE_ERROR; | 
 | 507 |             goto finish; | 
 | 508 |         } | 
 | 509 |  | 
| Patrick Venture | 0b02be9 | 2018-08-31 11:55:55 -0700 | [diff] [blame] | 510 |         for (i = 0; i < tmp_size; i++) | 
| Adriana Kobylak | d100ee5 | 2015-10-20 17:02:37 -0500 | [diff] [blame] | 511 |         { | 
| Patrick Venture | d211702 | 2018-02-06 08:54:37 -0800 | [diff] [blame] | 512 |             // Holder of the 2 chars that will become a byte | 
 | 513 |             char tmp_array[3] = {0}; | 
| Adriana Kobylak | d100ee5 | 2015-10-20 17:02:37 -0500 | [diff] [blame] | 514 |             strncpy(tmp_array, id_octet, 2); // 2 chars at a time | 
 | 515 |  | 
 | 516 |             int resp_byte = strtoul(tmp_array, NULL, 16); // Convert to hex byte | 
| Patrick Venture | d211702 | 2018-02-06 08:54:37 -0800 | [diff] [blame] | 517 |             // Copy end to first | 
| Patrick Venture | b51bf9c | 2018-09-10 15:53:14 -0700 | [diff] [blame] | 518 |             std::memcpy((void*)&resp_uuid[resp_loc], &resp_byte, 1); | 
| Adriana Kobylak | d100ee5 | 2015-10-20 17:02:37 -0500 | [diff] [blame] | 519 |             resp_loc--; | 
| Patrick Venture | 0b02be9 | 2018-08-31 11:55:55 -0700 | [diff] [blame] | 520 |             id_octet += 2; // Finished with the 2 chars, advance | 
| Adriana Kobylak | d100ee5 | 2015-10-20 17:02:37 -0500 | [diff] [blame] | 521 |         } | 
| Patrick Venture | 0b02be9 | 2018-08-31 11:55:55 -0700 | [diff] [blame] | 522 |         id_octet = strtok_r(NULL, "-", &tokptr); // Get next octet | 
| Adriana Kobylak | d100ee5 | 2015-10-20 17:02:37 -0500 | [diff] [blame] | 523 |     } | 
 | 524 |  | 
 | 525 |     // Data length | 
 | 526 |     *data_len = resp_size; | 
 | 527 |  | 
 | 528 |     // Pack the actual response | 
| Patrick Venture | b51bf9c | 2018-09-10 15:53:14 -0700 | [diff] [blame] | 529 |     std::memcpy(response, &resp_uuid, *data_len); | 
| Adriana Kobylak | d100ee5 | 2015-10-20 17:02:37 -0500 | [diff] [blame] | 530 |  | 
| vishwa | 1eaea4f | 2016-02-26 11:57:40 -0600 | [diff] [blame] | 531 | finish: | 
| Adriana Kobylak | d100ee5 | 2015-10-20 17:02:37 -0500 | [diff] [blame] | 532 |     sd_bus_error_free(&error); | 
| vishwa | 1eaea4f | 2016-02-26 11:57:40 -0600 | [diff] [blame] | 533 |     reply = sd_bus_message_unref(reply); | 
| Sergey Solomin | eb9b814 | 2016-08-23 09:07:28 -0500 | [diff] [blame] | 534 |     free(busname); | 
| Adriana Kobylak | d100ee5 | 2015-10-20 17:02:37 -0500 | [diff] [blame] | 535 |  | 
 | 536 |     return rc; | 
 | 537 | } | 
| Chris Austen | 6caf28b | 2015-10-13 12:40:40 -0500 | [diff] [blame] | 538 |  | 
| Adriana Kobylak | 3a552e1 | 2015-10-19 16:11:00 -0500 | [diff] [blame] | 539 | ipmi_ret_t ipmi_app_get_bt_capabilities(ipmi_netfn_t netfn, ipmi_cmd_t cmd, | 
| Patrick Venture | 0b02be9 | 2018-08-31 11:55:55 -0700 | [diff] [blame] | 540 |                                         ipmi_request_t request, | 
 | 541 |                                         ipmi_response_t response, | 
 | 542 |                                         ipmi_data_len_t data_len, | 
 | 543 |                                         ipmi_context_t context) | 
| vishwabmc | ba0bd5f | 2015-09-30 16:50:23 +0530 | [diff] [blame] | 544 | { | 
| vishwabmc | ba0bd5f | 2015-09-30 16:50:23 +0530 | [diff] [blame] | 545 |  | 
 | 546 |     // Status code. | 
 | 547 |     ipmi_ret_t rc = IPMI_CC_OK; | 
 | 548 |  | 
| Adriana Kobylak | 88ad815 | 2016-12-13 10:09:08 -0600 | [diff] [blame] | 549 |     // Per IPMI 2.0 spec, the input and output buffer size must be the max | 
 | 550 |     // buffer size minus one byte to allocate space for the length byte. | 
| Patrick Venture | 0b02be9 | 2018-08-31 11:55:55 -0700 | [diff] [blame] | 551 |     uint8_t str[] = {0x01, MAX_IPMI_BUFFER - 1, MAX_IPMI_BUFFER - 1, 0x0A, | 
 | 552 |                      0x01}; | 
| vishwabmc | ba0bd5f | 2015-09-30 16:50:23 +0530 | [diff] [blame] | 553 |  | 
 | 554 |     // Data length | 
 | 555 |     *data_len = sizeof(str); | 
 | 556 |  | 
 | 557 |     // Pack the actual response | 
| Patrick Venture | b51bf9c | 2018-09-10 15:53:14 -0700 | [diff] [blame] | 558 |     std::memcpy(response, &str, *data_len); | 
| vishwabmc | ba0bd5f | 2015-09-30 16:50:23 +0530 | [diff] [blame] | 559 |  | 
 | 560 |     return rc; | 
 | 561 | } | 
 | 562 |  | 
| Adriana Kobylak | 3a552e1 | 2015-10-19 16:11:00 -0500 | [diff] [blame] | 563 | ipmi_ret_t ipmi_app_wildcard_handler(ipmi_netfn_t netfn, ipmi_cmd_t cmd, | 
| Patrick Venture | 0b02be9 | 2018-08-31 11:55:55 -0700 | [diff] [blame] | 564 |                                      ipmi_request_t request, | 
 | 565 |                                      ipmi_response_t response, | 
 | 566 |                                      ipmi_data_len_t data_len, | 
 | 567 |                                      ipmi_context_t context) | 
| vishwabmc | ba0bd5f | 2015-09-30 16:50:23 +0530 | [diff] [blame] | 568 | { | 
| vishwabmc | ba0bd5f | 2015-09-30 16:50:23 +0530 | [diff] [blame] | 569 |     // Status code. | 
| Nan Li | 70aa8d9 | 2016-08-29 00:11:10 +0800 | [diff] [blame] | 570 |     ipmi_ret_t rc = IPMI_CC_INVALID; | 
| vishwabmc | ba0bd5f | 2015-09-30 16:50:23 +0530 | [diff] [blame] | 571 |  | 
 | 572 |     *data_len = strlen("THIS IS WILDCARD"); | 
 | 573 |  | 
 | 574 |     // Now pack actual response | 
| Patrick Venture | b51bf9c | 2018-09-10 15:53:14 -0700 | [diff] [blame] | 575 |     std::memcpy(response, "THIS IS WILDCARD", *data_len); | 
| vishwabmc | ba0bd5f | 2015-09-30 16:50:23 +0530 | [diff] [blame] | 576 |  | 
 | 577 |     return rc; | 
 | 578 | } | 
 | 579 |  | 
| Marri Devender Rao | 5e007a5 | 2018-01-08 06:18:36 -0600 | [diff] [blame] | 580 | ipmi_ret_t ipmi_app_get_sys_guid(ipmi_netfn_t netfn, ipmi_cmd_t cmd, | 
| Patrick Venture | 0b02be9 | 2018-08-31 11:55:55 -0700 | [diff] [blame] | 581 |                                  ipmi_request_t request, | 
 | 582 |                                  ipmi_response_t response, | 
 | 583 |                                  ipmi_data_len_t data_len, | 
 | 584 |                                  ipmi_context_t context) | 
| Marri Devender Rao | 5e007a5 | 2018-01-08 06:18:36 -0600 | [diff] [blame] | 585 |  | 
 | 586 | { | 
 | 587 |     ipmi_ret_t rc = IPMI_CC_OK; | 
 | 588 |     sdbusplus::bus::bus bus{ipmid_get_sd_bus_connection()}; | 
 | 589 |  | 
 | 590 |     try | 
 | 591 |     { | 
 | 592 |         // Get the Inventory object implementing BMC interface | 
 | 593 |         ipmi::DbusObjectInfo bmcObject = | 
 | 594 |             ipmi::getDbusObject(bus, bmc_interface); | 
 | 595 |  | 
 | 596 |         // Read UUID property value from bmcObject | 
 | 597 |         // UUID is in RFC4122 format Ex: 61a39523-78f2-11e5-9862-e6402cfc3223 | 
| Patrick Venture | 0b02be9 | 2018-08-31 11:55:55 -0700 | [diff] [blame] | 598 |         auto variant = | 
 | 599 |             ipmi::getDbusProperty(bus, bmcObject.second, bmcObject.first, | 
 | 600 |                                   bmc_guid_interface, bmc_guid_property); | 
| Marri Devender Rao | 5e007a5 | 2018-01-08 06:18:36 -0600 | [diff] [blame] | 601 |         std::string guidProp = variant.get<std::string>(); | 
 | 602 |  | 
 | 603 |         // Erase "-" characters from the property value | 
 | 604 |         guidProp.erase(std::remove(guidProp.begin(), guidProp.end(), '-'), | 
| Patrick Venture | 0b02be9 | 2018-08-31 11:55:55 -0700 | [diff] [blame] | 605 |                        guidProp.end()); | 
| Marri Devender Rao | 5e007a5 | 2018-01-08 06:18:36 -0600 | [diff] [blame] | 606 |  | 
 | 607 |         auto guidPropLen = guidProp.length(); | 
 | 608 |         // Validate UUID data | 
 | 609 |         // Divide by 2 as 1 byte is built from 2 chars | 
| Patrick Venture | 0b02be9 | 2018-08-31 11:55:55 -0700 | [diff] [blame] | 610 |         if ((guidPropLen <= 0) || ((guidPropLen / 2) != bmc_guid_len)) | 
| Marri Devender Rao | 5e007a5 | 2018-01-08 06:18:36 -0600 | [diff] [blame] | 611 |  | 
 | 612 |         { | 
 | 613 |             log<level::ERR>("Invalid UUID property value", | 
| Patrick Venture | 0b02be9 | 2018-08-31 11:55:55 -0700 | [diff] [blame] | 614 |                             entry("UUID_LENGTH=%d", guidPropLen)); | 
| Marri Devender Rao | 5e007a5 | 2018-01-08 06:18:36 -0600 | [diff] [blame] | 615 |             return IPMI_CC_RESPONSE_ERROR; | 
 | 616 |         } | 
 | 617 |  | 
 | 618 |         // Convert data in RFC4122(MSB) format to LSB format | 
 | 619 |         // Get 2 characters at a time as 1 byte is built from 2 chars and | 
 | 620 |         // convert to hex byte | 
 | 621 |         // TODO: Data printed for GUID command is not as per the | 
 | 622 |         // GUID format defined in IPMI specification 2.0 section 20.8 | 
 | 623 |         // Ticket raised: https://sourceforge.net/p/ipmitool/bugs/501/ | 
 | 624 |         uint8_t respGuid[bmc_guid_len]; | 
 | 625 |         for (size_t i = 0, respLoc = (bmc_guid_len - 1); | 
| Patrick Venture | 0b02be9 | 2018-08-31 11:55:55 -0700 | [diff] [blame] | 626 |              i < guidPropLen && respLoc >= 0; i += 2, respLoc--) | 
| Marri Devender Rao | 5e007a5 | 2018-01-08 06:18:36 -0600 | [diff] [blame] | 627 |         { | 
 | 628 |             auto value = static_cast<uint8_t>( | 
| Patrick Venture | 0b02be9 | 2018-08-31 11:55:55 -0700 | [diff] [blame] | 629 |                 std::stoi(guidProp.substr(i, 2).c_str(), NULL, 16)); | 
| Marri Devender Rao | 5e007a5 | 2018-01-08 06:18:36 -0600 | [diff] [blame] | 630 |             respGuid[respLoc] = value; | 
 | 631 |         } | 
 | 632 |  | 
 | 633 |         *data_len = bmc_guid_len; | 
| Patrick Venture | b51bf9c | 2018-09-10 15:53:14 -0700 | [diff] [blame] | 634 |         std::memcpy(response, &respGuid, bmc_guid_len); | 
| Marri Devender Rao | 5e007a5 | 2018-01-08 06:18:36 -0600 | [diff] [blame] | 635 |     } | 
 | 636 |     catch (const InternalFailure& e) | 
 | 637 |     { | 
 | 638 |         log<level::ERR>("Failed in reading BMC UUID property", | 
 | 639 |                         entry("INTERFACE=%s", bmc_interface), | 
 | 640 |                         entry("PROPERTY_INTERFACE=%s", bmc_guid_interface), | 
 | 641 |                         entry("PROPERTY=%s", bmc_guid_property)); | 
 | 642 |         return IPMI_CC_UNSPECIFIED_ERROR; | 
 | 643 |     } | 
 | 644 |     return rc; | 
 | 645 | } | 
 | 646 |  | 
| Xo Wang | f542e8b | 2017-08-09 15:34:16 -0700 | [diff] [blame] | 647 | static std::unique_ptr<SysInfoParamStore> sysInfoParamStore; | 
 | 648 |  | 
| Xo Wang | 8765133 | 2017-08-11 10:17:59 -0700 | [diff] [blame] | 649 | static std::string sysInfoReadSystemName() | 
 | 650 | { | 
 | 651 |     // Use the BMC hostname as the "System Name." | 
 | 652 |     char hostname[HOST_NAME_MAX + 1] = {}; | 
 | 653 |     if (gethostname(hostname, HOST_NAME_MAX) != 0) | 
 | 654 |     { | 
 | 655 |         perror("System info parameter: system name"); | 
 | 656 |     } | 
 | 657 |     return hostname; | 
 | 658 | } | 
 | 659 |  | 
| Xo Wang | f542e8b | 2017-08-09 15:34:16 -0700 | [diff] [blame] | 660 | struct IpmiSysInfoResp | 
 | 661 | { | 
 | 662 |     uint8_t paramRevision; | 
 | 663 |     uint8_t setSelector; | 
 | 664 |     union | 
 | 665 |     { | 
 | 666 |         struct | 
 | 667 |         { | 
 | 668 |             uint8_t encoding; | 
 | 669 |             uint8_t stringLen; | 
 | 670 |             uint8_t stringData0[14]; | 
 | 671 |         } __attribute__((packed)); | 
 | 672 |         uint8_t stringDataN[16]; | 
 | 673 |         uint8_t byteData; | 
 | 674 |     }; | 
 | 675 | } __attribute__((packed)); | 
 | 676 |  | 
 | 677 | /** | 
 | 678 |  * Split a string into (up to) 16-byte chunks as expected in response for get | 
 | 679 |  * system info parameter. | 
 | 680 |  * | 
 | 681 |  * @param[in] fullString: Input string to be split | 
 | 682 |  * @param[in] chunkIndex: Index of the chunk to be written out | 
 | 683 |  * @param[in,out] chunk: Output data buffer; must have 14 byte capacity if | 
 | 684 |  *          chunk_index = 0 and 16-byte capacity otherwise | 
 | 685 |  * @return the number of bytes written into the output buffer, or -EINVAL for | 
 | 686 |  * invalid arguments. | 
 | 687 |  */ | 
 | 688 | static int splitStringParam(const std::string& fullString, int chunkIndex, | 
 | 689 |                             uint8_t* chunk) | 
 | 690 | { | 
 | 691 |     constexpr int maxChunk = 255; | 
 | 692 |     constexpr int smallChunk = 14; | 
 | 693 |     constexpr int chunkSize = 16; | 
 | 694 |     if (chunkIndex > maxChunk || chunk == nullptr) | 
 | 695 |     { | 
 | 696 |         return -EINVAL; | 
 | 697 |     } | 
 | 698 |     try | 
 | 699 |     { | 
 | 700 |         std::string output; | 
 | 701 |         if (chunkIndex == 0) | 
 | 702 |         { | 
 | 703 |             // Output must have 14 byte capacity. | 
 | 704 |             output = fullString.substr(0, smallChunk); | 
 | 705 |         } | 
 | 706 |         else | 
 | 707 |         { | 
 | 708 |             // Output must have 16 byte capacity. | 
 | 709 |             output = fullString.substr((chunkIndex * chunkSize) - 2, chunkSize); | 
 | 710 |         } | 
 | 711 |  | 
 | 712 |         std::memcpy(chunk, output.c_str(), output.length()); | 
 | 713 |         return output.length(); | 
 | 714 |     } | 
 | 715 |     catch (const std::out_of_range& e) | 
 | 716 |     { | 
 | 717 |         // The position was beyond the end. | 
 | 718 |         return -EINVAL; | 
 | 719 |     } | 
 | 720 | } | 
 | 721 |  | 
 | 722 | /** | 
 | 723 |  * Packs the Get Sys Info Request Item into the response. | 
 | 724 |  * | 
 | 725 |  * @param[in] paramString - the parameter. | 
 | 726 |  * @param[in] setSelector - the selector | 
 | 727 |  * @param[in,out] resp - the System info response. | 
 | 728 |  * @return The number of bytes packed or failure from splitStringParam(). | 
 | 729 |  */ | 
 | 730 | static int packGetSysInfoResp(const std::string& paramString, | 
 | 731 |                               uint8_t setSelector, IpmiSysInfoResp* resp) | 
 | 732 | { | 
 | 733 |     uint8_t* dataBuffer = resp->stringDataN; | 
 | 734 |     resp->setSelector = setSelector; | 
 | 735 |     if (resp->setSelector == 0) // First chunk has only 14 bytes. | 
 | 736 |     { | 
 | 737 |         resp->encoding = 0; | 
 | 738 |         resp->stringLen = paramString.length(); | 
 | 739 |         dataBuffer = resp->stringData0; | 
 | 740 |     } | 
 | 741 |     return splitStringParam(paramString, resp->setSelector, dataBuffer); | 
 | 742 | } | 
 | 743 |  | 
 | 744 | ipmi_ret_t ipmi_app_get_system_info(ipmi_netfn_t netfn, ipmi_cmd_t cmd, | 
 | 745 |                                     ipmi_request_t request, | 
 | 746 |                                     ipmi_response_t response, | 
 | 747 |                                     ipmi_data_len_t dataLen, | 
 | 748 |                                     ipmi_context_t context) | 
 | 749 | { | 
 | 750 |     IpmiSysInfoResp resp = {}; | 
 | 751 |     size_t respLen = 0; | 
 | 752 |     uint8_t* const reqData = static_cast<uint8_t*>(request); | 
 | 753 |     std::string paramString; | 
 | 754 |     bool found; | 
 | 755 |     std::tuple<bool, std::string> ret; | 
 | 756 |     constexpr int minRequestSize = 4; | 
 | 757 |     constexpr int paramSelector = 1; | 
 | 758 |     constexpr uint8_t revisionOnly = 0x80; | 
 | 759 |     const uint8_t paramRequested = reqData[paramSelector]; | 
 | 760 |     int rc; | 
 | 761 |  | 
 | 762 |     if (*dataLen < minRequestSize) | 
 | 763 |     { | 
 | 764 |         return IPMI_CC_REQ_DATA_LEN_INVALID; | 
 | 765 |     } | 
 | 766 |  | 
 | 767 |     *dataLen = 0; // default to 0. | 
 | 768 |  | 
 | 769 |     // Parameters revision as of IPMI spec v2.0 rev. 1.1 (Feb 11, 2014 E6) | 
 | 770 |     resp.paramRevision = 0x11; | 
 | 771 |     if (reqData[0] & revisionOnly) // Get parameter revision only | 
 | 772 |     { | 
 | 773 |         respLen = 1; | 
 | 774 |         goto writeResponse; | 
 | 775 |     } | 
 | 776 |  | 
 | 777 |     // The "Set In Progress" parameter can be used for rollback of parameter | 
 | 778 |     // data and is not implemented. | 
 | 779 |     if (paramRequested == 0) | 
 | 780 |     { | 
 | 781 |         resp.byteData = 0; | 
 | 782 |         respLen = 2; | 
 | 783 |         goto writeResponse; | 
 | 784 |     } | 
 | 785 |  | 
 | 786 |     if (sysInfoParamStore == nullptr) | 
 | 787 |     { | 
 | 788 |         sysInfoParamStore = std::make_unique<SysInfoParamStore>(); | 
| Xo Wang | 8765133 | 2017-08-11 10:17:59 -0700 | [diff] [blame] | 789 |         sysInfoParamStore->update(IPMI_SYSINFO_SYSTEM_NAME, | 
 | 790 |                                   sysInfoReadSystemName); | 
| Xo Wang | f542e8b | 2017-08-09 15:34:16 -0700 | [diff] [blame] | 791 |     } | 
 | 792 |  | 
 | 793 |     // Parameters other than Set In Progress are assumed to be strings. | 
 | 794 |     ret = sysInfoParamStore->lookup(paramRequested); | 
 | 795 |     found = std::get<0>(ret); | 
 | 796 |     paramString = std::get<1>(ret); | 
 | 797 |     if (!found) | 
 | 798 |     { | 
 | 799 |         return IPMI_CC_SYSTEM_INFO_PARAMETER_NOT_SUPPORTED; | 
 | 800 |     } | 
 | 801 |     // TODO: Cache each parameter across multiple calls, until the whole string | 
 | 802 |     // has been read out. Otherwise, it's possible for a parameter to change | 
 | 803 |     // between requests for its chunks, returning chunks incoherent with each | 
 | 804 |     // other. For now, the parameter store is simply required to have only | 
 | 805 |     // idempotent callbacks. | 
 | 806 |     rc = packGetSysInfoResp(paramString, reqData[2], &resp); | 
 | 807 |     if (rc == -EINVAL) | 
 | 808 |     { | 
 | 809 |         return IPMI_CC_RESPONSE_ERROR; | 
 | 810 |     } | 
 | 811 |  | 
 | 812 |     respLen = sizeof(resp); // Write entire string data chunk in response. | 
 | 813 |  | 
 | 814 | writeResponse: | 
 | 815 |     std::memcpy(response, &resp, sizeof(resp)); | 
 | 816 |     *dataLen = respLen; | 
 | 817 |     return IPMI_CC_OK; | 
 | 818 | } | 
 | 819 |  | 
| Chris Austen | 6caf28b | 2015-10-13 12:40:40 -0500 | [diff] [blame] | 820 | void register_netfn_app_functions() | 
| vishwabmc | ba0bd5f | 2015-09-30 16:50:23 +0530 | [diff] [blame] | 821 | { | 
| Tom | 0573237 | 2016-09-06 17:21:23 +0530 | [diff] [blame] | 822 |     // <Get BT Interface Capabilities> | 
| Patrick Venture | 0b02be9 | 2018-08-31 11:55:55 -0700 | [diff] [blame] | 823 |     ipmi_register_callback(NETFUN_APP, IPMI_CMD_GET_CAP_BIT, NULL, | 
 | 824 |                            ipmi_app_get_bt_capabilities, PRIVILEGE_USER); | 
| Chris Austen | 6caf28b | 2015-10-13 12:40:40 -0500 | [diff] [blame] | 825 |  | 
| Tom | 0573237 | 2016-09-06 17:21:23 +0530 | [diff] [blame] | 826 |     // <Wildcard Command> | 
| Patrick Venture | 0b02be9 | 2018-08-31 11:55:55 -0700 | [diff] [blame] | 827 |     ipmi_register_callback(NETFUN_APP, IPMI_CMD_WILDCARD, NULL, | 
 | 828 |                            ipmi_app_wildcard_handler, PRIVILEGE_USER); | 
| Chris Austen | 6caf28b | 2015-10-13 12:40:40 -0500 | [diff] [blame] | 829 |  | 
| Tom | 0573237 | 2016-09-06 17:21:23 +0530 | [diff] [blame] | 830 |     // <Reset Watchdog Timer> | 
| Patrick Venture | 0b02be9 | 2018-08-31 11:55:55 -0700 | [diff] [blame] | 831 |     ipmi_register_callback(NETFUN_APP, IPMI_CMD_RESET_WD, NULL, | 
 | 832 |                            ipmi_app_watchdog_reset, PRIVILEGE_OPERATOR); | 
| Chris Austen | 6caf28b | 2015-10-13 12:40:40 -0500 | [diff] [blame] | 833 |  | 
| Tom | 0573237 | 2016-09-06 17:21:23 +0530 | [diff] [blame] | 834 |     // <Set Watchdog Timer> | 
| Patrick Venture | 0b02be9 | 2018-08-31 11:55:55 -0700 | [diff] [blame] | 835 |     ipmi_register_callback(NETFUN_APP, IPMI_CMD_SET_WD, NULL, | 
 | 836 |                            ipmi_app_watchdog_set, PRIVILEGE_OPERATOR); | 
| Chris Austen | 6caf28b | 2015-10-13 12:40:40 -0500 | [diff] [blame] | 837 |  | 
| William A. Kennington III | 73f4451 | 2018-02-09 15:28:46 -0800 | [diff] [blame] | 838 |     // <Get Watchdog Timer> | 
| Patrick Venture | 0b02be9 | 2018-08-31 11:55:55 -0700 | [diff] [blame] | 839 |     ipmi_register_callback(NETFUN_APP, IPMI_CMD_GET_WD, NULL, | 
 | 840 |                            ipmi_app_watchdog_get, PRIVILEGE_OPERATOR); | 
| William A. Kennington III | 73f4451 | 2018-02-09 15:28:46 -0800 | [diff] [blame] | 841 |  | 
| Tom | 0573237 | 2016-09-06 17:21:23 +0530 | [diff] [blame] | 842 |     // <Get Device ID> | 
| Patrick Venture | 0b02be9 | 2018-08-31 11:55:55 -0700 | [diff] [blame] | 843 |     ipmi_register_callback(NETFUN_APP, IPMI_CMD_GET_DEVICE_ID, NULL, | 
 | 844 |                            ipmi_app_get_device_id, PRIVILEGE_USER); | 
| Chris Austen | 6caf28b | 2015-10-13 12:40:40 -0500 | [diff] [blame] | 845 |  | 
| Tom | 0573237 | 2016-09-06 17:21:23 +0530 | [diff] [blame] | 846 |     // <Get Self Test Results> | 
| Patrick Venture | 0b02be9 | 2018-08-31 11:55:55 -0700 | [diff] [blame] | 847 |     ipmi_register_callback(NETFUN_APP, IPMI_CMD_GET_SELF_TEST_RESULTS, NULL, | 
 | 848 |                            ipmi_app_get_self_test_results, PRIVILEGE_USER); | 
| Nan Li | 41fa24a | 2016-11-10 20:12:37 +0800 | [diff] [blame] | 849 |  | 
| Tom | 0573237 | 2016-09-06 17:21:23 +0530 | [diff] [blame] | 850 |     // <Get Device GUID> | 
| Patrick Venture | 0b02be9 | 2018-08-31 11:55:55 -0700 | [diff] [blame] | 851 |     ipmi_register_callback(NETFUN_APP, IPMI_CMD_GET_DEVICE_GUID, NULL, | 
 | 852 |                            ipmi_app_get_device_guid, PRIVILEGE_USER); | 
| Adriana Kobylak | d100ee5 | 2015-10-20 17:02:37 -0500 | [diff] [blame] | 853 |  | 
| Tom | 0573237 | 2016-09-06 17:21:23 +0530 | [diff] [blame] | 854 |     // <Set ACPI Power State> | 
| Patrick Venture | 0b02be9 | 2018-08-31 11:55:55 -0700 | [diff] [blame] | 855 |     ipmi_register_callback(NETFUN_APP, IPMI_CMD_SET_ACPI, NULL, | 
 | 856 |                            ipmi_app_set_acpi_power_state, PRIVILEGE_ADMIN); | 
| Chris Austen | 6caf28b | 2015-10-13 12:40:40 -0500 | [diff] [blame] | 857 |  | 
| Tom Joseph | 69fabfe | 2017-08-04 10:15:01 +0530 | [diff] [blame] | 858 |     // <Get Channel Access> | 
| Patrick Venture | 0b02be9 | 2018-08-31 11:55:55 -0700 | [diff] [blame] | 859 |     ipmi_register_callback(NETFUN_APP, IPMI_CMD_GET_CHANNEL_ACCESS, NULL, | 
 | 860 |                            ipmi_get_channel_access, PRIVILEGE_USER); | 
| Tom Joseph | 69fabfe | 2017-08-04 10:15:01 +0530 | [diff] [blame] | 861 |  | 
| Tom | 0573237 | 2016-09-06 17:21:23 +0530 | [diff] [blame] | 862 |     // <Get Channel Info Command> | 
| Patrick Venture | 0b02be9 | 2018-08-31 11:55:55 -0700 | [diff] [blame] | 863 |     ipmi_register_callback(NETFUN_APP, IPMI_CMD_GET_CHAN_INFO, NULL, | 
 | 864 |                            ipmi_app_channel_info, PRIVILEGE_USER); | 
| Chris Austen | c2cd29d | 2016-02-05 20:02:29 -0600 | [diff] [blame] | 865 |  | 
| Marri Devender Rao | 5e007a5 | 2018-01-08 06:18:36 -0600 | [diff] [blame] | 866 |     // <Get System GUID Command> | 
| Patrick Venture | 0b02be9 | 2018-08-31 11:55:55 -0700 | [diff] [blame] | 867 |     ipmi_register_callback(NETFUN_APP, IPMI_CMD_GET_SYS_GUID, NULL, | 
 | 868 |                            ipmi_app_get_sys_guid, PRIVILEGE_USER); | 
| Tom Joseph | 7cbe228 | 2018-03-21 21:17:33 +0530 | [diff] [blame] | 869 |  | 
 | 870 |     // <Get Channel Cipher Suites Command> | 
| Patrick Venture | 0b02be9 | 2018-08-31 11:55:55 -0700 | [diff] [blame] | 871 |     ipmi_register_callback(NETFUN_APP, IPMI_CMD_GET_CHAN_CIPHER_SUITES, NULL, | 
 | 872 |                            getChannelCipherSuites, PRIVILEGE_CALLBACK); | 
| Tom Joseph | 1322768 | 2018-08-10 01:05:21 +0530 | [diff] [blame] | 873 |  | 
 | 874 |     // <Set Channel Access Command> | 
 | 875 |     ipmi_register_callback(NETFUN_APP, IPMI_CMD_SET_CHAN_ACCESS, NULL, | 
 | 876 |                            ipmi_set_channel_access, PRIVILEGE_ADMIN); | 
| Xo Wang | f542e8b | 2017-08-09 15:34:16 -0700 | [diff] [blame] | 877 |  | 
 | 878 |     // <Get System Info Command> | 
 | 879 |     ipmi_register_callback(NETFUN_APP, IPMI_CMD_GET_SYSTEM_INFO, NULL, | 
 | 880 |                            ipmi_app_get_system_info, PRIVILEGE_USER); | 
| vishwabmc | ba0bd5f | 2015-09-30 16:50:23 +0530 | [diff] [blame] | 881 |     return; | 
 | 882 | } |