diff options
Diffstat (limited to 'include/ipmid/message.hpp')
-rw-r--r-- | include/ipmid/message.hpp | 103 |
1 files changed, 76 insertions, 27 deletions
diff --git a/include/ipmid/message.hpp b/include/ipmid/message.hpp index 030618f..c828e3c 100644 --- a/include/ipmid/message.hpp +++ b/include/ipmid/message.hpp @@ -18,10 +18,12 @@ #include <algorithm> #include <boost/asio/spawn.hpp> #include <cstdint> +#include <exception> #include <ipmid/api-types.hpp> #include <ipmid/message/types.hpp> #include <memory> #include <phosphor-logging/log.hpp> +#include <sdbusplus/asio/connection.hpp> #include <tuple> #include <utility> #include <vector> @@ -33,23 +35,33 @@ struct Context { using ptr = std::shared_ptr<Context>; - Context() = default; - - Context(NetFn netFn, Cmd cmd, int channel, int userId, Privilege priv, - boost::asio::yield_context* yield = nullptr) : - netFn(netFn), - cmd(cmd), channel(channel), userId(userId), priv(priv), yield(yield) + Context() = delete; + Context(const Context&) = default; + Context& operator=(const Context&) = default; + Context(Context&&) = delete; + Context& operator=(Context&&) = delete; + + Context(std::shared_ptr<sdbusplus::asio::connection> bus, NetFn netFn, + Cmd cmd, int channel, int userId, uint32_t sessionId, + Privilege priv, int rqSA, boost::asio::yield_context& yield) : + bus(bus), + netFn(netFn), cmd(cmd), channel(channel), userId(userId), + sessionId(sessionId), priv(priv), rqSA(rqSA), yield(yield) { } + std::shared_ptr<sdbusplus::asio::connection> bus; // normal IPMI context (what call is this, from whence it came...) - NetFn netFn = 0; - Cmd cmd = 0; - int channel = 0; - int userId = 0; - Privilege priv = Privilege::None; - // if non-null, use this to do blocking asynchronous asio calls - boost::asio::yield_context* yield = nullptr; + NetFn netFn; + Cmd cmd; + int channel; + int userId; + uint32_t sessionId; + Privilege priv; + // srcAddr is only set on IPMB requests because + // Platform Event Message needs it to determine the incoming format + int rqSA; + boost::asio::yield_context yield; }; namespace message @@ -99,15 +111,15 @@ struct Payload Payload(Payload&&) = default; Payload& operator=(Payload&&) = default; - explicit Payload(std::vector<uint8_t>&& data) : - raw(std::move(data)), unpackCheck(false) + explicit Payload(std::vector<uint8_t>&& data) : raw(std::move(data)) { } ~Payload() { using namespace phosphor::logging; - if (trailingOk && !unpackCheck && !fullyUnpacked()) + if (raw.size() != 0 && std::uncaught_exceptions() == 0 && !trailingOk && + !unpackCheck && !unpackError) { log<level::ERR>("Failed to check request for full unpack"); } @@ -252,6 +264,27 @@ struct Payload return packRet; } + /** + * @brief Prepends another payload to this one + * + * Avoid using this unless absolutely required since it inserts into the + * front of the response payload. + * + * @param p - The payload to prepend + * + * @retunr int - non-zero on prepend errors + */ + int prepend(const ipmi::message::Payload& p) + { + if (bitCount != 0 || p.bitCount != 0) + { + return 1; + } + raw.reserve(raw.size() + p.raw.size()); + raw.insert(raw.begin(), p.raw.begin(), p.raw.end()); + return 0; + } + /****************************************************************** * Request operations *****************************************************************/ @@ -445,8 +478,8 @@ struct Payload size_t bitCount = 0; std::vector<uint8_t> raw; size_t rawIndex = 0; - bool trailingOk = false; - bool unpackCheck = true; + bool trailingOk = true; + bool unpackCheck = false; bool unpackError = false; }; @@ -513,6 +546,21 @@ struct Response return payload.pack(t); } + /** + * @brief Prepends another payload to this one + * + * Avoid using this unless absolutely required since it inserts into the + * front of the response payload. + * + * @param p - The payload to prepend + * + * @retunr int - non-zero on prepend errors + */ + int prepend(const ipmi::message::Payload& p) + { + return payload.prepend(p); + } + Payload payload; Context::ptr ctx; Cc cc; @@ -560,19 +608,20 @@ struct Request int unpack(Args&&... args) { int unpackRet = payload.unpack(std::forward<Args>(args)...); - if (unpackRet == ipmi::ccSuccess) + if (unpackRet != ipmi::ccSuccess) + { + // not all bits were consumed by requested parameters + return ipmi::ccReqDataLenInvalid; + } + if (!payload.trailingOk) { - if (!payload.trailingOk) + if (!payload.fullyUnpacked()) { - if (!payload.fullyUnpacked()) - { - // not all bits were consumed by requested parameters - return ipmi::ccReqDataLenInvalid; - } - payload.unpackCheck = false; + // not all bits were consumed by requested parameters + return ipmi::ccReqDataLenInvalid; } } - return unpackRet; + return ipmi::ccSuccess; } /** |