msgbuf: Define a separate msgbuf structure for encode/decode function

Define separate msgbuf structures to avoid casting away const-qualifiers
in the msgbuf constructor function:

* pldm_msgbuf_rw: for encode functions with non const-qualified buffer
* pldm_msgbuf_ro: for decode functions with const-qualified buffer

Further, use _Generic() to keep the API ergonomic while still yielding a
compile error when wrong msgbuf type is passed.

Change-Id: I71dbcb7996e9fb402b49870fce539a939c1497e5
Signed-off-by: John Chung <john.chung@arm.com>
Signed-off-by: Andrew Jeffery <andrew@codeconstruct.com.au>
diff --git a/tests/dsp/base.cpp b/tests/dsp/base.cpp
index a926104..0e274a8 100644
--- a/tests/dsp/base.cpp
+++ b/tests/dsp/base.cpp
@@ -1,3 +1,5 @@
+#include "msgbuf.hpp"
+
 #include <libpldm/base.h>
 #include <libpldm/pldm_types.h>
 
@@ -6,8 +8,6 @@
 #include <cstring>
 #include <vector>
 
-#include "msgbuf.h"
-
 #include <gmock/gmock.h>
 #include <gtest/gtest.h>
 
@@ -550,7 +550,7 @@
     constexpr uint32_t kSectionLength = 0x10;
 
     PLDM_MSG_DEFINE_P(msg, PLDM_MULTIPART_RECEIVE_REQ_BYTES);
-    PLDM_MSGBUF_DEFINE_P(buf);
+    PLDM_MSGBUF_RW_DEFINE_P(buf);
     int rc;
 
     // Header values don't matter for this test.
@@ -616,7 +616,7 @@
     constexpr uint8_t kFlag = PLDM_XFER_FIRST_PART;
 
     PLDM_MSG_DEFINE_P(msg, PLDM_MULTIPART_RECEIVE_REQ_BYTES);
-    PLDM_MSGBUF_DEFINE_P(buf);
+    PLDM_MSGBUF_RW_DEFINE_P(buf);
     int rc;
 
     // Header values don't matter for this test.
@@ -648,7 +648,7 @@
     constexpr uint8_t kFlag = PLDM_XFER_CURRENT_PART + 0x10;
 
     PLDM_MSG_DEFINE_P(msg, PLDM_MULTIPART_RECEIVE_REQ_BYTES);
-    PLDM_MSGBUF_DEFINE_P(buf);
+    PLDM_MSGBUF_RW_DEFINE_P(buf);
     int rc;
 
     // Header values don't matter for this test.
@@ -683,7 +683,7 @@
     constexpr uint32_t kSectionOffset = 0x0;
 
     PLDM_MSG_DEFINE_P(msg, PLDM_MULTIPART_RECEIVE_REQ_BYTES);
-    PLDM_MSGBUF_DEFINE_P(buf);
+    PLDM_MSGBUF_RW_DEFINE_P(buf);
     int rc;
 
     // Header values don't matter for this test.
@@ -720,7 +720,7 @@
     constexpr uint32_t kSectionOffset = 0x100;
 
     PLDM_MSG_DEFINE_P(msg, PLDM_MULTIPART_RECEIVE_REQ_BYTES);
-    PLDM_MSGBUF_DEFINE_P(buf);
+    PLDM_MSGBUF_RW_DEFINE_P(buf);
     int rc;
 
     // Header values don't matter for this test.
@@ -838,7 +838,7 @@
 
     struct pldm_base_multipart_receive_resp resp_data = {};
 
-    PLDM_MSGBUF_DEFINE_P(buf);
+    PLDM_MSGBUF_RW_DEFINE_P(buf);
     int rc;
 
     static constexpr const size_t payload_length =
@@ -888,7 +888,7 @@
 
     struct pldm_base_multipart_receive_resp resp_data = {};
 
-    PLDM_MSGBUF_DEFINE_P(buf);
+    PLDM_MSGBUF_RW_DEFINE_P(buf);
     int rc;
 
     static constexpr const size_t payload_length =
@@ -936,7 +936,7 @@
 
     struct pldm_base_multipart_receive_resp resp_data = {};
 
-    PLDM_MSGBUF_DEFINE_P(buf);
+    PLDM_MSGBUF_RW_DEFINE_P(buf);
     int rc;
 
     static constexpr const size_t payload_length =
@@ -979,7 +979,7 @@
 
     struct pldm_base_multipart_receive_resp resp_data = {};
 
-    PLDM_MSGBUF_DEFINE_P(buf);
+    PLDM_MSGBUF_RW_DEFINE_P(buf);
     int rc;
 
     /*
@@ -1029,7 +1029,7 @@
 
     struct pldm_base_multipart_receive_resp resp_data = {};
 
-    PLDM_MSGBUF_DEFINE_P(buf);
+    PLDM_MSGBUF_RW_DEFINE_P(buf);
     int rc;
 
     /*
@@ -1630,7 +1630,7 @@
 
     struct pldm_base_negotiate_transfer_params_resp resp_data = {};
 
-    PLDM_MSGBUF_DEFINE_P(buf);
+    PLDM_MSGBUF_RW_DEFINE_P(buf);
     int rc;
 
     static constexpr const size_t payload_length =
@@ -1672,7 +1672,7 @@
 
     struct pldm_base_negotiate_transfer_params_resp resp_data = {};
 
-    PLDM_MSGBUF_DEFINE_P(buf);
+    PLDM_MSGBUF_RW_DEFINE_P(buf);
     int rc;
 
     static constexpr const size_t payload_length =
@@ -1715,7 +1715,7 @@
 
     struct pldm_base_negotiate_transfer_params_resp resp_data = {};
 
-    PLDM_MSGBUF_DEFINE_P(buf);
+    PLDM_MSGBUF_RW_DEFINE_P(buf);
     int rc;
 
     static constexpr const size_t payload_length =
diff --git a/tests/dsp/file.cpp b/tests/dsp/file.cpp
index b8fe67f..6dc4296 100644
--- a/tests/dsp/file.cpp
+++ b/tests/dsp/file.cpp
@@ -1,12 +1,12 @@
+#include "msgbuf.hpp"
+
+#include <libpldm/base.h>
 #include <libpldm/file.h>
 #include <libpldm/pldm_types.h>
 
 #include <array>
 #include <cstdint>
 #include <cstring>
-#include <vector>
-
-#include "msgbuf.h"
 
 #include <gmock/gmock.h>
 #include <gtest/gtest.h>
@@ -93,7 +93,7 @@
 
     struct pldm_file_df_open_resp resp_data = {};
 
-    PLDM_MSGBUF_DEFINE_P(buf);
+    PLDM_MSGBUF_RW_DEFINE_P(buf);
     int rc;
 
     static constexpr const size_t payload_length = PLDM_DF_OPEN_RESP_BYTES;
@@ -124,7 +124,7 @@
 
     struct pldm_file_df_open_resp resp_data = {};
 
-    PLDM_MSGBUF_DEFINE_P(buf);
+    PLDM_MSGBUF_RW_DEFINE_P(buf);
     int rc;
 
     static constexpr const size_t payload_length = PLDM_DF_OPEN_RESP_BYTES;
@@ -155,7 +155,7 @@
 
     struct pldm_file_df_open_resp resp_data = {};
 
-    PLDM_MSGBUF_DEFINE_P(buf);
+    PLDM_MSGBUF_RW_DEFINE_P(buf);
     int rc;
 
     static constexpr const size_t payload_length = PLDM_DF_OPEN_RESP_BYTES;
@@ -256,7 +256,7 @@
 
     struct pldm_file_df_close_resp resp_data = {};
 
-    PLDM_MSGBUF_DEFINE_P(buf);
+    PLDM_MSGBUF_RW_DEFINE_P(buf);
     int rc;
 
     static constexpr const size_t payload_length = PLDM_DF_CLOSE_RESP_BYTES;
@@ -285,7 +285,7 @@
 
     struct pldm_file_df_close_resp resp_data = {};
 
-    PLDM_MSGBUF_DEFINE_P(buf);
+    PLDM_MSGBUF_RW_DEFINE_P(buf);
     int rc;
 
     static constexpr const size_t payload_length = PLDM_DF_CLOSE_RESP_BYTES;
@@ -390,7 +390,7 @@
 
     struct pldm_file_df_heartbeat_resp resp_data = {};
 
-    PLDM_MSGBUF_DEFINE_P(buf);
+    PLDM_MSGBUF_RW_DEFINE_P(buf);
     int rc;
 
     static constexpr const size_t payload_length = PLDM_DF_HEARTBEAT_RESP_BYTES;
@@ -422,7 +422,7 @@
 
     struct pldm_file_df_heartbeat_resp resp_data = {};
 
-    PLDM_MSGBUF_DEFINE_P(buf);
+    PLDM_MSGBUF_RW_DEFINE_P(buf);
     int rc;
 
     static constexpr const size_t payload_length = PLDM_DF_HEARTBEAT_RESP_BYTES;
@@ -455,7 +455,7 @@
 
     struct pldm_file_df_heartbeat_resp resp_data = {};
 
-    PLDM_MSGBUF_DEFINE_P(buf);
+    PLDM_MSGBUF_RW_DEFINE_P(buf);
     int rc;
 
     static constexpr const size_t payload_length = PLDM_DF_HEARTBEAT_RESP_BYTES;
@@ -568,7 +568,7 @@
 
     struct pldm_file_df_open_req req_data = {};
 
-    PLDM_MSGBUF_DEFINE_P(buf);
+    PLDM_MSGBUF_RW_DEFINE_P(buf);
     int rc;
 
     static constexpr const size_t payload_length = PLDM_DF_OPEN_REQ_BYTES;
@@ -600,7 +600,7 @@
 
     struct pldm_file_df_open_req req_data = {};
 
-    PLDM_MSGBUF_DEFINE_P(buf);
+    PLDM_MSGBUF_RW_DEFINE_P(buf);
     int rc;
 
     static constexpr const size_t payload_length = PLDM_DF_OPEN_REQ_BYTES;
@@ -632,7 +632,7 @@
 
     struct pldm_file_df_open_req req_data = {};
 
-    PLDM_MSGBUF_DEFINE_P(buf);
+    PLDM_MSGBUF_RW_DEFINE_P(buf);
     int rc;
 
     static constexpr const size_t payload_length = PLDM_DF_OPEN_REQ_BYTES;
@@ -701,7 +701,7 @@
 
     struct pldm_file_df_close_req req_data = {};
 
-    PLDM_MSGBUF_DEFINE_P(buf);
+    PLDM_MSGBUF_RW_DEFINE_P(buf);
     int rc;
 
     static constexpr const size_t payload_length = PLDM_DF_CLOSE_REQ_BYTES;
@@ -733,7 +733,7 @@
 
     struct pldm_file_df_close_req req_data = {};
 
-    PLDM_MSGBUF_DEFINE_P(buf);
+    PLDM_MSGBUF_RW_DEFINE_P(buf);
     int rc;
 
     static constexpr const size_t payload_length = PLDM_DF_CLOSE_REQ_BYTES;
diff --git a/tests/dsp/firmware_update.cpp b/tests/dsp/firmware_update.cpp
index 6d4f5a6..0fbd693 100644
--- a/tests/dsp/firmware_update.cpp
+++ b/tests/dsp/firmware_update.cpp
@@ -1,3 +1,5 @@
+#include "msgbuf.hpp"
+
 #include <endian.h>
 #include <libpldm/base.h>
 #include <libpldm/firmware_update.h>
@@ -15,8 +17,6 @@
 #include <string_view>
 #include <vector>
 
-#include "msgbuf.h"
-
 #include <gmock/gmock.h>
 #include <gtest/gtest.h>
 
@@ -1687,7 +1687,7 @@
     std::array<uint8_t, hdrSize + PLDM_QUERY_DOWNSTREAM_DEVICES_RESP_BYTES>
         responseMsg{};
 
-    PLDM_MSGBUF_DEFINE_P(buf);
+    PLDM_MSGBUF_RW_DEFINE_P(buf);
     rc = pldm_msgbuf_init_errno(buf, 0, responseMsg.data() + hdrSize,
                                 responseMsg.size() - hdrSize);
     EXPECT_EQ(rc, 0);
@@ -1733,7 +1733,7 @@
     std::array<uint8_t, hdrSize + PLDM_QUERY_DOWNSTREAM_DEVICES_RESP_BYTES>
         responseMsg{};
 
-    PLDM_MSGBUF_DEFINE_P(buf);
+    PLDM_MSGBUF_RW_DEFINE_P(buf);
     rc = pldm_msgbuf_init_errno(buf, 0, responseMsg.data() + hdrSize,
                                 responseMsg.size() - hdrSize);
     ASSERT_EQ(rc, 0);
@@ -1772,7 +1772,7 @@
                             2 /* Inject error length*/>
         responseMsg{};
 
-    PLDM_MSGBUF_DEFINE_P(buf);
+    PLDM_MSGBUF_RW_DEFINE_P(buf);
     rc = pldm_msgbuf_init_errno(buf, 0, responseMsg.data() + hdrSize,
                                 responseMsg.size() - hdrSize);
     ASSERT_EQ(rc, 0);
@@ -1848,7 +1848,7 @@
     PLDM_MSG_DEFINE_P(response, PLDM_QUERY_DOWNSTREAM_IDENTIFIERS_RESP_MIN_LEN);
     struct pldm_query_downstream_identifiers_resp resp_data = {};
     struct pldm_downstream_device_iter devs;
