summaryrefslogtreecommitdiffstats
path: root/dcmihandler.cpp
diff options
context:
space:
mode:
authorVladislav Vovchenko <vlad.vovchenko93@gmail.com>2017-08-17 00:31:14 +0300
committerBrad Bishop <bradleyb@fuzziesquirrel.com>2017-10-16 22:14:33 +0000
commit8f7a6f68d2488cbd6eb2e4af9adec61d97741e99 (patch)
treecc964a5689f4e25e1938a064c22ee388eafba31c /dcmihandler.cpp
parent1fe5c834b9ae4f09726dea8a1c7b3a05d87f1344 (diff)
downloadphosphor-host-ipmid-8f7a6f68d2488cbd6eb2e4af9adec61d97741e99.tar.gz
phosphor-host-ipmid-8f7a6f68d2488cbd6eb2e4af9adec61d97741e99.zip
Add DCMI Get/Set Management Controller Id String
Resolves openbmc/openbmc#1855 Change-Id: I878c7bcb1ea8b46cd3e932b1cbb2290fe612f652 Signed-off-by: Vladislav Vovchenko <vlad.vovchenko93@gmail.com> Signed-off-by: Brad Bishop <bradleyb@fuzziesquirrel.com>
Diffstat (limited to 'dcmihandler.cpp')
-rw-r--r--dcmihandler.cpp134
1 files changed, 134 insertions, 0 deletions
diff --git a/dcmihandler.cpp b/dcmihandler.cpp
index 5df6559..806ddd0 100644
--- a/dcmihandler.cpp
+++ b/dcmihandler.cpp
@@ -207,6 +207,17 @@ void writeAssetTag(const std::string& assetTag)
}
}
+std::string getHostName(void)
+{
+ sdbusplus::bus::bus bus{ ipmid_get_sd_bus_connection() };
+
+ auto service = ipmi::getService(bus, networkConfigIntf, networkConfigObj);
+ auto value = ipmi::getDbusProperty(bus, service,
+ networkConfigObj, networkConfigIntf, hostNameProp);
+
+ return value.get<std::string>();
+}
+
} // namespace dcmi
ipmi_ret_t getPowerLimit(ipmi_netfn_t netfn, ipmi_cmd_t cmd,
@@ -483,6 +494,115 @@ ipmi_ret_t setAssetTag(ipmi_netfn_t netfn, ipmi_cmd_t cmd,
}
}
+ipmi_ret_t getMgmntCtrlIdStr(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)
+{
+ auto requestData = reinterpret_cast<const dcmi::GetMgmntCtrlIdStrRequest *>
+ (request);
+ auto responseData = reinterpret_cast<dcmi::GetMgmntCtrlIdStrResponse *>
+ (response);
+ std::string hostName;
+
+ *data_len = 0;
+
+ if (requestData->groupID != dcmi::groupExtId ||
+ requestData->bytes > dcmi::maxBytes ||
+ requestData->offset + requestData->bytes > dcmi::maxCtrlIdStrLen)
+ {
+ return IPMI_CC_INVALID_FIELD_REQUEST;
+ }
+
+ try
+ {
+ hostName = dcmi::getHostName();
+ }
+ catch (InternalFailure& e)
+ {
+ return IPMI_CC_UNSPECIFIED_ERROR;
+ }
+
+ if (requestData->offset > hostName.length())
+ {
+ return IPMI_CC_PARM_OUT_OF_RANGE;
+ }
+ auto responseStr = hostName.substr(requestData->offset, requestData->bytes);
+ auto responseStrLen = std::min(static_cast<std::size_t>(requestData->bytes),
+ responseStr.length() + 1);
+ responseData->groupID = dcmi::groupExtId;
+ responseData->strLen = hostName.length();
+ std::copy(begin(responseStr), end(responseStr), responseData->data);
+
+ *data_len = sizeof(*responseData) + responseStrLen;
+ return IPMI_CC_OK;
+}
+
+ipmi_ret_t setMgmntCtrlIdStr(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 std::array<char, dcmi::maxCtrlIdStrLen + 1> newCtrlIdStr;
+
+ auto requestData = reinterpret_cast<const dcmi::SetMgmntCtrlIdStrRequest *>
+ (request);
+ auto responseData = reinterpret_cast<dcmi::SetMgmntCtrlIdStrResponse *>
+ (response);
+
+ *data_len = 0;
+
+ if (requestData->groupID != dcmi::groupExtId ||
+ requestData->bytes > dcmi::maxBytes ||
+ requestData->offset + requestData->bytes > dcmi::maxCtrlIdStrLen + 1 ||
+ (requestData->offset + requestData->bytes == dcmi::maxCtrlIdStrLen + 1 &&
+ requestData->data[requestData->bytes - 1] != '\0'))
+ {
+ return IPMI_CC_INVALID_FIELD_REQUEST;
+ }
+
+ try
+ {
+ /* if there is no old value and offset is not 0 */
+ if (newCtrlIdStr[0] == '\0' && requestData->offset != 0)
+ {
+ /* read old ctrlIdStr */
+ auto hostName = dcmi::getHostName();
+ hostName.resize(dcmi::maxCtrlIdStrLen);
+ std::copy(begin(hostName), end(hostName), begin(newCtrlIdStr));
+ newCtrlIdStr[hostName.length()] = '\0';
+ }
+
+ /* replace part of string and mark byte after the last as \0 */
+ auto restStrIter = std::copy_n(requestData->data,
+ requestData->bytes, begin(newCtrlIdStr) + requestData->offset);
+ /* if the last written byte is not 64th - add '\0' */
+ if (requestData->offset + requestData->bytes <= dcmi::maxCtrlIdStrLen)
+ {
+ *restStrIter = '\0';
+ }
+
+ /* if input data contains '\0' whole string is sent - update hostname */
+ auto it = std::find(requestData->data,
+ requestData->data + requestData->bytes, '\0');
+ if (it != requestData->data + requestData->bytes)
+ {
+ sdbusplus::bus::bus bus{ ipmid_get_sd_bus_connection() };
+ ipmi::setDbusProperty(bus, dcmi::networkServiceName,
+ dcmi::networkConfigObj, dcmi::networkConfigIntf,
+ dcmi::hostNameProp, std::string(newCtrlIdStr.data()));
+ }
+ }
+ catch (InternalFailure& e)
+ {
+ *data_len = 0;
+ return IPMI_CC_UNSPECIFIED_ERROR;
+ }
+
+ responseData->groupID = dcmi::groupExtId;
+ responseData->offset = requestData->offset + requestData->bytes;
+ *data_len = sizeof(*responseData);
+ return IPMI_CC_OK;
+}
+
void register_netfn_dcmi_functions()
{
// <Get Power Limit>
@@ -519,6 +639,20 @@ void register_netfn_dcmi_functions()
ipmi_register_callback(NETFUN_GRPEXT, dcmi::Commands::SET_ASSET_TAG,
NULL, setAssetTag, PRIVILEGE_OPERATOR);
+
+ // <Get Managment Controller Identifier String>
+ printf("Registering NetFn:[0x%X], Cmd:[0x%X]\n",
+ NETFUN_GRPEXT, dcmi::Commands::GET_MGMNT_CTRL_ID_STR);
+
+ ipmi_register_callback(NETFUN_GRPEXT, dcmi::Commands::GET_MGMNT_CTRL_ID_STR,
+ NULL, getMgmntCtrlIdStr, PRIVILEGE_USER);
+
+ // <Set Management Controller Identifier String>
+ printf("Registering NetFn:[0x%X], Cmd:[0x%X]\n",
+ NETFUN_GRPEXT, dcmi::Commands::SET_MGMNT_CTRL_ID_STR);
+ ipmi_register_callback(NETFUN_GRPEXT, dcmi::Commands::SET_MGMNT_CTRL_ID_STR,
+ NULL, setMgmntCtrlIdStr, PRIVILEGE_ADMIN);
+
return;
}
// 956379
OpenPOWER on IntegriCloud