Add RMCP Ping support

Added support of RMCP Ping/Pong request and response
(ASF messages).

Tested: Tested using rmcpping tool to send RMCP ping.

Resolves openbmc/phosphor-net-ipmid#15

Signed-off-by: Kirill Pakhomov <k.pakhomov@yadro.com>
Change-Id: Ie5199e6af69860d9406bdd516952b62c3d05793f
diff --git a/message_parsers.hpp b/message_parsers.hpp
index 5738c43..b26f9a3 100644
--- a/message_parsers.hpp
+++ b/message_parsers.hpp
@@ -24,6 +24,19 @@
 // RMCP Session Header Size
 constexpr size_t RMCP_SESSION_HEADER_SIZE = 4;
 
+// RMCP/ASF Pong Message ASF Header Data Length
+// as per IPMI spec 13.2.4
+constexpr size_t RMCP_ASF_PONG_DATA_LEN = 16;
+
+// ASF IANA
+constexpr uint32_t ASF_IANA = 4542;
+
+// ASF Supported Entities
+constexpr uint32_t ASF_SUPP_ENT = 0x81;
+
+// ASF Supported Entities
+constexpr uint32_t ASF_SUPP_INT = 0x00;
+
 // Maximum payload size
 constexpr size_t MAX_PAYLOAD_SIZE = 255;
 
@@ -34,13 +47,20 @@
     INVALID = 0xFF,
 };
 
-struct BasicHeader_t
+// RMCP Header
+struct RmcpHeader_t
 {
     // RMCP Header
     uint8_t version;
     uint8_t reserved;
     uint8_t rmcpSeqNum;
     uint8_t classOfMsg;
+} __attribute__((packed));
+
+struct BasicHeader_t
+{
+    // RMCP Header
+    struct RmcpHeader_t rmcp;
 
     // IPMI partial session header
     union
@@ -226,4 +246,54 @@
 
 } // namespace ipmi20parser
 
+#ifdef RMCP_PING
+namespace asfparser
+{
+
+// ASF message fields for RMCP Ping message
+struct AsfMessagePing_t
+{
+    struct parser::RmcpHeader_t rmcp;
+
+    uint32_t iana;
+    uint8_t msgType;
+    uint8_t msgTag;
+    uint8_t reserved;
+    uint8_t dataLen;
+} __attribute__((packed));
+
+// ASF message fields for RMCP Pong message
+struct AsfMessagePong_t
+{
+    struct AsfMessagePing_t ping;
+
+    uint32_t iana;
+    uint32_t oemDefined;
+    uint8_t suppEntities;
+    uint8_t suppInteract;
+    uint32_t reserved1;
+    uint16_t reserved2;
+} __attribute__((packed));
+
+/**
+ * @brief Unflatten an incoming packet and prepare the ASF message
+ *
+ * @param[in] inPacket - Incoming ASF packet
+ *
+ * @return ASF message in the packet on success
+ */
+std::shared_ptr<Message> unflatten(std::vector<uint8_t>& inPacket);
+
+/**
+ * @brief Generate the ASF packet with the RMCP header
+ *
+ * @param[in] asfMsgTag - ASF Message Tag from Ping request
+ *
+ * @return ASF packet on success
+ */
+std::vector<uint8_t> flatten(uint8_t asfMsgTag);
+
+} // namespace asfparser
+#endif // RMCP_PING
+
 } // namespace message