-    PLDM_MSGBUF_DEFINE_P(buf);
+    PLDM_MSGBUF_RW_DEFINE_P(buf);
     int rc = 0;
 
     rc = pldm_msgbuf_init_errno(buf, 0, response->payload,
@@ -1890,7 +1890,7 @@
     struct pldm_query_downstream_identifiers_resp resp = {};
     struct pldm_downstream_device_iter devs;
     struct pldm_downstream_device dev;
-    PLDM_MSGBUF_DEFINE_P(buf);
+    PLDM_MSGBUF_RW_DEFINE_P(buf);
     int rc = 0;
 
     rc = pldm_msgbuf_init_errno(buf, 0, response->payload,
@@ -1932,7 +1932,7 @@
     PLDM_MSG_DEFINE_P(response, payloadLen);
     struct pldm_downstream_device_iter devs;
     struct pldm_downstream_device dev;
-    PLDM_MSGBUF_DEFINE_P(buf);
+    PLDM_MSGBUF_RW_DEFINE_P(buf);
     int rc = 0;
 
     rc = pldm_msgbuf_init_errno(buf, 0, response->payload, payloadLen);
@@ -2020,7 +2020,7 @@
     PLDM_MSG_DEFINE_P(response, payloadLen);
     struct pldm_downstream_device_iter devs;
     struct pldm_downstream_device dev;
-    PLDM_MSGBUF_DEFINE_P(buf);
+    PLDM_MSGBUF_RW_DEFINE_P(buf);
     int rc = 0;
 
     rc = pldm_msgbuf_init_errno(buf, 0, response->payload, payloadLen);
@@ -2130,7 +2130,7 @@
     PLDM_MSG_DEFINE_P(response, payloadLen);
     struct pldm_downstream_device_iter devs;
     struct pldm_downstream_device dev;
-    PLDM_MSGBUF_DEFINE_P(buf);
+    PLDM_MSGBUF_RW_DEFINE_P(buf);
     int rc = 0;
 
     rc = pldm_msgbuf_init_errno(buf, 0, response->payload, payloadLen);
@@ -2245,7 +2245,7 @@
     PLDM_MSG_DEFINE_P(response, payloadLen);
     struct pldm_downstream_device_iter devs;
     struct pldm_downstream_device dev;
-    PLDM_MSGBUF_DEFINE_P(buf);
+    PLDM_MSGBUF_RW_DEFINE_P(buf);
     int rc = 0;
 
     rc = pldm_msgbuf_init_errno(buf, 0, response->payload, payloadLen);
@@ -2377,7 +2377,7 @@
     struct pldm_query_downstream_identifiers_resp resp_data = {};
     struct pldm_downstream_device_iter devs;
     PLDM_MSG_DEFINE_P(response, payloadLen);
-    PLDM_MSGBUF_DEFINE_P(buf);
+    PLDM_MSGBUF_RW_DEFINE_P(buf);
     void* devicesStart = NULL;
     size_t devicesLen;
     int rc = 0;
@@ -2421,7 +2421,7 @@
     struct pldm_query_downstream_identifiers_resp resp_data = {};
     struct pldm_downstream_device_iter devs;
     PLDM_MSG_DEFINE_P(response, payloadLen);
-    PLDM_MSGBUF_DEFINE_P(buf);
+    PLDM_MSGBUF_RW_DEFINE_P(buf);
     int rc = 0;
 
     rc = pldm_msgbuf_init_errno(buf, 0, response->payload, payloadLen);
@@ -2516,7 +2516,7 @@
         downstreamDeviceParamTableLen;
 
     PLDM_MSG_DEFINE_P(response, payload_len);
-    PLDM_MSGBUF_DEFINE_P(buf);
+    PLDM_MSGBUF_RW_DEFINE_P(buf);
     int rc = 0;
 
     rc = pldm_msgbuf_init_errno(buf, 0, response->payload, payload_len);
@@ -2625,7 +2625,7 @@
         downstreamDeviceParamTableLen;
 
     PLDM_MSG_DEFINE_P(response, payload_len);
-    PLDM_MSGBUF_DEFINE_P(buf);
+    PLDM_MSGBUF_RW_DEFINE_P(buf);
     int rc = 0;
 
     rc = pldm_msgbuf_init_errno(buf, 0, response->payload, payload_len);
@@ -2788,7 +2788,7 @@
 
     int rc = 0;
 
-    PLDM_MSGBUF_DEFINE_P(buf);
+    PLDM_MSGBUF_RW_DEFINE_P(buf);
     rc = pldm_msgbuf_init_errno(buf, 0, responseMsg.data() + hdrSize,
                                 responseMsg.size() - hdrSize);
     ASSERT_EQ(rc, 0);
diff --git a/tests/dsp/pdr.cpp b/tests/dsp/pdr.cpp
index 0cd95dc..148e56f 100644
--- a/tests/dsp/pdr.cpp
+++ b/tests/dsp/pdr.cpp
@@ -1,7 +1,8 @@
+#include "msgbuf.hpp"
+
 #include <endian.h>
 #include <libpldm/pdr.h>
 #include <libpldm/platform.h>
-#include <msgbuf.h>
 
 #include <array>
 #include <cstdint>
@@ -46,7 +47,7 @@
     }
 } pldm_entity_test;
 
-static void getEntity(struct pldm_msgbuf* buf, pldm_entity_test& entity)
+static void getEntity(struct pldm_msgbuf_ro* buf, pldm_entity_test& entity)
 {
     pldm_msgbuf_extract_uint16(buf, entity.entity_type);
     pldm_msgbuf_extract_uint16(buf, entity.entity_instance_num);
@@ -54,7 +55,7 @@
 }
 
 static void
-    getAssociationPdrDetails(struct pldm_msgbuf* buf,
+    getAssociationPdrDetails(struct pldm_msgbuf_ro* buf,
                              pldm_association_pdr_test& association_pdr_test)
 {
     pldm_msgbuf_extract_uint32(buf, association_pdr_test.record_handle);
@@ -68,7 +69,7 @@
 }
 
 static void
-    verifyEntityAssociationPdr(struct pldm_msgbuf* buf,
+    verifyEntityAssociationPdr(struct pldm_msgbuf_ro* buf,
                                const pldm_association_pdr_test& association_pdr,
                                const pldm_entity_test& container_entity1,
                                const pldm_entity_test& child_entity1)
@@ -1766,8 +1767,8 @@
 
     pldm_pdr_find_record(repo, currRecHandle, &data, &size, &nextRecHandle);
 
-    struct pldm_msgbuf _buf;
-    struct pldm_msgbuf* buf = &_buf;
+    struct pldm_msgbuf_ro _buf;
+    struct pldm_msgbuf_ro* buf = &_buf;
 
     auto rc =
         pldm_msgbuf_init_errno(buf,
diff --git a/tests/dsp/platform.cpp b/tests/dsp/platform.cpp
index 13a3229..3b202f1 100644
--- a/tests/dsp/platform.cpp
+++ b/tests/dsp/platform.cpp
@@ -1,3 +1,5 @@
+#include "msgbuf.hpp"
+
 #include <endian.h>
 #include <libpldm/base.h>
 #include <libpldm/entity.h>
@@ -11,8 +13,6 @@
 #include <cstring>
 #include <vector>
 
-#include "msgbuf.h"
-
 #include <gtest/gtest.h>
 
 constexpr auto hdrSize = sizeof(pldm_msg_hdr);
@@ -468,10 +468,10 @@
     alignas(pldm_msg) unsigned char data[sizeof(pldm_msg_hdr) +
                                          PLDM_GET_PDR_MIN_RESP_BYTES +
                                          sizeof(recordData) - 1 + 1];
-    PLDM_MSGBUF_DEFINE_P(buf);
+    PLDM_MSGBUF_RW_DEFINE_P(buf);
     int rc;
 
-    pldm_msg* msg = new (data) pldm_msg;
+    pldm_msg* msg = new (data) pldm_msg();
 
     rc = pldm_msgbuf_init_errno(buf, PLDM_GET_PDR_MIN_RESP_BYTES, msg->payload,
                                 sizeof(data) - sizeof(msg->hdr));
@@ -729,10 +729,10 @@
         data[sizeof(pldm_msg_hdr) + PLDM_GET_PDR_REPOSITORY_INFO_RESP_BYTES];
     uint8_t updateTime[PLDM_TIMESTAMP104_SIZE] = {0};
     uint8_t oemUpdateTime[PLDM_TIMESTAMP104_SIZE] = {0};
-    PLDM_MSGBUF_DEFINE_P(buf);
+    PLDM_MSGBUF_RW_DEFINE_P(buf);
     int rc;
 
-    pldm_msg* msg = new (data) pldm_msg;
+    pldm_msg* msg = new (data) pldm_msg();
 
     rc = pldm_msgbuf_init_errno(buf, PLDM_GET_PDR_REPOSITORY_INFO_RESP_BYTES,
                                 msg->payload, sizeof(data) - sizeof(msg->hdr));
@@ -1485,7 +1485,7 @@
         PLDM_POLL_FOR_PLATFORM_EVENT_MESSAGE_REQ_BYTES);
     EXPECT_EQ(rc, PLDM_SUCCESS);
 
-    PLDM_MSGBUF_DEFINE_P(buf);
+    PLDM_MSGBUF_RO_DEFINE_P(buf);
     rc = pldm_msgbuf_init_errno(
         buf, PLDM_POLL_FOR_PLATFORM_EVENT_MESSAGE_REQ_BYTES, request->payload,
         PLDM_POLL_FOR_PLATFORM_EVENT_MESSAGE_REQ_BYTES);
@@ -1523,7 +1523,7 @@
         PLDM_POLL_FOR_PLATFORM_EVENT_MESSAGE_REQ_BYTES);
     EXPECT_EQ(rc, PLDM_SUCCESS);
 
-    PLDM_MSGBUF_DEFINE_P(buf);
+    PLDM_MSGBUF_RO_DEFINE_P(buf);
     rc = pldm_msgbuf_init_errno(
         buf, PLDM_POLL_FOR_PLATFORM_EVENT_MESSAGE_REQ_BYTES, request->payload,
         PLDM_POLL_FOR_PLATFORM_EVENT_MESSAGE_REQ_BYTES);
@@ -1561,7 +1561,7 @@
         PLDM_POLL_FOR_PLATFORM_EVENT_MESSAGE_REQ_BYTES);
     EXPECT_EQ(rc, PLDM_SUCCESS);
 
-    PLDM_MSGBUF_DEFINE_P(buf);
+    PLDM_MSGBUF_RO_DEFINE_P(buf);
     rc = pldm_msgbuf_init_errno(
         buf, PLDM_POLL_FOR_PLATFORM_EVENT_MESSAGE_REQ_BYTES, request->payload,
         PLDM_POLL_FOR_PLATFORM_EVENT_MESSAGE_REQ_BYTES);
@@ -2033,7 +2033,7 @@
         eventDataIntegrityChecksum, response, payloadLength);
     EXPECT_EQ(rc, PLDM_SUCCESS);
 
-    PLDM_MSGBUF_DEFINE_P(buf);
+    PLDM_MSGBUF_RO_DEFINE_P(buf);
     rc = pldm_msgbuf_init_errno(
         buf, PLDM_POLL_FOR_PLATFORM_EVENT_MESSAGE_MIN_RESP_BYTES,
         response->payload, payloadLength);
@@ -2092,7 +2092,7 @@
         response, payloadLength);
     EXPECT_EQ(rc, PLDM_SUCCESS);
 
-    PLDM_MSGBUF_DEFINE_P(buf);
+    PLDM_MSGBUF_RO_DEFINE_P(buf);
     rc = pldm_msgbuf_init_errno(
         buf, PLDM_POLL_FOR_PLATFORM_EVENT_MESSAGE_MIN_RESP_BYTES,
         response->payload, payloadLength);
@@ -2131,7 +2131,7 @@
         response, payloadLength);
     EXPECT_EQ(rc, PLDM_SUCCESS);
 
-    PLDM_MSGBUF_DEFINE_P(buf);
+    PLDM_MSGBUF_RO_DEFINE_P(buf);
     rc = pldm_msgbuf_init_errno(
         buf, PLDM_POLL_FOR_PLATFORM_EVENT_MESSAGE_MIN_RESP_BYTES,
         response->payload, payloadLength);
@@ -2179,7 +2179,7 @@
         eventDataIntegrityChecksum, response, payloadLength);
     EXPECT_EQ(rc, PLDM_SUCCESS);
 
-    PLDM_MSGBUF_DEFINE_P(buf);
+    PLDM_MSGBUF_RO_DEFINE_P(buf);
     rc = pldm_msgbuf_init_errno(
         buf, PLDM_POLL_FOR_PLATFORM_EVENT_MESSAGE_MIN_RESP_BYTES,
         response->payload, payloadLength);
@@ -2346,9 +2346,9 @@
     static constexpr const uint8_t eventData = 34;
     static constexpr const uint8_t Tid = 0x03;
     struct pldm_platform_event_message_req req;
-    PLDM_MSGBUF_DEFINE_P(buf);
+    PLDM_MSGBUF_RO_DEFINE_P(buf);
+    const void* data;
     size_t len;
-    void* data;
 
     PLDM_MSG_DEFINE_P(request, PLDM_PLATFORM_EVENT_MESSAGE_MIN_REQ_BYTES +
                                    sizeof(eventData));
@@ -2673,7 +2673,7 @@
 
     EXPECT_EQ(rc, PLDM_SUCCESS);
 
