dsp: platform: Fix decode_set_event_receiver_req()

Per DSP0248 V1.3.0 table13, the heartbeatTimer field shall be omitted
from the request data if eventMessageGlobalEnable is not set to
enableAsyncKeepAlive.

gitlint-ignore: B1, UC1
Fixes: 66c7723adbdc ("msgbuf: Enable pldm_msgbuf_extract() into packed members")
Fixes: 9667f5823930 ("platform: pldm_msgbuf for decode_set_event_receiver_req()")
Fixes: 6ef2aa90a793 ("platform: Test invalid heartbeat conditions after assignment")
Fixes: 9c76679224cf ("libpldm: Migrate to subproject")
Change-Id: Ia2a0c71a1f37a0fd32670b9b66b051e18fb73dbe
Signed-off-by: Gilbert Chen <gilbertc@nvidia.com>
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 55c6928..2907ba3 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -110,6 +110,11 @@
    `tranferFlag` is `AcknowledgementOnly`, the value `eventIDToAcknowledge`
    should be the previously retrieved eventID (from the PLDM terminus).
 
+4. dsp: platform: Fix decode_set_event_receiver_req()
+
+   The heartbeat field shall be omitted if `eventMessageGlobalEnable` is not
+   `enableAsyncKeepAlive`.
+
 ## [0.9.1] - 2024-09-07
 
 ### Changed
diff --git a/include/libpldm/platform.h b/include/libpldm/platform.h
index 7ef48c7..ed4ef3b 100644
--- a/include/libpldm/platform.h
+++ b/include/libpldm/platform.h
@@ -29,12 +29,13 @@
 };
 
 /* Maximum size for request */
-#define PLDM_SET_STATE_EFFECTER_STATES_REQ_BYTES  19
-#define PLDM_GET_STATE_SENSOR_READINGS_REQ_BYTES  4
-#define PLDM_GET_NUMERIC_EFFECTER_VALUE_REQ_BYTES 2
-#define PLDM_GET_STATE_EFFECTER_STATES_REQ_BYTES  2
-#define PLDM_GET_SENSOR_READING_REQ_BYTES	  3
-#define PLDM_SET_EVENT_RECEIVER_REQ_BYTES	  5
+#define PLDM_SET_STATE_EFFECTER_STATES_REQ_BYTES    19
+#define PLDM_GET_STATE_SENSOR_READINGS_REQ_BYTES    4
+#define PLDM_GET_NUMERIC_EFFECTER_VALUE_REQ_BYTES   2
+#define PLDM_GET_STATE_EFFECTER_STATES_REQ_BYTES    2
+#define PLDM_GET_SENSOR_READING_REQ_BYTES	    3
+#define PLDM_SET_EVENT_RECEIVER_REQ_BYTES	    3
+#define PLDM_SET_EVENT_RECEIVER_REQ_HEARTBEAT_BYTES 2
 /* Response lengths are inclusive of completion code */
 #define PLDM_SET_STATE_EFFECTER_STATES_RESP_BYTES 1
 
diff --git a/src/dsp/platform.c b/src/dsp/platform.c
index 4b6898e..a800da5 100644
--- a/src/dsp/platform.c
+++ b/src/dsp/platform.c
@@ -2429,9 +2429,16 @@
 	}
 
 	pldm_msgbuf_extract_p(buf, event_message_global_enable);
+	if (rc) {
+		return rc;
+	}
+
 	pldm_msgbuf_extract_p(buf, transport_protocol_type);
 	pldm_msgbuf_extract_p(buf, event_receiver_address_info);
