summaryrefslogtreecommitdiffstats
path: root/apphandler.cpp
diff options
context:
space:
mode:
authorVernon Mauery <vernon.mauery@linux.intel.com>2019-03-25 13:33:03 -0700
committerVernon Mauery <vernon.mauery@linux.intel.com>2019-05-20 17:27:51 +0000
commit1554132bc08cf7b22777ae83c3ebd23997a61496 (patch)
treed3a4dce7977deda17ff4d1b6dfb2eee21b7a65fa /apphandler.cpp
parent572bac1735aef5587b72a26d760d875908919352 (diff)
downloadphosphor-host-ipmid-1554132bc08cf7b22777ae83c3ebd23997a61496.tar.gz
phosphor-host-ipmid-1554132bc08cf7b22777ae83c3ebd23997a61496.zip
rewrite Get Device GUID to use new provider API
Modify to use the new provider API. One by one, change calls to remove any legacy API constructs. Tested-by: ipmitool 6 8 30 ba 05 cd 7e 9d ac 89 4a 4c 52 ef f3 24 2d 5f (with matching change from bmcweb:) curl https://<bmcip>/redfish/v1/Managers/bmc ... "UUID": "5f2d24f3-ef52-4c4a-89ac-9d7ecd05ba30" Change-Id: I4cd3b945f76b4fe6c4fcf31d8e1962aaa768828e Signed-off-by: Vernon Mauery <vernon.mauery@linux.intel.com>
Diffstat (limited to 'apphandler.cpp')
-rw-r--r--apphandler.cpp150
1 files changed, 53 insertions, 97 deletions
diff --git a/apphandler.cpp b/apphandler.cpp
index 91bede5..ea40060 100644
--- a/apphandler.cpp
+++ b/apphandler.cpp
@@ -700,120 +700,75 @@ auto ipmiAppGetSelfTestResults() -> ipmi::RspType<uint8_t, uint8_t>
return ipmi::responseSuccess(notImplemented, zero);
}
-ipmi_ret_t ipmi_app_get_device_guid(ipmi_netfn_t netfn, ipmi_cmd_t cmd,
- ipmi_request_t request,
- ipmi_response_t response,
- ipmi_data_len_t data_len,
- ipmi_context_t context)
+static constexpr size_t uuidBinaryLength = 16;
+static std::array<uint8_t, uuidBinaryLength> rfc4122ToIpmi(std::string rfc4122)
{
- const char* objname = "/org/openbmc/control/chassis0";
- const char* iface = "org.freedesktop.DBus.Properties";
- const char* chassis_iface = "org.openbmc.control.Chassis";
- sd_bus_message* reply = NULL;
- sd_bus_error error = SD_BUS_ERROR_NULL;
- int r = 0;
- char* uuid = NULL;
- char* busname = NULL;
-
+ using Argument = xyz::openbmc_project::Common::InvalidArgument;
// UUID is in RFC4122 format. Ex: 61a39523-78f2-11e5-9862-e6402cfc3223
// Per IPMI Spec 2.0 need to convert to 16 hex bytes and reverse the byte
// order
// Ex: 0x2332fc2c40e66298e511f2782395a361
-
- const int resp_size = 16; // Response is 16 hex bytes per IPMI Spec
- uint8_t resp_uuid[resp_size]; // Array to hold the formatted response
- // Point resp end of array to save in reverse order
- int resp_loc = resp_size - 1;
- int i = 0;
- char* tokptr = NULL;
- char* id_octet = NULL;
- size_t total_uuid_size = 0;
- // 1 byte of resp is built from 2 chars of uuid.
- constexpr size_t max_uuid_size = 2 * resp_size;
-
- // Status code.
- ipmi_ret_t rc = IPMI_CC_OK;
- *data_len = 0;
-
- // Call Get properties method with the interface and property name
- r = mapper_get_service(bus, objname, &busname);
- if (r < 0)
- {
- log<level::ERR>("Failed to get bus name", entry("BUS=%s", objname),
- entry("ERRNO=0x%X", -r));
- goto finish;
- }
- r = sd_bus_call_method(bus, busname, objname, iface, "Get", &error, &reply,
- "ss", chassis_iface, "uuid");
- if (r < 0)
- {
- log<level::ERR>("Failed to call Get Method", entry("ERRNO=0x%X", -r));
- rc = IPMI_CC_UNSPECIFIED_ERROR;
- goto finish;
- }
-
- r = sd_bus_message_read(reply, "v", "s", &uuid);
- if (r < 0 || uuid == NULL)
+ constexpr size_t uuidHexLength = (2 * uuidBinaryLength);
+ constexpr size_t uuidRfc4122Length = (uuidHexLength + 4);
+ std::array<uint8_t, uuidBinaryLength> uuid;
+ if (rfc4122.size() == uuidRfc4122Length)
{
- log<level::ERR>("Failed to get a response", entry("ERRNO=0x%X", -r));
- rc = IPMI_CC_RESPONSE_ERROR;
- goto finish;
+ rfc4122.erase(std::remove(rfc4122.begin(), rfc4122.end(), '-'),
+ rfc4122.end());
}
-
- // Traverse the UUID
- // Get the UUID octects separated by dash
- id_octet = strtok_r(uuid, "-", &tokptr);
-
- if (id_octet == NULL)
+ if (rfc4122.size() != uuidHexLength)
{
- // Error
- log<level::ERR>("Unexpected UUID format", entry("UUID=%s", uuid));
- rc = IPMI_CC_RESPONSE_ERROR;
- goto finish;
+ elog<InvalidArgument>(Argument::ARGUMENT_NAME("rfc4122"),
+ Argument::ARGUMENT_VALUE(rfc4122.c_str()));
}
-
- while (id_octet != NULL)
+ for (size_t ind = 0; ind < uuidHexLength; ind += 2)
{
- // Calculate the octet string size since it varies
- // Divide it by 2 for the array size since 1 byte is built from 2 chars
- int tmp_size = strlen(id_octet) / 2;
-
- // Check if total UUID size has been exceeded
- if ((total_uuid_size += strlen(id_octet)) > max_uuid_size)
+ char v[3];
+ v[0] = rfc4122[ind];
+ v[1] = rfc4122[ind + 1];
+ v[2] = 0;
+ size_t err;
+ long b;
+ try
{
- // Error - UUID too long to store
- log<level::ERR>("UUID too long", entry("UUID=%s", uuid));
- rc = IPMI_CC_RESPONSE_ERROR;
- goto finish;
+ b = std::stoul(v, &err, 16);
}
-
- for (i = 0; i < tmp_size; i++)
+ catch (std::exception& e)
{
- // Holder of the 2 chars that will become a byte
- char tmp_array[3] = {0};
- strncpy(tmp_array, id_octet, 2); // 2 chars at a time
-
- int resp_byte = strtoul(tmp_array, NULL, 16); // Convert to hex byte
- // Copy end to first
- std::memcpy((void*)&resp_uuid[resp_loc], &resp_byte, 1);
- resp_loc--;
- id_octet += 2; // Finished with the 2 chars, advance
+ elog<InvalidArgument>(Argument::ARGUMENT_NAME("rfc4122"),
+ Argument::ARGUMENT_VALUE(rfc4122.c_str()));
}
- id_octet = strtok_r(NULL, "-", &tokptr); // Get next octet
+ // check that exactly two ascii bytes were converted
+ if (err != 2)
+ {
+ elog<InvalidArgument>(Argument::ARGUMENT_NAME("rfc4122"),
+ Argument::ARGUMENT_VALUE(rfc4122.c_str()));
+ }
+ uuid[uuidBinaryLength - (ind / 2) - 1] = static_cast<uint8_t>(b);
}
+ return uuid;
+}
+
+auto ipmiAppGetDeviceGuid()
+ -> ipmi::RspType<std::array<uint8_t, uuidBinaryLength>>
+{
+ // return a fixed GUID based on /etc/machine-id
+ // This should match the /redfish/v1/Managers/bmc's UUID data
- // Data length
- *data_len = resp_size;
+ // machine specific application ID (for BMC ID)
+ // generated by systemd-id128 -p new as per man page
+ static constexpr sd_id128_t bmcUuidAppId = SD_ID128_MAKE(
+ e0, e1, 73, 76, 64, 61, 47, da, a5, 0c, d0, cc, 64, 12, 45, 78);
- // Pack the actual response
- std::memcpy(response, &resp_uuid, *data_len);
+ sd_id128_t bmcUuid;
+ // create the UUID from /etc/machine-id via the systemd API
+ sd_id128_get_machine_app_specific(bmcUuidAppId, &bmcUuid);
-finish:
- sd_bus_error_free(&error);
- reply = sd_bus_message_unref(reply);
- free(busname);
+ char bmcUuidCstr[SD_ID128_STRING_MAX];
+ std::string systemUuid = sd_id128_to_string(bmcUuid, bmcUuidCstr);
- return rc;
+ std::array<uint8_t, uuidBinaryLength> uuid = rfc4122ToIpmi(systemUuid);
+ return ipmi::responseSuccess(uuid);
}
auto ipmiAppGetBtCapabilities()
@@ -1339,8 +1294,9 @@ void register_netfn_app_functions()
ipmi::Privilege::User, ipmiAppGetSelfTestResults);
// <Get Device GUID>
- ipmi_register_callback(NETFUN_APP, IPMI_CMD_GET_DEVICE_GUID, NULL,
- ipmi_app_get_device_guid, PRIVILEGE_USER);
+ ipmi::registerHandler(ipmi::prioOpenBmcBase, ipmi::netFnApp,
+ ipmi::app::cmdGetDeviceGuid, ipmi::Privilege::User,
+ ipmiAppGetDeviceGuid);
// <Set ACPI Power State>
ipmi_register_callback(NETFUN_APP, IPMI_CMD_SET_ACPI, NULL,
OpenPOWER on IntegriCloud