host-dump: Renamed host-dump-offload-transport build option
Currently dump manager using "host-dump-offload-transport" to mention
the transport protocol name to offload host dumps but, same transport
can use to other actions i.e create and delete. So, Changing build option
name into "host-transport" to make generic.
Also, transport code sources files are organized based on "offload" name
so, changed same as "host-transport".
Signed-off-by: Ramesh Iyyar <rameshi1@in.ibm.com>
Change-Id: I9e229218ea8c606e7092daf4d24fd6d16eb425c8
diff --git a/host-transport-extensions/default/default.cpp b/host-transport-extensions/default/default.cpp
new file mode 100644
index 0000000..9eb2bfe
--- /dev/null
+++ b/host-transport-extensions/default/default.cpp
@@ -0,0 +1,17 @@
+#include <cstdint>
+#include <stdexcept>
+
+namespace phosphor
+{
+namespace dump
+{
+namespace host
+{
+void requestOffload(uint32_t)
+{
+ throw std::runtime_error("Hostdump offload method not specified");
+}
+
+} // namespace host
+} // namespace dump
+} // namespace phosphor
diff --git a/host-transport-extensions/default/meson.build b/host-transport-extensions/default/meson.build
new file mode 100644
index 0000000..423c847
--- /dev/null
+++ b/host-transport-extensions/default/meson.build
@@ -0,0 +1,5 @@
+# SPDX-License-Identifier: Apache-2.0
+
+phosphor_dump_manager_sources += [
+ 'host-transport-extensions/default/default.cpp'
+ ]
diff --git a/host-transport-extensions/meson.build b/host-transport-extensions/meson.build
new file mode 100644
index 0000000..01fd02d
--- /dev/null
+++ b/host-transport-extensions/meson.build
@@ -0,0 +1,9 @@
+# SPDX-License-Identifier: Apache-2.0
+
+hostTransport = get_option('host-transport')
+
+if hostTransport == 'default'
+ subdir('default')
+elif hostTransport == 'pldm'
+ subdir('pldm')
+endif
diff --git a/host-transport-extensions/pldm/meson.build b/host-transport-extensions/pldm/meson.build
new file mode 100644
index 0000000..d9cedd9
--- /dev/null
+++ b/host-transport-extensions/pldm/meson.build
@@ -0,0 +1,7 @@
+# SPDX-License-Identifier: Apache-2.0
+
+phosphor_dump_manager_sources += [
+ 'host-transport-extensions/pldm/pldm_interface.cpp'
+ ]
+
+phosphor_dump_manager_dependency += [ dependency('libpldm') ]
diff --git a/host-transport-extensions/pldm/pldm_interface.cpp b/host-transport-extensions/pldm/pldm_interface.cpp
new file mode 100644
index 0000000..dfff103
--- /dev/null
+++ b/host-transport-extensions/pldm/pldm_interface.cpp
@@ -0,0 +1,180 @@
+/**
+ * Copyright © 2019 IBM Corporation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+#include "pldm_interface.hpp"
+
+#include "dump_utils.hpp"
+#include "xyz/openbmc_project/Common/error.hpp"
+
+#include <libpldm/base.h>
+#include <libpldm/platform.h>
+#include <unistd.h>
+
+#include <fstream>
+#include <phosphor-logging/elog-errors.hpp>
+#include <phosphor-logging/log.hpp>
+#include <sdbusplus/bus.hpp>
+
+namespace phosphor
+{
+namespace dump
+{
+namespace host
+{
+/**
+ * @brief Initiate offload of the dump with provided id
+ *
+ * @param[in] id - The Dump Source ID.
+ *
+ */
+void requestOffload(uint32_t id)
+{
+ pldm::requestOffload(id);
+}
+} // namespace host
+
+namespace pldm
+{
+
+using namespace phosphor::logging;
+
+constexpr auto eidPath = "/usr/share/pldm/host_eid";
+constexpr mctp_eid_t defaultEIDValue = 9;
+
+using InternalFailure =
+ sdbusplus::xyz::openbmc_project::Common::Error::InternalFailure;
+
+void closeFD(int fd)
+{
+ if (fd >= 0)
+ {
+ close(fd);
+ }
+}
+
+mctp_eid_t readEID()
+{
+ mctp_eid_t eid = defaultEIDValue;
+
+ std::ifstream eidFile{eidPath};
+ if (!eidFile.good())
+ {
+ log<level::ERR>("Could not open host EID file");
+ elog<InternalFailure>();
+ }
+ else
+ {
+ std::string eid;
+ eidFile >> eid;
+ if (!eid.empty())
+ {
+ eid = strtol(eid.c_str(), nullptr, 10);
+ }
+ else
+ {
+ log<level::ERR>("EID file was empty");
+ elog<InternalFailure>();
+ }
+ }
+
+ return eid;
+}
+
+int open()
+{
+ auto fd = pldm_open();
+ if (fd < 0)
+ {
+ auto e = errno;
+ log<level::ERR>("pldm_open failed", entry("ERRNO=%d", e),
+ entry("FD=%d\n", fd));
+ elog<InternalFailure>();
+ }
+ return fd;
+}
+
+void requestOffload(uint32_t id)
+{
+ uint16_t effecterId = 0x05; // TODO PhyP temporary Hardcoded value.
+
+ std::array<uint8_t, sizeof(pldm_msg_hdr) + sizeof(effecterId) + sizeof(id) +
+ sizeof(uint8_t)>
+ requestMsg{};
+ auto request = reinterpret_cast<pldm_msg*>(requestMsg.data());
+
+ std::array<uint8_t, sizeof(id)> effecterValue{};
+
+ memcpy(effecterValue.data(), &id, sizeof(id));
+
+ mctp_eid_t eid = readEID();
+
+ auto instanceID = getPLDMInstanceID(eid);
+
+ auto rc = encode_set_numeric_effecter_value_req(
+ instanceID, effecterId, PLDM_EFFECTER_DATA_SIZE_UINT32,
+ effecterValue.data(), request,
+ requestMsg.size() - sizeof(pldm_msg_hdr));
+
+ if (rc != PLDM_SUCCESS)
+ {
+ log<level::ERR>("Message encode failure. ", entry("RC=%d", rc));
+ elog<InternalFailure>();
+ }
+
+ uint8_t* responseMsg = nullptr;
+ size_t responseMsgSize{};
+
+ auto fd = open();
+
+ rc = pldm_send_recv(eid, fd, requestMsg.data(), requestMsg.size(),
+ &responseMsg, &responseMsgSize);
+ if (rc < 0)
+ {
+ closeFD(fd);
+ auto e = errno;
+ log<level::ERR>("pldm_send failed", entry("RC=%d", rc),
+ entry("ERRNO=%d", e));
+ elog<InternalFailure>();
+ }
+ pldm_msg* response = reinterpret_cast<pldm_msg*>(responseMsg);
+ log<level::INFO>(
+ "Done. PLDM message",
+ entry("RC=%d", static_cast<uint16_t>(response->payload[0])));
+
+ closeFD(fd);
+}
+
+uint8_t getPLDMInstanceID(uint8_t eid)
+{
+
+ constexpr auto pldmRequester = "xyz.openbmc_project.PLDM.Requester";
+ constexpr auto pldm = "/xyz/openbmc_project/pldm";
+
+ auto bus = sdbusplus::bus::new_default();
+ auto service = phosphor::dump::getService(bus, pldm, pldmRequester);
+
+ auto method = bus.new_method_call(service.c_str(), pldm, pldmRequester,
+ "GetInstanceId");
+ method.append(eid);
+ auto reply = bus.call(method);
+
+ uint8_t instanceID = 0;
+ reply.read(instanceID);
+
+ return instanceID;
+}
+} // namespace pldm
+} // namespace dump
+} // namespace phosphor
diff --git a/host-transport-extensions/pldm/pldm_interface.hpp b/host-transport-extensions/pldm/pldm_interface.hpp
new file mode 100644
index 0000000..fffa682
--- /dev/null
+++ b/host-transport-extensions/pldm/pldm_interface.hpp
@@ -0,0 +1,56 @@
+#pragma once
+
+#include <libpldm/pldm.h>
+
+namespace phosphor
+{
+namespace dump
+{
+namespace pldm
+{
+
+/**
+ * PLDMInterface
+ *
+ * Handles sending the SetNumericEffecterValue PLDM
+ * command to the host to start dump offload.
+ *
+ */
+
+/**
+ * @brief Kicks of the SetNumericEffecterValue command to
+ * start offload the dump
+ *
+ * @param[in] id - The Dump Source ID.
+ *
+ */
+
+void requestOffload(uint32_t id);
+
+/**
+ * @brief Reads the MCTP endpoint ID out of a file
+ */
+mctp_eid_t readEID();
+
+/**
+ * @brief Opens the PLDM file descriptor
+ */
+int open();
+
+/**
+ * @brief Closes the PLDM file descriptor
+ */
+void closeFD(int fd);
+
+/**
+ * @brief Returns the PLDM instance ID to use for PLDM commands
+ *
+ * @param[in] eid - The PLDM EID
+ *
+ * @return uint8_t - The instance ID
+ **/
+uint8_t getPLDMInstanceID(uint8_t eid);
+
+} // namespace pldm
+} // namespace dump
+} // namespace phosphor