-	pldm_msgbuf_extract_p(buf, heartbeat_timer);
+	if ((*event_message_global_enable ==
+	     PLDM_EVENT_MESSAGE_GLOBAL_ENABLE_ASYNC_KEEP_ALIVE)) {
+		pldm_msgbuf_extract_p(buf, heartbeat_timer);
+	}
 
 	rc = pldm_msgbuf_destroy(buf);
 	if (rc) {
diff --git a/tests/dsp/platform.cpp b/tests/dsp/platform.cpp
index e937dec..bd615c3 100644
--- a/tests/dsp/platform.cpp
+++ b/tests/dsp/platform.cpp
@@ -3539,10 +3539,8 @@
     uint8_t eventReceiverAddressInfo = 0x08;
     uint16_t heartbeatTimer = 0x78;
 
-    std::vector<uint8_t> requestMsg(hdrSize +
-                                    PLDM_SET_EVENT_RECEIVER_REQ_BYTES);
-    // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
-    auto request = reinterpret_cast<pldm_msg*>(requestMsg.data());
+    PLDM_MSG_DEFINE_P(request, PLDM_SET_EVENT_RECEIVER_REQ_BYTES +
+                                   PLDM_SET_EVENT_RECEIVER_REQ_HEARTBEAT_BYTES);
 
     auto rc = encode_set_event_receiver_req(
         0, eventMessageGlobalEnable, transportProtocolType,
@@ -3566,10 +3564,8 @@
     uint8_t eventReceiverAddressInfo = 0x08;
     uint16_t heartbeatTimer = 0;
 
-    std::vector<uint8_t> requestMsg(hdrSize +
-                                    PLDM_SET_EVENT_RECEIVER_REQ_BYTES);
-    // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
-    auto request = reinterpret_cast<pldm_msg*>(requestMsg.data());
+    PLDM_MSG_DEFINE_P(request, PLDM_SET_EVENT_RECEIVER_REQ_BYTES +
+                                   PLDM_SET_EVENT_RECEIVER_REQ_HEARTBEAT_BYTES);
 
     auto rc = encode_set_event_receiver_req(
         0, eventMessageGlobalEnable, transportProtocolType,
@@ -3639,9 +3635,8 @@
 
 TEST(SetEventReceiver, testGoodDecodeRequest)
 {
-
-    std::array<uint8_t, hdrSize + PLDM_SET_EVENT_RECEIVER_REQ_BYTES>
-        requestMsg{};
+    PLDM_MSG_DEFINE_P(request, PLDM_SET_EVENT_RECEIVER_REQ_BYTES +
+                                   PLDM_SET_EVENT_RECEIVER_REQ_HEARTBEAT_BYTES);
 
     uint8_t eventMessageGlobalEnable =
         PLDM_EVENT_MESSAGE_GLOBAL_ENABLE_ASYNC_KEEP_ALIVE;
@@ -3649,8 +3644,6 @@
     uint8_t eventReceiverAddressInfo = 0x08;
     uint16_t heartbeatTimer = 0x78;
 
-    // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
-    auto request = reinterpret_cast<pldm_msg*>(requestMsg.data());
     struct pldm_set_event_receiver_req* req =
         // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
         reinterpret_cast<struct pldm_set_event_receiver_req*>(request->payload);
@@ -3665,9 +3658,11 @@
     uint8_t reteventReceiverAddressInfo;
     uint16_t retheartbeatTimer;
     auto rc = decode_set_event_receiver_req(
-        request, requestMsg.size() - hdrSize, &reteventMessageGlobalEnable,
-        &rettransportProtocolType, &reteventReceiverAddressInfo,
-        &retheartbeatTimer);
+        request,
+        PLDM_SET_EVENT_RECEIVER_REQ_BYTES +
+            PLDM_SET_EVENT_RECEIVER_REQ_HEARTBEAT_BYTES,
+        &reteventMessageGlobalEnable, &rettransportProtocolType,
+        &reteventReceiverAddressInfo, &retheartbeatTimer);
 
     EXPECT_EQ(rc, PLDM_SUCCESS);
     EXPECT_EQ(eventMessageGlobalEnable, reteventMessageGlobalEnable);
@@ -3678,11 +3673,14 @@
 
 TEST(SetEventReceiver, testBadDecodeRequest)
 {
-    std::array<uint8_t, hdrSize + PLDM_SET_EVENT_RECEIVER_REQ_BYTES>
-        requestMsg{};
+    PLDM_MSG_DEFINE_P(request, PLDM_SET_EVENT_RECEIVER_REQ_BYTES +
+                                   PLDM_SET_EVENT_RECEIVER_REQ_HEARTBEAT_BYTES);
 
-    auto rc = decode_set_event_receiver_req(NULL, requestMsg.size() - hdrSize,
-                                            NULL, NULL, NULL, NULL);
+    auto rc = decode_set_event_receiver_req(
+        NULL,
+        PLDM_SET_EVENT_RECEIVER_REQ_BYTES +
+            PLDM_SET_EVENT_RECEIVER_REQ_HEARTBEAT_BYTES,
+        NULL, NULL, NULL, NULL);
     EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
 
     uint8_t eventMessageGlobalEnable =
@@ -3691,8 +3689,6 @@
     uint8_t eventReceiverAddressInfo = 0x08;
     uint16_t heartbeatTimer = 0x78;
 
-    // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
-    auto request = reinterpret_cast<pldm_msg*>(requestMsg.data());
     struct pldm_set_event_receiver_req* req =
         // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
         reinterpret_cast<struct pldm_set_event_receiver_req*>(request->payload);
@@ -3706,11 +3702,24 @@
     uint8_t rettransportProtocolType;
     uint8_t reteventReceiverAddressInfo;
     uint16_t retheartbeatTimer;
+
+#ifdef NDEBUG
     rc = decode_set_event_receiver_req(
-        request, requestMsg.size() - hdrSize - 1, &reteventMessageGlobalEnable,
-        &rettransportProtocolType, &reteventReceiverAddressInfo,
-        &retheartbeatTimer);
+        request,
+        PLDM_SET_EVENT_RECEIVER_REQ_BYTES +
+            PLDM_SET_EVENT_RECEIVER_REQ_HEARTBEAT_BYTES - 1,
+        &reteventMessageGlobalEnable, &rettransportProtocolType,
+        &reteventReceiverAddressInfo, &retheartbeatTimer);
     EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH);
+#else
+    EXPECT_DEATH(decode_set_event_receiver_req(
+                     request,
+                     PLDM_SET_EVENT_RECEIVER_REQ_BYTES +
+                         PLDM_SET_EVENT_RECEIVER_REQ_HEARTBEAT_BYTES - 1,
+                     &reteventMessageGlobalEnable, &rettransportProtocolType,
+                     &reteventReceiverAddressInfo, &retheartbeatTimer),
+                 "ctx->remaining >= 0");
+#endif
 }
 
 TEST(decodeNumericSensorPdrData, Uint8Test)