diff options
author | Vladislav Vovchenko <vlad.vovchenko93@gmail.com> | 2017-08-17 00:31:14 +0300 |
---|---|---|
committer | Brad Bishop <bradleyb@fuzziesquirrel.com> | 2017-10-16 22:14:33 +0000 |
commit | 8f7a6f68d2488cbd6eb2e4af9adec61d97741e99 (patch) | |
tree | cc964a5689f4e25e1938a064c22ee388eafba31c /dcmihandler.cpp | |
parent | 1fe5c834b9ae4f09726dea8a1c7b3a05d87f1344 (diff) | |
download | phosphor-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.cpp | 134 |
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 |