-    PLDM_MSGBUF_DEFINE_P(buf);
+    PLDM_MSGBUF_RO_DEFINE_P(buf);
 
     rc = pldm_msgbuf_init_errno(
         buf, PLDM_MSG_POLL_EVENT_LENGTH,
diff --git a/tests/fuzz/fd-fuzz.cpp b/tests/fuzz/fd-fuzz.cpp
index 9049ab8..258c27e 100644
--- a/tests/fuzz/fd-fuzz.cpp
+++ b/tests/fuzz/fd-fuzz.cpp
@@ -5,6 +5,8 @@
 #undef NDEBUG
 #endif
 
+#include "msgbuf.hpp"
+
 #include <libpldm/base.h>
 #include <libpldm/firmware_fd.h>
 #include <libpldm/firmware_update.h>
@@ -17,7 +19,6 @@
 #include <vector>
 
 #include "array.h"
-#include "msgbuf.h"
 
 /* Avoid out-of-memory, and
  * avoid wasting time on inputs larger than MCTP message limits */
@@ -48,7 +49,7 @@
 
 struct fuzz_ops_ctx
 {
-    struct pldm_msgbuf* fuzz_ctrl;
+    struct pldm_msgbuf_ro* fuzz_ctrl;
 
     /* Details of in-progress update, for consistency checking */
     bool current_update;
@@ -64,7 +65,7 @@
 /* Returns true with roughly `percent` chance */
 static bool fuzz_chance(struct fuzz_ops_ctx* ctx, uint8_t percent)
 {
-    uint8_t v;
+    uint8_t v = 0;
     assert(percent <= 100);
     int rc = pldm_msgbuf_extract_uint8(ctx->fuzz_ctrl, v);
     if (rc != 0)
@@ -368,8 +369,8 @@
 
 extern "C" int LLVMFuzzerTestOneInput(uint8_t* input, size_t len)
 {
-    PLDM_MSGBUF_DEFINE_P(fuzzproto);
-    PLDM_MSGBUF_DEFINE_P(fuzzctrl);
+    PLDM_MSGBUF_RO_DEFINE_P(fuzzproto);
+    PLDM_MSGBUF_RO_DEFINE_P(fuzzctrl);
     int rc;
 
     /* Split input into two parts. First FUZZCTRL_SIZE (0x400 bytes currently)
@@ -397,7 +398,7 @@
     while (true)
     {
         /* Arbitrary length send buffer */
-        uint32_t send_len;
+        uint32_t send_len = 0;
         rc = pldm_msgbuf_extract_uint32(fuzzctrl, send_len);
         if (rc)
         {
diff --git a/tests/meson.build b/tests/meson.build
index 0c3bc2b..7ded005 100644
--- a/tests/meson.build
+++ b/tests/meson.build
@@ -12,7 +12,10 @@
     gmock_dep = gtest_proj.dependency('gmock')
 endif
 
-test_include_dirs = [libpldm_include_dir, include_directories('../src')]
+test_include_dirs = [
+    libpldm_include_dir,
+    include_directories('../src', '../tests'),
+]
 
 tests = ['instance-id', 'msgbuf', 'responder', 'utils']
 
diff --git a/tests/msgbuf.cpp b/tests/msgbuf.cpp
index 67064fc..992475b 100644
--- a/tests/msgbuf.cpp
+++ b/tests/msgbuf.cpp
@@ -10,12 +10,12 @@
 #define NDEBUG 1
 #endif
 
-#include "msgbuf.h"
+#include "msgbuf.hpp"
 
 TEST(msgbuf, init_bad_minsize)
 {
-    struct pldm_msgbuf _ctx;
-    struct pldm_msgbuf* ctx = &_ctx;
+    struct pldm_msgbuf_rw _ctx;
+    struct pldm_msgbuf_rw* ctx = &_ctx;
     uint8_t buf[1] = {};
 
     EXPECT_NE(pldm_msgbuf_init_errno(ctx, sizeof(buf) + 1U, buf, sizeof(buf)),
@@ -24,8 +24,8 @@
 
 TEST(msgbuf, init_bad_len)
 {
-    struct pldm_msgbuf _ctx;
-    struct pldm_msgbuf* ctx = &_ctx;
+    struct pldm_msgbuf_rw _ctx;
+    struct pldm_msgbuf_rw* ctx = &_ctx;
     uint8_t buf[1] = {};
 
     EXPECT_NE(pldm_msgbuf_init_errno(ctx, sizeof(buf), buf, SIZE_MAX), 0);
@@ -33,8 +33,8 @@
 
 TEST(msgbuf, init_overflow)
 {
-    struct pldm_msgbuf _ctx;
-    struct pldm_msgbuf* ctx = &_ctx;
+    struct pldm_msgbuf_rw _ctx;
+    struct pldm_msgbuf_rw* ctx = &_ctx;
     // NOLINTNEXTLINE(performance-no-int-to-ptr)
     void* buf = (void*)UINTPTR_MAX;
 
@@ -43,8 +43,8 @@
 
 TEST(msgbuf, init_success)
 {
-    struct pldm_msgbuf _ctx;
-    struct pldm_msgbuf* ctx = &_ctx;
+    struct pldm_msgbuf_rw _ctx;
+    struct pldm_msgbuf_rw* ctx = &_ctx;
     uint8_t buf[1] = {};
 
     EXPECT_EQ(pldm_msgbuf_init_errno(ctx, sizeof(buf), buf, sizeof(buf)), 0);
@@ -52,8 +52,8 @@
 
 TEST(msgbuf, destroy_none)
 {
-    struct pldm_msgbuf _ctx;
-    struct pldm_msgbuf* ctx = &_ctx;
+    struct pldm_msgbuf_rw _ctx;
+    struct pldm_msgbuf_rw* ctx = &_ctx;
     uint8_t buf[1] = {};
 
     ASSERT_EQ(pldm_msgbuf_init_errno(ctx, sizeof(buf), buf, sizeof(buf)), 0);
@@ -62,8 +62,8 @@
 
 TEST(msgbuf, destroy_exact)
 {
-    struct pldm_msgbuf _ctx;
-    struct pldm_msgbuf* ctx = &_ctx;
+    struct pldm_msgbuf_ro _ctx;
+    struct pldm_msgbuf_ro* ctx = &_ctx;
     uint8_t buf[1] = {0xa5};
     uint8_t val;
 
@@ -75,8 +75,8 @@
 
 TEST(msgbuf, destroy_over)
 {
-    struct pldm_msgbuf _ctx;
-    struct pldm_msgbuf* ctx = &_ctx;
+    struct pldm_msgbuf_ro _ctx;
+    struct pldm_msgbuf_ro* ctx = &_ctx;
     uint8_t buf[1] = {0xa5};
     uint8_t val;
 
@@ -89,8 +89,8 @@
 
 TEST(msgbuf, destroy_under)
 {
-    struct pldm_msgbuf _ctx;
-    struct pldm_msgbuf* ctx = &_ctx;
+    struct pldm_msgbuf_ro _ctx;
+    struct pldm_msgbuf_ro* ctx = &_ctx;
     uint8_t buf[2] = {0x5a, 0xa5};
     uint8_t val;
 
@@ -102,8 +102,8 @@
 
 TEST(msgbuf, extract_one_uint8)
 {
-    struct pldm_msgbuf _ctx;
-    struct pldm_msgbuf* ctx = &_ctx;
+    struct pldm_msgbuf_ro _ctx;
+    struct pldm_msgbuf_ro* ctx = &_ctx;
     uint8_t buf[1] = {0xa5};
     uint8_t val;
 
@@ -115,8 +115,8 @@
 
 TEST(msgbuf, extract_over_uint8)
 {
-    struct pldm_msgbuf _ctx;
-    struct pldm_msgbuf* ctx = &_ctx;
+    struct pldm_msgbuf_ro _ctx;
+    struct pldm_msgbuf_ro* ctx = &_ctx;
     uint8_t buf[1] = {};
     uint8_t val;
 
@@ -127,8 +127,8 @@
 
 TEST(msgbuf, extract_under_uint8)
 {
-    struct pldm_msgbuf _ctx;
-    struct pldm_msgbuf* ctx = &_ctx;
+    struct pldm_msgbuf_ro _ctx;
+    struct pldm_msgbuf_ro* ctx = &_ctx;
 
     uint8_t buf[1] = {};
     uint8_t val;
@@ -141,8 +141,8 @@
 
 TEST(msgbuf, extract_one_int8)
 {
-    struct pldm_msgbuf _ctx;
-    struct pldm_msgbuf* ctx = &_ctx;
+    struct pldm_msgbuf_ro _ctx;
+    struct pldm_msgbuf_ro* ctx = &_ctx;
     int8_t buf[1] = {-1};
     int8_t val;
 
@@ -154,8 +154,8 @@
 
 TEST(msgbuf, extract_over_int8)
 {
-    struct pldm_msgbuf _ctx;
-    struct pldm_msgbuf* ctx = &_ctx;
+    struct pldm_msgbuf_ro _ctx;
+    struct pldm_msgbuf_ro* ctx = &_ctx;
     int8_t buf[1] = {};
     int8_t val;
 
@@ -166,8 +166,8 @@
 
 TEST(msgbuf, extract_under_int8)
 {
-    struct pldm_msgbuf _ctx;
-    struct pldm_msgbuf* ctx = &_ctx;
+    struct pldm_msgbuf_ro _ctx;
+    struct pldm_msgbuf_ro* ctx = &_ctx;
 
     uint8_t buf[1] = {};
     int8_t val;
@@ -180,8 +180,8 @@
 
 TEST(msgbuf, extract_one_uint16)
 {
-    struct pldm_msgbuf _ctx;
-    struct pldm_msgbuf* ctx = &_ctx;
+    struct pldm_msgbuf_ro _ctx;
+    struct pldm_msgbuf_ro* ctx = &_ctx;
     uint16_t buf[1] = {htole16(0x5aa5)};
     uint16_t val = {};
 
@@ -193,8 +193,8 @@
 
 TEST(msgbuf, extract_under_uint16)
 {
-    struct pldm_msgbuf _ctx;
-    struct pldm_msgbuf* ctx = &_ctx;
+    struct pldm_msgbuf_ro _ctx;
+    struct pldm_msgbuf_ro* ctx = &_ctx;
 
     uint16_t buf[1] = {};
     uint16_t val;
@@ -207,8 +207,8 @@
 
 TEST(msgbuf, extract_over_uint16)
 {
-    struct pldm_msgbuf _ctx;
-    struct pldm_msgbuf* ctx = &_ctx;
+    struct pldm_msgbuf_ro _ctx;
+    struct pldm_msgbuf_ro* ctx = &_ctx;
     uint16_t buf[1] = {};
     uint16_t val;
 
@@ -219,8 +219,8 @@
 
 TEST(msgbuf, extract_one_int16)
 {
-    struct pldm_msgbuf _ctx;
-    struct pldm_msgbuf* ctx = &_ctx;
+    struct pldm_msgbuf_ro _ctx;
+    struct pldm_msgbuf_ro* ctx = &_ctx;
     int16_t buf[1] = {(int16_t)(htole16((uint16_t)INT16_MIN))};
     int16_t val;
 
@@ -232,8 +232,8 @@
 
 TEST(msgbuf, extract_over_int16)
 {
-    struct pldm_msgbuf _ctx;
-    struct pldm_msgbuf* ctx = &_ctx;
+    struct pldm_msgbuf_ro _ctx;
+    struct pldm_msgbuf_ro* ctx = &_ctx;
     int16_t buf[1] = {};
     int16_t val;
 
@@ -244,8 +244,8 @@
 
 TEST(msgbuf, extract_under_int16)
 {
-    struct pldm_msgbuf _ctx;
-    struct pldm_msgbuf* ctx = &_ctx;
+    struct pldm_msgbuf_ro _ctx;
+    struct pldm_msgbuf_ro* ctx = &_ctx;
 
     int16_t buf[1] = {};
     int16_t val;
@@ -258,8 +258,8 @@
 
 TEST(msgbuf, extract_one_uint32)
 {
-    struct pldm_msgbuf _ctx;
-    struct pldm_msgbuf* ctx = &_ctx;
+    struct pldm_msgbuf_ro _ctx;
+    struct pldm_msgbuf_ro* ctx = &_ctx;
     uint32_t buf[1] = {htole32(0x5a00ffa5)};
     uint32_t val;
 
@@ -271,8 +271,8 @@
 
 TEST(msgbuf, extract_over_uint32)
 {
-    struct pldm_msgbuf _ctx;
-    struct pldm_msgbuf* ctx = &_ctx;
+    struct pldm_msgbuf_ro _ctx;
+    struct pldm_msgbuf_ro* ctx = &_ctx;
     uint32_t buf[1] = {};
     uint32_t val;
 
@@ -283,8 +283,8 @@
 
 TEST(msgbuf, extract_under_uint32)
 {
-    struct pldm_msgbuf _ctx;
-    struct pldm_msgbuf* ctx = &_ctx;
+    struct pldm_msgbuf_ro _ctx;
+    struct pldm_msgbuf_ro* ctx = &_ctx;
 
     uint32_t buf[1] = {};
     uint32_t val;
@@ -297,8 +297,8 @@
 
 TEST(msgbuf, extract_one_int32)
 {
-    struct pldm_msgbuf _ctx;
-    struct pldm_msgbuf* ctx = &_ctx;
+    struct pldm_msgbuf_ro _ctx;
+    struct pldm_msgbuf_ro* ctx = &_ctx;
     int32_t buf[1] = {(int32_t)(htole32((uint32_t)(INT32_MIN)))};
     int32_t val;
 
@@ -310,8 +310,8 @@
 
 TEST(msgbuf, extract_over_int32)
 {
-    struct pldm_msgbuf _ctx;
-    struct pldm_msgbuf* ctx = &_ctx;
+    struct pldm_msgbuf_ro _ctx;
+    struct pldm_msgbuf_ro* ctx = &_ctx;
     int32_t buf[1] = {};
     int32_t val;
 
@@ -322,8 +322,8 @@
 
 TEST(msgbuf, extract_under_int32)
 {
-    struct pldm_msgbuf _ctx;
-    struct pldm_msgbuf* ctx = &_ctx;
+    struct pldm_msgbuf_ro _ctx;
+    struct pldm_msgbuf_ro* ctx = &_ctx;
 
     int32_t buf[1] = {};
     int32_t val;
@@ -336,8 +336,8 @@
 
 TEST(msgbuf, extract_one_real32)
 {
-    struct pldm_msgbuf _ctx;
-    struct pldm_msgbuf* ctx = &_ctx;
+    struct pldm_msgbuf_ro _ctx;
+    struct pldm_msgbuf_ro* ctx = &_ctx;
     uint32_t buf[1] = {};
     uint32_t xform;
     real32_t val;
@@ -355,8 +355,8 @@
 
 TEST(msgbuf, extract_over_real32)
 {
-    struct pldm_msgbuf _ctx;
-    struct pldm_msgbuf* ctx = &_ctx;
+    struct pldm_msgbuf_ro _ctx;
+    struct pldm_msgbuf_ro* ctx = &_ctx;
     real32_t buf[1] = {};
     real32_t val;
 
@@ -367,8 +367,8 @@
 
 TEST(msgbuf, extract_under_real32)
 {
-    struct pldm_msgbuf _ctx;
-    struct pldm_msgbuf* ctx = &_ctx;
+    struct pldm_msgbuf_ro _ctx;
+    struct pldm_msgbuf_ro* ctx = &_ctx;
 
     real32_t buf[1] = {};
     real32_t val;
@@ -381,8 +381,8 @@
 
 TEST(msgbuf, extract_array_uint8_buf0_req0)
 {
-    struct pldm_msgbuf _ctx;
-    struct pldm_msgbuf* ctx = &_ctx;
+    struct pldm_msgbuf_ro _ctx;
+    struct pldm_msgbuf_ro* ctx = &_ctx;
     uint8_t buf[1] = {};
     uint8_t arr[1];
 
@@ -393,8 +393,8 @@
 
 TEST(msgbuf, extract_array_uint8_buf1_req1)
 {
-    struct pldm_msgbuf _ctx;
-    struct pldm_msgbuf* ctx = &_ctx;
+    struct pldm_msgbuf_ro _ctx;
+    struct pldm_msgbuf_ro* ctx = &_ctx;
     uint8_t buf[1] = {};
     uint8_t arr[1];
 
@@ -407,8 +407,8 @@
 
 TEST(msgbuf, extract_array_uint8_buf1_req2)
 {
-    struct pldm_msgbuf _ctx;
-    struct pldm_msgbuf* ctx = &_ctx;
+    struct pldm_msgbuf_ro _ctx;
+    struct pldm_msgbuf_ro* ctx = &_ctx;
     uint8_t buf[1] = {};
     uint8_t arr[2];
 
@@ -420,8 +420,8 @@
 
 TEST(msgbuf, extract_under_array_uint8)
 {
-    struct pldm_msgbuf _ctx;
-    struct pldm_msgbuf* ctx = &_ctx;
+    struct pldm_msgbuf_ro _ctx;
+    struct pldm_msgbuf_ro* ctx = &_ctx;
     uint8_t buf[1] = {};
     uint8_t arr[1];
 
@@ -433,8 +433,8 @@
 
 TEST(msgbuf, extract_array_char_buf0_req0)
 {
-    struct pldm_msgbuf _ctx;
-    struct pldm_msgbuf* ctx = &_ctx;
+    struct pldm_msgbuf_ro _ctx;
+    struct pldm_msgbuf_ro* ctx = &_ctx;
     char buf[1] = {'\0'};
     char arr[1] = {'1'};
 
@@ -445,8 +445,8 @@
 
 TEST(msgbuf, extract_array_char_buf1_req1)
 {
-    struct pldm_msgbuf _ctx;
-    struct pldm_msgbuf* ctx = &_ctx;
+    struct pldm_msgbuf_ro _ctx;
+    struct pldm_msgbuf_ro* ctx = &_ctx;
     char buf[1] = {'\0'};
     char arr[1] = {'1'};
 
@@ -459,8 +459,8 @@
 
 TEST(msgbuf, extract_array_char_buf1_req2)
 {
-    struct pldm_msgbuf _ctx;
-    struct pldm_msgbuf* ctx = &_ctx;
+    struct pldm_msgbuf_ro _ctx;
+    struct pldm_msgbuf_ro* ctx = &_ctx;
     char buf[1] = {'\0'};
     char arr[2] = {'1', '2'};
 
@@ -472,8 +472,8 @@
 
 TEST(msgbuf, extract_under_array_char)
 {
-    struct pldm_msgbuf _ctx;
-    struct pldm_msgbuf* ctx = &_ctx;
+    struct pldm_msgbuf_ro _ctx;
+    struct pldm_msgbuf_ro* ctx = &_ctx;
     char buf[1] = {'\0'};
     char arr[1] = {'1'};
 
@@ -485,8 +485,8 @@
 
 TEST(msgbuf, consumed_under)
 {
-    struct pldm_msgbuf _ctx;
-    struct pldm_msgbuf* ctx = &_ctx;
+    struct pldm_msgbuf_rw _ctx;
+    struct pldm_msgbuf_rw* ctx = &_ctx;
     uint8_t buf[1] = {};
 
     ASSERT_EQ(pldm_msgbuf_init_errno(ctx, 0, buf, sizeof(buf)), 0);
@@ -495,8 +495,8 @@
 
 TEST(msgbuf, consumed_exact)
 {
-    struct pldm_msgbuf _ctx;
-    struct pldm_msgbuf* ctx = &_ctx;
+    struct pldm_msgbuf_ro _ctx;
+    struct pldm_msgbuf_ro* ctx = &_ctx;
     uint8_t buf[1] = {};
     uint8_t val;
 
@@ -507,8 +507,8 @@
 
 TEST(msgbuf, consumed_over)
 {
-    struct pldm_msgbuf _ctx;
-    struct pldm_msgbuf* ctx = &_ctx;
+    struct pldm_msgbuf_ro _ctx;
+    struct pldm_msgbuf_ro* ctx = &_ctx;
     uint8_t buf[1] = {};
     uint8_t valid;
     uint8_t invalid;
@@ -521,8 +521,8 @@
 
 TEST(msgbuf, pldm_msgbuf_insert_int32_good)
 {
-    struct pldm_msgbuf _ctx;
-    struct pldm_msgbuf* ctx = &_ctx;
+    struct pldm_msgbuf_rw _ctx;
+    struct pldm_msgbuf_rw* ctx = &_ctx;
     int32_t src = -12345;
     int32_t checkVal = 0;
     uint8_t buf[sizeof(int32_t)] = {};
@@ -530,8 +530,8 @@
     ASSERT_EQ(pldm_msgbuf_init_errno(ctx, 0, buf, sizeof(buf)), 0);
     EXPECT_EQ(pldm_msgbuf_insert_int32(ctx, src), 0);
 
-    struct pldm_msgbuf _ctxExtract;
-    struct pldm_msgbuf* ctxExtract = &_ctxExtract;
+    struct pldm_msgbuf_ro _ctxExtract;
+    struct pldm_msgbuf_ro* ctxExtract = &_ctxExtract;
 
     ASSERT_EQ(pldm_msgbuf_init_errno(ctxExtract, 0, buf, sizeof(buf)), 0);
     EXPECT_EQ(pldm_msgbuf_extract_int32(ctxExtract, checkVal), 0);
@@ -543,8 +543,8 @@
 
 TEST(msgbuf, insert_under_int32)
 {
-    struct pldm_msgbuf _ctx;
-    struct pldm_msgbuf* ctx = &_ctx;
+    struct pldm_msgbuf_rw _ctx;
+    struct pldm_msgbuf_rw* ctx = &_ctx;
 
     int32_t buf[1] = {};
     int32_t val = 0;
@@ -557,8 +557,8 @@
 
 TEST(msgbuf, pldm_msgbuf_insert_uint32_good)
 {
-    struct pldm_msgbuf _ctx;
-    struct pldm_msgbuf* ctx = &_ctx;
+    struct pldm_msgbuf_rw _ctx;
+    struct pldm_msgbuf_rw* ctx = &_ctx;
     uint32_t src = 0xf1223344;
     uint32_t checkVal = 0;
     uint8_t buf[sizeof(uint32_t)] = {};
@@ -566,8 +566,8 @@
     ASSERT_EQ(pldm_msgbuf_init_errno(ctx, 0, buf, sizeof(buf)), 0);
     EXPECT_EQ(pldm_msgbuf_insert_uint32(ctx, src), 0);
 
-    struct pldm_msgbuf _ctxExtract;
-    struct pldm_msgbuf* ctxExtract = &_ctxExtract;
+    struct pldm_msgbuf_ro _ctxExtract;
+    struct pldm_msgbuf_ro* ctxExtract = &_ctxExtract;
 
     ASSERT_EQ(pldm_msgbuf_init_errno(ctxExtract, 0, buf, sizeof(buf)), 0);
     EXPECT_EQ(pldm_msgbuf_extract_uint32(ctxExtract, checkVal), 0);
@@ -579,8 +579,8 @@
 
 TEST(msgbuf, insert_under_uint32)
 {
-    struct pldm_msgbuf _ctx;
-    struct pldm_msgbuf* ctx = &_ctx;
+    struct pldm_msgbuf_rw _ctx;
+    struct pldm_msgbuf_rw* ctx = &_ctx;
 
     uint32_t buf[1] = {};
     uint32_t val = 0;
@@ -593,8 +593,8 @@
 
 TEST(msgbuf, pldm_msgbuf_insert_uint16_good)
 {
-    struct pldm_msgbuf _ctx;
-    struct pldm_msgbuf* ctx = &_ctx;
+    struct pldm_msgbuf_rw _ctx;
+    struct pldm_msgbuf_rw* ctx = &_ctx;
     uint16_t src = 0xf344;
     uint16_t checkVal = 0;
     uint8_t buf[sizeof(uint16_t)] = {};
@@ -602,8 +602,8 @@
     ASSERT_EQ(pldm_msgbuf_init_errno(ctx, 0, buf, sizeof(uint16_t)), 0);
     EXPECT_EQ(pldm_msgbuf_insert_uint16(ctx, src), 0);
 
-    struct pldm_msgbuf _ctxExtract;
-    struct pldm_msgbuf* ctxExtract = &_ctxExtract;
+    struct pldm_msgbuf_ro _ctxExtract;
+    struct pldm_msgbuf_ro* ctxExtract = &_ctxExtract;
 
     ASSERT_EQ(pldm_msgbuf_init_errno(ctxExtract, 0, buf, sizeof(buf)), 0);
     EXPECT_EQ(pldm_msgbuf_extract_uint16(ctxExtract, checkVal), 0);
@@ -615,8 +615,8 @@
 
 TEST(msgbuf, insert_under_uint16)
 {
-    struct pldm_msgbuf _ctx;
-    struct pldm_msgbuf* ctx = &_ctx;
+    struct pldm_msgbuf_rw _ctx;
+    struct pldm_msgbuf_rw* ctx = &_ctx;
 
     uint16_t buf[1] = {};
     uint16_t val = 0;
@@ -629,8 +629,8 @@
 
 TEST(msgbuf, pldm_msgbuf_insert_int16_good)
 {
-    struct pldm_msgbuf _ctx;
-    struct pldm_msgbuf* ctx = &_ctx;
+    struct pldm_msgbuf_rw _ctx;
+    struct pldm_msgbuf_rw* ctx = &_ctx;
     int16_t src = -12;
     int16_t checkVal = 0;
     uint8_t buf[sizeof(int16_t)] = {};
@@ -638,8 +638,8 @@
     ASSERT_EQ(pldm_msgbuf_init_errno(ctx, 0, buf, sizeof(uint16_t)), 0);
     EXPECT_EQ(pldm_msgbuf_insert_int16(ctx, src), 0);
 
-    struct pldm_msgbuf _ctxExtract;
-    struct pldm_msgbuf* ctxExtract = &_ctxExtract;
+    struct pldm_msgbuf_ro _ctxExtract;
+    struct pldm_msgbuf_ro* ctxExtract = &_ctxExtract;
 
     ASSERT_EQ(pldm_msgbuf_init_errno(ctxExtract, 0, buf, sizeof(buf)), 0);
     EXPECT_EQ(pldm_msgbuf_extract_int16(ctxExtract, checkVal), 0);
@@ -651,8 +651,8 @@
 
 TEST(msgbuf, insert_under_int16)
 {
-    struct pldm_msgbuf _ctx;
-    struct pldm_msgbuf* ctx = &_ctx;
+    struct pldm_msgbuf_rw _ctx;
+    struct pldm_msgbuf_rw* ctx = &_ctx;
 
     int16_t buf[1] = {};
     int16_t val = 0;
@@ -665,8 +665,8 @@
 
 TEST(msgbuf, pldm_msgbuf_insert_uint8_good)
 {
-    struct pldm_msgbuf _ctx;
-    struct pldm_msgbuf* ctx = &_ctx;
+    struct pldm_msgbuf_rw _ctx;
+    struct pldm_msgbuf_rw* ctx = &_ctx;
     uint8_t src = 0xf4;
     uint8_t checkVal = 0;
     uint8_t buf[sizeof(uint8_t)] = {};
@@ -674,8 +674,8 @@
     ASSERT_EQ(pldm_msgbuf_init_errno(ctx, 0, buf, sizeof(buf)), 0);
     EXPECT_EQ(pldm_msgbuf_insert_uint8(ctx, src), 0);
 
-    struct pldm_msgbuf _ctxExtract;
-    struct pldm_msgbuf* ctxExtract = &_ctxExtract;
+    struct pldm_msgbuf_ro _ctxExtract;
+    struct pldm_msgbuf_ro* ctxExtract = &_ctxExtract;
 
     ASSERT_EQ(pldm_msgbuf_init_errno(ctxExtract, 0, buf, sizeof(buf)), 0);
     EXPECT_EQ(pldm_msgbuf_extract_uint8(ctxExtract, checkVal), 0);
@@ -687,8 +687,8 @@
 
 TEST(msgbuf, insert_under_uint8)
 {
-    struct pldm_msgbuf _ctx;
-    struct pldm_msgbuf* ctx = &_ctx;
+    struct pldm_msgbuf_rw _ctx;
+    struct pldm_msgbuf_rw* ctx = &_ctx;
 
     uint8_t buf[1] = {};
     uint8_t val = 0;
@@ -701,8 +701,8 @@
 
 TEST(msgbuf, pldm_msgbuf_insert_int8_good)
 {
-    struct pldm_msgbuf _ctx;
-    struct pldm_msgbuf* ctx = &_ctx;
+    struct pldm_msgbuf_rw _ctx;
+    struct pldm_msgbuf_rw* ctx = &_ctx;
     int8_t src = -4;
     int8_t checkVal = 0;
     uint8_t buf[sizeof(int8_t)] = {};
@@ -710,8 +710,8 @@
     ASSERT_EQ(pldm_msgbuf_init_errno(ctx, 0, buf, sizeof(buf)), 0);
     EXPECT_EQ(pldm_msgbuf_insert_int8(ctx, src), 0);
 
-    struct pldm_msgbuf _ctxExtract;
-    struct pldm_msgbuf* ctxExtract = &_ctxExtract;
+    struct pldm_msgbuf_ro _ctxExtract;
+    struct pldm_msgbuf_ro* ctxExtract = &_ctxExtract;
 
     ASSERT_EQ(pldm_msgbuf_init_errno(ctxExtract, 0, buf, sizeof(buf)), 0);
     EXPECT_EQ(pldm_msgbuf_extract_int8(ctxExtract, checkVal), 0);
@@ -723,8 +723,8 @@
 
 TEST(msgbuf, insert_under_int8)
 {
-    struct pldm_msgbuf _ctx;
-    struct pldm_msgbuf* ctx = &_ctx;
+    struct pldm_msgbuf_rw _ctx;
+    struct pldm_msgbuf_rw* ctx = &_ctx;
 
     int8_t buf[1] = {};
     int8_t val = 0;
@@ -737,8 +737,8 @@
 
 TEST(msgbuf, pldm_msgbuf_insert_array_uint8_good)
 {
-    struct pldm_msgbuf _ctx;
-    struct pldm_msgbuf* ctx = &_ctx;
+    struct pldm_msgbuf_rw _ctx;
+    struct pldm_msgbuf_rw* ctx = &_ctx;
     uint8_t src[6] = {0x11, 0x22, 0x44, 0x55, 0x66, 0x77};
     uint8_t buf[6] = {};
     uint8_t retBuff[6] = {};
@@ -747,8 +747,8 @@
     EXPECT_EQ(
         pldm_msgbuf_insert_array_uint8(ctx, sizeof(src), src, sizeof(src)), 0);
 
-    struct pldm_msgbuf _ctxExtract;
-    struct pldm_msgbuf* ctxExtract = &_ctxExtract;
+    struct pldm_msgbuf_ro _ctxExtract;
+    struct pldm_msgbuf_ro* ctxExtract = &_ctxExtract;
 
     ASSERT_EQ(pldm_msgbuf_init_errno(ctxExtract, 0, buf, sizeof(buf)), 0);
     EXPECT_EQ(pldm_msgbuf_extract_array_uint8(ctxExtract, sizeof(retBuff),
@@ -762,8 +762,8 @@
 
 TEST(msgbuf, insert_under_array_uint8)
 {
-    struct pldm_msgbuf _ctx;
-    struct pldm_msgbuf* ctx = &_ctx;
+    struct pldm_msgbuf_rw _ctx;
+    struct pldm_msgbuf_rw* ctx = &_ctx;
 
     uint8_t buf[1] = {};
     uint8_t val[1] = {0};
@@ -777,8 +777,8 @@
 
 TEST(msgbuf, pldm_msgbuf_insert_array_char_good)
 {
-    struct pldm_msgbuf _ctx;
-    struct pldm_msgbuf* ctx = &_ctx;
+    struct pldm_msgbuf_rw _ctx;
+    struct pldm_msgbuf_rw* ctx = &_ctx;
     char src[6] = {0x11, 0x22, 0x44, 0x55, 0x66, 0x77};
     char buf[6] = {};
     char retBuff[6] = {};
@@ -787,8 +787,8 @@
     EXPECT_EQ(pldm_msgbuf_insert_array_char(ctx, sizeof(src), src, sizeof(src)),
               0);
 
-    struct pldm_msgbuf _ctxExtract;
-    struct pldm_msgbuf* ctxExtract = &_ctxExtract;
+    struct pldm_msgbuf_ro _ctxExtract;
+    struct pldm_msgbuf_ro* ctxExtract = &_ctxExtract;
 
     ASSERT_EQ(pldm_msgbuf_init_errno(ctxExtract, 0, buf, sizeof(buf)), 0);
     EXPECT_EQ(pldm_msgbuf_extract_array_char(ctxExtract, sizeof(retBuff),
@@ -802,8 +802,8 @@
 
 TEST(msgbuf, insert_under_array_char)
 {
-    struct pldm_msgbuf _ctx;
-    struct pldm_msgbuf* ctx = &_ctx;
+    struct pldm_msgbuf_rw _ctx;
+    struct pldm_msgbuf_rw* ctx = &_ctx;
     char buf[1] = {};
     char val[1] = {0};
 
@@ -816,8 +816,8 @@
 
 TEST(msgbuf, pldm_msgbuf_span_required_good)
 {
-    struct pldm_msgbuf _ctx;
-    struct pldm_msgbuf* ctx = &_ctx;
+    struct pldm_msgbuf_rw _ctx;
+    struct pldm_msgbuf_rw* ctx = &_ctx;
     uint8_t src[6] = {0x11, 0x22, 0x44, 0x55, 0x66, 0x77};
     uint8_t buf[6] = {0};
     const size_t required = 4;
@@ -829,13 +829,14 @@
     EXPECT_EQ(
         pldm_msgbuf_insert_array_uint8(ctx, sizeof(src), src, sizeof(src)), 0);
 
-    struct pldm_msgbuf _ctxExtract;
-    struct pldm_msgbuf* ctxExtract = &_ctxExtract;
+    struct pldm_msgbuf_ro _ctxExtract;
+    struct pldm_msgbuf_ro* ctxExtract = &_ctxExtract;
 
     ASSERT_EQ(pldm_msgbuf_init_errno(ctxExtract, 0, buf, sizeof(buf)), 0);
     EXPECT_EQ(pldm_msgbuf_extract_uint16(ctxExtract, testVal), 0);
-    EXPECT_EQ(pldm_msgbuf_span_required(ctxExtract, required, (void**)&retBuff),
-              0);
+    EXPECT_EQ(
+        pldm_msgbuf_span_required(ctxExtract, required, (const void**)&retBuff),
+        0);
 
     EXPECT_EQ(memcmp(expectData, retBuff, required), 0);
     EXPECT_EQ(pldm_msgbuf_complete(ctxExtract), 0);
@@ -844,8 +845,8 @@
 
 TEST(msgbuf, pldm_msgbuf_span_required_bad)
 {
-    struct pldm_msgbuf _ctx;
-    struct pldm_msgbuf* ctx = &_ctx;
+    struct pldm_msgbuf_rw _ctx;
+    struct pldm_msgbuf_rw* ctx = &_ctx;
     uint8_t src[6] = {0x11, 0x22, 0x44, 0x55, 0x66, 0x77};
     uint8_t buf[6] = {0};
     const size_t required = 4;
@@ -856,8 +857,8 @@
     EXPECT_EQ(
         pldm_msgbuf_insert_array_uint8(ctx, sizeof(src), src, sizeof(src)), 0);
 
-    struct pldm_msgbuf _ctxExtract;
-    struct pldm_msgbuf* ctxExtract = &_ctxExtract;
+    struct pldm_msgbuf_ro _ctxExtract;
+    struct pldm_msgbuf_ro* ctxExtract = &_ctxExtract;
 
     ASSERT_EQ(pldm_msgbuf_init_errno(ctxExtract, 0, buf, sizeof(buf)), 0);
     EXPECT_EQ(pldm_msgbuf_extract_uint16(ctxExtract, testVal), 0);
@@ -869,8 +870,8 @@
 
 TEST(msgbuf, span_required_under)
 {
-    struct pldm_msgbuf _ctx;
-    struct pldm_msgbuf* ctx = &_ctx;
+    struct pldm_msgbuf_rw _ctx;
+    struct pldm_msgbuf_rw* ctx = &_ctx;
 
     uint8_t buf[1] = {};
     void* cursor = nullptr;
@@ -883,8 +884,8 @@
 
 TEST(msgbuf, pldm_msgbuf_span_string_ascii_good)
 {
-    struct pldm_msgbuf _ctxExtract;
-    struct pldm_msgbuf* ctxExtract = &_ctxExtract;
+    struct pldm_msgbuf_ro _ctxExtract;
+    struct pldm_msgbuf_ro* ctxExtract = &_ctxExtract;
     uint8_t src[9] = {0x11, 0x22, 0x68, 0x65, 0x6c, 0x6c, 0x6f, 0x00, 0x77};
     constexpr size_t required = 6;
     const char expectData[required] = {0x68, 0x65, 0x6c, 0x6c, 0x6f, 0x00};
@@ -895,8 +896,9 @@
     ASSERT_EQ(pldm_msgbuf_init_errno(ctxExtract, 0, src, sizeof(src)), 0);
     EXPECT_EQ(pldm_msgbuf_extract_uint16(ctxExtract, testVal), 0);
     EXPECT_EQ(0x2211, testVal);
-    EXPECT_EQ(pldm_msgbuf_span_string_ascii(ctxExtract, (void**)&retBuff, NULL),
-              0);
+    EXPECT_EQ(
+        pldm_msgbuf_span_string_ascii(ctxExtract, (const void**)&retBuff, NULL),
+        0);
     EXPECT_EQ(pldm_msgbuf_extract_uint8(ctxExtract, testVal1), 0);
     EXPECT_EQ(0x77, testVal1);
 
@@ -907,8 +909,8 @@
 
 TEST(msgbuf, pldm_msgbuf_span_string_ascii_good_with_length)
 {
-    struct pldm_msgbuf _ctxExtract;
-    struct pldm_msgbuf* ctxExtract = &_ctxExtract;
+    struct pldm_msgbuf_ro _ctxExtract;
+    struct pldm_msgbuf_ro* ctxExtract = &_ctxExtract;
     uint8_t src[9] = {0x11, 0x22, 0x68, 0x65, 0x6c, 0x6c, 0x6f, 0x00, 0x77};
     constexpr size_t required = 6;
     const char expectData[required] = {0x68, 0x65, 0x6c, 0x6c, 0x6f, 0x00};
@@ -920,9 +922,9 @@
     ASSERT_EQ(pldm_msgbuf_init_errno(ctxExtract, 0, src, sizeof(src)), 0);
     EXPECT_EQ(pldm_msgbuf_extract_uint16(ctxExtract, testVal), 0);
     EXPECT_EQ(0x2211, testVal);
-    EXPECT_EQ(
-        pldm_msgbuf_span_string_ascii(ctxExtract, (void**)&retBuff, &length),
-        0);
+    EXPECT_EQ(pldm_msgbuf_span_string_ascii(ctxExtract, (const void**)&retBuff,
+                                            &length),
+              0);
     EXPECT_EQ(pldm_msgbuf_extract_uint8(ctxExtract, testVal1), 0);
     EXPECT_EQ(0x77, testVal1);
 
@@ -935,8 +937,8 @@
 
 TEST(msgbuf, pldm_msgbuf_span_string_ascii_allow_null_args)
 {
-    struct pldm_msgbuf _ctxExtract;
-    struct pldm_msgbuf* ctxExtract = &_ctxExtract;
+    struct pldm_msgbuf_ro _ctxExtract;
+    struct pldm_msgbuf_ro* ctxExtract = &_ctxExtract;
     uint8_t src[8] = {0x11, 0x22, 0x68, 0x65, 0x6c, 0x6c, 0x6f, 0x00};
     uint16_t testVal;
 
@@ -949,8 +951,8 @@
 
 TEST(msgbuf, pldm_msgbuf_span_string_ascii_bad_no_terminator)
 {
-    struct pldm_msgbuf _ctxExtract;
-    struct pldm_msgbuf* ctxExtract = &_ctxExtract;
+    struct pldm_msgbuf_ro _ctxExtract;
+    struct pldm_msgbuf_ro* ctxExtract = &_ctxExtract;
     uint8_t src[8] = {0x11, 0x22, 0x68, 0x65, 0x6c, 0x6c, 0x6f, 0x77};
     uint16_t testVal;
     char* retBuff = NULL;
@@ -958,15 +960,16 @@
     ASSERT_EQ(pldm_msgbuf_init_errno(ctxExtract, 0, src, sizeof(src)), 0);
     EXPECT_EQ(pldm_msgbuf_extract_uint16(ctxExtract, testVal), 0);
     EXPECT_EQ(0x2211, testVal);
-    EXPECT_EQ(pldm_msgbuf_span_string_ascii(ctxExtract, (void**)&retBuff, NULL),
-              -EOVERFLOW);
+    EXPECT_EQ(
+        pldm_msgbuf_span_string_ascii(ctxExtract, (const void**)&retBuff, NULL),
+        -EOVERFLOW);
     EXPECT_EQ(pldm_msgbuf_complete(ctxExtract), -EOVERFLOW);
 }
 
 TEST(msgbuf, pldm_msgbuf_span_string_ascii_under)
 {
-    struct pldm_msgbuf _ctxExtract;
-    struct pldm_msgbuf* ctxExtract = &_ctxExtract;
+    struct pldm_msgbuf_rw _ctxExtract;
+    struct pldm_msgbuf_rw* ctxExtract = &_ctxExtract;
 
     uint8_t src[1] = {};
     char* retBuff = NULL;
@@ -990,8 +993,8 @@
 
 TEST(msgbuf, pldm_msgbuf_span_string_utf16_good)
 {
-    struct pldm_msgbuf _ctxExtract;
-    struct pldm_msgbuf* ctxExtract = &_ctxExtract;
+    struct pldm_msgbuf_ro _ctxExtract;
+    struct pldm_msgbuf_ro* ctxExtract = &_ctxExtract;
     uint8_t src[] __attribute__((aligned(alignof(char16_t)))) = {
         0x11, 0x22, 0x11, 0x68, 0x22, 0x65, 0x33, 0x6c,
         0x44, 0x6c, 0x55, 0x6f, 0x00, 0x00, 0x34, 0x12};
@@ -1005,8 +1008,9 @@
     EXPECT_EQ(pldm_msgbuf_extract_uint16(ctxExtract, testVal), 0);
     EXPECT_EQ(0x2211, testVal);
 
-    ASSERT_EQ(pldm_msgbuf_span_string_utf16(ctxExtract, (void**)&retBuff, NULL),
-              0);
+    ASSERT_EQ(
+        pldm_msgbuf_span_string_utf16(ctxExtract, (const void**)&retBuff, NULL),
+        0);
     EXPECT_EQ(pldm_msgbuf_extract_uint16(ctxExtract, testVal1), 0);
     EXPECT_EQ(0x1234, testVal1);
 
@@ -1018,8 +1022,8 @@
 
 TEST(msgbuf, pldm_msgbuf_span_string_utf16_good2)
 {
-    struct pldm_msgbuf _ctxExtract;
-    struct pldm_msgbuf* ctxExtract = &_ctxExtract;
+    struct pldm_msgbuf_ro _ctxExtract;
+    struct pldm_msgbuf_ro* ctxExtract = &_ctxExtract;
     uint8_t src[24] = {0x11, 0x22, 0x11, 0x68, 0x22, 0x65, 0x33, 0x6c,
                        0x44, 0x6c, 0x55, 0x6f, 0x00, 0x00, 0x34, 0x12,
                        0x44, 0x6c, 0x55, 0x6f, 0x00, 0x00, 0x34, 0x12};
@@ -1037,8 +1041,9 @@
     EXPECT_EQ(pldm_msgbuf_extract_uint16(ctxExtract, testVal), 0);
     EXPECT_EQ(0x2211, testVal);
 
-    EXPECT_EQ(pldm_msgbuf_span_string_utf16(ctxExtract, (void**)&retBuff, NULL),
-              0);
+    EXPECT_EQ(
+        pldm_msgbuf_span_string_utf16(ctxExtract, (const void**)&retBuff, NULL),
+        0);
 
     ASSERT_EQ(0ul, (uintptr_t)retBuff & (alignof(char16_t) - 1));
     EXPECT_EQ(6ul, str16len((char16_t*)retBuff) + 1);
@@ -1049,9 +1054,9 @@
     EXPECT_EQ(pldm_msgbuf_extract_uint16(ctxExtract, testVal1), 0);
     EXPECT_EQ(0x1234, testVal1);
 
-    EXPECT_EQ(
-        pldm_msgbuf_span_string_utf16(ctxExtract, (void**)&retBuff1, &length),
-        0);
+    EXPECT_EQ(pldm_msgbuf_span_string_utf16(ctxExtract, (const void**)&retBuff1,
+                                            &length),
+              0);
 
     EXPECT_EQ(0ul, length % 2);
     EXPECT_EQ(memcmp(expectData1, retBuff1, length), 0);
@@ -1064,8 +1069,8 @@
 
 TEST(msgbuf, pldm_msgbuf_span_string_utf16_allow_null_args)
 {
-    struct pldm_msgbuf _ctxExtract;
-    struct pldm_msgbuf* ctxExtract = &_ctxExtract;
+    struct pldm_msgbuf_ro _ctxExtract;
+    struct pldm_msgbuf_ro* ctxExtract = &_ctxExtract;
     uint8_t src[14] = {0x11, 0x22, 0x11, 0x68, 0x22, 0x65, 0x33,
                        0x6c, 0x44, 0x6c, 0x55, 0x6f, 0x00, 0x00};
     uint16_t testVal;
@@ -1079,8 +1084,8 @@
 
 TEST(msgbuf, pldm_msgbuf_span_string_utf16_bad_no_terminator)
 {
-    struct pldm_msgbuf _ctxExtract;
-    struct pldm_msgbuf* ctxExtract = &_ctxExtract;
+    struct pldm_msgbuf_ro _ctxExtract;
+    struct pldm_msgbuf_ro* ctxExtract = &_ctxExtract;
     uint8_t src[14] = {0x11, 0x22, 0x11, 0x68, 0x22, 0x65, 0x33,
                        0x6c, 0x44, 0x6c, 0x55, 0x6f, 0x66, 0x77};
     uint16_t testVal;
@@ -1089,15 +1094,16 @@
     ASSERT_EQ(pldm_msgbuf_init_errno(ctxExtract, 0, src, sizeof(src)), 0);
     EXPECT_EQ(pldm_msgbuf_extract_uint16(ctxExtract, testVal), 0);
     EXPECT_EQ(0x2211, testVal);
-    EXPECT_EQ(pldm_msgbuf_span_string_utf16(ctxExtract, (void**)&retBuff, NULL),
-              -EOVERFLOW);
+    EXPECT_EQ(
+        pldm_msgbuf_span_string_utf16(ctxExtract, (const void**)&retBuff, NULL),
+        -EOVERFLOW);
     EXPECT_EQ(pldm_msgbuf_complete(ctxExtract), -EOVERFLOW);
 }
 
 TEST(msgbuf, pldm_msgbuf_span_string_utf16_bad_odd_size)
 {
-    struct pldm_msgbuf _ctxExtract;
-    struct pldm_msgbuf* ctxExtract = &_ctxExtract;
+    struct pldm_msgbuf_ro _ctxExtract;
+    struct pldm_msgbuf_ro* ctxExtract = &_ctxExtract;
     uint8_t src[] = {0x11, 0x22, 0x11, 0x68, 0x22, 0x65, 0x33,
                      0x6c, 0x44, 0x6c, 0x55, 0x00, 0x00};
     uint16_t testVal;
@@ -1106,15 +1112,16 @@
     ASSERT_EQ(pldm_msgbuf_init_errno(ctxExtract, 0, src, sizeof(src)), 0);
     EXPECT_EQ(pldm_msgbuf_extract_uint16(ctxExtract, testVal), 0);
     EXPECT_EQ(0x2211, testVal);
-    EXPECT_EQ(pldm_msgbuf_span_string_utf16(ctxExtract, (void**)&retBuff, NULL),
-              -EOVERFLOW);
+    EXPECT_EQ(
+        pldm_msgbuf_span_string_utf16(ctxExtract, (const void**)&retBuff, NULL),
+        -EOVERFLOW);
     EXPECT_EQ(pldm_msgbuf_complete(ctxExtract), -EOVERFLOW);
 }
 
 TEST(msgbuf, pldm_msgbuf_span_string_utf16_mix)
 {
-    struct pldm_msgbuf _ctxExtract;
-    struct pldm_msgbuf* ctxExtract = &_ctxExtract;
+    struct pldm_msgbuf_ro _ctxExtract;
+    struct pldm_msgbuf_ro* ctxExtract = &_ctxExtract;
     uint8_t src[36] = {0x2,  0x65, 0x6e, 0x00, // Language Tag "en"
                        0x00, 0x53, 0x00, 0x30, 0x00, 0x53, 0x00,
                        0x58, 0x00, 0x00,                   // Entity Name "S0S"
@@ -1145,30 +1152,36 @@
     EXPECT_EQ(pldm_msgbuf_extract_uint8(ctxExtract, name_count), 0);
     EXPECT_EQ(0x2, name_count);
 
-    EXPECT_EQ(pldm_msgbuf_span_string_ascii(ctxExtract, (void**)&tag, NULL), 0);
+    EXPECT_EQ(
+        pldm_msgbuf_span_string_ascii(ctxExtract, (const void**)&tag, NULL), 0);
     EXPECT_EQ(strncmp(expectTag0, tag, strlen(tag) + 1), 0);
 
-    EXPECT_EQ(pldm_msgbuf_span_string_utf16(ctxExtract, (void**)&name, NULL),
-              0);
+    EXPECT_EQ(
+        pldm_msgbuf_span_string_utf16(ctxExtract, (const void**)&name, NULL),
+        0);
     ASSERT_EQ(0ul, (uintptr_t)name & (alignof(char16_t) - 1));
     EXPECT_EQ(5ul, str16len((char16_t*)name) + 1);
     EXPECT_EQ(memcmp(expectName0, name,
                      sizeof(char16_t) * (str16len((char16_t*)name) + 1)),
               0);
 
-    EXPECT_EQ(pldm_msgbuf_span_string_ascii(ctxExtract, (void**)&tag1, &length),
-              0);
-    EXPECT_EQ(strncmp(expectTag1, tag1, length), 0);
     EXPECT_EQ(
-        pldm_msgbuf_span_string_utf16(ctxExtract, (void**)&name1, &length), 0);
+        pldm_msgbuf_span_string_ascii(ctxExtract, (const void**)&tag1, &length),
+        0);
+    EXPECT_EQ(strncmp(expectTag1, tag1, length), 0);
+    EXPECT_EQ(pldm_msgbuf_span_string_utf16(ctxExtract, (const void**)&name1,
+                                            &length),
+              0);
     EXPECT_EQ(0ul, length % 2);
     EXPECT_EQ(memcmp(expectName1, name1, length), 0);
 
-    EXPECT_EQ(pldm_msgbuf_span_string_ascii(ctxExtract, (void**)&tag2, NULL),
-              0);
+    EXPECT_EQ(
+        pldm_msgbuf_span_string_ascii(ctxExtract, (const void**)&tag2, NULL),
+        0);
     EXPECT_EQ(strncmp(expectTag2, tag2, strlen(tag2) + 1), 0);
-    EXPECT_EQ(pldm_msgbuf_span_string_utf16(ctxExtract, (void**)&name2, NULL),
-              0);
+    EXPECT_EQ(
+        pldm_msgbuf_span_string_utf16(ctxExtract, (const void**)&name2, NULL),
+        0);
     ASSERT_EQ(0ul, (uintptr_t)name2 & (alignof(char16_t) - 1));
     EXPECT_EQ(4ul, str16len((char16_t*)name2) + 1);
     EXPECT_EQ(memcmp(expectName2, name2,
@@ -1183,8 +1196,8 @@
 
 TEST(msgbuf, pldm_msgbuf_span_string_utf16_under)
 {
-    struct pldm_msgbuf _ctxExtract;
-    struct pldm_msgbuf* ctxExtract = &_ctxExtract;
+    struct pldm_msgbuf_rw _ctxExtract;
+    struct pldm_msgbuf_rw* ctxExtract = &_ctxExtract;
 
     uint8_t src[1] = {};
     char* retBuff = NULL;
@@ -1198,8 +1211,8 @@
 
 TEST(msgbuf, pldm_msgbuf_span_remaining_good)
 {
-    struct pldm_msgbuf _ctx;
-    struct pldm_msgbuf* ctx = &_ctx;
+    struct pldm_msgbuf_rw _ctx;
+    struct pldm_msgbuf_rw* ctx = &_ctx;
     uint8_t src[8] = {0x11, 0x22, 0x44, 0x55, 0x66, 0x77, 0x88, 0x99};
     uint8_t buf[8] = {0};
     uint16_t testVal;
@@ -1211,14 +1224,14 @@
     EXPECT_EQ(
         pldm_msgbuf_insert_array_uint8(ctx, sizeof(src), src, sizeof(src)), 0);
 
-    struct pldm_msgbuf _ctxExtract;
-    struct pldm_msgbuf* ctxExtract = &_ctxExtract;
+    struct pldm_msgbuf_ro _ctxExtract;
+    struct pldm_msgbuf_ro* ctxExtract = &_ctxExtract;
 
     ASSERT_EQ(pldm_msgbuf_init_errno(ctxExtract, 0, buf, sizeof(buf)), 0);
     EXPECT_EQ(pldm_msgbuf_extract_uint16(ctxExtract, testVal), 0);
-    EXPECT_EQ(
-        pldm_msgbuf_span_remaining(ctxExtract, (void**)&retBuff, &remaining),
-        0);
+    EXPECT_EQ(pldm_msgbuf_span_remaining(ctxExtract, (const void**)&retBuff,
+                                         &remaining),
+              0);
 
     EXPECT_EQ(remaining, sizeof(expectData));
     EXPECT_EQ(memcmp(expectData, retBuff, remaining), 0);
@@ -1228,8 +1241,8 @@
 
 TEST(msgbuf, pldm_msgbuf_span_remaining_bad)
 {
-    struct pldm_msgbuf _ctx;
-    struct pldm_msgbuf* ctx = &_ctx;
+    struct pldm_msgbuf_rw _ctx;
+    struct pldm_msgbuf_rw* ctx = &_ctx;
     uint8_t src[8] = {0x11, 0x22, 0x44, 0x55, 0x66, 0x77, 0x88, 0x99};
     uint8_t buf[8] = {0};
     uint16_t testVal;
@@ -1238,8 +1251,8 @@
     EXPECT_EQ(
         pldm_msgbuf_insert_array_uint8(ctx, sizeof(src), src, sizeof(src)), 0);
 
-    struct pldm_msgbuf _ctxExtract;
-    struct pldm_msgbuf* ctxExtract = &_ctxExtract;
+    struct pldm_msgbuf_ro _ctxExtract;
+    struct pldm_msgbuf_ro* ctxExtract = &_ctxExtract;
 
     ASSERT_EQ(pldm_msgbuf_init_errno(ctxExtract, 0, buf, sizeof(buf)), 0);
     EXPECT_EQ(pldm_msgbuf_extract_uint16(ctxExtract, testVal), 0);
@@ -1250,8 +1263,8 @@
 
 TEST(msgbuf, pldm_msgbuf_span_until_0_1)
 {
-    struct pldm_msgbuf _ctx;
-    struct pldm_msgbuf* ctx = &_ctx;
+    struct pldm_msgbuf_rw _ctx;
+    struct pldm_msgbuf_rw* ctx = &_ctx;
     uint8_t buf[] = {1};
 
     ASSERT_EQ(pldm_msgbuf_init_errno(ctx, 0, buf, sizeof(buf)), 0);
@@ -1261,8 +1274,8 @@
 
 TEST(msgbuf, pldm_msgbuf_span_until_0_1_p)
 {
-    struct pldm_msgbuf _ctx;
-    struct pldm_msgbuf* ctx = &_ctx;
+    struct pldm_msgbuf_rw _ctx;
+    struct pldm_msgbuf_rw* ctx = &_ctx;
     uint8_t buf[] = {1};
     void* start;
     size_t len;
@@ -1276,8 +1289,8 @@
 
 TEST(msgbuf, pldm_msgbuf_span_until_1_1)
 {
-    struct pldm_msgbuf _ctx;
-    struct pldm_msgbuf* ctx = &_ctx;
+    struct pldm_msgbuf_ro _ctx;
+    struct pldm_msgbuf_ro* ctx = &_ctx;
     uint8_t buf[] = {1};
     uint8_t val;
 
@@ -1289,8 +1302,8 @@
 
 TEST(msgbuf, pldm_msgbuf_span_until_1_2)
 {
-    struct pldm_msgbuf _ctx;
-    struct pldm_msgbuf* ctx = &_ctx;
+    struct pldm_msgbuf_ro _ctx;
+    struct pldm_msgbuf_ro* ctx = &_ctx;
     uint8_t buf[] = {0, 1};
     uint8_t val;
 
@@ -1303,8 +1316,8 @@
 
 TEST(msgbuf, pldm_msgbuf_span_until_1_3)
 {
-    struct pldm_msgbuf _ctx;
-    struct pldm_msgbuf* ctx = &_ctx;
+    struct pldm_msgbuf_ro _ctx;
+    struct pldm_msgbuf_ro* ctx = &_ctx;
     uint8_t buf[] = {0, 1, 2};
     uint8_t val;
 
@@ -1317,8 +1330,8 @@
 
 TEST(msgbuf, pldm_msgbuf_span_until_2_3)
 {
-    struct pldm_msgbuf _ctx;
-    struct pldm_msgbuf* ctx = &_ctx;
+    struct pldm_msgbuf_ro _ctx;
+    struct pldm_msgbuf_ro* ctx = &_ctx;
     uint8_t buf[] = {0, 1, 2};
     uint8_t val0;
     uint8_t val1;
@@ -1334,8 +1347,8 @@
 
 TEST(msgbuf, pldm_msgbuf_span_until_short)
 {
-    struct pldm_msgbuf _ctx;
-    struct pldm_msgbuf* ctx = &_ctx;
+    struct pldm_msgbuf_rw _ctx;
+    struct pldm_msgbuf_rw* ctx = &_ctx;
     uint8_t buf[] = {1};
 
     ASSERT_EQ(pldm_msgbuf_init_errno(ctx, 0, buf, sizeof(buf)), 0);
@@ -1345,8 +1358,8 @@
 
 TEST(msgbuf, pldm_msgbuf_span_until_saturated)
 {
-    struct pldm_msgbuf _ctx;
-    struct pldm_msgbuf* ctx = &_ctx;
+    struct pldm_msgbuf_ro _ctx;
+    struct pldm_msgbuf_ro* ctx = &_ctx;
     uint8_t buf[] = {1};
     uint16_t val;
 
@@ -1359,22 +1372,22 @@
 
 TEST(msgbuf, pldm_msgbuf_copy_good)
 {
-    struct pldm_msgbuf _src;
-    struct pldm_msgbuf* src = &_src;
+    struct pldm_msgbuf_ro _src;
+    struct pldm_msgbuf_ro* src = &_src;
     uint16_t buf[1] = {htole16(0x5aa5)};
 
     ASSERT_EQ(pldm_msgbuf_init_errno(src, sizeof(buf), buf, sizeof(buf)), 0);
 
-    struct pldm_msgbuf _dst;
-    struct pldm_msgbuf* dst = &_dst;
+    struct pldm_msgbuf_rw _dst;
+    struct pldm_msgbuf_rw* dst = &_dst;
     uint16_t checkVal = 0;
     uint8_t buf1[sizeof(buf)] = {};
 
     ASSERT_EQ(pldm_msgbuf_init_errno(dst, sizeof(buf1), buf1, sizeof(buf1)), 0);
     EXPECT_EQ(pldm_msgbuf_copy(dst, src, buf[0], name), 0);
 
-    ASSERT_EQ(pldm_msgbuf_init_errno(dst, sizeof(buf1), buf1, sizeof(buf1)), 0);
-    EXPECT_EQ(pldm_msgbuf_extract_uint16(dst, checkVal), 0);
+    ASSERT_EQ(pldm_msgbuf_init_errno(src, sizeof(buf1), buf1, sizeof(buf1)), 0);
+    EXPECT_EQ(pldm_msgbuf_extract_uint16(src, checkVal), 0);
 
     EXPECT_EQ(pldm_msgbuf_complete(src), 0);
     EXPECT_EQ(pldm_msgbuf_complete(dst), 0);
@@ -1384,10 +1397,10 @@
 
 TEST(msgbuf, pldm_msgbuf_copy_bad)
 {
-    struct pldm_msgbuf _src;
-    struct pldm_msgbuf* src = &_src;
-    struct pldm_msgbuf _dst;
-    struct pldm_msgbuf* dst = &_dst;
+    struct pldm_msgbuf_ro _src;
+    struct pldm_msgbuf_ro* src = &_src;
+    struct pldm_msgbuf_rw _dst;
+    struct pldm_msgbuf_rw* dst = &_dst;
     uint8_t buf[1] = {sizeof(uint8_t)};
     uint8_t buf1[1] = {sizeof(uint16_t)};
     uint16_t value = 8;
@@ -1405,10 +1418,10 @@
 {
     const char msg[] = "this is a message";
 
-    struct pldm_msgbuf _src;
-    struct pldm_msgbuf* src = &_src;
-    struct pldm_msgbuf _dst;
-    struct pldm_msgbuf* dst = &_dst;
+    struct pldm_msgbuf_ro _src;
+    struct pldm_msgbuf_ro* src = &_src;
+    struct pldm_msgbuf_rw _dst;
+    struct pldm_msgbuf_rw* dst = &_dst;
 
     char buf[sizeof(msg)] = {};
 
@@ -1424,10 +1437,10 @@
 {
     const char msg[] = "this is a message";
 
-    struct pldm_msgbuf _src;
-    struct pldm_msgbuf* src = &_src;
-    struct pldm_msgbuf _dst;
-    struct pldm_msgbuf* dst = &_dst;
+    struct pldm_msgbuf_ro _src;
+    struct pldm_msgbuf_ro* src = &_src;
+    struct pldm_msgbuf_rw _dst;
+    struct pldm_msgbuf_rw* dst = &_dst;
 
     char buf[sizeof(msg) + 1] = {};
 
@@ -1443,10 +1456,10 @@
 {
     const char msg[] = "this is a message";
 
-    struct pldm_msgbuf _src;
-    struct pldm_msgbuf* src = &_src;
-    struct pldm_msgbuf _dst;
-    struct pldm_msgbuf* dst = &_dst;
+    struct pldm_msgbuf_ro _src;
+    struct pldm_msgbuf_ro* src = &_src;
+    struct pldm_msgbuf_rw _dst;
+    struct pldm_msgbuf_rw* dst = &_dst;
 
     char buf[sizeof(msg) - 1] = {};
 
@@ -1461,10 +1474,10 @@
 {
     const char msg[] = {'a'};
 
-    struct pldm_msgbuf _src;
-    struct pldm_msgbuf* src = &_src;
-    struct pldm_msgbuf _dst;
-    struct pldm_msgbuf* dst = &_dst;
+    struct pldm_msgbuf_ro _src;
+    struct pldm_msgbuf_ro* src = &_src;
+    struct pldm_msgbuf_rw _dst;
+    struct pldm_msgbuf_rw* dst = &_dst;
 
     char buf[sizeof(msg)] = {};
 
@@ -1479,10 +1492,10 @@
 {
     const char16_t msg[] = u"this is a message";
 
-    struct pldm_msgbuf _src;
-    struct pldm_msgbuf* src = &_src;
-    struct pldm_msgbuf _dst;
-    struct pldm_msgbuf* dst = &_dst;
+    struct pldm_msgbuf_ro _src;
+    struct pldm_msgbuf_ro* src = &_src;
+    struct pldm_msgbuf_rw _dst;
+    struct pldm_msgbuf_rw* dst = &_dst;
 
     char buf[sizeof(msg)] = {};
 
@@ -1498,10 +1511,10 @@
 {
     const char16_t msg[] = u"this is a message";
 
-    struct pldm_msgbuf _src;
-    struct pldm_msgbuf* src = &_src;
-    struct pldm_msgbuf _dst;
-    struct pldm_msgbuf* dst = &_dst;
+    struct pldm_msgbuf_ro _src;
+    struct pldm_msgbuf_ro* src = &_src;
+    struct pldm_msgbuf_rw _dst;
+    struct pldm_msgbuf_rw* dst = &_dst;
 
     char buf[sizeof(msg) + 1] = {};
 
@@ -1517,10 +1530,10 @@
 {
     const char16_t msg[] = u"this is a message";
 
-    struct pldm_msgbuf _src;
-    struct pldm_msgbuf* src = &_src;
-    struct pldm_msgbuf _dst;
-    struct pldm_msgbuf* dst = &_dst;
+    struct pldm_msgbuf_ro _src;
+    struct pldm_msgbuf_ro* src = &_src;
+    struct pldm_msgbuf_rw _dst;
+    struct pldm_msgbuf_rw* dst = &_dst;
 
     char buf[sizeof(msg) - 1] = {};
 
@@ -1535,10 +1548,10 @@
 {
     const char16_t msg[] = {u'a'};
 
-    struct pldm_msgbuf _src;
-    struct pldm_msgbuf* src = &_src;
-    struct pldm_msgbuf _dst;
-    struct pldm_msgbuf* dst = &_dst;
+    struct pldm_msgbuf_ro _src;
+    struct pldm_msgbuf_ro* src = &_src;
+    struct pldm_msgbuf_rw _dst;
+    struct pldm_msgbuf_rw* dst = &_dst;
 
     char buf[sizeof(msg)] = {};
 
@@ -1551,7 +1564,7 @@
 
 TEST(msgbuf, extract_one_uint8_to_size)
 {
-    PLDM_MSGBUF_DEFINE_P(ctx);
+    PLDM_MSGBUF_RO_DEFINE_P(ctx);
     uint8_t buf[1] = {0xa5};
 
     size_t val;
@@ -1564,7 +1577,7 @@
 
 TEST(msgbuf, extract_under_uint8_to_size)
 {
-    PLDM_MSGBUF_DEFINE_P(ctx);
+    PLDM_MSGBUF_RO_DEFINE_P(ctx);
     uint8_t buf[1] = {};
     size_t val;
 
@@ -1576,7 +1589,7 @@
 
 TEST(msgbuf, extract_over_uint8_to_size)
 {
-    PLDM_MSGBUF_DEFINE_P(ctx);
+    PLDM_MSGBUF_RO_DEFINE_P(ctx);
     uint8_t buf[1] = {};
     size_t val;
 
@@ -1587,7 +1600,7 @@
 
 TEST(msgbuf, extract_one_uint16_to_size)
 {
-    PLDM_MSGBUF_DEFINE_P(ctx);
+    PLDM_MSGBUF_RO_DEFINE_P(ctx);
     uint16_t buf[1] = {htole16(0x5aa5)};
     size_t val;
 
@@ -1599,7 +1612,7 @@
 
 TEST(msgbuf, extract_under_uint16_to_size)
 {
-    PLDM_MSGBUF_DEFINE_P(ctx);
+    PLDM_MSGBUF_RO_DEFINE_P(ctx);
     uint16_t buf[1] = {};
     size_t val;
 
@@ -1611,7 +1624,7 @@
 
 TEST(msgbuf, extract_over_uint16_to_size)
 {
-    PLDM_MSGBUF_DEFINE_P(ctx);
+    PLDM_MSGBUF_RO_DEFINE_P(ctx);
     uint16_t buf[1] = {};
     size_t val;
 
@@ -1622,7 +1635,7 @@
 
 TEST(msgbuf, extract_one_uint32_to_size)
 {
-    PLDM_MSGBUF_DEFINE_P(ctx);
+    PLDM_MSGBUF_RO_DEFINE_P(ctx);
     uint32_t buf[1] = {htole32(0x5a00ffa5)};
     size_t val;
 
@@ -1634,7 +1647,7 @@
 
 TEST(msgbuf, extract_under_uint32_to_size)
 {
-    PLDM_MSGBUF_DEFINE_P(ctx);
+    PLDM_MSGBUF_RO_DEFINE_P(ctx);
     uint32_t buf[1] = {};
     size_t val;
 
@@ -1646,7 +1659,7 @@
 
 TEST(msgbuf, extract_over_uint32_to_size)
 {
-    PLDM_MSGBUF_DEFINE_P(ctx);
+    PLDM_MSGBUF_RO_DEFINE_P(ctx);
     uint32_t buf[1] = {};
     size_t val;
 
diff --git a/tests/msgbuf.hpp b/tests/msgbuf.hpp
new file mode 100644
index 0000000..1c11c96
--- /dev/null
+++ b/tests/msgbuf.hpp
@@ -0,0 +1,277 @@
+/* SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later */
+#ifndef PLDM_MSGBUF_HPP
+#define PLDM_MSGBUF_HPP
+
+#include <libpldm/compiler.h>
+
+#include "msgbuf/core.h"
+
+/*
+ * Use the C++ Function Overload to keep pldm_msgbuf related function consistent
+ * and to produce compile-time errors when the wrong pldm_msgbuf type is passed.
+ *
+ * Previously we cast away `const` in `pldm_msgbuf_init_error()`, which was a
+ * hack. Instead, introduce:
+ *   - pldm_msgbuf_ro: read-only buffer with a `const` cursor
+ *   - pldm_msgbuf_rw: read-write buffer with a non-const cursor
+ *
+ * `pldm_msgbuf_ro` is used by decode APIs to extract payloads into PLDM
+ * structures. `pldm_msgbuf_rw` is used by encode APIs to insert payloads from
+ * PLDM structures.
+ */
+
+#include <cstdint>
+#include <cstdio>
+#include <type_traits>
+
+// NOLINTBEGIN(bugprone-macro-parentheses)
+// NOLINTNEXTLINE(bugprone-reserved-identifier,cert-dcl37-c,cert-dcl51-cpp)
+#define PLDM__MSGBUF_DEFINE_P(name, mode)                                      \
+    struct pldm_msgbuf_##mode _##name LIBPLDM_CC_CLEANUP(                      \
+        pldm__msgbuf_##mode##_cleanup) = {NULL, INTMAX_MIN};                   \
+    auto* name = &(_##name)
+// NOLINTEND(bugprone-macro-parentheses)
+
+#define PLDM_MSGBUF_RO_DEFINE_P(name) PLDM__MSGBUF_DEFINE_P(name, ro)
+#define PLDM_MSGBUF_RW_DEFINE_P(name) PLDM__MSGBUF_DEFINE_P(name, rw)
+
+LIBPLDM_CC_ALWAYS_INLINE int pldm_msgbuf_init_errno(struct pldm_msgbuf_ro* ctx,
+                                                    size_t minsize,
+                                                    const void* buf, size_t len)
+{
+    return pldm_msgbuf_ro_init_errno(ctx, minsize, buf, len);
+}
+
+LIBPLDM_CC_ALWAYS_INLINE int pldm_msgbuf_init_errno(struct pldm_msgbuf_rw* ctx,
+                                                    size_t minsize,
+                                                    const void* buf, size_t len)
+{
+    return pldm_msgbuf_rw_init_errno(ctx, minsize, buf, len);
+}
+
+LIBPLDM_CC_ALWAYS_INLINE int pldm_msgbuf_validate(struct pldm_msgbuf_ro* ctx)
+{
+    return pldm_msgbuf_ro_validate(ctx);
+}
+
+LIBPLDM_CC_ALWAYS_INLINE int pldm_msgbuf_validate(struct pldm_msgbuf_rw* ctx)
+{
+    return pldm_msgbuf_rw_validate(ctx);
+}
+
+// NOLINTNEXTLINE(bugprone-reserved-identifier,cert-dcl37-c,cert-dcl51-cpp)
+LIBPLDM_CC_ALWAYS_INLINE int pldm__msgbuf_invalidate(struct pldm_msgbuf_ro* ctx)
+{
+    return pldm__msgbuf_ro_invalidate(ctx);
+}
+
+// NOLINTNEXTLINE(bugprone-reserved-identifier,cert-dcl37-c,cert-dcl51-cpp)
+LIBPLDM_CC_ALWAYS_INLINE int pldm__msgbuf_invalidate(struct pldm_msgbuf_rw* ctx)
+{
+    return pldm__msgbuf_rw_invalidate(ctx);
+}
+
+LIBPLDM_CC_ALWAYS_INLINE int pldm_msgbuf_consumed(struct pldm_msgbuf_ro* ctx)
+{
+    return pldm_msgbuf_ro_consumed(ctx);
+}
+
+LIBPLDM_CC_ALWAYS_INLINE int pldm_msgbuf_consumed(struct pldm_msgbuf_rw* ctx)
+{
+    return pldm_msgbuf_rw_consumed(ctx);
+}
+
+LIBPLDM_CC_ALWAYS_INLINE int pldm_msgbuf_discard(struct pldm_msgbuf_ro* ctx,
+                                                 int error)
+{
+    return pldm_msgbuf_ro_discard(ctx, error);
+}
+
+LIBPLDM_CC_ALWAYS_INLINE int pldm_msgbuf_discard(struct pldm_msgbuf_rw* ctx,
+                                                 int error)
+{
+    return pldm_msgbuf_rw_discard(ctx, error);
+}
+
+LIBPLDM_CC_ALWAYS_INLINE int pldm_msgbuf_complete(struct pldm_msgbuf_ro* ctx)
+{
+    return pldm_msgbuf_ro_complete(ctx);
+}
+
+LIBPLDM_CC_ALWAYS_INLINE int pldm_msgbuf_complete(struct pldm_msgbuf_rw* ctx)
+{
+    return pldm_msgbuf_rw_complete(ctx);
+}
+
+LIBPLDM_CC_ALWAYS_INLINE int
+    pldm_msgbuf_complete_consumed(struct pldm_msgbuf_ro* ctx)
+{
+    return pldm_msgbuf_ro_complete_consumed(ctx);
+}
+
+LIBPLDM_CC_ALWAYS_INLINE int
+    pldm_msgbuf_complete_consumed(struct pldm_msgbuf_rw* ctx)
+{
+    return pldm_msgbuf_rw_complete_consumed(ctx);
+}
+
+LIBPLDM_CC_ALWAYS_INLINE int
+    pldm_msgbuf_span_required(struct pldm_msgbuf_ro* ctx, size_t required,
+                              const void** cursor)
+{
+    return pldm_msgbuf_ro_span_required(ctx, required, cursor);
+}
+
+LIBPLDM_CC_ALWAYS_INLINE int
+    pldm_msgbuf_span_required(struct pldm_msgbuf_rw* ctx, size_t required,
+                              void** cursor)
+{
+    return pldm_msgbuf_rw_span_required(ctx, required, cursor);
+}
+
+LIBPLDM_CC_ALWAYS_INLINE int
+    pldm_msgbuf_span_string_ascii(struct pldm_msgbuf_rw* ctx, void** cursor,
+                                  size_t* length)
+{
+    return pldm_msgbuf_rw_span_string_ascii(ctx, cursor, length);
+}
+
+LIBPLDM_CC_ALWAYS_INLINE int
+    pldm_msgbuf_span_string_ascii(struct pldm_msgbuf_ro* ctx,
+                                  const void** cursor, size_t* length)
+{
+    return pldm_msgbuf_ro_span_string_ascii(ctx, cursor, length);
+}
+
+LIBPLDM_CC_ALWAYS_INLINE int pldm_msgbuf_span_string_utf16(pldm_msgbuf_ro* ctx,
+                                                           const void** cursor,
+                                                           size_t* length)
+{
+    return pldm_msgbuf_ro_span_string_utf16(ctx, cursor, length);
+}
+
+LIBPLDM_CC_ALWAYS_INLINE int pldm_msgbuf_span_string_utf16(pldm_msgbuf_rw* ctx,
+                                                           void** cursor,
+                                                           size_t* length)
+{
+    return pldm_msgbuf_rw_span_string_utf16(ctx, cursor, length);
+}
+
+LIBPLDM_CC_ALWAYS_INLINE int
+    pldm_msgbuf_span_remaining(struct pldm_msgbuf_rw* ctx, void** cursor,
+                               size_t* len)
+{
+    return pldm_msgbuf_rw_span_remaining(ctx, cursor, len);
+}
+
+LIBPLDM_CC_ALWAYS_INLINE int
+    pldm_msgbuf_span_remaining(struct pldm_msgbuf_ro* ctx, const void** cursor,
+                               size_t* len)
+{
+    return pldm_msgbuf_ro_span_remaining(ctx, cursor, len);
+}
+
+LIBPLDM_CC_ALWAYS_INLINE int pldm_msgbuf_span_until(struct pldm_msgbuf_ro* ctx,
+                                                    size_t trailer,
+                                                    const void** cursor,
+                                                    size_t* length)
+{
+    return pldm_msgbuf_ro_span_until(ctx, trailer, cursor, length);
+}
+
+LIBPLDM_CC_ALWAYS_INLINE int pldm_msgbuf_span_until(struct pldm_msgbuf_rw* ctx,
+                                                    size_t trailer,
+                                                    void** cursor,
+                                                    size_t* length)
+{
+    return pldm_msgbuf_rw_span_until(ctx, trailer, cursor, length);
+}
+
+#define pldm_msgbuf_extract_typecheck(ty, fn, dst, ...)                        \
+    pldm_msgbuf_typecheck_##ty<decltype(dst)>(__VA_ARGS__)
+
+#define pldm_msgbuf_extract_uint8(ctx, dst)                                    \
+    pldm_msgbuf_extract_typecheck(uint8_t, pldm__msgbuf_extract_uint8, dst,    \
+                                  ctx, (void*)&(dst))
+
+#define pldm_msgbuf_extract_int8(ctx, dst)                                     \
+    pldm_msgbuf_extract_typecheck(int8_t, pldm__msgbuf_extract_int8, dst, ctx, \
+                                  (void*)&(dst))
+
+#define pldm_msgbuf_extract_uint16(ctx, dst)                                   \
+    pldm_msgbuf_extract_typecheck(uint16_t, pldm__msgbuf_extract_uint16, dst,  \
+                                  ctx, (void*)&(dst))
+
+#define pldm_msgbuf_extract_int16(ctx, dst)                                    \
+    pldm_msgbuf_extract_typecheck(int16_t, pldm__msgbuf_extract_int16, dst,    \
+                                  ctx, (void*)&(dst))
+
+#define pldm_msgbuf_extract_uint32(ctx, dst)                                   \
+    pldm_msgbuf_extract_typecheck(uint32_t, pldm__msgbuf_extract_uint32, dst,  \
+                                  ctx, (void*)&(dst))
+
+#define pldm_msgbuf_extract_int32(ctx, dst)                                    \
+    pldm_msgbuf_extract_typecheck(int32_t, pldm__msgbuf_extract_int32, dst,    \
+                                  ctx, (void*)&(dst))
+
+#define pldm_msgbuf_extract_real32(ctx, dst)                                   \
+    pldm_msgbuf_extract_typecheck(real32_t, pldm__msgbuf_extract_real32, dst,  \
+                                  ctx, (void*)&(dst))
+
+template <typename T>
+LIBPLDM_CC_ALWAYS_INLINE int
+    pldm_msgbuf_typecheck_uint8_t(struct pldm_msgbuf_ro* ctx, void* buf)
+{
+    static_assert(std::is_same<uint8_t, T>::value);
+    return pldm__msgbuf_extract_uint8(ctx, buf);
+}
+
+template <typename T>
+LIBPLDM_CC_ALWAYS_INLINE int
+    pldm_msgbuf_typecheck_int8_t(struct pldm_msgbuf_ro* ctx, void* buf)
+{
+    static_assert(std::is_same<int8_t, T>::value);
+    return pldm__msgbuf_extract_int8(ctx, buf);
+}
+
+template <typename T>
+LIBPLDM_CC_ALWAYS_INLINE int
+    pldm_msgbuf_typecheck_uint16_t(struct pldm_msgbuf_ro* ctx, void* buf)
+{
+    static_assert(std::is_same<uint16_t, T>::value);
+    return pldm__msgbuf_extract_uint16(ctx, buf);
+}
+
+template <typename T>
+LIBPLDM_CC_ALWAYS_INLINE int
+    pldm_msgbuf_typecheck_int16_t(struct pldm_msgbuf_ro* ctx, void* buf)
+{
+    static_assert(std::is_same<int16_t, T>::value);
+    return pldm__msgbuf_extract_int16(ctx, buf);
+}
+
+template <typename T>
+LIBPLDM_CC_ALWAYS_INLINE int
+    pldm_msgbuf_typecheck_uint32_t(struct pldm_msgbuf_ro* ctx, void* buf)
+{
+    static_assert(std::is_same<uint32_t, T>::value);
+    return pldm__msgbuf_extract_uint32(ctx, buf);
+}
+
+template <typename T>
+LIBPLDM_CC_ALWAYS_INLINE int
+    pldm_msgbuf_typecheck_int32_t(struct pldm_msgbuf_ro* ctx, void* buf)
+{
+    static_assert(std::is_same<int32_t, T>::value);
+    return pldm__msgbuf_extract_int32(ctx, buf);
+}
+
+template <typename T>
+LIBPLDM_CC_ALWAYS_INLINE int
+    pldm_msgbuf_typecheck_real32_t(struct pldm_msgbuf_ro* ctx, void* buf)
+{
+    static_assert(std::is_same<real32_t, T>::value);
+    return pldm__msgbuf_extract_real32(ctx, buf);
+}
+
+#endif /* BUF_HPP */
diff --git a/tests/msgbuf_generic.c b/tests/msgbuf_generic.c
index 62160f3..28c8a53 100644
--- a/tests/msgbuf_generic.c
+++ b/tests/msgbuf_generic.c
@@ -28,8 +28,8 @@
 
 static void test_msgbuf_extract_generic_uint8(void)
 {
-    struct pldm_msgbuf _ctx;
-    struct pldm_msgbuf* ctx = &_ctx;
+    struct pldm_msgbuf_ro _ctx;
+    struct pldm_msgbuf_ro* ctx = &_ctx;
     uint8_t buf[1] = {0xa5};
     uint8_t val;
 
@@ -41,8 +41,8 @@
 
 static void test_msgbuf_extract_generic_int8(void)
 {
-    struct pldm_msgbuf _ctx;
-    struct pldm_msgbuf* ctx = &_ctx;
+    struct pldm_msgbuf_ro _ctx;
+    struct pldm_msgbuf_ro* ctx = &_ctx;
     int8_t buf[1] = {-1};
     int8_t val;
 
@@ -54,8 +54,8 @@
 
 static void test_msgbuf_extract_generic_uint16(void)
 {
-    struct pldm_msgbuf _ctx;
-    struct pldm_msgbuf* ctx = &_ctx;
+    struct pldm_msgbuf_ro _ctx;
+    struct pldm_msgbuf_ro* ctx = &_ctx;
     uint16_t buf[1] = {0x5aa5};
     uint16_t val;
 
@@ -67,8 +67,8 @@
 
 static void test_msgbuf_extract_generic_int16(void)
 {
-    struct pldm_msgbuf _ctx;
-    struct pldm_msgbuf* ctx = &_ctx;
+    struct pldm_msgbuf_ro _ctx;
+    struct pldm_msgbuf_ro* ctx = &_ctx;
     int16_t buf[1] = {(int16_t)(htole16((uint16_t)INT16_MIN))};
     int16_t val;
 
@@ -80,8 +80,8 @@
 
 static void test_msgbuf_extract_generic_uint32(void)
 {
-    struct pldm_msgbuf _ctx;
-    struct pldm_msgbuf* ctx = &_ctx;
+    struct pldm_msgbuf_ro _ctx;
+    struct pldm_msgbuf_ro* ctx = &_ctx;
     uint32_t buf[1] = {0x5a00ffa5};
     uint32_t val;
 
@@ -93,8 +93,8 @@
 
 static void test_msgbuf_extract_generic_int32(void)
 {
-    struct pldm_msgbuf _ctx;
-    struct pldm_msgbuf* ctx = &_ctx;
+    struct pldm_msgbuf_ro _ctx;
+    struct pldm_msgbuf_ro* ctx = &_ctx;
     int32_t buf[1] = {(int32_t)(htole32((uint32_t)INT32_MIN))};
     int32_t val;
 
@@ -106,8 +106,8 @@
 
 static void test_msgbuf_extract_generic_real32(void)
 {
-    struct pldm_msgbuf _ctx;
-    struct pldm_msgbuf* ctx = &_ctx;
+    struct pldm_msgbuf_ro _ctx;
+    struct pldm_msgbuf_ro* ctx = &_ctx;
     uint32_t buf[1];
     uint32_t xform;
     real32_t val;
@@ -125,8 +125,8 @@
 
 static void test_msgbuf_extract_array_generic_uint8(void)
 {
-    struct pldm_msgbuf _ctx;
-    struct pldm_msgbuf* ctx = &_ctx;
+    struct pldm_msgbuf_ro _ctx;
+    struct pldm_msgbuf_ro* ctx = &_ctx;
     uint32_t buf[1] = {0};
     uint8_t arr[1];
 
@@ -138,8 +138,8 @@
 
 static void test_msgbuf_insert_generic_int32(void)
 {
-    struct pldm_msgbuf _ctx;
-    struct pldm_msgbuf* ctx = &_ctx;
+    struct pldm_msgbuf_rw _ctx;
+    struct pldm_msgbuf_rw* ctx = &_ctx;
     int32_t src = -12345;
     int32_t checkVal = 0;
     uint8_t buf[sizeof(int32_t)] = {0};
@@ -147,8 +147,8 @@
     expect(pldm_msgbuf_init_errno(ctx, 0, buf, sizeof(buf)) == 0);
     expect(pldm_msgbuf_insert(ctx, src) == 0);
 
-    struct pldm_msgbuf _ctxExtract;
-    struct pldm_msgbuf* ctxExtract = &_ctxExtract;
+    struct pldm_msgbuf_ro _ctxExtract;
+    struct pldm_msgbuf_ro* ctxExtract = &_ctxExtract;
 
     expect(pldm_msgbuf_init_errno(ctxExtract, 0, buf, sizeof(buf)) == 0);
     expect(pldm_msgbuf_extract(ctxExtract, checkVal) == 0);
@@ -160,8 +160,8 @@
 
 static void test_msgbuf_insert_generic_uint32(void)
 {
-    struct pldm_msgbuf _ctx;
-    struct pldm_msgbuf* ctx = &_ctx;
+    struct pldm_msgbuf_rw _ctx;
+    struct pldm_msgbuf_rw* ctx = &_ctx;
     uint32_t src = 0xf1223344;
     uint32_t checkVal = 0;
     uint8_t buf[sizeof(uint32_t)] = {0};
@@ -169,8 +169,8 @@
     expect(pldm_msgbuf_init_errno(ctx, 0, buf, sizeof(buf)) == 0);
     expect(pldm_msgbuf_insert(ctx, src) == 0);
 
-    struct pldm_msgbuf _ctxExtract;
-    struct pldm_msgbuf* ctxExtract = &_ctxExtract;
+    struct pldm_msgbuf_ro _ctxExtract;
+    struct pldm_msgbuf_ro* ctxExtract = &_ctxExtract;
 
     expect(pldm_msgbuf_init_errno(ctxExtract, 0, buf, sizeof(buf)) == 0);
     expect(pldm_msgbuf_extract(ctxExtract, checkVal) == 0);
@@ -182,8 +182,8 @@
 
 static void test_msgbuf_insert_generic_uint16(void)
 {
-    struct pldm_msgbuf _ctx;
-    struct pldm_msgbuf* ctx = &_ctx;
+    struct pldm_msgbuf_rw _ctx;
+    struct pldm_msgbuf_rw* ctx = &_ctx;
     uint16_t src = 0xf344;
     uint16_t checkVal = 0;
     uint8_t buf[sizeof(uint16_t)] = {0};
@@ -191,8 +191,8 @@
     expect(pldm_msgbuf_init_errno(ctx, 0, buf, sizeof(uint16_t)) == 0);
     expect(pldm_msgbuf_insert(ctx, src) == 0);
 
-    struct pldm_msgbuf _ctxExtract;
-    struct pldm_msgbuf* ctxExtract = &_ctxExtract;
+    struct pldm_msgbuf_ro _ctxExtract;
+    struct pldm_msgbuf_ro* ctxExtract = &_ctxExtract;
 
     expect(pldm_msgbuf_init_errno(ctxExtract, 0, buf, sizeof(buf)) == 0);
     expect(pldm_msgbuf_extract(ctxExtract, checkVal) == 0);
@@ -204,8 +204,8 @@
 
 static void test_msgbuf_insert_generic_int16(void)
 {
-    struct pldm_msgbuf _ctx;
-    struct pldm_msgbuf* ctx = &_ctx;
+    struct pldm_msgbuf_rw _ctx;
+    struct pldm_msgbuf_rw* ctx = &_ctx;
     int16_t src = -12;
     int16_t checkVal = 0;
     uint8_t buf[sizeof(int16_t)] = {0};
@@ -213,8 +213,8 @@
     expect(pldm_msgbuf_init_errno(ctx, 0, buf, sizeof(uint16_t)) == 0);
     expect(pldm_msgbuf_insert(ctx, src) == 0);
 
-    struct pldm_msgbuf _ctxExtract;
-    struct pldm_msgbuf* ctxExtract = &_ctxExtract;
+    struct pldm_msgbuf_ro _ctxExtract;
+    struct pldm_msgbuf_ro* ctxExtract = &_ctxExtract;
 
     expect(pldm_msgbuf_init_errno(ctxExtract, 0, buf, sizeof(buf)) == 0);
     expect(pldm_msgbuf_extract(ctxExtract, checkVal) == 0);
@@ -226,8 +226,8 @@
 
 static void test_msgbuf_insert_generic_uint8(void)
 {
-    struct pldm_msgbuf _ctx;
-    struct pldm_msgbuf* ctx = &_ctx;
+    struct pldm_msgbuf_rw _ctx;
+    struct pldm_msgbuf_rw* ctx = &_ctx;
     uint8_t src = 0xf4;
     uint8_t checkVal = 0;
     uint8_t buf[sizeof(uint8_t)] = {0};
@@ -235,8 +235,8 @@
     expect(pldm_msgbuf_init_errno(ctx, 0, buf, sizeof(buf)) == 0);
     expect(pldm_msgbuf_insert(ctx, src) == 0);
 
-    struct pldm_msgbuf _ctxExtract;
-    struct pldm_msgbuf* ctxExtract = &_ctxExtract;
+    struct pldm_msgbuf_ro _ctxExtract;
+    struct pldm_msgbuf_ro* ctxExtract = &_ctxExtract;
 
     expect(pldm_msgbuf_init_errno(ctxExtract, 0, buf, sizeof(buf)) == 0);
     expect(pldm_msgbuf_extract(ctxExtract, checkVal) == 0);
@@ -248,8 +248,8 @@
 
 static void test_msgbuf_insert_generic_int8(void)
 {
-    struct pldm_msgbuf _ctx;
-    struct pldm_msgbuf* ctx = &_ctx;
+    struct pldm_msgbuf_rw _ctx;
+    struct pldm_msgbuf_rw* ctx = &_ctx;
     int8_t src = -4;
     int8_t checkVal = 0;
     uint8_t buf[sizeof(int8_t)] = {0};
@@ -257,8 +257,8 @@
     expect(pldm_msgbuf_init_errno(ctx, 0, buf, sizeof(buf)) == 0);
     expect(pldm_msgbuf_insert(ctx, src) == 0);
 
-    struct pldm_msgbuf _ctxExtract;
-    struct pldm_msgbuf* ctxExtract = &_ctxExtract;
+    struct pldm_msgbuf_ro _ctxExtract;
+    struct pldm_msgbuf_ro* ctxExtract = &_ctxExtract;
 
     expect(pldm_msgbuf_init_errno(ctxExtract, 0, buf, sizeof(buf)) == 0);
     expect(pldm_msgbuf_extract(ctxExtract, checkVal) == 0);
@@ -270,8 +270,8 @@
 
 static void test_msgbuf_insert_array_generic_uint8(void)
 {
-    struct pldm_msgbuf _ctx;
-    struct pldm_msgbuf* ctx = &_ctx;
+    struct pldm_msgbuf_rw _ctx;
+    struct pldm_msgbuf_rw* ctx = &_ctx;
     uint8_t src[6] = {0x11, 0x22, 0x44, 0x55, 0x66, 0x77};
     uint8_t buf[6] = {0};
     uint8_t retBuff[6] = {0};
@@ -279,8 +279,8 @@
     expect(pldm_msgbuf_init_errno(ctx, 0, buf, sizeof(buf)) == 0);
     expect(pldm_msgbuf_insert_array(ctx, sizeof(src), src, sizeof(src)) == 0);
 
-    struct pldm_msgbuf _ctxExtract;
-    struct pldm_msgbuf* ctxExtract = &_ctxExtract;
+    struct pldm_msgbuf_ro _ctxExtract;
+    struct pldm_msgbuf_ro* ctxExtract = &_ctxExtract;
 
     expect(pldm_msgbuf_init_errno(ctxExtract, 0, buf, sizeof(buf)) == 0);
     expect(pldm_msgbuf_extract_array(ctxExtract, sizeof(retBuff), retBuff,
diff --git a/tests/oem/meta/fileio.cpp b/tests/oem/meta/fileio.cpp
index 747f3be..845f0da 100644
--- a/tests/oem/meta/fileio.cpp
+++ b/tests/oem/meta/fileio.cpp
@@ -1,19 +1,21 @@
 /* SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later */
+
+#include "msgbuf.hpp"
+
 #include <endian.h>
+#include <libpldm/base.h>
 #include <libpldm/oem/meta/file_io.h>
 
 #include <cstdlib>
 #include <new>
 
-#include "msgbuf.h"
-
 #include "gmock/gmock.h"
 #include <gtest/gtest.h>
 
 TEST(DecodeOemMetaFileIoWriteReq, testGoodDecodeRequest)
 {
     constexpr const uint8_t postCode[4] = {0x93, 0xe0, 0x00, 0xea};
-    PLDM_MSGBUF_DEFINE_P(ctx);
+    PLDM_MSGBUF_RW_DEFINE_P(ctx);
     int rc;
 
     constexpr size_t encodedPayloadLen =
@@ -82,7 +84,7 @@
 
 TEST(DecodeOemMetaFileIoReadReq, testGoodDecodeRequest)
 {
-    PLDM_MSGBUF_DEFINE_P(ctx);
+    PLDM_MSGBUF_RW_DEFINE_P(ctx);
     int rc;
 
     constexpr size_t payloadLen = PLDM_OEM_META_FILE_IO_READ_REQ_MIN_LENGTH +