Update the RPC layer

This commit merges the 'tforg/topics/ts-rpc' into integration. The
change overhauls the RPC layer implement the following changes:
  - allow RPC compatibility check be adding versioning to the RPC layer
  - allow multiple memory shares between FF-A endpoints. (This was a
     concerning limitation for NWd endpoints where multiple clients
     may operate).
  - add service discovery support. After this change all SPs use the
    same FF-A UUID. This means the FF-A UUID identifies the protocol and
    not the service as before. As a result, to locate a service further
    discovery is needed on top of FF-A discovery. This is implemented
    in the RPC layer for performance reasons.
  - update discovery implementation and add the new discovery step
    needed after service locator locates the SP.
  - change protocol encoding types to be represented as dedicated
    interfaces of an SP. This removes encoding type identifiers and
    replaces these with service UUIDs.
  - add RPC ABI documentation

Change-Id: I7fbb28b17d44b04578595c8725674624297f01a0
Signed-off-by: Gyorgy Szing <Gyorgy.Szing@arm.com>
diff --git a/components/app/platform-inspect/attest_report_fetcher.cpp b/components/app/platform-inspect/attest_report_fetcher.cpp
index 4e43467..33977b5 100644
--- a/components/app/platform-inspect/attest_report_fetcher.cpp
+++ b/components/app/platform-inspect/attest_report_fetcher.cpp
@@ -25,23 +25,20 @@
 bool fetch_attest_report(std::vector<uint8_t> &report, std::string &error_msg)
 {
     bool success = false;
-    rpc_session_handle rpc_session_handle = NULL;
+    struct rpc_caller_session *rpc_session = NULL;
     struct service_context *attest_service_context = NULL;
-    int status;
 
     attest_service_context =
-        service_locator_query("sn:trustedfirmware.org:attestation:0", &status);
+        service_locator_query("sn:trustedfirmware.org:attestation:0");
 
     if (attest_service_context) {
 
-        struct rpc_caller *caller = NULL;
-        rpc_session_handle =
-            service_context_open(attest_service_context, TS_RPC_ENCODING_PACKED_C, &caller);
+        rpc_session = service_context_open(attest_service_context);
 
-        if (rpc_session_handle) {
+        if (rpc_session) {
 
-            psa_iat_client_init(caller);
-            attest_provision_client_init(caller);
+            psa_iat_client_init(rpc_session);
+            attest_provision_client_init(rpc_session);
 
             success = fetch_and_verify(report, error_msg);
         }
@@ -58,7 +55,7 @@
     /* Clean-up context */
     psa_iat_client_deinit();
     attest_provision_client_deinit();
-    service_context_close(attest_service_context, rpc_session_handle);
+    service_context_close(attest_service_context, rpc_session);
     service_context_relinquish(attest_service_context);
 
     return success;
diff --git a/components/app/ts-demo/test/ts-demo_tests.cpp b/components/app/ts-demo/test/ts-demo_tests.cpp
index 92f7369..e78f8a2 100644
--- a/components/app/ts-demo/test/ts-demo_tests.cpp
+++ b/components/app/ts-demo/test/ts-demo_tests.cpp
@@ -16,22 +16,19 @@
 
     void setup()
     {
-        struct rpc_caller *caller;
-        int status;
-
-        m_rpc_session_handle = NULL;
+        m_rpc_session = NULL;
         m_crypto_service_context = NULL;
         m_crypto_client = NULL;
 
         service_locator_init();
 
-        m_crypto_service_context = service_locator_query("sn:trustedfirmware.org:crypto:0", &status);
+        m_crypto_service_context = service_locator_query("sn:trustedfirmware.org:crypto:0");
         CHECK(m_crypto_service_context);
 
-        m_rpc_session_handle = service_context_open(m_crypto_service_context, TS_RPC_ENCODING_PACKED_C, &caller);
-        CHECK(m_rpc_session_handle);
+        m_rpc_session = service_context_open(m_crypto_service_context);
+        CHECK(m_rpc_session);
 
-        m_crypto_client = new packedc_crypto_client(caller);
+        m_crypto_client = new packedc_crypto_client(m_rpc_session);
     }
 
     void teardown()
@@ -40,9 +37,9 @@
         m_crypto_client = NULL;
 
 	if (m_crypto_service_context) {
-	        if (m_rpc_session_handle) {
-                        service_context_close(m_crypto_service_context, m_rpc_session_handle);
-                        m_rpc_session_handle = NULL;
+	        if (m_rpc_session) {
+                        service_context_close(m_crypto_service_context, m_rpc_session);
+                        m_rpc_session = NULL;
 	        }
 
                 service_context_relinquish(m_crypto_service_context);
@@ -50,7 +47,7 @@
 	}
     }
 
-    rpc_session_handle m_rpc_session_handle;
+    struct rpc_caller_session *m_rpc_session;
     struct service_context *m_crypto_service_context;
     crypto_client *m_crypto_client;
 };
diff --git a/components/messaging/ffa/libsp/ffa_direct_msg_routing_extension.c b/components/messaging/ffa/libsp/ffa_direct_msg_routing_extension.c
index 03a372f..f62d3f2 100644
--- a/components/messaging/ffa/libsp/ffa_direct_msg_routing_extension.c
+++ b/components/messaging/ffa/libsp/ffa_direct_msg_routing_extension.c
@@ -8,8 +8,9 @@
 #include <stdbool.h>
 
 #define SP_ID_INVALID FFA_ID_GET_ID_MASK
-#define FFA_ROUTING_EXT_RC_BIT BIT(0)
-#define FFA_ROUTING_EXT_ERROR_BIT BIT(1)
+#define FFA_ROUTING_EXT_RC_BIT		BIT32(31)
+#define FFA_ROUTING_EXT_ERROR_BIT	BIT32(30)
+#define FFA_ROUTING_EXT_BITS_MASK	(FFA_ROUTING_EXT_RC_BIT | FFA_ROUTING_EXT_ERROR_BIT)
 
 enum sp_rc_state { idle = 0, root, leaf, rc_root, internal, forwarding };
 
@@ -99,6 +100,9 @@
 	caller_id = req->source_id;
 	callee_id = SP_ID_INVALID;
 
+	if (FFA_IS_32_BIT_FUNC(req->function_id))
+		req->args.args32[0] &= ~FFA_ROUTING_EXT_BITS_MASK;
+
 	return FFA_OK;
 }
 
@@ -107,10 +111,17 @@
 	return request_received_hook(req);
 }
 
-void ffa_direct_msg_routing_ext_req_pre_hook(struct ffa_direct_msg *req)
+ffa_result ffa_direct_msg_routing_ext_req_pre_hook(struct ffa_direct_msg *req)
 {
+	if (FFA_IS_32_BIT_FUNC(req->function_id)) {
+		if (req->args.args32[0] & FFA_ROUTING_EXT_BITS_MASK)
+			return FFA_INVALID_PARAMETERS;
+	}
+
 	state = internal;
 	callee_id = req->destination_id;
+
+	return FFA_OK;
 }
 
 ffa_result ffa_direct_msg_routing_ext_req_post_hook(struct ffa_direct_msg *resp)
@@ -179,11 +190,18 @@
 	callee_id = SP_ID_INVALID;
 }
 
-void ffa_direct_msg_routing_ext_resp_pre_hook(struct ffa_direct_msg *resp)
+ffa_result ffa_direct_msg_routing_ext_resp_pre_hook(struct ffa_direct_msg *resp)
 {
+	if (FFA_IS_32_BIT_FUNC(resp->function_id)) {
+		if (resp->args.args32[0] & FFA_ROUTING_EXT_BITS_MASK)
+			return FFA_INVALID_PARAMETERS;
+	}
+
 	state = idle;
 	caller_id = SP_ID_INVALID;
 	callee_id = SP_ID_INVALID;
+
+	return FFA_OK;
 }
 
 ffa_result ffa_direct_msg_routing_ext_resp_post_hook(struct ffa_direct_msg *req)
@@ -195,10 +213,17 @@
 {
 }
 
-void ffa_direct_msg_routing_ext_rc_req_pre_hook(struct ffa_direct_msg *req)
+ffa_result ffa_direct_msg_routing_ext_rc_req_pre_hook(struct ffa_direct_msg *req)
 {
-	req->args.args32[0] = FFA_ROUTING_EXT_RC_BIT;
+	if (FFA_IS_32_BIT_FUNC(req->function_id)) {
+		if (req->args.args32[0] & FFA_ROUTING_EXT_BITS_MASK)
+			return FFA_INVALID_PARAMETERS;
+	}
+
+	req->args.args32[0] |= FFA_ROUTING_EXT_RC_BIT;
 	state = rc_root;
+
+	return FFA_OK;
 }
 
 ffa_result
diff --git a/components/messaging/ffa/libsp/include/ffa_api_defines.h b/components/messaging/ffa/libsp/include/ffa_api_defines.h
index f6e0212..e5aea41 100644
--- a/components/messaging/ffa/libsp/include/ffa_api_defines.h
+++ b/components/messaging/ffa/libsp/include/ffa_api_defines.h
@@ -62,6 +62,7 @@
 
 /* Utility macros */
 #define FFA_TO_32_BIT_FUNC(x)		((x) & (~UINT32_C(0x40000000)))
+#define FFA_TO_64_BIT_FUNC(x)		((x) | UINT32_C(0x40000000))
 #define FFA_IS_32_BIT_FUNC(x)		(((x) & UINT32_C(0x40000000)) == 0)
 #define FFA_IS_64_BIT_FUNC(x)		(((x) & UINT32_C(0x40000000)) != 0)
 
@@ -245,6 +246,9 @@
 /* FFA_MEM_TRANSACTION_FLAGS_ZERO_MEMORY is available too */
 /* FFA_MEM_TRANSACTION_FLAGS_TYPE_* is available too */
 
+/* Handle */
+#define FFA_MEM_HANDLE_INVALID				GENMASK_64(63, 0)
+
 /* Table 11.25: Descriptor to relinquish a memory region */
 #define FFA_RELINQUISH_FLAGS_ZERO_MEMORY_AFTER_RELINQUISH	BIT32(0)
 #define FFA_RELINQUISH_FLAGS_OPERATION_TIME_SLICING		BIT32(1)
diff --git a/components/messaging/ffa/libsp/include/ffa_direct_msg_routing_extension.h b/components/messaging/ffa/libsp/include/ffa_direct_msg_routing_extension.h
index 3715f50..8944200 100644
--- a/components/messaging/ffa/libsp/include/ffa_direct_msg_routing_extension.h
+++ b/components/messaging/ffa/libsp/include/ffa_direct_msg_routing_extension.h
@@ -14,22 +14,18 @@
 extern "C" {
 #endif
 
-ffa_result
-ffa_direct_msg_routing_ext_wait_post_hook(struct ffa_direct_msg *req);
+ffa_result ffa_direct_msg_routing_ext_wait_post_hook(struct ffa_direct_msg *req);
 
-void ffa_direct_msg_routing_ext_req_pre_hook(struct ffa_direct_msg *req);
-ffa_result
-ffa_direct_msg_routing_ext_req_post_hook(struct ffa_direct_msg *resp);
+ffa_result ffa_direct_msg_routing_ext_req_pre_hook(struct ffa_direct_msg *req);
+ffa_result ffa_direct_msg_routing_ext_req_post_hook(struct ffa_direct_msg *resp);
 void ffa_direct_msg_routing_ext_req_error_hook(void);
 
-void ffa_direct_msg_routing_ext_resp_pre_hook(struct ffa_direct_msg *resp);
-ffa_result
-ffa_direct_msg_routing_ext_resp_post_hook(struct ffa_direct_msg *req);
+ffa_result ffa_direct_msg_routing_ext_resp_pre_hook(struct ffa_direct_msg *resp);
+ffa_result ffa_direct_msg_routing_ext_resp_post_hook(struct ffa_direct_msg *req);
 void ffa_direct_msg_routing_ext_resp_error_hook(void);
 
-void ffa_direct_msg_routing_ext_rc_req_pre_hook(struct ffa_direct_msg *req);
-ffa_result
-ffa_direct_msg_routing_ext_rc_req_post_hook(struct ffa_direct_msg *resp);
+ffa_result ffa_direct_msg_routing_ext_rc_req_pre_hook(struct ffa_direct_msg *req);
+ffa_result ffa_direct_msg_routing_ext_rc_req_post_hook(struct ffa_direct_msg *resp);
 void ffa_direct_msg_routing_ext_rc_req_error_hook(void);
 
 #ifdef __cplusplus
diff --git a/components/messaging/ffa/libsp/include/sp_messaging.h b/components/messaging/ffa/libsp/include/sp_messaging.h
index 7173a92..c1c5a7a 100644
--- a/components/messaging/ffa/libsp/include/sp_messaging.h
+++ b/components/messaging/ffa/libsp/include/sp_messaging.h
@@ -16,7 +16,7 @@
 extern "C" {
 #endif
 
-#define SP_MSG_ARG_COUNT (4)
+#define SP_MSG_ARG_COUNT (5)
 
 /**
  * @brief      SP message type
diff --git a/components/messaging/ffa/libsp/sp_messaging.c b/components/messaging/ffa/libsp/sp_messaging.c
index 392006b..67fd7ee 100644
--- a/components/messaging/ffa/libsp/sp_messaging.c
+++ b/components/messaging/ffa/libsp/sp_messaging.c
@@ -12,21 +12,18 @@
 
 #include <string.h>
 
-#define SP_MSG_ARG_OFFSET (1)
-
 static void pack_ffa_direct_msg(const struct sp_msg *msg,
 				struct ffa_direct_msg *ffa_msg)
 {
 	ffa_msg->source_id = msg->source_id;
 	ffa_msg->destination_id = msg->destination_id;
 
-	ffa_msg->args.args64[0] = 0;
-	if (msg->is_64bit_message)
-		memcpy(&ffa_msg->args.args64[SP_MSG_ARG_OFFSET],
-		       msg->args.args64, sizeof(msg->args.args64));
-	else
-		memcpy(&ffa_msg->args.args32[SP_MSG_ARG_OFFSET],
-		       msg->args.args32, sizeof(msg->args.args32));
+	if (msg->is_64bit_message) {
+		ffa_msg->function_id = FFA_TO_64_BIT_FUNC(0);
+		memcpy(ffa_msg->args.args64, msg->args.args64, sizeof(msg->args.args64));
+	} else {
+		memcpy(ffa_msg->args.args32, msg->args.args32, sizeof(msg->args.args32));
+	}
 }
 
 static void unpack_ffa_direct_msg(const struct ffa_direct_msg *ffa_msg,
@@ -39,10 +36,9 @@
 		 */
 		msg->source_id = ffa_msg->source_id;
 		msg->destination_id = ffa_msg->destination_id;
-		msg->is_64bit_message = FFA_IS_64_BIT_FUNC(ffa_msg->function_id);
+		msg->is_64bit_message = false;
 
-		memcpy(msg->args.args32, &ffa_msg->args.args32[SP_MSG_ARG_OFFSET],
-		       sizeof(msg->args.args32));
+		memcpy(msg->args.args32, ffa_msg->args.args32, sizeof(msg->args.args32));
 	} else if (ffa_msg->function_id == FFA_MSG_SEND_DIRECT_REQ_64 ||
 		   ffa_msg->function_id == FFA_MSG_SEND_DIRECT_RESP_64) {
 		/*
@@ -50,10 +46,9 @@
 		 */
 		msg->source_id = ffa_msg->source_id;
 		msg->destination_id = ffa_msg->destination_id;
-		msg->is_64bit_message = FFA_IS_64_BIT_FUNC(ffa_msg->function_id);
+		msg->is_64bit_message = true;
 
-		memcpy(msg->args.args64, &ffa_msg->args.args64[SP_MSG_ARG_OFFSET],
-		       sizeof(msg->args.args64));
+		memcpy(msg->args.args64, ffa_msg->args.args64, sizeof(msg->args.args64));
 	} else {
 		/* Success has no message parameters */
 		*msg = (struct sp_msg){ 0 };
@@ -104,7 +99,11 @@
 	pack_ffa_direct_msg(req, &ffa_req);
 
 #if FFA_DIRECT_MSG_ROUTING_EXTENSION
-	ffa_direct_msg_routing_ext_req_pre_hook(&ffa_req);
+	ffa_res = ffa_direct_msg_routing_ext_req_pre_hook(&ffa_req);
+	if (ffa_res != FFA_OK) {
+		*resp = (struct sp_msg){ 0 };
+		return SP_RESULT_INVALID_PARAMETERS;
+	}
 #endif
 
 	if (req->is_64bit_message)
@@ -158,7 +157,11 @@
 	pack_ffa_direct_msg(resp, &ffa_resp);
 
 #if FFA_DIRECT_MSG_ROUTING_EXTENSION
-	ffa_direct_msg_routing_ext_resp_pre_hook(&ffa_resp);
+	ffa_res = ffa_direct_msg_routing_ext_resp_pre_hook(&ffa_resp);
+	if (ffa_res != FFA_OK) {
+		*req = (struct sp_msg){ 0 };
+		return SP_RESULT_INVALID_PARAMETERS;
+	}
 #endif
 
 	if (resp->is_64bit_message)
@@ -212,7 +215,11 @@
 
 	pack_ffa_direct_msg(req, &ffa_req);
 
-	ffa_direct_msg_routing_ext_rc_req_pre_hook(&ffa_req);
+	ffa_res = ffa_direct_msg_routing_ext_rc_req_pre_hook(&ffa_req);
+	if (ffa_res != FFA_OK) {
+		*resp = (struct sp_msg){ 0 };
+		return SP_RESULT_INVALID_PARAMETERS;
+	}
 
 	ffa_res = ffa_msg_send_direct_resp_32(ffa_req.source_id,
 					   ffa_req.destination_id,
diff --git a/components/messaging/ffa/libsp/test/test_sp_messaging.cpp b/components/messaging/ffa/libsp/test/test_sp_messaging.cpp
index e6582e5..15aba01 100644
--- a/components/messaging/ffa/libsp/test/test_sp_messaging.cpp
+++ b/components/messaging/ffa/libsp/test/test_sp_messaging.cpp
@@ -10,11 +10,9 @@
 #include "mock_ffa_api.h"
 #include "../include/sp_messaging.h"
 
-#define SP_MSG_ARG_OFFSET (1)
-
 #if FFA_DIRECT_MSG_ROUTING_EXTENSION
-#define ROUTING_EXT_RC_BIT BIT(0)
-#define ROUTING_EXT_ERR_BIT BIT(1)
+#define ROUTING_EXT_RC_BIT BIT(31)
+#define ROUTING_EXT_ERR_BIT BIT(30)
 #endif
 
 TEST_GROUP(sp_messaging)
@@ -37,7 +35,7 @@
 		int i = 0;
 
 		for (i = 0; i < SP_MSG_ARG_COUNT; i++) {
-			ffa_args[i + SP_MSG_ARG_OFFSET] = sp_args[i];
+			ffa_args[i] = sp_args[i];
 		}
 	}
 
@@ -46,7 +44,7 @@
 		int i = 0;
 
 		for (i = 0; i < SP_MSG_ARG_COUNT; i++) {
-			ffa_args[i + SP_MSG_ARG_OFFSET] = sp_args[i];
+			ffa_args[i] = sp_args[i];
 		}
 	}
 
@@ -58,9 +56,8 @@
 		msg->source_id = source_id;
 		msg->destination_id = dest_id;
 
-		msg->args.args32[0] = 0;
 		for (i = 0; i < SP_MSG_ARG_COUNT; i++) {
-			msg->args.args32[i + SP_MSG_ARG_OFFSET] = args32[i];
+			msg->args.args32[i] = args32[i];
 		}
 	}
 
@@ -72,9 +69,8 @@
 		msg->source_id = source_id;
 		msg->destination_id = dest_id;
 
-		msg->args.args64[0] = 0;
 		for (i = 0; i < SP_MSG_ARG_COUNT; i++) {
-			msg->args.args64[i + SP_MSG_ARG_OFFSET] = args64[i];
+			msg->args.args64[i] = args64[i];
 		}
 	}
 
@@ -86,7 +82,7 @@
 		msg->destination_id = dest_id;
 		msg->is_64bit_message = false;
 		for (i = 0; i < SP_MSG_ARG_COUNT; i++) {
-			msg->args.args32[i] = args32[i + SP_MSG_ARG_OFFSET];
+			msg->args.args32[i] = args32[i];
 		}
 	}
 
@@ -98,7 +94,7 @@
 		msg->destination_id = dest_id;
 		msg->is_64bit_message = true;
 		for (i = 0; i < SP_MSG_ARG_COUNT; i++) {
-			msg->args.args64[i] = args64[i + SP_MSG_ARG_OFFSET];
+			msg->args.args64[i] = args64[i];
 		}
 	}
 
@@ -114,13 +110,13 @@
 		if (sp_msg->is_64bit_message) {
 			for (i = 0; i < SP_MSG_ARG_COUNT; i++) {
 				UNSIGNED_LONGLONGS_EQUAL(
-					ffa_msg->args.args64[i + SP_MSG_ARG_OFFSET],
+					ffa_msg->args.args64[i],
 					sp_msg->args.args64[i]);
 			}
 		} else {
 			for (i = 0; i < SP_MSG_ARG_COUNT; i++) {
 				UNSIGNED_LONGS_EQUAL(
-					ffa_msg->args.args32[i + SP_MSG_ARG_OFFSET],
+					ffa_msg->args.args32[i],
 					sp_msg->args.args32[i]);
 			}
 		}
@@ -149,9 +145,10 @@
 	const uint16_t source_id = 0x1234;
 	const uint16_t dest_id = 0x5678;
 	const uint32_t args32[SP_MSG_ARG_COUNT] = { 0x01234567, 0x12345678,
-						    0x23456789, 0x3456789a };
+						    0x23456789, 0x3456789a, 0xbcdef012 };
 	const uint64_t args64[SP_MSG_ARG_COUNT] = { 0x0123456776543210, 0x1234567887654321,
-						    0x2345678998765432, 0x3456789aa9876543 };
+						    0x2345678998765432, 0x3456789aa9876543,
+						    0x210fedcba9876543 };
 	const sp_result result = -1;
 	const sp_msg empty_sp_msg = (const sp_msg){ 0 };
 };
@@ -299,6 +296,17 @@
 }
 
 #if FFA_DIRECT_MSG_ROUTING_EXTENSION
+TEST(sp_messaging, sp_msg_send_direct_req_rc_bits_conflict)
+{
+	sp_msg sp_req = { 0 };
+	sp_msg sp_resp = { 0 };
+
+	fill_sp_msg_32(&sp_req);
+	sp_req.args.args32[0] |= ROUTING_EXT_RC_BIT;
+
+	LONGS_EQUAL(SP_RESULT_INVALID_PARAMETERS, sp_msg_send_direct_req(&sp_req, &sp_resp));
+}
+
 TEST(sp_messaging, sp_msg_send_direct_req_rc_forwarding_success)
 {
 	const uint16_t root_id = 1;
@@ -345,9 +353,9 @@
 	wait_and_receive_request(root_id, own_id);
 
 	/* Sending request and receiving RC request from RC root */
-	expect_ffa_msg_send_direct_req_32(own_id, rc_root_id, 0, req.args.args32[1],
-				       req.args.args32[2], req.args.args32[3], req.args.args32[4],
-				       &rc_req, FFA_OK);
+	expect_ffa_msg_send_direct_req_32(own_id, rc_root_id, req.args.args32[0],
+					  req.args.args32[1], req.args.args32[2],
+					  req.args.args32[3], req.args.args32[4], &rc_req, FFA_OK);
 
 	/* Forwarding RC request to root and receiving RC response */
 	expect_ffa_msg_send_direct_resp_32(own_id, root_id, rc_req.args.args32[0],
@@ -395,9 +403,10 @@
 	wait_and_receive_request(root_id, own_id);
 
 	/* Sending request and receiving RC request from RC root */
-	expect_ffa_msg_send_direct_req_32(own_id, rc_root_id, 0, req.args.args32[1],
-				       req.args.args32[2], req.args.args32[3], req.args.args32[4],
-				       &rc_err, FFA_OK);
+	expect_ffa_msg_send_direct_req_32(own_id, rc_root_id, req.args.args32[0],
+					  req.args.args32[1], req.args.args32[2],
+					  req.args.args32[3], req.args.args32[4],
+					  &rc_err, FFA_OK);
 
 	LONGS_EQUAL(SP_RESULT_FFA(result),
 		    sp_msg_send_direct_req(&sp_req, &sp_resp));
@@ -456,9 +465,10 @@
 	wait_and_receive_request(root_id, own_id);
 
 	/* Sending request and receiving RC request from RC root */
-	expect_ffa_msg_send_direct_req_32(own_id, rc_root_id, 0, req.args.args32[1],
-				       req.args.args32[2], req.args.args32[3], req.args.args32[4],
-				       &rc_req, FFA_OK);
+	expect_ffa_msg_send_direct_req_32(own_id, rc_root_id, req.args.args32[0],
+					 req.args.args32[1], req.args.args32[2],
+					 req.args.args32[3], req.args.args32[4],
+					 &rc_req, FFA_OK);
 
 	/* Forwarding RC request to root and receiving a request to deny */
 	expect_ffa_msg_send_direct_resp_32(own_id, root_id, rc_req.args.args32[0],
@@ -534,9 +544,10 @@
 	wait_and_receive_request(root_id, own_id);
 
 	/* Sending request and receiving RC request from RC root */
-	expect_ffa_msg_send_direct_req_32(own_id, rc_root_id, 0, req.args.args32[1],
-				       req.args.args32[2], req.args.args32[3], req.args.args32[4],
-				       &rc_req, FFA_OK);
+	expect_ffa_msg_send_direct_req_32(own_id, rc_root_id, req.args.args32[0],
+					  req.args.args32[1], req.args.args32[2],
+					  req.args.args32[3], req.args.args32[4],
+					  &rc_req, FFA_OK);
 
 	/* Forwarding RC request to root and receiving RC response */
 	expect_ffa_msg_send_direct_resp_32(own_id, root_id, rc_req.args.args32[0],
@@ -612,9 +623,10 @@
 	wait_and_receive_request(root_id, own_id);
 
 	/* Sending request and receiving RC request from RC root */
-	expect_ffa_msg_send_direct_req_32(own_id, rc_root_id, 0, req.args.args32[1],
-				       req.args.args32[2], req.args.args32[3], req.args.args32[4],
-				       &rc_req, FFA_OK);
+	expect_ffa_msg_send_direct_req_32(own_id, rc_root_id, req.args.args32[0],
+					  req.args.args32[1], req.args.args32[2],
+					  req.args.args32[3], req.args.args32[4],
+					  &rc_req, FFA_OK);
 
 	/* Forwarding RC request to root and receiving RC response */
 	expect_ffa_msg_send_direct_resp_32(own_id, root_id, rc_req.args.args32[0],
@@ -693,9 +705,10 @@
 	wait_and_receive_request(root_id, own_id);
 
 	/* Sending request and receiving RC request from RC root */
-	expect_ffa_msg_send_direct_req_32(own_id, rc_root_id, 0, req.args.args32[1],
-				       req.args.args32[2], req.args.args32[3], req.args.args32[4],
-				       &rc_req, FFA_OK);
+	expect_ffa_msg_send_direct_req_32(own_id, rc_root_id, req.args.args32[0],
+					  req.args.args32[1], req.args.args32[2],
+					  req.args.args32[3], req.args.args32[4],
+					  &rc_req, FFA_OK);
 
 	/* Forwarding RC request to root and receiving RC response */
 	expect_ffa_msg_send_direct_resp_32(own_id, root_id, rc_req.args.args32[0],
@@ -767,9 +780,10 @@
 	wait_and_receive_request(root_id, own_id);
 
 	/* Sending request and receiving RC request from RC root */
-	expect_ffa_msg_send_direct_req_32(own_id, rc_root_id, 0, req.args.args32[1],
-				       req.args.args32[2], req.args.args32[3], req.args.args32[4],
-				       &rc_req, FFA_OK);
+	expect_ffa_msg_send_direct_req_32(own_id, rc_root_id, req.args.args32[0],
+					  req.args.args32[1], req.args.args32[2],
+					  req.args.args32[3], req.args.args32[4],
+					  &rc_req, FFA_OK);
 
 	/* Forwarding RC request to root and receiving RC response */
 	expect_ffa_msg_send_direct_resp_32(own_id, root_id, rc_req.args.args32[0],
@@ -834,9 +848,10 @@
 	wait_and_receive_request(root_id, own_id);
 
 	/* Sending request and receiving RC request from RC root */
-	expect_ffa_msg_send_direct_req_32(own_id, rc_root_id, 0, req.args.args32[1],
-				       req.args.args32[2], req.args.args32[3], req.args.args32[4],
-				       &rc_req, FFA_OK);
+	expect_ffa_msg_send_direct_req_32(own_id, rc_root_id, req.args.args32[0],
+					  req.args.args32[1], req.args.args32[2],
+					  req.args.args32[3], req.args.args32[4],
+					  &rc_req, FFA_OK);
 
 	/* Forwarding RC request to root and receiving RC response */
 	expect_ffa_msg_send_direct_resp_32(own_id, root_id, rc_req.args.args32[0],
@@ -940,6 +955,17 @@
 }
 
 #if FFA_DIRECT_MSG_ROUTING_EXTENSION
+TEST(sp_messaging, sp_msg_send_direct_resp_rc_bits_conflict)
+{
+	sp_msg sp_req = { 0 };
+	sp_msg sp_resp = { 0 };
+
+	fill_sp_msg_32(&sp_resp);
+	sp_resp.args.args32[0] |= ROUTING_EXT_RC_BIT;
+
+	LONGS_EQUAL(SP_RESULT_INVALID_PARAMETERS, sp_msg_send_direct_resp(&sp_resp, &sp_req));
+}
+
 TEST(sp_messaging, sp_msg_send_direct_resp_deny_rc_failure)
 {
 	uint32_t expected_ffa_args[5] = { 0 };
@@ -981,11 +1007,10 @@
 	fill_ffa_msg_32(&ffa_msg);
 	copy_sp_to_ffa_args_32(resp.args.args32, expected_ffa_args);
 
-	expect_ffa_msg_send_direct_resp_32(resp.source_id, resp.destination_id, 0,
-					expected_ffa_args[1],
-					expected_ffa_args[2],
-					expected_ffa_args[3],
-					expected_ffa_args[4], &rc_msg, FFA_OK);
+	expect_ffa_msg_send_direct_resp_32(resp.source_id, resp.destination_id,
+					   expected_ffa_args[0], expected_ffa_args[1],
+					   expected_ffa_args[2], expected_ffa_args[3],
+					   expected_ffa_args[4], &rc_msg, FFA_OK);
 
 	expect_ffa_msg_send_direct_resp_32(
 		rc_msg.destination_id, rc_msg.source_id,
@@ -1010,18 +1035,30 @@
 	MEMCMP_EQUAL(&empty_sp_msg, &resp, sizeof(empty_sp_msg));
 }
 
+TEST(sp_messaging, sp_msg_send_direct_rc_resp_rc_bits_conflict)
+{
+	sp_msg sp_req = { 0 };
+	sp_msg sp_resp = { 0 };
+
+	fill_sp_msg_32(&sp_req);
+	sp_req.args.args32[0] |= ROUTING_EXT_RC_BIT;
+
+	LONGS_EQUAL(SP_RESULT_INVALID_PARAMETERS, sp_msg_send_rc_req(&sp_req, &sp_resp));
+}
+
 TEST(sp_messaging, sp_msg_send_rc_req_ffa_error)
 {
 	ffa_result result = FFA_ABORTED;
 
 	fill_sp_msg_32(&resp);
 	memset(&req, 0x5a, sizeof(req));
+	req.args.args32[0] &= ~0xc0000000;
 	req.is_64bit_message = false;
 	fill_ffa_msg_32(&ffa_msg);
 
 	expect_ffa_msg_send_direct_resp_32(req.source_id, req.destination_id,
-					ROUTING_EXT_RC_BIT, req.args.args32[0],
-					req.args.args32[1], req.args.args32[2], req.args.args32[3],
+					ROUTING_EXT_RC_BIT | req.args.args32[0], req.args.args32[1],
+					req.args.args32[2], req.args.args32[3], req.args.args32[4],
 					&ffa_msg, result);
 
 	LONGS_EQUAL(SP_RESULT_FFA(result), sp_msg_send_rc_req(&req, &resp));
@@ -1046,8 +1083,8 @@
 	ffa_msg.args.args32[0] = 0;
 
 	expect_ffa_msg_send_direct_resp_32(req.source_id, req.destination_id,
-					ROUTING_EXT_RC_BIT, req.args.args32[0],
-					req.args.args32[1], req.args.args32[2], req.args.args32[3],
+					ROUTING_EXT_RC_BIT | req.args.args32[0], req.args.args32[1],
+					req.args.args32[2], req.args.args32[3], req.args.args32[4],
 					&ffa_msg, FFA_OK);
 
 	expect_ffa_msg_send_direct_resp_32(
@@ -1080,8 +1117,8 @@
 	ffa_msg.args.args32[1] = sp_err;
 
 	expect_ffa_msg_send_direct_resp_32(req.source_id, req.destination_id,
-					ROUTING_EXT_RC_BIT, req.args.args32[0],
-					req.args.args32[1], req.args.args32[2], req.args.args32[3],
+					ROUTING_EXT_RC_BIT | req.args.args32[0], req.args.args32[1],
+					req.args.args32[2], req.args.args32[3], req.args.args32[4],
 					&ffa_msg, FFA_OK);
 
 	LONGS_EQUAL(sp_err, sp_msg_send_rc_req(&req, &resp));
@@ -1102,11 +1139,11 @@
 	fill_ffa_msg_32(&ffa_msg);
 	ffa_msg.source_id = root_id;
 	ffa_msg.destination_id = own_id;
-	ffa_msg.args.args32[0] = ROUTING_EXT_RC_BIT;
+	ffa_msg.args.args32[0] = ROUTING_EXT_RC_BIT | req.args.args32[0];
 
 	expect_ffa_msg_send_direct_resp_32(req.source_id, req.destination_id,
-					ROUTING_EXT_RC_BIT, req.args.args32[0],
-					req.args.args32[1], req.args.args32[2], req.args.args32[3],
+					ROUTING_EXT_RC_BIT | req.args.args32[0], req.args.args32[1],
+					req.args.args32[2], req.args.args32[3], req.args.args32[4],
 					&ffa_msg, FFA_OK);
 
 	LONGS_EQUAL(SP_RESULT_OK, sp_msg_send_rc_req(&req, &resp));
diff --git a/components/rpc/common/caller/component.cmake b/components/rpc/common/caller/component.cmake
index 9cb5138..0c8934a 100644
--- a/components/rpc/common/caller/component.cmake
+++ b/components/rpc/common/caller/component.cmake
@@ -8,6 +8,16 @@
 	message(FATAL_ERROR "mandatory parameter TGT is not defined.")
 endif()
 
+target_include_directories(${TGT} PRIVATE
+	"${CMAKE_CURRENT_LIST_DIR}"
+)
+
+set_property(TARGET ${TGT} APPEND PROPERTY PUBLIC_HEADER
+	"${CMAKE_CURRENT_LIST_DIR}/rpc_caller_session.h"
+	"${CMAKE_CURRENT_LIST_DIR}/rpc_caller.h"
+	)
+
 target_sources(${TGT} PRIVATE
+	"${CMAKE_CURRENT_LIST_DIR}/rpc_caller_session.c"
 	"${CMAKE_CURRENT_LIST_DIR}/rpc_caller.c"
 	)
diff --git a/components/rpc/common/caller/rpc_caller.c b/components/rpc/common/caller/rpc_caller.c
index 2dceabe..4af9d8c 100644
--- a/components/rpc/common/caller/rpc_caller.c
+++ b/components/rpc/common/caller/rpc_caller.c
@@ -1,39 +1,63 @@
 /*
- * Copyright (c) 2020-2021, Arm Limited and Contributors. All rights reserved.
+ * Copyright (c) 2020-2023, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
 
-#include <rpc_caller.h>
-#include <stdint.h>
-#include <protocols/rpc/common/packed-c/encoding.h>
+#include "rpc_caller.h"
 
-void rpc_caller_init(struct rpc_caller *s, void *context)
+rpc_status_t rpc_caller_open_session(struct rpc_caller_interface *caller,
+				     const struct rpc_uuid *service_uuid,
+				     uint16_t endpoint_id)
 {
-	s->context = context;
+	if (!caller)
+		return RPC_ERROR_INVALID_VALUE;
 
-	/* The default encoding scheme - may be overridden by a client */
-	s->encoding = TS_RPC_ENCODING_PACKED_C;
+	return caller->open_session(caller->context, service_uuid, endpoint_id);
 }
 
-void rpc_caller_set_encoding_scheme(struct rpc_caller *s, uint32_t encoding)
+rpc_status_t rpc_caller_find_and_open_session(struct rpc_caller_interface *caller,
+					      const struct rpc_uuid *service_uuid)
 {
-	s->encoding = encoding;
+	if (!caller)
+		return RPC_ERROR_INVALID_VALUE;
+
+	return caller->find_and_open_session(caller->context, service_uuid);
 }
 
-rpc_call_handle rpc_caller_begin(struct rpc_caller *s,
-								uint8_t **req_buf, size_t req_len)
+rpc_status_t rpc_caller_close_session(struct rpc_caller_interface *caller)
 {
-	return s->call_begin(s->context, req_buf, req_len);
+	if (!caller)
+		return RPC_ERROR_INVALID_VALUE;
+
+	return caller->close_session(caller->context);
 }
 
-rpc_status_t rpc_caller_invoke(struct rpc_caller *s, rpc_call_handle handle,
-			uint32_t opcode, rpc_opstatus_t *opstatus, uint8_t **resp_buf, size_t *resp_len)
+rpc_status_t rpc_caller_create_shared_memory(struct rpc_caller_interface *caller, size_t length,
+					     struct rpc_caller_shared_memory *shared_memory)
 {
-	return s->call_invoke(s->context, handle, opcode, opstatus, resp_buf, resp_len);
+	if (!caller)
+		return RPC_ERROR_INVALID_VALUE;
+
+	return caller->create_shared_memory(caller->context, length, shared_memory);
 }
 
-void rpc_caller_end(struct rpc_caller *s, rpc_call_handle handle)
+rpc_status_t rpc_caller_release_shared_memory(struct rpc_caller_interface *caller,
+					      struct rpc_caller_shared_memory *shared_memory)
 {
-	s->call_end(s->context, handle);
+	if (!caller)
+		return RPC_ERROR_INVALID_VALUE;
+
+	return caller->release_shared_memory(caller->context, shared_memory);
+}
+
+rpc_status_t rpc_caller_call(struct rpc_caller_interface *caller, uint16_t opcode,
+			     struct rpc_caller_shared_memory *shared_memory, size_t request_length,
+			     size_t *response_length, service_status_t *service_status)
+{
+	if (!caller)
+		return RPC_ERROR_INVALID_VALUE;
+
+	return caller->call(caller->context, opcode, shared_memory, request_length,
+			    response_length, service_status);
 }
diff --git a/components/rpc/common/caller/rpc_caller.h b/components/rpc/common/caller/rpc_caller.h
new file mode 100644
index 0000000..9581fd0
--- /dev/null
+++ b/components/rpc/common/caller/rpc_caller.h
@@ -0,0 +1,86 @@
+/*
+ * Copyright (c) 2023, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef RPC_CALLER_H
+#define RPC_CALLER_H
+
+#include "rpc_status.h"
+#include "rpc_uuid.h"
+#include <stddef.h>
+#include <stdint.h>
+
+/*
+ * The rpc_caller public interface may be exported as a public interface to
+ * a shared library.
+ */
+#ifdef EXPORT_PUBLIC_INTERFACE_RPC_CALLER
+#define RPC_CALLER_EXPORTED __attribute__((__visibility__("default")))
+#else
+#define RPC_CALLER_EXPORTED
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * @brief Shared memory descriptor of an RPC caller
+ *
+ */
+struct rpc_caller_shared_memory {
+	uint64_t id;	/** Implementation defined ID of the shared memory */
+	void *buffer;	/** Address of the shared memory (virtual) */
+	size_t size;	/** Size of the shared memory */
+};
+
+struct rpc_caller_interface {
+	void *context;
+
+	rpc_status_t (*open_session)(void *context, const struct rpc_uuid *service_uuid,
+				     uint16_t endpoint_id);
+	rpc_status_t (*find_and_open_session)(void *context, const struct rpc_uuid *service_uuid);
+	rpc_status_t (*close_session)(void *context);
+
+	rpc_status_t (*create_shared_memory)(void *context, size_t size,
+					     struct rpc_caller_shared_memory *shared_memory);
+	rpc_status_t (*release_shared_memory)(void *context,
+					      struct rpc_caller_shared_memory *shared_memory);
+
+	rpc_status_t (*call)(void *context, uint16_t opcode,
+			     struct rpc_caller_shared_memory *shared_memory, size_t request_length,
+			     size_t *response_length, service_status_t *service_status);
+};
+
+RPC_CALLER_EXPORTED
+rpc_status_t rpc_caller_open_session(struct rpc_caller_interface *caller,
+				     const struct rpc_uuid *service_uuid,
+				     uint16_t endpoint_id);
+
+RPC_CALLER_EXPORTED
+rpc_status_t rpc_caller_find_and_open_session(struct rpc_caller_interface *caller,
+					      const struct rpc_uuid *service_uuid);
+
+RPC_CALLER_EXPORTED
+rpc_status_t rpc_caller_close_session(struct rpc_caller_interface *caller);
+
+RPC_CALLER_EXPORTED
+rpc_status_t rpc_caller_create_shared_memory(struct rpc_caller_interface *caller, size_t size,
+					     struct rpc_caller_shared_memory *shared_memory);
+
+RPC_CALLER_EXPORTED
+rpc_status_t rpc_caller_release_shared_memory(struct rpc_caller_interface *caller,
+					      struct rpc_caller_shared_memory *shared_memory);
+
+RPC_CALLER_EXPORTED
+rpc_status_t rpc_caller_call(struct rpc_caller_interface *caller, uint16_t opcode,
+			     struct rpc_caller_shared_memory *shared_memory, size_t request_length,
+			     size_t *response_length, service_status_t *service_status);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* RPC_CALLER_H */
diff --git a/components/rpc/common/caller/rpc_caller_session.c b/components/rpc/common/caller/rpc_caller_session.c
new file mode 100644
index 0000000..d72a318
--- /dev/null
+++ b/components/rpc/common/caller/rpc_caller_session.c
@@ -0,0 +1,217 @@
+/*
+ * Copyright (c) 2023, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include "rpc_caller_session.h"
+#include "util.h"
+#include <string.h>
+
+static rpc_status_t initalize_shared_memory(struct rpc_caller_session *session,
+					    struct rpc_caller_interface *caller,
+					    size_t shared_memory_size)
+{
+	if (shared_memory_size) {
+		rpc_status_t status = RPC_ERROR_INTERNAL;
+
+		status = rpc_caller_create_shared_memory(caller, shared_memory_size,
+							 &session->shared_memory);
+		if (status) {
+			rpc_caller_close_session(caller);
+			return status;
+		}
+
+		session->shared_memory_policy = alloc_for_session;
+	} else {
+		session->shared_memory = (struct rpc_caller_shared_memory){ 0 };
+		session->shared_memory_policy = alloc_for_each_call;
+	}
+
+	return RPC_SUCCESS;
+}
+
+rpc_status_t rpc_caller_session_open(struct rpc_caller_session *session,
+				     struct rpc_caller_interface *caller,
+				     const struct rpc_uuid *service_uuid,
+				     uint16_t endpoint_id,
+				     size_t shared_memory_size)
+{
+	rpc_status_t status = RPC_ERROR_INTERNAL;
+
+	if (!session || !caller || !service_uuid)
+		return RPC_ERROR_INVALID_VALUE;
+
+	status = rpc_caller_open_session(caller, service_uuid, endpoint_id);
+	if (status)
+		return status;
+
+	status = initalize_shared_memory(session, caller, shared_memory_size);
+	if (status)
+		return status;
+
+	session->caller = caller;
+	session->is_call_transaction_in_progress = false;
+	session->request_length = 0;
+
+	return status;
+}
+
+rpc_status_t rpc_caller_session_find_and_open(struct rpc_caller_session *session,
+					      struct rpc_caller_interface *caller,
+					      const struct rpc_uuid *service_uuid,
+					      size_t shared_memory_size)
+{
+	rpc_status_t status = RPC_ERROR_INTERNAL;
+
+	if (!session || !caller || !service_uuid)
+		return RPC_ERROR_INVALID_VALUE;
+
+	status = rpc_caller_find_and_open_session(caller, service_uuid);
+	if (status)
+		return status;
+
+	status = initalize_shared_memory(session, caller, shared_memory_size);
+	if (status)
+		return status;
+
+	session->caller = caller;
+	session->is_call_transaction_in_progress = false;
+	session->request_length = 0;
+
+	return status;
+}
+
+rpc_status_t rpc_caller_session_close(struct rpc_caller_session *session)
+{
+	if (!session)
+		return RPC_ERROR_INVALID_VALUE;
+
+	if (session->is_call_transaction_in_progress)
+		return RPC_ERROR_INVALID_STATE;
+
+	if (session->shared_memory_policy == alloc_for_session) {
+		rpc_status_t rpc_status = RPC_ERROR_INTERNAL;
+
+		rpc_status = rpc_caller_release_shared_memory(session->caller,
+							      &session->shared_memory);
+		if (rpc_status != RPC_SUCCESS)
+			return rpc_status;
+	}
+
+	return rpc_caller_close_session(session->caller);
+}
+
+rpc_call_handle rpc_caller_session_begin(struct rpc_caller_session *session,
+					 uint8_t **request_buffer, size_t request_length,
+					 size_t response_max_length)
+{
+	rpc_status_t status = RPC_ERROR_INTERNAL;
+	size_t required_buffer_length = MAX(request_length, response_max_length);
+
+	if (required_buffer_length > UINT32_MAX)
+		return NULL;
+
+	if (!session || !request_buffer || session->is_call_transaction_in_progress)
+		return NULL;
+
+	switch (session->shared_memory_policy) {
+	case alloc_for_each_call:
+		if (session->shared_memory.buffer || session->shared_memory.size)
+			return NULL; /* There's already a shared memory */
+
+		status = rpc_caller_create_shared_memory(session->caller, required_buffer_length,
+							 &session->shared_memory);
+		if (status)
+			return NULL; /* Failed to create shared memory */
+		break;
+
+	case alloc_for_session:
+		if (!session->shared_memory.buffer || !session->shared_memory.size)
+			return NULL; /* There's no shared memory */
+
+		if (session->shared_memory.size < required_buffer_length)
+			return NULL; /* The allocated shared memory is too small */
+		break;
+
+	default:
+		/* Invalid shared memory policy */
+		return NULL;
+	}
+
+	*request_buffer = session->shared_memory.buffer;
+
+	session->is_call_transaction_in_progress = true;
+	session->request_length = request_length;
+
+	return (rpc_call_handle)session;
+}
+
+rpc_status_t rpc_caller_session_invoke(rpc_call_handle handle, uint32_t opcode,
+				       uint8_t **response_buffer, size_t *response_length,
+				       service_status_t *service_status)
+{
+	struct rpc_caller_session *session = (struct rpc_caller_session *)handle;
+	rpc_status_t status = RPC_ERROR_INTERNAL;
+
+	if (!handle || !response_buffer || !response_length)
+		return RPC_ERROR_INVALID_VALUE;
+
+	if (!session->is_call_transaction_in_progress)
+		return RPC_ERROR_INVALID_STATE;
+
+	if (session->request_length &&
+	    (!session->shared_memory.buffer || !session->shared_memory.size))
+		return RPC_ERROR_INVALID_STATE;
+
+	status = rpc_caller_call(session->caller, opcode, &session->shared_memory,
+				session->request_length, response_length, service_status);
+	if (status || *response_length > session->shared_memory.size) {
+		*response_buffer = NULL;
+		*response_length = 0;
+		return status;
+	}
+
+	*response_buffer = session->shared_memory.buffer;
+
+	return status;
+}
+
+rpc_status_t rpc_caller_session_end(rpc_call_handle handle)
+{
+	struct rpc_caller_session *session = (struct rpc_caller_session *)handle;
+	rpc_status_t status = RPC_ERROR_INTERNAL;
+
+	if (!handle)
+		return RPC_ERROR_INVALID_VALUE;
+
+	if (!session->is_call_transaction_in_progress)
+		return RPC_ERROR_INVALID_STATE;
+
+	if (session->request_length &&
+	    (!session->shared_memory.buffer || !session->shared_memory.size))
+		return RPC_ERROR_INVALID_STATE; /* There's no shared memory */
+
+	switch (session->shared_memory_policy) {
+	case alloc_for_each_call:
+		status = rpc_caller_release_shared_memory(session->caller,
+								&session->shared_memory);
+		if (status)
+			return status; /* Failed to release shared memory */
+
+		session->shared_memory = (struct rpc_caller_shared_memory){ 0 };
+		break;
+
+	case alloc_for_session:
+		/* Nothing to do */
+		break;
+
+	default:
+		return RPC_ERROR_INVALID_STATE;
+	}
+
+	session->is_call_transaction_in_progress = false;
+	session->request_length = 0;
+
+	return RPC_SUCCESS;
+}
diff --git a/components/rpc/common/caller/rpc_caller_session.h b/components/rpc/common/caller/rpc_caller_session.h
new file mode 100644
index 0000000..debcf19
--- /dev/null
+++ b/components/rpc/common/caller/rpc_caller_session.h
@@ -0,0 +1,152 @@
+/*
+ * Copyright (c) 2023, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef RPC_CALLER_SESSION_H
+#define RPC_CALLER_SESSION_H
+
+#include "rpc_caller.h"
+#include "rpc_status.h"
+#include "rpc_uuid.h"
+#include <stdbool.h>
+#include <stddef.h>
+#include <stdint.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+typedef void *rpc_call_handle;
+
+enum rpc_caller_memory_policy {
+	alloc_for_each_call = 0,
+	alloc_for_session,
+};
+
+/**
+ * @brief RPC caller session
+ *
+ * Builds a session on top of the rpc_caller_interface. It provides high level functions for service
+ * caller implementations and for prior service discovery.
+ */
+struct rpc_caller_session {
+	/** Caller interface */
+	struct rpc_caller_interface *caller;
+
+	/** Shared memory instance for the exchanging of RPC request and response parameters. */
+	struct rpc_caller_shared_memory shared_memory;
+
+	/** Controls how and when the shared memory is allocated for the RPC calls. */
+	enum rpc_caller_memory_policy shared_memory_policy;
+
+	/**
+	 * Indicates if a call transaction has been started by the begin function but was not
+	 * finished yet (i.e. end was not called).
+	 */
+	bool is_call_transaction_in_progress;
+
+	/**
+	 * Stores the request length of the current transaction. Its value is set by the begin
+	 * function and then used in the invoke step.
+	 */
+	size_t request_length;
+};
+
+/**
+ * @brief
+ *
+ * @param session
+ * @param caller
+ * @param service_uuid
+ * @param endpoint_id
+ * @param shared_memory_size
+ * @return RPC_CALLER_EXPORTED
+ */
+RPC_CALLER_EXPORTED
+rpc_status_t rpc_caller_session_open(struct rpc_caller_session *session,
+				     struct rpc_caller_interface *caller,
+				     const struct rpc_uuid *service_uuid,
+				     uint16_t endpoint_id,
+				     size_t shared_memory_size);
+
+/**
+ * @brief
+ *
+ * @param session
+ * @param caller
+ * @param service_uuid
+ * @param shared_memory_size
+ * @return RPC_CALLER_EXPORTED
+ */
+RPC_CALLER_EXPORTED
+rpc_status_t rpc_caller_session_find_and_open(struct rpc_caller_session *session,
+					      struct rpc_caller_interface *caller,
+					      const struct rpc_uuid *service_uuid,
+					      size_t shared_memory_size);
+
+/**
+ * @brief Closes the RPC caller session
+ *
+ * @param session Caller session instance
+ * @return RPC_CALLER_EXPORTED
+ */
+RPC_CALLER_EXPORTED
+rpc_status_t rpc_caller_session_close(struct rpc_caller_session *session);
+
+/**
+ * @brief Begins an RPC call
+ *
+ * The function returns a buffer where the service caller can build the request.
+ *
+ * @param session Caller session instance
+ * @param request_buffer Pointer of the request buffer
+ * @param request_length Request length
+ * @param response_max_length Expected maximal length of the response
+ * @return rpc_call_handle Handle of the started call
+ */
+RPC_CALLER_EXPORTED
+rpc_call_handle rpc_caller_session_begin(struct rpc_caller_session *session,
+					 uint8_t **request_buffer,
+					 size_t request_length,
+					 size_t response_max_length);
+
+/**
+ * @brief Invoke phase of the RPC call
+ *
+ * Invokes the call on the remote side and returns the response buffer and service status. The
+ * service caller can parse the response from the response buffer.
+ * After this call the request buffer is not available for the service caller.
+ *
+ * @param handle RPC call handle
+ * @param opcode The opcode of the remote function
+ * @param response_buffer Pointer of the response buffer
+ * @param response_length Length of the response buffer
+ * @param service_status Service specific status code
+ * @return RPC_CALLER_EXPORTED
+ */
+RPC_CALLER_EXPORTED
+rpc_status_t rpc_caller_session_invoke(rpc_call_handle handle, uint32_t opcode,
+				       uint8_t **response_buffer,
+				       size_t *response_length,
+				       service_status_t *service_status);
+
+/**
+ * @brief Ends the RPC call
+ *
+ * Indicates if the response has been parsed by the service calls and the RPC session can free the
+ * response buffer.
+ *
+ * @param handle RPC call handle
+ * @return RPC_CALLER_EXPORTED
+ */
+RPC_CALLER_EXPORTED
+rpc_status_t rpc_caller_session_end(rpc_call_handle handle);
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* RPC_CALLER_SESSION_H */
diff --git a/components/rpc/common/demux/component.cmake b/components/rpc/common/demux/component.cmake
deleted file mode 100644
index a02eefc..0000000
--- a/components/rpc/common/demux/component.cmake
+++ /dev/null
@@ -1,13 +0,0 @@
-#-------------------------------------------------------------------------------
-# Copyright (c) 2021, Arm Limited and Contributors. All rights reserved.
-#
-# SPDX-License-Identifier: BSD-3-Clause
-#
-#-------------------------------------------------------------------------------
-if (NOT DEFINED TGT)
-	message(FATAL_ERROR "mandatory parameter TGT is not defined.")
-endif()
-
-target_sources(${TGT} PRIVATE
-	"${CMAKE_CURRENT_LIST_DIR}/rpc_demux.c"
-	)
diff --git a/components/rpc/common/demux/rpc_demux.c b/components/rpc/common/demux/rpc_demux.c
deleted file mode 100644
index 3460396..0000000
--- a/components/rpc/common/demux/rpc_demux.c
+++ /dev/null
@@ -1,57 +0,0 @@
-/*
- * Copyright (c) 2021, Arm Limited and Contributors. All rights reserved.
- *
- * SPDX-License-Identifier: BSD-3-Clause
- */
-
-#include <assert.h>
-#include <stddef.h>
-#include <protocols/rpc/common/packed-c/status.h>
-#include "rpc_demux.h"
-
-static rpc_status_t receive(struct rpc_interface *rpc_iface, struct call_req *req)
-{
-	rpc_status_t rpc_status = TS_RPC_ERROR_INTERFACE_DOES_NOT_EXIST;
-	struct rpc_demux *context = (struct rpc_demux*)rpc_iface->context;
-
-	unsigned int iface_id = call_req_get_interface_id(req);
-
-	if (iface_id < RPC_DEMUX_MAX_OUTPUTS) {
-
-		rpc_status = rpc_interface_receive(context->outputs[iface_id], req);
-	}
-
-	return rpc_status;
-}
-
-struct rpc_interface *rpc_demux_init(struct rpc_demux *context)
-{
-	context->input.receive = receive;
-	context->input.context = context;
-
-	for (unsigned int i = 0; i < RPC_DEMUX_MAX_OUTPUTS; ++i) {
-
-		context->outputs[i] = NULL;
-	}
-
-	return &context->input;
-}
-
-void rpc_demux_deinit(struct rpc_demux *context)
-{
-	(void)context;
-}
-
-void rpc_demux_attach(struct rpc_demux *context,
-	unsigned int iface_id, struct rpc_interface *output)
-{
-	assert(iface_id < RPC_DEMUX_MAX_OUTPUTS);
-	context->outputs[iface_id] = output;
-}
-
-void rpc_demux_dettach(struct rpc_demux *context,
-	unsigned int iface_id)
-{
-	assert(iface_id < RPC_DEMUX_MAX_OUTPUTS);
-	context->outputs[iface_id] = NULL;
-}
diff --git a/components/rpc/common/demux/rpc_demux.h b/components/rpc/common/demux/rpc_demux.h
deleted file mode 100644
index 46d7b0f..0000000
--- a/components/rpc/common/demux/rpc_demux.h
+++ /dev/null
@@ -1,78 +0,0 @@
-/*
- * Copyright (c) 2021, Arm Limited and Contributors. All rights reserved.
- *
- * SPDX-License-Identifier: BSD-3-Clause
- */
-
-#ifndef RPC_DEMUX_H
-#define RPC_DEMUX_H
-
-#include <rpc/common/endpoint/rpc_interface.h>
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-/*
- * The default maximum number of output interfaces.  May be
- * overridden to meet needs of deployment if necessary.
- */
-#ifndef RPC_DEMUX_MAX_OUTPUTS
-#define RPC_DEMUX_MAX_OUTPUTS				(8)
-#endif
-
-/** \brief RPC demux
- *
- * An rpc_demux is an rpc_interface that demultiplexes incoming call requests
- * to 1..* output interfaces.  Use an rpc_demux when multiple service
- * providers are co-located and associated with a single RPC endpoint.
- */
-struct rpc_demux
-{
-	struct rpc_interface input;
-	struct rpc_interface *outputs[RPC_DEMUX_MAX_OUTPUTS];
-};
-
-/**
- * \brief Initialize an rpc_demux
- *
- * After initialization, the required number of output interfaces need
- * to be attached,
- *
- * \param[in] context   The instance to initialize
- *
- * \return The input rpc_interface
- */
-struct rpc_interface *rpc_demux_init(struct rpc_demux *context);
-
-/**
- * \brief Cleans up when the instance is no longer needed
- *
- * \param[in] context   The instance to de-initialize
- */
-void rpc_demux_deinit(struct rpc_demux *context);
-
-/**
- * \brief Attach an output interface
- *
- * \param[in] context   The rpc_demux instance
- * \param[in] iface_id	The interface id (small integer)
- * \param[in] output	The interface to attach
- */
-void rpc_demux_attach(struct rpc_demux *context,
-	unsigned int iface_id, struct rpc_interface *output);
-
-/**
- * \brief Dettach an output interface
- *
- * \param[in] context   The rpc_demux instance
- * \param[in] iface_id	The interface id (small integer)
- */
-void rpc_demux_dettach(struct rpc_demux *context,
-	unsigned int iface_id);
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* RPC_DEMUX_H */
diff --git a/components/rpc/ffarpc/endpoint/component.cmake b/components/rpc/common/endpoint/component.cmake
similarity index 88%
rename from components/rpc/ffarpc/endpoint/component.cmake
rename to components/rpc/common/endpoint/component.cmake
index 9e43ac5..7d83028 100644
--- a/components/rpc/ffarpc/endpoint/component.cmake
+++ b/components/rpc/common/endpoint/component.cmake
@@ -9,6 +9,6 @@
 endif()
 
 target_sources(${TGT} PRIVATE
-	"${CMAKE_CURRENT_LIST_DIR}/ffarpc_call_ep.c"
+	"${CMAKE_CURRENT_LIST_DIR}/rpc_service_interface.c"
 	)
 
diff --git a/components/rpc/common/endpoint/rpc_interface.h b/components/rpc/common/endpoint/rpc_interface.h
deleted file mode 100644
index eb98587..0000000
--- a/components/rpc/common/endpoint/rpc_interface.h
+++ /dev/null
@@ -1,138 +0,0 @@
-/*
- * Copyright (c) 2020-2021, Arm Limited and Contributors. All rights reserved.
- *
- * SPDX-License-Identifier: BSD-3-Clause
- */
-
-#ifndef RPC_INTERFACE_H
-#define RPC_INTERFACE_H
-
-#include <stddef.h>
-#include <stdint.h>
-#include <rpc_status.h>
-#include <protocols/rpc/common/packed-c/status.h>
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-/* Definitions related to an rpc call endpoint */
-
-/** \brief Call parameter buffer
- *
- * Describes a buffer for holding call request and response parameters.
- */
-struct call_param_buf {
-	size_t size;
-	size_t data_len;
-	void *data;
-};
-
-static inline struct call_param_buf call_param_buf_init_empty(void *data, size_t size)
-{
-	struct call_param_buf v;
-
-	v.size = size;
-	v.data_len = 0;
-	v.data = data;
-
-	return v;
-}
-
-static inline struct call_param_buf call_param_buf_init_full(void *data,
-							       size_t size,
-							       size_t data_len)
-{
-	struct call_param_buf v;
-
-	v.size = size;
-	v.data_len = data_len;
-	v.data = data;
-
-	return v;
-}
-
-/** \brief Call request
- *
- * A call request object represents a request from a client that will
- * be handled by a call endpoint.
- */
-struct call_req {
-	uint32_t caller_id;
-	uint32_t interface_id;
-	uint32_t opcode;
-	uint32_t encoding;
-	rpc_opstatus_t opstatus;
-	struct call_param_buf req_buf;
-	struct call_param_buf resp_buf;
-};
-
-static inline uint32_t call_req_get_caller_id(const struct call_req *req)
-{
-	return req->caller_id;
-}
-
-static inline uint32_t call_req_get_interface_id(const struct call_req *req)
-{
-	return req->interface_id;
-}
-
-static inline uint32_t call_req_get_opcode(const struct call_req *req)
-{
-	return req->opcode;
-}
-
-static inline uint32_t call_req_get_encoding(const struct call_req *req)
-{
-	return req->encoding;
-}
-
-static inline rpc_opstatus_t call_req_get_opstatus(const struct call_req *req)
-{
-	return req->opstatus;
-}
-
-static inline void call_req_set_opstatus(struct call_req *req, rpc_opstatus_t opstatus)
-{
-	req->opstatus = opstatus;
-}
-
-static inline struct call_param_buf *call_req_get_req_buf(struct call_req *req)
-{
-	return &req->req_buf;
-}
-
-static inline struct call_param_buf *call_req_get_resp_buf(struct call_req *req)
-{
-	return &req->resp_buf;
-}
-
-/** \brief RPC interface
- *
- * A generalized RPC interface.  Provides a standard interface for a
- * call endpoint that handles incoming call requests.
- */
-struct rpc_interface
-{
-	void *context;
-	rpc_status_t (*receive)(struct rpc_interface *iface, struct call_req *req);
-};
-
-static inline rpc_status_t rpc_interface_receive(struct rpc_interface *iface,
-					  struct call_req *req)
-{
-	rpc_status_t rpc_status = TS_RPC_ERROR_INTERFACE_DOES_NOT_EXIST;
-
-	if (iface) {
-
-		rpc_status = iface->receive(iface, req);
-	}
-
-	return rpc_status;
-}
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* RPC_INTERFACE_H */
diff --git a/components/rpc/common/endpoint/rpc_service_interface.c b/components/rpc/common/endpoint/rpc_service_interface.c
new file mode 100644
index 0000000..67eeb2e
--- /dev/null
+++ b/components/rpc/common/endpoint/rpc_service_interface.c
@@ -0,0 +1,16 @@
+/*
+ * Copyright (c) 2023, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include "rpc_service_interface.h"
+
+rpc_status_t rpc_service_receive(struct rpc_service_interface *service,
+				 struct rpc_request *request)
+{
+	if (!service)
+		return RPC_ERROR_INVALID_VALUE;
+
+	return service->receive(service->context, request);
+}
diff --git a/components/rpc/common/endpoint/rpc_service_interface.h b/components/rpc/common/endpoint/rpc_service_interface.h
new file mode 100644
index 0000000..3fdfed2
--- /dev/null
+++ b/components/rpc/common/endpoint/rpc_service_interface.h
@@ -0,0 +1,88 @@
+/*
+ * Copyright (c) 2020-2023, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef RPC_INTERFACE_H
+#define RPC_INTERFACE_H
+
+#include "rpc_status.h"
+#include "rpc_uuid.h"
+#include <stddef.h>
+#include <stdint.h>
+
+#ifdef EXPORT_PUBLIC_INTERFACE_RPC_SERVICE
+#define RPC_SERVICE_EXPORTED __attribute__((__visibility__("default")))
+#else
+#define RPC_SERVICE_EXPORTED
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * @brief RPC buffer
+ *
+ * Describes an RPC buffer by its data pointer, size and the used data length.
+ */
+struct rpc_buffer {
+	uint8_t *data;
+	size_t data_length;
+	size_t size;
+};
+
+/**
+ * @brief RPC request
+ *
+ * The service should select the requested function by the opcode field. The call's request and
+ * response parameter buffer is accessible via the request and response rpc_buffers. The response's
+ * size must be indicated by the service through setting the data_length field of the response.
+ * The services can identify the caller via the source_id and client_id fields.
+ */
+struct rpc_request {
+	uint16_t source_id;			/** Call source ID (i.e. FF-A source ID) */
+	uint8_t interface_id;			/** Service interface ID */
+	uint16_t opcode;			/** Opcode of the required function */
+	uint32_t client_id;			/** Client ID for further caller identification */
+	service_status_t service_status;	/** Service specific status code */
+	struct rpc_buffer request;		/** Request buffer */
+	struct rpc_buffer response;		/** Response buffer */
+};
+
+/**
+ * @brief RPC service interface
+ *
+ * An endpoint (i.e. secure partition) can implement multiple services which are identified by their
+ * service UUID. Once an endpoint receives an RPC call, it selects the matching
+ * rpc_service_interface instance, builds the rpc_request structure and calls the interface's
+ * receive function.
+ * If the service is not able to parse the request (invalid opcode, request or response buffer)
+ * it should return an rpc_status_t value indicating the issue with the RPC request. Otherwise it
+ * must return RPC_SUCCESS.
+ * Service level status codes should be passed in a service specific way.
+ */
+struct rpc_service_interface {
+	void *context;
+	struct rpc_uuid uuid;
+
+	rpc_status_t (*receive)(void *context, struct rpc_request *request);
+};
+
+/**
+ * @brief Call the receive function of the RPC interface.
+ *
+ * @param service The service instance
+ * @param request RPC request
+ * @return rpc_status_t
+ */
+RPC_SERVICE_EXPORTED
+rpc_status_t rpc_service_receive(struct rpc_service_interface *service,
+				 struct rpc_request *request);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* RPC_INTERFACE_H */
diff --git a/components/rpc/common/interface/component.cmake b/components/rpc/common/interface/component.cmake
index e4b2477..ae219d6 100644
--- a/components/rpc/common/interface/component.cmake
+++ b/components/rpc/common/interface/component.cmake
@@ -1,5 +1,5 @@
 #-------------------------------------------------------------------------------
-# Copyright (c) 2020-2022, Arm Limited and Contributors. All rights reserved.
+# Copyright (c) 2020-2023, Arm Limited and Contributors. All rights reserved.
 #
 # SPDX-License-Identifier: BSD-3-Clause
 #
@@ -9,11 +9,14 @@
 endif()
 
 set_property(TARGET ${TGT} APPEND PROPERTY PUBLIC_HEADER
-	"${CMAKE_CURRENT_LIST_DIR}/rpc_caller.h"
 	"${CMAKE_CURRENT_LIST_DIR}/rpc_status.h"
+	"${CMAKE_CURRENT_LIST_DIR}/rpc_uuid.h"
 	)
 
 target_include_directories(${TGT} PUBLIC
 	"$<BUILD_INTERFACE:${CMAKE_CURRENT_LIST_DIR}>"
-	"$<INSTALL_INTERFACE:${TS_ENV}/include>"
+	)
+
+target_sources(${TGT} PRIVATE
+	"${CMAKE_CURRENT_LIST_DIR}/rpc_uuid.c"
 	)
diff --git a/components/rpc/common/interface/rpc_caller.h b/components/rpc/common/interface/rpc_caller.h
deleted file mode 100644
index 387489c..0000000
--- a/components/rpc/common/interface/rpc_caller.h
+++ /dev/null
@@ -1,94 +0,0 @@
-/*
- * Copyright (c) 2020-2021, Arm Limited and Contributors. All rights reserved.
- *
- * SPDX-License-Identifier: BSD-3-Clause
- */
-
-#ifndef RPC_CALLER_H
-#define RPC_CALLER_H
-
-#include <stddef.h>
-#include <stdint.h>
-#include "rpc_status.h"
-
-/*
- * The rpc_caller puplic interface may be exported as a public interface to
- * a shared library.
- */
-#ifdef EXPORT_PUBLIC_INTERFACE_RPC_CALLER
-#define RPC_CALLER_EXPORTED __attribute__((__visibility__("default")))
-#else
-#define RPC_CALLER_EXPORTED
-#endif
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-/*
- * Defines an abstract interface for calling operations provided by an rpc endpoint.
- * Concrete specializations will map the an RPC or direct calling mechanism to
- * suite the deployment.
- */
-
-typedef void *rpc_call_handle;
-
-struct rpc_caller
-{
-	void *context;
-	uint32_t encoding;
-
-	/* A concrete rpc_caller implements these methods */
-	rpc_call_handle (*call_begin)(void *context, uint8_t **req_buf, size_t req_len);
-
-	rpc_status_t (*call_invoke)(void *context, rpc_call_handle handle, uint32_t opcode,
-		     	rpc_opstatus_t *opstatus, uint8_t **resp_buf, size_t *resp_len);
-
-	void (*call_end)(void *context, rpc_call_handle handle);
-};
-
-/*
- * Called by a concrete rpc_caller to initialise the base rpc_caller.
- */
-void rpc_caller_init(struct rpc_caller *s, void *context);
-
-/*
- * Allows a client to specify the parameter encoding scheme that the client
- * intends to use during an RPC session.  It is the client's responsiblity
- * to choose an encoding scheme that is supported by the remote interface.
- */
-RPC_CALLER_EXPORTED void rpc_caller_set_encoding_scheme(struct rpc_caller *s,
-			uint32_t encoding);
-
-/*
- * Starts a call transaction. The returned handle is an identifier for the
- * transaction and must be passed as a parameter to call_invoke() and
- * call_end(). A concrete rpc_caller may perform resource allocation during
- * this call. This will include a buffer for the request message parameters.
- * Returns a NULL handle on failure.
- */
-RPC_CALLER_EXPORTED rpc_call_handle rpc_caller_begin(struct rpc_caller *s,
-			uint8_t **req_buf, size_t req_len);
-
-/*
- * Invokes the operation identified by the opcode. This method blocks
- * until the operation completes. The status of the call is returned. An
- * additional endpoint specific status value is also returned. If a response
- * message was received, the concrete rpc_caller will have allocated a
- * buffer for the reponse. This buffer will hold valid data until the point when
- * call_end() is called for the transaction.
- */
-RPC_CALLER_EXPORTED rpc_status_t rpc_caller_invoke(struct rpc_caller *s, rpc_call_handle handle,
-			uint32_t opcode, rpc_opstatus_t *opstatus, uint8_t **resp_buf, size_t *resp_len);
-
-/*
- * Ends the call transaction, allowing any resource associated with the
- * transaction to be freed.
- */
-RPC_CALLER_EXPORTED void rpc_caller_end(struct rpc_caller *s, rpc_call_handle handle);
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* RPC_CALLER_H */
diff --git a/components/rpc/common/interface/rpc_status.h b/components/rpc/common/interface/rpc_status.h
index cba9dac..5cd2590 100644
--- a/components/rpc/common/interface/rpc_status.h
+++ b/components/rpc/common/interface/rpc_status.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2020-2021, Arm Limited and Contributors. All rights reserved.
+ * Copyright (c) 2020-2023, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -13,22 +13,24 @@
 extern "C" {
 #endif
 
-/** \brief RPC status code type
- *
- * Used for returning the status of an RPC transaction.  This is
- * different from the opstatus which is used to return an endpoint
- * specific status value.
+/**
+ * Used for returning the status of an RPC transaction. These values indicating the result of the
+ * RPC layer operations. Service level result must be handled in a service specific way.
  */
+
 typedef int32_t rpc_status_t;
 
-/** \brief RPC operation status code type
- *
- * Used for returning the endpoint specific operation status.
- * Different service layer protocols will use different status
- * value schemes. Status values returned by an operation are
- * carried by the RPC layer using this type.
- */
-typedef int64_t rpc_opstatus_t;
+#define RPC_SUCCESS			(0)
+#define RPC_ERROR_INTERNAL		(-1)
+#define RPC_ERROR_INVALID_VALUE		(-2)
+#define RPC_ERROR_NOT_FOUND		(-3)
+#define RPC_ERROR_INVALID_STATE		(-4)
+#define RPC_ERROR_TRANSPORT_LAYER	(-5)
+#define RPC_ERROR_INVALID_REQUEST_BODY	(-6)
+#define RPC_ERROR_INVALID_RESPONSE_BODY	(-7)
+#define RPC_ERROR_RESOURCE_FAILURE	(-8)
+
+typedef int64_t service_status_t;
 
 #ifdef __cplusplus
 }
diff --git a/components/rpc/common/interface/rpc_uuid.c b/components/rpc/common/interface/rpc_uuid.c
new file mode 100644
index 0000000..fd88b6e
--- /dev/null
+++ b/components/rpc/common/interface/rpc_uuid.c
@@ -0,0 +1,13 @@
+/*
+ * Copyright (c) 2023, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include "rpc_uuid.h"
+#include <string.h>
+
+bool rpc_uuid_equal(const struct rpc_uuid *uuid_a, const struct rpc_uuid *uuid_b)
+{
+	return memcmp(uuid_a->uuid, uuid_b->uuid, sizeof(uuid_a->uuid)) == 0;
+}
diff --git a/components/rpc/common/interface/rpc_uuid.h b/components/rpc/common/interface/rpc_uuid.h
new file mode 100644
index 0000000..52782c7
--- /dev/null
+++ b/components/rpc/common/interface/rpc_uuid.h
@@ -0,0 +1,40 @@
+/*
+ * Copyright (c) 2023, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef RPC_UUID_H
+#define RPC_UUID_H
+
+#include <stdbool.h>
+#include <stdint.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * @brief RPC UUID
+ *
+ * Describes a UUID for identifying an RPC service.
+ */
+struct rpc_uuid {
+	uint8_t uuid[16];
+};
+
+/**
+ * @brief Checks if two RPC UUIDs are equal
+ *
+ * @param uuid_a UUID A
+ * @param uuid_b UUID B
+ * @return true
+ * @return false
+ */
+bool rpc_uuid_equal(const struct rpc_uuid *uuid_a, const struct rpc_uuid *uuid_b);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* RPC_UUID_H */
diff --git a/components/rpc/common/test/call_param_buf_comparator.h b/components/rpc/common/test/call_param_buf_comparator.h
deleted file mode 100644
index 6bfa727..0000000
--- a/components/rpc/common/test/call_param_buf_comparator.h
+++ /dev/null
@@ -1,50 +0,0 @@
-/* SPDX-License-Identifier: BSD-3-Clause */
-/*
- * Copyright (c) 2021, Arm Limited and Contributors. All rights reserved.
- */
-
-#ifndef CALL_PARAM_BUF_COMPARATOR_H_
-#define CALL_PARAM_BUF_COMPARATOR_H_
-
-#include <CppUTestExt/MockSupport.h>
-#include "../endpoint/rpc_interface.h"
-
-class call_param_buf_comparator : public MockNamedValueComparator
-{
-public:
-	enum check_mode {
-		mode_normal = 0,
-		mode_ignore_data_len
-	};
-
-	call_param_buf_comparator(check_mode mode = mode_normal) : mode(mode)
-	{
-	}
-
-	virtual bool isEqual(const void *object1, const void *object2)
-	{
-		struct call_param_buf *buf1 = (struct call_param_buf *)object1;
-		struct call_param_buf *buf2 = (struct call_param_buf *)object2;
-
-		return (buf1->size == buf2->size) &&
-			(mode == mode_ignore_data_len || (buf1->data_len == buf2->data_len)) &&
-			(buf1->data == buf2->data);
-	}
-
-	// LCOV_EXCL_START
-	virtual SimpleString valueToString(const void *object)
-	{
-		struct call_param_buf *buf = (struct call_param_buf *)object;
-
-		return StringFromFormat("<size = %zu, data_len = %zu%s, data = %p>",
-					buf->size, buf->data_len,
-					(mode == mode_ignore_data_len) ? " (ignored)" : "",
-					buf->data);
-	}
-	// LCOV_EXCL_STOP
-
-private:
-	check_mode mode;
-};
-
-#endif /* CALL_PARAM_BUF_COMPARATOR_H_ */
diff --git a/components/rpc/common/test/call_req_comparator.h b/components/rpc/common/test/call_req_comparator.h
deleted file mode 100644
index 753bab2..0000000
--- a/components/rpc/common/test/call_req_comparator.h
+++ /dev/null
@@ -1,68 +0,0 @@
-/* SPDX-License-Identifier: BSD-3-Clause */
-/*
- * Copyright (c) 2021, Arm Limited and Contributors. All rights reserved.
- */
-
-#ifndef CALL_REQ_COMPARATOR_H_
-#define CALL_REQ_COMPARATOR_H_
-
-#include <CppUTestExt/MockSupport.h>
-#include <inttypes.h>
-#include "call_param_buf_comparator.h"
-
-class call_req_comparator : public MockNamedValueComparator
-{
-public:
-	enum check_mode {
-		mode_normal = 0,
-		mode_ignore_opstatus
-	};
-
-	call_req_comparator(check_mode mode) : mode(mode)
-	{
-	}
-
-	virtual bool isEqual(const void *object1, const void *object2)
-	{
-		struct call_req *req1 = (struct call_req *)object1;
-		struct call_req *req2 = (struct call_req *)object2;
-		call_param_buf_comparator buf_comparator_normal;
-		call_param_buf_comparator buf_comparator_ignore_data_len(
-			call_param_buf_comparator::mode_ignore_data_len);
-
-		return (req1->caller_id == req2->caller_id) &&
-			(req1->interface_id == req2->interface_id) &&
-			(req1->opcode == req2->opcode) &&
-			(req1->encoding == req2->encoding) &&
-			(mode == mode_ignore_opstatus || req1->opstatus == req2->opstatus) &&
-			buf_comparator_normal.isEqual(&req1->req_buf, &req2->req_buf) &&
-			buf_comparator_ignore_data_len.isEqual(&req1->resp_buf, &req2->resp_buf);
-	}
-
-	// LCOV_EXCL_START
-	virtual SimpleString valueToString(const void *object)
-	{
-		struct call_req *req = (struct call_req *)object;
-		call_param_buf_comparator buf_comparator_normal;
-		call_param_buf_comparator buf_comparator_ignore_data_len(
-			call_param_buf_comparator::mode_ignore_data_len);
-		SimpleString req_buf_str = buf_comparator_normal.valueToString(&req->req_buf);
-		SimpleString resp_buf_str =
-			buf_comparator_ignore_data_len.valueToString(&req->resp_buf);
-
-		return StringFromFormat("caller_id = 0x%" PRIx32 ", interface_id = %" PRIu32 ", " \
-					"opcode = %" PRIu32 ", encoding = %" PRIu32 ", " \
-					"opstatus = 0x%" PRIx64 "%s, req_buf = %s, " \
-					"resp_buf = %s",
-					req->caller_id, req->interface_id, req->opcode,
-					req->encoding, req->opstatus,
-					(mode == mode_ignore_opstatus) ? " (ignore)" : "",
-					req_buf_str.asCharString(), resp_buf_str.asCharString());
-	}
-	// LCOV_EXCL_STOP
-
-private:
-	check_mode mode;
-};
-
-#endif /* CALL_REQ_COMPARATOR_H_ */
diff --git a/components/rpc/common/test/mock_rpc_interface.cpp b/components/rpc/common/test/mock_rpc_interface.cpp
index af3836d..cf4a005 100644
--- a/components/rpc/common/test/mock_rpc_interface.cpp
+++ b/components/rpc/common/test/mock_rpc_interface.cpp
@@ -5,34 +5,34 @@
 
 #include <CppUTestExt/MockSupport.h>
 #include "mock_rpc_interface.h"
-#include "call_req_comparator.h"
+#include "rpc_request_comparator.h"
 
-static call_req_comparator req_comparator(call_req_comparator::mode_ignore_opstatus);
+static rpc_request_comparator req_comparator(rpc_request_comparator::mode_ignore_opstatus);
 
 void mock_rpc_interface_init(void)
 {
 	mock().installComparator("call_req", req_comparator);
 }
 
-void expect_mock_rpc_interface_receive(struct rpc_interface *iface,
-				       const struct call_req *req, rpc_status_t result)
+void expect_mock_rpc_interface_receive(void *context,
+				       const struct rpc_request *req, rpc_status_t result)
 {
 	mock().expectOneCall("rpc_interface_receive").
-		onObject(iface).
-		withOutputParameterReturning("opstatus", &req->opstatus, sizeof(req->opstatus)).
-		withOutputParameterReturning("resp_buf_data_len", &req->resp_buf.data_len,
-					     sizeof(req->resp_buf.data_len)).
+		onObject(context).
+		withOutputParameterReturning("service_status", &req->service_status, sizeof(req->service_status)).
+		withOutputParameterReturning("resp_buf_data_len", &req->response.data_length,
+					     sizeof(req->response.data_length)).
 		withParameterOfType("call_req", "req", req).
 		andReturnValue(result);
 }
 
-rpc_status_t mock_rpc_interface_receive(struct rpc_interface *iface,
-					struct call_req *req)
+rpc_status_t mock_rpc_interface_receive(void *context,
+					struct rpc_request *req)
 {
 	return mock().actualCall("rpc_interface_receive").
-		onObject(iface).
-		withOutputParameter("opstatus", &req->opstatus).
-		withOutputParameter("resp_buf_data_len", &req->resp_buf.data_len).
+		onObject(context).
+		withOutputParameter("service_status", &req->service_status).
+		withOutputParameter("resp_buf_data_len", &req->response.data_length).
 		withParameterOfType("call_req", "req", req).
 		returnIntValue();
 }
diff --git a/components/rpc/common/test/mock_rpc_interface.h b/components/rpc/common/test/mock_rpc_interface.h
index 7e80c4a..d24e71f 100644
--- a/components/rpc/common/test/mock_rpc_interface.h
+++ b/components/rpc/common/test/mock_rpc_interface.h
@@ -6,7 +6,7 @@
 #ifndef MOCK_RPC_INTERFACE_H_
 #define MOCK_RPC_INTERFACE_H_
 
-#include "../endpoint/rpc_interface.h"
+#include "../endpoint/rpc_service_interface.h"
 
 #ifdef __cplusplus
 extern "C" {
@@ -14,11 +14,10 @@
 
 void mock_rpc_interface_init(void);
 
-void expect_mock_rpc_interface_receive(struct rpc_interface *iface,
-				       const struct call_req *req, rpc_status_t result);
+void expect_mock_rpc_interface_receive(void *context, const struct rpc_request *req,
+				       rpc_status_t result);
 
-rpc_status_t mock_rpc_interface_receive(struct rpc_interface *iface,
-					struct call_req *req);
+rpc_status_t mock_rpc_interface_receive(void *context, struct rpc_request *req);
 
 #ifdef __cplusplus
 }
diff --git a/components/rpc/common/test/rpc_buffer_comparator.h b/components/rpc/common/test/rpc_buffer_comparator.h
new file mode 100644
index 0000000..93d41be
--- /dev/null
+++ b/components/rpc/common/test/rpc_buffer_comparator.h
@@ -0,0 +1,50 @@
+/* SPDX-License-Identifier: BSD-3-Clause */
+/*
+ * Copyright (c) 2021, Arm Limited and Contributors. All rights reserved.
+ */
+
+#ifndef RPC_BUFFER_COMPARATOR_H_
+#define RPC_BUFFER_COMPARATOR_H_
+
+#include <CppUTestExt/MockSupport.h>
+#include "../endpoint/rpc_service_interface.h"
+
+class rpc_buffer_comparator : public MockNamedValueComparator
+{
+public:
+	enum check_mode {
+		mode_normal = 0,
+		mode_ignore_data_len
+	};
+
+	explicit rpc_buffer_comparator(check_mode mode = mode_normal) : mode(mode)
+	{
+	}
+
+	virtual bool isEqual(const void *object1, const void *object2)
+	{
+		struct rpc_buffer *buf1 = (struct rpc_buffer *)object1;
+		struct rpc_buffer *buf2 = (struct rpc_buffer *)object2;
+
+		return (buf1->data == buf2->data) &&
+			(buf1->size == buf2->size) &&
+			(mode == mode_ignore_data_len || buf1->data_length == buf2->data_length);
+	}
+
+	// LCOV_EXCL_START
+	virtual SimpleString valueToString(const void *object)
+	{
+		struct rpc_buffer *buf = (struct rpc_buffer *)object;
+
+		return StringFromFormat("<size = %zu, data_len = %zu%s, data = %p>",
+					buf->size, buf->data_length,
+					(mode == mode_ignore_data_len) ? " (ignored)" : "",
+					buf->data);
+	}
+	// LCOV_EXCL_STOP
+
+private:
+	check_mode mode;
+};
+
+#endif /* RPC_BUFFER_COMPARATOR_H_ */
diff --git a/components/rpc/common/test/rpc_request_comparator.h b/components/rpc/common/test/rpc_request_comparator.h
new file mode 100644
index 0000000..9a74671
--- /dev/null
+++ b/components/rpc/common/test/rpc_request_comparator.h
@@ -0,0 +1,68 @@
+/* SPDX-License-Identifier: BSD-3-Clause */
+/*
+ * Copyright (c) 2021, Arm Limited and Contributors. All rights reserved.
+ */
+
+#ifndef CALL_REQ_COMPARATOR_H_
+#define CALL_REQ_COMPARATOR_H_
+
+#include <CppUTestExt/MockSupport.h>
+#include <inttypes.h>
+#include "rpc_buffer_comparator.h"
+
+class rpc_request_comparator : public MockNamedValueComparator
+{
+public:
+	enum check_mode {
+		mode_normal = 0,
+		mode_ignore_opstatus
+	};
+
+	explicit rpc_request_comparator(check_mode mode) : mode(mode)
+	{
+	}
+
+	virtual bool isEqual(const void *object1, const void *object2)
+	{
+		struct rpc_request *req1 = (struct rpc_request *)object1;
+		struct rpc_request *req2 = (struct rpc_request *)object2;
+		rpc_buffer_comparator buf_comparator_normal;
+		rpc_buffer_comparator buf_comparator_ignore_data_len(
+			rpc_buffer_comparator::mode_ignore_data_len);
+
+		return (req1->source_id == req2->source_id) &&
+			(req1->interface_id == req2->interface_id) &&
+			(req1->opcode == req2->opcode) &&
+			(req1->client_id == req2->client_id) &&
+			(mode == mode_ignore_opstatus || req1->service_status == req2->service_status) &&
+			buf_comparator_normal.isEqual(&req1->request, &req2->request) &&
+			buf_comparator_ignore_data_len.isEqual(&req1->response, &req2->response);
+	}
+
+	// LCOV_EXCL_START
+	virtual SimpleString valueToString(const void *object)
+	{
+		struct rpc_request *req = (struct rpc_request *)object;
+		rpc_buffer_comparator buf_comparator_normal;
+		rpc_buffer_comparator buf_comparator_ignore_data_len(
+			rpc_buffer_comparator::mode_ignore_data_len);
+		SimpleString req_buf_str = buf_comparator_normal.valueToString(&req->request);
+		SimpleString resp_buf_str =
+			buf_comparator_ignore_data_len.valueToString(&req->response);
+
+		return StringFromFormat("caller_id = 0x%" PRIx32 ", interface_id = %" PRIu32 ", " \
+					"opcode = %" PRIu32 ", encoding = %" PRIu32 ", " \
+					"opstatus = 0x%" PRIx64 "%s, req_buf = %s, " \
+					"resp_buf = %s",
+					req->source_id, req->interface_id, req->opcode,
+					req->client_id, req->service_status,
+					(mode == mode_ignore_opstatus) ? " (ignore)" : "",
+					req_buf_str.asCharString(), resp_buf_str.asCharString());
+	}
+	// LCOV_EXCL_STOP
+
+private:
+	check_mode mode;
+};
+
+#endif /* CALL_REQ_COMPARATOR_H_ */
diff --git a/components/rpc/common/test/test_mock_rpc_interface.cpp b/components/rpc/common/test/test_mock_rpc_interface.cpp
index f3390f0..28bbf14 100644
--- a/components/rpc/common/test/test_mock_rpc_interface.cpp
+++ b/components/rpc/common/test/test_mock_rpc_interface.cpp
@@ -23,39 +23,39 @@
 		mock().clear();
 	}
 
-	struct rpc_interface iface;
+	struct rpc_service_interface iface;
 };
 
 TEST(mock_rpc_interface, receive)
 {
-	rpc_status_t res = TS_RPC_ERROR_INTERNAL;
-	struct call_req expected_req = { 0 };
-	struct call_req req = { 0 };
+	rpc_status_t res = RPC_ERROR_INTERNAL;
+	struct rpc_request expected_req = { 0 };
+	struct rpc_request req = { 0 };
 
 	iface.context = (void *)1;
 	iface.receive = mock_rpc_interface_receive;
 
-	expected_req.caller_id = 0x01234567;
-	expected_req.interface_id = 0x89abcdef;
-	expected_req.opcode = 0xfedcba98;
-	expected_req.encoding = 0x76543210;
-	expected_req.opstatus = (rpc_opstatus_t)-1;
+	expected_req.source_id = 0x4567;
+	expected_req.interface_id = 0xef;
+	expected_req.opcode = 0xba98;
+	expected_req.client_id = 0x76543210;
+	expected_req.service_status = (service_status_t)-1;
 
-	expected_req.req_buf.size = 1;
-	expected_req.req_buf.data_len = 2;
-	expected_req.req_buf.data = (void *)3;
+	expected_req.request.size = 1;
+	expected_req.request.data_length = 2;
+	expected_req.request.data = (uint8_t *)3;
 
-	expected_req.resp_buf.size = 4;
-	expected_req.resp_buf.data_len = 5;
-	expected_req.resp_buf.data = (void *)6;
+	expected_req.response.size = 4;
+	expected_req.response.data_length = 5;
+	expected_req.response.data = (uint8_t *)6;
 
 	memcpy(&req, &expected_req, sizeof(req));
-	req.opstatus = 0;
-	req.resp_buf.data_len = 0;
+	req.service_status = 0;
+	req.response.data_length = 0;
 
 	expect_mock_rpc_interface_receive(&iface, &expected_req, res);
 	LONGS_EQUAL(res, mock_rpc_interface_receive(&iface, &req));
 
-	UNSIGNED_LONGLONGS_EQUAL(expected_req.opstatus, req.opstatus);
-	UNSIGNED_LONGLONGS_EQUAL(expected_req.resp_buf.data_len, req.resp_buf.data_len);
+	UNSIGNED_LONGLONGS_EQUAL(expected_req.service_status, req.service_status);
+	UNSIGNED_LONGLONGS_EQUAL(expected_req.response.data_length, req.response.data_length);
 }
diff --git a/components/rpc/direct/direct_caller.c b/components/rpc/direct/direct_caller.c
index 61f25d7..e534abe 100644
--- a/components/rpc/direct/direct_caller.c
+++ b/components/rpc/direct/direct_caller.c
@@ -5,122 +5,114 @@
  */
 
 #include "direct_caller.h"
-#include <rpc/common/endpoint/rpc_interface.h>
-#include <protocols/rpc/common/packed-c/status.h>
+#include "components/rpc/common/endpoint/rpc_service_interface.h"
+#include "components/rpc/common/interface/rpc_uuid.h"
 #include <stdlib.h>
 
-#define DIRECT_CALLER_DEFAULT_REQ_BUF_SIZE      (4096)
-#define DIRECT_CALLER_DEFAULT_RESP_BUF_SIZE     (4096)
+struct direct_caller_context {
+	struct rpc_service_interface *service;
+};
 
-static rpc_call_handle call_begin(void *context, uint8_t **req_buf, size_t req_len);
-static rpc_status_t call_invoke(void *context, rpc_call_handle handle, uint32_t opcode,
-		     	rpc_opstatus_t *opstatus, uint8_t **resp_buf, size_t *resp_len);
-static void call_end(void *context, rpc_call_handle handle);
+static rpc_status_t find_and_open_session(void *context, const struct rpc_uuid *service_uuid);
 
-
-struct rpc_caller *direct_caller_init(struct direct_caller *s, struct rpc_interface *iface,
-                        size_t req_buf_size, size_t resp_buf_size)
+static rpc_status_t open_session(void *context, const struct rpc_uuid *service_uuid,
+				 uint16_t endpoint_id)
 {
-    struct rpc_caller *base = &s->rpc_caller;
+	(void)endpoint_id;
 
-    rpc_caller_init(base, s);
-    base->call_begin = call_begin;
-    base->call_invoke = call_invoke;
-    base->call_end = call_end;
-
-    s->rpc_interface = iface;
-    s->caller_id = 0;
-    s->is_call_transaction_in_progess = false;
-    s->req_len = 0;
-    s->req_buf_size = req_buf_size;
-    s->resp_buf_size = resp_buf_size;
-    s->req_buf = malloc(s->req_buf_size);
-    s->resp_buf = malloc(s->resp_buf_size);
-
-    if (!s->req_buf || !s->resp_buf) {
-
-        /* Buffer allocation failed */
-        base = NULL;
-        direct_caller_deinit(s);
-    }
-
-    return base;
+	return find_and_open_session(context, service_uuid);
 }
 
-struct rpc_caller *direct_caller_init_default(struct direct_caller *s, struct rpc_interface *iface)
+static rpc_status_t find_and_open_session(void *context, const struct rpc_uuid *service_uuid)
 {
-    /* Initialise with default buffer sizes */
-    return direct_caller_init(s, iface,
-        DIRECT_CALLER_DEFAULT_REQ_BUF_SIZE,
-        DIRECT_CALLER_DEFAULT_RESP_BUF_SIZE);
+	struct direct_caller_context *caller = (struct direct_caller_context *)context;
+
+	if (!rpc_uuid_equal(service_uuid, &caller->service->uuid))
+		return RPC_ERROR_NOT_FOUND;
+
+	return RPC_SUCCESS;
 }
 
-void direct_caller_deinit(struct direct_caller *s)
+static rpc_status_t close_session(void *context)
 {
-    free(s->req_buf);
-    s->req_buf = NULL;
-    free(s->resp_buf);
-    s->resp_buf = NULL;
+	return RPC_SUCCESS;
 }
 
-static rpc_call_handle call_begin(void *context, uint8_t **req_buf, size_t req_len)
+static rpc_status_t create_shared_memory(void *context, size_t size,
+					 struct rpc_caller_shared_memory *shared_memory)
 {
-    struct direct_caller *this_context = (struct direct_caller*)context;
-    rpc_call_handle handle = NULL;
+	shared_memory->id = 0;
+	shared_memory->buffer = calloc(1, size);
+	shared_memory->size = size;
 
-    if (!this_context->is_call_transaction_in_progess &&
-        (req_len <= this_context->req_buf_size)) {
-
-        this_context->is_call_transaction_in_progess = true;
-
-        if (req_buf){
-            *req_buf = this_context->req_buf;
-            this_context->req_len = req_len;
-        }
-
-        handle = this_context;
-    }
-
-    return handle;
+	return RPC_SUCCESS;
 }
 
-static rpc_status_t call_invoke(void *context, rpc_call_handle handle, uint32_t opcode,
-		     	rpc_opstatus_t *opstatus, uint8_t **resp_buf, size_t *resp_len)
+static rpc_status_t release_shared_memory(void *context,
+					  struct rpc_caller_shared_memory *shared_memory)
 {
-    struct direct_caller *this_context = (struct direct_caller*)context;
-    rpc_status_t status = TS_RPC_ERROR_INVALID_TRANSACTION;
+	free(shared_memory->buffer);
 
-    if ((handle == this_context) && this_context->is_call_transaction_in_progess) {
-
-        struct call_req req;
-
-        req.interface_id = 0;
-        req.opcode = opcode;
-        req.encoding = this_context->rpc_caller.encoding;
-        req.caller_id = this_context->caller_id;
-        req.opstatus = 0;
-        req.req_buf = call_param_buf_init_full(this_context->req_buf,
-                            this_context->req_buf_size, this_context->req_len);
-        req.resp_buf = call_param_buf_init_empty(this_context->resp_buf,
-                            this_context->resp_buf_size);
-
-        status = rpc_interface_receive(this_context->rpc_interface, &req);
-
-        *resp_buf = this_context->resp_buf;
-        *resp_len = call_req_get_resp_buf(&req)->data_len;
-        *opstatus = call_req_get_opstatus(&req);
-    }
-
-    return status;
+	return RPC_SUCCESS;
 }
 
-static void call_end(void *context, rpc_call_handle handle)
+static rpc_status_t call(void *context, uint16_t opcode,
+			 struct rpc_caller_shared_memory *shared_memory, size_t request_length,
+			 size_t *response_length, service_status_t *service_status)
 {
-    struct direct_caller *this_context = (struct direct_caller*)context;
+	struct direct_caller_context *caller = (struct direct_caller_context *)context;
+	struct rpc_request rpc_request = { 0 };
+	rpc_status_t status = RPC_ERROR_INTERNAL;
 
-    if ((handle == this_context) && this_context->is_call_transaction_in_progess) {
+	rpc_request.source_id = 0;
+	rpc_request.opcode = opcode;
+	rpc_request.client_id = 0;
+	rpc_request.request.data = shared_memory->buffer;
+	rpc_request.request.data_length = request_length;
+	rpc_request.request.size = shared_memory->size;
+	rpc_request.response.data = shared_memory->buffer;
+	rpc_request.response.data_length = 0;
+	rpc_request.response.size = shared_memory->size;
 
-        this_context->req_len = 0;
-        this_context->is_call_transaction_in_progess = false;
-    }
+	status = rpc_service_receive(caller->service, &rpc_request);
+
+	*response_length = rpc_request.response.data_length;
+	*service_status = rpc_request.service_status;
+
+	return status;
+}
+
+rpc_status_t direct_caller_init(struct rpc_caller_interface *caller,
+				struct rpc_service_interface *service)
+{
+	struct direct_caller_context *context = NULL;
+
+	if (!caller || caller->context)
+		return RPC_ERROR_INVALID_VALUE;
+
+	context = (struct direct_caller_context *)calloc(1, sizeof(struct direct_caller_context));
+	if (!context)
+		return RPC_ERROR_INTERNAL;
+
+	context->service = service;
+
+	caller->context = context;
+	caller->open_session = open_session;
+	caller->find_and_open_session = find_and_open_session;
+	caller->close_session = close_session;
+	caller->create_shared_memory = create_shared_memory;
+	caller->release_shared_memory = release_shared_memory;
+	caller->call = call;
+
+	return RPC_SUCCESS;
+}
+
+rpc_status_t direct_caller_deinit(struct rpc_caller_interface *rpc_caller)
+{
+	if (!rpc_caller || !rpc_caller->context)
+		return RPC_ERROR_INVALID_VALUE;
+
+	free(rpc_caller->context);
+
+	return RPC_SUCCESS;
 }
diff --git a/components/rpc/direct/direct_caller.h b/components/rpc/direct/direct_caller.h
index fe5ac08..e583ab3 100644
--- a/components/rpc/direct/direct_caller.h
+++ b/components/rpc/direct/direct_caller.h
@@ -7,40 +7,23 @@
 #ifndef DIRECT_CALLER_H
 #define DIRECT_CALLER_H
 
-#include <rpc_caller.h>
-#include <stdint.h>
-#include <stdbool.h>
-#include <stddef.h>
+#include "rpc_caller.h"
+
+struct rpc_service_interface;
 
 #ifdef __cplusplus
 extern "C" {
 #endif
 
-struct rpc_interface;
-
 /** An rpc_caller that calls methods associated with a specific endpoint
  *  directly.  Used when the caller and endpoint are running in the same
  *  execution context.
  **/
-struct direct_caller
-{
-    struct rpc_caller rpc_caller;
-    struct rpc_interface *rpc_interface;
-    uint32_t caller_id;
-    bool is_call_transaction_in_progess;
-    size_t req_len;
-    size_t req_buf_size;
-    size_t resp_buf_size;
-    uint8_t *req_buf;
-    uint8_t *resp_buf;
-};
 
-struct rpc_caller *direct_caller_init(struct direct_caller *s, struct rpc_interface *iface,
-                        size_t req_buf_size, size_t resp_buf_size);
+rpc_status_t direct_caller_init(struct rpc_caller_interface *caller,
+				struct rpc_service_interface *service);
 
-struct rpc_caller *direct_caller_init_default(struct direct_caller *s, struct rpc_interface *iface);
-
-void direct_caller_deinit(struct direct_caller *s);
+rpc_status_t direct_caller_deinit(struct rpc_caller_interface *caller);
 
 #ifdef __cplusplus
 }
diff --git a/components/rpc/dummy/dummy_caller.c b/components/rpc/dummy/dummy_caller.c
index 881f75f..c7f1f01 100644
--- a/components/rpc/dummy/dummy_caller.c
+++ b/components/rpc/dummy/dummy_caller.c
@@ -7,67 +7,121 @@
 #include "dummy_caller.h"
 #include <stdlib.h>
 
-static rpc_call_handle call_begin(void *context, uint8_t **req_buf, size_t req_len);
-static rpc_status_t call_invoke(void *context, rpc_call_handle handle, uint32_t opcode,
-		     	rpc_opstatus_t *opstatus, uint8_t **resp_buf, size_t *resp_len);
-static void call_end(void *context, rpc_call_handle handle);
+struct dummy_caller_context {
+	rpc_status_t rpc_status;
+	service_status_t service_status;
+	uint8_t *req_buf;
+};
 
-
-struct rpc_caller *dummy_caller_init(struct dummy_caller *s,
-    rpc_status_t rpc_status, rpc_opstatus_t opstatus)
+rpc_status_t open_session(void *context, const struct rpc_uuid *service_uuid, uint16_t endpoint_id)
 {
-    struct rpc_caller *base = &s->rpc_caller;
+	(void)context;
+	(void)service_uuid;
+	(void)endpoint_id;
 
-    rpc_caller_init(base, s);
-    base->call_begin = call_begin;
-    base->call_invoke = call_invoke;
-    base->call_end = call_end;
-
-    s->rpc_status = rpc_status;
-    s->opstatus = opstatus;
-    s->req_buf = NULL;
-
-    return base;
+	return RPC_SUCCESS;
 }
 
-void dummy_caller_deinit(struct dummy_caller *s)
+rpc_status_t find_and_open_session(void *context, const struct rpc_uuid *service_uuid)
 {
-    free(s->req_buf);
-    s->req_buf = NULL;
+	(void)context;
+	(void)service_uuid;
+
+	return RPC_SUCCESS;
 }
 
-static rpc_call_handle call_begin(void *context, uint8_t **req_buf, size_t req_len)
+static rpc_status_t close_session(void *context)
 {
-    struct dummy_caller *this_context = (struct dummy_caller*)context;
-    rpc_call_handle handle = this_context;
+	struct dummy_caller_context *caller_context = (struct dummy_caller_context *)context;
 
-    free(this_context->req_buf);
-    this_context->req_buf = malloc(req_len);
-    *req_buf = this_context->req_buf;
+	free(caller_context->req_buf);
 
-    return handle;
+	return RPC_SUCCESS;
 }
 
-static rpc_status_t call_invoke(void *context, rpc_call_handle handle, uint32_t opcode,
-		     	rpc_opstatus_t *opstatus, uint8_t **resp_buf, size_t *resp_len)
+static rpc_status_t create_shared_memory(void *context, size_t size,
+					 struct rpc_caller_shared_memory *shared_memory)
 {
-    (void)handle;
-    (void)opcode;
+	struct dummy_caller_context *caller_context = (struct dummy_caller_context *)context;
 
-    struct dummy_caller *this_context = (struct dummy_caller*)context;
+	if (caller_context->req_buf)
+		return RPC_ERROR_INVALID_STATE;
 
-    free(this_context->req_buf);
-    this_context->req_buf = NULL;
+	caller_context->req_buf = calloc(1, size);
 
-    *resp_buf = NULL;
-    *resp_len = 0;
-    *opstatus = this_context->opstatus;
+	shared_memory->id = 0;
+	shared_memory->buffer = caller_context->req_buf;
+	shared_memory->size = size;
 
-    return this_context->rpc_status;
+	return RPC_SUCCESS;
 }
 
-static void call_end(void *context, rpc_call_handle handle)
+static rpc_status_t release_shared_memory(void *context,
+					  struct rpc_caller_shared_memory *shared_memory)
 {
-    (void)context;
-    (void)handle;
+	struct dummy_caller_context *caller_context = (struct dummy_caller_context *)context;
+
+	if (shared_memory->buffer != caller_context->req_buf)
+		return RPC_ERROR_INVALID_VALUE;
+
+	if (!caller_context->req_buf)
+		return RPC_ERROR_INVALID_STATE;
+
+	free(caller_context->req_buf);
+	caller_context->req_buf = NULL;
+
+	return RPC_ERROR_INTERNAL;
 }
+
+static rpc_status_t call(void *context, uint16_t opcode,
+			 struct rpc_caller_shared_memory *shared_memory, size_t request_length,
+			 size_t *response_length, service_status_t *service_status)
+{
+	struct dummy_caller_context *caller_context = (struct dummy_caller_context *)context;
+
+	(void)opcode;
+	(void)shared_memory;
+	(void)request_length;
+
+	*response_length = 0;
+	*service_status = caller_context->rpc_status;
+
+	return caller_context->rpc_status;
+}
+
+rpc_status_t dummy_caller_init(struct rpc_caller_interface *rpc_caller, rpc_status_t rpc_status,
+			       service_status_t service_status)
+{
+	struct dummy_caller_context *context = NULL;
+
+	if (!rpc_caller || rpc_caller->context)
+		return RPC_ERROR_INVALID_VALUE;
+
+	context = (struct dummy_caller_context *)calloc(1, sizeof(struct dummy_caller_context));
+	if (!context)
+		return RPC_ERROR_INTERNAL;
+
+	context->rpc_status = rpc_status;
+	context->service_status = service_status;
+	context->req_buf = NULL;
+
+	rpc_caller->context = context;
+	rpc_caller->open_session = open_session;
+	rpc_caller->find_and_open_session = find_and_open_session;
+	rpc_caller->close_session = close_session;
+	rpc_caller->create_shared_memory = create_shared_memory;
+	rpc_caller->release_shared_memory = release_shared_memory;
+	rpc_caller->call = call;
+
+	return RPC_SUCCESS;
+}
+
+rpc_status_t dummy_caller_deinit(struct rpc_caller_interface *rpc_caller)
+{
+	if (!rpc_caller || !rpc_caller->context)
+		return RPC_ERROR_INVALID_VALUE;
+
+	free(rpc_caller->context);
+
+	return RPC_SUCCESS;
+}
\ No newline at end of file
diff --git a/components/rpc/dummy/dummy_caller.h b/components/rpc/dummy/dummy_caller.h
index b93c02f..a7522d8 100644
--- a/components/rpc/dummy/dummy_caller.h
+++ b/components/rpc/dummy/dummy_caller.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2020-2021, Arm Limited and Contributors. All rights reserved.
+ * Copyright (c) 2020-2023, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -7,7 +7,7 @@
 #ifndef DUMMY_CALLER
 #define DUMMY_CALLER
 
-#include <rpc_caller.h>
+#include "rpc_caller.h"
 #include <stdint.h>
 
 #ifdef __cplusplus
@@ -22,17 +22,10 @@
  * established but a client doesn't wish to treat the condition
  * as a fatal error.
  */
-struct dummy_caller
-{
-    struct rpc_caller rpc_caller;
-    rpc_status_t rpc_status;
-    rpc_opstatus_t opstatus;
-    uint8_t *req_buf;
-};
 
-struct rpc_caller *dummy_caller_init(struct dummy_caller *s,
-                                    rpc_status_t rpc_status, rpc_opstatus_t opstatus);
-void dummy_caller_deinit(struct dummy_caller *s);
+rpc_status_t dummy_caller_init(struct rpc_caller_interface *caller, rpc_status_t rpc_status,
+			       service_status_t service_status);
+rpc_status_t dummy_caller_deinit(struct rpc_caller_interface *caller);
 
 #ifdef __cplusplus
 }
diff --git a/components/rpc/ffarpc/caller/linux/component.cmake b/components/rpc/ffarpc/caller/linux/component.cmake
deleted file mode 100644
index bab7a99..0000000
--- a/components/rpc/ffarpc/caller/linux/component.cmake
+++ /dev/null
@@ -1,20 +0,0 @@
-#-------------------------------------------------------------------------------
-# Copyright (c) 2020-2022, Arm Limited and Contributors. All rights reserved.
-#
-# SPDX-License-Identifier: BSD-3-Clause
-#
-#-------------------------------------------------------------------------------
-if(NOT DEFINED TGT)
-	message(FATAL_ERROR "mandatory parameter TGT is not defined.")
-endif()
-
-include(${TS_ROOT}/external/LinuxFfaTeeDriver/LinuxFfaTeeDriver.cmake)
-
-target_sources(${TGT} PRIVATE
-	"${CMAKE_CURRENT_LIST_DIR}/ffarpc_caller.c"
-	"${CMAKE_CURRENT_LIST_DIR}/ffa_tee.c"
-)
-
-target_include_directories(${TGT} PRIVATE
-	"${LINUX_FFA_TEE_DRIVER_INCLUDE_DIR}"
-)
diff --git a/components/rpc/ffarpc/caller/linux/ffa_tee.c b/components/rpc/ffarpc/caller/linux/ffa_tee.c
deleted file mode 100644
index 3302637..0000000
--- a/components/rpc/ffarpc/caller/linux/ffa_tee.c
+++ /dev/null
@@ -1,238 +0,0 @@
-/*
- * Copyright (c) 2021-2022, Arm Limited and Contributors. All rights reserved.
- *
- * SPDX-License-Identifier: BSD-3-Clause
- */
-
-#include <arm_ffa_tee.h>
-#include <errno.h>
-#include <fcntl.h>
-#include <linux/tee.h>
-#include <stdbool.h>
-#include <stdint.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <sys/ioctl.h>
-#include <sys/mman.h>
-#include <sys/stat.h>
-#include <sys/types.h>
-#include <unistd.h>
-
-#define MAX_TEE_DEV_NUM 10
-
-int ffa_tee_find_dev(char *path, size_t path_len)
-{
-	struct tee_ioctl_version_data vers = {0};
-	char tmp_path[16] = {0};
-	int fd = -1, rc = -1, print_len = -1;
-	size_t n = 0;
-
-	if (!path || !path_len)
-		return -1;
-
-	for (n = 0; n < MAX_TEE_DEV_NUM; n++) {
-		/* Returns number of characters, excluding the null terminator */
-		print_len = snprintf(tmp_path, sizeof(tmp_path), "/dev/tee%zu", n);
-
-		fd = open(tmp_path, O_RDWR);
-		if (fd < 0)
-			continue;
-
-		memset(&vers, 0, sizeof(vers));
-		rc = ioctl(fd, TEE_IOC_VERSION, &vers);
-
-		close(fd);
-
-		/* Suitable device path was found */
-		if (!rc && vers.impl_id == TEE_IMPL_ID_FFATEE) {
-			/* Buffer is too short */
-			if (path_len < print_len + 1)
-				return -1;
-
-			memcpy(path, tmp_path, print_len + 1);
-			return 0;
-		}
-	}
-
-	return -1;
-}
-
-int ffa_tee_open_session(int fd, uint16_t part_id)
-{
-	int rc = -1;
-	struct tee_ioctl_open_session_arg *arg = NULL;
-	struct tee_ioctl_param *params = NULL;
-	const size_t arg_size = sizeof(struct tee_ioctl_open_session_arg) +
-				1 * sizeof(struct tee_ioctl_param);
-	union {
-		struct tee_ioctl_open_session_arg arg;
-		uint8_t data[arg_size];
-	} buf;
-	struct tee_ioctl_buf_data buf_data = {0};
-
-	memset(&buf, 0, sizeof(buf));
-
-	if (fd < 0) {
-		printf("%s():%d error\n", __func__, __LINE__);
-		return -1;
-	}
-
-	buf_data.buf_ptr = (uintptr_t)&buf;
-	buf_data.buf_len = sizeof(buf);
-
-	arg = &buf.arg;
-	arg->num_params = 1;
-	params = (struct tee_ioctl_param *)(arg + 1);
-
-	params[0].attr = TEE_IOCTL_PARAM_ATTR_TYPE_VALUE_INPUT;
-	params[0].a = part_id;
-
-	rc = ioctl(fd, TEE_IOC_OPEN_SESSION, &buf_data);
-	if (rc) {
-		printf("%s():%d error: %d\n", __func__, __LINE__, errno);
-		return -1;
-	}
-
-	return 0;
-}
-
-void ffa_tee_close_session(int fd)
-{
-	struct tee_ioctl_close_session_arg arg = {0};
-
-	if (ioctl(fd, TEE_IOC_CLOSE_SESSION, &arg))
-		printf("%s():%d error: %d\n", __func__, __LINE__, errno);
-}
-
-static int ffa_tee_invoke_func(int fd, struct tee_ioctl_buf_data *buf_data)
-{
-	int rc = -1;
-
-	rc = ioctl(fd, TEE_IOC_INVOKE, buf_data);
-	if (rc) {
-		printf("%s():%d error: %d\n", __func__, __LINE__, errno);
-		return -1;
-	}
-
-	return 0;
-}
-
-int ffa_tee_send_msg(int fd, uint16_t iface_id, uint16_t opcode, size_t req_len, uint16_t encoding,
-		     size_t *resp_len, int32_t *rpc_status, int32_t *opstatus)
-{
-	struct tee_ioctl_invoke_arg *arg = NULL;
-	struct tee_ioctl_param *params = NULL;
-	const size_t arg_size = sizeof(struct tee_ioctl_invoke_arg) +
-				1 * sizeof(struct tee_ioctl_param);
-	union {
-		struct tee_ioctl_invoke_arg arg;
-		uint8_t data[arg_size];
-	} buf;
-	struct tee_ioctl_buf_data buf_data = {0};
-	int rc = -1;
-
-	memset(&buf, 0, sizeof(buf));
-
-	buf_data.buf_ptr = (uintptr_t)&buf;
-	buf_data.buf_len = sizeof(buf);
-
-	arg = &buf.arg;
-	arg->func = CMD_SEND_MSG;
-	arg->num_params = 1;
-	params = (struct tee_ioctl_param *)(arg + 1);
-
-	params[0].attr = TEE_IOCTL_PARAM_ATTR_TYPE_VALUE_INOUT;
-	params[0].a = CMD_SEND_MSG_PARAM_A(iface_id, opcode);
-	params[0].b = CMD_SEND_MSG_PARAM_B(req_len);
-	params[0].c = CMD_SEND_MSG_PARAM_C(encoding);
-
-	rc = ffa_tee_invoke_func(fd, &buf_data);
-	if (rc)
-		return rc;
-
-	*resp_len = CMD_SEND_MSG_RESP_LEN(params[0].a);
-	*rpc_status = CMD_SEND_MSG_RPC_STATUS(params[0].b);
-	*opstatus = CMD_SEND_MSG_OP_STATUS(params[0].b);
-
-	return 0;
-}
-
-int ffa_tee_list_part_ids(int fd, const uint8_t *uuid, uint16_t *id_buf, size_t id_buf_cnt,
-			  size_t *populated, bool *buf_short)
-{
-	struct tee_ioctl_invoke_arg *arg = NULL;
-	struct tee_ioctl_param *params = NULL;
-	const size_t arg_size = sizeof(struct tee_ioctl_invoke_arg) +
-				2 * sizeof(struct tee_ioctl_param);
-	union {
-		struct tee_ioctl_invoke_arg arg;
-		uint8_t data[arg_size];
-	} buf;
-	struct tee_ioctl_buf_data buf_data = {0};
-	int rc = -1;
-
-	memset(&buf, 0, sizeof(buf));
-
-	buf_data.buf_ptr = (uintptr_t)&buf;
-	buf_data.buf_len = sizeof(buf);
-
-	arg = &buf.arg;
-	arg->func = CMD_GET_PARTITION_LIST;
-	arg->num_params = 2;
-	params = (struct tee_ioctl_param *)(arg + 1);
-
-	params[0].attr = TEE_IOCTL_PARAM_ATTR_TYPE_VALUE_INPUT;
-	memcpy(&params[0].a, uuid, 8);
-	memcpy(&params[0].b, uuid + 8, 8);
-	params[0].c = 0;
-
-	params[1].attr = TEE_IOCTL_PARAM_ATTR_TYPE_VALUE_INOUT;
-	params[1].a = (uintptr_t)id_buf;
-	params[1].b = id_buf_cnt;
-	params[1].c = 0;
-
-	rc = ffa_tee_invoke_func(fd, &buf_data);
-	if (rc)
-		return rc;
-
-	*populated = params[1].a;
-	*buf_short = (params[1].b != 0);
-
-	return 0;
-}
-
-int ffa_tee_share_mem(int fd, size_t req_size, void **addr, size_t *size, int *id)
-{
-	struct tee_ioctl_shm_alloc_data data = {.size = req_size};
-	int shm_fd = -1;
-
-	shm_fd = ioctl(fd, TEE_IOC_SHM_ALLOC, &data);
-	if (shm_fd < 0) {
-		printf("%s():%d error: %d\n", __func__, __LINE__, errno);
-		return -1;
-	}
-
-	*addr = mmap(NULL, data.size, PROT_READ | PROT_WRITE, MAP_SHARED, shm_fd, 0);
-	if (*addr == (void *)MAP_FAILED) {
-		printf("%s():%d error: %d\n", __func__, __LINE__, errno);
-		close(shm_fd);
-		return -1;
-	}
-	close(shm_fd);
-	*size = data.size;
-	*id = data.id;
-
-	return 0;
-}
-
-void ffa_tee_reclaim_mem(int fd, void *addr, size_t size)
-{
-	int rc = 0;
-
-	(void)fd;
-
-	rc = munmap(addr, size);
-	if (rc)
-		printf("%s():%d error: %d\n", __func__, __LINE__, errno);
-}
diff --git a/components/rpc/ffarpc/caller/linux/ffa_tee.h b/components/rpc/ffarpc/caller/linux/ffa_tee.h
deleted file mode 100644
index 3fe26f2..0000000
--- a/components/rpc/ffarpc/caller/linux/ffa_tee.h
+++ /dev/null
@@ -1,18 +0,0 @@
-/*
- * Copyright (c) 2021-2022, Arm Limited and Contributors. All rights reserved.
- *
- * SPDX-License-Identifier: BSD-3-Clause
- */
-
-#include <stdbool.h>
-#include <stdint.h>
-
-int ffa_tee_find_dev(char *path, size_t path_len);
-int ffa_tee_open_session(int fd, uint16_t part_id);
-void ffa_tee_close_session(int fd);
-int ffa_tee_send_msg(int fd, uint16_t iface_id, uint16_t opcode, size_t req_len, uint16_t encoding,
-		     size_t *resp_len, int32_t *rpc_status, int32_t *opstatus);
-int ffa_tee_list_part_ids(int fd, const uint8_t *uuid, uint16_t *id_buf, size_t id_buf_cnt,
-			  size_t *populated, bool *buf_short);
-int ffa_tee_share_mem(int fd, size_t req_size, void **addr, size_t *size, int *id);
-void ffa_tee_reclaim_mem(int fd, void *addr, size_t size);
diff --git a/components/rpc/ffarpc/caller/linux/ffarpc_caller.c b/components/rpc/ffarpc/caller/linux/ffarpc_caller.c
deleted file mode 100644
index 744532f..0000000
--- a/components/rpc/ffarpc/caller/linux/ffarpc_caller.c
+++ /dev/null
@@ -1,252 +0,0 @@
-/*
- * Copyright (c) 2020-2022, Arm Limited and Contributors. All rights reserved.
- *
- * SPDX-License-Identifier: BSD-3-Clause
- */
-
-#include "ffarpc_caller.h"
-#include "ffa_tee.h"
-#include <rpc/ffarpc/endpoint/ffarpc_call_args.h>
-#include <rpc/ffarpc/endpoint/ffarpc_call_ops.h>
-#include <protocols/rpc/common/packed-c/status.h>
-#include <fcntl.h>
-#include <sys/ioctl.h>
-#include <stdio.h>
-#include <unistd.h>
-#include <stdint.h>
-#include <stdlib.h>
-#include <string.h>
-#include <util.h>
-
-#define KERNEL_MOD_REQ_VER_MAJOR 1
-#define KERNEL_MOD_REQ_VER_MINOR 0
-#define KERNEL_MOD_REQ_VER_PATCH 0
-
-#define DEFAULT_SHMEM_BUF_SIZE			(4096)
-
-static rpc_call_handle call_begin(void *context, uint8_t **req_buf, size_t req_len);
-static rpc_status_t call_invoke(void *context, rpc_call_handle handle, uint32_t opcode,
-			rpc_opstatus_t *opstatus, uint8_t **resp_buf, size_t *resp_len);
-static void call_end(void *context, rpc_call_handle handle);
-
-bool ffarpc_caller_check_version(void)
-{
-	FILE *f = NULL;
-	int ver_major = -1, ver_minor = -1, ver_patch = -1, scan_cnt = 0;
-
-	f = fopen("/sys/module/arm_ffa_tee/version", "r");
-	if (f) {
-		scan_cnt = fscanf(f, "%d.%d.%d", &ver_major, &ver_minor, &ver_patch);
-		fclose(f);
-		if (scan_cnt != 3) {
-			printf("error: cannot read FF-A TEE driver version\n");
-			return false;
-		}
-	} else {
-		printf("error: FF-A TEE driver not available\n");
-		return false;
-	}
-
-	if (ver_major != KERNEL_MOD_REQ_VER_MAJOR)
-		goto err;
-
-	if (ver_minor < KERNEL_MOD_REQ_VER_MINOR)
-		goto err;
-
-	if (ver_minor == KERNEL_MOD_REQ_VER_MINOR)
-		if (ver_patch < KERNEL_MOD_REQ_VER_PATCH)
-			goto err;
-
-	return true;
-
-err:
-	printf("error: FF-A TEE driver is v%d.%d.%d but required v%d.%d.%d\n",
-		ver_major, ver_minor, ver_patch, KERNEL_MOD_REQ_VER_MAJOR,
-		KERNEL_MOD_REQ_VER_MINOR, KERNEL_MOD_REQ_VER_PATCH);
-
-	return false;
-}
-
-int ffarpc_caller_find_dev_path(char *path, size_t path_len)
-{
-	return ffa_tee_find_dev(path, path_len);
-}
-
-struct rpc_caller *ffarpc_caller_init(struct ffarpc_caller *s, const char *device_path)
-{
-	struct rpc_caller *base = &s->rpc_caller;
-
-	rpc_caller_init(base, s);
-	base->call_begin = call_begin;
-	base->call_invoke = call_invoke;
-	base->call_end = call_end;
-
-	s->device_path = device_path;
-	s->fd = -1;
-	s->dest_partition_id = 0;
-	s->dest_iface_id = 0;
-	s->shared_mem_id = -1;
-	s->shared_mem_required_size = DEFAULT_SHMEM_BUF_SIZE;
-	s->shared_mem_actual_size = 0;
-	s->shared_mem_buf = NULL;
-	s->req_len = 0;
-	s->resp_len = 0;
-	s->is_call_transaction_in_progess = false;
-
-	return base;
-}
-
-void ffarpc_caller_deinit(struct ffarpc_caller *s)
-{
-	s->rpc_caller.context = NULL;
-	s->rpc_caller.call_begin = NULL;
-	s->rpc_caller.call_invoke = NULL;
-	s->rpc_caller.call_end = NULL;
-
-	call_end(s, s);
-}
-
-size_t ffarpc_caller_discover(const struct ffarpc_caller *s, const struct uuid_canonical *uuid,
-						uint16_t *partition_ids, size_t discover_limit)
-{
-	size_t discover_count = 0;
-	bool buf_short = false;
-
-	if (uuid && partition_ids && s->device_path) {
-		int fd = -1;
-
-		fd = open(s->device_path, O_RDWR);
-
-		if (fd >= 0) {
-			int ioctl_status = -1;
-			struct uuid_octets uuid_buf = {0};
-
-			uuid_parse_to_octets(uuid->characters, uuid_buf.octets, UUID_OCTETS_LEN);
-
-			/* Ignore short buffer for now */
-			ioctl_status = ffa_tee_list_part_ids(fd, uuid_buf.octets, partition_ids,
-							     discover_limit, &discover_count,
-							     &buf_short);
-
-			close(fd);
-
-			if (ioctl_status) {
-				printf("%s():%d error: %d\n", __func__, __LINE__, ioctl_status);
-				return 0;
-			}
-		}
-	}
-
-	return discover_count;
-}
-
-int ffarpc_caller_open(struct ffarpc_caller *s, uint16_t dest_partition_id, uint16_t dest_iface_id)
-{
-	int ioctl_status = -1;
-
-	if (s->device_path) {
-
-		s->fd = open(s->device_path, O_RDWR);
-
-		if (s->fd >= 0) {
-			ioctl_status = ffa_tee_open_session(s->fd, dest_partition_id);
-
-			if (ioctl_status == 0) {
-				/* Session successfully opened */
-				s->dest_partition_id = dest_partition_id;
-				s->dest_iface_id = dest_iface_id;
-			} else {
-				close(s->fd);
-				s->fd = -1;
-			}
-		}
-	}
-
-	return ioctl_status;
-}
-
-int ffarpc_caller_close(struct ffarpc_caller *s)
-{
-	if (s->fd >= 0) {
-		ffa_tee_close_session(s->fd);
-		close(s->fd);
-		s->fd = -1;
-		s->dest_partition_id = 0;
-	}
-
-	return 0;
-}
-
-static rpc_call_handle call_begin(void *context, uint8_t **req_buf, size_t req_len)
-{
-	rpc_call_handle handle = NULL;
-	struct ffarpc_caller *s = (struct ffarpc_caller*)context;
-	int rc = -1;
-
-	if (!s->is_call_transaction_in_progess) {
-
-		s->is_call_transaction_in_progess = true;
-		handle = s;
-
-		rc = ffa_tee_share_mem(s->fd, MAX(s->shared_mem_required_size, req_len),
-				       &s->shared_mem_buf, &s->shared_mem_actual_size,
-				       &s->shared_mem_id);
-
-		if (rc == 0) {
-
-			*req_buf = s->shared_mem_buf;
-			s->req_len = req_len;
-		}
-		else {
-			/* Failed to allocate req buffer */
-			handle = NULL;
-			s->is_call_transaction_in_progess = false;
-		}
-	}
-
-	return handle;
-}
-
-static rpc_status_t call_invoke(void *context, rpc_call_handle handle, uint32_t opcode,
-				rpc_opstatus_t *opstatus, uint8_t **resp_buf, size_t *resp_len)
-{
-	int32_t rpc_opstatus = 0;
-	rpc_status_t rpc_status = TS_RPC_ERROR_INTERNAL;
-	struct ffarpc_caller *s = (struct ffarpc_caller*)context;
-
-	if ((handle == s) && s->is_call_transaction_in_progess) {
-		int kernel_op_status = 0;
-
-		kernel_op_status = ffa_tee_send_msg(s->fd, s->dest_iface_id, opcode, s->req_len,
-						    s->rpc_caller.encoding, &s->resp_len,
-						    &rpc_status, &rpc_opstatus);
-
-		*opstatus = (rpc_opstatus_t)rpc_opstatus;
-
-		if (kernel_op_status == 0) {
-			*resp_len = s->resp_len;
-			*resp_buf = s->shared_mem_buf;
-		}
-	}
-
-	return rpc_status;
-}
-
-static void call_end(void *context, rpc_call_handle handle)
-{
-	struct ffarpc_caller *s = (struct ffarpc_caller*)context;
-
-	if ((handle == s) && s->is_call_transaction_in_progess) {
-
-		/* Call transaction complete so free resource */
-		if (s->shared_mem_buf != NULL && s->shared_mem_actual_size != 0) {
-			ffa_tee_reclaim_mem(s->fd, s->shared_mem_buf, s->shared_mem_actual_size);
-			s->shared_mem_buf = NULL;
-			s->shared_mem_actual_size = 0;
-		}
-		s->req_len = 0;
-		s->resp_len = 0;
-
-		s->is_call_transaction_in_progess = false;
-	}
-}
diff --git a/components/rpc/ffarpc/caller/linux/ffarpc_caller.h b/components/rpc/ffarpc/caller/linux/ffarpc_caller.h
deleted file mode 100644
index 6bc4abe..0000000
--- a/components/rpc/ffarpc/caller/linux/ffarpc_caller.h
+++ /dev/null
@@ -1,51 +0,0 @@
-/*
- * Copyright (c) 2020-2022, Arm Limited and Contributors. All rights reserved.
- *
- * SPDX-License-Identifier: BSD-3-Clause
- */
-
-#ifndef FFARPC_CALLER_H
-#define FFARPC_CALLER_H
-
-#include <common/uuid/uuid.h>
-#include <rpc_caller.h>
-#include <stdbool.h>
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-/*
- * An RPC caller for Linux user-space clients.  Uses the FFA kernel driver
- * to communicate with RPC endpoints deployed in partitions accessible
- * via FFA.
- */
-struct ffarpc_caller {
-	struct rpc_caller rpc_caller;
-	int fd;
-	const char *device_path;
-	uint16_t dest_partition_id;
-	uint16_t dest_iface_id;
-	int shared_mem_id;
-	size_t shared_mem_required_size;
-	size_t shared_mem_actual_size;
-	void *shared_mem_buf;
-	size_t req_len;
-	size_t resp_len;
-	bool is_call_transaction_in_progess;
-};
-
-bool ffarpc_caller_check_version(void);
-int ffarpc_caller_find_dev_path(char *path, size_t path_len);
-struct rpc_caller *ffarpc_caller_init(struct ffarpc_caller *s, const char *device_path);
-void ffarpc_caller_deinit(struct ffarpc_caller *s);
-size_t ffarpc_caller_discover(const struct ffarpc_caller *s, const struct uuid_canonical *uuid,
-						uint16_t *partition_ids, size_t discover_limit);
-int ffarpc_caller_open(struct ffarpc_caller *s, uint16_t dest_partition_id, uint16_t dest_iface_id);
-int ffarpc_caller_close(struct ffarpc_caller *s);
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* FFARPC_CALLER_H */
diff --git a/components/rpc/ffarpc/caller/sp/component.cmake b/components/rpc/ffarpc/caller/sp/component.cmake
deleted file mode 100644
index 3bab840..0000000
--- a/components/rpc/ffarpc/caller/sp/component.cmake
+++ /dev/null
@@ -1,14 +0,0 @@
-#-------------------------------------------------------------------------------
-# Copyright (c) 2020, Arm Limited and Contributors. All rights reserved.
-#
-# SPDX-License-Identifier: BSD-3-Clause
-#
-#-------------------------------------------------------------------------------
-if (NOT DEFINED TGT)
-	message(FATAL_ERROR "mandatory parameter TGT is not defined.")
-endif()
-
-target_sources(${TGT} PRIVATE
-	"${CMAKE_CURRENT_LIST_DIR}/ffarpc_caller.c"
-	)
-
diff --git a/components/rpc/ffarpc/caller/sp/ffarpc_caller.c b/components/rpc/ffarpc/caller/sp/ffarpc_caller.c
deleted file mode 100644
index 78c769e..0000000
--- a/components/rpc/ffarpc/caller/sp/ffarpc_caller.c
+++ /dev/null
@@ -1,340 +0,0 @@
-/*
- * Copyright (c) 2020-2022, Arm Limited and Contributors. All rights reserved.
- *
- * SPDX-License-Identifier: BSD-3-Clause
- */
-
-#include "ffarpc_caller.h"
-#include "ffarpc_sp_call_args.h"
-#include <components/rpc/ffarpc/endpoint/ffarpc_call_ops.h>
-#include <protocols/rpc/common/packed-c/status.h>
-#include <ffa_api.h>
-#include <sp_memory_management.h>
-#include <sp_messaging.h>
-#include <sp_rxtx.h>
-#include <trace.h>
-#include <stdbool.h>
-#include <stdint.h>
-#include <stdio.h>
-
-uint8_t shared_buffer[4096] __aligned(4096);
-
-static rpc_call_handle call_begin(void *context, uint8_t **req_buf, size_t req_len)
-{
-	struct ffarpc_caller *this_context = (struct ffarpc_caller *)context;
-	rpc_call_handle handle = NULL;
-
-	if (context == NULL || req_buf == NULL) {
-		EMSG("invalid arguments");
-		goto out;
-	}
-
-	if (this_context->is_call_transaction_in_progess) {
-		EMSG("transaction already in progress");
-		goto out;
-	}
-
-	if (req_len > this_context->shared_mem_required_size) {
-		EMSG("req_len too big");
-		goto out;
-	}
-
-	if (this_context->dest_partition_id == 0) {
-		EMSG("the caller is not open");
-		goto out;
-	}
-
-	this_context->is_call_transaction_in_progess = true;
-	handle = this_context;
-
-	*req_buf = (req_len > 0) ? shared_buffer : NULL;
-
-	this_context->req_buf = *req_buf;
-	this_context->req_len = req_len;
-
-out:
-	return handle;
-}
-
-static rpc_status_t call_invoke(void *context, rpc_call_handle handle, uint32_t opcode,
-				rpc_opstatus_t *opstatus, uint8_t **resp_buf, size_t *resp_len)
-{
-	struct ffarpc_caller *this_context = (struct ffarpc_caller *)context;
-	sp_result sp_res = SP_RESULT_OK;
-	struct sp_msg req = { 0 };
-	struct sp_msg resp = { 0 };
-	rpc_status_t status = TS_RPC_ERROR_INTERNAL;
-
-	if (context == NULL || handle != this_context || opstatus == NULL ||
-	    resp_buf == NULL || resp_len == NULL) {
-		EMSG("invalid arguments");
-		status = TS_RPC_ERROR_INVALID_PARAMETER;
-		goto out;
-	}
-
-	if (!this_context->is_call_transaction_in_progess) {
-		EMSG("transaction was not started");
-		status = TS_RPC_ERROR_NOT_READY;
-		goto out;
-	}
-
-	if (this_context->req_len > UINT32_MAX) {
-		EMSG("req_len is too large");
-		goto out;
-	}
-
-	req.destination_id = this_context->dest_partition_id;
-	req.source_id = this_context->own_id;
-	req.is_64bit_message = false;
-	req.args.args32[SP_CALL_ARGS_IFACE_ID_OPCODE] =
-		FFA_CALL_ARGS_COMBINE_IFACE_ID_OPCODE(this_context->dest_iface_id, opcode);
-	req.args.args32[SP_CALL_ARGS_REQ_DATA_LEN] = (uint32_t)this_context->req_len;
-	req.args.args32[SP_CALL_ARGS_ENCODING] = this_context->rpc_caller.encoding;
-
-	/* Initialise the caller ID.  Depending on the call path, this may
-	 * be overridden by a higher privilege execution level, based on its
-	 * perspective of the caller identity.
-	 */
-	req.args.args32[SP_CALL_ARGS_CALLER_ID] = 0;
-
-	sp_res = sp_msg_send_direct_req(&req, &resp);
-	if (sp_res != SP_RESULT_OK) {
-		EMSG("sp_msg_send_direct_req(): error %"PRId32, sp_res);
-		goto out;
-	}
-
-	this_context->resp_len = (size_t)resp.args.args32[SP_CALL_ARGS_RESP_DATA_LEN];
-	if (this_context->resp_len > this_context->shared_mem_required_size) {
-		EMSG("invalid response length");
-		goto out;
-	}
-
-	status = resp.args.args32[SP_CALL_ARGS_RESP_RPC_STATUS];
-	*opstatus = (rpc_status_t)((int32_t)resp.args.args32[SP_CALL_ARGS_RESP_OP_STATUS]);
-
-	if (this_context->resp_len > 0)
-		this_context->resp_buf = shared_buffer;
-	else
-		this_context->resp_buf = NULL;
-
-	*resp_buf = this_context->resp_buf;
-	*resp_len = this_context->resp_len;
-out:
-	return status;
-}
-
-static void call_end(void *context, rpc_call_handle handle)
-{
-	struct ffarpc_caller *this_context = (struct ffarpc_caller *)context;
-
-	if (context == NULL || handle != this_context) {
-		EMSG("invalid arguments");
-		return;
-	}
-
-	this_context->req_buf = NULL;
-	this_context->req_len = 0;
-	this_context->resp_buf = NULL;
-	this_context->resp_len = 0;
-	this_context->is_call_transaction_in_progess = false;
-}
-
-struct rpc_caller *ffarpc_caller_init(struct ffarpc_caller *caller, uint16_t own_id)
-{
-	struct rpc_caller *base = &caller->rpc_caller;
-
-	rpc_caller_init(base, caller);
-	base->call_begin = call_begin;
-	base->call_invoke = call_invoke;
-	base->call_end = call_end;
-
-	caller->own_id = own_id;
-	caller->dest_partition_id = 0;
-	caller->dest_iface_id = 0;
-	caller->shared_mem_handle = 0;
-	caller->shared_mem_required_size = sizeof(shared_buffer);
-	caller->req_buf = NULL;
-	caller->req_len = 0;
-	caller->resp_buf = NULL;
-	caller->resp_len = 0;
-	caller->is_call_transaction_in_progess = false;
-
-	return base;
-}
-
-void ffarpc_caller_deinit(struct ffarpc_caller *caller)
-{
-	caller->rpc_caller.context = NULL;
-	caller->rpc_caller.call_begin = NULL;
-	caller->rpc_caller.call_invoke = NULL;
-	caller->rpc_caller.call_end = NULL;
-}
-
-uint32_t ffarpc_caller_discover(const uint8_t *uuid, uint16_t *sp_ids, uint32_t sp_max_cnt)
-{
-	ffa_result ffa_res = FFA_OK;
-	sp_result sp_res = SP_RESULT_OK;
-	const void *rx_buf_addr = NULL;
-	size_t rx_buf_size = 0;
-	const struct ffa_partition_information *partitions = NULL;
-	uint32_t sp_cnt = 0;
-	uint32_t i = 0;
-
-	if (uuid == NULL || sp_ids == NULL || sp_max_cnt == 0) {
-		EMSG("invalid arguments");
-		return 0;
-	}
-
-	ffa_res = ffa_partition_info_get((struct ffa_uuid *)uuid, &sp_cnt);
-	if (ffa_res != FFA_OK) {
-		EMSG("ffa_partition_info_get(): error %"PRId32, ffa_res);
-		return 0;
-	}
-
-	sp_res = sp_rxtx_buffer_rx_get(&rx_buf_addr, &rx_buf_size);
-	if (sp_res != SP_RESULT_OK) {
-		EMSG("sp_rxtx_buffer_rx_get(): error %"PRId32, sp_res);
-		return 0;
-	}
-
-	partitions = (const struct ffa_partition_information *)rx_buf_addr;
-	for (i = 0; i < sp_cnt && i < sp_max_cnt; i++)
-		sp_ids[i] = partitions[i].partition_id;
-
-	ffa_res = ffa_rx_release();
-	if (ffa_res != FFA_OK) {
-		EMSG("ffa_rx_release(): error %"PRId32, ffa_res);
-		return 0;
-	}
-
-	return sp_cnt;
-}
-
-int ffarpc_caller_open(struct ffarpc_caller *caller, uint16_t dest_partition_id,
-		       uint16_t dest_iface_id)
-{
-	sp_result sp_res = SP_RESULT_OK;
-	struct sp_msg req = { 0 };
-	struct sp_msg resp = { 0 };
-
-	struct sp_memory_descriptor desc = { 0 };
-	struct sp_memory_access_descriptor acc_desc = { 0 };
-	struct sp_memory_region region = { 0 };
-
-	uint64_t handle = 0;
-
-	rpc_status_t status = TS_RPC_ERROR_INTERNAL;
-
-	if (caller->dest_partition_id) {
-		EMSG("the caller is already open");
-		return -1;
-	}
-
-	if (caller->shared_mem_required_size > UINT32_MAX) {
-		EMSG("memory is too large to share");
-		return -1;
-	}
-
-	desc.sender_id = caller->own_id;
-	desc.memory_type = sp_memory_type_normal_memory;
-	desc.mem_region_attr.normal_memory.cacheability = sp_cacheability_write_back;
-	desc.mem_region_attr.normal_memory.shareability = sp_shareability_inner_shareable;
-
-	acc_desc.data_access = sp_data_access_read_write;
-	acc_desc.instruction_access = sp_instruction_access_not_specified;
-	acc_desc.receiver_id = dest_partition_id;
-
-	region.address = shared_buffer;
-	region.page_count = 1;
-
-	sp_res = sp_memory_share(&desc, &acc_desc, 1, &region, 1, &handle);
-	if (sp_res != SP_RESULT_OK) {
-		EMSG("sp_memory_share(): error %"PRId32, sp_res);
-		return -1;
-	}
-
-	req.source_id = caller->own_id;
-	req.destination_id = dest_partition_id;
-	req.is_64bit_message = false;
-	req.args.args32[SP_CALL_ARGS_IFACE_ID_OPCODE] =
-		FFA_CALL_ARGS_COMBINE_IFACE_ID_OPCODE(FFA_CALL_MGMT_IFACE_ID, FFA_CALL_OPCODE_SHARE_BUF);
-	req.args.args32[SP_CALL_ARGS_SHARE_MEM_HANDLE_LSW] = (uint32_t)(handle & UINT32_MAX);
-	req.args.args32[SP_CALL_ARGS_SHARE_MEM_HANDLE_MSW] = (uint32_t)(handle >> 32);
-	req.args.args32[SP_CALL_ARGS_SHARE_MEM_SIZE] = (uint32_t)(caller->shared_mem_required_size);
-
-	sp_res = sp_msg_send_direct_req(&req, &resp);
-	if (sp_res != SP_RESULT_OK) {
-		EMSG("sp_msg_send_direct_req(): error %"PRId32, sp_res);
-		return -1;
-	}
-
-	status = (rpc_status_t)resp.args.args32[SP_CALL_ARGS_RESP_RPC_STATUS];
-	if (status != TS_RPC_CALL_ACCEPTED) {
-		EMSG("RPC endpoint error: %"PRId32, status);
-
-		sp_res = sp_memory_reclaim(handle, 0);
-		if (sp_res != SP_RESULT_OK)
-			EMSG("sp_memory_reclaim(): error %"PRId32, sp_res);
-
-		return -1;
-	}
-
-	caller->dest_partition_id = dest_partition_id;
-	caller->dest_iface_id = dest_iface_id;
-	caller->shared_mem_handle = handle;
-
-	return 0;
-}
-
-int ffarpc_caller_close(struct ffarpc_caller *caller)
-{
-	sp_result sp_res = SP_RESULT_OK;
-	struct sp_msg req = { 0 };
-	struct sp_msg resp = { 0 };
-	uint32_t handle_lo = 0, handle_hi = 0;
-	rpc_status_t status = TS_RPC_ERROR_INTERNAL;
-
-	if (caller->dest_partition_id == 0) {
-		EMSG("the caller is already closed");
-		return -1;
-	}
-
-	handle_lo = (uint32_t)(caller->shared_mem_handle & UINT32_MAX);
-	handle_hi = (uint32_t)(caller->shared_mem_handle >> 32);
-
-	req.source_id = caller->own_id;
-	req.destination_id = caller->dest_partition_id;
-	req.is_64bit_message = false;
-	req.args.args32[SP_CALL_ARGS_IFACE_ID_OPCODE] =
-		FFA_CALL_ARGS_COMBINE_IFACE_ID_OPCODE(FFA_CALL_MGMT_IFACE_ID, FFA_CALL_OPCODE_UNSHARE_BUF);
-	req.args.args32[SP_CALL_ARGS_SHARE_MEM_HANDLE_LSW] = handle_lo;
-	req.args.args32[SP_CALL_ARGS_SHARE_MEM_HANDLE_MSW] = handle_hi;
-
-	sp_res = sp_msg_send_direct_req(&req, &resp);
-	if (sp_res != SP_RESULT_OK) {
-		EMSG("sp_msg_send_direct_req(): error %"PRId32, sp_res);
-		return -1;
-	}
-
-	status = (rpc_status_t)resp.args.args32[SP_CALL_ARGS_RESP_RPC_STATUS];
-	if (status) {
-		/*
-		 * The RPC endpoint failed to relinquish the shared memory but
-		 * still worth trying to reclaim the memory beside emiting an
-		 * error message.
-		 */
-		EMSG("RPC endpoint error %"PRId32, status);
-	}
-
-	sp_res = sp_memory_reclaim(caller->shared_mem_handle, 0);
-	if (sp_res != SP_RESULT_OK) {
-		EMSG("sp_memory_reclaim(): error %"PRId32, sp_res);
-		return -1;
-	}
-
-	caller->dest_partition_id = 0;
-	caller->dest_iface_id = 0;
-	caller->shared_mem_handle = 0;
-
-	return 0;
-}
diff --git a/components/rpc/ffarpc/caller/sp/ffarpc_caller.h b/components/rpc/ffarpc/caller/sp/ffarpc_caller.h
deleted file mode 100644
index c685043..0000000
--- a/components/rpc/ffarpc/caller/sp/ffarpc_caller.h
+++ /dev/null
@@ -1,41 +0,0 @@
-/*
- * Copyright (c) 2020-2022, Arm Limited and Contributors. All rights reserved.
- *
- * SPDX-License-Identifier: BSD-3-Clause
- */
-
-#ifndef FFA_SERVICE_CALLER_H
-#define FFA_SERVICE_CALLER_H
-
-#include <rpc_caller.h>
-#include <stdbool.h>
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-struct ffarpc_caller {
-	struct rpc_caller rpc_caller;
-	uint16_t own_id;
-	uint16_t dest_partition_id;
-	uint16_t dest_iface_id;
-	uint64_t shared_mem_handle;
-	size_t shared_mem_required_size;
-	uint8_t *req_buf;
-	uint8_t *resp_buf;
-	size_t req_len;
-	size_t resp_len;
-	bool is_call_transaction_in_progess;
-};
-
-struct rpc_caller *ffarpc_caller_init(struct ffarpc_caller *s, uint16_t own_id);
-void ffarpc_caller_deinit(struct ffarpc_caller *s);
-uint32_t ffarpc_caller_discover(const uint8_t *uuid, uint16_t *sp_ids, uint32_t sp_max_cnt);
-int ffarpc_caller_open(struct ffarpc_caller *s, uint16_t dest_partition_id, uint16_t dest_iface_id);
-int ffarpc_caller_close(struct ffarpc_caller *s);
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* FFA_SERVICE_CALLER_H */
diff --git a/components/rpc/ffarpc/caller/sp/ffarpc_sp_call_args.h b/components/rpc/ffarpc/caller/sp/ffarpc_sp_call_args.h
deleted file mode 100644
index e85c9a9..0000000
--- a/components/rpc/ffarpc/caller/sp/ffarpc_sp_call_args.h
+++ /dev/null
@@ -1,44 +0,0 @@
-/* SPDX-License-Identifier: BSD-3-Clause */
-/*
- * Copyright (c) 2021, Arm Limited and Contributors. All rights reserved.
- */
-
-#ifndef FFA_RPC_SP_CALL_ARGS_H_
-#define FFA_RPC_SP_CALL_ARGS_H_
-
-#include "components/rpc/ffarpc/endpoint/ffarpc_call_args.h"
-
-/*
- * sp_msg args is shifted by one compared to ffa_direct_msg because the first
- * parameter register (w3/w3) is used by the routing extension and it is not
- * included in sp_msg args.
- */
-#define FFA_TO_SP_CALL_OFFSET(offset) ((offset)-1)
-
-/* Common req & resp arg offests into sp_msg args structure */
-#define SP_CALL_ARGS_IFACE_ID_OPCODE                                           \
-	FFA_TO_SP_CALL_OFFSET(FFA_CALL_ARGS_IFACE_ID_OPCODE)
-
-/* Req arg offsets */
-#define SP_CALL_ARGS_REQ_DATA_LEN                                              \
-	FFA_TO_SP_CALL_OFFSET(FFA_CALL_ARGS_REQ_DATA_LEN)
-#define SP_CALL_ARGS_CALLER_ID FFA_TO_SP_CALL_OFFSET(FFA_CALL_ARGS_CALLER_ID)
-#define SP_CALL_ARGS_ENCODING FFA_TO_SP_CALL_OFFSET(FFA_CALL_ARGS_ENCODING)
-
-/* Resp arg offsets */
-#define SP_CALL_ARGS_RESP_DATA_LEN                                             \
-	FFA_TO_SP_CALL_OFFSET(FFA_CALL_ARGS_RESP_DATA_LEN)
-#define SP_CALL_ARGS_RESP_RPC_STATUS                                           \
-	FFA_TO_SP_CALL_OFFSET(FFA_CALL_ARGS_RESP_RPC_STATUS)
-#define SP_CALL_ARGS_RESP_OP_STATUS                                            \
-	FFA_TO_SP_CALL_OFFSET(FFA_CALL_ARGS_RESP_OP_STATUS)
-
-/* Share/unshare offsets */
-#define SP_CALL_ARGS_SHARE_MEM_HANDLE_LSW                                      \
-	FFA_TO_SP_CALL_OFFSET(FFA_CALL_ARGS_SHARE_MEM_HANDLE_LSW)
-#define SP_CALL_ARGS_SHARE_MEM_HANDLE_MSW                                      \
-	FFA_TO_SP_CALL_OFFSET(FFA_CALL_ARGS_SHARE_MEM_HANDLE_MSW)
-#define SP_CALL_ARGS_SHARE_MEM_SIZE                                            \
-	FFA_TO_SP_CALL_OFFSET(FFA_CALL_ARGS_SHARE_MEM_SIZE)
-
-#endif /* FFA_RPC_SP_CALL_ARGS_H_ */
diff --git a/components/rpc/ffarpc/caller/sp/test/component.cmake b/components/rpc/ffarpc/caller/sp/test/component.cmake
deleted file mode 100644
index 2dca8eb..0000000
--- a/components/rpc/ffarpc/caller/sp/test/component.cmake
+++ /dev/null
@@ -1,13 +0,0 @@
-#-------------------------------------------------------------------------------
-# Copyright (c) 2022, Arm Limited and Contributors. All rights reserved.
-#
-# SPDX-License-Identifier: BSD-3-Clause
-#
-#-------------------------------------------------------------------------------
-if (NOT DEFINED TGT)
-	message(FATAL_ERROR "mandatory parameter TGT is not defined.")
-endif()
-
-target_sources(${TGT} PRIVATE
-	"${CMAKE_CURRENT_LIST_DIR}/test_ffarpc_caller.cpp"
-)
diff --git a/components/rpc/ffarpc/caller/sp/test/test_ffarpc_caller.cpp b/components/rpc/ffarpc/caller/sp/test/test_ffarpc_caller.cpp
deleted file mode 100644
index 0b2c726..0000000
--- a/components/rpc/ffarpc/caller/sp/test/test_ffarpc_caller.cpp
+++ /dev/null
@@ -1,617 +0,0 @@
-/*
- * Copyright (c) 2022, Arm Limited and Contributors. All rights reserved.
- *
- * SPDX-License-Identifier: BSD-3-Clause
- */
-
-#include <CppUTest/TestHarness.h>
-#include <CppUTestExt/MockSupport.h>
-#include "../ffarpc_caller.h"
-#include "protocols/rpc/common/packed-c/status.h"
-#include "mock_ffa_api.h"
-#include "mock_sp_memory_management.h"
-#include "mock_sp_messaging.h"
-#include "mock_sp_rxtx.h"
-#include <string.h>
-
-extern uint8_t shared_buffer[4096];
-
-static const uint8_t uuid[16] = {
-	0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef,
-	0x12, 0x34, 0x56, 0x78, 0x9a, 0xbc, 0xde, 0xf0
-};
-
-static const struct ffa_partition_information partiton_info[5] = {
-	{.partition_id = 0x8001, .execution_context_count = 1, .partition_properties = 0},
-	{.partition_id = 0x8002, .execution_context_count = 1, .partition_properties = 0},
-	{.partition_id = 0x8003, .execution_context_count = 1, .partition_properties = 0},
-	{.partition_id = 0x8004, .execution_context_count = 1, .partition_properties = 0},
-	{.partition_id = 0x8005, .execution_context_count = 1, .partition_properties = 0},
-};
-
-TEST_GROUP(ffarpc_caller) {
-	TEST_SETUP()
-	{
-		own_id = 0x0123;
-		rpc_caller_instance = ffarpc_caller_init(&caller, own_id);
-		memset(&req, 0x00, sizeof(req));
-		memset(&resp, 0x00, sizeof(resp));
-		memset(&desc, 0x00, sizeof(desc));
-		memset(&acc_desc, 0x00, sizeof(acc_desc));
-		memset(&region, 0x00, sizeof(region));
-	}
-
-	TEST_TEARDOWN()
-	{
-		ffarpc_caller_deinit(&caller);
-		mock().checkExpectations();
-		mock().clear();
-	}
-
-	void setup_mem_share_descriptors(uint16_t sender_id, uint16_t dest_id)
-	{
-		desc.sender_id = sender_id;
-		desc.memory_type = sp_memory_type_normal_memory;
-		desc.mem_region_attr.normal_memory.cacheability = sp_cacheability_write_back;
-		desc.mem_region_attr.normal_memory.shareability = sp_shareability_inner_shareable;
-
-		acc_desc.data_access = sp_data_access_read_write;
-		acc_desc.instruction_access = sp_instruction_access_not_specified;
-		acc_desc.receiver_id = dest_id;
-
-		region.address = shared_buffer;
-		region.page_count = 1;
-	}
-
-	void expect_mem_share_msg(uint16_t src_id, uint16_t dst_id, uint64_t handle,
-				  size_t buffer_size, rpc_status_t rpc_status, sp_result res)
-	{
-		expect_mem_handler_msg(0, src_id, dst_id, handle, buffer_size, rpc_status, res);
-	}
-
-	void expect_mem_unshare_msg(uint16_t src_id, uint16_t dst_id, uint64_t handle,
-				    rpc_status_t rpc_status, sp_result res)
-	{
-		expect_mem_handler_msg(1, src_id, dst_id, handle, 0, rpc_status, res);
-	}
-
-	void expect_mem_handler_msg(uint16_t opcode, uint16_t src_id, uint16_t dst_id,
-				    uint64_t handle, size_t buffer_size,
-				    rpc_status_t rpc_status, sp_result res)
-	{
-		req.source_id = src_id;
-		req.destination_id = dst_id;
-		req.args.args32[0] = 0x1000 << 16 | opcode;
-		req.args.args32[1] = (handle & UINT32_MAX);
-		req.args.args32[2] = ((handle >> 32) & UINT32_MAX);
-		req.args.args32[3] = buffer_size;
-
-		resp.source_id = dst_id;
-		resp.destination_id = src_id;
-		resp.args.args32[0] = 0x1000 << 16 | opcode;
-		resp.args.args32[2] = rpc_status;
-
-		expect_sp_msg_send_direct_req(&req, &resp, res);
-	}
-
-	uint16_t own_id;
-	struct ffarpc_caller caller;
-	rpc_caller *rpc_caller_instance;
-	struct sp_msg req;
-	struct sp_msg resp;
-	struct sp_memory_descriptor desc;
-	struct sp_memory_access_descriptor acc_desc;
-	struct sp_memory_region region;
-};
-
-TEST(ffarpc_caller, discover_invalid_arguments)
-{
-	uint16_t sp_ids[5] = {0};
-
-	UNSIGNED_LONGS_EQUAL(0, ffarpc_caller_discover(NULL, sp_ids, 5));
-	UNSIGNED_LONGS_EQUAL(0, ffarpc_caller_discover(uuid, NULL, 5));
-	UNSIGNED_LONGS_EQUAL(0, ffarpc_caller_discover(uuid, sp_ids, 0));
-}
-
-TEST(ffarpc_caller, discover_partition_info_get_fail)
-{
-	uint32_t count = 0;
-	uint16_t sp_ids[5] = {0};
-
-	expect_ffa_partition_info_get((struct ffa_uuid *)uuid, &count, FFA_BUSY);
-	UNSIGNED_LONGS_EQUAL(0, ffarpc_caller_discover(uuid, sp_ids, 5));
-}
-
-TEST(ffarpc_caller, discover_rx_get_fail)
-{
-	uint32_t count = 5;
-	uint16_t sp_ids[5] = {0};
-	const void *buffer = NULL;
-	size_t size = 0;
-
-	expect_ffa_partition_info_get((struct ffa_uuid *)uuid, &count, FFA_OK);
-	expect_sp_rxtx_buffer_rx_get(&buffer, &size, SP_RESULT_INTERNAL_ERROR);
-	UNSIGNED_LONGS_EQUAL(0, ffarpc_caller_discover(uuid, sp_ids, 5));
-}
-
-TEST(ffarpc_caller, discover_rx_release_fail)
-{
-	uint32_t count = 5;
-	uint16_t sp_ids[5] = {0};
-	const void *buffer_ptr = partiton_info;
-	size_t size = sizeof(partiton_info);
-
-	expect_ffa_partition_info_get((struct ffa_uuid *)uuid, &count, FFA_OK);
-	expect_sp_rxtx_buffer_rx_get(&buffer_ptr, &size, SP_RESULT_OK);
-	expect_ffa_rx_release(FFA_BUSY);
-	UNSIGNED_LONGS_EQUAL(0, ffarpc_caller_discover(uuid, sp_ids, 5));
-}
-
-TEST(ffarpc_caller, discover)
-{
-	uint32_t count = 5;
-	uint16_t sp_ids[5] = {0};
-	const void *buffer_ptr = partiton_info;
-	size_t size = sizeof(partiton_info);
-	uint16_t expected_sp_ids[5] = {0x8001, 0x8002, 0x8003, 0x8004, 0x8005};
-
-	expect_ffa_partition_info_get((struct ffa_uuid *)uuid, &count, FFA_OK);
-	expect_sp_rxtx_buffer_rx_get(&buffer_ptr, &size, SP_RESULT_OK);
-	expect_ffa_rx_release(FFA_OK);
-	UNSIGNED_LONGS_EQUAL(count, ffarpc_caller_discover(uuid, sp_ids, count));
-	MEMCMP_EQUAL(expected_sp_ids, sp_ids, sizeof(expected_sp_ids));
-}
-
-TEST(ffarpc_caller, discover_less_max_cnt)
-{
-	uint32_t count = 5;
-	uint16_t sp_ids[2] = {0};
-	const void *buffer_ptr = partiton_info;
-	size_t size = sizeof(partiton_info);
-	uint16_t expected_sp_ids[2] = {0x8001, 0x8002};
-
-	expect_ffa_partition_info_get((struct ffa_uuid *)uuid, &count, FFA_OK);
-	expect_sp_rxtx_buffer_rx_get(&buffer_ptr, &size, SP_RESULT_OK);
-	expect_ffa_rx_release(FFA_OK);
-	UNSIGNED_LONGS_EQUAL(count, ffarpc_caller_discover(uuid, sp_ids, 2));
-	MEMCMP_EQUAL(expected_sp_ids, sp_ids, sizeof(expected_sp_ids));
-}
-
-TEST(ffarpc_caller, discover_more_max_cnt)
-{
-	uint32_t count = 2;
-	uint16_t sp_ids[5] = {0};
-	const void *buffer_ptr = partiton_info;
-	size_t size = sizeof(partiton_info);
-	uint16_t expected_sp_ids[5] = {0x8001, 0x8002, 0, 0, 0};
-
-	expect_ffa_partition_info_get((struct ffa_uuid *)uuid, &count, FFA_OK);
-	expect_sp_rxtx_buffer_rx_get(&buffer_ptr, &size, SP_RESULT_OK);
-	expect_ffa_rx_release(FFA_OK);
-	UNSIGNED_LONGS_EQUAL(count, ffarpc_caller_discover(uuid, sp_ids, 5));
-	MEMCMP_EQUAL(expected_sp_ids, sp_ids, sizeof(expected_sp_ids));
-}
-
-TEST(ffarpc_caller, open_already_opened)
-{
-	caller.dest_partition_id = 1;
-	LONGS_EQUAL(-1, ffarpc_caller_open(&caller, 0, 0));
-}
-
-TEST(ffarpc_caller, open_invalid_mem_size)
-{
-	caller.shared_mem_required_size = (size_t)UINT32_MAX + 1;
-	LONGS_EQUAL(-1, ffarpc_caller_open(&caller, 0, 0));
-}
-
-TEST(ffarpc_caller, open_share_fail)
-{
-	uint16_t dest_id = 0x1234;
-	uint64_t handle = 0x56789abcdef01234ULL;
-
-	setup_mem_share_descriptors(own_id, dest_id);
-
-	expect_sp_memory_share(&desc, &acc_desc, 1, &region, 1, &handle,
-			       SP_RESULT_INVALID_PARAMETERS);
-	LONGS_EQUAL(-1, ffarpc_caller_open(&caller, dest_id, 0));
-}
-
-TEST(ffarpc_caller, open_send_direct_req_fail)
-{
-	uint16_t dest_id = 0x1234;
-	uint64_t handle = 0x56789abcdef01234ULL;
-
-	setup_mem_share_descriptors(own_id, dest_id);
-
-	expect_sp_memory_share(&desc, &acc_desc, 1, &region, 1, &handle, SP_RESULT_OK);
-	expect_mem_share_msg(own_id, dest_id, handle, sizeof(shared_buffer),
-			     TS_RPC_ERROR_INTERNAL, SP_RESULT_INTERNAL_ERROR);
-	LONGS_EQUAL(-1, ffarpc_caller_open(&caller, dest_id, 0));
-}
-
-TEST(ffarpc_caller, open_send_direct_req_rpc_status_fail)
-{
-	uint16_t dest_id = 0x1234;
-	uint64_t handle = 0x56789abcdef01234ULL;
-
-	setup_mem_share_descriptors(own_id, dest_id);
-
-	expect_sp_memory_share(&desc, &acc_desc, 1, &region, 1, &handle, SP_RESULT_OK);
-	expect_mem_share_msg(own_id, dest_id, handle, sizeof(shared_buffer),
-			     TS_RPC_ERROR_INVALID_PARAMETER, SP_RESULT_OK);
-	expect_sp_memory_reclaim(handle, 0, SP_RESULT_OK);
-	LONGS_EQUAL(-1, ffarpc_caller_open(&caller, dest_id, 0));
-}
-
-TEST(ffarpc_caller, open_send_direct_req_rpc_status_fail_reclaim_fail)
-{
-	uint16_t dest_id = 0x1234;
-	uint64_t handle = 0x56789abcdef01234ULL;
-
-	setup_mem_share_descriptors(own_id, dest_id);
-
-	expect_sp_memory_share(&desc, &acc_desc, 1, &region, 1, &handle, SP_RESULT_OK);
-	expect_mem_share_msg(own_id, dest_id, handle, sizeof(shared_buffer),
-			     TS_RPC_ERROR_INVALID_PARAMETER, SP_RESULT_OK);
-	expect_sp_memory_reclaim(handle, 0, SP_RESULT_INVALID_PARAMETERS);
-	LONGS_EQUAL(-1, ffarpc_caller_open(&caller, dest_id, 0));
-}
-
-TEST(ffarpc_caller, open_success)
-{
-	uint16_t dest_id = 0x1234;
-	uint64_t handle = 0x56789abcdef01234ULL;
-
-	setup_mem_share_descriptors(own_id, dest_id);
-
-	expect_sp_memory_share(&desc, &acc_desc, 1, &region, 1, &handle, SP_RESULT_OK);
-	expect_mem_share_msg(own_id, dest_id, handle, sizeof(shared_buffer),
-			     TS_RPC_CALL_ACCEPTED, SP_RESULT_OK);
-	LONGS_EQUAL(0, ffarpc_caller_open(&caller, dest_id, 0));
-}
-
-TEST(ffarpc_caller, close_not_opened)
-{
-	LONGS_EQUAL(-1, ffarpc_caller_close(&caller));
-}
-
-TEST(ffarpc_caller, close_send_direct_msg_fail)
-{
-	caller.shared_mem_handle = 0x56789abcdef01234ULL;
-	caller.dest_partition_id = 0x1234;
-
-	expect_mem_unshare_msg(own_id, caller.dest_partition_id, caller.shared_mem_handle,
-			       TS_RPC_ERROR_INTERNAL, SP_RESULT_INVALID_PARAMETERS);
-	LONGS_EQUAL(-1, ffarpc_caller_close(&caller));
-}
-
-TEST(ffarpc_caller, close_mem_reclaim_fail)
-{
-	caller.shared_mem_handle = 0x56789abcdef01234ULL;
-	caller.dest_partition_id = 0x1234;
-
-	expect_mem_unshare_msg(own_id, caller.dest_partition_id, caller.shared_mem_handle,
-			       TS_RPC_CALL_ACCEPTED, SP_RESULT_OK);
-	expect_sp_memory_reclaim(caller.shared_mem_handle, 0, SP_RESULT_INVALID_PARAMETERS);
-	LONGS_EQUAL(-1, ffarpc_caller_close(&caller));
-}
-
-TEST(ffarpc_caller, close_endpoint_and_mem_reclaim_fail)
-{
-	caller.shared_mem_handle = 0x56789abcdef01234ULL;
-	caller.dest_partition_id = 0x1234;
-
-	expect_mem_unshare_msg(own_id, caller.dest_partition_id, caller.shared_mem_handle,
-			       TS_RPC_ERROR_ACCESS_DENIED, SP_RESULT_OK);
-	expect_sp_memory_reclaim(caller.shared_mem_handle, 0, SP_RESULT_INVALID_PARAMETERS);
-	LONGS_EQUAL(-1, ffarpc_caller_close(&caller));
-}
-
-TEST(ffarpc_caller, close_success)
-{
-	caller.shared_mem_handle = 0x56789abcdef01234ULL;
-	caller.dest_partition_id = 0x1234;
-
-	expect_mem_unshare_msg(own_id, caller.dest_partition_id, caller.shared_mem_handle,
-			       TS_RPC_CALL_ACCEPTED, SP_RESULT_OK);
-	expect_sp_memory_reclaim(caller.shared_mem_handle, 0, SP_RESULT_OK);
-	LONGS_EQUAL(0, ffarpc_caller_close(&caller));
-}
-
-TEST(ffarpc_caller, begin_null_context)
-{
-	uint8_t *buffer = NULL;
-
-	rpc_caller_instance->context = NULL;
-
-	POINTERS_EQUAL(NULL,  rpc_caller_begin(rpc_caller_instance, &buffer, 0));
-}
-
-TEST(ffarpc_caller, begin_null_buffer)
-{
-	POINTERS_EQUAL(NULL, rpc_caller_begin(rpc_caller_instance, NULL, 0));
-}
-
-TEST(ffarpc_caller, begin_transaction_in_progress)
-{
-	uint8_t *buffer = NULL;
-
-	caller.is_call_transaction_in_progess = true;
-	POINTERS_EQUAL(NULL, rpc_caller_begin(rpc_caller_instance, &buffer, 0));
-}
-
-TEST(ffarpc_caller, begin_too_large_req)
-{
-	uint8_t *buffer = NULL;
-
-	POINTERS_EQUAL(NULL, rpc_caller_begin(rpc_caller_instance, &buffer,
-					      sizeof(shared_buffer) + 1));
-}
-
-TEST(ffarpc_caller, begin_not_opened)
-{
-	uint8_t *buffer = NULL;
-
-	rpc_call_handle handle = rpc_caller_begin(rpc_caller_instance, &buffer,
-						  0);
-	POINTERS_EQUAL(NULL, handle);
-}
-
-TEST(ffarpc_caller, begin_with_buffer)
-{
-	uint8_t *buffer = NULL;
-
-	caller.dest_partition_id = 1;
-	rpc_call_handle handle = rpc_caller_begin(rpc_caller_instance, &buffer,
-						  sizeof(shared_buffer));
-	CHECK_TRUE(handle != NULL);
-	POINTERS_EQUAL(shared_buffer, buffer);
-}
-
-TEST(ffarpc_caller, begin_without_buffer)
-{
-	uint8_t *buffer = NULL;
-
-	caller.dest_partition_id = 1;
-	rpc_call_handle handle = rpc_caller_begin(rpc_caller_instance, &buffer,
-						  0);
-	CHECK_TRUE(handle != NULL);
-	POINTERS_EQUAL(NULL, buffer);
-}
-
-TEST(ffarpc_caller, invoke_null_context)
-{
-	rpc_opstatus_t opstatus = 0;
-	uint8_t *resp_buf = NULL;
-	size_t resp_len = 0;
-
-	rpc_caller_instance->context = NULL;
-	LONGS_EQUAL(TS_RPC_ERROR_INVALID_PARAMETER,
-		    rpc_caller_invoke(rpc_caller_instance, NULL, 0, &opstatus,
-				      &resp_buf, &resp_len));
-}
-
-TEST(ffarpc_caller, invoke_handle_context_diff)
-{
-	rpc_opstatus_t opstatus = 0;
-	uint8_t *resp_buf = NULL;
-	size_t resp_len = 0;
-
-	LONGS_EQUAL(TS_RPC_ERROR_INVALID_PARAMETER,
-		    rpc_caller_invoke(rpc_caller_instance, NULL, 0, &opstatus,
-				      &resp_buf, &resp_len));
-}
-
-TEST(ffarpc_caller, invoke_opstatus_null)
-{
-	rpc_call_handle handle = &caller;
-	uint8_t *resp_buf = NULL;
-	size_t resp_len = 0;
-
-	LONGS_EQUAL(TS_RPC_ERROR_INVALID_PARAMETER,
-		    rpc_caller_invoke(rpc_caller_instance, handle, 0, NULL,
-				      &resp_buf, &resp_len));
-}
-
-TEST(ffarpc_caller, invoke_resp_buf_null)
-{
-	rpc_call_handle handle = &caller;
-	rpc_opstatus_t opstatus = 0;
-	size_t resp_len = 0;
-
-	LONGS_EQUAL(TS_RPC_ERROR_INVALID_PARAMETER,
-		    rpc_caller_invoke(rpc_caller_instance, handle, 0,
-				      &opstatus, NULL, &resp_len));
-}
-
-TEST(ffarpc_caller, invoke_resp_len_null)
-{
-	rpc_call_handle handle = &caller;
-	rpc_opstatus_t opstatus = 0;
-	uint8_t *resp_buf = NULL;
-
-	LONGS_EQUAL(TS_RPC_ERROR_INVALID_PARAMETER,
-		    rpc_caller_invoke(rpc_caller_instance, handle, 0,
-				      &opstatus, &resp_buf, NULL));
-}
-
-TEST(ffarpc_caller, invoke_resp_no_begin)
-{
-	rpc_call_handle handle = &caller;
-	rpc_opstatus_t opstatus = 0;
-	uint8_t *resp_buf = NULL;
-	size_t resp_len = 0;
-
-	LONGS_EQUAL(TS_RPC_ERROR_NOT_READY,
-		    rpc_caller_invoke(rpc_caller_instance, handle, 0,
-				      &opstatus, &resp_buf, &resp_len));
-}
-
-TEST(ffarpc_caller, invoke_resp_long_req)
-{
-	rpc_call_handle handle = &caller;
-	rpc_opstatus_t opstatus = 0;
-	uint8_t *resp_buf = NULL;
-	size_t resp_len = 0;
-
-	caller.is_call_transaction_in_progess = true;
-	caller.req_len = (size_t)UINT32_MAX + 1;
-	LONGS_EQUAL(TS_RPC_ERROR_INTERNAL,
-		    rpc_caller_invoke(rpc_caller_instance, handle, 0,
-				      &opstatus, &resp_buf, &resp_len));
-}
-
-TEST(ffarpc_caller, invoke_send_direct_req_fail)
-{
-	rpc_call_handle handle = &caller;
-	uint16_t opcode = 0xfedc;
-	rpc_opstatus_t opstatus = 0;
-	uint8_t *resp_buf = NULL;
-	size_t resp_len = 0;
-
-	caller.is_call_transaction_in_progess = true;
-	caller.shared_mem_handle = 0x56789abcdef01234ULL;
-	caller.dest_partition_id = 0x1234;
-	caller.req_len = 0x3456789a;
-	caller.rpc_caller.encoding = 0xabcdef12;
-
-	req.source_id = own_id;
-	req.destination_id = caller.dest_partition_id;
-	req.args.args32[0] = opcode;
-	req.args.args32[1] = caller.req_len;
-	req.args.args32[2] = 0;
-	req.args.args32[3] = caller.rpc_caller.encoding;
-
-	expect_sp_msg_send_direct_req(&req, &resp, SP_RESULT_INTERNAL_ERROR);
-	LONGS_EQUAL(TS_RPC_ERROR_INTERNAL,
-		    rpc_caller_invoke(rpc_caller_instance, handle, opcode,
-				      &opstatus, &resp_buf, &resp_len));
-}
-
-TEST(ffarpc_caller, invoke_invalid_resp_len)
-{
-	rpc_call_handle handle = &caller;
-	uint16_t opcode = 0xfedc;
-	rpc_opstatus_t opstatus = 0;
-	uint8_t *resp_buf = NULL;
-	size_t resp_len = 0;
-
-	caller.is_call_transaction_in_progess = true;
-	caller.shared_mem_handle = 0x56789abcdef01234ULL;
-	caller.dest_partition_id = 0x1234;
-	caller.req_len = 0x3456789a;
-	caller.rpc_caller.encoding = 0xabcdef12;
-
-	req.source_id = own_id;
-	req.destination_id = caller.dest_partition_id;
-	req.args.args32[0] = opcode;
-	req.args.args32[1] = caller.req_len;
-	req.args.args32[2] = 0;
-	req.args.args32[3] = caller.rpc_caller.encoding;
-
-	resp.source_id = caller.dest_partition_id;
-	resp.destination_id = own_id;
-	resp.args.args32[0] = opcode;
-	resp.args.args32[1] = sizeof(shared_buffer) + 1;
-	resp.args.args32[2] = TS_RPC_CALL_ACCEPTED;
-	resp.args.args32[3] = 0;
-
-	expect_sp_msg_send_direct_req(&req, &resp, SP_RESULT_OK);
-	LONGS_EQUAL(TS_RPC_ERROR_INTERNAL,
-		    rpc_caller_invoke(rpc_caller_instance, handle, opcode,
-				      &opstatus, &resp_buf, &resp_len));
-}
-
-TEST(ffarpc_caller, invoke_with_response)
-{
-	rpc_call_handle handle = &caller;
-	uint16_t opcode = 0xfedc;
-	rpc_opstatus_t opstatus = 0;
-	uint8_t *resp_buf = NULL;
-	size_t resp_len = 0;
-
-	caller.is_call_transaction_in_progess = true;
-	caller.shared_mem_handle = 0x56789abcdef01234ULL;
-	caller.dest_partition_id = 0x1234;
-	caller.req_len = 0x3456789a;
-	caller.rpc_caller.encoding = 0xabcdef12;
-
-	req.source_id = own_id;
-	req.destination_id = caller.dest_partition_id;
-	req.args.args32[0] = opcode;
-	req.args.args32[1] = caller.req_len;
-	req.args.args32[2] = 0;
-	req.args.args32[3] = caller.rpc_caller.encoding;
-
-	resp.source_id = caller.dest_partition_id;
-	resp.destination_id = own_id;
-	resp.args.args32[0] = opcode;
-	resp.args.args32[1] = sizeof(shared_buffer);
-	resp.args.args32[2] = TS_RPC_CALL_ACCEPTED;
-	resp.args.args32[3] = 0;
-
-	expect_sp_msg_send_direct_req(&req, &resp, SP_RESULT_OK);
-	LONGS_EQUAL(TS_RPC_CALL_ACCEPTED,
-		    rpc_caller_invoke(rpc_caller_instance, handle, opcode,
-				      &opstatus, &resp_buf, &resp_len));
-	POINTERS_EQUAL(shared_buffer, resp_buf);
-	UNSIGNED_LONGS_EQUAL(sizeof(shared_buffer), resp_len);
-}
-
-TEST(ffarpc_caller, invoke_without_response)
-{
-	rpc_call_handle handle = &caller;
-	uint16_t opcode = 0xfedc;
-	rpc_opstatus_t opstatus = 0;
-	uint8_t *resp_buf = (uint8_t *)0x123;
-	size_t resp_len = 1;
-
-	caller.is_call_transaction_in_progess = true;
-	caller.shared_mem_handle = 0x56789abcdef01234ULL;
-	caller.dest_partition_id = 0x1234;
-	caller.req_len = 0x3456789a;
-	caller.rpc_caller.encoding = 0xabcdef12;
-
-	req.source_id = own_id;
-	req.destination_id = caller.dest_partition_id;
-	req.args.args32[0] = opcode;
-	req.args.args32[1] = caller.req_len;
-	req.args.args32[2] = 0;
-	req.args.args32[3] = caller.rpc_caller.encoding;
-
-	resp.source_id = caller.dest_partition_id;
-	resp.destination_id = own_id;
-	resp.args.args32[0] = opcode;
-	resp.args.args32[1] = 0;
-	resp.args.args32[2] = TS_RPC_CALL_ACCEPTED;
-	resp.args.args32[3] = 0;
-
-	expect_sp_msg_send_direct_req(&req, &resp, SP_RESULT_OK);
-	LONGS_EQUAL(TS_RPC_CALL_ACCEPTED,
-		    rpc_caller_invoke(rpc_caller_instance, handle, opcode,
-				      &opstatus, &resp_buf, &resp_len));
-	POINTERS_EQUAL(NULL, resp_buf);
-	UNSIGNED_LONGS_EQUAL(0, resp_len);
-}
-
-TEST(ffarpc_caller, end_null_context)
-{
-	rpc_call_handle handle = &caller;
-
-	caller.rpc_caller.context = NULL;
-	rpc_caller_end(rpc_caller_instance, handle);
-}
-
-TEST(ffarpc_caller, end_null_handle)
-{
-	rpc_caller_end(rpc_caller_instance, NULL);
-}
-
-TEST(ffarpc_caller, end)
-{
-	rpc_call_handle handle = &caller;
-
-	caller.is_call_transaction_in_progess = true;
-	rpc_caller_end(rpc_caller_instance, handle);
-	CHECK_FALSE(caller.is_call_transaction_in_progess);
-}
diff --git a/components/rpc/ffarpc/endpoint/ffarpc_call_args.h b/components/rpc/ffarpc/endpoint/ffarpc_call_args.h
deleted file mode 100644
index 1d2d9c9..0000000
--- a/components/rpc/ffarpc/endpoint/ffarpc_call_args.h
+++ /dev/null
@@ -1,50 +0,0 @@
-/*
- * Copyright (c) 2020-2021, Arm Limited and Contributors. All rights reserved.
- *
- * SPDX-License-Identifier: BSD-3-Clause
- */
-
-#ifndef FFA_CALL_ARGS_H
-#define FFA_CALL_ARGS_H
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-/*
- * Defines convention for use of FFA direct call arguments by
- * the SP service framework. This header file is used by the
- * normal world RPC caller and the RPC listener in the SP.
- */
-
-/* Macros for parameters carried in a single register */
-#define FFA_CALL_ARGS_COMBINE_IFACE_ID_OPCODE(i, o) \
-    (((i) << 16) | ((o) & 0xffff))
-#define FFA_CALL_ARGS_EXTRACT_IFACE(reg) \
-    ((reg) >> 16)
-#define FFA_CALL_ARGS_EXTRACT_OPCODE(reg) \
-    ((reg) & 0xffff)
-
-/* Common req & resp arg offests into msg_args structure */
-#define FFA_CALL_ARGS_IFACE_ID_OPCODE	    (1)
-
-/* Req arg offsets */
-#define FFA_CALL_ARGS_REQ_DATA_LEN		    (2)
-#define FFA_CALL_ARGS_CALLER_ID		        (3)
-#define FFA_CALL_ARGS_ENCODING		        (4)
-
-/* Resp arg offsets */
-#define FFA_CALL_ARGS_RESP_DATA_LEN		    (2)
-#define FFA_CALL_ARGS_RESP_RPC_STATUS	    (3)
-#define FFA_CALL_ARGS_RESP_OP_STATUS		(4)
-
-/* Share/unshare offsets */
-#define FFA_CALL_ARGS_SHARE_MEM_HANDLE_LSW	(2)
-#define FFA_CALL_ARGS_SHARE_MEM_HANDLE_MSW	(3)
-#define FFA_CALL_ARGS_SHARE_MEM_SIZE		(4)
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* FFA_CALL_ARGS_H */
diff --git a/components/rpc/ffarpc/endpoint/ffarpc_call_ep.c b/components/rpc/ffarpc/endpoint/ffarpc_call_ep.c
deleted file mode 100644
index 01a85f6..0000000
--- a/components/rpc/ffarpc/endpoint/ffarpc_call_ep.c
+++ /dev/null
@@ -1,288 +0,0 @@
-/*
- * Copyright (c) 2020-2022, Arm Limited and Contributors. All rights reserved.
- *
- * SPDX-License-Identifier: BSD-3-Clause
- */
-
-#include "components/rpc/ffarpc/caller/sp/ffarpc_sp_call_args.h"
-#include "ffarpc_call_ep.h"
-#include "ffarpc_call_ops.h"
-#include <ffa_api.h>
-#include <sp_memory_management.h>
-#include <protocols/rpc/common/packed-c/status.h>
-#include <trace.h>
-#include <stddef.h>
-#include <string.h>
-
-static void set_resp_args(uint32_t *resp_args, uint32_t ifaceid_opcode, uint32_t data_len,
-			  rpc_status_t rpc_status, rpc_opstatus_t opstatus)
-{
-	resp_args[SP_CALL_ARGS_IFACE_ID_OPCODE] = ifaceid_opcode;
-	resp_args[SP_CALL_ARGS_RESP_DATA_LEN] = data_len;
-	resp_args[SP_CALL_ARGS_RESP_RPC_STATUS] = rpc_status;
-	resp_args[SP_CALL_ARGS_RESP_OP_STATUS] = (uint32_t)opstatus;
-}
-
-static void set_mgmt_resp_args(uint32_t *resp_args, uint32_t ifaceid_opcode,
-			       rpc_status_t rpc_status)
-{
-	/*
-	 * Sets arguments for responses that originate from the ffa_call_ep
-	 * rather than from a higher layer service. These responses are not
-	 * associated with a shared buffer for any additional message payload.
-	 */
-	set_resp_args(resp_args, ifaceid_opcode, 0, rpc_status, 0);
-}
-
-static int find_free_shm(struct ffa_call_ep *call_ep)
-{
-	int i = 0;
-
-	if (!call_ep)
-		return -1;
-
-	for (i = 0; i < NUM_MAX_SESS; i++)
-		if (!call_ep->shmem_buf[i]) {
-			DMSG("shm slot %u allocated for %p", i, call_ep);
-			return i;
-		}
-
-	EMSG("shm slot allocation failed");
-	return -1;
-}
-
-static int find_shm(struct ffa_call_ep *call_ep, uint16_t source_id)
-{
-	int i = 0;
-
-	if (!call_ep)
-		return -1;
-
-	for (i = 0; i < NUM_MAX_SESS; i++)
-		if (call_ep->src_id[i] == source_id)
-			return i;
-
-	EMSG("shm not found for source 0x%x", source_id);
-	return -1;
-}
-
-static void init_shmem_buf(struct ffa_call_ep *call_ep, uint16_t source_id,
-			   const uint32_t *req_args, uint32_t *resp_args)
-{
-	sp_result sp_res = SP_RESULT_INTERNAL_ERROR;
-	struct sp_memory_descriptor desc = { };
-	struct sp_memory_access_descriptor acc_desc = { };
-	struct sp_memory_region region = { };
-	uint32_t in_region_count = 0;
-	uint32_t out_region_count = 1;
-	uint64_t handle = 0;
-	rpc_status_t rpc_status = TS_RPC_ERROR_INTERNAL;
-	int idx = find_free_shm(call_ep);
-
-	if (idx < 0) {
-		EMSG("shm init error");
-		goto out;
-	}
-
-	desc.sender_id = source_id;
-	desc.memory_type = sp_memory_type_not_specified;
-	desc.flags.transaction_type = sp_memory_transaction_type_share;
-	acc_desc.receiver_id = call_ep->own_id;
-	acc_desc.data_access = sp_data_access_read_write;
-	handle = req_args[SP_CALL_ARGS_SHARE_MEM_HANDLE_MSW];
-	handle = (handle << 32) | req_args[SP_CALL_ARGS_SHARE_MEM_HANDLE_LSW];
-
-	sp_res = sp_memory_retrieve(&desc, &acc_desc, &region, in_region_count,
-				    &out_region_count, handle);
-
-	if (sp_res == SP_RESULT_OK) {
-		size_t shmem_size = (size_t)req_args[SP_CALL_ARGS_SHARE_MEM_SIZE];
-
-		if (shmem_size > region.page_count * FFA_MEM_TRANSACTION_PAGE_SIZE) {
-			/*
-			 * The shared memory's size is smaller than the size
-			 * value forwarded in the direct message argument.
-			 */
-			uint16_t endpoints[1] = { call_ep->own_id };
-			struct sp_memory_transaction_flags flags = {
-				.zero_memory = false,
-				.operation_time_slicing = false,
-			};
-
-			sp_res = sp_memory_relinquish(handle, endpoints, ARRAY_SIZE(endpoints),
-						      &flags);
-			if (sp_res)
-				EMSG("memory relinquish error: %d", sp_res);
-
-			rpc_status = TS_RPC_ERROR_INVALID_PARAMETER;
-			goto out;
-		}
-
-		call_ep->shmem_buf[idx] = region.address;
-		call_ep->shmem_buf_handle[idx] = handle;
-		call_ep->shmem_buf_size[idx] = shmem_size;
-		call_ep->src_id[idx] = source_id;
-		rpc_status = TS_RPC_CALL_ACCEPTED;
-	} else {
-		EMSG("memory retrieve error: %d", sp_res);
-	}
-
-out:
-	set_mgmt_resp_args(resp_args, req_args[SP_CALL_ARGS_IFACE_ID_OPCODE], rpc_status);
-}
-
-static void deinit_shmem_buf(struct ffa_call_ep *call_ep, uint16_t source_id,
-			     const uint32_t *req_args, uint32_t *resp_args)
-{
-	sp_result sp_res = SP_RESULT_INTERNAL_ERROR;
-	rpc_status_t rpc_status = TS_RPC_ERROR_INTERNAL;
-	uint64_t handle = 0;
-	uint16_t endpoints[1] = { 0 };
-	uint32_t endpoint_cnt = 1;
-	struct sp_memory_transaction_flags flags = {
-		.zero_memory = false,
-		.operation_time_slicing = false,
-	};
-	int idx = find_shm(call_ep, source_id);
-
-	if (idx < 0) {
-		EMSG("shm deinit error");
-		goto out;
-	}
-
-	endpoints[0] = call_ep->own_id;
-
-	handle = call_ep->shmem_buf_handle[idx];
-
-	sp_res = sp_memory_relinquish(handle, endpoints, endpoint_cnt, &flags);
-	if (sp_res == SP_RESULT_OK) {
-		call_ep->shmem_buf[idx] = NULL;
-		call_ep->shmem_buf_handle[idx] = 0;
-		call_ep->shmem_buf_size[idx] = 0;
-		call_ep->src_id[idx] = 0xffff;
-		rpc_status = TS_RPC_CALL_ACCEPTED;
-	} else {
-		EMSG("memory relinquish error: %d", sp_res);
-	}
-
-out:
-	set_mgmt_resp_args(resp_args, req_args[SP_CALL_ARGS_IFACE_ID_OPCODE], rpc_status);
-}
-
-static void handle_service_msg(struct ffa_call_ep *call_ep, uint16_t source_id,
-			       const uint32_t *req_args, uint32_t *resp_args)
-{
-	rpc_status_t rpc_status = TS_RPC_ERROR_INVALID_PARAMETER;
-	struct call_req call_req = { 0 };
-
-	uint32_t ifaceid_opcode = req_args[SP_CALL_ARGS_IFACE_ID_OPCODE];
-	int idx = find_shm(call_ep, source_id);
-
-	call_req.caller_id = source_id;
-	call_req.interface_id = FFA_CALL_ARGS_EXTRACT_IFACE(ifaceid_opcode);
-	call_req.opcode = FFA_CALL_ARGS_EXTRACT_OPCODE(ifaceid_opcode);
-	call_req.encoding = req_args[SP_CALL_ARGS_ENCODING];
-
-	call_req.req_buf.data_len = req_args[SP_CALL_ARGS_REQ_DATA_LEN];
-	call_req.resp_buf.data_len = 0;
-
-	if (idx >= 0 && call_ep->shmem_buf[idx]) {
-		/* A shared buffer is available for call parameters */
-		if (call_req.req_buf.data_len > call_ep->shmem_buf_size[idx])
-			goto out;
-
-		call_req.req_buf.data = call_ep->shmem_buf[idx];
-		call_req.req_buf.size = call_ep->shmem_buf_size[idx];
-
-		call_req.resp_buf.data = call_ep->shmem_buf[idx];
-		call_req.resp_buf.size = call_ep->shmem_buf_size[idx];
-	}
-	else if (call_req.req_buf.data_len == 0) {
-		/* No shared buffer so only allow calls with no request data */
-		call_req.req_buf.data = NULL;
-		call_req.req_buf.size = 0;
-
-		call_req.resp_buf.data = NULL;
-		call_req.resp_buf.size = 0;
-	}
-	else {
-		/*
-		 * Caller has specified non-zero length request data but there is
-		 * no shared buffer to carry the request data.
-		 */
-		goto out;
-	}
-
-	rpc_status = rpc_interface_receive(call_ep->iface, &call_req);
-
-out:
-	set_resp_args(resp_args,
-		      ifaceid_opcode,
-		      call_req.resp_buf.data_len,
-		      rpc_status,
-		      call_req.opstatus);
-}
-
-static void handle_mgmt_msg(struct ffa_call_ep *call_ep, uint16_t source_id,
-			    const uint32_t *req_args, uint32_t *resp_args)
-{
-	uint32_t ifaceid_opcode = req_args[SP_CALL_ARGS_IFACE_ID_OPCODE];
-	uint32_t opcode = FFA_CALL_ARGS_EXTRACT_OPCODE(ifaceid_opcode);
-
-	switch (opcode) {
-	case FFA_CALL_OPCODE_SHARE_BUF:
-		init_shmem_buf(call_ep, source_id, req_args, resp_args);
-		break;
-	case FFA_CALL_OPCODE_UNSHARE_BUF:
-		deinit_shmem_buf(call_ep, source_id, req_args, resp_args);
-		break;
-	default:
-		set_mgmt_resp_args(resp_args, ifaceid_opcode, TS_RPC_ERROR_INVALID_OPCODE);
-		break;
-	}
-}
-
-void ffa_call_ep_init(struct ffa_call_ep *ffa_call_ep,
-		      struct rpc_interface *iface, uint16_t own_id)
-{
-	int i = 0;
-
-	ffa_call_ep->iface = iface;
-	ffa_call_ep->own_id = own_id;
-
-	for (i = 0; i < NUM_MAX_SESS; i++) {
-		ffa_call_ep->shmem_buf_handle[i] = 0;
-		ffa_call_ep->shmem_buf_size[i] = 0;
-		ffa_call_ep->shmem_buf[i] = NULL;
-		ffa_call_ep->src_id[i] = 0xffff;
-	}
-}
-
-void ffa_call_ep_receive(struct ffa_call_ep *call_ep,
-			 const struct sp_msg *req_msg,
-			 struct sp_msg *resp_msg)
-{
-	resp_msg->source_id = req_msg->destination_id;
-	resp_msg->destination_id = req_msg->source_id;
-	resp_msg->is_64bit_message = req_msg->is_64bit_message;
-	memset(&resp_msg->args, 0x00, sizeof(resp_msg->args));
-
-	if (!req_msg->is_64bit_message) {
-		const uint32_t *req_args = req_msg->args.args32;
-		uint32_t *resp_args = resp_msg->args.args32;
-		uint16_t source_id = req_msg->source_id;
-		uint32_t ifaceid_opcode = req_args[SP_CALL_ARGS_IFACE_ID_OPCODE];
-
-		if (FFA_CALL_ARGS_EXTRACT_IFACE(ifaceid_opcode) == FFA_CALL_MGMT_IFACE_ID) {
-			/* It's an RPC layer management request */
-			handle_mgmt_msg(call_ep, source_id, req_args, resp_args);
-		} else {
-			/* Assume anything else is a service request */
-			handle_service_msg(call_ep, source_id, req_args, resp_args);
-		}
-	} else {
-		EMSG("64 bit FF-A messages are not supported by the TS RPC layer");
-		resp_msg->args.args64[SP_CALL_ARGS_RESP_RPC_STATUS] =
-			TS_RPC_ERROR_INVALID_PARAMETER;
-	}
-}
diff --git a/components/rpc/ffarpc/endpoint/ffarpc_call_ep.h b/components/rpc/ffarpc/endpoint/ffarpc_call_ep.h
deleted file mode 100644
index 1ac1928..0000000
--- a/components/rpc/ffarpc/endpoint/ffarpc_call_ep.h
+++ /dev/null
@@ -1,43 +0,0 @@
-/*
- * Copyright (c) 2020-2022, Arm Limited and Contributors. All rights reserved.
- *
- * SPDX-License-Identifier: BSD-3-Clause
- */
-
-#ifndef FFA_CALL_EP_H
-#define FFA_CALL_EP_H
-
-#include <ffa_api.h>
-#include "sp_messaging.h"
-#include <components/rpc/common/endpoint/rpc_interface.h>
-#include <stddef.h>
-#include <stdint.h>
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-#ifndef NUM_MAX_SESS
-#define NUM_MAX_SESS (16)
-#endif
-
-struct ffa_call_ep {
-	struct rpc_interface *iface;
-	uint16_t own_id;
-	unsigned long shmem_buf_handle[NUM_MAX_SESS];
-	uint8_t *shmem_buf[NUM_MAX_SESS];
-	size_t shmem_buf_size[NUM_MAX_SESS];
-	uint16_t src_id[NUM_MAX_SESS];
- };
-
-void ffa_call_ep_init(struct ffa_call_ep *ffa_call_ep,
-		      struct rpc_interface *iface, uint16_t own_id);
-void ffa_call_ep_receive(struct ffa_call_ep *call_ep,
-			 const struct sp_msg *req_msg,
-			 struct sp_msg *resp_msg);
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* FFA_CALL_EP_H */
diff --git a/components/rpc/ffarpc/endpoint/ffarpc_call_ops.h b/components/rpc/ffarpc/endpoint/ffarpc_call_ops.h
deleted file mode 100644
index de22678..0000000
--- a/components/rpc/ffarpc/endpoint/ffarpc_call_ops.h
+++ /dev/null
@@ -1,29 +0,0 @@
-/*
- * Copyright (c) 2020-2021, Arm Limited and Contributors. All rights reserved.
- *
- * SPDX-License-Identifier: BSD-3-Clause
- */
-
-#ifndef FFA_CALL_OPS_H
-#define FFA_CALL_OPS_H
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-/* Common opcodes used by the FFA based RPC layer for management operations */
-enum
-{
-	FFA_CALL_OPCODE_SHARE_BUF		= 0,
-	FFA_CALL_OPCODE_UNSHARE_BUF		= 1,
-	FFA_CALL_OPCODE_LIMIT
-};
-
-/* Interface ID for FFA management interface */
-#define FFA_CALL_MGMT_IFACE_ID		(0x1000)
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* FFA_CALL_OPS_H */
diff --git a/components/rpc/ffarpc/endpoint/test/component.cmake b/components/rpc/ffarpc/endpoint/test/component.cmake
deleted file mode 100644
index 7f7da2c..0000000
--- a/components/rpc/ffarpc/endpoint/test/component.cmake
+++ /dev/null
@@ -1,13 +0,0 @@
-#-------------------------------------------------------------------------------
-# Copyright (c) 2022, Arm Limited and Contributors. All rights reserved.
-#
-# SPDX-License-Identifier: BSD-3-Clause
-#
-#-------------------------------------------------------------------------------
-if (NOT DEFINED TGT)
-	message(FATAL_ERROR "mandatory parameter TGT is not defined.")
-endif()
-
-target_sources(${TGT} PRIVATE
-	"${CMAKE_CURRENT_LIST_DIR}/test_ffarpc_call_ep.cpp"
-)
diff --git a/components/rpc/ffarpc/endpoint/test/test_ffarpc_call_ep.cpp b/components/rpc/ffarpc/endpoint/test/test_ffarpc_call_ep.cpp
deleted file mode 100644
index 506839a..0000000
--- a/components/rpc/ffarpc/endpoint/test/test_ffarpc_call_ep.cpp
+++ /dev/null
@@ -1,438 +0,0 @@
-/*
- * Copyright (c) 2022, Arm Limited and Contributors. All rights reserved.
- *
- * SPDX-License-Identifier: BSD-3-Clause
- */
-
-#include <CppUTest/TestHarness.h>
-#include <CppUTestExt/MockSupport.h>
-#include "../ffarpc_call_ep.h"
-#include "mock_sp_memory_management.h"
-#include "mock_rpc_interface.h"
-#include "call_param_buf_comparator.h"
-#include <string.h>
-
-TEST_GROUP(ffarpc_call_ep) {
-	TEST_SETUP()
-	{
-		rpc_iface.receive = mock_rpc_interface_receive;
-		ffa_call_ep_init(&ep, &rpc_iface, dst);
-
-		mock().installComparator("call_req", call_req_buf_comparator);
-
-		memset(&req, 0x00, sizeof(req));
-		memset(&resp, 0x00, sizeof(resp));
-		memset(&mem_desc, 0x00, sizeof(mem_desc));
-		memset(&mem_acc_desc, 0x00, sizeof(mem_acc_desc));
-		memset(&mem_region, 0x00, sizeof(mem_region));
-		out_region_count = 0;
-	}
-
-	TEST_TEARDOWN()
-	{
-		mock().checkExpectations();
-		mock().removeAllComparatorsAndCopiers();
-		mock().clear();
-	}
-
-	void do_mem_share(uint16_t source_id, uint16_t dest_id, uint64_t handle,
-			  uint32_t size)
-	{
-		req.source_id = source_id;
-		req.destination_id = dest_id;
-		req.args.args32[0] = (0x1000 << 16) | 0x0; // FFA_CALL_OPCODE_SHARE_BUF
-		req.args.args32[1] = handle & 0xffffffff;
-		req.args.args32[2] = (handle >> 32) & 0xffffffff;
-		req.args.args32[3] = size;
-
-		memset(&resp, 0x00, sizeof(resp));
-
-		ffa_call_ep_receive(&ep, &req, &resp);
-	}
-
-	void check_mem_share_response(uint16_t source_id, uint16_t dest_id,
-				      rpc_status_t rpc_status)
-	{
-		check_response(source_id, dest_id, 0x1000, 0x0, 0, rpc_status, 0);
-	}
-
-	void do_mem_unshare(uint16_t source_id, uint16_t dest_id)
-	{
-		req.source_id = source_id;
-		req.destination_id = dest_id;
-		req.args.args32[0] = (0x1000 << 16) | 0x1; // FFA_CALL_OPCODE_UNSHARE_BUF
-		req.args.args32[1] = 0;
-		req.args.args32[2] = 0;
-		req.args.args32[3] = 0;
-
-		memset(&resp, 0x00, sizeof(resp));
-
-		ffa_call_ep_receive(&ep, &req, &resp);
-	}
-
-	void check_mem_unshare_response(uint16_t source_id, uint16_t dest_id,
-					rpc_status_t rpc_status)
-	{
-		check_response(source_id, dest_id, 0x1000, 0x1, 0, rpc_status, 0);
-	}
-
-	void do_request(uint16_t source_id, uint16_t dest_id, uint16_t iface_id,
-			uint16_t opcode, uint32_t req_len, uint32_t encoding)
-	{
-		req.source_id = source_id;
-		req.destination_id = dest_id;
-		req.args.args32[0] = (iface_id << 16) | opcode;
-		req.args.args32[1] = req_len;
-		req.args.args32[2] = 0; // Caller id
-		req.args.args32[3] = encoding;
-
-		memset(&resp, 0x00, sizeof(resp));
-
-		ffa_call_ep_receive(&ep, &req, &resp);
-	}
-
-	void check_response(uint16_t source_id, uint16_t dest_id, uint16_t iface_id,
-			    uint16_t opcode, uint32_t data_len,
-			    rpc_status_t rpc_status, rpc_opstatus_t opstatus)
-	{
-		UNSIGNED_LONGLONGS_EQUAL(source_id, resp.source_id);
-		UNSIGNED_LONGLONGS_EQUAL(dest_id, resp.destination_id);
-		UNSIGNED_LONGS_EQUAL(iface_id, (resp.args.args32[0] >> 16) & 0xffff);
-		UNSIGNED_LONGS_EQUAL(opcode, resp.args.args32[0] & 0xffff);
-		UNSIGNED_LONGS_EQUAL(data_len, (uint32_t)resp.args.args32[1]);
-		LONGS_EQUAL(rpc_status, (rpc_status_t)resp.args.args32[2]);
-		LONGS_EQUAL(opstatus, (rpc_opstatus_t)resp.args.args32[3]);
-	}
-
-	void expect_retrieve(uint16_t source_id, uint16_t dest_id, uint64_t handle,
-			     void *address, size_t page_count, sp_result result)
-	{
-
-		mem_desc.sender_id = source_id;
-		mem_desc.memory_type = sp_memory_type_not_specified;
-		mem_desc.flags.transaction_type = sp_memory_transaction_type_share;
-		mem_acc_desc.receiver_id = dest_id;
-		mem_acc_desc.instruction_access = sp_instruction_access_not_specified;
-		mem_acc_desc.data_access = sp_data_access_read_write;
-		mem_region.address = address;
-		mem_region.page_count = page_count;
-
-		out_region_count = 1;
-
-		expect_sp_memory_retrieve(&mem_desc, &mem_acc_desc, &mem_acc_desc,
-					  NULL, &mem_region, 0, &out_region_count, handle, result);
-	}
-
-	struct rpc_interface rpc_iface;
-	struct ffa_call_ep ep;
-	struct sp_msg req;
-	struct sp_msg resp;
-	struct sp_memory_descriptor mem_desc;
-	struct sp_memory_access_descriptor mem_acc_desc;
-	struct sp_memory_region mem_region;
-	uint32_t out_region_count;
-
-	static const uint16_t src = 0x1234;
-	static const uint16_t dst = 0x5678;
-	static const uint64_t handle = 0xabcdef0123456789ULL;
-
-	call_param_buf_comparator call_req_buf_comparator;
-};
-
-TEST(ffarpc_call_ep, mem_share)
-{
-	expect_retrieve(src, dst, handle, (void *)0x123456789, 1, SP_RESULT_OK);
-	do_mem_share(src, dst, handle, 4096);
-	check_mem_share_response(dst, src, TS_RPC_CALL_ACCEPTED);
-}
-
-TEST(ffarpc_call_ep, mem_share_fill_all)
-{
-	for (uint16_t i = 0; i < NUM_MAX_SESS; i++) {
-		expect_retrieve(src + i, dst, handle, (void *)0x123456789, 1, SP_RESULT_OK);
-		do_mem_share(src + i, dst, handle, 4096);
-		check_mem_share_response(dst, src + i, TS_RPC_CALL_ACCEPTED);
-	}
-
-	do_mem_share(src + NUM_MAX_SESS, dst, handle, 4096);
-	check_mem_share_response(dst, src + NUM_MAX_SESS, TS_RPC_ERROR_INTERNAL);
-}
-
-TEST(ffarpc_call_ep, mem_share_retrieve_fail)
-{
-	expect_retrieve(src, dst, handle, (void *)0x123456789, 1, SP_RESULT_INVALID_PARAMETERS);
-	do_mem_share(src, dst, handle, 4096);
-	check_mem_share_response(dst, src, TS_RPC_ERROR_INTERNAL);
-}
-
-TEST(ffarpc_call_ep, mem_share_smaller_page_count)
-{
-	const uint16_t endpoints[1] = { dst };
-	const struct sp_memory_transaction_flags flags = {
-		.zero_memory = false,
-		.operation_time_slicing = false,
-	};
-	expect_retrieve(src, dst, handle, (void *)0x123456789, 1, SP_RESULT_OK);
-	expect_sp_memory_relinquish(handle, endpoints, 1, &flags, SP_RESULT_OK);
-	do_mem_share(src, dst, handle, 4096 * 2);
-	check_mem_share_response(dst, src, TS_RPC_ERROR_INVALID_PARAMETER);
-}
-
-TEST(ffarpc_call_ep, mem_share_smaller_page_count_relinquish_fail)
-{
-	const uint16_t endpoints[1] = { dst };
-	const struct sp_memory_transaction_flags flags = {
-		.zero_memory = false,
-		.operation_time_slicing = false,
-	};
-	expect_retrieve(src, dst, handle, (void *)0x123456789, 1, SP_RESULT_OK);
-	expect_sp_memory_relinquish(handle, endpoints, 1, &flags, SP_RESULT_INVALID_PARAMETERS);
-	do_mem_share(src, dst, handle, 4096 * 2);
-	check_mem_share_response(dst, src, TS_RPC_ERROR_INVALID_PARAMETER);
-}
-
-TEST(ffarpc_call_ep, mem_share_null_ep)
-{
-	req.source_id = src;
-	req.destination_id = dst;
-	req.args.args32[0] = (0x1000 << 16) | 0;
-
-	ffa_call_ep_receive(NULL, &req, &resp);
-}
-
-TEST(ffarpc_call_ep, mem_unshare)
-{
-	do_mem_unshare(src, dst);
-	check_mem_unshare_response(dst, src, TS_RPC_ERROR_INTERNAL);
-}
-
-TEST(ffarpc_call_ep, mem_share_unshare)
-{
-	const uint16_t endpoints[1] = { dst };
-	const struct sp_memory_transaction_flags flags = {
-		.zero_memory = false,
-		.operation_time_slicing = false,
-	};
-
-	expect_retrieve(src, dst, handle, (void *)0x123456789, 1, SP_RESULT_OK);
-	do_mem_share(src, dst, handle, 4096);
-	check_mem_share_response(dst, src, TS_RPC_CALL_ACCEPTED);
-
-	expect_sp_memory_relinquish(handle, endpoints, 1, &flags, SP_RESULT_OK);
-	do_mem_unshare(src, dst);
-	check_mem_unshare_response(dst, src, TS_RPC_CALL_ACCEPTED);
-}
-
-TEST(ffarpc_call_ep, mem_share_unshare_relinquish_fail)
-{
-	const uint16_t endpoints[1] = { dst };
-	const struct sp_memory_transaction_flags flags = {
-		.zero_memory = false,
-		.operation_time_slicing = false,
-	};
-
-	expect_retrieve(src, dst, handle, (void *)0x123456789, 1, SP_RESULT_OK);
-	do_mem_share(src, dst, handle, 4096);
-	check_mem_share_response(dst, src, TS_RPC_CALL_ACCEPTED);
-
-	expect_sp_memory_relinquish(handle, endpoints, 1, &flags, SP_RESULT_INVALID_PARAMETERS);
-	do_mem_unshare(src, dst);
-	check_mem_unshare_response(dst, src, TS_RPC_ERROR_INTERNAL);
-}
-
-TEST(ffarpc_call_ep, mem_share_unshare_relinquish_fail_then_success)
-{
-	const uint16_t endpoints[1] = { dst };
-	const struct sp_memory_transaction_flags flags = {
-		.zero_memory = false,
-		.operation_time_slicing = false,
-	};
-
-	expect_retrieve(src, dst, handle, (void *)0x123456789, 1, SP_RESULT_OK);
-	do_mem_share(src, dst, handle, 4096);
-	check_mem_share_response(dst, src, TS_RPC_CALL_ACCEPTED);
-
-	expect_sp_memory_relinquish(handle, endpoints, 1, &flags, SP_RESULT_INVALID_PARAMETERS);
-	do_mem_unshare(src, dst);
-	check_mem_unshare_response(dst, src, TS_RPC_ERROR_INTERNAL);
-
-	expect_sp_memory_relinquish(handle, endpoints, 1, &flags, SP_RESULT_OK);
-	do_mem_unshare(src, dst);
-	check_mem_unshare_response(dst, src, TS_RPC_CALL_ACCEPTED);
-}
-
-TEST(ffarpc_call_ep, mem_unshare_null_ep)
-{
-	req.source_id = src;
-	req.destination_id = dst;
-	req.args.args32[0] = (0x1000 << 16) | 1;
-
-	ffa_call_ep_receive(NULL, &req, &resp);
-}
-
-TEST(ffarpc_call_ep, invalid_mgmt_call)
-{
-	do_request(src, dst, 0x1000, 0xffff, 0, 0);
-	check_response(dst, src, 0x1000, 0xffff, 0, TS_RPC_ERROR_INVALID_OPCODE, 0);
-}
-
-TEST(ffarpc_call_ep, request_without_data)
-{
-	const struct call_req rpc_req = {
-		.caller_id = src,
-		.interface_id = 0xfedc,
-		.opcode = 0xbaab,
-		.encoding = 0x12345678,
-		.opstatus = 0,
-		.req_buf = {
-			.size = 0,
-			.data_len = 0,
-			.data = NULL,
-		},
-		.resp_buf = {
-			.size = 0,
-			.data_len = 0,
-			.data = NULL,
-		}
-	};
-
-	expect_mock_rpc_interface_receive(&rpc_iface, &rpc_req, TS_RPC_CALL_ACCEPTED);
-	do_request(src, dst, rpc_req.interface_id, rpc_req.opcode, 0, rpc_req.encoding);
-	check_response(dst, src, rpc_req.interface_id, rpc_req.opcode, 0, TS_RPC_CALL_ACCEPTED, 0);
-}
-
-TEST(ffarpc_call_ep, request_without_data_non_zero_length)
-{
-	const struct call_req rpc_req = {
-		.caller_id = src,
-		.interface_id = 0xfedc,
-		.opcode = 0xbaab,
-		.encoding = 0x12345678,
-		.opstatus = 0,
-		.req_buf = {
-			.size = 0,
-			.data_len = 0,
-			.data = NULL,
-		},
-		.resp_buf = {
-			.size = 0,
-			.data_len = 0,
-			.data = NULL,
-		}
-	};
-
-	do_request(src, dst, rpc_req.interface_id, rpc_req.opcode, 1, rpc_req.encoding);
-	check_response(dst, src, rpc_req.interface_id, rpc_req.opcode, 0, TS_RPC_ERROR_INVALID_PARAMETER, 0);
-}
-
-TEST(ffarpc_call_ep, request_with_data)
-{
-	const struct call_req rpc_req = {
-		.caller_id = src,
-		.interface_id = 0xfedc,
-		.opcode = 0xbaab,
-		.encoding = 0x12345678,
-		.opstatus = 0,
-		.req_buf = {
-			.size = 4096,
-			.data_len = 100,
-			.data = (void *)0x123456789,
-		},
-		.resp_buf = {
-			.size = 4096,
-			.data_len = 0,
-			.data = (void *)0x123456789,
-		}
-	};
-
-	expect_retrieve(src, dst, handle, rpc_req.req_buf.data, 1, SP_RESULT_OK);
-	do_mem_share(src, dst, handle, 4096);
-	check_mem_share_response(dst, src, TS_RPC_CALL_ACCEPTED);
-
-	expect_mock_rpc_interface_receive(&rpc_iface, &rpc_req, TS_RPC_CALL_ACCEPTED);
-	do_request(src, dst, rpc_req.interface_id, rpc_req.opcode, 100, rpc_req.encoding);
-	check_response(dst, src, rpc_req.interface_id, rpc_req.opcode, 0, TS_RPC_CALL_ACCEPTED, 0);
-}
-
-TEST(ffarpc_call_ep, request_with_data_buffer_overflow)
-{
-	const struct call_req rpc_req = {
-		.caller_id = src,
-		.interface_id = 0xfedc,
-		.opcode = 0xbaab,
-		.encoding = 0x12345678,
-		.opstatus = 0,
-		.req_buf = {
-			.size = 4096,
-			.data_len = 100,
-			.data = (void *)0x123456789,
-		},
-		.resp_buf = {
-			.size = 4096,
-			.data_len = 0,
-			.data = (void *)0x123456789,
-		}
-	};
-
-	expect_retrieve(src, dst, handle, rpc_req.req_buf.data, 1, SP_RESULT_OK);
-	do_mem_share(src, dst, handle, 4096);
-	check_mem_share_response(dst, src, TS_RPC_CALL_ACCEPTED);
-
-	do_request(src, dst, rpc_req.interface_id, rpc_req.opcode, 4097, rpc_req.encoding);
-	check_response(dst, src, rpc_req.interface_id, rpc_req.opcode, 0, TS_RPC_ERROR_INVALID_PARAMETER, 0);
-}
-
-TEST(ffarpc_call_ep, request_with_data_after_unshare)
-{
-	const uint16_t endpoints[1] = { dst };
-	const struct sp_memory_transaction_flags flags = {
-		.zero_memory = false,
-		.operation_time_slicing = false,
-	};
-	const struct call_req rpc_req = {
-		.caller_id = src,
-		.interface_id = 0xfedc,
-		.opcode = 0xbaab,
-		.encoding = 0x12345678,
-		.opstatus = 0,
-		.req_buf = {
-			.size = 4096,
-			.data_len = 100,
-			.data = (void *)0x123456789,
-		},
-		.resp_buf = {
-			.size = 4096,
-			.data_len = 0,
-			.data = (void *)0x123456789,
-		}
-	};
-
-	expect_retrieve(src, dst, handle, rpc_req.req_buf.data, 1, SP_RESULT_OK);
-	do_mem_share(src, dst, handle, 4096);
-	check_mem_share_response(dst, src, TS_RPC_CALL_ACCEPTED);
-
-	expect_sp_memory_relinquish(handle, endpoints, 1, &flags, SP_RESULT_OK);
-	do_mem_unshare(src, dst);
-	check_mem_unshare_response(dst, src, TS_RPC_CALL_ACCEPTED);
-
-	do_request(src, dst, rpc_req.interface_id, rpc_req.opcode, 100, rpc_req.encoding);
-	check_response(dst, src, rpc_req.interface_id, rpc_req.opcode, 0, TS_RPC_ERROR_INVALID_PARAMETER, 0);
-}
-
-TEST(ffarpc_call_ep, request_deny_64_bit)
-{
-	req.source_id = src;
-	req.destination_id = dst;
-	req.is_64bit_message = true;
-
-	memset(&resp, 0x5a, sizeof(resp));
-
-	ffa_call_ep_receive(&ep, &req, &resp);
-
-	UNSIGNED_LONGS_EQUAL(dst, resp.source_id);
-	UNSIGNED_LONGS_EQUAL(src, resp.destination_id);
-	UNSIGNED_LONGS_EQUAL(0, resp.args.args64[0]);
-	UNSIGNED_LONGLONGS_EQUAL(0, resp.args.args64[1]);
-	LONGLONGS_EQUAL(TS_RPC_ERROR_INVALID_PARAMETER, resp.args.args64[2]);
-	UNSIGNED_LONGLONGS_EQUAL(0, resp.args.args64[3]);
-}
diff --git a/components/rpc/mm_communicate/caller/linux/mm_communicate_caller.c b/components/rpc/mm_communicate/caller/linux/mm_communicate_caller.c
index 0287acf..6761616 100644
--- a/components/rpc/mm_communicate/caller/linux/mm_communicate_caller.c
+++ b/components/rpc/mm_communicate/caller/linux/mm_communicate_caller.c
@@ -6,6 +6,7 @@
 
 #include "mm_communicate_caller.h"
 #include "carveout.h"
+#include "util.h"
 #include <arm_ffa_user.h>
 #include <components/rpc/mm_communicate/common/mm_communicate_call_args.h>
 #include <protocols/rpc/common/packed-c/status.h>
@@ -23,31 +24,297 @@
 #define KERNEL_MOD_REQ_VER_MINOR 0
 #define KERNEL_MOD_REQ_VER_PATCH 0
 
-static rpc_call_handle call_begin(
-	void *context,
-	uint8_t **req_buf,
-	size_t req_len);
+struct mm_communicate_caller_context {
+	int ffa_fd;
+	const char *ffa_device_path;
+	uint16_t dest_partition_id;
+	uint8_t *comm_buffer;
+	size_t comm_buffer_size;
+	size_t req_len;
+	const struct mm_communicate_serializer *serializer;
+};
 
-static rpc_status_t call_invoke(
-	void *context,
-	rpc_call_handle handle,
-	uint32_t opcode,
-	rpc_opstatus_t *opstatus,
-	uint8_t **resp_buf,
-	size_t *resp_len);
+static const char mm_uuid[] = "ed32d533-99e6-4209-9cc0-2d72cdd998a7";
 
-static void call_end(
-	void *context,
-	rpc_call_handle handle);
+static rpc_status_t release_shared_memory(void *context,
+					  struct rpc_caller_shared_memory *shared_memory);
 
-static rpc_status_t mm_return_code_to_rpc_status(
-	int32_t return_code);
-
-bool mm_communicate_caller_check_version(void)
+static void rpc_uuid_to_efi_guid(const struct rpc_uuid *uuid, EFI_GUID *guid)
 {
-	FILE *f;
-	char mod_name[64];
-	int ver_major, ver_minor, ver_patch;
+	guid->Data1 = uuid->uuid[0] << 24 | uuid->uuid[1] << 16 | uuid->uuid[2] << 8 |
+		      uuid->uuid[3];
+	guid->Data2 = uuid->uuid[4] << 8 | uuid->uuid[5];
+	guid->Data3 = uuid->uuid[6] << 8 | uuid->uuid[7];
+	memcpy(guid->Data4, &uuid->uuid[8], sizeof(guid->Data4));
+}
+
+static rpc_status_t mm_return_code_to_rpc_status(int32_t return_code)
+{
+	rpc_status_t rpc_status = RPC_ERROR_INTERNAL;
+
+	switch (return_code) {
+	case MM_RETURN_CODE_NOT_SUPPORTED:
+		rpc_status = RPC_ERROR_NOT_FOUND;
+		break;
+	case MM_RETURN_CODE_INVALID_PARAMETER:
+		rpc_status = RPC_ERROR_INVALID_VALUE;
+		break;
+	case MM_RETURN_CODE_DENIED:
+		rpc_status = RPC_ERROR_INVALID_STATE;
+		break;
+	case MM_RETURN_CODE_NO_MEMORY:
+		rpc_status = RPC_ERROR_INTERNAL;
+		break;
+	default:
+		break;
+	}
+
+	return rpc_status;
+}
+
+static rpc_status_t open_session(void *context, const struct rpc_uuid *service_uuid,
+				 uint16_t endpoint_id)
+{
+	struct mm_communicate_caller_context *mm_context =
+		(struct mm_communicate_caller_context *)context;
+	EFI_GUID svc_guid = { 0 };
+
+	if (!context || !service_uuid)
+		return RPC_ERROR_INVALID_VALUE;
+
+	if (mm_context->ffa_fd >= 0)
+		return RPC_ERROR_INVALID_STATE;
+
+	rpc_uuid_to_efi_guid(service_uuid, &svc_guid);
+
+	mm_context->serializer = mm_communicate_serializer_find(&svc_guid);
+	if (!mm_context->serializer)
+		return RPC_ERROR_INTERNAL;
+
+	if (!mm_context->ffa_device_path) {
+		mm_context->serializer = NULL;
+		return RPC_ERROR_INTERNAL;
+	}
+
+	mm_context->ffa_fd = open(mm_context->ffa_device_path, O_RDWR);
+	if (mm_context->ffa_fd < 0) {
+		mm_context->serializer = NULL;
+		return RPC_ERROR_INTERNAL;
+	}
+
+	mm_context->dest_partition_id = endpoint_id;
+
+	return RPC_SUCCESS;
+}
+
+static rpc_status_t find_and_open_session(void *context, const struct rpc_uuid *service_uuid)
+{
+	struct mm_communicate_caller_context *mm_context =
+		(struct mm_communicate_caller_context *)context;
+	int fd = 0;
+	int status = 0;
+	struct ffa_ioctl_ep_desc discovered_partition = { 0 };
+
+	if (!context || !service_uuid)
+		return RPC_ERROR_INVALID_VALUE;
+
+	if (mm_context->ffa_fd >= 0)
+		return RPC_ERROR_INVALID_STATE;
+
+	if (!mm_context->ffa_device_path)
+		return RPC_ERROR_INTERNAL;
+
+	fd = open(mm_context->ffa_device_path, O_RDWR);
+	if (fd < 0)
+		return RPC_ERROR_INTERNAL;
+
+	discovered_partition.uuid_ptr = (uintptr_t)&mm_uuid;
+	discovered_partition.id = 0;
+
+	status = ioctl(fd, FFA_IOC_GET_PART_ID, &discovered_partition);
+	if (status < 0) {
+		close(fd);
+		return RPC_ERROR_INTERNAL;
+	}
+
+	status = close(fd);
+	if (status < 0)
+		return RPC_ERROR_INTERNAL;
+
+	return open_session(context, service_uuid, discovered_partition.id);
+}
+
+static rpc_status_t close_session(void *context)
+{
+	struct mm_communicate_caller_context *mm_context =
+		(struct mm_communicate_caller_context *)context;
+	int status = -1;
+
+	if (!context)
+		return RPC_ERROR_INVALID_VALUE;
+
+	if (mm_context->ffa_fd < 0)
+		return RPC_ERROR_INVALID_STATE;
+
+	if (mm_context->comm_buffer) {
+		struct rpc_caller_shared_memory memory = { 0 };
+		rpc_status_t rpc_status = RPC_ERROR_INTERNAL;
+
+		memory.id = 0;
+		memory.buffer = mm_context->comm_buffer;
+		memory.size = mm_context->comm_buffer_size;
+
+		rpc_status = release_shared_memory(context, &memory);
+		if (rpc_status != RPC_SUCCESS)
+			return rpc_status;
+	}
+
+	status = close(mm_context->ffa_fd);
+	if (status < 0)
+		return RPC_ERROR_INTERNAL;
+
+	mm_context->ffa_fd = -1;
+	mm_context->dest_partition_id = 0;
+	mm_context->serializer = NULL;
+
+	return RPC_SUCCESS;
+}
+
+static bool is_valid_shared_memory(const struct mm_communicate_caller_context *mm_context,
+				   const struct rpc_caller_shared_memory *shared_memory)
+{
+	uintptr_t comm_buffer_end = 0;
+	uintptr_t shared_memory_end = 0;
+
+	if (ADD_OVERFLOW((uintptr_t)mm_context->comm_buffer,
+			 (uintptr_t)mm_context->comm_buffer_size, &comm_buffer_end))
+		return false;
+
+	if (ADD_OVERFLOW((uintptr_t)shared_memory->buffer, (uintptr_t)shared_memory->size,
+			 &shared_memory_end))
+		return false;
+
+	return (uintptr_t)mm_context->comm_buffer <= (uintptr_t)shared_memory->buffer &&
+	       shared_memory_end <= comm_buffer_end;
+}
+
+static rpc_status_t create_shared_memory(void *context, size_t size,
+					 struct rpc_caller_shared_memory *shared_memory)
+{
+	struct mm_communicate_caller_context *mm_context =
+		(struct mm_communicate_caller_context *)context;
+	size_t hdr_size = 0;
+	size_t required_size = 0;
+	int status = -1;
+
+	if (!context || !shared_memory)
+		return RPC_ERROR_INVALID_VALUE;
+
+	*shared_memory = (struct rpc_caller_shared_memory){ 0 };
+
+	if (!mm_context->serializer || mm_context->comm_buffer)
+		return RPC_ERROR_INVALID_STATE;
+
+	hdr_size = mm_communicate_serializer_header_size(mm_context->serializer);
+	if (!hdr_size)
+		return RPC_ERROR_INTERNAL;
+
+	status = carveout_claim(&mm_context->comm_buffer, &mm_context->comm_buffer_size);
+	if (status) {
+		mm_context->comm_buffer = NULL;
+		mm_context->comm_buffer_size = 0;
+
+		return RPC_ERROR_INTERNAL;
+	}
+
+	if (ADD_OVERFLOW(hdr_size, size, &required_size) ||
+	    required_size > mm_context->comm_buffer_size) {
+		carveout_relinquish(mm_context->comm_buffer, mm_context->comm_buffer_size);
+		mm_context->comm_buffer = NULL;
+		mm_context->comm_buffer_size = 0;
+
+		return RPC_ERROR_INVALID_VALUE;
+	}
+
+	shared_memory->id = 0;
+	shared_memory->buffer = &mm_context->comm_buffer[hdr_size];
+	shared_memory->size = mm_context->comm_buffer_size - hdr_size;
+
+	return RPC_SUCCESS;
+}
+
+static rpc_status_t release_shared_memory(void *context,
+					  struct rpc_caller_shared_memory *shared_memory)
+{
+	struct mm_communicate_caller_context *mm_context =
+		(struct mm_communicate_caller_context *)context;
+
+	if (!context || !shared_memory)
+		return RPC_ERROR_INVALID_VALUE;
+
+	if (!mm_context->comm_buffer)
+		return RPC_ERROR_INVALID_STATE;
+
+	if (!is_valid_shared_memory(mm_context, shared_memory))
+		return RPC_ERROR_INVALID_VALUE;
+
+	memset(mm_context->comm_buffer, 0x00, mm_context->comm_buffer_size);
+
+	carveout_relinquish(mm_context->comm_buffer, mm_context->comm_buffer_size);
+	mm_context->comm_buffer = NULL;
+	mm_context->comm_buffer_size = 0;
+
+	return RPC_SUCCESS;
+}
+
+static rpc_status_t call(void *context, uint16_t opcode,
+			 struct rpc_caller_shared_memory *shared_memory, size_t request_length,
+			 size_t *response_length, service_status_t *service_status)
+{
+	struct mm_communicate_caller_context *mm_context =
+		(struct mm_communicate_caller_context *)context;
+	struct ffa_ioctl_msg_args direct_msg = { 0 };
+	int kernel_op_status = 0;
+	int32_t mm_return_code = 0;
+	uint8_t *resp_buf = NULL;
+
+	if (!context || !shared_memory || !response_length || !service_status)
+		return RPC_ERROR_INVALID_VALUE;
+
+	if (!is_valid_shared_memory(mm_context, shared_memory))
+		return RPC_ERROR_INVALID_VALUE;
+
+	mm_communicate_serializer_header_encode(mm_context->serializer, mm_context->comm_buffer,
+						opcode, request_length);
+
+	/* Make direct call to send the request */
+	direct_msg.dst_id = mm_context->dest_partition_id;
+	direct_msg.args[MM_COMMUNICATE_CALL_ARGS_COMM_BUFFER_OFFSET] = 0;
+
+	kernel_op_status = ioctl(mm_context->ffa_fd, FFA_IOC_MSG_SEND, &direct_msg);
+	if (kernel_op_status < 0)
+		return RPC_ERROR_INTERNAL;
+
+	/* Kernel send operation completed normally */
+	mm_return_code = direct_msg.args[MM_COMMUNICATE_CALL_ARGS_RETURN_CODE];
+	if (mm_return_code != MM_RETURN_CODE_SUCCESS)
+		return mm_return_code_to_rpc_status(mm_return_code);
+
+	mm_communicate_serializer_header_decode(mm_context->serializer, mm_context->comm_buffer,
+						(efi_status_t *)service_status, &resp_buf,
+						response_length);
+
+	if (resp_buf != shared_memory->buffer)
+		return RPC_ERROR_INVALID_RESPONSE_BODY;
+
+	return RPC_SUCCESS;
+}
+
+static bool mm_communicate_caller_check_version(void)
+{
+	FILE *f = NULL;
+	char mod_name[64] = { 0 };
+	int ver_major = 0, ver_minor = 0, ver_patch = 0;
 	bool mod_loaded = false;
 
 	f = fopen("/proc/modules", "r");
@@ -56,7 +323,7 @@
 		return false;
 	}
 
-	while (fscanf(f, "%64s %*[^\n]\n", mod_name) != EOF) {
+	while (fscanf(f, "%63s %*[^\n]\n", mod_name) != EOF) {
 		if (!strcmp(mod_name, "arm_ffa_user")) {
 			mod_loaded = true;
 			break;
@@ -97,269 +364,72 @@
 	return true;
 
 err:
-	printf("error: kernel module is v%d.%d.%d but required v%d.%d.%d\n",
-		ver_major, ver_minor, ver_patch, KERNEL_MOD_REQ_VER_MAJOR,
-		KERNEL_MOD_REQ_VER_MINOR, KERNEL_MOD_REQ_VER_PATCH);
+	printf("error: kernel module is v%d.%d.%d but required v%d.%d.%d\n", ver_major, ver_minor,
+	       ver_patch, KERNEL_MOD_REQ_VER_MAJOR, KERNEL_MOD_REQ_VER_MINOR,
+	       KERNEL_MOD_REQ_VER_PATCH);
 
 	return false;
 }
 
-struct rpc_caller *mm_communicate_caller_init(
-	struct mm_communicate_caller *s,
-	const char *ffa_device_path)
+rpc_status_t mm_communicate_caller_init(struct rpc_caller_interface *rpc_caller,
+					const char *ffa_device_path)
 {
-	struct rpc_caller *base = &s->rpc_caller;
+	struct mm_communicate_caller_context *context = NULL;
 
-	rpc_caller_init(base, s);
-	base->call_begin = call_begin;
-	base->call_invoke = call_invoke;
-	base->call_end = call_end;
+	if (!rpc_caller || !ffa_device_path)
+		return RPC_ERROR_INVALID_VALUE;
 
-	s->ffa_fd = -1;
-	s->ffa_device_path = ffa_device_path;
-	s->dest_partition_id = 0;
-	s->comm_buffer = NULL;
-	s->comm_buffer_size = 0;
-	s->scrub_len = 0;
-	s->req_len = 0;
-	s->is_call_transaction_in_progess = false;
-	s->serializer = NULL;
+	if (!mm_communicate_caller_check_version())
+		return RPC_ERROR_INTERNAL;
 
-	return base;
+	context = (struct mm_communicate_caller_context *)calloc(
+		1, sizeof(struct mm_communicate_caller_context));
+	if (!context)
+		return RPC_ERROR_INTERNAL;
+
+	context->ffa_fd = -1;
+	context->ffa_device_path = ffa_device_path;
+	context->dest_partition_id = 0;
+	context->comm_buffer = NULL;
+	context->comm_buffer_size = 0;
+	context->req_len = 0;
+	context->serializer = NULL;
+
+	rpc_caller->context = context;
+	rpc_caller->open_session = open_session;
+	rpc_caller->find_and_open_session = find_and_open_session;
+	rpc_caller->close_session = close_session;
+	rpc_caller->create_shared_memory = create_shared_memory;
+	rpc_caller->release_shared_memory = release_shared_memory;
+	rpc_caller->call = call;
+
+	return RPC_SUCCESS;
 }
 
-void mm_communicate_caller_deinit(
-	struct mm_communicate_caller *s)
+rpc_status_t mm_communicate_caller_deinit(struct rpc_caller_interface *rpc_caller)
 {
-	s->rpc_caller.context = NULL;
-	s->rpc_caller.call_begin = NULL;
-	s->rpc_caller.call_invoke = NULL;
-	s->rpc_caller.call_end = NULL;
+	struct mm_communicate_caller_context *mm_context = NULL;
+	rpc_status_t status = RPC_ERROR_INTERNAL;
 
-	call_end(s, s);
-	mm_communicate_caller_close(s);
-}
+	if (!rpc_caller || !rpc_caller->context)
+		return RPC_ERROR_INVALID_VALUE;
 
-size_t mm_communicate_caller_discover(
-	const struct mm_communicate_caller *s,
-	const struct uuid_canonical *uuid,
-	uint16_t *partition_ids,
-	size_t discover_limit)
-{
-	size_t discover_count = 0;
+	mm_context = (struct mm_communicate_caller_context *)rpc_caller->context;
 
-	if (uuid && partition_ids && s->ffa_device_path) {
-		int fd;
-
-		fd = open(s->ffa_device_path, O_RDWR);
-
-		if (fd >= 0) {
-			int ioctl_status;
-			struct ffa_ioctl_ep_desc discovered_partition;
-
-			discovered_partition.uuid_ptr = (uintptr_t)&uuid->characters;
-			discovered_partition.id = 0;
-
-			ioctl_status = ioctl(fd, FFA_IOC_GET_PART_ID, &discovered_partition);
-
-			if ((ioctl_status == 0) && (discover_count < discover_limit)) {
-				partition_ids[discover_count] = discovered_partition.id;
-				++discover_count;
-			}
-
-			close(fd);
-		}
+	if (mm_context->comm_buffer) {
+		carveout_relinquish(mm_context->comm_buffer, mm_context->comm_buffer_size);
+		mm_context->comm_buffer = NULL;
+		mm_context->comm_buffer_size = 0;
 	}
 
-	return discover_count;
-}
-
-int mm_communicate_caller_open(
-	struct mm_communicate_caller *s,
-	uint16_t dest_partition_id,
-	const EFI_GUID *svc_guid)
-{
-	int status = -1;
-
-	s->serializer = mm_communicate_serializer_find(svc_guid);
-
-	if (s->serializer && s->ffa_device_path) {
-
-		s->ffa_fd = open(s->ffa_device_path, O_RDWR);
-
-		if ((s->ffa_fd >= 0) && !s->comm_buffer) {
-
-			status = carveout_claim(
-				&s->comm_buffer,
-				&s->comm_buffer_size);
-
-			if (status == 0) {
-
-				s->dest_partition_id = dest_partition_id;
-			}
-			else {
-				/* Failed to claim carveout */
-				s->comm_buffer = NULL;
-				s->comm_buffer_size = 0;
-
-				mm_communicate_caller_close(s);
-			}
-		}
+	if (mm_context->ffa_fd >= 0) {
+		status = rpc_caller_close_session(rpc_caller);
+		if (status != RPC_SUCCESS)
+			return status;
 	}
 
-	if (status != 0) {
+	free(rpc_caller->context);
+	rpc_caller->context = NULL;
 
-		s->serializer = NULL;
-	}
-
-	return status;
-}
-
-int mm_communicate_caller_close(
-	struct mm_communicate_caller *s)
-{
-	if (s->ffa_fd >= 0) {
-
-		close(s->ffa_fd);
-		s->ffa_fd = -1;
-		s->dest_partition_id = 0;
-	}
-
-	if (s->comm_buffer) {
-
-		carveout_relinquish(s->comm_buffer, s->comm_buffer_size);
-		s->comm_buffer = NULL;
-		s->comm_buffer_size = 0;
-	}
-
-	s->serializer = NULL;
-
-	s->is_call_transaction_in_progess = false;
-
-	return ((s->ffa_fd < 0) && !s->comm_buffer) ? 0 : -1;
-}
-
-static rpc_call_handle call_begin(
-	void *context,
-	uint8_t **req_buf,
-	size_t req_len)
-{
-	rpc_call_handle handle = NULL;
-	struct mm_communicate_caller *s = (struct mm_communicate_caller*)context;
-	size_t hdr_size = mm_communicate_serializer_header_size(s->serializer);
-	*req_buf = NULL;
-
-	if (!s->is_call_transaction_in_progess && hdr_size) {
-
-		if (req_len + hdr_size <= s->comm_buffer_size) {
-
-			s->is_call_transaction_in_progess = true;
-			handle = s;
-
-			s->req_len = req_len;
-			*req_buf = &s->comm_buffer[hdr_size];
-
-			s->scrub_len = hdr_size + req_len;
-		}
-		else {
-
-			s->req_len = 0;
-		}
-	}
-
-	return handle;
-}
-
-static rpc_status_t call_invoke(
-	void *context,
-	rpc_call_handle handle,
-	uint32_t opcode,
-	rpc_opstatus_t *opstatus,
-	uint8_t **resp_buf,
-	size_t *resp_len)
-{
-	struct mm_communicate_caller *s = (struct mm_communicate_caller*)context;
-
-	rpc_status_t rpc_status = TS_RPC_ERROR_INTERNAL;
-	*resp_len = 0;
-
-	if ((handle == s) && s->is_call_transaction_in_progess) {
-
-		mm_communicate_serializer_header_encode(s->serializer,
-			s->comm_buffer, opcode, s->req_len);
-
-		/* Make direct call to send the request */
-		struct ffa_ioctl_msg_args direct_msg;
-		memset(&direct_msg, 0, sizeof(direct_msg));
-
-		direct_msg.dst_id = s->dest_partition_id;
-
-		direct_msg.args[MM_COMMUNICATE_CALL_ARGS_COMM_BUFFER_OFFSET] = 0;
-
-		int kernel_op_status = ioctl(s->ffa_fd, FFA_IOC_MSG_SEND, &direct_msg);
-
-		if (kernel_op_status == 0) {
-			/* Kernel send operation completed normally */
-			int32_t mm_return_code = direct_msg.args[MM_COMMUNICATE_CALL_ARGS_RETURN_CODE];
-
-			if (mm_return_code == MM_RETURN_CODE_SUCCESS) {
-				mm_communicate_serializer_header_decode(
-					s->serializer, s->comm_buffer, (efi_status_t *)opstatus,
-					resp_buf, resp_len);
-
-				if (*resp_len > s->req_len)
-					s->scrub_len =
-						mm_communicate_serializer_header_size(
-							s->serializer) + *resp_len;
-
-				rpc_status = TS_RPC_CALL_ACCEPTED;
-			} else {
-
-				rpc_status = mm_return_code_to_rpc_status(mm_return_code);
-			}
-		}
-	}
-
-	return rpc_status;
-}
-
-static void call_end(void *context, rpc_call_handle handle)
-{
-	struct mm_communicate_caller *s = (struct mm_communicate_caller*)context;
-
-	if ((handle == s) && s->is_call_transaction_in_progess) {
-
-		/* Call transaction complete */
-		s->req_len = 0;
-		s->is_call_transaction_in_progess = false;
-
-		/* Scrub the comms buffer */
-		memset(s->comm_buffer, 0, s->scrub_len);
-		s->scrub_len = 0;
-	}
-}
-
-static rpc_status_t mm_return_code_to_rpc_status(int32_t return_code)
-{
-	rpc_status_t rpc_status = TS_RPC_ERROR_INTERNAL;
-
-	switch (return_code)
-	{
-		case MM_RETURN_CODE_NOT_SUPPORTED:
-			rpc_status = TS_RPC_ERROR_INTERFACE_DOES_NOT_EXIST;
-			break;
-		case MM_RETURN_CODE_INVALID_PARAMETER:
-			rpc_status = TS_RPC_ERROR_INVALID_PARAMETER;
-			break;
-		case MM_RETURN_CODE_DENIED:
-			rpc_status = TS_RPC_ERROR_ACCESS_DENIED;
-			break;
-		case MM_RETURN_CODE_NO_MEMORY:
-			rpc_status = TS_RPC_ERROR_RESOURCE_FAILURE;
-			break;
-		default:
-			break;
-	}
-
-	return rpc_status;
+	return RPC_SUCCESS;
 }
diff --git a/components/rpc/mm_communicate/caller/linux/mm_communicate_caller.h b/components/rpc/mm_communicate/caller/linux/mm_communicate_caller.h
index 8420681..d1a2c5c 100644
--- a/components/rpc/mm_communicate/caller/linux/mm_communicate_caller.h
+++ b/components/rpc/mm_communicate/caller/linux/mm_communicate_caller.h
@@ -10,10 +10,9 @@
 #include <stdbool.h>
 #include <common/uuid/uuid.h>
 #include <protocols/common/efi/efi_types.h>
-#include <rpc_caller.h>
+#include "rpc_caller.h"
 #include "mm_communicate_serializer.h"
 
-
 #ifdef __cplusplus
 extern "C" {
 #endif
@@ -22,42 +21,12 @@
  * An RPC caller for Linux user-space clients that uses the MM_COMMUNICATE
  * protocol for calling UEFI SMM service endpoints.
  */
-struct mm_communicate_caller
-{
-	struct rpc_caller rpc_caller;
-	int ffa_fd;
-	const char *ffa_device_path;
-	uint16_t dest_partition_id;
-	uint8_t *comm_buffer;
-	size_t comm_buffer_size;
-	size_t req_len;
-	size_t scrub_len;
-	bool is_call_transaction_in_progess;
-	const struct mm_communicate_serializer *serializer;
-};
+RPC_CALLER_EXPORTED
+rpc_status_t mm_communicate_caller_init(struct rpc_caller_interface *caller,
+					const char *ffa_device_path);
 
-bool mm_communicate_caller_check_version(void);
-
-struct rpc_caller *mm_communicate_caller_init(
-	struct mm_communicate_caller *s,
-	const char *ffa_device_path);
-
-void mm_communicate_caller_deinit(
-	struct mm_communicate_caller *s);
-
-size_t mm_communicate_caller_discover(
-	const struct mm_communicate_caller *s,
-	const struct uuid_canonical *uuid,
-	uint16_t *partition_ids,
-	size_t discover_limit);
-
-int mm_communicate_caller_open(
-	struct mm_communicate_caller *s,
-	uint16_t dest_partition_id,
-	const EFI_GUID *svc_guid);
-
-int mm_communicate_caller_close(
-	struct mm_communicate_caller *s);
+RPC_CALLER_EXPORTED
+rpc_status_t mm_communicate_caller_deinit(struct rpc_caller_interface *caller);
 
 #ifdef __cplusplus
 }
diff --git a/components/rpc/mm_communicate/endpoint/sp/component.cmake b/components/rpc/mm_communicate/endpoint/sp/component.cmake
index 456b9a7..ca453ce 100644
--- a/components/rpc/mm_communicate/endpoint/sp/component.cmake
+++ b/components/rpc/mm_communicate/endpoint/sp/component.cmake
@@ -11,3 +11,14 @@
 target_sources(${TGT} PRIVATE
 	"${CMAKE_CURRENT_LIST_DIR}/mm_communicate_call_ep.c"
 )
+
+if(NOT ((TS_ENV STREQUAL "linux-pc") OR (TS_ENV STREQUAL "arm-linux")))
+	if(NOT DEFINED SP_BIN_UUID_CANON)
+		message(FATAL_ERROR "Mandatory parameter SP_BIN_UUID_CANON is not defined.")
+	endif()
+
+	# Verify that SP is using the TS protocol.
+	if ("${SP_FFA_UUID_CANON}" STREQUAL "${TS_RPC_UUID_CANON}")
+		message(FATAL_ERROR "The code is using MM RPC, but the SP_FFA_UUID_CANON is matching the TS RPC UUID.")
+	endif()
+endif()
\ No newline at end of file
diff --git a/components/rpc/mm_communicate/endpoint/sp/mm_communicate_call_ep.c b/components/rpc/mm_communicate/endpoint/sp/mm_communicate_call_ep.c
index 9db9288..42ca698 100644
--- a/components/rpc/mm_communicate/endpoint/sp/mm_communicate_call_ep.c
+++ b/components/rpc/mm_communicate/endpoint/sp/mm_communicate_call_ep.c
@@ -15,6 +15,9 @@
 {
 	unsigned int i = 0;
 
+	if (!call_ep || !comm_buffer)
+		return false;
+
 	if (comm_buffer_size < EFI_MM_COMMUNICATE_HEADER_SIZE)
 		return false;
 
@@ -43,21 +46,17 @@
 
 	call_req.guid = &header->HeaderGuid;
 
-	/*
-	 * The subtraction for size field should be overflow-safe because of the
-	 * check in the init funciton.
-	 */
 	call_req.req_buf.data = header->Data;
-	call_req.req_buf.data_len = header->MessageLength;
+	call_req.req_buf.data_length = header->MessageLength;
 	call_req.req_buf.size = buffer_size;
 
 	call_req.resp_buf.data = header->Data;
-	call_req.resp_buf.data_len = 0;
+	call_req.resp_buf.data_length = 0;
 	call_req.resp_buf.size = buffer_size;
 
 	result = iface->receive(iface, &call_req);
 
-	header->MessageLength = call_req.resp_buf.data_len;
+	header->MessageLength = call_req.resp_buf.data_length;
 
 	return result;
 }
diff --git a/components/rpc/mm_communicate/endpoint/sp/mm_communicate_call_ep.h b/components/rpc/mm_communicate/endpoint/sp/mm_communicate_call_ep.h
index 75d3515..15a7e62 100644
--- a/components/rpc/mm_communicate/endpoint/sp/mm_communicate_call_ep.h
+++ b/components/rpc/mm_communicate/endpoint/sp/mm_communicate_call_ep.h
@@ -6,7 +6,7 @@
 #ifndef MM_COMMUNICATE_CALL_EP_H_
 #define MM_COMMUNICATE_CALL_EP_H_
 
-#include "components/rpc/common/endpoint/rpc_interface.h"
+#include "components/rpc/common/endpoint/rpc_service_interface.h"
 #include "protocols/common/efi/efi_types.h"
 #include "ffa_api.h"
 #include <stdbool.h>
@@ -26,8 +26,8 @@
  */
 struct mm_service_call_req {
 	EFI_GUID *guid;
-	struct call_param_buf req_buf;
-	struct call_param_buf resp_buf;
+	struct rpc_buffer req_buf;
+	struct rpc_buffer resp_buf;
 };
 
 /**
diff --git a/components/rpc/mm_communicate/endpoint/sp/test/mm_service_call_req_comparator.h b/components/rpc/mm_communicate/endpoint/sp/test/mm_service_call_req_comparator.h
index 438a5d4..4280cd1 100644
--- a/components/rpc/mm_communicate/endpoint/sp/test/mm_service_call_req_comparator.h
+++ b/components/rpc/mm_communicate/endpoint/sp/test/mm_service_call_req_comparator.h
@@ -8,7 +8,7 @@
 
 #include <CppUTestExt/MockSupport.h>
 #include <string.h>
-#include "components/rpc/common/test/call_param_buf_comparator.h"
+#include "components/rpc/common/test/rpc_buffer_comparator.h"
 #include "../mm_communicate_call_ep.h"
 
 class mm_service_call_req_comparator : public MockNamedValueComparator
@@ -18,9 +18,9 @@
 	{
 		struct mm_service_call_req *req1 = (struct mm_service_call_req *)object1;
 		struct mm_service_call_req *req2 = (struct mm_service_call_req *)object2;
-		call_param_buf_comparator buf_comparator_normal;
-		call_param_buf_comparator buf_comparator_ignore_data_len(
-			call_param_buf_comparator::mode_ignore_data_len);
+		rpc_buffer_comparator buf_comparator_normal;
+		rpc_buffer_comparator buf_comparator_ignore_data_len(
+			rpc_buffer_comparator::mode_ignore_data_len);
 
 		return memcmp(req1->guid, req2->guid, sizeof(*req1->guid))  == 0 &&
 			buf_comparator_normal.isEqual(&req1->req_buf, &req2->req_buf) &&
@@ -31,9 +31,9 @@
 	virtual SimpleString valueToString(const void *object)
 	{
 		struct mm_service_call_req *req = (struct mm_service_call_req *)object;
-		call_param_buf_comparator buf_comparator_normal;
-		call_param_buf_comparator buf_comparator_ignore_data_len(
-			call_param_buf_comparator::mode_ignore_data_len);
+		rpc_buffer_comparator buf_comparator_normal;
+		rpc_buffer_comparator buf_comparator_ignore_data_len(
+			rpc_buffer_comparator::mode_ignore_data_len);
 		SimpleString req_buf_str = buf_comparator_normal.valueToString(&req->req_buf);
 		SimpleString resp_buf_str =
 			buf_comparator_ignore_data_len.valueToString(&req->resp_buf);
diff --git a/components/rpc/mm_communicate/endpoint/sp/test/mock_mm_service.cpp b/components/rpc/mm_communicate/endpoint/sp/test/mock_mm_service.cpp
index 0ae2a80..c8f38c7 100644
--- a/components/rpc/mm_communicate/endpoint/sp/test/mock_mm_service.cpp
+++ b/components/rpc/mm_communicate/endpoint/sp/test/mock_mm_service.cpp
@@ -19,8 +19,8 @@
 				    int64_t result)
 {
 	mock().expectOneCall("mm_service_receive").onObject(iface).
-		withOutputParameterReturning("resp_buf_data_len", &req->resp_buf.data_len,
-					     sizeof(req->resp_buf.data_len)).
+		withOutputParameterReturning("resp_buf_data_len", &req->resp_buf.data_length,
+					     sizeof(req->resp_buf.data_length)).
 		withParameterOfType("mm_service_call_req", "req", req).
 		andReturnValue(result);
 }
@@ -29,7 +29,7 @@
 				struct mm_service_call_req *req)
 {
 	return mock().actualCall("mm_service_receive").onObject(iface).
-		withOutputParameter("resp_buf_data_len", &req->resp_buf.data_len).
+		withOutputParameter("resp_buf_data_len", &req->resp_buf.data_length).
 		withParameterOfType("mm_service_call_req", "req", req).
 		returnLongIntValue();
 }
diff --git a/components/rpc/mm_communicate/endpoint/sp/test/test_mm_communicate_call_ep.cpp b/components/rpc/mm_communicate/endpoint/sp/test/test_mm_communicate_call_ep.cpp
index 5aaa3a6..a21eca7 100644
--- a/components/rpc/mm_communicate/endpoint/sp/test/test_mm_communicate_call_ep.cpp
+++ b/components/rpc/mm_communicate/endpoint/sp/test/test_mm_communicate_call_ep.cpp
@@ -187,14 +187,14 @@
 	struct mm_service_call_req req = {
 		.guid = &guid0,
 		.req_buf = {
-			.size = sizeof(comm_buffer) - EFI_MM_COMMUNICATE_HEADER_SIZE,
-			.data_len = req_len,
-			.data = header->Data
+			.data = header->Data,
+			.data_length = req_len,
+			.size = sizeof(comm_buffer) - EFI_MM_COMMUNICATE_HEADER_SIZE
 		},
 		.resp_buf = {
-			.size = sizeof(comm_buffer) - EFI_MM_COMMUNICATE_HEADER_SIZE,
-			.data_len = 0,
-			.data = header->Data
+			.data = header->Data,
+			.data_length = 0,
+			.size = sizeof(comm_buffer) - EFI_MM_COMMUNICATE_HEADER_SIZE
 		},
 	};
 
@@ -224,14 +224,14 @@
 	struct mm_service_call_req req = {
 		.guid = &guid0,
 		.req_buf = {
-			.size = sizeof(comm_buffer) - EFI_MM_COMMUNICATE_HEADER_SIZE - offset,
-			.data_len = req_len,
-			.data = header->Data
+			.data = header->Data,
+			.data_length = req_len,
+			.size = sizeof(comm_buffer) - EFI_MM_COMMUNICATE_HEADER_SIZE - offset
 		},
 		.resp_buf = {
-			.size = sizeof(comm_buffer) - EFI_MM_COMMUNICATE_HEADER_SIZE - offset,
-			.data_len = 0,
-			.data = header->Data
+			.data = header->Data,
+			.data_length = 0,
+			.size = sizeof(comm_buffer) - EFI_MM_COMMUNICATE_HEADER_SIZE - offset
 		},
 	};
 
@@ -260,14 +260,14 @@
 	struct mm_service_call_req req = {
 		.guid = &guid0,
 		.req_buf = {
-			.size = sizeof(comm_buffer) - EFI_MM_COMMUNICATE_HEADER_SIZE,
-			.data_len = req_len,
-			.data = header->Data
+			.data = header->Data,
+			.data_length = req_len,
+			.size = sizeof(comm_buffer) - EFI_MM_COMMUNICATE_HEADER_SIZE
 		},
 		.resp_buf = {
-			.size = sizeof(comm_buffer) - EFI_MM_COMMUNICATE_HEADER_SIZE,
-			.data_len = 0,
-			.data = header->Data
+			.data = header->Data,
+			.data_length = 0,
+			.size = sizeof(comm_buffer) - EFI_MM_COMMUNICATE_HEADER_SIZE
 		},
 	};
 
@@ -298,14 +298,14 @@
 	struct mm_service_call_req req = {
 		.guid = &guid1,
 		.req_buf = {
-			.size = sizeof(comm_buffer) - EFI_MM_COMMUNICATE_HEADER_SIZE,
-			.data_len = req_len,
-			.data = header->Data
+			.data = header->Data,
+			.data_length = req_len,
+			.size = sizeof(comm_buffer) - EFI_MM_COMMUNICATE_HEADER_SIZE
 		},
 		.resp_buf = {
-			.size = sizeof(comm_buffer) - EFI_MM_COMMUNICATE_HEADER_SIZE,
-			.data_len = 0,
-			.data = header->Data
+			.data = header->Data,
+			.data_length = 0,
+			.size = sizeof(comm_buffer) - EFI_MM_COMMUNICATE_HEADER_SIZE
 		},
 	};
 
diff --git a/components/rpc/mm_communicate/endpoint/sp/test/test_mock_mm_service.cpp b/components/rpc/mm_communicate/endpoint/sp/test/test_mock_mm_service.cpp
index 600386e..5e9149f 100644
--- a/components/rpc/mm_communicate/endpoint/sp/test/test_mock_mm_service.cpp
+++ b/components/rpc/mm_communicate/endpoint/sp/test/test_mock_mm_service.cpp
@@ -34,14 +34,14 @@
 	struct mm_service_call_req req = {
 		&guid,
 		.req_buf = {
-			.size = 20,
-			.data_len = 12,
-			.data = (void *)0x1234
+			.data = (uint8_t *)0x1234,
+			.data_length = 12,
+			.size = 20
 		},
 		.resp_buf = {
-			.size = 30,
-			.data_len = 15,
-			.data = (void *)0x2345
+			.data = (uint8_t *)0x2345,
+			.data_length = 15,
+			.size = 30
 		}
 	};
 	int64_t result = -123456;
diff --git a/components/rpc/psa_ipc/caller/sp/psa_ipc_caller.c b/components/rpc/psa_ipc/caller/sp/psa_ipc_caller.c
index bc5dfe7..499915a 100644
--- a/components/rpc/psa_ipc/caller/sp/psa_ipc_caller.c
+++ b/components/rpc/psa_ipc/caller/sp/psa_ipc_caller.c
@@ -5,108 +5,158 @@
  * SPDX-License-Identifier: BSD-3-Clause
  */
 #include "psa_ipc_caller.h"
+#include "rpc_caller.h"
+#include "rpc_status.h"
 #include <openamp_messenger_api.h>
-#include <protocols/rpc/common/packed-c/status.h>
-#include <rpc_caller.h>
-#include <rpc_status.h>
 #include <trace.h>
 #include <errno.h>
+#include <stdlib.h>
 #include <stdint.h>
 
-static rpc_call_handle psa_ipc_call_begin(void *context, uint8_t **req_buf,
-					  size_t req_len)
+struct psa_ipc_caller_context {
+	struct openamp_messenger openamp;
+};
+
+rpc_status_t open_session(void *context, const struct rpc_uuid *service_uuid, uint16_t endpoint_id)
 {
-	struct psa_ipc_caller *psa_ipc = context;
-	struct openamp_messenger *openamp = &psa_ipc->openamp;
-	rpc_call_handle handle;
-	int ret;
-
-	ret = openamp_messenger_call_begin(openamp, req_buf, req_len);
-	if (ret < 0)
-		return NULL;
-
-	handle = psa_ipc;
-
-	return handle;
+	return RPC_SUCCESS;
 }
 
-static rpc_status_t psa_ipc_call_invoke(void *context, rpc_call_handle handle,
-					uint32_t opcode, long int *opstatus,
-					uint8_t **resp_buf, size_t *resp_len)
+rpc_status_t find_and_open_session(void *context, const struct rpc_uuid *service_uuid)
 {
-	struct psa_ipc_caller *psa_ipc = context;
-	struct openamp_messenger *openamp = &psa_ipc->openamp;
-	int ret;
-
-	(void)opcode;
-
-	ret = openamp_messenger_call_invoke(openamp, resp_buf, resp_len);
-	if (ret == -EINVAL)
-		return TS_RPC_ERROR_INVALID_PARAMETER;
-	if (ret == -ENOTCONN)
-		return TS_RPC_ERROR_NOT_READY;
-	if (ret < 0)
-		return TS_RPC_ERROR_INTERNAL;
-
-	*opstatus = 0;
-
-	return TS_RPC_CALL_ACCEPTED;
+	return RPC_SUCCESS;
 }
 
-static void psa_ipc_call_end(void *context, rpc_call_handle handle)
+rpc_status_t close_session(void *context)
 {
-	struct psa_ipc_caller *psa_ipc = context;
-
-	if (!psa_ipc || psa_ipc != handle) {
-		EMSG("psa_ipc: call_end: invalid arguments");
-		return;
-	}
-
-	openamp_messenger_call_end(&psa_ipc->openamp);
+	return RPC_SUCCESS;
 }
 
+rpc_status_t create_shared_memory(void *context, size_t size,
+				  struct rpc_caller_shared_memory *shared_memory)
+{
+	return RPC_ERROR_INVALID_VALUE;
+}
+
+rpc_status_t release_shared_memory(void *context, struct rpc_caller_shared_memory *shared_memory)
+{
+	return RPC_ERROR_INVALID_VALUE;
+}
+
+rpc_status_t call(void *context, uint16_t opcode, struct rpc_caller_shared_memory *shared_memory,
+		  size_t request_length, size_t *response_length, service_status_t *service_status)
+{
+	return RPC_ERROR_INTERNAL;
+}
 
 void *psa_ipc_phys_to_virt(void *context, void *pa)
 {
-	struct psa_ipc_caller *psa_ipc = context;
-	struct openamp_messenger *openamp = &psa_ipc->openamp;
+	struct psa_ipc_caller_context *caller = (struct psa_ipc_caller_context *)context;
+	struct openamp_messenger *openamp = &caller->openamp;
 
 	return openamp_messenger_phys_to_virt(openamp, pa);
 }
 
 void *psa_ipc_virt_to_phys(void *context, void *va)
 {
-	struct psa_ipc_caller *psa_ipc = context;
-	struct openamp_messenger *openamp = &psa_ipc->openamp;
+	struct psa_ipc_caller_context *caller = (struct psa_ipc_caller_context *)context;
+	struct openamp_messenger *openamp = &caller->openamp;
 
 	return openamp_messenger_virt_to_phys(openamp, va);
 }
 
-struct rpc_caller *psa_ipc_caller_init(struct psa_ipc_caller *psa_ipc)
+rpc_status_t psa_ipc_caller_init(struct rpc_caller_interface *rpc_caller)
 {
-	struct rpc_caller *rpc = &psa_ipc->rpc_caller;
-	int ret;
+	struct psa_ipc_caller_context *context = NULL;
+	int ret = 0;
 
-	ret = openamp_messenger_init(&psa_ipc->openamp);
+	if (!rpc_caller || rpc_caller->context)
+		return RPC_ERROR_INVALID_VALUE;
+
+	context = (struct psa_ipc_caller_context *)calloc(1, sizeof(struct psa_ipc_caller_context));
+	if (!context)
+		return RPC_ERROR_INTERNAL;
+
+	ret = openamp_messenger_init(&context->openamp);
+	if (ret < 0) {
+		free(context);
+		return RPC_ERROR_TRANSPORT_LAYER;
+	}
+
+	rpc_caller->context = context;
+	rpc_caller->open_session = open_session;
+	rpc_caller->find_and_open_session = find_and_open_session;
+	rpc_caller->close_session = close_session;
+	rpc_caller->create_shared_memory = create_shared_memory;
+	rpc_caller->release_shared_memory = release_shared_memory;
+	rpc_caller->call = call;
+
+	return RPC_SUCCESS;
+}
+
+rpc_status_t psa_ipc_caller_deinit(struct rpc_caller_interface *rpc_caller)
+{
+	struct psa_ipc_caller_context *context = NULL;
+
+	context = (struct psa_ipc_caller_context *)rpc_caller->context;
+
+	openamp_messenger_deinit(&context->openamp);
+
+	free(context);
+
+	return RPC_SUCCESS;
+}
+
+psa_ipc_call_handle psa_ipc_caller_begin(struct rpc_caller_interface *caller,
+					 uint8_t **request_buffer,
+					 size_t request_length)
+{
+	struct psa_ipc_caller_context *context = NULL;
+	int ret = 0;
+
+	if (!caller || !caller->context)
+		return NULL;
+
+	context = (struct psa_ipc_caller_context *)caller->context;
+
+	ret = openamp_messenger_call_begin(&context->openamp, request_buffer, request_length);
 	if (ret < 0)
 		return NULL;
 
-	rpc_caller_init(rpc, &psa_ipc->rpc_caller);
-	rpc->call_begin = psa_ipc_call_begin;
-	rpc->call_invoke = psa_ipc_call_invoke;
-	rpc->call_end = psa_ipc_call_end;
+	return caller;
 
-	return rpc;
 }
 
-struct rpc_caller *psa_ipc_caller_deinit(struct psa_ipc_caller *psa_ipc)
+rpc_status_t psa_ipc_caller_invoke(psa_ipc_call_handle handle, uint32_t opcode,
+				   uint8_t **response_buffer, size_t *response_length)
 {
-	struct rpc_caller *rpc = &psa_ipc->rpc_caller;
+	struct rpc_caller_interface *caller = (struct rpc_caller_interface *)handle;
+	struct psa_ipc_caller_context *context = NULL;
+	int ret = 0;
 
-	rpc->context = NULL;
-	rpc->call_begin = NULL;
-	rpc->call_invoke = NULL;
-	rpc->call_end = NULL;
+	if (!handle || !caller->context)
+		return RPC_ERROR_INVALID_VALUE;
 
-	return rpc;
+	context = (struct psa_ipc_caller_context *)caller->context;
+
+	ret = openamp_messenger_call_invoke(&context->openamp, response_buffer, response_length);
+	if (ret < 0)
+		return RPC_ERROR_TRANSPORT_LAYER;
+
+	return RPC_SUCCESS;
 }
+
+rpc_status_t psa_ipc_caller_end(psa_ipc_call_handle handle)
+{
+	struct rpc_caller_interface *caller = (struct rpc_caller_interface *)handle;
+	struct psa_ipc_caller_context *context = NULL;
+
+	if (!handle || !caller->context)
+		return RPC_ERROR_INVALID_VALUE;
+
+	context = (struct psa_ipc_caller_context *)caller->context;
+
+	openamp_messenger_call_end(&context->openamp);
+
+	return RPC_SUCCESS;
+}
\ No newline at end of file
diff --git a/components/rpc/psa_ipc/caller/sp/psa_ipc_caller.h b/components/rpc/psa_ipc/caller/sp/psa_ipc_caller.h
index 1b84e98..f415ccc 100644
--- a/components/rpc/psa_ipc/caller/sp/psa_ipc_caller.h
+++ b/components/rpc/psa_ipc/caller/sp/psa_ipc_caller.h
@@ -5,16 +5,23 @@
  * SPDX-License-Identifier: BSD-3-Clause
  */
 
-#include <rpc_caller.h>
+#include "rpc_caller_session.h"
 #include <openamp_messenger_api.h>
 
-struct psa_ipc_caller {
-	struct rpc_caller rpc_caller;
-	struct openamp_messenger openamp;
-};
+typedef void *psa_ipc_call_handle;
 
 void *psa_ipc_phys_to_virt(void *context, void *pa);
 void *psa_ipc_virt_to_phys(void *context, void *va);
 
-struct rpc_caller *psa_ipc_caller_init(struct psa_ipc_caller *psaipc);
-struct rpc_caller *psa_ipc_caller_deinit(struct psa_ipc_caller *psaipc);
+rpc_status_t psa_ipc_caller_init(struct rpc_caller_interface *rpc_caller);
+rpc_status_t psa_ipc_caller_deinit(struct rpc_caller_interface *rpc_caller);
+
+psa_ipc_call_handle psa_ipc_caller_begin(struct rpc_caller_interface *caller,
+					 uint8_t **request_buffer,
+					 size_t request_length);
+
+rpc_status_t psa_ipc_caller_invoke(psa_ipc_call_handle handle, uint32_t opcode,
+				       uint8_t **response_buffer,
+				       size_t *response_length);
+
+rpc_status_t psa_ipc_caller_end(psa_ipc_call_handle handle);
\ No newline at end of file
diff --git a/components/rpc/psa_ipc/service_psa_ipc.c b/components/rpc/psa_ipc/service_psa_ipc.c
index 830f461..36c8e36 100644
--- a/components/rpc/psa_ipc/service_psa_ipc.c
+++ b/components/rpc/psa_ipc/service_psa_ipc.c
@@ -51,7 +51,7 @@
 static size_t psa_call_in_vec_len(const struct psa_invec *in_vec, size_t in_len)
 {
 	size_t req_len = 0;
-	int i;
+	int i = 0;
 
 	if (!in_vec || !in_len)
 		return 0;
@@ -62,25 +62,23 @@
 	return req_len;
 }
 
-static uint32_t psa_virt_to_phys_u32(struct rpc_caller *caller, void *va)
+static uint32_t psa_virt_to_phys_u32(struct rpc_caller_interface *caller, void *va)
 {
 	return (uintptr_t)psa_ipc_virt_to_phys(caller->context, va);
 }
 
-psa_handle_t psa_connect(struct rpc_caller *caller, uint32_t sid,
+psa_handle_t psa_connect(struct rpc_caller_interface *caller, uint32_t sid,
 			 uint32_t version)
 {
-	rpc_opstatus_t opstatus = PSA_SUCCESS;
-	struct s_openamp_msg *resp_msg = NULL;
+	struct s_openamp_msg *resp_msg;
 	struct ns_openamp_msg *req_msg;
-	rpc_call_handle rpc_handle;
+	psa_ipc_call_handle rpc_handle;
 	size_t resp_len;
 	uint8_t *resp;
 	uint8_t *req;
 	int ret;
 
-	rpc_handle = rpc_caller_begin(caller, &req,
-				      sizeof(struct ns_openamp_msg));
+	rpc_handle = psa_ipc_caller_begin(caller, &req, sizeof(struct ns_openamp_msg));
 	if (!rpc_handle) {
 		EMSG("psa_connect: could not get rpc handle");
 		return PSA_ERROR_GENERIC_ERROR;
@@ -92,32 +90,29 @@
 	req_msg->params.psa_connect_params.sid = sid;
 	req_msg->params.psa_connect_params.version = version;
 
-	ret = rpc_caller_invoke(caller, rpc_handle, 0, &opstatus, &resp,
-				&resp_len);
-	if (ret != TS_RPC_CALL_ACCEPTED) {
-		EMSG("psa_connect: invoke failed: %d", ret);
-		return PSA_ERROR_GENERIC_ERROR;
+	ret = psa_ipc_caller_invoke(rpc_handle, 0, &resp, &resp_len);
+	if (ret != RPC_SUCCESS) {
+		EMSG("invoke failed: %d", ret);
+		return PSA_NULL_HANDLE;
 	}
 
-	if (opstatus == PSA_SUCCESS)
-		resp_msg = (struct s_openamp_msg *)resp;
+	resp_msg = (struct s_openamp_msg *)resp;
 
-	rpc_caller_end(caller, rpc_handle);
+	psa_ipc_caller_end(rpc_handle);
 
 	return resp_msg ? (psa_handle_t)resp_msg->reply : PSA_NULL_HANDLE;
 }
 
-static psa_status_t __psa_call(struct rpc_caller *caller, psa_handle_t psa_handle,
+static psa_status_t __psa_call(struct rpc_caller_interface *caller, psa_handle_t psa_handle,
 			       int32_t client_id, int32_t type,
 			       const struct psa_invec *in_vec, size_t in_len,
 			       struct psa_outvec *out_vec, size_t out_len)
 {
-	rpc_opstatus_t opstatus = PSA_SUCCESS;
 	struct s_openamp_msg *resp_msg = NULL;
 	struct psa_outvec *out_vec_param;
 	struct psa_invec *in_vec_param;
 	struct ns_openamp_msg *req_msg;
-	rpc_call_handle rpc_handle;
+	psa_ipc_call_handle rpc_handle;
 	size_t in_vec_len;
 	size_t header_len;
 	uint8_t *payload;
@@ -133,7 +128,7 @@
 	header_len = psa_call_header_len(in_vec, in_len, out_vec, out_len);
 	in_vec_len = psa_call_in_vec_len(in_vec, in_len);
 
-	rpc_handle = rpc_caller_begin(caller, &req, header_len + in_vec_len);
+	rpc_handle = psa_ipc_caller_begin(caller, &req, header_len + in_vec_len);
 	if (!rpc_handle) {
 		EMSG("psa_call: could not get handle");
 		return PSA_ERROR_GENERIC_ERROR;
@@ -170,18 +165,12 @@
 		out_vec_param[i].len = out_vec[i].len;
 	}
 
-	ret = rpc_caller_invoke(caller, rpc_handle, 0, &opstatus, &resp,
-				&resp_len);
-	if (ret != TS_RPC_CALL_ACCEPTED) {
+	ret = psa_ipc_caller_invoke(rpc_handle, 0, &resp, &resp_len);
+	if (ret != RPC_SUCCESS) {
 		EMSG("psa_call: invoke failed: %d", ret);
 		return PSA_ERROR_GENERIC_ERROR;
 	}
 
-	if (opstatus != PSA_SUCCESS) {
-		EMSG("psa_call: psa_status invoke failed: %ld", opstatus);
-		return PSA_ERROR_GENERIC_ERROR;
-	}
-
 	resp_msg = (struct s_openamp_msg *)resp;
 
 	if (!resp_msg || !out_len || resp_msg->reply != PSA_SUCCESS)
@@ -199,12 +188,12 @@
 	}
 
 caller_end:
-	rpc_caller_end(caller, rpc_handle);
+	psa_ipc_caller_end(rpc_handle);
 
 	return resp_msg ? resp_msg->reply : PSA_ERROR_COMMUNICATION_FAILURE;
 }
 
-psa_status_t psa_call_client_id(struct rpc_caller *caller,
+psa_status_t psa_call_client_id(struct rpc_caller_interface *caller,
 				psa_handle_t psa_handle, int32_t client_id,
 				int32_t type, const struct psa_invec *in_vec,
 				size_t in_len, struct psa_outvec *out_vec,
@@ -214,7 +203,7 @@
 			  out_vec, out_len);
 }
 
-psa_status_t psa_call(struct rpc_caller *caller, psa_handle_t psa_handle,
+psa_status_t psa_call(struct rpc_caller_interface *caller, psa_handle_t psa_handle,
 		      int32_t type, const struct psa_invec *in_vec,
 		      size_t in_len, struct psa_outvec *out_vec, size_t out_len)
 {
@@ -222,11 +211,10 @@
 			  out_len);
 }
 
-void psa_close(struct rpc_caller *caller, psa_handle_t psa_handle)
+void psa_close(struct rpc_caller_interface *caller, psa_handle_t psa_handle)
 {
-	rpc_opstatus_t opstatus = PSA_SUCCESS;
 	struct ns_openamp_msg *req_msg;
-	rpc_call_handle rpc_handle;
+	psa_ipc_call_handle rpc_handle;
 	size_t resp_len;
 	uint8_t *resp;
 	uint8_t *req;
@@ -235,8 +223,7 @@
 	if ((psa_handle == PSA_NULL_HANDLE) || !caller)
 		return;
 
-	rpc_handle = rpc_caller_begin(caller, &req,
-				      sizeof(struct ns_openamp_msg));
+	rpc_handle = psa_ipc_caller_begin(caller, &req, sizeof(struct ns_openamp_msg));
 	if (!rpc_handle) {
 		EMSG("psa_close: could not get handle");
 		return;
@@ -247,12 +234,11 @@
 	req_msg->call_type = OPENAMP_PSA_CLOSE;
 	req_msg->params.psa_close_params.handle = psa_handle;
 
-	ret = rpc_caller_invoke(caller, rpc_handle, 0, &opstatus, &resp,
-				&resp_len);
+	ret = psa_ipc_caller_invoke(rpc_handle, 0, &resp, &resp_len);
 	if (ret != TS_RPC_CALL_ACCEPTED) {
 		EMSG("psa_close: invoke failed: %d", ret);
 		return;
 	}
 
-	rpc_caller_end(caller, rpc_handle);
+	psa_ipc_caller_end(rpc_handle);
 }
diff --git a/components/rpc/ffarpc/endpoint/component.cmake b/components/rpc/ts_rpc/caller/linux/component.cmake
similarity index 71%
copy from components/rpc/ffarpc/endpoint/component.cmake
copy to components/rpc/ts_rpc/caller/linux/component.cmake
index 9e43ac5..2df09d1 100644
--- a/components/rpc/ffarpc/endpoint/component.cmake
+++ b/components/rpc/ts_rpc/caller/linux/component.cmake
@@ -8,7 +8,11 @@
 	message(FATAL_ERROR "mandatory parameter TGT is not defined.")
 endif()
 
-target_sources(${TGT} PRIVATE
-	"${CMAKE_CURRENT_LIST_DIR}/ffarpc_call_ep.c"
+
+set_property(TARGET ${TGT} APPEND PROPERTY PUBLIC_HEADER
+	"${CMAKE_CURRENT_LIST_DIR}/ts_rpc_caller_linux.h"
 	)
 
+target_sources(${TGT} PRIVATE
+	"${CMAKE_CURRENT_LIST_DIR}/ts_rpc_caller_linux.c"
+	)
diff --git a/components/rpc/ts_rpc/caller/linux/ts_rpc_caller_linux.c b/components/rpc/ts_rpc/caller/linux/ts_rpc_caller_linux.c
new file mode 100644
index 0000000..b9fca47
--- /dev/null
+++ b/components/rpc/ts_rpc/caller/linux/ts_rpc_caller_linux.c
@@ -0,0 +1,363 @@
+/*
+ * Copyright (c) 2023, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include "ts_rpc_caller_linux.h"
+
+#include <errno.h>
+#include <fcntl.h>
+#include <linux/tee.h>
+#include <stdbool.h>
+#include <stdint.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/ioctl.h>
+#include <sys/mman.h>
+#include <sys/stat.h>
+#include <sys/types.h>
+#include <unistd.h>
+#include <util.h>
+
+#define INVALID_SESS_ID		  0
+#define MAX_TEE_DEV_NUM		  16
+#define TEE_IMPL_ID_TS_TEE	  3
+#define TS_TEE_DRV_REQ_VER_MAJOR  2
+#define TS_TEE_DRV_REQ_VER_MINOR  0
+#define TS_TEE_DRV_REQ_VER_PATCH  0
+#define TS_TEE_DRV_INVALID_SHM_ID (0)
+
+struct ts_tee_dev {
+	uint16_t endpoint_id;
+	char path[16];
+};
+
+struct ts_rpc_caller_linux_context {
+	struct ts_tee_dev ts_tee_devs[MAX_TEE_DEV_NUM];
+	uint32_t session_id;
+	int fd;
+};
+
+#define TEE_IOC_OPEN_SESSION_NUM_PARAMS 0
+static rpc_status_t open_session(void *context, const struct rpc_uuid *service_uuid,
+				 uint16_t endpoint_id)
+{
+	struct ts_rpc_caller_linux_context *caller = (struct ts_rpc_caller_linux_context *)context;
+	const size_t arg_size = sizeof(struct tee_ioctl_open_session_arg) +
+				TEE_IOC_OPEN_SESSION_NUM_PARAMS * sizeof(struct tee_ioctl_param);
+	union {
+		struct tee_ioctl_open_session_arg arg;
+		uint8_t data[arg_size];
+	} buf;
+	struct tee_ioctl_open_session_arg *arg = NULL;
+	struct tee_ioctl_buf_data buf_data = { 0 };
+	struct ts_tee_dev *dev = NULL;
+	int rc = -1;
+
+	if (caller->fd >= 0 || caller->session_id != INVALID_SESS_ID) {
+		printf("%s():%d session is already opened\n", __func__, __LINE__);
+		return RPC_ERROR_INVALID_STATE;
+	}
+
+	for (int i = 0; i < ARRAY_SIZE(caller->ts_tee_devs); i++) {
+		if (caller->ts_tee_devs[i].endpoint_id == endpoint_id) {
+			dev = &caller->ts_tee_devs[i];
+			break;
+		}
+	}
+
+	if (!dev) {
+		printf("%s():%d cannot find device for 0x%04x\n", __func__, __LINE__, endpoint_id);
+		return RPC_ERROR_NOT_FOUND;
+	}
+
+	caller->fd = open(dev->path, O_RDWR);
+	if (caller->fd < 0) {
+		printf("%s():%d cannot open %s: %d\n", __func__, __LINE__, dev->path, errno);
+		return RPC_ERROR_INTERNAL;
+	}
+
+	memset(&buf, 0, sizeof(buf));
+
+	buf_data.buf_ptr = (uintptr_t)&buf;
+	buf_data.buf_len = sizeof(buf);
+
+	arg = &buf.arg;
+	arg->num_params = TEE_IOC_OPEN_SESSION_NUM_PARAMS;
+
+	memcpy(arg->uuid, service_uuid->uuid, sizeof(service_uuid->uuid));
+
+	rc = ioctl(caller->fd, TEE_IOC_OPEN_SESSION, &buf_data);
+	if (rc) {
+		close(caller->fd);
+		caller->fd = -1;
+		return RPC_ERROR_INTERNAL;
+	}
+
+	caller->session_id = arg->session;
+
+	return RPC_SUCCESS;
+}
+
+static rpc_status_t find_and_open_session(void *context, const struct rpc_uuid *service_uuid)
+{
+	struct ts_rpc_caller_linux_context *caller = (struct ts_rpc_caller_linux_context *)context;
+
+	for (int i = 0; i < ARRAY_SIZE(caller->ts_tee_devs); i++) {
+		if (!open_session(context, service_uuid, caller->ts_tee_devs[i].endpoint_id))
+			return RPC_SUCCESS;
+	}
+
+	return RPC_ERROR_INTERNAL;
+}
+
+rpc_status_t close_session(void *context)
+{
+	struct ts_rpc_caller_linux_context *caller = (struct ts_rpc_caller_linux_context *)context;
+	struct tee_ioctl_close_session_arg arg = { 0 };
+	int rc = -1;
+
+	if (caller->fd < 0) {
+		printf("%s():%d session is already closed\n", __func__, __LINE__);
+		return RPC_ERROR_INVALID_STATE;
+	}
+
+	arg.session = caller->session_id;
+
+	rc = ioctl(caller->fd, TEE_IOC_CLOSE_SESSION, &arg);
+	if (rc) {
+		printf("%s():%d failed to close session: %d\n", __func__, __LINE__, errno);
+		return RPC_ERROR_INTERNAL;
+	}
+
+	close(caller->fd);
+	caller->fd = -1;
+	caller->session_id = INVALID_SESS_ID;
+
+	return RPC_SUCCESS;
+}
+
+rpc_status_t create_shared_memory(void *context, size_t size,
+				  struct rpc_caller_shared_memory *shared_memory)
+{
+	struct ts_rpc_caller_linux_context *caller = (struct ts_rpc_caller_linux_context *)context;
+	struct tee_ioctl_shm_alloc_data data = { .size = size };
+	int shm_fd = -1;
+
+	if (!size) {
+		shared_memory->buffer = NULL;
+		shared_memory->size = 0;
+		shared_memory->id = TS_TEE_DRV_INVALID_SHM_ID;
+
+		return RPC_SUCCESS;
+	}
+
+	shm_fd = ioctl(caller->fd, TEE_IOC_SHM_ALLOC, &data);
+	if (shm_fd < 0) {
+		printf("%s():%d failed to create shared memory: %d\n", __func__, __LINE__, errno);
+		return RPC_ERROR_INTERNAL;
+	}
+
+	shared_memory->buffer =
+		mmap(NULL, data.size, PROT_READ | PROT_WRITE, MAP_SHARED, shm_fd, 0);
+	if (shared_memory->buffer == (void *)MAP_FAILED) {
+		printf("%s():%d failed to map shared memory: %d\n", __func__, __LINE__, errno);
+		close(shm_fd);
+		return RPC_ERROR_INTERNAL;
+	}
+	close(shm_fd);
+	shared_memory->size = data.size;
+	shared_memory->id = data.id;
+
+	return RPC_SUCCESS;
+}
+
+rpc_status_t release_shared_memory(void *context, struct rpc_caller_shared_memory *shared_memory)
+{
+	(void)context;
+
+	if (shared_memory->id == TS_TEE_DRV_INVALID_SHM_ID)
+		return RPC_SUCCESS;
+
+	if (munmap(shared_memory->buffer, shared_memory->size)) {
+		printf("%s():%d failed to unmap shared memory: %d\n", __func__, __LINE__, errno);
+		return RPC_ERROR_INTERNAL;
+	}
+
+	*shared_memory = (struct rpc_caller_shared_memory){ 0 };
+
+	return RPC_SUCCESS;
+}
+
+#define TEE_IOC_INVOKE_NUM_PARAMS 1
+static rpc_status_t call(void *context, uint16_t opcode,
+			 struct rpc_caller_shared_memory *shared_memory, size_t request_length,
+			 size_t *response_length, service_status_t *service_status)
+{
+	struct ts_rpc_caller_linux_context *caller = (struct ts_rpc_caller_linux_context *)context;
+	const size_t arg_size = sizeof(struct tee_ioctl_invoke_arg) +
+				TEE_IOC_INVOKE_NUM_PARAMS * sizeof(struct tee_ioctl_param);
+	union {
+		struct tee_ioctl_invoke_arg arg;
+		uint8_t data[arg_size];
+	} buf;
+	struct tee_ioctl_buf_data buf_data = { 0 };
+	struct tee_ioctl_invoke_arg *arg = NULL;
+	struct tee_ioctl_param *params = NULL;
+	int rc = -1;
+
+	memset(&buf, 0, sizeof(buf));
+
+	buf_data.buf_ptr = (uintptr_t)&buf;
+	buf_data.buf_len = sizeof(buf);
+
+	arg = &buf.arg;
+	arg->func = opcode;
+	arg->session = caller->session_id;
+	arg->num_params = TEE_IOC_INVOKE_NUM_PARAMS;
+	params = (struct tee_ioctl_param *)(arg + 1);
+
+	params[0].attr = TEE_IOCTL_PARAM_ATTR_TYPE_VALUE_INOUT;
+	params[0].a = shared_memory->id;
+	params[0].b = request_length;
+	params[0].c = 0;
+
+	rc = ioctl(caller->fd, TEE_IOC_INVOKE, &buf_data);
+	if (rc) {
+		printf("%s():%d failed to invoke command: %d\n", __func__, __LINE__, errno);
+		return RPC_ERROR_INTERNAL;
+	}
+
+	*response_length = params[0].a;
+	*service_status = (int)arg->ret;
+
+	return RPC_SUCCESS;
+}
+
+static bool ts_tee_drv_check_version(void)
+{
+	unsigned int major = 0;
+	unsigned int minor = 0;
+	unsigned int patch = 0;
+	FILE *f = NULL;
+	int cnt = 0;
+
+	f = fopen("/sys/module/arm_tstee/version", "r");
+	if (f) {
+		cnt = fscanf(f, "%u.%u.%u", &major, &minor, &patch);
+		fclose(f);
+
+		if (cnt != 3) {
+			printf("error: cannot read TS TEE driver version\n");
+			return false;
+		}
+	} else {
+		printf("error: TS TEE driver not available\n");
+		return false;
+	}
+
+	if (major != TS_TEE_DRV_REQ_VER_MAJOR)
+		goto err;
+
+	if (minor < TS_TEE_DRV_REQ_VER_MINOR)
+		goto err;
+
+	if (minor == TS_TEE_DRV_REQ_VER_MINOR)
+		if (patch < TS_TEE_DRV_REQ_VER_PATCH)
+			goto err;
+
+	return true;
+
+err:
+	printf("error: TS TEE driver is v%u.%u.%u but required v%u.%u.%u\n", major, minor, patch,
+	       TS_TEE_DRV_REQ_VER_MAJOR, TS_TEE_DRV_REQ_VER_MINOR, TS_TEE_DRV_REQ_VER_PATCH);
+
+	return false;
+}
+
+static void ts_tee_drv_discover(struct ts_tee_dev *ts_tee_devs, size_t count)
+{
+	struct tee_ioctl_version_data vers = { 0 };
+	unsigned int tee_file_index = 0;
+	unsigned int ts_tee_dev_index = 0;
+	char path[16];
+	int rc = -1;
+	int fd = -1;
+
+	for (tee_file_index = 0; tee_file_index < MAX_TEE_DEV_NUM && ts_tee_dev_index < count;
+	     tee_file_index++) {
+		snprintf(path, sizeof(path), "/dev/tee%u", tee_file_index);
+
+		fd = open(path, O_RDWR);
+		if (fd < 0)
+			continue;
+
+		memset(&vers, 0, sizeof(vers));
+
+		rc = ioctl(fd, TEE_IOC_VERSION, &vers);
+		close(fd);
+
+		if (!rc && vers.impl_id == TEE_IMPL_ID_TS_TEE) {
+			ts_tee_devs[ts_tee_dev_index].endpoint_id = vers.impl_caps;
+			memcpy(ts_tee_devs[ts_tee_dev_index].path, path, sizeof(path));
+			ts_tee_dev_index++;
+		}
+	}
+}
+
+rpc_status_t ts_rpc_caller_linux_init(struct rpc_caller_interface *rpc_caller)
+{
+	struct ts_rpc_caller_linux_context *context = NULL;
+
+	if (!rpc_caller || rpc_caller->context)
+		return RPC_ERROR_INVALID_VALUE;
+
+	if (!ts_tee_drv_check_version())
+		return RPC_ERROR_INTERNAL;
+
+	context = (struct ts_rpc_caller_linux_context *)calloc(
+		1, sizeof(struct ts_rpc_caller_linux_context));
+	if (!context)
+		return RPC_ERROR_INTERNAL;
+
+	context->fd = -1;
+	context->session_id = INVALID_SESS_ID;
+
+	rpc_caller->context = context;
+	rpc_caller->open_session = open_session;
+	rpc_caller->find_and_open_session = find_and_open_session;
+	rpc_caller->close_session = close_session;
+	rpc_caller->create_shared_memory = create_shared_memory;
+	rpc_caller->release_shared_memory = release_shared_memory;
+	rpc_caller->call = call;
+
+	ts_tee_drv_discover(context->ts_tee_devs, ARRAY_SIZE(context->ts_tee_devs));
+
+	return RPC_SUCCESS;
+}
+
+rpc_status_t ts_rpc_caller_linux_deinit(struct rpc_caller_interface *rpc_caller)
+{
+	struct ts_rpc_caller_linux_context *caller = NULL;
+
+	if (!rpc_caller || !rpc_caller->context)
+		return RPC_ERROR_INVALID_VALUE;
+
+	caller = (struct ts_rpc_caller_linux_context *)rpc_caller->context;
+
+	if (caller->session_id != INVALID_SESS_ID) {
+		close_session(rpc_caller);
+		caller->session_id = INVALID_SESS_ID;
+	}
+
+	if (caller->fd >= 0) {
+		close(caller->fd);
+		caller->fd = -1;
+	}
+
+	free(rpc_caller->context);
+
+	return RPC_SUCCESS;
+}
diff --git a/components/rpc/ts_rpc/caller/linux/ts_rpc_caller_linux.h b/components/rpc/ts_rpc/caller/linux/ts_rpc_caller_linux.h
new file mode 100644
index 0000000..26c6ce8
--- /dev/null
+++ b/components/rpc/ts_rpc/caller/linux/ts_rpc_caller_linux.h
@@ -0,0 +1,26 @@
+/*
+ * Copyright (c) 2023, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef TS_RPC_CALLER_LINUX_H
+#define TS_RPC_CALLER_LINUX_H
+
+#include "components/rpc/common/caller/rpc_caller.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+RPC_CALLER_EXPORTED
+rpc_status_t ts_rpc_caller_linux_init(struct rpc_caller_interface *rpc_caller);
+
+RPC_CALLER_EXPORTED
+rpc_status_t ts_rpc_caller_linux_deinit(struct rpc_caller_interface *rpc_caller);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* TS_RPC_CALLER_LINUX_H */
diff --git a/components/rpc/ffarpc/endpoint/component.cmake b/components/rpc/ts_rpc/caller/sp/component.cmake
similarity index 72%
copy from components/rpc/ffarpc/endpoint/component.cmake
copy to components/rpc/ts_rpc/caller/sp/component.cmake
index 9e43ac5..5047202 100644
--- a/components/rpc/ffarpc/endpoint/component.cmake
+++ b/components/rpc/ts_rpc/caller/sp/component.cmake
@@ -8,7 +8,11 @@
 	message(FATAL_ERROR "mandatory parameter TGT is not defined.")
 endif()
 
-target_sources(${TGT} PRIVATE
-	"${CMAKE_CURRENT_LIST_DIR}/ffarpc_call_ep.c"
+
+set_property(TARGET ${TGT} APPEND PROPERTY PUBLIC_HEADER
+	"${CMAKE_CURRENT_LIST_DIR}/ts_rpc_caller_sp.h"
 	)
 
+target_sources(${TGT} PRIVATE
+	"${CMAKE_CURRENT_LIST_DIR}/ts_rpc_caller_sp.c"
+	)
diff --git a/components/rpc/ts_rpc/caller/sp/ts_rpc_caller_sp.c b/components/rpc/ts_rpc/caller/sp/ts_rpc_caller_sp.c
new file mode 100644
index 0000000..ffa3d9b
--- /dev/null
+++ b/components/rpc/ts_rpc/caller/sp/ts_rpc_caller_sp.c
@@ -0,0 +1,523 @@
+/*
+ * Copyright (c) 2023, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include "ts_rpc_caller_sp.h"
+#include <sp_memory_management.h>
+#include <sp_messaging.h>
+#include <string.h>
+#include <malloc.h>
+#include <ffa_api.h>
+#include <inttypes.h>
+#include <stdlib.h>
+#include <stdbool.h>
+#include <stdint.h>
+#include <stdio.h>
+#include <trace.h>
+
+#ifndef MAX_RPC_ENDPOINT_NUM
+#define MAX_RPC_ENDPOINT_NUM ((uint8_t)(16))
+#endif /* MAX_RPC_ENDPOINT_NUM */
+
+#ifndef MAX_SHM_NUM
+#define MAX_SHM_NUM ((uint8_t)(16))
+#endif /* MAX_SHM_NUM */
+
+static const struct sp_uuid ts_ffa_uuid = {
+	.uuid = { 0xbd, 0xcd, 0x76, 0xd7, 0x82, 0x5e, 0x47, 0x51,
+		  0x96, 0x3b, 0x86, 0xd4, 0xf8, 0x49, 0x43, 0xac}
+};
+
+struct ts_rpc_caller_sp_context {
+	uint16_t own_id;
+	uint16_t endpoint_id;
+	uint8_t interface_id;
+	struct rpc_caller_shared_memory shared_memories[MAX_SHM_NUM];
+	bool has_opened_session;
+};
+
+static struct rpc_caller_shared_memory *find_shared_memory_descriptor(
+	struct ts_rpc_caller_sp_context *context, uint64_t id)
+{
+	size_t i = 0;
+
+	for (i = 0; i < MAX_SHM_NUM; i++) {
+		if (context->shared_memories[i].id == id)
+			return &context->shared_memories[i];
+	}
+
+	return NULL;
+}
+
+rpc_status_t open_session(void *context, const struct rpc_uuid *service_uuid, uint16_t endpoint_id)
+{
+	struct ts_rpc_caller_sp_context *this_context = (struct ts_rpc_caller_sp_context *)context;
+	sp_result sp_res = SP_RESULT_INTERNAL_ERROR;
+	rpc_status_t status = RPC_ERROR_INTERNAL;
+	struct sp_msg req = { 0 };
+	struct sp_msg resp = { 0 };
+	uint8_t interface_id = 0;
+
+	if (!context || !service_uuid) {
+		EMSG("invalid arguments");
+		status = RPC_ERROR_INVALID_VALUE;
+		goto out;
+	}
+
+	if (this_context->has_opened_session) {
+		EMSG("the session is already open");
+		status = RPC_ERROR_INVALID_STATE;
+		goto out;
+	}
+
+	if (endpoint_id == this_context->own_id) {
+		EMSG("cannot open RPC session to self");
+		status = RPC_ERROR_INVALID_VALUE;
+		goto out;
+	}
+
+	req.source_id = this_context->own_id;
+	req.destination_id = endpoint_id;
+	req.is_64bit_message = false;
+
+	ts_rpc_abi_set_management_interface_id(req.args.args32);
+	ts_rpc_abi_set_opcode(req.args.args32, TS_RPC_ABI_MANAGEMENT_OPCODE_VERSION);
+
+	sp_res = sp_msg_send_direct_req(&req, &resp);
+	if (sp_res != SP_RESULT_OK) {
+		EMSG("sp_msg_send_direct_req(): error %"PRId32, sp_res);
+		goto out;
+	}
+
+	if (ts_rpc_abi_get_version(resp.args.args32) != TS_RPC_PROTOCOL_VERSION) {
+		EMSG("endpoint %"PRIu16" does not support protocol version %"PRIu32"",
+			endpoint_id, TS_RPC_PROTOCOL_VERSION);
+		goto out;
+	}
+
+	memset(req.args.args32, 0, sizeof(req.args.args32));
+	memset(resp.args.args32, 0, sizeof(resp.args.args32));
+
+	ts_rpc_abi_set_management_interface_id(req.args.args32);
+	ts_rpc_abi_set_opcode(req.args.args32, TS_RPC_ABI_MANAGEMENT_OPCODE_INTERFACE_ID_QUERY);
+	ts_rpc_abi_set_uuid(req.args.args32, service_uuid);
+
+	sp_res = sp_msg_send_direct_req(&req, &resp);
+	if (sp_res != SP_RESULT_OK) {
+		EMSG("sp_msg_send_direct_req(): error %"PRId32, sp_res);
+		goto out;
+	}
+
+	status = ts_rpc_abi_get_rpc_status(resp.args.args32);
+	if (status == RPC_SUCCESS) {
+		interface_id = ts_rpc_abi_get_queried_interface_id(resp.args.args32);
+
+		this_context->endpoint_id = endpoint_id;
+		this_context->interface_id = interface_id;
+		this_context->has_opened_session = true;
+	}
+
+out:
+	return status;
+}
+
+rpc_status_t find_and_open_session(void *context, const struct rpc_uuid *service_uuid)
+{
+	struct ts_rpc_caller_sp_context *this_context = (struct ts_rpc_caller_sp_context *)context;
+	sp_result sp_res = SP_RESULT_INTERNAL_ERROR;
+	ffa_result ffa_res = FFA_INVALID_PARAMETERS;
+	rpc_status_t status = RPC_SUCCESS;
+	uint32_t rpc_endpoint_count = MAX_RPC_ENDPOINT_NUM;
+	struct sp_partition_info rpc_endpoints[MAX_RPC_ENDPOINT_NUM] = {0};
+	uint32_t i = 0;
+
+	if (!context || !service_uuid) {
+		EMSG("invalid arguments");
+		return RPC_ERROR_INVALID_VALUE;
+	}
+
+	if (this_context->has_opened_session) {
+		EMSG("the session is already open");
+		return RPC_ERROR_INVALID_STATE;
+	}
+
+	sp_res = sp_discovery_partition_info_get(&ts_ffa_uuid, rpc_endpoints, &rpc_endpoint_count);
+	if (sp_res != SP_RESULT_OK) {
+		EMSG("sp_discovery_partition_info_get(): error %"PRId32, sp_res);
+		return RPC_ERROR_INTERNAL;
+	}
+
+	ffa_res = ffa_rx_release();
+	if (ffa_res != FFA_OK) {
+		EMSG("ffa_rx_release(): error %"PRId32, ffa_res);
+		return 0;
+	}
+
+	for (i = 0; i < rpc_endpoint_count; i++) {
+		if (rpc_endpoints[i].partition_id == this_context->own_id)
+			continue;
+
+		status = open_session(context, service_uuid, rpc_endpoints[i].partition_id);
+
+		if (status == RPC_SUCCESS)
+			return RPC_SUCCESS;
+	}
+
+	EMSG("no SP found supporting protocol version %"PRIu32" and the requested service",
+	     TS_RPC_PROTOCOL_VERSION);
+	return RPC_ERROR_INTERNAL;
+}
+
+rpc_status_t create_shared_memory(void *context, size_t size,
+				  struct rpc_caller_shared_memory *shared_memory)
+{
+	struct ts_rpc_caller_sp_context *this_context = (struct ts_rpc_caller_sp_context *)context;
+	sp_result sp_res = SP_RESULT_OK;
+	rpc_status_t status = RPC_ERROR_INTERNAL;
+	struct sp_msg req = { 0 };
+	struct sp_msg resp = { 0 };
+
+	struct sp_memory_descriptor desc = { 0 };
+	struct sp_memory_access_descriptor acc_desc = { 0 };
+	struct sp_memory_region region = { 0 };
+
+	uint64_t handle = 0;
+	void *buffer = NULL;
+	struct rpc_caller_shared_memory *stored_shared_memory_desc = NULL;
+
+	if (!context || !shared_memory) {
+		EMSG("invalid arguments");
+		status = RPC_ERROR_INVALID_VALUE;
+		goto err;
+	}
+
+	if (!this_context->has_opened_session) {
+		EMSG("session should be opened before creating shared memory");
+		status = RPC_ERROR_INVALID_STATE;
+		goto err;
+	}
+
+	if (size == 0) {
+		shared_memory->buffer = NULL;
+		shared_memory->size = 0;
+		shared_memory->id = FFA_MEM_HANDLE_INVALID;
+
+		return RPC_SUCCESS;
+	}
+
+	stored_shared_memory_desc = find_shared_memory_descriptor(this_context,
+								  FFA_MEM_HANDLE_INVALID);
+	if (!stored_shared_memory_desc) {
+		status = RPC_ERROR_INTERNAL;
+		EMSG("cannot find empty shared memory descriptor");
+		goto err;
+	}
+
+	size = ROUNDUP(size, FFA_MEM_TRANSACTION_PAGE_SIZE);
+	buffer = memalign(FFA_MEM_TRANSACTION_PAGE_SIZE, size);
+	if (!buffer) {
+		EMSG("memalign(): failed to allocate %lu bytes with %"PRIu32" alignment", size,
+		     FFA_MEM_TRANSACTION_PAGE_SIZE);
+		status = RPC_ERROR_INTERNAL;
+		goto err;
+	}
+	memset(buffer, 0, size);
+
+	desc.sender_id = this_context->own_id;
+	desc.memory_type = sp_memory_type_normal_memory;
+	desc.mem_region_attr.normal_memory.cacheability = sp_cacheability_write_back;
+	desc.mem_region_attr.normal_memory.shareability = sp_shareability_inner_shareable;
+
+	acc_desc.data_access = sp_data_access_read_write;
+	acc_desc.instruction_access = sp_instruction_access_not_specified;
+	acc_desc.receiver_id = this_context->endpoint_id;
+
+	region.address = buffer;
+	region.page_count = (uint32_t)ROUNDUP_DIV(size, FFA_MEM_TRANSACTION_PAGE_SIZE);
+
+	sp_res = sp_memory_share(&desc, &acc_desc, 1, &region, 1, &handle);
+	if (sp_res != SP_RESULT_OK) {
+		EMSG("sp_memory_share(): error %"PRId32, sp_res);
+		status = RPC_ERROR_INTERNAL;
+		goto err;
+	}
+
+	req.source_id = this_context->own_id;
+	req.destination_id = this_context->endpoint_id;
+	req.is_64bit_message = false;
+
+	ts_rpc_abi_set_management_interface_id(req.args.args32);
+	ts_rpc_abi_set_opcode(req.args.args32, TS_RPC_ABI_MANAGEMENT_OPCODE_MEMORY_RETRIEVE);
+	ts_rpc_abi_set_memory_handle(req.args.args32, handle);
+	ts_rpc_abi_set_memory_tag(req.args.args32, 0);
+
+	sp_res = sp_msg_send_direct_req(&req, &resp);
+	if (sp_res != SP_RESULT_OK) {
+		EMSG("sp_msg_send_direct_req(): error %"PRId32, sp_res);
+		status = RPC_ERROR_INTERNAL;
+		goto err;
+	}
+
+	status = ts_rpc_abi_get_rpc_status(resp.args.args32);
+	if (status != RPC_SUCCESS) {
+		EMSG("RPC endpoint error: %"PRId32, status);
+
+		sp_res = sp_memory_reclaim(handle, 0);
+		if (sp_res != SP_RESULT_OK)
+			EMSG("sp_memory_reclaim(): error %"PRId32, sp_res);
+
+		status = RPC_ERROR_INTERNAL;
+		goto err;
+	}
+
+	shared_memory->id = handle;
+	shared_memory->buffer = buffer;
+	shared_memory->size = size;
+
+	*stored_shared_memory_desc = *shared_memory;
+
+	return RPC_SUCCESS;
+
+err:
+	if (buffer)
+		free(buffer);
+	return status;
+}
+
+rpc_status_t release_shared_memory(void *context, struct rpc_caller_shared_memory *shared_memory)
+{
+	struct ts_rpc_caller_sp_context *this_context = (struct ts_rpc_caller_sp_context *)context;
+	sp_result sp_res = SP_RESULT_OK;
+	rpc_status_t status = RPC_ERROR_INTERNAL;
+	struct sp_msg req = { 0 };
+	struct sp_msg resp = { 0 };
+
+	struct rpc_caller_shared_memory *to_release = NULL;
+
+	if (!context || !shared_memory) {
+		EMSG("invalid arguments");
+		return RPC_ERROR_INVALID_VALUE;
+	}
+
+	if (shared_memory->id == FFA_MEM_HANDLE_INVALID)
+		return RPC_SUCCESS;
+
+	to_release = find_shared_memory_descriptor(this_context, shared_memory->id);
+	if (!to_release) {
+		EMSG("cannot find shared memory with specified handle");
+		return RPC_ERROR_INTERNAL;
+	}
+
+	req.source_id = this_context->own_id;
+	req.destination_id = this_context->endpoint_id;
+	req.is_64bit_message = false;
+
+	ts_rpc_abi_set_management_interface_id(req.args.args32);
+	ts_rpc_abi_set_opcode(req.args.args32, TS_RPC_ABI_MANAGEMENT_OPCODE_MEMORY_RELINQUISH);
+	ts_rpc_abi_set_memory_handle(req.args.args32, to_release->id);
+
+	sp_res = sp_msg_send_direct_req(&req, &resp);
+	if (sp_res != SP_RESULT_OK) {
+		EMSG("sp_msg_send_direct_req(): error %"PRId32, sp_res);
+		return RPC_ERROR_INTERNAL;
+	}
+
+	status = ts_rpc_abi_get_rpc_status(resp.args.args32);
+	if (status != RPC_SUCCESS) {
+		/*
+		 * The RPC endpoint failed to relinquish the shared memory but
+		 * still worth trying to reclaim the memory beside emitting an
+		 * error message.
+		 */
+		EMSG("RPC endpoint error %"PRId32, status);
+	}
+
+	sp_res = sp_memory_reclaim(to_release->id, 0);
+	if (sp_res != SP_RESULT_OK) {
+		EMSG("sp_memory_reclaim(): error %"PRId32, sp_res);
+		return RPC_ERROR_INTERNAL;
+	}
+
+	/*
+	 * Only remove shared memory entry and free it if both relinquish AND reclaim were
+	 * successful.
+	 */
+	if (status == RPC_SUCCESS) {
+		free(to_release->buffer);
+
+		to_release->id = FFA_MEM_HANDLE_INVALID;
+		to_release->buffer = NULL;
+		to_release->size = 0;
+	}
+
+	return status;
+}
+
+rpc_status_t call(void *context, uint16_t opcode, struct rpc_caller_shared_memory *shared_memory,
+		  size_t request_length, size_t *response_length, service_status_t *service_status)
+{
+
+	struct ts_rpc_caller_sp_context *this_context = (struct ts_rpc_caller_sp_context *)context;
+	sp_result sp_res = SP_RESULT_OK;
+	rpc_status_t status = RPC_ERROR_INTERNAL;
+	struct sp_msg req = { 0 };
+	struct sp_msg resp = { 0 };
+
+	if (!context || !shared_memory || !response_length || !service_status) {
+		EMSG("invalid arguments");
+		status = RPC_ERROR_INVALID_VALUE;
+		goto out;
+	}
+
+	if (!this_context->has_opened_session) {
+		EMSG("session should be opened before calling a service");
+		status = RPC_ERROR_INVALID_STATE;
+		goto out;
+	}
+
+	if (shared_memory->id != FFA_MEM_HANDLE_INVALID) {
+		/* Checking if the shared memory was allocated by us */
+		struct rpc_caller_shared_memory *stored_shared_memory = NULL;
+
+		stored_shared_memory = find_shared_memory_descriptor(this_context,
+								     shared_memory->id);
+		if (!stored_shared_memory) {
+			EMSG("cannot find shared memory with specified handle");
+			status = RPC_ERROR_INTERNAL;
+			goto out;
+		}
+	} else {
+		/* Call with no shared memory, the request length must be 0 */
+		if (request_length != 0) {
+			status = RPC_ERROR_INVALID_VALUE;
+			goto out;
+		}
+	}
+
+	req.source_id = this_context->own_id;
+	req.destination_id = this_context->endpoint_id;
+	req.is_64bit_message = false;
+
+	ts_rpc_abi_set_interface_id(req.args.args32, this_context->interface_id);
+	ts_rpc_abi_set_opcode(req.args.args32, opcode);
+	ts_rpc_abi_set_memory_handle(req.args.args32, shared_memory->id);
+	ts_rpc_abi_set_request_length(req.args.args32, request_length);
+	ts_rpc_abi_set_client_id(req.args.args32, 0);
+
+	sp_res = sp_msg_send_direct_req(&req, &resp);
+	if (sp_res != SP_RESULT_OK) {
+		EMSG("sp_msg_send_direct_req(): error %"PRId32, sp_res);
+		status = RPC_ERROR_INTERNAL;
+		goto out;
+	}
+
+	status = ts_rpc_abi_get_rpc_status(resp.args.args32);
+	if (status != RPC_SUCCESS) {
+		EMSG("RPC endpoint error %"PRId32, status);
+		goto out;
+	}
+
+	*service_status = ts_rpc_abi_get_service_status(resp.args.args32);
+	*response_length = ts_rpc_abi_get_response_length(resp.args.args32);
+
+out:
+	return status;
+}
+
+rpc_status_t close_session(void *context)
+{
+	struct ts_rpc_caller_sp_context *this_context = (struct ts_rpc_caller_sp_context *)context;
+	rpc_status_t status = RPC_ERROR_INTERNAL;
+
+	uint8_t i = 0;
+
+	if (!context) {
+		EMSG("invalid arguments");
+		return RPC_ERROR_INVALID_VALUE;
+	}
+
+	if (!this_context->has_opened_session) {
+		EMSG("session is already closed");
+		status = RPC_ERROR_INVALID_STATE;
+		goto out;
+	}
+
+	for (i = 0; i < MAX_SHM_NUM; i++) {
+		if (this_context->shared_memories[i].id != FFA_MEM_HANDLE_INVALID) {
+			status = release_shared_memory(context, &this_context->shared_memories[i]);
+
+			if (status != RPC_SUCCESS) {
+				EMSG("failed to release shared memory with handle %"PRIu64"",
+					this_context->shared_memories[i].id);
+				goto out;
+			}
+		}
+	}
+
+	this_context->endpoint_id = 0;
+	this_context->interface_id = 0;
+	this_context->has_opened_session = false;
+
+	return RPC_SUCCESS;
+
+out:
+	return status;
+}
+
+rpc_status_t ts_rpc_caller_sp_init(struct rpc_caller_interface *rpc_caller)
+{
+	struct ts_rpc_caller_sp_context *context = NULL;
+	uint16_t own_id;
+	uint8_t i = 0;
+
+	if (!rpc_caller || rpc_caller->context)
+		return RPC_ERROR_INVALID_VALUE;
+
+	if (sp_discovery_own_id_get(&own_id) != SP_RESULT_OK)
+		return RPC_ERROR_INTERNAL;
+
+	context = (struct ts_rpc_caller_sp_context *)
+		calloc(1, sizeof(struct ts_rpc_caller_sp_context));
+	if (!context)
+		return RPC_ERROR_INTERNAL;
+
+	for (i = 0; i < MAX_SHM_NUM; i++)
+		context->shared_memories[i].id = FFA_MEM_HANDLE_INVALID;
+
+	context->own_id = own_id;
+
+	rpc_caller->context = context;
+	rpc_caller->open_session = open_session;
+	rpc_caller->find_and_open_session = find_and_open_session;
+	rpc_caller->close_session = close_session;
+	rpc_caller->create_shared_memory = create_shared_memory;
+	rpc_caller->release_shared_memory = release_shared_memory;
+	rpc_caller->call = call;
+
+	return RPC_SUCCESS;
+}
+
+rpc_status_t ts_rpc_caller_sp_deinit(struct rpc_caller_interface *rpc_caller)
+{
+	struct ts_rpc_caller_sp_context *this_context =
+		(struct ts_rpc_caller_sp_context *)rpc_caller->context;
+	rpc_status_t status = RPC_ERROR_INTERNAL;
+
+	if (!rpc_caller || !rpc_caller->context)
+		return RPC_ERROR_INVALID_VALUE;
+
+	if (!this_context->has_opened_session) {
+		status = rpc_caller_close_session(rpc_caller);
+		if (status != RPC_SUCCESS) {
+			EMSG("failed to close session");
+			return RPC_ERROR_INTERNAL;
+		}
+	}
+
+	free(rpc_caller->context);
+	rpc_caller->context = NULL;
+
+	return RPC_SUCCESS;
+}
diff --git a/components/rpc/ts_rpc/caller/sp/ts_rpc_caller_sp.h b/components/rpc/ts_rpc/caller/sp/ts_rpc_caller_sp.h
new file mode 100644
index 0000000..07c51b5
--- /dev/null
+++ b/components/rpc/ts_rpc/caller/sp/ts_rpc_caller_sp.h
@@ -0,0 +1,33 @@
+/*
+ * Copyright (c) 2023, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef TS_RPC_CALLER_SP_H
+#define TS_RPC_CALLER_SP_H
+
+#include "rpc_status.h"
+#include "rpc_uuid.h"
+#include "sp_discovery.h"
+#include <common/uuid/uuid.h>
+#include "components/rpc/ts_rpc/common/ts_rpc_abi.h"
+#include "components/rpc/common/caller/rpc_caller.h"
+#include "util.h"
+
+/* Protocol version*/
+#define TS_RPC_PROTOCOL_VERSION		(1)
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+rpc_status_t ts_rpc_caller_sp_init(struct rpc_caller_interface *rpc_caller);
+
+rpc_status_t ts_rpc_caller_sp_deinit(struct rpc_caller_interface *rpc_caller);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* TS_RPC_CALLER_SP_H */
diff --git a/components/rpc/ffarpc/endpoint/component.cmake b/components/rpc/ts_rpc/common/component.cmake
similarity index 73%
copy from components/rpc/ffarpc/endpoint/component.cmake
copy to components/rpc/ts_rpc/common/component.cmake
index 9e43ac5..71d4e8e 100644
--- a/components/rpc/ffarpc/endpoint/component.cmake
+++ b/components/rpc/ts_rpc/common/component.cmake
@@ -8,7 +8,11 @@
 	message(FATAL_ERROR "mandatory parameter TGT is not defined.")
 endif()
 
-target_sources(${TGT} PRIVATE
-	"${CMAKE_CURRENT_LIST_DIR}/ffarpc_call_ep.c"
+
+set_property(TARGET ${TGT} APPEND PROPERTY PUBLIC_HEADER
+	"${CMAKE_CURRENT_LIST_DIR}/ts_rpc_abi.h"
 	)
 
+target_sources(${TGT} PRIVATE
+	"${CMAKE_CURRENT_LIST_DIR}/ts_rpc_abi.c"
+	)
diff --git a/components/rpc/ts_rpc/common/test/test_ts_rpc_abi.cpp b/components/rpc/ts_rpc/common/test/test_ts_rpc_abi.cpp
new file mode 100644
index 0000000..463792b
--- /dev/null
+++ b/components/rpc/ts_rpc/common/test/test_ts_rpc_abi.cpp
@@ -0,0 +1,191 @@
+/*
+ * Copyright (c) 2023, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include "../ts_rpc_abi.h"
+#include <stdint.h>
+#include <string.h>
+#include <CppUTest/TestHarness.h>
+
+TEST_GROUP(ts_rpc_abi) {
+	TEST_SETUP() {
+		memset(regs, 0x00, sizeof(regs));
+	}
+
+	void set_regs(uint32_t a0, uint32_t a1, uint32_t a2, uint32_t a3, uint32_t a4)
+	{
+		regs[0] = a0;
+		regs[1] = a1;
+		regs[2] = a2;
+		regs[3] = a3;
+		regs[4] = a4;
+	}
+
+	void check_regs(uint32_t a0, uint32_t a1, uint32_t a2, uint32_t a3, uint32_t a4)
+	{
+		UNSIGNED_LONGS_EQUAL(a0, regs[0]);
+		UNSIGNED_LONGS_EQUAL(a1, regs[1]);
+		UNSIGNED_LONGS_EQUAL(a2, regs[2]);
+		UNSIGNED_LONGS_EQUAL(a3, regs[3]);
+		UNSIGNED_LONGS_EQUAL(a4, regs[4]);
+	}
+
+	uint32_t regs[5];
+};
+
+TEST(ts_rpc_abi, flags)
+{
+	const uint8_t flags = 0x3f;
+
+	ts_rpc_abi_set_flags(regs, flags);
+	check_regs(0x3f000000, 0, 0, 0, 0);
+
+	UNSIGNED_LONGS_EQUAL(flags, ts_rpc_abi_get_flags(regs));
+}
+
+TEST(ts_rpc_abi, interface_id)
+{
+	const uint8_t interface_id = 0xa5;
+
+	ts_rpc_abi_set_interface_id(regs, interface_id);
+	check_regs(0x00a50000, 0, 0, 0, 0);
+
+	UNSIGNED_LONGS_EQUAL(interface_id, ts_rpc_abi_get_interface_id(regs));
+}
+
+TEST(ts_rpc_abi, management_interface_id)
+{
+	CHECK_FALSE(ts_rpc_abi_is_management_interface_id(regs));
+
+	ts_rpc_abi_set_management_interface_id(regs);
+	check_regs(0x00ff0000, 0, 0, 0, 0);
+
+	CHECK_TRUE(ts_rpc_abi_is_management_interface_id(regs));
+}
+
+TEST(ts_rpc_abi, opcode)
+{
+	const uint16_t opcode = 0x8765;
+
+	ts_rpc_abi_set_opcode(regs, 0x8765);
+	check_regs(0x00008765, 0, 0, 0, 0);
+
+	UNSIGNED_LONGS_EQUAL(0x8765, ts_rpc_abi_get_opcode(regs));
+}
+
+TEST(ts_rpc_abi, copy_control_reg)
+{
+	uint32_t source_regs[5] = { 0xfedcba98, 0, 0, 0, 0 };
+
+	ts_rpc_abi_copy_control_reg(regs, source_regs);
+
+	check_regs(0xfedcba98, 0, 0, 0, 0);
+}
+
+TEST(ts_rpc_abi, version)
+{
+	const uint32_t version = 0x98765432;
+
+	ts_rpc_abi_set_version(regs, version);
+	check_regs(0, version, 0, 0, 0);
+
+	UNSIGNED_LONGS_EQUAL(version, ts_rpc_abi_get_version(regs));
+
+}
+
+TEST(ts_rpc_abi, memory_handle)
+{
+	const uint64_t handle = 0xfedcba9876543210;
+
+	ts_rpc_abi_set_memory_handle(regs, handle);
+	check_regs(0, 0x76543210, 0xfedcba98, 0, 0);
+
+	UNSIGNED_LONGLONGS_EQUAL(handle, ts_rpc_abi_get_memory_handle(regs));
+}
+
+TEST(ts_rpc_abi, memory_tag)
+{
+	const uint64_t tag = 0xfedcba9876543210;
+
+	ts_rpc_abi_set_memory_tag(regs, tag);
+	check_regs(0, 0, 0, 0x76543210, 0xfedcba98);
+
+	UNSIGNED_LONGLONGS_EQUAL(tag, ts_rpc_abi_get_memory_tag(regs));
+}
+
+TEST(ts_rpc_abi, rpc_status)
+{
+	const uint32_t rpc_status = 0x89abcdef;
+
+	ts_rpc_abi_set_rpc_status(regs, rpc_status);
+	check_regs(0, rpc_status, 0, 0, 0);
+
+	UNSIGNED_LONGS_EQUAL(rpc_status, ts_rpc_abi_get_rpc_status(regs));
+}
+
+TEST(ts_rpc_abi, service_status)
+{
+	const uint32_t service_status = 0x89abcdef;
+
+	ts_rpc_abi_set_service_status(regs, service_status);
+	check_regs(0, 0, service_status, 0, 0);
+
+	UNSIGNED_LONGS_EQUAL(service_status, ts_rpc_abi_get_service_status(regs));
+}
+
+TEST(ts_rpc_abi, uuid)
+{
+	const struct rpc_uuid expected = {
+		.uuid = { 0xf0, 0x33, 0xbe, 0x6d, 0x6c, 0xc4, 0x47, 0x38,
+			  0x88, 0xfd, 0xdd, 0x44, 0xac, 0x56, 0x2b, 0x69}
+	};
+	struct rpc_uuid actual = { 0 };
+
+	ts_rpc_abi_set_uuid(regs, &expected);
+	check_regs(0, 0x6dbe33f0, 0x3847c46c, 0x44ddfd88, 0x692b56ac);
+
+	ts_rpc_abi_get_uuid(regs, &actual);
+	MEMCMP_EQUAL(expected.uuid, actual.uuid, sizeof(expected));
+}
+
+TEST(ts_rpc_abi, queried_interface_id)
+{
+	const uint8_t interface_id = 0xa5;
+
+	ts_rpc_abi_set_queried_interface_id(regs, interface_id);
+	check_regs(0, 0, interface_id, 0, 0);
+
+	UNSIGNED_LONGS_EQUAL(interface_id, ts_rpc_abi_get_queried_interface_id(regs));
+}
+
+TEST(ts_rpc_abi, request_length)
+{
+	const uint32_t length = 0x12345678;
+
+	ts_rpc_abi_set_request_length(regs, length);
+	check_regs(0, 0, 0, length, 0);
+
+	UNSIGNED_LONGS_EQUAL(length, ts_rpc_abi_get_request_length(regs));
+}
+
+TEST(ts_rpc_abi, client_id)
+{
+	const uint32_t client_id = 0xabcdef01;
+
+	ts_rpc_abi_set_client_id(regs, client_id);
+	check_regs(0, 0, 0, 0, client_id);
+
+	UNSIGNED_LONGS_EQUAL(client_id, ts_rpc_abi_get_client_id(regs));
+}
+
+TEST(ts_rpc_abi, response_length)
+{
+	const uint32_t length = 0x12345678;
+
+	ts_rpc_abi_set_response_length(regs, length);
+	check_regs(0, 0, 0, length, 0);
+
+	UNSIGNED_LONGS_EQUAL(length, ts_rpc_abi_get_response_length(regs));
+}
diff --git a/components/rpc/ts_rpc/common/ts_rpc_abi.c b/components/rpc/ts_rpc/common/ts_rpc_abi.c
new file mode 100644
index 0000000..674e668
--- /dev/null
+++ b/components/rpc/ts_rpc/common/ts_rpc_abi.c
@@ -0,0 +1,207 @@
+/*
+ * Copyright (c) 2023, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include "ts_rpc_abi.h"
+#include <string.h>
+
+#define TS_RPC_CONTROL_REG			(0)
+
+#define TS_RPC_FLAGS_REG			(0)
+#define TS_RPC_FLAGS_SHIFT			(24)
+#define TS_RPC_FLAGS_MASK			(0x3f)
+
+#define TS_RPC_INTERFACE_ID_REG			(0)
+#define TS_RPC_INTERFACE_ID_SHIFT		(16)
+#define TS_RPC_INTERFACE_ID_MASK		(0xff)
+
+#define TS_RPC_MANAGEMENT_INTERFACE_ID		(0xff)
+
+#define TS_RPC_OPCODE_REG			(0)
+#define TS_RPC_OPCODE_SHIFT			(0)
+#define TS_RPC_OPCODE_MASK			(0xffff)
+
+#define TS_RPC_VERSION_REG			(1)
+#define TS_RPC_MEMORY_HANDLE_LSW_REG		(1)
+#define TS_RPC_MEMORY_HANDLE_MSW_REG		(2)
+#define TS_RPC_MEMORY_TAG_LSW_REG		(3)
+#define TS_RPC_MEMORY_TAG_MSW_REG		(4)
+#define TS_RPC_RPC_STATUS_REG			(1)
+#define TS_RPC_SERVICE_STATUS_REG		(2)
+#define TS_RPC_UUID_START_REG			(1)
+
+#define TS_RPC_QUERIED_INTERFACE_ID_REG		(2)
+#define TS_RPC_QUERIED_INTERFACE_ID_SHIFT	(0)
+#define TS_RPC_QUERIED_INTERFACE_ID_MASK	(0xff)
+
+#define TS_RPC_REQUEST_LENGTH_REG		(3)
+#define TS_RPC_CLIENT_ID_REG			(4)
+#define TS_RPC_RESPONSE_LENGTH_REG		(3)
+#define TS_RPC_FAST_REQUEST_DATA_START_REG	(1)
+#define TS_RPC_FAST_RESPONSE_DATA_START_REG	(2)
+
+static uint32_t get_field(const uint32_t regs[5], uint32_t reg, uint32_t shift, uint32_t mask)
+{
+	return (regs[reg] >> shift) & mask;
+}
+
+static void set_field(uint32_t regs[5], uint32_t reg, uint32_t shift, uint32_t mask,
+		      uint32_t value)
+{
+	regs[reg] &= ~(mask << shift);
+	regs[reg] |= (value & mask) << shift;
+}
+
+uint8_t ts_rpc_abi_get_flags(const uint32_t regs[5])
+{
+	return get_field(regs, TS_RPC_FLAGS_REG, TS_RPC_FLAGS_SHIFT, TS_RPC_FLAGS_MASK);
+}
+
+void ts_rpc_abi_set_flags(uint32_t regs[5], uint8_t flags)
+{
+	set_field(regs, TS_RPC_FLAGS_REG, TS_RPC_FLAGS_SHIFT, TS_RPC_FLAGS_MASK, flags);
+}
+
+uint8_t ts_rpc_abi_get_interface_id(const uint32_t regs[5])
+{
+	return get_field(regs, TS_RPC_INTERFACE_ID_REG, TS_RPC_INTERFACE_ID_SHIFT,
+			 TS_RPC_INTERFACE_ID_MASK);
+}
+
+void ts_rpc_abi_set_interface_id(uint32_t regs[5], uint8_t interface_id)
+{
+	set_field(regs, TS_RPC_INTERFACE_ID_REG, TS_RPC_INTERFACE_ID_SHIFT,
+		  TS_RPC_INTERFACE_ID_MASK, interface_id);
+}
+
+bool ts_rpc_abi_is_management_interface_id(const uint32_t regs[5])
+{
+	return ts_rpc_abi_get_interface_id(regs) == TS_RPC_MANAGEMENT_INTERFACE_ID;
+}
+
+void ts_rpc_abi_set_management_interface_id(uint32_t regs[5])
+{
+	ts_rpc_abi_set_interface_id(regs, TS_RPC_MANAGEMENT_INTERFACE_ID);
+}
+
+uint16_t ts_rpc_abi_get_opcode(const uint32_t regs[5])
+{
+	return get_field(regs, TS_RPC_OPCODE_REG, TS_RPC_OPCODE_SHIFT, TS_RPC_OPCODE_MASK);
+}
+
+void ts_rpc_abi_set_opcode(uint32_t regs[5], uint16_t opcode)
+{
+	set_field(regs, TS_RPC_OPCODE_REG, TS_RPC_OPCODE_SHIFT, TS_RPC_OPCODE_MASK, opcode);
+}
+
+void ts_rpc_abi_copy_control_reg(uint32_t response_regs[5], const uint32_t request_regs[5])
+{
+	response_regs[TS_RPC_CONTROL_REG] = request_regs[TS_RPC_CONTROL_REG];
+}
+
+uint32_t ts_rpc_abi_get_version(const uint32_t regs[5])
+{
+	return regs[TS_RPC_VERSION_REG];
+}
+
+void ts_rpc_abi_set_version(uint32_t regs[5], uint32_t version)
+{
+	regs[TS_RPC_VERSION_REG] = version;
+}
+
+uint64_t ts_rpc_abi_get_memory_handle(const uint32_t regs[5])
+{
+	return (uint64_t)regs[TS_RPC_MEMORY_HANDLE_MSW_REG] << 32 |
+		regs[TS_RPC_MEMORY_HANDLE_LSW_REG];
+}
+
+void ts_rpc_abi_set_memory_handle(uint32_t regs[5], uint64_t handle)
+{
+	regs[TS_RPC_MEMORY_HANDLE_LSW_REG] = handle;
+	regs[TS_RPC_MEMORY_HANDLE_MSW_REG] = handle >> 32;
+}
+
+uint64_t ts_rpc_abi_get_memory_tag(const uint32_t regs[5])
+{
+	return (uint64_t)regs[TS_RPC_MEMORY_TAG_MSW_REG] << 32 | regs[TS_RPC_MEMORY_TAG_LSW_REG];
+}
+
+void ts_rpc_abi_set_memory_tag(uint32_t regs[5], uint64_t tag)
+{
+	regs[TS_RPC_MEMORY_TAG_LSW_REG] = tag;
+	regs[TS_RPC_MEMORY_TAG_MSW_REG] = tag >> 32;
+}
+
+uint32_t ts_rpc_abi_get_rpc_status(const uint32_t regs[5])
+{
+	return regs[TS_RPC_RPC_STATUS_REG];
+}
+
+void ts_rpc_abi_set_rpc_status(uint32_t regs[5], uint32_t status)
+{
+	regs[TS_RPC_RPC_STATUS_REG] = status;
+}
+
+uint32_t ts_rpc_abi_get_service_status(const uint32_t regs[5])
+{
+	return regs[TS_RPC_SERVICE_STATUS_REG];
+}
+
+void ts_rpc_abi_set_service_status(uint32_t regs[5], uint32_t status)
+{
+	regs[TS_RPC_SERVICE_STATUS_REG] = status;
+}
+
+void ts_rpc_abi_get_uuid(const uint32_t regs[5], struct rpc_uuid *uuid)
+{
+	memcpy(uuid, &regs[TS_RPC_UUID_START_REG], sizeof(*uuid));
+}
+
+void ts_rpc_abi_set_uuid(uint32_t regs[5], const struct rpc_uuid *uuid)
+{
+	memcpy(&regs[TS_RPC_UUID_START_REG], uuid, sizeof(*uuid));
+}
+
+uint8_t ts_rpc_abi_get_queried_interface_id(const uint32_t regs[5])
+{
+	return get_field(regs, TS_RPC_QUERIED_INTERFACE_ID_REG, TS_RPC_QUERIED_INTERFACE_ID_SHIFT,
+			 TS_RPC_QUERIED_INTERFACE_ID_MASK);
+}
+
+void ts_rpc_abi_set_queried_interface_id(uint32_t regs[5], uint8_t interface_id)
+{
+	set_field(regs, TS_RPC_QUERIED_INTERFACE_ID_REG, TS_RPC_QUERIED_INTERFACE_ID_SHIFT,
+		  TS_RPC_QUERIED_INTERFACE_ID_MASK, interface_id);
+}
+
+uint32_t ts_rpc_abi_get_request_length(const uint32_t regs[5])
+{
+	return regs[TS_RPC_REQUEST_LENGTH_REG];
+}
+
+void ts_rpc_abi_set_request_length(uint32_t regs[5], uint32_t length)
+{
+	regs[TS_RPC_REQUEST_LENGTH_REG] = length;
+}
+
+uint32_t ts_rpc_abi_get_client_id(const uint32_t regs[5])
+{
+	return regs[TS_RPC_CLIENT_ID_REG];
+}
+
+void ts_rpc_abi_set_client_id(uint32_t regs[5], uint32_t client_id)
+{
+	regs[TS_RPC_CLIENT_ID_REG] = client_id;
+}
+
+uint32_t ts_rpc_abi_get_response_length(const uint32_t regs[5])
+{
+	return regs[TS_RPC_RESPONSE_LENGTH_REG];
+}
+
+void ts_rpc_abi_set_response_length(uint32_t regs[5], uint32_t length)
+{
+	regs[TS_RPC_RESPONSE_LENGTH_REG] = length;
+}
diff --git a/components/rpc/ts_rpc/common/ts_rpc_abi.h b/components/rpc/ts_rpc/common/ts_rpc_abi.h
new file mode 100644
index 0000000..8b0fa1c
--- /dev/null
+++ b/components/rpc/ts_rpc/common/ts_rpc_abi.h
@@ -0,0 +1,83 @@
+/*
+ * Copyright (c) 2023, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef TS_RPC_ABI_H
+#define TS_RPC_ABI_H
+
+#include "rpc_uuid.h"
+#include <stdbool.h>
+#include <stddef.h>
+#include <stdint.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * @brief Trusted-services RPC ABI function
+ *
+ * This file contains getters and setters for TS ABI fields. They handle the five arg registers of
+ * the FF-A direct messages and extract or insert fields of suitable types.
+ */
+
+#define TS_RPC_ABI_FLAG_FAST_CALL			(0x01)
+
+#define TS_RPC_ABI_MANAGEMENT_OPCODE_VERSION		(0)
+#define TS_RPC_ABI_MANAGEMENT_OPCODE_MEMORY_RETRIEVE	(1)
+#define TS_RPC_ABI_MANAGEMENT_OPCODE_MEMORY_RELINQUISH	(2)
+#define TS_RPC_ABI_MANAGEMENT_OPCODE_INTERFACE_ID_QUERY	(3)
+
+#define TS_RPC_ABI_VERSION_V1				(1)
+
+uint8_t ts_rpc_abi_get_flags(const uint32_t regs[5]);
+void ts_rpc_abi_set_flags(uint32_t regs[5], uint8_t flags);
+
+uint8_t ts_rpc_abi_get_interface_id(const uint32_t regs[5]);
+void ts_rpc_abi_set_interface_id(uint32_t regs[5], uint8_t interface_id);
+
+bool ts_rpc_abi_is_management_interface_id(const uint32_t regs[5]);
+void ts_rpc_abi_set_management_interface_id(uint32_t regs[5]);
+
+uint16_t ts_rpc_abi_get_opcode(const uint32_t regs[5]);
+void ts_rpc_abi_set_opcode(uint32_t regs[5], uint16_t interface_id);
+
+void ts_rpc_abi_copy_control_reg(uint32_t response_regs[5], const uint32_t request_regs[5]);
+
+uint32_t ts_rpc_abi_get_version(const uint32_t regs[5]);
+void ts_rpc_abi_set_version(uint32_t regs[5], uint32_t version);
+
+uint64_t ts_rpc_abi_get_memory_handle(const uint32_t regs[5]);
+void ts_rpc_abi_set_memory_handle(uint32_t regs[5], uint64_t handle);
+
+uint64_t ts_rpc_abi_get_memory_tag(const uint32_t regs[5]);
+void ts_rpc_abi_set_memory_tag(uint32_t regs[5], uint64_t tag);
+
+uint32_t ts_rpc_abi_get_rpc_status(const uint32_t regs[5]);
+void ts_rpc_abi_set_rpc_status(uint32_t regs[5], uint32_t status);
+
+uint32_t ts_rpc_abi_get_service_status(const uint32_t regs[5]);
+void ts_rpc_abi_set_service_status(uint32_t regs[5], uint32_t status);
+
+void ts_rpc_abi_get_uuid(const uint32_t regs[5], struct rpc_uuid *uuid);
+void ts_rpc_abi_set_uuid(uint32_t regs[5], const struct rpc_uuid *uuid);
+
+uint8_t ts_rpc_abi_get_queried_interface_id(const uint32_t regs[5]);
+void ts_rpc_abi_set_queried_interface_id(uint32_t regs[5], uint8_t interface_id);
+
+uint32_t ts_rpc_abi_get_request_length(const uint32_t regs[5]);
+void ts_rpc_abi_set_request_length(uint32_t regs[5], uint32_t length);
+
+uint32_t ts_rpc_abi_get_client_id(const uint32_t regs[5]);
+void ts_rpc_abi_set_client_id(uint32_t regs[5], uint32_t client_id);
+
+uint32_t ts_rpc_abi_get_response_length(const uint32_t regs[5]);
+void ts_rpc_abi_set_response_length(uint32_t regs[5], uint32_t length);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* TS_RPC_ABI_H */
diff --git a/components/rpc/ffarpc/endpoint/component.cmake b/components/rpc/ts_rpc/endpoint/sp/component.cmake
similarity index 71%
copy from components/rpc/ffarpc/endpoint/component.cmake
copy to components/rpc/ts_rpc/endpoint/sp/component.cmake
index 9e43ac5..62d47dd 100644
--- a/components/rpc/ffarpc/endpoint/component.cmake
+++ b/components/rpc/ts_rpc/endpoint/sp/component.cmake
@@ -8,7 +8,11 @@
 	message(FATAL_ERROR "mandatory parameter TGT is not defined.")
 endif()
 
-target_sources(${TGT} PRIVATE
-	"${CMAKE_CURRENT_LIST_DIR}/ffarpc_call_ep.c"
+
+set_property(TARGET ${TGT} APPEND PROPERTY PUBLIC_HEADER
+	"${CMAKE_CURRENT_LIST_DIR}/ts_rpc_endpoint_sp.h"
 	)
 
+target_sources(${TGT} PRIVATE
+	"${CMAKE_CURRENT_LIST_DIR}/ts_rpc_endpoint_sp.c"
+	)
diff --git a/components/rpc/ts_rpc/endpoint/sp/ts_rpc_endpoint_sp.c b/components/rpc/ts_rpc/endpoint/sp/ts_rpc_endpoint_sp.c
new file mode 100644
index 0000000..d001158
--- /dev/null
+++ b/components/rpc/ts_rpc/endpoint/sp/ts_rpc_endpoint_sp.c
@@ -0,0 +1,339 @@
+/*
+ * Copyright (c) 2023, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include "ts_rpc_endpoint_sp.h"
+#include "sp_discovery.h"
+#include "sp_memory_management.h"
+#include "trace.h"
+#include <stdlib.h>
+#include <string.h>
+
+static const struct ts_rpc_shared_memory null_shared_memory = {
+	.owner_id = 0xffff, .handle = FFA_MEM_HANDLE_INVALID, .data = NULL, .size = 0, .used = true
+};
+
+static struct ts_rpc_shared_memory *find_free_shared_memory_descriptor(
+	struct ts_rpc_endpoint_sp *endpoint)
+{
+	struct ts_rpc_shared_memory *memory = endpoint->shared_memories;
+	struct ts_rpc_shared_memory *end = memory + endpoint->shared_memory_count;
+
+	for (; memory < end; memory++)
+		if (!memory->used)
+			return memory;
+
+	return NULL;
+}
+
+static struct ts_rpc_shared_memory *find_shared_memory_descriptor(
+	struct ts_rpc_endpoint_sp *endpoint, uint16_t owner_id, uint64_t handle)
+{
+	struct ts_rpc_shared_memory *memory = endpoint->shared_memories;
+	struct ts_rpc_shared_memory *end = memory + endpoint->shared_memory_count;
+
+	for (; memory < end; memory++)
+		if (memory->used && memory->owner_id == owner_id && memory->handle == handle)
+			return memory;
+
+	return NULL;
+}
+
+static rpc_status_t handle_memory_retrieve(struct ts_rpc_endpoint_sp *endpoint, uint16_t source_id,
+					   uint64_t memory_handle, uint64_t memory_tag)
+{
+	sp_result sp_res = SP_RESULT_INTERNAL_ERROR;
+	struct sp_memory_descriptor desc = { 0 };
+	struct sp_memory_access_descriptor acc_desc = { 0 };
+	struct sp_memory_region region = { 0 };
+	uint32_t in_region_count = 0;
+	uint32_t out_region_count = 1;
+	struct ts_rpc_shared_memory *memory = NULL;
+
+	(void)memory_tag;
+
+	memory = find_free_shared_memory_descriptor(endpoint);
+	if (!memory) {
+		EMSG("No available shared memory slot");
+		return RPC_ERROR_NOT_FOUND;
+	}
+
+	desc.sender_id = source_id;
+	desc.memory_type = sp_memory_type_not_specified;
+	desc.flags.transaction_type = sp_memory_transaction_type_share;
+	acc_desc.receiver_id = endpoint->own_id;
+	acc_desc.data_access = sp_data_access_read_write;
+
+	sp_res = sp_memory_retrieve(&desc, &acc_desc, &region, in_region_count,
+				    &out_region_count, memory_handle);
+	if (sp_res != SP_RESULT_OK) {
+		EMSG("Failed to retrieve memory: %d", sp_res);
+		return RPC_ERROR_TRANSPORT_LAYER;
+	}
+
+	memory->owner_id = source_id;
+	memory->handle = memory_handle;
+	memory->data = region.address;
+	memory->size = region.page_count * FFA_MEM_TRANSACTION_PAGE_SIZE;
+	memory->used = true;
+
+	return RPC_SUCCESS;
+}
+
+static rpc_status_t handle_memory_relinquish(struct ts_rpc_endpoint_sp *endpoint,
+					     uint16_t source_id, uint64_t memory_handle)
+{
+	sp_result sp_res = SP_RESULT_INTERNAL_ERROR;
+	uint16_t endpoints[1] = { 0 };
+	uint32_t endpoint_count = 1;
+	struct sp_memory_transaction_flags flags = {
+		.zero_memory = false,
+		.operation_time_slicing = false,
+	};
+	struct ts_rpc_shared_memory *memory = NULL;
+
+	memory = find_shared_memory_descriptor(endpoint, source_id, memory_handle);
+	if (!memory) {
+		EMSG("Shared memory not found");
+		return RPC_ERROR_NOT_FOUND;
+	}
+
+	endpoints[0] = endpoint->own_id;
+
+	sp_res = sp_memory_relinquish(memory->handle, endpoints, endpoint_count, &flags);
+	if (sp_res != SP_RESULT_OK) {
+		EMSG("Failed to relinquish memory: %d", sp_res);
+		return RPC_ERROR_TRANSPORT_LAYER;
+	}
+
+	*memory = (struct ts_rpc_shared_memory){ 0 };
+
+	return RPC_SUCCESS;
+}
+
+static rpc_status_t handle_interface_id_query(struct ts_rpc_endpoint_sp *endpoint,
+					      const struct rpc_uuid *service_uuid,
+					      uint8_t *interface_id)
+{
+	size_t i = 0;
+
+	for (i = 0; i < endpoint->service_count; i++) {
+		if (endpoint->services[i] &&
+		    rpc_uuid_equal(service_uuid, &endpoint->services[i]->uuid)) {
+			*interface_id = i;
+			return RPC_SUCCESS;
+		}
+	}
+
+	*interface_id = 0;
+	return RPC_ERROR_NOT_FOUND;
+}
+
+static void handle_management_interface(struct ts_rpc_endpoint_sp *endpoint, uint16_t source_id,
+					const uint32_t request[5], uint32_t response[5])
+{
+	uint16_t opcode = ts_rpc_abi_get_opcode(request);
+	rpc_status_t status = RPC_ERROR_INTERNAL;
+
+	switch (opcode) {
+	case TS_RPC_ABI_MANAGEMENT_OPCODE_VERSION:
+		ts_rpc_abi_set_version(response, TS_RPC_ABI_VERSION_V1);
+		/* Version call doesn't return RPC status, return from the function here */
+		return;
+
+	case TS_RPC_ABI_MANAGEMENT_OPCODE_MEMORY_RETRIEVE: {
+		uint64_t memory_handle = ts_rpc_abi_get_memory_handle(request);
+		uint64_t memory_tag = ts_rpc_abi_get_memory_tag(request);
+
+		status = handle_memory_retrieve(endpoint, source_id, memory_handle, memory_tag);
+		break;
+	}
+
+	case TS_RPC_ABI_MANAGEMENT_OPCODE_MEMORY_RELINQUISH: {
+		uint64_t memory_handle = ts_rpc_abi_get_memory_handle(request);
+
+		status = handle_memory_relinquish(endpoint, source_id, memory_handle);
+		break;
+	}
+
+	case TS_RPC_ABI_MANAGEMENT_OPCODE_INTERFACE_ID_QUERY: {
+		struct rpc_uuid uuid = { 0 };
+		uint8_t interface_id = 0;
+
+		ts_rpc_abi_get_uuid(request, &uuid);
+		status = handle_interface_id_query(endpoint, &uuid, &interface_id);
+		if (status == RPC_SUCCESS)
+			ts_rpc_abi_set_queried_interface_id(response, interface_id);
+		break;
+	}
+
+	default:
+		status = RPC_ERROR_INVALID_VALUE;
+	}
+
+	ts_rpc_abi_set_rpc_status(response, status);
+}
+
+static void handle_service_interfaces(struct ts_rpc_endpoint_sp *endpoint, uint16_t source_id,
+				      const uint32_t request[5], uint32_t response[5])
+{
+	uint8_t interface_id = 0;
+	uint64_t memory_handle = 0;
+	uint32_t request_length = 0;
+	struct rpc_service_interface *service = NULL;
+	const struct ts_rpc_shared_memory *memory = NULL;
+	struct rpc_request rpc_request = { 0 };
+	rpc_status_t status = RPC_ERROR_INTERNAL;
+
+	interface_id = ts_rpc_abi_get_interface_id(request);
+	if (interface_id >= endpoint->service_count) {
+		status = RPC_ERROR_INVALID_VALUE;
+		goto out;
+	}
+
+	service = endpoint->services[interface_id];
+	if (!service) {
+		status = RPC_ERROR_INTERNAL;
+		goto out;
+	}
+
+	memory_handle = ts_rpc_abi_get_memory_handle(request);
+	if (memory_handle != FFA_MEM_HANDLE_INVALID) {
+		/* Normal call with data in the shared memory */
+		memory = find_shared_memory_descriptor(endpoint, source_id, memory_handle);
+		if (!memory) {
+			status = RPC_ERROR_NOT_FOUND;
+			goto out;
+		}
+	} else {
+		/* Call without a shared memory */
+		memory = &null_shared_memory;
+	}
+
+	request_length = ts_rpc_abi_get_request_length(request);
+	if (request_length > memory->size) {
+		status = RPC_ERROR_INVALID_VALUE;
+		goto out;
+	}
+
+	rpc_request.request.data = memory->data;
+	rpc_request.request.data_length = request_length;
+	rpc_request.request.size = memory->size;
+
+	rpc_request.response.data = memory->data;
+	rpc_request.response.data_length = 0;
+	rpc_request.response.size = memory->size;
+
+	rpc_request.source_id = source_id;
+	rpc_request.interface_id = interface_id;
+	rpc_request.opcode = ts_rpc_abi_get_opcode(request);
+	rpc_request.client_id = ts_rpc_abi_get_client_id(request);
+
+	status = rpc_service_receive(service, &rpc_request);
+	if (status == RPC_SUCCESS) {
+		ts_rpc_abi_set_response_length(response, rpc_request.response.data_length);
+		ts_rpc_abi_set_service_status(response, rpc_request.service_status);
+	}
+
+out:
+	ts_rpc_abi_set_rpc_status(response, status);
+}
+
+rpc_status_t ts_rpc_endpoint_sp_init(struct ts_rpc_endpoint_sp *endpoint, size_t service_count,
+				     size_t shared_memory_count)
+{
+	sp_result result = SP_RESULT_OK;
+
+	if (!endpoint || !service_count)
+		return RPC_ERROR_INVALID_VALUE;
+
+	result = sp_discovery_own_id_get(&endpoint->own_id);
+	if (result != SP_RESULT_OK)
+		return RPC_ERROR_TRANSPORT_LAYER;
+
+	endpoint->services = calloc(service_count, sizeof(struct rpc_service_interface *));
+	if (!endpoint->services)
+		return RPC_ERROR_RESOURCE_FAILURE;
+
+	endpoint->service_count = service_count;
+	endpoint->shared_memories = calloc(shared_memory_count,
+					   sizeof(struct ts_rpc_shared_memory));
+	if (!endpoint->shared_memories) {
+		free(endpoint->services);
+		return RPC_ERROR_RESOURCE_FAILURE;
+	}
+
+	endpoint->shared_memory_count = shared_memory_count;
+
+	return RPC_SUCCESS;
+}
+
+rpc_status_t ts_rpc_endpoint_sp_deinit(struct ts_rpc_endpoint_sp *endpoint)
+{
+	struct ts_rpc_shared_memory *memory = NULL;
+	struct ts_rpc_shared_memory *end = NULL;
+	rpc_status_t status = RPC_SUCCESS;
+
+	if (!endpoint)
+		return RPC_ERROR_INVALID_VALUE;
+
+	memory = endpoint->shared_memories;
+	end = memory + endpoint->shared_memory_count;
+
+	for (; memory < end; memory++) {
+		status = handle_memory_relinquish(endpoint, memory->owner_id, memory->handle);
+		if (status)
+			return status;
+	}
+
+	free(endpoint->services);
+	free(endpoint->shared_memories);
+
+	*endpoint = (struct ts_rpc_endpoint_sp){ 0 };
+
+	return RPC_SUCCESS;
+}
+
+rpc_status_t ts_rpc_endpoint_sp_add_service(struct ts_rpc_endpoint_sp *endpoint,
+					    struct rpc_service_interface *service)
+{
+	size_t i = 0;
+
+	if (!endpoint || !service)
+		return RPC_ERROR_INVALID_VALUE;
+
+	for (i = 0; i < endpoint->service_count; i++) {
+		if (!endpoint->services[i]) {
+			endpoint->services[i] = service;
+			return RPC_SUCCESS;
+		}
+	}
+
+	return RPC_ERROR_RESOURCE_FAILURE;
+}
+
+void ts_rpc_endpoint_sp_receive(struct ts_rpc_endpoint_sp *endpoint, const struct sp_msg *request,
+				struct sp_msg *response)
+{
+	response->source_id = request->destination_id;
+	response->destination_id = request->source_id;
+	response->is_64bit_message = request->is_64bit_message;
+	memset(&response->args, 0x00, sizeof(response->args));
+	ts_rpc_abi_copy_control_reg(response->args.args32, request->args.args32);
+
+	if (!request->is_64bit_message) {
+		if (ts_rpc_abi_is_management_interface_id(request->args.args32)) {
+			handle_management_interface(endpoint, request->source_id,
+						    request->args.args32, response->args.args32);
+		} else {
+			handle_service_interfaces(endpoint, request->source_id,
+						  request->args.args32, response->args.args32);
+		}
+	} else {
+		EMSG("64 bit FF-A messages are not supported by the TS RPC layer, src = 0x%04x",
+		     request->source_id);
+		ts_rpc_abi_set_rpc_status(response->args.args32, RPC_ERROR_INVALID_VALUE);
+	}
+}
diff --git a/components/rpc/ts_rpc/endpoint/sp/ts_rpc_endpoint_sp.h b/components/rpc/ts_rpc/endpoint/sp/ts_rpc_endpoint_sp.h
new file mode 100644
index 0000000..63aa71c
--- /dev/null
+++ b/components/rpc/ts_rpc/endpoint/sp/ts_rpc_endpoint_sp.h
@@ -0,0 +1,98 @@
+/*
+ * Copyright (c) 2023, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef TS_RPC_ENDPOINT_SP_H
+#define TS_RPC_ENDPOINT_SP_H
+
+#include "components/rpc/common/endpoint/rpc_service_interface.h"
+#include "components/rpc/ts_rpc/common/ts_rpc_abi.h"
+#include "sp_messaging.h"
+#include <stdbool.h>
+#include <stddef.h>
+#include <stdint.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * @brief TS RPC shared memory
+ *
+ * The structure describes an FF-A shared memory slot in the endpoint implementation. The shared
+ * memory is identified by its owner (FF-A ID) and handle (FF-A memory handle). After retrieval the
+ * data and size fields are filled. The used field indicates if a given memory slot of the pool is
+ * used and contains valid information.
+ */
+struct ts_rpc_shared_memory {
+	uint16_t owner_id;
+	uint64_t handle;
+	void *data;
+	size_t size;
+	bool used;
+};
+
+/**
+ * @brief TS RPC endpoint for SPs
+ *
+ * This component connects the FF-A layer and the services by implementing TS RPC on FF-A direct
+ * messages and shared memories.
+ * The structure contains the endpoint's own FF-A ID to be used in FF-A calls.
+ * It also contains of list of services. These services are selected based on the interface ID of
+ * the RPC request. The endpoint handles the shared memory pool.
+ */
+struct ts_rpc_endpoint_sp {
+	uint16_t own_id;
+	struct rpc_service_interface **services;
+	size_t service_count;
+	struct ts_rpc_shared_memory *shared_memories;
+	size_t shared_memory_count;
+};
+
+/**
+ * @brief Init TS RPC endpoint
+ *
+ * @param endpoint The endpoint instance
+ * @param service_count Service count
+ * @param shared_memory_count Shared memory pool size
+ * @return rpc_status_t
+ */
+rpc_status_t ts_rpc_endpoint_sp_init(struct ts_rpc_endpoint_sp *endpoint, size_t service_count,
+				     size_t shared_memory_count);
+
+/**
+ * @brief Deinit TS RPC endpoint
+ *
+ * @param endpoint The endpoint instance
+ * @return rpc_status_t
+ */
+rpc_status_t ts_rpc_endpoint_sp_deinit(struct ts_rpc_endpoint_sp *endpoint);
+
+/**
+ * @brief Add service to the endpoint. The interface IDs are assigned sequentially. The maximal
+ * service count is determined by the service_count parameter of ts_rpc_endpoint_sp_init.
+ *
+ * @param endpoint The endpoint instance
+ * @param service The service instance
+ * @return rpc_status_t
+ */
+rpc_status_t ts_rpc_endpoint_sp_add_service(struct ts_rpc_endpoint_sp *endpoint,
+					    struct rpc_service_interface *service);
+
+/**
+ * @brief Handle received FF-A message
+ *
+ * @param endpoint The endpoint instance
+ * @param request The request FF-A message
+ * @param response The response FF-A message
+ */
+void ts_rpc_endpoint_sp_receive(struct ts_rpc_endpoint_sp *endpoint, const struct sp_msg *request,
+				struct sp_msg *response);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* TS_RPC_ENDPOINT_SP_H */
diff --git a/components/service/attestation/client/provision/attest_provision_client.c b/components/service/attestation/client/provision/attest_provision_client.c
index 5549db1..404a545 100644
--- a/components/service/attestation/client/provision/attest_provision_client.c
+++ b/components/service/attestation/client/provision/attest_provision_client.c
@@ -24,9 +24,9 @@
 static struct service_client instance;
 
 
-psa_status_t attest_provision_client_init(struct rpc_caller *caller)
+psa_status_t attest_provision_client_init(struct rpc_caller_session *session)
 {
-	return service_client_init(&instance, caller);
+	return service_client_init(&instance, session);
 }
 
 void attest_provision_client_deinit(void)
@@ -51,20 +51,23 @@
 	rpc_call_handle call_handle;
 	uint8_t *req_buf;
 
-	call_handle = rpc_caller_begin(instance.caller, &req_buf, 0);
+	call_handle = rpc_caller_session_begin(instance.session, &req_buf, 0,
+					       tlv_required_space(data_size));
 
 	if (call_handle) {
 
 		uint8_t *resp_buf;
 		size_t resp_len;
-		rpc_opstatus_t opstatus;
+		service_status_t service_status;
 
-		instance.rpc_status = rpc_caller_invoke(instance.caller, call_handle,
-			TS_ATTESTATION_OPCODE_EXPORT_IAK_PUBLIC_KEY, &opstatus, &resp_buf, &resp_len);
+		instance.rpc_status =
+			rpc_caller_session_invoke(call_handle,
+						  TS_ATTESTATION_OPCODE_EXPORT_IAK_PUBLIC_KEY,
+						  &resp_buf, &resp_len, &service_status);
 
-		if (instance.rpc_status == TS_RPC_CALL_ACCEPTED) {
+		if (instance.rpc_status == RPC_SUCCESS) {
 
-			psa_status = opstatus;
+			psa_status = service_status;
 
 			if (psa_status == PSA_SUCCESS) {
 
@@ -92,7 +95,7 @@
 			}
 		}
 
-		rpc_caller_end(instance.caller, call_handle);
+		rpc_caller_session_end(call_handle);
 	}
 
 	return psa_status;
@@ -113,27 +116,26 @@
 	rpc_call_handle call_handle;
 	uint8_t *req_buf;
 
-	call_handle = rpc_caller_begin(instance.caller, &req_buf, req_len);
+	call_handle = rpc_caller_session_begin(instance.session, &req_buf, req_len, 0);
 
 	if (call_handle) {
 
 		uint8_t *resp_buf;
 		size_t resp_len;
-		rpc_opstatus_t opstatus;
+		service_status_t service_status;
 		struct tlv_iterator req_iter;
 
 		tlv_iterator_begin(&req_iter, req_buf, req_len);
 		tlv_encode(&req_iter, &key_record);
 
-		instance.rpc_status = rpc_caller_invoke(instance.caller, call_handle,
-			TS_ATTESTATION_OPCODE_IMPORT_IAK, &opstatus, &resp_buf, &resp_len);
+		instance.rpc_status =
+			rpc_caller_session_invoke(call_handle, TS_ATTESTATION_OPCODE_IMPORT_IAK,
+						  &resp_buf, &resp_len, &service_status);
 
-		if (instance.rpc_status == TS_RPC_CALL_ACCEPTED) {
+		if (instance.rpc_status == RPC_SUCCESS)
+			psa_status = service_status;
 
-			psa_status = opstatus;
-		}
-
-		rpc_caller_end(instance.caller, call_handle);
+		rpc_caller_session_end(call_handle);
 	}
 
 	return psa_status;
@@ -146,23 +148,22 @@
 	rpc_call_handle call_handle;
 	uint8_t *req_buf;
 
-	call_handle = rpc_caller_begin(instance.caller, &req_buf, 0);
+	call_handle = rpc_caller_session_begin(instance.session, &req_buf, 0, 0);
 
 	if (call_handle) {
 
 		uint8_t *resp_buf;
 		size_t resp_len;
-		rpc_opstatus_t opstatus;
+		service_status_t service_status;
 
-		instance.rpc_status = rpc_caller_invoke(instance.caller, call_handle,
-			TS_ATTESTATION_OPCODE_IAK_EXISTS, &opstatus, &resp_buf, &resp_len);
+		instance.rpc_status =
+			rpc_caller_session_invoke(call_handle, TS_ATTESTATION_OPCODE_IAK_EXISTS,
+						  &resp_buf, &resp_len, &service_status);
 
-		if (instance.rpc_status == TS_RPC_CALL_ACCEPTED) {
+		if (instance.rpc_status == RPC_SUCCESS)
+			psa_status = service_status;
 
-			psa_status = opstatus;
-		}
-
-		rpc_caller_end(instance.caller, call_handle);
+		rpc_caller_session_end(call_handle);
 	}
 
 	return psa_status;
diff --git a/components/service/attestation/client/provision/attest_provision_client.h b/components/service/attestation/client/provision/attest_provision_client.h
index 73ddbf7..300cde7 100644
--- a/components/service/attestation/client/provision/attest_provision_client.h
+++ b/components/service/attestation/client/provision/attest_provision_client.h
@@ -8,7 +8,7 @@
 #define ATTEST_PROVISION_CLIENT_H
 
 #include <psa/error.h>
-#include <rpc_caller.h>
+#include "rpc_caller_session.h"
 
 #ifdef __cplusplus
 extern "C" {
@@ -23,7 +23,7 @@
  *
  * @return     A status indicating the success/failure of the operation
  */
-psa_status_t attest_provision_client_init(struct rpc_caller *caller);
+psa_status_t attest_provision_client_init(struct rpc_caller_session *session);
 
 /**
  * @brief      De-initialises the singleton attestion provisioning client
diff --git a/components/service/attestation/client/psa/iat_client.c b/components/service/attestation/client/psa/iat_client.c
index 649e950..407572b 100644
--- a/components/service/attestation/client/psa/iat_client.c
+++ b/components/service/attestation/client/psa/iat_client.c
@@ -7,6 +7,7 @@
 #include <stddef.h>
 #include <string.h>
 #include "iat_client.h"
+#include "rpc_caller_session.h"
 #include <common/tlv/tlv.h>
 #include <psa/initial_attestation.h>
 #include <service/common/client/service_client.h>
@@ -23,9 +24,9 @@
 static struct service_client instance;
 
 
-psa_status_t psa_iat_client_init(struct rpc_caller *caller)
+psa_status_t psa_iat_client_init(struct rpc_caller_session *session)
 {
-	return service_client_init(&instance, caller);
+	return service_client_init(&instance, session);
 }
 
 void psa_iat_client_deinit(void)
@@ -40,106 +41,109 @@
 
 psa_status_t psa_initial_attest_get_token(
 	const uint8_t *auth_challenge, size_t challenge_size,
-    uint8_t *token_buf, size_t token_buf_size, size_t *token_size)
+	uint8_t *token_buf, size_t token_buf_size, size_t *token_size)
 {
-    psa_status_t psa_status = PSA_ERROR_INVALID_ARGUMENT;
-    size_t req_len = tlv_required_space(challenge_size);
+	psa_status_t psa_status = PSA_ERROR_INVALID_ARGUMENT;
+	size_t req_len = tlv_required_space(challenge_size);
+	struct tlv_record challenge_record = { 0 };
+	rpc_call_handle call_handle;
+	uint8_t *req_buf;
 
-    if (!token_buf || !token_buf_size) return PSA_ERROR_INVALID_ARGUMENT;
+	if (!token_buf || !token_buf_size)
+		return PSA_ERROR_INVALID_ARGUMENT;
 
-    struct tlv_record challenge_record;
-    challenge_record.tag = TS_ATTESTATION_GET_TOKEN_IN_TAG_AUTH_CHALLENGE;
-    challenge_record.length = challenge_size;
-    challenge_record.value = auth_challenge;
-
-    rpc_call_handle call_handle;
-    uint8_t *req_buf;
+	challenge_record.tag = TS_ATTESTATION_GET_TOKEN_IN_TAG_AUTH_CHALLENGE;
+	challenge_record.length = challenge_size;
+	challenge_record.value = auth_challenge;
 
 	*token_size = 0;
 
-    call_handle = rpc_caller_begin(instance.caller, &req_buf, req_len);
+	call_handle = rpc_caller_session_begin(instance.session, &req_buf, req_len,
+					       tlv_required_space(token_buf_size));
 
-    if (call_handle) {
+	if (call_handle) {
 
-        uint8_t *resp_buf;
-        size_t resp_len;
-        rpc_opstatus_t opstatus;
-        struct tlv_iterator req_iter;
+		uint8_t *resp_buf;
+		size_t resp_len;
+		service_status_t service_status;
+		struct tlv_iterator req_iter;
 
-        tlv_iterator_begin(&req_iter, req_buf, req_len);
-        tlv_encode(&req_iter, &challenge_record);
+		tlv_iterator_begin(&req_iter, req_buf, req_len);
+		tlv_encode(&req_iter, &challenge_record);
 
-        instance.rpc_status = rpc_caller_invoke(instance.caller, call_handle,
-            TS_ATTESTATION_OPCODE_GET_TOKEN, &opstatus, &resp_buf, &resp_len);
+		instance.rpc_status =
+			rpc_caller_session_invoke(call_handle, TS_ATTESTATION_OPCODE_GET_TOKEN,
+						  &resp_buf, &resp_len, &service_status);
 
-        if (instance.rpc_status == TS_RPC_CALL_ACCEPTED) {
+		if (instance.rpc_status == RPC_SUCCESS) {
 
-            psa_status = opstatus;
+			psa_status = service_status;
 
-            if (psa_status == PSA_SUCCESS) {
+			if (psa_status == PSA_SUCCESS) {
+				struct tlv_const_iterator resp_iter;
+				struct tlv_record decoded_record;
 
-                struct tlv_const_iterator resp_iter;
-                struct tlv_record decoded_record;
-                tlv_const_iterator_begin(&resp_iter, resp_buf, resp_len);
+				tlv_const_iterator_begin(&resp_iter, resp_buf, resp_len);
 
-                if (tlv_find_decode(&resp_iter,
-						TS_ATTESTATION_GET_TOKEN_OUT_TAG_TOKEN, &decoded_record)) {
+				if (tlv_find_decode(&resp_iter,
+					TS_ATTESTATION_GET_TOKEN_OUT_TAG_TOKEN, &decoded_record)) {
 
-                    if (decoded_record.length <= token_buf_size) {
+					if (decoded_record.length <= token_buf_size) {
 
-                        memcpy(token_buf, decoded_record.value, decoded_record.length);
-                        *token_size = decoded_record.length;
-                    }
-                    else {
-                        /* Provided buffer is too small */
-                        psa_status = PSA_ERROR_BUFFER_TOO_SMALL;
-                    }
-                }
-                else {
-                    /* Mandatory response parameter missing */
-                    psa_status = PSA_ERROR_GENERIC_ERROR;
-                }
+						memcpy(token_buf, decoded_record.value,
+						       decoded_record.length);
+						*token_size = decoded_record.length;
+					} else {
+						/* Provided buffer is too small */
+						psa_status = PSA_ERROR_BUFFER_TOO_SMALL;
+					}
+				} else {
+					/* Mandatory response parameter missing */
+					psa_status = PSA_ERROR_GENERIC_ERROR;
+				}
 			}
-        }
+		}
 
-        rpc_caller_end(instance.caller, call_handle);
-    }
+		rpc_caller_session_end(call_handle);
+	}
 
-    return psa_status;
+	return psa_status;
 }
 
 psa_status_t psa_initial_attest_get_token_size(
 	size_t challenge_size, size_t *token_size)
 {
-    psa_status_t psa_status = PSA_ERROR_INVALID_ARGUMENT;
-    struct ts_attestation_get_token_size_in req_msg;
-    size_t req_len = sizeof(struct ts_attestation_get_token_size_in);
+	psa_status_t psa_status = PSA_ERROR_INVALID_ARGUMENT;
+	struct ts_attestation_get_token_size_in req_msg;
+	size_t req_len = sizeof(struct ts_attestation_get_token_size_in);
 
-    *token_size = 0;  /* For failure case */
+	*token_size = 0;  /* For failure case */
 
-    req_msg.challenge_size = challenge_size;
+	req_msg.challenge_size = challenge_size;
 
-    rpc_call_handle call_handle;
-    uint8_t *req_buf;
+	rpc_call_handle call_handle;
+	uint8_t *req_buf;
 
-    call_handle = rpc_caller_begin(instance.caller, &req_buf, req_len);
+	call_handle = rpc_caller_session_begin(instance.session, &req_buf, req_len,
+					       sizeof(struct ts_attestation_get_token_size_out));
 
-    if (call_handle) {
+	if (call_handle) {
 
-        uint8_t *resp_buf;
-        size_t resp_len;
-        rpc_opstatus_t opstatus;
+		uint8_t *resp_buf;
+		size_t resp_len;
+		service_status_t service_status;
 
-        memcpy(req_buf, &req_msg, req_len);
+		memcpy(req_buf, &req_msg, req_len);
 
-        instance.rpc_status = rpc_caller_invoke(instance.caller, call_handle,
-                    TS_ATTESTATION_OPCODE_GET_TOKEN_SIZE, &opstatus, &resp_buf, &resp_len);
+		instance.rpc_status =
+			rpc_caller_session_invoke(call_handle, TS_ATTESTATION_OPCODE_GET_TOKEN_SIZE,
+						  &resp_buf, &resp_len, &service_status);
 
-        if (instance.rpc_status == TS_RPC_CALL_ACCEPTED) {
+		if (instance.rpc_status == RPC_SUCCESS) {
 
-            psa_status = opstatus;
+			psa_status = service_status;
 
-            if (psa_status == PSA_SUCCESS) {
+			if (psa_status == PSA_SUCCESS) {
 
 				if (resp_len >= sizeof(struct ts_attestation_get_token_size_out)) {
 
@@ -151,11 +155,11 @@
 					/* Failed to decode response message */
 					psa_status = PSA_ERROR_GENERIC_ERROR;
 				}
-            }
-        }
+			}
+		}
 
-        rpc_caller_end(instance.caller, call_handle);
-    }
+		rpc_caller_session_end(call_handle);
+	}
 
-    return psa_status;
+	return psa_status;
 }
diff --git a/components/service/attestation/client/psa/iat_client.h b/components/service/attestation/client/psa/iat_client.h
index 7daeacf..d4ee4f8 100644
--- a/components/service/attestation/client/psa/iat_client.h
+++ b/components/service/attestation/client/psa/iat_client.h
@@ -8,7 +8,7 @@
 #define PSA_IAT_CLIENT_H
 
 #include <psa/error.h>
-#include <rpc_caller.h>
+#include "rpc_caller_session.h"
 
 #ifdef __cplusplus
 extern "C" {
@@ -25,7 +25,7 @@
  *
  * @return     A status indicating the success/failure of the operation
  */
-psa_status_t psa_iat_client_init(struct rpc_caller *caller);
+psa_status_t psa_iat_client_init(struct rpc_caller_session *session);
 
 /**
  * @brief      De-initialises the singleton IAT client
diff --git a/components/service/attestation/client/psa_ipc/iat_ipc_client.c b/components/service/attestation/client/psa_ipc/iat_ipc_client.c
index c26a0fe..1420731 100644
--- a/components/service/attestation/client/psa_ipc/iat_ipc_client.c
+++ b/components/service/attestation/client/psa_ipc/iat_ipc_client.c
@@ -22,9 +22,9 @@
 static struct service_client instance;
 
 
-psa_status_t psa_iat_client_init(struct rpc_caller *caller)
+psa_status_t psa_iat_client_init(struct rpc_caller_session *session)
 {
-	return service_client_init(&instance, caller);
+	return service_client_init(&instance, session);
 }
 
 void psa_iat_client_deinit(void)
@@ -44,7 +44,7 @@
 					  size_t *token_size)
 {
 	psa_status_t status = PSA_ERROR_INVALID_ARGUMENT;
-	struct rpc_caller *caller = instance.caller;
+	struct rpc_caller_interface *caller = instance.session->caller;
 	struct psa_invec in_vec[] = {
 		{ .base = psa_ptr_const_to_u32(auth_challenge), .len = challenge_size},
 	};
@@ -68,7 +68,7 @@
 psa_status_t psa_initial_attest_get_token_size(size_t challenge_size,
 						size_t *token_size)
 {
-	struct rpc_caller *caller = instance.caller;
+	struct rpc_caller_interface *caller = instance.session->caller;
 	psa_status_t status;
 	struct psa_invec in_vec[] = {
 		{ .base = psa_ptr_to_u32(&challenge_size), .len = sizeof(uint32_t)}
diff --git a/components/service/attestation/provider/attest_provider.c b/components/service/attestation/provider/attest_provider.c
index a658ac2..dd1f3e5 100644
--- a/components/service/attestation/provider/attest_provider.c
+++ b/components/service/attestation/provider/attest_provider.c
@@ -3,21 +3,23 @@
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
+
+#include "attest_provider.h"
+#include "protocols/service/attestation/packed-c/opcodes.h"
+#include "protocols/rpc/common/packed-c/status.h"
+#include "service/attestation/key_mngr/attest_key_mngr.h"
+#include "service/attestation/reporter/attest_report.h"
+#include "psa/initial_attestation.h"
+#include "attestation_uuid.h"
 #include <stdlib.h>
 #include <string.h>
-#include <protocols/service/attestation/packed-c/opcodes.h>
-#include <protocols/rpc/common/packed-c/status.h>
-#include <service/attestation/key_mngr/attest_key_mngr.h>
-#include <service/attestation/reporter/attest_report.h>
-#include <psa/initial_attestation.h>
-#include "attest_provider.h"
 
 /* Service request handlers */
-static rpc_status_t get_token_handler(void *context, struct call_req* req);
-static rpc_status_t get_token_size_handler(void *context, struct call_req* req);
-static rpc_status_t export_iak_public_key_handler(void *context, struct call_req* req);
-static rpc_status_t import_iak_handler(void *context, struct call_req* req);
-static rpc_status_t iak_exists_handler(void *context, struct call_req* req);
+static rpc_status_t get_token_handler(void *context, struct rpc_request *req);
+static rpc_status_t get_token_size_handler(void *context, struct rpc_request *req);
+static rpc_status_t export_iak_public_key_handler(void *context, struct rpc_request *req);
+static rpc_status_t import_iak_handler(void *context, struct rpc_request *req);
+static rpc_status_t iak_exists_handler(void *context, struct rpc_request *req);
 
 /* Handler mapping table for service */
 static const struct service_handler handler_table[] = {
@@ -28,22 +30,19 @@
 	{TS_ATTESTATION_OPCODE_IAK_EXISTS,              iak_exists_handler}
 };
 
-struct rpc_interface *attest_provider_init(struct attest_provider *context)
+struct rpc_service_interface *attest_provider_init(struct attest_provider *context)
 {
-	struct rpc_interface *rpc_interface = NULL;
+	const struct rpc_uuid attest_service_uuid = { .uuid = TS_PSA_ATTESTATION_SERVICE_UUID };
 
-	if (context) {
+	if (!context)
+		return NULL;
 
-		for (size_t encoding = 0; encoding < TS_RPC_ENCODING_LIMIT; ++encoding)
-			context->serializers[encoding] = NULL;
+	context->serializer = NULL;
 
-		service_provider_init(&context->base_provider, context,
-					handler_table, sizeof(handler_table)/sizeof(struct service_handler));
+	service_provider_init(&context->base_provider, context, &attest_service_uuid,
+			      handler_table, sizeof(handler_table)/sizeof(struct service_handler));
 
-		rpc_interface = service_provider_get_rpc_interface(&context->base_provider);
-	}
-
-	return rpc_interface;
+	return service_provider_get_rpc_interface(&context->base_provider);
 }
 
 void attest_provider_deinit(struct attest_provider *context)
@@ -52,181 +51,143 @@
 }
 
 void attest_provider_register_serializer(struct attest_provider *context,
-				unsigned int encoding, const struct attest_provider_serializer *serializer)
+					 const struct attest_provider_serializer *serializer)
 {
-	if (encoding < TS_RPC_ENCODING_LIMIT)
-		context->serializers[encoding] = serializer;
+	context->serializer = serializer;
 }
 
-static const struct attest_provider_serializer *get_attest_serializer(
-				struct attest_provider *context, const struct call_req *req)
+static rpc_status_t get_token_handler(void *context, struct rpc_request *req)
 {
-	const struct attest_provider_serializer *serializer = NULL;
-	unsigned int encoding = call_req_get_encoding(req);
-
-	if (encoding < TS_RPC_ENCODING_LIMIT) serializer = context->serializers[encoding];
-
-	return serializer;
-}
-
-static rpc_status_t get_token_handler(void *context, struct call_req* req)
-{
-	struct attest_provider *this_instance = (struct attest_provider*)context;
-	rpc_status_t rpc_status = TS_RPC_ERROR_SERIALIZATION_NOT_SUPPORTED;
-
+	struct attest_provider *this_instance = (struct attest_provider *)context;
+	rpc_status_t rpc_status = RPC_ERROR_INTERNAL;
 	uint8_t challenge[PSA_INITIAL_ATTEST_CHALLENGE_SIZE_64];
 	size_t challenge_len = sizeof(challenge);
+	const struct attest_provider_serializer *serializer = this_instance->serializer;
+	const uint8_t *token = NULL;
+	size_t token_size = 0;
 
-	struct call_param_buf *req_buf = call_req_get_req_buf(req);
-	const struct attest_provider_serializer *serializer = get_attest_serializer(this_instance, req);
+	if (!serializer)
+		return rpc_status;
 
-	if (serializer)
-		rpc_status = serializer->deserialize_get_token_req(req_buf, challenge, &challenge_len);
+	rpc_status = serializer->deserialize_get_token_req(&req->request, challenge,
+							   &challenge_len);
+	if (rpc_status != RPC_SUCCESS)
+		return rpc_status;
 
-	if (rpc_status == TS_RPC_CALL_ACCEPTED) {
+	req->service_status = attest_report_create((int32_t)req->source_id, challenge,
+						   challenge_len, &token, &token_size);
 
-		const uint8_t *token = NULL;
-		size_t token_size = 0;
+	if (req->service_status == PSA_SUCCESS)
+		rpc_status = serializer->serialize_get_token_resp(&req->response, token,
+								  token_size);
 
-		rpc_opstatus_t opstatus = attest_report_create((int32_t)call_req_get_caller_id(req),
-			challenge, challenge_len,
-			&token, &token_size);
-
-		if (opstatus == PSA_SUCCESS) {
-
-			struct call_param_buf *resp_buf = call_req_get_resp_buf(req);
-			rpc_status = serializer->serialize_get_token_resp(resp_buf, token, token_size);
-		}
-
-		attest_report_destroy(token);
-		call_req_set_opstatus(req, opstatus);
-	}
+	attest_report_destroy(token);
 
 	return rpc_status;
 }
 
-static rpc_status_t get_token_size_handler(void *context, struct call_req* req)
+static rpc_status_t get_token_size_handler(void *context, struct rpc_request *req)
 {
 	struct attest_provider *this_instance = (struct attest_provider*)context;
-	rpc_status_t rpc_status = TS_RPC_ERROR_SERIALIZATION_NOT_SUPPORTED;
-
+	rpc_status_t rpc_status = RPC_ERROR_INTERNAL;
 	uint8_t challenge[PSA_INITIAL_ATTEST_CHALLENGE_SIZE_64];
 	size_t challenge_len = sizeof(challenge);
-
-	struct call_param_buf *req_buf = call_req_get_req_buf(req);
-	const struct attest_provider_serializer *serializer = get_attest_serializer(this_instance, req);
+	const struct attest_provider_serializer *serializer = this_instance->serializer;
+	const uint8_t *token = NULL;
+	size_t token_size = 0;
 
 	memset(challenge, 0, sizeof(challenge));
 
-	if (serializer)
-		rpc_status = serializer->deserialize_get_token_size_req(req_buf, &challenge_len);
+	if (!serializer)
+		return rpc_status;
 
-	if (rpc_status == TS_RPC_CALL_ACCEPTED) {
+	rpc_status = serializer->deserialize_get_token_size_req(&req->request, &challenge_len);
+	if (rpc_status != RPC_SUCCESS)
+		return rpc_status;
 
-		const uint8_t *token = NULL;
-		size_t token_size = 0;
+	req->service_status = attest_report_create((int32_t)req->source_id, challenge,
+						   challenge_len, &token, &token_size);
 
-		rpc_opstatus_t opstatus = attest_report_create((int32_t)call_req_get_caller_id(req),
-			challenge, challenge_len,
-			&token, &token_size);
+	if (req->service_status == PSA_SUCCESS)
+		rpc_status = serializer->serialize_get_token_size_resp(&req->response, token_size);
 
-		if (opstatus == PSA_SUCCESS) {
-
-			struct call_param_buf *resp_buf = call_req_get_resp_buf(req);
-			rpc_status = serializer->serialize_get_token_size_resp(resp_buf, token_size);
-		}
-
-		attest_report_destroy(token);
-		call_req_set_opstatus(req, opstatus);
-	}
+	attest_report_destroy(token);
 
 	return rpc_status;
 }
 
-static rpc_status_t export_iak_public_key_handler(void *context, struct call_req* req)
+static rpc_status_t export_iak_public_key_handler(void *context, struct rpc_request *req)
 {
-    rpc_status_t rpc_status = TS_RPC_ERROR_SERIALIZATION_NOT_SUPPORTED;
-    const struct attest_provider_serializer *serializer = get_attest_serializer(context, req);
+	struct attest_provider *this_instance = (struct attest_provider *)context;
+	rpc_status_t rpc_status = RPC_ERROR_INTERNAL;
+	const struct attest_provider_serializer *serializer = this_instance->serializer;
+	size_t max_key_size = 0;
+	uint8_t *key_buffer = NULL;
+	size_t export_size = 0;
 
-	if (serializer) {
+	if (!serializer)
+		return rpc_status;
 
-		size_t max_key_size = attest_key_mngr_max_iak_export_size();
-		uint8_t *key_buffer = malloc(max_key_size);
+	max_key_size = attest_key_mngr_max_iak_export_size();
+	key_buffer = malloc(max_key_size);
 
-		if (key_buffer) {
+	if (!key_buffer)
+		return rpc_status;
 
-			size_t export_size = 0;
-			rpc_opstatus_t opstatus =
-				attest_key_mngr_export_iak_public_key(key_buffer, max_key_size, &export_size);
+	req->service_status = attest_key_mngr_export_iak_public_key(key_buffer, max_key_size,
+								    &export_size);
 
-			rpc_status = TS_RPC_CALL_ACCEPTED;
+	rpc_status = RPC_SUCCESS;
 
-			if (opstatus == PSA_SUCCESS) {
+	if (req->service_status == PSA_SUCCESS)
+		rpc_status = serializer->serialize_export_iak_public_key_resp(
+			&req->response, key_buffer, export_size);
 
-				struct call_param_buf *resp_buf = call_req_get_resp_buf(req);
-				rpc_status =
-					serializer->serialize_export_iak_public_key_resp(resp_buf,
-						key_buffer, export_size);
-			}
-
-			free(key_buffer);
-			call_req_set_opstatus(req, opstatus);
-		}
-		else {
-			/* Failed to allocate key buffer */
-			rpc_status = TS_RPC_ERROR_RESOURCE_FAILURE;
-		}
-	}
+	free(key_buffer);
 
 	return rpc_status;
 }
 
-static rpc_status_t import_iak_handler(void *context, struct call_req* req)
+static rpc_status_t import_iak_handler(void *context, struct rpc_request *req)
 {
-	rpc_status_t rpc_status = TS_RPC_ERROR_SERIALIZATION_NOT_SUPPORTED;
-	struct call_param_buf *req_buf = call_req_get_req_buf(req);
-	const struct attest_provider_serializer *serializer = get_attest_serializer(context, req);
+	struct attest_provider *this_instance = (struct attest_provider *)context;
+	rpc_status_t rpc_status = RPC_ERROR_INTERNAL;
+	const struct attest_provider_serializer *serializer = this_instance->serializer;
+	size_t key_data_len = 0;
+	uint8_t *key_buffer = NULL;
 
-	if (serializer) {
+	if (!serializer)
+		return rpc_status;
 
-		size_t key_data_len = attest_key_mngr_max_iak_import_size();
-		uint8_t *key_buffer = malloc(key_data_len);
+	key_data_len = attest_key_mngr_max_iak_import_size();
+	key_buffer = malloc(key_data_len);
 
-		if (key_buffer) {
+	if (!key_buffer)
+		return rpc_status;
 
-			rpc_status =
-				serializer->deserialize_import_iak_req(req_buf, key_buffer, &key_data_len);
+	rpc_status = serializer->deserialize_import_iak_req(&req->request, key_buffer,
+							    &key_data_len);
 
-			if (rpc_status == TS_RPC_CALL_ACCEPTED) {
+	if (rpc_status == RPC_SUCCESS)
+		req->service_status = attest_key_mngr_import_iak(key_buffer, key_data_len);
 
-				rpc_opstatus_t opstatus;
-				opstatus = attest_key_mngr_import_iak(key_buffer, key_data_len);
-				call_req_set_opstatus(req, opstatus);
-			}
-
-			free(key_buffer);
-		}
-		else {
-
-			rpc_status = TS_RPC_ERROR_RESOURCE_FAILURE;
-		}
-	}
+	free(key_buffer);
 
 	return rpc_status;
 }
 
-static rpc_status_t iak_exists_handler(void *context, struct call_req* req)
+static rpc_status_t iak_exists_handler(void *context, struct rpc_request *req)
 {
-    (void)context;
+	(void)context;
 
-    rpc_opstatus_t opstatus = PSA_ERROR_DOES_NOT_EXIST;
+	service_status_t opstatus = PSA_ERROR_DOES_NOT_EXIST;
 
 	if (attest_key_mngr_iak_exists()) {
 
 	   opstatus = PSA_SUCCESS;
 	}
 
-	call_req_set_opstatus(req, opstatus);
+	req->service_status = opstatus;
 
-	return TS_RPC_CALL_ACCEPTED;
+	return RPC_SUCCESS;
 }
diff --git a/components/service/attestation/provider/attest_provider.h b/components/service/attestation/provider/attest_provider.h
index 26f21b5..4f2e268 100644
--- a/components/service/attestation/provider/attest_provider.h
+++ b/components/service/attestation/provider/attest_provider.h
@@ -7,12 +7,12 @@
 #ifndef ATTEST_PROVIDER_H
 #define ATTEST_PROVIDER_H
 
-#include <rpc/common/endpoint/rpc_interface.h>
-#include <rpc_caller.h>
-#include <service/common/provider/service_provider.h>
-#include <service/attestation/provider/serializer/attest_provider_serializer.h>
-#include <service/attestation/key_mngr/attest_key_mngr.h>
-#include <protocols/rpc/common/packed-c/encoding.h>
+#include "rpc/common/endpoint/rpc_service_interface.h"
+#include "rpc/common/caller/rpc_caller.h"
+#include "service/common/provider/service_provider.h"
+#include "service/attestation/provider/serializer/attest_provider_serializer.h"
+#include "service/attestation/key_mngr/attest_key_mngr.h"
+#include "protocols/rpc/common/packed-c/encoding.h"
 
 #ifdef __cplusplus
 extern "C" {
@@ -24,8 +24,8 @@
  */
 struct attest_provider
 {
-    struct service_provider base_provider;
-    const struct attest_provider_serializer *serializers[TS_RPC_ENCODING_LIMIT];
+	struct service_provider base_provider;
+	const struct attest_provider_serializer *serializer;
 };
 
 /**
@@ -38,7 +38,7 @@
  *
  * \return An rpc_interface or NULL on failure
  */
-struct rpc_interface *attest_provider_init(struct attest_provider *context);
+struct rpc_service_interface *attest_provider_init(struct attest_provider *context);
 
 /**
  * \brief Cleans up when the instance is no longer needed
@@ -55,7 +55,7 @@
  * \param[in] serializer  A concrete serializer
  */
 void attest_provider_register_serializer(struct attest_provider *context,
-    unsigned int encoding, const struct attest_provider_serializer *serializer);
+	const struct attest_provider_serializer *serializer);
 
 #ifdef __cplusplus
 } /* extern "C" */
diff --git a/components/service/attestation/provider/attestation_uuid.h b/components/service/attestation/provider/attestation_uuid.h
new file mode 100644
index 0000000..4c08760
--- /dev/null
+++ b/components/service/attestation/provider/attestation_uuid.h
@@ -0,0 +1,21 @@
+/*
+ * Copyright (c) 2023, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef ATTESTATION_UUID_H
+#define ATTESTATION_UUID_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define TS_PSA_ATTESTATION_SERVICE_UUID \
+{ 0xa1, 0xba, 0xf1, 0x55, 0x88, 0x76, 0x46, 0x95, 0x8f, 0x7c, 0x54, 0x95, 0x5e, 0x8d, 0xb9, 0x74 }
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* ATTESTATION_UUID_H */
diff --git a/components/service/attestation/provider/serializer/attest_provider_serializer.h b/components/service/attestation/provider/serializer/attest_provider_serializer.h
index 1c05ab0..78b11a6 100644
--- a/components/service/attestation/provider/serializer/attest_provider_serializer.h
+++ b/components/service/attestation/provider/serializer/attest_provider_serializer.h
@@ -7,9 +7,9 @@
 #ifndef ATTEST_PROVIDER_SERIALIZER_H
 #define ATTEST_PROVIDER_SERIALIZER_H
 
+#include "components/rpc/common/endpoint/rpc_service_interface.h"
 #include <stddef.h>
 #include <stdint.h>
-#include <rpc/common/endpoint/rpc_interface.h>
 
 /* Provides a common interface for parameter serialization operations
  * for the attestation service provider.  Allows alternative serialization
@@ -19,28 +19,28 @@
  */
 struct attest_provider_serializer {
 
-    /* Operation: get_token */
-    rpc_status_t (*deserialize_get_token_req)(const struct call_param_buf *req_buf,
-        uint8_t *auth_challenge, size_t *auth_challenge_len);
+	/* Operation: get_token */
+	rpc_status_t (*deserialize_get_token_req)(const struct rpc_buffer *req_buf,
+						  uint8_t *auth_challenge,
+						  size_t *auth_challenge_len);
 
-    rpc_status_t (*serialize_get_token_resp)(struct call_param_buf *resp_buf,
-        const uint8_t *token,
-        size_t token_size);
+	rpc_status_t (*serialize_get_token_resp)(struct rpc_buffer *resp_buf, const uint8_t *token,
+						 size_t token_size);
 
-    /* Operation: get_token_size */
-    rpc_status_t (*deserialize_get_token_size_req)(const struct call_param_buf *req_buf,
-        size_t *auth_challenge_len);
+	/* Operation: get_token_size */
+	rpc_status_t (*deserialize_get_token_size_req)(const struct rpc_buffer *req_buf,
+						       size_t *auth_challenge_len);
 
-    rpc_status_t (*serialize_get_token_size_resp)(struct call_param_buf *resp_buf,
-        size_t token_size);
+	rpc_status_t (*serialize_get_token_size_resp)(struct rpc_buffer *resp_buf,
+						      size_t token_size);
 
-    /* Operation: export_iak_public_key */
-    rpc_status_t (*serialize_export_iak_public_key_resp)(struct call_param_buf *resp_buf,
-                                        const uint8_t *data, size_t data_len);
+	/* Operation: export_iak_public_key */
+	rpc_status_t (*serialize_export_iak_public_key_resp)(struct rpc_buffer *resp_buf,
+							     const uint8_t *data, size_t data_len);
 
-    /* Operation: import_iak */
-    rpc_status_t (*deserialize_import_iak_req)(const struct call_param_buf *req_buf,
-                                        uint8_t *data, size_t *data_len);
+	/* Operation: import_iak */
+	rpc_status_t (*deserialize_import_iak_req)(const struct rpc_buffer *req_buf, uint8_t *data,
+						   size_t *data_len);
 };
 
 #endif /* ATTEST_PROVIDER_SERIALIZER_H */
diff --git a/components/service/attestation/provider/serializer/packed-c/packedc_attest_provider_serializer.c b/components/service/attestation/provider/serializer/packed-c/packedc_attest_provider_serializer.c
index 65e76f3..e2c6ea1 100644
--- a/components/service/attestation/provider/serializer/packed-c/packedc_attest_provider_serializer.c
+++ b/components/service/attestation/provider/serializer/packed-c/packedc_attest_provider_serializer.c
@@ -3,159 +3,158 @@
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
-#include <string.h>
-#include <common/tlv/tlv.h>
-#include <protocols/rpc/common/packed-c/status.h>
-#include <protocols/service/attestation/packed-c/get_token.h>
-#include <protocols/service/attestation/packed-c/get_token_size.h>
-#include <protocols/service/attestation/packed-c/export_iak_public_key.h>
-#include <protocols/service/attestation/packed-c/import_iak.h>
-#include "packedc_attest_provider_serializer.h"
 
+#include <common/tlv/tlv.h>
+#include "packedc_attest_provider_serializer.h"
+#include "protocols/rpc/common/packed-c/status.h"
+#include "protocols/service/attestation/packed-c/get_token.h"
+#include "protocols/service/attestation/packed-c/get_token_size.h"
+#include "protocols/service/attestation/packed-c/export_iak_public_key.h"
+#include "protocols/service/attestation/packed-c/import_iak.h"
+#include <string.h>
 
 /* Operation: get_token */
-static rpc_status_t deserialize_get_token_req(const struct call_param_buf *req_buf,
-    uint8_t *auth_challenge, size_t *auth_challenge_len)
+static rpc_status_t deserialize_get_token_req(const struct rpc_buffer *req_buf,
+					      uint8_t *auth_challenge, size_t *auth_challenge_len)
 {
-    rpc_status_t rpc_status = TS_RPC_ERROR_INVALID_REQ_BODY;
-    struct tlv_const_iterator req_iter;
-    struct tlv_record decoded_record;
+	rpc_status_t rpc_status = RPC_ERROR_INVALID_REQUEST_BODY;
+	struct tlv_const_iterator req_iter = { 0 };
+	struct tlv_record decoded_record = { 0 };
 
-    tlv_const_iterator_begin(&req_iter, (uint8_t*)req_buf->data, req_buf->data_len);
+	tlv_const_iterator_begin(&req_iter, (uint8_t *)req_buf->data, req_buf->data_length);
 
-    if (tlv_find_decode(&req_iter,
-        TS_ATTESTATION_GET_TOKEN_IN_TAG_AUTH_CHALLENGE, &decoded_record)) {
+	if (tlv_find_decode(&req_iter,
+		TS_ATTESTATION_GET_TOKEN_IN_TAG_AUTH_CHALLENGE, &decoded_record)) {
 
-        if (decoded_record.length <= *auth_challenge_len) {
+		if (decoded_record.length <= *auth_challenge_len) {
 
-            memcpy(auth_challenge, decoded_record.value, decoded_record.length);
-            *auth_challenge_len = decoded_record.length;
-            rpc_status = TS_RPC_CALL_ACCEPTED;
-        }
-    }
+			memcpy(auth_challenge, decoded_record.value, decoded_record.length);
+			*auth_challenge_len = decoded_record.length;
+			rpc_status = RPC_SUCCESS;
+		}
+	}
 
-    return rpc_status;
+	return rpc_status;
 }
 
-static rpc_status_t serialize_get_token_resp(struct call_param_buf *resp_buf,
-    const uint8_t *token, size_t token_size)
+static rpc_status_t serialize_get_token_resp(struct rpc_buffer *resp_buf, const uint8_t *token,
+					     size_t token_size)
 {
-    rpc_status_t rpc_status = TS_RPC_ERROR_INTERNAL;
-    struct tlv_iterator resp_iter;
+	rpc_status_t rpc_status = RPC_ERROR_INTERNAL;
+	struct tlv_iterator resp_iter = { 0 };
+	struct tlv_record token_record = { 0 };
 
-    struct tlv_record token_record;
-    token_record.tag = TS_ATTESTATION_GET_TOKEN_OUT_TAG_TOKEN;
-    token_record.length = token_size;
-    token_record.value = token;
+	token_record.tag = TS_ATTESTATION_GET_TOKEN_OUT_TAG_TOKEN;
+	token_record.length = token_size;
+	token_record.value = token;
 
-    tlv_iterator_begin(&resp_iter, resp_buf->data, resp_buf->size);
+	tlv_iterator_begin(&resp_iter, resp_buf->data, resp_buf->size);
 
-    if (tlv_encode(&resp_iter, &token_record)) {
+	if (tlv_encode(&resp_iter, &token_record)) {
 
-        resp_buf->data_len = tlv_required_space(token_size);
-        rpc_status = TS_RPC_CALL_ACCEPTED;
-    }
+		resp_buf->data_length = tlv_required_space(token_size);
+		rpc_status = RPC_SUCCESS;
+	}
 
-    return rpc_status;
+	return rpc_status;
 }
 
 /* Operation: get_token_size */
-static rpc_status_t deserialize_get_token_size_req(const struct call_param_buf *req_buf,
-    size_t *auth_challenge_len)
+static rpc_status_t deserialize_get_token_size_req(const struct rpc_buffer *req_buf,
+						   size_t *auth_challenge_len)
 {
-    rpc_status_t rpc_status = TS_RPC_ERROR_INVALID_REQ_BODY;
-    struct ts_attestation_get_token_size_in recv_msg;
-    size_t expected_fixed_len = sizeof(struct ts_attestation_get_token_size_in);
+	rpc_status_t rpc_status = RPC_ERROR_INVALID_REQUEST_BODY;
+	struct ts_attestation_get_token_size_in recv_msg = { 0 };
+	size_t expected_fixed_len = sizeof(struct ts_attestation_get_token_size_in);
 
-    if (expected_fixed_len <= req_buf->data_len) {
+	if (expected_fixed_len <= req_buf->data_length) {
 
-        memcpy(&recv_msg, req_buf->data, expected_fixed_len);
-        *auth_challenge_len = recv_msg.challenge_size;
-        rpc_status = TS_RPC_CALL_ACCEPTED;
-    }
+		memcpy(&recv_msg, req_buf->data, expected_fixed_len);
+		*auth_challenge_len = recv_msg.challenge_size;
+		rpc_status = RPC_SUCCESS;
+	}
 
-    return rpc_status;
+	return rpc_status;
 }
 
-static rpc_status_t serialize_get_token_size_resp(struct call_param_buf *resp_buf,
-    size_t token_size)
+static rpc_status_t serialize_get_token_size_resp(struct rpc_buffer *resp_buf, size_t token_size)
 {
-    rpc_status_t rpc_status = TS_RPC_ERROR_INTERNAL;
-    struct ts_attestation_get_token_size_out resp_msg;
-    size_t fixed_len = sizeof(struct ts_attestation_get_token_size_out);
+	rpc_status_t rpc_status = RPC_ERROR_INTERNAL;
+	struct ts_attestation_get_token_size_out resp_msg = { 0 };
+	size_t fixed_len = sizeof(struct ts_attestation_get_token_size_out);
 
-    resp_msg.token_size = token_size;
+	resp_msg.token_size = token_size;
 
-    if (fixed_len <= resp_buf->size) {
+	if (fixed_len <= resp_buf->size) {
 
-        memcpy(resp_buf->data, &resp_msg, fixed_len);
-        resp_buf->data_len = fixed_len;
-        rpc_status = TS_RPC_CALL_ACCEPTED;
-    }
+		memcpy(resp_buf->data, &resp_msg, fixed_len);
+		resp_buf->data_length = fixed_len;
+		rpc_status = RPC_SUCCESS;
+	}
 
-    return rpc_status;
+	return rpc_status;
 }
 
 /* Operation: export_iak_public_key */
-static rpc_status_t serialize_export_iak_public_key_resp(struct call_param_buf *resp_buf,
-    const uint8_t *data, size_t data_len)
+static rpc_status_t serialize_export_iak_public_key_resp(struct rpc_buffer *resp_buf,
+							 const uint8_t *data, size_t data_len)
 {
-    rpc_status_t rpc_status = TS_RPC_ERROR_INTERNAL;
-    struct tlv_iterator resp_iter;
+	rpc_status_t rpc_status = RPC_ERROR_INTERNAL;
+	struct tlv_iterator resp_iter = { 0 };
+	struct tlv_record key_record = { 0 };
 
-    struct tlv_record key_record;
-    key_record.tag = TS_ATTESTATION_EXPORT_IAK_PUBLIC_KEY_OUT_TAG_DATA;
-    key_record.length = data_len;
-    key_record.value = data;
+	key_record.tag = TS_ATTESTATION_EXPORT_IAK_PUBLIC_KEY_OUT_TAG_DATA;
+	key_record.length = data_len;
+	key_record.value = data;
 
-    tlv_iterator_begin(&resp_iter, resp_buf->data, resp_buf->size);
+	tlv_iterator_begin(&resp_iter, resp_buf->data, resp_buf->size);
 
-    if (tlv_encode(&resp_iter, &key_record)) {
+	if (tlv_encode(&resp_iter, &key_record)) {
 
-        resp_buf->data_len = tlv_required_space(data_len);
-        rpc_status = TS_RPC_CALL_ACCEPTED;
-    }
+		resp_buf->data_length = tlv_required_space(data_len);
+		rpc_status = RPC_SUCCESS;
+	}
 
-    return rpc_status;
+	return rpc_status;
 }
 
 /* Operation: import_iak */
-static rpc_status_t deserialize_import_iak_req(const struct call_param_buf *req_buf,
-    uint8_t *data, size_t *data_len)
+static rpc_status_t deserialize_import_iak_req(const struct rpc_buffer *req_buf, uint8_t *data,
+					       size_t *data_len)
 {
-    rpc_status_t rpc_status = TS_RPC_ERROR_INVALID_REQ_BODY;
-    struct tlv_const_iterator req_iter;
-    struct tlv_record decoded_record;
-    size_t out_buf_size = *data_len;
+	rpc_status_t rpc_status = RPC_ERROR_INVALID_REQUEST_BODY;
+	struct tlv_const_iterator req_iter = { 0 };
+	struct tlv_record decoded_record = { 0 };
+	size_t out_buf_size = *data_len;
 
-    *data_len = 0;
+	*data_len = 0;
 
-    tlv_const_iterator_begin(&req_iter, (uint8_t*)req_buf->data, req_buf->data_len);
+	tlv_const_iterator_begin(&req_iter, (uint8_t *)req_buf->data, req_buf->data_length);
 
-    if (tlv_find_decode(&req_iter, TS_ATTESTATION_IMPORT_IAK_IN_TAG_DATA, &decoded_record)) {
+	if (tlv_find_decode(&req_iter, TS_ATTESTATION_IMPORT_IAK_IN_TAG_DATA, &decoded_record)) {
 
-        if (decoded_record.length <= out_buf_size) {
+		if (decoded_record.length <= out_buf_size) {
 
-            memcpy(data, decoded_record.value, decoded_record.length);
-            *data_len = decoded_record.length;
-            rpc_status = TS_RPC_CALL_ACCEPTED;
-        }
-    }
+			memcpy(data, decoded_record.value, decoded_record.length);
+			*data_len = decoded_record.length;
+			rpc_status = RPC_SUCCESS;
+		}
+	}
 
-    return rpc_status;
+	return rpc_status;
 }
 
 /* Singleton method to provide access to the serializer instance */
 const struct attest_provider_serializer *packedc_attest_provider_serializer_instance(void)
 {
-    static const struct attest_provider_serializer instance = {
-        deserialize_get_token_req,
-        serialize_get_token_resp,
-        deserialize_get_token_size_req,
-        serialize_get_token_size_resp,
-        serialize_export_iak_public_key_resp,
-        deserialize_import_iak_req
-    };
+	static const struct attest_provider_serializer instance = {
+		deserialize_get_token_req,
+		serialize_get_token_resp,
+		deserialize_get_token_size_req,
+		serialize_get_token_size_resp,
+		serialize_export_iak_public_key_resp,
+		deserialize_import_iak_req
+	};
 
-    return &instance;
+	return &instance;
 }
diff --git a/components/service/attestation/provider/serializer/packed-c/packedc_attest_provider_serializer.h b/components/service/attestation/provider/serializer/packed-c/packedc_attest_provider_serializer.h
index b73adf8..436767b 100644
--- a/components/service/attestation/provider/serializer/packed-c/packedc_attest_provider_serializer.h
+++ b/components/service/attestation/provider/serializer/packed-c/packedc_attest_provider_serializer.h
@@ -7,7 +7,7 @@
 #ifndef PACKEDC_ATTEST_PROVIDER_SERIALIZER_H
 #define PACKEDC_ATTEST_PROVIDER_SERIALIZER_H
 
-#include <service/attestation/provider/serializer/attest_provider_serializer.h>
+#include "components/service/attestation/provider/serializer/attest_provider_serializer.h"
 
 #ifdef __cplusplus
 extern "C" {
diff --git a/components/service/attestation/test/service/attestation_provisioning_tests.cpp b/components/service/attestation/test/service/attestation_provisioning_tests.cpp
index 204ab4c..1a15b3d 100644
--- a/components/service/attestation/test/service/attestation_provisioning_tests.cpp
+++ b/components/service/attestation/test/service/attestation_provisioning_tests.cpp
@@ -19,23 +19,20 @@
 {
     void setup()
     {
-        struct rpc_caller *caller;
-        int status;
-
-        m_rpc_session_handle = NULL;
+        m_rpc_session = NULL;
         m_attest_service_context = NULL;
 
         service_locator_init();
 
         m_attest_service_context =
-            service_locator_query("sn:trustedfirmware.org:attestation:0", &status);
+            service_locator_query("sn:trustedfirmware.org:attestation:0");
         CHECK_TRUE(m_attest_service_context);
 
-        m_rpc_session_handle =
-            service_context_open(m_attest_service_context, TS_RPC_ENCODING_PACKED_C, &caller);
-        CHECK_TRUE(m_rpc_session_handle);
+        m_rpc_session =
+            service_context_open(m_attest_service_context);
+        CHECK_TRUE(m_rpc_session);
 
-        attest_provision_client_init(caller);
+        attest_provision_client_init(m_rpc_session);
     }
 
     void teardown()
@@ -43,9 +40,9 @@
         attest_provision_client_deinit();
 
 	if (m_attest_service_context) {
-		if (m_rpc_session_handle) {
-			service_context_close(m_attest_service_context, m_rpc_session_handle);
-			m_rpc_session_handle = NULL;
+		if (m_rpc_session) {
+			service_context_close(m_attest_service_context, m_rpc_session);
+			m_rpc_session = NULL;
 		}
 
 		service_context_relinquish(m_attest_service_context);
@@ -53,7 +50,7 @@
 	}
     }
 
-    rpc_session_handle m_rpc_session_handle;
+    struct rpc_caller_session *m_rpc_session;
     struct service_context *m_attest_service_context;
 };
 
diff --git a/components/service/attestation/test/service/attestation_service_tests.cpp b/components/service/attestation/test/service/attestation_service_tests.cpp
index f786035..ed6a0aa 100644
--- a/components/service/attestation/test/service/attestation_service_tests.cpp
+++ b/components/service/attestation/test/service/attestation_service_tests.cpp
@@ -19,23 +19,20 @@
 {
     void setup()
     {
-        struct rpc_caller *caller;
-        int status;
-
-        m_rpc_session_handle = NULL;
+        m_rpc_session = NULL;
         m_attest_service_context = NULL;
 
         service_locator_init();
 
         m_attest_service_context =
-            service_locator_query("sn:trustedfirmware.org:attestation:0", &status);
+            service_locator_query("sn:trustedfirmware.org:attestation:0");
         CHECK_TRUE(m_attest_service_context);
 
-        m_rpc_session_handle =
-            service_context_open(m_attest_service_context, TS_RPC_ENCODING_PACKED_C, &caller);
-        CHECK_TRUE(m_rpc_session_handle);
+        m_rpc_session =
+            service_context_open(m_attest_service_context);
+        CHECK_TRUE(m_rpc_session);
 
-        psa_iat_client_init(caller);
+        psa_iat_client_init(m_rpc_session);
     }
 
     void teardown()
@@ -43,9 +40,9 @@
         psa_iat_client_deinit();
 
 	if (m_attest_service_context) {
-		if (m_rpc_session_handle) {
-			service_context_close(m_attest_service_context, m_rpc_session_handle);
-			m_rpc_session_handle = NULL;
+		if (m_rpc_session) {
+			service_context_close(m_attest_service_context, m_rpc_session);
+			m_rpc_session = NULL;
 		}
 
 		service_context_relinquish(m_attest_service_context);
@@ -53,7 +50,7 @@
 	}
     }
 
-    rpc_session_handle m_rpc_session_handle;
+    struct rpc_caller_session *m_rpc_session;
     struct service_context *m_attest_service_context;
 };
 
diff --git a/components/service/block_storage/block_store/client/block_storage_client.c b/components/service/block_storage/block_store/client/block_storage_client.c
index de73fbc..ec741aa 100644
--- a/components/service/block_storage/block_store/client/block_storage_client.c
+++ b/components/service/block_storage/block_store/client/block_storage_client.c
@@ -8,7 +8,7 @@
 #include <stdbool.h>
 #include <stdlib.h>
 #include <string.h>
-#include "rpc_caller.h"
+#include "rpc_caller_session.h"
 #include "block_storage_client.h"
 #include "protocols/rpc/common/packed-c/status.h"
 #include "protocols/service/block_storage/packed-c/messages.h"
@@ -27,29 +27,28 @@
 	memcpy(req_msg.partition_guid, partition_guid->octets, sizeof(req_msg.partition_guid));
 
 	rpc_call_handle call_handle =
-		rpc_caller_begin(this_context->client.caller, &req_buf, req_len);
+		rpc_caller_session_begin(this_context->client.session, &req_buf, req_len,
+					 sizeof(struct ts_block_storage_get_partition_info_out));
 
 	if (call_handle) {
-
-		uint8_t *resp_buf;
-		size_t resp_len;
-		rpc_opstatus_t op_status;
+		uint8_t *resp_buf = NULL;
+		size_t resp_len = 0;
+		service_status_t service_status = 0;
 
 		memcpy(req_buf, &req_msg, req_len);
 
-		this_context->client.rpc_status = rpc_caller_invoke(
-			this_context->client.caller, call_handle,
-			TS_BLOCK_STORAGE_OPCODE_GET_PARTITION_INFO,
-			&op_status, &resp_buf, &resp_len);
+		this_context->client.rpc_status = rpc_caller_session_invoke(
+			call_handle, TS_BLOCK_STORAGE_OPCODE_GET_PARTITION_INFO, &resp_buf,
+			&resp_len, &service_status);
 
-		if (this_context->client.rpc_status == TS_RPC_CALL_ACCEPTED) {
+		if (this_context->client.rpc_status == RPC_SUCCESS) {
 
-			psa_status = op_status;
+			psa_status = service_status;
 
 			if (psa_status == PSA_SUCCESS) {
 
 				if (resp_len >=
-						sizeof(struct ts_block_storage_get_partition_info_out)) {
+				    sizeof(struct ts_block_storage_get_partition_info_out)) {
 
 					struct ts_block_storage_get_partition_info_out resp_msg;
 
@@ -73,10 +72,10 @@
 			}
 		}
 
-		rpc_caller_end(this_context->client.caller, call_handle);
+		rpc_caller_session_end(call_handle);
 	} else {
 
-		this_context->client.rpc_status = TS_RPC_ERROR_RESOURCE_FAILURE;
+		this_context->client.rpc_status = RPC_ERROR_INTERNAL;
 	}
 
 	return psa_status;
@@ -98,24 +97,24 @@
 	memcpy(req_msg.partition_guid, partition_guid->octets, sizeof(req_msg.partition_guid));
 
 	rpc_call_handle call_handle =
-		rpc_caller_begin(this_context->client.caller, &req_buf, req_len);
+		rpc_caller_session_begin(this_context->client.session, &req_buf, req_len,
+					 sizeof(struct ts_block_storage_open_out));
 
 	if (call_handle) {
 
-		uint8_t *resp_buf;
-		size_t resp_len;
-		rpc_opstatus_t op_status;
+		uint8_t *resp_buf = NULL;
+		size_t resp_len = 0;
+		service_status_t service_status = 0;
 
 		memcpy(req_buf, &req_msg, req_len);
 
-		this_context->client.rpc_status = rpc_caller_invoke(
-			this_context->client.caller, call_handle,
-			TS_BLOCK_STORAGE_OPCODE_OPEN,
-			&op_status, &resp_buf, &resp_len);
+		this_context->client.rpc_status = rpc_caller_session_invoke(
+			call_handle, TS_BLOCK_STORAGE_OPCODE_OPEN, &resp_buf, &resp_len,
+			&service_status);
 
-		if (this_context->client.rpc_status == TS_RPC_CALL_ACCEPTED) {
+		if (this_context->client.rpc_status == RPC_SUCCESS) {
 
-			psa_status = op_status;
+			psa_status = service_status;
 
 			if (psa_status == PSA_SUCCESS) {
 
@@ -132,10 +131,10 @@
 			}
 		}
 
-		rpc_caller_end(this_context->client.caller, call_handle);
+		rpc_caller_session_end(call_handle);
 	} else {
 
-		this_context->client.rpc_status = TS_RPC_ERROR_RESOURCE_FAILURE;
+		this_context->client.rpc_status = RPC_ERROR_INTERNAL;
 	}
 
 	return psa_status;
@@ -156,28 +155,27 @@
 	req_msg.handle = handle;
 
 	rpc_call_handle call_handle =
-		rpc_caller_begin(this_context->client.caller, &req_buf, req_len);
+		rpc_caller_session_begin(this_context->client.session, &req_buf, req_len, 0);
 
 	if (call_handle) {
 
-		uint8_t *resp_buf;
-		size_t resp_len;
-		rpc_opstatus_t op_status;
+		uint8_t *resp_buf = NULL;
+		size_t resp_len = 0;
+		service_status_t service_status = 0;
 
 		memcpy(req_buf, &req_msg, req_len);
 
-		this_context->client.rpc_status = rpc_caller_invoke(
-			this_context->client.caller, call_handle,
-			TS_BLOCK_STORAGE_OPCODE_CLOSE,
-			&op_status, &resp_buf, &resp_len);
+		this_context->client.rpc_status = rpc_caller_session_invoke(
+			call_handle, TS_BLOCK_STORAGE_OPCODE_CLOSE,
+			&resp_buf, &resp_len, &service_status);
 
-		if (this_context->client.rpc_status == TS_RPC_CALL_ACCEPTED)
-			psa_status = op_status;
+		if (this_context->client.rpc_status == RPC_SUCCESS)
+			psa_status = service_status;
 
-		rpc_caller_end(this_context->client.caller, call_handle);
+		rpc_caller_session_end(call_handle);
 	} else {
 
-		this_context->client.rpc_status = TS_RPC_ERROR_RESOURCE_FAILURE;
+		this_context->client.rpc_status = RPC_ERROR_INTERNAL;
 	}
 
 	return psa_status;
@@ -208,24 +206,24 @@
 	req_msg.len = buffer_size;
 
 	rpc_call_handle call_handle =
-		rpc_caller_begin(this_context->client.caller, &req_buf, req_len);
+		rpc_caller_session_begin(this_context->client.session, &req_buf, req_len,
+					 buffer_size);
 
 	if (call_handle) {
 
-		uint8_t *resp_buf;
-		size_t resp_len;
-		rpc_opstatus_t op_status;
+		uint8_t *resp_buf = NULL;
+		size_t resp_len = 0;
+		service_status_t service_status = 0;
 
 		memcpy(req_buf, &req_msg, req_len);
 
-		this_context->client.rpc_status = rpc_caller_invoke(
-			this_context->client.caller, call_handle,
-			TS_BLOCK_STORAGE_OPCODE_READ,
-			&op_status, &resp_buf, &resp_len);
+		this_context->client.rpc_status = rpc_caller_session_invoke(
+			call_handle, TS_BLOCK_STORAGE_OPCODE_READ, &resp_buf, &resp_len,
+			&service_status);
 
-		if (this_context->client.rpc_status == TS_RPC_CALL_ACCEPTED) {
+		if (this_context->client.rpc_status == RPC_SUCCESS) {
 
-			psa_status = op_status;
+			psa_status = service_status;
 
 			if (psa_status == PSA_SUCCESS) {
 
@@ -240,10 +238,10 @@
 			}
 		}
 
-		rpc_caller_end(this_context->client.caller, call_handle);
+		rpc_caller_session_end(call_handle);
 	} else {
 
-		this_context->client.rpc_status = TS_RPC_ERROR_RESOURCE_FAILURE;
+		this_context->client.rpc_status = RPC_ERROR_INTERNAL;
 	}
 
 	return psa_status;
@@ -271,13 +269,13 @@
 	req_msg.offset = offset;
 
 	rpc_call_handle call_handle =
-		rpc_caller_begin(this_context->client.caller, &req_buf, req_len);
+		rpc_caller_session_begin(this_context->client.session, &req_buf, req_len,
+					 sizeof(struct ts_block_storage_write_out));
 
 	if (call_handle) {
-
-		uint8_t *resp_buf;
-		size_t resp_len;
-		rpc_opstatus_t op_status;
+		uint8_t *resp_buf = NULL;
+		size_t resp_len = 0;
+		service_status_t service_status = 0;
 
 		/* Copy fixed size message */
 		memcpy(req_buf, &req_msg, sizeof(req_msg));
@@ -285,14 +283,13 @@
 		/* Copy variable length data */
 		memcpy(&req_buf[sizeof(req_msg)], data, data_len);
 
-		this_context->client.rpc_status = rpc_caller_invoke(
-			this_context->client.caller, call_handle,
-			TS_BLOCK_STORAGE_OPCODE_WRITE,
-			&op_status, &resp_buf, &resp_len);
+		this_context->client.rpc_status = rpc_caller_session_invoke(
+			call_handle, TS_BLOCK_STORAGE_OPCODE_WRITE,
+			&resp_buf, &resp_len, &service_status);
 
-		if (this_context->client.rpc_status == TS_RPC_CALL_ACCEPTED) {
+		if (this_context->client.rpc_status == RPC_SUCCESS) {
 
-			psa_status = op_status;
+			psa_status = service_status;
 
 			if (psa_status == PSA_SUCCESS) {
 
@@ -309,10 +306,10 @@
 			}
 		}
 
-		rpc_caller_end(this_context->client.caller, call_handle);
+		rpc_caller_session_end(call_handle);
 	} else {
 
-		this_context->client.rpc_status = TS_RPC_ERROR_RESOURCE_FAILURE;
+		this_context->client.rpc_status = RPC_ERROR_INTERNAL;
 	}
 
 	return psa_status;
@@ -337,29 +334,28 @@
 	req_msg.num_blocks = num_blocks;
 
 	rpc_call_handle call_handle =
-		rpc_caller_begin(this_context->client.caller, &req_buf, req_len);
+		rpc_caller_session_begin(this_context->client.session, &req_buf, req_len, 0);
 
 	if (call_handle) {
 
-		uint8_t *resp_buf;
-		size_t resp_len;
-		rpc_opstatus_t op_status;
+		uint8_t *resp_buf = NULL;
+		size_t resp_len = 0;
+		service_status_t service_status = 0;
 
 		/* Copy fixed size message */
 		memcpy(req_buf, &req_msg, sizeof(req_msg));
 
-		this_context->client.rpc_status = rpc_caller_invoke(
-			this_context->client.caller, call_handle,
-			TS_BLOCK_STORAGE_OPCODE_ERASE,
-			&op_status, &resp_buf, &resp_len);
+		this_context->client.rpc_status = rpc_caller_session_invoke(
+			call_handle, TS_BLOCK_STORAGE_OPCODE_ERASE,
+			&resp_buf, &resp_len, &service_status);
 
-		if (this_context->client.rpc_status == TS_RPC_CALL_ACCEPTED)
-			psa_status = op_status;
+		if (this_context->client.rpc_status == RPC_SUCCESS)
+			psa_status = service_status;
 
-		rpc_caller_end(this_context->client.caller, call_handle);
+		rpc_caller_session_end(call_handle);
 	} else {
 
-		this_context->client.rpc_status = TS_RPC_ERROR_RESOURCE_FAILURE;
+		this_context->client.rpc_status = RPC_ERROR_INTERNAL;
 	}
 
 	return psa_status;
@@ -367,9 +363,9 @@
 
 struct block_store *block_storage_client_init(
 	struct block_storage_client *block_storage_client,
-	struct rpc_caller *caller)
+	struct rpc_caller_session *session)
 {
-	service_client_init(&block_storage_client->client, caller);
+	service_client_init(&block_storage_client->client, session);
 
 	/* Define concrete block store interface */
 	static const struct block_store_interface interface = {
diff --git a/components/service/block_storage/block_store/client/block_storage_client.h b/components/service/block_storage/block_store/client/block_storage_client.h
index ee52ae0..244a05f 100644
--- a/components/service/block_storage/block_store/client/block_storage_client.h
+++ b/components/service/block_storage/block_store/client/block_storage_client.h
@@ -37,7 +37,7 @@
  */
 struct block_store *block_storage_client_init(
 	struct block_storage_client *block_storage_client,
-	struct rpc_caller *caller);
+	struct rpc_caller_session *session);
 
 /**
  * \brief De-initialize a block_storage_client
diff --git a/components/service/block_storage/factory/client/block_store_factory.c b/components/service/block_storage/factory/client/block_store_factory.c
index c84faef..842ca4d 100644
--- a/components/service/block_storage/factory/client/block_store_factory.c
+++ b/components/service/block_storage/factory/client/block_store_factory.c
@@ -13,7 +13,7 @@
 
 struct block_store_assembly {
 	struct block_storage_client client;
-	rpc_session_handle rpc_session_handle;
+	struct rpc_caller_session *rpc_session;
 	struct service_context *service_context;
 };
 
@@ -25,26 +25,19 @@
 
 	if (assembly) {
 
-		int status;
-
-		assembly->rpc_session_handle = NULL;
+		assembly->rpc_session = NULL;
 		assembly->service_context = NULL;
 
 		service_locator_init();
 
-		assembly->service_context = service_locator_query(sn, &status);
+		assembly->service_context = service_locator_query(sn);
 
 		if (assembly->service_context) {
 
-			struct rpc_caller *caller;
+			assembly->rpc_session = service_context_open(assembly->service_context);
 
-			assembly->rpc_session_handle = service_context_open(
-				assembly->service_context,
-				TS_RPC_ENCODING_PACKED_C,
-				&caller);
-
-			if (assembly->rpc_session_handle)
-				product = block_storage_client_init(&assembly->client, caller);
+			if (assembly->rpc_session)
+				product = block_storage_client_init(&assembly->client, assembly->rpc_session);
 		}
 
 		if (!product) {
@@ -72,10 +65,10 @@
 
 		if (assembly->service_context) {
 
-			if (assembly->rpc_session_handle) {
+			if (assembly->rpc_session) {
 				service_context_close(
-					assembly->service_context, assembly->rpc_session_handle);
-				assembly->rpc_session_handle = NULL;
+					assembly->service_context, assembly->rpc_session);
+				assembly->rpc_session = NULL;
 			}
 
 			service_context_relinquish(assembly->service_context);
diff --git a/components/service/block_storage/provider/block_storage_provider.c b/components/service/block_storage/provider/block_storage_provider.c
index b0715e6..e3b4f28 100644
--- a/components/service/block_storage/provider/block_storage_provider.c
+++ b/components/service/block_storage/provider/block_storage_provider.c
@@ -7,15 +7,15 @@
 #include "protocols/service/block_storage/packed-c/opcodes.h"
 #include "protocols/rpc/common/packed-c/status.h"
 #include "block_storage_provider.h"
-
+#include "block_storage_uuid.h"
 
 /* Service request handlers */
-static rpc_status_t get_partition_info_handler(void *context, struct call_req* req);
-static rpc_status_t open_handler(void *context, struct call_req* req);
-static rpc_status_t close_handler(void *context, struct call_req* req);
-static rpc_status_t read_handler(void *context, struct call_req* req);
-static rpc_status_t write_handler(void *context, struct call_req* req);
-static rpc_status_t erase_handler(void *context, struct call_req* req);
+static rpc_status_t get_partition_info_handler(void *context, struct rpc_request *req);
+static rpc_status_t open_handler(void *context, struct rpc_request *req);
+static rpc_status_t close_handler(void *context, struct rpc_request *req);
+static rpc_status_t read_handler(void *context, struct rpc_request *req);
+static rpc_status_t write_handler(void *context, struct rpc_request *req);
+static rpc_status_t erase_handler(void *context, struct rpc_request *req);
 
 /* Handler mapping table for service */
 static const struct service_handler handler_table[] = {
@@ -27,20 +27,21 @@
 	{TS_BLOCK_STORAGE_OPCODE_ERASE,              erase_handler}
 };
 
-struct rpc_interface *block_storage_provider_init(
+struct rpc_service_interface *block_storage_provider_init(
 	struct block_storage_provider *context,
 	struct block_store *block_store)
 {
-	struct rpc_interface *rpc_interface = NULL;
+	struct rpc_service_interface *rpc_interface = NULL;
+	const struct rpc_uuid block_storage_service_uuid = {
+		.uuid = TS_BLOCK_STORAGE_SERVICE_UUID
+	};
 
 	if (context) {
-
-		for (size_t encoding = 0; encoding < TS_RPC_ENCODING_LIMIT; ++encoding)
-			context->serializers[encoding] = NULL;
+		context->serializer = NULL;
 
 		context->block_store = block_store;
 
-		service_provider_init(&context->base_provider, context,
+		service_provider_init(&context->base_provider, context, &block_storage_service_uuid,
 			handler_table, sizeof(handler_table)/sizeof(struct service_handler));
 
 		rpc_interface = service_provider_get_rpc_interface(&context->base_provider);
@@ -57,40 +58,34 @@
 
 void block_storage_provider_register_serializer(
 	struct block_storage_provider *context,
-	unsigned int encoding,
 	const struct block_storage_serializer *serializer)
 {
-	if (encoding < TS_RPC_ENCODING_LIMIT)
-		context->serializers[encoding] = serializer;
+	context->serializer = serializer;
 }
 
 static const struct block_storage_serializer* get_block_storage_serializer(
 	struct block_storage_provider *context,
-	const struct call_req *req)
+	const struct rpc_request *req)
 {
-	const struct block_storage_serializer* serializer = NULL;
-	unsigned int encoding = call_req_get_encoding(req);
 
-	if (encoding < TS_RPC_ENCODING_LIMIT) serializer = context->serializers[encoding];
-
-	return serializer;
+	return context->serializer;
 }
 
-static rpc_status_t get_partition_info_handler(void *context, struct call_req *req)
+static rpc_status_t get_partition_info_handler(void *context, struct rpc_request *req)
 {
 	struct block_storage_provider *this_instance = (struct block_storage_provider*)context;
-	rpc_status_t rpc_status = TS_RPC_ERROR_SERIALIZATION_NOT_SUPPORTED;
+	rpc_status_t rpc_status = RPC_ERROR_INTERNAL;
 
-	struct call_param_buf *req_buf = call_req_get_req_buf(req);
 	const struct block_storage_serializer *serializer =
 		get_block_storage_serializer(this_instance, req);
 
 	struct uuid_octets partition_guid = {0};
 
 	if (serializer)
-		rpc_status = serializer->deserialize_get_partition_info_req(req_buf, &partition_guid);
+		rpc_status = serializer->deserialize_get_partition_info_req(&req->request,
+									    &partition_guid);
 
-	if (rpc_status == TS_RPC_CALL_ACCEPTED) {
+	if (rpc_status == RPC_SUCCESS) {
 
 		struct storage_partition_info partition_info;
 
@@ -99,62 +94,55 @@
 			&partition_guid,
 			&partition_info);
 
-		call_req_set_opstatus(req, op_status);
+		req->service_status = op_status;
 
-		if (op_status == PSA_SUCCESS) {
-
-			struct call_param_buf *resp_buf = call_req_get_resp_buf(req);
+		if (op_status == PSA_SUCCESS)
 			rpc_status = serializer->serialize_get_partition_info_resp(
-				resp_buf,
-				&partition_info);
-		}
+				&req->response, &partition_info);
 	}
 
 	return rpc_status;
 }
 
-static rpc_status_t open_handler(void *context, struct call_req *req)
+static rpc_status_t open_handler(void *context, struct rpc_request *req)
 {
 	struct block_storage_provider *this_instance = (struct block_storage_provider*)context;
-	rpc_status_t rpc_status = TS_RPC_ERROR_SERIALIZATION_NOT_SUPPORTED;
+	rpc_status_t rpc_status = RPC_ERROR_INTERNAL;
 
-	struct call_param_buf *req_buf = call_req_get_req_buf(req);
 	const struct block_storage_serializer *serializer =
 		get_block_storage_serializer(this_instance, req);
 
 	struct uuid_octets partition_guid = {0};
 
 	if (serializer)
-		rpc_status = serializer->deserialize_open_req(req_buf, &partition_guid);
+		rpc_status = serializer->deserialize_open_req(&req->request, &partition_guid);
 
-	if (rpc_status == TS_RPC_CALL_ACCEPTED) {
+	if (rpc_status == RPC_SUCCESS) {
 
 		storage_partition_handle_t handle = 0;
 
 		psa_status_t op_status = block_store_open(
 			this_instance->block_store,
-			req->caller_id,
+			req->source_id,
 			&partition_guid,
 			&handle);
 
-		call_req_set_opstatus(req, op_status);
+		req->service_status = op_status;
 
 		if (op_status == PSA_SUCCESS) {
-
-			struct call_param_buf *resp_buf = call_req_get_resp_buf(req);
-			rpc_status = serializer->serialize_open_resp(resp_buf, handle);
+			rpc_status = serializer->serialize_open_resp(&req->response, handle);
 		}
 	}
 
 	return rpc_status;
 }
 
-static rpc_status_t close_handler(void *context, struct call_req *req)
+static rpc_status_t close_handler(void *context, struct rpc_request *req)
 {
 	struct block_storage_provider *this_instance = (struct block_storage_provider*)context;
-	rpc_status_t rpc_status = TS_RPC_ERROR_SERIALIZATION_NOT_SUPPORTED;
+	rpc_status_t rpc_status = RPC_ERROR_INTERNAL;
 
-	struct call_param_buf *req_buf = call_req_get_req_buf(req);
+	struct rpc_buffer *req_buf = &req->request;
 	const struct block_storage_serializer *serializer =
 		get_block_storage_serializer(this_instance, req);
 
@@ -163,25 +151,25 @@
 	if (serializer)
 		rpc_status = serializer->deserialize_close_req(req_buf, &handle);
 
-	if (rpc_status == TS_RPC_CALL_ACCEPTED) {
+	if (rpc_status == RPC_SUCCESS) {
 
 		psa_status_t op_status = block_store_close(
 			this_instance->block_store,
-			req->caller_id,
+			req->source_id,
 			handle);
 
-		call_req_set_opstatus(req, op_status);
+		req->service_status = op_status;
 	}
 
 	return rpc_status;
 }
 
-static rpc_status_t read_handler(void *context, struct call_req *req)
+static rpc_status_t read_handler(void *context, struct rpc_request *req)
 {
 	struct block_storage_provider *this_instance = (struct block_storage_provider*)context;
-	rpc_status_t rpc_status = TS_RPC_ERROR_SERIALIZATION_NOT_SUPPORTED;
+	rpc_status_t rpc_status = RPC_ERROR_INTERNAL;
 
-	struct call_param_buf *req_buf = call_req_get_req_buf(req);
+	struct rpc_buffer *req_buf = &req->request;
 	const struct block_storage_serializer *serializer =
 		get_block_storage_serializer(this_instance, req);
 
@@ -193,36 +181,33 @@
 	if (serializer)
 		rpc_status = serializer->deserialize_read_req(req_buf, &handle, &lba, &offset, &len);
 
-	if (rpc_status == TS_RPC_CALL_ACCEPTED) {
-
-		struct call_param_buf *resp_buf = call_req_get_resp_buf(req);
-
+	if (rpc_status == RPC_SUCCESS) {
 		/* Defend against oversize read length */
-		if (len > resp_buf->size)
-			len = resp_buf->size;
+		if (len > req->response.size)
+			len = req->response.size;
 
 		psa_status_t op_status = block_store_read(
 			this_instance->block_store,
-			req->caller_id,
+			req->source_id,
 			handle,
 			lba,
 			offset,
 			len,
-			(uint8_t*)resp_buf->data,
-			&resp_buf->data_len);
+			(uint8_t *)req->response.data,
+			&req->response.data_length);
 
-		call_req_set_opstatus(req, op_status);
+		req->service_status = op_status;
 	}
 
 	return rpc_status;
 }
 
-static rpc_status_t write_handler(void *context, struct call_req *req)
+static rpc_status_t write_handler(void *context, struct rpc_request *req)
 {
 	struct block_storage_provider *this_instance = (struct block_storage_provider*)context;
-	rpc_status_t rpc_status = TS_RPC_ERROR_SERIALIZATION_NOT_SUPPORTED;
+	rpc_status_t rpc_status = RPC_ERROR_INTERNAL;
 
-	struct call_param_buf *req_buf = call_req_get_req_buf(req);
+	struct rpc_buffer *req_buf = &req->request;
 	const struct block_storage_serializer *serializer =
 		get_block_storage_serializer(this_instance, req);
 
@@ -236,13 +221,13 @@
 		rpc_status = serializer->deserialize_write_req(req_buf, &handle, &lba,
 			&offset, &data, &data_len);
 
-	if (rpc_status == TS_RPC_CALL_ACCEPTED) {
+	if (rpc_status == RPC_SUCCESS) {
 
 		size_t num_written = 0;
 
 		psa_status_t op_status = block_store_write(
 			this_instance->block_store,
-			req->caller_id,
+			req->source_id,
 			handle,
 			lba,
 			offset,
@@ -250,11 +235,11 @@
 			data_len,
 			&num_written);
 
-		call_req_set_opstatus(req, op_status);
+		req->service_status = op_status;
 
 		if (op_status == PSA_SUCCESS) {
 
-			struct call_param_buf *resp_buf = call_req_get_resp_buf(req);
+			struct rpc_buffer *resp_buf = &req->response;
 			rpc_status = serializer->serialize_write_resp(resp_buf, num_written);
 		}
 	}
@@ -262,12 +247,12 @@
 	return rpc_status;
 }
 
-static rpc_status_t erase_handler(void *context, struct call_req *req)
+static rpc_status_t erase_handler(void *context, struct rpc_request *req)
 {
 	struct block_storage_provider *this_instance = (struct block_storage_provider*)context;
-	rpc_status_t rpc_status = TS_RPC_ERROR_SERIALIZATION_NOT_SUPPORTED;
+	rpc_status_t rpc_status = RPC_ERROR_INTERNAL;
 
-	struct call_param_buf *req_buf = call_req_get_req_buf(req);
+	struct rpc_buffer *req_buf = &req->request;
 	const struct block_storage_serializer *serializer =
 		get_block_storage_serializer(this_instance, req);
 
@@ -279,16 +264,16 @@
 		rpc_status = serializer->deserialize_erase_req(req_buf, &handle,
 			&begin_lba, &num_blocks);
 
-	if (rpc_status == TS_RPC_CALL_ACCEPTED) {
+	if (rpc_status == RPC_SUCCESS) {
 
 		psa_status_t op_status = block_store_erase(
 			this_instance->block_store,
-			req->caller_id,
+			req->source_id,
 			handle,
 			begin_lba,
 			num_blocks);
 
-		call_req_set_opstatus(req, op_status);
+		req->service_status = op_status;
 	}
 
 	return rpc_status;
diff --git a/components/service/block_storage/provider/block_storage_provider.h b/components/service/block_storage/provider/block_storage_provider.h
index b647ac7..71f4e8c 100644
--- a/components/service/block_storage/provider/block_storage_provider.h
+++ b/components/service/block_storage/provider/block_storage_provider.h
@@ -7,10 +7,10 @@
 #ifndef BLOCK_STORAGE_PROVIDER_H
 #define BLOCK_STORAGE_PROVIDER_H
 
-#include "rpc/common/endpoint/rpc_interface.h"
+#include "components/rpc/common/endpoint/rpc_service_interface.h"
 #include "service/common/provider/service_provider.h"
 #include "service/block_storage/block_store/block_store.h"
-#include "service/block_storage/provider/serializer/block_storage_serializer.h"
+#include "serializer/block_storage_serializer.h"
 #include "protocols/rpc/common/packed-c/encoding.h"
 
 #ifdef __cplusplus
@@ -21,11 +21,11 @@
 struct block_storage_provider
 {
 	struct service_provider base_provider;
-	const struct block_storage_serializer *serializers[TS_RPC_ENCODING_LIMIT];
+	const struct block_storage_serializer *serializer;
 	struct block_store *block_store;
 };
 
-struct rpc_interface *block_storage_provider_init(
+struct rpc_service_interface *block_storage_provider_init(
 	struct block_storage_provider *context,
 	struct block_store *block_store);
 
@@ -34,7 +34,6 @@
 
 void block_storage_provider_register_serializer(
 	struct block_storage_provider *context,
-	unsigned int encoding,
 	const struct block_storage_serializer *serializer);
 
 #ifdef __cplusplus
diff --git a/components/service/block_storage/provider/block_storage_uuid.h b/components/service/block_storage/provider/block_storage_uuid.h
new file mode 100644
index 0000000..efda29e
--- /dev/null
+++ b/components/service/block_storage/provider/block_storage_uuid.h
@@ -0,0 +1,21 @@
+/*
+ * Copyright (c) 2023, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef BLOCK_STORAGE_UUID_H
+#define BLOCK_STORAGE_UUID_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define TS_BLOCK_STORAGE_SERVICE_UUID \
+{ 0x63, 0x64, 0x6e, 0x80, 0xeb, 0x52, 0x46, 0x2f, 0xac, 0x4f, 0x8c, 0xdf, 0x39, 0x87, 0x51, 0x9c }
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* BLOCK_STORAGE_UUID_H */
diff --git a/components/service/block_storage/provider/serializer/block_storage_serializer.h b/components/service/block_storage/provider/serializer/block_storage_serializer.h
index 493c73c..6aad6bf 100644
--- a/components/service/block_storage/provider/serializer/block_storage_serializer.h
+++ b/components/service/block_storage/provider/serializer/block_storage_serializer.h
@@ -10,7 +10,7 @@
 #include <stddef.h>
 #include <stdint.h>
 #include "common/uuid/uuid.h"
-#include "rpc/common/endpoint/rpc_interface.h"
+#include "components/rpc/common/endpoint/rpc_service_interface.h"
 #include "service/block_storage/block_store/block_store.h"
 
 /* Provides a common interface for parameter serialization operations
@@ -22,43 +22,43 @@
 struct block_storage_serializer {
 
 	/* Operation: get_partition_info */
-	rpc_status_t (*deserialize_get_partition_info_req)(const struct call_param_buf *req_buf,
+	rpc_status_t (*deserialize_get_partition_info_req)(const struct rpc_buffer *req_buf,
 		struct uuid_octets *partition_guid);
 
-	rpc_status_t (*serialize_get_partition_info_resp)(struct call_param_buf *resp_buf,
+	rpc_status_t (*serialize_get_partition_info_resp)(struct rpc_buffer *resp_buf,
 		struct storage_partition_info *info);
 
 	/* Operation: open */
-	rpc_status_t (*deserialize_open_req)(const struct call_param_buf *req_buf,
+	rpc_status_t (*deserialize_open_req)(const struct rpc_buffer *req_buf,
 		struct uuid_octets *partition_guid);
 
-	rpc_status_t (*serialize_open_resp)(struct call_param_buf *resp_buf,
+	rpc_status_t (*serialize_open_resp)(struct rpc_buffer *resp_buf,
 		storage_partition_handle_t handle);
 
 	/* Operation: close */
-	rpc_status_t (*deserialize_close_req)(const struct call_param_buf *req_buf,
+	rpc_status_t (*deserialize_close_req)(const struct rpc_buffer *req_buf,
 		storage_partition_handle_t *handle);
 
 	/* Operation: read */
-	rpc_status_t (*deserialize_read_req)(const struct call_param_buf *req_buf,
+	rpc_status_t (*deserialize_read_req)(const struct rpc_buffer *req_buf,
 		storage_partition_handle_t *handle,
 		uint64_t *lba,
 		size_t *offset,
 		size_t *len);
 
 	/* Operation: write */
-	rpc_status_t (*deserialize_write_req)(const struct call_param_buf *req_buf,
+	rpc_status_t (*deserialize_write_req)(const struct rpc_buffer *req_buf,
 		storage_partition_handle_t *handle,
 		uint64_t *lba,
 		size_t *offset,
 		const uint8_t **data,
 		size_t *data_len);
 
-	rpc_status_t (*serialize_write_resp)(struct call_param_buf *resp_buf,
+	rpc_status_t (*serialize_write_resp)(struct rpc_buffer *resp_buf,
 		size_t num_written);
 
 	/* Operation: erase */
-	rpc_status_t (*deserialize_erase_req)(const struct call_param_buf *req_buf,
+	rpc_status_t (*deserialize_erase_req)(const struct rpc_buffer *req_buf,
 		storage_partition_handle_t *handle,
 		uint64_t *begin_lba,
 		size_t *num_blocks);
diff --git a/components/service/block_storage/provider/serializer/packed-c/packedc_block_storage_serializer.c b/components/service/block_storage/provider/serializer/packed-c/packedc_block_storage_serializer.c
index 5e54039..f11d574 100644
--- a/components/service/block_storage/provider/serializer/packed-c/packedc_block_storage_serializer.c
+++ b/components/service/block_storage/provider/serializer/packed-c/packedc_block_storage_serializer.c
@@ -12,27 +12,27 @@
 
 
 /* Operation: get_partition_info */
-rpc_status_t deserialize_get_partition_info_req(const struct call_param_buf *req_buf,
+rpc_status_t deserialize_get_partition_info_req(const struct rpc_buffer *req_buf,
 	struct uuid_octets *partition_guid)
 {
-	rpc_status_t rpc_status = TS_RPC_ERROR_INVALID_REQ_BODY;
+	rpc_status_t rpc_status = RPC_ERROR_INVALID_REQUEST_BODY;
 	struct ts_block_storage_get_partition_info_in recv_msg;
 	size_t expected_fixed_len = sizeof(struct ts_block_storage_get_partition_info_in);
 
-	if (expected_fixed_len <= req_buf->data_len) {
+	if (expected_fixed_len <= req_buf->data_length) {
 
 		memcpy(&recv_msg, req_buf->data, expected_fixed_len);
 		memcpy(&partition_guid->octets, recv_msg.partition_guid, sizeof(partition_guid->octets));
-		rpc_status = TS_RPC_CALL_ACCEPTED;
+		rpc_status = RPC_SUCCESS;
 	}
 
 	return rpc_status;
 }
 
-rpc_status_t serialize_get_partition_info_resp(struct call_param_buf *resp_buf,
+rpc_status_t serialize_get_partition_info_resp(struct rpc_buffer *resp_buf,
 	struct storage_partition_info *info)
 {
-	rpc_status_t rpc_status = TS_RPC_ERROR_INTERNAL;
+	rpc_status_t rpc_status = RPC_ERROR_INTERNAL;
 	struct ts_block_storage_get_partition_info_out resp_msg;
 	size_t fixed_len = sizeof(struct ts_block_storage_get_partition_info_out);
 
@@ -48,35 +48,35 @@
 	if (fixed_len <= resp_buf->size) {
 
 		memcpy(resp_buf->data, &resp_msg, fixed_len);
-		resp_buf->data_len = fixed_len;
-		rpc_status = TS_RPC_CALL_ACCEPTED;
+		resp_buf->data_length = fixed_len;
+		rpc_status = RPC_SUCCESS;
 	}
 
 	return rpc_status;
 }
 
 /* Operation: open */
-rpc_status_t deserialize_open_req(const struct call_param_buf *req_buf,
+rpc_status_t deserialize_open_req(const struct rpc_buffer *req_buf,
 	struct uuid_octets *partition_guid)
 {
-	rpc_status_t rpc_status = TS_RPC_ERROR_INVALID_REQ_BODY;
+	rpc_status_t rpc_status = RPC_ERROR_INVALID_REQUEST_BODY;
 	struct ts_block_storage_open_in recv_msg;
 	size_t expected_fixed_len = sizeof(struct ts_block_storage_open_in);
 
-	if (expected_fixed_len <= req_buf->data_len) {
+	if (expected_fixed_len <= req_buf->data_length) {
 
 		memcpy(&recv_msg, req_buf->data, expected_fixed_len);
 		memcpy(&partition_guid->octets, recv_msg.partition_guid, sizeof(partition_guid->octets));
-		rpc_status = TS_RPC_CALL_ACCEPTED;
+		rpc_status = RPC_SUCCESS;
 	}
 
 	return rpc_status;
 }
 
-rpc_status_t serialize_open_resp(struct call_param_buf *resp_buf,
+rpc_status_t serialize_open_resp(struct rpc_buffer *resp_buf,
 	storage_partition_handle_t handle)
 {
-	rpc_status_t rpc_status = TS_RPC_ERROR_INTERNAL;
+	rpc_status_t rpc_status = RPC_ERROR_INTERNAL;
 	struct ts_block_storage_open_out resp_msg;
 	size_t fixed_len = sizeof(struct ts_block_storage_open_out);
 
@@ -85,68 +85,68 @@
 	if (fixed_len <= resp_buf->size) {
 
 		memcpy(resp_buf->data, &resp_msg, fixed_len);
-		resp_buf->data_len = fixed_len;
-		rpc_status = TS_RPC_CALL_ACCEPTED;
+		resp_buf->data_length = fixed_len;
+		rpc_status = RPC_SUCCESS;
 	}
 
 	return rpc_status;
 }
 
 /* Operation: close */
-rpc_status_t deserialize_close_req(const struct call_param_buf *req_buf,
+rpc_status_t deserialize_close_req(const struct rpc_buffer *req_buf,
 	storage_partition_handle_t *handle)
 {
-	rpc_status_t rpc_status = TS_RPC_ERROR_INVALID_REQ_BODY;
+	rpc_status_t rpc_status = RPC_ERROR_INVALID_REQUEST_BODY;
 	struct ts_block_storage_close_in recv_msg;
 	size_t expected_fixed_len = sizeof(struct ts_block_storage_close_in);
 
-	if (expected_fixed_len <= req_buf->data_len) {
+	if (expected_fixed_len <= req_buf->data_length) {
 
 		memcpy(&recv_msg, req_buf->data, expected_fixed_len);
 		*handle = recv_msg.handle;
-		rpc_status = TS_RPC_CALL_ACCEPTED;
+		rpc_status = RPC_SUCCESS;
 	}
 
 	return rpc_status;
 }
 
 /* Operation: read */
-rpc_status_t deserialize_read_req(const struct call_param_buf *req_buf,
+rpc_status_t deserialize_read_req(const struct rpc_buffer *req_buf,
 	storage_partition_handle_t *handle,
 	uint64_t *lba,
 	size_t *offset,
 	size_t *len)
 {
-	rpc_status_t rpc_status = TS_RPC_ERROR_INVALID_REQ_BODY;
+	rpc_status_t rpc_status = RPC_ERROR_INVALID_REQUEST_BODY;
 	struct ts_block_storage_read_in recv_msg;
 	size_t expected_fixed_len = sizeof(struct ts_block_storage_read_in);
 
-	if (expected_fixed_len <= req_buf->data_len) {
+	if (expected_fixed_len <= req_buf->data_length) {
 
 		memcpy(&recv_msg, req_buf->data, expected_fixed_len);
 		*handle = recv_msg.handle;
 		*lba = recv_msg.lba;
 		*offset = recv_msg.offset;
 		*len = recv_msg.len;
-		rpc_status = TS_RPC_CALL_ACCEPTED;
+		rpc_status = RPC_SUCCESS;
 	}
 
 	return rpc_status;
 }
 
 /* Operation: write */
-rpc_status_t deserialize_write_req(const struct call_param_buf *req_buf,
+rpc_status_t deserialize_write_req(const struct rpc_buffer *req_buf,
 	storage_partition_handle_t *handle,
 	uint64_t *lba,
 	size_t *offset,
 	const uint8_t **data,
-	size_t *data_len)
+	size_t *data_length)
 {
-	rpc_status_t rpc_status = TS_RPC_ERROR_INVALID_REQ_BODY;
+	rpc_status_t rpc_status = RPC_ERROR_INVALID_REQUEST_BODY;
 	struct ts_block_storage_write_in recv_msg;
 	size_t expected_fixed_len = sizeof(struct ts_block_storage_write_in);
 
-	if (expected_fixed_len <= req_buf->data_len) {
+	if (expected_fixed_len <= req_buf->data_length) {
 
 		memcpy(&recv_msg, req_buf->data, expected_fixed_len);
 
@@ -155,18 +155,18 @@
 		*offset = recv_msg.offset;
 
 		*data = (const uint8_t*)req_buf->data + expected_fixed_len;
-		*data_len = req_buf->data_len - expected_fixed_len;
+		*data_length = req_buf->data_length - expected_fixed_len;
 
-		rpc_status = TS_RPC_CALL_ACCEPTED;
+		rpc_status = RPC_SUCCESS;
 	}
 
 	return rpc_status;
 }
 
-rpc_status_t serialize_write_resp(struct call_param_buf *resp_buf,
+rpc_status_t serialize_write_resp(struct rpc_buffer *resp_buf,
 	size_t num_written)
 {
-	rpc_status_t rpc_status = TS_RPC_ERROR_INTERNAL;
+	rpc_status_t rpc_status = RPC_ERROR_INTERNAL;
 	struct ts_block_storage_write_out resp_msg;
 	size_t fixed_len = sizeof(struct ts_block_storage_write_out);
 
@@ -175,24 +175,24 @@
 	if (fixed_len <= resp_buf->size) {
 
 		memcpy(resp_buf->data, &resp_msg, fixed_len);
-		resp_buf->data_len = fixed_len;
-		rpc_status = TS_RPC_CALL_ACCEPTED;
+		resp_buf->data_length = fixed_len;
+		rpc_status = RPC_SUCCESS;
 	}
 
 	return rpc_status;
 }
 
 /* Operation: erase */
-rpc_status_t deserialize_erase_req(const struct call_param_buf *req_buf,
+rpc_status_t deserialize_erase_req(const struct rpc_buffer *req_buf,
 	storage_partition_handle_t *handle,
 	uint64_t *begin_lba,
 	size_t *num_blocks)
 {
-	rpc_status_t rpc_status = TS_RPC_ERROR_INVALID_REQ_BODY;
+	rpc_status_t rpc_status = RPC_ERROR_INVALID_REQUEST_BODY;
 	struct ts_block_storage_erase_in recv_msg;
 	size_t expected_fixed_len = sizeof(struct ts_block_storage_erase_in);
 
-	if (expected_fixed_len <= req_buf->data_len) {
+	if (expected_fixed_len <= req_buf->data_length) {
 
 		memcpy(&recv_msg, req_buf->data, expected_fixed_len);
 
@@ -200,7 +200,7 @@
 		*begin_lba = recv_msg.begin_lba;
 		*num_blocks = (size_t)recv_msg.num_blocks;
 
-		rpc_status = TS_RPC_CALL_ACCEPTED;
+		rpc_status = RPC_SUCCESS;
 	}
 
 	return rpc_status;
diff --git a/components/service/common/client/service_client.c b/components/service/common/client/service_client.c
index d5e8735..109c909 100644
--- a/components/service/common/client/service_client.c
+++ b/components/service/common/client/service_client.c
@@ -4,32 +4,31 @@
  * SPDX-License-Identifier: BSD-3-Clause
  */
 
-#include <stddef.h>
-#include <protocols/rpc/common/packed-c/status.h>
 #include "service_client.h"
+#include <stddef.h>
 
-psa_status_t service_client_init(
-	struct service_client *context,
-	struct rpc_caller *caller)
+psa_status_t service_client_init(struct service_client *context,
+				 struct rpc_caller_session *session)
 {
-	context->caller = caller;
-	context->rpc_status = TS_RPC_CALL_ACCEPTED;
+	if (!context || !session)
+		return PSA_ERROR_INVALID_ARGUMENT;
+
+	context->session = session;
+	context->rpc_status = RPC_SUCCESS;
 
 	context->service_info.supported_encodings = 0;
-	context->service_info.max_payload = 0;
+	context->service_info.max_payload = 4096;
 
 	return PSA_SUCCESS;
 }
 
-void service_client_deinit(
-	struct service_client *context)
+void service_client_deinit(struct service_client *context)
 {
-	context->caller = NULL;
+	context->session = NULL;
 }
 
-void service_client_set_service_info(
-	struct service_client *context,
-	const struct service_info *service_info)
+void service_client_set_service_info(struct service_client *context,
+				     const struct service_info *service_info)
 {
 	context->service_info = *service_info;
 }
diff --git a/components/service/common/client/service_client.h b/components/service/common/client/service_client.h
index df5b31b..70a6aee 100644
--- a/components/service/common/client/service_client.h
+++ b/components/service/common/client/service_client.h
@@ -9,7 +9,7 @@
 
 #include <stddef.h>
 #include <psa/error.h>
-#include <rpc_caller.h>
+#include "components/rpc/common/caller/rpc_caller_session.h"
 #include <service/common/client/service_info.h>
 
 #ifdef __cplusplus
@@ -23,11 +23,11 @@
  * Includes common information about the service that will have been discovered
  * in some way.  The TS discovery protocol provides a way to do this.  If
  * service info is not available, the service_info structure stays in its
- * initialied state.
+ * initialised state.
  */
 struct service_client
 {
-	struct rpc_caller *caller;
+	struct rpc_caller_session *session;
 	int rpc_status;
 	struct service_info service_info;
 };
@@ -45,7 +45,7 @@
  */
 psa_status_t service_client_init(
 	struct service_client *context,
-	struct rpc_caller *caller);
+	struct rpc_caller_session *session);
 
 /**
  * @brief      De-initialises the service client
diff --git a/components/service/common/include/psa/client.h b/components/service/common/include/psa/client.h
index 2f39aa6..db40d7a 100644
--- a/components/service/common/include/psa/client.h
+++ b/components/service/common/include/psa/client.h
@@ -109,7 +109,7 @@
  * \arg                           version[15:8] -- major version number.
  * \arg                           version[7:0]  -- minor version number.
  */
-uint32_t psa_framework_version(struct rpc_caller *caller);
+uint32_t psa_framework_version(struct rpc_caller_interface *caller);
 
 /**
  * \brief Retrieve the version of an RoT Service or indicate that it is not
@@ -122,7 +122,7 @@
  *                              caller is not permitted to access the service.
  * \retval > 0                  The version of the implemented RoT Service.
  */
-uint32_t psa_version(struct rpc_caller *caller, uint32_t sid);
+uint32_t psa_version(struct rpc_caller_interface *caller, uint32_t sid);
 
 /**
  * \brief Connect to an RoT Service by its SID.
@@ -143,7 +143,7 @@
  * \arg                           The caller is not allowed to access the RoT
  *                                service.
  */
-psa_handle_t psa_connect(struct rpc_caller *caller, uint32_t sid,
+psa_handle_t psa_connect(struct rpc_caller_interface *caller, uint32_t sid,
 			 uint32_t version);
 
 /**
@@ -179,7 +179,7 @@
  * \arg                           The message is unrecognized by the RoT
  *                                Service or incorrectly formatted.
  */
-psa_status_t psa_call(struct rpc_caller *caller, psa_handle_t handle,
+psa_status_t psa_call(struct rpc_caller_interface *caller, psa_handle_t handle,
 		      int32_t type, const struct psa_invec *in_vec,
 		      size_t in_len, struct psa_outvec *out_vec, size_t out_len);
 
@@ -217,7 +217,7 @@
  * \arg                           The message is unrecognized by the RoT
  *                                Service or incorrectly formatted.
  */
-psa_status_t psa_call_client_id(struct rpc_caller *caller, psa_handle_t handle,
+psa_status_t psa_call_client_id(struct rpc_caller_interface *caller, psa_handle_t handle,
 				int32_t client_id, int32_t type,
 				const struct psa_invec *in_vec, size_t in_len,
 				struct psa_outvec *out_vec, size_t out_len);
@@ -237,7 +237,7 @@
  * \arg                           The connection is currently handling a
  *                                request.
  */
-void psa_close(struct rpc_caller *caller, psa_handle_t handle);
+void psa_close(struct rpc_caller_interface *caller, psa_handle_t handle);
 
 #ifdef __cplusplus
 }
diff --git a/components/service/common/provider/service_provider.c b/components/service/common/provider/service_provider.c
index e2f21da..b6fbe3d 100644
--- a/components/service/common/provider/service_provider.c
+++ b/components/service/common/provider/service_provider.c
@@ -7,14 +7,14 @@
 #include "service_provider.h"
 #include <protocols/rpc/common/packed-c/status.h>
 #include <stddef.h>
+#include <string.h>
 
 static const struct service_handler *find_handler(const struct service_provider *sp,
-							  uint32_t opcode)
+						  uint32_t opcode)
 {
 	const struct service_handler *handler = NULL;
 
 	if ((opcode >= sp->opcode_range_lo) && (opcode <= sp->opcode_range_hi)) {
-
 		size_t index = 0;
 
 		while (index < sp->num_handlers) {
@@ -40,7 +40,6 @@
 	 * providers are chained.
 	 */
 	for (size_t index = 0; index < sp->num_handlers; index++) {
-
 		uint32_t opcode = service_handler_get_opcode(&sp->handlers[index]);
 
 		if (opcode < lo) lo = opcode;
@@ -51,37 +50,35 @@
 	sp->opcode_range_hi = hi;
 }
 
-static rpc_status_t receive(struct rpc_interface *rpc_iface, struct call_req *req)
+static rpc_status_t receive(void *context, struct rpc_request *req)
 {
+	struct rpc_service_interface *rpc_iface = (struct rpc_service_interface *)context;
 	rpc_status_t rpc_status;
 	struct service_provider *sp = NULL;
 	const struct service_handler *handler = NULL;
 
 	sp = (struct service_provider*)((char*)rpc_iface - offsetof(struct service_provider, iface));
-	handler = find_handler(sp, call_req_get_opcode(req));
+	handler = find_handler(sp, req->opcode);
 
 	if (handler) {
-
-		 rpc_status = service_handler_invoke(handler, rpc_iface->context, req);
-	}
-	else if (sp->successor) {
-
-		rpc_status = rpc_interface_receive(sp->successor, req);
-	}
-	else {
-
-		rpc_status = TS_RPC_ERROR_INVALID_OPCODE;
+		rpc_status = service_handler_invoke(handler, rpc_iface->context, req);
+	} else if (sp->successor) {
+		rpc_status = rpc_service_receive(sp->successor, req);
+	} else {
+		rpc_status = RPC_ERROR_INVALID_VALUE;
 	}
 
 	return rpc_status;
 }
 
 void service_provider_init(struct service_provider *sp, void *context,
-				 const struct service_handler *handlers,
-				 size_t num_handlers)
+			   const struct rpc_uuid *service_uuid,
+			   const struct service_handler *handlers,
+			   size_t num_handlers)
 {
 	sp->iface.receive = receive;
 	sp->iface.context = context;
+	memcpy(&sp->iface.uuid, service_uuid, sizeof(sp->iface.uuid));
 
 	sp->handlers = handlers;
 	sp->num_handlers = num_handlers;
@@ -92,7 +89,7 @@
 }
 
 void service_provider_extend(struct service_provider *context,
-                    struct service_provider *sub_provider)
+			     struct service_provider *sub_provider)
 {
 	sub_provider->successor = context->successor;
 	context->successor = &sub_provider->iface;
diff --git a/components/service/common/provider/service_provider.h b/components/service/common/provider/service_provider.h
index a0e853e..c64adb9 100644
--- a/components/service/common/provider/service_provider.h
+++ b/components/service/common/provider/service_provider.h
@@ -7,7 +7,7 @@
 #ifndef SERVICE_PROVIDER_H
 #define SERVICE_PROVIDER_H
 
-#include <rpc/common/endpoint/rpc_interface.h>
+#include "rpc/common/endpoint/rpc_service_interface.h"
 #include <stddef.h>
 #include <stdint.h>
 
@@ -22,11 +22,11 @@
  */
 struct service_handler {
 	uint32_t opcode;
-	rpc_status_t (*invoke)(void *context, struct call_req* req);
+	rpc_status_t (*invoke)(void *context, struct rpc_request *req);
 };
 
-static inline int service_handler_invoke(const struct service_handler *handler,
-						  void *context, struct call_req* req)
+static inline int service_handler_invoke(const struct service_handler *handler, void *context,
+					 struct rpc_request *req)
 {
 	return handler->invoke(context, req);
 }
@@ -39,27 +39,27 @@
 /** \brief Service provider
  *
  * A generalised service provider that acts as an rpc call endpoint.  It receives call
- * requests and delegates them to the approprate handle provided by a concrete service
+ * requests and delegates them to the appropriate handle provided by a concrete service
  * provider.  To support service specialization and proxying, unhandled requests may
  * optionally be passed to a delegate rpc_interface to form a chain of responsibility.
  */
 struct service_provider {
-	struct rpc_interface iface;
+	struct rpc_service_interface iface;
 	const struct service_handler *handlers;
 	size_t num_handlers;
 	uint32_t opcode_range_lo;
 	uint32_t opcode_range_hi;
-	struct rpc_interface *successor;
+	struct rpc_service_interface *successor;
 };
 
-static inline struct rpc_interface *service_provider_get_rpc_interface(struct service_provider *sp)
+static inline struct rpc_service_interface *service_provider_get_rpc_interface(struct service_provider *sp)
 {
 	return &sp->iface;
 }
 
 void service_provider_init(struct service_provider *sp, void *context,
-				 	const struct service_handler *handlers,
-				 	size_t num_handlers);
+			   const struct rpc_uuid *service_uuid,
+			   const struct service_handler *handlers, size_t num_handlers);
 
 /*
  * Extend the core set of operations provided by a service provider by
@@ -69,7 +69,7 @@
  * provider if needed.
  */
 void service_provider_extend(struct service_provider *context,
-                    struct service_provider *sub_provider);
+			     struct service_provider *sub_provider);
 
 /*
  * Link a successor to this service provider to extend the chain of responsibility
@@ -77,7 +77,7 @@
  * modular configuration of service capabilities.
  */
 static inline void service_provider_link_successor(struct service_provider *sp,
-					struct rpc_interface *successor)
+						   struct rpc_service_interface *successor)
 {
 	sp->successor = successor;
 }
diff --git a/components/service/common/provider/test/service_framework_tests.cpp b/components/service/common/provider/test/service_framework_tests.cpp
index afcbffa..568f9c6 100644
--- a/components/service/common/provider/test/service_framework_tests.cpp
+++ b/components/service/common/provider/test/service_framework_tests.cpp
@@ -9,46 +9,49 @@
 #include <service/common/provider/service_provider.h>
 #include <protocols/rpc/common/packed-c/status.h>
 #include <rpc/direct/direct_caller.h>
+#include "rpc/common/caller/rpc_caller_session.h"
 #include <CppUTest/TestHarness.h>
 
 
 TEST_GROUP(ServiceFrameworkTests)
 {
-	static rpc_status_t handlerThatSucceeds(void *context, struct call_req* req)
+	static rpc_status_t handlerThatSucceeds(void *context, struct rpc_request* req)
 	{
 		(void)context;
 
-		struct call_param_buf *respBuf = call_req_get_resp_buf(req);
+		struct rpc_buffer *respBuf = &req->response;
 
 		std::string responseString("Yay!");
-		respBuf->data_len = responseString.copy((char*)respBuf->data, respBuf->size);
+		respBuf->data_length = responseString.copy((char*)respBuf->data, respBuf->size);
 
-		call_req_set_opstatus(req, SERVICE_SPECIFIC_SUCCESS_CODE);
+		req->service_status = SERVICE_SPECIFIC_SUCCESS_CODE;
 
-		return TS_RPC_CALL_ACCEPTED;
+		return RPC_SUCCESS;
 	}
 
-	static rpc_status_t handlerThatFails(void *context, struct call_req* req)
+	static rpc_status_t handlerThatFails(void *context, struct rpc_request* req)
 	{
 		(void)context;
 
-		struct call_param_buf *respBuf = call_req_get_resp_buf(req);
+		struct rpc_buffer *respBuf = &req->response;
 
 		std::string responseString("Ehh!");
-		respBuf->data_len = responseString.copy((char*)respBuf->data, respBuf->size);
+		respBuf->data_length = responseString.copy((char*)respBuf->data, respBuf->size);
 
-		call_req_set_opstatus(req, SERVICE_SPECIFIC_ERROR_CODE);
+		req->service_status = SERVICE_SPECIFIC_ERROR_CODE;
 
-		return TS_RPC_CALL_ACCEPTED;
+		return RPC_SUCCESS;
 	}
 
 	void setup()
 	{
 		memset(&m_direct_caller, 0, sizeof(m_direct_caller));
+		memset(&m_session, 0, sizeof(m_session));
 	}
 
 	void teardown()
 	{
+		rpc_caller_session_close(&m_session);
 		direct_caller_deinit(&m_direct_caller);
 	}
 
@@ -58,39 +61,52 @@
 	static const int SERVICE_SPECIFIC_ERROR_CODE = 101;
 	static const int SERVICE_SPECIFIC_SUCCESS_CODE = 100;
 
-	struct direct_caller m_direct_caller;
+	struct rpc_caller_interface m_direct_caller;
+	struct rpc_caller_session m_session;
 };
 
 TEST(ServiceFrameworkTests, serviceWithNoOps)
 {
 	/* Constructs a service endpoint with no handlers */
+	struct rpc_uuid service_uuid = { .uuid = {
+		0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef,
+		0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef } };
 	struct service_provider service_provider;
+	rpc_status_t rpc_status = RPC_ERROR_INTERNAL;
 
-	service_provider_init(&service_provider, &service_provider, NULL, 0);
-	struct rpc_caller *caller = direct_caller_init_default(&m_direct_caller,
-											service_provider_get_rpc_interface(&service_provider));
+	service_provider_init(&service_provider, &service_provider, &service_uuid, NULL, 0);
+	rpc_status = direct_caller_init(&m_direct_caller,
+					service_provider_get_rpc_interface(&service_provider));
+	LONGS_EQUAL(RPC_SUCCESS, rpc_status);
+
+	rpc_status = rpc_caller_session_find_and_open(&m_session, &m_direct_caller, &service_uuid,
+						      4096);
+	LONGS_EQUAL(RPC_SUCCESS, rpc_status);
 
 	rpc_call_handle handle;
 	uint8_t *req_buf;
 	uint8_t *resp_buf;
 	size_t req_len = 100;
 	size_t resp_len;
-	rpc_opstatus_t opstatus;
+	service_status_t service_status;
 
-	handle = rpc_caller_begin(caller, &req_buf, req_len);
+	handle = rpc_caller_session_begin(&m_session, &req_buf, req_len, 0);
 	CHECK_TRUE(handle);
 
-	rpc_status_t rpc_status = rpc_caller_invoke(caller, handle, SOME_ARBITRARY_OPCODE,
-									&opstatus, &resp_buf, &resp_len);
+	rpc_status = rpc_caller_session_invoke(handle, SOME_ARBITRARY_OPCODE, &resp_buf, &resp_len,
+					       &service_status);
 
-	rpc_caller_end(caller, handle);
+	rpc_caller_session_end(handle);
 
-	LONGS_EQUAL(TS_RPC_ERROR_INVALID_OPCODE, rpc_status);
+	LONGS_EQUAL(RPC_ERROR_INVALID_VALUE, rpc_status);
 }
 
 TEST(ServiceFrameworkTests, serviceWithOps)
 {
 	/* Constructs a service endpoint with a couple of handlers */
+	struct rpc_uuid service_uuid = { .uuid = {
+		0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef,
+		0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef } };
 	struct service_handler handlers[2];
 	handlers[0].opcode = SOME_ARBITRARY_OPCODE;
 	handlers[0].invoke = handlerThatSucceeds;
@@ -98,71 +114,81 @@
 	handlers[1].invoke = handlerThatFails;
 
 	struct service_provider service_provider;
+	rpc_status_t rpc_status;
 
-	service_provider_init(&service_provider, &service_provider, handlers, 2);
-	struct rpc_caller *caller = direct_caller_init_default(&m_direct_caller,
-											service_provider_get_rpc_interface(&service_provider));
+	service_provider_init(&service_provider, &service_provider, &service_uuid, handlers, 2);
+	rpc_status = direct_caller_init(&m_direct_caller,
+					service_provider_get_rpc_interface(&service_provider));
+	LONGS_EQUAL(RPC_SUCCESS, rpc_status);
+
+	rpc_status = rpc_caller_session_find_and_open(&m_session, &m_direct_caller, &service_uuid,
+						      4096);
+	LONGS_EQUAL(RPC_SUCCESS, rpc_status);
 
 	rpc_call_handle handle;
-	rpc_status_t rpc_status;
 	uint8_t *req_buf;
 	uint8_t *resp_buf;
 	size_t req_len = 100;
 	size_t resp_len;
-	rpc_opstatus_t opstatus;
+	service_status_t service_status;
 	std::string respString;
 
 	/* Expect this call transaction to succeed */
-	handle = rpc_caller_begin(caller, &req_buf, req_len);
+	handle = rpc_caller_session_begin(&m_session, &req_buf, req_len, 0);
 	CHECK_TRUE(handle);
 
-	rpc_status = rpc_caller_invoke(caller, handle, SOME_ARBITRARY_OPCODE,
-									&opstatus, &resp_buf, &resp_len);
+	rpc_status = rpc_caller_session_invoke(handle, SOME_ARBITRARY_OPCODE, &resp_buf, &resp_len,
+					       &service_status);
 
 	respString = std::string((const char*)resp_buf, resp_len);
 
-	rpc_caller_end(caller, handle);
+	rpc_caller_session_end(handle);
 
-	LONGS_EQUAL(TS_RPC_CALL_ACCEPTED, rpc_status);
-	LONGS_EQUAL(SERVICE_SPECIFIC_SUCCESS_CODE, opstatus);
+	LONGS_EQUAL(RPC_SUCCESS, rpc_status);
+	LONGS_EQUAL(SERVICE_SPECIFIC_SUCCESS_CODE, service_status);
 	STRCMP_EQUAL("Yay!", respString.c_str());
 
 	/* Expect this call transaction to fail */
-	handle = rpc_caller_begin(caller, &req_buf, req_len);
+	handle = rpc_caller_session_begin(&m_session, &req_buf, req_len, 0);
 	CHECK_TRUE(handle);
 
-	rpc_status = rpc_caller_invoke(caller, handle, ANOTHER_ARBITRARY_OPCODE,
-		&opstatus, &resp_buf, &resp_len);
+	rpc_status = rpc_caller_session_invoke(handle, ANOTHER_ARBITRARY_OPCODE, &resp_buf,
+					       &resp_len, &service_status);
 
 	respString = std::string((const char*)resp_buf, resp_len);
 
-	rpc_caller_end(caller, handle);
+	rpc_caller_session_end(handle);
 
-	LONGS_EQUAL(TS_RPC_CALL_ACCEPTED, rpc_status);
-	LONGS_EQUAL(SERVICE_SPECIFIC_ERROR_CODE, opstatus);
+	LONGS_EQUAL(RPC_SUCCESS, rpc_status);
+	LONGS_EQUAL(SERVICE_SPECIFIC_ERROR_CODE, service_status);
 	STRCMP_EQUAL("Ehh!", respString.c_str());
 
 	/* Try an unsupported opcode */
-	handle = rpc_caller_begin(caller, &req_buf, req_len);
+	handle = rpc_caller_session_begin(&m_session, &req_buf, req_len, 0);
 	CHECK_TRUE(handle);
 
-	rpc_status = rpc_caller_invoke(caller, handle, YET_ANOTHER_ARBITRARY_OPCODE,
-		&opstatus, &resp_buf, &resp_len);
+	rpc_status = rpc_caller_session_invoke(handle, YET_ANOTHER_ARBITRARY_OPCODE, &resp_buf, &resp_len,
+					       &service_status);
 
-	rpc_caller_end(caller, handle);
+	rpc_caller_session_end(handle);
 
-	LONGS_EQUAL(TS_RPC_ERROR_INVALID_OPCODE, rpc_status);
+	LONGS_EQUAL(RPC_ERROR_INVALID_VALUE, rpc_status);
 }
 
 TEST(ServiceFrameworkTests, serviceProviderChain)
 {
+	struct rpc_uuid service_uuid = { .uuid = {
+		0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef,
+		0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef } };
+	rpc_status_t rpc_status;
+
 	/* Construct the base service provider */
 	struct service_handler base_handlers[1];
 	base_handlers[0].opcode = 100;
 	base_handlers[0].invoke = handlerThatSucceeds;
 
 	struct service_provider base_provider;
-	service_provider_init(&base_provider, &base_provider, base_handlers, 1);
+	service_provider_init(&base_provider, &base_provider, &service_uuid, base_handlers, 1);
 
 	/* Construct a sub provider and extend the base */
 	struct service_handler sub0_handlers[1];
@@ -170,7 +196,7 @@
 	sub0_handlers[0].invoke = handlerThatSucceeds;
 
 	struct service_provider sub0_provider;
-	service_provider_init(&sub0_provider, &sub0_provider, sub0_handlers, 1);
+	service_provider_init(&sub0_provider, &sub0_provider, &service_uuid, sub0_handlers, 1);
 	service_provider_extend(&base_provider, &sub0_provider);
 
 	/* Construct another sub provider and extend the base */
@@ -179,75 +205,76 @@
 	sub1_handlers[0].invoke = handlerThatSucceeds;
 
 	struct service_provider sub1_provider;
-	service_provider_init(&sub1_provider, &sub1_provider, sub1_handlers, 1);
+	service_provider_init(&sub1_provider, &sub1_provider, &service_uuid, sub1_handlers, 1);
 	service_provider_extend(&base_provider, &sub1_provider);
 
 	/* Use a direct_caller to make RPC calls to the base provider at the head of the chain */
-	struct rpc_caller *caller = direct_caller_init_default(&m_direct_caller,
-									service_provider_get_rpc_interface(&base_provider));
+	rpc_status = direct_caller_init(&m_direct_caller,
+					service_provider_get_rpc_interface(&base_provider));
+	LONGS_EQUAL(rpc_status, RPC_SUCCESS);
+
+	rpc_status = rpc_caller_session_find_and_open(&m_session, &m_direct_caller, &service_uuid,
+						      4096);
+	LONGS_EQUAL(rpc_status, RPC_SUCCESS);
 
 	rpc_call_handle handle;
-	rpc_status_t rpc_status;
 	uint8_t *req_buf;
 	uint8_t *resp_buf;
 	size_t req_len = 100;
 	size_t resp_len;
-	rpc_opstatus_t opstatus;
+	service_status_t service_status;
 	std::string respString;
 
 	/* Expect calls that will be handled by all three chained service providers to succeed */
-	handle = rpc_caller_begin(caller, &req_buf, req_len);
+	handle = rpc_caller_session_begin(&m_session, &req_buf, req_len, 0);
 	CHECK_TRUE(handle);
 
-	rpc_status = rpc_caller_invoke(caller, handle, 100,
-									&opstatus, &resp_buf, &resp_len);
+	rpc_status = rpc_caller_session_invoke(handle, 100, &resp_buf, &resp_len, &service_status);
+	LONGS_EQUAL(RPC_SUCCESS, rpc_status);
 
 	respString = std::string((const char*)resp_buf, resp_len);
 
-	rpc_caller_end(caller, handle);
+	rpc_caller_session_end(handle);
 
-	LONGS_EQUAL(TS_RPC_CALL_ACCEPTED, rpc_status);
-	LONGS_EQUAL(SERVICE_SPECIFIC_SUCCESS_CODE, opstatus);
+	LONGS_EQUAL(RPC_SUCCESS, rpc_status);
+	LONGS_EQUAL(SERVICE_SPECIFIC_SUCCESS_CODE, service_status);
 	STRCMP_EQUAL("Yay!", respString.c_str());
 
 	/* This one should beb handled by sub0 */
-	handle = rpc_caller_begin(caller, &req_buf, req_len);
+	handle = rpc_caller_session_begin(&m_session, &req_buf, req_len, 0);
 	CHECK_TRUE(handle);
 
-	rpc_status = rpc_caller_invoke(caller, handle, 200,
-									&opstatus, &resp_buf, &resp_len);
+	rpc_status = rpc_caller_session_invoke(handle, 200, &resp_buf, &resp_len, &service_status);
 
 	respString = std::string((const char*)resp_buf, resp_len);
 
-	rpc_caller_end(caller, handle);
+	rpc_caller_session_end(handle);
 
-	LONGS_EQUAL(TS_RPC_CALL_ACCEPTED, rpc_status);
-	LONGS_EQUAL(SERVICE_SPECIFIC_SUCCESS_CODE, opstatus);
+	LONGS_EQUAL(RPC_SUCCESS, rpc_status);
+	LONGS_EQUAL(SERVICE_SPECIFIC_SUCCESS_CODE, service_status);
 	STRCMP_EQUAL("Yay!", respString.c_str());
 
 	/* This one should beb handled by sub1 */
-	handle = rpc_caller_begin(caller, &req_buf, req_len);
+	handle = rpc_caller_session_begin(&m_session, &req_buf, req_len, 0);
 	CHECK_TRUE(handle);
 
-	rpc_status = rpc_caller_invoke(caller, handle, 300,
-									&opstatus, &resp_buf, &resp_len);
+	rpc_status = rpc_caller_session_invoke(handle, 300, &resp_buf, &resp_len, &service_status);
 
 	respString = std::string((const char*)resp_buf, resp_len);
 
-	rpc_caller_end(caller, handle);
+	rpc_caller_session_end(handle);
 
-	LONGS_EQUAL(TS_RPC_CALL_ACCEPTED, rpc_status);
-	LONGS_EQUAL(SERVICE_SPECIFIC_SUCCESS_CODE, opstatus);
+	LONGS_EQUAL(RPC_SUCCESS, rpc_status);
+	LONGS_EQUAL(SERVICE_SPECIFIC_SUCCESS_CODE, service_status);
 	STRCMP_EQUAL("Yay!", respString.c_str());
 
 	/* Try an unsupported opcode */
-	handle = rpc_caller_begin(caller, &req_buf, req_len);
+	handle = rpc_caller_session_begin(&m_session, &req_buf, req_len, 0);
 	CHECK_TRUE(handle);
 
-	rpc_status = rpc_caller_invoke(caller, handle, 400,
-		&opstatus, &resp_buf, &resp_len);
+	rpc_status = rpc_caller_session_invoke(handle, 400, &resp_buf, &resp_len, &service_status);
 
-	rpc_caller_end(caller, handle);
+	rpc_caller_session_end(handle);
 
-	LONGS_EQUAL(TS_RPC_ERROR_INVALID_OPCODE, rpc_status);
+	LONGS_EQUAL(RPC_ERROR_INVALID_VALUE, rpc_status);
 }
diff --git a/components/service/common/serializer/protobuf/pb_helper.h b/components/service/common/serializer/protobuf/pb_helper.h
index 1f109b0..61c0ae9 100644
--- a/components/service/common/serializer/protobuf/pb_helper.h
+++ b/components/service/common/serializer/protobuf/pb_helper.h
@@ -13,6 +13,8 @@
 extern "C" {
 #endif
 
+#define PB_PACKET_LENGTH(payload_length)	((payload_length) + 16)
+
 /* Returns an initialised pb_callback_t structure for encoding a variable length byte array */
 extern pb_callback_t pb_out_byte_array(const pb_bytes_array_t *byte_array);
 
diff --git a/components/service/crypto/backend/psa_ipc/crypto_ipc_backend.c b/components/service/crypto/backend/psa_ipc/crypto_ipc_backend.c
index 6262c0c..9bf1c78 100644
--- a/components/service/crypto/backend/psa_ipc/crypto_ipc_backend.c
+++ b/components/service/crypto/backend/psa_ipc/crypto_ipc_backend.c
@@ -10,9 +10,9 @@
 #include <protocols/rpc/common/packed-c/status.h>
 #include "crypto_ipc_backend.h"
 
-psa_status_t crypto_ipc_backend_init(struct rpc_caller *caller)
+psa_status_t crypto_ipc_backend_init(struct rpc_caller_session *session)
 {
-	psa_status_t status = psa_crypto_client_init(caller);
+	psa_status_t status = psa_crypto_client_init(session);
 
 	if (status == PSA_SUCCESS)
 		status = psa_crypto_init();
diff --git a/components/service/crypto/backend/psa_ipc/crypto_ipc_backend.h b/components/service/crypto/backend/psa_ipc/crypto_ipc_backend.h
index 4724364..27ac598 100644
--- a/components/service/crypto/backend/psa_ipc/crypto_ipc_backend.h
+++ b/components/service/crypto/backend/psa_ipc/crypto_ipc_backend.h
@@ -57,7 +57,7 @@
  *
  * \return PSA_SUCCESS if backend initialized successfully
  */
-psa_status_t crypto_ipc_backend_init(struct rpc_caller *caller);
+psa_status_t crypto_ipc_backend_init(struct rpc_caller_session *session);
 
 /**
  * \brief Clean-up to free any resource used by the crypto backend
diff --git a/components/service/crypto/backend/stub/stub_crypto_backend.c b/components/service/crypto/backend/stub/stub_crypto_backend.c
index f969b43..edb45f8 100644
--- a/components/service/crypto/backend/stub/stub_crypto_backend.c
+++ b/components/service/crypto/backend/stub/stub_crypto_backend.c
@@ -13,11 +13,20 @@
 
 psa_status_t stub_crypto_backend_init(void)
 {
-	static struct dummy_caller dummy_caller;
-	struct rpc_caller *caller = dummy_caller_init(&dummy_caller,
-		TS_RPC_CALL_ACCEPTED, PSA_ERROR_SERVICE_FAILURE);
+	static struct rpc_caller_interface dummy_caller;
+	struct rpc_caller_session session = { 0 };
+	rpc_status_t rpc_status = RPC_ERROR_INTERNAL;
+	psa_status_t status = PSA_ERROR_GENERIC_ERROR;
 
-	psa_status_t status = psa_crypto_client_init(caller);
+	rpc_status = dummy_caller_init(&dummy_caller, RPC_SUCCESS, PSA_ERROR_SERVICE_FAILURE);
+	if (rpc_status != RPC_SUCCESS)
+		return PSA_ERROR_GENERIC_ERROR;
+
+	rpc_status = rpc_caller_session_find_and_open(&session, &dummy_caller, NULL, 0);
+	if (rpc_status != RPC_SUCCESS)
+		return PSA_ERROR_GENERIC_ERROR;
+
+	status = psa_crypto_client_init(&session);
 
 	if (status == PSA_SUCCESS)
 		status = psa_crypto_init();
diff --git a/components/service/crypto/client/caller/packed-c/crypto_caller_aead.h b/components/service/crypto/client/caller/packed-c/crypto_caller_aead.h
index c4ffb20..bf39762 100644
--- a/components/service/crypto/client/caller/packed-c/crypto_caller_aead.h
+++ b/components/service/crypto/client/caller/packed-c/crypto_caller_aead.h
@@ -10,6 +10,7 @@
 #include <string.h>
 #include <stdlib.h>
 #include <psa/crypto.h>
+#include "rpc_caller_session.h"
 #include <service/common/client/service_client.h>
 #include <protocols/rpc/common/packed-c/status.h>
 #include <protocols/service/crypto/packed-c/opcodes.h>
@@ -36,23 +37,24 @@
 	rpc_call_handle call_handle;
 	uint8_t *req_buf;
 
-	call_handle = rpc_caller_begin(context->caller, &req_buf, req_len);
+	call_handle = rpc_caller_session_begin(context->session, &req_buf, req_len,
+					       sizeof(struct ts_crypto_aead_setup_out));
 
 	if (call_handle) {
 
 		uint8_t *resp_buf;
 		size_t resp_len;
-		rpc_opstatus_t opstatus;
+		service_status_t service_status;
 
 		memcpy(req_buf, &req_msg, req_len);
 
 		context->rpc_status =
-			rpc_caller_invoke(context->caller, call_handle,
-				opcode, &opstatus, &resp_buf, &resp_len);
+			rpc_caller_session_invoke(call_handle, opcode,
+				&resp_buf, &resp_len, &service_status);
 
-		if (context->rpc_status == TS_RPC_CALL_ACCEPTED) {
+		if (context->rpc_status == RPC_SUCCESS) {
 
-			psa_status = opstatus;
+			psa_status = service_status;
 
 			if (psa_status == PSA_SUCCESS) {
 
@@ -69,7 +71,7 @@
 			}
 		}
 
-		rpc_caller_end(context->caller, call_handle);
+		rpc_caller_session_end(call_handle);
 	}
 
 	return psa_status;
@@ -110,23 +112,23 @@
 	rpc_call_handle call_handle;
 	uint8_t *req_buf;
 
-	call_handle = rpc_caller_begin(context->caller, &req_buf, req_len);
+	call_handle = rpc_caller_session_begin(context->session, &req_buf, req_len, 0);
 
 	if (call_handle) {
 
 		uint8_t *resp_buf;
 		size_t resp_len;
-		rpc_opstatus_t opstatus;
+		service_status_t service_status;
 
 		memcpy(req_buf, &req_msg, req_fixed_len);
 
 		context->rpc_status =
-			rpc_caller_invoke(context->caller, call_handle,
-				TS_CRYPTO_OPCODE_AEAD_GENERATE_NONCE, &opstatus, &resp_buf, &resp_len);
+			rpc_caller_session_invoke(call_handle, TS_CRYPTO_OPCODE_AEAD_GENERATE_NONCE,
+						  &resp_buf, &resp_len, &service_status);
 
-		if (context->rpc_status == TS_RPC_CALL_ACCEPTED) {
+		if (context->rpc_status == RPC_SUCCESS) {
 
-			psa_status = opstatus;
+			psa_status = service_status;
 
 			if (psa_status == PSA_SUCCESS) {
 
@@ -154,7 +156,7 @@
 			}
 		}
 
-		rpc_caller_end(context->caller, call_handle);
+		rpc_caller_session_end(call_handle);
 	}
 
 	return psa_status;
@@ -182,13 +184,13 @@
 	rpc_call_handle call_handle;
 	uint8_t *req_buf;
 
-	call_handle = rpc_caller_begin(context->caller, &req_buf, req_len);
+	call_handle = rpc_caller_session_begin(context->session, &req_buf, req_len, 0);
 
 	if (call_handle) {
 
 		uint8_t *resp_buf;
 		size_t resp_len;
-		rpc_opstatus_t opstatus;
+		service_status_t service_status;
 		struct tlv_iterator req_iter;
 
 		memcpy(req_buf, &req_msg, req_fixed_len);
@@ -197,12 +199,13 @@
 		tlv_encode(&req_iter, &data_record);
 
 		context->rpc_status =
-			rpc_caller_invoke(context->caller, call_handle,
-				TS_CRYPTO_OPCODE_AEAD_SET_NONCE, &opstatus, &resp_buf, &resp_len);
+			rpc_caller_session_invoke(call_handle, TS_CRYPTO_OPCODE_AEAD_SET_NONCE,
+						  &resp_buf, &resp_len, &service_status);
 
-		if (context->rpc_status == TS_RPC_CALL_ACCEPTED) psa_status = opstatus;
+		if (context->rpc_status == RPC_SUCCESS)
+			psa_status = service_status;
 
-		rpc_caller_end(context->caller, call_handle);
+		rpc_caller_session_end(call_handle);
 	}
 
 	return psa_status;
@@ -225,23 +228,24 @@
 	rpc_call_handle call_handle;
 	uint8_t *req_buf;
 
-	call_handle = rpc_caller_begin(context->caller, &req_buf, req_len);
+	call_handle = rpc_caller_session_begin(context->session, &req_buf, req_len, 0);
 
 	if (call_handle) {
 
 		uint8_t *resp_buf;
 		size_t resp_len;
-		rpc_opstatus_t opstatus;
+		service_status_t service_status;
 
 		memcpy(req_buf, &req_msg, req_fixed_len);
 
 		context->rpc_status =
-			rpc_caller_invoke(context->caller, call_handle,
-				TS_CRYPTO_OPCODE_AEAD_SET_LENGTHS, &opstatus, &resp_buf, &resp_len);
+			rpc_caller_session_invoke(call_handle, TS_CRYPTO_OPCODE_AEAD_SET_LENGTHS,
+						  &resp_buf, &resp_len, &service_status);
 
-		if (context->rpc_status == TS_RPC_CALL_ACCEPTED) psa_status = opstatus;
+		if (context->rpc_status == RPC_SUCCESS)
+			psa_status = service_status;
 
-		rpc_caller_end(context->caller, call_handle);
+		rpc_caller_session_end(call_handle);
 	}
 
 	return psa_status;
@@ -269,13 +273,13 @@
 	rpc_call_handle call_handle;
 	uint8_t *req_buf;
 
-	call_handle = rpc_caller_begin(context->caller, &req_buf, req_len);
+	call_handle = rpc_caller_session_begin(context->session, &req_buf, req_len, 0);
 
 	if (call_handle) {
 
 		uint8_t *resp_buf;
 		size_t resp_len;
-		rpc_opstatus_t opstatus;
+		service_status_t service_status;
 		struct tlv_iterator req_iter;
 
 		memcpy(req_buf, &req_msg, req_fixed_len);
@@ -284,12 +288,13 @@
 		tlv_encode(&req_iter, &data_record);
 
 		context->rpc_status =
-			rpc_caller_invoke(context->caller, call_handle,
-				TS_CRYPTO_OPCODE_AEAD_UPDATE_AD, &opstatus, &resp_buf, &resp_len);
+			rpc_caller_session_invoke(call_handle, TS_CRYPTO_OPCODE_AEAD_UPDATE_AD,
+						  &resp_buf, &resp_len, &service_status);
 
-		if (context->rpc_status == TS_RPC_CALL_ACCEPTED) psa_status = opstatus;
+		if (context->rpc_status == RPC_SUCCESS)
+			psa_status = service_status;
 
-		rpc_caller_end(context->caller, call_handle);
+		rpc_caller_session_end(call_handle);
 	}
 
 	return psa_status;
@@ -321,13 +326,13 @@
 	rpc_call_handle call_handle;
 	uint8_t *req_buf;
 
-	call_handle = rpc_caller_begin(context->caller, &req_buf, req_len);
+	call_handle = rpc_caller_session_begin(context->session, &req_buf, req_len, 0);
 
 	if (call_handle) {
 
 		uint8_t *resp_buf;
 		size_t resp_len;
-		rpc_opstatus_t opstatus;
+		service_status_t service_status;
 		struct tlv_iterator req_iter;
 
 		memcpy(req_buf, &req_msg, req_fixed_len);
@@ -336,12 +341,12 @@
 		tlv_encode(&req_iter, &data_record);
 
 		context->rpc_status =
-			rpc_caller_invoke(context->caller, call_handle,
-				TS_CRYPTO_OPCODE_AEAD_UPDATE, &opstatus, &resp_buf, &resp_len);
+			rpc_caller_session_invoke(call_handle, TS_CRYPTO_OPCODE_AEAD_UPDATE,
+						  &resp_buf, &resp_len, &service_status);
 
-		if (context->rpc_status == TS_RPC_CALL_ACCEPTED) {
+		if (context->rpc_status == RPC_SUCCESS) {
 
-			psa_status = opstatus;
+			psa_status = service_status;
 
 			if (psa_status == PSA_SUCCESS) {
 
@@ -369,7 +374,7 @@
 			}
 		}
 
-		rpc_caller_end(context->caller, call_handle);
+		rpc_caller_session_end(call_handle);
 	}
 
 	return psa_status;
@@ -396,23 +401,23 @@
 	rpc_call_handle call_handle;
 	uint8_t *req_buf;
 
-	call_handle = rpc_caller_begin(context->caller, &req_buf, req_len);
+	call_handle = rpc_caller_session_begin(context->session, &req_buf, req_len, 0);
 
 	if (call_handle) {
 
 		uint8_t *resp_buf;
 		size_t resp_len;
-		rpc_opstatus_t opstatus;
+		service_status_t service_status;
 
 		memcpy(req_buf, &req_msg, req_fixed_len);
 
 		context->rpc_status =
-			rpc_caller_invoke(context->caller, call_handle,
-				TS_CRYPTO_OPCODE_AEAD_FINISH, &opstatus, &resp_buf, &resp_len);
+			rpc_caller_session_invoke(call_handle, TS_CRYPTO_OPCODE_AEAD_FINISH,
+						  &resp_buf, &resp_len, &service_status);
 
-		if (context->rpc_status == TS_RPC_CALL_ACCEPTED) {
+		if (context->rpc_status == RPC_SUCCESS) {
 
-			psa_status = opstatus;
+			psa_status = service_status;
 
 			if (psa_status == PSA_SUCCESS) {
 
@@ -458,7 +463,7 @@
 			}
 		}
 
-		rpc_caller_end(context->caller, call_handle);
+		rpc_caller_session_end(call_handle);
 	}
 
 	return psa_status;
@@ -490,13 +495,13 @@
 	rpc_call_handle call_handle;
 	uint8_t *req_buf;
 
-	call_handle = rpc_caller_begin(context->caller, &req_buf, req_len);
+	call_handle = rpc_caller_session_begin(context->session, &req_buf, req_len, 0);
 
 	if (call_handle) {
 
 		uint8_t *resp_buf;
 		size_t resp_len;
-		rpc_opstatus_t opstatus;
+		service_status_t service_status;
 		struct tlv_iterator req_iter;
 
 		memcpy(req_buf, &req_msg, req_fixed_len);
@@ -505,12 +510,12 @@
 		tlv_encode(&req_iter, &data_record);
 
 		context->rpc_status =
-			rpc_caller_invoke(context->caller, call_handle,
-				TS_CRYPTO_OPCODE_AEAD_VERIFY, &opstatus, &resp_buf, &resp_len);
+			rpc_caller_session_invoke(call_handle, TS_CRYPTO_OPCODE_AEAD_VERIFY,
+						  &resp_buf, &resp_len, &service_status);
 
-		if (context->rpc_status == TS_RPC_CALL_ACCEPTED) {
+		if (context->rpc_status == RPC_SUCCESS) {
 
-			psa_status = opstatus;
+			psa_status = service_status;
 
 			if (psa_status == PSA_SUCCESS) {
 
@@ -538,7 +543,7 @@
 			}
 		}
 
-		rpc_caller_end(context->caller, call_handle);
+		rpc_caller_session_end(call_handle);
 	}
 
 	return psa_status;
@@ -557,23 +562,24 @@
 	rpc_call_handle call_handle;
 	uint8_t *req_buf;
 
-	call_handle = rpc_caller_begin(context->caller, &req_buf, req_len);
+	call_handle = rpc_caller_session_begin(context->session, &req_buf, req_len, 0);
 
 	if (call_handle) {
 
 		uint8_t *resp_buf;
 		size_t resp_len;
-		rpc_opstatus_t opstatus;
+		service_status_t service_status;
 
 		memcpy(req_buf, &req_msg, req_fixed_len);
 
 		context->rpc_status =
-			rpc_caller_invoke(context->caller, call_handle,
-				TS_CRYPTO_OPCODE_AEAD_ABORT, &opstatus, &resp_buf, &resp_len);
+			rpc_caller_session_invoke(call_handle, TS_CRYPTO_OPCODE_AEAD_ABORT,
+						  &resp_buf, &resp_len, &service_status);
 
-		if (context->rpc_status == TS_RPC_CALL_ACCEPTED) psa_status = opstatus;
+		if (context->rpc_status == RPC_SUCCESS)
+			psa_status = service_status;
 
-		rpc_caller_end(context->caller, call_handle);
+		rpc_caller_session_end(call_handle);
 	}
 
 	return psa_status;
diff --git a/components/service/crypto/client/caller/packed-c/crypto_caller_asymmetric_decrypt.h b/components/service/crypto/client/caller/packed-c/crypto_caller_asymmetric_decrypt.h
index 3ff6b52..9b3a68c 100644
--- a/components/service/crypto/client/caller/packed-c/crypto_caller_asymmetric_decrypt.h
+++ b/components/service/crypto/client/caller/packed-c/crypto_caller_asymmetric_decrypt.h
@@ -54,13 +54,13 @@
 	rpc_call_handle call_handle;
 	uint8_t *req_buf;
 
-	call_handle = rpc_caller_begin(context->caller, &req_buf, req_len);
+	call_handle = rpc_caller_session_begin(context->session, &req_buf, req_len, 0);
 
 	if (call_handle) {
 
 		uint8_t *resp_buf;
 		size_t resp_len;
-		rpc_opstatus_t opstatus;
+		service_status_t service_status;
 		struct tlv_iterator req_iter;
 
 		memcpy(req_buf, &req_msg, req_fixed_len);
@@ -70,12 +70,12 @@
 		if (salt) tlv_encode(&req_iter, &salt_record);
 
 		context->rpc_status =
-			rpc_caller_invoke(context->caller, call_handle,
-					TS_CRYPTO_OPCODE_ASYMMETRIC_DECRYPT, &opstatus, &resp_buf, &resp_len);
+			rpc_caller_session_invoke(call_handle, TS_CRYPTO_OPCODE_ASYMMETRIC_DECRYPT,
+						  &resp_buf, &resp_len, &service_status);
 
-		if (context->rpc_status == TS_RPC_CALL_ACCEPTED) {
+		if (context->rpc_status == RPC_SUCCESS) {
 
-			psa_status = opstatus;
+			psa_status = service_status;
 
 			if (psa_status == PSA_SUCCESS) {
 
@@ -103,7 +103,7 @@
 			}
 		}
 
-		rpc_caller_end(context->caller, call_handle);
+		rpc_caller_session_end(call_handle);
 	}
 
 	return psa_status;
diff --git a/components/service/crypto/client/caller/packed-c/crypto_caller_asymmetric_encrypt.h b/components/service/crypto/client/caller/packed-c/crypto_caller_asymmetric_encrypt.h
index 8ad40a3..a260526 100644
--- a/components/service/crypto/client/caller/packed-c/crypto_caller_asymmetric_encrypt.h
+++ b/components/service/crypto/client/caller/packed-c/crypto_caller_asymmetric_encrypt.h
@@ -54,13 +54,14 @@
 	rpc_call_handle call_handle;
 	uint8_t *req_buf;
 
-	call_handle = rpc_caller_begin(context->caller, &req_buf, req_len);
+	call_handle = rpc_caller_session_begin(context->session, &req_buf, req_len,
+					       tlv_required_space(output_size));
 
 	if (call_handle) {
 
 		uint8_t *resp_buf;
 		size_t resp_len;
-		rpc_opstatus_t opstatus = PSA_ERROR_GENERIC_ERROR;
+		service_status_t service_status = PSA_ERROR_GENERIC_ERROR;
 		struct tlv_iterator req_iter;
 
 		memcpy(req_buf, &req_msg, req_fixed_len);
@@ -70,12 +71,12 @@
 		if (salt) tlv_encode(&req_iter, &salt_record);
 
 		context->rpc_status =
-			rpc_caller_invoke(context->caller, call_handle,
-					TS_CRYPTO_OPCODE_ASYMMETRIC_ENCRYPT, &opstatus, &resp_buf, &resp_len);
+			rpc_caller_session_invoke(call_handle, TS_CRYPTO_OPCODE_ASYMMETRIC_ENCRYPT,
+						  &resp_buf, &resp_len, &service_status);
 
-		if (context->rpc_status == TS_RPC_CALL_ACCEPTED) {
+		if (context->rpc_status == RPC_SUCCESS) {
 
-			psa_status = opstatus;
+			psa_status = service_status;
 
 			if (psa_status == PSA_SUCCESS) {
 
@@ -103,7 +104,7 @@
 			}
 		}
 
-		rpc_caller_end(context->caller, call_handle);
+		rpc_caller_session_end(call_handle);
 	}
 
 	return psa_status;
diff --git a/components/service/crypto/client/caller/packed-c/crypto_caller_cipher.h b/components/service/crypto/client/caller/packed-c/crypto_caller_cipher.h
index 632ca35..de087da 100644
--- a/components/service/crypto/client/caller/packed-c/crypto_caller_cipher.h
+++ b/components/service/crypto/client/caller/packed-c/crypto_caller_cipher.h
@@ -36,23 +36,23 @@
 	rpc_call_handle call_handle;
 	uint8_t *req_buf;
 
-	call_handle = rpc_caller_begin(context->caller, &req_buf, req_len);
+	call_handle = rpc_caller_session_begin(context->session, &req_buf, req_len, 0);
 
 	if (call_handle) {
 
 		uint8_t *resp_buf;
 		size_t resp_len;
-		rpc_opstatus_t opstatus;
+		service_status_t service_status;
 
 		memcpy(req_buf, &req_msg, req_len);
 
 		context->rpc_status =
-			rpc_caller_invoke(context->caller, call_handle,
-				opcode, &opstatus, &resp_buf, &resp_len);
+			rpc_caller_session_invoke(call_handle, opcode, &resp_buf, &resp_len,
+						  &service_status);
 
-		if (context->rpc_status == TS_RPC_CALL_ACCEPTED) {
+		if (context->rpc_status == RPC_SUCCESS) {
 
-			psa_status = opstatus;
+			psa_status = service_status;
 
 			if (psa_status == PSA_SUCCESS) {
 
@@ -69,7 +69,7 @@
 			}
 		}
 
-		rpc_caller_end(context->caller, call_handle);
+		rpc_caller_session_end(call_handle);
 	}
 
 	return psa_status;
@@ -110,23 +110,25 @@
 	rpc_call_handle call_handle;
 	uint8_t *req_buf;
 
-	call_handle = rpc_caller_begin(context->caller, &req_buf, req_len);
+	call_handle = rpc_caller_session_begin(context->session, &req_buf, req_len,
+					       tlv_required_space(iv_size));
 
 	if (call_handle) {
 
 		uint8_t *resp_buf;
 		size_t resp_len;
-		rpc_opstatus_t opstatus;
+		service_status_t service_status;
 
 		memcpy(req_buf, &req_msg, req_fixed_len);
 
 		context->rpc_status =
-			rpc_caller_invoke(context->caller, call_handle,
-				TS_CRYPTO_OPCODE_CIPHER_GENERATE_IV, &opstatus, &resp_buf, &resp_len);
+			rpc_caller_session_invoke(call_handle,
+				TS_CRYPTO_OPCODE_CIPHER_GENERATE_IV, &resp_buf, &resp_len,
+				&service_status);
 
-		if (context->rpc_status == TS_RPC_CALL_ACCEPTED) {
+		if (context->rpc_status == RPC_SUCCESS) {
 
-			psa_status = opstatus;
+			psa_status = service_status;
 
 			if (psa_status == PSA_SUCCESS) {
 
@@ -154,7 +156,7 @@
 			}
 		}
 
-		rpc_caller_end(context->caller, call_handle);
+		rpc_caller_session_end(call_handle);
 	}
 
 	return psa_status;
@@ -182,13 +184,13 @@
 	rpc_call_handle call_handle;
 	uint8_t *req_buf;
 
-	call_handle = rpc_caller_begin(context->caller, &req_buf, req_len);
+	call_handle = rpc_caller_session_begin(context->session, &req_buf, req_len, 0);
 
 	if (call_handle) {
 
 		uint8_t *resp_buf;
 		size_t resp_len;
-		rpc_opstatus_t opstatus;
+		service_status_t service_status;
 		struct tlv_iterator req_iter;
 
 		memcpy(req_buf, &req_msg, req_fixed_len);
@@ -197,12 +199,13 @@
 		tlv_encode(&req_iter, &data_record);
 
 		context->rpc_status =
-			rpc_caller_invoke(context->caller, call_handle,
-				TS_CRYPTO_OPCODE_CIPHER_SET_IV, &opstatus, &resp_buf, &resp_len);
+			rpc_caller_session_invoke(call_handle, TS_CRYPTO_OPCODE_CIPHER_SET_IV,
+						  &resp_buf, &resp_len, &service_status);
 
-		if (context->rpc_status == TS_RPC_CALL_ACCEPTED) psa_status = opstatus;
+		if (context->rpc_status == RPC_SUCCESS)
+			psa_status = service_status;
 
-		rpc_caller_end(context->caller, call_handle);
+		rpc_caller_session_end(call_handle);
 	}
 
 	return psa_status;
@@ -234,13 +237,13 @@
 	rpc_call_handle call_handle;
 	uint8_t *req_buf;
 
-	call_handle = rpc_caller_begin(context->caller, &req_buf, req_len);
+	call_handle = rpc_caller_session_begin(context->session, &req_buf, req_len, 0);
 
 	if (call_handle) {
 
 		uint8_t *resp_buf;
 		size_t resp_len;
-		rpc_opstatus_t opstatus;
+		service_status_t service_status;
 		struct tlv_iterator req_iter;
 
 		memcpy(req_buf, &req_msg, req_fixed_len);
@@ -249,12 +252,12 @@
 		tlv_encode(&req_iter, &data_record);
 
 		context->rpc_status =
-			rpc_caller_invoke(context->caller, call_handle,
-				TS_CRYPTO_OPCODE_CIPHER_UPDATE, &opstatus, &resp_buf, &resp_len);
+			rpc_caller_session_invoke(call_handle, TS_CRYPTO_OPCODE_CIPHER_UPDATE,
+						  &resp_buf, &resp_len, &service_status);
 
-		if (context->rpc_status == TS_RPC_CALL_ACCEPTED) {
+		if (context->rpc_status == RPC_SUCCESS) {
 
-			psa_status = opstatus;
+			psa_status = service_status;
 
 			if (psa_status == PSA_SUCCESS) {
 
@@ -282,7 +285,7 @@
 			}
 		}
 
-		rpc_caller_end(context->caller, call_handle);
+		rpc_caller_session_end(call_handle);
 	}
 
 	return psa_status;
@@ -305,23 +308,23 @@
 	rpc_call_handle call_handle;
 	uint8_t *req_buf;
 
-	call_handle = rpc_caller_begin(context->caller, &req_buf, req_len);
+	call_handle = rpc_caller_session_begin(context->session, &req_buf, req_len, 0);
 
 	if (call_handle) {
 
 		uint8_t *resp_buf;
 		size_t resp_len;
-		rpc_opstatus_t opstatus;
+		service_status_t service_status;
 
 		memcpy(req_buf, &req_msg, req_fixed_len);
 
 		context->rpc_status =
-			rpc_caller_invoke(context->caller, call_handle,
-				TS_CRYPTO_OPCODE_CIPHER_FINISH, &opstatus, &resp_buf, &resp_len);
+			rpc_caller_session_invoke(call_handle, TS_CRYPTO_OPCODE_CIPHER_FINISH,
+						  &resp_buf, &resp_len, &service_status);
 
-		if (context->rpc_status == TS_RPC_CALL_ACCEPTED) {
+		if (context->rpc_status == RPC_SUCCESS) {
 
-			psa_status = opstatus;
+			psa_status = service_status;
 
 			if (psa_status == PSA_SUCCESS) {
 
@@ -349,7 +352,7 @@
 			}
 		}
 
-		rpc_caller_end(context->caller, call_handle);
+		rpc_caller_session_end(call_handle);
 	}
 
 	return psa_status;
@@ -368,23 +371,24 @@
 	rpc_call_handle call_handle;
 	uint8_t *req_buf;
 
-	call_handle = rpc_caller_begin(context->caller, &req_buf, req_len);
+	call_handle = rpc_caller_session_begin(context->session, &req_buf, req_len, 0);
 
 	if (call_handle) {
 
 		uint8_t *resp_buf;
 		size_t resp_len;
-		rpc_opstatus_t opstatus;
+		service_status_t service_status;
 
 		memcpy(req_buf, &req_msg, req_fixed_len);
 
 		context->rpc_status =
-			rpc_caller_invoke(context->caller, call_handle,
-				TS_CRYPTO_OPCODE_CIPHER_ABORT, &opstatus, &resp_buf, &resp_len);
+			rpc_caller_session_invoke(call_handle, TS_CRYPTO_OPCODE_CIPHER_ABORT,
+						  &resp_buf, &resp_len, &service_status);
 
-		if (context->rpc_status == TS_RPC_CALL_ACCEPTED) psa_status = opstatus;
+		if (context->rpc_status == RPC_SUCCESS)
+			psa_status = service_status;
 
-		rpc_caller_end(context->caller, call_handle);
+		rpc_caller_session_end(call_handle);
 	}
 
 	return psa_status;
diff --git a/components/service/crypto/client/caller/packed-c/crypto_caller_copy_key.h b/components/service/crypto/client/caller/packed-c/crypto_caller_copy_key.h
index 8336bdf..0e03ebe 100644
--- a/components/service/crypto/client/caller/packed-c/crypto_caller_copy_key.h
+++ b/components/service/crypto/client/caller/packed-c/crypto_caller_copy_key.h
@@ -37,22 +37,24 @@
 	rpc_call_handle call_handle;
 	uint8_t *req_buf;
 
-	call_handle = rpc_caller_begin(context->caller, &req_buf, req_len);
+	call_handle = rpc_caller_session_begin(context->session, &req_buf, req_len,
+					       sizeof(struct ts_crypto_copy_key_out));
 
 	if (call_handle) {
 
 		uint8_t *resp_buf;
 		size_t resp_len;
-		rpc_opstatus_t opstatus;
+		service_status_t service_status;
 
 		memcpy(req_buf, &req_msg, req_len);
 
-		context->rpc_status = rpc_caller_invoke(context->caller, call_handle,
-			TS_CRYPTO_OPCODE_COPY_KEY, &opstatus, &resp_buf, &resp_len);
+		context->rpc_status =
+			rpc_caller_session_invoke(call_handle, TS_CRYPTO_OPCODE_COPY_KEY,
+						  &resp_buf, &resp_len, &service_status);
 
-		if (context->rpc_status == TS_RPC_CALL_ACCEPTED) {
+		if (context->rpc_status == RPC_SUCCESS) {
 
-			psa_status = opstatus;
+			psa_status = service_status;
 
 			if (psa_status == PSA_SUCCESS) {
 
@@ -69,7 +71,7 @@
 			}
 		}
 
-		rpc_caller_end(context->caller, call_handle);
+		rpc_caller_session_end(call_handle);
 	}
 
 	return psa_status;
diff --git a/components/service/crypto/client/caller/packed-c/crypto_caller_destroy_key.h b/components/service/crypto/client/caller/packed-c/crypto_caller_destroy_key.h
index ed3c81c..0a88ab5 100644
--- a/components/service/crypto/client/caller/packed-c/crypto_caller_destroy_key.h
+++ b/components/service/crypto/client/caller/packed-c/crypto_caller_destroy_key.h
@@ -19,37 +19,38 @@
 #endif
 
 static inline psa_status_t crypto_caller_destroy_key(struct service_client *context,
-    psa_key_id_t id)
+	psa_key_id_t id)
 {
-    psa_status_t psa_status = PSA_ERROR_GENERIC_ERROR;
-    struct ts_crypto_destroy_key_in req_msg;
-    size_t req_len = sizeof(struct ts_crypto_destroy_key_in);
+	psa_status_t psa_status = PSA_ERROR_GENERIC_ERROR;
+	struct ts_crypto_destroy_key_in req_msg;
+	size_t req_len = sizeof(struct ts_crypto_destroy_key_in);
 
-    req_msg.id = id;
+	req_msg.id = id;
 
-    rpc_call_handle call_handle;
-    uint8_t *req_buf;
+	rpc_call_handle call_handle;
+	uint8_t *req_buf;
 
-    call_handle = rpc_caller_begin(context->caller, &req_buf, req_len);
+	call_handle = rpc_caller_session_begin(context->session, &req_buf, req_len, 0);
 
-    if (call_handle) {
+	if (call_handle) {
 
-        uint8_t *resp_buf;
-        size_t resp_len;
-        rpc_opstatus_t opstatus;
+		uint8_t *resp_buf;
+		size_t resp_len;
+		service_status_t service_status;
 
-        memcpy(req_buf, &req_msg, req_len);
+		memcpy(req_buf, &req_msg, req_len);
 
-        context->rpc_status =
-            rpc_caller_invoke(context->caller, call_handle,
-                        TS_CRYPTO_OPCODE_DESTROY_KEY, &opstatus, &resp_buf, &resp_len);
+		context->rpc_status =
+			rpc_caller_session_invoke(call_handle, TS_CRYPTO_OPCODE_DESTROY_KEY,
+						  &resp_buf, &resp_len, &service_status);
 
-        if (context->rpc_status == TS_RPC_CALL_ACCEPTED) psa_status = opstatus;
+		if (context->rpc_status == RPC_SUCCESS)
+			psa_status = service_status;
 
-        rpc_caller_end(context->caller, call_handle);
-    }
+		rpc_caller_session_end(call_handle);
+	}
 
-    return psa_status;
+	return psa_status;
 }
 
 #ifdef __cplusplus
diff --git a/components/service/crypto/client/caller/packed-c/crypto_caller_export_key.h b/components/service/crypto/client/caller/packed-c/crypto_caller_export_key.h
index fb25ad2..bad11f6 100644
--- a/components/service/crypto/client/caller/packed-c/crypto_caller_export_key.h
+++ b/components/service/crypto/client/caller/packed-c/crypto_caller_export_key.h
@@ -36,23 +36,24 @@
 	rpc_call_handle call_handle;
 	uint8_t *req_buf;
 
-	call_handle = rpc_caller_begin(context->caller, &req_buf, req_len);
+	call_handle = rpc_caller_session_begin(context->session, &req_buf, req_len,
+					       tlv_required_space(data_size));
 
 	if (call_handle) {
 
 		uint8_t *resp_buf;
 		size_t resp_len;
-		rpc_opstatus_t opstatus;
+		service_status_t service_status;
 
 		memcpy(req_buf, &req_msg, req_len);
 
 		context->rpc_status =
-			rpc_caller_invoke(context->caller, call_handle,
-					TS_CRYPTO_OPCODE_EXPORT_KEY, &opstatus, &resp_buf, &resp_len);
+			rpc_caller_session_invoke(call_handle, TS_CRYPTO_OPCODE_EXPORT_KEY,
+						  &resp_buf, &resp_len, &service_status);
 
-		if (context->rpc_status == TS_RPC_CALL_ACCEPTED) {
+		if (context->rpc_status == RPC_SUCCESS) {
 
-			psa_status = opstatus;
+			psa_status = service_status;
 
 			if (psa_status == PSA_SUCCESS) {
 
@@ -80,7 +81,7 @@
 			}
 		}
 
-		rpc_caller_end(context->caller, call_handle);
+		rpc_caller_session_end(call_handle);
 	}
 
 	return psa_status;
diff --git a/components/service/crypto/client/caller/packed-c/crypto_caller_export_public_key.h b/components/service/crypto/client/caller/packed-c/crypto_caller_export_public_key.h
index 465e86a..0710af6 100644
--- a/components/service/crypto/client/caller/packed-c/crypto_caller_export_public_key.h
+++ b/components/service/crypto/client/caller/packed-c/crypto_caller_export_public_key.h
@@ -35,23 +35,24 @@
 	rpc_call_handle call_handle;
 	uint8_t *req_buf;
 
-	call_handle = rpc_caller_begin(context->caller, &req_buf, req_len);
+	call_handle = rpc_caller_session_begin(context->session, &req_buf, req_len,
+					       tlv_required_space(data_size));
 
 	if (call_handle) {
 
 		uint8_t *resp_buf;
 		size_t resp_len;
-		rpc_opstatus_t opstatus;
+		service_status_t service_status;
 
 		memcpy(req_buf, &req_msg, req_len);
 
 		context->rpc_status =
-			rpc_caller_invoke(context->caller, call_handle,
-				TS_CRYPTO_OPCODE_EXPORT_PUBLIC_KEY, &opstatus, &resp_buf, &resp_len);
+			rpc_caller_session_invoke(call_handle, TS_CRYPTO_OPCODE_EXPORT_PUBLIC_KEY,
+						  &resp_buf, &resp_len, &service_status);
 
-		if (context->rpc_status == TS_RPC_CALL_ACCEPTED) {
+		if (context->rpc_status == RPC_SUCCESS) {
 
-			psa_status = opstatus;
+			psa_status = service_status;
 
 			if (psa_status == PSA_SUCCESS) {
 
@@ -79,7 +80,7 @@
 			}
 		}
 
-		rpc_caller_end(context->caller, call_handle);
+		rpc_caller_session_end(call_handle);
 	}
 
 	return psa_status;
diff --git a/components/service/crypto/client/caller/packed-c/crypto_caller_generate_key.h b/components/service/crypto/client/caller/packed-c/crypto_caller_generate_key.h
index ccc952f..2dd67d5 100644
--- a/components/service/crypto/client/caller/packed-c/crypto_caller_generate_key.h
+++ b/components/service/crypto/client/caller/packed-c/crypto_caller_generate_key.h
@@ -37,23 +37,24 @@
 	rpc_call_handle call_handle;
 	uint8_t *req_buf;
 
-	call_handle = rpc_caller_begin(context->caller, &req_buf, req_len);
+	call_handle = rpc_caller_session_begin(context->session, &req_buf, req_len,
+					       sizeof(struct ts_crypto_generate_key_out));
 
 	if (call_handle) {
 
 		uint8_t *resp_buf;
 		size_t resp_len;
-		rpc_opstatus_t opstatus;
+		service_status_t service_status;
 
 		memcpy(req_buf, &req_msg, req_len);
 
 		context->rpc_status =
-			rpc_caller_invoke(context->caller, call_handle,
-						TS_CRYPTO_OPCODE_GENERATE_KEY, &opstatus, &resp_buf, &resp_len);
+			rpc_caller_session_invoke(call_handle, TS_CRYPTO_OPCODE_GENERATE_KEY,
+						  &resp_buf, &resp_len, &service_status);
 
-		if (context->rpc_status == TS_RPC_CALL_ACCEPTED) {
+		if (context->rpc_status == RPC_SUCCESS) {
 
-			psa_status = opstatus;
+			psa_status = service_status;
 
 			if (psa_status == PSA_SUCCESS) {
 
@@ -70,7 +71,7 @@
 			}
 		}
 
-		rpc_caller_end(context->caller, call_handle);
+		rpc_caller_session_end(call_handle);
 	}
 
 	return psa_status;
diff --git a/components/service/crypto/client/caller/packed-c/crypto_caller_generate_random.h b/components/service/crypto/client/caller/packed-c/crypto_caller_generate_random.h
index 33a0779..b9711bb 100644
--- a/components/service/crypto/client/caller/packed-c/crypto_caller_generate_random.h
+++ b/components/service/crypto/client/caller/packed-c/crypto_caller_generate_random.h
@@ -31,23 +31,24 @@
 	rpc_call_handle call_handle;
 	uint8_t *req_buf;
 
-	call_handle = rpc_caller_begin(context->caller, &req_buf, req_len);
+	call_handle = rpc_caller_session_begin(context->session, &req_buf, req_len,
+					       tlv_required_space(output_size));
 
 	if (call_handle) {
 
 		uint8_t *resp_buf;
 		size_t resp_len;
-		rpc_opstatus_t opstatus;
+		service_status_t service_status;
 
 		memcpy(req_buf, &req_msg, req_len);
 
 		context->rpc_status =
-			rpc_caller_invoke(context->caller, call_handle,
-					TS_CRYPTO_OPCODE_GENERATE_RANDOM, &opstatus, &resp_buf, &resp_len);
+			rpc_caller_session_invoke(call_handle, TS_CRYPTO_OPCODE_GENERATE_RANDOM,
+						  &resp_buf, &resp_len, &service_status);
 
-		if (context->rpc_status == TS_RPC_CALL_ACCEPTED) {
+		if (context->rpc_status == RPC_SUCCESS) {
 
-			psa_status = opstatus;
+			psa_status = service_status;
 
 			if (psa_status == PSA_SUCCESS) {
 
@@ -74,7 +75,7 @@
 			}
 		}
 
-		rpc_caller_end(context->caller, call_handle);
+		rpc_caller_session_end(call_handle);
 	}
 
 	return psa_status;
diff --git a/components/service/crypto/client/caller/packed-c/crypto_caller_get_key_attributes.h b/components/service/crypto/client/caller/packed-c/crypto_caller_get_key_attributes.h
index 9ea3eb4..1a79bc3 100644
--- a/components/service/crypto/client/caller/packed-c/crypto_caller_get_key_attributes.h
+++ b/components/service/crypto/client/caller/packed-c/crypto_caller_get_key_attributes.h
@@ -32,23 +32,24 @@
 	rpc_call_handle call_handle;
 	uint8_t *req_buf;
 
-	call_handle = rpc_caller_begin(context->caller, &req_buf, req_len);
+	call_handle = rpc_caller_session_begin(context->session, &req_buf, req_len,
+					       sizeof(struct ts_crypto_get_key_attributes_out));
 
 	if (call_handle) {
 
 		uint8_t *resp_buf;
 		size_t resp_len;
-		rpc_opstatus_t opstatus;
+		service_status_t service_status;
 
 		memcpy(req_buf, &req_msg, req_len);
 
 		context->rpc_status =
-			rpc_caller_invoke(context->caller, call_handle,
-						TS_CRYPTO_OPCODE_GET_KEY_ATTRIBUTES, &opstatus, &resp_buf, &resp_len);
+			rpc_caller_session_invoke(call_handle, TS_CRYPTO_OPCODE_GET_KEY_ATTRIBUTES,
+						  &resp_buf, &resp_len, &service_status);
 
-		if (context->rpc_status == TS_RPC_CALL_ACCEPTED) {
+		if (context->rpc_status == RPC_SUCCESS) {
 
-			psa_status = opstatus;
+			psa_status = service_status;
 
 			if (psa_status == PSA_SUCCESS) {
 
@@ -66,7 +67,7 @@
 			}
 		}
 
-		rpc_caller_end(context->caller, call_handle);
+		rpc_caller_session_end(call_handle);
 	}
 
 	return psa_status;
diff --git a/components/service/crypto/client/caller/packed-c/crypto_caller_hash.h b/components/service/crypto/client/caller/packed-c/crypto_caller_hash.h
index 3682007..924f15e 100644
--- a/components/service/crypto/client/caller/packed-c/crypto_caller_hash.h
+++ b/components/service/crypto/client/caller/packed-c/crypto_caller_hash.h
@@ -33,23 +33,23 @@
 	rpc_call_handle call_handle;
 	uint8_t *req_buf;
 
-	call_handle = rpc_caller_begin(context->caller, &req_buf, req_len);
+	call_handle = rpc_caller_session_begin(context->session, &req_buf, req_len, 0);
 
 	if (call_handle) {
 
 		uint8_t *resp_buf;
 		size_t resp_len;
-		rpc_opstatus_t opstatus;
+		service_status_t service_status;
 
 		memcpy(req_buf, &req_msg, req_len);
 
 		context->rpc_status =
-			rpc_caller_invoke(context->caller, call_handle,
-				TS_CRYPTO_OPCODE_HASH_SETUP, &opstatus, &resp_buf, &resp_len);
+			rpc_caller_session_invoke(call_handle, TS_CRYPTO_OPCODE_HASH_SETUP,
+						  &resp_buf, &resp_len, &service_status);
 
-		if (context->rpc_status == TS_RPC_CALL_ACCEPTED) {
+		if (context->rpc_status == RPC_SUCCESS) {
 
-			psa_status = opstatus;
+			psa_status = service_status;
 
 			if (psa_status == PSA_SUCCESS) {
 
@@ -66,7 +66,7 @@
 			}
 		}
 
-		rpc_caller_end(context->caller, call_handle);
+		rpc_caller_session_end(call_handle);
 	}
 
 	return psa_status;
@@ -94,13 +94,13 @@
 	rpc_call_handle call_handle;
 	uint8_t *req_buf;
 
-	call_handle = rpc_caller_begin(context->caller, &req_buf, req_len);
+	call_handle = rpc_caller_session_begin(context->session, &req_buf, req_len, 0);
 
 	if (call_handle) {
 
 		uint8_t *resp_buf;
 		size_t resp_len;
-		rpc_opstatus_t opstatus;
+		service_status_t service_status;
 		struct tlv_iterator req_iter;
 
 		memcpy(req_buf, &req_msg, req_fixed_len);
@@ -109,12 +109,13 @@
 		tlv_encode(&req_iter, &data_record);
 
 		context->rpc_status =
-			rpc_caller_invoke(context->caller, call_handle,
-				TS_CRYPTO_OPCODE_HASH_UPDATE, &opstatus, &resp_buf, &resp_len);
+			rpc_caller_session_invoke(call_handle, TS_CRYPTO_OPCODE_HASH_UPDATE,
+						  &resp_buf, &resp_len, &service_status);
 
-		if (context->rpc_status == TS_RPC_CALL_ACCEPTED) psa_status = opstatus;
+		if (context->rpc_status == RPC_SUCCESS)
+			psa_status = service_status;
 
-		rpc_caller_end(context->caller, call_handle);
+		rpc_caller_session_end(call_handle);
 	}
 
 	return psa_status;
@@ -137,23 +138,24 @@
 	rpc_call_handle call_handle;
 	uint8_t *req_buf;
 
-	call_handle = rpc_caller_begin(context->caller, &req_buf, req_len);
+	call_handle = rpc_caller_session_begin(context->session, &req_buf, req_len,
+					       tlv_required_space(hash_size));
 
 	if (call_handle) {
 
 		uint8_t *resp_buf;
 		size_t resp_len;
-		rpc_opstatus_t opstatus;
+		service_status_t service_status;
 
 		memcpy(req_buf, &req_msg, req_fixed_len);
 
 		context->rpc_status =
-			rpc_caller_invoke(context->caller, call_handle,
-				TS_CRYPTO_OPCODE_HASH_FINISH, &opstatus, &resp_buf, &resp_len);
+			rpc_caller_session_invoke(call_handle, TS_CRYPTO_OPCODE_HASH_FINISH,
+						  &resp_buf, &resp_len, &service_status);
 
-		if (context->rpc_status == TS_RPC_CALL_ACCEPTED) {
+		if (context->rpc_status == RPC_SUCCESS) {
 
-			psa_status = opstatus;
+			psa_status = service_status;
 
 			if (psa_status == PSA_SUCCESS) {
 
@@ -181,7 +183,7 @@
 			}
 		}
 
-		rpc_caller_end(context->caller, call_handle);
+		rpc_caller_session_end(call_handle);
 	}
 
 	return psa_status;
@@ -200,23 +202,24 @@
 	rpc_call_handle call_handle;
 	uint8_t *req_buf;
 
-	call_handle = rpc_caller_begin(context->caller, &req_buf, req_len);
+	call_handle = rpc_caller_session_begin(context->session, &req_buf, req_len, 0);
 
 	if (call_handle) {
 
 		uint8_t *resp_buf;
 		size_t resp_len;
-		rpc_opstatus_t opstatus;
+		service_status_t service_status;
 
 		memcpy(req_buf, &req_msg, req_fixed_len);
 
 		context->rpc_status =
-			rpc_caller_invoke(context->caller, call_handle,
-				TS_CRYPTO_OPCODE_HASH_ABORT, &opstatus, &resp_buf, &resp_len);
+			rpc_caller_session_invoke(call_handle, TS_CRYPTO_OPCODE_HASH_ABORT,
+						  &resp_buf, &resp_len, &service_status);
 
-		if (context->rpc_status == TS_RPC_CALL_ACCEPTED) psa_status = opstatus;
+		if (context->rpc_status == RPC_SUCCESS)
+			psa_status = service_status;
 
-		rpc_caller_end(context->caller, call_handle);
+		rpc_caller_session_end(call_handle);
 	}
 
 	return psa_status;
@@ -244,13 +247,13 @@
 	rpc_call_handle call_handle;
 	uint8_t *req_buf;
 
-	call_handle = rpc_caller_begin(context->caller, &req_buf, req_len);
+	call_handle = rpc_caller_session_begin(context->session, &req_buf, req_len, 0);
 
 	if (call_handle) {
 
 		uint8_t *resp_buf;
 		size_t resp_len;
-		rpc_opstatus_t opstatus;
+		service_status_t service_status;
 		struct tlv_iterator req_iter;
 
 		memcpy(req_buf, &req_msg, req_fixed_len);
@@ -259,12 +262,13 @@
 		tlv_encode(&req_iter, &data_record);
 
 		context->rpc_status =
-			rpc_caller_invoke(context->caller, call_handle,
-				TS_CRYPTO_OPCODE_HASH_VERIFY, &opstatus, &resp_buf, &resp_len);
+			rpc_caller_session_invoke(call_handle, TS_CRYPTO_OPCODE_HASH_VERIFY,
+						  &resp_buf, &resp_len, &service_status);
 
-		if (context->rpc_status == TS_RPC_CALL_ACCEPTED) psa_status = opstatus;
+		if (context->rpc_status == RPC_SUCCESS)
+			psa_status = service_status;
 
-		rpc_caller_end(context->caller, call_handle);
+		rpc_caller_session_end(call_handle);
 	}
 
 	return psa_status;
@@ -284,23 +288,23 @@
 	rpc_call_handle call_handle;
 	uint8_t *req_buf;
 
-	call_handle = rpc_caller_begin(context->caller, &req_buf, req_len);
+	call_handle = rpc_caller_session_begin(context->session, &req_buf, req_len, 0);
 
 	if (call_handle) {
 
 		uint8_t *resp_buf;
 		size_t resp_len;
-		rpc_opstatus_t opstatus;
+		service_status_t service_status;
 
 		memcpy(req_buf, &req_msg, req_fixed_len);
 
 		context->rpc_status =
-			rpc_caller_invoke(context->caller, call_handle,
-				TS_CRYPTO_OPCODE_HASH_CLONE, &opstatus, &resp_buf, &resp_len);
+			rpc_caller_session_invoke(call_handle, TS_CRYPTO_OPCODE_HASH_CLONE,
+						  &resp_buf, &resp_len, &service_status);
 
-		if (context->rpc_status == TS_RPC_CALL_ACCEPTED) {
+		if (context->rpc_status == RPC_SUCCESS) {
 
-			psa_status = opstatus;
+			psa_status = service_status;
 
 			if (psa_status == PSA_SUCCESS) {
 
@@ -317,7 +321,7 @@
 			}
 		}
 
-		rpc_caller_end(context->caller, call_handle);
+		rpc_caller_session_end(call_handle);
 	}
 
 	return psa_status;
diff --git a/components/service/crypto/client/caller/packed-c/crypto_caller_import_key.h b/components/service/crypto/client/caller/packed-c/crypto_caller_import_key.h
index 8c1949d..bc2e6d7 100644
--- a/components/service/crypto/client/caller/packed-c/crypto_caller_import_key.h
+++ b/components/service/crypto/client/caller/packed-c/crypto_caller_import_key.h
@@ -45,13 +45,13 @@
 	rpc_call_handle call_handle;
 	uint8_t *req_buf;
 
-	call_handle = rpc_caller_begin(context->caller, &req_buf, req_len);
+	call_handle = rpc_caller_session_begin(context->session, &req_buf, req_len, 0);
 
 	if (call_handle) {
 
 		uint8_t *resp_buf;
 		size_t resp_len;
-		rpc_opstatus_t opstatus;
+		service_status_t service_status;
 		struct tlv_iterator req_iter;
 
 		memcpy(req_buf, &req_msg, req_fixed_len);
@@ -60,12 +60,12 @@
 		tlv_encode(&req_iter, &key_record);
 
 		context->rpc_status =
-			rpc_caller_invoke(context->caller, call_handle,
-						TS_CRYPTO_OPCODE_IMPORT_KEY, &opstatus, &resp_buf, &resp_len);
+			rpc_caller_session_invoke(call_handle, TS_CRYPTO_OPCODE_IMPORT_KEY,
+						  &resp_buf, &resp_len, &service_status);
 
-		if (context->rpc_status == TS_RPC_CALL_ACCEPTED) {
+		if (context->rpc_status == RPC_SUCCESS) {
 
-			psa_status = opstatus;
+			psa_status = service_status;
 
 			if (psa_status == PSA_SUCCESS) {
 
@@ -82,7 +82,7 @@
 			}
 		}
 
-		rpc_caller_end(context->caller, call_handle);
+		rpc_caller_session_end(call_handle);
 	}
 
 	return psa_status;
diff --git a/components/service/crypto/client/caller/packed-c/crypto_caller_key_derivation.h b/components/service/crypto/client/caller/packed-c/crypto_caller_key_derivation.h
index 763e2af..c60e02d 100644
--- a/components/service/crypto/client/caller/packed-c/crypto_caller_key_derivation.h
+++ b/components/service/crypto/client/caller/packed-c/crypto_caller_key_derivation.h
@@ -34,23 +34,24 @@
 	rpc_call_handle call_handle;
 	uint8_t *req_buf;
 
-	call_handle = rpc_caller_begin(context->caller, &req_buf, req_len);
+	call_handle = rpc_caller_session_begin(context->session, &req_buf, req_len, 0);
 
 	if (call_handle) {
 
 		uint8_t *resp_buf;
 		size_t resp_len;
-		rpc_opstatus_t opstatus;
+		service_status_t service_status;
 
 		memcpy(req_buf, &req_msg, req_len);
 
 		context->rpc_status =
-			rpc_caller_invoke(context->caller, call_handle,
-				TS_CRYPTO_OPCODE_KEY_DERIVATION_SETUP, &opstatus, &resp_buf, &resp_len);
+			rpc_caller_session_invoke(call_handle,
+						  TS_CRYPTO_OPCODE_KEY_DERIVATION_SETUP,
+						  &resp_buf, &resp_len, &service_status);
 
-		if (context->rpc_status == TS_RPC_CALL_ACCEPTED) {
+		if (context->rpc_status == RPC_SUCCESS) {
 
-			psa_status = opstatus;
+			psa_status = service_status;
 
 			if (psa_status == PSA_SUCCESS) {
 
@@ -67,7 +68,7 @@
 			}
 		}
 
-		rpc_caller_end(context->caller, call_handle);
+		rpc_caller_session_end(call_handle);
 	}
 
 	return psa_status;
@@ -86,23 +87,24 @@
 	rpc_call_handle call_handle;
 	uint8_t *req_buf;
 
-	call_handle = rpc_caller_begin(context->caller, &req_buf, req_len);
+	call_handle = rpc_caller_session_begin(context->session, &req_buf, req_len, 0);
 
 	if (call_handle) {
 
 		uint8_t *resp_buf;
 		size_t resp_len;
-		rpc_opstatus_t opstatus;
+		service_status_t service_status;
 
 		memcpy(req_buf, &req_msg, req_len);
 
 		context->rpc_status =
-			rpc_caller_invoke(context->caller, call_handle,
-				TS_CRYPTO_OPCODE_KEY_DERIVATION_GET_CAPACITY, &opstatus, &resp_buf, &resp_len);
+			rpc_caller_session_invoke(call_handle,
+						  TS_CRYPTO_OPCODE_KEY_DERIVATION_GET_CAPACITY,
+						  &resp_buf, &resp_len, &service_status);
 
-		if (context->rpc_status == TS_RPC_CALL_ACCEPTED) {
+		if (context->rpc_status == RPC_SUCCESS) {
 
-			psa_status = opstatus;
+			psa_status = service_status;
 
 			if (psa_status == PSA_SUCCESS) {
 
@@ -119,7 +121,7 @@
 			}
 		}
 
-		rpc_caller_end(context->caller, call_handle);
+		rpc_caller_session_end(call_handle);
 	}
 
 	return psa_status;
@@ -139,23 +141,25 @@
 	rpc_call_handle call_handle;
 	uint8_t *req_buf;
 
-	call_handle = rpc_caller_begin(context->caller, &req_buf, req_len);
+	call_handle = rpc_caller_session_begin(context->session, &req_buf, req_len, 0);
 
 	if (call_handle) {
 
 		uint8_t *resp_buf;
 		size_t resp_len;
-		rpc_opstatus_t opstatus;
+		service_status_t service_status;
 
 		memcpy(req_buf, &req_msg, req_len);
 
 		context->rpc_status =
-			rpc_caller_invoke(context->caller, call_handle,
-				TS_CRYPTO_OPCODE_KEY_DERIVATION_SET_CAPACITY, &opstatus, &resp_buf, &resp_len);
+			rpc_caller_session_invoke(call_handle,
+						  TS_CRYPTO_OPCODE_KEY_DERIVATION_SET_CAPACITY,
+						  &resp_buf, &resp_len, &service_status);
 
-		if (context->rpc_status == TS_RPC_CALL_ACCEPTED) psa_status = opstatus;
+		if (context->rpc_status == RPC_SUCCESS)
+			psa_status = service_status;
 
-		rpc_caller_end(context->caller, call_handle);
+		rpc_caller_session_end(call_handle);
 	}
 
 	return psa_status;
@@ -185,13 +189,13 @@
 	rpc_call_handle call_handle;
 	uint8_t *req_buf;
 
-	call_handle = rpc_caller_begin(context->caller, &req_buf, req_len);
+	call_handle = rpc_caller_session_begin(context->session, &req_buf, req_len, 0);
 
 	if (call_handle) {
 
 		uint8_t *resp_buf;
 		size_t resp_len;
-		rpc_opstatus_t opstatus;
+		service_status_t service_status;
 		struct tlv_iterator req_iter;
 
 		memcpy(req_buf, &req_msg, req_fixed_len);
@@ -200,12 +204,14 @@
 		tlv_encode(&req_iter, &data_record);
 
 		context->rpc_status =
-			rpc_caller_invoke(context->caller, call_handle,
-				TS_CRYPTO_OPCODE_KEY_DERIVATION_INPUT_BYTES, &opstatus, &resp_buf, &resp_len);
+			rpc_caller_session_invoke(call_handle,
+						  TS_CRYPTO_OPCODE_KEY_DERIVATION_INPUT_BYTES,
+						  &resp_buf, &resp_len, &service_status);
 
-		if (context->rpc_status == TS_RPC_CALL_ACCEPTED) psa_status = opstatus;
+		if (context->rpc_status == RPC_SUCCESS)
+			psa_status = service_status;
 
-		rpc_caller_end(context->caller, call_handle);
+		rpc_caller_session_end(call_handle);
 	}
 
 	return psa_status;
@@ -227,23 +233,25 @@
 	rpc_call_handle call_handle;
 	uint8_t *req_buf;
 
-	call_handle = rpc_caller_begin(context->caller, &req_buf, req_len);
+	call_handle = rpc_caller_session_begin(context->session, &req_buf, req_len, 0);
 
 	if (call_handle) {
 
 		uint8_t *resp_buf;
 		size_t resp_len;
-		rpc_opstatus_t opstatus;
+		service_status_t service_status;
 
 		memcpy(req_buf, &req_msg, req_len);
 
 		context->rpc_status =
-			rpc_caller_invoke(context->caller, call_handle,
-				TS_CRYPTO_OPCODE_KEY_DERIVATION_INPUT_KEY, &opstatus, &resp_buf, &resp_len);
+			rpc_caller_session_invoke(call_handle,
+						  TS_CRYPTO_OPCODE_KEY_DERIVATION_INPUT_KEY,
+						  &resp_buf, &resp_len, &service_status);
 
-		if (context->rpc_status == TS_RPC_CALL_ACCEPTED) psa_status = opstatus;
+		if (context->rpc_status == RPC_SUCCESS)
+			psa_status = service_status;
 
-		rpc_caller_end(context->caller, call_handle);
+		rpc_caller_session_end(call_handle);
 	}
 
 	return psa_status;
@@ -265,23 +273,25 @@
 	rpc_call_handle call_handle;
 	uint8_t *req_buf;
 
-	call_handle = rpc_caller_begin(context->caller, &req_buf, req_len);
+	call_handle = rpc_caller_session_begin(context->session, &req_buf, req_len,
+					       tlv_required_space(output_length));
 
 	if (call_handle) {
 
 		uint8_t *resp_buf;
 		size_t resp_len;
-		rpc_opstatus_t opstatus;
+		service_status_t service_status;
 
 		memcpy(req_buf, &req_msg, req_fixed_len);
 
 		context->rpc_status =
-			rpc_caller_invoke(context->caller, call_handle,
-				TS_CRYPTO_OPCODE_KEY_DERIVATION_OUTPUT_BYTES, &opstatus, &resp_buf, &resp_len);
+			rpc_caller_session_invoke(call_handle,
+						  TS_CRYPTO_OPCODE_KEY_DERIVATION_OUTPUT_BYTES,
+						  &resp_buf, &resp_len, &service_status);
 
-		if (context->rpc_status == TS_RPC_CALL_ACCEPTED) {
+		if (context->rpc_status == RPC_SUCCESS) {
 
-			psa_status = opstatus;
+			psa_status = service_status;
 
 			if (psa_status == PSA_SUCCESS) {
 
@@ -308,7 +318,7 @@
 			}
 		}
 
-		rpc_caller_end(context->caller, call_handle);
+		rpc_caller_session_end(call_handle);
 	}
 
 	return psa_status;
@@ -322,6 +332,7 @@
 	psa_status_t psa_status = PSA_ERROR_GENERIC_ERROR;
 	struct ts_crypto_key_derivation_output_key_in req_msg;
 	size_t req_len = sizeof(struct ts_crypto_key_derivation_output_key_in);
+	size_t resp_len = sizeof(struct ts_crypto_key_derivation_output_key_out);
 
 	/* Set default outputs for failure case */
 	*key = 0;
@@ -332,23 +343,24 @@
 	rpc_call_handle call_handle;
 	uint8_t *req_buf;
 
-	call_handle = rpc_caller_begin(context->caller, &req_buf, req_len);
+	call_handle = rpc_caller_session_begin(context->session, &req_buf, req_len, resp_len);
 
 	if (call_handle) {
 
 		uint8_t *resp_buf;
 		size_t resp_len;
-		rpc_opstatus_t opstatus;
+		service_status_t service_status;
 
 		memcpy(req_buf, &req_msg, req_len);
 
 		context->rpc_status =
-			rpc_caller_invoke(context->caller, call_handle,
-				TS_CRYPTO_OPCODE_KEY_DERIVATION_OUTPUT_KEY, &opstatus, &resp_buf, &resp_len);
+			rpc_caller_session_invoke(call_handle,
+						  TS_CRYPTO_OPCODE_KEY_DERIVATION_OUTPUT_KEY,
+						  &resp_buf, &resp_len,  &service_status);
 
-		if (context->rpc_status == TS_RPC_CALL_ACCEPTED) {
+		if (context->rpc_status == RPC_SUCCESS) {
 
-			psa_status = opstatus;
+			psa_status = service_status;
 
 			if (psa_status == PSA_SUCCESS) {
 
@@ -366,7 +378,7 @@
 			}
 		}
 
-		rpc_caller_end(context->caller, call_handle);
+		rpc_caller_session_end(call_handle);
 	}
 
 	return psa_status;
@@ -385,23 +397,25 @@
 	rpc_call_handle call_handle;
 	uint8_t *req_buf;
 
-	call_handle = rpc_caller_begin(context->caller, &req_buf, req_len);
+	call_handle = rpc_caller_session_begin(context->session, &req_buf, req_len, 0);
 
 	if (call_handle) {
 
 		uint8_t *resp_buf;
 		size_t resp_len;
-		rpc_opstatus_t opstatus;
+		service_status_t service_status;
 
 		memcpy(req_buf, &req_msg, req_fixed_len);
 
 		context->rpc_status =
-			rpc_caller_invoke(context->caller, call_handle,
-				TS_CRYPTO_OPCODE_KEY_DERIVATION_ABORT, &opstatus, &resp_buf, &resp_len);
+			rpc_caller_session_invoke(call_handle,
+						  TS_CRYPTO_OPCODE_KEY_DERIVATION_ABORT,
+						  &resp_buf, &resp_len, &service_status);
 
-		if (context->rpc_status == TS_RPC_CALL_ACCEPTED) psa_status = opstatus;
+		if (context->rpc_status == RPC_SUCCESS)
+			psa_status = service_status;
 
-		rpc_caller_end(context->caller, call_handle);
+		rpc_caller_session_end(call_handle);
 	}
 
 	return psa_status;
@@ -433,13 +447,13 @@
 	rpc_call_handle call_handle;
 	uint8_t *req_buf;
 
-	call_handle = rpc_caller_begin(context->caller, &req_buf, req_len);
+	call_handle = rpc_caller_session_begin(context->session, &req_buf, req_len, 0);
 
 	if (call_handle) {
 
 		uint8_t *resp_buf;
 		size_t resp_len;
-		rpc_opstatus_t opstatus;
+		service_status_t service_status;
 		struct tlv_iterator req_iter;
 
 		memcpy(req_buf, &req_msg, req_fixed_len);
@@ -448,12 +462,14 @@
 		tlv_encode(&req_iter, &data_record);
 
 		context->rpc_status =
-			rpc_caller_invoke(context->caller, call_handle,
-				TS_CRYPTO_OPCODE_KEY_DERIVATION_KEY_AGREEMENT, &opstatus, &resp_buf, &resp_len);
+			rpc_caller_session_invoke(call_handle,
+						  TS_CRYPTO_OPCODE_KEY_DERIVATION_KEY_AGREEMENT,
+						  &resp_buf, &resp_len, &service_status);
 
-		if (context->rpc_status == TS_RPC_CALL_ACCEPTED) psa_status = opstatus;
+		if (context->rpc_status == RPC_SUCCESS)
+			psa_status = service_status;
 
-		rpc_caller_end(context->caller, call_handle);
+		rpc_caller_session_end(call_handle);
 	}
 
 	return psa_status;
@@ -486,13 +502,13 @@
 	rpc_call_handle call_handle;
 	uint8_t *req_buf;
 
-	call_handle = rpc_caller_begin(context->caller, &req_buf, req_len);
+	call_handle = rpc_caller_session_begin(context->session, &req_buf, req_len, 0);
 
 	if (call_handle) {
 
 		uint8_t *resp_buf;
 		size_t resp_len;
-		rpc_opstatus_t opstatus;
+		service_status_t service_status;
 		struct tlv_iterator req_iter;
 
 		memcpy(req_buf, &req_msg, req_fixed_len);
@@ -501,12 +517,13 @@
 		tlv_encode(&req_iter, &data_record);
 
 		context->rpc_status =
-			rpc_caller_invoke(context->caller, call_handle,
-				TS_CRYPTO_OPCODE_KEY_DERIVATION_RAW_KEY_AGREEMENT, &opstatus, &resp_buf, &resp_len);
+			rpc_caller_session_invoke(call_handle,
+						  TS_CRYPTO_OPCODE_KEY_DERIVATION_RAW_KEY_AGREEMENT,
+						  &resp_buf, &resp_len, &service_status);
 
-		if (context->rpc_status == TS_RPC_CALL_ACCEPTED) {
+		if (context->rpc_status == RPC_SUCCESS) {
 
-			psa_status = opstatus;
+			psa_status = service_status;
 
 			if (psa_status == PSA_SUCCESS) {
 
@@ -534,7 +551,7 @@
 			}
 		}
 
-		rpc_caller_end(context->caller, call_handle);
+		rpc_caller_session_end(call_handle);
 	}
 
 	return psa_status;
diff --git a/components/service/crypto/client/caller/packed-c/crypto_caller_mac.h b/components/service/crypto/client/caller/packed-c/crypto_caller_mac.h
index 739f312..c476da0 100644
--- a/components/service/crypto/client/caller/packed-c/crypto_caller_mac.h
+++ b/components/service/crypto/client/caller/packed-c/crypto_caller_mac.h
@@ -36,23 +36,23 @@
 	rpc_call_handle call_handle;
 	uint8_t *req_buf;
 
-	call_handle = rpc_caller_begin(context->caller, &req_buf, req_len);
+	call_handle = rpc_caller_session_begin(context->session, &req_buf, req_len, 0);
 
 	if (call_handle) {
 
 		uint8_t *resp_buf;
 		size_t resp_len;
-		rpc_opstatus_t opstatus;
+		service_status_t service_status;
 
 		memcpy(req_buf, &req_msg, req_len);
 
 		context->rpc_status =
-			rpc_caller_invoke(context->caller, call_handle,
-				opcode, &opstatus, &resp_buf, &resp_len);
+			rpc_caller_session_invoke(call_handle, opcode, &resp_buf, &resp_len,
+						  &service_status);
 
-		if (context->rpc_status == TS_RPC_CALL_ACCEPTED) {
+		if (context->rpc_status == RPC_SUCCESS) {
 
-			psa_status = opstatus;
+			psa_status = service_status;
 
 			if (psa_status == PSA_SUCCESS) {
 
@@ -69,7 +69,7 @@
 			}
 		}
 
-		rpc_caller_end(context->caller, call_handle);
+		rpc_caller_session_end(call_handle);
 	}
 
 	return psa_status;
@@ -113,13 +113,13 @@
 	rpc_call_handle call_handle;
 	uint8_t *req_buf;
 
-	call_handle = rpc_caller_begin(context->caller, &req_buf, req_len);
+	call_handle = rpc_caller_session_begin(context->session, &req_buf, req_len, 0);
 
 	if (call_handle) {
 
 		uint8_t *resp_buf;
 		size_t resp_len;
-		rpc_opstatus_t opstatus;
+		service_status_t service_status;
 		struct tlv_iterator req_iter;
 
 		memcpy(req_buf, &req_msg, req_fixed_len);
@@ -128,12 +128,13 @@
 		tlv_encode(&req_iter, &data_record);
 
 		context->rpc_status =
-			rpc_caller_invoke(context->caller, call_handle,
-				TS_CRYPTO_OPCODE_MAC_UPDATE, &opstatus, &resp_buf, &resp_len);
+			rpc_caller_session_invoke(call_handle,  TS_CRYPTO_OPCODE_MAC_UPDATE,
+						  &resp_buf, &resp_len, &service_status);
 
-		if (context->rpc_status == TS_RPC_CALL_ACCEPTED) psa_status = opstatus;
+		if (context->rpc_status == RPC_SUCCESS)
+			psa_status = service_status;
 
-		rpc_caller_end(context->caller, call_handle);
+		rpc_caller_session_end(call_handle);
 	}
 
 	return psa_status;
@@ -156,23 +157,24 @@
 	rpc_call_handle call_handle;
 	uint8_t *req_buf;
 
-	call_handle = rpc_caller_begin(context->caller, &req_buf, req_len);
+	call_handle = rpc_caller_session_begin(context->session, &req_buf, req_len,
+					       tlv_required_space(mac_size));
 
 	if (call_handle) {
 
 		uint8_t *resp_buf;
 		size_t resp_len;
-		rpc_opstatus_t opstatus;
+		service_status_t service_status;
 
 		memcpy(req_buf, &req_msg, req_fixed_len);
 
 		context->rpc_status =
-			rpc_caller_invoke(context->caller, call_handle,
-				TS_CRYPTO_OPCODE_MAC_SIGN_FINISH, &opstatus, &resp_buf, &resp_len);
+			rpc_caller_session_invoke(call_handle, TS_CRYPTO_OPCODE_MAC_SIGN_FINISH,
+						  &resp_buf, &resp_len, &service_status);
 
-		if (context->rpc_status == TS_RPC_CALL_ACCEPTED) {
+		if (context->rpc_status == RPC_SUCCESS) {
 
-			psa_status = opstatus;
+			psa_status = service_status;
 
 			if (psa_status == PSA_SUCCESS) {
 
@@ -200,7 +202,7 @@
 			}
 		}
 
-		rpc_caller_end(context->caller, call_handle);
+		rpc_caller_session_end(call_handle);
 	}
 
 	return psa_status;
@@ -228,13 +230,13 @@
 	rpc_call_handle call_handle;
 	uint8_t *req_buf;
 
-	call_handle = rpc_caller_begin(context->caller, &req_buf, req_len);
+	call_handle = rpc_caller_session_begin(context->session, &req_buf, req_len, 0);
 
 	if (call_handle) {
 
 		uint8_t *resp_buf;
 		size_t resp_len;
-		rpc_opstatus_t opstatus;
+		service_status_t service_status;
 		struct tlv_iterator req_iter;
 
 		memcpy(req_buf, &req_msg, req_fixed_len);
@@ -243,12 +245,13 @@
 		tlv_encode(&req_iter, &data_record);
 
 		context->rpc_status =
-			rpc_caller_invoke(context->caller, call_handle,
-				TS_CRYPTO_OPCODE_MAC_VERIFY_FINISH, &opstatus, &resp_buf, &resp_len);
+			rpc_caller_session_invoke(call_handle, TS_CRYPTO_OPCODE_MAC_VERIFY_FINISH,
+						  &resp_buf, &resp_len, &service_status);
 
-		if (context->rpc_status == TS_RPC_CALL_ACCEPTED) psa_status = opstatus;
+		if (context->rpc_status == RPC_SUCCESS)
+			psa_status = service_status;
 
-		rpc_caller_end(context->caller, call_handle);
+		rpc_caller_session_end(call_handle);
 	}
 
 	return psa_status;
@@ -267,23 +270,24 @@
 	rpc_call_handle call_handle;
 	uint8_t *req_buf;
 
-	call_handle = rpc_caller_begin(context->caller, &req_buf, req_len);
+	call_handle = rpc_caller_session_begin(context->session, &req_buf, req_len, 0);
 
 	if (call_handle) {
 
 		uint8_t *resp_buf;
 		size_t resp_len;
-		rpc_opstatus_t opstatus;
+		service_status_t service_status;
 
 		memcpy(req_buf, &req_msg, req_fixed_len);
 
 		context->rpc_status =
-			rpc_caller_invoke(context->caller, call_handle,
-				TS_CRYPTO_OPCODE_MAC_ABORT, &opstatus, &resp_buf, &resp_len);
+			rpc_caller_session_invoke(call_handle, TS_CRYPTO_OPCODE_MAC_ABORT,
+						  &resp_buf, &resp_len, &service_status);
 
-		if (context->rpc_status == TS_RPC_CALL_ACCEPTED) psa_status = opstatus;
+		if (context->rpc_status == RPC_SUCCESS)
+			psa_status = service_status;
 
-		rpc_caller_end(context->caller, call_handle);
+		rpc_caller_session_end(call_handle);
 	}
 
 	return psa_status;
diff --git a/components/service/crypto/client/caller/packed-c/crypto_caller_purge_key.h b/components/service/crypto/client/caller/packed-c/crypto_caller_purge_key.h
index 84af48f..be30434 100644
--- a/components/service/crypto/client/caller/packed-c/crypto_caller_purge_key.h
+++ b/components/service/crypto/client/caller/packed-c/crypto_caller_purge_key.h
@@ -30,23 +30,24 @@
 	rpc_call_handle call_handle;
 	uint8_t *req_buf;
 
-	call_handle = rpc_caller_begin(context->caller, &req_buf, req_len);
+	call_handle = rpc_caller_session_begin(context->session, &req_buf, req_len, 0);
 
 	if (call_handle) {
 
 		uint8_t *resp_buf;
 		size_t resp_len;
-		rpc_opstatus_t opstatus;
+		service_status_t service_status;
 
 		memcpy(req_buf, &req_msg, req_len);
 
 		context->rpc_status =
-			rpc_caller_invoke(context->caller, call_handle,
-						TS_CRYPTO_OPCODE_PURGE_KEY, &opstatus, &resp_buf, &resp_len);
+			rpc_caller_session_invoke(call_handle, TS_CRYPTO_OPCODE_PURGE_KEY,
+						  &resp_buf, &resp_len, &service_status);
 
-		if (context->rpc_status == TS_RPC_CALL_ACCEPTED) psa_status = opstatus;
+		if (context->rpc_status == RPC_SUCCESS)
+			psa_status = service_status;
 
-		rpc_caller_end(context->caller, call_handle);
+		rpc_caller_session_end(call_handle);
 	}
 
 	return psa_status;
diff --git a/components/service/crypto/client/caller/packed-c/crypto_caller_sign_hash.h b/components/service/crypto/client/caller/packed-c/crypto_caller_sign_hash.h
index 4a9ed20..1de03b2 100644
--- a/components/service/crypto/client/caller/packed-c/crypto_caller_sign_hash.h
+++ b/components/service/crypto/client/caller/packed-c/crypto_caller_sign_hash.h
@@ -45,13 +45,14 @@
 	rpc_call_handle call_handle;
 	uint8_t *req_buf;
 
-	call_handle = rpc_caller_begin(context->caller, &req_buf, req_len);
+	call_handle = rpc_caller_session_begin(context->session, &req_buf, req_len,
+					       tlv_required_space(signature_size));
 
 	if (call_handle) {
 
 		uint8_t *resp_buf;
 		size_t resp_len;
-		rpc_opstatus_t opstatus;
+		service_status_t service_status;
 		struct tlv_iterator req_iter;
 
 		memcpy(req_buf, &req_msg, req_fixed_len);
@@ -60,12 +61,12 @@
 		tlv_encode(&req_iter, &hash_record);
 
 		context->rpc_status =
-			rpc_caller_invoke(context->caller, call_handle,
-						opcode, &opstatus, &resp_buf, &resp_len);
+			rpc_caller_session_invoke(call_handle, opcode, &resp_buf, &resp_len,
+						  &service_status);
 
-		if (context->rpc_status == TS_RPC_CALL_ACCEPTED) {
+		if (context->rpc_status == RPC_SUCCESS) {
 
-			psa_status = opstatus;
+			psa_status = service_status;
 
 			if (psa_status == PSA_SUCCESS) {
 
@@ -93,7 +94,7 @@
 			}
 		}
 
-		rpc_caller_end(context->caller, call_handle);
+		rpc_caller_session_end(call_handle);
 	}
 
 	return psa_status;
diff --git a/components/service/crypto/client/caller/packed-c/crypto_caller_verify_hash.h b/components/service/crypto/client/caller/packed-c/crypto_caller_verify_hash.h
index daa1133..1f3d46e 100644
--- a/components/service/crypto/client/caller/packed-c/crypto_caller_verify_hash.h
+++ b/components/service/crypto/client/caller/packed-c/crypto_caller_verify_hash.h
@@ -49,13 +49,13 @@
 	rpc_call_handle call_handle;
 	uint8_t *req_buf;
 
-	call_handle = rpc_caller_begin(context->caller, &req_buf, req_len);
+	call_handle = rpc_caller_session_begin(context->session, &req_buf, req_len, 0);
 
 	if (call_handle) {
 
 		uint8_t *resp_buf;
 		size_t resp_len;
-		rpc_opstatus_t opstatus;
+		service_status_t service_status;
 		struct tlv_iterator req_iter;
 
 		memcpy(req_buf, &req_msg, req_fixed_len);
@@ -65,12 +65,13 @@
 		tlv_encode(&req_iter, &sig_record);
 
 		context->rpc_status =
-			rpc_caller_invoke(context->caller, call_handle,
-					opcode, &opstatus, &resp_buf, &resp_len);
+			rpc_caller_session_invoke(call_handle, opcode, &resp_buf, &resp_len,
+						  &service_status);
 
-		if (context->rpc_status == TS_RPC_CALL_ACCEPTED) psa_status = opstatus;
+		if (context->rpc_status == RPC_SUCCESS)
+			psa_status = service_status;
 
-		rpc_caller_end(context->caller, call_handle);
+		rpc_caller_session_end(call_handle);
 	}
 
 	return psa_status;
diff --git a/components/service/crypto/client/caller/psa_ipc/crypto_caller_aead.h b/components/service/crypto/client/caller/psa_ipc/crypto_caller_aead.h
index 393ba44..64e9c61 100644
--- a/components/service/crypto/client/caller/psa_ipc/crypto_caller_aead.h
+++ b/components/service/crypto/client/caller/psa_ipc/crypto_caller_aead.h
@@ -39,7 +39,7 @@
 					      size_t *aeadtext_length)
 {
 	struct service_client *ipc = context;
-	struct rpc_caller *caller = ipc->caller;
+	struct rpc_caller_interface *caller = ipc->session->caller;
 	psa_status_t status;
 	size_t in_len;
 	int i;
@@ -100,7 +100,7 @@
 					      size_t *plaintext_length)
 {
 	struct service_client *ipc = context;
-	struct rpc_caller *caller = ipc->caller;
+	struct rpc_caller_interface *caller = ipc->session->caller;
 	psa_status_t status;
 	size_t in_len;
 	int i;
@@ -153,7 +153,7 @@
 					    psa_algorithm_t alg)
 {
 	struct service_client *ipc = context;
-	struct rpc_caller *caller = ipc->caller;
+	struct rpc_caller_interface *caller = ipc->session->caller;
 	psa_status_t status;
 	struct psa_ipc_crypto_pack_iovec iov = {
 		.function_id = TFM_CRYPTO_AEAD_ENCRYPT_SETUP_SID,
@@ -183,7 +183,7 @@
 					    psa_algorithm_t alg)
 {
 	struct service_client *ipc = context;
-	struct rpc_caller *caller = ipc->caller;
+	struct rpc_caller_interface *caller = ipc->session->caller;
 	psa_status_t status;
 	struct psa_ipc_crypto_pack_iovec iov = {
 		.function_id = TFM_CRYPTO_AEAD_DECRYPT_SETUP_SID,
@@ -214,7 +214,7 @@
 					     size_t *nonce_length)
 {
 	struct service_client *ipc = context;
-	struct rpc_caller *caller = ipc->caller;
+	struct rpc_caller_interface *caller = ipc->session->caller;
 	psa_status_t status;
 	struct psa_ipc_crypto_pack_iovec iov = {
 		.function_id = TFM_CRYPTO_AEAD_GENERATE_NONCE_SID,
@@ -244,7 +244,7 @@
 						size_t nonce_length)
 {
 	struct service_client *ipc = context;
-	struct rpc_caller *caller = ipc->caller;
+	struct rpc_caller_interface *caller = ipc->session->caller;
 	psa_status_t status;
 	struct psa_ipc_crypto_pack_iovec iov = {
 		.function_id = TFM_CRYPTO_AEAD_SET_NONCE_SID,
@@ -273,7 +273,7 @@
 					  size_t plaintext_length)
 {
 	struct service_client *ipc = context;
-	struct rpc_caller *caller = ipc->caller;
+	struct rpc_caller_interface *caller = ipc->session->caller;
 	psa_status_t status;
 	struct psa_ipc_crypto_pack_iovec iov = {
 		.function_id = TFM_CRYPTO_AEAD_SET_LENGTHS_SID,
@@ -303,7 +303,7 @@
 						size_t input_length)
 {
 	struct service_client *ipc = context;
-	struct rpc_caller *caller = ipc->caller;
+	struct rpc_caller_interface *caller = ipc->session->caller;
 	psa_status_t status;
 	struct psa_ipc_crypto_pack_iovec iov = {
 		.function_id = TFM_CRYPTO_AEAD_UPDATE_AD_SID,
@@ -345,7 +345,7 @@
 					     size_t *output_length)
 {
 	struct service_client *ipc = context;
-	struct rpc_caller *caller = ipc->caller;
+	struct rpc_caller_interface *caller = ipc->session->caller;
 	psa_status_t status;
 	struct psa_ipc_crypto_pack_iovec iov = {
 		.function_id = TFM_CRYPTO_AEAD_UPDATE_SID,
@@ -390,7 +390,7 @@
 					     size_t *tag_length)
 {
 	struct service_client *ipc = context;
-	struct rpc_caller *caller = ipc->caller;
+	struct rpc_caller_interface *caller = ipc->session->caller;
 	psa_status_t status;
 	struct psa_ipc_crypto_pack_iovec iov = {
 		.function_id = TFM_CRYPTO_AEAD_FINISH_SID,
@@ -443,7 +443,7 @@
 					     size_t tag_length)
 {
 	struct service_client *ipc = context;
-	struct rpc_caller *caller = ipc->caller;
+	struct rpc_caller_interface *caller = ipc->session->caller;
 	psa_status_t status;
 	struct psa_ipc_crypto_pack_iovec iov = {
 		.function_id = TFM_CRYPTO_AEAD_VERIFY_SID,
@@ -489,7 +489,7 @@
 					    uint32_t op_handle)
 {
 	struct service_client *ipc = context;
-	struct rpc_caller *caller = ipc->caller;
+	struct rpc_caller_interface *caller = ipc->session->caller;
 	psa_status_t status;
 	struct psa_ipc_crypto_pack_iovec iov = {
 		.function_id = TFM_CRYPTO_AEAD_ABORT_SID,
diff --git a/components/service/crypto/client/caller/psa_ipc/crypto_caller_asymmetric_decrypt.h b/components/service/crypto/client/caller/psa_ipc/crypto_caller_asymmetric_decrypt.h
index 03682e7..368ba39 100644
--- a/components/service/crypto/client/caller/psa_ipc/crypto_caller_asymmetric_decrypt.h
+++ b/components/service/crypto/client/caller/psa_ipc/crypto_caller_asymmetric_decrypt.h
@@ -34,7 +34,7 @@
 				    size_t *output_length)
 {
 	struct service_client *ipc = context;
-	struct rpc_caller *caller = ipc->caller;
+	struct rpc_caller_interface *caller = ipc->session->caller;
 	psa_status_t status;
 	size_t in_len;
 	struct psa_ipc_crypto_pack_iovec iov = {
diff --git a/components/service/crypto/client/caller/psa_ipc/crypto_caller_asymmetric_encrypt.h b/components/service/crypto/client/caller/psa_ipc/crypto_caller_asymmetric_encrypt.h
index 60f5770..9cedbe8 100644
--- a/components/service/crypto/client/caller/psa_ipc/crypto_caller_asymmetric_encrypt.h
+++ b/components/service/crypto/client/caller/psa_ipc/crypto_caller_asymmetric_encrypt.h
@@ -34,7 +34,7 @@
 				    size_t *output_length)
 {
 	struct service_client *ipc = context;
-	struct rpc_caller *caller = ipc->caller;
+	struct rpc_caller_interface *caller = ipc->session->caller;
 	psa_status_t status;
 	size_t in_len;
 	struct psa_ipc_crypto_pack_iovec iov = {
diff --git a/components/service/crypto/client/caller/psa_ipc/crypto_caller_cipher.h b/components/service/crypto/client/caller/psa_ipc/crypto_caller_cipher.h
index 0d32444..8da954d 100644
--- a/components/service/crypto/client/caller/psa_ipc/crypto_caller_cipher.h
+++ b/components/service/crypto/client/caller/psa_ipc/crypto_caller_cipher.h
@@ -31,7 +31,7 @@
 					      psa_algorithm_t alg)
 {
 	struct service_client *ipc = context;
-	struct rpc_caller *caller = ipc->caller;
+	struct rpc_caller_interface *caller = ipc->session->caller;
 	psa_status_t status;
 	struct psa_ipc_crypto_pack_iovec iov = {
 		.function_id = TFM_CRYPTO_CIPHER_ENCRYPT_SETUP_SID,
@@ -59,7 +59,7 @@
 					      psa_algorithm_t alg)
 {
 	struct service_client *ipc = context;
-	struct rpc_caller *caller = ipc->caller;
+	struct rpc_caller_interface *caller = ipc->session->caller;
 	psa_status_t status;
 	struct psa_ipc_crypto_pack_iovec iov = {
 		.function_id = TFM_CRYPTO_CIPHER_DECRYPT_SETUP_SID,
@@ -88,7 +88,7 @@
 					    size_t *iv_length)
 {
 	struct service_client *ipc = context;
-	struct rpc_caller *caller = ipc->caller;
+	struct rpc_caller_interface *caller = ipc->session->caller;
 	psa_status_t status;
 	struct psa_ipc_crypto_pack_iovec iov = {
 		.function_id = TFM_CRYPTO_CIPHER_GENERATE_IV_SID,
@@ -116,7 +116,7 @@
 					       size_t iv_length)
 {
 	struct service_client *ipc = context;
-	struct rpc_caller *caller = ipc->caller;
+	struct rpc_caller_interface *caller = ipc->session->caller;
 	psa_status_t status;
 	struct psa_ipc_crypto_pack_iovec iov = {
 		.function_id = TFM_CRYPTO_CIPHER_SET_IV_SID,
@@ -146,7 +146,7 @@
 					       size_t *output_length)
 {
 	struct service_client *ipc = context;
-	struct rpc_caller *caller = ipc->caller;
+	struct rpc_caller_interface *caller = ipc->session->caller;
 	psa_status_t status;
 	struct psa_ipc_crypto_pack_iovec iov = {
 		.function_id = TFM_CRYPTO_CIPHER_UPDATE_SID,
@@ -176,7 +176,7 @@
 					       size_t *output_length)
 {
 	struct service_client *ipc = context;
-	struct rpc_caller *caller = ipc->caller;
+	struct rpc_caller_interface *caller = ipc->session->caller;
 	psa_status_t status;
 	struct psa_ipc_crypto_pack_iovec iov = {
 		.function_id = TFM_CRYPTO_CIPHER_FINISH_SID,
@@ -203,7 +203,7 @@
 					      uint32_t op_handle)
 {
 	struct service_client *ipc = context;
-	struct rpc_caller *caller = ipc->caller;
+	struct rpc_caller_interface *caller = ipc->session->caller;
 	psa_status_t status;
 	struct psa_ipc_crypto_pack_iovec iov = {
 		.function_id = TFM_CRYPTO_CIPHER_ABORT_SID,
diff --git a/components/service/crypto/client/caller/psa_ipc/crypto_caller_copy_key.h b/components/service/crypto/client/caller/psa_ipc/crypto_caller_copy_key.h
index 71cf438..f737b8e 100644
--- a/components/service/crypto/client/caller/psa_ipc/crypto_caller_copy_key.h
+++ b/components/service/crypto/client/caller/psa_ipc/crypto_caller_copy_key.h
@@ -30,7 +30,7 @@
 						  psa_key_id_t *target_key)
 {
 	struct service_client *ipc = context;
-	struct rpc_caller *caller = ipc->caller;
+	struct rpc_caller_interface *caller = ipc->session->caller;
 	psa_status_t status;
 	struct psa_ipc_crypto_pack_iovec iov = {
 		.function_id = TFM_CRYPTO_COPY_KEY_SID,
diff --git a/components/service/crypto/client/caller/psa_ipc/crypto_caller_destroy_key.h b/components/service/crypto/client/caller/psa_ipc/crypto_caller_destroy_key.h
index 85bd2b4..5baeb2f 100644
--- a/components/service/crypto/client/caller/psa_ipc/crypto_caller_destroy_key.h
+++ b/components/service/crypto/client/caller/psa_ipc/crypto_caller_destroy_key.h
@@ -28,7 +28,7 @@
 						     psa_key_id_t id)
 {
 	struct service_client *ipc = context;
-	struct rpc_caller *caller = ipc->caller;
+	struct rpc_caller_interface *caller = ipc->session->caller;
 	psa_status_t status;
 	struct psa_ipc_crypto_pack_iovec iov = {
 		.function_id = TFM_CRYPTO_DESTROY_KEY_SID,
diff --git a/components/service/crypto/client/caller/psa_ipc/crypto_caller_export_key.h b/components/service/crypto/client/caller/psa_ipc/crypto_caller_export_key.h
index 5e95430..d9a9fca 100644
--- a/components/service/crypto/client/caller/psa_ipc/crypto_caller_export_key.h
+++ b/components/service/crypto/client/caller/psa_ipc/crypto_caller_export_key.h
@@ -31,7 +31,7 @@
 						    size_t *data_length)
 {
 	struct service_client *ipc = context;
-	struct rpc_caller *caller = ipc->caller;
+	struct rpc_caller_interface *caller = ipc->session->caller;
 	psa_status_t status;
 	struct psa_ipc_crypto_pack_iovec iov = {
 		.function_id = TFM_CRYPTO_EXPORT_KEY_SID,
diff --git a/components/service/crypto/client/caller/psa_ipc/crypto_caller_export_public_key.h b/components/service/crypto/client/caller/psa_ipc/crypto_caller_export_public_key.h
index 349dc6c..5f62d9c 100644
--- a/components/service/crypto/client/caller/psa_ipc/crypto_caller_export_public_key.h
+++ b/components/service/crypto/client/caller/psa_ipc/crypto_caller_export_public_key.h
@@ -31,7 +31,7 @@
 							   size_t *data_length)
 {
 	struct service_client *ipc = context;
-	struct rpc_caller *caller = ipc->caller;
+	struct rpc_caller_interface *caller = ipc->session->caller;
 	psa_status_t status;
 	struct psa_ipc_crypto_pack_iovec iov = {
 		.function_id = TFM_CRYPTO_EXPORT_PUBLIC_KEY_SID,
diff --git a/components/service/crypto/client/caller/psa_ipc/crypto_caller_generate_key.h b/components/service/crypto/client/caller/psa_ipc/crypto_caller_generate_key.h
index 31c6901..adb1957 100644
--- a/components/service/crypto/client/caller/psa_ipc/crypto_caller_generate_key.h
+++ b/components/service/crypto/client/caller/psa_ipc/crypto_caller_generate_key.h
@@ -29,7 +29,7 @@
 						      psa_key_id_t *id)
 {
 	struct service_client *ipc = context;
-	struct rpc_caller *caller = ipc->caller;
+	struct rpc_caller_interface *caller = ipc->session->caller;
 	psa_status_t status;
 	struct psa_ipc_crypto_pack_iovec iov = {
 		.function_id = TFM_CRYPTO_GENERATE_KEY_SID,
diff --git a/components/service/crypto/client/caller/psa_ipc/crypto_caller_generate_random.h b/components/service/crypto/client/caller/psa_ipc/crypto_caller_generate_random.h
index ce51ded..f5dd217 100644
--- a/components/service/crypto/client/caller/psa_ipc/crypto_caller_generate_random.h
+++ b/components/service/crypto/client/caller/psa_ipc/crypto_caller_generate_random.h
@@ -29,7 +29,7 @@
 							 size_t output_size)
 {
 	struct service_client *ipc = context;
-	struct rpc_caller *caller = ipc->caller;
+	struct rpc_caller_interface *caller = ipc->session->caller;
 	psa_status_t status;
 	struct psa_ipc_crypto_pack_iovec iov = {
 		.function_id = TFM_CRYPTO_GENERATE_RANDOM_SID,
diff --git a/components/service/crypto/client/caller/psa_ipc/crypto_caller_get_key_attributes.h b/components/service/crypto/client/caller/psa_ipc/crypto_caller_get_key_attributes.h
index ea90af7..8ae3512 100644
--- a/components/service/crypto/client/caller/psa_ipc/crypto_caller_get_key_attributes.h
+++ b/components/service/crypto/client/caller/psa_ipc/crypto_caller_get_key_attributes.h
@@ -30,7 +30,7 @@
 					    psa_key_attributes_t *attributes)
 {
 	struct service_client *ipc = context;
-	struct rpc_caller *caller = ipc->caller;
+	struct rpc_caller_interface *caller = ipc->session->caller;
 	psa_status_t status;
 	struct psa_ipc_crypto_pack_iovec iov = {
 		.function_id = TFM_CRYPTO_GET_KEY_ATTRIBUTES_SID,
diff --git a/components/service/crypto/client/caller/psa_ipc/crypto_caller_hash.h b/components/service/crypto/client/caller/psa_ipc/crypto_caller_hash.h
index 77ef4ea..e13f5db 100644
--- a/components/service/crypto/client/caller/psa_ipc/crypto_caller_hash.h
+++ b/components/service/crypto/client/caller/psa_ipc/crypto_caller_hash.h
@@ -30,7 +30,7 @@
 					    psa_algorithm_t alg)
 {
 	struct service_client *ipc = context;
-	struct rpc_caller *caller = ipc->caller;
+	struct rpc_caller_interface *caller = ipc->session->caller;
 	psa_status_t status;
 	struct psa_ipc_crypto_pack_iovec iov = {
 		.function_id = TFM_CRYPTO_HASH_SETUP_SID,
@@ -57,7 +57,7 @@
 					     size_t input_length)
 {
 	struct service_client *ipc = context;
-	struct rpc_caller *caller = ipc->caller;
+	struct rpc_caller_interface *caller = ipc->session->caller;
 	psa_status_t status;
 	struct psa_ipc_crypto_pack_iovec iov = {
 		.function_id = TFM_CRYPTO_HASH_UPDATE_SID,
@@ -85,7 +85,7 @@
 					     size_t *hash_length)
 {
 	struct service_client *ipc = context;
-	struct rpc_caller *caller = ipc->caller;
+	struct rpc_caller_interface *caller = ipc->session->caller;
 	psa_status_t status;
 	struct psa_ipc_crypto_pack_iovec iov = {
 		.function_id = TFM_CRYPTO_HASH_FINISH_SID,
@@ -112,7 +112,7 @@
 					    uint32_t op_handle)
 {
 	struct service_client *ipc = context;
-	struct rpc_caller *caller = ipc->caller;
+	struct rpc_caller_interface *caller = ipc->session->caller;
 	psa_status_t status;
 	struct psa_ipc_crypto_pack_iovec iov = {
 		.function_id = TFM_CRYPTO_HASH_ABORT_SID,
@@ -138,7 +138,7 @@
 					     size_t hash_length)
 {
 	struct service_client *ipc = context;
-	struct rpc_caller *caller = ipc->caller;
+	struct rpc_caller_interface *caller = ipc->session->caller;
 	psa_status_t status;
 	struct psa_ipc_crypto_pack_iovec iov = {
 		.function_id = TFM_CRYPTO_HASH_VERIFY_SID,
@@ -164,7 +164,7 @@
 					    uint32_t *target_op_handle)
 {
 	struct service_client *ipc = context;
-	struct rpc_caller *caller = ipc->caller;
+	struct rpc_caller_interface *caller = ipc->session->caller;
 	psa_status_t status;
 	struct psa_ipc_crypto_pack_iovec iov = {
 		.function_id = TFM_CRYPTO_HASH_CLONE_SID,
diff --git a/components/service/crypto/client/caller/psa_ipc/crypto_caller_import_key.h b/components/service/crypto/client/caller/psa_ipc/crypto_caller_import_key.h
index 0c946a2..0444221 100644
--- a/components/service/crypto/client/caller/psa_ipc/crypto_caller_import_key.h
+++ b/components/service/crypto/client/caller/psa_ipc/crypto_caller_import_key.h
@@ -30,7 +30,7 @@
 				    psa_key_id_t *id)
 {
 	struct service_client *ipc = context;
-	struct rpc_caller *caller = ipc->caller;
+	struct rpc_caller_interface *caller = ipc->session->caller;
 	psa_status_t status;
 	struct psa_ipc_crypto_pack_iovec iov = {
 		.function_id = TFM_CRYPTO_IMPORT_KEY_SID,
diff --git a/components/service/crypto/client/caller/psa_ipc/crypto_caller_key_derivation.h b/components/service/crypto/client/caller/psa_ipc/crypto_caller_key_derivation.h
index 8bc3297..f165db1 100644
--- a/components/service/crypto/client/caller/psa_ipc/crypto_caller_key_derivation.h
+++ b/components/service/crypto/client/caller/psa_ipc/crypto_caller_key_derivation.h
@@ -30,7 +30,7 @@
 					      psa_algorithm_t alg)
 {
 	struct service_client *ipc = context;
-	struct rpc_caller *caller = ipc->caller;
+	struct rpc_caller_interface *caller = ipc->session->caller;
 	psa_status_t status;
 	struct psa_ipc_crypto_pack_iovec iov = {
 		.function_id = TFM_CRYPTO_KEY_DERIVATION_SETUP_SID,
@@ -56,7 +56,7 @@
 					     size_t *capacity)
 {
 	struct service_client *ipc = context;
-	struct rpc_caller *caller = ipc->caller;
+	struct rpc_caller_interface *caller = ipc->session->caller;
 	psa_status_t status;
 	struct psa_ipc_crypto_pack_iovec iov = {
 		.function_id = TFM_CRYPTO_KEY_DERIVATION_GET_CAPACITY_SID,
@@ -81,7 +81,7 @@
 					     size_t capacity)
 {
 	struct service_client *ipc = context;
-	struct rpc_caller *caller = ipc->caller;
+	struct rpc_caller_interface *caller = ipc->session->caller;
 	psa_status_t status;
 	struct psa_ipc_crypto_pack_iovec iov = {
 		.function_id = TFM_CRYPTO_KEY_DERIVATION_SET_CAPACITY_SID,
@@ -106,7 +106,7 @@
 					    size_t data_length)
 {
 	struct service_client *ipc = context;
-	struct rpc_caller *caller = ipc->caller;
+	struct rpc_caller_interface *caller = ipc->session->caller;
 	psa_status_t status;
 	struct psa_ipc_crypto_pack_iovec iov = {
 		.function_id = TFM_CRYPTO_KEY_DERIVATION_INPUT_BYTES_SID,
@@ -131,7 +131,7 @@
 					  psa_key_id_t key)
 {
 	struct service_client *ipc = context;
-	struct rpc_caller *caller = ipc->caller;
+	struct rpc_caller_interface *caller = ipc->session->caller;
 	psa_status_t status;
 	struct psa_ipc_crypto_pack_iovec iov = {
 		.function_id = TFM_CRYPTO_KEY_DERIVATION_INPUT_KEY_SID,
@@ -156,7 +156,7 @@
 					     size_t output_length)
 {
 	struct service_client *ipc = context;
-	struct rpc_caller *caller = ipc->caller;
+	struct rpc_caller_interface *caller = ipc->session->caller;
 	psa_status_t status;
 	struct psa_ipc_crypto_pack_iovec iov = {
 		.function_id = TFM_CRYPTO_KEY_DERIVATION_OUTPUT_BYTES_SID,
@@ -182,7 +182,7 @@
 				   psa_key_id_t *key)
 {
 	struct service_client *ipc = context;
-	struct rpc_caller *caller = ipc->caller;
+	struct rpc_caller_interface *caller = ipc->session->caller;
 	psa_status_t status;
 	struct psa_ipc_crypto_pack_iovec iov = {
 		.function_id = TFM_CRYPTO_KEY_DERIVATION_OUTPUT_KEY_SID,
@@ -208,7 +208,7 @@
 					      uint32_t op_handle)
 {
 	struct service_client *ipc = context;
-	struct rpc_caller *caller = ipc->caller;
+	struct rpc_caller_interface *caller = ipc->session->caller;
 	psa_status_t status;
 	struct psa_ipc_crypto_pack_iovec iov = {
 		.function_id = TFM_CRYPTO_KEY_DERIVATION_ABORT_SID,
@@ -236,7 +236,7 @@
 				      size_t peer_key_length)
 {
 	struct service_client *ipc = context;
-	struct rpc_caller *caller = ipc->caller;
+	struct rpc_caller_interface *caller = ipc->session->caller;
 	psa_status_t status;
 	struct psa_ipc_crypto_pack_iovec iov = {
 		.function_id = TFM_CRYPTO_KEY_DERIVATION_KEY_AGREEMENT_SID,
@@ -267,7 +267,7 @@
 					   size_t *output_length)
 {
 	struct service_client *ipc = context;
-	struct rpc_caller *caller = ipc->caller;
+	struct rpc_caller_interface *caller = ipc->session->caller;
 	psa_status_t status;
 	struct psa_ipc_crypto_pack_iovec iov = {
 		.function_id = TFM_CRYPTO_RAW_KEY_AGREEMENT_SID,
diff --git a/components/service/crypto/client/caller/psa_ipc/crypto_caller_mac.h b/components/service/crypto/client/caller/psa_ipc/crypto_caller_mac.h
index 5969233..8e8053d 100644
--- a/components/service/crypto/client/caller/psa_ipc/crypto_caller_mac.h
+++ b/components/service/crypto/client/caller/psa_ipc/crypto_caller_mac.h
@@ -31,7 +31,7 @@
 						psa_algorithm_t alg)
 {
 	struct service_client *ipc = context;
-	struct rpc_caller *caller = ipc->caller;
+	struct rpc_caller_interface *caller = ipc->session->caller;
 	psa_status_t status;
 	struct psa_ipc_crypto_pack_iovec iov = {
 		.function_id = TFM_CRYPTO_MAC_SIGN_SETUP_SID,
@@ -59,7 +59,7 @@
 					  psa_algorithm_t alg)
 {
 	struct service_client *ipc = context;
-	struct rpc_caller *caller = ipc->caller;
+	struct rpc_caller_interface *caller = ipc->session->caller;
 	psa_status_t status;
 	struct psa_ipc_crypto_pack_iovec iov = {
 		.function_id = TFM_CRYPTO_MAC_VERIFY_SETUP_SID,
@@ -87,7 +87,7 @@
 					    size_t input_length)
 {
 	struct service_client *ipc = context;
-	struct rpc_caller *caller = ipc->caller;
+	struct rpc_caller_interface *caller = ipc->session->caller;
 	psa_status_t status;
 	struct psa_ipc_crypto_pack_iovec iov = {
 		.function_id = TFM_CRYPTO_MAC_UPDATE_SID,
@@ -115,7 +115,7 @@
 						 size_t *mac_length)
 {
 	struct service_client *ipc = context;
-	struct rpc_caller *caller = ipc->caller;
+	struct rpc_caller_interface *caller = ipc->session->caller;
 	psa_status_t status;
 	struct psa_ipc_crypto_pack_iovec iov = {
 		.function_id = TFM_CRYPTO_MAC_SIGN_FINISH_SID,
@@ -144,7 +144,7 @@
 					   size_t mac_length)
 {
 	struct service_client *ipc = context;
-	struct rpc_caller *caller = ipc->caller;
+	struct rpc_caller_interface *caller = ipc->session->caller;
 	psa_status_t status;
 	struct psa_ipc_crypto_pack_iovec iov = {
 		.function_id = TFM_CRYPTO_MAC_VERIFY_FINISH_SID,
@@ -169,7 +169,7 @@
 					   uint32_t op_handle)
 {
 	struct service_client *ipc = context;
-	struct rpc_caller *caller = ipc->caller;
+	struct rpc_caller_interface *caller = ipc->session->caller;
 	psa_status_t status;
 	struct psa_ipc_crypto_pack_iovec iov = {
 		.function_id = TFM_CRYPTO_MAC_ABORT_SID,
diff --git a/components/service/crypto/client/caller/psa_ipc/crypto_caller_purge_key.h b/components/service/crypto/client/caller/psa_ipc/crypto_caller_purge_key.h
index b5894e0..6235859 100644
--- a/components/service/crypto/client/caller/psa_ipc/crypto_caller_purge_key.h
+++ b/components/service/crypto/client/caller/psa_ipc/crypto_caller_purge_key.h
@@ -28,7 +28,7 @@
 						   psa_key_id_t id)
 {
 	struct service_client *ipc = context;
-	struct rpc_caller *caller = ipc->caller;
+	struct rpc_caller_interface *caller = ipc->session->caller;
 	psa_status_t status;
 	struct psa_ipc_crypto_pack_iovec iov = {
 		.function_id = TFM_CRYPTO_PURGE_KEY_SID,
diff --git a/components/service/crypto/client/caller/psa_ipc/crypto_caller_sign_hash.h b/components/service/crypto/client/caller/psa_ipc/crypto_caller_sign_hash.h
index 254ee5a..ef84458 100644
--- a/components/service/crypto/client/caller/psa_ipc/crypto_caller_sign_hash.h
+++ b/components/service/crypto/client/caller/psa_ipc/crypto_caller_sign_hash.h
@@ -34,7 +34,7 @@
 						   size_t *signature_length)
 {
 	struct service_client *ipc = context;
-	struct rpc_caller *caller = ipc->caller;
+	struct rpc_caller_interface *caller = ipc->session->caller;
 	psa_status_t status;
 	struct psa_ipc_crypto_pack_iovec iov = {
 		.function_id = TFM_CRYPTO_ASYMMETRIC_SIGN_HASH_SID,
@@ -67,7 +67,7 @@
 						   size_t *signature_length)
 {
 	struct service_client *ipc = context;
-	struct rpc_caller *caller = ipc->caller;
+	struct rpc_caller_interface *caller = ipc->session->caller;
 	psa_status_t status;
 	struct psa_ipc_crypto_pack_iovec iov = {
 		.function_id = TFM_CRYPTO_ASYMMETRIC_SIGN_MESSAGE_SID,
diff --git a/components/service/crypto/client/caller/psa_ipc/crypto_caller_verify_hash.h b/components/service/crypto/client/caller/psa_ipc/crypto_caller_verify_hash.h
index 515f2a8..0e2aef1 100644
--- a/components/service/crypto/client/caller/psa_ipc/crypto_caller_verify_hash.h
+++ b/components/service/crypto/client/caller/psa_ipc/crypto_caller_verify_hash.h
@@ -34,7 +34,7 @@
 						     uint32_t function_id)
 {
 	struct service_client *ipc = context;
-	struct rpc_caller *caller = ipc->caller;
+	struct rpc_caller_interface *caller = ipc->session->caller;
 	psa_status_t status;
 	struct psa_ipc_crypto_pack_iovec iov = {
 		.function_id = function_id,
diff --git a/components/service/crypto/client/cpp/crypto_client.cpp b/components/service/crypto/client/cpp/crypto_client.cpp
index 3537c8a..9d5609a 100644
--- a/components/service/crypto/client/cpp/crypto_client.cpp
+++ b/components/service/crypto/client/cpp/crypto_client.cpp
@@ -5,7 +5,6 @@
  */
 
 #include "crypto_client.h"
-#include <service/discovery/client/discovery_client.h>
 #include <protocols/rpc/common/packed-c/status.h>
 
 crypto_client::crypto_client() :
@@ -14,15 +13,10 @@
 	service_client_init(&m_client, NULL);
 }
 
-crypto_client::crypto_client(struct rpc_caller *caller) :
+crypto_client::crypto_client(struct rpc_caller_session *session) :
 	m_client()
 {
-	service_client_init(&m_client, caller);
-
-	if (caller) {
-
-		discovery_client_get_service_info(&m_client);
-	}
+	service_client_init(&m_client, session);
 }
 
 crypto_client::~crypto_client()
@@ -30,14 +24,9 @@
 	service_client_deinit(&m_client);
 }
 
-void crypto_client::set_caller(struct rpc_caller *caller)
+void crypto_client::set_caller(struct rpc_caller_session *session)
 {
-	m_client.caller = caller;
-
-	if (caller) {
-
-		discovery_client_get_service_info(&m_client);
-	}
+	m_client.session = session;
 }
 
 int crypto_client::err_rpc_status() const
diff --git a/components/service/crypto/client/cpp/crypto_client.h b/components/service/crypto/client/cpp/crypto_client.h
index ccb0714..eebe60e 100644
--- a/components/service/crypto/client/cpp/crypto_client.h
+++ b/components/service/crypto/client/cpp/crypto_client.h
@@ -237,8 +237,8 @@
 
 protected:
 	crypto_client();
-	crypto_client(struct rpc_caller *caller);
-	void set_caller(struct rpc_caller *caller);
+	crypto_client(struct rpc_caller_session *session);
+	void set_caller(struct rpc_caller_session *session);
 
 	struct service_client m_client;
 };
diff --git a/components/service/crypto/client/cpp/protocol/packed-c/packedc_crypto_client.cpp b/components/service/crypto/client/cpp/protocol/packed-c/packedc_crypto_client.cpp
index 4e10f9b..2465f05 100644
--- a/components/service/crypto/client/cpp/protocol/packed-c/packedc_crypto_client.cpp
+++ b/components/service/crypto/client/cpp/protocol/packed-c/packedc_crypto_client.cpp
@@ -15,8 +15,8 @@
 
 }
 
-packedc_crypto_client::packedc_crypto_client(struct rpc_caller *caller) :
-	crypto_client(caller)
+packedc_crypto_client::packedc_crypto_client(struct rpc_caller_session *session) :
+	crypto_client(session)
 {
 
 }
diff --git a/components/service/crypto/client/cpp/protocol/packed-c/packedc_crypto_client.h b/components/service/crypto/client/cpp/protocol/packed-c/packedc_crypto_client.h
index d74ba60..c0e8958 100644
--- a/components/service/crypto/client/cpp/protocol/packed-c/packedc_crypto_client.h
+++ b/components/service/crypto/client/cpp/protocol/packed-c/packedc_crypto_client.h
@@ -7,6 +7,7 @@
 #ifndef PACKEDC_CRYPTO_CLIENT_H
 #define PACKEDC_CRYPTO_CLIENT_H
 
+#include "rpc_caller_session.h"
 #include <service/crypto/client/cpp/crypto_client.h>
 #include <protocols/service/crypto/packed-c/key_attributes.h>
 
@@ -17,7 +18,7 @@
 {
 public:
 	packedc_crypto_client();
-	packedc_crypto_client(struct rpc_caller *caller);
+	packedc_crypto_client(struct rpc_caller_session *session);
 	virtual ~packedc_crypto_client();
 
 	/* Key lifecycle methods */
diff --git a/components/service/crypto/client/cpp/protocol/protobuf/protobuf_crypto_client.cpp b/components/service/crypto/client/cpp/protocol/protobuf/protobuf_crypto_client.cpp
index 337485f..c84c753 100644
--- a/components/service/crypto/client/cpp/protocol/protobuf/protobuf_crypto_client.cpp
+++ b/components/service/crypto/client/cpp/protocol/protobuf/protobuf_crypto_client.cpp
@@ -9,7 +9,6 @@
 #include "protobuf_crypto_client.h"
 #include <protocols/rpc/common/packed-c/status.h>
 #include <service/common/serializer/protobuf/pb_helper.h>
-#include <rpc_caller.h>
 #include <service/crypto/protobuf/opcodes.pb.h>
 #include <service/crypto/protobuf/generate_key.pb.h>
 #include <service/crypto/protobuf/destroy_key.pb.h>
@@ -30,8 +29,8 @@
 
 }
 
-protobuf_crypto_client::protobuf_crypto_client(struct rpc_caller *caller) :
-	crypto_client(caller)
+protobuf_crypto_client::protobuf_crypto_client(struct rpc_caller_session *session) :
+	crypto_client(session)
 {
 
 }
@@ -69,23 +68,25 @@
 		rpc_call_handle call_handle;
 		uint8_t *req_buf;
 
-		call_handle = rpc_caller_begin(m_client.caller, &req_buf, req_len);
+		call_handle = rpc_caller_session_begin(m_client.session, &req_buf, req_len, 0);
 
 		if (call_handle) {
 
 			uint8_t *resp_buf;
 			size_t resp_len;
-			rpc_opstatus_t opstatus;
+			service_status_t service_status;
 
 			pb_ostream_t ostream = pb_ostream_from_buffer(req_buf, req_len);
 			pb_encode(&ostream, ts_crypto_GenerateKeyIn_fields, &req_msg);
 
-			m_client.rpc_status = rpc_caller_invoke(m_client.caller, call_handle,
-				ts_crypto_Opcode_GENERATE_KEY, &opstatus, &resp_buf, &resp_len);
+			m_client.rpc_status =
+				rpc_caller_session_invoke(call_handle,
+							  ts_crypto_Opcode_GENERATE_KEY,
+							  &resp_buf, &resp_len, &service_status);
 
-			if (m_client.rpc_status == TS_RPC_CALL_ACCEPTED) {
+			if (m_client.rpc_status == RPC_SUCCESS) {
 
-				psa_status = opstatus;
+				psa_status = service_status;
 
 				if (psa_status == PSA_SUCCESS) {
 
@@ -103,7 +104,7 @@
 				}
 			}
 
-			rpc_caller_end(m_client.caller, call_handle);
+			rpc_caller_session_end(call_handle);
 		}
 	}
 
@@ -123,23 +124,24 @@
 		rpc_call_handle call_handle;
 		uint8_t *req_buf;
 
-		call_handle = rpc_caller_begin(m_client.caller, &req_buf, req_len);
+		call_handle = rpc_caller_session_begin(m_client.session, &req_buf, req_len, 0);
 
 		if (call_handle) {
 
 			uint8_t *resp_buf;
 			size_t resp_len;
-			rpc_opstatus_t opstatus;
+			service_status_t service_status;
 
 			pb_ostream_t ostream = pb_ostream_from_buffer(req_buf, req_len);
 			pb_encode(&ostream, ts_crypto_DestroyKeyIn_fields, &req_msg);
 
-			m_client.rpc_status = rpc_caller_invoke(m_client.caller, call_handle,
-				ts_crypto_Opcode_DESTROY_KEY, &opstatus, &resp_buf, &resp_len);
+			m_client.rpc_status =
+				rpc_caller_session_invoke(call_handle, ts_crypto_Opcode_DESTROY_KEY,
+							  &resp_buf, &resp_len, &service_status);
 
-			if (m_client.rpc_status == TS_RPC_CALL_ACCEPTED) psa_status = opstatus;
+			if (m_client.rpc_status == RPC_SUCCESS) psa_status = service_status;
 
-			rpc_caller_end(m_client.caller, call_handle);
+			rpc_caller_session_end(call_handle);
 		}
 	}
 
@@ -164,23 +166,24 @@
 		rpc_call_handle call_handle;
 		uint8_t *req_buf;
 
-		call_handle = rpc_caller_begin(m_client.caller, &req_buf, req_len);
+		call_handle = rpc_caller_session_begin(m_client.session, &req_buf, req_len, 0);
 
 		if (call_handle) {
 
 			uint8_t *resp_buf;
 			size_t resp_len;
-			rpc_opstatus_t opstatus;
+			service_status_t service_status;
 
 			pb_ostream_t ostream = pb_ostream_from_buffer(req_buf, req_len);
 			pb_encode(&ostream, ts_crypto_ImportKeyIn_fields, &req_msg);
 
-			m_client.rpc_status = rpc_caller_invoke(m_client.caller, call_handle,
-				ts_crypto_Opcode_IMPORT_KEY, &opstatus, &resp_buf, &resp_len);
+			m_client.rpc_status =
+				rpc_caller_session_invoke(call_handle, ts_crypto_Opcode_IMPORT_KEY,
+							  &resp_buf, &resp_len, &service_status);
 
-			if (m_client.rpc_status == TS_RPC_CALL_ACCEPTED) {
+			if (m_client.rpc_status == RPC_SUCCESS) {
 
-				psa_status = opstatus;
+				psa_status = service_status;
 
 				if (psa_status == PSA_SUCCESS) {
 
@@ -198,7 +201,7 @@
 				}
 			}
 
-			rpc_caller_end(m_client.caller, call_handle);
+			rpc_caller_session_end(call_handle);
 		}
 	}
 
@@ -254,23 +257,25 @@
 		rpc_call_handle call_handle;
 		uint8_t *req_buf;
 
-		call_handle = rpc_caller_begin(m_client.caller, &req_buf, req_len);
+		call_handle = rpc_caller_session_begin(m_client.session, &req_buf, req_len,
+						       PB_PACKET_LENGTH(data_size));
 
 		if (call_handle) {
 
 			uint8_t *resp_buf;
 			size_t resp_len;
-			rpc_opstatus_t opstatus;
+			service_status_t service_status;
 
 			pb_ostream_t ostream = pb_ostream_from_buffer(req_buf, req_len);
 			pb_encode(&ostream, ts_crypto_ExportKeyIn_fields, &req_msg);
 
-			m_client.rpc_status = rpc_caller_invoke(m_client.caller, call_handle,
-				ts_crypto_Opcode_EXPORT_KEY, &opstatus, &resp_buf, &resp_len);
+			m_client.rpc_status =
+				rpc_caller_session_invoke(call_handle, ts_crypto_Opcode_EXPORT_KEY,
+							  &resp_buf, &resp_len, &service_status);
 
-			if (m_client.rpc_status == TS_RPC_CALL_ACCEPTED) {
+			if (m_client.rpc_status == RPC_SUCCESS) {
 
-				psa_status = opstatus;
+				psa_status = service_status;
 
 				if (psa_status == PSA_SUCCESS) {
 
@@ -308,7 +313,7 @@
 				}
 			}
 
-			rpc_caller_end(m_client.caller, call_handle);
+			rpc_caller_session_end(call_handle);
 		}
 	}
 
@@ -330,23 +335,26 @@
 		rpc_call_handle call_handle;
 		uint8_t *req_buf;
 
-		call_handle = rpc_caller_begin(m_client.caller, &req_buf, req_len);
+		call_handle = rpc_caller_session_begin(m_client.session, &req_buf, req_len,
+						       PB_PACKET_LENGTH(data_size));
 
 		if (call_handle) {
 
 			uint8_t *resp_buf;
 			size_t resp_len;
-			rpc_opstatus_t opstatus;
+			service_status_t service_status;
 
 			pb_ostream_t ostream = pb_ostream_from_buffer(req_buf, req_len);
 			pb_encode(&ostream, ts_crypto_ExportPublicKeyIn_fields, &req_msg);
 
-			m_client.rpc_status = rpc_caller_invoke(m_client.caller, call_handle,
-				ts_crypto_Opcode_EXPORT_PUBLIC_KEY, &opstatus, &resp_buf, &resp_len);
+			m_client.rpc_status =
+				rpc_caller_session_invoke(call_handle,
+							  ts_crypto_Opcode_EXPORT_PUBLIC_KEY,
+							  &resp_buf, &resp_len, &service_status);
 
-			if (m_client.rpc_status == TS_RPC_CALL_ACCEPTED) {
+			if (m_client.rpc_status == RPC_SUCCESS) {
 
-				psa_status = opstatus;
+				psa_status = service_status;
 
 				if (psa_status == PSA_SUCCESS) {
 
@@ -385,7 +393,7 @@
 				}
 			}
 
-			rpc_caller_end(m_client.caller, call_handle);
+			rpc_caller_session_end(call_handle);
 		}
 	}
 
@@ -432,23 +440,25 @@
 		rpc_call_handle call_handle;
 		uint8_t *req_buf;
 
-		call_handle = rpc_caller_begin(m_client.caller, &req_buf, req_len);
+		call_handle = rpc_caller_session_begin(m_client.session, &req_buf, req_len,
+						       PB_PACKET_LENGTH(signature_size));
 
 		if (call_handle) {
 
 			uint8_t *resp_buf;
 			size_t resp_len;
-			rpc_opstatus_t opstatus;
+			service_status_t service_status;
 
 			pb_ostream_t ostream = pb_ostream_from_buffer(req_buf, req_len);
 			pb_encode(&ostream, ts_crypto_SignHashIn_fields, &req_msg);
 
-			m_client.rpc_status = rpc_caller_invoke(m_client.caller, call_handle,
-						opcode, &opstatus, &resp_buf, &resp_len);
+			m_client.rpc_status =
+				rpc_caller_session_invoke(call_handle, opcode, &resp_buf, &resp_len,
+							  &service_status);
 
-			if (m_client.rpc_status == TS_RPC_CALL_ACCEPTED) {
+			if (m_client.rpc_status == RPC_SUCCESS) {
 
-				psa_status = opstatus;
+				psa_status = service_status;
 
 				if (psa_status == PSA_SUCCESS) {
 
@@ -481,7 +491,7 @@
 				}
 			}
 
-			rpc_caller_end(m_client.caller, call_handle);
+			rpc_caller_session_end(call_handle);
 		}
 	}
 
@@ -531,23 +541,24 @@
 		rpc_call_handle call_handle;
 		uint8_t *req_buf;
 
-		call_handle = rpc_caller_begin(m_client.caller, &req_buf, req_len);
+		call_handle = rpc_caller_session_begin(m_client.session, &req_buf, req_len, 0);
 
 		if (call_handle) {
 
 			uint8_t *resp_buf;
 			size_t resp_len;
-			rpc_opstatus_t opstatus;
+			service_status_t service_status;
 
 			pb_ostream_t ostream = pb_ostream_from_buffer(req_buf, req_len);
 			pb_encode(&ostream, ts_crypto_VerifyHashIn_fields, &req_msg);
 
-			m_client.rpc_status = rpc_caller_invoke(m_client.caller, call_handle,
-						opcode, &opstatus, &resp_buf, &resp_len);
+			m_client.rpc_status =
+				rpc_caller_session_invoke(call_handle, opcode, &resp_buf, &resp_len,
+							  &service_status);
 
-			if (m_client.rpc_status == TS_RPC_CALL_ACCEPTED) psa_status = opstatus;
+			if (m_client.rpc_status == RPC_SUCCESS) psa_status = service_status;
 
-			rpc_caller_end(m_client.caller, call_handle);
+			rpc_caller_session_end(call_handle);
 		}
 	}
 
@@ -586,23 +597,26 @@
 		rpc_call_handle call_handle;
 		uint8_t *req_buf;
 
-		call_handle = rpc_caller_begin(m_client.caller, &req_buf, req_len);
+		call_handle = rpc_caller_session_begin(m_client.session, &req_buf, req_len,
+						       PB_PACKET_LENGTH(output_size));
 
 		if (call_handle) {
 
 			uint8_t *resp_buf;
 			size_t resp_len;
-			rpc_opstatus_t opstatus = PSA_ERROR_GENERIC_ERROR;
+			service_status_t service_status = PSA_ERROR_GENERIC_ERROR;
 
 			pb_ostream_t ostream = pb_ostream_from_buffer(req_buf, req_len);
 			pb_encode(&ostream, ts_crypto_AsymmetricEncryptIn_fields, &req_msg);
 
-			m_client.rpc_status = rpc_caller_invoke(m_client.caller, call_handle,
-						ts_crypto_Opcode_ASYMMETRIC_ENCRYPT, &opstatus, &resp_buf, &resp_len);
+			m_client.rpc_status =
+				rpc_caller_session_invoke(call_handle,
+							  ts_crypto_Opcode_ASYMMETRIC_ENCRYPT,
+							  &resp_buf, &resp_len, &service_status);
 
-			if (m_client.rpc_status == TS_RPC_CALL_ACCEPTED) {
+			if (m_client.rpc_status == RPC_SUCCESS) {
 
-				psa_status = opstatus;
+				psa_status = service_status;
 
 				if (psa_status == PSA_SUCCESS) {
 
@@ -635,7 +649,7 @@
 				}
 			}
 
-			rpc_caller_end(m_client.caller, call_handle);
+			rpc_caller_session_end(call_handle);
 		}
 	}
 
@@ -674,23 +688,25 @@
 		rpc_call_handle call_handle;
 		uint8_t *req_buf;
 
-		call_handle = rpc_caller_begin(m_client.caller, &req_buf, req_len);
+		call_handle = rpc_caller_session_begin(m_client.session, &req_buf, req_len, 0);
 
 		if (call_handle) {
 
 			uint8_t *resp_buf;
 			size_t resp_len;
-			rpc_opstatus_t opstatus;
+			service_status_t service_status;
 
 			pb_ostream_t ostream = pb_ostream_from_buffer(req_buf, req_len);
 			pb_encode(&ostream, ts_crypto_AsymmetricDecryptIn_fields, &req_msg);
 
-			m_client.rpc_status = rpc_caller_invoke(m_client.caller, call_handle,
-						ts_crypto_Opcode_ASYMMETRIC_DECRYPT, &opstatus, &resp_buf, &resp_len);
+			m_client.rpc_status =
+				rpc_caller_session_invoke(call_handle,
+							  ts_crypto_Opcode_ASYMMETRIC_DECRYPT,
+							  &resp_buf, &resp_len, &service_status);
 
-			if (m_client.rpc_status == TS_RPC_CALL_ACCEPTED) {
+			if (m_client.rpc_status == RPC_SUCCESS) {
 
-				psa_status = opstatus;
+				psa_status = service_status;
 
 				if (psa_status == PSA_SUCCESS) {
 
@@ -723,7 +739,7 @@
 				}
 			}
 
-			rpc_caller_end(m_client.caller, call_handle);
+			rpc_caller_session_end(call_handle);
 		}
 	}
 
@@ -746,23 +762,25 @@
 		rpc_call_handle call_handle;
 		uint8_t *req_buf;
 
-		call_handle = rpc_caller_begin(m_client.caller, &req_buf, req_len);
+		call_handle = rpc_caller_session_begin(m_client.session, &req_buf, req_len, output_size + 8);
 
 		if (call_handle) {
 
 			uint8_t *resp_buf;
 			size_t resp_len;
-			rpc_opstatus_t opstatus;
+			service_status_t service_status;
 
 			pb_ostream_t ostream = pb_ostream_from_buffer(req_buf, req_len);
 			pb_encode(&ostream, ts_crypto_GenerateRandomIn_fields, &req_msg);
 
-			m_client.rpc_status = rpc_caller_invoke(m_client.caller, call_handle,
-					ts_crypto_Opcode_GENERATE_RANDOM, &opstatus, &resp_buf, &resp_len);
+			m_client.rpc_status =
+				rpc_caller_session_invoke(call_handle,
+							  ts_crypto_Opcode_GENERATE_RANDOM,
+							  &resp_buf, &resp_len, &service_status);
 
-			if (m_client.rpc_status == TS_RPC_CALL_ACCEPTED) {
+			if (m_client.rpc_status == RPC_SUCCESS) {
 
-				psa_status = opstatus;
+				psa_status = service_status;
 
 				if (psa_status == PSA_SUCCESS) {
 
@@ -792,7 +810,7 @@
 				}
 			}
 
-			rpc_caller_end(m_client.caller, call_handle);
+			rpc_caller_session_end(call_handle);
 		}
 	}
 
diff --git a/components/service/crypto/client/cpp/protocol/protobuf/protobuf_crypto_client.h b/components/service/crypto/client/cpp/protocol/protobuf/protobuf_crypto_client.h
index abe4439..8ce896f 100644
--- a/components/service/crypto/client/cpp/protocol/protobuf/protobuf_crypto_client.h
+++ b/components/service/crypto/client/cpp/protocol/protobuf/protobuf_crypto_client.h
@@ -9,6 +9,7 @@
 
 #include <service/crypto/client/cpp/crypto_client.h>
 #include <service/crypto/protobuf/key_attributes.pb.h>
+#include "rpc_caller_session.h"
 
 /*
  * A concrete crypto_client that uses the protobuf based crypto access protocol
@@ -17,7 +18,7 @@
 {
 public:
 	protobuf_crypto_client();
-	protobuf_crypto_client(struct rpc_caller *caller);
+	protobuf_crypto_client(struct rpc_caller_session *session);
 	virtual ~protobuf_crypto_client();
 
 	/* Key lifecycle methods */
diff --git a/components/service/crypto/client/psa/psa_crypto_client.c b/components/service/crypto/client/psa/psa_crypto_client.c
index 1c0e055..e42d37a 100644
--- a/components/service/crypto/client/psa/psa_crypto_client.c
+++ b/components/service/crypto/client/psa/psa_crypto_client.c
@@ -9,7 +9,7 @@
 
 struct psa_crypto_client psa_crypto_client_instance = {
 
-	.base.caller = NULL,
+	.base.session = NULL,
 
 	/* To conform to PSA API, psa_crypto_init needs to be called.
 	 * This state variable is used enforces this.
@@ -20,17 +20,15 @@
 psa_status_t psa_crypto_init(void) {
 
 	/* Must be called after psa_crypto_client_init */
-	if (psa_crypto_client_instance.base.caller) {
-
+	if (psa_crypto_client_instance.base.session)
 		psa_crypto_client_instance.init_status = PSA_SUCCESS;
-	}
 
 	return psa_crypto_client_instance.init_status;
 }
 
-psa_status_t psa_crypto_client_init(struct rpc_caller *caller)
+psa_status_t psa_crypto_client_init(struct rpc_caller_session *session)
 {
-	return service_client_init(&psa_crypto_client_instance.base, caller);
+	return service_client_init(&psa_crypto_client_instance.base, session);
 }
 
 void psa_crypto_client_deinit(void)
diff --git a/components/service/crypto/client/psa/psa_crypto_client.h b/components/service/crypto/client/psa/psa_crypto_client.h
index fbf6046..0041501 100644
--- a/components/service/crypto/client/psa/psa_crypto_client.h
+++ b/components/service/crypto/client/psa/psa_crypto_client.h
@@ -39,7 +39,7 @@
  *
  * @return     A status indicating the success/failure of the operation
  */
-psa_status_t psa_crypto_client_init(struct rpc_caller *caller);
+psa_status_t psa_crypto_client_init(struct rpc_caller_session *session);
 
 /**
  * @brief      De-initialises the single psa crypto client
diff --git a/components/service/crypto/client/test/standalone/standalone_crypto_client.cpp b/components/service/crypto/client/test/standalone/standalone_crypto_client.cpp
index b36264d..6146477 100644
--- a/components/service/crypto/client/test/standalone/standalone_crypto_client.cpp
+++ b/components/service/crypto/client/test/standalone/standalone_crypto_client.cpp
@@ -5,6 +5,8 @@
  */
 
 #include "standalone_crypto_client.h"
+#include "service/secure_storage/frontend/secure_storage_provider/secure_storage_uuid.h"
+#include "service/crypto/provider/crypto_uuid.h"
 #include <service/crypto/factory/crypto_provider_factory.h>
 #include <service/crypto/backend/mbedcrypto/mbedcrypto_backend.h>
 #include <service/secure_storage/backend/secure_flash_store/secure_flash_store.h>
@@ -17,7 +19,8 @@
     m_storage_client(),
     m_crypto_caller(),
     m_storage_caller(),
-    m_dummy_storage_caller()
+    m_crypto_session(),
+    m_storage_session()
 {
 
 }
@@ -32,42 +35,55 @@
     bool should_do = test_crypto_client::init();
 
     if (should_do) {
-
-        struct rpc_caller *storage_caller;
+        const struct rpc_uuid storage_uuid = { .uuid = TS_PSA_INTERNAL_TRUSTED_STORAGE_UUID };
+        const struct rpc_uuid crypto_uuid = { .uuid = TS_PSA_CRYPTO_PROTOBUF_SERVICE_UUID };
+        rpc_status_t rpc_status = RPC_ERROR_INTERNAL;
 
         if (!is_fault_injected(FAILED_TO_DISCOVER_SECURE_STORAGE)) {
 
             /* Establish rpc session with storage provider */
             struct storage_backend *storage_backend = sfs_init(sfs_flash_ram_instance());
-            struct rpc_interface *storage_ep = secure_storage_provider_init(&m_storage_provider,
-                                                                storage_backend);
-            storage_caller = direct_caller_init_default(&m_storage_caller, storage_ep);
-        }
-        else {
+            struct rpc_service_interface *storage_service =
+                secure_storage_provider_init(&m_storage_provider, storage_backend, &storage_uuid);
+            rpc_status = direct_caller_init(&m_storage_caller, storage_service);
+        } else {
 
             /*
              * Missing storage service fault injected.  To allow a somewhat viable
              * crypto service to be started, use a dummy _caller that will safely
              * terminate storage calls with an appropriate error.
              */
-            storage_caller = dummy_caller_init(&m_dummy_storage_caller,
-                        TS_RPC_CALL_ACCEPTED, PSA_ERROR_STORAGE_FAILURE);
+            rpc_status = dummy_caller_init(&m_storage_caller, RPC_SUCCESS, PSA_ERROR_STORAGE_FAILURE);
         }
 
-        struct rpc_interface *crypto_iface = NULL;
+        if (rpc_status != RPC_SUCCESS)
+            return false;
+
+        rpc_status = rpc_caller_session_find_and_open(&m_storage_session, &m_storage_caller,
+                                                      &storage_uuid, 4096);
+        if (rpc_status != RPC_SUCCESS)
+            return false;
+
+        struct rpc_service_interface *crypto_iface = NULL;
         struct storage_backend *client_storage_backend =
-            secure_storage_client_init(&m_storage_client, storage_caller);
+            secure_storage_client_init(&m_storage_client, &m_storage_session);
 
         if (mbedcrypto_backend_init(client_storage_backend, 0) == PSA_SUCCESS) {
 
-            m_crypto_provider = crypto_provider_factory_create();
+            m_crypto_provider = crypto_protobuf_provider_factory_create();
             crypto_iface = service_provider_get_rpc_interface(&m_crypto_provider->base_provider);
         }
 
-        struct rpc_caller *crypto_caller = direct_caller_init_default(&m_crypto_caller, crypto_iface);
-        rpc_caller_set_encoding_scheme(crypto_caller, TS_RPC_ENCODING_PROTOBUF);
+        rpc_status = direct_caller_init(&m_crypto_caller, crypto_iface);
+        if (rpc_status != RPC_SUCCESS)
+            return false;
 
-        crypto_client::set_caller(crypto_caller);
+        rpc_status = rpc_caller_session_find_and_open(&m_crypto_session, &m_crypto_caller,
+                                                      &crypto_uuid, 4096);
+        if (rpc_status != RPC_SUCCESS)
+            return false;
+
+        crypto_client::set_caller(&m_crypto_session);
     }
 
     return should_do;
@@ -83,6 +99,9 @@
         secure_storage_provider_deinit(&m_storage_provider);
         secure_storage_client_deinit(&m_storage_client);
 
+        rpc_caller_session_close(&m_storage_session);
+        rpc_caller_session_close(&m_crypto_session);
+
         direct_caller_deinit(&m_storage_caller);
         direct_caller_deinit(&m_crypto_caller);
     }
diff --git a/components/service/crypto/client/test/standalone/standalone_crypto_client.h b/components/service/crypto/client/test/standalone/standalone_crypto_client.h
index 8df0861..c6d9ace 100644
--- a/components/service/crypto/client/test/standalone/standalone_crypto_client.h
+++ b/components/service/crypto/client/test/standalone/standalone_crypto_client.h
@@ -46,9 +46,10 @@
     struct crypto_provider *m_crypto_provider;
     struct secure_storage_provider m_storage_provider;
     struct secure_storage_client m_storage_client;
-    struct direct_caller m_crypto_caller;
-    struct direct_caller m_storage_caller;
-    struct dummy_caller m_dummy_storage_caller;
+    struct rpc_caller_interface m_crypto_caller;
+    struct rpc_caller_interface m_storage_caller;
+    struct rpc_caller_session m_crypto_session;
+    struct rpc_caller_session m_storage_session;
 };
 
 #endif /* STANDALONE_CRYPTO_CLIENT_H */
diff --git a/components/service/crypto/factory/crypto_provider_factory.h b/components/service/crypto/factory/crypto_provider_factory.h
index f4b1491..f5b8787 100644
--- a/components/service/crypto/factory/crypto_provider_factory.h
+++ b/components/service/crypto/factory/crypto_provider_factory.h
@@ -28,6 +28,8 @@
  */
 struct crypto_provider *crypto_provider_factory_create(void);
 
+struct crypto_provider *crypto_protobuf_provider_factory_create(void);
+
 /**
  * \brief Destroys a created crypto provider
  *
diff --git a/components/service/crypto/factory/full/crypto_provider_factory.c b/components/service/crypto/factory/full/crypto_provider_factory.c
index ee2b447..45af9aa 100644
--- a/components/service/crypto/factory/full/crypto_provider_factory.c
+++ b/components/service/crypto/factory/full/crypto_provider_factory.c
@@ -19,8 +19,6 @@
 #include <service/crypto/provider/extension/mac/serializer/packed-c/packedc_mac_provider_serializer.h>
 #include <service/crypto/provider/extension/aead/aead_provider.h>
 #include <service/crypto/provider/extension/aead/serializer/packed-c/packedc_aead_provider_serializer.h>
-#include <service/discovery/provider/discovery_provider.h>
-#include <service/discovery/provider/serializer/packed-c/packedc_discovery_provider_serializer.h>
 
 /**
  * A crypto provider factory that constucts a crypto provider
@@ -32,12 +30,12 @@
 static struct full_crypto_provider
 {
 	struct crypto_provider crypto_provider;
+	struct crypto_provider crypto_provider_protobuf;
 	struct hash_provider hash_provider;
 	struct cipher_provider cipher_provider;
 	struct key_derivation_provider key_derivation_provider;
 	struct mac_provider mac_provider;
 	struct aead_provider aead_provider;
-
 } instance;
 
 struct crypto_provider *crypto_provider_factory_create(void)
@@ -45,17 +43,8 @@
 	/**
 	 * Initialize the core crypto provider
 	 */
-	crypto_provider_init(&instance.crypto_provider);
-
-	/* Register serializers for the core crypto provider */
-	crypto_provider_register_serializer(&instance.crypto_provider,
-		TS_RPC_ENCODING_PROTOBUF, pb_crypto_provider_serializer_instance());
-	crypto_provider_register_serializer(&instance.crypto_provider,
-		TS_RPC_ENCODING_PACKED_C, packedc_crypto_provider_serializer_instance());
-
-	/* Register serializer for the associated discovery provider */
-	discovery_provider_register_serializer(&instance.crypto_provider.discovery_provider,
-		TS_RPC_ENCODING_PACKED_C, packedc_discovery_provider_serializer_instance());
+	crypto_provider_init(&instance.crypto_provider, TS_RPC_ENCODING_PACKED_C,
+			     packedc_crypto_provider_serializer_instance());
 
 	/**
 	 * Extend with hash operations
@@ -85,7 +74,8 @@
 	key_derivation_provider_init(&instance.key_derivation_provider);
 
 	key_derivation_provider_register_serializer(&instance.key_derivation_provider,
-		TS_RPC_ENCODING_PACKED_C, packedc_key_derivation_provider_serializer_instance());
+		TS_RPC_ENCODING_PACKED_C,
+		packedc_key_derivation_provider_serializer_instance());
 
 	crypto_provider_extend(&instance.crypto_provider,
 		&instance.key_derivation_provider.base_provider);
@@ -115,6 +105,14 @@
 	return &instance.crypto_provider;
 }
 
+struct crypto_provider *crypto_protobuf_provider_factory_create(void)
+{
+	crypto_provider_init(&instance.crypto_provider_protobuf, TS_RPC_ENCODING_PROTOBUF,
+			     pb_crypto_provider_serializer_instance());
+
+	return &instance.crypto_provider_protobuf;
+}
+
 /**
  * \brief Destroys a created crypto provider
  *
diff --git a/components/service/crypto/provider/crypto_provider.c b/components/service/crypto/provider/crypto_provider.c
index 67a5b34..d1798d7 100644
--- a/components/service/crypto/provider/crypto_provider.c
+++ b/components/service/crypto/provider/crypto_provider.c
@@ -3,100 +3,98 @@
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
+#include <protocols/rpc/common/packed-c/status.h>
+#include <protocols/service/crypto/packed-c/opcodes.h>
+#include <psa/crypto.h>
+#include <service/crypto/provider/crypto_provider.h>
 #include <stdint.h>
 #include <stdlib.h>
-#include <protocols/service/crypto/packed-c/opcodes.h>
-#include <service/crypto/provider/crypto_provider.h>
-#include <protocols/rpc/common/packed-c/status.h>
-#include <psa/crypto.h>
+
+#include "crypto_uuid.h"
 
 /* Service request handlers */
-static rpc_status_t generate_key_handler(void *context, struct call_req* req);
-static rpc_status_t destroy_key_handler(void *context, struct call_req* req);
-static rpc_status_t export_key_handler(void *context, struct call_req* req);
-static rpc_status_t export_public_key_handler(void *context, struct call_req* req);
-static rpc_status_t import_key_handler(void *context, struct call_req* req);
-static rpc_status_t asymmetric_sign_handler(void *context, struct call_req* req);
-static rpc_status_t asymmetric_verify_handler(void *context, struct call_req* req);
-static rpc_status_t asymmetric_decrypt_handler(void *context, struct call_req* req);
-static rpc_status_t asymmetric_encrypt_handler(void *context, struct call_req* req);
-static rpc_status_t generate_random_handler(void *context, struct call_req* req);
-static rpc_status_t copy_key_handler(void *context, struct call_req* req);
-static rpc_status_t purge_key_handler(void *context, struct call_req* req);
-static rpc_status_t get_key_attributes_handler(void *context, struct call_req* req);
+static rpc_status_t generate_key_handler(void *context, struct rpc_request *req);
+static rpc_status_t destroy_key_handler(void *context, struct rpc_request *req);
+static rpc_status_t export_key_handler(void *context, struct rpc_request *req);
+static rpc_status_t export_public_key_handler(void *context, struct rpc_request *req);
+static rpc_status_t import_key_handler(void *context, struct rpc_request *req);
+static rpc_status_t asymmetric_sign_handler(void *context, struct rpc_request *req);
+static rpc_status_t asymmetric_verify_handler(void *context, struct rpc_request *req);
+static rpc_status_t asymmetric_decrypt_handler(void *context, struct rpc_request *req);
+static rpc_status_t asymmetric_encrypt_handler(void *context, struct rpc_request *req);
+static rpc_status_t generate_random_handler(void *context, struct rpc_request *req);
+static rpc_status_t copy_key_handler(void *context, struct rpc_request *req);
+static rpc_status_t purge_key_handler(void *context, struct rpc_request *req);
+static rpc_status_t get_key_attributes_handler(void *context, struct rpc_request *req);
 
 /* Handler mapping table for service */
 static const struct service_handler handler_table[] = {
-	{TS_CRYPTO_OPCODE_GENERATE_KEY,         generate_key_handler},
-	{TS_CRYPTO_OPCODE_DESTROY_KEY,          destroy_key_handler},
-	{TS_CRYPTO_OPCODE_EXPORT_KEY,           export_key_handler},
-	{TS_CRYPTO_OPCODE_EXPORT_PUBLIC_KEY,    export_public_key_handler},
-	{TS_CRYPTO_OPCODE_IMPORT_KEY,           import_key_handler},
-	{TS_CRYPTO_OPCODE_SIGN_HASH,            asymmetric_sign_handler},
-	{TS_CRYPTO_OPCODE_VERIFY_HASH,          asymmetric_verify_handler},
-	{TS_CRYPTO_OPCODE_ASYMMETRIC_DECRYPT,   asymmetric_decrypt_handler},
-	{TS_CRYPTO_OPCODE_ASYMMETRIC_ENCRYPT,   asymmetric_encrypt_handler},
-	{TS_CRYPTO_OPCODE_GENERATE_RANDOM,      generate_random_handler},
-	{TS_CRYPTO_OPCODE_COPY_KEY,          	copy_key_handler},
-	{TS_CRYPTO_OPCODE_PURGE_KEY,          	purge_key_handler},
-	{TS_CRYPTO_OPCODE_GET_KEY_ATTRIBUTES, 	get_key_attributes_handler},
-	{TS_CRYPTO_OPCODE_SIGN_MESSAGE,         asymmetric_sign_handler},
-	{TS_CRYPTO_OPCODE_VERIFY_MESSAGE,       asymmetric_verify_handler},
+	{ TS_CRYPTO_OPCODE_GENERATE_KEY, generate_key_handler },
+	{ TS_CRYPTO_OPCODE_DESTROY_KEY, destroy_key_handler },
+	{ TS_CRYPTO_OPCODE_EXPORT_KEY, export_key_handler },
+	{ TS_CRYPTO_OPCODE_EXPORT_PUBLIC_KEY, export_public_key_handler },
+	{ TS_CRYPTO_OPCODE_IMPORT_KEY, import_key_handler },
+	{ TS_CRYPTO_OPCODE_SIGN_HASH, asymmetric_sign_handler },
+	{ TS_CRYPTO_OPCODE_VERIFY_HASH, asymmetric_verify_handler },
+	{ TS_CRYPTO_OPCODE_ASYMMETRIC_DECRYPT, asymmetric_decrypt_handler },
+	{ TS_CRYPTO_OPCODE_ASYMMETRIC_ENCRYPT, asymmetric_encrypt_handler },
+	{ TS_CRYPTO_OPCODE_GENERATE_RANDOM, generate_random_handler },
+	{ TS_CRYPTO_OPCODE_COPY_KEY, copy_key_handler },
+	{ TS_CRYPTO_OPCODE_PURGE_KEY, purge_key_handler },
+	{ TS_CRYPTO_OPCODE_GET_KEY_ATTRIBUTES, get_key_attributes_handler },
+	{ TS_CRYPTO_OPCODE_SIGN_MESSAGE, asymmetric_sign_handler },
+	{ TS_CRYPTO_OPCODE_VERIFY_MESSAGE, asymmetric_verify_handler },
 };
 
-struct rpc_interface *crypto_provider_init(struct crypto_provider *context)
+struct rpc_service_interface *
+crypto_provider_init(struct crypto_provider *context, unsigned int encoding,
+		     const struct crypto_provider_serializer *serializer)
 {
-	/* Initialise the crypto provider */
-	for (size_t encoding = 0; encoding < TS_RPC_ENCODING_LIMIT; ++encoding)
-		context->serializers[encoding] = NULL;
+	const struct rpc_uuid crypto_service_uuid[2] = {
+		{ .uuid = TS_PSA_CRYPTO_SERVICE_UUID },
+		{ .uuid = TS_PSA_CRYPTO_PROTOBUF_SERVICE_UUID },
+	};
 
-	service_provider_init(&context->base_provider, context,
-					handler_table, sizeof(handler_table)/sizeof(struct service_handler));
+	if (encoding >= TS_RPC_ENCODING_LIMIT)
+		return NULL;
 
-	/* Initialise the associated discovery provider */
-	discovery_provider_init(&context->discovery_provider);
-	service_provider_extend(&context->base_provider, &context->discovery_provider.base_provider);
+	context->serializer = serializer;
+
+	service_provider_init(&context->base_provider, context, &crypto_service_uuid[encoding],
+			      handler_table,
+			      sizeof(handler_table) / sizeof(struct service_handler));
 
 	return service_provider_get_rpc_interface(&context->base_provider);
 }
 
 void crypto_provider_deinit(struct crypto_provider *context)
 {
-	discovery_provider_deinit(&context->discovery_provider);
+	(void)context;
 }
 
 void crypto_provider_register_serializer(struct crypto_provider *context,
-				unsigned int encoding, const struct crypto_provider_serializer *serializer)
+					 const struct crypto_provider_serializer *serializer)
 {
-	if (encoding < TS_RPC_ENCODING_LIMIT) {
-
-		context->serializers[encoding] = serializer;
-		discovery_provider_register_supported_encoding(&context->discovery_provider, encoding);
-	}
+	context->serializer = serializer;
 }
 
-void crypto_provider_extend(struct crypto_provider *context,
-                    struct service_provider *sub_provider)
+void crypto_provider_extend(struct crypto_provider *context, struct service_provider *sub_provider)
 {
 	service_provider_extend(&context->base_provider, sub_provider);
 }
 
-static const struct crypto_provider_serializer* get_crypto_serializer(void *context,
-														const struct call_req *req)
+static const struct crypto_provider_serializer *get_crypto_serializer(void *context,
+								      const struct rpc_request *req)
 {
-	struct crypto_provider *this_instance = (struct crypto_provider*)context;
-	const struct crypto_provider_serializer* serializer = NULL;
-	unsigned int encoding = call_req_get_encoding(req);
+	struct crypto_provider *this_instance = (struct crypto_provider *)context;
 
-	if (encoding < TS_RPC_ENCODING_LIMIT) serializer = this_instance->serializers[encoding];
-
-	return serializer;
+	return this_instance->serializer;
 }
 
-static rpc_status_t generate_key_handler(void *context, struct call_req* req)
+static rpc_status_t generate_key_handler(void *context, struct rpc_request *req)
 {
-	rpc_status_t rpc_status = TS_RPC_ERROR_SERIALIZATION_NOT_SUPPORTED;
-	struct call_param_buf *req_buf = call_req_get_req_buf(req);
+	rpc_status_t rpc_status = RPC_ERROR_INTERNAL;
+	struct rpc_buffer *req_buf = &req->request;
 	const struct crypto_provider_serializer *serializer = get_crypto_serializer(context, req);
 
 	psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
@@ -104,20 +102,18 @@
 	if (serializer)
 		rpc_status = serializer->deserialize_generate_key_req(req_buf, &attributes);
 
-	if (rpc_status == TS_RPC_CALL_ACCEPTED) {
-
+	if (rpc_status == RPC_SUCCESS) {
 		psa_status_t psa_status;
 		psa_key_id_t id;
 
 		psa_status = psa_generate_key(&attributes, &id);
 
 		if (psa_status == PSA_SUCCESS) {
-
-			struct call_param_buf *resp_buf = call_req_get_resp_buf(req);
+			struct rpc_buffer *resp_buf = &req->response;
 			rpc_status = serializer->serialize_generate_key_resp(resp_buf, id);
 		}
 
-		call_req_set_opstatus(req, psa_status);
+		req->service_status = psa_status;
 	}
 
 	psa_reset_key_attributes(&attributes);
@@ -125,10 +121,10 @@
 	return rpc_status;
 }
 
-static rpc_status_t destroy_key_handler(void *context, struct call_req* req)
+static rpc_status_t destroy_key_handler(void *context, struct rpc_request *req)
 {
-	rpc_status_t rpc_status = TS_RPC_ERROR_SERIALIZATION_NOT_SUPPORTED;
-	struct call_param_buf *req_buf = call_req_get_req_buf(req);
+	rpc_status_t rpc_status = RPC_ERROR_INTERNAL;
+	struct rpc_buffer *req_buf = &req->request;
 	const struct crypto_provider_serializer *serializer = get_crypto_serializer(context, req);
 
 	psa_key_id_t id;
@@ -136,21 +132,20 @@
 	if (serializer)
 		rpc_status = serializer->deserialize_destroy_key_req(req_buf, &id);
 
-	if (rpc_status == TS_RPC_CALL_ACCEPTED) {
-
+	if (rpc_status == RPC_SUCCESS) {
 		psa_status_t psa_status;
 
 		psa_status = psa_destroy_key(id);
-		call_req_set_opstatus(req, psa_status);
+		req->service_status = psa_status;
 	}
 
 	return rpc_status;
 }
 
-static rpc_status_t export_key_handler(void *context, struct call_req* req)
+static rpc_status_t export_key_handler(void *context, struct rpc_request *req)
 {
-	rpc_status_t rpc_status = TS_RPC_ERROR_SERIALIZATION_NOT_SUPPORTED;
-	struct call_param_buf *req_buf = call_req_get_req_buf(req);
+	rpc_status_t rpc_status = RPC_ERROR_INTERNAL;
+	struct rpc_buffer *req_buf = &req->request;
 	const struct crypto_provider_serializer *serializer = get_crypto_serializer(context, req);
 
 	psa_key_id_t id;
@@ -158,40 +153,37 @@
 	if (serializer)
 		rpc_status = serializer->deserialize_export_key_req(req_buf, &id);
 
-	if (rpc_status == TS_RPC_CALL_ACCEPTED) {
-
+	if (rpc_status == RPC_SUCCESS) {
 		size_t max_export_size = PSA_EXPORT_KEY_PAIR_MAX_SIZE;
 		uint8_t *key_buffer = malloc(max_export_size);
 
 		if (key_buffer) {
-
 			size_t export_size;
-			psa_status_t psa_status = psa_export_key(id, key_buffer,
-				max_export_size, &export_size);
+			psa_status_t psa_status =
+				psa_export_key(id, key_buffer, max_export_size, &export_size);
 
 			if (psa_status == PSA_SUCCESS) {
+				struct rpc_buffer *resp_buf = &req->response;
 
-				struct call_param_buf *resp_buf = call_req_get_resp_buf(req);
-				rpc_status = serializer->serialize_export_key_resp(resp_buf,
-					key_buffer, export_size);
+				rpc_status = serializer->serialize_export_key_resp(
+					resp_buf, key_buffer, export_size);
 			}
 
 			free(key_buffer);
-			call_req_set_opstatus(req, psa_status);
-		}
-		else {
+			req->service_status = psa_status;
+		} else {
 			/* Failed to allocate key buffer */
-			rpc_status = TS_RPC_ERROR_RESOURCE_FAILURE;
+			rpc_status = RPC_ERROR_RESOURCE_FAILURE;
 		}
 	}
 
 	return rpc_status;
 }
 
-static rpc_status_t export_public_key_handler(void *context, struct call_req* req)
+static rpc_status_t export_public_key_handler(void *context, struct rpc_request *req)
 {
-	rpc_status_t rpc_status = TS_RPC_ERROR_SERIALIZATION_NOT_SUPPORTED;
-	struct call_param_buf *req_buf = call_req_get_req_buf(req);
+	rpc_status_t rpc_status = RPC_ERROR_INTERNAL;
+	struct rpc_buffer *req_buf = &req->request;
 	const struct crypto_provider_serializer *serializer = get_crypto_serializer(context, req);
 
 	psa_key_id_t id;
@@ -199,85 +191,79 @@
 	if (serializer)
 		rpc_status = serializer->deserialize_export_public_key_req(req_buf, &id);
 
-	if (rpc_status == TS_RPC_CALL_ACCEPTED) {
-
+	if (rpc_status == RPC_SUCCESS) {
 		size_t max_export_size = PSA_EXPORT_PUBLIC_KEY_MAX_SIZE;
 		uint8_t *key_buffer = malloc(max_export_size);
 
 		if (key_buffer) {
-
 			size_t export_size;
-			psa_status_t psa_status = psa_export_public_key(id, key_buffer,
-				max_export_size, &export_size);
+			psa_status_t psa_status = psa_export_public_key(
+				id, key_buffer, max_export_size, &export_size);
 
 			if (psa_status == PSA_SUCCESS) {
+				struct rpc_buffer *resp_buf = &req->response;
 
-				struct call_param_buf *resp_buf = call_req_get_resp_buf(req);
-				rpc_status = serializer->serialize_export_public_key_resp(resp_buf,
-					key_buffer, export_size);
+				rpc_status = serializer->serialize_export_public_key_resp(
+					resp_buf, key_buffer, export_size);
 			}
 
 			free(key_buffer);
-			call_req_set_opstatus(req, psa_status);
-		}
-		else {
+			req->service_status = psa_status;
+		} else {
 			/* Failed to allocate key buffer */
-			rpc_status = TS_RPC_ERROR_RESOURCE_FAILURE;
+			rpc_status = RPC_ERROR_RESOURCE_FAILURE;
 		}
 	}
 
 	return rpc_status;
 }
 
-static rpc_status_t import_key_handler(void *context, struct call_req* req)
+static rpc_status_t import_key_handler(void *context, struct rpc_request *req)
 {
-	rpc_status_t rpc_status = TS_RPC_ERROR_SERIALIZATION_NOT_SUPPORTED;
-	struct call_param_buf *req_buf = call_req_get_req_buf(req);
+	rpc_status_t rpc_status = RPC_ERROR_INTERNAL;
+	struct rpc_buffer *req_buf = &req->request;
 	const struct crypto_provider_serializer *serializer = get_crypto_serializer(context, req);
 
 	if (serializer) {
-
 		size_t key_data_len = serializer->max_deserialised_parameter_size(req_buf);
 		uint8_t *key_buffer = malloc(key_data_len);
 
 		if (key_buffer) {
-
 			psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
-			rpc_status = serializer->deserialize_import_key_req(req_buf, &attributes,
-				key_buffer, &key_data_len);
+			rpc_status = serializer->deserialize_import_key_req(
+				req_buf, &attributes, key_buffer, &key_data_len);
 
-			if (rpc_status == TS_RPC_CALL_ACCEPTED) {
-
+			if (rpc_status == RPC_SUCCESS) {
 				psa_status_t psa_status;
 				psa_key_id_t id;
 
-				psa_status = psa_import_key(&attributes, key_buffer, key_data_len, &id);
+				psa_status =
+					psa_import_key(&attributes, key_buffer, key_data_len, &id);
 
 				if (psa_status == PSA_SUCCESS) {
+					struct rpc_buffer *resp_buf = &req->response;
 
-					struct call_param_buf *resp_buf = call_req_get_resp_buf(req);
-					rpc_status = serializer->serialize_import_key_resp(resp_buf, id);
+					rpc_status =
+						serializer->serialize_import_key_resp(resp_buf, id);
 				}
 
-				call_req_set_opstatus(req, psa_status);
+				req->service_status = psa_status;
 			}
 
 			psa_reset_key_attributes(&attributes);
 			free(key_buffer);
-		}
-		else {
-
-			rpc_status = TS_RPC_ERROR_RESOURCE_FAILURE;
+		} else {
+			rpc_status = RPC_ERROR_RESOURCE_FAILURE;
 		}
 	}
 
 	return rpc_status;
 }
 
-static rpc_status_t asymmetric_sign_handler(void *context, struct call_req* req)
+static rpc_status_t asymmetric_sign_handler(void *context, struct rpc_request *req)
 {
-	rpc_status_t rpc_status = TS_RPC_ERROR_SERIALIZATION_NOT_SUPPORTED;
-	struct call_param_buf *req_buf = call_req_get_req_buf(req);
+	rpc_status_t rpc_status = RPC_ERROR_INTERNAL;
+	struct rpc_buffer *req_buf = &req->request;
 	const struct crypto_provider_serializer *serializer = get_crypto_serializer(context, req);
 
 	psa_key_id_t id;
@@ -286,36 +272,37 @@
 	uint8_t hash_buffer[PSA_HASH_MAX_SIZE];
 
 	if (serializer)
-		rpc_status = serializer->deserialize_asymmetric_sign_req(req_buf, &id, &alg, hash_buffer, &hash_len);
+		rpc_status = serializer->deserialize_asymmetric_sign_req(req_buf, &id, &alg,
+									 hash_buffer, &hash_len);
 
-	if (rpc_status == TS_RPC_CALL_ACCEPTED) {
-
+	if (rpc_status == RPC_SUCCESS) {
 		psa_status_t psa_status;
 		size_t sig_len;
 		uint8_t sig_buffer[PSA_SIGNATURE_MAX_SIZE];
 
-		psa_status = (call_req_get_opcode(req) == TS_CRYPTO_OPCODE_SIGN_HASH) ?
-			psa_sign_hash(id, alg, hash_buffer, hash_len,
-				sig_buffer, sizeof(sig_buffer), &sig_len) :
-			psa_sign_message(id, alg, hash_buffer, hash_len,
-				sig_buffer, sizeof(sig_buffer), &sig_len);
+		psa_status = (req->opcode == TS_CRYPTO_OPCODE_SIGN_HASH) ?
+				     psa_sign_hash(id, alg, hash_buffer, hash_len, sig_buffer,
+						   sizeof(sig_buffer), &sig_len) :
+				     psa_sign_message(id, alg, hash_buffer, hash_len, sig_buffer,
+						      sizeof(sig_buffer), &sig_len);
 
 		if (psa_status == PSA_SUCCESS) {
+			struct rpc_buffer *resp_buf = &req->response;
 
-			struct call_param_buf *resp_buf = call_req_get_resp_buf(req);
-			rpc_status = serializer->serialize_asymmetric_sign_resp(resp_buf, sig_buffer, sig_len);
+			rpc_status = serializer->serialize_asymmetric_sign_resp(
+				resp_buf, sig_buffer, sig_len);
 		}
 
-		call_req_set_opstatus(req, psa_status);
+		req->service_status = psa_status;
 	}
 
 	return rpc_status;
 }
 
-static rpc_status_t asymmetric_verify_handler(void *context, struct call_req* req)
+static rpc_status_t asymmetric_verify_handler(void *context, struct rpc_request *req)
 {
-	rpc_status_t rpc_status = TS_RPC_ERROR_SERIALIZATION_NOT_SUPPORTED;
-	struct call_param_buf *req_buf = call_req_get_req_buf(req);
+	rpc_status_t rpc_status = RPC_ERROR_INTERNAL;
+	struct rpc_buffer *req_buf = &req->request;
 	const struct crypto_provider_serializer *serializer = get_crypto_serializer(context, req);
 
 	psa_key_id_t id;
@@ -326,36 +313,31 @@
 	uint8_t sig_buffer[PSA_SIGNATURE_MAX_SIZE];
 
 	if (serializer)
-		rpc_status = serializer->deserialize_asymmetric_verify_req(req_buf, &id, &alg,
-											hash_buffer, &hash_len,
-											sig_buffer, &sig_len);
+		rpc_status = serializer->deserialize_asymmetric_verify_req(
+			req_buf, &id, &alg, hash_buffer, &hash_len, sig_buffer, &sig_len);
 
-	if (rpc_status == TS_RPC_CALL_ACCEPTED) {
-
+	if (rpc_status == RPC_SUCCESS) {
 		psa_status_t psa_status;
 
-		psa_status = (call_req_get_opcode(req) == TS_CRYPTO_OPCODE_VERIFY_HASH) ?
-			psa_verify_hash(id, alg,
-				hash_buffer, hash_len,
-				sig_buffer, sig_len) :
-			psa_verify_message(id, alg,
-				hash_buffer, hash_len,
-				sig_buffer, sig_len);
+		psa_status = (req->opcode == TS_CRYPTO_OPCODE_VERIFY_HASH) ?
+				     psa_verify_hash(id, alg, hash_buffer, hash_len, sig_buffer,
+						     sig_len) :
+				     psa_verify_message(id, alg, hash_buffer, hash_len, sig_buffer,
+							sig_len);
 
-		call_req_set_opstatus(req, psa_status);
+		req->service_status = psa_status;
 	}
 
 	return rpc_status;
 }
 
-static rpc_status_t asymmetric_decrypt_handler(void *context, struct call_req* req)
+static rpc_status_t asymmetric_decrypt_handler(void *context, struct rpc_request *req)
 {
-	rpc_status_t rpc_status = TS_RPC_ERROR_SERIALIZATION_NOT_SUPPORTED;
-	struct call_param_buf *req_buf = call_req_get_req_buf(req);
+	rpc_status_t rpc_status = RPC_ERROR_INTERNAL;
+	struct rpc_buffer *req_buf = &req->request;
 	const struct crypto_provider_serializer *serializer = get_crypto_serializer(context, req);
 
 	if (serializer) {
-
 		size_t max_param_size = serializer->max_deserialised_parameter_size(req_buf);
 
 		psa_key_id_t id;
@@ -366,61 +348,54 @@
 		uint8_t *salt_buffer = malloc(salt_len);
 
 		if (ciphertext_buffer && salt_buffer) {
+			rpc_status = serializer->deserialize_asymmetric_decrypt_req(
+				req_buf, &id, &alg, ciphertext_buffer, &ciphertext_len, salt_buffer,
+				&salt_len);
 
-			rpc_status = serializer->deserialize_asymmetric_decrypt_req(req_buf,
-													&id, &alg,
-													ciphertext_buffer, &ciphertext_len,
-													salt_buffer, &salt_len);
-
-			if (rpc_status == TS_RPC_CALL_ACCEPTED) {
-
+			if (rpc_status == RPC_SUCCESS) {
 				psa_status_t psa_status;
 				psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
 
 				psa_status = psa_get_key_attributes(id, &attributes);
 
 				if (psa_status == PSA_SUCCESS) {
-
-					size_t max_decrypt_size = PSA_ASYMMETRIC_DECRYPT_OUTPUT_SIZE(
-						psa_get_key_type(&attributes),
-						psa_get_key_bits(&attributes),
-						alg);
+					size_t max_decrypt_size =
+						PSA_ASYMMETRIC_DECRYPT_OUTPUT_SIZE(
+							psa_get_key_type(&attributes),
+							psa_get_key_bits(&attributes), alg);
 
 					size_t plaintext_len;
 					uint8_t *plaintext_buffer = malloc(max_decrypt_size);
 
 					if (plaintext_buffer) {
-
 						/* Salt is an optional parameter */
 						uint8_t *salt = (salt_len) ? salt_buffer : NULL;
 
-						psa_status = psa_asymmetric_decrypt(id, alg,
-									ciphertext_buffer, ciphertext_len,
-									salt, salt_len,
-									plaintext_buffer, max_decrypt_size, &plaintext_len);
+						psa_status = psa_asymmetric_decrypt(
+							id, alg, ciphertext_buffer, ciphertext_len,
+							salt, salt_len, plaintext_buffer,
+							max_decrypt_size, &plaintext_len);
 
 						if (psa_status == PSA_SUCCESS) {
-
-							struct call_param_buf *resp_buf = call_req_get_resp_buf(req);
-							rpc_status = serializer->serialize_asymmetric_decrypt_resp(resp_buf,
-																plaintext_buffer, plaintext_len);
+							struct rpc_buffer *resp_buf =
+								&req->response;
+							rpc_status = serializer->serialize_asymmetric_decrypt_resp(
+								resp_buf, plaintext_buffer, plaintext_len);
 						}
 
 						free(plaintext_buffer);
-					}
-					else {
+					} else {
 						/* Failed to allocate ouptput buffer */
-						rpc_status = TS_RPC_ERROR_RESOURCE_FAILURE;
+						rpc_status = RPC_ERROR_RESOURCE_FAILURE;
 					}
 				}
 
-				call_req_set_opstatus(req, psa_status);
+				req->service_status = psa_status;
 				psa_reset_key_attributes(&attributes);
 			}
-		}
-		else {
+		} else {
 			/* Failed to allocate buffers */
-			rpc_status = TS_RPC_ERROR_RESOURCE_FAILURE;
+			rpc_status = RPC_ERROR_RESOURCE_FAILURE;
 		}
 
 		free(ciphertext_buffer);
@@ -430,14 +405,13 @@
 	return rpc_status;
 }
 
-static rpc_status_t asymmetric_encrypt_handler(void *context, struct call_req* req)
+static rpc_status_t asymmetric_encrypt_handler(void *context, struct rpc_request *req)
 {
-	rpc_status_t rpc_status = TS_RPC_ERROR_SERIALIZATION_NOT_SUPPORTED;
-	struct call_param_buf *req_buf = call_req_get_req_buf(req);
+	rpc_status_t rpc_status = RPC_ERROR_INTERNAL;
+	struct rpc_buffer *req_buf = &req->request;
 	const struct crypto_provider_serializer *serializer = get_crypto_serializer(context, req);
 
 	if (serializer) {
-
 		size_t max_param_size = serializer->max_deserialised_parameter_size(req_buf);
 
 		psa_key_id_t id;
@@ -448,61 +422,55 @@
 		uint8_t *salt_buffer = malloc(salt_len);
 
 		if (plaintext_buffer && salt_buffer) {
+			rpc_status = serializer->deserialize_asymmetric_encrypt_req(
+				req_buf, &id, &alg, plaintext_buffer, &plaintext_len, salt_buffer,
+				&salt_len);
 
-			rpc_status = serializer->deserialize_asymmetric_encrypt_req(req_buf,
-													&id, &alg,
-													plaintext_buffer, &plaintext_len,
-													salt_buffer, &salt_len);
-
-			if (rpc_status == TS_RPC_CALL_ACCEPTED) {
-
+			if (rpc_status == RPC_SUCCESS) {
 				psa_status_t psa_status;
 				psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
 
 				psa_status = psa_get_key_attributes(id, &attributes);
 
 				if (psa_status == PSA_SUCCESS) {
-
-					size_t max_encrypt_size = PSA_ASYMMETRIC_ENCRYPT_OUTPUT_SIZE(
-						psa_get_key_type(&attributes),
-						psa_get_key_bits(&attributes),
-						alg);
+					size_t max_encrypt_size =
+						PSA_ASYMMETRIC_ENCRYPT_OUTPUT_SIZE(
+							psa_get_key_type(&attributes),
+							psa_get_key_bits(&attributes), alg);
 
 					size_t ciphertext_len;
 					uint8_t *ciphertext_buffer = malloc(max_encrypt_size);
 
 					if (ciphertext_buffer) {
-
 						/* Salt is an optional parameter */
 						uint8_t *salt = (salt_len) ? salt_buffer : NULL;
 
-						psa_status = psa_asymmetric_encrypt(id, alg,
-									plaintext_buffer, plaintext_len,
-									salt, salt_len,
-									ciphertext_buffer, max_encrypt_size, &ciphertext_len);
+						psa_status = psa_asymmetric_encrypt(
+							id, alg, plaintext_buffer, plaintext_len,
+							salt, salt_len, ciphertext_buffer,
+							max_encrypt_size, &ciphertext_len);
 
 						if (psa_status == PSA_SUCCESS) {
+							struct rpc_buffer *resp_buf =
+								&req->response;
 
-							struct call_param_buf *resp_buf = call_req_get_resp_buf(req);
-							rpc_status = serializer->serialize_asymmetric_encrypt_resp(resp_buf,
-																ciphertext_buffer, ciphertext_len);
+							rpc_status = serializer->serialize_asymmetric_encrypt_resp(
+								resp_buf, ciphertext_buffer, ciphertext_len);
 						}
 
 						free(ciphertext_buffer);
-					}
-					else {
+					} else {
 						/* Failed to allocate ouptput buffer */
-						rpc_status = TS_RPC_ERROR_RESOURCE_FAILURE;
+						rpc_status = RPC_ERROR_RESOURCE_FAILURE;
 					}
 				}
 
-				call_req_set_opstatus(req, psa_status);
+				req->service_status = psa_status;
 				psa_reset_key_attributes(&attributes);
 			}
-		}
-		else {
+		} else {
 			/* Failed to allocate buffers */
-			rpc_status = TS_RPC_ERROR_RESOURCE_FAILURE;
+			rpc_status = RPC_ERROR_RESOURCE_FAILURE;
 		}
 
 		free(plaintext_buffer);
@@ -512,10 +480,10 @@
 	return rpc_status;
 }
 
-static rpc_status_t generate_random_handler(void *context, struct call_req* req)
+static rpc_status_t generate_random_handler(void *context, struct rpc_request *req)
 {
-	rpc_status_t rpc_status = TS_RPC_ERROR_SERIALIZATION_NOT_SUPPORTED;
-	struct call_param_buf *req_buf = call_req_get_req_buf(req);
+	rpc_status_t rpc_status = RPC_ERROR_INTERNAL;
+	struct rpc_buffer *req_buf = &req->request;
 	const struct crypto_provider_serializer *serializer = get_crypto_serializer(context, req);
 
 	size_t output_size;
@@ -523,59 +491,55 @@
 	if (serializer)
 		rpc_status = serializer->deserialize_generate_random_req(req_buf, &output_size);
 
-	if (rpc_status == TS_RPC_CALL_ACCEPTED) {
-
+	if (rpc_status == RPC_SUCCESS) {
 		psa_status_t psa_status;
 		uint8_t *output_buffer = malloc(output_size);
 
 		if (output_buffer) {
-
 			psa_status = psa_generate_random(output_buffer, output_size);
 
 			if (psa_status == PSA_SUCCESS) {
+				struct rpc_buffer *resp_buf = &req->response;
 
-				struct call_param_buf *resp_buf = call_req_get_resp_buf(req);
-				rpc_status = serializer->serialize_generate_random_resp(resp_buf,
-													output_buffer, output_size);
+				rpc_status = serializer->serialize_generate_random_resp(
+					resp_buf, output_buffer, output_size);
 			}
 
-			call_req_set_opstatus(req, psa_status);
+			req->service_status = psa_status;
 			free(output_buffer);
-		}
-		else {
+		} else {
 			/* Failed to allocate output buffer */
-			rpc_status = TS_RPC_ERROR_RESOURCE_FAILURE;
+			rpc_status = RPC_ERROR_RESOURCE_FAILURE;
 		}
 	}
 
 	return rpc_status;
 }
 
-static rpc_status_t copy_key_handler(void *context, struct call_req* req)
+static rpc_status_t copy_key_handler(void *context, struct rpc_request *req)
 {
-	rpc_status_t rpc_status = TS_RPC_ERROR_SERIALIZATION_NOT_SUPPORTED;
-	struct call_param_buf *req_buf = call_req_get_req_buf(req);
+	rpc_status_t rpc_status = RPC_ERROR_INTERNAL;
+	struct rpc_buffer *req_buf = &req->request;
 	const struct crypto_provider_serializer *serializer = get_crypto_serializer(context, req);
 
 	psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
 	psa_key_id_t source_key_id;
 
 	if (serializer)
-		rpc_status = serializer->deserialize_copy_key_req(req_buf, &attributes, &source_key_id);
+		rpc_status =
+			serializer->deserialize_copy_key_req(req_buf, &attributes, &source_key_id);
 
-	if (rpc_status == TS_RPC_CALL_ACCEPTED) {
-
+	if (rpc_status == RPC_SUCCESS) {
 		psa_key_id_t target_key_id;
 
 		psa_status_t psa_status = psa_copy_key(source_key_id, &attributes, &target_key_id);
 
 		if (psa_status == PSA_SUCCESS) {
-
-			struct call_param_buf *resp_buf = call_req_get_resp_buf(req);
+			struct rpc_buffer *resp_buf = &req->response;
 			rpc_status = serializer->serialize_copy_key_resp(resp_buf, target_key_id);
 		}
 
-		call_req_set_opstatus(req, psa_status);
+		req->service_status = psa_status;
 	}
 
 	psa_reset_key_attributes(&attributes);
@@ -583,10 +547,10 @@
 	return rpc_status;
 }
 
-static rpc_status_t purge_key_handler(void *context, struct call_req* req)
+static rpc_status_t purge_key_handler(void *context, struct rpc_request *req)
 {
-	rpc_status_t rpc_status = TS_RPC_ERROR_SERIALIZATION_NOT_SUPPORTED;
-	struct call_param_buf *req_buf = call_req_get_req_buf(req);
+	rpc_status_t rpc_status = RPC_ERROR_INTERNAL;
+	struct rpc_buffer *req_buf = &req->request;
 	const struct crypto_provider_serializer *serializer = get_crypto_serializer(context, req);
 
 	psa_key_id_t id;
@@ -594,19 +558,18 @@
 	if (serializer)
 		rpc_status = serializer->deserialize_purge_key_req(req_buf, &id);
 
-	if (rpc_status == TS_RPC_CALL_ACCEPTED) {
-
+	if (rpc_status == RPC_SUCCESS) {
 		psa_status_t psa_status = psa_purge_key(id);
-		call_req_set_opstatus(req, psa_status);
+		req->service_status = psa_status;
 	}
 
 	return rpc_status;
 }
 
-static rpc_status_t get_key_attributes_handler(void *context, struct call_req* req)
+static rpc_status_t get_key_attributes_handler(void *context, struct rpc_request *req)
 {
-	rpc_status_t rpc_status = TS_RPC_ERROR_SERIALIZATION_NOT_SUPPORTED;
-	struct call_param_buf *req_buf = call_req_get_req_buf(req);
+	rpc_status_t rpc_status = RPC_ERROR_INTERNAL;
+	struct rpc_buffer *req_buf = &req->request;
 	const struct crypto_provider_serializer *serializer = get_crypto_serializer(context, req);
 
 	psa_key_id_t id;
@@ -614,20 +577,20 @@
 	if (serializer)
 		rpc_status = serializer->deserialize_get_key_attributes_req(req_buf, &id);
 
-	if (rpc_status == TS_RPC_CALL_ACCEPTED) {
-
+	if (rpc_status == RPC_SUCCESS) {
 		psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
 
 		psa_status_t psa_status = psa_get_key_attributes(id, &attributes);
 
 		if (psa_status == PSA_SUCCESS) {
+			struct rpc_buffer *resp_buf = &req->response;
 
-			struct call_param_buf *resp_buf = call_req_get_resp_buf(req);
-			rpc_status = serializer->serialize_get_key_attributes_resp(resp_buf, &attributes);
+			rpc_status = serializer->serialize_get_key_attributes_resp(resp_buf,
+										   &attributes);
 		}
 
 		psa_reset_key_attributes(&attributes);
-		call_req_set_opstatus(req, psa_status);
+		req->service_status = psa_status;
 	}
 
 	return rpc_status;
diff --git a/components/service/crypto/provider/crypto_provider.h b/components/service/crypto/provider/crypto_provider.h
index ce33c23..1720264 100644
--- a/components/service/crypto/provider/crypto_provider.h
+++ b/components/service/crypto/provider/crypto_provider.h
@@ -7,10 +7,9 @@
 #ifndef CRYPTO_PROVIDER_H
 #define CRYPTO_PROVIDER_H
 
-#include <rpc/common/endpoint/rpc_interface.h>
+#include "components/rpc/common/endpoint/rpc_service_interface.h"
 #include <service/common/provider/service_provider.h>
 #include <service/crypto/provider/serializer/crypto_provider_serializer.h>
-#include <service/discovery/provider/discovery_provider.h>
 #include <protocols/rpc/common/packed-c/encoding.h>
 
 #ifdef __cplusplus
@@ -20,8 +19,7 @@
 struct crypto_provider
 {
 	struct service_provider base_provider;
-	const struct crypto_provider_serializer *serializers[TS_RPC_ENCODING_LIMIT];
-	struct discovery_provider discovery_provider;
+	const struct crypto_provider_serializer *serializer;
 };
 
 /*
@@ -29,7 +27,8 @@
  * backend that realizes the PSA Crypto API should have been initialized
  * prior to initializing the crypto provider.
  */
-struct rpc_interface *crypto_provider_init(struct crypto_provider *context);
+struct rpc_service_interface *crypto_provider_init(struct crypto_provider *context,
+	unsigned int encoding, const struct crypto_provider_serializer *serializer);
 
 /*
  * When operation of the provider is no longer required, this function
@@ -44,7 +43,6 @@
  * for compatibility with different types of client.
  */
 void crypto_provider_register_serializer(struct crypto_provider *context,
-	unsigned int encoding,
 	const struct crypto_provider_serializer *serializer);
 
 /*
diff --git a/components/service/crypto/provider/crypto_uuid.h b/components/service/crypto/provider/crypto_uuid.h
new file mode 100644
index 0000000..ec35f24
--- /dev/null
+++ b/components/service/crypto/provider/crypto_uuid.h
@@ -0,0 +1,24 @@
+/*
+ * Copyright (c) 2023, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef CRYPTO_UUID_H
+#define CRYPTO_UUID_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define TS_PSA_CRYPTO_SERVICE_UUID \
+{ 0xd9, 0xdf, 0x52, 0xd5, 0x16, 0xa2, 0x4b, 0xb2, 0x9a, 0xa4, 0xd2, 0x6d, 0x3b, 0x84, 0xe8, 0xc0 }
+
+#define TS_PSA_CRYPTO_PROTOBUF_SERVICE_UUID \
+{ 0x6b, 0xa9, 0xde, 0x75, 0x39, 0x3e, 0x4c, 0x7f, 0xaa, 0xbb, 0x7f, 0x71, 0xcc, 0x6b, 0x14, 0x2e }
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* CRYPTO_UUID_H */
diff --git a/components/service/crypto/provider/extension/aead/aead_provider.c b/components/service/crypto/provider/extension/aead/aead_provider.c
index 14a2543..696474e 100644
--- a/components/service/crypto/provider/extension/aead/aead_provider.c
+++ b/components/service/crypto/provider/extension/aead/aead_provider.c
@@ -11,15 +11,15 @@
 #include <psa/crypto.h>
 
 /* Service request handlers */
-static rpc_status_t aead_setup_handler(void *context, struct call_req *req);
-static rpc_status_t aead_generate_nonce_handler(void *context, struct call_req *req);
-static rpc_status_t aead_set_nonce_handler(void *context, struct call_req *req);
-static rpc_status_t aead_set_lengths_handler(void *context, struct call_req *req);
-static rpc_status_t aead_update_ad_handler(void *context, struct call_req *req);
-static rpc_status_t aead_update_handler(void *context, struct call_req *req);
-static rpc_status_t aead_finish_handler(void *context, struct call_req *req);
-static rpc_status_t aead_verify_handler(void *context, struct call_req *req);
-static rpc_status_t aead_abort_handler(void *context, struct call_req *req);
+static rpc_status_t aead_setup_handler(void *context, struct rpc_request *req);
+static rpc_status_t aead_generate_nonce_handler(void *context, struct rpc_request *req);
+static rpc_status_t aead_set_nonce_handler(void *context, struct rpc_request *req);
+static rpc_status_t aead_set_lengths_handler(void *context, struct rpc_request *req);
+static rpc_status_t aead_update_ad_handler(void *context, struct rpc_request *req);
+static rpc_status_t aead_update_handler(void *context, struct rpc_request *req);
+static rpc_status_t aead_finish_handler(void *context, struct rpc_request *req);
+static rpc_status_t aead_verify_handler(void *context, struct rpc_request *req);
+static rpc_status_t aead_abort_handler(void *context, struct rpc_request *req);
 
 /* Handler mapping table for service */
 static const struct service_handler handler_table[] = {
@@ -37,12 +37,14 @@
 
 void aead_provider_init(struct aead_provider *context)
 {
+	const struct rpc_uuid nil_uuid = { 0 };
+
 	crypto_context_pool_init(&context->context_pool);
 
 	for (size_t encoding = 0; encoding < TS_RPC_ENCODING_LIMIT; ++encoding)
 		context->serializers[encoding] = NULL;
 
-	service_provider_init(&context->base_provider, context,
+	service_provider_init(&context->base_provider, context, &nil_uuid,
 		handler_table, sizeof(handler_table)/sizeof(struct service_handler));
 }
 
@@ -59,21 +61,18 @@
 }
 
 static const struct aead_provider_serializer* get_serializer(void *context,
-	const struct call_req *req)
+	const struct rpc_request *req)
 {
 	struct aead_provider *this_instance = (struct aead_provider*)context;
-	const struct aead_provider_serializer* serializer = NULL;
-	unsigned int encoding = call_req_get_encoding(req);
+	unsigned int encoding = 0; /* No other encodings supported */
 
-	if (encoding < TS_RPC_ENCODING_LIMIT) serializer = this_instance->serializers[encoding];
-
-	return serializer;
+	return this_instance->serializers[encoding];
 }
 
-static rpc_status_t aead_setup_handler(void *context, struct call_req *req)
+static rpc_status_t aead_setup_handler(void *context, struct rpc_request *req)
 {
-	rpc_status_t rpc_status = TS_RPC_ERROR_SERIALIZATION_NOT_SUPPORTED;
-	struct call_param_buf *req_buf = call_req_get_req_buf(req);
+	rpc_status_t rpc_status = RPC_ERROR_INTERNAL;
+	struct rpc_buffer *req_buf = &req->request;
 	const struct aead_provider_serializer *serializer = get_serializer(context, req);
 	struct aead_provider *this_instance = (struct aead_provider*)context;
 
@@ -83,13 +82,13 @@
 	if (serializer)
 		rpc_status = serializer->deserialize_aead_setup_req(req_buf, &key_id, &alg);
 
-	if (rpc_status == TS_RPC_CALL_ACCEPTED) {
+	if (rpc_status == RPC_SUCCESS) {
 
 		uint32_t op_handle;
 
 		struct crypto_context *crypto_context =
 			crypto_context_pool_alloc(&this_instance->context_pool,
-				CRYPTO_CONTEXT_OP_ID_AEAD, call_req_get_caller_id(req),
+				CRYPTO_CONTEXT_OP_ID_AEAD, req->source_id,
 				&op_handle);
 
 		if (crypto_context) {
@@ -98,36 +97,34 @@
 
 			crypto_context->op.aead = psa_aead_operation_init();
 
-			psa_status = (call_req_get_opcode(req) == TS_CRYPTO_OPCODE_AEAD_ENCRYPT_SETUP) ?
+			psa_status = (req->opcode == TS_CRYPTO_OPCODE_AEAD_ENCRYPT_SETUP) ?
 				psa_aead_encrypt_setup(&crypto_context->op.aead, key_id, alg) :
 				psa_aead_decrypt_setup(&crypto_context->op.aead, key_id, alg);
 
 			if (psa_status == PSA_SUCCESS) {
 
-				struct call_param_buf *resp_buf = call_req_get_resp_buf(req);
+				struct rpc_buffer *resp_buf = &req->response;
 				rpc_status = serializer->serialize_aead_setup_resp(resp_buf, op_handle);
 			}
 
-			if ((psa_status != PSA_SUCCESS) || (rpc_status != TS_RPC_CALL_ACCEPTED)) {
-
+			if ((psa_status != PSA_SUCCESS) || (rpc_status != RPC_SUCCESS))
 				crypto_context_pool_free(&this_instance->context_pool, crypto_context);
-			}
 
-			call_req_set_opstatus(req, psa_status);
+			req->service_status = psa_status;
 		}
 		else {
 			/* Failed to allocate crypto context for transaction */
-			rpc_status = TS_RPC_ERROR_RESOURCE_FAILURE;
+			rpc_status = RPC_ERROR_RESOURCE_FAILURE;
 		}
 	}
 
 	return rpc_status;
 }
 
-static rpc_status_t aead_generate_nonce_handler(void *context, struct call_req *req)
+static rpc_status_t aead_generate_nonce_handler(void *context, struct rpc_request *req)
 {
-	rpc_status_t rpc_status = TS_RPC_ERROR_SERIALIZATION_NOT_SUPPORTED;
-	struct call_param_buf *req_buf = call_req_get_req_buf(req);
+	rpc_status_t rpc_status = RPC_ERROR_INTERNAL;
+	struct rpc_buffer *req_buf = &req->request;
 	const struct aead_provider_serializer *serializer = get_serializer(context, req);
 	struct aead_provider *this_instance = (struct aead_provider*)context;
 
@@ -136,13 +133,13 @@
 	if (serializer)
 		rpc_status = serializer->deserialize_aead_generate_nonce_req(req_buf, &op_handle);
 
-	if (rpc_status == TS_RPC_CALL_ACCEPTED) {
+	if (rpc_status == RPC_SUCCESS) {
 
 		psa_status_t psa_status = PSA_ERROR_BAD_STATE;
 
 		struct crypto_context *crypto_context =
 			crypto_context_pool_find(&this_instance->context_pool,
-				CRYPTO_CONTEXT_OP_ID_AEAD, call_req_get_caller_id(req),
+				CRYPTO_CONTEXT_OP_ID_AEAD, req->source_id,
 				op_handle);
 
 		if (crypto_context) {
@@ -155,22 +152,22 @@
 
 			if (psa_status == PSA_SUCCESS) {
 
-				struct call_param_buf *resp_buf = call_req_get_resp_buf(req);
+				struct rpc_buffer *resp_buf = &req->response;
 				rpc_status = serializer->serialize_aead_generate_nonce_resp(resp_buf,
 					nonce, nonce_len);
 			}
 		}
 
-		call_req_set_opstatus(req, psa_status);
+		req->service_status = psa_status;
 	}
 
 	return rpc_status;
 }
 
-static rpc_status_t aead_set_nonce_handler(void *context, struct call_req *req)
+static rpc_status_t aead_set_nonce_handler(void *context, struct rpc_request *req)
 {
-	rpc_status_t rpc_status = TS_RPC_ERROR_SERIALIZATION_NOT_SUPPORTED;
-	struct call_param_buf *req_buf = call_req_get_req_buf(req);
+	rpc_status_t rpc_status = RPC_ERROR_INTERNAL;
+	struct rpc_buffer *req_buf = &req->request;
 	const struct aead_provider_serializer *serializer = get_serializer(context, req);
 	struct aead_provider *this_instance = (struct aead_provider*)context;
 
@@ -182,13 +179,13 @@
 		rpc_status = serializer->deserialize_aead_set_nonce_req(req_buf, &op_handle,
 			&nonce, &nonce_len);
 
-	if (rpc_status == TS_RPC_CALL_ACCEPTED) {
+	if (rpc_status == RPC_SUCCESS) {
 
 		psa_status_t psa_status = PSA_ERROR_BAD_STATE;
 
 		struct crypto_context *crypto_context =
 			crypto_context_pool_find(&this_instance->context_pool,
-				CRYPTO_CONTEXT_OP_ID_AEAD, call_req_get_caller_id(req),
+				CRYPTO_CONTEXT_OP_ID_AEAD, req->source_id,
 				op_handle);
 
 		if (crypto_context) {
@@ -196,16 +193,16 @@
 			psa_status = psa_aead_set_nonce(&crypto_context->op.aead, nonce, nonce_len);
 		}
 
-		call_req_set_opstatus(req, psa_status);
+		req->service_status = psa_status;
 	}
 
 	return rpc_status;
 }
 
-static rpc_status_t aead_set_lengths_handler(void *context, struct call_req *req)
+static rpc_status_t aead_set_lengths_handler(void *context, struct rpc_request *req)
 {
-	rpc_status_t rpc_status = TS_RPC_ERROR_SERIALIZATION_NOT_SUPPORTED;
-	struct call_param_buf *req_buf = call_req_get_req_buf(req);
+	rpc_status_t rpc_status = RPC_ERROR_INTERNAL;
+	struct rpc_buffer *req_buf = &req->request;
 	const struct aead_provider_serializer *serializer = get_serializer(context, req);
 	struct aead_provider *this_instance = (struct aead_provider*)context;
 
@@ -217,13 +214,13 @@
 		rpc_status = serializer->deserialize_aead_set_lengths_req(req_buf, &op_handle,
 			&ad_length, &plaintext_length);
 
-	if (rpc_status == TS_RPC_CALL_ACCEPTED) {
+	if (rpc_status == RPC_SUCCESS) {
 
 		psa_status_t psa_status = PSA_ERROR_BAD_STATE;
 
 		struct crypto_context *crypto_context =
 			crypto_context_pool_find(&this_instance->context_pool,
-				CRYPTO_CONTEXT_OP_ID_AEAD, call_req_get_caller_id(req),
+				CRYPTO_CONTEXT_OP_ID_AEAD, req->source_id,
 				op_handle);
 
 		if (crypto_context) {
@@ -232,16 +229,16 @@
 				ad_length, plaintext_length);
 		}
 
-		call_req_set_opstatus(req, psa_status);
+		req->service_status = psa_status;
 	}
 
 	return rpc_status;
 }
 
-static rpc_status_t aead_update_ad_handler(void *context, struct call_req *req)
+static rpc_status_t aead_update_ad_handler(void *context, struct rpc_request *req)
 {
-	rpc_status_t rpc_status = TS_RPC_ERROR_SERIALIZATION_NOT_SUPPORTED;
-	struct call_param_buf *req_buf = call_req_get_req_buf(req);
+	rpc_status_t rpc_status = RPC_ERROR_INTERNAL;
+	struct rpc_buffer *req_buf = &req->request;
 	const struct aead_provider_serializer *serializer = get_serializer(context, req);
 	struct aead_provider *this_instance = (struct aead_provider*)context;
 
@@ -253,13 +250,13 @@
 		rpc_status = serializer->deserialize_aead_update_ad_req(req_buf, &op_handle,
 			&input, &input_len);
 
-	if (rpc_status == TS_RPC_CALL_ACCEPTED) {
+	if (rpc_status == RPC_SUCCESS) {
 
 		psa_status_t psa_status = PSA_ERROR_BAD_STATE;
 
 		struct crypto_context *crypto_context =
 			crypto_context_pool_find(&this_instance->context_pool,
-				CRYPTO_CONTEXT_OP_ID_AEAD, call_req_get_caller_id(req),
+				CRYPTO_CONTEXT_OP_ID_AEAD, req->source_id,
 				op_handle);
 
 		if (crypto_context) {
@@ -267,16 +264,16 @@
 			psa_status = psa_aead_update_ad(&crypto_context->op.aead, input, input_len);
 		}
 
-		call_req_set_opstatus(req, psa_status);
+		req->service_status = psa_status;
 	}
 
 	return rpc_status;
 }
 
-static rpc_status_t aead_update_handler(void *context, struct call_req *req)
+static rpc_status_t aead_update_handler(void *context, struct rpc_request *req)
 {
-	rpc_status_t rpc_status = TS_RPC_ERROR_SERIALIZATION_NOT_SUPPORTED;
-	struct call_param_buf *req_buf = call_req_get_req_buf(req);
+	rpc_status_t rpc_status = RPC_ERROR_INTERNAL;
+	struct rpc_buffer *req_buf = &req->request;
 	const struct aead_provider_serializer *serializer = get_serializer(context, req);
 	struct aead_provider *this_instance = (struct aead_provider*)context;
 
@@ -288,13 +285,13 @@
 		rpc_status = serializer->deserialize_aead_update_req(req_buf, &op_handle,
 			&input, &input_len);
 
-	if (rpc_status == TS_RPC_CALL_ACCEPTED) {
+	if (rpc_status == RPC_SUCCESS) {
 
 		psa_status_t psa_status = PSA_ERROR_BAD_STATE;
 
 		struct crypto_context *crypto_context =
 			crypto_context_pool_find(&this_instance->context_pool,
-				CRYPTO_CONTEXT_OP_ID_AEAD, call_req_get_caller_id(req),
+				CRYPTO_CONTEXT_OP_ID_AEAD, req->source_id,
 				op_handle);
 
 		if (crypto_context) {
@@ -311,7 +308,7 @@
 
 				if (psa_status == PSA_SUCCESS) {
 
-					struct call_param_buf *resp_buf = call_req_get_resp_buf(req);
+					struct rpc_buffer *resp_buf = &req->response;
 					rpc_status = serializer->serialize_aead_update_resp(resp_buf,
 						output, output_len);
 				}
@@ -324,16 +321,16 @@
 			}
 		}
 
-		call_req_set_opstatus(req, psa_status);
+		req->service_status = psa_status;
 	}
 
 	return rpc_status;
 }
 
-static rpc_status_t aead_finish_handler(void *context, struct call_req *req)
+static rpc_status_t aead_finish_handler(void *context, struct rpc_request *req)
 {
-	rpc_status_t rpc_status = TS_RPC_ERROR_SERIALIZATION_NOT_SUPPORTED;
-	struct call_param_buf *req_buf = call_req_get_req_buf(req);
+	rpc_status_t rpc_status = RPC_ERROR_INTERNAL;
+	struct rpc_buffer *req_buf = &req->request;
 	const struct aead_provider_serializer *serializer = get_serializer(context, req);
 	struct aead_provider *this_instance = (struct aead_provider*)context;
 
@@ -342,13 +339,13 @@
 	if (serializer)
 		rpc_status = serializer->deserialize_aead_finish_req(req_buf, &op_handle);
 
-	if (rpc_status == TS_RPC_CALL_ACCEPTED) {
+	if (rpc_status == RPC_SUCCESS) {
 
 		psa_status_t psa_status = PSA_ERROR_BAD_STATE;
 
 		struct crypto_context *crypto_context =
 			crypto_context_pool_find(&this_instance->context_pool,
-				CRYPTO_CONTEXT_OP_ID_AEAD, call_req_get_caller_id(req),
+				CRYPTO_CONTEXT_OP_ID_AEAD, req->source_id,
 				op_handle);
 
 		if (crypto_context) {
@@ -365,7 +362,7 @@
 
 			if (psa_status == PSA_SUCCESS) {
 
-				struct call_param_buf *resp_buf = call_req_get_resp_buf(req);
+				struct rpc_buffer *resp_buf = &req->response;
 				rpc_status = serializer->serialize_aead_finish_resp(resp_buf,
 					ciphertext, ciphertext_len,
 					tag, tag_len);
@@ -374,16 +371,16 @@
 			}
 		}
 
-		call_req_set_opstatus(req, psa_status);
+		req->service_status = psa_status;
 	}
 
 	return rpc_status;
 }
 
-static rpc_status_t aead_verify_handler(void *context, struct call_req *req)
+static rpc_status_t aead_verify_handler(void *context, struct rpc_request *req)
 {
-	rpc_status_t rpc_status = TS_RPC_ERROR_SERIALIZATION_NOT_SUPPORTED;
-	struct call_param_buf *req_buf = call_req_get_req_buf(req);
+	rpc_status_t rpc_status = RPC_ERROR_INTERNAL;
+	struct rpc_buffer *req_buf = &req->request;
 	const struct aead_provider_serializer *serializer = get_serializer(context, req);
 	struct aead_provider *this_instance = (struct aead_provider*)context;
 
@@ -395,13 +392,13 @@
 		rpc_status = serializer->deserialize_aead_verify_req(req_buf, &op_handle,
 			&tag, &tag_len);
 
-	if (rpc_status == TS_RPC_CALL_ACCEPTED) {
+	if (rpc_status == RPC_SUCCESS) {
 
 		psa_status_t psa_status = PSA_ERROR_BAD_STATE;
 
 		struct crypto_context *crypto_context =
 			crypto_context_pool_find(&this_instance->context_pool,
-				CRYPTO_CONTEXT_OP_ID_AEAD, call_req_get_caller_id(req),
+				CRYPTO_CONTEXT_OP_ID_AEAD, req->source_id,
 				op_handle);
 
 		if (crypto_context) {
@@ -415,7 +412,7 @@
 
 			if (psa_status == PSA_SUCCESS) {
 
-				struct call_param_buf *resp_buf = call_req_get_resp_buf(req);
+				struct rpc_buffer *resp_buf = &req->response;
 				rpc_status = serializer->serialize_aead_verify_resp(resp_buf,
 					plaintext, plaintext_len);
 
@@ -423,16 +420,16 @@
 			}
 		}
 
-		call_req_set_opstatus(req, psa_status);
+		req->service_status = psa_status;
 	}
 
 	return rpc_status;
 }
 
-static rpc_status_t aead_abort_handler(void *context, struct call_req *req)
+static rpc_status_t aead_abort_handler(void *context, struct rpc_request *req)
 {
-	rpc_status_t rpc_status = TS_RPC_ERROR_SERIALIZATION_NOT_SUPPORTED;
-	struct call_param_buf *req_buf = call_req_get_req_buf(req);
+	rpc_status_t rpc_status = RPC_ERROR_INTERNAL;
+	struct rpc_buffer *req_buf = &req->request;
 	const struct aead_provider_serializer *serializer = get_serializer(context, req);
 	struct aead_provider *this_instance = (struct aead_provider*)context;
 
@@ -441,7 +438,7 @@
 	if (serializer)
 		rpc_status = serializer->deserialize_aead_abort_req(req_buf, &op_handle);
 
-	if (rpc_status == TS_RPC_CALL_ACCEPTED) {
+	if (rpc_status == RPC_SUCCESS) {
 
 		/* Return success if operation is no longer active and
 		 * doesn't need aborting.
@@ -450,7 +447,7 @@
 
 		struct crypto_context *crypto_context =
 			crypto_context_pool_find(&this_instance->context_pool,
-				CRYPTO_CONTEXT_OP_ID_AEAD, call_req_get_caller_id(req),
+				CRYPTO_CONTEXT_OP_ID_AEAD, req->source_id,
 				op_handle);
 
 		if (crypto_context) {
@@ -459,7 +456,7 @@
 			crypto_context_pool_free(&this_instance->context_pool, crypto_context);
 		}
 
-		call_req_set_opstatus(req, psa_status);
+		req->service_status = psa_status;
 	}
 
 	return rpc_status;
diff --git a/components/service/crypto/provider/extension/aead/aead_provider.h b/components/service/crypto/provider/extension/aead/aead_provider.h
index 33fa7d0..b25cde8 100644
--- a/components/service/crypto/provider/extension/aead/aead_provider.h
+++ b/components/service/crypto/provider/extension/aead/aead_provider.h
@@ -7,7 +7,7 @@
 #ifndef AEAD_PROVIDER_H
 #define AEAD_PROVIDER_H
 
-#include <rpc/common/endpoint/rpc_interface.h>
+#include "components/rpc/common/endpoint/rpc_service_interface.h"
 #include <service/common/provider/service_provider.h>
 #include <service/crypto/provider/extension/aead/serializer/aead_provider_serializer.h>
 #include <service/crypto/provider/crypto_context_pool.h>
diff --git a/components/service/crypto/provider/extension/aead/serializer/aead_provider_serializer.h b/components/service/crypto/provider/extension/aead/serializer/aead_provider_serializer.h
index bb1a2a9..2bf7a01 100644
--- a/components/service/crypto/provider/extension/aead/serializer/aead_provider_serializer.h
+++ b/components/service/crypto/provider/extension/aead/serializer/aead_provider_serializer.h
@@ -10,7 +10,7 @@
 #include <stddef.h>
 #include <stdint.h>
 #include <psa/crypto.h>
-#include <rpc/common/endpoint/rpc_interface.h>
+#include "components/rpc/common/endpoint/rpc_service_interface.h"
 
 /* Provides a common interface for parameter serialization operations
  * for the aead service provider.
@@ -18,62 +18,62 @@
 struct aead_provider_serializer {
 
 	/* Operation: aead_setup */
-	rpc_status_t (*deserialize_aead_setup_req)(const struct call_param_buf *req_buf,
+	rpc_status_t (*deserialize_aead_setup_req)(const struct rpc_buffer *req_buf,
 		psa_key_id_t *id,
 		psa_algorithm_t *alg);
 
-	rpc_status_t (*serialize_aead_setup_resp)(struct call_param_buf *resp_buf,
+	rpc_status_t (*serialize_aead_setup_resp)(struct rpc_buffer *resp_buf,
 		uint32_t op_handle);
 
 	/* Operation: aead_generate_nonce */
-	rpc_status_t (*deserialize_aead_generate_nonce_req)(const struct call_param_buf *req_buf,
+	rpc_status_t (*deserialize_aead_generate_nonce_req)(const struct rpc_buffer *req_buf,
 		uint32_t *op_handle);
 
-	rpc_status_t (*serialize_aead_generate_nonce_resp)(struct call_param_buf *resp_buf,
+	rpc_status_t (*serialize_aead_generate_nonce_resp)(struct rpc_buffer *resp_buf,
 		const uint8_t *nonce, size_t nonce_len);
 
 	/* Operation: aead_set_nonce */
-	rpc_status_t (*deserialize_aead_set_nonce_req)(const struct call_param_buf *req_buf,
+	rpc_status_t (*deserialize_aead_set_nonce_req)(const struct rpc_buffer *req_buf,
 		uint32_t *op_handle,
 		const uint8_t **nonce, size_t *nonce_len);
 
 	/* Operation: aead_set_lengths */
-	rpc_status_t (*deserialize_aead_set_lengths_req)(const struct call_param_buf *req_buf,
+	rpc_status_t (*deserialize_aead_set_lengths_req)(const struct rpc_buffer *req_buf,
 		uint32_t *op_handle,
 		size_t *ad_length,
 		size_t *plaintext_length);
 
 	/* Operation: aead_update_ad */
-	rpc_status_t (*deserialize_aead_update_ad_req)(const struct call_param_buf *req_buf,
+	rpc_status_t (*deserialize_aead_update_ad_req)(const struct rpc_buffer *req_buf,
 		uint32_t *op_handle,
 		const uint8_t **input, size_t *input_len);
 
 	/* Operation: aead_update */
-	rpc_status_t (*deserialize_aead_update_req)(const struct call_param_buf *req_buf,
+	rpc_status_t (*deserialize_aead_update_req)(const struct rpc_buffer *req_buf,
 		uint32_t *op_handle,
 		const uint8_t **input, size_t *input_len);
 
-	rpc_status_t (*serialize_aead_update_resp)(struct call_param_buf *resp_buf,
+	rpc_status_t (*serialize_aead_update_resp)(struct rpc_buffer *resp_buf,
 		const uint8_t *output, size_t output_len);
 
 	/* Operation: aead_finish */
-	rpc_status_t (*deserialize_aead_finish_req)(const struct call_param_buf *req_buf,
+	rpc_status_t (*deserialize_aead_finish_req)(const struct rpc_buffer *req_buf,
 		uint32_t *op_handle);
 
-	rpc_status_t (*serialize_aead_finish_resp)(struct call_param_buf *resp_buf,
+	rpc_status_t (*serialize_aead_finish_resp)(struct rpc_buffer *resp_buf,
 		const uint8_t *aeadtext, size_t aeadtext_len,
 		const uint8_t *tag, size_t tag_len);
 
 	/* Operation: aead_verify */
-	rpc_status_t (*deserialize_aead_verify_req)(const struct call_param_buf *req_buf,
+	rpc_status_t (*deserialize_aead_verify_req)(const struct rpc_buffer *req_buf,
 		uint32_t *op_handle,
 		const uint8_t **tag, size_t *tag_len);
 
-	rpc_status_t (*serialize_aead_verify_resp)(struct call_param_buf *resp_buf,
+	rpc_status_t (*serialize_aead_verify_resp)(struct rpc_buffer *resp_buf,
 		const uint8_t *plaintext, size_t plaintext_len);
 
 	/* Operation: aead_abort */
-	rpc_status_t (*deserialize_aead_abort_req)(const struct call_param_buf *req_buf,
+	rpc_status_t (*deserialize_aead_abort_req)(const struct rpc_buffer *req_buf,
 		uint32_t *op_handle);
 };
 
diff --git a/components/service/crypto/provider/extension/aead/serializer/packed-c/packedc_aead_provider_serializer.c b/components/service/crypto/provider/extension/aead/serializer/packed-c/packedc_aead_provider_serializer.c
index 6f00b3e..738d5f2 100644
--- a/components/service/crypto/provider/extension/aead/serializer/packed-c/packedc_aead_provider_serializer.c
+++ b/components/service/crypto/provider/extension/aead/serializer/packed-c/packedc_aead_provider_serializer.c
@@ -11,29 +11,29 @@
 #include "packedc_aead_provider_serializer.h"
 
 /* Operation: aead_setup */
-static rpc_status_t deserialize_aead_setup_req(const struct call_param_buf *req_buf,
+static rpc_status_t deserialize_aead_setup_req(const struct rpc_buffer *req_buf,
 	psa_key_id_t *id,
 	psa_algorithm_t *alg)
 {
-	rpc_status_t rpc_status = TS_RPC_ERROR_INVALID_REQ_BODY;
+	rpc_status_t rpc_status = RPC_ERROR_INVALID_REQUEST_BODY;
 	struct ts_crypto_aead_setup_in recv_msg;
 	size_t expected_fixed_len = sizeof(struct ts_crypto_aead_setup_in);
 
-	if (expected_fixed_len <= req_buf->data_len) {
+	if (expected_fixed_len <= req_buf->data_length) {
 
 		memcpy(&recv_msg, req_buf->data, expected_fixed_len);
 		*id = recv_msg.key_id;
 		*alg = recv_msg.alg;
-		rpc_status = TS_RPC_CALL_ACCEPTED;
+		rpc_status = RPC_SUCCESS;
 	}
 
 	return rpc_status;
 }
 
-static rpc_status_t serialize_aead_setup_resp(struct call_param_buf *resp_buf,
+static rpc_status_t serialize_aead_setup_resp(struct rpc_buffer *resp_buf,
 	uint32_t op_handle)
 {
-	rpc_status_t rpc_status = TS_RPC_ERROR_INTERNAL;
+	rpc_status_t rpc_status = RPC_ERROR_INTERNAL;
 	struct ts_crypto_aead_setup_out resp_msg;
 	size_t fixed_len = sizeof(struct ts_crypto_aead_setup_out);
 
@@ -42,35 +42,35 @@
 	if (fixed_len <= resp_buf->size) {
 
 		memcpy(resp_buf->data, &resp_msg, fixed_len);
-		resp_buf->data_len = fixed_len;
-		rpc_status = TS_RPC_CALL_ACCEPTED;
+		resp_buf->data_length = fixed_len;
+		rpc_status = RPC_SUCCESS;
 	}
 
 	return rpc_status;
 }
 
 /* Operation: aead_generate_nonce */
-static rpc_status_t deserialize_aead_generate_nonce_req(const struct call_param_buf *req_buf,
+static rpc_status_t deserialize_aead_generate_nonce_req(const struct rpc_buffer *req_buf,
 	uint32_t *op_handle)
 {
-	rpc_status_t rpc_status = TS_RPC_ERROR_INVALID_REQ_BODY;
+	rpc_status_t rpc_status = RPC_ERROR_INVALID_REQUEST_BODY;
 	struct ts_crypto_aead_generate_nonce_in recv_msg;
 	size_t expected_fixed_len = sizeof(struct ts_crypto_aead_generate_nonce_in);
 
-	if (expected_fixed_len <= req_buf->data_len) {
+	if (expected_fixed_len <= req_buf->data_length) {
 
 		memcpy(&recv_msg, req_buf->data, expected_fixed_len);
 		*op_handle = recv_msg.op_handle;
-		rpc_status = TS_RPC_CALL_ACCEPTED;
+		rpc_status = RPC_SUCCESS;
 	}
 
 	return rpc_status;
 }
 
-static rpc_status_t serialize_aead_generate_nonce_resp(struct call_param_buf *resp_buf,
+static rpc_status_t serialize_aead_generate_nonce_resp(struct rpc_buffer *resp_buf,
 	const uint8_t *nonce, size_t nonce_len)
 {
-	rpc_status_t rpc_status = TS_RPC_ERROR_INTERNAL;
+	rpc_status_t rpc_status = RPC_ERROR_INTERNAL;
 	struct tlv_iterator resp_iter;
 
 	struct tlv_record out_record;
@@ -82,28 +82,28 @@
 
 	if (tlv_encode(&resp_iter, &out_record)) {
 
-		resp_buf->data_len = tlv_required_space(out_record.length);
-		rpc_status = TS_RPC_CALL_ACCEPTED;
+		resp_buf->data_length = tlv_required_space(out_record.length);
+		rpc_status = RPC_SUCCESS;
 	}
 
 	return rpc_status;
 }
 
 /* Operation: aead_set_nonce */
-static rpc_status_t deserialize_aead_set_nonce_req(const struct call_param_buf *req_buf,
+static rpc_status_t deserialize_aead_set_nonce_req(const struct rpc_buffer *req_buf,
 	uint32_t *op_handle,
 	const uint8_t **nonce, size_t *nonce_len)
 {
-	rpc_status_t rpc_status = TS_RPC_ERROR_INVALID_REQ_BODY;
+	rpc_status_t rpc_status = RPC_ERROR_INVALID_REQUEST_BODY;
 	struct ts_crypto_aead_set_nonce_in recv_msg;
 	size_t expected_fixed_len = sizeof(struct ts_crypto_aead_set_nonce_in);
 
-	if (expected_fixed_len <= req_buf->data_len) {
+	if (expected_fixed_len <= req_buf->data_length) {
 
 		struct tlv_const_iterator req_iter;
 		struct tlv_record decoded_record;
 
-		rpc_status = TS_RPC_CALL_ACCEPTED;
+		rpc_status = RPC_SUCCESS;
 
 		memcpy(&recv_msg, req_buf->data, expected_fixed_len);
 
@@ -111,7 +111,7 @@
 
 		tlv_const_iterator_begin(&req_iter,
 			(uint8_t*)req_buf->data + expected_fixed_len,
-			req_buf->data_len - expected_fixed_len);
+			req_buf->data_length - expected_fixed_len);
 
 		if (tlv_find_decode(&req_iter, TS_CRYPTO_AEAD_SET_NONCE_IN_TAG_NONCE, &decoded_record)) {
 
@@ -128,18 +128,18 @@
 }
 
 /* Operation: aead_set_lengths */
-static rpc_status_t deserialize_aead_set_lengths_req(const struct call_param_buf *req_buf,
+static rpc_status_t deserialize_aead_set_lengths_req(const struct rpc_buffer *req_buf,
 	uint32_t *op_handle,
 	size_t *ad_length,
 	size_t *plaintext_length)
 {
-	rpc_status_t rpc_status = TS_RPC_ERROR_INVALID_REQ_BODY;
+	rpc_status_t rpc_status = RPC_ERROR_INVALID_REQUEST_BODY;
 	struct ts_crypto_aead_set_lengths_in recv_msg;
 	size_t expected_fixed_len = sizeof(struct ts_crypto_aead_set_lengths_in);
 
-	if (expected_fixed_len <= req_buf->data_len) {
+	if (expected_fixed_len <= req_buf->data_length) {
 
-		rpc_status = TS_RPC_CALL_ACCEPTED;
+		rpc_status = RPC_SUCCESS;
 
 		memcpy(&recv_msg, req_buf->data, expected_fixed_len);
 
@@ -152,20 +152,20 @@
 }
 
 /* Operation: aead_update_ad */
-static rpc_status_t deserialize_aead_update_ad_req(const struct call_param_buf *req_buf,
+static rpc_status_t deserialize_aead_update_ad_req(const struct rpc_buffer *req_buf,
 	uint32_t *op_handle,
 	const uint8_t **input, size_t *input_len)
 {
-	rpc_status_t rpc_status = TS_RPC_ERROR_INVALID_REQ_BODY;
+	rpc_status_t rpc_status = RPC_ERROR_INVALID_REQUEST_BODY;
 	struct ts_crypto_aead_update_ad_in recv_msg;
 	size_t expected_fixed_len = sizeof(struct ts_crypto_aead_update_ad_in);
 
-	if (expected_fixed_len <= req_buf->data_len) {
+	if (expected_fixed_len <= req_buf->data_length) {
 
 		struct tlv_const_iterator req_iter;
 		struct tlv_record decoded_record;
 
-		rpc_status = TS_RPC_CALL_ACCEPTED;
+		rpc_status = RPC_SUCCESS;
 
 		memcpy(&recv_msg, req_buf->data, expected_fixed_len);
 
@@ -173,7 +173,7 @@
 
 		tlv_const_iterator_begin(&req_iter,
 			(uint8_t*)req_buf->data + expected_fixed_len,
-			req_buf->data_len - expected_fixed_len);
+			req_buf->data_length - expected_fixed_len);
 
 		if (tlv_find_decode(&req_iter, TS_CRYPTO_AEAD_UPDATE_AD_IN_TAG_DATA, &decoded_record)) {
 
@@ -190,20 +190,20 @@
 }
 
 /* Operation: aead_update */
-static rpc_status_t deserialize_aead_update_req(const struct call_param_buf *req_buf,
+static rpc_status_t deserialize_aead_update_req(const struct rpc_buffer *req_buf,
 	uint32_t *op_handle,
 	const uint8_t **input, size_t *input_len)
 {
-	rpc_status_t rpc_status = TS_RPC_ERROR_INVALID_REQ_BODY;
+	rpc_status_t rpc_status = RPC_ERROR_INVALID_REQUEST_BODY;
 	struct ts_crypto_aead_update_in recv_msg;
 	size_t expected_fixed_len = sizeof(struct ts_crypto_aead_update_in);
 
-	if (expected_fixed_len <= req_buf->data_len) {
+	if (expected_fixed_len <= req_buf->data_length) {
 
 		struct tlv_const_iterator req_iter;
 		struct tlv_record decoded_record;
 
-		rpc_status = TS_RPC_CALL_ACCEPTED;
+		rpc_status = RPC_SUCCESS;
 
 		memcpy(&recv_msg, req_buf->data, expected_fixed_len);
 
@@ -211,7 +211,7 @@
 
 		tlv_const_iterator_begin(&req_iter,
 			(uint8_t*)req_buf->data + expected_fixed_len,
-			req_buf->data_len - expected_fixed_len);
+			req_buf->data_length - expected_fixed_len);
 
 		if (tlv_find_decode(&req_iter, TS_CRYPTO_AEAD_UPDATE_IN_TAG_DATA, &decoded_record)) {
 
@@ -227,10 +227,10 @@
 	return rpc_status;
 }
 
-static rpc_status_t serialize_aead_update_resp(struct call_param_buf *resp_buf,
+static rpc_status_t serialize_aead_update_resp(struct rpc_buffer *resp_buf,
 	const uint8_t *output, size_t output_len)
 {
-	rpc_status_t rpc_status = TS_RPC_ERROR_INTERNAL;
+	rpc_status_t rpc_status = RPC_ERROR_INTERNAL;
 	struct tlv_iterator resp_iter;
 
 	struct tlv_record out_record;
@@ -242,40 +242,40 @@
 
 	if (tlv_encode(&resp_iter, &out_record)) {
 
-		resp_buf->data_len = tlv_required_space(out_record.length);
-		rpc_status = TS_RPC_CALL_ACCEPTED;
+		resp_buf->data_length = tlv_required_space(out_record.length);
+		rpc_status = RPC_SUCCESS;
 	}
 
 	return rpc_status;
 }
 
 /* Operation: aead_finish */
-static rpc_status_t deserialize_aead_finish_req(const struct call_param_buf *req_buf,
+static rpc_status_t deserialize_aead_finish_req(const struct rpc_buffer *req_buf,
 	uint32_t *op_handle)
 {
-	rpc_status_t rpc_status = TS_RPC_ERROR_INVALID_REQ_BODY;
+	rpc_status_t rpc_status = RPC_ERROR_INVALID_REQUEST_BODY;
 	struct ts_crypto_aead_finish_in recv_msg;
 	size_t expected_fixed_len = sizeof(struct ts_crypto_aead_finish_in);
 
-	if (expected_fixed_len <= req_buf->data_len) {
+	if (expected_fixed_len <= req_buf->data_length) {
 
 		memcpy(&recv_msg, req_buf->data, expected_fixed_len);
 		*op_handle = recv_msg.op_handle;
-		rpc_status = TS_RPC_CALL_ACCEPTED;
+		rpc_status = RPC_SUCCESS;
 	}
 
 	return rpc_status;
 }
 
-static rpc_status_t serialize_aead_finish_resp(struct call_param_buf *resp_buf,
+static rpc_status_t serialize_aead_finish_resp(struct rpc_buffer *resp_buf,
 	const uint8_t *aeadtext, size_t aeadtext_len,
 	const uint8_t *tag, size_t tag_len)
 {
-	rpc_status_t rpc_status = TS_RPC_ERROR_INTERNAL;
+	rpc_status_t rpc_status = RPC_ERROR_INTERNAL;
 	struct tlv_iterator resp_iter;
 	int encoded_tlv_count = 0;
 
-	resp_buf->data_len = 0;
+	resp_buf->data_length = 0;
 
 	tlv_iterator_begin(&resp_iter, resp_buf->data, resp_buf->size);
 
@@ -286,7 +286,7 @@
 
 	if (tlv_encode(&resp_iter, &out_record)) {
 
-		resp_buf->data_len += tlv_required_space(out_record.length);
+		resp_buf->data_length += tlv_required_space(out_record.length);
 		++encoded_tlv_count;
 	}
 
@@ -296,31 +296,32 @@
 
 	if (tlv_encode(&resp_iter, &out_record)) {
 
-		resp_buf->data_len += tlv_required_space(out_record.length);
+		resp_buf->data_length += tlv_required_space(out_record.length);
 		++encoded_tlv_count;
 	}
 
 	/* Check that expected TLV records have been encoded */
-	if (encoded_tlv_count == 2) rpc_status = TS_RPC_CALL_ACCEPTED;
+	if (encoded_tlv_count == 2)
+		rpc_status = RPC_SUCCESS;
 
 	return rpc_status;
 }
 
 /* Operation: aead_verify */
-static rpc_status_t deserialize_aead_verify_req(const struct call_param_buf *req_buf,
+static rpc_status_t deserialize_aead_verify_req(const struct rpc_buffer *req_buf,
 	uint32_t *op_handle,
 	const uint8_t **tag, size_t *tag_len)
 {
-	rpc_status_t rpc_status = TS_RPC_ERROR_INVALID_REQ_BODY;
+	rpc_status_t rpc_status = RPC_ERROR_INVALID_REQUEST_BODY;
 	struct ts_crypto_aead_verify_in recv_msg;
 	size_t expected_fixed_len = sizeof(struct ts_crypto_aead_verify_in);
 
-	if (expected_fixed_len <= req_buf->data_len) {
+	if (expected_fixed_len <= req_buf->data_length) {
 
 		struct tlv_const_iterator req_iter;
 		struct tlv_record decoded_record;
 
-		rpc_status = TS_RPC_CALL_ACCEPTED;
+		rpc_status = RPC_SUCCESS;
 
 		memcpy(&recv_msg, req_buf->data, expected_fixed_len);
 
@@ -328,7 +329,7 @@
 
 		tlv_const_iterator_begin(&req_iter,
 			(uint8_t*)req_buf->data + expected_fixed_len,
-			req_buf->data_len - expected_fixed_len);
+			req_buf->data_length - expected_fixed_len);
 
 		if (tlv_find_decode(&req_iter, TS_CRYPTO_AEAD_VERIFY_IN_TAG_TAG, &decoded_record)) {
 
@@ -344,10 +345,10 @@
 	return rpc_status;
 }
 
-static rpc_status_t serialize_aead_verify_resp(struct call_param_buf *resp_buf,
+static rpc_status_t serialize_aead_verify_resp(struct rpc_buffer *resp_buf,
 	const uint8_t *plaintext, size_t plaintext_len)
 {
-	rpc_status_t rpc_status = TS_RPC_ERROR_INTERNAL;
+	rpc_status_t rpc_status = RPC_ERROR_INTERNAL;
 	struct tlv_iterator resp_iter;
 
 	struct tlv_record out_record;
@@ -359,26 +360,26 @@
 
 	if (tlv_encode(&resp_iter, &out_record)) {
 
-		resp_buf->data_len = tlv_required_space(out_record.length);
-		rpc_status = TS_RPC_CALL_ACCEPTED;
+		resp_buf->data_length = tlv_required_space(out_record.length);
+		rpc_status = RPC_SUCCESS;
 	}
 
 	return rpc_status;
 }
 
 /* Operation: aead_abort */
-static rpc_status_t deserialize_aead_abort_req(const struct call_param_buf *req_buf,
+static rpc_status_t deserialize_aead_abort_req(const struct rpc_buffer *req_buf,
 	uint32_t *op_handle)
 {
-	rpc_status_t rpc_status = TS_RPC_ERROR_INVALID_REQ_BODY;
+	rpc_status_t rpc_status = RPC_ERROR_INVALID_REQUEST_BODY;
 	struct ts_crypto_aead_abort_in recv_msg;
 	size_t expected_fixed_len = sizeof(struct ts_crypto_aead_abort_in);
 
-	if (expected_fixed_len <= req_buf->data_len) {
+	if (expected_fixed_len <= req_buf->data_length) {
 
 		memcpy(&recv_msg, req_buf->data, expected_fixed_len);
 		*op_handle = recv_msg.op_handle;
-		rpc_status = TS_RPC_CALL_ACCEPTED;
+		rpc_status = RPC_SUCCESS;
 	}
 
 	return rpc_status;
diff --git a/components/service/crypto/provider/extension/cipher/cipher_provider.c b/components/service/crypto/provider/extension/cipher/cipher_provider.c
index a5dd037..ceecdee 100644
--- a/components/service/crypto/provider/extension/cipher/cipher_provider.c
+++ b/components/service/crypto/provider/extension/cipher/cipher_provider.c
@@ -11,12 +11,12 @@
 #include <psa/crypto.h>
 
 /* Service request handlers */
-static rpc_status_t cipher_setup_handler(void *context, struct call_req* req);
-static rpc_status_t cipher_generate_iv_handler(void *context, struct call_req* req);
-static rpc_status_t cipher_set_iv_handler(void *context, struct call_req* req);
-static rpc_status_t cipher_update_handler(void *context, struct call_req* req);
-static rpc_status_t cipher_finish_handler(void *context, struct call_req* req);
-static rpc_status_t cipher_abort_handler(void *context, struct call_req* req);
+static rpc_status_t cipher_setup_handler(void *context, struct rpc_request *req);
+static rpc_status_t cipher_generate_iv_handler(void *context, struct rpc_request *req);
+static rpc_status_t cipher_set_iv_handler(void *context, struct rpc_request *req);
+static rpc_status_t cipher_update_handler(void *context, struct rpc_request *req);
+static rpc_status_t cipher_finish_handler(void *context, struct rpc_request *req);
+static rpc_status_t cipher_abort_handler(void *context, struct rpc_request *req);
 
 /* Handler mapping table for service */
 static const struct service_handler handler_table[] = {
@@ -31,12 +31,14 @@
 
 void cipher_provider_init(struct cipher_provider *context)
 {
+	const struct rpc_uuid nil_uuid = { 0 };
+
 	crypto_context_pool_init(&context->context_pool);
 
 	for (size_t encoding = 0; encoding < TS_RPC_ENCODING_LIMIT; ++encoding)
 		context->serializers[encoding] = NULL;
 
-	service_provider_init(&context->base_provider, context,
+	service_provider_init(&context->base_provider, context, &nil_uuid,
 		handler_table, sizeof(handler_table)/sizeof(struct service_handler));
 }
 
@@ -53,21 +55,18 @@
 }
 
 static const struct cipher_provider_serializer* get_serializer(void *context,
-	const struct call_req *req)
+	const struct rpc_request *req)
 {
 	struct cipher_provider *this_instance = (struct cipher_provider*)context;
-	const struct cipher_provider_serializer* serializer = NULL;
-	unsigned int encoding = call_req_get_encoding(req);
+	unsigned int encoding = 0; /* No other encodings supported */
 
-	if (encoding < TS_RPC_ENCODING_LIMIT) serializer = this_instance->serializers[encoding];
-
-	return serializer;
+	return this_instance->serializers[encoding];
 }
 
-static rpc_status_t cipher_setup_handler(void *context, struct call_req* req)
+static rpc_status_t cipher_setup_handler(void *context, struct rpc_request *req)
 {
-	rpc_status_t rpc_status = TS_RPC_ERROR_SERIALIZATION_NOT_SUPPORTED;
-	struct call_param_buf *req_buf = call_req_get_req_buf(req);
+	rpc_status_t rpc_status = RPC_ERROR_INTERNAL;
+	struct rpc_buffer *req_buf = &req->request;
 	const struct cipher_provider_serializer *serializer = get_serializer(context, req);
 	struct cipher_provider *this_instance = (struct cipher_provider*)context;
 
@@ -77,13 +76,13 @@
 	if (serializer)
 		rpc_status = serializer->deserialize_cipher_setup_req(req_buf, &key_id, &alg);
 
-	if (rpc_status == TS_RPC_CALL_ACCEPTED) {
+	if (rpc_status == RPC_SUCCESS) {
 
 		uint32_t op_handle;
 
 		struct crypto_context *crypto_context =
 			crypto_context_pool_alloc(&this_instance->context_pool,
-				CRYPTO_CONTEXT_OP_ID_CIPHER, call_req_get_caller_id(req),
+				CRYPTO_CONTEXT_OP_ID_CIPHER, req->source_id,
 				&op_handle);
 
 		if (crypto_context) {
@@ -92,36 +91,34 @@
 
 			crypto_context->op.cipher = psa_cipher_operation_init();
 
-			psa_status = (call_req_get_opcode(req) == TS_CRYPTO_OPCODE_CIPHER_ENCRYPT_SETUP) ?
+			psa_status = (req->opcode == TS_CRYPTO_OPCODE_CIPHER_ENCRYPT_SETUP) ?
 				psa_cipher_encrypt_setup(&crypto_context->op.cipher, key_id, alg) :
 				psa_cipher_decrypt_setup(&crypto_context->op.cipher, key_id, alg);
 
 			if (psa_status == PSA_SUCCESS) {
 
-				struct call_param_buf *resp_buf = call_req_get_resp_buf(req);
+				struct rpc_buffer *resp_buf = &req->response;
 				rpc_status = serializer->serialize_cipher_setup_resp(resp_buf, op_handle);
 			}
 
-			if ((psa_status != PSA_SUCCESS) || (rpc_status != TS_RPC_CALL_ACCEPTED)) {
-
+			if ((psa_status != PSA_SUCCESS) || (rpc_status != RPC_SUCCESS))
 				crypto_context_pool_free(&this_instance->context_pool, crypto_context);
-			}
 
-			call_req_set_opstatus(req, psa_status);
+			req->service_status = psa_status;
 		}
 		else {
 			/* Failed to allocate crypto context for transaction */
-			rpc_status = TS_RPC_ERROR_RESOURCE_FAILURE;
+			rpc_status = RPC_ERROR_RESOURCE_FAILURE;
 		}
 	}
 
 	return rpc_status;
 }
 
-static rpc_status_t cipher_generate_iv_handler(void *context, struct call_req* req)
+static rpc_status_t cipher_generate_iv_handler(void *context, struct rpc_request *req)
 {
-	rpc_status_t rpc_status = TS_RPC_ERROR_SERIALIZATION_NOT_SUPPORTED;
-	struct call_param_buf *req_buf = call_req_get_req_buf(req);
+	rpc_status_t rpc_status = RPC_ERROR_INTERNAL;
+	struct rpc_buffer *req_buf = &req->request;
 	const struct cipher_provider_serializer *serializer = get_serializer(context, req);
 	struct cipher_provider *this_instance = (struct cipher_provider*)context;
 
@@ -130,13 +127,13 @@
 	if (serializer)
 		rpc_status = serializer->deserialize_cipher_generate_iv_req(req_buf, &op_handle);
 
-	if (rpc_status == TS_RPC_CALL_ACCEPTED) {
+	if (rpc_status == RPC_SUCCESS) {
 
 		psa_status_t psa_status = PSA_ERROR_BAD_STATE;
 
 		struct crypto_context *crypto_context =
 			crypto_context_pool_find(&this_instance->context_pool,
-				CRYPTO_CONTEXT_OP_ID_CIPHER, call_req_get_caller_id(req),
+				CRYPTO_CONTEXT_OP_ID_CIPHER, req->source_id,
 				op_handle);
 
 		if (crypto_context) {
@@ -148,21 +145,21 @@
 
 			if (psa_status == PSA_SUCCESS) {
 
-				struct call_param_buf *resp_buf = call_req_get_resp_buf(req);
+				struct rpc_buffer *resp_buf = &req->response;
 				rpc_status = serializer->serialize_cipher_generate_iv_resp(resp_buf, iv, iv_len);
 			}
 		}
 
-		call_req_set_opstatus(req, psa_status);
+		req->service_status = psa_status;
 	}
 
 	return rpc_status;
 }
 
-static rpc_status_t cipher_set_iv_handler(void *context, struct call_req* req)
+static rpc_status_t cipher_set_iv_handler(void *context, struct rpc_request *req)
 {
-	rpc_status_t rpc_status = TS_RPC_ERROR_SERIALIZATION_NOT_SUPPORTED;
-	struct call_param_buf *req_buf = call_req_get_req_buf(req);
+	rpc_status_t rpc_status = RPC_ERROR_INTERNAL;
+	struct rpc_buffer *req_buf = &req->request;
 	const struct cipher_provider_serializer *serializer = get_serializer(context, req);
 	struct cipher_provider *this_instance = (struct cipher_provider*)context;
 
@@ -174,13 +171,13 @@
 		rpc_status = serializer->deserialize_cipher_set_iv_req(req_buf, &op_handle,
 			&iv, &iv_len);
 
-	if (rpc_status == TS_RPC_CALL_ACCEPTED) {
+	if (rpc_status == RPC_SUCCESS) {
 
 		psa_status_t psa_status = PSA_ERROR_BAD_STATE;
 
 		struct crypto_context *crypto_context =
 			crypto_context_pool_find(&this_instance->context_pool,
-				CRYPTO_CONTEXT_OP_ID_CIPHER, call_req_get_caller_id(req),
+				CRYPTO_CONTEXT_OP_ID_CIPHER, req->source_id,
 				op_handle);
 
 		if (crypto_context) {
@@ -188,16 +185,16 @@
 			psa_status = psa_cipher_set_iv(&crypto_context->op.cipher, iv, iv_len);
 		}
 
-		call_req_set_opstatus(req, psa_status);
+		req->service_status = psa_status;
 	}
 
 	return rpc_status;
 }
 
-static rpc_status_t cipher_update_handler(void *context, struct call_req* req)
+static rpc_status_t cipher_update_handler(void *context, struct rpc_request *req)
 {
-	rpc_status_t rpc_status = TS_RPC_ERROR_SERIALIZATION_NOT_SUPPORTED;
-	struct call_param_buf *req_buf = call_req_get_req_buf(req);
+	rpc_status_t rpc_status = RPC_ERROR_INTERNAL;
+	struct rpc_buffer *req_buf = &req->request;
 	const struct cipher_provider_serializer *serializer = get_serializer(context, req);
 	struct cipher_provider *this_instance = (struct cipher_provider*)context;
 
@@ -209,13 +206,13 @@
 		rpc_status = serializer->deserialize_cipher_update_req(req_buf, &op_handle,
 			&input, &input_len);
 
-	if (rpc_status == TS_RPC_CALL_ACCEPTED) {
+	if (rpc_status == RPC_SUCCESS) {
 
 		psa_status_t psa_status = PSA_ERROR_BAD_STATE;
 
 		struct crypto_context *crypto_context =
 			crypto_context_pool_find(&this_instance->context_pool,
-				CRYPTO_CONTEXT_OP_ID_CIPHER, call_req_get_caller_id(req),
+				CRYPTO_CONTEXT_OP_ID_CIPHER, req->source_id,
 				op_handle);
 
 		if (crypto_context) {
@@ -232,7 +229,7 @@
 
 				if (psa_status == PSA_SUCCESS) {
 
-					struct call_param_buf *resp_buf = call_req_get_resp_buf(req);
+					struct rpc_buffer *resp_buf = &req->response;
 					rpc_status = serializer->serialize_cipher_update_resp(resp_buf,
 						output, output_len);
 				}
@@ -245,16 +242,16 @@
 			}
 		}
 
-		call_req_set_opstatus(req, psa_status);
+		req->service_status = psa_status;
 	}
 
 	return rpc_status;
 }
 
-static rpc_status_t cipher_finish_handler(void *context, struct call_req* req)
+static rpc_status_t cipher_finish_handler(void *context, struct rpc_request *req)
 {
-	rpc_status_t rpc_status = TS_RPC_ERROR_SERIALIZATION_NOT_SUPPORTED;
-	struct call_param_buf *req_buf = call_req_get_req_buf(req);
+	rpc_status_t rpc_status = RPC_ERROR_INTERNAL;
+	struct rpc_buffer *req_buf = &req->request;
 	const struct cipher_provider_serializer *serializer = get_serializer(context, req);
 	struct cipher_provider *this_instance = (struct cipher_provider*)context;
 
@@ -263,13 +260,13 @@
 	if (serializer)
 		rpc_status = serializer->deserialize_cipher_finish_req(req_buf, &op_handle);
 
-	if (rpc_status == TS_RPC_CALL_ACCEPTED) {
+	if (rpc_status == RPC_SUCCESS) {
 
 		psa_status_t psa_status = PSA_ERROR_BAD_STATE;
 
 		struct crypto_context *crypto_context =
 			crypto_context_pool_find(&this_instance->context_pool,
-				CRYPTO_CONTEXT_OP_ID_CIPHER, call_req_get_caller_id(req),
+				CRYPTO_CONTEXT_OP_ID_CIPHER, req->source_id,
 				op_handle);
 
 		if (crypto_context) {
@@ -281,23 +278,23 @@
 
 			if (psa_status == PSA_SUCCESS) {
 
-				struct call_param_buf *resp_buf = call_req_get_resp_buf(req);
+				struct rpc_buffer *resp_buf = &req->response;
 				rpc_status = serializer->serialize_cipher_finish_resp(resp_buf, output, output_len);
 
 				crypto_context_pool_free(&this_instance->context_pool, crypto_context);
 			}
 		}
 
-		call_req_set_opstatus(req, psa_status);
+		req->service_status = psa_status;
 	}
 
 	return rpc_status;
 }
 
-static rpc_status_t cipher_abort_handler(void *context, struct call_req* req)
+static rpc_status_t cipher_abort_handler(void *context, struct rpc_request *req)
 {
-	rpc_status_t rpc_status = TS_RPC_ERROR_SERIALIZATION_NOT_SUPPORTED;
-	struct call_param_buf *req_buf = call_req_get_req_buf(req);
+	rpc_status_t rpc_status = RPC_ERROR_INTERNAL;
+	struct rpc_buffer *req_buf = &req->request;
 	const struct cipher_provider_serializer *serializer = get_serializer(context, req);
 	struct cipher_provider *this_instance = (struct cipher_provider*)context;
 
@@ -306,7 +303,7 @@
 	if (serializer)
 		rpc_status = serializer->deserialize_cipher_abort_req(req_buf, &op_handle);
 
-	if (rpc_status == TS_RPC_CALL_ACCEPTED) {
+	if (rpc_status == RPC_SUCCESS) {
 
 		/* Return success if operation is no longer active and
 		 * doesn't need aborting.
@@ -315,7 +312,7 @@
 
 		struct crypto_context *crypto_context =
 			crypto_context_pool_find(&this_instance->context_pool,
-				CRYPTO_CONTEXT_OP_ID_CIPHER, call_req_get_caller_id(req),
+				CRYPTO_CONTEXT_OP_ID_CIPHER, req->source_id,
 				op_handle);
 
 		if (crypto_context) {
@@ -324,7 +321,7 @@
 			crypto_context_pool_free(&this_instance->context_pool, crypto_context);
 		}
 
-		call_req_set_opstatus(req, psa_status);
+		req->service_status = psa_status;
 	}
 
 	return rpc_status;
diff --git a/components/service/crypto/provider/extension/cipher/cipher_provider.h b/components/service/crypto/provider/extension/cipher/cipher_provider.h
index df2a27d..be03a80 100644
--- a/components/service/crypto/provider/extension/cipher/cipher_provider.h
+++ b/components/service/crypto/provider/extension/cipher/cipher_provider.h
@@ -7,7 +7,7 @@
 #ifndef CIPHER_PROVIDER_H
 #define CIPHER_PROVIDER_H
 
-#include <rpc/common/endpoint/rpc_interface.h>
+#include "components/rpc/common/endpoint/rpc_service_interface.h"
 #include <service/common/provider/service_provider.h>
 #include <service/crypto/provider/extension/cipher/serializer/cipher_provider_serializer.h>
 #include <service/crypto/provider/crypto_context_pool.h>
diff --git a/components/service/crypto/provider/extension/cipher/serializer/cipher_provider_serializer.h b/components/service/crypto/provider/extension/cipher/serializer/cipher_provider_serializer.h
index ccc9b96..21169d9 100644
--- a/components/service/crypto/provider/extension/cipher/serializer/cipher_provider_serializer.h
+++ b/components/service/crypto/provider/extension/cipher/serializer/cipher_provider_serializer.h
@@ -10,7 +10,7 @@
 #include <stddef.h>
 #include <stdint.h>
 #include <psa/crypto.h>
-#include <rpc/common/endpoint/rpc_interface.h>
+#include "components/rpc/common/endpoint/rpc_service_interface.h"
 
 /* Provides a common interface for parameter serialization operations
  * for the cipher service provider.
@@ -18,42 +18,42 @@
 struct cipher_provider_serializer {
 
 	/* Operation: cipher_setup */
-	rpc_status_t (*deserialize_cipher_setup_req)(const struct call_param_buf *req_buf,
+	rpc_status_t (*deserialize_cipher_setup_req)(const struct rpc_buffer *req_buf,
 		psa_key_id_t *id,
 		psa_algorithm_t *alg);
 
-	rpc_status_t (*serialize_cipher_setup_resp)(struct call_param_buf *resp_buf,
+	rpc_status_t (*serialize_cipher_setup_resp)(struct rpc_buffer *resp_buf,
 		uint32_t op_handle);
 
 	/* Operation: cipher_generate_iv */
-	rpc_status_t (*deserialize_cipher_generate_iv_req)(const struct call_param_buf *req_buf,
+	rpc_status_t (*deserialize_cipher_generate_iv_req)(const struct rpc_buffer *req_buf,
 		uint32_t *op_handle);
 
-	rpc_status_t (*serialize_cipher_generate_iv_resp)(struct call_param_buf *resp_buf,
+	rpc_status_t (*serialize_cipher_generate_iv_resp)(struct rpc_buffer *resp_buf,
 		const uint8_t *iv, size_t iv_len);
 
 	/* Operation: cipher_set_iv */
-	rpc_status_t (*deserialize_cipher_set_iv_req)(const struct call_param_buf *req_buf,
+	rpc_status_t (*deserialize_cipher_set_iv_req)(const struct rpc_buffer *req_buf,
 		uint32_t *op_handle,
 		const uint8_t **iv, size_t *iv_len);
 
 	/* Operation: cipher_update */
-	rpc_status_t (*deserialize_cipher_update_req)(const struct call_param_buf *req_buf,
+	rpc_status_t (*deserialize_cipher_update_req)(const struct rpc_buffer *req_buf,
 		uint32_t *op_handle,
 		const uint8_t **data, size_t *data_len);
 
-	rpc_status_t (*serialize_cipher_update_resp)(struct call_param_buf *resp_buf,
+	rpc_status_t (*serialize_cipher_update_resp)(struct rpc_buffer *resp_buf,
 		const uint8_t *data, size_t data_len);
 
 	/* Operation: cipher_finish */
-	rpc_status_t (*deserialize_cipher_finish_req)(const struct call_param_buf *req_buf,
+	rpc_status_t (*deserialize_cipher_finish_req)(const struct rpc_buffer *req_buf,
 		uint32_t *op_handle);
 
-	rpc_status_t (*serialize_cipher_finish_resp)(struct call_param_buf *resp_buf,
+	rpc_status_t (*serialize_cipher_finish_resp)(struct rpc_buffer *resp_buf,
 		const uint8_t *data, size_t data_len);
 
 	/* Operation: cipher_abort */
-	rpc_status_t (*deserialize_cipher_abort_req)(const struct call_param_buf *req_buf,
+	rpc_status_t (*deserialize_cipher_abort_req)(const struct rpc_buffer *req_buf,
 		uint32_t *op_handle);
 };
 
diff --git a/components/service/crypto/provider/extension/cipher/serializer/packed-c/packedc_cipher_provider_serializer.c b/components/service/crypto/provider/extension/cipher/serializer/packed-c/packedc_cipher_provider_serializer.c
index 1acb165..eb9cce3 100644
--- a/components/service/crypto/provider/extension/cipher/serializer/packed-c/packedc_cipher_provider_serializer.c
+++ b/components/service/crypto/provider/extension/cipher/serializer/packed-c/packedc_cipher_provider_serializer.c
@@ -11,29 +11,29 @@
 #include "packedc_cipher_provider_serializer.h"
 
 /* Operation: cipher_setup */
-static rpc_status_t deserialize_cipher_setup_req(const struct call_param_buf *req_buf,
+static rpc_status_t deserialize_cipher_setup_req(const struct rpc_buffer *req_buf,
 	psa_key_id_t *id,
 	psa_algorithm_t *alg)
 {
-	rpc_status_t rpc_status = TS_RPC_ERROR_INVALID_REQ_BODY;
+	rpc_status_t rpc_status = RPC_ERROR_INVALID_REQUEST_BODY;
 	struct ts_crypto_cipher_setup_in recv_msg;
 	size_t expected_fixed_len = sizeof(struct ts_crypto_cipher_setup_in);
 
-	if (expected_fixed_len <= req_buf->data_len) {
+	if (expected_fixed_len <= req_buf->data_length) {
 
 		memcpy(&recv_msg, req_buf->data, expected_fixed_len);
 		*id = recv_msg.key_id;
 		*alg = recv_msg.alg;
-		rpc_status = TS_RPC_CALL_ACCEPTED;
+		rpc_status = RPC_SUCCESS;
 	}
 
 	return rpc_status;
 }
 
-static rpc_status_t serialize_cipher_setup_resp(struct call_param_buf *resp_buf,
+static rpc_status_t serialize_cipher_setup_resp(struct rpc_buffer *resp_buf,
 	uint32_t op_handle)
 {
-	rpc_status_t rpc_status = TS_RPC_ERROR_INTERNAL;
+	rpc_status_t rpc_status = RPC_ERROR_INTERNAL;
 	struct ts_crypto_cipher_setup_out resp_msg;
 	size_t fixed_len = sizeof(struct ts_crypto_cipher_setup_out);
 
@@ -42,35 +42,35 @@
 	if (fixed_len <= resp_buf->size) {
 
 		memcpy(resp_buf->data, &resp_msg, fixed_len);
-		resp_buf->data_len = fixed_len;
-		rpc_status = TS_RPC_CALL_ACCEPTED;
+		resp_buf->data_length = fixed_len;
+		rpc_status = RPC_SUCCESS;
 	}
 
 	return rpc_status;
 }
 
 /* Operation: cipher_generate_iv */
-static rpc_status_t deserialize_cipher_generate_iv_req(const struct call_param_buf *req_buf,
+static rpc_status_t deserialize_cipher_generate_iv_req(const struct rpc_buffer *req_buf,
 	uint32_t *op_handle)
 {
-	rpc_status_t rpc_status = TS_RPC_ERROR_INVALID_REQ_BODY;
+	rpc_status_t rpc_status = RPC_ERROR_INVALID_REQUEST_BODY;
 	struct ts_crypto_cipher_generate_iv_in recv_msg;
 	size_t expected_fixed_len = sizeof(struct ts_crypto_cipher_generate_iv_in);
 
-	if (expected_fixed_len <= req_buf->data_len) {
+	if (expected_fixed_len <= req_buf->data_length) {
 
 		memcpy(&recv_msg, req_buf->data, expected_fixed_len);
 		*op_handle = recv_msg.op_handle;
-		rpc_status = TS_RPC_CALL_ACCEPTED;
+		rpc_status = RPC_SUCCESS;
 	}
 
 	return rpc_status;
 }
 
-static rpc_status_t serialize_cipher_generate_iv_resp(struct call_param_buf *resp_buf,
+static rpc_status_t serialize_cipher_generate_iv_resp(struct rpc_buffer *resp_buf,
 	const uint8_t *iv, size_t iv_len)
 {
-	rpc_status_t rpc_status = TS_RPC_ERROR_INTERNAL;
+	rpc_status_t rpc_status = RPC_ERROR_INTERNAL;
 	struct tlv_iterator resp_iter;
 
 	struct tlv_record out_record;
@@ -82,28 +82,28 @@
 
 	if (tlv_encode(&resp_iter, &out_record)) {
 
-		resp_buf->data_len = tlv_required_space(iv_len);
-		rpc_status = TS_RPC_CALL_ACCEPTED;
+		resp_buf->data_length = tlv_required_space(iv_len);
+		rpc_status = RPC_SUCCESS;
 	}
 
 	return rpc_status;
 }
 
 /* Operation: cipher_set_iv */
-static rpc_status_t deserialize_cipher_set_iv_req(const struct call_param_buf *req_buf,
+static rpc_status_t deserialize_cipher_set_iv_req(const struct rpc_buffer *req_buf,
 	uint32_t *op_handle,
 	const uint8_t **iv, size_t *iv_len)
 {
-	rpc_status_t rpc_status = TS_RPC_ERROR_INVALID_REQ_BODY;
+	rpc_status_t rpc_status = RPC_ERROR_INVALID_REQUEST_BODY;
 	struct ts_crypto_cipher_set_iv_in recv_msg;
 	size_t expected_fixed_len = sizeof(struct ts_crypto_cipher_set_iv_in);
 
-	if (expected_fixed_len <= req_buf->data_len) {
+	if (expected_fixed_len <= req_buf->data_length) {
 
 		struct tlv_const_iterator req_iter;
 		struct tlv_record decoded_record;
 
-		rpc_status = TS_RPC_CALL_ACCEPTED;
+		rpc_status = RPC_SUCCESS;
 
 		memcpy(&recv_msg, req_buf->data, expected_fixed_len);
 
@@ -111,7 +111,7 @@
 
 		tlv_const_iterator_begin(&req_iter,
 			(uint8_t*)req_buf->data + expected_fixed_len,
-			req_buf->data_len - expected_fixed_len);
+			req_buf->data_length - expected_fixed_len);
 
 		if (tlv_find_decode(&req_iter, TS_CRYPTO_CIPHER_SET_IV_IN_TAG_IV, &decoded_record)) {
 
@@ -128,20 +128,20 @@
 }
 
 /* Operation: cipher_update */
-static rpc_status_t deserialize_cipher_update_req(const struct call_param_buf *req_buf,
+static rpc_status_t deserialize_cipher_update_req(const struct rpc_buffer *req_buf,
 	uint32_t *op_handle,
-	const uint8_t **data, size_t *data_len)
+	const uint8_t **data, size_t *data_length)
 {
-	rpc_status_t rpc_status = TS_RPC_ERROR_INVALID_REQ_BODY;
+	rpc_status_t rpc_status = RPC_ERROR_INVALID_REQUEST_BODY;
 	struct ts_crypto_cipher_update_in recv_msg;
 	size_t expected_fixed_len = sizeof(struct ts_crypto_cipher_update_in);
 
-	if (expected_fixed_len <= req_buf->data_len) {
+	if (expected_fixed_len <= req_buf->data_length) {
 
 		struct tlv_const_iterator req_iter;
 		struct tlv_record decoded_record;
 
-		rpc_status = TS_RPC_CALL_ACCEPTED;
+		rpc_status = RPC_SUCCESS;
 
 		memcpy(&recv_msg, req_buf->data, expected_fixed_len);
 
@@ -149,97 +149,97 @@
 
 		tlv_const_iterator_begin(&req_iter,
 			(uint8_t*)req_buf->data + expected_fixed_len,
-			req_buf->data_len - expected_fixed_len);
+			req_buf->data_length - expected_fixed_len);
 
 		if (tlv_find_decode(&req_iter, TS_CRYPTO_CIPHER_UPDATE_IN_TAG_DATA, &decoded_record)) {
 
 			*data = decoded_record.value;
-			*data_len = decoded_record.length;
+			*data_length = decoded_record.length;
 		}
 		else {
 			/* Default to a zero length data */
-			*data_len = 0;
+			*data_length = 0;
 		}
 	}
 
 	return rpc_status;
 }
 
-static rpc_status_t serialize_cipher_update_resp(struct call_param_buf *resp_buf,
-		const uint8_t *data, size_t data_len)
+static rpc_status_t serialize_cipher_update_resp(struct rpc_buffer *resp_buf,
+		const uint8_t *data, size_t data_length)
 {
-	rpc_status_t rpc_status = TS_RPC_ERROR_INTERNAL;
+	rpc_status_t rpc_status = RPC_ERROR_INTERNAL;
 	struct tlv_iterator resp_iter;
 
 	struct tlv_record out_record;
 	out_record.tag = TS_CRYPTO_CIPHER_UPDATE_OUT_TAG_DATA;
-	out_record.length = data_len;
+	out_record.length = data_length;
 	out_record.value = data;
 
 	tlv_iterator_begin(&resp_iter, resp_buf->data, resp_buf->size);
 
 	if (tlv_encode(&resp_iter, &out_record)) {
 
-		resp_buf->data_len = tlv_required_space(data_len);
-		rpc_status = TS_RPC_CALL_ACCEPTED;
+		resp_buf->data_length = tlv_required_space(data_length);
+		rpc_status = RPC_SUCCESS;
 	}
 
 	return rpc_status;
 }
 
 /* Operation: cipher_finish */
-static rpc_status_t deserialize_cipher_finish_req(const struct call_param_buf *req_buf,
+static rpc_status_t deserialize_cipher_finish_req(const struct rpc_buffer *req_buf,
 	uint32_t *op_handle)
 {
-	rpc_status_t rpc_status = TS_RPC_ERROR_INVALID_REQ_BODY;
+	rpc_status_t rpc_status = RPC_ERROR_INVALID_REQUEST_BODY;
 	struct ts_crypto_cipher_finish_in recv_msg;
 	size_t expected_fixed_len = sizeof(struct ts_crypto_cipher_finish_in);
 
-	if (expected_fixed_len <= req_buf->data_len) {
+	if (expected_fixed_len <= req_buf->data_length) {
 
 		memcpy(&recv_msg, req_buf->data, expected_fixed_len);
 		*op_handle = recv_msg.op_handle;
-		rpc_status = TS_RPC_CALL_ACCEPTED;
+		rpc_status = RPC_SUCCESS;
 	}
 
 	return rpc_status;
 }
 
-static rpc_status_t serialize_cipher_finish_resp(struct call_param_buf *resp_buf,
-	const uint8_t *data, size_t data_len)
+static rpc_status_t serialize_cipher_finish_resp(struct rpc_buffer *resp_buf,
+	const uint8_t *data, size_t data_length)
 {
-	rpc_status_t rpc_status = TS_RPC_ERROR_INTERNAL;
+	rpc_status_t rpc_status = RPC_ERROR_INTERNAL;
 	struct tlv_iterator resp_iter;
 
 	struct tlv_record out_record;
 	out_record.tag = TS_CRYPTO_CIPHER_FINISH_OUT_TAG_DATA;
-	out_record.length = data_len;
+	out_record.length = data_length;
 	out_record.value = data;
 
 	tlv_iterator_begin(&resp_iter, resp_buf->data, resp_buf->size);
 
 	if (tlv_encode(&resp_iter, &out_record)) {
 
-		resp_buf->data_len = tlv_required_space(data_len);
-		rpc_status = TS_RPC_CALL_ACCEPTED;
+		resp_buf->data_length = tlv_required_space(data_length);
+		rpc_status = RPC_SUCCESS;
 	}
 
 	return rpc_status;
 }
 
 /* Operation: cipher_abort */
-static rpc_status_t deserialize_cipher_abort_req(const struct call_param_buf *req_buf,
+static rpc_status_t deserialize_cipher_abort_req(const struct rpc_buffer *req_buf,
 	uint32_t *op_handle)
 {
-	rpc_status_t rpc_status = TS_RPC_ERROR_INVALID_REQ_BODY;
+	rpc_status_t rpc_status = RPC_ERROR_INVALID_REQUEST_BODY;
 	struct ts_crypto_cipher_abort_in recv_msg;
 	size_t expected_fixed_len = sizeof(struct ts_crypto_cipher_abort_in);
 
-	if (expected_fixed_len <= req_buf->data_len) {
+	if (expected_fixed_len <= req_buf->data_length) {
 
 		memcpy(&recv_msg, req_buf->data, expected_fixed_len);
 		*op_handle = recv_msg.op_handle;
-		rpc_status = TS_RPC_CALL_ACCEPTED;
+		rpc_status = RPC_SUCCESS;
 	}
 
 	return rpc_status;
diff --git a/components/service/crypto/provider/extension/hash/hash_provider.c b/components/service/crypto/provider/extension/hash/hash_provider.c
index b50fac1..1c4da5d 100644
--- a/components/service/crypto/provider/extension/hash/hash_provider.c
+++ b/components/service/crypto/provider/extension/hash/hash_provider.c
@@ -11,12 +11,12 @@
 #include <psa/crypto.h>
 
 /* Service request handlers */
-static rpc_status_t hash_setup_handler(void *context, struct call_req* req);
-static rpc_status_t hash_update_handler(void *context, struct call_req* req);
-static rpc_status_t hash_finish_handler(void *context, struct call_req* req);
-static rpc_status_t hash_abort_handler(void *context, struct call_req* req);
-static rpc_status_t hash_verify_handler(void *context, struct call_req* req);
-static rpc_status_t hash_clone_handler(void *context, struct call_req* req);
+static rpc_status_t hash_setup_handler(void *context, struct rpc_request *req);
+static rpc_status_t hash_update_handler(void *context, struct rpc_request *req);
+static rpc_status_t hash_finish_handler(void *context, struct rpc_request *req);
+static rpc_status_t hash_abort_handler(void *context, struct rpc_request *req);
+static rpc_status_t hash_verify_handler(void *context, struct rpc_request *req);
+static rpc_status_t hash_clone_handler(void *context, struct rpc_request *req);
 
 /* Handler mapping table for service */
 static const struct service_handler handler_table[] = {
@@ -30,12 +30,14 @@
 
 void hash_provider_init(struct hash_provider *context)
 {
+	const struct rpc_uuid nil_uuid = { 0 };
+
 	crypto_context_pool_init(&context->context_pool);
 
 	for (size_t encoding = 0; encoding < TS_RPC_ENCODING_LIMIT; ++encoding)
 		context->serializers[encoding] = NULL;
 
-	service_provider_init(&context->base_provider, context,
+	service_provider_init(&context->base_provider, context, &nil_uuid,
 		handler_table, sizeof(handler_table)/sizeof(struct service_handler));
 }
 
@@ -52,21 +54,18 @@
 }
 
 static const struct hash_provider_serializer* get_serializer(void *context,
-	const struct call_req *req)
+	const struct rpc_request *req)
 {
 	struct hash_provider *this_instance = (struct hash_provider*)context;
-	const struct hash_provider_serializer* serializer = NULL;
-	unsigned int encoding = call_req_get_encoding(req);
+	unsigned int encoding = 0; /* No other encodings supported */
 
-	if (encoding < TS_RPC_ENCODING_LIMIT) serializer = this_instance->serializers[encoding];
-
-	return serializer;
+	return this_instance->serializers[encoding];
 }
 
-static rpc_status_t hash_setup_handler(void *context, struct call_req* req)
+static rpc_status_t hash_setup_handler(void *context, struct rpc_request *req)
 {
-	rpc_status_t rpc_status = TS_RPC_ERROR_SERIALIZATION_NOT_SUPPORTED;
-	struct call_param_buf *req_buf = call_req_get_req_buf(req);
+	rpc_status_t rpc_status = RPC_ERROR_INTERNAL;
+	struct rpc_buffer *req_buf = &req->request;
 	const struct hash_provider_serializer *serializer = get_serializer(context, req);
 	struct hash_provider *this_instance = (struct hash_provider*)context;
 
@@ -75,13 +74,13 @@
 	if (serializer)
 		rpc_status = serializer->deserialize_hash_setup_req(req_buf, &alg);
 
-	if (rpc_status == TS_RPC_CALL_ACCEPTED) {
+	if (rpc_status == RPC_SUCCESS) {
 
 		uint32_t op_handle;
 
 		struct crypto_context *crypto_context =
 			crypto_context_pool_alloc(&this_instance->context_pool,
-				CRYPTO_CONTEXT_OP_ID_HASH, call_req_get_caller_id(req),
+				CRYPTO_CONTEXT_OP_ID_HASH, req->source_id,
 				&op_handle);
 
 		if (crypto_context) {
@@ -93,30 +92,28 @@
 
 			if (psa_status == PSA_SUCCESS) {
 
-				struct call_param_buf *resp_buf = call_req_get_resp_buf(req);
+				struct rpc_buffer *resp_buf = &req->response;
 				rpc_status = serializer->serialize_hash_setup_resp(resp_buf, op_handle);
 			}
 
-			if ((psa_status != PSA_SUCCESS) || (rpc_status != TS_RPC_CALL_ACCEPTED)) {
-
+			if ((psa_status != PSA_SUCCESS) || (rpc_status != RPC_SUCCESS))
 				crypto_context_pool_free(&this_instance->context_pool, crypto_context);
-			}
 
-			call_req_set_opstatus(req, psa_status);
+			req->service_status = psa_status;
 		}
 		else {
 			/* Failed to allocate crypto context for transaction */
-			rpc_status = TS_RPC_ERROR_RESOURCE_FAILURE;
+			rpc_status = RPC_ERROR_RESOURCE_FAILURE;
 		}
 	}
 
 	return rpc_status;
 }
 
-static rpc_status_t hash_update_handler(void *context, struct call_req* req)
+static rpc_status_t hash_update_handler(void *context, struct rpc_request *req)
 {
-	rpc_status_t rpc_status = TS_RPC_ERROR_SERIALIZATION_NOT_SUPPORTED;
-	struct call_param_buf *req_buf = call_req_get_req_buf(req);
+	rpc_status_t rpc_status = RPC_ERROR_INTERNAL;
+	struct rpc_buffer *req_buf = &req->request;
 	const struct hash_provider_serializer *serializer = get_serializer(context, req);
 	struct hash_provider *this_instance = (struct hash_provider*)context;
 
@@ -127,13 +124,13 @@
 	if (serializer)
 		rpc_status = serializer->deserialize_hash_update_req(req_buf, &op_handle, &data, &data_len);
 
-	if (rpc_status == TS_RPC_CALL_ACCEPTED) {
+	if (rpc_status == RPC_SUCCESS) {
 
 		psa_status_t psa_status = PSA_ERROR_BAD_STATE;
 
 		struct crypto_context *crypto_context =
 			crypto_context_pool_find(&this_instance->context_pool,
-				CRYPTO_CONTEXT_OP_ID_HASH, call_req_get_caller_id(req),
+				CRYPTO_CONTEXT_OP_ID_HASH, req->source_id,
 				op_handle);
 
 		if (crypto_context) {
@@ -141,16 +138,16 @@
 			psa_status = psa_hash_update(&crypto_context->op.hash, data, data_len);
 		}
 
-		call_req_set_opstatus(req, psa_status);
+		req->service_status = psa_status;
 	}
 
 	return rpc_status;
 }
 
-static rpc_status_t hash_finish_handler(void *context, struct call_req* req)
+static rpc_status_t hash_finish_handler(void *context, struct rpc_request *req)
 {
-	rpc_status_t rpc_status = TS_RPC_ERROR_SERIALIZATION_NOT_SUPPORTED;
-	struct call_param_buf *req_buf = call_req_get_req_buf(req);
+	rpc_status_t rpc_status = RPC_ERROR_INTERNAL;
+	struct rpc_buffer *req_buf = &req->request;
 	const struct hash_provider_serializer *serializer = get_serializer(context, req);
 	struct hash_provider *this_instance = (struct hash_provider*)context;
 
@@ -159,13 +156,13 @@
 	if (serializer)
 		rpc_status = serializer->deserialize_hash_finish_req(req_buf, &op_handle);
 
-	if (rpc_status == TS_RPC_CALL_ACCEPTED) {
+	if (rpc_status == RPC_SUCCESS) {
 
 		psa_status_t psa_status = PSA_ERROR_BAD_STATE;
 
 		struct crypto_context *crypto_context =
 			crypto_context_pool_find(&this_instance->context_pool,
-				CRYPTO_CONTEXT_OP_ID_HASH, call_req_get_caller_id(req),
+				CRYPTO_CONTEXT_OP_ID_HASH, req->source_id,
 				op_handle);
 
 		if (crypto_context) {
@@ -177,23 +174,23 @@
 
 			if (psa_status == PSA_SUCCESS) {
 
-				struct call_param_buf *resp_buf = call_req_get_resp_buf(req);
+				struct rpc_buffer *resp_buf = &req->response;
 				rpc_status = serializer->serialize_hash_finish_resp(resp_buf, hash, hash_len);
 
 				crypto_context_pool_free(&this_instance->context_pool, crypto_context);
 			}
 		}
 
-		call_req_set_opstatus(req, psa_status);
+		req->service_status = psa_status;
 	}
 
 	return rpc_status;
 }
 
-static rpc_status_t hash_abort_handler(void *context, struct call_req* req)
+static rpc_status_t hash_abort_handler(void *context, struct rpc_request *req)
 {
-	rpc_status_t rpc_status = TS_RPC_ERROR_SERIALIZATION_NOT_SUPPORTED;
-	struct call_param_buf *req_buf = call_req_get_req_buf(req);
+	rpc_status_t rpc_status = RPC_ERROR_INTERNAL;
+	struct rpc_buffer *req_buf = &req->request;
 	const struct hash_provider_serializer *serializer = get_serializer(context, req);
 	struct hash_provider *this_instance = (struct hash_provider*)context;
 
@@ -202,7 +199,7 @@
 	if (serializer)
 		rpc_status = serializer->deserialize_hash_abort_req(req_buf, &op_handle);
 
-	if (rpc_status == TS_RPC_CALL_ACCEPTED) {
+	if (rpc_status == RPC_SUCCESS) {
 
 		/* Return success if operation is no longer active and
 		 * doesn't need aborting.
@@ -211,7 +208,7 @@
 
 		struct crypto_context *crypto_context =
 			crypto_context_pool_find(&this_instance->context_pool,
-				CRYPTO_CONTEXT_OP_ID_HASH, call_req_get_caller_id(req),
+				CRYPTO_CONTEXT_OP_ID_HASH, req->source_id,
 				op_handle);
 
 		if (crypto_context) {
@@ -220,16 +217,16 @@
 			crypto_context_pool_free(&this_instance->context_pool, crypto_context);
 		}
 
-		call_req_set_opstatus(req, psa_status);
+		req->service_status = psa_status;
 	}
 
 	return rpc_status;
 }
 
-static rpc_status_t hash_verify_handler(void *context, struct call_req* req)
+static rpc_status_t hash_verify_handler(void *context, struct rpc_request *req)
 {
-	rpc_status_t rpc_status = TS_RPC_ERROR_SERIALIZATION_NOT_SUPPORTED;
-	struct call_param_buf *req_buf = call_req_get_req_buf(req);
+	rpc_status_t rpc_status = RPC_ERROR_INTERNAL;
+	struct rpc_buffer *req_buf = &req->request;
 	const struct hash_provider_serializer *serializer = get_serializer(context, req);
 	struct hash_provider *this_instance = (struct hash_provider*)context;
 
@@ -240,13 +237,13 @@
 	if (serializer)
 		rpc_status = serializer->deserialize_hash_verify_req(req_buf, &op_handle, &hash, &hash_len);
 
-	if (rpc_status == TS_RPC_CALL_ACCEPTED) {
+	if (rpc_status == RPC_SUCCESS) {
 
 		psa_status_t psa_status = PSA_ERROR_BAD_STATE;
 
 		struct crypto_context *crypto_context =
 			crypto_context_pool_find(&this_instance->context_pool,
-				CRYPTO_CONTEXT_OP_ID_HASH, call_req_get_caller_id(req),
+				CRYPTO_CONTEXT_OP_ID_HASH, req->source_id,
 				op_handle);
 
 		if (crypto_context) {
@@ -257,16 +254,16 @@
 				crypto_context_pool_free(&this_instance->context_pool, crypto_context);
 		}
 
-		call_req_set_opstatus(req, psa_status);
+		req->service_status = psa_status;
 	}
 
 	return rpc_status;
 }
 
-static rpc_status_t hash_clone_handler(void *context, struct call_req* req)
+static rpc_status_t hash_clone_handler(void *context, struct rpc_request *req)
 {
-	rpc_status_t rpc_status = TS_RPC_ERROR_SERIALIZATION_NOT_SUPPORTED;
-	struct call_param_buf *req_buf = call_req_get_req_buf(req);
+	rpc_status_t rpc_status = RPC_ERROR_INTERNAL;
+	struct rpc_buffer *req_buf = &req->request;
 	const struct hash_provider_serializer *serializer = get_serializer(context, req);
 	struct hash_provider *this_instance = (struct hash_provider*)context;
 
@@ -275,13 +272,13 @@
 	if (serializer)
 		rpc_status = serializer->deserialize_hash_clone_req(req_buf, &source_op_handle);
 
-	if (rpc_status == TS_RPC_CALL_ACCEPTED) {
+	if (rpc_status == RPC_SUCCESS) {
 
 		psa_status_t psa_status = PSA_ERROR_BAD_STATE;
 
 		struct crypto_context *source_crypto_context =
 			crypto_context_pool_find(&this_instance->context_pool,
-				CRYPTO_CONTEXT_OP_ID_HASH, call_req_get_caller_id(req),
+				CRYPTO_CONTEXT_OP_ID_HASH, req->source_id,
 				source_op_handle);
 
 		if (source_crypto_context) {
@@ -290,7 +287,7 @@
 
 			struct crypto_context *target_crypto_context = crypto_context_pool_alloc(
 				&this_instance->context_pool,
-				CRYPTO_CONTEXT_OP_ID_HASH, call_req_get_caller_id(req),
+				CRYPTO_CONTEXT_OP_ID_HASH, req->source_id,
 				&target_op_handle);
 
 			if (target_crypto_context) {
@@ -302,13 +299,13 @@
 
 				if (psa_status == PSA_SUCCESS) {
 
-					struct call_param_buf *resp_buf = call_req_get_resp_buf(req);
+					struct rpc_buffer *resp_buf = &req->response;
 					rpc_status = serializer->serialize_hash_clone_resp(resp_buf, target_op_handle);
 				}
 			}
 		}
 
-		call_req_set_opstatus(req, psa_status);
+		req->service_status = psa_status;
 	}
 
 	return rpc_status;
diff --git a/components/service/crypto/provider/extension/hash/hash_provider.h b/components/service/crypto/provider/extension/hash/hash_provider.h
index 917d1f1..2dad161 100644
--- a/components/service/crypto/provider/extension/hash/hash_provider.h
+++ b/components/service/crypto/provider/extension/hash/hash_provider.h
@@ -7,7 +7,7 @@
 #ifndef HASH_PROVIDER_H
 #define HASH_PROVIDER_H
 
-#include <rpc/common/endpoint/rpc_interface.h>
+#include "components/rpc/common/endpoint/rpc_service_interface.h"
 #include <service/common/provider/service_provider.h>
 #include <service/crypto/provider/extension/hash/serializer/hash_provider_serializer.h>
 #include <service/crypto/provider/crypto_context_pool.h>
diff --git a/components/service/crypto/provider/extension/hash/serializer/hash_provider_serializer.h b/components/service/crypto/provider/extension/hash/serializer/hash_provider_serializer.h
index 1611e6e..bfb4d8b 100644
--- a/components/service/crypto/provider/extension/hash/serializer/hash_provider_serializer.h
+++ b/components/service/crypto/provider/extension/hash/serializer/hash_provider_serializer.h
@@ -10,7 +10,7 @@
 #include <stddef.h>
 #include <stdint.h>
 #include <psa/crypto.h>
-#include <rpc/common/endpoint/rpc_interface.h>
+#include "components/rpc/common/endpoint/rpc_service_interface.h"
 
 /* Provides a common interface for parameter serialization operations
  * for the hash service provider.
@@ -18,38 +18,38 @@
 struct hash_provider_serializer {
 
 	/* Operation: hash_setup */
-	rpc_status_t (*deserialize_hash_setup_req)(const struct call_param_buf *req_buf,
+	rpc_status_t (*deserialize_hash_setup_req)(const struct rpc_buffer *req_buf,
 		psa_algorithm_t *alg);
 
-	rpc_status_t (*serialize_hash_setup_resp)(struct call_param_buf *resp_buf,
+	rpc_status_t (*serialize_hash_setup_resp)(struct rpc_buffer *resp_buf,
 		uint32_t op_handle);
 
 	/* Operation: hash_update */
-	rpc_status_t (*deserialize_hash_update_req)(const struct call_param_buf *req_buf,
+	rpc_status_t (*deserialize_hash_update_req)(const struct rpc_buffer *req_buf,
 		uint32_t *op_handle,
 		const uint8_t **data, size_t *data_len);
 
 	/* Operation: hash_finish */
-	rpc_status_t (*deserialize_hash_finish_req)(const struct call_param_buf *req_buf,
+	rpc_status_t (*deserialize_hash_finish_req)(const struct rpc_buffer *req_buf,
 		uint32_t *op_handle);
 
-	rpc_status_t (*serialize_hash_finish_resp)(struct call_param_buf *resp_buf,
+	rpc_status_t (*serialize_hash_finish_resp)(struct rpc_buffer *resp_buf,
 		const uint8_t *hash, size_t hash_len);
 
 	/* Operation: hash_abort */
-	rpc_status_t (*deserialize_hash_abort_req)(const struct call_param_buf *req_buf,
+	rpc_status_t (*deserialize_hash_abort_req)(const struct rpc_buffer *req_buf,
 		uint32_t *op_handle);
 
 	/* Operation: hash_verify */
-	rpc_status_t (*deserialize_hash_verify_req)(const struct call_param_buf *req_buf,
+	rpc_status_t (*deserialize_hash_verify_req)(const struct rpc_buffer *req_buf,
 		uint32_t *op_handle,
 		const uint8_t **hash, size_t *hash_len);
 
 	/* Operation: hash_clone */
-	rpc_status_t (*deserialize_hash_clone_req)(const struct call_param_buf *req_buf,
+	rpc_status_t (*deserialize_hash_clone_req)(const struct rpc_buffer *req_buf,
 		uint32_t *source_op_handle);
 
-	rpc_status_t (*serialize_hash_clone_resp)(struct call_param_buf *resp_buf,
+	rpc_status_t (*serialize_hash_clone_resp)(struct rpc_buffer *resp_buf,
 		uint32_t target_op_handle);
 };
 
diff --git a/components/service/crypto/provider/extension/hash/serializer/packed-c/packedc_hash_provider_serializer.c b/components/service/crypto/provider/extension/hash/serializer/packed-c/packedc_hash_provider_serializer.c
index ac0c35e..6f131c5 100644
--- a/components/service/crypto/provider/extension/hash/serializer/packed-c/packedc_hash_provider_serializer.c
+++ b/components/service/crypto/provider/extension/hash/serializer/packed-c/packedc_hash_provider_serializer.c
@@ -11,27 +11,27 @@
 #include "packedc_hash_provider_serializer.h"
 
 /* Operation: hash_setup */
-static rpc_status_t deserialize_hash_setup_req(const struct call_param_buf *req_buf,
+static rpc_status_t deserialize_hash_setup_req(const struct rpc_buffer *req_buf,
 	psa_algorithm_t *alg)
 {
-	rpc_status_t rpc_status = TS_RPC_ERROR_INVALID_REQ_BODY;
+	rpc_status_t rpc_status = RPC_ERROR_INVALID_REQUEST_BODY;
 	struct ts_crypto_hash_setup_in recv_msg;
 	size_t expected_fixed_len = sizeof(struct ts_crypto_hash_setup_in);
 
-	if (expected_fixed_len <= req_buf->data_len) {
+	if (expected_fixed_len <= req_buf->data_length) {
 
 		memcpy(&recv_msg, req_buf->data, expected_fixed_len);
 		*alg = recv_msg.alg;
-		rpc_status = TS_RPC_CALL_ACCEPTED;
+		rpc_status = RPC_SUCCESS;
 	}
 
 	return rpc_status;
 }
 
-static rpc_status_t serialize_hash_setup_resp(struct call_param_buf *resp_buf,
+static rpc_status_t serialize_hash_setup_resp(struct rpc_buffer *resp_buf,
 	uint32_t op_handle)
 {
-	rpc_status_t rpc_status = TS_RPC_ERROR_INTERNAL;
+	rpc_status_t rpc_status = RPC_ERROR_INTERNAL;
 	struct ts_crypto_hash_setup_out resp_msg;
 	size_t fixed_len = sizeof(struct ts_crypto_hash_setup_out);
 
@@ -40,28 +40,28 @@
 	if (fixed_len <= resp_buf->size) {
 
 		memcpy(resp_buf->data, &resp_msg, fixed_len);
-		resp_buf->data_len = fixed_len;
-		rpc_status = TS_RPC_CALL_ACCEPTED;
+		resp_buf->data_length = fixed_len;
+		rpc_status = RPC_SUCCESS;
 	}
 
 	return rpc_status;
 }
 
 /* Operation: hash_update */
-static rpc_status_t deserialize_hash_update_req(const struct call_param_buf *req_buf,
+static rpc_status_t deserialize_hash_update_req(const struct rpc_buffer *req_buf,
 	uint32_t *op_handle,
-	const uint8_t **data, size_t *data_len)
+	const uint8_t **data, size_t *data_length)
 {
-	rpc_status_t rpc_status = TS_RPC_ERROR_INVALID_REQ_BODY;
+	rpc_status_t rpc_status = RPC_ERROR_INVALID_REQUEST_BODY;
 	struct ts_crypto_hash_update_in recv_msg;
 	size_t expected_fixed_len = sizeof(struct ts_crypto_hash_update_in);
 
-	if (expected_fixed_len <= req_buf->data_len) {
+	if (expected_fixed_len <= req_buf->data_length) {
 
 		struct tlv_const_iterator req_iter;
 		struct tlv_record decoded_record;
 
-		rpc_status = TS_RPC_CALL_ACCEPTED;
+		rpc_status = RPC_SUCCESS;
 
 		memcpy(&recv_msg, req_buf->data, expected_fixed_len);
 
@@ -69,16 +69,16 @@
 
 		tlv_const_iterator_begin(&req_iter,
 			(uint8_t*)req_buf->data + expected_fixed_len,
-			req_buf->data_len - expected_fixed_len);
+			req_buf->data_length - expected_fixed_len);
 
 		if (tlv_find_decode(&req_iter, TS_CRYPTO_HASH_UPDATE_IN_TAG_DATA, &decoded_record)) {
 
 			*data = decoded_record.value;
-			*data_len = decoded_record.length;
+			*data_length = decoded_record.length;
 		}
 		else {
 			/* Default to a zero length data */
-			*data_len = 0;
+			*data_length = 0;
 		}
 	}
 
@@ -86,27 +86,27 @@
 }
 
 /* Operation: hash_finish */
-static rpc_status_t deserialize_hash_finish_req(const struct call_param_buf *req_buf,
+static rpc_status_t deserialize_hash_finish_req(const struct rpc_buffer *req_buf,
 	uint32_t *op_handle)
 {
-	rpc_status_t rpc_status = TS_RPC_ERROR_INVALID_REQ_BODY;
+	rpc_status_t rpc_status = RPC_ERROR_INVALID_REQUEST_BODY;
 	struct ts_crypto_hash_finish_in recv_msg;
 	size_t expected_fixed_len = sizeof(struct ts_crypto_hash_finish_in);
 
-	if (expected_fixed_len <= req_buf->data_len) {
+	if (expected_fixed_len <= req_buf->data_length) {
 
 		memcpy(&recv_msg, req_buf->data, expected_fixed_len);
 		*op_handle = recv_msg.op_handle;
-		rpc_status = TS_RPC_CALL_ACCEPTED;
+		rpc_status = RPC_SUCCESS;
 	}
 
 	return rpc_status;
 }
 
-static rpc_status_t serialize_hash_finish_resp(struct call_param_buf *resp_buf,
+static rpc_status_t serialize_hash_finish_resp(struct rpc_buffer *resp_buf,
 	const uint8_t *hash, size_t hash_len)
 {
-	rpc_status_t rpc_status = TS_RPC_ERROR_INTERNAL;
+	rpc_status_t rpc_status = RPC_ERROR_INTERNAL;
 	struct tlv_iterator resp_iter;
 
 	struct tlv_record out_record;
@@ -118,46 +118,46 @@
 
 	if (tlv_encode(&resp_iter, &out_record)) {
 
-		resp_buf->data_len = tlv_required_space(hash_len);
-		rpc_status = TS_RPC_CALL_ACCEPTED;
+		resp_buf->data_length = tlv_required_space(hash_len);
+		rpc_status = RPC_SUCCESS;
 	}
 
 	return rpc_status;
 }
 
 /* Operation: hash_abort */
-static rpc_status_t deserialize_hash_abort_req(const struct call_param_buf *req_buf,
+static rpc_status_t deserialize_hash_abort_req(const struct rpc_buffer *req_buf,
 	uint32_t *op_handle)
 {
-	rpc_status_t rpc_status = TS_RPC_ERROR_INVALID_REQ_BODY;
+	rpc_status_t rpc_status = RPC_ERROR_INVALID_REQUEST_BODY;
 	struct ts_crypto_hash_abort_in recv_msg;
 	size_t expected_fixed_len = sizeof(struct ts_crypto_hash_abort_in);
 
-	if (expected_fixed_len <= req_buf->data_len) {
+	if (expected_fixed_len <= req_buf->data_length) {
 
 		memcpy(&recv_msg, req_buf->data, expected_fixed_len);
 		*op_handle = recv_msg.op_handle;
-		rpc_status = TS_RPC_CALL_ACCEPTED;
+		rpc_status = RPC_SUCCESS;
 	}
 
 	return rpc_status;
 }
 
 /* Operation: hash_verify */
-static rpc_status_t deserialize_hash_verify_req(const struct call_param_buf *req_buf,
+static rpc_status_t deserialize_hash_verify_req(const struct rpc_buffer *req_buf,
 	uint32_t *op_handle,
 	const uint8_t **hash, size_t *hash_len)
 {
-	rpc_status_t rpc_status = TS_RPC_ERROR_INVALID_REQ_BODY;
+	rpc_status_t rpc_status = RPC_ERROR_INVALID_REQUEST_BODY;
 	struct ts_crypto_hash_verify_in recv_msg;
 	size_t expected_fixed_len = sizeof(struct ts_crypto_hash_verify_in);
 
-	if (expected_fixed_len <= req_buf->data_len) {
+	if (expected_fixed_len <= req_buf->data_length) {
 
 		struct tlv_const_iterator req_iter;
 		struct tlv_record decoded_record;
 
-		rpc_status = TS_RPC_CALL_ACCEPTED;
+		rpc_status = RPC_SUCCESS;
 
 		memcpy(&recv_msg, req_buf->data, expected_fixed_len);
 
@@ -165,7 +165,7 @@
 
 		tlv_const_iterator_begin(&req_iter,
 			(uint8_t*)req_buf->data + expected_fixed_len,
-			req_buf->data_len - expected_fixed_len);
+			req_buf->data_length - expected_fixed_len);
 
 		if (tlv_find_decode(&req_iter, TS_CRYPTO_HASH_VERIFY_IN_TAG_HASH, &decoded_record)) {
 
@@ -182,27 +182,27 @@
 }
 
 /* Operation: hash_clone */
-static rpc_status_t deserialize_hash_clone_req(const struct call_param_buf *req_buf,
+static rpc_status_t deserialize_hash_clone_req(const struct rpc_buffer *req_buf,
 	uint32_t *source_op_handle)
 {
-	rpc_status_t rpc_status = TS_RPC_ERROR_INVALID_REQ_BODY;
+	rpc_status_t rpc_status = RPC_ERROR_INVALID_REQUEST_BODY;
 	struct ts_crypto_hash_clone_in recv_msg;
 	size_t expected_fixed_len = sizeof(struct ts_crypto_hash_clone_in);
 
-	if (expected_fixed_len <= req_buf->data_len) {
+	if (expected_fixed_len <= req_buf->data_length) {
 
 		memcpy(&recv_msg, req_buf->data, expected_fixed_len);
 		*source_op_handle = recv_msg.source_op_handle;
-		rpc_status = TS_RPC_CALL_ACCEPTED;
+		rpc_status = RPC_SUCCESS;
 	}
 
 	return rpc_status;
 }
 
-static rpc_status_t serialize_hash_clone_resp(struct call_param_buf *resp_buf,
+static rpc_status_t serialize_hash_clone_resp(struct rpc_buffer *resp_buf,
 	uint32_t target_op_handle)
 {
-	rpc_status_t rpc_status = TS_RPC_ERROR_INTERNAL;
+	rpc_status_t rpc_status = RPC_ERROR_INTERNAL;
 	struct ts_crypto_hash_clone_out resp_msg;
 	size_t fixed_len = sizeof(struct ts_crypto_hash_clone_out);
 
@@ -211,8 +211,8 @@
 	if (fixed_len <= resp_buf->size) {
 
 		memcpy(resp_buf->data, &resp_msg, fixed_len);
-		resp_buf->data_len = fixed_len;
-		rpc_status = TS_RPC_CALL_ACCEPTED;
+		resp_buf->data_length = fixed_len;
+		rpc_status = RPC_SUCCESS;
 	}
 
 	return rpc_status;
diff --git a/components/service/crypto/provider/extension/key_derivation/key_derivation_provider.c b/components/service/crypto/provider/extension/key_derivation/key_derivation_provider.c
index aebcf92..9503f7c 100644
--- a/components/service/crypto/provider/extension/key_derivation/key_derivation_provider.c
+++ b/components/service/crypto/provider/extension/key_derivation/key_derivation_provider.c
@@ -11,16 +11,17 @@
 #include <psa/crypto.h>
 
 /* Service request handlers */
-static rpc_status_t key_derivation_setup_handler(void *context, struct call_req* req);
-static rpc_status_t key_derivation_get_capacity_handler(void *context, struct call_req* req);
-static rpc_status_t key_derivation_set_capacity_handler(void *context, struct call_req* req);
-static rpc_status_t key_derivation_input_bytes_handler(void *context, struct call_req* req);
-static rpc_status_t key_derivation_input_key_handler(void *context, struct call_req* req);
-static rpc_status_t key_derivation_output_bytes_handler(void *context, struct call_req* req);
-static rpc_status_t key_derivation_output_key_handler(void *context, struct call_req* req);
-static rpc_status_t key_derivation_abort_handler(void *context, struct call_req* req);
-static rpc_status_t key_derivation_key_agreement_handler(void *context, struct call_req* req);
-static rpc_status_t key_derivation_raw_key_agreement_handler(void *context, struct call_req* req);
+static rpc_status_t key_derivation_setup_handler(void *context, struct rpc_request *req);
+static rpc_status_t key_derivation_get_capacity_handler(void *context, struct rpc_request *req);
+static rpc_status_t key_derivation_set_capacity_handler(void *context, struct rpc_request *req);
+static rpc_status_t key_derivation_input_bytes_handler(void *context, struct rpc_request *req);
+static rpc_status_t key_derivation_input_key_handler(void *context, struct rpc_request *req);
+static rpc_status_t key_derivation_output_bytes_handler(void *context, struct rpc_request *req);
+static rpc_status_t key_derivation_output_key_handler(void *context, struct rpc_request *req);
+static rpc_status_t key_derivation_abort_handler(void *context, struct rpc_request *req);
+static rpc_status_t key_derivation_key_agreement_handler(void *context, struct rpc_request *req);
+static rpc_status_t key_derivation_raw_key_agreement_handler(void *context,
+							     struct rpc_request *req);
 
 /* Handler mapping table for service */
 static const struct service_handler handler_table[] = {
@@ -38,12 +39,14 @@
 
 void key_derivation_provider_init(struct key_derivation_provider *context)
 {
+	const struct rpc_uuid nil_uuid = { 0 };
+
 	crypto_context_pool_init(&context->context_pool);
 
 	for (size_t encoding = 0; encoding < TS_RPC_ENCODING_LIMIT; ++encoding)
 		context->serializers[encoding] = NULL;
 
-	service_provider_init(&context->base_provider, context,
+	service_provider_init(&context->base_provider, context, &nil_uuid,
 		handler_table, sizeof(handler_table)/sizeof(struct service_handler));
 }
 
@@ -60,21 +63,18 @@
 }
 
 static const struct key_derivation_provider_serializer* get_serializer(void *context,
-	const struct call_req *req)
+	const struct rpc_request *req)
 {
 	struct key_derivation_provider *this_instance = (struct key_derivation_provider*)context;
-	const struct key_derivation_provider_serializer* serializer = NULL;
-	unsigned int encoding = call_req_get_encoding(req);
+	unsigned int encoding = 0; /* No other encodings supported */
 
-	if (encoding < TS_RPC_ENCODING_LIMIT) serializer = this_instance->serializers[encoding];
-
-	return serializer;
+	return this_instance->serializers[encoding];
 }
 
-static rpc_status_t key_derivation_setup_handler(void *context, struct call_req* req)
+static rpc_status_t key_derivation_setup_handler(void *context, struct rpc_request *req)
 {
-	rpc_status_t rpc_status = TS_RPC_ERROR_SERIALIZATION_NOT_SUPPORTED;
-	struct call_param_buf *req_buf = call_req_get_req_buf(req);
+	rpc_status_t rpc_status = RPC_ERROR_INTERNAL;
+	struct rpc_buffer *req_buf = &req->request;
 	const struct key_derivation_provider_serializer *serializer = get_serializer(context, req);
 	struct key_derivation_provider *this_instance = (struct key_derivation_provider*)context;
 
@@ -83,13 +83,13 @@
 	if (serializer)
 		rpc_status = serializer->deserialize_key_derivation_setup_req(req_buf, &alg);
 
-	if (rpc_status == TS_RPC_CALL_ACCEPTED) {
+	if (rpc_status == RPC_SUCCESS) {
 
 		uint32_t op_handle;
 
 		struct crypto_context *crypto_context =
 			crypto_context_pool_alloc(&this_instance->context_pool,
-				CRYPTO_CONTEXT_OP_ID_KEY_DERIVATION, call_req_get_caller_id(req),
+				CRYPTO_CONTEXT_OP_ID_KEY_DERIVATION, req->source_id,
 				&op_handle);
 
 		if (crypto_context) {
@@ -101,30 +101,28 @@
 
 			if (psa_status == PSA_SUCCESS) {
 
-				struct call_param_buf *resp_buf = call_req_get_resp_buf(req);
+				struct rpc_buffer *resp_buf = &req->response;
 				rpc_status = serializer->serialize_key_derivation_setup_resp(resp_buf, op_handle);
 			}
 
-			if ((psa_status != PSA_SUCCESS) || (rpc_status != TS_RPC_CALL_ACCEPTED)) {
-
+			if ((psa_status != PSA_SUCCESS) || (rpc_status != RPC_SUCCESS))
 				crypto_context_pool_free(&this_instance->context_pool, crypto_context);
-			}
 
-			call_req_set_opstatus(req, psa_status);
+			req->service_status = psa_status;
 		}
 		else {
 			/* Failed to allocate crypto context for transaction */
-			rpc_status = TS_RPC_ERROR_RESOURCE_FAILURE;
+			rpc_status = RPC_ERROR_RESOURCE_FAILURE;
 		}
 	}
 
 	return rpc_status;
 }
 
-static rpc_status_t key_derivation_get_capacity_handler(void *context, struct call_req* req)
+static rpc_status_t key_derivation_get_capacity_handler(void *context, struct rpc_request *req)
 {
-	rpc_status_t rpc_status = TS_RPC_ERROR_SERIALIZATION_NOT_SUPPORTED;
-	struct call_param_buf *req_buf = call_req_get_req_buf(req);
+	rpc_status_t rpc_status = RPC_ERROR_INTERNAL;
+	struct rpc_buffer *req_buf = &req->request;
 	const struct key_derivation_provider_serializer *serializer = get_serializer(context, req);
 	struct key_derivation_provider *this_instance = (struct key_derivation_provider*)context;
 
@@ -133,13 +131,13 @@
 	if (serializer)
 		rpc_status = serializer->deserialize_key_derivation_get_capacity_req(req_buf, &op_handle);
 
-	if (rpc_status == TS_RPC_CALL_ACCEPTED) {
+	if (rpc_status == RPC_SUCCESS) {
 
 		psa_status_t psa_status = PSA_ERROR_BAD_STATE;
 
 		struct crypto_context *crypto_context =
 			crypto_context_pool_find(&this_instance->context_pool,
-				CRYPTO_CONTEXT_OP_ID_KEY_DERIVATION, call_req_get_caller_id(req),
+				CRYPTO_CONTEXT_OP_ID_KEY_DERIVATION, req->source_id,
 				op_handle);
 
 		if (crypto_context) {
@@ -151,22 +149,22 @@
 
 			if (psa_status == PSA_SUCCESS) {
 
-				struct call_param_buf *resp_buf = call_req_get_resp_buf(req);
+				struct rpc_buffer *resp_buf = &req->response;
 				rpc_status = serializer->serialize_key_derivation_get_capacity_resp(resp_buf,
 					capacity);
 			}
 		}
 
-		call_req_set_opstatus(req, psa_status);
+		req->service_status = psa_status;
 	}
 
 	return rpc_status;
 }
 
-static rpc_status_t key_derivation_set_capacity_handler(void *context, struct call_req* req)
+static rpc_status_t key_derivation_set_capacity_handler(void *context, struct rpc_request *req)
 {
-	rpc_status_t rpc_status = TS_RPC_ERROR_SERIALIZATION_NOT_SUPPORTED;
-	struct call_param_buf *req_buf = call_req_get_req_buf(req);
+	rpc_status_t rpc_status = RPC_ERROR_INTERNAL;
+	struct rpc_buffer *req_buf = &req->request;
 	const struct key_derivation_provider_serializer *serializer = get_serializer(context, req);
 	struct key_derivation_provider *this_instance = (struct key_derivation_provider*)context;
 
@@ -177,13 +175,13 @@
 		rpc_status = serializer->deserialize_key_derivation_set_capacity_req(req_buf,
 			&op_handle, &capacity);
 
-	if (rpc_status == TS_RPC_CALL_ACCEPTED) {
+	if (rpc_status == RPC_SUCCESS) {
 
 		psa_status_t psa_status = PSA_ERROR_BAD_STATE;
 
 		struct crypto_context *crypto_context =
 			crypto_context_pool_find(&this_instance->context_pool,
-				CRYPTO_CONTEXT_OP_ID_KEY_DERIVATION, call_req_get_caller_id(req),
+				CRYPTO_CONTEXT_OP_ID_KEY_DERIVATION, req->source_id,
 				op_handle);
 
 		if (crypto_context) {
@@ -192,16 +190,16 @@
 				capacity);
 		}
 
-		call_req_set_opstatus(req, psa_status);
+		req->service_status = psa_status;
 	}
 
 	return rpc_status;
 }
 
-static rpc_status_t key_derivation_input_bytes_handler(void *context, struct call_req* req)
+static rpc_status_t key_derivation_input_bytes_handler(void *context, struct rpc_request *req)
 {
-	rpc_status_t rpc_status = TS_RPC_ERROR_SERIALIZATION_NOT_SUPPORTED;
-	struct call_param_buf *req_buf = call_req_get_req_buf(req);
+	rpc_status_t rpc_status = RPC_ERROR_INTERNAL;
+	struct rpc_buffer *req_buf = &req->request;
 	const struct key_derivation_provider_serializer *serializer = get_serializer(context, req);
 	struct key_derivation_provider *this_instance = (struct key_derivation_provider*)context;
 
@@ -214,13 +212,13 @@
 		rpc_status = serializer->deserialize_key_derivation_input_bytes_req(req_buf,
 			&op_handle, &step, &data, &data_len);
 
-	if (rpc_status == TS_RPC_CALL_ACCEPTED) {
+	if (rpc_status == RPC_SUCCESS) {
 
 		psa_status_t psa_status = PSA_ERROR_BAD_STATE;
 
 		struct crypto_context *crypto_context =
 			crypto_context_pool_find(&this_instance->context_pool,
-				CRYPTO_CONTEXT_OP_ID_KEY_DERIVATION, call_req_get_caller_id(req),
+				CRYPTO_CONTEXT_OP_ID_KEY_DERIVATION, req->source_id,
 				op_handle);
 
 		if (crypto_context) {
@@ -229,16 +227,16 @@
 				step, data, data_len);
 		}
 
-		call_req_set_opstatus(req, psa_status);
+		req->service_status = psa_status;
 	}
 
 	return rpc_status;
 }
 
-static rpc_status_t key_derivation_input_key_handler(void *context, struct call_req* req)
+static rpc_status_t key_derivation_input_key_handler(void *context, struct rpc_request *req)
 {
-	rpc_status_t rpc_status = TS_RPC_ERROR_SERIALIZATION_NOT_SUPPORTED;
-	struct call_param_buf *req_buf = call_req_get_req_buf(req);
+	rpc_status_t rpc_status = RPC_ERROR_INTERNAL;
+	struct rpc_buffer *req_buf = &req->request;
 	const struct key_derivation_provider_serializer *serializer = get_serializer(context, req);
 	struct key_derivation_provider *this_instance = (struct key_derivation_provider*)context;
 
@@ -250,7 +248,7 @@
 		rpc_status = serializer->deserialize_key_derivation_input_key_req(req_buf,
 			&op_handle, &step, &key_id);
 
-	if (rpc_status == TS_RPC_CALL_ACCEPTED) {
+	if (rpc_status == RPC_SUCCESS) {
 
 		psa_status_t psa_status = PSA_ERROR_INVALID_HANDLE;
 
@@ -260,7 +258,7 @@
 
 			struct crypto_context *crypto_context =
 				crypto_context_pool_find(&this_instance->context_pool,
-					CRYPTO_CONTEXT_OP_ID_KEY_DERIVATION, call_req_get_caller_id(req),
+					CRYPTO_CONTEXT_OP_ID_KEY_DERIVATION, req->source_id,
 					op_handle);
 
 			if (crypto_context) {
@@ -270,16 +268,16 @@
 			}
 		}
 
-		call_req_set_opstatus(req, psa_status);
+		req->service_status = psa_status;
 	}
 
 	return rpc_status;
 }
 
-static rpc_status_t key_derivation_output_bytes_handler(void *context, struct call_req* req)
+static rpc_status_t key_derivation_output_bytes_handler(void *context, struct rpc_request *req)
 {
-	rpc_status_t rpc_status = TS_RPC_ERROR_SERIALIZATION_NOT_SUPPORTED;
-	struct call_param_buf *req_buf = call_req_get_req_buf(req);
+	rpc_status_t rpc_status = RPC_ERROR_INTERNAL;
+	struct rpc_buffer *req_buf = &req->request;
 	const struct key_derivation_provider_serializer *serializer = get_serializer(context, req);
 	struct key_derivation_provider *this_instance = (struct key_derivation_provider*)context;
 
@@ -290,13 +288,13 @@
 		rpc_status = serializer->deserialize_key_derivation_output_bytes_req(req_buf,
 			&op_handle, &output_len);
 
-	if (rpc_status == TS_RPC_CALL_ACCEPTED) {
+	if (rpc_status == RPC_SUCCESS) {
 
 		psa_status_t psa_status = PSA_ERROR_BAD_STATE;
 
 		struct crypto_context *crypto_context =
 			crypto_context_pool_find(&this_instance->context_pool,
-				CRYPTO_CONTEXT_OP_ID_KEY_DERIVATION, call_req_get_caller_id(req),
+				CRYPTO_CONTEXT_OP_ID_KEY_DERIVATION, req->source_id,
 				op_handle);
 
 		if (crypto_context) {
@@ -310,7 +308,7 @@
 
 				if (psa_status == PSA_SUCCESS) {
 
-					struct call_param_buf *resp_buf = call_req_get_resp_buf(req);
+					struct rpc_buffer *resp_buf = &req->response;
 					rpc_status = serializer->serialize_key_derivation_output_bytes_resp(resp_buf,
 						output, output_len);
 				}
@@ -323,16 +321,16 @@
 			}
 		}
 
-		call_req_set_opstatus(req, psa_status);
+		req->service_status = psa_status;
 	}
 
 	return rpc_status;
 }
 
-static rpc_status_t key_derivation_output_key_handler(void *context, struct call_req* req)
+static rpc_status_t key_derivation_output_key_handler(void *context, struct rpc_request *req)
 {
-	rpc_status_t rpc_status = TS_RPC_ERROR_SERIALIZATION_NOT_SUPPORTED;
-	struct call_param_buf *req_buf = call_req_get_req_buf(req);
+	rpc_status_t rpc_status = RPC_ERROR_INTERNAL;
+	struct rpc_buffer *req_buf = &req->request;
 	const struct key_derivation_provider_serializer *serializer = get_serializer(context, req);
 	struct key_derivation_provider *this_instance = (struct key_derivation_provider*)context;
 
@@ -343,13 +341,13 @@
 		rpc_status = serializer->deserialize_key_derivation_output_key_req(req_buf,
 			&op_handle, &attributes);
 
-	if (rpc_status == TS_RPC_CALL_ACCEPTED) {
+	if (rpc_status == RPC_SUCCESS) {
 
 		psa_status_t psa_status = PSA_ERROR_BAD_STATE;
 
 		struct crypto_context *crypto_context =
 			crypto_context_pool_find(&this_instance->context_pool,
-				CRYPTO_CONTEXT_OP_ID_KEY_DERIVATION, call_req_get_caller_id(req),
+				CRYPTO_CONTEXT_OP_ID_KEY_DERIVATION, req->source_id,
 				op_handle);
 
 		if (crypto_context) {
@@ -362,13 +360,13 @@
 
 			if (psa_status == PSA_SUCCESS) {
 
-				struct call_param_buf *resp_buf = call_req_get_resp_buf(req);
+				struct rpc_buffer *resp_buf = &req->response;
 				rpc_status = serializer->serialize_key_derivation_output_key_resp(resp_buf,
 					key_id);
 			}
 		}
 
-		call_req_set_opstatus(req, psa_status);
+		req->service_status = psa_status;
 	}
 
 	psa_reset_key_attributes(&attributes);
@@ -376,10 +374,10 @@
 	return rpc_status;
 }
 
-static rpc_status_t key_derivation_abort_handler(void *context, struct call_req* req)
+static rpc_status_t key_derivation_abort_handler(void *context, struct rpc_request *req)
 {
-	rpc_status_t rpc_status = TS_RPC_ERROR_SERIALIZATION_NOT_SUPPORTED;
-	struct call_param_buf *req_buf = call_req_get_req_buf(req);
+	rpc_status_t rpc_status = RPC_ERROR_INTERNAL;
+	struct rpc_buffer *req_buf = &req->request;
 	const struct key_derivation_provider_serializer *serializer = get_serializer(context, req);
 	struct key_derivation_provider *this_instance = (struct key_derivation_provider*)context;
 
@@ -388,7 +386,7 @@
 	if (serializer)
 		rpc_status = serializer->deserialize_key_derivation_abort_req(req_buf, &op_handle);
 
-	if (rpc_status == TS_RPC_CALL_ACCEPTED) {
+	if (rpc_status == RPC_SUCCESS) {
 
 		/* Return success if operation is no longer active and
 		 * doesn't need aborting.
@@ -397,7 +395,7 @@
 
 		struct crypto_context *crypto_context =
 			crypto_context_pool_find(&this_instance->context_pool,
-				CRYPTO_CONTEXT_OP_ID_KEY_DERIVATION, call_req_get_caller_id(req),
+				CRYPTO_CONTEXT_OP_ID_KEY_DERIVATION, req->source_id,
 				op_handle);
 
 		if (crypto_context) {
@@ -406,16 +404,16 @@
 			crypto_context_pool_free(&this_instance->context_pool, crypto_context);
 		}
 
-		call_req_set_opstatus(req, psa_status);
+		req->service_status = psa_status;
 	}
 
 	return rpc_status;
 }
 
-static rpc_status_t key_derivation_key_agreement_handler(void *context, struct call_req* req)
+static rpc_status_t key_derivation_key_agreement_handler(void *context, struct rpc_request *req)
 {
-	rpc_status_t rpc_status = TS_RPC_ERROR_SERIALIZATION_NOT_SUPPORTED;
-	struct call_param_buf *req_buf = call_req_get_req_buf(req);
+	rpc_status_t rpc_status = RPC_ERROR_INTERNAL;
+	struct rpc_buffer *req_buf = &req->request;
 	const struct key_derivation_provider_serializer *serializer = get_serializer(context, req);
 	struct key_derivation_provider *this_instance = (struct key_derivation_provider*)context;
 
@@ -429,13 +427,13 @@
 		rpc_status = serializer->deserialize_key_derivation_key_agreement_req(req_buf,
 			&op_handle, &step, &private_key_id, &peer_key, &peer_key_len);
 
-	if (rpc_status == TS_RPC_CALL_ACCEPTED) {
+	if (rpc_status == RPC_SUCCESS) {
 
 		psa_status_t psa_status = PSA_ERROR_BAD_STATE;
 
 		struct crypto_context *crypto_context =
 			crypto_context_pool_find(&this_instance->context_pool,
-				CRYPTO_CONTEXT_OP_ID_KEY_DERIVATION, call_req_get_caller_id(req),
+				CRYPTO_CONTEXT_OP_ID_KEY_DERIVATION, req->source_id,
 				op_handle);
 
 		if (crypto_context) {
@@ -444,16 +442,16 @@
 				step, private_key_id, peer_key, peer_key_len);
 		}
 
-		call_req_set_opstatus(req, psa_status);
+		req->service_status = psa_status;
 	}
 
 	return rpc_status;
 }
 
-static rpc_status_t key_derivation_raw_key_agreement_handler(void *context, struct call_req* req)
+static rpc_status_t key_derivation_raw_key_agreement_handler(void *context, struct rpc_request *req)
 {
-	rpc_status_t rpc_status = TS_RPC_ERROR_SERIALIZATION_NOT_SUPPORTED;
-	struct call_param_buf *req_buf = call_req_get_req_buf(req);
+	rpc_status_t rpc_status = RPC_ERROR_INTERNAL;
+	struct rpc_buffer *req_buf = &req->request;
 	const struct key_derivation_provider_serializer *serializer = get_serializer(context, req);
 
 	psa_algorithm_t alg;
@@ -465,7 +463,7 @@
 		rpc_status = serializer->deserialize_key_derivation_raw_key_agreement_req(req_buf,
 			&alg, &private_key_id, &peer_key, &peer_key_len);
 
-	if (rpc_status == TS_RPC_CALL_ACCEPTED) {
+	if (rpc_status == RPC_SUCCESS) {
 
 		size_t output_len;
 		uint8_t output[PSA_RAW_KEY_AGREEMENT_OUTPUT_MAX_SIZE];
@@ -476,12 +474,12 @@
 
 		if (psa_status == PSA_SUCCESS) {
 
-			struct call_param_buf *resp_buf = call_req_get_resp_buf(req);
+			struct rpc_buffer *resp_buf = &req->response;
 			rpc_status = serializer->serialize_key_derivation_raw_key_agreement_resp(resp_buf,
 				output, output_len);
 		}
 
-		call_req_set_opstatus(req, psa_status);
+		req->service_status = psa_status;
 	}
 
 	return rpc_status;
diff --git a/components/service/crypto/provider/extension/key_derivation/key_derivation_provider.h b/components/service/crypto/provider/extension/key_derivation/key_derivation_provider.h
index 1ac07f2..0abaed6 100644
--- a/components/service/crypto/provider/extension/key_derivation/key_derivation_provider.h
+++ b/components/service/crypto/provider/extension/key_derivation/key_derivation_provider.h
@@ -7,7 +7,7 @@
 #ifndef KEY_DERIVATION_PROVIDER_H
 #define KEY_DERIVATION_PROVIDER_H
 
-#include <rpc/common/endpoint/rpc_interface.h>
+#include "components/rpc/common/endpoint/rpc_service_interface.h"
 #include <service/common/provider/service_provider.h>
 #include <service/crypto/provider/extension/key_derivation/serializer/key_derivation_provider_serializer.h>
 #include <service/crypto/provider/crypto_context_pool.h>
diff --git a/components/service/crypto/provider/extension/key_derivation/serializer/key_derivation_provider_serializer.h b/components/service/crypto/provider/extension/key_derivation/serializer/key_derivation_provider_serializer.h
index 4bbeb41..bff1a64 100644
--- a/components/service/crypto/provider/extension/key_derivation/serializer/key_derivation_provider_serializer.h
+++ b/components/service/crypto/provider/extension/key_derivation/serializer/key_derivation_provider_serializer.h
@@ -10,7 +10,7 @@
 #include <stddef.h>
 #include <stdint.h>
 #include <psa/crypto.h>
-#include <rpc/common/endpoint/rpc_interface.h>
+#include "components/rpc/common/endpoint/rpc_service_interface.h"
 
 /* Provides a common interface for parameter serialization operations
  * for the key_derivation service provider.
@@ -18,70 +18,70 @@
 struct key_derivation_provider_serializer {
 
 	/* Operation: key_derivation_setup */
-	rpc_status_t (*deserialize_key_derivation_setup_req)(const struct call_param_buf *req_buf,
+	rpc_status_t (*deserialize_key_derivation_setup_req)(const struct rpc_buffer *req_buf,
 		psa_algorithm_t *alg);
 
-	rpc_status_t (*serialize_key_derivation_setup_resp)(struct call_param_buf *resp_buf,
+	rpc_status_t (*serialize_key_derivation_setup_resp)(struct rpc_buffer *resp_buf,
 		uint32_t op_handle);
 
 	/* Operation: key_derivation_get_capacity */
-	rpc_status_t (*deserialize_key_derivation_get_capacity_req)(const struct call_param_buf *req_buf,
-		uint32_t *op_handle);
+	rpc_status_t (*deserialize_key_derivation_get_capacity_req)(
+		const struct rpc_buffer *req_buf, uint32_t *op_handle);
 
-	rpc_status_t (*serialize_key_derivation_get_capacity_resp)(struct call_param_buf *resp_buf,
+	rpc_status_t (*serialize_key_derivation_get_capacity_resp)(struct rpc_buffer *resp_buf,
 		size_t capacity);
 
 	/* Operation: key_derivation_set_capacity */
-	rpc_status_t (*deserialize_key_derivation_set_capacity_req)(const struct call_param_buf *req_buf,
-		uint32_t *op_handle,
-		size_t *capacity);
+	rpc_status_t (*deserialize_key_derivation_set_capacity_req)(
+		const struct rpc_buffer *req_buf, uint32_t *op_handle, size_t *capacity);
 
 	/* Operation: key_derivation_input_bytes */
-	rpc_status_t (*deserialize_key_derivation_input_bytes_req)(const struct call_param_buf *req_buf,
+	rpc_status_t (*deserialize_key_derivation_input_bytes_req)(const struct rpc_buffer *req_buf,
 		uint32_t *op_handle,
 		psa_key_derivation_step_t *step,
 		const uint8_t **data, size_t *data_len);
 
 	/* Operation: key_derivation_input_key */
-	rpc_status_t (*deserialize_key_derivation_input_key_req)(const struct call_param_buf *req_buf,
+	rpc_status_t (*deserialize_key_derivation_input_key_req)(const struct rpc_buffer *req_buf,
 		uint32_t *op_handle,
 		psa_key_derivation_step_t *step,
 		psa_key_id_t *key_id);
 
 	/* Operation: key_derivation_output_bytes */
-	rpc_status_t (*deserialize_key_derivation_output_bytes_req)(const struct call_param_buf *req_buf,
-		uint32_t *op_handle,
-		size_t *output_len);
+	rpc_status_t (*deserialize_key_derivation_output_bytes_req)(
+		const struct rpc_buffer *req_buf, uint32_t *op_handle, size_t *output_len);
 
-	rpc_status_t (*serialize_key_derivation_output_bytes_resp)(struct call_param_buf *resp_buf,
+	rpc_status_t (*serialize_key_derivation_output_bytes_resp)(struct rpc_buffer *resp_buf,
 		const uint8_t *data, size_t data_len);
 
 	/* Operation: key_derivation_output_key */
-	rpc_status_t (*deserialize_key_derivation_output_key_req)(const struct call_param_buf *req_buf,
+	rpc_status_t (*deserialize_key_derivation_output_key_req)(const struct rpc_buffer *req_buf,
 		uint32_t *op_handle,
 		psa_key_attributes_t *attributes);
 
-	rpc_status_t (*serialize_key_derivation_output_key_resp)(struct call_param_buf *resp_buf,
+	rpc_status_t (*serialize_key_derivation_output_key_resp)(struct rpc_buffer *resp_buf,
 		psa_key_id_t key_id);
 
 	/* Operation: key_derivation_abort */
-	rpc_status_t (*deserialize_key_derivation_abort_req)(const struct call_param_buf *req_buf,
+	rpc_status_t (*deserialize_key_derivation_abort_req)(const struct rpc_buffer *req_buf,
 		uint32_t *op_handle);
 
 	/* Operation: key_derivation_key_agreement */
-	rpc_status_t (*deserialize_key_derivation_key_agreement_req)(const struct call_param_buf *req_buf,
+	rpc_status_t (*deserialize_key_derivation_key_agreement_req)(
+		const struct rpc_buffer *req_buf,
 		uint32_t *op_handle,
 		psa_key_derivation_step_t *step,
 		psa_key_id_t *private_key_id,
 		const uint8_t **peer_key, size_t *peer_key_len);
 
 	/* Operation: key_derivation_raw_key_agreement */
-	rpc_status_t (*deserialize_key_derivation_raw_key_agreement_req)(const struct call_param_buf *req_buf,
+	rpc_status_t (*deserialize_key_derivation_raw_key_agreement_req)(
+		const struct rpc_buffer *req_buf,
 		psa_algorithm_t *alg,
 		psa_key_id_t *private_key_id,
 		const uint8_t **peer_key, size_t *peer_key_len);
 
-	rpc_status_t (*serialize_key_derivation_raw_key_agreement_resp)(struct call_param_buf *resp_buf,
+	rpc_status_t (*serialize_key_derivation_raw_key_agreement_resp)(struct rpc_buffer *resp_buf,
 		const uint8_t *output, size_t output_len);
 };
 
diff --git a/components/service/crypto/provider/extension/key_derivation/serializer/packed-c/packedc_key_derivation_provider_serializer.c b/components/service/crypto/provider/extension/key_derivation/serializer/packed-c/packedc_key_derivation_provider_serializer.c
index 0d92f50..03bb3dc 100644
--- a/components/service/crypto/provider/extension/key_derivation/serializer/packed-c/packedc_key_derivation_provider_serializer.c
+++ b/components/service/crypto/provider/extension/key_derivation/serializer/packed-c/packedc_key_derivation_provider_serializer.c
@@ -13,28 +13,28 @@
 
 /* Operation: key_derivation_setup */
 static rpc_status_t deserialize_key_derivation_setup_req(
-	const struct call_param_buf *req_buf,
+	const struct rpc_buffer *req_buf,
 	psa_algorithm_t *alg)
 {
-	rpc_status_t rpc_status = TS_RPC_ERROR_INVALID_REQ_BODY;
+	rpc_status_t rpc_status = RPC_ERROR_INVALID_REQUEST_BODY;
 	struct ts_crypto_key_derivation_setup_in recv_msg;
 	size_t expected_fixed_len = sizeof(struct ts_crypto_key_derivation_setup_in);
 
-	if (expected_fixed_len <= req_buf->data_len) {
+	if (expected_fixed_len <= req_buf->data_length) {
 
 		memcpy(&recv_msg, req_buf->data, expected_fixed_len);
 		*alg = recv_msg.alg;
-		rpc_status = TS_RPC_CALL_ACCEPTED;
+		rpc_status = RPC_SUCCESS;
 	}
 
 	return rpc_status;
 }
 
 static rpc_status_t serialize_key_derivation_setup_resp(
-	struct call_param_buf *resp_buf,
+	struct rpc_buffer *resp_buf,
 	uint32_t op_handle)
 {
-	rpc_status_t rpc_status = TS_RPC_ERROR_INTERNAL;
+	rpc_status_t rpc_status = RPC_ERROR_INTERNAL;
 	struct ts_crypto_key_derivation_setup_out resp_msg;
 	size_t fixed_len = sizeof(struct ts_crypto_key_derivation_setup_out);
 
@@ -43,8 +43,8 @@
 	if (fixed_len <= resp_buf->size) {
 
 		memcpy(resp_buf->data, &resp_msg, fixed_len);
-		resp_buf->data_len = fixed_len;
-		rpc_status = TS_RPC_CALL_ACCEPTED;
+		resp_buf->data_length = fixed_len;
+		rpc_status = RPC_SUCCESS;
 	}
 
 	return rpc_status;
@@ -52,28 +52,28 @@
 
 /* Operation: key_derivation_get_capacity */
 static rpc_status_t deserialize_key_derivation_get_capacity_req(
-	const struct call_param_buf *req_buf,
+	const struct rpc_buffer *req_buf,
 	uint32_t *op_handle)
 {
-	rpc_status_t rpc_status = TS_RPC_ERROR_INVALID_REQ_BODY;
+	rpc_status_t rpc_status = RPC_ERROR_INVALID_REQUEST_BODY;
 	struct ts_crypto_key_derivation_get_capacity_in recv_msg;
 	size_t expected_fixed_len = sizeof(struct ts_crypto_key_derivation_get_capacity_in);
 
-	if (expected_fixed_len <= req_buf->data_len) {
+	if (expected_fixed_len <= req_buf->data_length) {
 
 		memcpy(&recv_msg, req_buf->data, expected_fixed_len);
 		*op_handle = recv_msg.op_handle;
-		rpc_status = TS_RPC_CALL_ACCEPTED;
+		rpc_status = RPC_SUCCESS;
 	}
 
 	return rpc_status;
 }
 
 static rpc_status_t serialize_key_derivation_get_capacity_resp(
-	struct call_param_buf *resp_buf,
+	struct rpc_buffer *resp_buf,
 	size_t capacity)
 {
-	rpc_status_t rpc_status = TS_RPC_ERROR_INTERNAL;
+	rpc_status_t rpc_status = RPC_ERROR_INTERNAL;
 	struct ts_crypto_key_derivation_get_capacity_out resp_msg;
 	size_t fixed_len = sizeof(struct ts_crypto_key_derivation_get_capacity_out);
 
@@ -82,8 +82,8 @@
 	if (fixed_len <= resp_buf->size) {
 
 		memcpy(resp_buf->data, &resp_msg, fixed_len);
-		resp_buf->data_len = fixed_len;
-		rpc_status = TS_RPC_CALL_ACCEPTED;
+		resp_buf->data_length = fixed_len;
+		rpc_status = RPC_SUCCESS;
 	}
 
 	return rpc_status;
@@ -91,20 +91,20 @@
 
 /* Operation: key_derivation_set_capacity */
 static rpc_status_t deserialize_key_derivation_set_capacity_req(
-	const struct call_param_buf *req_buf,
+	const struct rpc_buffer *req_buf,
 	uint32_t *op_handle,
 	size_t *capacity)
 {
-	rpc_status_t rpc_status = TS_RPC_ERROR_INVALID_REQ_BODY;
+	rpc_status_t rpc_status = RPC_ERROR_INVALID_REQUEST_BODY;
 	struct ts_crypto_key_derivation_set_capacity_in recv_msg;
 	size_t expected_fixed_len = sizeof(struct ts_crypto_key_derivation_set_capacity_in);
 
-	if (expected_fixed_len <= req_buf->data_len) {
+	if (expected_fixed_len <= req_buf->data_length) {
 
 		memcpy(&recv_msg, req_buf->data, expected_fixed_len);
 		*op_handle = recv_msg.op_handle;
 		*capacity = recv_msg.capacity;
-		rpc_status = TS_RPC_CALL_ACCEPTED;
+		rpc_status = RPC_SUCCESS;
 	}
 
 	return rpc_status;
@@ -112,21 +112,21 @@
 
 /* Operation: key_derivation_input_bytes */
 static rpc_status_t deserialize_key_derivation_input_bytes_req(
-	const struct call_param_buf *req_buf,
+	const struct rpc_buffer *req_buf,
 	uint32_t *op_handle,
 	psa_key_derivation_step_t *step,
-	const uint8_t **data, size_t *data_len)
+	const uint8_t **data, size_t *data_length)
 {
-	rpc_status_t rpc_status = TS_RPC_ERROR_INVALID_REQ_BODY;
+	rpc_status_t rpc_status = RPC_ERROR_INVALID_REQUEST_BODY;
 	struct ts_crypto_key_derivation_input_bytes_in recv_msg;
 	size_t expected_fixed_len = sizeof(struct ts_crypto_key_derivation_input_bytes_in);
 
-	if (expected_fixed_len <= req_buf->data_len) {
+	if (expected_fixed_len <= req_buf->data_length) {
 
 		struct tlv_const_iterator req_iter;
 		struct tlv_record decoded_record;
 
-		rpc_status = TS_RPC_CALL_ACCEPTED;
+		rpc_status = RPC_SUCCESS;
 
 		memcpy(&recv_msg, req_buf->data, expected_fixed_len);
 
@@ -135,17 +135,17 @@
 
 		tlv_const_iterator_begin(&req_iter,
 			(uint8_t*)req_buf->data + expected_fixed_len,
-			req_buf->data_len - expected_fixed_len);
+			req_buf->data_length - expected_fixed_len);
 
 		if (tlv_find_decode(&req_iter,
 			TS_CRYPTO_KEY_DERIVATION_INPUT_BYTES_IN_TAG_DATA, &decoded_record)) {
 
 			*data = decoded_record.value;
-			*data_len = decoded_record.length;
+			*data_length = decoded_record.length;
 		}
 		else {
 			/* Default to a zero length data */
-			*data_len = 0;
+			*data_length = 0;
 		}
 	}
 
@@ -154,22 +154,22 @@
 
 /* Operation: key_derivation_input_key */
 static rpc_status_t deserialize_key_derivation_input_key_req(
-	const struct call_param_buf *req_buf,
+	const struct rpc_buffer *req_buf,
 	uint32_t *op_handle,
 	psa_key_derivation_step_t *step,
 	psa_key_id_t *key_id)
 {
-	rpc_status_t rpc_status = TS_RPC_ERROR_INVALID_REQ_BODY;
+	rpc_status_t rpc_status = RPC_ERROR_INVALID_REQUEST_BODY;
 	struct ts_crypto_key_derivation_input_key_in recv_msg;
 	size_t expected_fixed_len = sizeof(struct ts_crypto_key_derivation_input_key_in);
 
-	if (expected_fixed_len <= req_buf->data_len) {
+	if (expected_fixed_len <= req_buf->data_length) {
 
 		memcpy(&recv_msg, req_buf->data, expected_fixed_len);
 		*op_handle = recv_msg.op_handle;
 		*step = recv_msg.step;
 		*key_id = recv_msg.key_id;
-		rpc_status = TS_RPC_CALL_ACCEPTED;
+		rpc_status = RPC_SUCCESS;
 	}
 
 	return rpc_status;
@@ -177,43 +177,43 @@
 
 /* Operation: key_derivation_output_bytes */
 static rpc_status_t deserialize_key_derivation_output_bytes_req(
-	const struct call_param_buf *req_buf,
+	const struct rpc_buffer *req_buf,
 	uint32_t *op_handle,
 	size_t *output_len)
 {
-	rpc_status_t rpc_status = TS_RPC_ERROR_INVALID_REQ_BODY;
+	rpc_status_t rpc_status = RPC_ERROR_INVALID_REQUEST_BODY;
 	struct ts_crypto_key_derivation_output_bytes_in recv_msg;
 	size_t expected_fixed_len = sizeof(struct ts_crypto_key_derivation_output_bytes_in);
 
-	if (expected_fixed_len <= req_buf->data_len) {
+	if (expected_fixed_len <= req_buf->data_length) {
 
 		memcpy(&recv_msg, req_buf->data, expected_fixed_len);
 		*op_handle = recv_msg.op_handle;
 		*output_len = recv_msg.output_len;
-		rpc_status = TS_RPC_CALL_ACCEPTED;
+		rpc_status = RPC_SUCCESS;
 	}
 
 	return rpc_status;
 }
 
 static rpc_status_t serialize_key_derivation_output_bytes_resp(
-	struct call_param_buf *resp_buf,
-	const uint8_t *data, size_t data_len)
+	struct rpc_buffer *resp_buf,
+	const uint8_t *data, size_t data_length)
 {
-	rpc_status_t rpc_status = TS_RPC_ERROR_INTERNAL;
+	rpc_status_t rpc_status = RPC_ERROR_INTERNAL;
 	struct tlv_iterator resp_iter;
 
 	struct tlv_record out_record;
 	out_record.tag = TS_CRYPTO_KEY_DERIVATION_OUTPUT_BYTES_OUT_TAG_DATA;
-	out_record.length = data_len;
+	out_record.length = data_length;
 	out_record.value = data;
 
 	tlv_iterator_begin(&resp_iter, resp_buf->data, resp_buf->size);
 
 	if (tlv_encode(&resp_iter, &out_record)) {
 
-		resp_buf->data_len = tlv_required_space(data_len);
-		rpc_status = TS_RPC_CALL_ACCEPTED;
+		resp_buf->data_length = tlv_required_space(data_length);
+		rpc_status = RPC_SUCCESS;
 	}
 
 	return rpc_status;
@@ -221,15 +221,15 @@
 
 /* Operation: key_derivation_output_key */
 static rpc_status_t deserialize_key_derivation_output_key_req(
-	const struct call_param_buf *req_buf,
+	const struct rpc_buffer *req_buf,
 	uint32_t *op_handle,
 	psa_key_attributes_t *attributes)
 {
-	rpc_status_t rpc_status = TS_RPC_ERROR_INVALID_REQ_BODY;
+	rpc_status_t rpc_status = RPC_ERROR_INVALID_REQUEST_BODY;
 	struct ts_crypto_key_derivation_output_key_in recv_msg;
 	size_t expected_fixed_len = sizeof(struct ts_crypto_key_derivation_output_key_in);
 
-	if (expected_fixed_len <= req_buf->data_len) {
+	if (expected_fixed_len <= req_buf->data_length) {
 
 		memcpy(&recv_msg, req_buf->data, expected_fixed_len);
 
@@ -237,17 +237,17 @@
 		packedc_crypto_provider_translate_key_attributes_from_proto(attributes,
 			&recv_msg.attributes);
 
-		rpc_status = TS_RPC_CALL_ACCEPTED;
+		rpc_status = RPC_SUCCESS;
 	}
 
 	return rpc_status;
 }
 
 static rpc_status_t serialize_key_derivation_output_key_resp(
-	struct call_param_buf *resp_buf,
+	struct rpc_buffer *resp_buf,
 	psa_key_id_t key_id)
 {
-	rpc_status_t rpc_status = TS_RPC_ERROR_INTERNAL;
+	rpc_status_t rpc_status = RPC_ERROR_INTERNAL;
 	struct ts_crypto_key_derivation_output_key_out resp_msg;
 	size_t fixed_len = sizeof(struct ts_crypto_key_derivation_output_key_out);
 
@@ -256,8 +256,8 @@
 	if (fixed_len <= resp_buf->size) {
 
 		memcpy(resp_buf->data, &resp_msg, fixed_len);
-		resp_buf->data_len = fixed_len;
-		rpc_status = TS_RPC_CALL_ACCEPTED;
+		resp_buf->data_length = fixed_len;
+		rpc_status = RPC_SUCCESS;
 	}
 
 	return rpc_status;
@@ -265,18 +265,18 @@
 
 /* Operation: key_derivation_abort */
 static rpc_status_t deserialize_key_derivation_abort_req(
-	const struct call_param_buf *req_buf,
+	const struct rpc_buffer *req_buf,
 	uint32_t *op_handle)
 {
-	rpc_status_t rpc_status = TS_RPC_ERROR_INVALID_REQ_BODY;
+	rpc_status_t rpc_status = RPC_ERROR_INVALID_REQUEST_BODY;
 	struct ts_crypto_key_derivation_abort_in recv_msg;
 	size_t expected_fixed_len = sizeof(struct ts_crypto_key_derivation_abort_in);
 
-	if (expected_fixed_len <= req_buf->data_len) {
+	if (expected_fixed_len <= req_buf->data_length) {
 
 		memcpy(&recv_msg, req_buf->data, expected_fixed_len);
 		*op_handle = recv_msg.op_handle;
-		rpc_status = TS_RPC_CALL_ACCEPTED;
+		rpc_status = RPC_SUCCESS;
 	}
 
 	return rpc_status;
@@ -284,22 +284,22 @@
 
 /* Operation: key_derivation_key_agreement */
 static rpc_status_t deserialize_key_derivation_key_agreement_req(
-	const struct call_param_buf *req_buf,
+	const struct rpc_buffer *req_buf,
 	uint32_t *op_handle,
 	psa_key_derivation_step_t *step,
 	psa_key_id_t *private_key_id,
 	const uint8_t **peer_key, size_t *peer_key_len)
 {
-	rpc_status_t rpc_status = TS_RPC_ERROR_INVALID_REQ_BODY;
+	rpc_status_t rpc_status = RPC_ERROR_INVALID_REQUEST_BODY;
 	struct ts_crypto_key_derivation_key_agreement_in recv_msg;
 	size_t expected_fixed_len = sizeof(struct ts_crypto_key_derivation_key_agreement_in);
 
-	if (expected_fixed_len <= req_buf->data_len) {
+	if (expected_fixed_len <= req_buf->data_length) {
 
 		struct tlv_const_iterator req_iter;
 		struct tlv_record decoded_record;
 
-		rpc_status = TS_RPC_CALL_ACCEPTED;
+		rpc_status = RPC_SUCCESS;
 
 		memcpy(&recv_msg, req_buf->data, expected_fixed_len);
 
@@ -309,7 +309,7 @@
 
 		tlv_const_iterator_begin(&req_iter,
 			(uint8_t*)req_buf->data + expected_fixed_len,
-			req_buf->data_len - expected_fixed_len);
+			req_buf->data_length - expected_fixed_len);
 
 		if (tlv_find_decode(&req_iter,
 			TS_CRYPTO_KEY_DERIVATION_KEY_AGREEMENT_IN_TAG_PEER_KEY, &decoded_record)) {
@@ -328,21 +328,21 @@
 
 /* Operation: key_derivation_raw_key_agreement */
 static rpc_status_t deserialize_key_derivation_raw_key_agreement_req(
-	const struct call_param_buf *req_buf,
+	const struct rpc_buffer *req_buf,
 	psa_algorithm_t *alg,
 	psa_key_id_t *private_key_id,
 	const uint8_t **peer_key, size_t *peer_key_len)
 {
-	rpc_status_t rpc_status = TS_RPC_ERROR_INVALID_REQ_BODY;
+	rpc_status_t rpc_status = RPC_ERROR_INVALID_REQUEST_BODY;
 	struct ts_crypto_raw_key_agreement_in recv_msg;
 	size_t expected_fixed_len = sizeof(struct ts_crypto_raw_key_agreement_in);
 
-	if (expected_fixed_len <= req_buf->data_len) {
+	if (expected_fixed_len <= req_buf->data_length) {
 
 		struct tlv_const_iterator req_iter;
 		struct tlv_record decoded_record;
 
-		rpc_status = TS_RPC_CALL_ACCEPTED;
+		rpc_status = RPC_SUCCESS;
 
 		memcpy(&recv_msg, req_buf->data, expected_fixed_len);
 
@@ -351,7 +351,7 @@
 
 		tlv_const_iterator_begin(&req_iter,
 			(uint8_t*)req_buf->data + expected_fixed_len,
-			req_buf->data_len - expected_fixed_len);
+			req_buf->data_length - expected_fixed_len);
 
 		if (tlv_find_decode(&req_iter,
 			TS_CRYPTO_RAW_KEY_AGREEMENT_IN_TAG_PEER_KEY, &decoded_record)) {
@@ -369,10 +369,10 @@
 }
 
 static rpc_status_t serialize_key_derivation_raw_key_agreement_resp(
-	struct call_param_buf *resp_buf,
+	struct rpc_buffer *resp_buf,
 	const uint8_t *output, size_t output_len)
 {
-	rpc_status_t rpc_status = TS_RPC_ERROR_INTERNAL;
+	rpc_status_t rpc_status = RPC_ERROR_INTERNAL;
 	struct tlv_iterator resp_iter;
 
 	struct tlv_record out_record;
@@ -384,8 +384,8 @@
 
 	if (tlv_encode(&resp_iter, &out_record)) {
 
-		resp_buf->data_len = tlv_required_space(output_len);
-		rpc_status = TS_RPC_CALL_ACCEPTED;
+		resp_buf->data_length = tlv_required_space(output_len);
+		rpc_status = RPC_SUCCESS;
 	}
 
 	return rpc_status;
diff --git a/components/service/crypto/provider/extension/mac/mac_provider.c b/components/service/crypto/provider/extension/mac/mac_provider.c
index eef5558..1e2081e 100644
--- a/components/service/crypto/provider/extension/mac/mac_provider.c
+++ b/components/service/crypto/provider/extension/mac/mac_provider.c
@@ -11,11 +11,11 @@
 #include <psa/crypto.h>
 
 /* Service request handlers */
-static rpc_status_t mac_setup_handler(void *context, struct call_req* req);
-static rpc_status_t mac_update_handler(void *context, struct call_req* req);
-static rpc_status_t mac_sign_finish_handler(void *context, struct call_req* req);
-static rpc_status_t mac_verify_finish_handler(void *context, struct call_req* req);
-static rpc_status_t mac_abort_handler(void *context, struct call_req* req);
+static rpc_status_t mac_setup_handler(void *context, struct rpc_request *req);
+static rpc_status_t mac_update_handler(void *context, struct rpc_request *req);
+static rpc_status_t mac_sign_finish_handler(void *context, struct rpc_request *req);
+static rpc_status_t mac_verify_finish_handler(void *context, struct rpc_request *req);
+static rpc_status_t mac_abort_handler(void *context, struct rpc_request *req);
 
 /* Handler mapping table for service */
 static const struct service_handler handler_table[] = {
@@ -29,12 +29,14 @@
 
 void mac_provider_init(struct mac_provider *context)
 {
+	const struct rpc_uuid nil_uuid = { 0 };
+
 	crypto_context_pool_init(&context->context_pool);
 
 	for (size_t encoding = 0; encoding < TS_RPC_ENCODING_LIMIT; ++encoding)
 		context->serializers[encoding] = NULL;
 
-	service_provider_init(&context->base_provider, context,
+	service_provider_init(&context->base_provider, context, &nil_uuid,
 		handler_table, sizeof(handler_table)/sizeof(struct service_handler));
 }
 
@@ -51,21 +53,18 @@
 }
 
 static const struct mac_provider_serializer* get_serializer(void *context,
-	const struct call_req *req)
+	const struct rpc_request *req)
 {
 	struct mac_provider *this_instance = (struct mac_provider*)context;
-	const struct mac_provider_serializer* serializer = NULL;
-	unsigned int encoding = call_req_get_encoding(req);
+	unsigned int encoding = 0; /* No other encodings supported */
 
-	if (encoding < TS_RPC_ENCODING_LIMIT) serializer = this_instance->serializers[encoding];
-
-	return serializer;
+	return this_instance->serializers[encoding];
 }
 
-static rpc_status_t mac_setup_handler(void *context, struct call_req* req)
+static rpc_status_t mac_setup_handler(void *context, struct rpc_request *req)
 {
-	rpc_status_t rpc_status = TS_RPC_ERROR_SERIALIZATION_NOT_SUPPORTED;
-	struct call_param_buf *req_buf = call_req_get_req_buf(req);
+	rpc_status_t rpc_status = RPC_ERROR_INTERNAL;
+	struct rpc_buffer *req_buf = &req->request;
 	const struct mac_provider_serializer *serializer = get_serializer(context, req);
 	struct mac_provider *this_instance = (struct mac_provider*)context;
 
@@ -75,13 +74,13 @@
 	if (serializer)
 		rpc_status = serializer->deserialize_mac_setup_req(req_buf, &key_id, &alg);
 
-	if (rpc_status == TS_RPC_CALL_ACCEPTED) {
+	if (rpc_status == RPC_SUCCESS) {
 
 		uint32_t op_handle;
 
 		struct crypto_context *crypto_context =
 			crypto_context_pool_alloc(&this_instance->context_pool,
-				CRYPTO_CONTEXT_OP_ID_MAC, call_req_get_caller_id(req),
+				CRYPTO_CONTEXT_OP_ID_MAC, req->source_id,
 				&op_handle);
 
 		if (crypto_context) {
@@ -89,36 +88,34 @@
 			crypto_context->op.mac = psa_mac_operation_init();
 
 			psa_status_t psa_status =
-				(call_req_get_opcode(req) == TS_CRYPTO_OPCODE_MAC_SIGN_SETUP) ?
+				(req->opcode == TS_CRYPTO_OPCODE_MAC_SIGN_SETUP) ?
 					psa_mac_sign_setup(&crypto_context->op.mac, key_id, alg) :
 					psa_mac_verify_setup(&crypto_context->op.mac, key_id, alg);
 
 			if (psa_status == PSA_SUCCESS) {
 
-				struct call_param_buf *resp_buf = call_req_get_resp_buf(req);
+				struct rpc_buffer *resp_buf = &req->response;
 				rpc_status = serializer->serialize_mac_setup_resp(resp_buf, op_handle);
 			}
 
-			if ((psa_status != PSA_SUCCESS) || (rpc_status != TS_RPC_CALL_ACCEPTED)) {
-
+			if ((psa_status != PSA_SUCCESS) || (rpc_status != RPC_SUCCESS))
 				crypto_context_pool_free(&this_instance->context_pool, crypto_context);
-			}
 
-			call_req_set_opstatus(req, psa_status);
+			req->service_status = psa_status;
 		}
 		else {
 			/* Failed to allocate crypto context for transaction */
-			rpc_status = TS_RPC_ERROR_RESOURCE_FAILURE;
+			rpc_status = RPC_ERROR_RESOURCE_FAILURE;
 		}
 	}
 
 	return rpc_status;
 }
 
-static rpc_status_t mac_update_handler(void *context, struct call_req* req)
+static rpc_status_t mac_update_handler(void *context, struct rpc_request *req)
 {
-	rpc_status_t rpc_status = TS_RPC_ERROR_SERIALIZATION_NOT_SUPPORTED;
-	struct call_param_buf *req_buf = call_req_get_req_buf(req);
+	rpc_status_t rpc_status = RPC_ERROR_INTERNAL;
+	struct rpc_buffer *req_buf = &req->request;
 	const struct mac_provider_serializer *serializer = get_serializer(context, req);
 	struct mac_provider *this_instance = (struct mac_provider*)context;
 
@@ -129,13 +126,13 @@
 	if (serializer)
 		rpc_status = serializer->deserialize_mac_update_req(req_buf, &op_handle, &data, &data_len);
 
-	if (rpc_status == TS_RPC_CALL_ACCEPTED) {
+	if (rpc_status == RPC_SUCCESS) {
 
 		psa_status_t psa_status = PSA_ERROR_BAD_STATE;
 
 		struct crypto_context *crypto_context =
 			crypto_context_pool_find(&this_instance->context_pool,
-				CRYPTO_CONTEXT_OP_ID_MAC, call_req_get_caller_id(req),
+				CRYPTO_CONTEXT_OP_ID_MAC, req->source_id,
 				op_handle);
 
 		if (crypto_context) {
@@ -143,16 +140,16 @@
 			psa_status = psa_mac_update(&crypto_context->op.mac, data, data_len);
 		}
 
-		call_req_set_opstatus(req, psa_status);
+		req->service_status = psa_status;
 	}
 
 	return rpc_status;
 }
 
-static rpc_status_t mac_sign_finish_handler(void *context, struct call_req* req)
+static rpc_status_t mac_sign_finish_handler(void *context, struct rpc_request *req)
 {
-	rpc_status_t rpc_status = TS_RPC_ERROR_SERIALIZATION_NOT_SUPPORTED;
-	struct call_param_buf *req_buf = call_req_get_req_buf(req);
+	rpc_status_t rpc_status = RPC_ERROR_INTERNAL;
+	struct rpc_buffer *req_buf = &req->request;
 	const struct mac_provider_serializer *serializer = get_serializer(context, req);
 	struct mac_provider *this_instance = (struct mac_provider*)context;
 
@@ -161,13 +158,13 @@
 	if (serializer)
 		rpc_status = serializer->deserialize_mac_sign_finish_req(req_buf, &op_handle);
 
-	if (rpc_status == TS_RPC_CALL_ACCEPTED) {
+	if (rpc_status == RPC_SUCCESS) {
 
 		psa_status_t psa_status = PSA_ERROR_BAD_STATE;
 
 		struct crypto_context *crypto_context =
 			crypto_context_pool_find(&this_instance->context_pool,
-				CRYPTO_CONTEXT_OP_ID_MAC, call_req_get_caller_id(req),
+				CRYPTO_CONTEXT_OP_ID_MAC, req->source_id,
 				op_handle);
 
 		if (crypto_context) {
@@ -179,23 +176,23 @@
 
 			if (psa_status == PSA_SUCCESS) {
 
-				struct call_param_buf *resp_buf = call_req_get_resp_buf(req);
+				struct rpc_buffer *resp_buf = &req->response;
 				rpc_status = serializer->serialize_mac_sign_finish_resp(resp_buf, mac, mac_len);
 
 				crypto_context_pool_free(&this_instance->context_pool, crypto_context);
 			}
 		}
 
-		call_req_set_opstatus(req, psa_status);
+		req->service_status = psa_status;
 	}
 
 	return rpc_status;
 }
 
-static rpc_status_t mac_verify_finish_handler(void *context, struct call_req* req)
+static rpc_status_t mac_verify_finish_handler(void *context, struct rpc_request *req)
 {
-	rpc_status_t rpc_status = TS_RPC_ERROR_SERIALIZATION_NOT_SUPPORTED;
-	struct call_param_buf *req_buf = call_req_get_req_buf(req);
+	rpc_status_t rpc_status = RPC_ERROR_INTERNAL;
+	struct rpc_buffer *req_buf = &req->request;
 	const struct mac_provider_serializer *serializer = get_serializer(context, req);
 	struct mac_provider *this_instance = (struct mac_provider*)context;
 
@@ -207,13 +204,13 @@
 		rpc_status = serializer->deserialize_mac_verify_finish_req(req_buf,
 			&op_handle, &mac, &mac_len);
 
-	if (rpc_status == TS_RPC_CALL_ACCEPTED) {
+	if (rpc_status == RPC_SUCCESS) {
 
 		psa_status_t psa_status = PSA_ERROR_BAD_STATE;
 
 		struct crypto_context *crypto_context =
 			crypto_context_pool_find(&this_instance->context_pool,
-				CRYPTO_CONTEXT_OP_ID_MAC, call_req_get_caller_id(req),
+				CRYPTO_CONTEXT_OP_ID_MAC, req->source_id,
 				op_handle);
 
 		if (crypto_context) {
@@ -226,16 +223,16 @@
 			}
 		}
 
-		call_req_set_opstatus(req, psa_status);
+		req->service_status = psa_status;
 	}
 
 	return rpc_status;
 }
 
-static rpc_status_t mac_abort_handler(void *context, struct call_req* req)
+static rpc_status_t mac_abort_handler(void *context, struct rpc_request *req)
 {
-	rpc_status_t rpc_status = TS_RPC_ERROR_SERIALIZATION_NOT_SUPPORTED;
-	struct call_param_buf *req_buf = call_req_get_req_buf(req);
+	rpc_status_t rpc_status = RPC_ERROR_INTERNAL;
+	struct rpc_buffer *req_buf = &req->request;
 	const struct mac_provider_serializer *serializer = get_serializer(context, req);
 	struct mac_provider *this_instance = (struct mac_provider*)context;
 
@@ -244,7 +241,7 @@
 	if (serializer)
 		rpc_status = serializer->deserialize_mac_abort_req(req_buf, &op_handle);
 
-	if (rpc_status == TS_RPC_CALL_ACCEPTED) {
+	if (rpc_status == RPC_SUCCESS) {
 
 		/* Return success if operation is no longer active and
 		 * doesn't need aborting.
@@ -253,7 +250,7 @@
 
 		struct crypto_context *crypto_context =
 			crypto_context_pool_find(&this_instance->context_pool,
-				CRYPTO_CONTEXT_OP_ID_MAC, call_req_get_caller_id(req),
+				CRYPTO_CONTEXT_OP_ID_MAC, req->source_id,
 				op_handle);
 
 		if (crypto_context) {
@@ -262,7 +259,7 @@
 			crypto_context_pool_free(&this_instance->context_pool, crypto_context);
 		}
 
-		call_req_set_opstatus(req, psa_status);
+		req->service_status = psa_status;
 	}
 
 	return rpc_status;
diff --git a/components/service/crypto/provider/extension/mac/mac_provider.h b/components/service/crypto/provider/extension/mac/mac_provider.h
index 5e3cbe2..d987f5a 100644
--- a/components/service/crypto/provider/extension/mac/mac_provider.h
+++ b/components/service/crypto/provider/extension/mac/mac_provider.h
@@ -7,7 +7,7 @@
 #ifndef MAC_PROVIDER_H
 #define MAC_PROVIDER_H
 
-#include <rpc/common/endpoint/rpc_interface.h>
+#include "components/rpc/common/endpoint/rpc_service_interface.h"
 #include <service/common/provider/service_provider.h>
 #include <service/crypto/provider/extension/mac/serializer/mac_provider_serializer.h>
 #include <service/crypto/provider/crypto_context_pool.h>
diff --git a/components/service/crypto/provider/extension/mac/serializer/mac_provider_serializer.h b/components/service/crypto/provider/extension/mac/serializer/mac_provider_serializer.h
index 3f5e5c6..0ad0465 100644
--- a/components/service/crypto/provider/extension/mac/serializer/mac_provider_serializer.h
+++ b/components/service/crypto/provider/extension/mac/serializer/mac_provider_serializer.h
@@ -10,7 +10,7 @@
 #include <stddef.h>
 #include <stdint.h>
 #include <psa/crypto.h>
-#include <rpc/common/endpoint/rpc_interface.h>
+#include "components/rpc/common/endpoint/rpc_service_interface.h"
 
 /* Provides a common interface for parameter serialization operations
  * for the mac service provider.
@@ -18,32 +18,32 @@
 struct mac_provider_serializer {
 
 	/* Operation: mac_setup */
-	rpc_status_t (*deserialize_mac_setup_req)(const struct call_param_buf *req_buf,
+	rpc_status_t (*deserialize_mac_setup_req)(const struct rpc_buffer *req_buf,
 		psa_key_id_t *key_id,
 		psa_algorithm_t *alg);
 
-	rpc_status_t (*serialize_mac_setup_resp)(struct call_param_buf *resp_buf,
+	rpc_status_t (*serialize_mac_setup_resp)(struct rpc_buffer *resp_buf,
 		uint32_t op_handle);
 
 	/* Operation: mac_update */
-	rpc_status_t (*deserialize_mac_update_req)(const struct call_param_buf *req_buf,
+	rpc_status_t (*deserialize_mac_update_req)(const struct rpc_buffer *req_buf,
 		uint32_t *op_handle,
 		const uint8_t **data, size_t *data_len);
 
 	/* Operation: mac_sign_finish */
-	rpc_status_t (*deserialize_mac_sign_finish_req)(const struct call_param_buf *req_buf,
+	rpc_status_t (*deserialize_mac_sign_finish_req)(const struct rpc_buffer *req_buf,
 		uint32_t *op_handle);
 
-	rpc_status_t (*serialize_mac_sign_finish_resp)(struct call_param_buf *resp_buf,
+	rpc_status_t (*serialize_mac_sign_finish_resp)(struct rpc_buffer *resp_buf,
 		const uint8_t *mac, size_t mac_len);
 
 	/* Operation: mac_verify_finish */
-	rpc_status_t (*deserialize_mac_verify_finish_req)(const struct call_param_buf *req_buf,
+	rpc_status_t (*deserialize_mac_verify_finish_req)(const struct rpc_buffer *req_buf,
 		uint32_t *op_handle,
 		const uint8_t **mac, size_t *mac_len);
 
 	/* Operation: mac_abort */
-	rpc_status_t (*deserialize_mac_abort_req)(const struct call_param_buf *req_buf,
+	rpc_status_t (*deserialize_mac_abort_req)(const struct rpc_buffer *req_buf,
 		uint32_t *op_handle);
 };
 
diff --git a/components/service/crypto/provider/extension/mac/serializer/packed-c/packedc_mac_provider_serializer.c b/components/service/crypto/provider/extension/mac/serializer/packed-c/packedc_mac_provider_serializer.c
index fa3a2c9..a82b98d 100644
--- a/components/service/crypto/provider/extension/mac/serializer/packed-c/packedc_mac_provider_serializer.c
+++ b/components/service/crypto/provider/extension/mac/serializer/packed-c/packedc_mac_provider_serializer.c
@@ -11,29 +11,29 @@
 #include "packedc_mac_provider_serializer.h"
 
 /* Operation: mac_setup */
-static rpc_status_t deserialize_mac_setup_req(const struct call_param_buf *req_buf,
+static rpc_status_t deserialize_mac_setup_req(const struct rpc_buffer *req_buf,
 	psa_key_id_t *key_id,
 	psa_algorithm_t *alg)
 {
-	rpc_status_t rpc_status = TS_RPC_ERROR_INVALID_REQ_BODY;
+	rpc_status_t rpc_status = RPC_ERROR_INVALID_REQUEST_BODY;
 	struct ts_crypto_mac_setup_in recv_msg;
 	size_t expected_fixed_len = sizeof(struct ts_crypto_mac_setup_in);
 
-	if (expected_fixed_len <= req_buf->data_len) {
+	if (expected_fixed_len <= req_buf->data_length) {
 
 		memcpy(&recv_msg, req_buf->data, expected_fixed_len);
 		*key_id = recv_msg.key_id;
 		*alg = recv_msg.alg;
-		rpc_status = TS_RPC_CALL_ACCEPTED;
+		rpc_status = RPC_SUCCESS;
 	}
 
 	return rpc_status;
 }
 
-static rpc_status_t serialize_mac_setup_resp(struct call_param_buf *resp_buf,
+static rpc_status_t serialize_mac_setup_resp(struct rpc_buffer *resp_buf,
 	uint32_t op_handle)
 {
-	rpc_status_t rpc_status = TS_RPC_ERROR_INTERNAL;
+	rpc_status_t rpc_status = RPC_ERROR_INTERNAL;
 	struct ts_crypto_mac_setup_out resp_msg;
 	size_t fixed_len = sizeof(struct ts_crypto_mac_setup_out);
 
@@ -42,28 +42,28 @@
 	if (fixed_len <= resp_buf->size) {
 
 		memcpy(resp_buf->data, &resp_msg, fixed_len);
-		resp_buf->data_len = fixed_len;
-		rpc_status = TS_RPC_CALL_ACCEPTED;
+		resp_buf->data_length = fixed_len;
+		rpc_status = RPC_SUCCESS;
 	}
 
 	return rpc_status;
 }
 
 /* Operation: mac_update */
-static rpc_status_t deserialize_mac_update_req(const struct call_param_buf *req_buf,
+static rpc_status_t deserialize_mac_update_req(const struct rpc_buffer *req_buf,
 	uint32_t *op_handle,
-	const uint8_t **data, size_t *data_len)
+	const uint8_t **data, size_t *data_length)
 {
-	rpc_status_t rpc_status = TS_RPC_ERROR_INVALID_REQ_BODY;
+	rpc_status_t rpc_status = RPC_ERROR_INVALID_REQUEST_BODY;
 	struct ts_crypto_mac_update_in recv_msg;
 	size_t expected_fixed_len = sizeof(struct ts_crypto_mac_update_in);
 
-	if (expected_fixed_len <= req_buf->data_len) {
+	if (expected_fixed_len <= req_buf->data_length) {
 
 		struct tlv_const_iterator req_iter;
 		struct tlv_record decoded_record;
 
-		rpc_status = TS_RPC_CALL_ACCEPTED;
+		rpc_status = RPC_SUCCESS;
 
 		memcpy(&recv_msg, req_buf->data, expected_fixed_len);
 
@@ -71,16 +71,16 @@
 
 		tlv_const_iterator_begin(&req_iter,
 			(uint8_t*)req_buf->data + expected_fixed_len,
-			req_buf->data_len - expected_fixed_len);
+			req_buf->data_length - expected_fixed_len);
 
 		if (tlv_find_decode(&req_iter, TS_CRYPTO_MAC_UPDATE_IN_TAG_DATA, &decoded_record)) {
 
 			*data = decoded_record.value;
-			*data_len = decoded_record.length;
+			*data_length = decoded_record.length;
 		}
 		else {
 			/* Default to a zero length data */
-			*data_len = 0;
+			*data_length = 0;
 		}
 	}
 
@@ -88,27 +88,27 @@
 }
 
 /* Operation: mac_finish */
-static rpc_status_t deserialize_mac_sign_finish_req(const struct call_param_buf *req_buf,
+static rpc_status_t deserialize_mac_sign_finish_req(const struct rpc_buffer *req_buf,
 	uint32_t *op_handle)
 {
-	rpc_status_t rpc_status = TS_RPC_ERROR_INVALID_REQ_BODY;
+	rpc_status_t rpc_status = RPC_ERROR_INVALID_REQUEST_BODY;
 	struct ts_crypto_mac_sign_finish_in recv_msg;
 	size_t expected_fixed_len = sizeof(struct ts_crypto_mac_sign_finish_in);
 
-	if (expected_fixed_len <= req_buf->data_len) {
+	if (expected_fixed_len <= req_buf->data_length) {
 
 		memcpy(&recv_msg, req_buf->data, expected_fixed_len);
 		*op_handle = recv_msg.op_handle;
-		rpc_status = TS_RPC_CALL_ACCEPTED;
+		rpc_status = RPC_SUCCESS;
 	}
 
 	return rpc_status;
 }
 
-static rpc_status_t serialize_mac_sign_finish_resp(struct call_param_buf *resp_buf,
+static rpc_status_t serialize_mac_sign_finish_resp(struct rpc_buffer *resp_buf,
 	const uint8_t *mac, size_t mac_len)
 {
-	rpc_status_t rpc_status = TS_RPC_ERROR_INTERNAL;
+	rpc_status_t rpc_status = RPC_ERROR_INTERNAL;
 	struct tlv_iterator resp_iter;
 
 	struct tlv_record out_record;
@@ -120,28 +120,28 @@
 
 	if (tlv_encode(&resp_iter, &out_record)) {
 
-		resp_buf->data_len = tlv_required_space(mac_len);
-		rpc_status = TS_RPC_CALL_ACCEPTED;
+		resp_buf->data_length = tlv_required_space(mac_len);
+		rpc_status = RPC_SUCCESS;
 	}
 
 	return rpc_status;
 }
 
 /* Operation: mac_verify_finish */
-static rpc_status_t deserialize_mac_verify_finish_req(const struct call_param_buf *req_buf,
+static rpc_status_t deserialize_mac_verify_finish_req(const struct rpc_buffer *req_buf,
 	uint32_t *op_handle,
 	const uint8_t **mac, size_t *mac_len)
 {
-	rpc_status_t rpc_status = TS_RPC_ERROR_INVALID_REQ_BODY;
+	rpc_status_t rpc_status = RPC_ERROR_INVALID_REQUEST_BODY;
 	struct ts_crypto_mac_verify_finish_in recv_msg;
 	size_t expected_fixed_len = sizeof(struct ts_crypto_mac_verify_finish_in);
 
-	if (expected_fixed_len <= req_buf->data_len) {
+	if (expected_fixed_len <= req_buf->data_length) {
 
 		struct tlv_const_iterator req_iter;
 		struct tlv_record decoded_record;
 
-		rpc_status = TS_RPC_CALL_ACCEPTED;
+		rpc_status = RPC_SUCCESS;
 
 		memcpy(&recv_msg, req_buf->data, expected_fixed_len);
 
@@ -149,7 +149,7 @@
 
 		tlv_const_iterator_begin(&req_iter,
 			(uint8_t*)req_buf->data + expected_fixed_len,
-			req_buf->data_len - expected_fixed_len);
+			req_buf->data_length - expected_fixed_len);
 
 		if (tlv_find_decode(&req_iter, TS_CRYPTO_MAC_SIGN_FINISH_OUT_TAG_MAC, &decoded_record)) {
 
@@ -166,18 +166,18 @@
 }
 
 /* Operation: mac_abort */
-static rpc_status_t deserialize_mac_abort_req(const struct call_param_buf *req_buf,
+static rpc_status_t deserialize_mac_abort_req(const struct rpc_buffer *req_buf,
 	uint32_t *op_handle)
 {
-	rpc_status_t rpc_status = TS_RPC_ERROR_INVALID_REQ_BODY;
+	rpc_status_t rpc_status = RPC_ERROR_INVALID_REQUEST_BODY;
 	struct ts_crypto_mac_abort_in recv_msg;
 	size_t expected_fixed_len = sizeof(struct ts_crypto_mac_abort_in);
 
-	if (expected_fixed_len <= req_buf->data_len) {
+	if (expected_fixed_len <= req_buf->data_length) {
 
 		memcpy(&recv_msg, req_buf->data, expected_fixed_len);
 		*op_handle = recv_msg.op_handle;
-		rpc_status = TS_RPC_CALL_ACCEPTED;
+		rpc_status = RPC_SUCCESS;
 	}
 
 	return rpc_status;
diff --git a/components/service/crypto/provider/serializer/crypto_provider_serializer.h b/components/service/crypto/provider/serializer/crypto_provider_serializer.h
index 57364f2..afc2f05 100644
--- a/components/service/crypto/provider/serializer/crypto_provider_serializer.h
+++ b/components/service/crypto/provider/serializer/crypto_provider_serializer.h
@@ -7,10 +7,11 @@
 #ifndef CRYPTO_PROVIDER_SERIALIZER_H
 #define CRYPTO_PROVIDER_SERIALIZER_H
 
+#include <psa/crypto.h>
 #include <stddef.h>
 #include <stdint.h>
-#include <psa/crypto.h>
-#include <rpc/common/endpoint/rpc_interface.h>
+
+#include "components/rpc/common/endpoint/rpc_service_interface.h"
 
 /* Provides a common interface for parameter serialization operations
  * for the crypto service provider.  Allows alternative serialization
@@ -19,103 +20,104 @@
  * implement this interface.
  */
 struct crypto_provider_serializer {
-
-    /* Returns the maximum deserialized parameter size that could
+	/* Returns the maximum deserialized parameter size that could
      * be encoded in a request buffer.  Used for determining worst-case
      * buffer size without having to actually deserialize the message.
      */
-    size_t (*max_deserialised_parameter_size)(const struct call_param_buf *req_buf);
+	size_t (*max_deserialised_parameter_size)(const struct rpc_buffer *req_buf);
 
-    /* Operation: generate_key */
-    rpc_status_t (*deserialize_generate_key_req)(const struct call_param_buf *req_buf,
-                                        psa_key_attributes_t *attributes);
+	/* Operation: generate_key */
+	rpc_status_t (*deserialize_generate_key_req)(const struct rpc_buffer *req_buf,
+						     psa_key_attributes_t *attributes);
 
-    rpc_status_t (*serialize_generate_key_resp)(struct call_param_buf *resp_buf,
-                                        psa_key_id_t id);
+	rpc_status_t (*serialize_generate_key_resp)(struct rpc_buffer *resp_buf, psa_key_id_t id);
 
-    /* Operation: destroy_key */
-    rpc_status_t (*deserialize_destroy_key_req)(const struct call_param_buf *req_buf,
-                                        psa_key_id_t *id);
+	/* Operation: destroy_key */
+	rpc_status_t (*deserialize_destroy_key_req)(const struct rpc_buffer *req_buf,
+						    psa_key_id_t *id);
 
-    /* Operation: export_key */
-    rpc_status_t (*deserialize_export_key_req)(const struct call_param_buf *req_buf,
-                                        psa_key_id_t *id);
+	/* Operation: export_key */
+	rpc_status_t (*deserialize_export_key_req)(const struct rpc_buffer *req_buf,
+						   psa_key_id_t *id);
 
-    rpc_status_t (*serialize_export_key_resp)(struct call_param_buf *resp_buf,
-                                        const uint8_t *data, size_t data_len);
+	rpc_status_t (*serialize_export_key_resp)(struct rpc_buffer *resp_buf, const uint8_t *data,
+						  size_t data_len);
 
-    /* Operation: export_public_key */
-    rpc_status_t (*deserialize_export_public_key_req)(const struct call_param_buf *req_buf,
-                                        psa_key_id_t *id);
+	/* Operation: export_public_key */
+	rpc_status_t (*deserialize_export_public_key_req)(const struct rpc_buffer *req_buf,
+							  psa_key_id_t *id);
 
-    rpc_status_t (*serialize_export_public_key_resp)(struct call_param_buf *resp_buf,
-                                        const uint8_t *data, size_t data_len);
+	rpc_status_t (*serialize_export_public_key_resp)(struct rpc_buffer *resp_buf,
+							 const uint8_t *data, size_t data_len);
 
-    /* Operation: import_key */
-    rpc_status_t (*deserialize_import_key_req)(const struct call_param_buf *req_buf,
-                                        psa_key_attributes_t *attributes,
-                                        uint8_t *data, size_t *data_len);
+	/* Operation: import_key */
+	rpc_status_t (*deserialize_import_key_req)(const struct rpc_buffer *req_buf,
+						   psa_key_attributes_t *attributes, uint8_t *data,
+						   size_t *data_len);
 
-    rpc_status_t (*serialize_import_key_resp)(struct call_param_buf *resp_buf,
-                                        psa_key_id_t id);
+	rpc_status_t (*serialize_import_key_resp)(struct rpc_buffer *resp_buf, psa_key_id_t id);
 
-    /* Operation: copy_key */
-    rpc_status_t (*deserialize_copy_key_req)(const struct call_param_buf *req_buf,
-                                        psa_key_attributes_t *attributes,
-                                        psa_key_id_t *source_id);
+	/* Operation: copy_key */
+	rpc_status_t (*deserialize_copy_key_req)(const struct rpc_buffer *req_buf,
+						 psa_key_attributes_t *attributes,
+						 psa_key_id_t *source_id);
 
-    rpc_status_t (*serialize_copy_key_resp)(struct call_param_buf *resp_buf,
-                                        psa_key_id_t target_id);
+	rpc_status_t (*serialize_copy_key_resp)(struct rpc_buffer *resp_buf,
+						psa_key_id_t target_id);
 
-    /* Operation: purge_key */
-    rpc_status_t (*deserialize_purge_key_req)(const struct call_param_buf *req_buf,
-                                        psa_key_id_t *id);
+	/* Operation: purge_key */
+	rpc_status_t (*deserialize_purge_key_req)(const struct rpc_buffer *req_buf,
+						  psa_key_id_t *id);
 
-    /* Operation: get_key_attributes */
-    rpc_status_t (*deserialize_get_key_attributes_req)(const struct call_param_buf *req_buf,
-                                        psa_key_id_t *id);
+	/* Operation: get_key_attributes */
+	rpc_status_t (*deserialize_get_key_attributes_req)(const struct rpc_buffer *req_buf,
+							   psa_key_id_t *id);
 
-    rpc_status_t (*serialize_get_key_attributes_resp)(struct call_param_buf *resp_buf,
-                                        const psa_key_attributes_t *attributes);
+	rpc_status_t (*serialize_get_key_attributes_resp)(struct rpc_buffer *resp_buf,
+							  const psa_key_attributes_t *attributes);
 
-    /* Operation: sign_hash */
-    rpc_status_t (*deserialize_asymmetric_sign_req)(const struct call_param_buf *req_buf,
-                                        psa_key_id_t *id, psa_algorithm_t *alg,
-                                        uint8_t *hash, size_t *hash_len);
+	/* Operation: sign_hash */
+	rpc_status_t (*deserialize_asymmetric_sign_req)(const struct rpc_buffer *req_buf,
+							psa_key_id_t *id, psa_algorithm_t *alg,
+							uint8_t *hash, size_t *hash_len);
 
-    rpc_status_t (*serialize_asymmetric_sign_resp)(struct call_param_buf *resp_buf,
-                                        const uint8_t *sig, size_t sig_len);
+	rpc_status_t (*serialize_asymmetric_sign_resp)(struct rpc_buffer *resp_buf,
+						       const uint8_t *sig, size_t sig_len);
 
-    /* Operation: verify_hash */
-    rpc_status_t (*deserialize_asymmetric_verify_req)(const struct call_param_buf *req_buf,
-                                        psa_key_id_t *id, psa_algorithm_t *alg,
-                                        uint8_t *hash, size_t *hash_len,
-                                        uint8_t *sig, size_t *sig_len);
+	/* Operation: verify_hash */
+	rpc_status_t (*deserialize_asymmetric_verify_req)(const struct rpc_buffer *req_buf,
+							  psa_key_id_t *id, psa_algorithm_t *alg,
+							  uint8_t *hash, size_t *hash_len,
+							  uint8_t *sig, size_t *sig_len);
 
-    /* Operation: asymmetric_decrypt */
-    rpc_status_t (*deserialize_asymmetric_decrypt_req)(const struct call_param_buf *req_buf,
-                                        psa_key_id_t *id, psa_algorithm_t *alg,
-                                        uint8_t *ciphertext, size_t *ciphertext_len,
-                                        uint8_t *salt, size_t *salt_len);
+	/* Operation: asymmetric_decrypt */
+	rpc_status_t (*deserialize_asymmetric_decrypt_req)(const struct rpc_buffer *req_buf,
+							   psa_key_id_t *id, psa_algorithm_t *alg,
+							   uint8_t *ciphertext,
+							   size_t *ciphertext_len, uint8_t *salt,
+							   size_t *salt_len);
 
-    rpc_status_t (*serialize_asymmetric_decrypt_resp)(struct call_param_buf *resp_buf,
-                                        const uint8_t *plaintext, size_t plaintext_len);
+	rpc_status_t (*serialize_asymmetric_decrypt_resp)(struct rpc_buffer *resp_buf,
+							  const uint8_t *plaintext,
+							  size_t plaintext_len);
 
-    /* Operation: asymmetric_encrypt */
-    rpc_status_t (*deserialize_asymmetric_encrypt_req)(const struct call_param_buf *req_buf,
-                                        psa_key_id_t *id, psa_algorithm_t *alg,
-                                        uint8_t *plaintext, size_t *plaintext_len,
-                                        uint8_t *salt, size_t *salt_len);
+	/* Operation: asymmetric_encrypt */
+	rpc_status_t (*deserialize_asymmetric_encrypt_req)(const struct rpc_buffer *req_buf,
+							   psa_key_id_t *id, psa_algorithm_t *alg,
+							   uint8_t *plaintext,
+							   size_t *plaintext_len, uint8_t *salt,
+							   size_t *salt_len);
 
-    rpc_status_t (*serialize_asymmetric_encrypt_resp)(struct call_param_buf *resp_buf,
-                                        const uint8_t *ciphertext, size_t ciphertext_len);
+	rpc_status_t (*serialize_asymmetric_encrypt_resp)(struct rpc_buffer *resp_buf,
+							  const uint8_t *ciphertext,
+							  size_t ciphertext_len);
 
-    /* Operation: generate_random */
-    rpc_status_t (*deserialize_generate_random_req)(const struct call_param_buf *req_buf,
-                                        size_t *size);
+	/* Operation: generate_random */
+	rpc_status_t (*deserialize_generate_random_req)(const struct rpc_buffer *req_buf,
+							size_t *size);
 
-    rpc_status_t (*serialize_generate_random_resp)(struct call_param_buf *resp_buf,
-                                        const uint8_t *output, size_t output_len);
+	rpc_status_t (*serialize_generate_random_resp)(struct rpc_buffer *resp_buf,
+						       const uint8_t *output, size_t output_len);
 };
 
 #endif /* CRYPTO_PROVIDER_SERIALIZER_H */
diff --git a/components/service/crypto/provider/serializer/packed-c/packedc_crypto_provider_serializer.c b/components/service/crypto/provider/serializer/packed-c/packedc_crypto_provider_serializer.c
index 4a7e59f..2ca39ea 100644
--- a/components/service/crypto/provider/serializer/packed-c/packedc_crypto_provider_serializer.c
+++ b/components/service/crypto/provider/serializer/packed-c/packedc_crypto_provider_serializer.c
@@ -3,708 +3,640 @@
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
-#include <string.h>
-#include <stdlib.h>
+#include "packedc_crypto_provider_serializer.h"
+
 #include <common/tlv/tlv.h>
-#include <psa/crypto.h>
 #include <protocols/rpc/common/packed-c/status.h>
-#include <protocols/service/crypto/packed-c/key_attributes.h>
 #include <protocols/service/crypto/packed-c/asymmetric_decrypt.h>
 #include <protocols/service/crypto/packed-c/asymmetric_encrypt.h>
+#include <protocols/service/crypto/packed-c/copy_key.h>
 #include <protocols/service/crypto/packed-c/destroy_key.h>
 #include <protocols/service/crypto/packed-c/export_key.h>
 #include <protocols/service/crypto/packed-c/export_public_key.h>
 #include <protocols/service/crypto/packed-c/generate_key.h>
 #include <protocols/service/crypto/packed-c/generate_random.h>
-#include <protocols/service/crypto/packed-c/import_key.h>
-#include <protocols/service/crypto/packed-c/copy_key.h>
-#include <protocols/service/crypto/packed-c/purge_key.h>
 #include <protocols/service/crypto/packed-c/get_key_attributes.h>
+#include <protocols/service/crypto/packed-c/import_key.h>
+#include <protocols/service/crypto/packed-c/key_attributes.h>
+#include <protocols/service/crypto/packed-c/purge_key.h>
 #include <protocols/service/crypto/packed-c/sign_hash.h>
 #include <protocols/service/crypto/packed-c/verify_hash.h>
-#include "packedc_crypto_provider_serializer.h"
+#include <psa/crypto.h>
+#include <stdlib.h>
+#include <string.h>
+
 #include "packedc_key_attributes_translator.h"
 
 /* Returns the maximum possible deserialized parameter size for a packed-c encoded message. */
-static size_t max_deserialised_parameter_size(const struct call_param_buf *req_buf)
+static size_t max_deserialised_parameter_size(const struct rpc_buffer *req_buf)
 {
-    /*
-     * Assume that a deserialized parameter must be the same size or smaller than the
-     * entire serialized message.
-     */
-    return req_buf->data_len;
+	/*
+	 * Assume that a deserialized parameter must be the same size or smaller than the
+	 * entire serialized message.
+	 */
+	return req_buf->data_length;
 }
 
 /* Operation: generate_key */
-static rpc_status_t deserialize_generate_key_req(const struct call_param_buf *req_buf,
-                                            psa_key_attributes_t *attributes)
+static rpc_status_t deserialize_generate_key_req(const struct rpc_buffer *req_buf,
+						 psa_key_attributes_t *attributes)
 {
-    rpc_status_t rpc_status = TS_RPC_ERROR_INVALID_REQ_BODY;
-    struct ts_crypto_generate_key_in recv_msg;
-    size_t expected_fixed_len = sizeof(struct ts_crypto_generate_key_in);
+	rpc_status_t rpc_status = RPC_ERROR_INVALID_REQUEST_BODY;
+	struct ts_crypto_generate_key_in recv_msg;
+	size_t expected_fixed_len = sizeof(struct ts_crypto_generate_key_in);
 
-    if (expected_fixed_len <= req_buf->data_len) {
+	if (expected_fixed_len <= req_buf->data_length) {
+		memcpy(&recv_msg, req_buf->data, expected_fixed_len);
+		packedc_crypto_provider_translate_key_attributes_from_proto(attributes,
+									    &recv_msg.attributes);
 
-        memcpy(&recv_msg, req_buf->data, expected_fixed_len);
-        packedc_crypto_provider_translate_key_attributes_from_proto(attributes,
-            &recv_msg.attributes);
+		rpc_status = RPC_SUCCESS;
+	}
 
-        rpc_status = TS_RPC_CALL_ACCEPTED;
-    }
-
-    return rpc_status;
+	return rpc_status;
 }
 
-static rpc_status_t serialize_generate_key_resp(struct call_param_buf *resp_buf,
-                                            psa_key_id_t id)
+static rpc_status_t serialize_generate_key_resp(struct rpc_buffer *resp_buf, psa_key_id_t id)
 {
-    rpc_status_t rpc_status = TS_RPC_ERROR_INTERNAL;
-    struct ts_crypto_generate_key_out resp_msg;
-    size_t fixed_len = sizeof(struct ts_crypto_generate_key_out);
+	rpc_status_t rpc_status = RPC_ERROR_INTERNAL;
+	struct ts_crypto_generate_key_out resp_msg;
+	size_t fixed_len = sizeof(struct ts_crypto_generate_key_out);
 
-    resp_msg.id = id;
+	resp_msg.id = id;
 
-    if (fixed_len <= resp_buf->size) {
+	if (fixed_len <= resp_buf->size) {
+		memcpy(resp_buf->data, &resp_msg, fixed_len);
+		resp_buf->data_length = fixed_len;
+		rpc_status = RPC_SUCCESS;
+	}
 
-        memcpy(resp_buf->data, &resp_msg, fixed_len);
-        resp_buf->data_len = fixed_len;
-        rpc_status = TS_RPC_CALL_ACCEPTED;
-    }
-
-    return rpc_status;
+	return rpc_status;
 }
 
 /* Operation: destroy_key */
-static rpc_status_t deserialize_destroy_key_req(const struct call_param_buf *req_buf,
-                                            psa_key_id_t *id)
+static rpc_status_t deserialize_destroy_key_req(const struct rpc_buffer *req_buf, psa_key_id_t *id)
 {
-    rpc_status_t rpc_status = TS_RPC_ERROR_INVALID_REQ_BODY;
-    struct ts_crypto_destroy_key_in recv_msg;
-    size_t expected_fixed_len = sizeof(struct ts_crypto_destroy_key_in);
+	rpc_status_t rpc_status = RPC_ERROR_INVALID_REQUEST_BODY;
+	struct ts_crypto_destroy_key_in recv_msg;
+	size_t expected_fixed_len = sizeof(struct ts_crypto_destroy_key_in);
 
-    if (expected_fixed_len <= req_buf->data_len) {
+	if (expected_fixed_len <= req_buf->data_length) {
+		memcpy(&recv_msg, req_buf->data, expected_fixed_len);
+		*id = recv_msg.id;
+		rpc_status = RPC_SUCCESS;
+	}
 
-        memcpy(&recv_msg, req_buf->data, expected_fixed_len);
-        *id = recv_msg.id;
-        rpc_status = TS_RPC_CALL_ACCEPTED;
-    }
-
-    return rpc_status;
+	return rpc_status;
 }
 
 /* Operation: export_key */
-static rpc_status_t deserialize_export_key_req(const struct call_param_buf *req_buf,
-                                            psa_key_id_t *id)
+static rpc_status_t deserialize_export_key_req(const struct rpc_buffer *req_buf, psa_key_id_t *id)
 {
-    rpc_status_t rpc_status = TS_RPC_ERROR_INVALID_REQ_BODY;
-    struct ts_crypto_export_key_in recv_msg;
-    size_t expected_fixed_len = sizeof(struct ts_crypto_export_key_in);
+	rpc_status_t rpc_status = RPC_ERROR_INVALID_REQUEST_BODY;
+	struct ts_crypto_export_key_in recv_msg;
+	size_t expected_fixed_len = sizeof(struct ts_crypto_export_key_in);
 
-    if (expected_fixed_len <= req_buf->data_len) {
+	if (expected_fixed_len <= req_buf->data_length) {
+		memcpy(&recv_msg, req_buf->data, expected_fixed_len);
+		*id = recv_msg.id;
+		rpc_status = RPC_SUCCESS;
+	}
 
-        memcpy(&recv_msg, req_buf->data, expected_fixed_len);
-        *id = recv_msg.id;
-        rpc_status = TS_RPC_CALL_ACCEPTED;
-    }
-
-    return rpc_status;
+	return rpc_status;
 }
 
-static rpc_status_t serialize_export_key_resp(struct call_param_buf *resp_buf,
-                                    const uint8_t *data, size_t data_len)
+static rpc_status_t serialize_export_key_resp(struct rpc_buffer *resp_buf, const uint8_t *data,
+					      size_t data_length)
 {
-    rpc_status_t rpc_status = TS_RPC_ERROR_INTERNAL;
-    struct tlv_iterator resp_iter;
+	rpc_status_t rpc_status = RPC_ERROR_INTERNAL;
+	struct tlv_iterator resp_iter;
+	struct tlv_record key_record;
 
-    struct tlv_record key_record;
-    key_record.tag = TS_CRYPTO_EXPORT_KEY_OUT_TAG_DATA;
-    key_record.length = data_len;
-    key_record.value = data;
+	key_record.tag = TS_CRYPTO_EXPORT_KEY_OUT_TAG_DATA;
+	key_record.length = data_length;
+	key_record.value = data;
 
-    tlv_iterator_begin(&resp_iter, resp_buf->data, resp_buf->size);
+	tlv_iterator_begin(&resp_iter, resp_buf->data, resp_buf->size);
 
-    if (tlv_encode(&resp_iter, &key_record)) {
+	if (tlv_encode(&resp_iter, &key_record)) {
+		resp_buf->data_length = tlv_required_space(data_length);
+		rpc_status = RPC_SUCCESS;
+	}
 
-        resp_buf->data_len = tlv_required_space(data_len);
-        rpc_status = TS_RPC_CALL_ACCEPTED;
-    }
-
-    return rpc_status;
+	return rpc_status;
 }
 
 /* Operation: export_public_key */
-static rpc_status_t deserialize_export_public_key_req(const struct call_param_buf *req_buf,
-                                                psa_key_id_t *id)
+static rpc_status_t deserialize_export_public_key_req(const struct rpc_buffer *req_buf,
+						      psa_key_id_t *id)
 {
-    rpc_status_t rpc_status = TS_RPC_ERROR_INVALID_REQ_BODY;
-    struct ts_crypto_export_public_key_in recv_msg;
-    size_t expected_fixed_len = sizeof(struct ts_crypto_export_public_key_in);
+	rpc_status_t rpc_status = RPC_ERROR_INVALID_REQUEST_BODY;
+	struct ts_crypto_export_public_key_in recv_msg;
+	size_t expected_fixed_len = sizeof(struct ts_crypto_export_public_key_in);
 
-    if (expected_fixed_len <= req_buf->data_len) {
+	if (expected_fixed_len <= req_buf->data_length) {
+		memcpy(&recv_msg, req_buf->data, expected_fixed_len);
+		*id = recv_msg.id;
+		rpc_status = RPC_SUCCESS;
+	}
 
-        memcpy(&recv_msg, req_buf->data, expected_fixed_len);
-        *id = recv_msg.id;
-        rpc_status = TS_RPC_CALL_ACCEPTED;
-    }
-
-    return rpc_status;
+	return rpc_status;
 }
 
-static rpc_status_t serialize_export_public_key_resp(struct call_param_buf *resp_buf,
-                                            const uint8_t *data, size_t data_len)
+static rpc_status_t serialize_export_public_key_resp(struct rpc_buffer *resp_buf,
+						     const uint8_t *data, size_t data_length)
 {
-    rpc_status_t rpc_status = TS_RPC_ERROR_INTERNAL;
-    struct tlv_iterator resp_iter;
+	rpc_status_t rpc_status = RPC_ERROR_INTERNAL;
+	struct tlv_iterator resp_iter;
+	struct tlv_record key_record;
 
-    struct tlv_record key_record;
-    key_record.tag = TS_CRYPTO_EXPORT_PUBLIC_KEY_OUT_TAG_DATA;
-    key_record.length = data_len;
-    key_record.value = data;
+	key_record.tag = TS_CRYPTO_EXPORT_PUBLIC_KEY_OUT_TAG_DATA;
+	key_record.length = data_length;
+	key_record.value = data;
 
-    tlv_iterator_begin(&resp_iter, resp_buf->data, resp_buf->size);
+	tlv_iterator_begin(&resp_iter, resp_buf->data, resp_buf->size);
 
-    if (tlv_encode(&resp_iter, &key_record)) {
+	if (tlv_encode(&resp_iter, &key_record)) {
+		resp_buf->data_length = tlv_required_space(data_length);
+		rpc_status = RPC_SUCCESS;
+	}
 
-        resp_buf->data_len = tlv_required_space(data_len);
-        rpc_status = TS_RPC_CALL_ACCEPTED;
-    }
-
-    return rpc_status;
+	return rpc_status;
 }
 
 /* Operation: import_key */
-static rpc_status_t deserialize_import_key_req(const struct call_param_buf *req_buf,
-                    psa_key_attributes_t *attributes, uint8_t *data, size_t *data_len)
+static rpc_status_t deserialize_import_key_req(const struct rpc_buffer *req_buf,
+					       psa_key_attributes_t *attributes, uint8_t *data,
+					       size_t *data_length)
 {
-    rpc_status_t rpc_status = TS_RPC_ERROR_INVALID_REQ_BODY;
-    struct ts_crypto_import_key_in recv_msg;
-    size_t expected_fixed_len = sizeof(struct ts_crypto_import_key_in);
+	rpc_status_t rpc_status = RPC_ERROR_INVALID_REQUEST_BODY;
+	struct ts_crypto_import_key_in recv_msg;
+	size_t expected_fixed_len = sizeof(struct ts_crypto_import_key_in);
 
-    if (expected_fixed_len <= req_buf->data_len) {
+	if (expected_fixed_len <= req_buf->data_length) {
+		struct tlv_const_iterator req_iter;
+		struct tlv_record decoded_record;
 
-        struct tlv_const_iterator req_iter;
-        struct tlv_record decoded_record;
+		rpc_status = RPC_SUCCESS;
 
-        rpc_status = TS_RPC_CALL_ACCEPTED;
+		memcpy(&recv_msg, req_buf->data, expected_fixed_len);
+		packedc_crypto_provider_translate_key_attributes_from_proto(attributes,
+									    &recv_msg.attributes);
 
-        memcpy(&recv_msg, req_buf->data, expected_fixed_len);
-        packedc_crypto_provider_translate_key_attributes_from_proto(attributes,
-            &recv_msg.attributes);
+		tlv_const_iterator_begin(&req_iter, (uint8_t *)req_buf->data + expected_fixed_len,
+					 req_buf->data_length - expected_fixed_len);
 
-        tlv_const_iterator_begin(&req_iter,
-            (uint8_t*)req_buf->data + expected_fixed_len,
-            req_buf->data_len - expected_fixed_len);
+		if (tlv_find_decode(&req_iter, TS_CRYPTO_IMPORT_KEY_IN_TAG_DATA, &decoded_record)) {
+			if (decoded_record.length <= *data_length) {
+				memcpy(data, decoded_record.value, decoded_record.length);
+				*data_length = decoded_record.length;
+			} else {
+				/* Buffer provided too small */
+				return RPC_ERROR_INVALID_REQUEST_BODY;
+			}
+		} else {
+			/* Default for missing parameter */
+			*data_length = 0;
+		}
+	}
 
-        if (tlv_find_decode(&req_iter, TS_CRYPTO_IMPORT_KEY_IN_TAG_DATA, &decoded_record)) {
-
-            if (decoded_record.length <= *data_len) {
-
-                memcpy(data, decoded_record.value, decoded_record.length);
-                *data_len = decoded_record.length;
-            }
-            else {
-                /* Buffer provided too small */
-                return TS_RPC_ERROR_INVALID_REQ_BODY;
-            }
-        }
-        else {
-            /* Default for missing parameter */
-            *data_len = 0;
-        }
-    }
-
-    return rpc_status;
+	return rpc_status;
 }
 
-static rpc_status_t serialize_import_key_resp(struct call_param_buf *resp_buf,
-                                        psa_key_id_t id)
+static rpc_status_t serialize_import_key_resp(struct rpc_buffer *resp_buf, psa_key_id_t id)
 {
-    rpc_status_t rpc_status = TS_RPC_ERROR_INTERNAL;
-    struct ts_crypto_import_key_out resp_msg;
-    size_t fixed_len = sizeof(struct ts_crypto_import_key_out);
+	rpc_status_t rpc_status = RPC_ERROR_INTERNAL;
+	struct ts_crypto_import_key_out resp_msg;
+	size_t fixed_len = sizeof(struct ts_crypto_import_key_out);
 
-    resp_msg.id = id;
+	resp_msg.id = id;
 
-    if (fixed_len <= resp_buf->size) {
+	if (fixed_len <= resp_buf->size) {
+		memcpy(resp_buf->data, &resp_msg, fixed_len);
+		resp_buf->data_length = fixed_len;
+		rpc_status = RPC_SUCCESS;
+	}
 
-        memcpy(resp_buf->data, &resp_msg, fixed_len);
-        resp_buf->data_len = fixed_len;
-        rpc_status = TS_RPC_CALL_ACCEPTED;
-    }
-
-    return rpc_status;
+	return rpc_status;
 }
 
 /* Operation: copy_key */
-static rpc_status_t deserialize_copy_key_req(const struct call_param_buf *req_buf,
-                                        psa_key_attributes_t *attributes,
-                                        psa_key_id_t *source_id)
+static rpc_status_t deserialize_copy_key_req(const struct rpc_buffer *req_buf,
+					     psa_key_attributes_t *attributes,
+					     psa_key_id_t *source_id)
 {
-    rpc_status_t rpc_status = TS_RPC_ERROR_INVALID_REQ_BODY;
-    struct ts_crypto_copy_key_in recv_msg;
-    size_t expected_fixed_len = sizeof(struct ts_crypto_copy_key_in);
+	rpc_status_t rpc_status = RPC_ERROR_INVALID_REQUEST_BODY;
+	struct ts_crypto_copy_key_in recv_msg;
+	size_t expected_fixed_len = sizeof(struct ts_crypto_copy_key_in);
 
-    if (expected_fixed_len <= req_buf->data_len) {
+	if (expected_fixed_len <= req_buf->data_length) {
+		rpc_status = RPC_SUCCESS;
 
-        rpc_status = TS_RPC_CALL_ACCEPTED;
+		memcpy(&recv_msg, req_buf->data, expected_fixed_len);
+		packedc_crypto_provider_translate_key_attributes_from_proto(attributes,
+									    &recv_msg.attributes);
 
-        memcpy(&recv_msg, req_buf->data, expected_fixed_len);
-        packedc_crypto_provider_translate_key_attributes_from_proto(attributes,
-            &recv_msg.attributes);
+		*source_id = recv_msg.source_key_id;
+	}
 
-        *source_id = recv_msg.source_key_id;
-    }
-
-    return rpc_status;
+	return rpc_status;
 }
 
-static rpc_status_t serialize_copy_key_resp(struct call_param_buf *resp_buf,
-                                        psa_key_id_t target_id)
+static rpc_status_t serialize_copy_key_resp(struct rpc_buffer *resp_buf, psa_key_id_t target_id)
 {
-    rpc_status_t rpc_status = TS_RPC_ERROR_INTERNAL;
-    struct ts_crypto_copy_key_out resp_msg;
-    size_t fixed_len = sizeof(struct ts_crypto_copy_key_out);
+	rpc_status_t rpc_status = RPC_ERROR_INTERNAL;
+	struct ts_crypto_copy_key_out resp_msg;
+	size_t fixed_len = sizeof(struct ts_crypto_copy_key_out);
 
-    resp_msg.target_key_id = target_id;
+	resp_msg.target_key_id = target_id;
 
-    if (fixed_len <= resp_buf->size) {
+	if (fixed_len <= resp_buf->size) {
+		memcpy(resp_buf->data, &resp_msg, fixed_len);
+		resp_buf->data_length = fixed_len;
+		rpc_status = RPC_SUCCESS;
+	}
 
-        memcpy(resp_buf->data, &resp_msg, fixed_len);
-        resp_buf->data_len = fixed_len;
-        rpc_status = TS_RPC_CALL_ACCEPTED;
-    }
-
-    return rpc_status;
+	return rpc_status;
 }
 
 /* Operation: purge_key */
-static rpc_status_t deserialize_purge_key_req(const struct call_param_buf *req_buf,
-                                        psa_key_id_t *id)
+static rpc_status_t deserialize_purge_key_req(const struct rpc_buffer *req_buf, psa_key_id_t *id)
 {
-    rpc_status_t rpc_status = TS_RPC_ERROR_INVALID_REQ_BODY;
-    struct ts_crypto_purge_key_in recv_msg;
-    size_t expected_fixed_len = sizeof(struct ts_crypto_purge_key_in);
+	rpc_status_t rpc_status = RPC_ERROR_INVALID_REQUEST_BODY;
+	struct ts_crypto_purge_key_in recv_msg;
+	size_t expected_fixed_len = sizeof(struct ts_crypto_purge_key_in);
 
-    if (expected_fixed_len <= req_buf->data_len) {
+	if (expected_fixed_len <= req_buf->data_length) {
+		memcpy(&recv_msg, req_buf->data, expected_fixed_len);
+		*id = recv_msg.id;
+		rpc_status = RPC_SUCCESS;
+	}
 
-        memcpy(&recv_msg, req_buf->data, expected_fixed_len);
-        *id = recv_msg.id;
-        rpc_status = TS_RPC_CALL_ACCEPTED;
-    }
-
-    return rpc_status;
+	return rpc_status;
 }
 
 /* Operation: get_key_attributes */
-static rpc_status_t deserialize_get_key_attributes_req(const struct call_param_buf *req_buf,
-                                        psa_key_id_t *id)
+static rpc_status_t deserialize_get_key_attributes_req(const struct rpc_buffer *req_buf,
+						       psa_key_id_t *id)
 {
-    rpc_status_t rpc_status = TS_RPC_ERROR_INVALID_REQ_BODY;
-    struct ts_crypto_get_key_attributes_in recv_msg;
-    size_t expected_fixed_len = sizeof(struct ts_crypto_get_key_attributes_in);
+	rpc_status_t rpc_status = RPC_ERROR_INVALID_REQUEST_BODY;
+	struct ts_crypto_get_key_attributes_in recv_msg;
+	size_t expected_fixed_len = sizeof(struct ts_crypto_get_key_attributes_in);
 
-    if (expected_fixed_len <= req_buf->data_len) {
+	if (expected_fixed_len <= req_buf->data_length) {
+		memcpy(&recv_msg, req_buf->data, expected_fixed_len);
+		*id = recv_msg.id;
+		rpc_status = RPC_SUCCESS;
+	}
 
-        memcpy(&recv_msg, req_buf->data, expected_fixed_len);
-        *id = recv_msg.id;
-        rpc_status = TS_RPC_CALL_ACCEPTED;
-    }
-
-    return rpc_status;
+	return rpc_status;
 }
 
-static rpc_status_t serialize_get_key_attributes_resp(struct call_param_buf *resp_buf,
-                                        const psa_key_attributes_t *attributes)
+static rpc_status_t serialize_get_key_attributes_resp(struct rpc_buffer *resp_buf,
+						      const psa_key_attributes_t *attributes)
 {
-    rpc_status_t rpc_status = TS_RPC_ERROR_INTERNAL;
-    struct ts_crypto_get_key_attributes_out resp_msg;
-    size_t fixed_len = sizeof(struct ts_crypto_get_key_attributes_out);
+	rpc_status_t rpc_status = RPC_ERROR_INTERNAL;
+	struct ts_crypto_get_key_attributes_out resp_msg;
+	size_t fixed_len = sizeof(struct ts_crypto_get_key_attributes_out);
 
-    packedc_crypto_provider_translate_key_attributes_to_proto(&resp_msg.attributes, attributes);
+	packedc_crypto_provider_translate_key_attributes_to_proto(&resp_msg.attributes, attributes);
 
-    if (fixed_len <= resp_buf->size) {
+	if (fixed_len <= resp_buf->size) {
+		memcpy(resp_buf->data, &resp_msg, fixed_len);
+		resp_buf->data_length = fixed_len;
+		rpc_status = RPC_SUCCESS;
+	}
 
-        memcpy(resp_buf->data, &resp_msg, fixed_len);
-        resp_buf->data_len = fixed_len;
-        rpc_status = TS_RPC_CALL_ACCEPTED;
-    }
-
-    return rpc_status;
+	return rpc_status;
 }
 
 /* Operation: sign_hash */
-static rpc_status_t deserialize_asymmetric_sign_req(const struct call_param_buf *req_buf,
-                            psa_key_id_t *id, psa_algorithm_t *alg,
-                            uint8_t *hash, size_t *hash_len)
+static rpc_status_t deserialize_asymmetric_sign_req(const struct rpc_buffer *req_buf,
+						    psa_key_id_t *id, psa_algorithm_t *alg,
+						    uint8_t *hash, size_t *hash_len)
 {
-    rpc_status_t rpc_status = TS_RPC_ERROR_INVALID_REQ_BODY;
-    struct ts_crypto_sign_hash_in recv_msg;
-    size_t expected_fixed_len = sizeof(struct ts_crypto_sign_hash_in);
+	rpc_status_t rpc_status = RPC_ERROR_INVALID_REQUEST_BODY;
+	struct ts_crypto_sign_hash_in recv_msg;
+	size_t expected_fixed_len = sizeof(struct ts_crypto_sign_hash_in);
 
-    if (expected_fixed_len <= req_buf->data_len) {
+	if (expected_fixed_len <= req_buf->data_length) {
+		struct tlv_const_iterator req_iter;
+		struct tlv_record decoded_record;
 
-        struct tlv_const_iterator req_iter;
-        struct tlv_record decoded_record;
+		rpc_status = RPC_SUCCESS;
 
-        rpc_status = TS_RPC_CALL_ACCEPTED;
+		memcpy(&recv_msg, req_buf->data, expected_fixed_len);
 
-        memcpy(&recv_msg, req_buf->data, expected_fixed_len);
+		*id = recv_msg.id;
+		*alg = recv_msg.alg;
 
-        *id = recv_msg.id;
-        *alg = recv_msg.alg;
+		tlv_const_iterator_begin(&req_iter, (uint8_t *)req_buf->data + expected_fixed_len,
+					 req_buf->data_length - expected_fixed_len);
 
-        tlv_const_iterator_begin(&req_iter,
-            (uint8_t*)req_buf->data + expected_fixed_len,
-            req_buf->data_len - expected_fixed_len);
+		if (tlv_find_decode(&req_iter, TS_CRYPTO_SIGN_HASH_IN_TAG_HASH, &decoded_record)) {
+			if (decoded_record.length <= *hash_len) {
+				memcpy(hash, decoded_record.value, decoded_record.length);
+				*hash_len = decoded_record.length;
+			} else {
+				/* Buffer provided too small */
+				return RPC_ERROR_INVALID_REQUEST_BODY;
+			}
+		} else {
+			/* Default to a zero length hash */
+			*hash_len = 0;
+		}
+	}
 
-        if (tlv_find_decode(&req_iter, TS_CRYPTO_SIGN_HASH_IN_TAG_HASH, &decoded_record)) {
-
-            if (decoded_record.length <= *hash_len) {
-
-                memcpy(hash, decoded_record.value, decoded_record.length);
-                *hash_len = decoded_record.length;
-            }
-            else {
-                /* Buffer provided too small */
-                return TS_RPC_ERROR_INVALID_REQ_BODY;
-            }
-        }
-        else {
-            /* Default to a zero length hash */
-            *hash_len = 0;
-        }
-    }
-
-    return rpc_status;
+	return rpc_status;
 }
 
-static rpc_status_t serialize_asymmetric_sign_resp(struct call_param_buf *resp_buf,
-                            const uint8_t *sig, size_t sig_len)
+static rpc_status_t serialize_asymmetric_sign_resp(struct rpc_buffer *resp_buf, const uint8_t *sig,
+						   size_t sig_len)
 {
-    rpc_status_t rpc_status = TS_RPC_ERROR_INTERNAL;
-    struct tlv_iterator resp_iter;
+	rpc_status_t rpc_status = RPC_ERROR_INTERNAL;
+	struct tlv_iterator resp_iter;
+	struct tlv_record sig_record;
 
-    struct tlv_record sig_record;
-    sig_record.tag = TS_CRYPTO_SIGN_HASH_OUT_TAG_SIGNATURE;
-    sig_record.length = sig_len;
-    sig_record.value = sig;
+	sig_record.tag = TS_CRYPTO_SIGN_HASH_OUT_TAG_SIGNATURE;
+	sig_record.length = sig_len;
+	sig_record.value = sig;
 
-    tlv_iterator_begin(&resp_iter, resp_buf->data, resp_buf->size);
+	tlv_iterator_begin(&resp_iter, resp_buf->data, resp_buf->size);
 
-    if (tlv_encode(&resp_iter, &sig_record)) {
+	if (tlv_encode(&resp_iter, &sig_record)) {
+		resp_buf->data_length = tlv_required_space(sig_len);
+		rpc_status = RPC_SUCCESS;
+	}
 
-        resp_buf->data_len = tlv_required_space(sig_len);
-        rpc_status = TS_RPC_CALL_ACCEPTED;
-    }
-
-    return rpc_status;
+	return rpc_status;
 }
 
 /* Operation: verify_hash */
-static rpc_status_t deserialize_asymmetric_verify_req(const struct call_param_buf *req_buf,
-                                psa_key_id_t *id, psa_algorithm_t *alg,
-                                uint8_t *hash, size_t *hash_len,
-                                uint8_t *sig, size_t *sig_len)
+static rpc_status_t deserialize_asymmetric_verify_req(const struct rpc_buffer *req_buf,
+						      psa_key_id_t *id, psa_algorithm_t *alg,
+						      uint8_t *hash, size_t *hash_len, uint8_t *sig,
+						      size_t *sig_len)
 {
-    rpc_status_t rpc_status = TS_RPC_ERROR_INVALID_REQ_BODY;
-    struct ts_crypto_verify_hash_in recv_msg;
-    size_t expected_fixed_len = sizeof(struct ts_crypto_verify_hash_in);
+	rpc_status_t rpc_status = RPC_ERROR_INVALID_REQUEST_BODY;
+	struct ts_crypto_verify_hash_in recv_msg;
+	size_t expected_fixed_len = sizeof(struct ts_crypto_verify_hash_in);
 
-    if (expected_fixed_len <= req_buf->data_len) {
+	if (expected_fixed_len <= req_buf->data_length) {
+		struct tlv_const_iterator req_iter;
+		struct tlv_record decoded_record;
 
-        struct tlv_const_iterator req_iter;
-        struct tlv_record decoded_record;
+		rpc_status = RPC_SUCCESS;
 
-        rpc_status = TS_RPC_CALL_ACCEPTED;
+		memcpy(&recv_msg, req_buf->data, expected_fixed_len);
 
-        memcpy(&recv_msg, req_buf->data, expected_fixed_len);
+		*id = recv_msg.id;
+		*alg = recv_msg.alg;
 
-        *id = recv_msg.id;
-        *alg = recv_msg.alg;
+		tlv_const_iterator_begin(&req_iter, (uint8_t *)req_buf->data + expected_fixed_len,
+					 req_buf->data_length - expected_fixed_len);
 
-        tlv_const_iterator_begin(&req_iter,
-            (uint8_t*)req_buf->data + expected_fixed_len,
-            req_buf->data_len - expected_fixed_len);
+		if (tlv_find_decode(&req_iter, TS_CRYPTO_VERIFY_HASH_IN_TAG_HASH,
+				    &decoded_record)) {
+			if (decoded_record.length <= *hash_len) {
+				memcpy(hash, decoded_record.value, decoded_record.length);
+				*hash_len = decoded_record.length;
+			} else {
+				/* Buffer provided too small */
+				return RPC_ERROR_INVALID_REQUEST_BODY;
+			}
+		} else {
+			/* Default to a zero length hash */
+			*hash_len = 0;
+		}
 
-        if (tlv_find_decode(&req_iter, TS_CRYPTO_VERIFY_HASH_IN_TAG_HASH, &decoded_record)) {
+		if (tlv_find_decode(&req_iter, TS_CRYPTO_VERIFY_HASH_IN_TAG_SIGNATURE,
+				    &decoded_record)) {
+			if (decoded_record.length <= *sig_len) {
+				memcpy(sig, decoded_record.value, decoded_record.length);
+				*sig_len = decoded_record.length;
+			} else {
+				/* Buffer provided too small */
+				return RPC_ERROR_INVALID_REQUEST_BODY;
+			}
+		} else {
+			/* Default to a zero length hash */
+			*sig_len = 0;
+		}
+	}
 
-            if (decoded_record.length <= *hash_len) {
-
-                memcpy(hash, decoded_record.value, decoded_record.length);
-                *hash_len = decoded_record.length;
-            }
-            else {
-                /* Buffer provided too small */
-                return TS_RPC_ERROR_INVALID_REQ_BODY;
-            }
-        }
-        else {
-            /* Default to a zero length hash */
-            *hash_len = 0;
-        }
-
-        if (tlv_find_decode(&req_iter, TS_CRYPTO_VERIFY_HASH_IN_TAG_SIGNATURE, &decoded_record)) {
-
-            if (decoded_record.length <= *sig_len) {
-
-                memcpy(sig, decoded_record.value, decoded_record.length);
-                *sig_len = decoded_record.length;
-            }
-            else {
-                /* Buffer provided too small */
-                return TS_RPC_ERROR_INVALID_REQ_BODY;
-            }
-        }
-        else {
-            /* Default to a zero length hash */
-            *sig_len = 0;
-        }
-    }
-
-    return rpc_status;
+	return rpc_status;
 }
 
 /* Operation: asymmetric_decrypt */
-static rpc_status_t deserialize_asymmetric_decrypt_req(const struct call_param_buf *req_buf,
-                                psa_key_id_t *id, psa_algorithm_t *alg,
-                                uint8_t *ciphertext, size_t *ciphertext_len,
-                                uint8_t *salt, size_t *salt_len)
+static rpc_status_t deserialize_asymmetric_decrypt_req(const struct rpc_buffer *req_buf,
+						       psa_key_id_t *id, psa_algorithm_t *alg,
+						       uint8_t *ciphertext, size_t *ciphertext_len,
+						       uint8_t *salt, size_t *salt_len)
 {
-    rpc_status_t rpc_status = TS_RPC_ERROR_INVALID_REQ_BODY;
-    struct ts_crypto_asymmetric_decrypt_in recv_msg;
-    size_t expected_fixed_len = sizeof(struct ts_crypto_asymmetric_decrypt_in);
+	rpc_status_t rpc_status = RPC_ERROR_INVALID_REQUEST_BODY;
+	struct ts_crypto_asymmetric_decrypt_in recv_msg;
+	size_t expected_fixed_len = sizeof(struct ts_crypto_asymmetric_decrypt_in);
 
-    if (expected_fixed_len <= req_buf->data_len) {
+	if (expected_fixed_len <= req_buf->data_length) {
+		struct tlv_const_iterator req_iter;
+		struct tlv_record decoded_record;
 
-        struct tlv_const_iterator req_iter;
-        struct tlv_record decoded_record;
+		rpc_status = RPC_SUCCESS;
 
-        rpc_status = TS_RPC_CALL_ACCEPTED;
+		memcpy(&recv_msg, req_buf->data, expected_fixed_len);
 
-        memcpy(&recv_msg, req_buf->data, expected_fixed_len);
+		*id = recv_msg.id;
+		*alg = recv_msg.alg;
 
-        *id = recv_msg.id;
-        *alg = recv_msg.alg;
+		tlv_const_iterator_begin(&req_iter, (uint8_t *)req_buf->data + expected_fixed_len,
+					 req_buf->data_length - expected_fixed_len);
 
-        tlv_const_iterator_begin(&req_iter,
-            (uint8_t*)req_buf->data + expected_fixed_len,
-            req_buf->data_len - expected_fixed_len);
+		if (tlv_find_decode(&req_iter, TS_CRYPTO_ASYMMETRIC_DECRYPT_IN_TAG_CIPHERTEXT,
+				    &decoded_record)) {
+			if (decoded_record.length <= *ciphertext_len) {
+				memcpy(ciphertext, decoded_record.value, decoded_record.length);
+				*ciphertext_len = decoded_record.length;
+			} else {
+				/* Buffer provided too small */
+				return RPC_ERROR_INVALID_REQUEST_BODY;
+			}
+		} else {
+			/* Default to a zero length hash */
+			*ciphertext_len = 0;
+		}
 
-        if (tlv_find_decode(&req_iter, TS_CRYPTO_ASYMMETRIC_DECRYPT_IN_TAG_CIPHERTEXT, &decoded_record)) {
+		if (tlv_find_decode(&req_iter, TS_CRYPTO_ASYMMETRIC_DECRYPT_IN_TAG_SALT,
+				    &decoded_record)) {
+			if (decoded_record.length <= *salt_len) {
+				memcpy(salt, decoded_record.value, decoded_record.length);
+				*salt_len = decoded_record.length;
+			} else {
+				/* Buffer provided too small */
+				return RPC_ERROR_INVALID_REQUEST_BODY;
+			}
+		} else {
+			/* Default to a zero length hash */
+			*salt_len = 0;
+		}
+	}
 
-            if (decoded_record.length <= *ciphertext_len) {
-
-                memcpy(ciphertext, decoded_record.value, decoded_record.length);
-                *ciphertext_len = decoded_record.length;
-            }
-            else {
-                /* Buffer provided too small */
-                return TS_RPC_ERROR_INVALID_REQ_BODY;
-            }
-        }
-        else {
-            /* Default to a zero length hash */
-            *ciphertext_len = 0;
-        }
-
-        if (tlv_find_decode(&req_iter, TS_CRYPTO_ASYMMETRIC_DECRYPT_IN_TAG_SALT, &decoded_record)) {
-
-            if (decoded_record.length <= *salt_len) {
-
-                memcpy(salt, decoded_record.value, decoded_record.length);
-                *salt_len = decoded_record.length;
-            }
-            else {
-                /* Buffer provided too small */
-                return TS_RPC_ERROR_INVALID_REQ_BODY;
-            }
-        }
-        else {
-            /* Default to a zero length hash */
-            *salt_len = 0;
-        }
-    }
-
-    return rpc_status;
+	return rpc_status;
 }
 
-static rpc_status_t serialize_asymmetric_decrypt_resp(struct call_param_buf *resp_buf,
-                                const uint8_t *plaintext, size_t plaintext_len)
+static rpc_status_t serialize_asymmetric_decrypt_resp(struct rpc_buffer *resp_buf,
+						      const uint8_t *plaintext,
+						      size_t plaintext_len)
 {
-    rpc_status_t rpc_status = TS_RPC_ERROR_INTERNAL;
-    struct tlv_iterator resp_iter;
+	rpc_status_t rpc_status = RPC_ERROR_INTERNAL;
+	struct tlv_iterator resp_iter;
+	struct tlv_record sig_record;
 
-    struct tlv_record sig_record;
-    sig_record.tag = TS_CRYPTO_ASYMMETRIC_DECRYPT_OUT_TAG_PLAINTEXT;
-    sig_record.length = plaintext_len;
-    sig_record.value = plaintext;
+	sig_record.tag = TS_CRYPTO_ASYMMETRIC_DECRYPT_OUT_TAG_PLAINTEXT;
+	sig_record.length = plaintext_len;
+	sig_record.value = plaintext;
 
-    tlv_iterator_begin(&resp_iter, resp_buf->data, resp_buf->size);
+	tlv_iterator_begin(&resp_iter, resp_buf->data, resp_buf->size);
 
-    if (tlv_encode(&resp_iter, &sig_record)) {
+	if (tlv_encode(&resp_iter, &sig_record)) {
+		resp_buf->data_length = tlv_required_space(plaintext_len);
+		rpc_status = RPC_SUCCESS;
+	}
 
-        resp_buf->data_len = tlv_required_space(plaintext_len);
-        rpc_status = TS_RPC_CALL_ACCEPTED;
-    }
-
-    return rpc_status;
+	return rpc_status;
 }
 
 /* Operation: asymmetric_encrypt */
-static rpc_status_t deserialize_asymmetric_encrypt_req(const struct call_param_buf *req_buf,
-                                    psa_key_id_t *id, psa_algorithm_t *alg,
-                                    uint8_t *plaintext, size_t *plaintext_len,
-                                    uint8_t *salt, size_t *salt_len)
+static rpc_status_t deserialize_asymmetric_encrypt_req(const struct rpc_buffer *req_buf,
+						       psa_key_id_t *id, psa_algorithm_t *alg,
+						       uint8_t *plaintext, size_t *plaintext_len,
+						       uint8_t *salt, size_t *salt_len)
 {
-    rpc_status_t rpc_status = TS_RPC_ERROR_INVALID_REQ_BODY;
-    struct ts_crypto_asymmetric_encrypt_in recv_msg;
-    size_t expected_fixed_len = sizeof(struct ts_crypto_asymmetric_encrypt_in);
+	rpc_status_t rpc_status = RPC_ERROR_INVALID_REQUEST_BODY;
+	struct ts_crypto_asymmetric_encrypt_in recv_msg;
+	size_t expected_fixed_len = sizeof(struct ts_crypto_asymmetric_encrypt_in);
 
-    if (expected_fixed_len <= req_buf->data_len) {
+	if (expected_fixed_len <= req_buf->data_length) {
+		struct tlv_const_iterator req_iter;
+		struct tlv_record decoded_record;
 
-        struct tlv_const_iterator req_iter;
-        struct tlv_record decoded_record;
+		rpc_status = RPC_SUCCESS;
 
-        rpc_status = TS_RPC_CALL_ACCEPTED;
+		memcpy(&recv_msg, req_buf->data, expected_fixed_len);
 
-        memcpy(&recv_msg, req_buf->data, expected_fixed_len);
+		*id = recv_msg.id;
+		*alg = recv_msg.alg;
 
-        *id = recv_msg.id;
-        *alg = recv_msg.alg;
+		tlv_const_iterator_begin(&req_iter, (uint8_t *)req_buf->data + expected_fixed_len,
+					 req_buf->data_length - expected_fixed_len);
 
-        tlv_const_iterator_begin(&req_iter,
-            (uint8_t*)req_buf->data + expected_fixed_len,
-            req_buf->data_len - expected_fixed_len);
+		if (tlv_find_decode(&req_iter, TS_CRYPTO_ASYMMETRIC_ENCRYPT_IN_TAG_PLAINTEXT,
+				    &decoded_record)) {
+			if (decoded_record.length <= *plaintext_len) {
+				memcpy(plaintext, decoded_record.value, decoded_record.length);
+				*plaintext_len = decoded_record.length;
+			} else {
+				/* Buffer provided too small */
+				return RPC_ERROR_INVALID_REQUEST_BODY;
+			}
+		} else {
+			/* Default to a zero length hash */
+			*plaintext_len = 0;
+		}
 
-        if (tlv_find_decode(&req_iter, TS_CRYPTO_ASYMMETRIC_ENCRYPT_IN_TAG_PLAINTEXT, &decoded_record)) {
+		if (tlv_find_decode(&req_iter, TS_CRYPTO_ASYMMETRIC_ENCRYPT_IN_TAG_SALT,
+				    &decoded_record)) {
+			if (decoded_record.length <= *salt_len) {
+				memcpy(salt, decoded_record.value, decoded_record.length);
+				*salt_len = decoded_record.length;
+			} else {
+				/* Buffer provided too small */
+				return RPC_ERROR_INVALID_REQUEST_BODY;
+			}
+		} else {
+			/* Default to a zero length hash */
+			*salt_len = 0;
+		}
+	}
 
-            if (decoded_record.length <= *plaintext_len) {
-
-                memcpy(plaintext, decoded_record.value, decoded_record.length);
-                *plaintext_len = decoded_record.length;
-            }
-            else {
-                /* Buffer provided too small */
-                return TS_RPC_ERROR_INVALID_REQ_BODY;
-            }
-        }
-        else {
-            /* Default to a zero length hash */
-            *plaintext_len = 0;
-        }
-
-        if (tlv_find_decode(&req_iter, TS_CRYPTO_ASYMMETRIC_ENCRYPT_IN_TAG_SALT, &decoded_record)) {
-
-            if (decoded_record.length <= *salt_len) {
-
-                memcpy(salt, decoded_record.value, decoded_record.length);
-                *salt_len = decoded_record.length;
-            }
-            else {
-                /* Buffer provided too small */
-                return TS_RPC_ERROR_INVALID_REQ_BODY;
-            }
-        }
-        else {
-            /* Default to a zero length hash */
-            *salt_len = 0;
-        }
-    }
-
-    return rpc_status;
+	return rpc_status;
 }
 
-static rpc_status_t serialize_asymmetric_encrypt_resp(struct call_param_buf *resp_buf,
-                                    const uint8_t *ciphertext, size_t ciphertext_len)
+static rpc_status_t serialize_asymmetric_encrypt_resp(struct rpc_buffer *resp_buf,
+						      const uint8_t *ciphertext,
+						      size_t ciphertext_len)
 {
-    rpc_status_t rpc_status = TS_RPC_ERROR_INTERNAL;
-    struct tlv_iterator resp_iter;
+	rpc_status_t rpc_status = RPC_ERROR_INTERNAL;
+	struct tlv_iterator resp_iter;
+	struct tlv_record sig_record;
 
-    struct tlv_record sig_record;
-    sig_record.tag = TS_CRYPTO_ASYMMETRIC_ENCRYPT_OUT_TAG_CIPHERTEXT;
-    sig_record.length = ciphertext_len;
-    sig_record.value = ciphertext;
+	sig_record.tag = TS_CRYPTO_ASYMMETRIC_ENCRYPT_OUT_TAG_CIPHERTEXT;
+	sig_record.length = ciphertext_len;
+	sig_record.value = ciphertext;
 
-    tlv_iterator_begin(&resp_iter, resp_buf->data, resp_buf->size);
+	tlv_iterator_begin(&resp_iter, resp_buf->data, resp_buf->size);
 
-    if (tlv_encode(&resp_iter, &sig_record)) {
+	if (tlv_encode(&resp_iter, &sig_record)) {
+		resp_buf->data_length = tlv_required_space(ciphertext_len);
+		rpc_status = RPC_SUCCESS;
+	}
 
-        resp_buf->data_len = tlv_required_space(ciphertext_len);
-        rpc_status = TS_RPC_CALL_ACCEPTED;
-    }
-
-    return rpc_status;
+	return rpc_status;
 }
 
 /* Operation: generate_random */
-static rpc_status_t deserialize_generate_random_req(const struct call_param_buf *req_buf,
-                                        size_t *size)
+static rpc_status_t deserialize_generate_random_req(const struct rpc_buffer *req_buf, size_t *size)
 {
-    rpc_status_t rpc_status = TS_RPC_ERROR_INVALID_REQ_BODY;
-    struct ts_crypto_generate_random_in recv_msg;
-    size_t expected_fixed_len = sizeof(struct ts_crypto_generate_random_in);
+	rpc_status_t rpc_status = RPC_ERROR_INVALID_REQUEST_BODY;
+	struct ts_crypto_generate_random_in recv_msg;
+	size_t expected_fixed_len = sizeof(struct ts_crypto_generate_random_in);
 
-    if (expected_fixed_len <= req_buf->data_len) {
+	if (expected_fixed_len <= req_buf->data_length) {
+		memcpy(&recv_msg, req_buf->data, expected_fixed_len);
+		*size = recv_msg.size;
+		rpc_status = RPC_SUCCESS;
+	}
 
-        memcpy(&recv_msg, req_buf->data, expected_fixed_len);
-        *size = recv_msg.size;
-        rpc_status = TS_RPC_CALL_ACCEPTED;
-    }
-
-    return rpc_status;
+	return rpc_status;
 }
 
-static rpc_status_t serialize_generate_random_resp(struct call_param_buf *resp_buf,
-                                        const uint8_t *output, size_t output_len)
+static rpc_status_t serialize_generate_random_resp(struct rpc_buffer *resp_buf,
+						   const uint8_t *output, size_t output_len)
 {
-    rpc_status_t rpc_status = TS_RPC_ERROR_INTERNAL;
-    struct tlv_iterator resp_iter;
+	rpc_status_t rpc_status = RPC_ERROR_INTERNAL;
+	struct tlv_iterator resp_iter;
+	struct tlv_record out_record;
 
-    struct tlv_record out_record;
-    out_record.tag = TS_CRYPTO_GENERATE_RANDOM_OUT_TAG_RANDOM_BYTES;
-    out_record.length = output_len;
-    out_record.value = output;
+	out_record.tag = TS_CRYPTO_GENERATE_RANDOM_OUT_TAG_RANDOM_BYTES;
+	out_record.length = output_len;
+	out_record.value = output;
 
-    tlv_iterator_begin(&resp_iter, resp_buf->data, resp_buf->size);
+	tlv_iterator_begin(&resp_iter, resp_buf->data, resp_buf->size);
 
-    if (tlv_encode(&resp_iter, &out_record)) {
+	if (tlv_encode(&resp_iter, &out_record)) {
+		resp_buf->data_length = tlv_required_space(output_len);
+		rpc_status = RPC_SUCCESS;
+	}
 
-        resp_buf->data_len = tlv_required_space(output_len);
-        rpc_status = TS_RPC_CALL_ACCEPTED;
-    }
-
-    return rpc_status;
+	return rpc_status;
 }
 
 /* Singleton method to provide access to the serializer instance */
 const struct crypto_provider_serializer *packedc_crypto_provider_serializer_instance(void)
 {
-    static const struct crypto_provider_serializer instance = {
-        max_deserialised_parameter_size,
-        deserialize_generate_key_req,
-        serialize_generate_key_resp,
-        deserialize_destroy_key_req,
-        deserialize_export_key_req,
-        serialize_export_key_resp,
-        deserialize_export_public_key_req,
-        serialize_export_public_key_resp,
-        deserialize_import_key_req,
-        serialize_import_key_resp,
-        deserialize_copy_key_req,
-        serialize_copy_key_resp,
-        deserialize_purge_key_req,
-        deserialize_get_key_attributes_req,
-        serialize_get_key_attributes_resp,
-        deserialize_asymmetric_sign_req,
-        serialize_asymmetric_sign_resp,
-        deserialize_asymmetric_verify_req,
-        deserialize_asymmetric_decrypt_req,
-        serialize_asymmetric_decrypt_resp,
-        deserialize_asymmetric_encrypt_req,
-        serialize_asymmetric_encrypt_resp,
-        deserialize_generate_random_req,
-        serialize_generate_random_resp
-    };
+	static const struct crypto_provider_serializer instance = {
+		max_deserialised_parameter_size,    deserialize_generate_key_req,
+		serialize_generate_key_resp,	    deserialize_destroy_key_req,
+		deserialize_export_key_req,	    serialize_export_key_resp,
+		deserialize_export_public_key_req,  serialize_export_public_key_resp,
+		deserialize_import_key_req,	    serialize_import_key_resp,
+		deserialize_copy_key_req,	    serialize_copy_key_resp,
+		deserialize_purge_key_req,	    deserialize_get_key_attributes_req,
+		serialize_get_key_attributes_resp,  deserialize_asymmetric_sign_req,
+		serialize_asymmetric_sign_resp,	    deserialize_asymmetric_verify_req,
+		deserialize_asymmetric_decrypt_req, serialize_asymmetric_decrypt_resp,
+		deserialize_asymmetric_encrypt_req, serialize_asymmetric_encrypt_resp,
+		deserialize_generate_random_req,    serialize_generate_random_resp
+	};
 
-    return &instance;
+	return &instance;
 }
diff --git a/components/service/crypto/provider/serializer/protobuf/pb_crypto_provider_serializer.c b/components/service/crypto/provider/serializer/protobuf/pb_crypto_provider_serializer.c
index 6df375d..34cc326 100644
--- a/components/service/crypto/provider/serializer/protobuf/pb_crypto_provider_serializer.c
+++ b/components/service/crypto/provider/serializer/protobuf/pb_crypto_provider_serializer.c
@@ -3,71 +3,71 @@
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
-#include <string.h>
-#include <stdlib.h>
+#include "pb_crypto_provider_serializer.h"
+
+#include <pb_decode.h>
+#include <pb_encode.h>
 #include <protocols/rpc/common/packed-c/status.h>
+#include <psa/crypto.h>
 #include <service/common/serializer/protobuf/pb_helper.h>
-#include <service/crypto/protobuf/generate_key.pb.h>
+#include <service/crypto/protobuf/asymmetric_decrypt.pb.h>
+#include <service/crypto/protobuf/asymmetric_encrypt.pb.h>
 #include <service/crypto/protobuf/destroy_key.pb.h>
 #include <service/crypto/protobuf/export_key.pb.h>
 #include <service/crypto/protobuf/export_public_key.pb.h>
+#include <service/crypto/protobuf/generate_key.pb.h>
+#include <service/crypto/protobuf/generate_random.pb.h>
 #include <service/crypto/protobuf/import_key.pb.h>
 #include <service/crypto/protobuf/sign_hash.pb.h>
 #include <service/crypto/protobuf/verify_hash.pb.h>
-#include <service/crypto/protobuf/asymmetric_decrypt.pb.h>
-#include <service/crypto/protobuf/asymmetric_encrypt.pb.h>
-#include <service/crypto/protobuf/generate_random.pb.h>
-#include <pb_decode.h>
-#include <pb_encode.h>
-#include <psa/crypto.h>
-#include "pb_key_attributes_translator.h"
-#include "pb_crypto_provider_serializer.h"
+#include <stdlib.h>
+#include <string.h>
 
+#include "pb_key_attributes_translator.h"
 
 /* Returns the maximum possible deserialized parameter size for a protobuf encoded message. */
-static size_t max_deserialised_parameter_size(const struct call_param_buf *req_buf)
+static size_t max_deserialised_parameter_size(const struct rpc_buffer *req_buf)
 {
 	/*
 	 * Assume that a deserialized parameter must be the same size or smaller than the
 	 * entire serialized message.
 	 */
-	return req_buf->data_len;
+	return req_buf->data_length;
 }
 
 /* Operation: generate_key */
-static rpc_status_t deserialize_generate_key_req(const struct call_param_buf *req_buf,
-											psa_key_attributes_t *attributes)
+static rpc_status_t deserialize_generate_key_req(const struct rpc_buffer *req_buf,
+						 psa_key_attributes_t *attributes)
 {
-	rpc_status_t rpc_status = TS_RPC_ERROR_INVALID_REQ_BODY;
+	rpc_status_t rpc_status = RPC_ERROR_INVALID_REQUEST_BODY;
 	ts_crypto_GenerateKeyIn recv_msg = ts_crypto_GenerateKeyIn_init_default;
 
-	pb_istream_t istream = pb_istream_from_buffer((const uint8_t*)req_buf->data, req_buf->data_len);
+	pb_istream_t istream =
+		pb_istream_from_buffer((const uint8_t *)req_buf->data, req_buf->data_length);
 
-	if (pb_decode(&istream, ts_crypto_GenerateKeyIn_fields, &recv_msg) && recv_msg.has_attributes) {
-
+	if (pb_decode(&istream, ts_crypto_GenerateKeyIn_fields, &recv_msg) &&
+	    recv_msg.has_attributes) {
 		pb_crypto_provider_translate_key_attributes(attributes, &recv_msg.attributes);
-		rpc_status = TS_RPC_CALL_ACCEPTED;
+		rpc_status = RPC_SUCCESS;
 	}
 
 	return rpc_status;
 }
 
-static rpc_status_t serialize_generate_key_resp(struct call_param_buf *resp_buf,
-											psa_key_id_t id)
+static rpc_status_t serialize_generate_key_resp(struct rpc_buffer *resp_buf, psa_key_id_t id)
 {
 	size_t packed_resp_size;
-	rpc_status_t rpc_status = TS_RPC_ERROR_INTERNAL;
+	rpc_status_t rpc_status = RPC_ERROR_INTERNAL;
 	ts_crypto_GenerateKeyOut resp_msg = ts_crypto_GenerateKeyOut_init_default;
 	resp_msg.id = id;
 
 	if (pb_get_encoded_size(&packed_resp_size, ts_crypto_GenerateKeyOut_fields, &resp_msg) &&
-		(packed_resp_size <= resp_buf->size)) {
-
-		pb_ostream_t ostream = pb_ostream_from_buffer((uint8_t*)resp_buf->data, packed_resp_size);
+	    (packed_resp_size <= resp_buf->size)) {
+		pb_ostream_t ostream =
+			pb_ostream_from_buffer((uint8_t *)resp_buf->data, packed_resp_size);
 		if (pb_encode(&ostream, ts_crypto_GenerateKeyOut_fields, &resp_msg)) {
-
-			resp_buf->data_len = packed_resp_size;
-			rpc_status = TS_RPC_CALL_ACCEPTED;
+			resp_buf->data_length = packed_resp_size;
+			rpc_status = RPC_SUCCESS;
 		}
 	}
 
@@ -75,60 +75,57 @@
 }
 
 /* Operation: destroy_key */
-static rpc_status_t deserialize_destroy_key_req(const struct call_param_buf *req_buf,
-											psa_key_id_t *id)
+static rpc_status_t deserialize_destroy_key_req(const struct rpc_buffer *req_buf, psa_key_id_t *id)
 {
-	rpc_status_t rpc_status = TS_RPC_ERROR_INVALID_REQ_BODY;
+	rpc_status_t rpc_status = RPC_ERROR_INVALID_REQUEST_BODY;
 	ts_crypto_DestroyKeyIn recv_msg = ts_crypto_DestroyKeyIn_init_default;
 
-	pb_istream_t istream = pb_istream_from_buffer((const uint8_t*)req_buf->data, req_buf->data_len);
+	pb_istream_t istream =
+		pb_istream_from_buffer((const uint8_t *)req_buf->data, req_buf->data_length);
 
 	if (pb_decode(&istream, ts_crypto_DestroyKeyIn_fields, &recv_msg)) {
-
 		*id = recv_msg.id;
-		rpc_status = TS_RPC_CALL_ACCEPTED;
+		rpc_status = RPC_SUCCESS;
 	}
 
 	return rpc_status;
 }
 
 /* Operation: export_key */
-static rpc_status_t deserialize_export_key_req(const struct call_param_buf *req_buf,
-											psa_key_id_t *id)
+static rpc_status_t deserialize_export_key_req(const struct rpc_buffer *req_buf, psa_key_id_t *id)
 {
-	rpc_status_t rpc_status = TS_RPC_ERROR_INVALID_REQ_BODY;
+	rpc_status_t rpc_status = RPC_ERROR_INVALID_REQUEST_BODY;
 	ts_crypto_ExportKeyIn recv_msg = ts_crypto_ExportKeyIn_init_default;
 
-	pb_istream_t istream = pb_istream_from_buffer((const uint8_t*)req_buf->data, req_buf->data_len);
+	pb_istream_t istream =
+		pb_istream_from_buffer((const uint8_t *)req_buf->data, req_buf->data_length);
 
 	if (pb_decode(&istream, ts_crypto_ExportKeyIn_fields, &recv_msg)) {
-
 		*id = recv_msg.id;
-		rpc_status = TS_RPC_CALL_ACCEPTED;
+		rpc_status = RPC_SUCCESS;
 	}
 
 	return rpc_status;
 }
 
-static rpc_status_t serialize_export_key_resp(struct call_param_buf *resp_buf,
-									const uint8_t *data, size_t data_len)
+static rpc_status_t serialize_export_key_resp(struct rpc_buffer *resp_buf, const uint8_t *data,
+					      size_t data_length)
 {
 	size_t packed_resp_size;
-	rpc_status_t rpc_status = TS_RPC_ERROR_INTERNAL;
+	rpc_status_t rpc_status = RPC_ERROR_INTERNAL;
 	ts_crypto_ExportKeyOut resp_msg = ts_crypto_ExportKeyOut_init_default;
-	pb_bytes_array_t *key_buffer = pb_malloc_byte_array(data_len);
+	pb_bytes_array_t *key_buffer = pb_malloc_byte_array(data_length);
 
-	memcpy(&key_buffer->bytes, data, data_len);
+	memcpy(&key_buffer->bytes, data, data_length);
 	resp_msg.data = pb_out_byte_array(key_buffer);
 
 	if (pb_get_encoded_size(&packed_resp_size, ts_crypto_ExportKeyOut_fields, &resp_msg) &&
-		(packed_resp_size <= resp_buf->size)) {
-
-		pb_ostream_t ostream = pb_ostream_from_buffer((uint8_t*)resp_buf->data, packed_resp_size);
+	    (packed_resp_size <= resp_buf->size)) {
+		pb_ostream_t ostream =
+			pb_ostream_from_buffer((uint8_t *)resp_buf->data, packed_resp_size);
 		if (pb_encode(&ostream, ts_crypto_ExportKeyOut_fields, &resp_msg)) {
-
-			resp_buf->data_len = packed_resp_size;
-			rpc_status = TS_RPC_CALL_ACCEPTED;
+			resp_buf->data_length = packed_resp_size;
+			rpc_status = RPC_SUCCESS;
 		}
 	}
 
@@ -138,42 +135,42 @@
 }
 
 /* Operation: export_public_key */
-static rpc_status_t deserialize_export_public_key_req(const struct call_param_buf *req_buf,
-												psa_key_id_t *id)
+static rpc_status_t deserialize_export_public_key_req(const struct rpc_buffer *req_buf,
+						      psa_key_id_t *id)
 {
-	rpc_status_t rpc_status = TS_RPC_ERROR_INVALID_REQ_BODY;
+	rpc_status_t rpc_status = RPC_ERROR_INVALID_REQUEST_BODY;
 	ts_crypto_ExportPublicKeyIn recv_msg = ts_crypto_ExportPublicKeyIn_init_default;
 
-	pb_istream_t istream = pb_istream_from_buffer((const uint8_t*)req_buf->data, req_buf->data_len);
+	pb_istream_t istream =
+		pb_istream_from_buffer((const uint8_t *)req_buf->data, req_buf->data_length);
 
 	if (pb_decode(&istream, ts_crypto_ExportPublicKeyIn_fields, &recv_msg)) {
-
 		*id = recv_msg.id;
-		rpc_status = TS_RPC_CALL_ACCEPTED;
+		rpc_status = RPC_SUCCESS;
 	}
 
 	return rpc_status;
 }
 
-static rpc_status_t serialize_export_public_key_resp(struct call_param_buf *resp_buf,
-											const uint8_t *data, size_t data_len)
+static rpc_status_t serialize_export_public_key_resp(struct rpc_buffer *resp_buf,
+						     const uint8_t *data, size_t data_length)
 {
 	size_t packed_resp_size;
-	rpc_status_t rpc_status = TS_RPC_ERROR_INTERNAL;
+	rpc_status_t rpc_status = RPC_ERROR_INTERNAL;
 	ts_crypto_ExportPublicKeyOut resp_msg = ts_crypto_ExportPublicKeyOut_init_default;
 
-	pb_bytes_array_t *key_buffer = pb_malloc_byte_array(data_len);
+	pb_bytes_array_t *key_buffer = pb_malloc_byte_array(data_length);
 	resp_msg.data = pb_out_byte_array(key_buffer);
-	memcpy(&key_buffer->bytes, data, data_len);
+	memcpy(&key_buffer->bytes, data, data_length);
 
-	if (pb_get_encoded_size(&packed_resp_size, ts_crypto_ExportPublicKeyOut_fields, &resp_msg) &&
-		(packed_resp_size <= resp_buf->size)) {
-
-		pb_ostream_t ostream = pb_ostream_from_buffer((uint8_t*)resp_buf->data, packed_resp_size);
+	if (pb_get_encoded_size(&packed_resp_size, ts_crypto_ExportPublicKeyOut_fields,
+				&resp_msg) &&
+	    (packed_resp_size <= resp_buf->size)) {
+		pb_ostream_t ostream =
+			pb_ostream_from_buffer((uint8_t *)resp_buf->data, packed_resp_size);
 		if (pb_encode(&ostream, ts_crypto_ExportPublicKeyOut_fields, &resp_msg)) {
-
-			resp_buf->data_len = packed_resp_size;
-			rpc_status = TS_RPC_CALL_ACCEPTED;
+			resp_buf->data_length = packed_resp_size;
+			rpc_status = RPC_SUCCESS;
 		}
 	}
 
@@ -183,27 +180,27 @@
 }
 
 /* Operation: import_key */
-static rpc_status_t deserialize_import_key_req(const struct call_param_buf *req_buf,
-					psa_key_attributes_t *attributes, uint8_t *data, size_t *data_len)
+static rpc_status_t deserialize_import_key_req(const struct rpc_buffer *req_buf,
+					       psa_key_attributes_t *attributes, uint8_t *data,
+					       size_t *data_length)
 {
-	rpc_status_t rpc_status = TS_RPC_ERROR_INVALID_REQ_BODY;
+	rpc_status_t rpc_status = RPC_ERROR_INVALID_REQUEST_BODY;
 	ts_crypto_ImportKeyIn recv_msg = ts_crypto_ImportKeyIn_init_default;
 
-	pb_bytes_array_t *key_buffer = pb_malloc_byte_array(*data_len);
+	pb_bytes_array_t *key_buffer = pb_malloc_byte_array(*data_length);
 	recv_msg.data = pb_in_byte_array(key_buffer);
 
-	pb_istream_t istream = pb_istream_from_buffer((const uint8_t*)req_buf->data, req_buf->data_len);
+	pb_istream_t istream =
+		pb_istream_from_buffer((const uint8_t *)req_buf->data, req_buf->data_length);
 
 	if (pb_decode(&istream, ts_crypto_ImportKeyIn_fields, &recv_msg) &&
-		recv_msg.has_attributes &&
-		(key_buffer->size <= *data_len)) {
-
+	    recv_msg.has_attributes && (key_buffer->size <= *data_length)) {
 		pb_crypto_provider_translate_key_attributes(attributes, &recv_msg.attributes);
 
 		memcpy(data, &key_buffer->bytes, key_buffer->size);
-		*data_len = key_buffer->size;
+		*data_length = key_buffer->size;
 
-		rpc_status = TS_RPC_CALL_ACCEPTED;
+		rpc_status = RPC_SUCCESS;
 	}
 
 	free(key_buffer);
@@ -211,22 +208,20 @@
 	return rpc_status;
 }
 
-static rpc_status_t serialize_import_key_resp(struct call_param_buf *resp_buf,
-										psa_key_id_t id)
+static rpc_status_t serialize_import_key_resp(struct rpc_buffer *resp_buf, psa_key_id_t id)
 {
 	size_t packed_resp_size;
-	rpc_status_t rpc_status = TS_RPC_ERROR_INTERNAL;
+	rpc_status_t rpc_status = RPC_ERROR_INTERNAL;
 	ts_crypto_ImportKeyOut resp_msg = ts_crypto_ImportKeyOut_init_default;
 	resp_msg.id = id;
 
 	if (pb_get_encoded_size(&packed_resp_size, ts_crypto_ImportKeyOut_fields, &resp_msg) &&
-		(packed_resp_size <= resp_buf->size)) {
-
-		pb_ostream_t ostream = pb_ostream_from_buffer((uint8_t*)resp_buf->data, packed_resp_size);
+	    (packed_resp_size <= resp_buf->size)) {
+		pb_ostream_t ostream =
+			pb_ostream_from_buffer((uint8_t *)resp_buf->data, packed_resp_size);
 		if (pb_encode(&ostream, ts_crypto_ImportKeyOut_fields, &resp_msg)) {
-
-			resp_buf->data_len = packed_resp_size;
-			rpc_status = TS_RPC_CALL_ACCEPTED;
+			resp_buf->data_length = packed_resp_size;
+			rpc_status = RPC_SUCCESS;
 		}
 	}
 
@@ -234,77 +229,75 @@
 }
 
 /* Operation: copy_key */
-static rpc_status_t deserialize_copy_key_req(const struct call_param_buf *req_buf,
-									psa_key_attributes_t *attributes,
-									psa_key_id_t *source_id)
+static rpc_status_t deserialize_copy_key_req(const struct rpc_buffer *req_buf,
+					     psa_key_attributes_t *attributes,
+					     psa_key_id_t *source_id)
 {
 	(void)req_buf;
 	(void)attributes;
 	(void)source_id;
 
-	return TS_RPC_ERROR_INVALID_REQ_BODY;
+	return RPC_ERROR_INVALID_REQUEST_BODY;
 }
 
-static rpc_status_t serialize_copy_key_resp(struct call_param_buf *resp_buf,
-									psa_key_id_t target_id)
+static rpc_status_t serialize_copy_key_resp(struct rpc_buffer *resp_buf, psa_key_id_t target_id)
 {
 	(void)resp_buf;
 	(void)target_id;
 
-	return TS_RPC_ERROR_INTERNAL;
+	return RPC_ERROR_INTERNAL;
 }
 
 /* Operation: purge_key */
-static rpc_status_t deserialize_purge_key_req(const struct call_param_buf *req_buf,
-									psa_key_id_t *id)
+static rpc_status_t deserialize_purge_key_req(const struct rpc_buffer *req_buf, psa_key_id_t *id)
 {
 	(void)req_buf;
 	(void)id;
 
-	return TS_RPC_ERROR_INVALID_REQ_BODY;
+	return RPC_ERROR_INVALID_REQUEST_BODY;
 }
 
 /* Operation: get_key_attributes */
-static rpc_status_t deserialize_get_key_attributes_req(const struct call_param_buf *req_buf,
-									psa_key_id_t *id)
+static rpc_status_t deserialize_get_key_attributes_req(const struct rpc_buffer *req_buf,
+						       psa_key_id_t *id)
 {
 	(void)req_buf;
 	(void)id;
 
-	return TS_RPC_ERROR_INVALID_REQ_BODY;
+	return RPC_ERROR_INVALID_REQUEST_BODY;
 }
 
-static rpc_status_t serialize_get_key_attributes_resp(struct call_param_buf *resp_buf,
-									const psa_key_attributes_t *attributes)
+static rpc_status_t serialize_get_key_attributes_resp(struct rpc_buffer *resp_buf,
+						      const psa_key_attributes_t *attributes)
 {
 	(void)resp_buf;
 	(void)attributes;
 
-	return TS_RPC_ERROR_INTERNAL;
+	return RPC_ERROR_INTERNAL;
 }
 
 /* Operation: sign_hash */
-static rpc_status_t deserialize_asymmetric_sign_req(const struct call_param_buf *req_buf,
-							psa_key_id_t *id, psa_algorithm_t *alg,
-							uint8_t *hash, size_t *hash_len)
+static rpc_status_t deserialize_asymmetric_sign_req(const struct rpc_buffer *req_buf,
+						    psa_key_id_t *id, psa_algorithm_t *alg,
+						    uint8_t *hash, size_t *hash_len)
 {
-	rpc_status_t rpc_status = TS_RPC_ERROR_INVALID_REQ_BODY;
+	rpc_status_t rpc_status = RPC_ERROR_INVALID_REQUEST_BODY;
 	ts_crypto_SignHashIn recv_msg = ts_crypto_SignHashIn_init_default;
 
 	pb_bytes_array_t *hash_buffer = pb_malloc_byte_array(*hash_len);
 	recv_msg.hash = pb_in_byte_array(hash_buffer);
 
-	pb_istream_t istream = pb_istream_from_buffer((const uint8_t*)req_buf->data, req_buf->data_len);
+	pb_istream_t istream =
+		pb_istream_from_buffer((const uint8_t *)req_buf->data, req_buf->data_length);
 
 	if (pb_decode(&istream, ts_crypto_SignHashIn_fields, &recv_msg)) {
-
 		*id = recv_msg.id;
 		*alg = recv_msg.alg;
 
 		memcpy(hash, &hash_buffer->bytes, hash_buffer->size);
 		*hash_len = hash_buffer->size;
 
-		rpc_status = TS_RPC_CALL_ACCEPTED;
+		rpc_status = RPC_SUCCESS;
 	}
 
 	free(hash_buffer);
@@ -312,11 +305,11 @@
 	return rpc_status;
 }
 
-static rpc_status_t serialize_asymmetric_sign_resp(struct call_param_buf *resp_buf,
-							const uint8_t *sig, size_t sig_len)
+static rpc_status_t serialize_asymmetric_sign_resp(struct rpc_buffer *resp_buf, const uint8_t *sig,
+						   size_t sig_len)
 {
 	size_t packed_resp_size;
-	rpc_status_t rpc_status = TS_RPC_ERROR_INTERNAL;
+	rpc_status_t rpc_status = RPC_ERROR_INTERNAL;
 	ts_crypto_SignHashOut resp_msg = ts_crypto_SignHashOut_init_default;
 
 	pb_bytes_array_t *sig_buffer = pb_malloc_byte_array(sig_len);
@@ -324,13 +317,12 @@
 	memcpy(&sig_buffer->bytes, sig, sig_len);
 
 	if (pb_get_encoded_size(&packed_resp_size, ts_crypto_SignHashOut_fields, &resp_msg) &&
-		(packed_resp_size <= resp_buf->size)) {
-
-		pb_ostream_t ostream = pb_ostream_from_buffer((uint8_t*)resp_buf->data, packed_resp_size);
+	    (packed_resp_size <= resp_buf->size)) {
+		pb_ostream_t ostream =
+			pb_ostream_from_buffer((uint8_t *)resp_buf->data, packed_resp_size);
 		if (pb_encode(&ostream, ts_crypto_SignHashOut_fields, &resp_msg)) {
-
-			resp_buf->data_len = packed_resp_size;
-			rpc_status = TS_RPC_CALL_ACCEPTED;
+			resp_buf->data_length = packed_resp_size;
+			rpc_status = RPC_SUCCESS;
 		}
 	}
 
@@ -340,12 +332,12 @@
 }
 
 /* Operation: verify_hash */
-static rpc_status_t deserialize_asymmetric_verify_req(const struct call_param_buf *req_buf,
-								psa_key_id_t *id, psa_algorithm_t *alg,
-								uint8_t *hash, size_t *hash_len,
-								uint8_t *sig, size_t *sig_len)
+static rpc_status_t deserialize_asymmetric_verify_req(const struct rpc_buffer *req_buf,
+						      psa_key_id_t *id, psa_algorithm_t *alg,
+						      uint8_t *hash, size_t *hash_len, uint8_t *sig,
+						      size_t *sig_len)
 {
-	rpc_status_t rpc_status = TS_RPC_ERROR_INVALID_REQ_BODY;
+	rpc_status_t rpc_status = RPC_ERROR_INVALID_REQUEST_BODY;
 	ts_crypto_VerifyHashIn recv_msg = ts_crypto_VerifyHashIn_init_default;
 
 	pb_bytes_array_t *hash_buffer = pb_malloc_byte_array(*hash_len);
@@ -354,10 +346,10 @@
 	pb_bytes_array_t *sig_buffer = pb_malloc_byte_array(*sig_len);
 	recv_msg.signature = pb_in_byte_array(sig_buffer);
 
-	pb_istream_t istream = pb_istream_from_buffer((const uint8_t*)req_buf->data, req_buf->data_len);
+	pb_istream_t istream =
+		pb_istream_from_buffer((const uint8_t *)req_buf->data, req_buf->data_length);
 
 	if (pb_decode(&istream, ts_crypto_VerifyHashIn_fields, &recv_msg)) {
-
 		*id = recv_msg.id;
 		*alg = recv_msg.alg;
 
@@ -367,7 +359,7 @@
 		memcpy(sig, &sig_buffer->bytes, sig_buffer->size);
 		*sig_len = sig_buffer->size;
 
-		rpc_status = TS_RPC_CALL_ACCEPTED;
+		rpc_status = RPC_SUCCESS;
 	}
 
 	free(hash_buffer);
@@ -377,12 +369,12 @@
 }
 
 /* Operation: asymmetric_decrypt */
-static rpc_status_t deserialize_asymmetric_decrypt_req(const struct call_param_buf *req_buf,
-								psa_key_id_t *id, psa_algorithm_t *alg,
-								uint8_t *ciphertext, size_t *ciphertext_len,
-								uint8_t *salt, size_t *salt_len)
+static rpc_status_t deserialize_asymmetric_decrypt_req(const struct rpc_buffer *req_buf,
+						       psa_key_id_t *id, psa_algorithm_t *alg,
+						       uint8_t *ciphertext, size_t *ciphertext_len,
+						       uint8_t *salt, size_t *salt_len)
 {
-	rpc_status_t rpc_status = TS_RPC_ERROR_INVALID_REQ_BODY;
+	rpc_status_t rpc_status = RPC_ERROR_INVALID_REQUEST_BODY;
 	ts_crypto_AsymmetricDecryptIn recv_msg = ts_crypto_AsymmetricDecryptIn_init_default;
 
 	pb_bytes_array_t *ciphertext_buffer = pb_malloc_byte_array(*ciphertext_len);
@@ -391,10 +383,10 @@
 	pb_bytes_array_t *salt_buffer = pb_malloc_byte_array(*salt_len);
 	recv_msg.salt = pb_in_byte_array(salt_buffer);
 
-	pb_istream_t istream = pb_istream_from_buffer((const uint8_t*)req_buf->data, req_buf->data_len);
+	pb_istream_t istream =
+		pb_istream_from_buffer((const uint8_t *)req_buf->data, req_buf->data_length);
 
 	if (pb_decode(&istream, ts_crypto_AsymmetricDecryptIn_fields, &recv_msg)) {
-
 		*id = recv_msg.id;
 		*alg = recv_msg.alg;
 
@@ -404,13 +396,12 @@
 		if (salt_buffer->size < *salt_len) {
 			memcpy(salt, &salt_buffer->bytes, salt_buffer->size);
 			*salt_len = salt_buffer->size;
-		}
-		else {
+		} else {
 			/* Set default for missing optional parameter */
 			*salt_len = 0;
 		}
 
-		rpc_status = TS_RPC_CALL_ACCEPTED;
+		rpc_status = RPC_SUCCESS;
 	}
 
 	free(ciphertext_buffer);
@@ -419,25 +410,26 @@
 	return rpc_status;
 }
 
-static rpc_status_t serialize_asymmetric_decrypt_resp(struct call_param_buf *resp_buf,
-								const uint8_t *plaintext, size_t plaintext_len)
+static rpc_status_t serialize_asymmetric_decrypt_resp(struct rpc_buffer *resp_buf,
+						      const uint8_t *plaintext,
+						      size_t plaintext_len)
 {
 	size_t packed_resp_size;
-	rpc_status_t rpc_status = TS_RPC_ERROR_INTERNAL;
+	rpc_status_t rpc_status = RPC_ERROR_INTERNAL;
 	ts_crypto_AsymmetricDecryptOut resp_msg = ts_crypto_AsymmetricDecryptOut_init_default;
 
 	pb_bytes_array_t *plaintext_buffer = pb_malloc_byte_array(plaintext_len);
 	resp_msg.plaintext = pb_out_byte_array(plaintext_buffer);
 	memcpy(&plaintext_buffer->bytes, plaintext, plaintext_len);
 
-	if (pb_get_encoded_size(&packed_resp_size, ts_crypto_AsymmetricDecryptOut_fields, &resp_msg) &&
-		(packed_resp_size <= resp_buf->size)) {
-
-		pb_ostream_t ostream = pb_ostream_from_buffer((uint8_t*)resp_buf->data, packed_resp_size);
+	if (pb_get_encoded_size(&packed_resp_size, ts_crypto_AsymmetricDecryptOut_fields,
+				&resp_msg) &&
+	    (packed_resp_size <= resp_buf->size)) {
+		pb_ostream_t ostream =
+			pb_ostream_from_buffer((uint8_t *)resp_buf->data, packed_resp_size);
 		if (pb_encode(&ostream, ts_crypto_AsymmetricDecryptOut_fields, &resp_msg)) {
-
-			resp_buf->data_len = packed_resp_size;
-			rpc_status = TS_RPC_CALL_ACCEPTED;
+			resp_buf->data_length = packed_resp_size;
+			rpc_status = RPC_SUCCESS;
 		}
 	}
 
@@ -447,12 +439,12 @@
 }
 
 /* Operation: asymmetric_encrypt */
-static rpc_status_t deserialize_asymmetric_encrypt_req(const struct call_param_buf *req_buf,
-									psa_key_id_t *id, psa_algorithm_t *alg,
-									uint8_t *plaintext, size_t *plaintext_len,
-									uint8_t *salt, size_t *salt_len)
+static rpc_status_t deserialize_asymmetric_encrypt_req(const struct rpc_buffer *req_buf,
+						       psa_key_id_t *id, psa_algorithm_t *alg,
+						       uint8_t *plaintext, size_t *plaintext_len,
+						       uint8_t *salt, size_t *salt_len)
 {
-	rpc_status_t rpc_status = TS_RPC_ERROR_INVALID_REQ_BODY;
+	rpc_status_t rpc_status = RPC_ERROR_INVALID_REQUEST_BODY;
 	ts_crypto_AsymmetricEncryptIn recv_msg = ts_crypto_AsymmetricEncryptIn_init_default;
 
 	pb_bytes_array_t *plaintext_buffer = pb_malloc_byte_array(*plaintext_len);
@@ -461,10 +453,10 @@
 	pb_bytes_array_t *salt_buffer = pb_malloc_byte_array(*salt_len);
 	recv_msg.salt = pb_in_byte_array(salt_buffer);
 
-	pb_istream_t istream = pb_istream_from_buffer((const uint8_t*)req_buf->data, req_buf->data_len);
+	pb_istream_t istream =
+		pb_istream_from_buffer((const uint8_t *)req_buf->data, req_buf->data_length);
 
 	if (pb_decode(&istream, ts_crypto_AsymmetricEncryptIn_fields, &recv_msg)) {
-
 		*id = recv_msg.id;
 		*alg = recv_msg.alg;
 
@@ -474,13 +466,12 @@
 		if (salt_buffer->size < *salt_len) {
 			memcpy(salt, &salt_buffer->bytes, salt_buffer->size);
 			*salt_len = salt_buffer->size;
-		}
-		else {
+		} else {
 			/* Set default for missing optional parameter */
 			*salt_len = 0;
 		}
 
-		rpc_status = TS_RPC_CALL_ACCEPTED;
+		rpc_status = RPC_SUCCESS;
 	}
 
 	free(plaintext_buffer);
@@ -489,25 +480,26 @@
 	return rpc_status;
 }
 
-static rpc_status_t serialize_asymmetric_encrypt_resp(struct call_param_buf *resp_buf,
-									const uint8_t *ciphertext, size_t ciphertext_len)
+static rpc_status_t serialize_asymmetric_encrypt_resp(struct rpc_buffer *resp_buf,
+						      const uint8_t *ciphertext,
+						      size_t ciphertext_len)
 {
 	size_t packed_resp_size;
-	rpc_status_t rpc_status = TS_RPC_ERROR_INTERNAL;
+	rpc_status_t rpc_status = RPC_ERROR_INTERNAL;
 	ts_crypto_AsymmetricEncryptOut resp_msg = ts_crypto_AsymmetricEncryptOut_init_default;
 
 	pb_bytes_array_t *ciphertext_buffer = pb_malloc_byte_array(ciphertext_len);
 	resp_msg.ciphertext = pb_out_byte_array(ciphertext_buffer);
 	memcpy(&ciphertext_buffer->bytes, ciphertext, ciphertext_len);
 
-	if (pb_get_encoded_size(&packed_resp_size, ts_crypto_AsymmetricEncryptOut_fields, &resp_msg) &&
-		(packed_resp_size <= resp_buf->size)) {
-
-		pb_ostream_t ostream = pb_ostream_from_buffer((uint8_t*)resp_buf->data, packed_resp_size);
+	if (pb_get_encoded_size(&packed_resp_size, ts_crypto_AsymmetricEncryptOut_fields,
+				&resp_msg) &&
+	    (packed_resp_size <= resp_buf->size)) {
+		pb_ostream_t ostream =
+			pb_ostream_from_buffer((uint8_t *)resp_buf->data, packed_resp_size);
 		if (pb_encode(&ostream, ts_crypto_AsymmetricEncryptOut_fields, &resp_msg)) {
-
-			resp_buf->data_len = packed_resp_size;
-			rpc_status = TS_RPC_CALL_ACCEPTED;
+			resp_buf->data_length = packed_resp_size;
+			rpc_status = RPC_SUCCESS;
 		}
 	}
 
@@ -517,29 +509,28 @@
 }
 
 /* Operation: generate_random */
-static rpc_status_t deserialize_generate_random_req(const struct call_param_buf *req_buf,
-										size_t *size)
+static rpc_status_t deserialize_generate_random_req(const struct rpc_buffer *req_buf, size_t *size)
 {
-	rpc_status_t rpc_status = TS_RPC_ERROR_INVALID_REQ_BODY;
+	rpc_status_t rpc_status = RPC_ERROR_INVALID_REQUEST_BODY;
 	ts_crypto_GenerateRandomIn recv_msg = ts_crypto_GenerateRandomIn_init_default;
 
-	pb_istream_t istream = pb_istream_from_buffer((const uint8_t*)req_buf->data, req_buf->data_len);
+	pb_istream_t istream =
+		pb_istream_from_buffer((const uint8_t *)req_buf->data, req_buf->data_length);
 
 	if (pb_decode(&istream, ts_crypto_GenerateRandomIn_fields, &recv_msg)) {
-
 		*size = recv_msg.size;
 
-		rpc_status = TS_RPC_CALL_ACCEPTED;
+		rpc_status = RPC_SUCCESS;
 	}
 
 	return rpc_status;
 }
 
-static rpc_status_t serialize_generate_random_resp(struct call_param_buf *resp_buf,
-										const uint8_t *output, size_t output_len)
+static rpc_status_t serialize_generate_random_resp(struct rpc_buffer *resp_buf,
+						   const uint8_t *output, size_t output_len)
 {
 	size_t packed_resp_size;
-	rpc_status_t rpc_status = TS_RPC_ERROR_INTERNAL;
+	rpc_status_t rpc_status = RPC_ERROR_INTERNAL;
 	ts_crypto_GenerateRandomOut resp_msg = ts_crypto_GenerateRandomOut_init_default;
 
 	pb_bytes_array_t *output_buffer = pb_malloc_byte_array(output_len);
@@ -547,13 +538,12 @@
 	memcpy(&output_buffer->bytes, output, output_len);
 
 	if (pb_get_encoded_size(&packed_resp_size, ts_crypto_GenerateRandomOut_fields, &resp_msg) &&
-		(packed_resp_size <= resp_buf->size)) {
-
-		pb_ostream_t ostream = pb_ostream_from_buffer((uint8_t*)resp_buf->data, packed_resp_size);
+	    (packed_resp_size <= resp_buf->size)) {
+		pb_ostream_t ostream =
+			pb_ostream_from_buffer((uint8_t *)resp_buf->data, packed_resp_size);
 		if (pb_encode(&ostream, ts_crypto_GenerateRandomOut_fields, &resp_msg)) {
-
-			resp_buf->data_len = packed_resp_size;
-			rpc_status = TS_RPC_CALL_ACCEPTED;
+			resp_buf->data_length = packed_resp_size;
+			rpc_status = RPC_SUCCESS;
 		}
 	}
 
@@ -566,30 +556,18 @@
 const struct crypto_provider_serializer *pb_crypto_provider_serializer_instance(void)
 {
 	static const struct crypto_provider_serializer instance = {
-		max_deserialised_parameter_size,
-		deserialize_generate_key_req,
-		serialize_generate_key_resp,
-		deserialize_destroy_key_req,
-		deserialize_export_key_req,
-		serialize_export_key_resp,
-		deserialize_export_public_key_req,
-		serialize_export_public_key_resp,
-		deserialize_import_key_req,
-		serialize_import_key_resp,
-		deserialize_copy_key_req,
-		serialize_copy_key_resp,
-		deserialize_purge_key_req,
-		deserialize_get_key_attributes_req,
-		serialize_get_key_attributes_resp,
-		deserialize_asymmetric_sign_req,
-		serialize_asymmetric_sign_resp,
-		deserialize_asymmetric_verify_req,
-		deserialize_asymmetric_decrypt_req,
-		serialize_asymmetric_decrypt_resp,
-		deserialize_asymmetric_encrypt_req,
-		serialize_asymmetric_encrypt_resp,
-		deserialize_generate_random_req,
-		serialize_generate_random_resp
+		max_deserialised_parameter_size,    deserialize_generate_key_req,
+		serialize_generate_key_resp,	    deserialize_destroy_key_req,
+		deserialize_export_key_req,	    serialize_export_key_resp,
+		deserialize_export_public_key_req,  serialize_export_public_key_resp,
+		deserialize_import_key_req,	    serialize_import_key_resp,
+		deserialize_copy_key_req,	    serialize_copy_key_resp,
+		deserialize_purge_key_req,	    deserialize_get_key_attributes_req,
+		serialize_get_key_attributes_resp,  deserialize_asymmetric_sign_req,
+		serialize_asymmetric_sign_resp,	    deserialize_asymmetric_verify_req,
+		deserialize_asymmetric_decrypt_req, serialize_asymmetric_decrypt_resp,
+		deserialize_asymmetric_encrypt_req, serialize_asymmetric_encrypt_resp,
+		deserialize_generate_random_req,    serialize_generate_random_resp
 	};
 
 	return &instance;
diff --git a/components/service/crypto/test/service/crypto_service_limit_tests.cpp b/components/service/crypto/test/service/crypto_service_limit_tests.cpp
index 913fe77..eaa907a 100644
--- a/components/service/crypto/test/service/crypto_service_limit_tests.cpp
+++ b/components/service/crypto/test/service/crypto_service_limit_tests.cpp
@@ -8,9 +8,8 @@
 #include <vector>
 #include <cstring>
 #include <cstdint>
-#include <service/crypto/client/cpp/protocol/protobuf/protobuf_crypto_client.h>
-#include <protocols/rpc/common/packed-c/encoding.h>
-#include <service_locator.h>
+#include <service/crypto/client/cpp/protocol/packed-c/packedc_crypto_client.h>
+#include <service/locator/interface/service_locator.h>
 #include <CppUTest/TestHarness.h>
 
 /*
@@ -21,22 +20,16 @@
 {
     void setup()
     {
-        struct rpc_caller *caller;
-        int status;
-
-        m_rpc_session_handle = NULL;
-        m_crypto_service_context = NULL;
-        m_crypto_client = NULL;
-
         service_locator_init();
 
-        m_crypto_service_context = service_locator_query("sn:trustedfirmware.org:crypto:0", &status);
-        CHECK(m_crypto_service_context);
+        m_service_context = service_locator_query("sn:trustedfirmware.org:crypto:0");
+        CHECK_TRUE(m_service_context != NULL);
 
-        m_rpc_session_handle = service_context_open(m_crypto_service_context, TS_RPC_ENCODING_PROTOBUF, &caller);
-        CHECK(m_rpc_session_handle);
+        m_session = service_context_open(m_service_context);
+        CHECK_TRUE(m_session != NULL);
 
-        m_crypto_client = new protobuf_crypto_client(caller);
+        m_crypto_client = new packedc_crypto_client(m_session);
+        CHECK(m_crypto_client != NULL);
     }
 
     void teardown()
@@ -44,15 +37,15 @@
         delete m_crypto_client;
         m_crypto_client = NULL;
 
-	if (m_crypto_service_context) {
-	        if (m_rpc_session_handle) {
-                        service_context_close(m_crypto_service_context, m_rpc_session_handle);
-                        m_rpc_session_handle = NULL;
-	        }
+        if (m_session) {
+            service_context_close(m_service_context, m_session);
+            m_session = NULL;
+        }
 
-                service_context_relinquish(m_crypto_service_context);
-                m_crypto_service_context = NULL;
-	}
+        if (m_service_context) {
+            service_context_relinquish(m_service_context);
+            m_service_context = NULL;
+        }
     }
 
     psa_status_t generateVolatileEccKeyPair(std::vector<psa_key_id_t> &key_ids)
@@ -118,8 +111,8 @@
      */
     const size_t MAX_KEY_SLOTS = 30;
 
-    rpc_session_handle m_rpc_session_handle;
-    struct service_context *m_crypto_service_context;
+    struct service_context *m_service_context;
+    struct rpc_caller_session *m_session;
     crypto_client *m_crypto_client;
 };
 
diff --git a/components/service/crypto/test/service/extension/cipher/packed-c/cipher_service_packedc_tests.cpp b/components/service/crypto/test/service/extension/cipher/packed-c/cipher_service_packedc_tests.cpp
index f9da7d8..4cac762 100644
--- a/components/service/crypto/test/service/extension/cipher/packed-c/cipher_service_packedc_tests.cpp
+++ b/components/service/crypto/test/service/extension/cipher/packed-c/cipher_service_packedc_tests.cpp
@@ -17,22 +17,19 @@
 {
 	void setup()
 	{
-		struct rpc_caller *caller;
-		int status;
-
-		m_rpc_session_handle = NULL;
+		m_rpc_session = NULL;
 		m_crypto_service_context = NULL;
 		m_scenarios = NULL;
 
 		service_locator_init();
 
-		m_crypto_service_context = service_locator_query("sn:trustedfirmware.org:crypto:0", &status);
+		m_crypto_service_context = service_locator_query("sn:trustedfirmware.org:crypto:0");
 		CHECK_TRUE(m_crypto_service_context);
 
-		m_rpc_session_handle = service_context_open(m_crypto_service_context, TS_RPC_ENCODING_PACKED_C, &caller);
-		CHECK_TRUE(m_rpc_session_handle);
+		m_rpc_session = service_context_open(m_crypto_service_context);
+		CHECK_TRUE(m_rpc_session);
 
-		m_scenarios = new cipher_service_scenarios(new packedc_crypto_client(caller));
+		m_scenarios = new cipher_service_scenarios(new packedc_crypto_client(m_rpc_session));
 	}
 
 	void teardown()
@@ -41,9 +38,9 @@
 		m_scenarios = NULL;
 
 		if (m_crypto_service_context) {
-			if (m_rpc_session_handle) {
-				service_context_close(m_crypto_service_context, m_rpc_session_handle);
-				m_rpc_session_handle = NULL;
+			if (m_rpc_session) {
+				service_context_close(m_crypto_service_context, m_rpc_session);
+				m_rpc_session = NULL;
 			}
 
 			service_context_relinquish(m_crypto_service_context);
@@ -51,7 +48,7 @@
 		}
 	}
 
-	rpc_session_handle m_rpc_session_handle;
+	struct rpc_caller_session *m_rpc_session;
 	struct service_context *m_crypto_service_context;
 	cipher_service_scenarios *m_scenarios;
 };
@@ -64,4 +61,4 @@
 TEST(CryptoCipherServicePackedcTests, cipherAbort)
 {
 	m_scenarios->cipherAbort();
-}
+}
\ No newline at end of file
diff --git a/components/service/crypto/test/service/extension/hash/packed-c/hash_service_packedc_tests.cpp b/components/service/crypto/test/service/extension/hash/packed-c/hash_service_packedc_tests.cpp
index 060169a..530c175 100644
--- a/components/service/crypto/test/service/extension/hash/packed-c/hash_service_packedc_tests.cpp
+++ b/components/service/crypto/test/service/extension/hash/packed-c/hash_service_packedc_tests.cpp
@@ -17,22 +17,19 @@
 {
 	void setup()
 	{
-		struct rpc_caller *caller;
-		int status;
-
-		m_rpc_session_handle = NULL;
+		m_rpc_session = NULL;
 		m_crypto_service_context = NULL;
 		m_scenarios = NULL;
 
 		service_locator_init();
 
-		m_crypto_service_context = service_locator_query("sn:trustedfirmware.org:crypto:0", &status);
+		m_crypto_service_context = service_locator_query("sn:trustedfirmware.org:crypto:0");
 		CHECK_TRUE(m_crypto_service_context);
 
-		m_rpc_session_handle = service_context_open(m_crypto_service_context, TS_RPC_ENCODING_PACKED_C, &caller);
-		CHECK_TRUE(m_rpc_session_handle);
+		m_rpc_session = service_context_open(m_crypto_service_context);
+		CHECK_TRUE(m_rpc_session);
 
-		m_scenarios = new hash_service_scenarios(new packedc_crypto_client(caller));
+		m_scenarios = new hash_service_scenarios(new packedc_crypto_client(m_rpc_session));
 	}
 
 	void teardown()
@@ -41,9 +38,9 @@
 		m_scenarios = NULL;
 
 		if (m_crypto_service_context) {
-			if (m_rpc_session_handle) {
-				service_context_close(m_crypto_service_context, m_rpc_session_handle);
-				m_rpc_session_handle = NULL;
+			if (m_rpc_session) {
+				service_context_close(m_crypto_service_context, m_rpc_session);
+				m_rpc_session = NULL;
 			}
 
 			service_context_relinquish(m_crypto_service_context);
@@ -51,7 +48,7 @@
 		}
 	}
 
-	rpc_session_handle m_rpc_session_handle;
+	struct rpc_caller_session *m_rpc_session;
 	struct service_context *m_crypto_service_context;
 	hash_service_scenarios *m_scenarios;
 };
@@ -69,4 +66,4 @@
 TEST(CryptoHashServicePackedcTests, hashAbort)
 {
 	m_scenarios->hashAbort();
-}
+}
\ No newline at end of file
diff --git a/components/service/crypto/test/service/extension/key_derivation/packed-c/key_derivation_service_packedc_tests.cpp b/components/service/crypto/test/service/extension/key_derivation/packed-c/key_derivation_service_packedc_tests.cpp
index c322437..8212bc2 100644
--- a/components/service/crypto/test/service/extension/key_derivation/packed-c/key_derivation_service_packedc_tests.cpp
+++ b/components/service/crypto/test/service/extension/key_derivation/packed-c/key_derivation_service_packedc_tests.cpp
@@ -17,22 +17,19 @@
 {
 	void setup()
 	{
-		struct rpc_caller *caller;
-		int status;
-
-		m_rpc_session_handle = NULL;
+		m_rpc_session = NULL;
 		m_crypto_service_context = NULL;
 		m_scenarios = NULL;
 
 		service_locator_init();
 
-		m_crypto_service_context = service_locator_query("sn:trustedfirmware.org:crypto:0", &status);
+		m_crypto_service_context = service_locator_query("sn:trustedfirmware.org:crypto:0");
 		CHECK_TRUE(m_crypto_service_context);
 
-		m_rpc_session_handle = service_context_open(m_crypto_service_context, TS_RPC_ENCODING_PACKED_C, &caller);
-		CHECK_TRUE(m_rpc_session_handle);
+		m_rpc_session = service_context_open(m_crypto_service_context);
+		CHECK_TRUE(m_rpc_session);
 
-		m_scenarios = new key_derivation_service_scenarios(new packedc_crypto_client(caller));
+		m_scenarios = new key_derivation_service_scenarios(new packedc_crypto_client(m_rpc_session));
 	}
 
 	void teardown()
@@ -41,9 +38,9 @@
 		m_scenarios = NULL;
 
 		if (m_crypto_service_context) {
-			if (m_rpc_session_handle) {
-				service_context_close(m_crypto_service_context, m_rpc_session_handle);
-				m_rpc_session_handle = NULL;
+			if (m_rpc_session) {
+				service_context_close(m_crypto_service_context, m_rpc_session);
+				m_rpc_session = NULL;
 			}
 
 			service_context_relinquish(m_crypto_service_context);
@@ -51,7 +48,7 @@
 		}
 	}
 
-	rpc_session_handle m_rpc_session_handle;
+	struct rpc_caller_session *m_rpc_session;
 	struct service_context *m_crypto_service_context;
 	key_derivation_service_scenarios *m_scenarios;
 };
@@ -69,4 +66,4 @@
 TEST(CryptoKeyDerivationServicePackedcTests, deriveAbort)
 {
 	m_scenarios->deriveAbort();
-}
+}
\ No newline at end of file
diff --git a/components/service/crypto/test/service/extension/mac/packed-c/mac_service_packedc_tests.cpp b/components/service/crypto/test/service/extension/mac/packed-c/mac_service_packedc_tests.cpp
index d6c1c30..b8f4d97 100644
--- a/components/service/crypto/test/service/extension/mac/packed-c/mac_service_packedc_tests.cpp
+++ b/components/service/crypto/test/service/extension/mac/packed-c/mac_service_packedc_tests.cpp
@@ -17,22 +17,19 @@
 {
 	void setup()
 	{
-		struct rpc_caller *caller;
-		int status;
-
-		m_rpc_session_handle = NULL;
+		m_rpc_session = NULL;
 		m_crypto_service_context = NULL;
 		m_scenarios = NULL;
 
 		service_locator_init();
 
-		m_crypto_service_context = service_locator_query("sn:trustedfirmware.org:crypto:0", &status);
+		m_crypto_service_context = service_locator_query("sn:trustedfirmware.org:crypto:0");
 		CHECK_TRUE(m_crypto_service_context);
 
-		m_rpc_session_handle = service_context_open(m_crypto_service_context, TS_RPC_ENCODING_PACKED_C, &caller);
-		CHECK_TRUE(m_rpc_session_handle);
+		m_rpc_session = service_context_open(m_crypto_service_context);
+		CHECK_TRUE(m_rpc_session);
 
-		m_scenarios = new mac_service_scenarios(new packedc_crypto_client(caller));
+		m_scenarios = new mac_service_scenarios(new packedc_crypto_client(m_rpc_session));
 	}
 
 	void teardown()
@@ -41,9 +38,9 @@
 		m_scenarios = NULL;
 
 		if (m_crypto_service_context) {
-			if (m_rpc_session_handle) {
-				service_context_close(m_crypto_service_context, m_rpc_session_handle);
-				m_rpc_session_handle = NULL;
+			if (m_rpc_session) {
+				service_context_close(m_crypto_service_context, m_rpc_session);
+				m_rpc_session = NULL;
 			}
 
 			service_context_relinquish(m_crypto_service_context);
@@ -51,7 +48,7 @@
 		}
 	}
 
-	rpc_session_handle m_rpc_session_handle;
+	struct rpc_caller_session *m_rpc_session;
 	struct service_context *m_crypto_service_context;
 	mac_service_scenarios *m_scenarios;
 };
@@ -64,4 +61,4 @@
 TEST(CryptoMacServicePackedcTests, macAbort)
 {
 	m_scenarios->macAbort();
-}
+}
\ No newline at end of file
diff --git a/components/service/crypto/test/service/packed-c/crypto_service_packedc_tests.cpp b/components/service/crypto/test/service/packed-c/crypto_service_packedc_tests.cpp
index a02d646..de66e58 100644
--- a/components/service/crypto/test/service/packed-c/crypto_service_packedc_tests.cpp
+++ b/components/service/crypto/test/service/packed-c/crypto_service_packedc_tests.cpp
@@ -17,22 +17,19 @@
 {
 	void setup()
 	{
-		struct rpc_caller *caller;
-		int status;
-
-		m_rpc_session_handle = NULL;
+		m_rpc_session = NULL;
 		m_crypto_service_context = NULL;
 		m_scenarios = NULL;
 
 		service_locator_init();
 
-		m_crypto_service_context = service_locator_query("sn:trustedfirmware.org:crypto:0", &status);
+		m_crypto_service_context = service_locator_query("sn:trustedfirmware.org:crypto:0");
 		CHECK_TRUE(m_crypto_service_context);
 
-		m_rpc_session_handle = service_context_open(m_crypto_service_context, TS_RPC_ENCODING_PACKED_C, &caller);
-		CHECK_TRUE(m_rpc_session_handle);
+		m_rpc_session = service_context_open(m_crypto_service_context);
+		CHECK_TRUE(m_rpc_session);
 
-		m_scenarios = new crypto_service_scenarios(new packedc_crypto_client(caller));
+		m_scenarios = new crypto_service_scenarios(new packedc_crypto_client(m_rpc_session));
 	}
 
 	void teardown()
@@ -41,9 +38,9 @@
 		m_scenarios = NULL;
 
 		if (m_crypto_service_context) {
-			if (m_rpc_session_handle) {
-				service_context_close(m_crypto_service_context, m_rpc_session_handle);
-				m_rpc_session_handle = NULL;
+			if (m_rpc_session) {
+				service_context_close(m_crypto_service_context, m_rpc_session);
+				m_rpc_session = NULL;
 			}
 
 			service_context_relinquish(m_crypto_service_context);
@@ -51,7 +48,7 @@
 		}
 	}
 
-	rpc_session_handle m_rpc_session_handle;
+	struct rpc_caller_session *m_rpc_session;
 	struct service_context *m_crypto_service_context;
 	crypto_service_scenarios *m_scenarios;
 };
diff --git a/components/service/crypto/test/service/protobuf/crypto_service_protobuf_tests.cpp b/components/service/crypto/test/service/protobuf/crypto_service_protobuf_tests.cpp
index 885ebdc..56030ee 100644
--- a/components/service/crypto/test/service/protobuf/crypto_service_protobuf_tests.cpp
+++ b/components/service/crypto/test/service/protobuf/crypto_service_protobuf_tests.cpp
@@ -17,22 +17,19 @@
 {
     void setup()
     {
-        struct rpc_caller *caller;
-        int status;
-
-        m_rpc_session_handle = NULL;
+        m_rpc_session = NULL;
         m_crypto_service_context = NULL;
         m_scenarios = NULL;
 
         service_locator_init();
 
-        m_crypto_service_context = service_locator_query("sn:trustedfirmware.org:crypto:0", &status);
+        m_crypto_service_context = service_locator_query("sn:trustedfirmware.org:crypto-protobuf:0");
         CHECK_TRUE(m_crypto_service_context);
 
-        m_rpc_session_handle = service_context_open(m_crypto_service_context, TS_RPC_ENCODING_PROTOBUF, &caller);
-        CHECK_TRUE(m_rpc_session_handle);
+        m_rpc_session = service_context_open(m_crypto_service_context);
+        CHECK_TRUE(m_rpc_session);
 
-        m_scenarios = new crypto_service_scenarios(new protobuf_crypto_client(caller));
+        m_scenarios = new crypto_service_scenarios(new protobuf_crypto_client(m_rpc_session));
     }
 
     void teardown()
@@ -40,18 +37,18 @@
         delete m_scenarios;
         m_scenarios = NULL;
 
-	if (m_crypto_service_context) {
-	        if (m_rpc_session_handle) {
-                        service_context_close(m_crypto_service_context, m_rpc_session_handle);
-                        m_rpc_session_handle = NULL;
-	        }
+        if (m_crypto_service_context) {
+                if (m_rpc_session) {
+                            service_context_close(m_crypto_service_context, m_rpc_session);
+                            m_rpc_session = NULL;
+                }
 
                 service_context_relinquish(m_crypto_service_context);
                 m_crypto_service_context = NULL;
-	}
+        }
     }
 
-    rpc_session_handle m_rpc_session_handle;
+    struct rpc_caller_session *m_rpc_session;
     struct service_context *m_crypto_service_context;
     crypto_service_scenarios *m_scenarios;
 };
diff --git a/components/service/discovery/client/component.cmake b/components/service/discovery/client/component.cmake
deleted file mode 100644
index ce48d00..0000000
--- a/components/service/discovery/client/component.cmake
+++ /dev/null
@@ -1,13 +0,0 @@
-#-------------------------------------------------------------------------------
-# Copyright (c) 2021, Arm Limited and Contributors. All rights reserved.
-#
-# SPDX-License-Identifier: BSD-3-Clause
-#
-#-------------------------------------------------------------------------------
-if (NOT DEFINED TGT)
-	message(FATAL_ERROR "mandatory parameter TGT is not defined.")
-endif()
-
-target_sources(${TGT} PRIVATE
-	"${CMAKE_CURRENT_LIST_DIR}/discovery_client.c"
-	)
diff --git a/components/service/discovery/client/discovery_client.c b/components/service/discovery/client/discovery_client.c
deleted file mode 100644
index 5fc2ff3..0000000
--- a/components/service/discovery/client/discovery_client.c
+++ /dev/null
@@ -1,60 +0,0 @@
-/*
- * Copyright (c) 2021, Arm Limited and Contributors. All rights reserved.
- *
- * SPDX-License-Identifier: BSD-3-Clause
- */
-
-#include <string.h>
-#include <common/tlv/tlv.h>
-#include <protocols/service/discovery/packed-c/get_service_info.h>
-#include <protocols/service/discovery/packed-c/opcodes.h>
-#include <protocols/rpc/common/packed-c/status.h>
-#include "discovery_client.h"
-
-psa_status_t discovery_client_get_service_info(
-	struct service_client *service_client)
-{
-	psa_status_t psa_status = PSA_ERROR_GENERIC_ERROR;
-	rpc_call_handle call_handle;
-	uint8_t *req_buf;
-
-	call_handle = rpc_caller_begin(service_client->caller, &req_buf, 0);
-
-	if (call_handle) {
-
-		uint8_t *resp_buf;
-		size_t resp_len;
-		rpc_opstatus_t opstatus;
-
-		service_client->rpc_status = rpc_caller_invoke(service_client->caller, call_handle,
-			TS_DISCOVERY_OPCODE_GET_SERVICE_INFO, &opstatus, &resp_buf, &resp_len);
-
-		if (service_client->rpc_status == TS_RPC_CALL_ACCEPTED) {
-
-			psa_status = opstatus;
-
-			if (psa_status == PSA_SUCCESS) {
-
-				if (resp_len >= sizeof(struct ts_discovery_get_service_info_out)) {
-
-					struct ts_discovery_get_service_info_out resp_msg;
-					memcpy(&resp_msg, resp_buf, sizeof(struct ts_discovery_get_service_info_out));
-
-					service_client->service_info.supported_encodings =
-						resp_msg.supported_encodings;
-
-					service_client->service_info.max_payload =
-						resp_msg.max_payload;
-				}
-				else {
-					/* Failed to decode response message */
-					psa_status = PSA_ERROR_GENERIC_ERROR;
-				}
-			}
-		}
-
-		rpc_caller_end(service_client->caller, call_handle);
-	}
-
-	return psa_status;
-}
diff --git a/components/service/discovery/client/discovery_client.h b/components/service/discovery/client/discovery_client.h
deleted file mode 100644
index 7be4338..0000000
--- a/components/service/discovery/client/discovery_client.h
+++ /dev/null
@@ -1,37 +0,0 @@
-/*
- * Copyright (c) 2021, Arm Limited and Contributors. All rights reserved.
- *
- * SPDX-License-Identifier: BSD-3-Clause
- */
-
-#ifndef DISCOVERY_CLIENT_H
-#define DISCOVERY_CLIENT_H
-
-#include <psa/error.h>
-#include <service/common/client/service_client.h>
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-/**
- * @brief Get service info
- *
- * Discover service information from the service provider
- * instance associated with the provided service_client
- * object. If information is discovered, the service_client
- * object is updated with the discovered information.
- *
- * @param[in]  service_client 	An initialized service client
- *
- * @return     Success if information discovered
- */
-psa_status_t discovery_client_get_service_info(
-	struct service_client *service_client);
-
-
-#ifdef __cplusplus
-} /* extern "C" */
-#endif
-
-#endif /* DISCOVERY_CLIENT_H */
diff --git a/components/service/discovery/provider/component.cmake b/components/service/discovery/provider/component.cmake
deleted file mode 100644
index 85dfa85..0000000
--- a/components/service/discovery/provider/component.cmake
+++ /dev/null
@@ -1,13 +0,0 @@
-#-------------------------------------------------------------------------------
-# Copyright (c) 2021, Arm Limited and Contributors. All rights reserved.
-#
-# SPDX-License-Identifier: BSD-3-Clause
-#
-#-------------------------------------------------------------------------------
-if (NOT DEFINED TGT)
-	message(FATAL_ERROR "mandatory parameter TGT is not defined.")
-endif()
-
-target_sources(${TGT} PRIVATE
-	"${CMAKE_CURRENT_LIST_DIR}/discovery_provider.c"
-	)
diff --git a/components/service/discovery/provider/discovery_info.h b/components/service/discovery/provider/discovery_info.h
deleted file mode 100644
index 2d46a5a..0000000
--- a/components/service/discovery/provider/discovery_info.h
+++ /dev/null
@@ -1,66 +0,0 @@
-/*
- * Copyright (c) 2021, Arm Limited and Contributors. All rights reserved.
- *
- * SPDX-License-Identifier: BSD-3-Clause
- */
-
-#ifndef DISCOVERY_INFO_H
-#define DISCOVERY_INFO_H
-
-#include <stddef.h>
-#include <stdint.h>
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-/**
- * Information about the service deployment.
- */
-struct discovery_deployment_info
-{
-	/**
-	 * The RPC interface id that should be used for directing call
-	 * requests to this service provider instance.
-	 */
-	uint16_t interface_id;
-
-	/**
-	 * The instance number assigned to this service provider instance.
-	 * This can be used by a client for identifying a particular instance
-	 * of a service provider for cases where multple instances of the same
-	 * type of service provider are deployed.  The instance may be reflected
-	 * to clients using a standard convention such as a device numder
-	 * e.g. /dev/ps0 on Linux.
-	 */
-	uint16_t instance;
-
-	/**
-	 * When the discovery provider and associated service provider are
-	 * co-located (e.g. running in the same SP or TA), the max_payload
-	 * value reported by the discovery provider is determined from the
-	 * response buffer size associated with an incoming call_req object.
-	 * However in cases where call requests are forwarded, say to a
-	 * secure enclave, a different max_payload value may apply.  This
-	 * value allows for a deployment specific override that will
-	 * be reported instead.  Should be set to zero if no override
-	 * applies.
-	 */
-	size_t max_payload_override;
-};
-
-/**
- * Aggregate of all discovery info
- */
-struct discovery_info
-{
-	struct discovery_deployment_info deployment;
-
-	uint32_t supported_encodings;
-};
-
-#ifdef __cplusplus
-} /* extern "C" */
-#endif
-
-#endif /* DISCOVERY_INFO_H */
diff --git a/components/service/discovery/provider/discovery_provider.c b/components/service/discovery/provider/discovery_provider.c
deleted file mode 100644
index 2297d52..0000000
--- a/components/service/discovery/provider/discovery_provider.c
+++ /dev/null
@@ -1,153 +0,0 @@
-/*
- * Copyright (c) 2021, Arm Limited and Contributors. All rights reserved.
- *
- * SPDX-License-Identifier: BSD-3-Clause
- */
-
-#include <stddef.h>
-#include <protocols/service/discovery/packed-c/opcodes.h>
-#include <service/discovery/provider/discovery_provider.h>
-#include <protocols/rpc/common/packed-c/status.h>
-#include <psa/error.h>
-
-/* Service request handlers */
-static rpc_status_t get_service_info_handler(void *context, struct call_req *req);
-static rpc_status_t get_provider_info_handler(void *context, struct call_req *req);
-static rpc_status_t get_service_caps_handler(void *context, struct call_req *req);
-
-/* Other private functions */
-static size_t determine_max_payload(
-	const struct discovery_deployment_info *deployment_info,
-	const struct call_req *req);
-
-/* Handler mapping table for service */
-static const struct service_handler handler_table[] = {
-	{TS_DISCOVERY_OPCODE_GET_SERVICE_INFO,          get_service_info_handler},
-	{TS_DISCOVERY_OPCODE_GET_PROVIDER_INFO,         get_provider_info_handler},
-	{TS_DISCOVERY_OPCODE_GET_SERVICE_CAPS,          get_service_caps_handler}
-};
-
-
-void discovery_provider_init(struct discovery_provider *context)
-{
-	/* Initialise the base provider */
-	for (size_t encoding = 0; encoding < TS_RPC_ENCODING_LIMIT; ++encoding)
-		context->serializers[encoding] = NULL;
-
-	service_provider_init(&context->base_provider, context,
-					handler_table, sizeof(handler_table)/sizeof(struct service_handler));
-
-	/* Set default deployment settings.  Deployment specific settings may be
-	 * applied using discovery_provider_set_deployment_info().
-	 */
-	context->info.deployment.interface_id = 0;
-	context->info.deployment.instance = 0;
-	context->info.deployment.max_payload_override = 0;
-
-	/* Bitmap is set when serializers are registered */
-	context->info.supported_encodings = 0;
-}
-
-void discovery_provider_deinit(struct discovery_provider *context)
-{
-	(void)context;
-}
-
-void discovery_provider_register_serializer(struct discovery_provider *context,
-				unsigned int encoding, const struct discovery_provider_serializer *serializer)
-{
-	if (encoding < TS_RPC_ENCODING_LIMIT)
-		context->serializers[encoding] = serializer;
-}
-
-void discovery_provider_register_supported_encoding(
-	struct discovery_provider *context,
-	unsigned int encoding)
-{
-	context->info.supported_encodings |= (1U << encoding);
-}
-
-void discovery_provider_set_deployment_info(
-	struct discovery_provider *context,
-	const struct discovery_deployment_info *deployment_info)
-{
-	context->info.deployment = *deployment_info;
-}
-
-static const struct discovery_provider_serializer* get_discovery_serializer(void *context,
-														const struct call_req *req)
-{
-	struct discovery_provider *this_instance = (struct discovery_provider*)context;
-	const struct discovery_provider_serializer* serializer = NULL;
-	unsigned int encoding = call_req_get_encoding(req);
-
-	if (encoding < TS_RPC_ENCODING_LIMIT) serializer = this_instance->serializers[encoding];
-
-	return serializer;
-}
-
-static rpc_status_t get_service_info_handler(void *context, struct call_req* req)
-{
-	struct discovery_provider *this_instance = (struct discovery_provider*)context;
-	rpc_status_t rpc_status = TS_RPC_ERROR_SERIALIZATION_NOT_SUPPORTED;
-	const struct discovery_provider_serializer *serializer = get_discovery_serializer(context, req);
-
-	if (serializer) {
-
-		size_t max_payload = determine_max_payload(&this_instance->info.deployment, req);
-		struct call_param_buf *resp_buf = call_req_get_resp_buf(req);
-
-		rpc_status = serializer->serialize_get_service_info_resp(resp_buf,
-			max_payload,
-			&this_instance->info);
-
-		call_req_set_opstatus(req, PSA_SUCCESS);
-	}
-
-	return rpc_status;
-}
-
-static rpc_status_t get_provider_info_handler(void *context, struct call_req* req)
-{
-	(void)context;
-
-	call_req_set_opstatus(req, PSA_ERROR_NOT_SUPPORTED);
-	return TS_RPC_CALL_ACCEPTED;
-}
-
-static rpc_status_t get_service_caps_handler(void *context, struct call_req* req)
-{
-	(void)context;
-
-	call_req_set_opstatus(req, PSA_ERROR_NOT_SUPPORTED);
-	return TS_RPC_CALL_ACCEPTED;
-}
-
-static size_t determine_max_payload(
-	const struct discovery_deployment_info *deployment_info,
-	const struct call_req *req)
-{
-	size_t max_payload;
-
-	if (!deployment_info->max_payload_override) {
-
-		/* No deployment specific override has been provided so
-		 * determine the maximum payload value from the call_req
-		 * buffer sizes.  This will have been set by the
-		 * underlying RPC layer.
-		 */
-		const struct call_param_buf *req_buf = &req->req_buf;
-		const struct call_param_buf *resp_buf = &req->resp_buf;
-
-		max_payload = (req_buf->size < resp_buf->size) ?
-			req_buf->size :
-			resp_buf->size;
-	}
-	else {
-
-		/* A deployment specific override has been provided */
-		max_payload = deployment_info->max_payload_override;
-	}
-
-	return max_payload;
-}
diff --git a/components/service/discovery/provider/discovery_provider.h b/components/service/discovery/provider/discovery_provider.h
deleted file mode 100644
index 298cef0..0000000
--- a/components/service/discovery/provider/discovery_provider.h
+++ /dev/null
@@ -1,72 +0,0 @@
-/*
- * Copyright (c) 2021, Arm Limited and Contributors. All rights reserved.
- *
- * SPDX-License-Identifier: BSD-3-Clause
- */
-
-#ifndef DISCOVERY_PROVIDER_H
-#define DISCOVERY_PROVIDER_H
-
-#include <stdint.h>
-#include <service/common/provider/service_provider.h>
-#include <service/discovery/provider/serializer/discovery_provider_serializer.h>
-#include <service/discovery/provider/discovery_info.h>
-#include <protocols/rpc/common/packed-c/encoding.h>
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-/**
- * Instance data for a discover_provider object.
- */
-struct discovery_provider
-{
-	struct service_provider base_provider;
-	const struct discovery_provider_serializer *serializers[TS_RPC_ENCODING_LIMIT];
-
-	struct discovery_info info;
-};
-
-/**
- * Initializes an instance of the discovery service provider.
- */
-void discovery_provider_init(
-	struct discovery_provider *context);
-
-/**
- * When operation of the provider is no longer required, this function
- * frees any resource used by the previously initialized provider instance.
- */
-void discovery_provider_deinit(
-	struct discovery_provider *context);
-
-/**
- * Register a serializer for supportng a particular parameter encoding.
- */
-void discovery_provider_register_serializer(
-	struct discovery_provider *context,
-	unsigned int encoding,
-	const struct discovery_provider_serializer *serializer);
-
-/**
- * Register a supported protocol encoding for the service provider that
- * this discovery provider represents.
- */
-void discovery_provider_register_supported_encoding(
-	struct discovery_provider *context,
-	unsigned int encoding);
-
-/**
- * Sets deployment specific information that is adverstised by the
- * discovery provider.
- */
-void discovery_provider_set_deployment_info(
-	struct discovery_provider *context,
-	const struct discovery_deployment_info *deployment_info);
-
-#ifdef __cplusplus
-} /* extern "C" */
-#endif
-
-#endif /* DISCOVERY_PROVIDER_H */
diff --git a/components/service/discovery/provider/serializer/discovery_provider_serializer.h b/components/service/discovery/provider/serializer/discovery_provider_serializer.h
deleted file mode 100644
index 89d166f..0000000
--- a/components/service/discovery/provider/serializer/discovery_provider_serializer.h
+++ /dev/null
@@ -1,28 +0,0 @@
-/*
- * Copyright (c) 2021, Arm Limited and Contributors. All rights reserved.
- *
- * SPDX-License-Identifier: BSD-3-Clause
- */
-
-#ifndef DISCOVERY_PROVIDER_SERIALIZER_H
-#define DISCOVERY_PROVIDER_SERIALIZER_H
-
-#include <stddef.h>
-#include <service/discovery/provider/discovery_info.h>
-#include <rpc/common/endpoint/rpc_interface.h>
-
-/* Provides a common interface for parameter serialization operations
- * for the discovery service provider.  Allows alternative serialization
- * protocols to be used without hard-wiring a particular protocol
- * into the service provider code.  A concrete serializer must
- * implement this interface.
- */
-struct discovery_provider_serializer {
-
-	/* Operation: get_service_info */
-	rpc_status_t (*serialize_get_service_info_resp)(struct call_param_buf *resp_buf,
-		size_t max_payload,
-		const struct discovery_info *info);
-};
-
-#endif /* DISCOVERY_PROVIDER_SERIALIZER_H */
diff --git a/components/service/discovery/provider/serializer/packed-c/component.cmake b/components/service/discovery/provider/serializer/packed-c/component.cmake
deleted file mode 100644
index 319f062..0000000
--- a/components/service/discovery/provider/serializer/packed-c/component.cmake
+++ /dev/null
@@ -1,13 +0,0 @@
-#-------------------------------------------------------------------------------
-# Copyright (c) 2021, Arm Limited and Contributors. All rights reserved.
-#
-# SPDX-License-Identifier: BSD-3-Clause
-#
-#-------------------------------------------------------------------------------
-if (NOT DEFINED TGT)
-	message(FATAL_ERROR "mandatory parameter TGT is not defined.")
-endif()
-
-target_sources(${TGT} PRIVATE
-	"${CMAKE_CURRENT_LIST_DIR}/packedc_discovery_provider_serializer.c"
-	)
diff --git a/components/service/discovery/provider/serializer/packed-c/packedc_discovery_provider_serializer.c b/components/service/discovery/provider/serializer/packed-c/packedc_discovery_provider_serializer.c
deleted file mode 100644
index 5550ce7..0000000
--- a/components/service/discovery/provider/serializer/packed-c/packedc_discovery_provider_serializer.c
+++ /dev/null
@@ -1,46 +0,0 @@
-/*
- * Copyright (c) 2021, Arm Limited and Contributors. All rights reserved.
- *
- * SPDX-License-Identifier: BSD-3-Clause
- */
-#include <string.h>
-#include <protocols/rpc/common/packed-c/status.h>
-#include <protocols/service/discovery/packed-c/get_service_info.h>
-#include "packedc_discovery_provider_serializer.h"
-
-/* Operation: get_service_info */
-static rpc_status_t serialize_get_service_info_resp(struct call_param_buf *resp_buf,
-	size_t max_payload,
-	const struct discovery_info *info)
-{
-	rpc_status_t rpc_status = TS_RPC_ERROR_INTERNAL;
-	struct ts_discovery_get_service_info_out resp_msg;
-	size_t fixed_len = sizeof(struct ts_discovery_get_service_info_out);
-
-	resp_msg.instance = info->deployment.instance;
-	resp_msg.interface_id = info->deployment.interface_id;
-
-	resp_msg.max_payload = max_payload;
-	resp_msg.supported_encodings = info->supported_encodings;
-
-	if (fixed_len <= resp_buf->size) {
-
-		memcpy(resp_buf->data, &resp_msg, fixed_len);
-		resp_buf->data_len = fixed_len;
-
-		rpc_status = TS_RPC_CALL_ACCEPTED;
-	}
-
-	return rpc_status;
-}
-
-/* Singleton method to provide access to the serializer instance */
-const struct discovery_provider_serializer *packedc_discovery_provider_serializer_instance(void)
-{
-	static const struct discovery_provider_serializer instance =
-	{
-		serialize_get_service_info_resp
-	};
-
-	return &instance;
-}
diff --git a/components/service/discovery/provider/serializer/packed-c/packedc_discovery_provider_serializer.h b/components/service/discovery/provider/serializer/packed-c/packedc_discovery_provider_serializer.h
deleted file mode 100644
index 8bfd68a..0000000
--- a/components/service/discovery/provider/serializer/packed-c/packedc_discovery_provider_serializer.h
+++ /dev/null
@@ -1,26 +0,0 @@
-/*
- * Copyright (c) 2021, Arm Limited and Contributors. All rights reserved.
- *
- * SPDX-License-Identifier: BSD-3-Clause
- */
-
-#ifndef PACKEDC_DISCOVERY_PROVIDER_SERIALIZER_H
-#define PACKEDC_DISCOVERY_PROVIDER_SERIALIZER_H
-
-#include <service/discovery/provider/serializer/discovery_provider_serializer.h>
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-/**
- * Singleton method to provide access to the packed-c serializer
- * for the discovery service provider.
- */
-const struct discovery_provider_serializer *packedc_discovery_provider_serializer_instance(void);
-
-#ifdef __cplusplus
-} /* extern "C" */
-#endif
-
-#endif /* PACKEDC_DISCOVERY_PROVIDER_SERIALIZER_H */
diff --git a/components/service/discovery/test/service/component.cmake b/components/service/discovery/test/service/component.cmake
deleted file mode 100644
index 7f8a18a..0000000
--- a/components/service/discovery/test/service/component.cmake
+++ /dev/null
@@ -1,13 +0,0 @@
-#-------------------------------------------------------------------------------
-# Copyright (c) 2021, Arm Limited and Contributors. All rights reserved.
-#
-# SPDX-License-Identifier: BSD-3-Clause
-#
-#-------------------------------------------------------------------------------
-if (NOT DEFINED TGT)
-	message(FATAL_ERROR "mandatory parameter TGT is not defined.")
-endif()
-
-target_sources(${TGT} PRIVATE
-	"${CMAKE_CURRENT_LIST_DIR}/discovery_service_tests.cpp"
-	)
diff --git a/components/service/discovery/test/service/discovery_service_tests.cpp b/components/service/discovery/test/service/discovery_service_tests.cpp
deleted file mode 100644
index eab0c20..0000000
--- a/components/service/discovery/test/service/discovery_service_tests.cpp
+++ /dev/null
@@ -1,69 +0,0 @@
-/*
- * Copyright (c) 2021-2022, Arm Limited and Contributors. All rights reserved.
- *
- * SPDX-License-Identifier: BSD-3-Clause
- */
-
-#include <service/discovery/client/discovery_client.h>
-#include <protocols/rpc/common/packed-c/encoding.h>
-#include <service_locator.h>
-#include <CppUTest/TestHarness.h>
-
-/*
- * Service-level tests for the discovery service.  The discovery service
- * provides common operations that may be called at all service endpoints.
- * These tests use the crypto service as the target.
- */
-TEST_GROUP(DiscoveryServiceTests)
-{
-	void setup()
-	{
-		int status;
-
-		m_rpc_session_handle = NULL;
-		m_service_context = NULL;
-
-		service_locator_init();
-
-		m_service_context =
-			service_locator_query("sn:trustedfirmware.org:crypto:0", &status);
-		CHECK_TRUE(m_service_context);
-
-		m_rpc_session_handle =
-			service_context_open(m_service_context, TS_RPC_ENCODING_PACKED_C, &m_caller);
-		CHECK_TRUE(m_rpc_session_handle);
-	}
-
-	void teardown()
-	{
-		if (m_service_context) {
-			if (m_rpc_session_handle) {
-				service_context_close(m_service_context, m_rpc_session_handle);
-				m_rpc_session_handle = NULL;
-			}
-
-			service_context_relinquish(m_service_context);
-			m_service_context = NULL;
-		}
-	}
-
-	struct rpc_caller *m_caller;
-	rpc_session_handle m_rpc_session_handle;
-	struct service_context *m_service_context;
-};
-
-TEST(DiscoveryServiceTests, checkServiceInfo)
-{
-	struct service_client service_client;
-	psa_status_t status;
-
-	status = service_client_init(&service_client, m_caller);
-	LONGS_EQUAL(PSA_SUCCESS, status);
-
-	status = discovery_client_get_service_info(&service_client);
-	LONGS_EQUAL(PSA_SUCCESS, status);
-
-	/* Check discovered service info looks reasonable */
-	CHECK_TRUE(service_client.service_info.max_payload);
-	CHECK_TRUE(service_client.service_info.supported_encodings);
-}
diff --git a/components/service/fwu/provider/fwu_provider.c b/components/service/fwu/provider/fwu_provider.c
index 275d399..e94f653 100644
--- a/components/service/fwu/provider/fwu_provider.c
+++ b/components/service/fwu/provider/fwu_provider.c
@@ -13,17 +13,18 @@
 #include "protocols/service/fwu/packed-c/opcodes.h"
 #include "service/fwu/agent/update_agent.h"
 #include "service/fwu/provider/serializer/fwu_provider_serializer.h"
+#include "fwu_uuid.h"
 
 /* Service request handlers */
-static rpc_status_t begin_staging_handler(void *context, struct call_req *req);
-static rpc_status_t end_staging_handler(void *context, struct call_req *req);
-static rpc_status_t cancel_staging_handler(void *context, struct call_req *req);
-static rpc_status_t open_handler(void *context, struct call_req *req);
-static rpc_status_t write_stream_handler(void *context, struct call_req *req);
-static rpc_status_t read_stream_handler(void *context, struct call_req *req);
-static rpc_status_t commit_handler(void *context, struct call_req *req);
-static rpc_status_t accept_image_handler(void *context, struct call_req *req);
-static rpc_status_t select_previous_handler(void *context, struct call_req *req);
+static rpc_status_t begin_staging_handler(void *context, struct rpc_request *req);
+static rpc_status_t end_staging_handler(void *context, struct rpc_request *req);
+static rpc_status_t cancel_staging_handler(void *context, struct rpc_request *req);
+static rpc_status_t open_handler(void *context, struct rpc_request *req);
+static rpc_status_t write_stream_handler(void *context, struct rpc_request *req);
+static rpc_status_t read_stream_handler(void *context, struct rpc_request *req);
+static rpc_status_t commit_handler(void *context, struct rpc_request *req);
+static rpc_status_t accept_image_handler(void *context, struct rpc_request *req);
+static rpc_status_t select_previous_handler(void *context, struct rpc_request *req);
 
 /* Handler mapping table for service */
 static const struct service_handler handler_table[] = {
@@ -38,29 +39,25 @@
 	{ TS_FWU_OPCODE_SELECT_PREVIOUS, select_previous_handler }
 };
 
-struct rpc_interface *fwu_provider_init(struct fwu_provider *context,
+struct rpc_service_interface *fwu_provider_init(struct fwu_provider *context,
 					struct update_agent *update_agent)
 {
+	const struct rpc_uuid service_uuid = { .uuid = TS_FWU_SERVICE_UUID };
 	/* Initialise the fwu_provider */
 	context->update_agent = update_agent;
 
 	for (size_t encoding = 0; encoding < TS_RPC_ENCODING_LIMIT; ++encoding)
 		context->serializers[encoding] = NULL;
 
-	service_provider_init(&context->base_provider, context, handler_table,
+	service_provider_init(&context->base_provider, context, &service_uuid, handler_table,
 			      sizeof(handler_table) / sizeof(struct service_handler));
 
-	/* Initialise the associated discovery_provider and attach it */
-	discovery_provider_init(&context->discovery_provider);
-	service_provider_extend(&context->base_provider,
-				&context->discovery_provider.base_provider);
-
 	return service_provider_get_rpc_interface(&context->base_provider);
 }
 
 void fwu_provider_deinit(struct fwu_provider *context)
 {
-	discovery_provider_deinit(&context->discovery_provider);
+	(void)context;
 }
 
 void fwu_provider_register_serializer(struct fwu_provider *context, unsigned int encoding,
@@ -68,16 +65,14 @@
 {
 	if (encoding < TS_RPC_ENCODING_LIMIT) {
 		context->serializers[encoding] = serializer;
-		discovery_provider_register_supported_encoding(&context->discovery_provider,
-							       encoding);
 	}
 }
 
 static const struct fwu_provider_serializer *get_fwu_serializer(struct fwu_provider *this_instance,
-								const struct call_req *req)
+								const struct rpc_request *req)
 {
 	const struct fwu_provider_serializer *serializer = NULL;
-	unsigned int encoding = call_req_get_encoding(req);
+	unsigned int encoding = 0;
 
 	if (encoding < TS_RPC_ENCODING_LIMIT)
 		serializer = this_instance->serializers[encoding];
@@ -85,43 +80,37 @@
 	return serializer;
 }
 
-static rpc_status_t begin_staging_handler(void *context, struct call_req *req)
+static rpc_status_t begin_staging_handler(void *context, struct rpc_request *req)
 {
 	struct fwu_provider *this_instance = (struct fwu_provider *)context;
 
-	int op_status = update_agent_begin_staging(this_instance->update_agent);
+	req->service_status = update_agent_begin_staging(this_instance->update_agent);
 
-	call_req_set_opstatus(req, op_status);
-
-	return TS_RPC_CALL_ACCEPTED;
+	return RPC_SUCCESS;
 }
 
-static rpc_status_t end_staging_handler(void *context, struct call_req *req)
+static rpc_status_t end_staging_handler(void *context, struct rpc_request *req)
 {
 	struct fwu_provider *this_instance = (struct fwu_provider *)context;
 
-	int op_status = update_agent_end_staging(this_instance->update_agent);
+	req->service_status = update_agent_end_staging(this_instance->update_agent);
 
-	call_req_set_opstatus(req, op_status);
-
-	return TS_RPC_CALL_ACCEPTED;
+	return RPC_SUCCESS;
 }
 
-static rpc_status_t cancel_staging_handler(void *context, struct call_req *req)
+static rpc_status_t cancel_staging_handler(void *context, struct rpc_request *req)
 {
 	struct fwu_provider *this_instance = (struct fwu_provider *)context;
 
-	int op_status = update_agent_cancel_staging(this_instance->update_agent);
+	req->service_status = update_agent_cancel_staging(this_instance->update_agent);
 
-	call_req_set_opstatus(req, op_status);
-
-	return TS_RPC_CALL_ACCEPTED;
+	return RPC_SUCCESS;
 }
 
-static rpc_status_t open_handler(void *context, struct call_req *req)
+static rpc_status_t open_handler(void *context, struct rpc_request *req)
 {
-	rpc_status_t rpc_status = TS_RPC_ERROR_SERIALIZATION_NOT_SUPPORTED;
-	struct call_param_buf *req_buf = call_req_get_req_buf(req);
+	rpc_status_t rpc_status = RPC_ERROR_INTERNAL;
+	struct rpc_buffer *req_buf = &req->request;
 	struct fwu_provider *this_instance = (struct fwu_provider *)context;
 	const struct fwu_provider_serializer *serializer = get_fwu_serializer(this_instance, req);
 	struct uuid_octets image_type_uuid;
@@ -129,26 +118,24 @@
 	if (serializer)
 		rpc_status = serializer->deserialize_open_req(req_buf, &image_type_uuid);
 
-	if (rpc_status == TS_RPC_CALL_ACCEPTED) {
+	if (rpc_status == RPC_SUCCESS) {
 		uint32_t handle = 0;
-		int op_status =
+		req->service_status =
 			update_agent_open(this_instance->update_agent, &image_type_uuid, &handle);
 
-		if (!op_status) {
-			struct call_param_buf *resp_buf = call_req_get_resp_buf(req);
+		if (!req->service_status) {
+			struct rpc_buffer *resp_buf = &req->response;
 			rpc_status = serializer->serialize_open_resp(resp_buf, handle);
 		}
-
-		call_req_set_opstatus(req, op_status);
 	}
 
 	return rpc_status;
 }
 
-static rpc_status_t write_stream_handler(void *context, struct call_req *req)
+static rpc_status_t write_stream_handler(void *context, struct rpc_request *req)
 {
-	rpc_status_t rpc_status = TS_RPC_ERROR_SERIALIZATION_NOT_SUPPORTED;
-	struct call_param_buf *req_buf = call_req_get_req_buf(req);
+	rpc_status_t rpc_status = RPC_ERROR_INTERNAL;
+	struct rpc_buffer *req_buf = &req->request;
 	struct fwu_provider *this_instance = (struct fwu_provider *)context;
 	const struct fwu_provider_serializer *serializer = get_fwu_serializer(this_instance, req);
 	uint32_t handle = 0;
@@ -159,20 +146,18 @@
 		rpc_status = serializer->deserialize_write_stream_req(req_buf, &handle, &data_len,
 								      &data);
 
-	if (rpc_status == TS_RPC_CALL_ACCEPTED) {
-		int op_status = update_agent_write_stream(this_instance->update_agent, handle, data,
-							  data_len);
-
-		call_req_set_opstatus(req, op_status);
+	if (rpc_status == RPC_SUCCESS) {
+		req->service_status = update_agent_write_stream(this_instance->update_agent, handle,
+								data, data_len);
 	}
 
 	return rpc_status;
 }
 
-static rpc_status_t read_stream_handler(void *context, struct call_req *req)
+static rpc_status_t read_stream_handler(void *context, struct rpc_request *req)
 {
-	rpc_status_t rpc_status = TS_RPC_ERROR_SERIALIZATION_NOT_SUPPORTED;
-	struct call_param_buf *req_buf = call_req_get_req_buf(req);
+	rpc_status_t rpc_status = RPC_ERROR_INTERNAL;
+	struct rpc_buffer *req_buf = &req->request;
 	struct fwu_provider *this_instance = (struct fwu_provider *)context;
 	const struct fwu_provider_serializer *serializer = get_fwu_serializer(this_instance, req);
 	uint32_t handle = 0;
@@ -180,8 +165,8 @@
 	if (serializer)
 		rpc_status = serializer->deserialize_read_stream_req(req_buf, &handle);
 
-	if (rpc_status == TS_RPC_CALL_ACCEPTED) {
-		struct call_param_buf *resp_buf = call_req_get_resp_buf(req);
+	if (rpc_status == RPC_SUCCESS) {
+		struct rpc_buffer *resp_buf = &req->response;
 		uint8_t *payload_buf;
 		size_t max_payload;
 		size_t read_len = 0;
@@ -189,24 +174,23 @@
 
 		serializer->read_stream_resp_payload(resp_buf, &payload_buf, &max_payload);
 
-		int op_status = update_agent_read_stream(this_instance->update_agent, handle,
+		req->service_status = update_agent_read_stream(this_instance->update_agent, handle,
 							 payload_buf, max_payload, &read_len,
 							 &total_len);
 
-		if (!op_status)
+		if (!req->service_status)
 			rpc_status = serializer->serialize_read_stream_resp(resp_buf, read_len,
 									    total_len);
 
-		call_req_set_opstatus(req, op_status);
 	}
 
 	return rpc_status;
 }
 
-static rpc_status_t commit_handler(void *context, struct call_req *req)
+static rpc_status_t commit_handler(void *context, struct rpc_request *req)
 {
-	rpc_status_t rpc_status = TS_RPC_ERROR_SERIALIZATION_NOT_SUPPORTED;
-	struct call_param_buf *req_buf = call_req_get_req_buf(req);
+	rpc_status_t rpc_status = RPC_ERROR_INTERNAL;
+	struct rpc_buffer *req_buf = &req->request;
 	struct fwu_provider *this_instance = (struct fwu_provider *)context;
 	const struct fwu_provider_serializer *serializer = get_fwu_serializer(this_instance, req);
 	uint32_t handle = 0;
@@ -217,24 +201,23 @@
 		rpc_status = serializer->deserialize_commit_req(req_buf, &handle, &accepted,
 								&max_atomic_len);
 
-	if (rpc_status == TS_RPC_CALL_ACCEPTED) {
-		int op_status = update_agent_commit(this_instance->update_agent, handle, accepted);
+	if (rpc_status == RPC_SUCCESS) {
+		req->service_status = update_agent_commit(this_instance->update_agent, handle,
+							  accepted);
 
-		if (!op_status) {
-			struct call_param_buf *resp_buf = call_req_get_resp_buf(req);
+		if (!req->service_status) {
+			struct rpc_buffer *resp_buf = &req->response;
 			rpc_status = serializer->serialize_commit_resp(resp_buf, 0, 0);
 		}
-
-		call_req_set_opstatus(req, op_status);
 	}
 
 	return rpc_status;
 }
 
-static rpc_status_t accept_image_handler(void *context, struct call_req *req)
+static rpc_status_t accept_image_handler(void *context, struct rpc_request *req)
 {
-	rpc_status_t rpc_status = TS_RPC_ERROR_SERIALIZATION_NOT_SUPPORTED;
-	struct call_param_buf *req_buf = call_req_get_req_buf(req);
+	rpc_status_t rpc_status = RPC_ERROR_INTERNAL;
+	struct rpc_buffer *req_buf = &req->request;
 	struct fwu_provider *this_instance = (struct fwu_provider *)context;
 	const struct fwu_provider_serializer *serializer = get_fwu_serializer(this_instance, req);
 	struct uuid_octets image_type_uuid;
@@ -242,22 +225,18 @@
 	if (serializer)
 		rpc_status = serializer->deserialize_accept_req(req_buf, &image_type_uuid);
 
-	if (rpc_status == TS_RPC_CALL_ACCEPTED) {
-		int op_status = update_agent_accept(this_instance->update_agent, &image_type_uuid);
-
-		call_req_set_opstatus(req, op_status);
-	}
+	if (rpc_status == RPC_SUCCESS)
+		req->service_status = update_agent_accept(this_instance->update_agent,
+							  &image_type_uuid);
 
 	return rpc_status;
 }
 
-static rpc_status_t select_previous_handler(void *context, struct call_req *req)
+static rpc_status_t select_previous_handler(void *context, struct rpc_request *req)
 {
 	struct fwu_provider *this_instance = (struct fwu_provider *)context;
 
-	int op_status = update_agent_select_previous(this_instance->update_agent);
+	req->service_status = update_agent_select_previous(this_instance->update_agent);
 
-	call_req_set_opstatus(req, op_status);
-
-	return TS_RPC_CALL_ACCEPTED;
+	return RPC_SUCCESS;
 }
diff --git a/components/service/fwu/provider/fwu_provider.h b/components/service/fwu/provider/fwu_provider.h
index 94c6ce5..037889a 100644
--- a/components/service/fwu/provider/fwu_provider.h
+++ b/components/service/fwu/provider/fwu_provider.h
@@ -8,9 +8,8 @@
 #define FWU_PROVIDER_H
 
 #include "protocols/rpc/common/packed-c/encoding.h"
-#include "rpc/common/endpoint/rpc_interface.h"
+#include "rpc/common/endpoint/rpc_service_interface.h"
 #include "service/common/provider/service_provider.h"
-#include "service/discovery/provider/discovery_provider.h"
 
 #ifdef __cplusplus
 extern "C" {
@@ -34,7 +33,6 @@
 struct fwu_provider {
 	struct service_provider base_provider;
 	const struct fwu_provider_serializer *serializers[TS_RPC_ENCODING_LIMIT];
-	struct discovery_provider discovery_provider;
 	struct update_agent *update_agent;
 };
 
@@ -46,8 +44,8 @@
  *
  * \return A pointer to the exposed rpc_interface or NULL on failure
  */
-struct rpc_interface *fwu_provider_init(struct fwu_provider *context,
-					struct update_agent *update_agent);
+struct rpc_service_interface *fwu_provider_init(struct fwu_provider *context,
+						struct update_agent *update_agent);
 
 /**
  * \brief De-initialise a fwu_provider
diff --git a/components/service/fwu/provider/fwu_uuid.h b/components/service/fwu/provider/fwu_uuid.h
new file mode 100644
index 0000000..4fe4776
--- /dev/null
+++ b/components/service/fwu/provider/fwu_uuid.h
@@ -0,0 +1,21 @@
+/*
+ * Copyright (c) 2023, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef FWU_UUID_H
+#define FWU_UUID_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define TS_FWU_SERVICE_UUID \
+{ 0x68, 0x23, 0xa8, 0x38, 0x1b, 0x06, 0x47, 0x0e, 0x97, 0x74, 0x0c, 0xce, 0x8b, 0xfb, 0x53, 0xfd }
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* FWU_UUID_H */
diff --git a/components/service/fwu/provider/serializer/fwu_provider_serializer.h b/components/service/fwu/provider/serializer/fwu_provider_serializer.h
index 0529068..c9df194 100644
--- a/components/service/fwu/provider/serializer/fwu_provider_serializer.h
+++ b/components/service/fwu/provider/serializer/fwu_provider_serializer.h
@@ -12,7 +12,7 @@
 #include <stdint.h>
 
 #include "common/uuid/uuid.h"
-#include "rpc/common/endpoint/rpc_interface.h"
+#include "rpc/common/endpoint/rpc_service_interface.h"
 
 /* Provides a common interface for parameter serialization operations
  * for the fwu service provider. Allows alternative serialization
@@ -22,36 +22,36 @@
  */
 struct fwu_provider_serializer {
 	/* Operation: open */
-	rpc_status_t (*deserialize_open_req)(const struct call_param_buf *req_buf,
+	rpc_status_t (*deserialize_open_req)(const struct rpc_buffer *req_buf,
 					     struct uuid_octets *image_type_uuid);
 
-	rpc_status_t (*serialize_open_resp)(struct call_param_buf *resp_buf, uint32_t handle);
+	rpc_status_t (*serialize_open_resp)(struct rpc_buffer *resp_buf, uint32_t handle);
 
 	/* Operation: write_stream */
-	rpc_status_t (*deserialize_write_stream_req)(const struct call_param_buf *req_buf,
+	rpc_status_t (*deserialize_write_stream_req)(const struct rpc_buffer *req_buf,
 						     uint32_t *handle, size_t *data_len,
 						     const uint8_t **data);
 
 	/* Operation: read_stream */
-	rpc_status_t (*deserialize_read_stream_req)(const struct call_param_buf *req_buf,
+	rpc_status_t (*deserialize_read_stream_req)(const struct rpc_buffer *req_buf,
 						    uint32_t *handle);
 
-	void (*read_stream_resp_payload)(const struct call_param_buf *resp_buf,
+	void (*read_stream_resp_payload)(const struct rpc_buffer *resp_buf,
 					 uint8_t **payload_buf, size_t *max_payload);
 
-	rpc_status_t (*serialize_read_stream_resp)(struct call_param_buf *resp_buf,
+	rpc_status_t (*serialize_read_stream_resp)(struct rpc_buffer *resp_buf,
 						   size_t read_bytes, size_t total_bytes);
 
 	/* Operation: commit */
-	rpc_status_t (*deserialize_commit_req)(const struct call_param_buf *req_buf,
+	rpc_status_t (*deserialize_commit_req)(const struct rpc_buffer *req_buf,
 					       uint32_t *handle, bool *accepted,
 					       size_t *max_atomic_len);
 
-	rpc_status_t (*serialize_commit_resp)(struct call_param_buf *resp_buf, size_t progress,
+	rpc_status_t (*serialize_commit_resp)(struct rpc_buffer *resp_buf, size_t progress,
 					      size_t total_work);
 
 	/* Operation: accept_image */
-	rpc_status_t (*deserialize_accept_req)(const struct call_param_buf *req_buf,
+	rpc_status_t (*deserialize_accept_req)(const struct rpc_buffer *req_buf,
 					       struct uuid_octets *image_type_uuid);
 };
 
diff --git a/components/service/fwu/provider/serializer/packed-c/packedc_fwu_provider_serializer.c b/components/service/fwu/provider/serializer/packed-c/packedc_fwu_provider_serializer.c
index 9bafb42..cb013d4 100644
--- a/components/service/fwu/provider/serializer/packed-c/packedc_fwu_provider_serializer.c
+++ b/components/service/fwu/provider/serializer/packed-c/packedc_fwu_provider_serializer.c
@@ -10,27 +10,27 @@
 #include "protocols/rpc/common/packed-c/status.h"
 #include "protocols/service/fwu/packed-c/fwu_proto.h"
 
-static rpc_status_t deserialize_open_req(const struct call_param_buf *req_buf,
+static rpc_status_t deserialize_open_req(const struct rpc_buffer *req_buf,
 					 struct uuid_octets *image_type_uuid)
 {
-	rpc_status_t rpc_status = TS_RPC_ERROR_INVALID_REQ_BODY;
+	rpc_status_t rpc_status = RPC_ERROR_INVALID_REQUEST_BODY;
 	size_t expected_fixed_len = sizeof(struct ts_fwu_open_in);
 
-	if (expected_fixed_len <= req_buf->data_len) {
+	if (expected_fixed_len <= req_buf->data_length) {
 		const struct ts_fwu_open_in *recv_msg =
 			(const struct ts_fwu_open_in *)req_buf->data;
 
 		memcpy(image_type_uuid->octets, recv_msg->image_type_uuid, UUID_OCTETS_LEN);
 
-		rpc_status = TS_RPC_CALL_ACCEPTED;
+		rpc_status = RPC_SUCCESS;
 	}
 
 	return rpc_status;
 }
 
-static rpc_status_t serialize_open_resp(struct call_param_buf *resp_buf, uint32_t handle)
+static rpc_status_t serialize_open_resp(struct rpc_buffer *resp_buf, uint32_t handle)
 {
-	rpc_status_t rpc_status = TS_RPC_ERROR_INTERNAL;
+	rpc_status_t rpc_status = RPC_ERROR_INTERNAL;
 	size_t fixed_len = sizeof(struct ts_fwu_open_out);
 
 	if (fixed_len <= resp_buf->size) {
@@ -38,53 +38,53 @@
 
 		resp_msg->handle = handle;
 
-		resp_buf->data_len = fixed_len;
-		rpc_status = TS_RPC_CALL_ACCEPTED;
+		resp_buf->data_length = fixed_len;
+		rpc_status = RPC_SUCCESS;
 	}
 
 	return rpc_status;
 }
 
 /* Operation: write_stream */
-static rpc_status_t deserialize_write_stream_req(const struct call_param_buf *req_buf,
-						 uint32_t *handle, size_t *data_len,
+static rpc_status_t deserialize_write_stream_req(const struct rpc_buffer *req_buf,
+						 uint32_t *handle, size_t *data_length,
 						 const uint8_t **data)
 {
-	rpc_status_t rpc_status = TS_RPC_ERROR_INVALID_REQ_BODY;
+	rpc_status_t rpc_status = RPC_ERROR_INVALID_REQUEST_BODY;
 	size_t expected_fixed_len = sizeof(struct ts_fwu_write_stream_in);
 
-	if (expected_fixed_len <= req_buf->data_len) {
+	if (expected_fixed_len <= req_buf->data_length) {
 		const struct ts_fwu_write_stream_in *recv_msg =
 			(const struct ts_fwu_write_stream_in *)req_buf->data;
 
 		*handle = recv_msg->handle;
-		*data_len = recv_msg->data_len;
+		*data_length = recv_msg->data_len;
 		*data = recv_msg->payload;
-		rpc_status = TS_RPC_CALL_ACCEPTED;
+		rpc_status = RPC_SUCCESS;
 	}
 
 	return rpc_status;
 }
 
 /* Operation: read_stream */
-static rpc_status_t deserialize_read_stream_req(const struct call_param_buf *req_buf,
+static rpc_status_t deserialize_read_stream_req(const struct rpc_buffer *req_buf,
 						uint32_t *handle)
 {
-	rpc_status_t rpc_status = TS_RPC_ERROR_INVALID_REQ_BODY;
+	rpc_status_t rpc_status = RPC_ERROR_INVALID_REQUEST_BODY;
 	size_t expected_fixed_len = sizeof(struct ts_fwu_read_stream_in);
 
-	if (expected_fixed_len <= req_buf->data_len) {
+	if (expected_fixed_len <= req_buf->data_length) {
 		const struct ts_fwu_read_stream_in *recv_msg =
 			(const struct ts_fwu_read_stream_in *)req_buf->data;
 
 		*handle = recv_msg->handle;
-		rpc_status = TS_RPC_CALL_ACCEPTED;
+		rpc_status = RPC_SUCCESS;
 	}
 
 	return rpc_status;
 }
 
-static void read_stream_resp_payload(const struct call_param_buf *resp_buf, uint8_t **payload_buf,
+static void read_stream_resp_payload(const struct rpc_buffer *resp_buf, uint8_t **payload_buf,
 				     size_t *max_payload)
 {
 	struct ts_fwu_read_stream_out *resp_msg = (struct ts_fwu_read_stream_out *)resp_buf->data;
@@ -97,15 +97,15 @@
 		*max_payload = resp_buf->size - fixed_len;
 }
 
-static rpc_status_t serialize_read_stream_resp(struct call_param_buf *resp_buf, size_t read_bytes,
+static rpc_status_t serialize_read_stream_resp(struct rpc_buffer *resp_buf, size_t read_bytes,
 					       size_t total_bytes)
 {
-	rpc_status_t rpc_status = TS_RPC_ERROR_INTERNAL;
+	rpc_status_t rpc_status = RPC_ERROR_INTERNAL;
 	struct ts_fwu_read_stream_out *resp_msg = (struct ts_fwu_read_stream_out *)resp_buf->data;
 	size_t proto_overhead = offsetof(struct ts_fwu_read_stream_out, payload);
 
 	if (read_bytes > (SIZE_MAX - proto_overhead))
-		return TS_RPC_ERROR_INVALID_PARAMETER;
+		return RPC_ERROR_INVALID_VALUE;
 
 	size_t required_len = proto_overhead + read_bytes;
 
@@ -113,37 +113,37 @@
 		resp_msg->read_bytes = read_bytes;
 		resp_msg->total_bytes = total_bytes;
 
-		resp_buf->data_len = required_len;
-		rpc_status = TS_RPC_CALL_ACCEPTED;
+		resp_buf->data_length = required_len;
+		rpc_status = RPC_SUCCESS;
 	}
 
 	return rpc_status;
 }
 
 /* Operation: commit */
-static rpc_status_t deserialize_commit_req(const struct call_param_buf *req_buf, uint32_t *handle,
+static rpc_status_t deserialize_commit_req(const struct rpc_buffer *req_buf, uint32_t *handle,
 					   bool *accepted, size_t *max_atomic_len)
 {
-	rpc_status_t rpc_status = TS_RPC_ERROR_INVALID_REQ_BODY;
+	rpc_status_t rpc_status = RPC_ERROR_INVALID_REQUEST_BODY;
 	size_t expected_fixed_len = sizeof(struct ts_fwu_commit_in);
 
-	if (expected_fixed_len <= req_buf->data_len) {
+	if (expected_fixed_len <= req_buf->data_length) {
 		const struct ts_fwu_commit_in *recv_msg =
 			(const struct ts_fwu_commit_in *)req_buf->data;
 
 		*handle = recv_msg->handle;
 		*accepted = (recv_msg->acceptance_req == 0);
 		*max_atomic_len = recv_msg->max_atomic_len;
-		rpc_status = TS_RPC_CALL_ACCEPTED;
+		rpc_status = RPC_SUCCESS;
 	}
 
 	return rpc_status;
 }
 
-static rpc_status_t serialize_commit_resp(struct call_param_buf *resp_buf, size_t progress,
+static rpc_status_t serialize_commit_resp(struct rpc_buffer *resp_buf, size_t progress,
 					  size_t total_work)
 {
-	rpc_status_t rpc_status = TS_RPC_ERROR_INTERNAL;
+	rpc_status_t rpc_status = RPC_ERROR_INTERNAL;
 	struct ts_fwu_commit_out *resp_msg = (struct ts_fwu_commit_out *)resp_buf->data;
 
 	size_t required_len = sizeof(struct ts_fwu_commit_out);
@@ -152,26 +152,26 @@
 		resp_msg->progress = progress;
 		resp_msg->total_work = total_work;
 
-		resp_buf->data_len = required_len;
-		rpc_status = TS_RPC_CALL_ACCEPTED;
+		resp_buf->data_length = required_len;
+		rpc_status = RPC_SUCCESS;
 	}
 
 	return rpc_status;
 }
 
 /* Operation: accept_image */
-static rpc_status_t deserialize_accept_req(const struct call_param_buf *req_buf,
+static rpc_status_t deserialize_accept_req(const struct rpc_buffer *req_buf,
 					   struct uuid_octets *image_type_uuid)
 {
-	rpc_status_t rpc_status = TS_RPC_ERROR_INVALID_REQ_BODY;
+	rpc_status_t rpc_status = RPC_ERROR_INVALID_REQUEST_BODY;
 	size_t expected_fixed_len = sizeof(struct ts_fwu_accept_image_in);
 
-	if (expected_fixed_len <= req_buf->data_len) {
+	if (expected_fixed_len <= req_buf->data_length) {
 		const struct ts_fwu_accept_image_in *recv_msg =
 			(const struct ts_fwu_accept_image_in *)req_buf->data;
 
 		memcpy(image_type_uuid->octets, recv_msg->image_type_uuid, UUID_OCTETS_LEN);
-		rpc_status = TS_RPC_CALL_ACCEPTED;
+		rpc_status = RPC_SUCCESS;
 	}
 
 	return rpc_status;
diff --git a/components/service/fwu/test/fwu_client/remote/remote_fwu_client.cpp b/components/service/fwu/test/fwu_client/remote/remote_fwu_client.cpp
index d4503a5..803dfe6 100644
--- a/components/service/fwu/test/fwu_client/remote/remote_fwu_client.cpp
+++ b/components/service/fwu/test/fwu_client/remote/remote_fwu_client.cpp
@@ -15,12 +15,11 @@
 #include "protocols/service/fwu/packed-c/fwu_proto.h"
 #include "protocols/service/fwu/packed-c/opcodes.h"
 #include "protocols/service/fwu/packed-c/status.h"
-#include "service/discovery/client/discovery_client.h"
 
 remote_fwu_client::remote_fwu_client()
 	: fwu_client()
 	, m_client()
-	, m_rpc_session_handle(NULL)
+	, m_rpc_session(NULL)
 	, m_service_context(NULL)
 {
 	open_session();
@@ -33,25 +32,19 @@
 
 void remote_fwu_client::open_session(void)
 {
-	struct rpc_caller *caller = NULL;
-	int status;
-
-	m_rpc_session_handle = NULL;
+	m_rpc_session = NULL;
 	m_service_context = NULL;
 
 	service_locator_init();
 
-	m_service_context = service_locator_query("sn:trustedfirmware.org:fwu:0", &status);
+	m_service_context = service_locator_query("sn:trustedfirmware.org:fwu:0");
 
 	if (m_service_context) {
-		m_rpc_session_handle =
-			service_context_open(m_service_context, TS_RPC_ENCODING_PACKED_C, &caller);
+		m_rpc_session =
+			service_context_open(m_service_context);
 
-		if (m_rpc_session_handle) {
-			assert(caller);
-
-			service_client_init(&m_client, caller);
-			discovery_client_get_service_info(&m_client);
+		if (m_rpc_session) {
+			service_client_init(&m_client, m_rpc_session);
 
 		} else {
 			service_context_relinquish(m_service_context);
@@ -65,9 +58,9 @@
 	if (m_service_context) {
 		service_client_deinit(&m_client);
 
-		if (m_rpc_session_handle) {
-			service_context_close(m_service_context, m_rpc_session_handle);
-			m_rpc_session_handle = NULL;
+		if (m_rpc_session) {
+			service_context_close(m_service_context, m_rpc_session);
+			m_rpc_session = NULL;
 		}
 
 		service_context_relinquish(m_service_context);
@@ -85,20 +78,20 @@
 	if (!m_service_context)
 		return fwu_status;
 
-	call_handle = rpc_caller_begin(m_client.caller, &req_buf, req_len);
+	call_handle = rpc_caller_session_begin(m_rpc_session, &req_buf, req_len, 0);
 
 	if (call_handle) {
 		uint8_t *resp_buf;
 		size_t resp_len;
-		rpc_opstatus_t opstatus;
+		service_status_t service_status;
 
-		m_client.rpc_status = rpc_caller_invoke(m_client.caller, call_handle, opcode,
-							&opstatus, &resp_buf, &resp_len);
+		m_client.rpc_status = rpc_caller_session_invoke(call_handle, opcode,
+							&resp_buf, &resp_len, &service_status);
 
 		if (m_client.rpc_status == TS_RPC_CALL_ACCEPTED)
-			fwu_status = opstatus;
+			fwu_status = service_status;
 
-		rpc_caller_end(m_client.caller, call_handle);
+		rpc_caller_session_end(call_handle);
 	}
 
 	return fwu_status;
@@ -133,23 +126,23 @@
 	rpc_call_handle call_handle;
 	uint8_t *req_buf;
 
-	call_handle = rpc_caller_begin(m_client.caller, &req_buf, req_len);
+	call_handle = rpc_caller_session_begin(m_rpc_session, &req_buf, req_len, 0);
 
 	if (call_handle) {
 		uint8_t *resp_buf;
 		size_t resp_len;
-		rpc_opstatus_t opstatus;
+		service_status_t service_status;
 
 		memcpy(req_buf, &req_msg, req_len);
 
-		m_client.rpc_status = rpc_caller_invoke(m_client.caller, call_handle,
-							TS_FWU_OPCODE_ACCEPT_IMAGE, &opstatus,
-							&resp_buf, &resp_len);
+		m_client.rpc_status = rpc_caller_session_invoke(call_handle,
+							TS_FWU_OPCODE_ACCEPT_IMAGE,
+							&resp_buf, &resp_len, &service_status);
 
 		if (m_client.rpc_status == TS_RPC_CALL_ACCEPTED)
-			fwu_status = opstatus;
+			fwu_status = service_status;
 
-		rpc_caller_end(m_client.caller, call_handle);
+		rpc_caller_session_end(call_handle);
 	}
 
 	return fwu_status;
@@ -174,21 +167,22 @@
 	rpc_call_handle call_handle;
 	uint8_t *req_buf;
 
-	call_handle = rpc_caller_begin(m_client.caller, &req_buf, req_len);
+	call_handle = rpc_caller_session_begin(m_rpc_session, &req_buf, req_len,
+					       sizeof(struct ts_fwu_open_out));
 
 	if (call_handle) {
 		uint8_t *resp_buf;
 		size_t resp_len;
-		rpc_opstatus_t opstatus;
+		service_status_t service_status;
 
 		memcpy(req_buf, &req_msg, req_len);
 
-		m_client.rpc_status = rpc_caller_invoke(m_client.caller, call_handle,
-							TS_FWU_OPCODE_OPEN, &opstatus, &resp_buf,
-							&resp_len);
+		m_client.rpc_status = rpc_caller_session_invoke(call_handle,
+							TS_FWU_OPCODE_OPEN, &resp_buf,
+							&resp_len, &service_status);
 
 		if (m_client.rpc_status == TS_RPC_CALL_ACCEPTED) {
-			fwu_status = opstatus;
+			fwu_status = service_status;
 
 			if ((fwu_status == FWU_STATUS_SUCCESS) &&
 			    (resp_len >= sizeof(struct ts_fwu_open_out))) {
@@ -199,7 +193,7 @@
 			}
 		}
 
-		rpc_caller_end(m_client.caller, call_handle);
+		rpc_caller_session_end(call_handle);
 	}
 
 	return fwu_status;
@@ -220,23 +214,23 @@
 	rpc_call_handle call_handle;
 	uint8_t *req_buf;
 
-	call_handle = rpc_caller_begin(m_client.caller, &req_buf, req_len);
+	call_handle = rpc_caller_session_begin(m_rpc_session, &req_buf, req_len, 0);
 
 	if (call_handle) {
 		uint8_t *resp_buf;
 		size_t resp_len;
-		rpc_opstatus_t opstatus;
+		service_status_t service_status;
 
 		memcpy(req_buf, &req_msg, req_len);
 
-		m_client.rpc_status = rpc_caller_invoke(m_client.caller, call_handle,
-							TS_FWU_OPCODE_COMMIT, &opstatus, &resp_buf,
-							&resp_len);
+		m_client.rpc_status = rpc_caller_session_invoke(call_handle,
+							TS_FWU_OPCODE_COMMIT, &resp_buf,
+							&resp_len, &service_status);
 
 		if (m_client.rpc_status == TS_RPC_CALL_ACCEPTED)
-			fwu_status = opstatus;
+			fwu_status = service_status;
 
-		rpc_caller_end(m_client.caller, call_handle);
+		rpc_caller_session_end(call_handle);
 	}
 
 	return fwu_status;
@@ -273,29 +267,29 @@
 		rpc_call_handle call_handle;
 		uint8_t *req_buf;
 
-		call_handle = rpc_caller_begin(m_client.caller, &req_buf, req_len);
+		call_handle = rpc_caller_session_begin(m_rpc_session, &req_buf, req_len, 0);
 
 		if (call_handle) {
 			uint8_t *resp_buf;
 			size_t resp_len;
-			rpc_opstatus_t opstatus;
+			service_status_t service_status;
 
 			memcpy(req_buf, &req_msg, proto_overhead);
 			memcpy(&req_buf[proto_overhead], &data[total_written], write_len);
 
 			total_written += write_len;
 
-			m_client.rpc_status = rpc_caller_invoke(m_client.caller, call_handle,
+			m_client.rpc_status = rpc_caller_session_invoke(call_handle,
 								TS_FWU_OPCODE_WRITE_STREAM,
-								&opstatus, &resp_buf, &resp_len);
+								&resp_buf, &resp_len, &service_status);
 
-			rpc_caller_end(m_client.caller, call_handle);
+			rpc_caller_session_end(call_handle);
 
 			if (m_client.rpc_status != TS_RPC_CALL_ACCEPTED)
 				return FWU_STATUS_NOT_AVAILABLE;
 
-			if (opstatus != FWU_STATUS_SUCCESS)
-				return (int)opstatus;
+			if (service_status != FWU_STATUS_SUCCESS)
+				return (int)service_status;
 
 		} else
 			return FWU_STATUS_NOT_AVAILABLE;
@@ -322,23 +316,24 @@
 	rpc_call_handle call_handle;
 	uint8_t *req_buf;
 
-	call_handle = rpc_caller_begin(m_client.caller, &req_buf, req_len);
+	call_handle = rpc_caller_session_begin(m_rpc_session, &req_buf, req_len,
+					       sizeof(struct ts_fwu_read_stream_out) + buf_size);
 
 	if (call_handle) {
 		uint8_t *resp_buf;
 		size_t resp_len;
-		rpc_opstatus_t opstatus;
+		service_status_t service_status;
 
 		memcpy(req_buf, &req_msg, req_len);
 
-		m_client.rpc_status = rpc_caller_invoke(m_client.caller, call_handle,
-							TS_FWU_OPCODE_READ_STREAM, &opstatus,
-							&resp_buf, &resp_len);
+		m_client.rpc_status = rpc_caller_session_invoke(call_handle,
+							TS_FWU_OPCODE_READ_STREAM,
+							&resp_buf, &resp_len, &service_status);
 
 		size_t proto_overhead = offsetof(ts_fwu_read_stream_out, payload);
 
 		if (m_client.rpc_status == TS_RPC_CALL_ACCEPTED) {
-			fwu_status = opstatus;
+			fwu_status = service_status;
 
 			if ((fwu_status == FWU_STATUS_SUCCESS) && (resp_len >= proto_overhead)) {
 				const struct ts_fwu_read_stream_out *resp_msg =
@@ -357,7 +352,7 @@
 			}
 		}
 
-		rpc_caller_end(m_client.caller, call_handle);
+		rpc_caller_session_end(call_handle);
 	}
 
 	return fwu_status;
diff --git a/components/service/fwu/test/fwu_client/remote/remote_fwu_client.h b/components/service/fwu/test/fwu_client/remote/remote_fwu_client.h
index c9a440e..ce0511c 100644
--- a/components/service/fwu/test/fwu_client/remote/remote_fwu_client.h
+++ b/components/service/fwu/test/fwu_client/remote/remote_fwu_client.h
@@ -46,7 +46,7 @@
 	void close_session(void);
 
 	struct service_client m_client;
-	rpc_session_handle m_rpc_session_handle;
+	struct rpc_caller_session *m_rpc_session;
 	struct service_context *m_service_context;
 };
 
diff --git a/components/service/fwu/test/fwu_dut/sim/sim_fwu_dut.cpp b/components/service/fwu/test/fwu_dut/sim/sim_fwu_dut.cpp
index 260cb65..5415cc7 100644
--- a/components/service/fwu/test/fwu_dut/sim/sim_fwu_dut.cpp
+++ b/components/service/fwu/test/fwu_dut/sim/sim_fwu_dut.cpp
@@ -14,8 +14,6 @@
 #include "common/endian/le.h"
 #include "media/disk/guid.h"
 #include "media/volume/index/volume_index.h"
-#include "service/discovery/provider/discovery_provider.h"
-#include "service/discovery/provider/serializer/packed-c/packedc_discovery_provider_serializer.h"
 #include "service/fwu/fw_store/banked/metadata_serializer/v1/metadata_serializer_v1.h"
 #include "service/fwu/fw_store/banked/metadata_serializer/v2/metadata_serializer_v2.h"
 #include "service/fwu/fw_store/banked/volume_id.h"
@@ -70,10 +68,6 @@
 	fwu_provider_register_serializer(&m_fwu_provider, TS_RPC_ENCODING_PACKED_C,
 					 packedc_fwu_provider_serializer_instance());
 
-	discovery_provider_register_serializer(&m_fwu_provider.discovery_provider,
-					       TS_RPC_ENCODING_PACKED_C,
-					       packedc_discovery_provider_serializer_instance());
-
 	m_metadata_checker = create_metadata_checker();
 }
 
@@ -146,7 +140,7 @@
 	m_is_booted = false;
 }
 
-struct rpc_interface *sim_fwu_dut::get_service_interface(void)
+struct rpc_service_interface *sim_fwu_dut::get_service_interface(void)
 {
 	return m_service_iface;
 }
diff --git a/components/service/fwu/test/fwu_dut/sim/sim_fwu_dut.h b/components/service/fwu/test/fwu_dut/sim/sim_fwu_dut.h
index aa6e75b..f10d2c5 100644
--- a/components/service/fwu/test/fwu_dut/sim/sim_fwu_dut.h
+++ b/components/service/fwu/test/fwu_dut/sim/sim_fwu_dut.h
@@ -55,7 +55,7 @@
 	metadata_checker *create_metadata_checker(bool is_primary = true) const;
 	fwu_client *create_fwu_client(void);
 
-	struct rpc_interface *get_service_interface(void);
+	struct rpc_service_interface *get_service_interface(void);
 
 private:
 	/* Maximum locations supported */
@@ -100,7 +100,7 @@
 	struct boot_info m_boot_info;
 	metadata_checker *m_metadata_checker;
 	unsigned int m_num_locations;
-	struct rpc_interface *m_service_iface;
+	struct rpc_service_interface *m_service_iface;
 
 	/* Firmware storage */
 	struct ram_block_store m_fw_flash;
diff --git a/components/service/locator/interface/service_locator.h b/components/service/locator/interface/service_locator.h
index 1fba453..87f1f0d 100644
--- a/components/service/locator/interface/service_locator.h
+++ b/components/service/locator/interface/service_locator.h
@@ -7,7 +7,7 @@
 #ifndef SERVICE_LOCATOR_H
 #define SERVICE_LOCATOR_H
 
-#include <rpc_caller.h>
+#include "components/rpc/common/caller/rpc_caller_session.h"
 
 /*
  * The service_locator puplic interface may be exported as a public interface to
@@ -32,7 +32,6 @@
  * client code may be reused accross different service deployment scenarios.
  */
 struct service_location_strategy;
-typedef void* rpc_session_handle;
 
 /*
  * Initialises the singleton service locator.  Must be called once
@@ -64,7 +63,7 @@
  * the client should call the relinquish method.  Returns NULL
  * if no service is located that corresponds to the service name.
  */
-SERVICE_LOCATOR_EXPORTED struct service_context *service_locator_query(const char *sn, int *status);
+SERVICE_LOCATOR_EXPORTED struct service_context *service_locator_query(const char *sn);
 
 /*
  * The service_context struct represents a service instance to a client
@@ -74,11 +73,11 @@
  */
 struct service_context
 {
-    void *context;
+	void *context;
 
-    rpc_session_handle (*open)(void *context, struct rpc_caller **caller);
-    void (*close)(void *context, rpc_session_handle session_handle);
-    void (*relinquish)(void *context);
+	struct rpc_caller_session *(*open)(void *context);
+	void (*close)(void *context, struct rpc_caller_session *session);
+	void (*relinquish)(void *context);
 };
 
 /*
@@ -88,7 +87,7 @@
  */
 struct service_location_strategy
 {
-    struct service_context *(*query)(const char *sn, int *status);
+	struct service_context *(*query)(const char *sn);
 };
 
 /*
@@ -96,12 +95,12 @@
  * service_context.  The parameter encoding scheme that the client
  * intends to use for serializing RPC parameters must be specified.
  */
-SERVICE_LOCATOR_EXPORTED rpc_session_handle service_context_open(struct service_context *s, uint32_t encoding, struct rpc_caller **caller);
+SERVICE_LOCATOR_EXPORTED struct rpc_caller_session *service_context_open(struct service_context *s);
 
 /*
  * Close an RPC session.
  */
-SERVICE_LOCATOR_EXPORTED void service_context_close(struct service_context *s, rpc_session_handle session_handle);
+SERVICE_LOCATOR_EXPORTED void service_context_close(struct service_context *s, struct rpc_caller_session *session_handle);
 
 /*
  * Called by a client when it has finished using a service context.
diff --git a/components/service/locator/linux/ffa/linuxffa_location_strategy.c b/components/service/locator/linux/ffa/linuxffa_location_strategy.c
index 330449b..d49c077 100644
--- a/components/service/locator/linux/ffa/linuxffa_location_strategy.c
+++ b/components/service/locator/linux/ffa/linuxffa_location_strategy.c
@@ -6,204 +6,74 @@
 
 #include "linuxffa_location_strategy.h"
 #include "linuxffa_service_context.h"
-#include <common/uuid/uuid.h>
-#include <service/locator/service_name.h>
-#include <rpc/ffarpc/caller/linux/ffarpc_caller.h>
-#include <deployments/se-proxy/se_proxy_interfaces.h>
+#include "common/uuid/uuid.h"
+#include "service/locator/service_name.h"
+#include "components/service/attestation/provider/attestation_uuid.h"
+#include "components/service/block_storage/provider/block_storage_uuid.h"
+#include "components/service/crypto/provider/crypto_uuid.h"
+#include "components/service/fwu/provider/fwu_uuid.h"
+#include "components/service/secure_storage/frontend/secure_storage_provider/secure_storage_uuid.h"
+#include "components/service/test_runner/provider/test_runner_uuid.h"
 #include <stddef.h>
 #include <string.h>
 #include <stdbool.h>
 #include <stdint.h>
 
-/*
- * There is the potential for there to be alternative deployment possibilities
- * for a service instance.  This will depend on deployment decisions such as
- * running one service instance per SP, or multiple services per SP.  The FFA
- * location strategy accommodates this by allowing for more than one suggestion
- * for a service to partition mapping.
- */
-#define MAX_PARTITION_SUGGESTIONS           (4)
 
-/*
- * The maximum number of partition instances, identified by a particular UUID,
- * that may be discovered.
- */
-#define MAX_PARTITION_INSTANCES             (4)
+static struct service_context *query(const char *sn);
+static const struct rpc_uuid *suggest_ts_service_uuids(const char *sn);
 
-/*
- * Structure to specify the location of a service endpoint reachable via FFA.
- */
-struct ffa_service_location
-{
-	struct uuid_canonical uuid;
-	uint16_t iface_id;
-};
-
-
-static struct service_context *query(const char *sn,
-	int *status);
-static size_t suggest_tf_org_partition_uuids(const char *sn,
-	struct ffa_service_location *candidates, size_t candidate_limit);
-static size_t use_ffa_partition_uuid(const char *sn,
-	struct ffa_service_location *candidates, size_t candidate_limit);
-static bool discover_partition(const char *sn,
-	struct uuid_canonical *uuid, const char *dev_path, uint16_t *partition_id);
-
-const struct service_location_strategy *linuxffa_location_strategy(void)
+const struct service_location_strategy *linux_ts_location_strategy(void)
 {
 	static const struct service_location_strategy strategy = { query };
 	return &strategy;
 }
 
-static struct service_context *query(const char *sn, int *status)
+static struct service_context *query(const char *sn)
 {
-	struct service_context *result = NULL;
-	struct ffa_service_location candidate_locations[MAX_PARTITION_SUGGESTIONS];
-	size_t num_suggestons = 0;
-	size_t suggeston_index;
-	char dev_path[16] = {0};
-
-	if (!ffarpc_caller_check_version())
-		return NULL;
-
-	if (ffarpc_caller_find_dev_path(dev_path, sizeof(dev_path)))
-		return NULL;
+	const struct rpc_uuid *service_uuid = NULL;
 
 	/* Determine one or more candidate partition UUIDs from the specified service name. */
-	if (sn_check_authority(sn, "trustedfirmware.org")) {
-		num_suggestons =
-			suggest_tf_org_partition_uuids(sn, candidate_locations, MAX_PARTITION_SUGGESTIONS);
-	}
-	else if (sn_check_authority(sn, "ffa")) {
-		num_suggestons =
-			use_ffa_partition_uuid(sn, candidate_locations, MAX_PARTITION_SUGGESTIONS);
-	}
+	if (!sn_check_authority(sn, "trustedfirmware.org"))
+		return NULL;
 
-	/* Attempt to discover suitable partitions */
-	for (suggeston_index = 0; suggeston_index < num_suggestons; ++suggeston_index) {
+	service_uuid = suggest_ts_service_uuids(sn);
+	if (!service_uuid)
+		return NULL;
 
-		uint16_t partition_id;
-
-		if (discover_partition(sn, &candidate_locations[suggeston_index].uuid,
-			dev_path, &partition_id)) {
-
-			struct linuxffa_service_context *new_context =
-				linuxffa_service_context_create(dev_path,
-					partition_id, candidate_locations[suggeston_index].iface_id);
-
-			if (new_context) result = &new_context->service_context;
-			break;
-		}
-	}
-
-	return result;
+	return (struct service_context *)linux_ts_service_context_create(service_uuid);
 }
 
 /*
- * Returns a list of partition UUIDs and interface IDs to identify partitions that
- * could potentially host the requested service.  This mapping is based trustedfirmware.org
- * ffa partition UUIDs. There may be multiple UUIDs because of different deployment decisions
- * such as dedicated SP, SP hosting multiple services.
+ * Returns a list of service UUIDs to identify partitions that could potentially host the requested
+ * service.  This mapping is based trustedfirmware.org service UUIDs. There may be multiple UUIDs
+ * because of different deployment decisions such as dedicated SP, SP hosting multiple services.
  */
-static size_t suggest_tf_org_partition_uuids(const char *sn,
-	struct ffa_service_location *candidates, size_t candidate_limit)
+static const struct rpc_uuid *suggest_ts_service_uuids(const char *sn)
 {
-	const struct service_to_uuid
+	static const struct service_to_uuid
 	{
 		const char *service;
-		const char *uuid;
-		uint16_t iface_id;
+		struct rpc_uuid uuid;
 	}
 	partition_lookup[] =
 	{
-		/* Services in dedicated SPs */
-		{"crypto",                      "d9df52d5-16a2-4bb2-9aa4-d26d3b84e8c0", 0},
-		{"internal-trusted-storage",    "dc1eef48-b17a-4ccf-ac8b-dfcff7711b14", 0},
-		{"protected-storage",           "751bf801-3dde-4768-a514-0f10aeed1790", 0},
-		{"test-runner",                 "33c75baf-ac6a-4fe4-8ac7-e9909bee2d17", 0},
-		{"attestation",                 "a1baf155-8876-4695-8f7c-54955e8db974", 0},
-		{"block-storage",               "63646e80-eb52-462f-ac4f-8cdf3987519c", 0},
-		{"fwu",                         "6823a838-1b06-470e-9774-0cce8bfb53fd", 0},
-
-		/* Secure Enclave proxy accessed services */
-		{"crypto",                      "46bb39d1-b4d9-45b5-88ff-040027dab249", SE_PROXY_INTERFACE_ID_CRYPTO},
-		{"internal-trusted-storage",    "46bb39d1-b4d9-45b5-88ff-040027dab249", SE_PROXY_INTERFACE_ID_ITS},
-		{"protected-storage",           "46bb39d1-b4d9-45b5-88ff-040027dab249", SE_PROXY_INTERFACE_ID_PS},
-		{"attestation",                 "46bb39d1-b4d9-45b5-88ff-040027dab249", SE_PROXY_INTERFACE_ID_ATTEST},
-		{NULL,                          NULL,                                   0}
+		{"crypto-protobuf",             {.uuid = TS_PSA_CRYPTO_PROTOBUF_SERVICE_UUID}},
+		{"crypto",                      {.uuid = TS_PSA_CRYPTO_SERVICE_UUID}},
+		{"internal-trusted-storage",    {.uuid = TS_PSA_INTERNAL_TRUSTED_STORAGE_UUID}},
+		{"protected-storage",           {.uuid = TS_PSA_PROTECTED_STORAGE_UUID}},
+		{"test-runner",                 {.uuid = TS_TEST_RUNNER_SERVICE_UUID}},
+		{"attestation",                 {.uuid = TS_PSA_ATTESTATION_SERVICE_UUID}},
+		{"block-storage",               {.uuid = TS_BLOCK_STORAGE_SERVICE_UUID}},
+		{"fwu",                         {.uuid = TS_FWU_SERVICE_UUID}},
+		{NULL,                          {.uuid = {0}}}
 	};
 
-	const struct service_to_uuid *entry = &partition_lookup[0];
-	size_t num_suggestions = 0;
+	const struct service_to_uuid *entry = NULL;
 
-	while (entry->service && (num_suggestions < candidate_limit)) {
+	for (entry = &partition_lookup[0]; entry->service != NULL; entry++)
+		if (sn_check_service(sn, entry->service))
+			return &entry->uuid;
 
-		if (sn_check_service(sn, entry->service)) {
-
-			memcpy(candidates[num_suggestions].uuid.characters, entry->uuid,
-				UUID_CANONICAL_FORM_LEN + 1);
-
-			candidates[num_suggestions].iface_id = entry->iface_id;
-
-			++num_suggestions;
-		}
-
-		++entry;
-	}
-
-	return num_suggestions;
-}
-
-/*
- * When an ffa service name where the service field is an explicit UUID is used, the UUID
- * is used directly for partition discovery.
- */
-static size_t use_ffa_partition_uuid(const char *sn,
-	struct ffa_service_location *candidates, size_t candidate_limit)
-{
-	size_t num_suggestions = 0;
-
-	if ((num_suggestions < candidate_limit) &&
-		(sn_read_service(sn, candidates[num_suggestions].uuid.characters,
-			UUID_CANONICAL_FORM_LEN + 1) == UUID_CANONICAL_FORM_LEN)) {
-
-		candidates[num_suggestions].iface_id = 0;
-
-		++num_suggestions;
-	}
-
-	return num_suggestions;
-}
-
-/*
- * Attempt to discover the partition that hosts the requested service instance.
- */
-static bool discover_partition(const char *sn,
-	struct uuid_canonical *uuid, const char *dev_path, uint16_t *partition_id)
-{
-	bool discovered = false;
-
-	if (uuid_is_valid(uuid->characters) == UUID_CANONICAL_FORM_LEN) {
-
-		struct ffarpc_caller ffarpc_caller;
-		unsigned int required_instance = sn_get_service_instance(sn);
-
-		ffarpc_caller_init(&ffarpc_caller, dev_path);
-
-		uint16_t discovered_partitions[MAX_PARTITION_INSTANCES];
-		size_t discovered_count;
-
-		discovered_count = ffarpc_caller_discover(&ffarpc_caller, uuid,
-										discovered_partitions, MAX_PARTITION_INSTANCES);
-
-		if ((discovered_count > 0) && (required_instance < discovered_count)) {
-
-			*partition_id = discovered_partitions[required_instance];
-			discovered = true;
-		}
-
-		ffarpc_caller_deinit(&ffarpc_caller);
-	}
-
-	return discovered;
+	return NULL;
 }
diff --git a/components/service/locator/linux/ffa/linuxffa_location_strategy.h b/components/service/locator/linux/ffa/linuxffa_location_strategy.h
index 6bb7eeb..da8260c 100644
--- a/components/service/locator/linux/ffa/linuxffa_location_strategy.h
+++ b/components/service/locator/linux/ffa/linuxffa_location_strategy.h
@@ -7,7 +7,7 @@
 #ifndef LINUXFFA_LOCATION_STRATEGY_H
 #define LINUXFFA_LOCATION_STRATEGY_H
 
-#include <service_locator.h>
+#include "service_locator.h"
 
 #ifdef __cplusplus
 extern "C" {
@@ -15,10 +15,10 @@
 
 /*
  * Returns a service_location_strategy for locating a service instance
- * hosted in a secure partition, accessed using FFA from Linux userspace.
- * Relies on an FFA Linux kernel driver.
+ * hosted in a secure partition, accessed using TS RPC from Linux userspace.
+ * Relies on an TS Linux kernel driver.
  */
-const struct service_location_strategy *linuxffa_location_strategy(void);
+const struct service_location_strategy *linux_ts_location_strategy(void);
 
 #ifdef __cplusplus
 }
diff --git a/components/service/locator/linux/ffa/linuxffa_service_context.c b/components/service/locator/linux/ffa/linuxffa_service_context.c
index 7548095..ad6ebc2 100644
--- a/components/service/locator/linux/ffa/linuxffa_service_context.c
+++ b/components/service/locator/linux/ffa/linuxffa_service_context.c
@@ -5,87 +5,94 @@
  */
 
 #include "linuxffa_service_context.h"
-#include <rpc/ffarpc/caller/linux/ffarpc_caller.h>
+#include "components/rpc/ts_rpc/caller/linux/ts_rpc_caller_linux.h"
 #include <stdlib.h>
 #include <string.h>
 
+struct linux_ts_service_context
+{
+    struct service_context service_context;
+    struct rpc_caller_interface caller;
+    struct rpc_uuid service_uuid;
+};
+
 /* Concrete service_context methods */
-static rpc_session_handle linuxffa_service_context_open(void *context, struct rpc_caller **caller);
-static void linuxffa_service_context_close(void *context, rpc_session_handle session_handle);
-static void linuxffa_service_context_relinquish(void *context);
+static struct rpc_caller_session *linux_ts_service_context_open(void *context);
+static void linux_ts_service_context_close(void *context, struct rpc_caller_session *session);
+static void linux_ts_service_context_relinquish(void *context);
 
 
-struct linuxffa_service_context *linuxffa_service_context_create(const char *dev_path,
-    uint16_t partition_id, uint16_t iface_id)
+struct linux_ts_service_context *linux_ts_service_context_create(const struct rpc_uuid *service_uuid)
+
 {
-    struct linuxffa_service_context *new_context =
-        (struct linuxffa_service_context*)malloc(sizeof(struct linuxffa_service_context));
+	struct linux_ts_service_context *new_context = NULL;
+	rpc_status_t rpc_status = RPC_ERROR_INTERNAL;
 
-    if (new_context) {
-        new_context->ffa_dev_path = strdup(dev_path);
-        if (!new_context->ffa_dev_path) {
-            free(new_context);
-            return NULL;
-        }
+	if (!service_uuid)
+		return NULL;
 
-        new_context->partition_id = partition_id;
-        new_context->iface_id = iface_id;
+	new_context = (struct linux_ts_service_context *)
+		calloc(1, sizeof(struct linux_ts_service_context));
+	if (!new_context)
+		return NULL;
 
-        new_context->service_context.context = new_context;
-        new_context->service_context.open = linuxffa_service_context_open;
-        new_context->service_context.close = linuxffa_service_context_close;
-        new_context->service_context.relinquish = linuxffa_service_context_relinquish;
-    }
+	rpc_status = ts_rpc_caller_linux_init(&new_context->caller);
+	if (rpc_status != RPC_SUCCESS) {
+		free(new_context);
+		return NULL;
+	}
 
-    return new_context;
+	memcpy(&new_context->service_uuid, service_uuid, sizeof(new_context->service_uuid));
+
+	new_context->service_context.context = new_context;
+	new_context->service_context.open = linux_ts_service_context_open;
+	new_context->service_context.close = linux_ts_service_context_close;
+	new_context->service_context.relinquish = linux_ts_service_context_relinquish;
+
+	return new_context;
 }
 
-static rpc_session_handle linuxffa_service_context_open(void *context, struct rpc_caller **caller)
+static struct rpc_caller_session *linux_ts_service_context_open(void *context)
 {
-    struct linuxffa_service_context *this_context = (struct linuxffa_service_context*)context;
-    rpc_session_handle session_handle = NULL;
-    struct ffarpc_caller *ffarpc_caller =
-        (struct ffarpc_caller*)malloc(sizeof(struct ffarpc_caller));
+	struct linux_ts_service_context *this_context = (struct linux_ts_service_context *)context;
+	struct rpc_caller_session *session = NULL;
+	rpc_status_t rpc_status = RPC_ERROR_INTERNAL;
 
-    if (ffarpc_caller) {
+	if (!context)
+		return NULL;
 
-        int status;
-        *caller = ffarpc_caller_init(ffarpc_caller, this_context->ffa_dev_path);
-        status = ffarpc_caller_open(ffarpc_caller,
-            this_context->partition_id, this_context->iface_id);
+	session = (struct rpc_caller_session *)calloc(1, sizeof(struct rpc_caller_session));
+	if (!session)
+		return NULL;
 
-		if (status == 0) {
-            /* Successfully opened session */
-            session_handle = ffarpc_caller;
-		}
-		else {
-            /* Failed to open session */
-			ffarpc_caller_close(ffarpc_caller);
-            ffarpc_caller_deinit(ffarpc_caller);
-            free(ffarpc_caller);
-		}
-    }
+	rpc_status = rpc_caller_session_find_and_open(session, &this_context->caller,
+						      &this_context->service_uuid, 8192);
+	if (rpc_status != RPC_SUCCESS) {
+		free(session);
+		return NULL;
+	}
 
-    return session_handle;
+	return session;
 }
 
-static void linuxffa_service_context_close(void *context, rpc_session_handle session_handle)
+static void linux_ts_service_context_close(void *context, struct rpc_caller_session *session)
 {
-    struct ffarpc_caller *ffarpc_caller = (struct ffarpc_caller*)session_handle;
+	(void)context;
 
-    (void)context;
+	if (!session)
+		return;
 
-    if (ffarpc_caller) {
-
-		ffarpc_caller_close(ffarpc_caller);
-        ffarpc_caller_deinit(ffarpc_caller);
-        free(ffarpc_caller);
-    }
+	rpc_caller_session_close(session);
+	free(session);
 }
 
-static void linuxffa_service_context_relinquish(void *context)
+static void linux_ts_service_context_relinquish(void *context)
 {
-    struct linuxffa_service_context *this_context = (struct linuxffa_service_context*)context;
-    free(this_context->ffa_dev_path);
-    free(this_context);
-}
+	struct linux_ts_service_context *this_context = (struct linux_ts_service_context *)context;
+
+	if (!context)
+		return;
+
+	ts_rpc_caller_linux_deinit(&this_context->caller);
+	free(context);
+}
\ No newline at end of file
diff --git a/components/service/locator/linux/ffa/linuxffa_service_context.h b/components/service/locator/linux/ffa/linuxffa_service_context.h
index 2f6fc26..196f534 100644
--- a/components/service/locator/linux/ffa/linuxffa_service_context.h
+++ b/components/service/locator/linux/ffa/linuxffa_service_context.h
@@ -7,7 +7,7 @@
 #ifndef LINUXFFA_SERVICE_CONTEXT_H
 #define LINUXFFA_SERVICE_CONTEXT_H
 
-#include <service_locator.h>
+#include "service_locator.h"
 
 #ifdef __cplusplus
 extern "C" {
@@ -18,20 +18,13 @@
  * a partition, accessed via FFA.  This service_context is suitable
  * for use by client applications running in Linux userspace.
  */
-struct linuxffa_service_context
-{
-    struct service_context service_context;
-    char *ffa_dev_path;
-    uint16_t partition_id;
-    uint16_t iface_id;
-};
+struct linux_ts_service_context;
 
 /*
- * Factory method to create a service context associated with theh specified
- * partition id and RPC interface instance.
+ * Factory method to create a service context associated with the specified
+ * service UUID.
  */
-struct linuxffa_service_context *linuxffa_service_context_create(const char *dev_path,
-    uint16_t partition_id, uint16_t iface_id);
+struct linux_ts_service_context *linux_ts_service_context_create(const struct rpc_uuid *service_uuid);
 
 #ifdef __cplusplus
 }
diff --git a/components/service/locator/linux/linux_env.c b/components/service/locator/linux/linux_env.c
index 4bef301..2d920c6 100644
--- a/components/service/locator/linux/linux_env.c
+++ b/components/service/locator/linux/linux_env.c
@@ -14,6 +14,6 @@
 	 * Register all service location strategies that could be used
 	 * to locate services from Linux userspace.
 	 */
-	service_locator_register_strategy(linuxffa_location_strategy());
+	service_locator_register_strategy(linux_ts_location_strategy());
 	service_locator_register_strategy(mm_communicate_location_strategy());
 }
diff --git a/components/service/locator/linux/mm_communicate/mm_communicate_location_strategy.c b/components/service/locator/linux/mm_communicate/mm_communicate_location_strategy.c
index b9f6a21..4c22756 100644
--- a/components/service/locator/linux/mm_communicate/mm_communicate_location_strategy.c
+++ b/components/service/locator/linux/mm_communicate/mm_communicate_location_strategy.c
@@ -12,8 +12,6 @@
 #include <rpc/mm_communicate/caller/linux/mm_communicate_caller.h>
 #include <protocols/service/smm_variable/smm_variable_proto.h>
 
-#define MAX_PARTITION_INSTANCES		(1)
-
 /* Structure to define the location of an smm service */
 struct smm_service_location
 {
@@ -36,7 +34,7 @@
 	{
 		{
 			.service = "smm-variable",
-			.uuid = "ed32d533-99e6-4209-9cc0-2d72cdd998a7",
+			.uuid = SMM_VARIABLE_CANONICAL_GUID,
 			.svc_guid = SMM_VARIABLE_GUID
 		},
 		{
@@ -69,62 +67,27 @@
 	return found;
 }
 
-bool discover_partition(const char *dev_path, struct smm_service_location *location)
+static struct service_context *query(const char *sn)
 {
-	bool discovered = false;
+	struct smm_service_location location = { 0 };
+	struct mm_communicate_service_context *new_context = NULL;
+	static const char *dev_path = "/sys/kernel/debug/arm_ffa_user";
 
-	if (uuid_is_valid(location->uuid.characters) == UUID_CANONICAL_FORM_LEN) {
 
-		struct mm_communicate_caller mm_communicate_caller;
+	if (!sn_check_authority(sn, "trustedfirmware.org"))
+		return NULL;
 
-		if (!mm_communicate_caller_check_version())
-			return false;
+	if (!find_candidate_location(sn, &location))
+		return NULL;
 
-		mm_communicate_caller_init(&mm_communicate_caller, dev_path);
+	new_context = mm_communicate_service_context_create(
+			dev_path,
+			location.partition_id,
+			&location.svc_guid);
+	if (!new_context)
+		return NULL;
 
-		uint16_t discovered_partitions[MAX_PARTITION_INSTANCES];
-		size_t discovered_count;
-
-		discovered_count = mm_communicate_caller_discover(
-			&mm_communicate_caller,
-			&location->uuid,
-			discovered_partitions,
-			MAX_PARTITION_INSTANCES);
-
-		if (discovered_count > 0) {
-
-			location->partition_id = discovered_partitions[0];
-			discovered = true;
-		}
-
-		mm_communicate_caller_deinit(&mm_communicate_caller);
-	}
-
-	return discovered;
-}
-
-static struct service_context *query(const char *sn, int *status)
-{
-	struct service_context *result = NULL;
-
-	if (!sn_check_authority(sn, "trustedfirmware.org")) return NULL;
-
-	struct smm_service_location location;
-	const char *dev_path = "/sys/kernel/debug/arm_ffa_user";
-
-	if (find_candidate_location(sn, &location) &&
-		discover_partition(dev_path, &location)) {
-
-		struct mm_communicate_service_context *new_context =
-			mm_communicate_service_context_create(
-				dev_path,
-				location.partition_id,
-				&location.svc_guid);
-
-		if (new_context) result = &new_context->service_context;
-	}
-
-	return result;
+	return &new_context->service_context;
 }
 
 const struct service_location_strategy *mm_communicate_location_strategy(void)
diff --git a/components/service/locator/linux/mm_communicate/mm_communicate_service_context.c b/components/service/locator/linux/mm_communicate/mm_communicate_service_context.c
index 358210f..5573795 100644
--- a/components/service/locator/linux/mm_communicate/mm_communicate_service_context.c
+++ b/components/service/locator/linux/mm_communicate/mm_communicate_service_context.c
@@ -4,100 +4,93 @@
  * SPDX-License-Identifier: BSD-3-Clause
  */
 
-#include <stdlib.h>
 #include <rpc/mm_communicate/caller/linux/mm_communicate_caller.h>
 #include "mm_communicate_service_context.h"
+#include <stdlib.h>
+#include <string.h>
 
 /* Concrete service_context methods */
-static rpc_session_handle mm_communicate_service_context_open(void *context,
-	struct rpc_caller **caller);
+static struct rpc_caller_session *mm_communicate_service_context_open(void *context);
 static void mm_communicate_service_context_close(void *context,
-	rpc_session_handle session_handle);
+	struct rpc_caller_session *session_handle);
 static void mm_communicate_service_context_relinquish(void *context);
 
+static void efi_guid_to_rpc_uuid(const EFI_GUID *guid, struct rpc_uuid *uuid)
+{
+	uuid->uuid[0] = (guid->Data1 >> 24) & 0xff;
+	uuid->uuid[1] = (guid->Data1 >> 16) & 0xff;
+	uuid->uuid[2] = (guid->Data1 >> 8) & 0xff;
+	uuid->uuid[3] = guid->Data1 & 0xff;
+	uuid->uuid[4] = (guid->Data2 >> 8) & 0xff;
+	uuid->uuid[5] = guid->Data2 & 0xff;
+	uuid->uuid[6] = (guid->Data3 >> 8) & 0xff;
+	uuid->uuid[7] = guid->Data3 & 0xff;
+	memcpy(&uuid->uuid[8], guid->Data4, sizeof(guid->Data4));
+}
 
 struct mm_communicate_service_context *mm_communicate_service_context_create(
 	const char *dev_path,
 	uint16_t partition_id,
 	const EFI_GUID *svc_guid)
 {
-	struct mm_communicate_service_context *new_context = (struct mm_communicate_service_context*)
-		malloc(sizeof(struct mm_communicate_service_context));
+	struct mm_communicate_service_context *new_context =
+		(struct mm_communicate_service_context*)calloc(1, sizeof(struct mm_communicate_service_context));
+	rpc_status_t rpc_status = RPC_ERROR_INTERNAL;
 
-	if (new_context) {
+	if (!new_context)
+		return NULL;
 
-		new_context->ffa_dev_path = dev_path;
-		new_context->partition_id = partition_id;
-		new_context->svc_guid = *svc_guid;
-
-		new_context->service_context.context = new_context;
-		new_context->service_context.open = mm_communicate_service_context_open;
-		new_context->service_context.close = mm_communicate_service_context_close;
-		new_context->service_context.relinquish = mm_communicate_service_context_relinquish;
+	rpc_status = mm_communicate_caller_init(&new_context->caller, dev_path);
+	if (rpc_status != RPC_SUCCESS) {
+		free(new_context);
+		return NULL;
 	}
 
+	new_context->partition_id = partition_id;
+	new_context->svc_guid = *svc_guid;
+
+	new_context->service_context.context = new_context;
+	new_context->service_context.open = mm_communicate_service_context_open;
+	new_context->service_context.close = mm_communicate_service_context_close;
+	new_context->service_context.relinquish = mm_communicate_service_context_relinquish;
+
 	return new_context;
 }
 
-static rpc_session_handle mm_communicate_service_context_open(
-	void *context,
-	struct rpc_caller **caller)
+static struct rpc_caller_session *mm_communicate_service_context_open(void *context)
 {
 	struct mm_communicate_service_context *this_context =
 		(struct mm_communicate_service_context*)context;
+	struct rpc_caller_session *session = (struct rpc_caller_session *)calloc(1, sizeof(struct rpc_caller_session));
+	rpc_status_t rpc_status = RPC_ERROR_INTERNAL;
+	struct rpc_uuid service_uuid = { 0 };
 
-	rpc_session_handle session_handle = NULL;
-
-	if (!mm_communicate_caller_check_version())
+	if (!session)
 		return NULL;
 
-	struct mm_communicate_caller *mm_communicate_caller =
-		(struct mm_communicate_caller*)malloc(sizeof(struct mm_communicate_caller));
+	efi_guid_to_rpc_uuid(&this_context->svc_guid, &service_uuid);
 
-	if (mm_communicate_caller) {
-
-		*caller = mm_communicate_caller_init(mm_communicate_caller,
-			this_context->ffa_dev_path);
-		int status = mm_communicate_caller_open(mm_communicate_caller,
-			this_context->partition_id, &this_context->svc_guid);
-
-		if (status == 0) {
-			/* Successfully opened session */
-			session_handle = mm_communicate_caller;
-		}
-		else {
-			/* Failed to open session */
-			mm_communicate_caller_close(mm_communicate_caller);
-			mm_communicate_caller_deinit(mm_communicate_caller);
-			free(mm_communicate_caller);
-		}
+	/* The memory size is set to 0 because carveout configuration controls this. */
+	rpc_status = rpc_caller_session_find_and_open(session, &this_context->caller,
+						      &service_uuid, 0);
+	if (rpc_status != RPC_SUCCESS) {
+		free(session);
+		return NULL;
 	}
 
-	return session_handle;
+	return session;
 }
 
-static void mm_communicate_service_context_close(
-	void *context,
-	rpc_session_handle session_handle)
+static void mm_communicate_service_context_close(void *context, struct rpc_caller_session *session)
 {
-	struct mm_communicate_caller *mm_communicate_caller =
-		(struct mm_communicate_caller*)session_handle;
-
 	(void)context;
 
-	if (mm_communicate_caller) {
-
-		mm_communicate_caller_close(mm_communicate_caller);
-		mm_communicate_caller_deinit(mm_communicate_caller);
-		free(mm_communicate_caller);
-	}
+	rpc_caller_session_close(session);
+	free(session);
 }
 
 static void mm_communicate_service_context_relinquish(
 	void *context)
 {
-	struct mm_communicate_service_context *this_context =
-		(struct mm_communicate_service_context*)context;
-
-	free(this_context);
+	free(context);
 }
diff --git a/components/service/locator/linux/mm_communicate/mm_communicate_service_context.h b/components/service/locator/linux/mm_communicate/mm_communicate_service_context.h
index 6771c31..27535ce 100644
--- a/components/service/locator/linux/mm_communicate/mm_communicate_service_context.h
+++ b/components/service/locator/linux/mm_communicate/mm_communicate_service_context.h
@@ -22,7 +22,7 @@
 struct mm_communicate_service_context
 {
 	struct service_context service_context;
-	const char *ffa_dev_path;
+	struct rpc_caller_interface caller;
 	uint16_t partition_id;
 	EFI_GUID svc_guid;
 };
diff --git a/components/service/locator/service_locator.c b/components/service/locator/service_locator.c
index 6f1f218..d1efc9b 100644
--- a/components/service/locator/service_locator.c
+++ b/components/service/locator/service_locator.c
@@ -4,7 +4,7 @@
  * SPDX-License-Identifier: BSD-3-Clause
  */
 
-#include <service_locator.h>
+#include "service_locator.h"
 #include "service_name.h"
 #include <assert.h>
 #include <stddef.h>
@@ -16,59 +16,56 @@
  */
 static struct service_locator
 {
-    unsigned int num_strategies;
-    const struct service_location_strategy *strategies[SERVICE_LOCATOR_MAX_STATEGIES];
+	unsigned int num_strategies;
+	const struct service_location_strategy *strategies[SERVICE_LOCATOR_MAX_STATEGIES];
 
 } service_locator_instance = { .num_strategies = 0 };
 
 
 void service_locator_init(void)
 {
-    if (service_locator_instance.num_strategies == 0) service_locator_envinit();
+	if (service_locator_instance.num_strategies == 0) service_locator_envinit();
 }
 
 void service_locator_register_strategy(const struct service_location_strategy *strategy)
 {
-    assert(service_locator_instance.num_strategies < SERVICE_LOCATOR_MAX_STATEGIES);
+	assert(service_locator_instance.num_strategies < SERVICE_LOCATOR_MAX_STATEGIES);
 
-    if (service_locator_instance.num_strategies < SERVICE_LOCATOR_MAX_STATEGIES) {
+	if (service_locator_instance.num_strategies < SERVICE_LOCATOR_MAX_STATEGIES) {
 
-        service_locator_instance.strategies[service_locator_instance.num_strategies] = strategy;
-        ++service_locator_instance.num_strategies;
-    }
+		service_locator_instance.strategies[service_locator_instance.num_strategies] = strategy;
+		++service_locator_instance.num_strategies;
+	}
 }
 
-struct service_context *service_locator_query(const char *sn, int *status)
+struct service_context *service_locator_query(const char *sn)
 {
-    struct service_context *located_context = NULL;
-    unsigned int index = 0;
+	struct service_context *located_context = NULL;
+	unsigned int index = 0;
 
-    if (sn_is_valid(sn)) {
+	if (sn_is_valid(sn)) {
 
-        while (!located_context && (index < service_locator_instance.num_strategies)) {
+		while (!located_context && (index < service_locator_instance.num_strategies)) {
 
-            located_context = service_locator_instance.strategies[index]->query(sn, status);
-            ++index;
-        }
-    }
+			located_context = service_locator_instance.strategies[index]->query(sn);
+			++index;
+		}
+	}
 
-    return located_context;
+	return located_context;
 }
 
-rpc_session_handle service_context_open(struct service_context *s, uint32_t encoding, struct rpc_caller **caller)
+struct rpc_caller_session *service_context_open(struct service_context *s)
 {
-    rpc_session_handle handle = s->open(s->context, caller);
-    if (handle) rpc_caller_set_encoding_scheme(*caller, encoding);
-
-    return handle;
+	return s->open(s->context);
 }
 
-void service_context_close(struct service_context *s, rpc_session_handle session_handle)
+void service_context_close(struct service_context *s, struct rpc_caller_session *session)
 {
-    s->close(s->context, session_handle);
+	s->close(s->context, session);
 }
 
 void service_context_relinquish(struct service_context *s)
 {
-    s->relinquish(s->context);
+	s->relinquish(s->context);
 }
diff --git a/components/service/locator/sp/ffa/spffa_location_strategy.c b/components/service/locator/sp/ffa/spffa_location_strategy.c
index a9b1680..df06bfc 100644
--- a/components/service/locator/sp/ffa/spffa_location_strategy.c
+++ b/components/service/locator/sp/ffa/spffa_location_strategy.c
@@ -10,13 +10,12 @@
 #include "sp_discovery.h"
 #include <common/uuid/uuid.h>
 #include <service/locator/service_name.h>
-#include <rpc/ffarpc/caller/sp/ffarpc_caller.h>
+#include "components/rpc/ts_rpc/caller/sp/ts_rpc_caller_sp.h"
 #include <trace.h>
 
-static struct service_context *query(const char *sn, int *status);
-static bool discover_partition(const struct uuid_octets *uuid, uint16_t *partition_id);
+static struct service_context *query(const char *sn);
 
-const struct service_location_strategy *spffa_location_strategy(void)
+const struct service_location_strategy *sp_ts_location_strategy(void)
 {
 	static const struct service_location_strategy strategy = { query };
 	return &strategy;
@@ -27,78 +26,35 @@
  * endpoints reachable via FFA from within a client secure partition where
  * associated service endpoints are explicitly defined by configuration data.
  * The service to locate is specified by a service name that consists of a
- * UUID and an optional instance number.  If pesent, the instance number
+ * UUID and an optional instance number.  If present, the instance number
  * is treated as the destination RPC interface id.  If not specified,
  * an interface id of zero is assumed.
  */
-static struct service_context *query(const char *sn, int *status)
+static struct service_context *query(const char *sn)
 {
-	struct service_context *result = NULL;
+	struct uuid_canonical uuid = { 0 };
+	struct rpc_uuid service_uuid = { 0 };
+	struct sp_ts_service_context *new_context = NULL;
 
 	/* This strategy only locates endpoints reachable via FFA */
-	if (sn_check_authority(sn, "ffa")) {
-
-		struct uuid_canonical uuid;
-
-		if (sn_read_service(sn, uuid.characters, UUID_CANONICAL_FORM_LEN + 1) &&
-			uuid_is_valid(uuid.characters)) {
-
-			uint16_t partition_id;
-			struct uuid_octets uuid_octets;
-
-			uuid_parse_to_octets(uuid.characters, uuid_octets.octets, UUID_OCTETS_LEN);
-
-			if (discover_partition(&uuid_octets, &partition_id)) {
-
-				unsigned int iface_id =
-					sn_get_service_instance(sn);
-
-				struct spffa_service_context *new_context =
-					spffa_service_context_create(partition_id, iface_id);
-
-				if (new_context) {
-
-					result = &new_context->service_context;
-				}
-				else {
-
-					EMSG("locate query: context create failed");
-				}
-			}
-			else {
-
-				EMSG("locate query: partition not discovered");
-			}
-		}
-		else {
-
-			EMSG("locate query: invalid uuid");
-		}
+	if (!sn_check_authority(sn, "ffa")) {
+		EMSG("failed to check authority");
+		return NULL;
 	}
 
-	return result;
-}
-
-static bool discover_partition(const struct uuid_octets *uuid, uint16_t *partition_id)
-{
-	bool discovered = false;
-	struct ffarpc_caller ffarpc_caller;
-	uint16_t discovered_partitions[1];
-	uint16_t own_id = 0;
-
-	if (sp_discovery_own_id_get(&own_id) != SP_RESULT_OK)
-		return false;
-
-	ffarpc_caller_init(&ffarpc_caller, own_id);
-
-	if (ffarpc_caller_discover(uuid->octets, discovered_partitions,
-				   sizeof(discovered_partitions)/sizeof(uint16_t))) {
-
-		*partition_id = discovered_partitions[0];
-		discovered = true;
+	if (!sn_read_service(sn, uuid.characters, sizeof(uuid.characters)) ||
+	    !uuid_is_valid(uuid.characters)) {
+		EMSG("invalid uuid");
+		return NULL;
 	}
 
-	ffarpc_caller_deinit(&ffarpc_caller);
+	uuid_parse_to_octets(uuid.characters, service_uuid.uuid, sizeof(service_uuid.uuid));
 
-	return discovered;
+	new_context = spffa_service_context_create(&service_uuid);
+	if (!new_context) {
+		EMSG("context create failed");
+		return NULL;
+	}
+
+	return &new_context->service_context;
 }
diff --git a/components/service/locator/sp/ffa/spffa_location_strategy.h b/components/service/locator/sp/ffa/spffa_location_strategy.h
index edaf76b..55762c5 100644
--- a/components/service/locator/sp/ffa/spffa_location_strategy.h
+++ b/components/service/locator/sp/ffa/spffa_location_strategy.h
@@ -18,7 +18,7 @@
  * hosted in a secure partition, accessed using FFA from another secure
  * partition.
  */
-const struct service_location_strategy *spffa_location_strategy(void);
+const struct service_location_strategy *sp_ts_location_strategy(void);
 
 #ifdef __cplusplus
 }
diff --git a/components/service/locator/sp/ffa/spffa_service_context.c b/components/service/locator/sp/ffa/spffa_service_context.c
index b3b4370..0c1616f 100644
--- a/components/service/locator/sp/ffa/spffa_service_context.c
+++ b/components/service/locator/sp/ffa/spffa_service_context.c
@@ -5,86 +5,71 @@
  */
 
 #include "spffa_service_context.h"
-#include <rpc/ffarpc/caller/sp/ffarpc_caller.h>
+#include "rpc/ts_rpc/caller/sp/ts_rpc_caller_sp.h"
 #include "sp_discovery.h"
 #include <stdlib.h>
+#include <string.h>
 
 /* Concrete service_context methods */
-static rpc_session_handle spffa_service_context_open(void *context, struct rpc_caller **caller);
-static void spffa_service_context_close(void *context, rpc_session_handle session_handle);
-static void spffa_service_context_relinquish(void *context);
+static struct rpc_caller_session *sp_ts_service_context_open(void *context);
+static void sp_ts_service_context_close(void *context, struct rpc_caller_session *session);
+static void sp_ts_service_context_relinquish(void *context);
 
 
-struct spffa_service_context *spffa_service_context_create(
-	uint16_t partition_id, uint16_t iface_id)
+struct sp_ts_service_context *spffa_service_context_create(const struct rpc_uuid *service_uuid)
 {
-	struct spffa_service_context *new_context =
-		(struct spffa_service_context*)malloc(sizeof(struct spffa_service_context));
+	struct sp_ts_service_context *new_context =
+		(struct sp_ts_service_context*)malloc(sizeof(struct sp_ts_service_context));
+	rpc_status_t rpc_status = RPC_ERROR_INTERNAL;
 
-	if (new_context) {
-		new_context->partition_id = partition_id;
-		new_context->iface_id = iface_id;
+	if (!new_context)
+		return NULL;
 
-		new_context->service_context.context = new_context;
-		new_context->service_context.open = spffa_service_context_open;
-		new_context->service_context.close = spffa_service_context_close;
-		new_context->service_context.relinquish = spffa_service_context_relinquish;
+	rpc_status = ts_rpc_caller_sp_init(&new_context->caller);
+	if (rpc_status != RPC_SUCCESS) {
+		free(new_context);
+		return NULL;
 	}
 
+	memcpy(&new_context->service_uuid, service_uuid, sizeof(new_context->service_uuid));
+
+	new_context->service_context.context = new_context;
+	new_context->service_context.open = sp_ts_service_context_open;
+	new_context->service_context.close = sp_ts_service_context_close;
+	new_context->service_context.relinquish = sp_ts_service_context_relinquish;
+
 	return new_context;
 }
 
-static rpc_session_handle spffa_service_context_open(void *context, struct rpc_caller **caller)
+static struct rpc_caller_session *sp_ts_service_context_open(void *context)
 {
-	struct spffa_service_context *this_context = (struct spffa_service_context*)context;
-	rpc_session_handle session_handle = NULL;
-	struct ffarpc_caller *ffarpc_caller =
-		(struct ffarpc_caller*)malloc(sizeof(struct ffarpc_caller));
+	struct sp_ts_service_context *this_context = (struct sp_ts_service_context *)context;
+	struct rpc_caller_session *session =
+		(struct rpc_caller_session *)calloc(1, sizeof(struct rpc_caller_session));
+	rpc_status_t rpc_status = RPC_ERROR_INTERNAL;
 
-	if (ffarpc_caller) {
-		uint16_t own_id = 0;
+	if (!session)
+		return NULL;
 
-		if (sp_discovery_own_id_get(&own_id) != SP_RESULT_OK)
-			return NULL;
-
-		*caller = ffarpc_caller_init(ffarpc_caller, own_id);
-		if (!*caller)
-			return NULL;
-
-		int status = ffarpc_caller_open(ffarpc_caller,
-			this_context->partition_id, this_context->iface_id);
-
-		if (status == 0) {
-			/* Successfully opened session */
-			session_handle = ffarpc_caller;
-		}
-		else {
-			/* Failed to open session */
-			ffarpc_caller_close(ffarpc_caller);
-			ffarpc_caller_deinit(ffarpc_caller);
-			free(ffarpc_caller);
-		}
+	rpc_status = rpc_caller_session_find_and_open(session, &this_context->caller,
+						      &this_context->service_uuid, 4096);
+	if (rpc_status != RPC_SUCCESS) {
+		free(session);
+		return NULL;
 	}
 
-	return session_handle;
+	return session;
 }
 
-static void spffa_service_context_close(void *context, rpc_session_handle session_handle)
+static void sp_ts_service_context_close(void *context, struct rpc_caller_session *session)
 {
-	struct ffarpc_caller *ffarpc_caller = (struct ffarpc_caller*)session_handle;
-
 	(void)context;
 
-	if (ffarpc_caller) {
-
-		ffarpc_caller_close(ffarpc_caller);
-		ffarpc_caller_deinit(ffarpc_caller);
-		free(ffarpc_caller);
-	}
+	rpc_caller_session_close(session);
+	free(session);
 }
 
-static void spffa_service_context_relinquish(void *context)
+static void sp_ts_service_context_relinquish(void *context)
 {
-	struct spffa_service_context *this_context = (struct spffa_service_context*)context;
-	free(this_context);
+	free(context);
 }
diff --git a/components/service/locator/sp/ffa/spffa_service_context.h b/components/service/locator/sp/ffa/spffa_service_context.h
index 26e6fb9..ff9b2f2 100644
--- a/components/service/locator/sp/ffa/spffa_service_context.h
+++ b/components/service/locator/sp/ffa/spffa_service_context.h
@@ -18,20 +18,18 @@
  * a partition, accessed via FFA.  This service_context is suitable
  * for use by client applications running in a secure partition.
  */
-struct spffa_service_context
+struct sp_ts_service_context
 {
 	struct service_context service_context;
-	uint16_t partition_id;
-	uint16_t iface_id;
+	struct rpc_caller_interface caller;
+	struct rpc_uuid service_uuid;
 };
 
 /*
  * Factory method to create a service context associated with the specified
  * partition id and RPC interface instance.
  */
-struct spffa_service_context *spffa_service_context_create(
-	uint16_t partition_id,
-	uint16_t iface_id);
+struct sp_ts_service_context *spffa_service_context_create(const struct rpc_uuid *service_uuid);
 
 #ifdef __cplusplus
 }
diff --git a/components/service/locator/sp/sp_env.c b/components/service/locator/sp/sp_env.c
index 51507cb..585ab21 100644
--- a/components/service/locator/sp/sp_env.c
+++ b/components/service/locator/sp/sp_env.c
@@ -14,5 +14,5 @@
 	 * Register all service location strategies that could be used
 	 * to locate services from a secure partition.
 	 */
-	service_locator_register_strategy(spffa_location_strategy());
+	service_locator_register_strategy(sp_ts_location_strategy());
 }
diff --git a/components/service/locator/standalone/services/attestation/attestation_service_context.cpp b/components/service/locator/standalone/services/attestation/attestation_service_context.cpp
index df676cd..24778e6 100644
--- a/components/service/locator/standalone/services/attestation/attestation_service_context.cpp
+++ b/components/service/locator/standalone/services/attestation/attestation_service_context.cpp
@@ -88,10 +88,9 @@
 
 	/* Initialize the attestation service provider */
 	local_attest_key_mngr_init(LOCAL_ATTEST_KEY_MNGR_VOLATILE_IAK);
-	struct rpc_interface *attest_ep = attest_provider_init(&m_attest_provider);
+	struct rpc_service_interface *attest_ep = attest_provider_init(&m_attest_provider);
 
-	attest_provider_register_serializer(&m_attest_provider,
-		TS_RPC_ENCODING_PACKED_C, packedc_attest_provider_serializer_instance());
+	attest_provider_register_serializer(&m_attest_provider, packedc_attest_provider_serializer_instance());
 
 	standalone_service_context::set_rpc_interface(attest_ep);
 }
diff --git a/components/service/locator/standalone/services/block-storage/block_storage_service_context.cpp b/components/service/locator/standalone/services/block-storage/block_storage_service_context.cpp
index dc367fa..87f5346 100644
--- a/components/service/locator/standalone/services/block-storage/block_storage_service_context.cpp
+++ b/components/service/locator/standalone/services/block-storage/block_storage_service_context.cpp
@@ -30,15 +30,13 @@
 	assert(m_block_store);
 
 	/* Initialise the block storage service provider */
-	struct rpc_interface *rpc_iface = block_storage_provider_init(
+	struct rpc_service_interface *rpc_iface = block_storage_provider_init(
 		&m_block_storage_provider,
 		m_block_store);
 	assert(rpc_iface);
 
-	block_storage_provider_register_serializer(
-		&m_block_storage_provider,
-		TS_RPC_ENCODING_PACKED_C,
-		packedc_block_storage_serializer_instance());
+	block_storage_provider_register_serializer(&m_block_storage_provider,
+						   packedc_block_storage_serializer_instance());
 
 	standalone_service_context::set_rpc_interface(rpc_iface);
 }
diff --git a/components/service/locator/standalone/services/crypto/crypto_service_context.cpp b/components/service/locator/standalone/services/crypto/crypto_service_context.cpp
index c22bb0b..7840803 100644
--- a/components/service/locator/standalone/services/crypto/crypto_service_context.cpp
+++ b/components/service/locator/standalone/services/crypto/crypto_service_context.cpp
@@ -8,13 +8,14 @@
 #include <service/crypto/factory/crypto_provider_factory.h>
 #include <service/crypto/backend/mbedcrypto/mbedcrypto_backend.h>
 
-crypto_service_context::crypto_service_context(const char *sn) :
+crypto_service_context::crypto_service_context(const char *sn, unsigned int encoding) :
     standalone_service_context(sn),
+    m_encoding(encoding),
     m_crypto_provider(NULL),
     m_storage_client(),
     m_null_store(),
     m_storage_service_context(NULL),
-    m_storage_session_handle(NULL)
+    m_storage_session(NULL)
 {
 
 }
@@ -28,24 +29,21 @@
 {
     struct storage_backend *storage_backend = NULL;
     struct storage_backend *null_storage_backend = null_store_init(&m_null_store);
-    struct rpc_caller *storage_caller = NULL;
-    int status;
 
     /* Locate and open RPC session with internal-trusted-storage service to
      * provide a persistent keystore
      */
     m_storage_service_context =
-        service_locator_query("sn:trustedfirmware.org:internal-trusted-storage:0", &status);
+        service_locator_query("sn:trustedfirmware.org:internal-trusted-storage:0");
 
     if (m_storage_service_context) {
 
-        m_storage_session_handle =
-            service_context_open(m_storage_service_context,
-                TS_RPC_ENCODING_PACKED_C, &storage_caller);
+        m_storage_session =
+            service_context_open(m_storage_service_context);
 
-        if (m_storage_session_handle) {
+        if (m_storage_session) {
 
-            storage_backend = secure_storage_client_init(&m_storage_client, storage_caller);
+            storage_backend = secure_storage_client_init(&m_storage_client, m_storage_session);
         }
     }
 
@@ -58,11 +56,15 @@
     }
 
     /* Initialise the crypto service provider */
-    struct rpc_interface *crypto_iface = NULL;
+    struct rpc_service_interface *crypto_iface = NULL;
 
     if (mbedcrypto_backend_init(storage_backend, 0) == PSA_SUCCESS) {
 
-        m_crypto_provider = crypto_provider_factory_create();
+        if (m_encoding == TS_RPC_ENCODING_PACKED_C)
+            m_crypto_provider = crypto_provider_factory_create();
+        else
+            m_crypto_provider = crypto_protobuf_provider_factory_create();
+
         crypto_iface = service_provider_get_rpc_interface(&m_crypto_provider->base_provider);
     }
 
@@ -71,9 +73,9 @@
 
 void crypto_service_context::do_deinit()
 {
-    if (m_storage_session_handle) {
-        service_context_close(m_storage_service_context, m_storage_session_handle);
-        m_storage_session_handle = NULL;
+    if (m_storage_session) {
+        service_context_close(m_storage_service_context, m_storage_session);
+        m_storage_session = NULL;
     }
 
     if (m_storage_service_context) {
diff --git a/components/service/locator/standalone/services/crypto/crypto_service_context.h b/components/service/locator/standalone/services/crypto/crypto_service_context.h
index 6010a4e..b3be294 100644
--- a/components/service/locator/standalone/services/crypto/crypto_service_context.h
+++ b/components/service/locator/standalone/services/crypto/crypto_service_context.h
@@ -16,7 +16,7 @@
 class crypto_service_context : public standalone_service_context
 {
 public:
-    crypto_service_context(const char *sn);
+    crypto_service_context(const char *sn, unsigned int encoding);
     virtual ~crypto_service_context();
 
 private:
@@ -24,11 +24,12 @@
     void do_init();
     void do_deinit();
 
+    unsigned int m_encoding;
     struct crypto_provider *m_crypto_provider;
     struct secure_storage_client m_storage_client;
     struct null_store m_null_store;
     struct service_context *m_storage_service_context;
-    rpc_session_handle m_storage_session_handle;
+    struct rpc_caller_session *m_storage_session;
 };
 
 #endif /* STANDALONE_CRYPTO_SERVICE_CONTEXT_H */
diff --git a/components/service/locator/standalone/services/fwu/fwu_service_context.cpp b/components/service/locator/standalone/services/fwu/fwu_service_context.cpp
index 2691ba8..2980d2a 100644
--- a/components/service/locator/standalone/services/fwu/fwu_service_context.cpp
+++ b/components/service/locator/standalone/services/fwu/fwu_service_context.cpp
@@ -6,11 +6,10 @@
 
 #include "fwu_service_context.h"
 
-struct rpc_interface *fwu_service_context::m_provider_iface = NULL;
+struct rpc_service_interface *fwu_service_context::m_provider_iface = NULL;
 
 fwu_service_context::fwu_service_context(const char *sn)
 	: standalone_service_context(sn)
-	, m_rpc_demux()
 {
 }
 
@@ -18,37 +17,22 @@
 {
 }
 
-void fwu_service_context::set_provider(struct rpc_interface *iface)
+void fwu_service_context::set_provider(struct rpc_service_interface *iface)
 {
 	m_provider_iface = iface;
 }
 
 void fwu_service_context::do_init()
 {
-	/* For the case where no service interface has been provided,
-	 * use an rpc_demux with nothing attached. This will safely
-	 * return an error if call requests are made to the rpc endpoint.
-	 */
-	struct rpc_interface *rpc_iface = rpc_demux_init(&m_rpc_demux);
-
-	if (m_provider_iface) {
-		/* A service provider is available. This facility allows a test
-		 * case to apply an fwu_provider with a particular configuration
-		 * to suite test goals.
-		 */
-		rpc_iface = m_provider_iface;
-	}
-
-	standalone_service_context::set_rpc_interface(rpc_iface);
+	standalone_service_context::set_rpc_interface(m_provider_iface);
 }
 
 void fwu_service_context::do_deinit()
 {
-	rpc_demux_deinit(&m_rpc_demux);
 	set_provider(NULL);
 }
 
-void fwu_service_context_set_provider(struct rpc_interface *iface)
+void fwu_service_context_set_provider(struct rpc_service_interface *iface)
 {
 	fwu_service_context::set_provider(iface);
 }
\ No newline at end of file
diff --git a/components/service/locator/standalone/services/fwu/fwu_service_context.h b/components/service/locator/standalone/services/fwu/fwu_service_context.h
index 4cb23d2..9a7b9cb 100644
--- a/components/service/locator/standalone/services/fwu/fwu_service_context.h
+++ b/components/service/locator/standalone/services/fwu/fwu_service_context.h
@@ -7,7 +7,6 @@
 #ifndef STANDALONE_FWU_SERVICE_CONTEXT_H
 #define STANDALONE_FWU_SERVICE_CONTEXT_H
 
-#include "rpc/common/demux/rpc_demux.h"
 #include "service/locator/standalone/standalone_service_context.h"
 
 class fwu_service_context : public standalone_service_context {
@@ -15,15 +14,13 @@
 	explicit fwu_service_context(const char *sn);
 	virtual ~fwu_service_context();
 
-	static void set_provider(struct rpc_interface *iface);
+	static void set_provider(struct rpc_service_interface *iface);
 
 private:
 	void do_init();
 	void do_deinit();
 
-	static struct rpc_interface *m_provider_iface;
-
-	struct rpc_demux m_rpc_demux;
+	static struct rpc_service_interface *m_provider_iface;
 };
 
 /*
@@ -35,6 +32,6 @@
 #define FWU_SERVICE_CONTEXT_EXPORTED
 #endif
 
-FWU_SERVICE_CONTEXT_EXPORTED void fwu_service_context_set_provider(struct rpc_interface *iface);
+FWU_SERVICE_CONTEXT_EXPORTED void fwu_service_context_set_provider(struct rpc_service_interface *iface);
 
 #endif /* STANDALONE_FWU_SERVICE_CONTEXT_H */
diff --git a/components/service/locator/standalone/services/internal-trusted-storage/its_service_context.cpp b/components/service/locator/standalone/services/internal-trusted-storage/its_service_context.cpp
index 72cc62e..e2a58dc 100644
--- a/components/service/locator/standalone/services/internal-trusted-storage/its_service_context.cpp
+++ b/components/service/locator/standalone/services/internal-trusted-storage/its_service_context.cpp
@@ -5,6 +5,7 @@
  */
 
 #include "its_service_context.h"
+#include "components/service/secure_storage/frontend/secure_storage_provider/secure_storage_uuid.h"
 
 its_service_context::its_service_context(const char *sn) :
     standalone_service_context(sn),
@@ -21,8 +22,10 @@
 
 void its_service_context::do_init()
 {
+    const rpc_uuid service_uuid = {.uuid = TS_PSA_INTERNAL_TRUSTED_STORAGE_UUID};
     struct storage_backend *storage_backend = mock_store_init(&m_mock_store);
-    struct rpc_interface *storage_ep = secure_storage_provider_init(&m_storage_provider, storage_backend);
+    struct rpc_service_interface *storage_ep =
+        secure_storage_provider_init(&m_storage_provider, storage_backend, &service_uuid);
 
     standalone_service_context::set_rpc_interface(storage_ep);
 }
diff --git a/components/service/locator/standalone/services/protected-storage/ps_service_context.cpp b/components/service/locator/standalone/services/protected-storage/ps_service_context.cpp
index 56e87c8..edad9df 100644
--- a/components/service/locator/standalone/services/protected-storage/ps_service_context.cpp
+++ b/components/service/locator/standalone/services/protected-storage/ps_service_context.cpp
@@ -7,7 +7,9 @@
 #include "ps_service_context.h"
 #include "service/block_storage/factory/client/block_store_factory.h"
 #include "service/secure_storage/backend/secure_flash_store/secure_flash_store.h"
+#include "service/secure_storage/frontend/secure_storage_provider/secure_storage_uuid.h"
 #include "media/disk/guid.h"
+#include <assert.h>
 
 ps_service_context::ps_service_context(const char *sn) :
 	standalone_service_context(sn),
@@ -27,12 +29,13 @@
 {
 	struct uuid_octets guid;
 	const struct sfs_flash_info_t *flash_info = NULL;
+	const struct rpc_uuid service_uuid = {.uuid = TS_PSA_PROTECTED_STORAGE_UUID };
 
 	uuid_guid_octets_from_canonical(&guid,
 		DISK_GUID_UNIQUE_PARTITION_PSA_PS);
 
-	m_block_store = client_block_store_factory_create(
-		"sn:trustedfirmware.org:block-storage:0");
+	m_block_store = client_block_store_factory_create("sn:trustedfirmware.org:block-storage:0");
+	assert(m_block_store != NULL);
 
 	psa_status_t status = sfs_flash_block_store_adapter_init(
 		&m_sfs_flash_adapter,
@@ -43,14 +46,13 @@
 		MAX_NUM_FILES,
 		&flash_info);
 
-	if (status == PSA_SUCCESS) {
+	assert(status == PSA_SUCCESS);
 
-		struct storage_backend *storage_backend = sfs_init(flash_info);
-		struct rpc_interface *storage_ep = secure_storage_provider_init(
-			&m_storage_provider, storage_backend);
+	struct storage_backend *storage_backend = sfs_init(flash_info);
+	struct rpc_service_interface *storage_ep = secure_storage_provider_init(
+			&m_storage_provider, storage_backend, &service_uuid);
 
-		standalone_service_context::set_rpc_interface(storage_ep);
-	}
+	standalone_service_context::set_rpc_interface(storage_ep);
 }
 
 void ps_service_context::do_deinit()
diff --git a/components/service/locator/standalone/services/smm-variable/smm_variable_service_context.cpp b/components/service/locator/standalone/services/smm-variable/smm_variable_service_context.cpp
index 0b28917..ae4698f 100644
--- a/components/service/locator/standalone/services/smm-variable/smm_variable_service_context.cpp
+++ b/components/service/locator/standalone/services/smm-variable/smm_variable_service_context.cpp
@@ -13,7 +13,7 @@
 	m_persistent_store_client(),
 	m_volatile_store(),
 	m_storage_service_context(NULL),
-	m_storage_session_handle(NULL)
+	m_storage_session(NULL)
 {
 
 }
@@ -25,33 +25,29 @@
 
 void smm_variable_service_context::do_init()
 {
-    /* Initialize the persistent storage backend - uses protected storage service */
+	/* Initialize the persistent storage backend - uses protected storage service */
 	struct storage_backend *peristent_backend = NULL;
-    struct rpc_caller *storage_caller = NULL;
-    int status = 0;
 
-    /* Locate and open RPC session with the protected-storage service */
-    m_storage_service_context =
-		service_locator_query("sn:trustedfirmware.org:protected-storage:0", &status);
+	/* Locate and open RPC session with the protected-storage service */
+	m_storage_service_context =
+		service_locator_query("sn:trustedfirmware.org:protected-storage:0");
 
-    if (m_storage_service_context) {
+	if (m_storage_service_context) {
 
-        m_storage_session_handle = service_context_open(
-			m_storage_service_context, TS_RPC_ENCODING_PACKED_C,
-			&storage_caller);
+		m_storage_session = service_context_open(m_storage_service_context);
 
-        if (m_storage_session_handle) {
+		if (m_storage_session) {
 
-            peristent_backend = secure_storage_client_init(
-				&m_persistent_store_client, storage_caller);
-        }
-    }
+			peristent_backend = secure_storage_client_init(
+				&m_persistent_store_client, m_storage_session);
+		}
+	}
 
 	/* Initialize the volatile storage backend */
 	struct storage_backend *volatile_backend  = mock_store_init(&m_volatile_store);
 
 	/* Initialize the smm_variable service provider */
-	struct rpc_interface *service_iface = smm_variable_provider_init(
+	struct rpc_service_interface *service_iface = smm_variable_provider_init(
 		&m_smm_variable_provider,
  		0,		/* owner id */
 		MAX_VARIABLES,
@@ -63,17 +59,17 @@
 
 void smm_variable_service_context::do_deinit()
 {
-    if (m_storage_session_handle) {
-        service_context_close(m_storage_service_context, m_storage_session_handle);
-        m_storage_session_handle = NULL;
-    }
+	if (m_storage_session) {
+		service_context_close(m_storage_service_context, m_storage_session);
+		m_storage_session = NULL;
+	}
 
-    if (m_storage_service_context) {
-        service_context_relinquish(m_storage_service_context);
-        m_storage_service_context = NULL;
-    }
+	if (m_storage_service_context) {
+		service_context_relinquish(m_storage_service_context);
+		m_storage_service_context = NULL;
+	}
 
 	smm_variable_provider_deinit(&m_smm_variable_provider);
-    secure_storage_client_deinit(&m_persistent_store_client);
-    mock_store_deinit(&m_volatile_store);
+	secure_storage_client_deinit(&m_persistent_store_client);
+	mock_store_deinit(&m_volatile_store);
 }
diff --git a/components/service/locator/standalone/services/smm-variable/smm_variable_service_context.h b/components/service/locator/standalone/services/smm-variable/smm_variable_service_context.h
index 011c97a..10c9880 100644
--- a/components/service/locator/standalone/services/smm-variable/smm_variable_service_context.h
+++ b/components/service/locator/standalone/services/smm-variable/smm_variable_service_context.h
@@ -34,7 +34,7 @@
 	struct secure_storage_client m_persistent_store_client;
 	struct mock_store m_volatile_store;
 	struct service_context *m_storage_service_context;
-	rpc_session_handle m_storage_session_handle;
+	struct rpc_caller_session *m_storage_session;
 };
 
 #endif /* STANDALONE_SMM_VARIABLE_SERVICE_CONTEXT_H */
diff --git a/components/service/locator/standalone/services/test-runner/test_runner_service_context.cpp b/components/service/locator/standalone/services/test-runner/test_runner_service_context.cpp
index 103f188..89aa402 100644
--- a/components/service/locator/standalone/services/test-runner/test_runner_service_context.cpp
+++ b/components/service/locator/standalone/services/test-runner/test_runner_service_context.cpp
@@ -21,7 +21,7 @@
 
 void test_runner_service_context::do_init()
 {
-    struct rpc_interface *test_runner_ep = test_runner_provider_init(&m_test_runner_provider);
+    struct rpc_service_interface *test_runner_ep = test_runner_provider_init(&m_test_runner_provider);
 
     test_runner_provider_register_serializer(&m_test_runner_provider,
                     TS_RPC_ENCODING_PACKED_C, packedc_test_runner_provider_serializer_instance());
diff --git a/components/service/locator/standalone/standalone_env.cpp b/components/service/locator/standalone/standalone_env.cpp
index 18b43d8..9ca80d4 100644
--- a/components/service/locator/standalone/standalone_env.cpp
+++ b/components/service/locator/standalone/standalone_env.cpp
@@ -18,9 +18,13 @@
 
 void service_locator_envinit(void)
 {
-	static crypto_service_context crypto_context("sn:trustedfirmware.org:crypto:0");
+	static crypto_service_context crypto_context("sn:trustedfirmware.org:crypto:0", TS_RPC_ENCODING_PACKED_C);
 	standalone_service_registry::instance()->regsiter_service_instance(&crypto_context);
 
+	static crypto_service_context crypto_context_protobuf("sn:trustedfirmware.org:crypto-protobuf:0",
+							      TS_RPC_ENCODING_PROTOBUF);
+	standalone_service_registry::instance()->regsiter_service_instance(&crypto_context_protobuf);
+
 	static its_service_context its_service_context("sn:trustedfirmware.org:internal-trusted-storage:0");
 	standalone_service_registry::instance()->regsiter_service_instance(&its_service_context);
 
diff --git a/components/service/locator/standalone/standalone_location_strategy.cpp b/components/service/locator/standalone/standalone_location_strategy.cpp
index 57e370c..e480453 100644
--- a/components/service/locator/standalone/standalone_location_strategy.cpp
+++ b/components/service/locator/standalone/standalone_location_strategy.cpp
@@ -8,18 +8,15 @@
 #include "standalone_service_registry.h"
 #include "standalone_service_context.h"
 
-static struct service_context *query(const char *sn, int *status)
+static struct service_context *query(const char *sn)
 {
-    struct service_context *result = NULL;
     standalone_service_registry *registry = standalone_service_registry::instance();
-    standalone_service_context *query_result = registry->query(sn, status);
+    standalone_service_context *query_result = registry->query(sn);
 
-    if (query_result) {
+    if (!query_result)
+        return NULL;
 
-        result = query_result->get_service_context();
-    }
-
-    return result;
+    return query_result->get_service_context();
 }
 
 const struct service_location_strategy *standalone_location_strategy(void)
diff --git a/components/service/locator/standalone/standalone_service_context.cpp b/components/service/locator/standalone/standalone_service_context.cpp
index c4fda1e..1810836 100644
--- a/components/service/locator/standalone/standalone_service_context.cpp
+++ b/components/service/locator/standalone/standalone_service_context.cpp
@@ -8,8 +8,8 @@
 #include <cassert>
 
 /* Concrete C service_context methods */
-static rpc_session_handle standalone_service_context_open(void *context, struct rpc_caller **caller);
-static void standalone_service_context_close(void *context, rpc_session_handle session_handle);
+static struct rpc_caller_session *standalone_service_context_open(void *context);
+static void standalone_service_context_close(void *context, rpc_caller_session *session_handle);
 static void standalone_service_context_relinquish(void *context);
 
 
@@ -62,17 +62,46 @@
 	if (!m_ref_count) do_deinit();
 }
 
-rpc_session_handle standalone_service_context::open(struct rpc_caller **caller)
+struct rpc_caller_session *standalone_service_context::open()
 {
-	struct rpc_session *session = new rpc_session(m_rpc_interface, m_rpc_buffer_size_override);
-	*caller = session->m_rpc_caller;
-	return static_cast<rpc_session_handle>(session);
+	rpc_status_t status = RPC_ERROR_INTERNAL;
+	struct rpc_caller_interface *caller = NULL;
+	struct rpc_caller_session *session = NULL;
+
+	caller = (struct rpc_caller_interface *)calloc(1, sizeof(struct rpc_caller_interface));
+	if (!caller)
+		return NULL;
+
+	session = (struct rpc_caller_session *)calloc(1, sizeof(struct rpc_caller_session));
+	if (!session) {
+		free(caller);
+		return NULL;
+	}
+
+	status = direct_caller_init(caller, m_rpc_interface);
+	if (status != RPC_SUCCESS) {
+		free(caller);
+		free(session);
+		return NULL;
+	}
+
+	status = rpc_caller_session_open(session, caller, &m_rpc_interface->uuid, 0, 0x8000);
+	if (status != RPC_SUCCESS) {
+		direct_caller_deinit(caller);
+		free(caller);
+		free(session);
+		return NULL;
+	}
+
+	return session;
 }
 
-void standalone_service_context::close(rpc_session_handle session_handle)
+void standalone_service_context::close(rpc_caller_session *session)
 {
-	struct rpc_session *session = reinterpret_cast<struct rpc_session*>(session_handle);
-	delete session;
+	rpc_caller_session_close(session);
+	direct_caller_deinit(session->caller);
+	free(session->caller);
+	free(session);
 }
 
 const std::string &standalone_service_context::get_service_name() const
@@ -85,41 +114,22 @@
 	return &m_service_context;
 }
 
-void standalone_service_context::set_rpc_interface(rpc_interface *iface)
+void standalone_service_context::set_rpc_interface(rpc_service_interface *iface)
 {
 	m_rpc_interface = iface;
 }
 
-standalone_service_context::rpc_session::rpc_session(
-	struct rpc_interface *rpc_interface,
-	size_t rpc_buffer_size_override) :
-	m_direct_caller(),
-	m_rpc_caller()
+static struct rpc_caller_session *standalone_service_context_open(void *context)
 {
-	m_rpc_caller = (rpc_buffer_size_override) ?
-		direct_caller_init(&m_direct_caller, rpc_interface,
-			rpc_buffer_size_override, rpc_buffer_size_override) :
-		direct_caller_init_default(&m_direct_caller, rpc_interface);
-}
-
-standalone_service_context::rpc_session::~rpc_session()
-{
-	direct_caller_deinit(&m_direct_caller);
-}
-
-static rpc_session_handle standalone_service_context_open(void *context, struct rpc_caller **caller)
-{
-	rpc_session_handle handle = NULL;
 	standalone_service_context *this_context = reinterpret_cast<standalone_service_context*>(context);
 
-	if (this_context) {
-		handle = this_context->open(caller);
-	}
+	if (!this_context)
+		return NULL;
 
-	return handle;
+	return this_context->open();
 }
 
-static void standalone_service_context_close(void *context, rpc_session_handle session_handle)
+static void standalone_service_context_close(void *context, struct rpc_caller_session *session_handle)
 {
 	standalone_service_context *this_context = reinterpret_cast<standalone_service_context*>(context);
 
diff --git a/components/service/locator/standalone/standalone_service_context.h b/components/service/locator/standalone/standalone_service_context.h
index 64e903d..f9d1a0d 100644
--- a/components/service/locator/standalone/standalone_service_context.h
+++ b/components/service/locator/standalone/standalone_service_context.h
@@ -9,8 +9,9 @@
 
 #include <cstddef>
 #include <service_locator.h>
-#include <rpc/common/endpoint/rpc_interface.h>
-#include <rpc/direct/direct_caller.h>
+#include "rpc/common/caller/rpc_caller_session.h"
+#include "rpc/common/endpoint/rpc_service_interface.h"
+#include "rpc/direct/direct_caller.h"
 #include <string>
 
 class standalone_service_context
@@ -23,35 +24,24 @@
     void init();
     void deinit();
 
-    rpc_session_handle open(struct rpc_caller **caller);
-    void close(rpc_session_handle session_handle);
+    struct rpc_caller_session *open();
+    void close(struct rpc_caller_session *session);
 
     const std::string &get_service_name() const;
     struct service_context *get_service_context();
 
 protected:
-    void set_rpc_interface(rpc_interface *iface);
+    void set_rpc_interface(rpc_service_interface *iface);
 
     virtual void do_init() {}
     virtual void do_deinit() {}
 
 private:
-
-    struct rpc_session
-    {
-        rpc_session(struct rpc_interface *rpc_interface,
-            size_t rpc_buffer_size_override);
-        ~rpc_session();
-
-        struct direct_caller m_direct_caller;
-        struct rpc_caller *m_rpc_caller;
-    };
-
     std::string m_sn;
     int m_ref_count;
     size_t m_rpc_buffer_size_override;
     struct service_context m_service_context;
-    struct rpc_interface *m_rpc_interface;
+    struct rpc_service_interface *m_rpc_interface;
 };
 
 #endif /* STANDALONE_SERVICE_CONTEXT_H */
diff --git a/components/service/locator/standalone/standalone_service_registry.cpp b/components/service/locator/standalone/standalone_service_registry.cpp
index 5625bc0..bbe39a9 100644
--- a/components/service/locator/standalone/standalone_service_registry.cpp
+++ b/components/service/locator/standalone/standalone_service_registry.cpp
@@ -51,11 +51,10 @@
     return context;
 }
 
-standalone_service_context *standalone_service_registry::query(const char *sn, int *status)
+standalone_service_context *standalone_service_registry::query(const char *sn)
 {
     size_t index;
     standalone_service_context *context = NULL;
-    (void)status;
 
     if (find_context_index(sn, &index)) {
 
diff --git a/components/service/locator/standalone/standalone_service_registry.h b/components/service/locator/standalone/standalone_service_registry.h
index 7a76aeb..51da5da 100644
--- a/components/service/locator/standalone/standalone_service_registry.h
+++ b/components/service/locator/standalone/standalone_service_registry.h
@@ -29,7 +29,7 @@
     void regsiter_service_instance(standalone_service_context *service_context);
     standalone_service_context *deregsiter_service_instance(const char *sn);
 
-    standalone_service_context *query(const char *sn, int *status);
+    standalone_service_context *query(const char *sn);
 
 private:
     bool find_context_index(const char *sn, size_t *index) const;
diff --git a/components/service/secure_storage/backend/secure_storage_client/secure_storage_client.c b/components/service/secure_storage/backend/secure_storage_client/secure_storage_client.c
index fed2fe7..b94fc41 100644
--- a/components/service/secure_storage/backend/secure_storage_client/secure_storage_client.c
+++ b/components/service/secure_storage/backend/secure_storage_client/secure_storage_client.c
@@ -5,29 +5,31 @@
  */
 
 #include "secure_storage_client.h"
-#include <protocols/service/secure_storage/packed-c/secure_storage_proto.h>
-#include <protocols/rpc/common/packed-c/status.h>
-#include <rpc_caller.h>
+#include "protocols/service/secure_storage/packed-c/secure_storage_proto.h"
+#include "protocols/rpc/common/packed-c/status.h"
+#include "rpc_caller_session.h"
+#include "util.h"
 #include <string.h>
 
-
 static psa_status_t secure_storage_client_set(void *context,
-			 uint32_t client_id,
-			 psa_storage_uid_t uid,
-			 size_t data_length,
-			 const void *p_data,
-			 psa_storage_create_flags_t create_flags)
+					      uint32_t client_id,
+					      psa_storage_uid_t uid,
+					      size_t data_length,
+					      const void *p_data,
+					      psa_storage_create_flags_t create_flags)
 {
-	struct secure_storage_client *this_context = (struct secure_storage_client*)context;
-	uint8_t *request;
-	uint8_t *response;
+	struct secure_storage_client *this_context = (struct secure_storage_client *)context;
+	uint8_t *request = NULL;
+	uint8_t *response = NULL;
 	size_t request_length = 0;
 	size_t response_length = 0;
-	struct secure_storage_request_set *request_desc;
-	rpc_call_handle handle;
-	psa_status_t psa_status = PSA_SUCCESS;
+	struct secure_storage_request_set *request_desc = NULL;
+	rpc_call_handle handle = 0;
+	rpc_status_t rpc_status = RPC_ERROR_INTERNAL;
+	service_status_t service_status = 0;
+	psa_status_t psa_status = PSA_ERROR_GENERIC_ERROR;
 
-	this_context->client.rpc_status = TS_RPC_CALL_ACCEPTED;
+	this_context->client.rpc_status = RPC_SUCCESS;
 
 	(void)client_id;
 
@@ -35,64 +37,52 @@
 	if (p_data == NULL && data_length != 0)
 		return PSA_ERROR_INVALID_ARGUMENT;
 
-	request_length = sizeof(*request_desc) + data_length;
-	if (request_length < data_length) {
-		/* size_t overflow */
+	if (ADD_OVERFLOW(sizeof(*request_desc), data_length, &request_length))
 		return PSA_ERROR_INVALID_ARGUMENT;
-	}
 
-	handle = rpc_caller_begin(this_context->client.caller, &request, request_length);
+	handle = rpc_caller_session_begin(this_context->client.session, &request, request_length,
+					  0);
+	if (!handle)
+		goto out;
 
-	if (handle) {
-		rpc_opstatus_t opstatus = PSA_ERROR_GENERIC_ERROR;
+	/* Populating request descriptor */
+	request_desc = (struct secure_storage_request_set *)request;
+	request_desc->uid = uid;
+	request_desc->data_length = data_length;
+	request_desc->create_flags = create_flags;
+	memcpy(&request_desc->p_data, p_data, data_length);
 
-		/* Populating request descriptor */
-		request_desc = (struct secure_storage_request_set *)request;
-		request_desc->uid = uid;
-		request_desc->data_length = data_length;
-		request_desc->create_flags = create_flags;
-		memcpy(&request_desc->p_data, p_data, data_length);
+	rpc_status = rpc_caller_session_invoke(handle, TS_SECURE_STORAGE_OPCODE_SET,
+						&response, &response_length, &service_status);
+	if (rpc_status == RPC_SUCCESS)
+		psa_status = service_status;
 
-		this_context->client.rpc_status = rpc_caller_invoke(this_context->client.caller,
-						handle,
-						TS_SECURE_STORAGE_OPCODE_SET,
-						&opstatus, &response,
-						&response_length);
-
-		if (this_context->client.rpc_status != TS_RPC_CALL_ACCEPTED) {
-			/* RPC failure */
-			psa_status = PSA_ERROR_GENERIC_ERROR;
-		}
-		else {
-			psa_status = opstatus;
-		}
-
-		rpc_caller_end(this_context->client.caller, handle);
-	}
-	else {
+	rpc_status = rpc_caller_session_end(handle);
+	if (psa_status == PSA_SUCCESS && rpc_status != RPC_SUCCESS)
 		psa_status = PSA_ERROR_GENERIC_ERROR;
-	}
 
+out:
 	return psa_status;
 }
 
 static psa_status_t secure_storage_client_get(void *context,
-			 uint32_t client_id,
-			 psa_storage_uid_t uid,
-			 size_t data_offset,
-			 size_t data_size,
-			 void *p_data,
-			 size_t *p_data_length)
+					      uint32_t client_id,
+					      psa_storage_uid_t uid,
+					      size_t data_offset,
+					      size_t data_size,
+					      void *p_data,
+					      size_t *p_data_length)
 {
 	struct secure_storage_client *this_context = (struct secure_storage_client*)context;
-	uint8_t *request;
-	uint8_t *response;
+	uint8_t *request = NULL;
+	uint8_t *response = NULL;
 	size_t response_length = 0;
-	struct secure_storage_request_get *request_desc;
-	rpc_call_handle handle;
-	psa_status_t psa_status = PSA_SUCCESS;
-
-	this_context->client.rpc_status = TS_RPC_CALL_ACCEPTED;
+	size_t expected_response_length = data_size;
+	struct secure_storage_request_get *request_desc = NULL;
+	rpc_call_handle handle = 0;
+	rpc_status_t rpc_status = RPC_ERROR_INTERNAL;
+	service_status_t service_status = 0;
+	psa_status_t psa_status = PSA_ERROR_GENERIC_ERROR;
 
 	(void)client_id;
 
@@ -100,43 +90,37 @@
 	if (p_data == NULL && data_size != 0)
 		return PSA_ERROR_INVALID_ARGUMENT;
 
-	handle = rpc_caller_begin(this_context->client.caller, &request, sizeof(*request_desc));
+	handle = rpc_caller_session_begin(this_context->client.session, &request,
+					  sizeof(*request_desc), expected_response_length);
+	if (!handle)
+		goto out;
 
-	if (handle) {
-		rpc_opstatus_t opstatus = PSA_ERROR_GENERIC_ERROR;
+	/* Populating request descriptor */
+	request_desc = (struct secure_storage_request_get *)request;
+	request_desc->uid = uid;
+	request_desc->data_offset = data_offset;
+	request_desc->data_size = data_size;
 
-		/* Populating request descriptor */
-		request_desc = (struct secure_storage_request_get *)request;
-		request_desc->uid = uid;
-		request_desc->data_offset = data_offset;
-		request_desc->data_size = data_size;
+	rpc_status = rpc_caller_session_invoke(handle, TS_SECURE_STORAGE_OPCODE_GET, &response,
+					       &response_length, &service_status);
+	if (rpc_status != RPC_SUCCESS || response_length > data_size)
+		goto session_end;
 
-		this_context->client.rpc_status = rpc_caller_invoke(this_context->client.caller,
-						handle,
-						TS_SECURE_STORAGE_OPCODE_GET,
-						&opstatus, &response,
-						&response_length);
+	psa_status = service_status;
 
-		if (this_context->client.rpc_status != TS_RPC_CALL_ACCEPTED ) {
-			/* RPC failure */
-			psa_status = PSA_ERROR_GENERIC_ERROR;
-		}
-		else {
-			psa_status = opstatus;
-		}
+	/* Filling output parameters */
+	if (psa_status != PSA_SUCCESS)
+		goto session_end;
 
-		/* Filling output parameters */
-		if (psa_status == PSA_SUCCESS) {
-			*p_data_length = (response_length <= data_size) ? response_length : data_size;
-			memcpy(p_data, response, *p_data_length);
-		}
+	*p_data_length = response_length;
+	memcpy(p_data, response, response_length);
 
-		rpc_caller_end(this_context->client.caller, handle);
-	}
-	else {
+session_end:
+	rpc_status = rpc_caller_session_end(handle);
+	if (psa_status == PSA_SUCCESS && rpc_status != RPC_SUCCESS)
 		psa_status = PSA_ERROR_GENERIC_ERROR;
-	}
 
+out:
 	return psa_status;
 }
 
@@ -146,12 +130,14 @@
 				struct psa_storage_info_t *p_info)
 {
 	struct secure_storage_client *this_context = (struct secure_storage_client*)context;
-	uint8_t *request;
-	uint8_t *response;
+	uint8_t *request = NULL;
+	uint8_t *response = NULL;
 	size_t response_length = 0;
-	struct secure_storage_request_get_info *request_desc;
-	struct secure_storage_response_get_info *response_desc;
-	rpc_call_handle handle;
+	struct secure_storage_request_get_info *request_desc = NULL;
+	struct secure_storage_response_get_info *response_desc = NULL;
+	rpc_call_handle handle = 0;
+	rpc_status_t rpc_status = RPC_ERROR_INTERNAL;
+	service_status_t service_status = 0;
 	psa_status_t psa_status = PSA_ERROR_GENERIC_ERROR;
 
 	(void)client_id;
@@ -160,162 +146,120 @@
 	if (p_info == NULL)
 		return PSA_ERROR_INVALID_ARGUMENT;
 
-	handle = rpc_caller_begin(this_context->client.caller, &request, sizeof(*request_desc));
+	handle = rpc_caller_session_begin(this_context->client.session, &request,
+					  sizeof(*request_desc), sizeof(*response_desc));
+	if (!handle)
+		goto out;
 
-	if (handle) {
-		rpc_opstatus_t opstatus = PSA_ERROR_GENERIC_ERROR;
+	/* Populating request descriptor */
+	request_desc = (struct secure_storage_request_get_info *)request;
+	request_desc->uid = uid;
 
-		/* Populating request descriptor */
-		request_desc = (struct secure_storage_request_get_info *)request;
-		request_desc->uid = uid;
+	rpc_status = rpc_caller_session_invoke(handle, TS_SECURE_STORAGE_OPCODE_GET_INFO,
+					       &response, &response_length, &service_status);
+	if (rpc_status != RPC_SUCCESS ||
+	   (service_status == PSA_SUCCESS && response_length != sizeof(*response_desc)))
+		goto session_end;
 
-		this_context->client.rpc_status = rpc_caller_invoke(this_context->client.caller, handle,
-						TS_SECURE_STORAGE_OPCODE_GET_INFO,
-						&opstatus, &response,
-						&response_length);
+	psa_status = service_status;
 
-		if (this_context->client.rpc_status != TS_RPC_CALL_ACCEPTED) {
-			/* RPC failure */
-			psa_status = PSA_ERROR_GENERIC_ERROR;
-		} else {
-			if (response_length == sizeof(*response_desc)) {
-				/* Response length matches the expected size */
-				psa_status = opstatus;
-			} else if (!response_length) {
-				/*
-				 * In case of an empty response use opstatus but
-				 * fall back to PSA_ERROR_GENERIC_ERROR if opstatus
-				 * contains PSA_SUCCESS as this is an invalid case.
-				 */
-				if (opstatus != PSA_SUCCESS)
-					psa_status = opstatus;
-				else
-					psa_status = PSA_ERROR_GENERIC_ERROR;
-			} else {
-				/* Invalid length */
-				psa_status = PSA_ERROR_GENERIC_ERROR;
-			}
-		}
+	if (psa_status == PSA_SUCCESS) {
+		response_desc = (struct secure_storage_response_get_info *)response;
 
-		if (psa_status == PSA_SUCCESS) {
-			response_desc = (struct secure_storage_response_get_info *)response;
-			p_info->capacity = response_desc->capacity;
-			p_info->size = response_desc->size;
-			p_info->flags = response_desc->flags;
-		} else {
-			p_info->capacity = 0;
-			p_info->size = 0;
-			p_info->flags = PSA_STORAGE_FLAG_NONE;
-		}
-
-		rpc_caller_end(this_context->client.caller, handle);
+		p_info->capacity = response_desc->capacity;
+		p_info->size = response_desc->size;
+		p_info->flags = response_desc->flags;
+	} else {
+		p_info->capacity = 0;
+		p_info->size = 0;
+		p_info->flags = PSA_STORAGE_FLAG_NONE;
 	}
-	else {
+
+session_end:
+	rpc_status = rpc_caller_session_end(handle);
+	if (psa_status == PSA_SUCCESS && rpc_status != RPC_SUCCESS)
 		psa_status = PSA_ERROR_GENERIC_ERROR;
-	}
 
+out:
 	return psa_status;
 }
 
 static psa_status_t secure_storage_client_remove(void *context,
-						uint32_t client_id,
-						psa_storage_uid_t uid)
+						 uint32_t client_id,
+						 psa_storage_uid_t uid)
 {
 	struct secure_storage_client *this_context = (struct secure_storage_client*)context;
-	uint8_t *request;
-	uint8_t *response;
+	uint8_t *request = NULL;
+	uint8_t *response = NULL;
 	size_t response_length = 0;
-	struct secure_storage_request_remove *request_desc;
-	rpc_call_handle handle;
-	psa_status_t psa_status = PSA_SUCCESS;
-
-	this_context->client.rpc_status = TS_RPC_CALL_ACCEPTED;
+	struct secure_storage_request_remove *request_desc = NULL;
+	rpc_call_handle handle = 0;
+	rpc_status_t rpc_status = RPC_ERROR_INTERNAL;
+	service_status_t service_status = 0;
+	psa_status_t psa_status = PSA_ERROR_GENERIC_ERROR;
 
 	(void)client_id;
 
-	handle = rpc_caller_begin(this_context->client.caller, &request, sizeof(*request_desc));
+	handle = rpc_caller_session_begin(this_context->client.session, &request,
+					  sizeof(*request_desc), 0);
+	if (!handle)
+		goto out;
 
-	if (handle) {
-		rpc_opstatus_t opstatus = PSA_ERROR_GENERIC_ERROR;
+	/* Populating request descriptor */
+	request_desc = (struct secure_storage_request_remove *)request;
+	request_desc->uid = uid;
 
-		/* Populating request descriptor */
-		request_desc = (struct secure_storage_request_remove *)request;
-		request_desc->uid = uid;
+	rpc_status = rpc_caller_session_invoke(handle, TS_SECURE_STORAGE_OPCODE_REMOVE,
+					       &response, &response_length, &service_status);
+	if (rpc_status == RPC_SUCCESS)
+		psa_status = service_status;
 
-		this_context->client.rpc_status = rpc_caller_invoke(this_context->client.caller,
-						handle,
-						TS_SECURE_STORAGE_OPCODE_REMOVE,
-						&opstatus, &response,
-						&response_length);
-
-		if (this_context->client.rpc_status != TS_RPC_CALL_ACCEPTED) {
-			/* RPC failure */
-			psa_status = PSA_ERROR_GENERIC_ERROR;
-		}
-		else {
-			psa_status = opstatus;
-		}
-
-		rpc_caller_end(this_context->client.caller, handle);
-	}
-	else {
+	rpc_status = rpc_caller_session_end(handle);
+	if (psa_status == PSA_SUCCESS && rpc_status != RPC_SUCCESS)
 		psa_status = PSA_ERROR_GENERIC_ERROR;
-	}
 
+out:
 	return psa_status;
 }
 
 static psa_status_t secure_storage_client_create(void *context,
-                            uint32_t client_id,
-                            uint64_t uid,
-                            size_t capacity,
-                            uint32_t create_flags)
+						 uint32_t client_id,
+						 uint64_t uid,
+						 size_t capacity,
+						 uint32_t create_flags)
 {
 	struct secure_storage_client *this_context = (struct secure_storage_client*)context;
-	uint8_t *request;
-	uint8_t *response;
-	size_t request_length = 0;
+	uint8_t *request = NULL;
+	uint8_t *response = NULL;
 	size_t response_length = 0;
-	struct secure_storage_request_create *request_desc;
-	rpc_call_handle handle;
+	struct secure_storage_request_create *request_desc = NULL;
+	rpc_call_handle handle = 0;
+	rpc_status_t rpc_status = RPC_ERROR_INTERNAL;
+	service_status_t service_status = 0;
 	psa_status_t psa_status = PSA_SUCCESS;
 
-	this_context->client.rpc_status = TS_RPC_CALL_ACCEPTED;
-
 	(void)client_id;
 
-	request_length = sizeof(*request_desc);
+	handle = rpc_caller_session_begin(this_context->client.session, &request,
+					  sizeof(*request_desc), 0);
+	if (!handle)
+		goto out;
 
-	handle = rpc_caller_begin(this_context->client.caller, &request, request_length);
+	request_desc = (struct secure_storage_request_create *)request;
+	request_desc->uid = uid;
+	request_desc->capacity = capacity;
+	request_desc->create_flags = create_flags;
 
-	if (handle) {
-		rpc_opstatus_t opstatus = PSA_ERROR_GENERIC_ERROR;
+	rpc_status = rpc_caller_session_invoke(handle, TS_SECURE_STORAGE_OPCODE_CREATE,
+					       &response, &response_length, &service_status);
+	if (rpc_status == RPC_SUCCESS)
+		psa_status = service_status;
 
-		request_desc = (struct secure_storage_request_create*)request;
-		request_desc->uid = uid;
-		request_desc->capacity = capacity;
-		request_desc->create_flags = create_flags;
-
-		this_context->client.rpc_status = rpc_caller_invoke(this_context->client.caller,
-						handle,
-						TS_SECURE_STORAGE_OPCODE_CREATE,
-						&opstatus, &response,
-						&response_length);
-
-		if (this_context->client.rpc_status != TS_RPC_CALL_ACCEPTED) {
-			/* RPC failure */
-			psa_status = PSA_ERROR_GENERIC_ERROR;
-		}
-		else {
-			psa_status = opstatus;
-		}
-
-		rpc_caller_end(this_context->client.caller, handle);
-	}
-	else {
+	rpc_status = rpc_caller_session_end(handle);
+	if (psa_status == PSA_SUCCESS && rpc_status != RPC_SUCCESS)
 		psa_status = PSA_ERROR_GENERIC_ERROR;
-	}
 
+out:
 	return psa_status;
 }
 
@@ -327,115 +271,94 @@
                             const void *p_data)
 {
 	struct secure_storage_client *this_context = (struct secure_storage_client*)context;
-	uint8_t *request;
-	uint8_t *response;
+	uint8_t *request = NULL;
+	uint8_t *response = NULL;
 	size_t request_length = 0;
 	size_t response_length = 0;
-	struct secure_storage_request_set_extended *request_desc;
-	rpc_call_handle handle;
+	struct secure_storage_request_set_extended *request_desc = NULL;
+	rpc_call_handle handle = 0;
+	rpc_status_t rpc_status = RPC_ERROR_INTERNAL;
+	service_status_t service_status = 0;
 	psa_status_t psa_status = PSA_SUCCESS;
 
-	this_context->client.rpc_status = TS_RPC_CALL_ACCEPTED;
-
 	(void)client_id;
 
 	/* Validating input parameters */
 	if (p_data == NULL)
 		return PSA_ERROR_INVALID_ARGUMENT;
 
-	request_length = sizeof(*request_desc) + data_length;
-	if (request_length < data_length) {
-		/* size_t overflow */
+	if (ADD_OVERFLOW(sizeof(*request_desc), data_length, &request_length))
 		return PSA_ERROR_INVALID_ARGUMENT;
-	}
 
-	handle = rpc_caller_begin(this_context->client.caller, &request, request_length);
+	handle = rpc_caller_session_begin(this_context->client.session, &request, request_length,
+					  0);
+	if (!handle)
+		goto out;
 
-	if (handle) {
-		rpc_opstatus_t opstatus = PSA_ERROR_GENERIC_ERROR;
+	/* Populating request descriptor */
+	request_desc = (struct secure_storage_request_set_extended *)request;
+	request_desc->uid = uid;
+	request_desc->data_offset = data_offset;
+	request_desc->data_length = data_length;
+	memcpy(&request_desc->p_data, p_data, data_length);
 
-		/* Populating request descriptor */
-		request_desc = (struct secure_storage_request_set_extended *)request;
-		request_desc->uid = uid;
-		request_desc->data_offset = data_offset;
-		request_desc->data_length = data_length;
-		memcpy(&request_desc->p_data, p_data, data_length);
+	rpc_status = rpc_caller_session_invoke(handle, TS_SECURE_STORAGE_OPCODE_SET_EXTENDED,
+					       &response, &response_length, &service_status);
+	if (rpc_status == RPC_SUCCESS)
+		psa_status = service_status;
 
-		this_context->client.rpc_status = rpc_caller_invoke(this_context->client.caller,
-						handle,
-						TS_SECURE_STORAGE_OPCODE_SET_EXTENDED,
-						&opstatus, &response,
-						&response_length);
-
-		if (this_context->client.rpc_status != TS_RPC_CALL_ACCEPTED) {
-			/* RPC failure */
-			psa_status = PSA_ERROR_GENERIC_ERROR;
-		}
-		else {
-			psa_status = opstatus;
-		}
-
-		rpc_caller_end(this_context->client.caller, handle);
-	}
-	else {
+	rpc_status = rpc_caller_session_end(handle);
+	if (psa_status == PSA_SUCCESS && rpc_status != RPC_SUCCESS)
 		psa_status = PSA_ERROR_GENERIC_ERROR;
-	}
 
+out:
 	return psa_status;
 }
 
 static uint32_t secure_storage_get_support(void *context, uint32_t client_id)
 {
 	struct secure_storage_client *this_context = (struct secure_storage_client*)context;
-	uint8_t *request;
-	uint8_t *response;
+	uint8_t *request = NULL;
+	uint8_t *response = NULL;
 	size_t response_length = 0;
-	struct secure_storage_response_get_support *response_desc;
-	rpc_call_handle handle;
+	struct secure_storage_response_get_support *response_desc = NULL;
+	rpc_call_handle handle = 0;
 	psa_status_t psa_status = PSA_ERROR_GENERIC_ERROR;
+	service_status_t service_status = 0;
+	rpc_status_t rpc_status = RPC_ERROR_INTERNAL;
 	uint32_t feature_map = 0;
 
 	(void)client_id;
 
-	handle = rpc_caller_begin(this_context->client.caller, &request, 0);
+	handle = rpc_caller_session_begin(this_context->client.session, &request, 0,
+					  sizeof(*response_desc));
+	if (!handle)
+		goto out;
 
-	if (handle) {
-		rpc_opstatus_t opstatus = PSA_ERROR_GENERIC_ERROR;
+	rpc_status = rpc_caller_session_invoke(handle, TS_SECURE_STORAGE_OPCODE_GET_SUPPORT,
+					       &response, &response_length, &service_status);
+	if (rpc_status != RPC_SUCCESS || response_length < sizeof(*response_desc))
+		goto session_end;
 
-		this_context->client.rpc_status = rpc_caller_invoke(this_context->client.caller,
-						handle,
-						TS_SECURE_STORAGE_OPCODE_GET_SUPPORT,
-						&opstatus, &response,
-						&response_length);
+	psa_status = service_status;
+	if (psa_status != PSA_SUCCESS)
+		goto session_end;
 
-		if (this_context->client.rpc_status != TS_RPC_CALL_ACCEPTED) {
-			/* RPC failure */
-			psa_status = PSA_ERROR_GENERIC_ERROR;
-		} else {
-			if (response_length < sizeof(*response_desc)) {
-				psa_status = PSA_ERROR_GENERIC_ERROR;
-			}
-			else {
-				psa_status = opstatus;
-			}
-		}
+	response_desc = (struct secure_storage_response_get_support *)response;
+	feature_map = response_desc->support;
 
-		if (psa_status == PSA_SUCCESS) {
-			response_desc = (struct secure_storage_response_get_support*)response;
-			feature_map = response_desc->support;
-		}
+session_end:
+	rpc_caller_session_end(handle);
 
-		rpc_caller_end(this_context->client.caller, handle);
-	}
-
+out:
 	return feature_map;
 }
 
 
 struct storage_backend *secure_storage_client_init(struct secure_storage_client *context,
-								struct rpc_caller *caller)
+								struct rpc_caller_session *session)
 {
-	service_client_init(&context->client, caller);
+	service_client_init(&context->client, session);
 
 	static const struct storage_backend_interface interface =
 	{
diff --git a/components/service/secure_storage/backend/secure_storage_client/secure_storage_client.h b/components/service/secure_storage/backend/secure_storage_client/secure_storage_client.h
index cb90e62..28f15f8 100644
--- a/components/service/secure_storage/backend/secure_storage_client/secure_storage_client.h
+++ b/components/service/secure_storage/backend/secure_storage_client/secure_storage_client.h
@@ -36,7 +36,7 @@
  * @return     Pointer to inialized storage backend or NULL on failure
  */
 struct storage_backend *secure_storage_client_init(struct secure_storage_client *context,
-                                struct rpc_caller *caller);
+						   struct rpc_caller_session *session);
 
 /**
  * @brief      Deinitialize a secure storage client
diff --git a/components/service/secure_storage/backend/secure_storage_client/test/secure_storage_client_tests.cpp b/components/service/secure_storage/backend/secure_storage_client/test/secure_storage_client_tests.cpp
index 7cd887e..33a01a2 100644
--- a/components/service/secure_storage/backend/secure_storage_client/test/secure_storage_client_tests.cpp
+++ b/components/service/secure_storage/backend/secure_storage_client/test/secure_storage_client_tests.cpp
@@ -6,6 +6,7 @@
 
 #include <CppUTest/TestHarness.h>
 #include <rpc/direct/direct_caller.h>
+#include "service/secure_storage/frontend/secure_storage_provider/secure_storage_uuid.h"
 #include <service/secure_storage/frontend/psa/its/its_frontend.h>
 #include <service/secure_storage/frontend/psa/its/test/its_api_tests.h>
 #include <service/secure_storage/frontend/psa/ps/ps_frontend.h>
@@ -23,14 +24,23 @@
      */
     void setup()
     {
+        struct rpc_uuid service_uuid = { .uuid = TS_PSA_INTERNAL_TRUSTED_STORAGE_UUID };
         struct storage_backend *storage_provider_backend =
             mock_store_init(&m_mock_store);
-        struct rpc_interface *storage_ep =
-            secure_storage_provider_init(&m_storage_provider, storage_provider_backend);
-        struct rpc_caller *storage_caller =
-            direct_caller_init_default(&m_storage_caller, storage_ep);
+        struct rpc_service_interface *storage_ep =
+            secure_storage_provider_init(&m_storage_provider, storage_provider_backend,
+                                         &service_uuid);
+        rpc_status_t rpc_status = RPC_ERROR_INTERNAL;
+
+        rpc_status = direct_caller_init(&m_storage_caller, storage_ep);
+        CHECK_EQUAL(RPC_SUCCESS, rpc_status);
+
+        rpc_status = rpc_caller_session_find_and_open(&m_storage_session, &m_storage_caller,
+                                                      &service_uuid, 4096);
+        CHECK_EQUAL(RPC_SUCCESS, rpc_status);
+
         struct storage_backend *storage_client_backend =
-            secure_storage_client_init(&m_storage_client, storage_caller);
+            secure_storage_client_init(&m_storage_client, &m_storage_session);
 
         psa_its_frontend_init(storage_client_backend);
         psa_ps_frontend_init(storage_client_backend);
@@ -41,13 +51,15 @@
         mock_store_deinit(&m_mock_store);
         secure_storage_provider_deinit(&m_storage_provider);
         secure_storage_client_deinit(&m_storage_client);
+        rpc_caller_session_close(&m_storage_session);
         direct_caller_deinit(&m_storage_caller);
     }
 
     struct mock_store m_mock_store;
     struct secure_storage_provider m_storage_provider;
     struct secure_storage_client m_storage_client;
-    struct direct_caller m_storage_caller;
+    struct rpc_caller_interface m_storage_caller;
+    struct rpc_caller_session m_storage_session;
 };
 
 TEST(SecureStorageClientTests, itsStoreNewItem)
diff --git a/components/service/secure_storage/backend/secure_storage_client/test/secure_storage_proxy_tests.cpp b/components/service/secure_storage/backend/secure_storage_client/test/secure_storage_proxy_tests.cpp
index c028776..ac53769 100644
--- a/components/service/secure_storage/backend/secure_storage_client/test/secure_storage_proxy_tests.cpp
+++ b/components/service/secure_storage/backend/secure_storage_client/test/secure_storage_proxy_tests.cpp
@@ -6,6 +6,7 @@
 
 #include <CppUTest/TestHarness.h>
 #include <rpc/direct/direct_caller.h>
+#include "service/secure_storage/frontend/secure_storage_provider/secure_storage_uuid.h"
 #include <service/secure_storage/frontend/psa/its/its_frontend.h>
 #include <service/secure_storage/frontend/psa/its/test/its_api_tests.h>
 #include <service/secure_storage/frontend/psa/ps/ps_frontend.h>
@@ -24,25 +25,35 @@
      */
     void setup()
     {
+        struct rpc_uuid service_uuid = { .uuid = TS_PSA_PROTECTED_STORAGE_UUID };
         /* Initialise the actual storage provider */
         struct storage_backend *storage_provider_backend =
             mock_store_init(&m_mock_store);
-        struct rpc_interface *storage_ep =
-            secure_storage_provider_init(&m_storage_provider, storage_provider_backend);
-        struct rpc_caller *storage_caller =
-            direct_caller_init_default(&m_storage_caller, storage_ep);
+        struct rpc_service_interface *storage_ep =
+            secure_storage_provider_init(&m_storage_provider, storage_provider_backend,
+                                         &service_uuid);
+        rpc_status_t rpc_status = RPC_ERROR_INTERNAL;
+
+        rpc_status = direct_caller_init(&m_storage_caller, storage_ep);
+        CHECK_EQUAL(RPC_SUCCESS, rpc_status);
+
+        rpc_status = rpc_caller_session_find_and_open(&m_storage_session, &m_storage_caller,
+                                                      &service_uuid, 4096);
+        CHECK_EQUAL(RPC_SUCCESS, rpc_status);
 
         /* Initialise the intermediate proxy */
         struct storage_backend *proxy_backend =
-            secure_storage_client_init(&m_proxy_client, storage_caller);
-        struct rpc_interface *proxy_ep =
-            secure_storage_provider_init(&m_proxy_provider, proxy_backend);
-        struct rpc_caller *proxy_caller =
-            direct_caller_init_default(&m_proxy_caller, proxy_ep);
+            secure_storage_client_init(&m_proxy_client, &m_storage_session);
+        struct rpc_service_interface *proxy_ep =
+            secure_storage_provider_init(&m_proxy_provider, proxy_backend, &service_uuid);
+        direct_caller_init(&m_proxy_caller, proxy_ep);
+
+        rpc_caller_session_find_and_open(&m_proxy_session, &m_proxy_caller, &service_uuid,
+                                         4096);
 
         /* Initialise the client-side backend that talks to the proxy */
         struct storage_backend *storage_client_backend =
-            secure_storage_client_init(&m_storage_client, proxy_caller);
+            secure_storage_client_init(&m_storage_client, &m_proxy_session);
 
         psa_its_frontend_init(storage_client_backend);
         psa_ps_frontend_init(storage_client_backend);
@@ -58,6 +69,9 @@
 
         secure_storage_client_deinit(&m_storage_client);
 
+        rpc_caller_session_close(&m_proxy_session);
+        rpc_caller_session_close(&m_storage_session);
+
         direct_caller_deinit(&m_proxy_caller);
         direct_caller_deinit(&m_storage_caller);
     }
@@ -67,8 +81,10 @@
     struct secure_storage_client m_proxy_client;
     struct secure_storage_provider m_proxy_provider;
     struct secure_storage_client m_storage_client;
-    struct direct_caller m_storage_caller;
-    struct direct_caller m_proxy_caller;
+    struct rpc_caller_interface m_storage_caller;
+    struct rpc_caller_interface m_proxy_caller;
+    struct rpc_caller_session m_storage_session;
+    struct rpc_caller_session m_proxy_session;
 };
 
 TEST(SecureStorageProxyTests, itsStoreNewItem)
diff --git a/components/service/secure_storage/backend/secure_storage_ipc/secure_storage_ipc.c b/components/service/secure_storage/backend/secure_storage_ipc/secure_storage_ipc.c
index 0609326..986628c 100644
--- a/components/service/secure_storage/backend/secure_storage_ipc/secure_storage_ipc.c
+++ b/components/service/secure_storage/backend/secure_storage_ipc/secure_storage_ipc.c
@@ -18,7 +18,7 @@
 			 const void *p_data, psa_storage_create_flags_t create_flags)
 {
 	struct secure_storage_ipc *ipc = context;
-	struct rpc_caller *caller = ipc->client.caller;
+	struct rpc_caller_interface *caller = ipc->client.session->caller;
 	psa_status_t psa_status;
 	struct psa_invec in_vec[] = {
 		{ .base = psa_ptr_to_u32(&uid), .len = sizeof(uid) },
@@ -46,7 +46,7 @@
 					   size_t *p_data_length)
 {
 	struct secure_storage_ipc *ipc = context;
-	struct rpc_caller *caller = ipc->client.caller;
+	struct rpc_caller_interface *caller = ipc->client.session->caller;
 	psa_status_t psa_status;
 	uint32_t offset = (uint32_t)data_offset;
 	struct psa_invec in_vec[] = {
@@ -78,7 +78,7 @@
 						struct psa_storage_info_t *p_info)
 {
 	struct secure_storage_ipc *ipc = context;
-	struct rpc_caller *caller = ipc->client.caller;
+	struct rpc_caller_interface *caller = ipc->client.session->caller;
 	psa_status_t psa_status;
 	struct psa_invec in_vec[] = {
 		{ .base = psa_ptr_to_u32(&uid), .len = sizeof(uid) },
@@ -102,7 +102,7 @@
 						psa_storage_uid_t uid)
 {
 	struct secure_storage_ipc *ipc = context;
-	struct rpc_caller *caller = ipc->client.caller;
+	struct rpc_caller_interface *caller = ipc->client.session->caller;
 	psa_status_t psa_status;
 	struct psa_invec in_vec[] = {
 		{ .base = psa_ptr_to_u32(&uid), .len = sizeof(uid) },
@@ -152,7 +152,7 @@
 static uint32_t secure_storage_get_support(void *context, uint32_t client_id)
 {
 	struct secure_storage_ipc *ipc = context;
-	struct rpc_caller *caller = ipc->client.caller;
+	struct rpc_caller_interface *caller = ipc->client.session->caller;
 	psa_status_t psa_status;
 	uint32_t support_flags;
 	struct psa_outvec out_vec[] = {
@@ -169,9 +169,9 @@
 }
 
 struct storage_backend *secure_storage_ipc_init(struct secure_storage_ipc *context,
-						struct rpc_caller *caller)
+						struct rpc_caller_session *session)
 {
-	service_client_init(&context->client, caller);
+	service_client_init(&context->client, session);
 
 	static const struct storage_backend_interface interface =
 	{
diff --git a/components/service/secure_storage/backend/secure_storage_ipc/secure_storage_ipc.h b/components/service/secure_storage/backend/secure_storage_ipc/secure_storage_ipc.h
index 6bb47ac..33045e9 100644
--- a/components/service/secure_storage/backend/secure_storage_ipc/secure_storage_ipc.h
+++ b/components/service/secure_storage/backend/secure_storage_ipc/secure_storage_ipc.h
@@ -37,7 +37,7 @@
  * @return     Pointer to inialized storage backend or NULL on failure
  */
 struct storage_backend *secure_storage_ipc_init(struct secure_storage_ipc *context,
-						struct rpc_caller *caller);
+						struct rpc_caller_session *session);
 
 /**
  * @brief      Deinitialize a secure storage ipc client
diff --git a/components/service/secure_storage/factory/common/sfs/storage_factory.c b/components/service/secure_storage/factory/common/sfs/storage_factory.c
index a579887..ae86a05 100644
--- a/components/service/secure_storage/factory/common/sfs/storage_factory.c
+++ b/components/service/secure_storage/factory/common/sfs/storage_factory.c
@@ -5,7 +5,6 @@
  *
  */
 
-#include <rpc/ffarpc/caller/sp/ffarpc_caller.h>
 #include <protocols/rpc/common/packed-c/status.h>
 #include <service/secure_storage/backend/secure_flash_store/secure_flash_store.h>
 #include <service/secure_storage/backend/secure_flash_store/flash/ram/sfs_flash_ram.h>
diff --git a/components/service/secure_storage/factory/sp/optee_trusted_store/component.cmake b/components/service/secure_storage/factory/sp/optee_trusted_store/component.cmake
deleted file mode 100644
index b06adb5..0000000
--- a/components/service/secure_storage/factory/sp/optee_trusted_store/component.cmake
+++ /dev/null
@@ -1,14 +0,0 @@
-#-------------------------------------------------------------------------------
-# Copyright (c) 2021, Arm Limited and Contributors. All rights reserved.
-#
-# SPDX-License-Identifier: BSD-3-Clause
-#
-#-------------------------------------------------------------------------------
-if (NOT DEFINED TGT)
-	message(FATAL_ERROR "mandatory parameter TGT is not defined.")
-endif()
-
-target_sources(${TGT} PRIVATE
-	"${CMAKE_CURRENT_LIST_DIR}/storage_factory.c"
-	)
-
diff --git a/components/service/secure_storage/factory/sp/optee_trusted_store/storage_factory.c b/components/service/secure_storage/factory/sp/optee_trusted_store/storage_factory.c
deleted file mode 100644
index b81925f..0000000
--- a/components/service/secure_storage/factory/sp/optee_trusted_store/storage_factory.c
+++ /dev/null
@@ -1,111 +0,0 @@
-/*
- * Copyright (c) 2021-2022, Arm Limited. All rights reserved.
- *
- * SPDX-License-Identifier: BSD-3-Clause
- *
- */
-
-/**
- * A storage factory that creates storage backends that communicate with an
- * S-EL1 partition to access trusted storage provided by OPTEE. The S-EL1
- * partition is assumed to host a conventional secure storage provider
- * that can be accessed using the secure storage access protocol.
- * Uses a default UUID to discover the S-EL1 partition if no external
- * configuration overrides this.
- */
-#include <rpc/ffarpc/caller/sp/ffarpc_caller.h>
-#include <protocols/rpc/common/packed-c/status.h>
-#include <service/secure_storage/backend/secure_storage_client/secure_storage_client.h>
-#include <service/secure_storage/backend/null_store/null_store.h>
-#include <service/secure_storage/factory/storage_factory.h>
-#include <ffa_api.h>
-#include "sp_discovery.h"
-#include <stdbool.h>
-#include <stddef.h>
-
-/* NOTE: this is the ITS partition UUID - should be changed when S-EL1 SP is ready */
-#define OPTEE_TRUSTED_STORE_UUID_BYTES \
-	{ 0xdc, 0x1e, 0xef, 0x48, 0xb1, 0x7a, 0x4c, 0xcf, \
-	  0xac, 0x8b, 0xdf, 0xcf, 0xf7, 0x71, 0x1b, 0x14 }
-
-static const uint8_t default_optee_trusted_store_uuid[] = OPTEE_TRUSTED_STORE_UUID_BYTES;
-
-/* The storage backed specialization constructed by this factory */
-struct optee_trusted_store
-{
-	struct secure_storage_client secure_storage_client;
-	struct ffarpc_caller ffarpc_caller;
-	bool in_use;
-};
-
-/* Only supports construction of a single instance */
-static struct optee_trusted_store backend_instance = { .in_use = false };
-
-/* Used on failure if no association with a storage provider is established */
-static struct null_store null_store;
-
-
-struct storage_backend *storage_factory_create(
-			enum storage_factory_security_class security_class)
-{
-	struct rpc_caller *storage_caller;
-	uint16_t storage_sp_ids[1];
-	struct optee_trusted_store *new_backend = &backend_instance;
-	struct storage_backend *result = NULL;
-
-	if (!new_backend->in_use) {
-		uint16_t own_id = 0;
-
-		if (sp_discovery_own_id_get(&own_id) != SP_RESULT_OK)
-			return NULL;
-
-		storage_caller = ffarpc_caller_init(&new_backend->ffarpc_caller, own_id);
-		if (!storage_caller)
-			return NULL;
-
-		/* Try discovering candidate endpoints in preference order */
-		if (ffarpc_caller_discover(default_optee_trusted_store_uuid, storage_sp_ids,
-					   sizeof(storage_sp_ids)/sizeof(uint16_t))) {
-
-			if (ffarpc_caller_open(&new_backend->ffarpc_caller,
-					       storage_sp_ids[0], 0) == 0) {
-
-				result = secure_storage_client_init(
-					&new_backend->secure_storage_client,
-					storage_caller);
-			}
-		}
-
-		if (!result) {
-
-			/* Failed to discover or open an RPC session with provider */
-			ffarpc_caller_deinit(&new_backend->ffarpc_caller);
-		}
-
-		new_backend->in_use = (result != NULL);
-	}
-
-	if (!result) {
-
-		/**
-		 * Errors during SP initialisation can be difficult to handle so
-		 * returns a valid storage_backend, albeit one that just returns
-		 * an appropriate status code if any methods are called.  This
-		 * allows an error to be reported to a requesting client where
-		 * it may be easier to handle.
-		 */
-		result = null_store_init(&null_store);
-	}
-
-	return result;
-}
-
-void storage_factory_destroy(struct storage_backend *backend)
-{
-	if (backend) {
-
-		secure_storage_client_deinit(&backend_instance.secure_storage_client);
-		ffarpc_caller_deinit(&backend_instance.ffarpc_caller);
-		backend_instance.in_use = false;
-	}
-}
diff --git a/components/service/secure_storage/factory/sp/rot_store/storage_factory.c b/components/service/secure_storage/factory/sp/rot_store/storage_factory.c
index 5fb0f3b..ed0b999 100644
--- a/components/service/secure_storage/factory/sp/rot_store/storage_factory.c
+++ b/components/service/secure_storage/factory/sp/rot_store/storage_factory.c
@@ -14,35 +14,35 @@
  * requested storage class is used.  The availability of Internal Trusted
  * and Protected stores will depend on the platform.
  */
-#include <rpc/ffarpc/caller/sp/ffarpc_caller.h>
+#include "rpc/ts_rpc/caller/sp/ts_rpc_caller_sp.h"
+#include "rpc/common/caller/rpc_caller_session.h"
 #include <protocols/rpc/common/packed-c/status.h>
 #include <service/secure_storage/backend/secure_storage_client/secure_storage_client.h>
 #include <service/secure_storage/backend/null_store/null_store.h>
 #include <service/secure_storage/factory/storage_factory.h>
+#include "service/secure_storage/frontend/secure_storage_provider/secure_storage_uuid.h"
 #include <ffa_api.h>
 #include "sp_discovery.h"
 #include <stdbool.h>
 #include <stddef.h>
 
 /* Defaults to using PSA storage partitions if no external configuration specified */
-#define ITS_STORE_UUID_BYTES \
-	{ 0xdc, 0x1e, 0xef, 0x48, 0xb1, 0x7a, 0x4c, 0xcf, \
-	  0xac, 0x8b, 0xdf, 0xcf, 0xf7, 0x71, 0x1b, 0x14 }
-
-#define PS_STORE_UUID_BYTES \
-	{ 0x75, 0x1b, 0xf8, 0x01, 0x3d, 0xde, 0x47, 0x68, \
-	  0xa5, 0x14, 0x0f, 0x10, 0xae, 0xed, 0x17, 0x90 }
-
 #define MAX_CANDIDATE_UUIDS		(2)
 
-static const uint8_t default_internal_store_uuid[] = ITS_STORE_UUID_BYTES;
-static const uint8_t default_protected_store_uuid[] = PS_STORE_UUID_BYTES;
+static const struct rpc_uuid default_internal_store_uuid = {
+	.uuid = TS_PSA_INTERNAL_TRUSTED_STORAGE_UUID
+};
+
+static const struct rpc_uuid default_protected_store_uuid = {
+	.uuid = TS_PSA_PROTECTED_STORAGE_UUID
+};
 
 /* The storage backed specialization constructed by this factory */
 struct rot_store
 {
 	struct secure_storage_client secure_storage_client;
-	struct ffarpc_caller ffarpc_caller;
+	struct rpc_caller_interface caller;
+	struct rpc_caller_session session;
 	bool in_use;
 };
 
@@ -52,60 +52,45 @@
 /* Used on failure if no association with a storage provider is established */
 static struct null_store null_store;
 
-static int select_candidate_uuids(const uint8_t *candidates[], int max_candidates,
+static int select_candidate_uuids(const struct rpc_uuid *candidates[], int max_candidates,
 				  enum storage_factory_security_class security_class);
 
 
 struct storage_backend *storage_factory_create(
 			enum storage_factory_security_class security_class)
 {
-	struct rpc_caller *storage_caller;
-	uint16_t storage_sp_ids[1];
 	struct rot_store *new_backend = &backend_instance;
-	const uint8_t *candidate_uuids[MAX_CANDIDATE_UUIDS];
+	const struct rpc_uuid *candidate_uuids[MAX_CANDIDATE_UUIDS];
 	int num_candidate_uuids = select_candidate_uuids(candidate_uuids, MAX_CANDIDATE_UUIDS,
 							 security_class);
 
 	struct storage_backend *result = NULL;
 
 	if (num_candidate_uuids && !new_backend->in_use) {
-		uint16_t own_id = 0;
+		rpc_status_t rpc_status = RPC_ERROR_INTERNAL;
 
-		if (sp_discovery_own_id_get(&own_id) != SP_RESULT_OK)
-			return NULL;
-
-		storage_caller = ffarpc_caller_init(&new_backend->ffarpc_caller, own_id);
-		if (!storage_caller)
+		rpc_status = ts_rpc_caller_sp_init(&new_backend->caller);
+		if (rpc_status != RPC_SUCCESS)
 			return NULL;
 
 		for (int i = 0; i < num_candidate_uuids; i++) {
+			rpc_status = rpc_caller_session_find_and_open(&new_backend->session,
+								      &new_backend->caller,
+								      candidate_uuids[i], 4096);
 
-			/* Try discovering candidate endpoints in preference order */
-			if (ffarpc_caller_discover(candidate_uuids[i], storage_sp_ids,
-						   sizeof(storage_sp_ids)/sizeof(uint16_t))) {
-
-				if (ffarpc_caller_open(&new_backend->ffarpc_caller,
-						       storage_sp_ids[0], 0) == 0) {
-
-					result = secure_storage_client_init(
-						&new_backend->secure_storage_client,
-						storage_caller);
-				}
-
+			if (rpc_status == RPC_SUCCESS) {
+				result = secure_storage_client_init(
+					&new_backend->secure_storage_client,
+					&new_backend->session);
 				break;
 			}
 		}
 
-		if (!result) {
-
-			/* Failed to discover or open an RPC session with provider */
-			ffarpc_caller_deinit(&new_backend->ffarpc_caller);
-		}
-
 		new_backend->in_use = (result != NULL);
 	}
 
 	if (!result) {
+		ts_rpc_caller_sp_deinit(&new_backend->caller);
 
 		/**
 		 * Errors during SP initialisation can be difficult to handle so
@@ -125,29 +110,25 @@
 	if (backend) {
 
 		secure_storage_client_deinit(&backend_instance.secure_storage_client);
-		ffarpc_caller_deinit(&backend_instance.ffarpc_caller);
+		rpc_caller_session_close(&backend_instance.session);
+		ts_rpc_caller_sp_deinit(&backend_instance.caller);
 		backend_instance.in_use = false;
 	}
 }
 
-static int select_candidate_uuids(const uint8_t *candidates[],
-							int max_candidates,
-							enum storage_factory_security_class security_class)
+static int select_candidate_uuids(const struct rpc_uuid *candidates[], int max_candidates,
+				  enum storage_factory_security_class security_class)
 {
 	/* Runtime configuration not yet supported so fallback to using default UUIDs */
 	int num_candidates = 0;
 
 	if (max_candidates >= 2) {
-
 		if (security_class == storage_factory_security_class_INTERNAL_TRUSTED) {
-
-			candidates[0] = default_internal_store_uuid;
-			candidates[1] = default_protected_store_uuid;
-		}
-		else {
-
-			candidates[0] = default_protected_store_uuid;
-			candidates[1] = default_internal_store_uuid;
+			candidates[0] = &default_internal_store_uuid;
+			candidates[1] = &default_protected_store_uuid;
+		} else {
+			candidates[0] = &default_protected_store_uuid;
+			candidates[1] = &default_internal_store_uuid;
 		}
 
 		num_candidates = 2;
diff --git a/components/service/secure_storage/frontend/secure_storage_provider/secure_storage_provider.c b/components/service/secure_storage/frontend/secure_storage_provider/secure_storage_provider.c
index 4401dc0..8278521 100644
--- a/components/service/secure_storage/frontend/secure_storage_provider/secure_storage_provider.c
+++ b/components/service/secure_storage/frontend/secure_storage_provider/secure_storage_provider.c
@@ -5,203 +5,174 @@
  */
 
 #include "secure_storage_provider.h"
-#include <protocols/service/secure_storage/packed-c/secure_storage_proto.h>
-#include <protocols/service/psa/packed-c/status.h>
-#include <protocols/rpc/common/packed-c/status.h>
-#include <components/rpc/common/endpoint/rpc_interface.h>
+#include "components/common/utils/include/util.h"
+#include "components/rpc/common/endpoint/rpc_service_interface.h"
+#include "protocols/service/secure_storage/packed-c/secure_storage_proto.h"
 
-
-static rpc_status_t set_handler(void *context, struct call_req *req)
+static rpc_status_t set_handler(void *context, struct rpc_request *req)
 {
 	struct secure_storage_provider *this_context = (struct secure_storage_provider*)context;
-	struct secure_storage_request_set *request_desc;
-	psa_status_t psa_status;
+	struct secure_storage_request_set *request_desc = NULL;
+	size_t request_length = 0;
 
 	/* Checking if the descriptor fits into the request buffer */
-	if (req->req_buf.data_len < sizeof(struct secure_storage_request_set))
-		return TS_RPC_ERROR_INVALID_REQ_BODY;
+	if (req->request.data_length < sizeof(*request_desc))
+		return RPC_ERROR_INVALID_REQUEST_BODY;
 
-	request_desc = (struct secure_storage_request_set *)(req->req_buf.data);
+	request_desc = (struct secure_storage_request_set *)(req->request.data);
 
 	/* Checking for overflow */
-	if (sizeof(struct secure_storage_request_set) + request_desc->data_length < request_desc->data_length)
-		return TS_RPC_ERROR_INVALID_REQ_BODY;
+	if (ADD_OVERFLOW(sizeof(*request_desc), request_desc->data_length, &request_length))
+		return RPC_ERROR_INVALID_REQUEST_BODY;
 
-	/* Checking if descriptor and data fits into the request buffer */
-	if (req->req_buf.data_len < sizeof(struct secure_storage_request_set) + request_desc->data_length)
-		return TS_RPC_ERROR_INVALID_REQ_BODY;
+	/* Checking if the request descriptor and the data fits into the request buffer */
+	if (req->request.data_length < request_length)
+		return RPC_ERROR_INVALID_REQUEST_BODY;
 
-	psa_status = this_context->backend->interface->set(this_context->backend->context,
-				req->caller_id,
-				request_desc->uid,
-				request_desc->data_length,
-				request_desc->p_data,
-				request_desc->create_flags);
-	call_req_set_opstatus(req, psa_status);
+	req->service_status = this_context->backend->interface->set(
+		this_context->backend->context, req->source_id, request_desc->uid,
+		request_desc->data_length, request_desc->p_data,
+		request_desc->create_flags);
 
-	return TS_RPC_CALL_ACCEPTED;
+	return RPC_SUCCESS;
 }
 
-static rpc_status_t get_handler(void *context, struct call_req *req)
+static rpc_status_t get_handler(void *context, struct rpc_request *req)
 {
 	struct secure_storage_provider *this_context = (struct secure_storage_provider*)context;
-	struct secure_storage_request_get *request_desc;
-	psa_status_t psa_status;
+	struct secure_storage_request_get *request_desc = NULL;
 
-	/* Checking if the descriptor fits into the request buffer */
-	if (req->req_buf.data_len < sizeof(struct secure_storage_request_get))
-		return TS_RPC_ERROR_INVALID_REQ_BODY;
+	/* Checking if the request descriptor fits into the request buffer */
+	if (req->request.data_length < sizeof(*request_desc))
+		return RPC_ERROR_INVALID_REQUEST_BODY;
 
-	request_desc = (struct secure_storage_request_get *)(req->req_buf.data);
+	request_desc = (struct secure_storage_request_get *)(req->request.data);
 
 	/* Clip the requested data size if it's too big for the response buffer */
-	size_t data_size = (req->resp_buf.size < request_desc->data_size) ?
-		req->resp_buf.size :
-		request_desc->data_size;
+	size_t data_size = MIN(req->response.size, request_desc->data_size);
 
-	psa_status = this_context->backend->interface->get(this_context->backend->context,
-				req->caller_id, request_desc->uid,
-				request_desc->data_offset,
-				data_size,
-				req->resp_buf.data, &req->resp_buf.data_len);
-	call_req_set_opstatus(req, psa_status);
+	req->service_status = this_context->backend->interface->get(
+		this_context->backend->context, req->source_id, request_desc->uid,
+		request_desc->data_offset, data_size,
+		req->response.data, &req->response.data_length);
 
-	return TS_RPC_CALL_ACCEPTED;
+	return RPC_SUCCESS;
 }
 
-static rpc_status_t get_info_handler(void *context, struct call_req *req)
+static rpc_status_t get_info_handler(void *context, struct rpc_request *req)
 {
 	struct secure_storage_provider *this_context = (struct secure_storage_provider*)context;
-	struct secure_storage_request_get_info *request_desc;
-	struct secure_storage_response_get_info *response_desc;
-	struct psa_storage_info_t storage_info;
-	psa_status_t psa_status;
+	struct secure_storage_request_get_info *request_desc = NULL;
+	struct secure_storage_response_get_info *response_desc = NULL;
+	struct psa_storage_info_t storage_info = { 0 };
 
 	/* Checking if the descriptor fits into the request buffer */
-	if (req->req_buf.data_len < sizeof(struct secure_storage_request_get_info))
-		return TS_RPC_ERROR_INVALID_REQ_BODY;
+	if (req->request.data_length < sizeof(*request_desc))
+		return RPC_ERROR_INVALID_REQUEST_BODY;
 
-	request_desc = (struct secure_storage_request_get_info *)(req->req_buf.data);
+	request_desc = (struct secure_storage_request_get_info *)(req->request.data);
 
 	/* Checking if the response structure would fit the response buffer */
-	if (req->resp_buf.size < sizeof(struct secure_storage_response_get_info))
-		return TS_RPC_ERROR_INVALID_RESP_BODY;
+	if (req->response.size < sizeof(*response_desc))
+		return RPC_ERROR_INVALID_RESPONSE_BODY;
 
-	response_desc = (struct secure_storage_response_get_info *)(req->resp_buf.data);
+	response_desc = (struct secure_storage_response_get_info *)(req->response.data);
 
-	psa_status = this_context->backend->interface->get_info(this_context->backend->context,
-				req->caller_id,
-				request_desc->uid,
-				&storage_info);
-	call_req_set_opstatus(req, psa_status);
+	req->service_status = this_context->backend->interface->get_info(
+		this_context->backend->context, req->source_id, request_desc->uid, &storage_info);
 
-	if (psa_status != PSA_SUCCESS) {
-		req->resp_buf.data_len = 0;
-	}
-	else {
+	if (req->service_status == PSA_SUCCESS) {
 		response_desc->capacity = storage_info.capacity;
 		response_desc->size = storage_info.size;
 		response_desc->flags = storage_info.flags;
-
-		req->resp_buf.data_len = sizeof(struct secure_storage_response_get_info);
+		req->response.data_length = sizeof(*response_desc);
 	}
 
-	return TS_RPC_CALL_ACCEPTED;
+	return RPC_SUCCESS;
 }
 
-static rpc_status_t remove_handler(void *context, struct call_req *req)
+static rpc_status_t remove_handler(void *context, struct rpc_request *req)
 {
 	struct secure_storage_provider *this_context = (struct secure_storage_provider*)context;
-	struct secure_storage_request_remove *request_desc;
-	psa_status_t psa_status;
+	struct secure_storage_request_remove *request_desc = NULL;
 
 	/* Checking if the descriptor fits into the request buffer */
-	if (req->req_buf.data_len < sizeof(struct secure_storage_request_remove))
-		return TS_RPC_ERROR_INVALID_REQ_BODY;
+	if (req->request.data_length < sizeof(*request_desc))
+		return RPC_ERROR_INVALID_REQUEST_BODY;
 
-	request_desc = (struct secure_storage_request_remove *)(req->req_buf.data);
+	request_desc = (struct secure_storage_request_remove *)(req->request.data);
 
-	psa_status = this_context->backend->interface->remove(this_context->backend->context,
-				req->caller_id,
-				request_desc->uid);
-	call_req_set_opstatus(req, psa_status);
+	req->service_status = this_context->backend->interface->remove(
+		this_context->backend->context, req->source_id, request_desc->uid);
 
-	return TS_RPC_CALL_ACCEPTED;
+	return RPC_SUCCESS;
 }
 
-static rpc_status_t create_handler(void *context, struct call_req *req)
+static rpc_status_t create_handler(void *context, struct rpc_request *req)
 {
 	struct secure_storage_provider *this_context = (struct secure_storage_provider*)context;
-	struct secure_storage_request_create *request_desc;
-	psa_status_t psa_status;
+	struct secure_storage_request_create *request_desc = NULL;
 
 	/* Checking if the descriptor fits into the request buffer */
-	if (req->req_buf.data_len < sizeof(struct secure_storage_request_create))
-		return TS_RPC_ERROR_INVALID_REQ_BODY;
+	if (req->request.data_length < sizeof(*request_desc))
+		return RPC_ERROR_INVALID_REQUEST_BODY;
 
-	request_desc = (struct secure_storage_request_create *)(req->req_buf.data);
+	request_desc = (struct secure_storage_request_create *)(req->request.data);
 
-	psa_status = this_context->backend->interface->create(this_context->backend->context,
-				req->caller_id,
-				request_desc->uid,
-				request_desc->capacity,
-				request_desc->create_flags);
-	call_req_set_opstatus(req, psa_status);
+	req->service_status = this_context->backend->interface->create(
+		this_context->backend->context, req->source_id, request_desc->uid,
+		request_desc->capacity, request_desc->create_flags);
 
-	return TS_RPC_CALL_ACCEPTED;
+	return RPC_SUCCESS;
 }
 
-static rpc_status_t set_extended_handler(void *context, struct call_req *req)
+static rpc_status_t set_extended_handler(void *context, struct rpc_request *req)
 {
 	struct secure_storage_provider *this_context = (struct secure_storage_provider*)context;
-	struct secure_storage_request_set_extended *request_desc;
-	psa_status_t psa_status;
+	struct secure_storage_request_set_extended *request_desc = NULL;
+	size_t request_length = 0;
 
 	/* Checking if the descriptor fits into the request buffer */
-	if (req->req_buf.data_len < sizeof(struct secure_storage_request_set_extended))
-		return TS_RPC_ERROR_INVALID_REQ_BODY;
+	if (req->request.data_length < sizeof(*request_desc))
+		return RPC_ERROR_INVALID_REQUEST_BODY;
 
-	request_desc = (struct secure_storage_request_set_extended *)(req->req_buf.data);
+	request_desc = (struct secure_storage_request_set_extended *)(req->request.data);
 
 	/* Checking for overflow */
-	if (sizeof(struct secure_storage_request_set_extended) + request_desc->data_length < request_desc->data_length)
-		return TS_RPC_ERROR_INVALID_REQ_BODY;
+	if (ADD_OVERFLOW(sizeof(*request_desc), request_desc->data_length, &request_length))
+		return RPC_ERROR_INVALID_REQUEST_BODY;
 
-	/* Checking if descriptor and data fits into the request buffer */
-	if (req->req_buf.data_len < sizeof(struct secure_storage_request_set_extended) + request_desc->data_length)
-		return TS_RPC_ERROR_INVALID_REQ_BODY;
+	/* Checking if the request descriptor and the data fits into the request buffer */
+	if (req->request.data_length < request_length)
+		return RPC_ERROR_INVALID_REQUEST_BODY;
 
-	psa_status = this_context->backend->interface->set_extended(this_context->backend->context,
-				req->caller_id,
-				request_desc->uid,
-				request_desc->data_offset,
-				request_desc->data_length,
-				request_desc->p_data);
-	call_req_set_opstatus(req, psa_status);
+	req->service_status = this_context->backend->interface->set_extended(
+		this_context->backend->context, req->source_id, request_desc->uid,
+		request_desc->data_offset, request_desc->data_length, request_desc->p_data);
 
-	return TS_RPC_CALL_ACCEPTED;
+	return RPC_SUCCESS;
 }
 
-static rpc_status_t get_support_handler(void *context, struct call_req *req)
+static rpc_status_t get_support_handler(void *context, struct rpc_request *req)
 {
 	struct secure_storage_provider *this_context = (struct secure_storage_provider*)context;
-	struct secure_storage_response_get_support *response_desc;
+	struct secure_storage_response_get_support *response_desc = NULL;
 	uint32_t feature_map;
 
 	/* Checking if the response structure would fit the response buffer */
-	if (req->resp_buf.size < sizeof(struct secure_storage_response_get_support))
-		return TS_RPC_ERROR_INVALID_RESP_BODY;
+	if (req->response.size < sizeof(struct secure_storage_response_get_support))
+		return RPC_ERROR_INVALID_RESPONSE_BODY;
 
-	response_desc = (struct secure_storage_response_get_support *)(req->resp_buf.data);
+	response_desc = (struct secure_storage_response_get_support *)(req->response.data);
 
 	feature_map = this_context->backend->interface->get_support(this_context->backend->context,
-				req->caller_id);
-	call_req_set_opstatus(req, PSA_SUCCESS);
+				req->source_id);
 
+	req->service_status = PSA_SUCCESS;
 	response_desc->support = feature_map;
-	req->resp_buf.data_len = sizeof(struct secure_storage_response_get_support);
+	req->response.data_length = sizeof(struct secure_storage_response_get_support);
 
-	return TS_RPC_CALL_ACCEPTED;
+	return RPC_SUCCESS;
 }
 
 /* Handler mapping table for service */
@@ -215,25 +186,22 @@
 	{TS_SECURE_STORAGE_OPCODE_GET_SUPPORT,	get_support_handler}
 };
 
-struct rpc_interface *secure_storage_provider_init(struct secure_storage_provider *context,
-												struct storage_backend *backend)
+struct rpc_service_interface *secure_storage_provider_init(struct secure_storage_provider *context,
+							   struct storage_backend *backend,
+							   const struct rpc_uuid *service_uuid)
 {
-	struct rpc_interface *rpc_interface = NULL;
+	struct rpc_service_interface *rpc_interface = NULL;
 
-	if (context == NULL)
-		goto out;
+	if (!context || !backend)
+		return NULL;
 
-	if (backend == NULL)
-		goto out;
-
-	service_provider_init(&context->base_provider, context, handler_table,
+	service_provider_init(&context->base_provider, context, service_uuid, handler_table,
 				  sizeof(handler_table) / sizeof(handler_table[0]));
 
 	rpc_interface = service_provider_get_rpc_interface(&context->base_provider);
 
 	context->backend = backend;
 
-out:
 	return rpc_interface;
 }
 
diff --git a/components/service/secure_storage/frontend/secure_storage_provider/secure_storage_provider.h b/components/service/secure_storage/frontend/secure_storage_provider/secure_storage_provider.h
index 65e49da..4b5f643 100644
--- a/components/service/secure_storage/frontend/secure_storage_provider/secure_storage_provider.h
+++ b/components/service/secure_storage/frontend/secure_storage_provider/secure_storage_provider.h
@@ -7,8 +7,8 @@
 #ifndef SECURE_STORAGE_PROVIDER_H
 #define SECURE_STORAGE_PROVIDER_H
 
-#include <service/common/provider/service_provider.h>
-#include <service/secure_storage/backend/storage_backend.h>
+#include "service/common/provider/service_provider.h"
+#include "service/secure_storage/backend/storage_backend.h"
 
 #ifdef __cplusplus
 extern "C" {
@@ -25,8 +25,9 @@
 	struct storage_backend *backend;
 };
 
-struct rpc_interface *secure_storage_provider_init(struct secure_storage_provider *context,
-										struct storage_backend *backend);
+struct rpc_service_interface *secure_storage_provider_init(struct secure_storage_provider *context,
+							   struct storage_backend *backend,
+							   const struct rpc_uuid *service_uuid);
 
 void secure_storage_provider_deinit(struct secure_storage_provider *context);
 
diff --git a/components/service/secure_storage/frontend/secure_storage_provider/secure_storage_uuid.h b/components/service/secure_storage/frontend/secure_storage_provider/secure_storage_uuid.h
new file mode 100644
index 0000000..ab2112c
--- /dev/null
+++ b/components/service/secure_storage/frontend/secure_storage_provider/secure_storage_uuid.h
@@ -0,0 +1,23 @@
+/*
+ * Copyright (c) 2023, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+#ifndef SECURE_STORAGE_UUID_H
+#define SECURE_STORAGE_UUID_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define TS_PSA_INTERNAL_TRUSTED_STORAGE_UUID \
+{ 0xdc, 0x1e, 0xef, 0x48, 0xb1, 0x7a, 0x4c, 0xcf, 0xac, 0x8b, 0xdf, 0xcf, 0xf7, 0x71, 0x1b, 0x14, }
+
+#define TS_PSA_PROTECTED_STORAGE_UUID \
+{ 0x75, 0x1b, 0xf8, 0x01, 0x3d, 0xde, 0x47, 0x68, 0xa5, 0x14, 0x0f, 0x10, 0xae, 0xed, 0x17, 0x90, }
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* SECURE_STORAGE_UUID_H */
diff --git a/components/service/secure_storage/test/service/its_service_tests.cpp b/components/service/secure_storage/test/service/its_service_tests.cpp
index 8706a1e..78c63af 100644
--- a/components/service/secure_storage/test/service/its_service_tests.cpp
+++ b/components/service/secure_storage/test/service/its_service_tests.cpp
@@ -20,21 +20,18 @@
 {
     void setup()
     {
-        struct rpc_caller *caller;
-        int status;
-
-        m_rpc_session_handle = NULL;
+        m_rpc_session = NULL;
         m_its_service_context = NULL;
 
         service_locator_init();
 
-        m_its_service_context = service_locator_query("sn:trustedfirmware.org:internal-trusted-storage:0", &status);
+        m_its_service_context = service_locator_query("sn:trustedfirmware.org:internal-trusted-storage:0");
         CHECK(m_its_service_context);
 
-        m_rpc_session_handle = service_context_open(m_its_service_context, TS_RPC_ENCODING_PACKED_C, &caller);
-        CHECK(m_rpc_session_handle);
+        m_rpc_session = service_context_open(m_its_service_context);
+        CHECK(m_rpc_session);
 
-        struct storage_backend *storage_backend = secure_storage_client_init(&m_storage_client, caller);
+        struct storage_backend *storage_backend = secure_storage_client_init(&m_storage_client, m_rpc_session);
 
         psa_its_frontend_init(storage_backend);
     }
@@ -44,9 +41,9 @@
         psa_its_frontend_init(NULL);
 
 	if (m_its_service_context) {
-		if (m_rpc_session_handle) {
-			service_context_close(m_its_service_context, m_rpc_session_handle);
-			m_rpc_session_handle = NULL;
+		if (m_rpc_session) {
+			service_context_close(m_its_service_context, m_rpc_session);
+			m_rpc_session = NULL;
 		}
 
 		service_context_relinquish(m_its_service_context);
@@ -56,7 +53,7 @@
         secure_storage_client_deinit(&m_storage_client);
     }
 
-    rpc_session_handle m_rpc_session_handle;
+    struct rpc_caller_session *m_rpc_session;
     struct service_context *m_its_service_context;
     struct secure_storage_client m_storage_client;
 };
@@ -64,4 +61,4 @@
 TEST(ItsServiceTests, storeNewItem)
 {
     its_api_tests::storeNewItem();
-}
+}
\ No newline at end of file
diff --git a/components/service/secure_storage/test/service/ps_service_tests.cpp b/components/service/secure_storage/test/service/ps_service_tests.cpp
index cdb8bb7..4385f60 100644
--- a/components/service/secure_storage/test/service/ps_service_tests.cpp
+++ b/components/service/secure_storage/test/service/ps_service_tests.cpp
@@ -22,21 +22,18 @@
 {
     void setup()
     {
-        struct rpc_caller *caller;
-        int status;
-
-        m_rpc_session_handle = NULL;
+        m_rpc_session = NULL;
         m_its_service_context = NULL;
 
         service_locator_init();
 
-        m_its_service_context = service_locator_query("sn:trustedfirmware.org:protected-storage:0", &status);
+        m_its_service_context = service_locator_query("sn:trustedfirmware.org:protected-storage:0");
         CHECK(m_its_service_context);
 
-        m_rpc_session_handle = service_context_open(m_its_service_context, TS_RPC_ENCODING_PACKED_C, &caller);
-        CHECK(m_rpc_session_handle);
+        m_rpc_session = service_context_open(m_its_service_context);
+        CHECK(m_rpc_session);
 
-        struct storage_backend *storage_backend = secure_storage_client_init(&m_storage_client, caller);
+        struct storage_backend *storage_backend = secure_storage_client_init(&m_storage_client, m_rpc_session);
 
         psa_ps_frontend_init(storage_backend);
         psa_its_frontend_init(storage_backend);
@@ -48,9 +45,9 @@
         psa_its_frontend_init(NULL);
 
 	if (m_its_service_context) {
-		if (m_rpc_session_handle) {
-			service_context_close(m_its_service_context, m_rpc_session_handle);
-			m_rpc_session_handle = NULL;
+		if (m_rpc_session) {
+			service_context_close(m_its_service_context, m_rpc_session);
+			m_rpc_session = NULL;
 		}
 
 		service_context_relinquish(m_its_service_context);
@@ -60,7 +57,7 @@
         secure_storage_client_deinit(&m_storage_client);
     }
 
-    rpc_session_handle m_rpc_session_handle;
+    struct rpc_caller_session *m_rpc_session;
     struct service_context *m_its_service_context;
     struct secure_storage_client m_storage_client;
 };
@@ -78,4 +75,4 @@
 TEST(PsServiceTests, createAndSetExtended)
 {
     ps_api_tests::createAndSetExtended();
-}
+}
\ No newline at end of file
diff --git a/components/service/smm_variable/backend/uefi_variable_store.c b/components/service/smm_variable/backend/uefi_variable_store.c
index de85bc5..16294e8 100644
--- a/components/service/smm_variable/backend/uefi_variable_store.c
+++ b/components/service/smm_variable/backend/uefi_variable_store.c
@@ -697,7 +697,7 @@
 					context->owner_id,
 					info->metadata.uid,
 					0,
-					max_data_len,
+					storage_info.size,
 					data,
 					&got_len);
 
diff --git a/components/service/smm_variable/client/cpp/smm_variable_client.cpp b/components/service/smm_variable/client/cpp/smm_variable_client.cpp
index b6b4ed9..704ddd0 100644
--- a/components/service/smm_variable/client/cpp/smm_variable_client.cpp
+++ b/components/service/smm_variable/client/cpp/smm_variable_client.cpp
@@ -6,20 +6,18 @@
 
 #include <cstring>
 #include <protocols/rpc/common/packed-c/status.h>
-#include <rpc_caller.h>
 #include "smm_variable_client.h"
 
 smm_variable_client::smm_variable_client() :
-	m_caller(NULL),
-	m_err_rpc_status(TS_RPC_CALL_ACCEPTED)
+	session(NULL),
+	m_err_rpc_status(RPC_SUCCESS)
 {
 
 }
 
-smm_variable_client::smm_variable_client(
-	struct rpc_caller *caller) :
-	m_caller(caller),
-	m_err_rpc_status(TS_RPC_CALL_ACCEPTED)
+smm_variable_client::smm_variable_client(struct rpc_caller_session *session) :
+	session(session),
+	m_err_rpc_status(RPC_SUCCESS)
 {
 
 }
@@ -29,9 +27,9 @@
 
 }
 
-void smm_variable_client::set_caller(struct rpc_caller *caller)
+void smm_variable_client::set_caller_session(struct rpc_caller_session *session)
 {
-	m_caller = caller;
+	this->session = session;
 }
 
 int smm_variable_client::err_rpc_status() const
@@ -71,13 +69,13 @@
 	rpc_call_handle call_handle;
 	uint8_t *req_buf;
 
-	call_handle = rpc_caller_begin(m_caller, &req_buf, req_len);
+	call_handle = rpc_caller_session_begin(session, &req_buf, req_len, 0);
 
 	if (call_handle) {
 
 		uint8_t *resp_buf;
-        size_t resp_len;
-		rpc_opstatus_t opstatus;
+		size_t resp_len;
+		service_status_t service_status;
 
 		SMM_VARIABLE_COMMUNICATE_ACCESS_VARIABLE *access_var =
 			(SMM_VARIABLE_COMMUNICATE_ACCESS_VARIABLE*)req_buf;
@@ -95,19 +93,19 @@
 		if (override_name_size) access_var->NameSize = override_name_size;
 		if (override_data_size) access_var->DataSize = override_data_size;
 
-		m_err_rpc_status = rpc_caller_invoke(m_caller, call_handle,
-			SMM_VARIABLE_FUNCTION_SET_VARIABLE, &opstatus, &resp_buf, &resp_len);
+		m_err_rpc_status = rpc_caller_session_invoke(call_handle,
+			SMM_VARIABLE_FUNCTION_SET_VARIABLE, &resp_buf, &resp_len, &service_status);
 
-		if (m_err_rpc_status == TS_RPC_CALL_ACCEPTED) {
+		if (m_err_rpc_status == RPC_SUCCESS) {
 
-			efi_status = opstatus;
+			efi_status = service_status;
 		}
 		else {
 
 			efi_status = rpc_to_efi_status();
 		}
 
-		rpc_caller_end(m_caller, call_handle);
+		rpc_caller_session_end(call_handle);
 	}
 
 	return efi_status;
@@ -138,17 +136,18 @@
 	std::vector<int16_t> var_name = to_variable_name(name);
 	size_t name_size = var_name.size() * sizeof(int16_t);
 	size_t req_len = SMM_VARIABLE_COMMUNICATE_ACCESS_VARIABLE_SIZE(name_size, 0);
+	size_t resp_len = SMM_VARIABLE_COMMUNICATE_ACCESS_VARIABLE_SIZE(name_size, 0);
 
 	rpc_call_handle call_handle;
 	uint8_t *req_buf;
 
-	call_handle = rpc_caller_begin(m_caller, &req_buf, req_len);
+	call_handle = rpc_caller_session_begin(session, &req_buf, req_len, resp_len);
 
 	if (call_handle) {
 
 		uint8_t *resp_buf;
-        size_t resp_len;
-		rpc_opstatus_t opstatus;
+		size_t resp_len;
+		service_status_t service_status;
 
 		SMM_VARIABLE_COMMUNICATE_ACCESS_VARIABLE *access_var =
 			(SMM_VARIABLE_COMMUNICATE_ACCESS_VARIABLE*)req_buf;
@@ -162,12 +161,12 @@
 		/* To support invalid size testing, use overrides if set */
 		if (override_name_size) access_var->NameSize = override_name_size;
 
-		m_err_rpc_status = rpc_caller_invoke(m_caller, call_handle,
-			SMM_VARIABLE_FUNCTION_GET_VARIABLE, &opstatus, &resp_buf, &resp_len);
+		m_err_rpc_status = rpc_caller_session_invoke(call_handle,
+			SMM_VARIABLE_FUNCTION_GET_VARIABLE, &resp_buf, &resp_len, &service_status);
 
-		if (m_err_rpc_status == TS_RPC_CALL_ACCEPTED) {
+		if (m_err_rpc_status == RPC_SUCCESS) {
 
-			efi_status = opstatus;
+			efi_status = service_status;
 
 			if (resp_len >= SMM_VARIABLE_COMMUNICATE_ACCESS_VARIABLE_NAME_OFFSET) {
 
@@ -198,7 +197,7 @@
 			efi_status = rpc_to_efi_status();
 		}
 
-		rpc_caller_end(m_caller, call_handle);
+		rpc_caller_session_end(call_handle);
 	}
 
 	return efi_status;
@@ -231,16 +230,17 @@
 	efi_status_t efi_status = EFI_NOT_READY;
 
 	size_t req_len = sizeof(SMM_VARIABLE_COMMUNICATE_QUERY_VARIABLE_INFO);
+	size_t resp_len = sizeof(SMM_VARIABLE_COMMUNICATE_QUERY_VARIABLE_INFO);
 	rpc_call_handle call_handle;
 	uint8_t *req_buf;
 
-	call_handle = rpc_caller_begin(m_caller, &req_buf, req_len);
+	call_handle = rpc_caller_session_begin(session, &req_buf, req_len, resp_len);
 
 	if (call_handle) {
 
 		uint8_t *resp_buf;
-        size_t resp_len;
-		rpc_opstatus_t opstatus;
+		size_t resp_len;
+		service_status_t service_status;
 
 		SMM_VARIABLE_COMMUNICATE_QUERY_VARIABLE_INFO *query =
 			(SMM_VARIABLE_COMMUNICATE_QUERY_VARIABLE_INFO*)req_buf;
@@ -250,12 +250,13 @@
 		query->MaximumVariableStorageSize = 0;
 		query->RemainingVariableStorageSize = 0;
 
-		m_err_rpc_status = rpc_caller_invoke(m_caller, call_handle,
-			SMM_VARIABLE_FUNCTION_QUERY_VARIABLE_INFO, &opstatus, &resp_buf, &resp_len);
+		m_err_rpc_status = rpc_caller_session_invoke(call_handle,
+			SMM_VARIABLE_FUNCTION_QUERY_VARIABLE_INFO, &resp_buf, &resp_len,
+			&service_status);
 
-		if (m_err_rpc_status == TS_RPC_CALL_ACCEPTED) {
+		if (m_err_rpc_status == RPC_SUCCESS) {
 
-			efi_status = opstatus;
+			efi_status = service_status;
 
 			if (efi_status == EFI_SUCCESS) {
 
@@ -282,7 +283,7 @@
 			efi_status = rpc_to_efi_status();
 		}
 
-		rpc_caller_end(m_caller, call_handle);
+		rpc_caller_session_end(call_handle);
 	}
 
 	return efi_status;
@@ -298,17 +299,18 @@
 	std::vector<int16_t> var_name = to_variable_name(name);
 	size_t name_size = var_name.size() * sizeof(int16_t);
 	size_t req_len = SMM_VARIABLE_COMMUNICATE_GET_NEXT_VARIABLE_NAME_SIZE(name_size);
+	size_t resp_len = SMM_VARIABLE_COMMUNICATE_GET_NEXT_VARIABLE_NAME_SIZE(name_size);
 
 	rpc_call_handle call_handle;
 	uint8_t *req_buf;
 
-	call_handle = rpc_caller_begin(m_caller, &req_buf, req_len);
+	call_handle = rpc_caller_session_begin(session, &req_buf, req_len, resp_len);
 
 	if (call_handle) {
 
 		uint8_t *resp_buf;
-        size_t resp_len;
-		rpc_opstatus_t opstatus;
+		size_t resp_len;
+		service_status_t service_status;
 
 		SMM_VARIABLE_COMMUNICATE_GET_NEXT_VARIABLE_NAME *next_var =
 			(SMM_VARIABLE_COMMUNICATE_GET_NEXT_VARIABLE_NAME*)req_buf;
@@ -321,12 +323,13 @@
 		/* To support invalid size testing, use overrides if set */
 		if (override_name_size) next_var->NameSize = override_name_size;
 
-		m_err_rpc_status = rpc_caller_invoke(m_caller, call_handle,
-			SMM_VARIABLE_FUNCTION_GET_NEXT_VARIABLE_NAME, &opstatus, &resp_buf, &resp_len);
+		m_err_rpc_status = rpc_caller_session_invoke(call_handle,
+			SMM_VARIABLE_FUNCTION_GET_NEXT_VARIABLE_NAME, &resp_buf, &resp_len,
+			&service_status);
 
-		if (m_err_rpc_status == TS_RPC_CALL_ACCEPTED) {
+		if (m_err_rpc_status == RPC_SUCCESS) {
 
-			efi_status = opstatus;
+			efi_status = service_status;
 
 			if (efi_status == EFI_SUCCESS) {
 
@@ -352,7 +355,7 @@
 			efi_status = rpc_to_efi_status();
 		}
 
-		rpc_caller_end(m_caller, call_handle);
+		rpc_caller_session_end(call_handle);
 	}
 
 	return efi_status;
@@ -362,31 +365,31 @@
 {
 	efi_status_t efi_status = EFI_NOT_READY;
 
-	size_t req_len = 0;
 	rpc_call_handle call_handle;
 	uint8_t *req_buf;
 
-	call_handle = rpc_caller_begin(m_caller, &req_buf, req_len);
+	call_handle = rpc_caller_session_begin(session, &req_buf, 0, 0);
 
 	if (call_handle) {
 
 		uint8_t *resp_buf;
-        size_t resp_len;
-		rpc_opstatus_t opstatus;
+		size_t resp_len;
+		service_status_t service_status;
 
-		m_err_rpc_status = rpc_caller_invoke(m_caller, call_handle,
-			SMM_VARIABLE_FUNCTION_EXIT_BOOT_SERVICE, &opstatus, &resp_buf, &resp_len);
+		m_err_rpc_status = rpc_caller_session_invoke(call_handle,
+			SMM_VARIABLE_FUNCTION_EXIT_BOOT_SERVICE, &resp_buf, &resp_len,
+			&service_status);
 
-		if (m_err_rpc_status == TS_RPC_CALL_ACCEPTED) {
+		if (m_err_rpc_status == RPC_SUCCESS) {
 
-			efi_status = opstatus;
+			efi_status = service_status;
 		}
 		else {
 
 			efi_status = rpc_to_efi_status();
 		}
 
-		rpc_caller_end(m_caller, call_handle);
+		rpc_caller_session_end(call_handle);
 	}
 
 	return efi_status;
@@ -415,17 +418,18 @@
 	std::vector<int16_t> var_name = to_variable_name(name);
 	size_t name_size = var_name.size() * sizeof(int16_t);
 	size_t req_len = SMM_VARIABLE_COMMUNICATE_VAR_CHECK_VARIABLE_PROPERTY_SIZE(name_size);
+	size_t resp_len = SMM_VARIABLE_COMMUNICATE_VAR_CHECK_VARIABLE_PROPERTY_SIZE(name_size);
 
 	rpc_call_handle call_handle;
 	uint8_t *req_buf;
 
-	call_handle = rpc_caller_begin(m_caller, &req_buf, req_len);
+	call_handle = rpc_caller_session_begin(session, &req_buf, req_len, resp_len);
 
 	if (call_handle) {
 
 		uint8_t *resp_buf;
-        size_t resp_len;
-		rpc_opstatus_t opstatus;
+		size_t resp_len;
+		service_status_t service_status;
 
 		SMM_VARIABLE_COMMUNICATE_VAR_CHECK_VARIABLE_PROPERTY *req_msg =
 			(SMM_VARIABLE_COMMUNICATE_VAR_CHECK_VARIABLE_PROPERTY*)req_buf;
@@ -439,20 +443,20 @@
 		/* To support invalid size testing, use override if set */
 		if (override_name_size) req_msg->NameSize = override_name_size;
 
-		m_err_rpc_status = rpc_caller_invoke(m_caller, call_handle,
-			SMM_VARIABLE_FUNCTION_VAR_CHECK_VARIABLE_PROPERTY_SET, &opstatus,
-			&resp_buf, &resp_len);
+		m_err_rpc_status = rpc_caller_session_invoke(call_handle,
+			SMM_VARIABLE_FUNCTION_VAR_CHECK_VARIABLE_PROPERTY_SET, &resp_buf, &resp_len,
+			&service_status);
 
-		if (m_err_rpc_status == TS_RPC_CALL_ACCEPTED) {
+		if (m_err_rpc_status == RPC_SUCCESS) {
 
-			efi_status = opstatus;
+			efi_status = service_status;
 		}
 		else {
 
 			efi_status = rpc_to_efi_status();
 		}
 
-		rpc_caller_end(m_caller, call_handle);
+		rpc_caller_session_end(call_handle);
 	}
 
 	return efi_status;
@@ -481,17 +485,18 @@
 	std::vector<int16_t> var_name = to_variable_name(name);
 	size_t name_size = var_name.size() * sizeof(int16_t);
 	size_t req_len = SMM_VARIABLE_COMMUNICATE_VAR_CHECK_VARIABLE_PROPERTY_SIZE(name_size);
+	size_t resp_len = SMM_VARIABLE_COMMUNICATE_VAR_CHECK_VARIABLE_PROPERTY_SIZE(name_size);
 
 	rpc_call_handle call_handle;
 	uint8_t *req_buf;
 
-	call_handle = rpc_caller_begin(m_caller, &req_buf, req_len);
+	call_handle = rpc_caller_session_begin(session, &req_buf, req_len, resp_len);
 
 	if (call_handle) {
 
 		uint8_t *resp_buf;
         size_t resp_len;
-		rpc_opstatus_t opstatus;
+		service_status_t service_status;
 
 		SMM_VARIABLE_COMMUNICATE_VAR_CHECK_VARIABLE_PROPERTY *req_msg =
 			(SMM_VARIABLE_COMMUNICATE_VAR_CHECK_VARIABLE_PROPERTY*)req_buf;
@@ -504,13 +509,13 @@
 		/* To support invalid size testing, use overrides if set */
 		if (override_name_size) req_msg->NameSize = override_name_size;
 
-		m_err_rpc_status = rpc_caller_invoke(m_caller, call_handle,
-			SMM_VARIABLE_FUNCTION_VAR_CHECK_VARIABLE_PROPERTY_GET, &opstatus,
-			&resp_buf, &resp_len);
+		m_err_rpc_status = rpc_caller_session_invoke(call_handle,
+			SMM_VARIABLE_FUNCTION_VAR_CHECK_VARIABLE_PROPERTY_GET, &resp_buf, &resp_len,
+			&service_status);
 
-		if (m_err_rpc_status == TS_RPC_CALL_ACCEPTED) {
+		if (m_err_rpc_status == RPC_SUCCESS) {
 
-			efi_status = opstatus;
+			efi_status = service_status;
 
 			if (efi_status == EFI_SUCCESS) {
 
@@ -535,7 +540,7 @@
 			efi_status = rpc_to_efi_status();
 		}
 
-		rpc_caller_end(m_caller, call_handle);
+		rpc_caller_session_end(call_handle);
 	}
 
 	return efi_status;
@@ -547,23 +552,25 @@
 	efi_status_t efi_status = EFI_NOT_READY;
 
 	size_t req_len = 0;
+	size_t resp_len = sizeof(SMM_VARIABLE_COMMUNICATE_GET_PAYLOAD_SIZE);
 	rpc_call_handle call_handle;
 	uint8_t *req_buf;
 
-	call_handle = rpc_caller_begin(m_caller, &req_buf, req_len);
+	call_handle = rpc_caller_session_begin(session, &req_buf, req_len, resp_len);
 
 	if (call_handle) {
 
 		uint8_t *resp_buf;
-        size_t resp_len;
-		rpc_opstatus_t opstatus;
+		size_t resp_len;
+		service_status_t service_status;
 
-		m_err_rpc_status = rpc_caller_invoke(m_caller, call_handle,
-			SMM_VARIABLE_FUNCTION_GET_PAYLOAD_SIZE, &opstatus, &resp_buf, &resp_len);
+		m_err_rpc_status = rpc_caller_session_invoke(call_handle,
+			SMM_VARIABLE_FUNCTION_GET_PAYLOAD_SIZE, &resp_buf, &resp_len,
+			&service_status);
 
-		if (m_err_rpc_status == TS_RPC_CALL_ACCEPTED) {
+		if (m_err_rpc_status == RPC_SUCCESS) {
 
-			efi_status = opstatus;
+			efi_status = service_status;
 
 			if (efi_status == EFI_SUCCESS) {
 
@@ -585,7 +592,7 @@
 			efi_status = rpc_to_efi_status();
 		}
 
-		rpc_caller_end(m_caller, call_handle);
+		rpc_caller_session_end(call_handle);
 	}
 
 	return efi_status;
@@ -597,38 +604,29 @@
 
 	switch (m_err_rpc_status)
 	{
-		case TS_RPC_ERROR_EP_DOES_NOT_EXIT:
-			efi_status = EFI_UNSUPPORTED;
-			break;
-		case TS_RPC_ERROR_INVALID_OPCODE:
-			efi_status = EFI_UNSUPPORTED;
-			break;
-		case TS_RPC_ERROR_SERIALIZATION_NOT_SUPPORTED:
-			efi_status = EFI_PROTOCOL_ERROR;
-			break;
-		case TS_RPC_ERROR_INVALID_REQ_BODY:
-			efi_status = EFI_PROTOCOL_ERROR;
-			break;
-		case TS_RPC_ERROR_INVALID_RESP_BODY:
+		case RPC_ERROR_INTERNAL:
 			efi_status = EFI_DEVICE_ERROR;
 			break;
-		case TS_RPC_ERROR_RESOURCE_FAILURE:
-			efi_status = EFI_OUT_OF_RESOURCES;
+		case RPC_ERROR_INVALID_VALUE:
+			efi_status = EFI_INVALID_PARAMETER;
 			break;
-		case TS_RPC_ERROR_NOT_READY:
+		case RPC_ERROR_NOT_FOUND:
+			efi_status = EFI_UNSUPPORTED;
+			break;
+		case RPC_ERROR_INVALID_STATE:
 			efi_status = EFI_NOT_READY;
 			break;
-		case TS_RPC_ERROR_INVALID_TRANSACTION:
-			efi_status = EFI_INVALID_PARAMETER;
+		case RPC_ERROR_TRANSPORT_LAYER:
+			efi_status = EFI_PROTOCOL_ERROR;
 			break;
-		case TS_RPC_ERROR_INTERNAL:
+		case RPC_ERROR_INVALID_REQUEST_BODY:
+			efi_status = EFI_PROTOCOL_ERROR;
+			break;
+		case RPC_ERROR_INVALID_RESPONSE_BODY:
 			efi_status = EFI_DEVICE_ERROR;
 			break;
-		case TS_RPC_ERROR_INVALID_PARAMETER:
-			efi_status = EFI_INVALID_PARAMETER;
-			break;
-		case TS_RPC_ERROR_INTERFACE_DOES_NOT_EXIST:
-			efi_status = EFI_UNSUPPORTED;
+		case RPC_ERROR_RESOURCE_FAILURE:
+			efi_status = EFI_OUT_OF_RESOURCES;
 			break;
 		default:
 			break;
diff --git a/components/service/smm_variable/client/cpp/smm_variable_client.h b/components/service/smm_variable/client/cpp/smm_variable_client.h
index 1841d70..10992ad 100644
--- a/components/service/smm_variable/client/cpp/smm_variable_client.h
+++ b/components/service/smm_variable/client/cpp/smm_variable_client.h
@@ -12,8 +12,8 @@
 #include <vector>
 #include <protocols/common/efi/efi_status.h>
 #include <protocols/service/smm_variable/smm_variable_proto.h>
+#include "components/rpc/common/caller/rpc_caller_session.h"
 
-struct rpc_caller;
 
 /*
  * Provides a C++ client interface for accessing an instance of the smm-variable service.
@@ -25,10 +25,10 @@
 public:
 
 	smm_variable_client();
-	smm_variable_client(struct rpc_caller *caller);
+	smm_variable_client(struct rpc_caller_session *session);
 	~smm_variable_client();
 
-	void set_caller(struct rpc_caller *caller);
+	void set_caller_session(struct rpc_caller_session *session);
 	int err_rpc_status() const;
 
 	/* Set a string type variable */
@@ -123,7 +123,7 @@
 	static std::vector<int16_t> to_variable_name(const std::wstring &string);
 	static const std::wstring from_variable_name(const int16_t *name, size_t name_size);
 
-	struct rpc_caller *m_caller;
+	struct rpc_caller_session *session;
 	int m_err_rpc_status;
 };
 
diff --git a/components/service/smm_variable/frontend/mm_communicate/smm_variable_mm_service.c b/components/service/smm_variable/frontend/mm_communicate/smm_variable_mm_service.c
index 585fbde..1fc6be6 100644
--- a/components/service/smm_variable/frontend/mm_communicate/smm_variable_mm_service.c
+++ b/components/service/smm_variable/frontend/mm_communicate/smm_variable_mm_service.c
@@ -12,45 +12,33 @@
 	struct rpc_interface *smm_variable_rpc_interface;
 };
 
-static rpc_opstatus_t convert_rpc_status(rpc_status_t rpc_status)
+static service_status_t convert_rpc_status(rpc_status_t rpc_status)
 {
 	switch (rpc_status) {
-	case TS_RPC_CALL_ACCEPTED:
+	case RPC_SUCCESS:
 		return MM_RETURN_CODE_SUCCESS;
 
-	case TS_RPC_ERROR_EP_DOES_NOT_EXIT:
+	case RPC_ERROR_INTERNAL:
+		return MM_RETURN_CODE_INVALID_PARAMETER;
+
+	case RPC_ERROR_INVALID_VALUE:
+		return MM_RETURN_CODE_INVALID_PARAMETER;
+
+	case RPC_ERROR_NOT_FOUND:
 		return MM_RETURN_CODE_NOT_SUPPORTED;
 
-	case TS_RPC_ERROR_INVALID_OPCODE:
+	case RPC_ERROR_INVALID_STATE:
 		return MM_RETURN_CODE_INVALID_PARAMETER;
 
-	case TS_RPC_ERROR_SERIALIZATION_NOT_SUPPORTED:
+	case RPC_ERROR_TRANSPORT_LAYER:
 		return MM_RETURN_CODE_INVALID_PARAMETER;
 
-	case TS_RPC_ERROR_INVALID_REQ_BODY:
+	case RPC_ERROR_INVALID_REQUEST_BODY:
 		return MM_RETURN_CODE_INVALID_PARAMETER;
 
-	case TS_RPC_ERROR_INVALID_RESP_BODY:
+	case RPC_ERROR_INVALID_RESPONSE_BODY:
 		return MM_RETURN_CODE_INVALID_PARAMETER;
 
-	case TS_RPC_ERROR_RESOURCE_FAILURE:
-		return MM_RETURN_CODE_NOT_SUPPORTED;
-
-	case TS_RPC_ERROR_NOT_READY:
-		return MM_RETURN_CODE_NOT_SUPPORTED;
-
-	case TS_RPC_ERROR_INVALID_TRANSACTION:
-		return MM_RETURN_CODE_INVALID_PARAMETER;
-
-	case TS_RPC_ERROR_INTERNAL:
-		return MM_RETURN_CODE_NOT_SUPPORTED;
-
-	case TS_RPC_ERROR_INVALID_PARAMETER:
-		return MM_RETURN_CODE_INVALID_PARAMETER;
-
-	case TS_RPC_ERROR_INTERFACE_DOES_NOT_EXIST:
-		return MM_RETURN_CODE_NOT_SUPPORTED;
-
 	default:
 		return MM_RETURN_CODE_NOT_SUPPORTED;
 	}
@@ -61,39 +49,39 @@
 {
 	SMM_VARIABLE_COMMUNICATE_HEADER *header = NULL;
 	struct smm_variable_mm_service *service = iface->context;
-	struct call_req rpc_req = { 0 };
-	rpc_status_t rpc_status = TS_RPC_ERROR_INTERNAL;
+	struct rpc_request rpc_req = { 0 };
+	rpc_status_t rpc_status = RPC_ERROR_INTERNAL;
 
-	if (mm_req->req_buf.data_len < SMM_VARIABLE_COMMUNICATE_HEADER_SIZE)
+	if (mm_req->req_buf.data_length < SMM_VARIABLE_COMMUNICATE_HEADER_SIZE)
 		return MM_RETURN_CODE_DENIED;
 
 	header = (SMM_VARIABLE_COMMUNICATE_HEADER *)mm_req->req_buf.data;
 
 	rpc_req.opcode = header->Function;
-	rpc_req.req_buf.data = header->Data;
-	rpc_req.req_buf.data_len = mm_req->req_buf.data_len - SMM_VARIABLE_COMMUNICATE_HEADER_SIZE;
-	rpc_req.req_buf.size = mm_req->req_buf.size - SMM_VARIABLE_COMMUNICATE_HEADER_SIZE;
+	rpc_req.request.data = header->Data;
+	rpc_req.request.data_length = mm_req->req_buf.data_length - SMM_VARIABLE_COMMUNICATE_HEADER_SIZE;
+	rpc_req.request.size = mm_req->req_buf.size - SMM_VARIABLE_COMMUNICATE_HEADER_SIZE;
 
-	rpc_req.resp_buf.data = header->Data;
-	rpc_req.resp_buf.data_len = 0;
-	rpc_req.resp_buf.size = mm_req->resp_buf.size - SMM_VARIABLE_COMMUNICATE_HEADER_SIZE;
+	rpc_req.response.data = header->Data;
+	rpc_req.response.data_length = 0;
+	rpc_req.response.size = mm_req->resp_buf.size - SMM_VARIABLE_COMMUNICATE_HEADER_SIZE;
 
 	rpc_status = service->iface->receive(service->iface, &rpc_req);
 
-	header->ReturnStatus = rpc_req.opstatus;
+	header->ReturnStatus = rpc_req.service_status;
 
-	if (ADD_OVERFLOW(rpc_req.resp_buf.data_len, SMM_VARIABLE_COMMUNICATE_HEADER_SIZE,
-			 &mm_req->resp_buf.data_len))
+	if (ADD_OVERFLOW(rpc_req.response.data_length, SMM_VARIABLE_COMMUNICATE_HEADER_SIZE,
+			 &mm_req->resp_buf.data_length))
 		return MM_RETURN_CODE_NO_MEMORY;
 
-	if (mm_req->resp_buf.data_len > mm_req->resp_buf.size)
+	if (mm_req->resp_buf.data_length > mm_req->resp_buf.size)
 		return MM_RETURN_CODE_NO_MEMORY;
 
 	return convert_rpc_status(rpc_status);
 }
 
 struct mm_service_interface *smm_variable_mm_service_init(struct smm_variable_mm_service *service,
-						       struct rpc_interface *iface)
+						       struct rpc_service_interface *iface)
 {
 	assert(service != NULL);
 	assert(iface != NULL);
diff --git a/components/service/smm_variable/frontend/mm_communicate/smm_variable_mm_service.h b/components/service/smm_variable/frontend/mm_communicate/smm_variable_mm_service.h
index 420419f..f1f2cc5 100644
--- a/components/service/smm_variable/frontend/mm_communicate/smm_variable_mm_service.h
+++ b/components/service/smm_variable/frontend/mm_communicate/smm_variable_mm_service.h
@@ -6,7 +6,7 @@
 #ifndef SMM_VARIABLE_MM_SERVICE_H_
 #define SMM_VARIABLE_MM_SERVICE_H_
 
-#include "components/rpc/common/endpoint/rpc_interface.h"
+#include "components/rpc/common/endpoint/rpc_service_interface.h"
 #include "components/rpc/mm_communicate/endpoint/sp/mm_communicate_call_ep.h"
 #include "protocols/service/smm_variable/smm_variable_proto.h"
 
@@ -20,11 +20,11 @@
  */
 struct smm_variable_mm_service {
 	struct mm_service_interface mm_service;
-	struct rpc_interface *iface;
+	struct rpc_service_interface *iface;
 };
 
 struct mm_service_interface *smm_variable_mm_service_init(struct smm_variable_mm_service *service,
-							  struct rpc_interface *iface);
+							  struct rpc_service_interface *iface);
 
 #ifdef __cplusplus
 }
diff --git a/components/service/smm_variable/frontend/mm_communicate/test/test_smm_variable_mm_service.cpp b/components/service/smm_variable/frontend/mm_communicate/test/test_smm_variable_mm_service.cpp
index 1973033..ca74884 100644
--- a/components/service/smm_variable/frontend/mm_communicate/test/test_smm_variable_mm_service.cpp
+++ b/components/service/smm_variable/frontend/mm_communicate/test/test_smm_variable_mm_service.cpp
@@ -33,8 +33,8 @@
 	}
 
 	struct smm_variable_mm_service service = { 0 };
-	struct rpc_interface rpc_iface = { 0 };
-	struct call_req rpc_req = { 0 };
+	struct rpc_service_interface rpc_iface = { 0 };
+	struct rpc_request rpc_req = { 0 };
 	struct mm_service_call_req mm_req = { 0 };
 };
 
@@ -75,7 +75,7 @@
 
 	mm_service = smm_variable_mm_service_init(&service, &rpc_iface);
 
-	mm_req.req_buf.data_len = SMM_VARIABLE_COMMUNICATE_HEADER_SIZE - 1;
+	mm_req.req_buf.data_length = SMM_VARIABLE_COMMUNICATE_HEADER_SIZE - 1;
 	result = mm_service->receive(mm_service, &mm_req);
 	LONGS_EQUAL(MM_RETURN_CODE_DENIED, result);
 }
@@ -88,36 +88,36 @@
 	int32_t result = 0;
 
 	mm_req.req_buf.size = sizeof(buffer);
-	mm_req.req_buf.data_len = SMM_VARIABLE_COMMUNICATE_HEADER_SIZE;
+	mm_req.req_buf.data_length = SMM_VARIABLE_COMMUNICATE_HEADER_SIZE;
 	mm_req.req_buf.data = buffer;
 
 	mm_req.resp_buf.size = sizeof(buffer);
-	mm_req.resp_buf.data_len = 0;
+	mm_req.resp_buf.data_length = 0;
 	mm_req.resp_buf.data = buffer;
 
 	header->Function = 0x0123456789abcdefULL;
 	header->ReturnStatus = 0;
 
 	rpc_req.opcode = header->Function;
-	rpc_req.opstatus = 0xfedcba9876543210ULL;
-	rpc_req.req_buf.size = sizeof(buffer) - SMM_VARIABLE_COMMUNICATE_HEADER_SIZE;
-	rpc_req.req_buf.data_len = 0;
-	rpc_req.req_buf.data = buffer + SMM_VARIABLE_COMMUNICATE_HEADER_SIZE;
-	rpc_req.resp_buf.size = sizeof(buffer) - SMM_VARIABLE_COMMUNICATE_HEADER_SIZE;
-	rpc_req.resp_buf.data_len = 16;
-	rpc_req.resp_buf.data = buffer + SMM_VARIABLE_COMMUNICATE_HEADER_SIZE;
+	rpc_req.service_status = 0xfedcba9876543210ULL;
+	rpc_req.request.size = sizeof(buffer) - SMM_VARIABLE_COMMUNICATE_HEADER_SIZE;
+	rpc_req.request.data_length = 0;
+	rpc_req.request.data = buffer + SMM_VARIABLE_COMMUNICATE_HEADER_SIZE;
+	rpc_req.response.size = sizeof(buffer) - SMM_VARIABLE_COMMUNICATE_HEADER_SIZE;
+	rpc_req.response.data_length = 16;
+	rpc_req.response.data = buffer + SMM_VARIABLE_COMMUNICATE_HEADER_SIZE;
 
 	rpc_iface.receive = mock_rpc_interface_receive;
 
 	mm_service = smm_variable_mm_service_init(&service, &rpc_iface);
 
-	expect_mock_rpc_interface_receive(&rpc_iface, &rpc_req, TS_RPC_CALL_ACCEPTED);
+	expect_mock_rpc_interface_receive(&rpc_iface, &rpc_req, RPC_SUCCESS);
 	result = mm_service->receive(mm_service, &mm_req);
 
 	LONGS_EQUAL(MM_RETURN_CODE_SUCCESS, result);
-	UNSIGNED_LONGLONGS_EQUAL(rpc_req.opstatus, header->ReturnStatus);
-	UNSIGNED_LONGLONGS_EQUAL(rpc_req.resp_buf.data_len + SMM_VARIABLE_COMMUNICATE_HEADER_SIZE,
-				 mm_req.resp_buf.data_len);
+	UNSIGNED_LONGLONGS_EQUAL(rpc_req.service_status, header->ReturnStatus);
+	UNSIGNED_LONGLONGS_EQUAL(rpc_req.response.data_length + SMM_VARIABLE_COMMUNICATE_HEADER_SIZE,
+				 mm_req.resp_buf.data_length);
 }
 
 TEST(smm_variable_mm_service, receive_data)
@@ -128,36 +128,36 @@
 	int32_t result = 0;
 
 	mm_req.req_buf.size = sizeof(buffer);
-	mm_req.req_buf.data_len = SMM_VARIABLE_COMMUNICATE_HEADER_SIZE + 32;
+	mm_req.req_buf.data_length = SMM_VARIABLE_COMMUNICATE_HEADER_SIZE + 32;
 	mm_req.req_buf.data = buffer;
 
 	mm_req.resp_buf.size = sizeof(buffer);
-	mm_req.resp_buf.data_len = 0;
+	mm_req.resp_buf.data_length = 0;
 	mm_req.resp_buf.data = buffer;
 
 	header->Function = 0x0123456789abcdefULL;
 	header->ReturnStatus = 0;
 
 	rpc_req.opcode = header->Function;
-	rpc_req.opstatus = 0xfedcba9876543210ULL;
-	rpc_req.req_buf.size = sizeof(buffer) - SMM_VARIABLE_COMMUNICATE_HEADER_SIZE;
-	rpc_req.req_buf.data_len = 32;
-	rpc_req.req_buf.data = buffer + SMM_VARIABLE_COMMUNICATE_HEADER_SIZE;
-	rpc_req.resp_buf.size = sizeof(buffer) - SMM_VARIABLE_COMMUNICATE_HEADER_SIZE;
-	rpc_req.resp_buf.data_len = 16;
-	rpc_req.resp_buf.data = buffer + SMM_VARIABLE_COMMUNICATE_HEADER_SIZE;
+	rpc_req.service_status = 0xfedcba9876543210ULL;
+	rpc_req.request.size = sizeof(buffer) - SMM_VARIABLE_COMMUNICATE_HEADER_SIZE;
+	rpc_req.request.data_length = 32;
+	rpc_req.request.data = buffer + SMM_VARIABLE_COMMUNICATE_HEADER_SIZE;
+	rpc_req.response.size = sizeof(buffer) - SMM_VARIABLE_COMMUNICATE_HEADER_SIZE;
+	rpc_req.response.data_length = 16;
+	rpc_req.response.data = buffer + SMM_VARIABLE_COMMUNICATE_HEADER_SIZE;
 
 	rpc_iface.receive = mock_rpc_interface_receive;
 
 	mm_service = smm_variable_mm_service_init(&service, &rpc_iface);
 
-	expect_mock_rpc_interface_receive(&rpc_iface, &rpc_req, TS_RPC_CALL_ACCEPTED);
+	expect_mock_rpc_interface_receive(&rpc_iface, &rpc_req, RPC_SUCCESS);
 	result = mm_service->receive(mm_service, &mm_req);
 
 	LONGS_EQUAL(MM_RETURN_CODE_SUCCESS, result);
-	UNSIGNED_LONGLONGS_EQUAL(rpc_req.opstatus, header->ReturnStatus);
-	UNSIGNED_LONGLONGS_EQUAL(rpc_req.resp_buf.data_len + SMM_VARIABLE_COMMUNICATE_HEADER_SIZE,
-				 mm_req.resp_buf.data_len);
+	UNSIGNED_LONGLONGS_EQUAL(rpc_req.service_status, header->ReturnStatus);
+	UNSIGNED_LONGLONGS_EQUAL(rpc_req.response.data_length + SMM_VARIABLE_COMMUNICATE_HEADER_SIZE,
+				 mm_req.resp_buf.data_length);
 }
 
 TEST(smm_variable_mm_service, receive_long_response)
@@ -168,36 +168,36 @@
 	int32_t result = 0;
 
 	mm_req.req_buf.size = sizeof(buffer);
-	mm_req.req_buf.data_len = SMM_VARIABLE_COMMUNICATE_HEADER_SIZE + 32;
+	mm_req.req_buf.data_length = SMM_VARIABLE_COMMUNICATE_HEADER_SIZE + 32;
 	mm_req.req_buf.data = buffer;
 
 	mm_req.resp_buf.size = sizeof(buffer);
-	mm_req.resp_buf.data_len = 0;
+	mm_req.resp_buf.data_length = 0;
 	mm_req.resp_buf.data = buffer;
 
 	header->Function = 0x0123456789abcdefULL;
 	header->ReturnStatus = 0;
 
 	rpc_req.opcode = header->Function;
-	rpc_req.opstatus = 0xfedcba9876543210ULL;
-	rpc_req.req_buf.size = sizeof(buffer) - SMM_VARIABLE_COMMUNICATE_HEADER_SIZE;
-	rpc_req.req_buf.data_len = 32;
-	rpc_req.req_buf.data = buffer + SMM_VARIABLE_COMMUNICATE_HEADER_SIZE;
-	rpc_req.resp_buf.size = sizeof(buffer) - SMM_VARIABLE_COMMUNICATE_HEADER_SIZE;
-	rpc_req.resp_buf.data_len = std::numeric_limits<size_t>::max() - SMM_VARIABLE_COMMUNICATE_HEADER_SIZE + 1;
-	rpc_req.resp_buf.data = buffer + SMM_VARIABLE_COMMUNICATE_HEADER_SIZE;
+	rpc_req.service_status = 0xfedcba9876543210ULL;
+	rpc_req.request.size = sizeof(buffer) - SMM_VARIABLE_COMMUNICATE_HEADER_SIZE;
+	rpc_req.request.data_length = 32;
+	rpc_req.request.data = buffer + SMM_VARIABLE_COMMUNICATE_HEADER_SIZE;
+	rpc_req.response.size = sizeof(buffer) - SMM_VARIABLE_COMMUNICATE_HEADER_SIZE;
+	rpc_req.response.data_length = std::numeric_limits<size_t>::max() - SMM_VARIABLE_COMMUNICATE_HEADER_SIZE + 1;
+	rpc_req.response.data = buffer + SMM_VARIABLE_COMMUNICATE_HEADER_SIZE;
 
 	rpc_iface.receive = mock_rpc_interface_receive;
 
 	mm_service = smm_variable_mm_service_init(&service, &rpc_iface);
 
-	expect_mock_rpc_interface_receive(&rpc_iface, &rpc_req, TS_RPC_CALL_ACCEPTED);
+	expect_mock_rpc_interface_receive(&rpc_iface, &rpc_req, RPC_SUCCESS);
 	result = mm_service->receive(mm_service, &mm_req);
 
 	LONGS_EQUAL(MM_RETURN_CODE_NO_MEMORY, result);
-	UNSIGNED_LONGLONGS_EQUAL(rpc_req.opstatus, header->ReturnStatus);
-	UNSIGNED_LONGLONGS_EQUAL(rpc_req.resp_buf.data_len + SMM_VARIABLE_COMMUNICATE_HEADER_SIZE,
-				 mm_req.resp_buf.data_len);
+	UNSIGNED_LONGLONGS_EQUAL(rpc_req.service_status, header->ReturnStatus);
+	UNSIGNED_LONGLONGS_EQUAL(rpc_req.response.data_length + SMM_VARIABLE_COMMUNICATE_HEADER_SIZE,
+				 mm_req.resp_buf.data_length);
 }
 
 TEST(smm_variable_mm_service, receive_response_larger_than_size)
@@ -208,36 +208,36 @@
 	int32_t result = 0;
 
 	mm_req.req_buf.size = sizeof(buffer);
-	mm_req.req_buf.data_len = SMM_VARIABLE_COMMUNICATE_HEADER_SIZE + 32;
+	mm_req.req_buf.data_length = SMM_VARIABLE_COMMUNICATE_HEADER_SIZE + 32;
 	mm_req.req_buf.data = buffer;
 
 	mm_req.resp_buf.size = 15 + SMM_VARIABLE_COMMUNICATE_HEADER_SIZE;
-	mm_req.resp_buf.data_len = 0;
+	mm_req.resp_buf.data_length = 0;
 	mm_req.resp_buf.data = buffer;
 
 	header->Function = 0x0123456789abcdefULL;
 	header->ReturnStatus = 0;
 
 	rpc_req.opcode = header->Function;
-	rpc_req.opstatus = 0xfedcba9876543210ULL;
-	rpc_req.req_buf.size = sizeof(buffer) - SMM_VARIABLE_COMMUNICATE_HEADER_SIZE;
-	rpc_req.req_buf.data_len = 32;
-	rpc_req.req_buf.data = buffer + SMM_VARIABLE_COMMUNICATE_HEADER_SIZE;
-	rpc_req.resp_buf.size = 15;
-	rpc_req.resp_buf.data_len = 16;
-	rpc_req.resp_buf.data = buffer + SMM_VARIABLE_COMMUNICATE_HEADER_SIZE;
+	rpc_req.service_status = 0xfedcba9876543210ULL;
+	rpc_req.request.size = sizeof(buffer) - SMM_VARIABLE_COMMUNICATE_HEADER_SIZE;
+	rpc_req.request.data_length = 32;
+	rpc_req.request.data = buffer + SMM_VARIABLE_COMMUNICATE_HEADER_SIZE;
+	rpc_req.response.size = 15;
+	rpc_req.response.data_length = 16;
+	rpc_req.response.data = buffer + SMM_VARIABLE_COMMUNICATE_HEADER_SIZE;
 
 	rpc_iface.receive = mock_rpc_interface_receive;
 
 	mm_service = smm_variable_mm_service_init(&service, &rpc_iface);
 
-	expect_mock_rpc_interface_receive(&rpc_iface, &rpc_req, TS_RPC_CALL_ACCEPTED);
+	expect_mock_rpc_interface_receive(&rpc_iface, &rpc_req, RPC_SUCCESS);
 	result = mm_service->receive(mm_service, &mm_req);
 
 	LONGS_EQUAL(MM_RETURN_CODE_NO_MEMORY, result);
-	UNSIGNED_LONGLONGS_EQUAL(rpc_req.opstatus, header->ReturnStatus);
-	UNSIGNED_LONGLONGS_EQUAL(rpc_req.resp_buf.data_len + SMM_VARIABLE_COMMUNICATE_HEADER_SIZE,
-				 mm_req.resp_buf.data_len);
+	UNSIGNED_LONGLONGS_EQUAL(rpc_req.service_status, header->ReturnStatus);
+	UNSIGNED_LONGLONGS_EQUAL(rpc_req.response.data_length + SMM_VARIABLE_COMMUNICATE_HEADER_SIZE,
+				 mm_req.resp_buf.data_length);
 }
 
 TEST(smm_variable_mm_service, receive_data_error_codes)
@@ -251,41 +251,37 @@
 		rpc_status_t rpc_status;
 		int32_t mm_result;
 	} status_mapping[] = {
-		{TS_RPC_CALL_ACCEPTED, MM_RETURN_CODE_SUCCESS},
-		{TS_RPC_ERROR_EP_DOES_NOT_EXIT, MM_RETURN_CODE_NOT_SUPPORTED},
-		{TS_RPC_ERROR_INVALID_OPCODE, MM_RETURN_CODE_INVALID_PARAMETER},
-		{TS_RPC_ERROR_SERIALIZATION_NOT_SUPPORTED, MM_RETURN_CODE_INVALID_PARAMETER},
-		{TS_RPC_ERROR_INVALID_REQ_BODY, MM_RETURN_CODE_INVALID_PARAMETER},
-		{TS_RPC_ERROR_INVALID_RESP_BODY, MM_RETURN_CODE_INVALID_PARAMETER},
-		{TS_RPC_ERROR_RESOURCE_FAILURE, MM_RETURN_CODE_NOT_SUPPORTED},
-		{TS_RPC_ERROR_NOT_READY, MM_RETURN_CODE_NOT_SUPPORTED},
-		{TS_RPC_ERROR_INVALID_TRANSACTION, MM_RETURN_CODE_INVALID_PARAMETER},
-		{TS_RPC_ERROR_INTERNAL, MM_RETURN_CODE_NOT_SUPPORTED},
-		{TS_RPC_ERROR_INVALID_PARAMETER, MM_RETURN_CODE_INVALID_PARAMETER},
-		{TS_RPC_ERROR_INTERFACE_DOES_NOT_EXIST, MM_RETURN_CODE_NOT_SUPPORTED},
+		{RPC_SUCCESS, MM_RETURN_CODE_SUCCESS},
+		{RPC_ERROR_INTERNAL, MM_RETURN_CODE_INVALID_PARAMETER},
+		{RPC_ERROR_INVALID_VALUE, MM_RETURN_CODE_INVALID_PARAMETER},
+		{RPC_ERROR_NOT_FOUND, MM_RETURN_CODE_NOT_SUPPORTED},
+		{RPC_ERROR_INVALID_STATE, MM_RETURN_CODE_INVALID_PARAMETER},
+		{RPC_ERROR_TRANSPORT_LAYER, MM_RETURN_CODE_INVALID_PARAMETER},
+		{RPC_ERROR_INVALID_REQUEST_BODY, MM_RETURN_CODE_INVALID_PARAMETER},
+		{RPC_ERROR_INVALID_RESPONSE_BODY, MM_RETURN_CODE_INVALID_PARAMETER},
 		{1, MM_RETURN_CODE_NOT_SUPPORTED}
 
 	};
 
 	mm_req.req_buf.size = sizeof(buffer);
-	mm_req.req_buf.data_len = SMM_VARIABLE_COMMUNICATE_HEADER_SIZE + 32;
+	mm_req.req_buf.data_length = SMM_VARIABLE_COMMUNICATE_HEADER_SIZE + 32;
 	mm_req.req_buf.data = buffer;
 
 	mm_req.resp_buf.size = sizeof(buffer);
-	mm_req.resp_buf.data_len = 0;
+	mm_req.resp_buf.data_length = 0;
 	mm_req.resp_buf.data = buffer;
 
 	header->Function = 0x0123456789abcdefULL;
 	header->ReturnStatus = 0;
 
 	rpc_req.opcode = header->Function;
-	rpc_req.opstatus = 0xfedcba9876543210ULL;
-	rpc_req.req_buf.size = sizeof(buffer) - SMM_VARIABLE_COMMUNICATE_HEADER_SIZE;
-	rpc_req.req_buf.data_len = 32;
-	rpc_req.req_buf.data = buffer + SMM_VARIABLE_COMMUNICATE_HEADER_SIZE;
-	rpc_req.resp_buf.size = sizeof(buffer) - SMM_VARIABLE_COMMUNICATE_HEADER_SIZE;
-	rpc_req.resp_buf.data_len = 16;
-	rpc_req.resp_buf.data = buffer + SMM_VARIABLE_COMMUNICATE_HEADER_SIZE;
+	rpc_req.service_status = 0xfedcba9876543210ULL;
+	rpc_req.request.size = sizeof(buffer) - SMM_VARIABLE_COMMUNICATE_HEADER_SIZE;
+	rpc_req.request.data_length = 32;
+	rpc_req.request.data = buffer + SMM_VARIABLE_COMMUNICATE_HEADER_SIZE;
+	rpc_req.response.size = sizeof(buffer) - SMM_VARIABLE_COMMUNICATE_HEADER_SIZE;
+	rpc_req.response.data_length = 16;
+	rpc_req.response.data = buffer + SMM_VARIABLE_COMMUNICATE_HEADER_SIZE;
 
 	rpc_iface.receive = mock_rpc_interface_receive;
 
@@ -296,8 +292,8 @@
 		result = mm_service->receive(mm_service, &mm_req);
 
 		LONGS_EQUAL(status_mapping[i].mm_result, result);
-		UNSIGNED_LONGLONGS_EQUAL(rpc_req.opstatus, header->ReturnStatus);
-		UNSIGNED_LONGLONGS_EQUAL(rpc_req.resp_buf.data_len + SMM_VARIABLE_COMMUNICATE_HEADER_SIZE,
-					mm_req.resp_buf.data_len);
+		UNSIGNED_LONGLONGS_EQUAL(rpc_req.service_status, header->ReturnStatus);
+		UNSIGNED_LONGLONGS_EQUAL(rpc_req.response.data_length + SMM_VARIABLE_COMMUNICATE_HEADER_SIZE,
+					mm_req.resp_buf.data_length);
 	}
 }
diff --git a/components/service/smm_variable/provider/smm_variable_provider.c b/components/service/smm_variable/provider/smm_variable_provider.c
index a9679b7..f1c3c71 100644
--- a/components/service/smm_variable/provider/smm_variable_provider.c
+++ b/components/service/smm_variable/provider/smm_variable_provider.c
@@ -11,14 +11,14 @@
 #include "smm_variable_provider.h"
 
 /* Service request handlers */
-static rpc_status_t get_variable_handler(void *context, struct call_req *req);
-static rpc_status_t get_next_variable_name_handler(void *context, struct call_req *req);
-static rpc_status_t set_variable_handler(void *context, struct call_req *req);
-static rpc_status_t query_variable_info_handler(void *context, struct call_req *req);
-static rpc_status_t exit_boot_service_handler(void *context, struct call_req *req);
-static rpc_status_t set_var_check_property_handler(void *context, struct call_req *req);
-static rpc_status_t get_var_check_property_handler(void *context, struct call_req *req);
-static rpc_status_t get_payload_size_handler(void *context, struct call_req *req);
+static rpc_status_t get_variable_handler(void *context, struct rpc_request *req);
+static rpc_status_t get_next_variable_name_handler(void *context, struct rpc_request *req);
+static rpc_status_t set_variable_handler(void *context, struct rpc_request *req);
+static rpc_status_t query_variable_info_handler(void *context, struct rpc_request *req);
+static rpc_status_t exit_boot_service_handler(void *context, struct rpc_request *req);
+static rpc_status_t set_var_check_property_handler(void *context, struct rpc_request *req);
+static rpc_status_t get_var_check_property_handler(void *context, struct rpc_request *req);
+static rpc_status_t get_payload_size_handler(void *context, struct rpc_request *req);
 
 /* Handler mapping table for service */
 static const struct service_handler handler_table[] = {
@@ -32,19 +32,20 @@
 	{SMM_VARIABLE_FUNCTION_GET_PAYLOAD_SIZE,					get_payload_size_handler}
 };
 
-struct rpc_interface *smm_variable_provider_init(
+struct rpc_service_interface *smm_variable_provider_init(
 	struct smm_variable_provider *context,
  	uint32_t owner_id,
 	size_t max_variables,
 	struct storage_backend *persistent_store,
 	struct storage_backend *volatile_store)
 {
-	struct rpc_interface *rpc_interface = NULL;
+	struct rpc_service_interface *rpc_interface = NULL;
+	const struct rpc_uuid dummy_uuid = { .uuid = { 0 }};
 
 	if (context) {
 
-		service_provider_init(&context->base_provider, context,
-					handler_table, sizeof(handler_table)/sizeof(struct service_handler));
+		service_provider_init(&context->base_provider, context, &dummy_uuid,
+				      handler_table, sizeof(handler_table)/sizeof(struct service_handler));
 
 		if (uefi_variable_store_init(
 				&context->variable_store,
@@ -65,18 +66,18 @@
 	uefi_variable_store_deinit(&context->variable_store);
 }
 
-static efi_status_t sanitize_access_variable_param(struct call_req *req, size_t *param_len)
+static efi_status_t sanitize_access_variable_param(struct rpc_request *req, size_t *param_len)
 {
 	efi_status_t efi_status = EFI_INVALID_PARAMETER;
 	*param_len = 0;
-	const struct call_param_buf *req_buf = call_req_get_req_buf(req);
+	const struct rpc_buffer *req_buf = &req->request;
 
-	if (req_buf->data_len >= SMM_VARIABLE_COMMUNICATE_ACCESS_VARIABLE_NAME_OFFSET) {
+	if (req_buf->data_length >= SMM_VARIABLE_COMMUNICATE_ACCESS_VARIABLE_NAME_OFFSET) {
 
 		const SMM_VARIABLE_COMMUNICATE_ACCESS_VARIABLE *param =
 			(const SMM_VARIABLE_COMMUNICATE_ACCESS_VARIABLE*)req_buf->data;
 
-		size_t max_space_for_name = req_buf->data_len -
+		size_t max_space_for_name = req_buf->data_length -
 			SMM_VARIABLE_COMMUNICATE_ACCESS_VARIABLE_NAME_OFFSET;
 
 		if (param->NameSize <= max_space_for_name) {
@@ -89,18 +90,18 @@
 	return efi_status;
 }
 
-static efi_status_t sanitize_get_next_var_name_param(struct call_req *req, size_t *param_len)
+static efi_status_t sanitize_get_next_var_name_param(struct rpc_request *req, size_t *param_len)
 {
 	efi_status_t efi_status = EFI_INVALID_PARAMETER;
 	*param_len = 0;
-	const struct call_param_buf *req_buf = call_req_get_req_buf(req);
+	const struct rpc_buffer *req_buf = &req->request;
 
-	if (req_buf->data_len >= SMM_VARIABLE_COMMUNICATE_GET_NEXT_VARIABLE_NAME_NAME_OFFSET) {
+	if (req_buf->data_length >= SMM_VARIABLE_COMMUNICATE_GET_NEXT_VARIABLE_NAME_NAME_OFFSET) {
 
 		const SMM_VARIABLE_COMMUNICATE_GET_NEXT_VARIABLE_NAME *param =
 			(const SMM_VARIABLE_COMMUNICATE_GET_NEXT_VARIABLE_NAME*)req_buf->data;
 
-		size_t max_space_for_name = req_buf->data_len -
+		size_t max_space_for_name = req_buf->data_length -
 			SMM_VARIABLE_COMMUNICATE_GET_NEXT_VARIABLE_NAME_NAME_OFFSET;
 
 		if (param->NameSize <= max_space_for_name) {
@@ -113,18 +114,18 @@
 	return efi_status;
 }
 
-static efi_status_t sanitize_var_check_property_param(struct call_req *req, size_t *param_len)
+static efi_status_t sanitize_var_check_property_param(struct rpc_request *req, size_t *param_len)
 {
 	efi_status_t efi_status = EFI_INVALID_PARAMETER;
 	*param_len = 0;
-	const struct call_param_buf *req_buf = call_req_get_req_buf(req);
+	const struct rpc_buffer *req_buf = &req->request;
 
-	if (req_buf->data_len >= SMM_VARIABLE_COMMUNICATE_VAR_CHECK_VARIABLE_PROPERTY_NAME_OFFSET) {
+	if (req_buf->data_length >= SMM_VARIABLE_COMMUNICATE_VAR_CHECK_VARIABLE_PROPERTY_NAME_OFFSET) {
 
 		const SMM_VARIABLE_COMMUNICATE_VAR_CHECK_VARIABLE_PROPERTY *param =
 			(const SMM_VARIABLE_COMMUNICATE_VAR_CHECK_VARIABLE_PROPERTY*)req_buf->data;
 
-		size_t max_space_for_name = req_buf->data_len -
+		size_t max_space_for_name = req_buf->data_length -
 			SMM_VARIABLE_COMMUNICATE_VAR_CHECK_VARIABLE_PROPERTY_NAME_OFFSET;
 
 		if (param->NameSize <= max_space_for_name) {
@@ -137,7 +138,7 @@
 	return efi_status;
 }
 
-static rpc_status_t get_variable_handler(void *context, struct call_req *req)
+static rpc_status_t get_variable_handler(void *context, struct rpc_request *req)
 {
 	struct smm_variable_provider *this_instance = (struct smm_variable_provider*)context;
 
@@ -147,11 +148,11 @@
 	if (efi_status == EFI_SUCCESS) {
 
 		/* Valid access variable header parameter */
-		struct call_param_buf *resp_buf = call_req_get_resp_buf(req);
+		struct rpc_buffer *resp_buf = &req->response;
 
 		if (resp_buf->size >= param_len) {
 
-			struct call_param_buf *req_buf = call_req_get_req_buf(req);
+			struct rpc_buffer *req_buf = &req->request;
 			size_t max_data_len = resp_buf->size - param_len;
 
 			memmove(resp_buf->data, req_buf->data, param_len);
@@ -160,7 +161,7 @@
 				&this_instance->variable_store,
 				(SMM_VARIABLE_COMMUNICATE_ACCESS_VARIABLE*)resp_buf->data,
 				max_data_len,
-				&resp_buf->data_len);
+				&resp_buf->data_length);
 		}
 		else {
 
@@ -169,12 +170,12 @@
 		}
 	}
 
-	call_req_set_opstatus(req, efi_status);
+	req->service_status = efi_status;
 
-	return TS_RPC_CALL_ACCEPTED;
+	return RPC_SUCCESS;
 }
 
-static rpc_status_t get_next_variable_name_handler(void *context, struct call_req* req)
+static rpc_status_t get_next_variable_name_handler(void *context, struct rpc_request* req)
 {
 	struct smm_variable_provider *this_instance = (struct smm_variable_provider*)context;
 
@@ -184,11 +185,11 @@
 	if (efi_status == EFI_SUCCESS) {
 
 		/* Valid get next variable name header */
-		struct call_param_buf *resp_buf = call_req_get_resp_buf(req);
+		struct rpc_buffer *resp_buf = &req->response;
 
 		if (resp_buf->size >= param_len) {
 
-			struct call_param_buf *req_buf = call_req_get_req_buf(req);
+			struct rpc_buffer *req_buf = &req->request;
 			size_t max_name_len = resp_buf->size -
 				SMM_VARIABLE_COMMUNICATE_GET_NEXT_VARIABLE_NAME_NAME_OFFSET;
 
@@ -198,7 +199,7 @@
 				&this_instance->variable_store,
 				(SMM_VARIABLE_COMMUNICATE_GET_NEXT_VARIABLE_NAME*)resp_buf->data,
 				max_name_len,
-				&resp_buf->data_len);
+				&resp_buf->data_length);
 		}
 		else {
 
@@ -207,12 +208,12 @@
 		}
 	}
 
-	call_req_set_opstatus(req, efi_status);
+	req->service_status = efi_status;
 
-	return TS_RPC_CALL_ACCEPTED;
+	return RPC_SUCCESS;
 }
 
-static rpc_status_t set_variable_handler(void *context, struct call_req* req)
+static rpc_status_t set_variable_handler(void *context, struct rpc_request* req)
 {
 	struct smm_variable_provider *this_instance = (struct smm_variable_provider*)context;
 
@@ -224,12 +225,12 @@
 		/* Access variable header is whole.  Check that buffer length can
 		 * accommodate the data.
 		 */
-		struct call_param_buf *req_buf = call_req_get_req_buf(req);
+		struct rpc_buffer *req_buf = &req->request;
 
 		const SMM_VARIABLE_COMMUNICATE_ACCESS_VARIABLE *access_var =
 			(const SMM_VARIABLE_COMMUNICATE_ACCESS_VARIABLE*)req_buf->data;
 
-		size_t space_for_data = req_buf->data_len -
+		size_t space_for_data = req_buf->data_length -
 			SMM_VARIABLE_COMMUNICATE_ACCESS_VARIABLE_DATA_OFFSET(access_var);
 
 		if (access_var->DataSize <= space_for_data) {
@@ -245,25 +246,25 @@
 		}
 	}
 
-	call_req_set_opstatus(req, efi_status);
+	req->service_status = efi_status;
 
-	return TS_RPC_CALL_ACCEPTED;
+	return RPC_SUCCESS;
 }
 
-static rpc_status_t query_variable_info_handler(void *context, struct call_req* req)
+static rpc_status_t query_variable_info_handler(void *context, struct rpc_request* req)
 {
 	efi_status_t efi_status = EFI_INVALID_PARAMETER;
 	struct smm_variable_provider *this_instance = (struct smm_variable_provider*)context;
 
-	const struct call_param_buf *req_buf = call_req_get_req_buf(req);
+	const struct rpc_buffer *req_buf = &req->request;
 
-	if (req_buf->data_len >= sizeof(SMM_VARIABLE_COMMUNICATE_QUERY_VARIABLE_INFO)) {
+	if (req_buf->data_length >= sizeof(SMM_VARIABLE_COMMUNICATE_QUERY_VARIABLE_INFO)) {
 
-		struct call_param_buf *resp_buf = call_req_get_resp_buf(req);
+		struct rpc_buffer *resp_buf = &req->response;
 
-		if (resp_buf->size >= req_buf->data_len) {
+		if (resp_buf->size >= req_buf->data_length) {
 
-			memmove(resp_buf->data, req_buf->data, req_buf->data_len);
+			memmove(resp_buf->data, req_buf->data, req_buf->data_length);
 
 			efi_status = uefi_variable_store_query_variable_info(
 				&this_instance->variable_store,
@@ -271,7 +272,7 @@
 
 			if (efi_status == EFI_SUCCESS) {
 
-				resp_buf->data_len = sizeof(SMM_VARIABLE_COMMUNICATE_QUERY_VARIABLE_INFO);
+				resp_buf->data_length = sizeof(SMM_VARIABLE_COMMUNICATE_QUERY_VARIABLE_INFO);
 			}
 		}
 		else {
@@ -281,22 +282,22 @@
 		}
 	}
 
-	call_req_set_opstatus(req, efi_status);
+	req->service_status = efi_status;
 
-	return TS_RPC_CALL_ACCEPTED;
+	return RPC_SUCCESS;
 }
 
-static rpc_status_t exit_boot_service_handler(void *context, struct call_req* req)
+static rpc_status_t exit_boot_service_handler(void *context, struct rpc_request* req)
 {
 	struct smm_variable_provider *this_instance = (struct smm_variable_provider*)context;
 
 	efi_status_t efi_status = uefi_variable_store_exit_boot_service(&this_instance->variable_store);
-	call_req_set_opstatus(req, efi_status);
+	req->service_status = efi_status;
 
-	return TS_RPC_CALL_ACCEPTED;
+	return RPC_SUCCESS;
 }
 
-static rpc_status_t set_var_check_property_handler(void *context, struct call_req *req)
+static rpc_status_t set_var_check_property_handler(void *context, struct rpc_request *req)
 {
 	struct smm_variable_provider *this_instance = (struct smm_variable_provider*)context;
 
@@ -306,7 +307,7 @@
 	if (efi_status == EFI_SUCCESS) {
 
 		/* Request parameter structue looks whole */
-		struct call_param_buf *req_buf = call_req_get_req_buf(req);
+		struct rpc_buffer *req_buf = &req->request;
 
 		const SMM_VARIABLE_COMMUNICATE_VAR_CHECK_VARIABLE_PROPERTY *check_property =
 			(const SMM_VARIABLE_COMMUNICATE_VAR_CHECK_VARIABLE_PROPERTY*)req_buf->data;
@@ -316,12 +317,12 @@
 			check_property);
 	}
 
-	call_req_set_opstatus(req, efi_status);
+	req->service_status = efi_status;
 
-	return TS_RPC_CALL_ACCEPTED;
+	return RPC_SUCCESS;
 }
 
-static rpc_status_t get_var_check_property_handler(void *context, struct call_req *req)
+static rpc_status_t get_var_check_property_handler(void *context, struct rpc_request *req)
 {
 	struct smm_variable_provider *this_instance = (struct smm_variable_provider*)context;
 
@@ -331,13 +332,13 @@
 	if (efi_status == EFI_SUCCESS) {
 
 		/* Request parameter structue looks whole */
-		struct call_param_buf *resp_buf = call_req_get_resp_buf(req);
+		struct rpc_buffer *resp_buf = &req->response;
 
 		if (resp_buf->size >= param_len) {
 
-			struct call_param_buf *req_buf = call_req_get_req_buf(req);
+			struct rpc_buffer *req_buf = &req->request;
 			memmove(resp_buf->data, req_buf->data, param_len);
-			resp_buf->data_len = param_len;
+			resp_buf->data_length = param_len;
 
 			efi_status = uefi_variable_store_get_var_check_property(
 				&this_instance->variable_store,
@@ -350,12 +351,12 @@
 		}
 	}
 
-	call_req_set_opstatus(req, efi_status);
+	req->service_status = efi_status;
 
-	return TS_RPC_CALL_ACCEPTED;
+	return RPC_SUCCESS;
 }
 
-static rpc_status_t get_payload_size_handler(void *context, struct call_req *req)
+static rpc_status_t get_payload_size_handler(void *context, struct rpc_request *req)
 {
 	(void)context;
 
@@ -363,10 +364,10 @@
 	 * name is also carried in the buffer, the maximum payload size depends on the name size.  This
 	 * function therefore treats the payload as name + data.
 	 */
-	size_t payload_size = req->req_buf.size - SMM_VARIABLE_COMMUNICATE_ACCESS_VARIABLE_NAME_OFFSET;
+	size_t payload_size = req->request.size - SMM_VARIABLE_COMMUNICATE_ACCESS_VARIABLE_NAME_OFFSET;
 
 	efi_status_t efi_status = EFI_SUCCESS;
-	struct call_param_buf *resp_buf = call_req_get_resp_buf(req);
+	struct rpc_buffer *resp_buf = &req->response;
 
 	if (resp_buf->size >= sizeof(SMM_VARIABLE_COMMUNICATE_GET_PAYLOAD_SIZE)) {
 
@@ -374,7 +375,7 @@
 			(SMM_VARIABLE_COMMUNICATE_GET_PAYLOAD_SIZE*)resp_buf->data;
 
 		resp_msg->VariablePayloadSize = payload_size;
-		resp_buf->data_len = sizeof(SMM_VARIABLE_COMMUNICATE_GET_PAYLOAD_SIZE);
+		resp_buf->data_length = sizeof(SMM_VARIABLE_COMMUNICATE_GET_PAYLOAD_SIZE);
 	}
 	else {
 
@@ -382,7 +383,7 @@
 		efi_status = EFI_BAD_BUFFER_SIZE;
 	}
 
-	call_req_set_opstatus(req, efi_status);
+	req->service_status = efi_status;
 
-	return TS_RPC_CALL_ACCEPTED;
+	return RPC_SUCCESS;
 }
diff --git a/components/service/smm_variable/provider/smm_variable_provider.h b/components/service/smm_variable/provider/smm_variable_provider.h
index c679397..4c22fab 100644
--- a/components/service/smm_variable/provider/smm_variable_provider.h
+++ b/components/service/smm_variable/provider/smm_variable_provider.h
@@ -7,9 +7,9 @@
 #ifndef SMM_VARIABLE_PROVIDER_H
 #define SMM_VARIABLE_PROVIDER_H
 
-#include <rpc/common/endpoint/rpc_interface.h>
-#include <service/common/provider/service_provider.h>
-#include <service/smm_variable/backend/uefi_variable_store.h>
+#include "rpc/common/endpoint/rpc_service_interface.h"
+#include "service/common/provider/service_provider.h"
+#include "service/smm_variable/backend/uefi_variable_store.h"
 
 #ifdef __cplusplus
 extern "C" {
@@ -41,7 +41,7 @@
  *
  * \return An rpc_interface or NULL on failure
  */
-struct rpc_interface *smm_variable_provider_init(
+struct rpc_service_interface *smm_variable_provider_init(
 	struct smm_variable_provider *context,
  	uint32_t owner_id,
 	size_t max_variables,
diff --git a/components/service/smm_variable/test/service/smm_variable_attack_tests.cpp b/components/service/smm_variable/test/service/smm_variable_attack_tests.cpp
index d9f07b2..330789e 100644
--- a/components/service/smm_variable/test/service/smm_variable_attack_tests.cpp
+++ b/components/service/smm_variable/test/service/smm_variable_attack_tests.cpp
@@ -19,23 +19,20 @@
 {
 	void setup()
 	{
-		struct rpc_caller *caller;
-		int status;
-
-		m_rpc_session_handle = NULL;
+		m_rpc_session = NULL;
 		m_service_context = NULL;
 
 		service_locator_init();
 
 		m_service_context =
-			service_locator_query("sn:trustedfirmware.org:smm-variable:0", &status);
+			service_locator_query("sn:trustedfirmware.org:smm-variable:0");
 		CHECK_TRUE(m_service_context);
 
-		m_rpc_session_handle =
-			service_context_open(m_service_context, TS_RPC_ENCODING_PACKED_C, &caller);
-		CHECK_TRUE(m_rpc_session_handle);
+		m_rpc_session =
+			service_context_open(m_service_context);
+		CHECK_TRUE(m_rpc_session);
 
-		m_client = new smm_variable_client(caller);
+		m_client = new smm_variable_client(m_rpc_session);
 
 		setup_common_guid();
 	}
@@ -46,9 +43,9 @@
 		m_client = NULL;
 
 		if (m_service_context) {
-			if (m_rpc_session_handle) {
-				service_context_close(m_service_context, m_rpc_session_handle);
-				m_rpc_session_handle = NULL;
+			if (m_rpc_session) {
+				service_context_close(m_service_context, m_rpc_session);
+				m_rpc_session = NULL;
 			}
 
 			service_context_relinquish(m_service_context);
@@ -72,7 +69,7 @@
 	}
 
 	smm_variable_client *m_client;
-	rpc_session_handle m_rpc_session_handle;
+	struct rpc_caller_session *m_rpc_session;
 	struct service_context *m_service_context;
 	EFI_GUID m_common_guid;
 };
diff --git a/components/service/smm_variable/test/service/smm_variable_service_tests.cpp b/components/service/smm_variable/test/service/smm_variable_service_tests.cpp
index 5284423..af43425 100644
--- a/components/service/smm_variable/test/service/smm_variable_service_tests.cpp
+++ b/components/service/smm_variable/test/service/smm_variable_service_tests.cpp
@@ -17,23 +17,20 @@
 {
 	void setup()
 	{
-		struct rpc_caller *caller;
-		int status;
-
-		m_rpc_session_handle = NULL;
+		m_rpc_session = NULL;
 		m_service_context = NULL;
 
 		service_locator_init();
 
 		m_service_context =
-			service_locator_query("sn:trustedfirmware.org:smm-variable:0", &status);
+			service_locator_query("sn:trustedfirmware.org:smm-variable:0");
 		CHECK_TRUE(m_service_context);
 
-		m_rpc_session_handle =
-			service_context_open(m_service_context, TS_RPC_ENCODING_PACKED_C, &caller);
-		CHECK_TRUE(m_rpc_session_handle);
+		m_rpc_session =
+			service_context_open(m_service_context);
+		CHECK_TRUE(m_rpc_session);
 
-		m_client = new smm_variable_client(caller);
+		m_client = new smm_variable_client(m_rpc_session);
 
 		setup_common_guid();
 	}
@@ -44,9 +41,9 @@
 		m_client = NULL;
 
 		if (m_service_context) {
-			if (m_rpc_session_handle) {
-				service_context_close(m_service_context, m_rpc_session_handle);
-				m_rpc_session_handle = NULL;
+			if (m_rpc_session) {
+				service_context_close(m_service_context, m_rpc_session);
+				m_rpc_session = NULL;
 			}
 
 			service_context_relinquish(m_service_context);
@@ -225,7 +222,7 @@
 	}
 
 	smm_variable_client *m_client;
-	rpc_session_handle m_rpc_session_handle;
+	struct rpc_caller_session *m_rpc_session;
 	struct service_context *m_service_context;
 	EFI_GUID m_common_guid;
 };
diff --git a/components/service/spm_test/spm_test.cmake b/components/service/spm_test/spm_test.cmake
index c595370..e8a1ccd 100644
--- a/components/service/spm_test/spm_test.cmake
+++ b/components/service/spm_test/spm_test.cmake
@@ -1,5 +1,5 @@
 #-------------------------------------------------------------------------------
-# Copyright (c) 2022, Arm Limited and Contributors. All rights reserved.
+# Copyright (c) 2022-2023, Arm Limited and Contributors. All rights reserved.
 #
 # SPDX-License-Identifier: BSD-3-Clause
 #
@@ -64,7 +64,7 @@
 
 include(${TS_ROOT}/tools/cmake/common/ExportSp.cmake)
 export_sp(
-	SP_UUID_CANON ${SP_UUID_CANON}
+	SP_FFA_UUID_CANON ${SP_FFA_UUID_CANON}
 	SP_BIN_UUID_CANON ${SP_BIN_UUID_CANON}
 	SP_NAME "spm-test${SP_NUMBER}"
 	MK_IN ${TS_ROOT}/environments/opteesp/sp.mk.in
diff --git a/components/service/test_runner/client/cpp/test_runner_client.cpp b/components/service/test_runner/client/cpp/test_runner_client.cpp
index 27ace7b..31df93d 100644
--- a/components/service/test_runner/client/cpp/test_runner_client.cpp
+++ b/components/service/test_runner/client/cpp/test_runner_client.cpp
@@ -22,10 +22,10 @@
     service_client_init(&m_client, NULL);
 }
 
-test_runner_client::test_runner_client(struct rpc_caller *caller) :
+test_runner_client::test_runner_client(struct rpc_caller_session *session) :
     m_client()
 {
-    service_client_init(&m_client, caller);
+    service_client_init(&m_client, session);
 }
 
 test_runner_client::~test_runner_client()
@@ -33,9 +33,9 @@
     service_client_deinit(&m_client);
 }
 
-void test_runner_client::set_caller(struct rpc_caller *caller)
+void test_runner_client::set_caller(struct rpc_caller_session *session)
 {
-    m_client.caller = caller;
+    m_client.session = session;
 }
 
 int test_runner_client::err_rpc_status() const
@@ -65,7 +65,7 @@
     std::vector<struct test_result> &results)
 {
     int test_status = TS_TEST_RUNNER_STATUS_ERROR;
-    m_client.rpc_status = TS_RPC_ERROR_RESOURCE_FAILURE;
+    m_client.rpc_status = RPC_ERROR_RESOURCE_FAILURE;
     rpc_call_handle call_handle;
     uint8_t *req_buf;
     std::vector<uint8_t> req_param;
@@ -73,13 +73,14 @@
     serialize_test_spec(req_param, spec);
 
     size_t req_len = req_param.size();
-    call_handle = rpc_caller_begin(m_client.caller, &req_buf, req_len);
+    size_t resp_len = 1024;
+    call_handle = rpc_caller_session_begin(m_client.session, &req_buf, req_len, resp_len);
 
     if (call_handle) {
 
         uint8_t *resp_buf;
         size_t resp_len;
-        rpc_opstatus_t opstatus;
+        service_status_t service_status;
 
         memcpy(req_buf, req_param.data(), req_len);
 
@@ -87,12 +88,12 @@
             TS_TEST_RUNNER_OPCODE_LIST_TESTS :
             TS_TEST_RUNNER_OPCODE_RUN_TESTS;
 
-        m_client.rpc_status = rpc_caller_invoke(m_client.caller, call_handle,
-            opcode, &opstatus, &resp_buf, &resp_len);
+        m_client.rpc_status = rpc_caller_session_invoke(call_handle,
+            opcode, &resp_buf, &resp_len, &service_status);
 
         if (m_client.rpc_status == TS_RPC_CALL_ACCEPTED) {
 
-            test_status = opstatus;
+            test_status = service_status;
 
             if (test_status == TS_TEST_RUNNER_STATUS_SUCCESS) {
 
@@ -100,7 +101,7 @@
             }
         }
 
-        rpc_caller_end(m_client.caller, call_handle);
+        rpc_caller_session_end(call_handle);
     }
 
     return test_status;
diff --git a/components/service/test_runner/client/cpp/test_runner_client.h b/components/service/test_runner/client/cpp/test_runner_client.h
index d3d39ce..cdac879 100644
--- a/components/service/test_runner/client/cpp/test_runner_client.h
+++ b/components/service/test_runner/client/cpp/test_runner_client.h
@@ -21,10 +21,10 @@
 {
 public:
     test_runner_client();
-    test_runner_client(struct rpc_caller *caller);
+    test_runner_client(struct rpc_caller_session *session);
     virtual ~test_runner_client();
 
-    void set_caller(struct rpc_caller *caller);
+    void set_caller(struct rpc_caller_session *session);
     int err_rpc_status() const;
 
     int run_tests(const struct test_spec &spec,
diff --git a/components/service/test_runner/provider/serializer/packed-c/packedc_test_runner_provider_serializer.c b/components/service/test_runner/provider/serializer/packed-c/packedc_test_runner_provider_serializer.c
index 2c53b93..74fdd66 100644
--- a/components/service/test_runner/provider/serializer/packed-c/packedc_test_runner_provider_serializer.c
+++ b/components/service/test_runner/provider/serializer/packed-c/packedc_test_runner_provider_serializer.c
@@ -3,202 +3,200 @@
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
+#include "packedc_test_runner_provider_serializer.h"
+
+#include <common/tlv/tlv.h>
+#include <protocols/rpc/common/packed-c/status.h>
+#include <protocols/service/test_runner/packed-c/list_tests.h>
+#include <protocols/service/test_runner/packed-c/run_tests.h>
 #include <stddef.h>
 #include <stdlib.h>
 #include <string.h>
-#include <common/tlv/tlv.h>
-#include <protocols/rpc/common/packed-c/status.h>
-#include <protocols/service/test_runner/packed-c/run_tests.h>
-#include <protocols/service/test_runner/packed-c/list_tests.h>
-#include "packedc_test_runner_provider_serializer.h"
 
 /* Common rerialization methods used for different operations */
-static rpc_status_t deserialize_test_spec(const struct call_param_buf *req_buf,
-        struct test_spec *test_spec)
+static rpc_status_t deserialize_test_spec(const struct rpc_buffer *req_buf,
+					  struct test_spec *test_spec)
 {
-    struct tlv_const_iterator req_iter;
-    struct tlv_record decoded_record;
+	struct tlv_const_iterator req_iter;
+	struct tlv_record decoded_record;
 
-    test_spec->name[0] = 0;
-    test_spec->group[0] = 0;
+	test_spec->name[0] = 0;
+	test_spec->group[0] = 0;
 
-    tlv_const_iterator_begin(&req_iter, (uint8_t*)req_buf->data, req_buf->data_len);
+	tlv_const_iterator_begin(&req_iter, (uint8_t *)req_buf->data, req_buf->data_length);
 
-    if (tlv_find_decode(&req_iter, TS_TEST_RUNNER_TEST_SPEC_TAG_NAME, &decoded_record)) {
+	if (tlv_find_decode(&req_iter, TS_TEST_RUNNER_TEST_SPEC_TAG_NAME, &decoded_record)) {
+		if ((decoded_record.length > 0) && (decoded_record.length < TEST_NAME_MAX_LEN)) {
+			memcpy(test_spec->name, decoded_record.value, decoded_record.length);
+			test_spec->name[decoded_record.length] = 0;
+		}
+	}
 
-        if ((decoded_record.length > 0) && (decoded_record.length < TEST_NAME_MAX_LEN)) {
+	if (tlv_find_decode(&req_iter, TS_TEST_RUNNER_TEST_SPEC_TAG_GROUP, &decoded_record)) {
+		if ((decoded_record.length > 0) && (decoded_record.length < TEST_GROUP_MAX_LEN)) {
+			memcpy(test_spec->group, decoded_record.value, decoded_record.length);
+			test_spec->group[decoded_record.length] = 0;
+		}
+	}
 
-            memcpy(test_spec->name, decoded_record.value, decoded_record.length);
-            test_spec->name[decoded_record.length] = 0;
-        }
-    }
-
-    if (tlv_find_decode(&req_iter, TS_TEST_RUNNER_TEST_SPEC_TAG_GROUP, &decoded_record)) {
-
-        if ((decoded_record.length > 0) && (decoded_record.length < TEST_GROUP_MAX_LEN)) {
-
-            memcpy(test_spec->group, decoded_record.value, decoded_record.length);
-            test_spec->group[decoded_record.length] = 0;
-        }
-    }
-
-    return TS_RPC_CALL_ACCEPTED;
+	return TS_RPC_CALL_ACCEPTED;
 }
 
 static uint8_t *serialize_test_result(const struct test_result *result, size_t *serialized_len)
 {
-    uint8_t *out_buf;
-    size_t fixed_len = sizeof(struct ts_test_runner_test_result);
-    size_t required_space = fixed_len;
-    size_t name_len = strlen(result->name);
-    size_t group_len = strlen(result->group);
+	uint8_t *out_buf;
+	size_t fixed_len = sizeof(struct ts_test_runner_test_result);
+	size_t required_space = fixed_len;
+	size_t name_len = strlen(result->name);
+	size_t group_len = strlen(result->group);
 
-    if (name_len)   required_space += tlv_required_space(name_len);
-    if (group_len)  required_space += tlv_required_space(group_len);
-    if (result->run_state == TEST_RUN_STATE_FAILED)
-        required_space += tlv_required_space(sizeof(struct ts_test_runner_test_failure));
+	if (name_len)
+		required_space += tlv_required_space(name_len);
+	if (group_len)
+		required_space += tlv_required_space(group_len);
+	if (result->run_state == TEST_RUN_STATE_FAILED)
+		required_space += tlv_required_space(sizeof(struct ts_test_runner_test_failure));
 
-    *serialized_len = required_space;
+	*serialized_len = required_space;
 
-    out_buf = malloc(required_space);
+	out_buf = malloc(required_space);
 
-    if (out_buf) {
+	if (out_buf) {
+		struct ts_test_runner_test_result result_msg;
+		struct tlv_iterator tlv_iter;
 
-        struct ts_test_runner_test_result result_msg;
-        result_msg.run_state = result->run_state;
+		result_msg.run_state = result->run_state;
 
-        memcpy(out_buf, &result_msg, fixed_len);
+		memcpy(out_buf, &result_msg, fixed_len);
 
-        struct tlv_iterator tlv_iter;
-        tlv_iterator_begin(&tlv_iter, (uint8_t*)out_buf + fixed_len, required_space - fixed_len);
+		tlv_iterator_begin(&tlv_iter, (uint8_t *)out_buf + fixed_len,
+				   required_space - fixed_len);
 
-        if (name_len) {
+		if (name_len) {
+			struct tlv_record record;
 
-            struct tlv_record record;
-            record.tag = TS_TEST_RUNNER_TEST_RESULT_TAG_NAME;
-            record.length = name_len;
-            record.value = (const uint8_t*)result->name;
-            tlv_encode(&tlv_iter, &record);
-        }
+			record.tag = TS_TEST_RUNNER_TEST_RESULT_TAG_NAME;
+			record.length = name_len;
+			record.value = (const uint8_t *)result->name;
+			tlv_encode(&tlv_iter, &record);
+		}
 
-        if (group_len) {
+		if (group_len) {
+			struct tlv_record record;
 
-            struct tlv_record record;
-            record.tag = TS_TEST_RUNNER_TEST_RESULT_TAG_GROUP;
-            record.length = group_len;
-            record.value = (const uint8_t*)result->group;
-            tlv_encode(&tlv_iter, &record);
-        }
+			record.tag = TS_TEST_RUNNER_TEST_RESULT_TAG_GROUP;
+			record.length = group_len;
+			record.value = (const uint8_t *)result->group;
+			tlv_encode(&tlv_iter, &record);
+		}
 
-        if (result->run_state == TEST_RUN_STATE_FAILED) {
+		if (result->run_state == TEST_RUN_STATE_FAILED) {
+			struct ts_test_runner_test_failure serialized_failure;
+			struct tlv_record record;
 
-            struct ts_test_runner_test_failure serialized_failure;
-            serialized_failure.line_num = result->failure.line_num;
-            serialized_failure.info = result->failure.info;
+			serialized_failure.line_num = result->failure.line_num;
+			serialized_failure.info = result->failure.info;
 
-            struct tlv_record record;
-            record.tag = TS_TEST_RUNNER_TEST_RESULT_TAG_FAILURE;
-            record.length = sizeof(serialized_failure);
-            record.value = (const uint8_t*)&serialized_failure;
-            tlv_encode(&tlv_iter, &record);
-        }
-    }
+			record.tag = TS_TEST_RUNNER_TEST_RESULT_TAG_FAILURE;
+			record.length = sizeof(serialized_failure);
+			record.value = (const uint8_t *)&serialized_failure;
+			tlv_encode(&tlv_iter, &record);
+		}
+	}
 
-    return out_buf;
+	return out_buf;
 }
 
-static rpc_status_t serialize_test_results(struct call_param_buf *resp_buf,
-        const struct test_summary *summary,
-        const struct test_result *results)
+static rpc_status_t serialize_test_results(struct rpc_buffer *resp_buf,
+					   const struct test_summary *summary,
+					   const struct test_result *results)
 {
-    size_t space_used = 0;
-    rpc_status_t rpc_status = TS_RPC_CALL_ACCEPTED;
+	size_t space_used = 0;
+	rpc_status_t rpc_status = TS_RPC_CALL_ACCEPTED;
 
-    /* Serialize fixed size summary */
-    struct  ts_test_runner_result_summary summary_msg;
-    size_t fixed_len = sizeof(struct  ts_test_runner_result_summary);
+	/* Serialize fixed size summary */
+	struct ts_test_runner_result_summary summary_msg;
+	size_t fixed_len = sizeof(struct ts_test_runner_result_summary);
 
-    summary_msg.num_tests = summary->num_tests;
-    summary_msg.num_passed = summary->num_passed;
-    summary_msg.num_failed = summary->num_failed;
+	summary_msg.num_tests = summary->num_tests;
+	summary_msg.num_passed = summary->num_passed;
+	summary_msg.num_failed = summary->num_failed;
 
-    if (fixed_len + space_used <= resp_buf->size) {
+	if (fixed_len + space_used <= resp_buf->size) {
+		memcpy((uint8_t *)resp_buf->data + space_used, &summary_msg, fixed_len);
+		space_used += fixed_len;
 
-        memcpy((uint8_t*)resp_buf->data + space_used, &summary_msg, fixed_len);
-        space_used += fixed_len;
+		/* Serialize test result objects */
+		struct tlv_iterator resp_iter;
 
-        /* Serialize test result objects */
-        struct tlv_iterator resp_iter;
-        tlv_iterator_begin(&resp_iter, (uint8_t*)resp_buf->data + space_used, resp_buf->size - space_used);
+		tlv_iterator_begin(&resp_iter, (uint8_t *)resp_buf->data + space_used,
+				   resp_buf->size - space_used);
 
-        for (size_t i = 0; (i < summary->num_results) && (rpc_status == TS_RPC_CALL_ACCEPTED); ++i) {
+		for (size_t i = 0;
+		     (i < summary->num_results) && (rpc_status == TS_RPC_CALL_ACCEPTED); ++i) {
+			size_t serialised_len;
+			uint8_t *serialize_buf =
+				serialize_test_result(&results[i], &serialised_len);
 
-            size_t serialised_len;
-            uint8_t *serialize_buf = serialize_test_result(&results[i], &serialised_len);
+			if (serialize_buf) {
+				struct tlv_record result_record;
 
-            if (serialize_buf) {
+				result_record.tag = TS_TEST_RUNNER_TEST_RESULT_TAG;
+				result_record.length = serialised_len;
+				result_record.value = serialize_buf;
 
-                struct tlv_record result_record;
-                result_record.tag = TS_TEST_RUNNER_TEST_RESULT_TAG;
-                result_record.length = serialised_len;
-                result_record.value = serialize_buf;
+				if (tlv_encode(&resp_iter, &result_record)) {
+					space_used += tlv_required_space(serialised_len);
+				} else {
+					/* Insufficient buffer space */
+					rpc_status = RPC_ERROR_RESOURCE_FAILURE;
+				}
 
-                if (tlv_encode(&resp_iter, &result_record)) {
+				free(serialize_buf);
+			}
+		}
+	}
 
-                    space_used += tlv_required_space(serialised_len);
-                }
-                else {
-                    /* Insufficient buffer space */
-                    rpc_status = TS_RPC_ERROR_RESOURCE_FAILURE;
-                }
+	resp_buf->data_length = space_used;
 
-                free(serialize_buf);
-            }
-        }
-    }
-
-    resp_buf->data_len = space_used;
-
-    return rpc_status;
+	return rpc_status;
 }
 
 /* Operation: run_tests */
-static rpc_status_t deserialize_run_tests_req(const struct call_param_buf *req_buf,
-        struct test_spec *test_spec)
+static rpc_status_t deserialize_run_tests_req(const struct rpc_buffer *req_buf,
+					      struct test_spec *test_spec)
 {
-    return deserialize_test_spec(req_buf, test_spec);
+	return deserialize_test_spec(req_buf, test_spec);
 }
 
-static rpc_status_t serialize_run_tests_resp(struct call_param_buf *resp_buf,
-        const struct test_summary *summary,
-        const struct test_result *results)
+static rpc_status_t serialize_run_tests_resp(struct rpc_buffer *resp_buf,
+					     const struct test_summary *summary,
+					     const struct test_result *results)
 {
-    return serialize_test_results(resp_buf, summary, results);
+	return serialize_test_results(resp_buf, summary, results);
 }
 
 /* Operation: list_tests */
-static rpc_status_t deserialize_list_tests_req(const struct call_param_buf *req_buf,
-        struct test_spec *test_spec)
+static rpc_status_t deserialize_list_tests_req(const struct rpc_buffer *req_buf,
+					       struct test_spec *test_spec)
 {
-    return deserialize_test_spec(req_buf, test_spec);
+	return deserialize_test_spec(req_buf, test_spec);
 }
 
-static rpc_status_t serialize_list_tests_resp(struct call_param_buf *resp_buf,
-        const struct test_summary *summary,
-        const struct test_result *results)
+static rpc_status_t serialize_list_tests_resp(struct rpc_buffer *resp_buf,
+					      const struct test_summary *summary,
+					      const struct test_result *results)
 {
-    return serialize_test_results(resp_buf, summary, results);
+	return serialize_test_results(resp_buf, summary, results);
 }
 
 /* Singleton method to provide access to the serializer instance */
 const struct test_runner_provider_serializer *packedc_test_runner_provider_serializer_instance(void)
 {
-    static const struct test_runner_provider_serializer instance = {
-        deserialize_run_tests_req,
-        serialize_run_tests_resp,
-        deserialize_list_tests_req,
-        serialize_list_tests_resp
-    };
+	static const struct test_runner_provider_serializer instance = {
+		deserialize_run_tests_req, serialize_run_tests_resp, deserialize_list_tests_req,
+		serialize_list_tests_resp
+	};
 
-    return &instance;
+	return &instance;
 }
diff --git a/components/service/test_runner/provider/serializer/test_runner_provider_serializer.h b/components/service/test_runner/provider/serializer/test_runner_provider_serializer.h
index bd457f7..4999a1e 100644
--- a/components/service/test_runner/provider/serializer/test_runner_provider_serializer.h
+++ b/components/service/test_runner/provider/serializer/test_runner_provider_serializer.h
@@ -7,7 +7,7 @@
 #ifndef TEST_RUNNER_PROVIDER_SERIALIZER_H
 #define TEST_RUNNER_PROVIDER_SERIALIZER_H
 
-#include <rpc/common/endpoint/rpc_interface.h>
+#include "rpc/common/endpoint/rpc_service_interface.h"
 #include <service/test_runner/common/test_runner.h>
 
 /* Provides a common interface for parameter serialization operations
@@ -18,21 +18,21 @@
  */
 struct test_runner_provider_serializer {
 
-    /* Operation: run_tests */
-    rpc_status_t (*deserialize_run_tests_req)(const struct call_param_buf *req_buf,
-        struct test_spec *test_spec);
+	/* Operation: run_tests */
+	rpc_status_t (*deserialize_run_tests_req)(const struct rpc_buffer *req_buf,
+		struct test_spec *test_spec);
 
-    rpc_status_t (*serialize_run_tests_resp)(struct call_param_buf *resp_buf,
-        const struct test_summary *summary,
-        const struct test_result *results);
+	rpc_status_t (*serialize_run_tests_resp)(struct rpc_buffer *resp_buf,
+		const struct test_summary *summary,
+		const struct test_result *results);
 
-    /* Operation: list_tests */
-    rpc_status_t (*deserialize_list_tests_req)(const struct call_param_buf *req_buf,
-        struct test_spec *test_spec);
+	/* Operation: list_tests */
+	rpc_status_t (*deserialize_list_tests_req)(const struct rpc_buffer *req_buf,
+		struct test_spec *test_spec);
 
-    rpc_status_t (*serialize_list_tests_resp)(struct call_param_buf *resp_buf,
-        const struct test_summary *summary,
-        const struct test_result *results);
+	rpc_status_t (*serialize_list_tests_resp)(struct rpc_buffer *resp_buf,
+		const struct test_summary *summary,
+		const struct test_result *results);
 };
 
 #endif /* TEST_RUNNER_PROVIDER_SERIALIZER_H */
diff --git a/components/service/test_runner/provider/test_runner_provider.c b/components/service/test_runner/provider/test_runner_provider.c
index a0a2da7..47ff9e8 100644
--- a/components/service/test_runner/provider/test_runner_provider.c
+++ b/components/service/test_runner/provider/test_runner_provider.c
@@ -3,202 +3,203 @@
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
-#include <stdlib.h>
-#include <stdbool.h>
+#include "test_runner_provider.h"
+
+#include <protocols/rpc/common/packed-c/status.h>
 #include <protocols/service/test_runner/packed-c/opcodes.h>
 #include <protocols/service/test_runner/packed-c/status.h>
-#include <protocols/rpc/common/packed-c/status.h>
-#include "test_runner_provider.h"
+#include <stdbool.h>
+#include <stdlib.h>
+
 #include "test_runner_backend.h"
+#include "test_runner_uuid.h"
 
 /* Service request handlers */
-static rpc_status_t run_tests_handler(void *context, struct call_req* req);
-static rpc_status_t list_tests_handler(void *context, struct call_req* req);
+static rpc_status_t run_tests_handler(void *context, struct rpc_request *req);
+static rpc_status_t list_tests_handler(void *context, struct rpc_request *req);
 
 /* Handler mapping table for service */
 static const struct service_handler handler_table[] = {
-    {TS_TEST_RUNNER_OPCODE_RUN_TESTS,          run_tests_handler},
-    {TS_TEST_RUNNER_OPCODE_LIST_TESTS,         list_tests_handler}
+	{ TS_TEST_RUNNER_OPCODE_RUN_TESTS, run_tests_handler },
+	{ TS_TEST_RUNNER_OPCODE_LIST_TESTS, list_tests_handler }
 };
 
-struct rpc_interface *test_runner_provider_init(struct test_runner_provider *context)
+struct rpc_service_interface *test_runner_provider_init(struct test_runner_provider *context)
 {
-    struct rpc_interface *rpc_interface = NULL;
+	struct rpc_service_interface *rpc_interface = NULL;
+	const struct rpc_uuid service_uuid = { .uuid = TS_TEST_RUNNER_SERVICE_UUID };
 
-    if (context) {
+	if (context) {
+		for (size_t encoding = 0; encoding < TS_RPC_ENCODING_LIMIT; ++encoding)
+			context->serializers[encoding] = NULL;
 
-        for (size_t encoding = 0; encoding < TS_RPC_ENCODING_LIMIT; ++encoding)
-            context->serializers[encoding] = NULL;
+		context->backend_list = NULL;
 
-        context->backend_list = NULL;
+		service_provider_init(&context->base_provider, context, &service_uuid,
+				      handler_table,
+				      sizeof(handler_table) / sizeof(struct service_handler));
 
-        service_provider_init(&context->base_provider, context,
-                    handler_table, sizeof(handler_table)/sizeof(struct service_handler));
+		rpc_interface = service_provider_get_rpc_interface(&context->base_provider);
 
-        rpc_interface = service_provider_get_rpc_interface(&context->base_provider);
+		/* Allow a deployment specific test_runner backend to be registrered */
+		test_runner_register_default_backend(context);
+	}
 
-        /* Allow a deployment specific test_runner backend to be registrered */
-        test_runner_register_default_backend(context);
-    }
-
-    return rpc_interface;
+	return rpc_interface;
 }
 
 void test_runner_provider_deinit(struct test_runner_provider *context)
 {
-    (void)context;
+	(void)context;
 }
 
-void test_runner_provider_register_serializer(struct test_runner_provider *context,
-                unsigned int encoding, const struct test_runner_provider_serializer *serializer)
+void test_runner_provider_register_serializer(
+	struct test_runner_provider *context, unsigned int encoding,
+	const struct test_runner_provider_serializer *serializer)
 {
-    if (encoding < TS_RPC_ENCODING_LIMIT)
-        context->serializers[encoding] = serializer;
+	if (encoding < TS_RPC_ENCODING_LIMIT)
+		context->serializers[encoding] = serializer;
 }
 
 void test_runner_provider_register_backend(struct test_runner_provider *context,
-                struct test_runner_backend *backend)
+					   struct test_runner_backend *backend)
 {
-    /* Insert into list of backend test runners */
-    backend->next = context->backend_list;
-    context->backend_list = backend;
+	/* Insert into list of backend test runners */
+	backend->next = context->backend_list;
+	context->backend_list = backend;
 }
 
-static const struct test_runner_provider_serializer* get_test_runner_serializer(
-                struct test_runner_provider *context, const struct call_req *req)
+static const struct test_runner_provider_serializer *
+get_test_runner_serializer(struct test_runner_provider *context, const struct rpc_request *req)
 {
-    const struct test_runner_provider_serializer* serializer = NULL;
-    unsigned int encoding = call_req_get_encoding(req);
+	const struct test_runner_provider_serializer *serializer = NULL;
+	unsigned int encoding = 0; /* Only one encoding is supported now */
 
-    if (encoding < TS_RPC_ENCODING_LIMIT) serializer = context->serializers[encoding];
+	if (encoding < TS_RPC_ENCODING_LIMIT)
+		serializer = context->serializers[encoding];
 
-    return serializer;
+	return serializer;
 }
 
 static struct test_result *alloc_result_buf(struct test_runner_provider *context,
-                const struct test_spec *test_spec, size_t *result_limit)
+					    const struct test_spec *test_spec, size_t *result_limit)
 {
-    struct test_result *space = NULL;
-    size_t total_tests = 0;
-    struct test_runner_backend *backend = context->backend_list;
+	struct test_result *space = NULL;
+	size_t total_tests = 0;
+	struct test_runner_backend *backend = context->backend_list;
 
-    while (backend) {
+	while (backend) {
+		total_tests += backend->count_tests(test_spec);
+		backend = backend->next;
+	}
 
-        total_tests += backend->count_tests(test_spec);
-        backend = backend->next;
-    }
+	space = malloc(total_tests * sizeof(struct test_result));
 
-    space = malloc(total_tests * sizeof(struct test_result));
-
-    *result_limit = total_tests;
-    return space;
+	*result_limit = total_tests;
+	return space;
 }
 
-static int run_qualifying_tests(struct test_runner_provider *context, bool list_only, const struct test_spec *spec,
-		        struct test_summary *summary, struct test_result *results, size_t result_limit)
+static int run_qualifying_tests(struct test_runner_provider *context, bool list_only,
+				const struct test_spec *spec, struct test_summary *summary,
+				struct test_result *results, size_t result_limit)
 {
-    int test_status = TS_TEST_RUNNER_STATUS_SUCCESS;
-    struct test_runner_backend *backend = context->backend_list;
+	int test_status = TS_TEST_RUNNER_STATUS_SUCCESS;
+	struct test_runner_backend *backend = context->backend_list;
 
-    summary->num_tests = 0;
+	summary->num_tests = 0;
 	summary->num_results = 0;
 	summary->num_passed = 0;
 	summary->num_failed = 0;
 
-    while (backend && (test_status == TS_TEST_RUNNER_STATUS_SUCCESS)) {
+	while (backend && (test_status == TS_TEST_RUNNER_STATUS_SUCCESS)) {
+		struct test_summary interim_summary;
 
-        struct test_summary interim_summary;
+		if (list_only) {
+			backend->list_tests(spec, &interim_summary, &results[summary->num_results],
+					    result_limit - summary->num_results);
+		} else {
+			test_status = backend->run_tests(spec, &interim_summary,
+							 &results[summary->num_results],
+							 result_limit - summary->num_results);
+		}
 
-        if (list_only) {
+		summary->num_tests += interim_summary.num_tests;
+		summary->num_results += interim_summary.num_results;
+		summary->num_passed += interim_summary.num_passed;
+		summary->num_failed += interim_summary.num_failed;
 
-            backend->list_tests(spec, &interim_summary,
-                            &results[summary->num_results],
-                            result_limit - summary->num_results);
-        }
-        else {
+		backend = backend->next;
+	}
 
-            test_status = backend->run_tests(spec, &interim_summary,
-                            &results[summary->num_results],
-                            result_limit - summary->num_results);
-        }
-
-        summary->num_tests += interim_summary.num_tests;
-	    summary->num_results += interim_summary.num_results;
-	    summary->num_passed += interim_summary.num_passed;
-	    summary->num_failed += interim_summary.num_failed;
-
-        backend = backend->next;
-    }
-
-    return test_status;
+	return test_status;
 }
 
-static rpc_status_t run_tests_handler(void *context, struct call_req* req)
+static rpc_status_t run_tests_handler(void *context, struct rpc_request *req)
 {
-    struct test_runner_provider *this_instance = (struct test_runner_provider*)context;
-    rpc_status_t rpc_status = TS_RPC_ERROR_SERIALIZATION_NOT_SUPPORTED;
-    struct test_spec test_spec;
+	struct test_runner_provider *this_instance = (struct test_runner_provider *)context;
+	rpc_status_t rpc_status = RPC_ERROR_INTERNAL;
+	struct test_spec test_spec;
 
-    struct call_param_buf *req_buf = call_req_get_req_buf(req);
-    const struct test_runner_provider_serializer *serializer = get_test_runner_serializer(this_instance, req);
+	struct rpc_buffer *req_buf = &req->request;
+	const struct test_runner_provider_serializer *serializer =
+		get_test_runner_serializer(this_instance, req);
 
-    if (serializer)
-        rpc_status = serializer->deserialize_run_tests_req(req_buf, &test_spec);
+	if (serializer)
+		rpc_status = serializer->deserialize_run_tests_req(req_buf, &test_spec);
 
-    if (rpc_status == TS_RPC_CALL_ACCEPTED) {
+	if (rpc_status == RPC_SUCCESS) {
+		struct test_summary summary;
+		size_t result_limit = 0;
+		struct test_result *result_buf =
+			alloc_result_buf(this_instance, &test_spec, &result_limit);
 
-        int test_status;
-        struct test_summary summary;
-        size_t result_limit = 0;
-        struct test_result *result_buf = alloc_result_buf(this_instance, &test_spec, &result_limit);
+		req->service_status = run_qualifying_tests(this_instance, false, &test_spec,
+							   &summary, result_buf, result_limit);
 
-        test_status = run_qualifying_tests(this_instance, false, &test_spec, &summary, result_buf, result_limit);
+		if (req->service_status == TS_TEST_RUNNER_STATUS_SUCCESS) {
+			struct rpc_buffer *resp_buf = &req->response;
 
-        call_req_set_opstatus(req, test_status);
+			rpc_status = serializer->serialize_run_tests_resp(resp_buf, &summary,
+									  result_buf);
 
-        if (test_status == TS_TEST_RUNNER_STATUS_SUCCESS) {
+			free(result_buf);
+		}
+	}
 
-            struct call_param_buf *resp_buf = call_req_get_resp_buf(req);
-            rpc_status = serializer->serialize_run_tests_resp(resp_buf, &summary, result_buf);
-
-            free(result_buf);
-        }
-    }
-
-    return rpc_status;
+	return rpc_status;
 }
 
-static rpc_status_t list_tests_handler(void *context, struct call_req* req)
+static rpc_status_t list_tests_handler(void *context, struct rpc_request *req)
 {
-    struct test_runner_provider *this_instance = (struct test_runner_provider*)context;
-    rpc_status_t rpc_status = TS_RPC_ERROR_SERIALIZATION_NOT_SUPPORTED;
-    struct test_spec test_spec;
+	struct test_runner_provider *this_instance = (struct test_runner_provider *)context;
+	rpc_status_t rpc_status = RPC_ERROR_INTERNAL;
+	struct test_spec test_spec;
 
-    struct call_param_buf *req_buf = call_req_get_req_buf(req);
-    const struct test_runner_provider_serializer *serializer = get_test_runner_serializer(this_instance, req);
+	struct rpc_buffer *req_buf = &req->request;
+	const struct test_runner_provider_serializer *serializer =
+		get_test_runner_serializer(this_instance, req);
 
-    if (serializer)
-        rpc_status = serializer->deserialize_list_tests_req(req_buf, &test_spec);
+	if (serializer)
+		rpc_status = serializer->deserialize_list_tests_req(req_buf, &test_spec);
 
-    if (rpc_status == TS_RPC_CALL_ACCEPTED) {
+	if (rpc_status == TS_RPC_CALL_ACCEPTED) {
+		struct test_summary summary;
+		size_t result_limit = 0;
+		struct test_result *result_buf =
+			alloc_result_buf(this_instance, &test_spec, &result_limit);
 
-        int test_status;
-        struct test_summary summary;
-        size_t result_limit = 0;
-        struct test_result *result_buf = alloc_result_buf(this_instance, &test_spec, &result_limit);
+		req->service_status = run_qualifying_tests(this_instance, true, &test_spec,
+							   &summary, result_buf, result_limit);
 
-        test_status = run_qualifying_tests(this_instance, true, &test_spec, &summary, result_buf, result_limit);
+		if (req->service_status == TS_TEST_RUNNER_STATUS_SUCCESS) {
+			struct rpc_buffer *resp_buf = &req->response;
 
-        call_req_set_opstatus(req, test_status);
+			rpc_status = serializer->serialize_list_tests_resp(resp_buf, &summary,
+									   result_buf);
 
-        if (test_status == TS_TEST_RUNNER_STATUS_SUCCESS) {
+			free(result_buf);
+		}
+	}
 
-            struct call_param_buf *resp_buf = call_req_get_resp_buf(req);
-            rpc_status = serializer->serialize_list_tests_resp(resp_buf, &summary, result_buf);
-
-            free(result_buf);
-        }
-    }
-
-    return rpc_status;
+	return rpc_status;
 }
diff --git a/components/service/test_runner/provider/test_runner_provider.h b/components/service/test_runner/provider/test_runner_provider.h
index e5c9230..e81932d 100644
--- a/components/service/test_runner/provider/test_runner_provider.h
+++ b/components/service/test_runner/provider/test_runner_provider.h
@@ -7,8 +7,7 @@
 #ifndef TEST_RUNNER_PROVIDER_H
 #define TEST_RUNNER_PROVIDER_H
 
-#include <rpc/common/endpoint/rpc_interface.h>
-#include <rpc_caller.h>
+#include "components/rpc/common/endpoint/rpc_service_interface.h"
 #include <service/common/provider/service_provider.h>
 #include <service/test_runner/provider/serializer/test_runner_provider_serializer.h>
 #include <protocols/rpc/common/packed-c/encoding.h>
@@ -26,7 +25,7 @@
     struct test_runner_backend *backend_list;
 };
 
-struct rpc_interface *test_runner_provider_init(struct test_runner_provider *context);
+struct rpc_service_interface *test_runner_provider_init(struct test_runner_provider *context);
 
 void test_runner_provider_deinit(struct test_runner_provider *context);
 
diff --git a/components/service/test_runner/provider/test_runner_uuid.h b/components/service/test_runner/provider/test_runner_uuid.h
new file mode 100644
index 0000000..c71b058
--- /dev/null
+++ b/components/service/test_runner/provider/test_runner_uuid.h
@@ -0,0 +1,21 @@
+/*
+ * Copyright (c) 2023, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef TEST_RUNNER_UUID_H
+#define TEST_RUNNER_UUID_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define TS_TEST_RUNNER_SERVICE_UUID \
+{ 0x33, 0xc7, 0x5b, 0xaf, 0xac, 0x6a, 0x4f, 0xe4, 0x8a, 0xc7, 0xe9, 0x90, 0x9b, 0xee, 0x2d, 0x17 }
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* TEST_RUNNER_UUID_H */
diff --git a/components/service/test_runner/test/service/test_runner_service_tests.cpp b/components/service/test_runner/test/service/test_runner_service_tests.cpp
index 774465d..850d46b 100644
--- a/components/service/test_runner/test/service/test_runner_service_tests.cpp
+++ b/components/service/test_runner/test/service/test_runner_service_tests.cpp
@@ -22,22 +22,19 @@
 {
     void setup()
     {
-        struct rpc_caller *caller;
-        int status;
-
-        m_rpc_session_handle = NULL;
+        m_rpc_session = NULL;
         m_test_runner_service_context = NULL;
         m_test_runner_client = NULL;
 
         service_locator_init();
 
-        m_test_runner_service_context = service_locator_query("sn:trustedfirmware.org:test-runner:0", &status);
+        m_test_runner_service_context = service_locator_query("sn:trustedfirmware.org:test-runner:0");
         CHECK(m_test_runner_service_context);
 
-        m_rpc_session_handle = service_context_open(m_test_runner_service_context, TS_RPC_ENCODING_PACKED_C, &caller);
-        CHECK(m_rpc_session_handle);
+        m_rpc_session = service_context_open(m_test_runner_service_context);
+        CHECK(m_rpc_session);
 
-        m_test_runner_client = new test_runner_client(caller);
+        m_test_runner_client = new test_runner_client(m_rpc_session);
     }
 
     void teardown()
@@ -46,9 +43,9 @@
         m_test_runner_client = NULL;
 
 	if (m_test_runner_service_context) {
-	        if (m_rpc_session_handle) {
-                        service_context_close(m_test_runner_service_context, m_rpc_session_handle);
-                        m_rpc_session_handle = NULL;
+	        if (m_rpc_session) {
+                        service_context_close(m_test_runner_service_context, m_rpc_session);
+                        m_rpc_session = NULL;
 	        }
 
                 service_context_relinquish(m_test_runner_service_context);
@@ -56,7 +53,7 @@
 	}
     }
 
-    rpc_session_handle m_rpc_session_handle;
+    struct rpc_caller_session *m_rpc_session;
     struct service_context *m_test_runner_service_context;
     test_runner_client *m_test_runner_client;
 };
diff --git a/deployments/attestation/config/default-opteesp/CMakeLists.txt b/deployments/attestation/config/default-opteesp/CMakeLists.txt
index 4d3011f..58ecb34 100644
--- a/deployments/attestation/config/default-opteesp/CMakeLists.txt
+++ b/deployments/attestation/config/default-opteesp/CMakeLists.txt
@@ -20,7 +20,8 @@
 project(trusted-services LANGUAGES C ASM)
 add_executable(attestation)
 target_include_directories(attestation PRIVATE "${TOP_LEVEL_INCLUDE_DIRS}")
-set(SP_UUID_CANON "a1baf155-8876-4695-8f7c-54955e8db974")
+set(SP_BIN_UUID_CANON "a1baf155-8876-4695-8f7c-54955e8db974")
+set(SP_FFA_UUID_CANON "${TS_RPC_UUID_CANON}")
 set(SP_HEAP_SIZE "32 * 1024" CACHE STRING "SP heap size in bytes")
 set(TRACE_PREFIX "ATT" CACHE STRING "Trace prefix")
 
@@ -38,6 +39,7 @@
 #  Deployment specific components
 #
 #-------------------------------------------------------------------------------
+
 add_components(TARGET "attestation"
 	BASE_DIR ${TS_ROOT}
 	COMPONENTS
@@ -86,7 +88,8 @@
 
 include(${TS_ROOT}/tools/cmake/common/ExportSp.cmake)
 export_sp(
-	SP_UUID_CANON ${SP_UUID_CANON}
+	SP_FFA_UUID_CANON ${SP_FFA_UUID_CANON}
+	SP_BIN_UUID_CANON ${SP_BIN_UUID_CANON}
 	SP_NAME "attestation"
 	MK_IN ${TS_ROOT}/environments/opteesp/sp.mk.in
 	DTS_IN ${CMAKE_CURRENT_LIST_DIR}/default_attestation.dts.in
diff --git a/deployments/attestation/config/default-sp/CMakeLists.txt b/deployments/attestation/config/default-sp/CMakeLists.txt
index a1063ba..cdcbdcd 100644
--- a/deployments/attestation/config/default-sp/CMakeLists.txt
+++ b/deployments/attestation/config/default-sp/CMakeLists.txt
@@ -23,8 +23,8 @@
 add_executable(attestation)
 target_include_directories(attestation PRIVATE "${TOP_LEVEL_INCLUDE_DIRS}")
 set(SP_NAME "attestation")
-set(SP_UUID_CANON "a1baf155-8876-4695-8f7c-54955e8db974")
-set(SP_UUID_LE "0x55f1baa1 0x95467688 0x95547c8f 0x74b98d5e")
+set(SP_BIN_UUID_CANON "a1baf155-8876-4695-8f7c-54955e8db974")
+set(SP_FFA_UUID_CANON "${TS_RPC_UUID_CANON}")
 set(TRACE_PREFIX "ATT" CACHE STRING "Trace prefix")
 set(SP_STACK_SIZE "64 * 1024" CACHE STRING "Stack size")
 set(SP_HEAP_SIZE "32 * 1024" CACHE STRING "Heap size")
@@ -69,11 +69,11 @@
 
 endif()
 
-compiler_generate_binary_output(TARGET attestation NAME "${SP_UUID_CANON}.bin" SP_BINARY)
-install(FILES ${CMAKE_CURRENT_BINARY_DIR}/${SP_UUID_CANON}.bin DESTINATION ${TS_ENV}/bin)
+compiler_generate_binary_output(TARGET attestation NAME "${SP_BIN_UUID_CANON}.bin" SP_BINARY)
+install(FILES ${CMAKE_CURRENT_BINARY_DIR}/${SP_BIN_UUID_CANON}.bin DESTINATION ${TS_ENV}/bin)
 
 include(${TS_ROOT}/tools/cmake/common/ExportMemoryRegionsToManifest.cmake REQUIRED)
-export_memory_regions_to_manifest(TARGET attestation NAME "${SP_UUID_CANON}_memory_regions.dtsi" RES EXPORT_MEMORY_REGIONS_DTSI)
+export_memory_regions_to_manifest(TARGET attestation NAME "${SP_BIN_UUID_CANON}_memory_regions.dtsi" RES EXPORT_MEMORY_REGIONS_DTSI)
 
 #-------------------------------------------------------------------------------
 #  Deployment specific install options
@@ -88,9 +88,10 @@
 
 include(${TS_ROOT}/tools/cmake/common/ExportSp.cmake)
 export_sp(
-	SP_UUID_CANON ${SP_UUID_CANON}
+	SP_FFA_UUID_CANON ${SP_FFA_UUID_CANON}
+	SP_BIN_UUID_CANON ${SP_BIN_UUID_CANON}
 	SP_NAME ${SP_NAME}
 	DTS_IN ${CMAKE_CURRENT_LIST_DIR}/default_${SP_NAME}.dts.in
-	DTS_MEM_REGIONS ${SP_UUID_CANON}_memory_regions.dtsi
+	DTS_MEM_REGIONS ${SP_BIN_UUID_CANON}_memory_regions.dtsi
 	JSON_IN ${TS_ROOT}/environments/sp/sp_pkg.json.in
 )
diff --git a/deployments/attestation/env/commonsp/attestation_sp.c b/deployments/attestation/env/commonsp/attestation_sp.c
index 266f3fb..0ed3f65 100644
--- a/deployments/attestation/env/commonsp/attestation_sp.c
+++ b/deployments/attestation/env/commonsp/attestation_sp.c
@@ -4,7 +4,9 @@
  * SPDX-License-Identifier: BSD-3-Clause
  */
 
-#include "rpc/ffarpc/endpoint/ffarpc_call_ep.h"
+#include "components/rpc/ts_rpc/endpoint/sp/ts_rpc_endpoint_sp.h"
+#include "components/rpc/ts_rpc/caller/sp/ts_rpc_caller_sp.h"
+#include "components/rpc/common/caller/rpc_caller_session.h"
 #include "protocols/rpc/common/packed-c/status.h"
 #include "config/ramstore/config_ramstore.h"
 #include "config/loader/sp/sp_config_loader.h"
@@ -32,12 +34,13 @@
 {
 	/* Service provider objects */
 	struct attest_provider attest_provider = { 0 };
-	struct rpc_interface *attest_iface = NULL;
-	struct ffa_call_ep ffarpc_call_ep = { 0 };
+	struct rpc_service_interface *attest_iface = NULL;
+	struct ts_rpc_endpoint_sp rpc_endpoint = { 0 };
 	struct sp_msg req_msg = { 0 };
 	struct sp_msg resp_msg = { 0 };
 	uint16_t own_id = 0;
 	sp_result result = SP_RESULT_INTERNAL_ERROR;
+	rpc_status_t rpc_status = RPC_ERROR_INTERNAL;
 
 	/* Claim source objects */
 	struct claim_source *claim_source = NULL;
@@ -127,9 +130,19 @@
 	}
 
 	attest_provider_register_serializer(&attest_provider,
-		TS_RPC_ENCODING_PACKED_C, packedc_attest_provider_serializer_instance());
+					    packedc_attest_provider_serializer_instance());
 
-	ffa_call_ep_init(&ffarpc_call_ep, attest_iface, own_id);
+	rpc_status = ts_rpc_endpoint_sp_init(&rpc_endpoint, 1, 16);
+	if (rpc_status != RPC_SUCCESS) {
+		EMSG("Failed to initialize RPC endpoint: %d", rpc_status);
+		goto fatal_error;
+	}
+
+	rpc_status = ts_rpc_endpoint_sp_add_service(&rpc_endpoint, attest_iface);
+	if (rpc_status != RPC_SUCCESS) {
+		EMSG("Failed to add service to RPC endpoint: %d", rpc_status);
+		goto fatal_error;
+	}
 
 	/*********************************************************
 	 * End of boot phase
@@ -141,7 +154,7 @@
 	}
 
 	while (1) {
-		ffa_call_ep_receive(&ffarpc_call_ep, &req_msg, &resp_msg);
+		ts_rpc_endpoint_sp_receive(&rpc_endpoint, &req_msg, &resp_msg);
 
 		result = sp_msg_send_direct_resp(&resp_msg, &req_msg);
 		if (result != SP_RESULT_OK) {
@@ -188,27 +201,27 @@
 
 bool locate_crypto_service(void)
 {
-	int status = 0;
-	struct rpc_caller *caller = NULL;
+	struct rpc_caller_session *session = NULL;
 	psa_status_t psa_status = PSA_ERROR_GENERIC_ERROR;
 
 	service_locator_init();
 
 	/* todo - add option to use configurable crypto service location */
 	struct service_context *crypto_service_context =
-		service_locator_query("sn:ffa:d9df52d5-16a2-4bb2-9aa4-d26d3b84e8c0:0", &status);
+		service_locator_query("sn:ffa:d9df52d5-16a2-4bb2-9aa4-d26d3b84e8c0:0");
 
 	if (!crypto_service_context) {
-		EMSG("Service locator query failed: %d", status);
+		EMSG("Service locator query failed");
 		return false;
 	}
 
-	if (!service_context_open(crypto_service_context, TS_RPC_ENCODING_PACKED_C, &caller)) {
+	session = service_context_open(crypto_service_context);
+	if (!session) {
 		EMSG("Failed to open crypto service context");
 		return false;
 	}
 
-	psa_status = psa_crypto_client_init(caller);
+	psa_status = psa_crypto_client_init(session);
 	if (psa_status != PSA_SUCCESS) {
 		EMSG("Failed to init PSA crypto client: %d", psa_status);
 		return false;
diff --git a/deployments/attestation/env/commonsp/attestation_sp.cmake b/deployments/attestation/env/commonsp/attestation_sp.cmake
index e483184..fcef307 100644
--- a/deployments/attestation/env/commonsp/attestation_sp.cmake
+++ b/deployments/attestation/env/commonsp/attestation_sp.cmake
@@ -21,7 +21,9 @@
 		"components/config/loader/sp"
 		"components/messaging/ffa/libsp"
 		"components/rpc/common/interface"
-		"components/rpc/ffarpc/endpoint"
+		"components/rpc/common/endpoint"
+		"components/rpc/ts_rpc/common"
+		"components/rpc/ts_rpc/endpoint/sp"
 )
 
 target_sources(attestation PRIVATE
diff --git a/deployments/attestation/infra/tpm-eventlog-psa.cmake b/deployments/attestation/infra/tpm-eventlog-psa.cmake
index b734ac9..00150d4 100644
--- a/deployments/attestation/infra/tpm-eventlog-psa.cmake
+++ b/deployments/attestation/infra/tpm-eventlog-psa.cmake
@@ -16,7 +16,7 @@
 	BASE_DIR ${TS_ROOT}
 	COMPONENTS
 		"components/common/uuid"
-		"components/rpc/ffarpc/caller/sp"
+		"components/rpc/ts_rpc/caller/sp"
 		"components/rpc/common/caller"
 		"components/service/common/client"
 		"components/service/locator"
diff --git a/deployments/block-storage/config/cfi-flash-optee/CMakeLists.txt b/deployments/block-storage/config/cfi-flash-optee/CMakeLists.txt
index 0229b5d..b6501f2 100644
--- a/deployments/block-storage/config/cfi-flash-optee/CMakeLists.txt
+++ b/deployments/block-storage/config/cfi-flash-optee/CMakeLists.txt
@@ -25,7 +25,8 @@
 project(trusted-services LANGUAGES C ASM)
 add_executable(block-storage)
 target_include_directories(block-storage PRIVATE "${TOP_LEVEL_INCLUDE_DIRS}")
-set(SP_UUID_CANON "63646e80-eb52-462f-ac4f-8cdf3987519c")
+set(SP_BIN_UUID_CANON "63646e80-eb52-462f-ac4f-8cdf3987519c")
+set(SP_FFA_UUID_CANON "${TS_RPC_UUID_CANON}")
 set(SP_HEAP_SIZE "120 * 1024" CACHE STRING "SP heap size in bytes")
 set(TRACE_PREFIX "BLOCK" CACHE STRING "Trace prefix")
 
@@ -38,6 +39,7 @@
 #  that provides ram-backed block stoarged, configured with storage partitions
 #  that conform to the 'ref' scheme used for test.
 #-------------------------------------------------------------------------------
+
 add_components(TARGET "block-storage"
 	BASE_DIR ${TS_ROOT}
 	COMPONENTS
@@ -91,7 +93,8 @@
 
 include(${TS_ROOT}/tools/cmake/common/ExportSp.cmake)
 export_sp(
-	SP_UUID_CANON ${SP_UUID_CANON}
+	SP_FFA_UUID_CANON ${SP_FFA_UUID_CANON}
+	SP_BIN_UUID_CANON ${SP_BIN_UUID_CANON}
 	SP_NAME "block-storage"
 	MK_IN ${TS_ROOT}/environments/opteesp/sp.mk.in
 	DTS_IN ${CMAKE_CURRENT_LIST_DIR}/default_block-storage.dts.in
diff --git a/deployments/block-storage/config/default-opteesp/CMakeLists.txt b/deployments/block-storage/config/default-opteesp/CMakeLists.txt
index 17cbf68..5592dcd 100644
--- a/deployments/block-storage/config/default-opteesp/CMakeLists.txt
+++ b/deployments/block-storage/config/default-opteesp/CMakeLists.txt
@@ -18,7 +18,8 @@
 project(trusted-services LANGUAGES C ASM)
 add_executable(block-storage)
 target_include_directories(block-storage PRIVATE "${TOP_LEVEL_INCLUDE_DIRS}")
-set(SP_UUID_CANON "63646e80-eb52-462f-ac4f-8cdf3987519c")
+set(SP_BIN_UUID_CANON "63646e80-eb52-462f-ac4f-8cdf3987519c")
+set(SP_FFA_UUID_CANON "${TS_RPC_UUID_CANON}")
 set(SP_HEAP_SIZE "120 * 1024" CACHE STRING "SP heap size in bytes")
 set(TRACE_PREFIX "BLOCK" CACHE STRING "Trace prefix")
 
@@ -31,6 +32,7 @@
 #  that provides ram-backed block stoarged, configured with storage partitions
 #  that conform to the 'ref' scheme used for test.
 #-------------------------------------------------------------------------------
+
 add_components(TARGET "block-storage"
 	BASE_DIR ${TS_ROOT}
 	COMPONENTS
@@ -69,7 +71,8 @@
 
 include(${TS_ROOT}/tools/cmake/common/ExportSp.cmake)
 export_sp(
-	SP_UUID_CANON ${SP_UUID_CANON}
+	SP_FFA_UUID_CANON ${SP_FFA_UUID_CANON}
+	SP_BIN_UUID_CANON ${SP_BIN_UUID_CANON}
 	SP_NAME "block-storage"
 	MK_IN ${TS_ROOT}/environments/opteesp/sp.mk.in
 	DTS_IN ${CMAKE_CURRENT_LIST_DIR}/default_block-storage.dts.in
diff --git a/deployments/block-storage/config/default-sp/CMakeLists.txt b/deployments/block-storage/config/default-sp/CMakeLists.txt
index f765cf8..2241c9c 100644
--- a/deployments/block-storage/config/default-sp/CMakeLists.txt
+++ b/deployments/block-storage/config/default-sp/CMakeLists.txt
@@ -22,8 +22,8 @@
 target_include_directories(block-storage PRIVATE "${TOP_LEVEL_INCLUDE_DIRS}")
 
 set(SP_NAME "block-storage")
-set(SP_UUID_CANON "63646e80-eb52-462f-ac4f-8cdf3987519c")
-set(SP_UUID_LE "0x806e6463 0x2f4652eb 0xdf8c4fac 0x9c518739")
+set(SP_BIN_UUID_CANON "63646e80-eb52-462f-ac4f-8cdf3987519c")
+set(SP_FFA_UUID_CANON "${TS_RPC_UUID_CANON}")
 set(SP_HEAP_SIZE "120 * 1024" CACHE STRING "SP heap size in bytes")
 set(SP_STACK_SIZE "64 * 1024" CACHE STRING "Stack size")
 set(TRACE_PREFIX "BLOCK" CACHE STRING "Trace prefix")
@@ -57,11 +57,11 @@
 
 endif()
 
-compiler_generate_binary_output(TARGET block-storage NAME "${SP_UUID_CANON}.bin" SP_BINARY)
-install(FILES ${CMAKE_CURRENT_BINARY_DIR}/${SP_UUID_CANON}.bin DESTINATION ${TS_ENV}/bin)
+compiler_generate_binary_output(TARGET block-storage NAME "${SP_BIN_UUID_CANON}.bin" SP_BINARY)
+install(FILES ${CMAKE_CURRENT_BINARY_DIR}/${SP_BIN_UUID_CANON}.bin DESTINATION ${TS_ENV}/bin)
 
 include(${TS_ROOT}/tools/cmake/common/ExportMemoryRegionsToManifest.cmake REQUIRED)
-export_memory_regions_to_manifest(TARGET block-storage NAME "${SP_UUID_CANON}_memory_regions.dtsi" RES EXPORT_MEMORY_REGIONS_DTSI)
+export_memory_regions_to_manifest(TARGET block-storage NAME "${SP_BIN_UUID_CANON}_memory_regions.dtsi" RES EXPORT_MEMORY_REGIONS_DTSI)
 
 #-------------------------------------------------------------------------------
 #  Deployment specific install options
@@ -76,9 +76,10 @@
 
 include(${TS_ROOT}/tools/cmake/common/ExportSp.cmake REQUIRED)
 export_sp(
-	SP_UUID_CANON ${SP_UUID_CANON}
+	SP_FFA_UUID_CANON ${SP_FFA_UUID_CANON}
+	SP_BIN_UUID_CANON ${SP_BIN_UUID_CANON}
 	SP_NAME ${SP_NAME}
 	DTS_IN ${CMAKE_CURRENT_LIST_DIR}/default_${SP_NAME}.dts.in
-	DTS_MEM_REGIONS ${SP_UUID_CANON}_memory_regions.dtsi
+	DTS_MEM_REGIONS ${SP_BIN_UUID_CANON}_memory_regions.dtsi
 	JSON_IN ${TS_ROOT}/environments/sp/sp_pkg.json.in
 )
diff --git a/deployments/block-storage/config/edk2-secure-flash-opteesp/CMakeLists.txt b/deployments/block-storage/config/edk2-secure-flash-opteesp/CMakeLists.txt
index 60d2403..5b8bedf 100644
--- a/deployments/block-storage/config/edk2-secure-flash-opteesp/CMakeLists.txt
+++ b/deployments/block-storage/config/edk2-secure-flash-opteesp/CMakeLists.txt
@@ -29,7 +29,8 @@
 project(trusted-services LANGUAGES C ASM)
 add_executable(block-storage)
 target_include_directories(block-storage PRIVATE "${TOP_LEVEL_INCLUDE_DIRS}")
-set(SP_UUID_CANON "63646e80-eb52-462f-ac4f-8cdf3987519c")
+set(SP_BIN_UUID_CANON "63646e80-eb52-462f-ac4f-8cdf3987519c")
+set(SP_FFA_UUID_CANON "${TS_RPC_UUID_CANON}")
 set(SP_HEAP_SIZE "120 * 1024" CACHE STRING "SP heap size in bytes")
 set(TRACE_PREFIX "BLOCK" CACHE STRING "Trace prefix")
 
@@ -40,6 +41,7 @@
 #-------------------------------------------------------------------------------
 #  Deployment specific components.
 #-------------------------------------------------------------------------------
+
 add_components(TARGET "block-storage"
 	BASE_DIR ${TS_ROOT}
 	COMPONENTS
@@ -92,7 +94,8 @@
 
 include(${TS_ROOT}/tools/cmake/common/ExportSp.cmake)
 export_sp(
-	SP_UUID_CANON ${SP_UUID_CANON}
+	SP_FFA_UUID_CANON ${SP_FFA_UUID_CANON}
+	SP_BIN_UUID_CANON ${SP_BIN_UUID_CANON}
 	SP_NAME "block-storage"
 	MK_IN ${TS_ROOT}/environments/opteesp/sp.mk.in
 	DTS_IN ${CMAKE_CURRENT_LIST_DIR}/default_block-storage.dts.in
diff --git a/deployments/block-storage/config/semihosted-opteesp/CMakeLists.txt b/deployments/block-storage/config/semihosted-opteesp/CMakeLists.txt
index f6463cd..2be5176 100644
--- a/deployments/block-storage/config/semihosted-opteesp/CMakeLists.txt
+++ b/deployments/block-storage/config/semihosted-opteesp/CMakeLists.txt
@@ -24,7 +24,8 @@
 project(trusted-services LANGUAGES C ASM)
 add_executable(block-storage)
 target_include_directories(block-storage PRIVATE "${TOP_LEVEL_INCLUDE_DIRS}")
-set(SP_UUID_CANON "63646e80-eb52-462f-ac4f-8cdf3987519c")
+set(SP_BIN_UUID_CANON "63646e80-eb52-462f-ac4f-8cdf3987519c")
+set(SP_FFA_UUID_CANON "${TS_RPC_UUID_CANON}")
 set(SP_HEAP_SIZE "120 * 1024" CACHE STRING "SP heap size in bytes")
 set(TRACE_PREFIX "BLOCK" CACHE STRING "Trace prefix")
 
@@ -44,6 +45,7 @@
 #  that provides NV storage backed by a semihosted file residing in a host
 #  device filesystem.
 #-------------------------------------------------------------------------------
+
 add_components(TARGET "block-storage"
 	BASE_DIR ${TS_ROOT}
 	COMPONENTS
@@ -88,7 +90,8 @@
 
 include(${TS_ROOT}/tools/cmake/common/ExportSp.cmake)
 export_sp(
-	SP_UUID_CANON ${SP_UUID_CANON}
+	SP_FFA_UUID_CANON ${SP_FFA_UUID_CANON}
+	SP_BIN_UUID_CANON ${SP_BIN_UUID_CANON}
 	SP_NAME "block-storage"
 	MK_IN ${TS_ROOT}/environments/opteesp/sp.mk.in
 	DTS_IN ${CMAKE_CURRENT_LIST_DIR}/default_block-storage.dts.in
diff --git a/deployments/block-storage/env/commonsp/block_storage_sp.c b/deployments/block-storage/env/commonsp/block_storage_sp.c
index 5f3d53c..10ede2d 100644
--- a/deployments/block-storage/env/commonsp/block_storage_sp.c
+++ b/deployments/block-storage/env/commonsp/block_storage_sp.c
@@ -4,7 +4,7 @@
  */
 
 #include "common/crc32/crc32.h"
-#include "rpc/ffarpc/endpoint/ffarpc_call_ep.h"
+#include "rpc/ts_rpc/endpoint/sp/ts_rpc_endpoint_sp.h"
 #include "protocols/rpc/common/packed-c/status.h"
 #include "config/ramstore/config_ramstore.h"
 #include "config/loader/sp/sp_config_loader.h"
@@ -22,14 +22,15 @@
 
 void __noreturn sp_main(union ffa_boot_info *boot_info)
 {
-	struct ffa_call_ep ffarpc_call_ep = { 0 };
+	struct ts_rpc_endpoint_sp rpc_endpoint = { 0 };
 	struct block_storage_provider service_provider = { 0 };
 	struct block_store *backend = NULL;
-	struct rpc_interface *service_iface = NULL;
+	struct rpc_service_interface *service_iface = NULL;
 	struct sp_msg req_msg = { 0 };
 	struct sp_msg resp_msg = { 0 };
 	uint16_t own_id = 0;
 	sp_result result = SP_RESULT_INTERNAL_ERROR;
+	rpc_status_t rpc_status = RPC_ERROR_INTERNAL;
 
 	/* Boot phase */
 	if (!sp_init(&own_id)) {
@@ -61,13 +62,21 @@
 		goto fatal_error;
 	}
 
-	block_storage_provider_register_serializer(
-		&service_provider,
-		TS_RPC_ENCODING_PACKED_C,
-		packedc_block_storage_serializer_instance());
+	block_storage_provider_register_serializer(&service_provider,
+						   packedc_block_storage_serializer_instance());
 
 	/* Associate service interface with FFA call endpoint */
-	ffa_call_ep_init(&ffarpc_call_ep, service_iface, own_id);
+	rpc_status = ts_rpc_endpoint_sp_init(&rpc_endpoint, 1, 16);
+	if (rpc_status != RPC_SUCCESS) {
+		EMSG("Failed to initialize RPC endpoint: %d", rpc_status);
+		goto fatal_error;
+	}
+
+	rpc_status = ts_rpc_endpoint_sp_add_service(&rpc_endpoint, service_iface);
+	if (rpc_status != RPC_SUCCESS) {
+		EMSG("Failed to add service to RPC endpoint: %d", rpc_status);
+		goto fatal_error;
+	}
 
 	/* End of boot phase */
 	result = sp_msg_wait(&req_msg);
@@ -77,7 +86,7 @@
 	}
 
 	while (1) {
-		ffa_call_ep_receive(&ffarpc_call_ep, &req_msg, &resp_msg);
+		ts_rpc_endpoint_sp_receive(&rpc_endpoint, &req_msg, &resp_msg);
 
 		result = sp_msg_send_direct_resp(&resp_msg, &req_msg);
 		if (result != SP_RESULT_OK) {
diff --git a/deployments/block-storage/env/commonsp/block_storage_sp.cmake b/deployments/block-storage/env/commonsp/block_storage_sp.cmake
index d55474c..78da5d7 100644
--- a/deployments/block-storage/env/commonsp/block_storage_sp.cmake
+++ b/deployments/block-storage/env/commonsp/block_storage_sp.cmake
@@ -22,7 +22,9 @@
 		"components/config/loader/sp"
 		"components/messaging/ffa/libsp"
 		"components/rpc/common/interface"
-		"components/rpc/ffarpc/endpoint"
+		"components/rpc/common/endpoint"
+		"components/rpc/ts_rpc/common"
+		"components/rpc/ts_rpc/endpoint/sp"
 )
 
 target_sources(block-storage PRIVATE
diff --git a/deployments/component-test/component-test.cmake b/deployments/component-test/component-test.cmake
index 2724ccf..99ceb78 100644
--- a/deployments/component-test/component-test.cmake
+++ b/deployments/component-test/component-test.cmake
@@ -42,16 +42,12 @@
 		"components/config/ramstore/test"
 		"components/messaging/ffa/libsp/mock"
 		"components/rpc/common/caller"
+		"components/rpc/common/endpoint"
 		"components/rpc/common/interface"
-		"components/rpc/common/demux"
 		"components/rpc/common/test"
 		"components/rpc/common/test/protocol"
 		"components/rpc/direct"
 		"components/rpc/dummy"
-		"components/rpc/ffarpc/caller/sp"
-		"components/rpc/ffarpc/caller/sp/test"
-		"components/rpc/ffarpc/endpoint"
-		"components/rpc/ffarpc/endpoint/test"
 		"components/service/common/include"
 		"components/service/common/serializer/protobuf"
 		"components/service/common/client"
@@ -69,10 +65,6 @@
 		"components/service/locator/standalone/services/block-storage"
 		"components/service/locator/standalone/services/fwu"
 		"components/service/locator/standalone/services/smm-variable"
-		"components/service/discovery/client"
-		"components/service/discovery/provider"
-		"components/service/discovery/provider/serializer/packed-c"
-		"components/service/discovery/test/service"
 		"components/service/attestation/include"
 		"components/service/attestation/claims"
 		"components/service/attestation/claims/sources/boot_seed_generator"
diff --git a/deployments/crypto/config/default-opteesp/CMakeLists.txt b/deployments/crypto/config/default-opteesp/CMakeLists.txt
index 1301b1f..1e4069d 100644
--- a/deployments/crypto/config/default-opteesp/CMakeLists.txt
+++ b/deployments/crypto/config/default-opteesp/CMakeLists.txt
@@ -27,7 +27,8 @@
 project(trusted-services LANGUAGES C ASM)
 add_executable(crypto)
 target_include_directories(crypto PRIVATE "${TOP_LEVEL_INCLUDE_DIRS}")
-set(SP_UUID_CANON "d9df52d5-16a2-4bb2-9aa4-d26d3b84e8c0")
+set(SP_BIN_UUID_CANON "d9df52d5-16a2-4bb2-9aa4-d26d3b84e8c0")
+set(SP_FFA_UUID_CANON "${TS_RPC_UUID_CANON}")
 set(SP_HEAP_SIZE "490 * 1024" CACHE STRING "SP heap size in bytes")
 set(TRACE_PREFIX "CRYPTO" CACHE STRING "Trace prefix")
 
@@ -39,6 +40,7 @@
 #  Deployment specific components
 #
 #-------------------------------------------------------------------------------
+
 add_components(TARGET "crypto"
 	BASE_DIR ${TS_ROOT}
 	COMPONENTS
@@ -87,7 +89,8 @@
 
 include(${TS_ROOT}/tools/cmake/common/ExportSp.cmake)
 export_sp(
-	SP_UUID_CANON ${SP_UUID_CANON}
+	SP_FFA_UUID_CANON ${SP_FFA_UUID_CANON}
+	SP_BIN_UUID_CANON ${SP_BIN_UUID_CANON}
 	SP_NAME "crypto"
 	MK_IN ${TS_ROOT}/environments/opteesp/sp.mk.in
 	DTS_IN ${CMAKE_CURRENT_LIST_DIR}/default_crypto.dts.in
diff --git a/deployments/crypto/config/default-sp/CMakeLists.txt b/deployments/crypto/config/default-sp/CMakeLists.txt
index df6080f..83594c5 100644
--- a/deployments/crypto/config/default-sp/CMakeLists.txt
+++ b/deployments/crypto/config/default-sp/CMakeLists.txt
@@ -30,8 +30,8 @@
 add_executable(crypto)
 target_include_directories(crypto PRIVATE "${TOP_LEVEL_INCLUDE_DIRS}")
 set(SP_NAME "crypto")
-set(SP_UUID_CANON "d9df52d5-16a2-4bb2-9aa4-d26d3b84e8c0")
-set(SP_UUID_LE "0xd552dfd9 0xb24ba216 0x6dd2a49a 0xc0e8843b")
+set(SP_BIN_UUID_CANON "d9df52d5-16a2-4bb2-9aa4-d26d3b84e8c0")
+set(SP_FFA_UUID_CANON "${TS_RPC_UUID_CANON}")
 set(TRACE_PREFIX "CRYPTO" CACHE STRING "Trace prefix")
 set(SP_STACK_SIZE "64 * 1024" CACHE STRING "Stack size")
 set(SP_HEAP_SIZE "490 * 1024" CACHE STRING "Heap size")
@@ -70,11 +70,11 @@
 
 endif()
 
-compiler_generate_binary_output(TARGET crypto NAME "${SP_UUID_CANON}.bin" SP_BINARY)
-install(FILES ${CMAKE_CURRENT_BINARY_DIR}/${SP_UUID_CANON}.bin DESTINATION ${TS_ENV}/bin)
+compiler_generate_binary_output(TARGET crypto NAME "${SP_BIN_UUID_CANON}.bin" SP_BINARY)
+install(FILES ${CMAKE_CURRENT_BINARY_DIR}/${SP_BIN_UUID_CANON}.bin DESTINATION ${TS_ENV}/bin)
 
 include(${TS_ROOT}/tools/cmake/common/ExportMemoryRegionsToManifest.cmake REQUIRED)
-export_memory_regions_to_manifest(TARGET crypto NAME "${SP_UUID_CANON}_memory_regions.dtsi" RES EXPORT_MEMORY_REGIONS_DTSI)
+export_memory_regions_to_manifest(TARGET crypto NAME "${SP_BIN_UUID_CANON}_memory_regions.dtsi" RES EXPORT_MEMORY_REGIONS_DTSI)
 
 #-------------------------------------------------------------------------------
 #  Deployment specific install options
@@ -89,9 +89,10 @@
 
 include(${TS_ROOT}/tools/cmake/common/ExportSp.cmake REQUIRED)
 export_sp(
-	SP_UUID_CANON ${SP_UUID_CANON}
+	SP_FFA_UUID_CANON ${SP_FFA_UUID_CANON}
+	SP_BIN_UUID_CANON ${SP_BIN_UUID_CANON}
 	SP_NAME ${SP_NAME}
 	DTS_IN ${CMAKE_CURRENT_LIST_DIR}/default_${SP_NAME}.dts.in
-	DTS_MEM_REGIONS ${SP_UUID_CANON}_memory_regions.dtsi
+	DTS_MEM_REGIONS ${SP_BIN_UUID_CANON}_memory_regions.dtsi
 	JSON_IN ${TS_ROOT}/environments/sp/sp_pkg.json.in
 )
diff --git a/deployments/crypto/crypto.cmake b/deployments/crypto/crypto.cmake
index 5b7b58e..ba5db56 100644
--- a/deployments/crypto/crypto.cmake
+++ b/deployments/crypto/crypto.cmake
@@ -10,11 +10,10 @@
 	COMPONENTS
 		"components/common/tlv"
 		"components/rpc/common/interface"
+		"components/rpc/common/endpoint"
 		"components/service/common/include"
 		"components/service/common/serializer/protobuf"
 		"components/service/common/provider"
-		"components/service/discovery/provider"
-		"components/service/discovery/provider/serializer/packed-c"
 		"components/service/crypto/provider"
 		"components/service/crypto/provider/serializer/protobuf"
 		"components/service/crypto/provider/serializer/packed-c"
diff --git a/deployments/crypto/env/commonsp/crypto_sp.c b/deployments/crypto/env/commonsp/crypto_sp.c
index a8abd46..e671954 100644
--- a/deployments/crypto/env/commonsp/crypto_sp.c
+++ b/deployments/crypto/env/commonsp/crypto_sp.c
@@ -3,7 +3,8 @@
  * Copyright (c) 2020-2022, Arm Limited and Contributors. All rights reserved.
  */
 
-#include "rpc/ffarpc/endpoint/ffarpc_call_ep.h"
+#include "components/rpc/common/endpoint/rpc_service_interface.h"
+#include "components/rpc/ts_rpc/endpoint/sp/ts_rpc_endpoint_sp.h"
 #include "service/secure_storage/factory/storage_factory.h"
 #include "service/crypto/factory/crypto_provider_factory.h"
 #include "service/crypto/backend/mbedcrypto/mbedcrypto_backend.h"
@@ -21,14 +22,17 @@
 void __noreturn sp_main(union ffa_boot_info *boot_info)
 {
 	struct crypto_provider *crypto_provider = NULL;
-	struct ffa_call_ep ffarpc_call_ep = { 0 };
-	struct rpc_interface *crypto_iface = NULL;
+	struct crypto_provider *crypto_protobuf_provider = NULL;
+	struct ts_rpc_endpoint_sp rpc_endpoint = { 0 };
+	struct rpc_service_interface *crypto_iface = NULL;
+	struct rpc_service_interface *crypto_iface_protobuf = NULL;
 	struct sp_msg req_msg = { 0 };
 	struct sp_msg resp_msg = { 0 };
 	struct storage_backend *storage_backend = NULL;
 	uint16_t own_id = 0;
 	psa_status_t psa_status = PSA_ERROR_GENERIC_ERROR;
 	sp_result result = SP_RESULT_INTERNAL_ERROR;
+	rpc_status_t rpc_status = RPC_ERROR_INTERNAL;
 
 	/* Boot phase */
 	if (!sp_init(&own_id)) {
@@ -63,13 +67,42 @@
 		goto fatal_error;
 	}
 
+	crypto_protobuf_provider = crypto_protobuf_provider_factory_create();
+	if (!crypto_protobuf_provider) {
+		EMSG("Failed to create crypto protobuf provider factory");
+		goto fatal_error;
+	}
+
 	crypto_iface = service_provider_get_rpc_interface(&crypto_provider->base_provider);
 	if (!crypto_iface) {
 		EMSG("Failed to create service provider RPC interface");
 		goto fatal_error;
 	}
 
-	ffa_call_ep_init(&ffarpc_call_ep, crypto_iface, own_id);
+	crypto_iface_protobuf = service_provider_get_rpc_interface(
+		&crypto_protobuf_provider->base_provider);
+	if (!crypto_iface_protobuf) {
+		EMSG("Failed to create service provider RPC interface");
+		goto fatal_error;
+	}
+
+	rpc_status = ts_rpc_endpoint_sp_init(&rpc_endpoint, 2, 16);
+	if (rpc_status != RPC_SUCCESS) {
+		EMSG("Failed to initialize RPC endpoint: %d", rpc_status);
+		goto fatal_error;
+	}
+
+	rpc_status = ts_rpc_endpoint_sp_add_service(&rpc_endpoint, crypto_iface);
+	if (rpc_status != RPC_SUCCESS) {
+		EMSG("Failed to add service to RPC endpoint: %d", rpc_status);
+		goto fatal_error;
+	}
+
+	rpc_status = ts_rpc_endpoint_sp_add_service(&rpc_endpoint, crypto_iface_protobuf);
+	if (rpc_status != RPC_SUCCESS) {
+		EMSG("Failed to add service to RPC endpoint: %d", rpc_status);
+		goto fatal_error;
+	}
 
 	/* End of boot phase */
 	result = sp_msg_wait(&req_msg);
@@ -79,7 +112,7 @@
 	}
 
 	while (1) {
-		ffa_call_ep_receive(&ffarpc_call_ep, &req_msg, &resp_msg);
+		ts_rpc_endpoint_sp_receive(&rpc_endpoint, &req_msg, &resp_msg);
 
 		result = sp_msg_send_direct_resp(&resp_msg, &req_msg);
 		if (result != SP_RESULT_OK) {
diff --git a/deployments/crypto/env/commonsp/crypto_sp.cmake b/deployments/crypto/env/commonsp/crypto_sp.cmake
index 10e7e3c..5888b6a 100644
--- a/deployments/crypto/env/commonsp/crypto_sp.cmake
+++ b/deployments/crypto/env/commonsp/crypto_sp.cmake
@@ -20,7 +20,9 @@
 		"components/config/ramstore"
 		"components/config/loader/sp"
 		"components/messaging/ffa/libsp"
-		"components/rpc/ffarpc/endpoint"
+		"components/rpc/common/endpoint"
+		"components/rpc/ts_rpc/common"
+		"components/rpc/ts_rpc/endpoint/sp"
 )
 
 target_sources(crypto PRIVATE
diff --git a/deployments/crypto/infra/baremetal-psa.cmake b/deployments/crypto/infra/baremetal-psa.cmake
index afd3bbe..2aa1562 100644
--- a/deployments/crypto/infra/baremetal-psa.cmake
+++ b/deployments/crypto/infra/baremetal-psa.cmake
@@ -14,7 +14,7 @@
 add_components(TARGET "crypto"
 	BASE_DIR ${TS_ROOT}
 	COMPONENTS
-		"components/rpc/ffarpc/caller/sp"
+		"components/rpc/ts_rpc/caller/sp"
 		"components/rpc/common/caller"
 		"components/service/common/client"
 		"components/service/crypto/backend/mbedcrypto/trng_adapter/platform"
diff --git a/deployments/deployment.cmake b/deployments/deployment.cmake
index 3e13a54..76b0f18 100644
--- a/deployments/deployment.cmake
+++ b/deployments/deployment.cmake
@@ -74,3 +74,6 @@
 if (NOT "${UC_CMAKE_BUILD_TYPE}" IN_LIST TS_SUPPORTED_BUILD_TYPES)
 	message(FATAL_ERROR "Unknown build type \"${CMAKE_BUILD_TYPE}\" specified in CMAKE_BUILD_TYPE.")
 endif()
+
+# Default protocol UUID used by TS SPs.
+set(TS_RPC_UUID_CANON "bdcd76d7-825e-4751-963b-86d4f84943ac" CACHE STRING "Trusted Services PRC (protocol) UUID.")
diff --git a/deployments/env-test/config/baremetal-fvp_base_revc-opteesp/CMakeLists.txt b/deployments/env-test/config/baremetal-fvp_base_revc-opteesp/CMakeLists.txt
index 959f158..00d3717 100644
--- a/deployments/env-test/config/baremetal-fvp_base_revc-opteesp/CMakeLists.txt
+++ b/deployments/env-test/config/baremetal-fvp_base_revc-opteesp/CMakeLists.txt
@@ -20,7 +20,8 @@
 project(trusted-services LANGUAGES C ASM)
 add_executable(env-test)
 target_include_directories(env-test PRIVATE "${TOP_LEVEL_INCLUDE_DIRS}")
-set(SP_UUID_CANON "33c75baf-ac6a-4fe4-8ac7-e9909bee2d17")
+set(SP_BIN_UUID_CANON "33c75baf-ac6a-4fe4-8ac7-e9909bee2d17")
+set(SP_FFA_UUID_CANON "${TS_RPC_UUID_CANON}")
 set(SP_HEAP_SIZE "32 * 1024" CACHE STRING "SP heap size in bytes")
 set(TRACE_PREFIX "ENVTEST" CACHE STRING "Trace prefix")
 
@@ -40,6 +41,7 @@
 #  Defines environment and test suites for env-test deployment
 #
 #-------------------------------------------------------------------------------
+
 add_components(TARGET "env-test"
 	BASE_DIR ${TS_ROOT}
 	COMPONENTS
@@ -87,7 +89,8 @@
 
 include(${TS_ROOT}/tools/cmake/common/ExportSp.cmake)
 export_sp(
-	SP_UUID_CANON ${SP_UUID_CANON}
+	SP_FFA_UUID_CANON ${SP_FFA_UUID_CANON}
+	SP_BIN_UUID_CANON ${SP_BIN_UUID_CANON}
 	SP_NAME "env-test"
 	MK_IN ${TS_ROOT}/environments/opteesp/sp.mk.in
 	DTS_IN ${CMAKE_CURRENT_LIST_DIR}/default_env-test.dts.in
diff --git a/deployments/env-test/config/baremetal-fvp_base_revc-sp/CMakeLists.txt b/deployments/env-test/config/baremetal-fvp_base_revc-sp/CMakeLists.txt
index ab371b2..9fa7974 100644
--- a/deployments/env-test/config/baremetal-fvp_base_revc-sp/CMakeLists.txt
+++ b/deployments/env-test/config/baremetal-fvp_base_revc-sp/CMakeLists.txt
@@ -22,8 +22,8 @@
 add_executable(env-test)
 target_include_directories(env-test PRIVATE "${TOP_LEVEL_INCLUDE_DIRS}")
 set(SP_NAME "env-test")
-set(SP_UUID_CANON "33c75baf-ac6a-4fe4-8ac7-e9909bee2d17")
-set(SP_UUID_LE "0xaf5bc733 0xe44f6aac 0x90e9c78a 0x172dee9b")
+set(SP_BIN_UUID_CANON "33c75baf-ac6a-4fe4-8ac7-e9909bee2d17")
+set(SP_FFA_UUID_CANON "${TS_RPC_UUID_CANON}")
 set(TRACE_PREFIX "ENVTEST" CACHE STRING "Trace prefix")
 set(SP_STACK_SIZE "64 * 1024" CACHE STRING "Stack size")
 set(SP_HEAP_SIZE "32 * 1024" CACHE STRING "Heap size")
@@ -69,11 +69,11 @@
 
 endif()
 
-compiler_generate_binary_output(TARGET env-test NAME "${SP_UUID_CANON}.bin" SP_BINARY)
-install(FILES ${CMAKE_CURRENT_BINARY_DIR}/${SP_UUID_CANON}.bin DESTINATION ${TS_ENV}/bin)
+compiler_generate_binary_output(TARGET env-test NAME "${SP_BIN_UUID_CANON}.bin" SP_BINARY)
+install(FILES ${CMAKE_CURRENT_BINARY_DIR}/${SP_BIN_UUID_CANON}.bin DESTINATION ${TS_ENV}/bin)
 
 include(${TS_ROOT}/tools/cmake/common/ExportMemoryRegionsToManifest.cmake REQUIRED)
-export_memory_regions_to_manifest(TARGET env-test NAME "${SP_UUID_CANON}_memory_regions.dtsi" RES EXPORT_MEMORY_REGIONS_DTSI)
+export_memory_regions_to_manifest(TARGET env-test NAME "${SP_BIN_UUID_CANON}_memory_regions.dtsi" RES EXPORT_MEMORY_REGIONS_DTSI)
 
 #-------------------------------------------------------------------------------
 #  Deployment specific install options
@@ -88,9 +88,10 @@
 
 include(${TS_ROOT}/tools/cmake/common/ExportSp.cmake REQUIRED)
 export_sp(
-	SP_UUID_CANON ${SP_UUID_CANON}
+	SP_FFA_UUID_CANON ${SP_FFA_UUID_CANON}
+	SP_BIN_UUID_CANON ${SP_BIN_UUID_CANON}
 	SP_NAME ${SP_NAME}
 	DTS_IN ${CMAKE_CURRENT_LIST_DIR}/default_${SP_NAME}.dts.in
-	DTS_MEM_REGIONS ${SP_UUID_CANON}_memory_regions.dtsi
+	DTS_MEM_REGIONS ${SP_BIN_UUID_CANON}_memory_regions.dtsi
 	JSON_IN ${TS_ROOT}/environments/sp/sp_pkg.json.in
 )
diff --git a/deployments/env-test/config/n1sdp-opteesp/CMakeLists.txt b/deployments/env-test/config/n1sdp-opteesp/CMakeLists.txt
index 5954385..1ddbcf9 100644
--- a/deployments/env-test/config/n1sdp-opteesp/CMakeLists.txt
+++ b/deployments/env-test/config/n1sdp-opteesp/CMakeLists.txt
@@ -21,7 +21,9 @@
 project(trusted-services LANGUAGES C ASM)
 add_executable(env-test)
 target_include_directories(env-test PRIVATE "${TOP_LEVEL_INCLUDE_DIRS}")
-set(SP_UUID_CANON "33c75baf-ac6a-4fe4-8ac7-e9909bee2d17")
+set(SP_BIN_UUID_CANON "33c75baf-ac6a-4fe4-8ac7-e9909bee2d17")
+set(SP_FFA_UUID_CANON "${TS_RPC_UUID_CANON}")
+
 set(SP_HEAP_SIZE "32 * 1024" CACHE STRING "SP heap size in bytes")
 set(TRACE_PREFIX "ENVTEST" CACHE STRING "Trace prefix")
 
@@ -33,6 +35,7 @@
 #  Deployment specific components
 #
 #-------------------------------------------------------------------------------
+
 add_components(TARGET "env-test"
 	BASE_DIR ${TS_ROOT}
 	COMPONENTS
@@ -80,7 +83,8 @@
 
 include(${TS_ROOT}/tools/cmake/common/ExportSp.cmake)
 export_sp(
-	SP_UUID_CANON ${SP_UUID_CANON}
+	SP_FFA_UUID_CANON ${SP_FFA_UUID_CANON}
+	SP_BIN_UUID_CANON ${SP_BIN_UUID_CANON}
 	SP_NAME "env-test"
 	MK_IN ${TS_ROOT}/environments/opteesp/sp.mk.in
 	DTS_IN ${CMAKE_CURRENT_LIST_DIR}/default_env-test.dts.in
diff --git a/deployments/env-test/env/commonsp/env_test_sp.c b/deployments/env-test/env/commonsp/env_test_sp.c
index 35c871b..daaf50a 100644
--- a/deployments/env-test/env/commonsp/env_test_sp.c
+++ b/deployments/env-test/env/commonsp/env_test_sp.c
@@ -3,7 +3,8 @@
  * Copyright (c) 2021-2022, Arm Limited and Contributors. All rights reserved.
  */
 
-#include "rpc/ffarpc/endpoint/ffarpc_call_ep.h"
+#include "components/rpc/common/endpoint/rpc_service_interface.h"
+#include "components/rpc/ts_rpc/endpoint/sp/ts_rpc_endpoint_sp.h"
 #include "service/test_runner/provider/test_runner_provider.h"
 #include "service/test_runner/provider/serializer/packed-c/packedc_test_runner_provider_serializer.h"
 #include "protocols/rpc/common/packed-c/status.h"
@@ -21,12 +22,13 @@
 void __noreturn sp_main(union ffa_boot_info *boot_info)
 {
 	struct test_runner_provider test_runner_provider = { 0 };
-	struct ffa_call_ep ffarpc_call_ep = { 0 };
-	struct rpc_interface *test_runner_iface = NULL;
+	struct ts_rpc_endpoint_sp rpc_endpoint = { 0 };
+	struct rpc_service_interface *test_runner_iface = NULL;
 	struct sp_msg req_msg = { 0 };
 	struct sp_msg resp_msg = { 0 };
 	uint16_t own_id = 0;
 	sp_result result = SP_RESULT_INTERNAL_ERROR;
+	rpc_status_t rpc_status = RPC_ERROR_INTERNAL;
 
 	/* Boot */
 	if (!sp_init(&own_id)) {
@@ -53,7 +55,17 @@
 
 	env_test_register_tests(&test_runner_provider);
 
-	ffa_call_ep_init(&ffarpc_call_ep, test_runner_iface, own_id);
+	rpc_status = ts_rpc_endpoint_sp_init(&rpc_endpoint, 1, 16);
+	if (rpc_status != RPC_SUCCESS) {
+		EMSG("Failed to initialize RPC endpoint: %d", rpc_status);
+		goto fatal_error;
+	}
+
+	rpc_status = ts_rpc_endpoint_sp_add_service(&rpc_endpoint, test_runner_iface);
+	if (rpc_status != RPC_SUCCESS) {
+		EMSG("Failed to add service to RPC endpoint: %d", rpc_status);
+		goto fatal_error;
+	}
 
  	/* End of boot phase */
 	result = sp_msg_wait(&req_msg);
@@ -63,7 +75,7 @@
 	}
 
 	while (1) {
-		ffa_call_ep_receive(&ffarpc_call_ep, &req_msg, &resp_msg);
+		ts_rpc_endpoint_sp_receive(&rpc_endpoint, &req_msg, &resp_msg);
 
 		resp_msg.source_id = req_msg.destination_id;
 		resp_msg.destination_id = req_msg.source_id;
diff --git a/deployments/env-test/env/commonsp/env_test_sp.cmake b/deployments/env-test/env/commonsp/env_test_sp.cmake
index df57ef2..d5ee245 100644
--- a/deployments/env-test/env/commonsp/env_test_sp.cmake
+++ b/deployments/env-test/env/commonsp/env_test_sp.cmake
@@ -21,7 +21,9 @@
 		"components/config/loader/sp"
 		"components/messaging/ffa/libsp"
 		"components/rpc/common/interface"
-		"components/rpc/ffarpc/endpoint"
+		"components/rpc/common/endpoint"
+		"components/rpc/ts_rpc/common"
+		"components/rpc/ts_rpc/endpoint/sp"
 )
 
 target_sources(env-test PRIVATE
diff --git a/deployments/env-test/suites/baremetal-tests.cmake b/deployments/env-test/suites/baremetal-tests.cmake
index 325e238..e62ac2f 100644
--- a/deployments/env-test/suites/baremetal-tests.cmake
+++ b/deployments/env-test/suites/baremetal-tests.cmake
@@ -22,6 +22,7 @@
 		"components/service/secure_storage/frontend/psa/its"
 		"components/service/secure_storage/backend/secure_storage_client"
 		"components/config/test/sp"
+		"components/rpc/common/caller"
 		"components/service/block_storage/block_store"
 		"components/service/block_storage/block_store/device"
 		"components/service/block_storage/block_store/device/semihosting"
diff --git a/deployments/fwu/config/default-opteesp/CMakeLists.txt b/deployments/fwu/config/default-opteesp/CMakeLists.txt
index 98c35d9..f5087d8 100644
--- a/deployments/fwu/config/default-opteesp/CMakeLists.txt
+++ b/deployments/fwu/config/default-opteesp/CMakeLists.txt
@@ -20,7 +20,8 @@
 project(trusted-services LANGUAGES C ASM)
 add_executable(fwu)
 target_include_directories(fwu PRIVATE "${TOP_LEVEL_INCLUDE_DIRS}")
-set(SP_UUID_CANON "6823a838-1b06-470e-9774-0cce8bfb53fd")
+set(SP_BIN_UUID_CANON "6823a838-1b06-470e-9774-0cce8bfb53fd")
+set(SP_FFA_UUID_CANON "${TS_RPC_UUID_CANON}")
 set(SP_HEAP_SIZE "32 * 1024" CACHE STRING "SP heap size in bytes")
 
 target_include_directories(fwu PRIVATE
@@ -38,6 +39,7 @@
 #  Deployment specific components
 #
 #-------------------------------------------------------------------------------
+
 add_components(TARGET "fwu"
 	BASE_DIR ${TS_ROOT}
 	COMPONENTS
@@ -86,7 +88,8 @@
 
 include(${TS_ROOT}/tools/cmake/common/ExportSp.cmake)
 export_sp(
-	SP_UUID_CANON ${SP_UUID_CANON}
+	SP_FFA_UUID_CANON ${SP_FFA_UUID_CANON}
+	SP_BIN_UUID_CANON ${SP_BIN_UUID_CANON}
 	SP_NAME "fwu"
 	DTS_IN ${CMAKE_CURRENT_LIST_DIR}/default_fwu.dts.in
 	JSON_IN ${TS_ROOT}/environments/opteesp/sp_pkg.json.in
diff --git a/deployments/fwu/config/default-sp/CMakeLists.txt b/deployments/fwu/config/default-sp/CMakeLists.txt
index c488a2f..f84ba8f 100644
--- a/deployments/fwu/config/default-sp/CMakeLists.txt
+++ b/deployments/fwu/config/default-sp/CMakeLists.txt
@@ -23,7 +23,8 @@
 add_executable(fwu)
 target_include_directories(fwu PRIVATE "${TOP_LEVEL_INCLUDE_DIRS}")
 set(SP_NAME "fwu")
-set(SP_UUID_CANON "6823a838-1b06-470e-9774-0cce8bfb53fd")
+set(SP_BIN_UUID_CANON "6823a838-1b06-470e-9774-0cce8bfb53fd")
+set(SP_FFA_UUID_CANON "${TS_RPC_UUID_CANON}")
 set(SP_STACK_SIZE "64 * 1024" CACHE STRING "Stack size")
 set(SP_HEAP_SIZE "32 * 1024" CACHE STRING "Heap size")
 
@@ -68,11 +69,11 @@
 
 endif()
 
-compiler_generate_binary_output(TARGET fwu NAME "${SP_UUID_CANON}.bin" SP_BINARY)
-install(FILES ${CMAKE_CURRENT_BINARY_DIR}/${SP_UUID_CANON}.bin DESTINATION ${TS_ENV}/bin)
+compiler_generate_binary_output(TARGET fwu NAME "${SP_BIN_UUID_CANON}.bin" SP_BINARY)
+install(FILES ${CMAKE_CURRENT_BINARY_DIR}/${SP_BIN_UUID_CANON}.bin DESTINATION ${TS_ENV}/bin)
 
 include(${TS_ROOT}/tools/cmake/common/ExportMemoryRegionsToManifest.cmake REQUIRED)
-export_memory_regions_to_manifest(TARGET fwu NAME "${SP_UUID_CANON}_memory_regions.dtsi" RES EXPORT_MEMORY_REGIONS_DTSI)
+export_memory_regions_to_manifest(TARGET fwu NAME "${SP_BIN_UUID_CANON}_memory_regions.dtsi" RES EXPORT_MEMORY_REGIONS_DTSI)
 
 #-------------------------------------------------------------------------------
 #  Deployment specific install options
@@ -87,9 +88,10 @@
 
 include(${TS_ROOT}/tools/cmake/common/ExportSp.cmake)
 export_sp(
-	SP_UUID_CANON ${SP_UUID_CANON}
+	SP_FFA_UUID_CANON ${SP_FFA_UUID_CANON}
+	SP_BIN_UUID_CANON ${SP_BIN_UUID_CANON}
 	SP_NAME ${SP_NAME}
 	DTS_IN ${CMAKE_CURRENT_LIST_DIR}/default_${SP_NAME}.dts.in
-	DTS_MEM_REGIONS ${SP_UUID_CANON}_memory_regions.dtsi
+	DTS_MEM_REGIONS ${SP_BIN_UUID_CANON}_memory_regions.dtsi
 	JSON_IN ${TS_ROOT}/environments/sp/sp_pkg.json.in
 )
diff --git a/deployments/fwu/env/commonsp/fwu_sp.c b/deployments/fwu/env/commonsp/fwu_sp.c
index 812db1e..e3e0544 100644
--- a/deployments/fwu/env/commonsp/fwu_sp.c
+++ b/deployments/fwu/env/commonsp/fwu_sp.c
@@ -10,9 +10,8 @@
 #include "config/ramstore/config_ramstore.h"
 #include "media/volume/factory/volume_factory.h"
 #include "protocols/rpc/common/packed-c/status.h"
-#include "rpc/ffarpc/endpoint/ffarpc_call_ep.h"
-#include "service/discovery/provider/discovery_provider.h"
-#include "service/discovery/provider/serializer/packed-c/packedc_discovery_provider_serializer.h"
+#include "components/rpc/common/endpoint/rpc_service_interface.h"
+#include "components/rpc/ts_rpc/endpoint/sp/ts_rpc_endpoint_sp.h"
 #include "service/fwu/agent/update_agent.h"
 #include "service/fwu/config/fwu_configure.h"
 #include "service/fwu/fw_store/banked/bank_scheme.h"
@@ -43,15 +42,16 @@
 
 void __noreturn sp_main(union ffa_boot_info *boot_info)
 {
-	struct ffa_call_ep ffarpc_call_ep = { 0 };
+	struct ts_rpc_endpoint_sp rpc_endpoint = { 0 };
 	struct fwu_provider service_provider = { 0 };
-	struct rpc_interface *service_iface = NULL;
+	struct rpc_service_interface *service_iface = NULL;
 	struct update_agent update_agent = { 0 };
 	struct fw_store fw_store = { 0 };
 	struct sp_msg req_msg = { 0 };
 	struct sp_msg resp_msg = { 0 };
 	uint16_t own_id = 0;
 	sp_result result = SP_RESULT_INTERNAL_ERROR;
+	rpc_status_t rpc_status = RPC_ERROR_INTERNAL;
 
 	/* Boot phase */
 	if (!sp_init(&own_id)) {
@@ -106,12 +106,18 @@
 	fwu_provider_register_serializer(&service_provider, TS_RPC_ENCODING_PACKED_C,
 					 packedc_fwu_provider_serializer_instance());
 
-	discovery_provider_register_serializer(&service_provider.discovery_provider,
-					       TS_RPC_ENCODING_PACKED_C,
-					       packedc_discovery_provider_serializer_instance());
-
 	/* Associate service interface with FFA call endpoint */
-	ffa_call_ep_init(&ffarpc_call_ep, service_iface, own_id);
+	rpc_status = ts_rpc_endpoint_sp_init(&rpc_endpoint, 1, 16);
+	if (rpc_status != RPC_SUCCESS) {
+		EMSG("Failed to initialize RPC endpoint: %d", rpc_status);
+		goto fatal_error;
+	}
+
+	rpc_status = ts_rpc_endpoint_sp_add_service(&rpc_endpoint, service_iface);
+	if (rpc_status != RPC_SUCCESS) {
+		EMSG("Failed to add service to RPC endpoint: %d", rpc_status);
+		goto fatal_error;
+	}
 
 	/* End of boot phase */
 	result = sp_msg_wait(&req_msg);
@@ -121,7 +127,7 @@
 	}
 
 	while (1) {
-		ffa_call_ep_receive(&ffarpc_call_ep, &req_msg, &resp_msg);
+		ts_rpc_endpoint_sp_receive(&rpc_endpoint, &req_msg, &resp_msg);
 
 		result = sp_msg_send_direct_resp(&resp_msg, &req_msg);
 		if (result != SP_RESULT_OK) {
diff --git a/deployments/fwu/env/commonsp/fwu_sp.cmake b/deployments/fwu/env/commonsp/fwu_sp.cmake
index 875af62..2fd8ca7 100644
--- a/deployments/fwu/env/commonsp/fwu_sp.cmake
+++ b/deployments/fwu/env/commonsp/fwu_sp.cmake
@@ -22,12 +22,12 @@
 		"components/config/loader/sp"
 		"components/messaging/ffa/libsp"
 		"components/rpc/common/interface"
-		"components/rpc/ffarpc/endpoint"
+		"components/rpc/common/endpoint"
+		"components/rpc/ts_rpc/common"
+		"components/rpc/ts_rpc/endpoint/sp"
 		"components/service/common/provider"
 		"components/service/fwu/provider"
 		"components/service/fwu/provider/serializer/packed-c"
-		"components/service/discovery/provider"
-		"components/service/discovery/provider/serializer/packed-c"
 )
 
 target_sources(fwu PRIVATE
diff --git a/deployments/internal-trusted-storage/config/default-opteesp/CMakeLists.txt b/deployments/internal-trusted-storage/config/default-opteesp/CMakeLists.txt
index 1e141ec..5ae53d7 100644
--- a/deployments/internal-trusted-storage/config/default-opteesp/CMakeLists.txt
+++ b/deployments/internal-trusted-storage/config/default-opteesp/CMakeLists.txt
@@ -17,7 +17,9 @@
 project(trusted-services LANGUAGES C ASM)
 add_executable(internal-trusted-storage)
 target_include_directories(internal-trusted-storage PRIVATE "${TOP_LEVEL_INCLUDE_DIRS}")
-set(SP_UUID_CANON "dc1eef48-b17a-4ccf-ac8b-dfcff7711b14")
+set(SP_BIN_UUID_CANON "dc1eef48-b17a-4ccf-ac8b-dfcff7711b14")
+set(SP_FFA_UUID_CANON "${TS_RPC_UUID_CANON}")
+
 set(SP_HEAP_SIZE "32 * 1024" CACHE STRING "SP heap size in bytes")
 set(TRACE_PREFIX "ITS" CACHE STRING "Trace prefix")
 
@@ -30,6 +32,7 @@
 #  ram backed storage for SFS.
 #
 #-------------------------------------------------------------------------------
+
 add_components(TARGET "internal-trusted-storage"
 	BASE_DIR ${TS_ROOT}
 	COMPONENTS
@@ -69,7 +72,8 @@
 
 include(${TS_ROOT}/tools/cmake/common/ExportSp.cmake)
 export_sp(
-	SP_UUID_CANON ${SP_UUID_CANON}
+	SP_FFA_UUID_CANON ${SP_FFA_UUID_CANON}
+	SP_BIN_UUID_CANON ${SP_BIN_UUID_CANON}
 	SP_NAME "internal-trusted-storage"
 	MK_IN ${TS_ROOT}/environments/opteesp/sp.mk.in
 	DTS_IN ${CMAKE_CURRENT_LIST_DIR}/default_internal-trusted-storage.dts.in
diff --git a/deployments/internal-trusted-storage/config/default-sp/CMakeLists.txt b/deployments/internal-trusted-storage/config/default-sp/CMakeLists.txt
index 3627493..fd54a63 100644
--- a/deployments/internal-trusted-storage/config/default-sp/CMakeLists.txt
+++ b/deployments/internal-trusted-storage/config/default-sp/CMakeLists.txt
@@ -20,7 +20,8 @@
 add_executable(internal-trusted-storage)
 target_include_directories(internal-trusted-storage PRIVATE "${TOP_LEVEL_INCLUDE_DIRS}")
 set(SP_NAME "internal-trusted-storage")
-set(SP_UUID_CANON "dc1eef48-b17a-4ccf-ac8b-dfcff7711b14")
+set(SP_BIN_UUID_CANON "dc1eef48-b17a-4ccf-ac8b-dfcff7711b14")
+set(SP_FFA_UUID_CANON "${TS_RPC_UUID_CANON}")
 set(TRACE_PREFIX "ITS" CACHE STRING "Trace prefix")
 set(SP_STACK_SIZE "64 * 1024" CACHE STRING "Stack size")
 set(SP_HEAP_SIZE "32 * 1024" CACHE STRING "Heap size")
@@ -55,11 +56,11 @@
 
 endif()
 
-compiler_generate_binary_output(TARGET internal-trusted-storage NAME "${SP_UUID_CANON}.bin" SP_BINARY)
-install(FILES ${CMAKE_CURRENT_BINARY_DIR}/${SP_UUID_CANON}.bin DESTINATION ${TS_ENV}/bin)
+compiler_generate_binary_output(TARGET internal-trusted-storage NAME "${SP_BIN_UUID_CANON}.bin" SP_BINARY)
+install(FILES ${CMAKE_CURRENT_BINARY_DIR}/${SP_BIN_UUID_CANON}.bin DESTINATION ${TS_ENV}/bin)
 
 include(${TS_ROOT}/tools/cmake/common/ExportMemoryRegionsToManifest.cmake REQUIRED)
-export_memory_regions_to_manifest(TARGET internal-trusted-storage NAME "${SP_UUID_CANON}_memory_regions.dtsi" RES EXPORT_MEMORY_REGIONS_DTSI)
+export_memory_regions_to_manifest(TARGET internal-trusted-storage NAME "${SP_BIN_UUID_CANON}_memory_regions.dtsi" RES EXPORT_MEMORY_REGIONS_DTSI)
 
 #-------------------------------------------------------------------------------
 #  Deployment specific install options
@@ -75,9 +76,10 @@
 
 include(${TS_ROOT}/tools/cmake/common/ExportSp.cmake REQUIRED)
 export_sp(
-	SP_UUID_CANON ${SP_UUID_CANON}
+	SP_FFA_UUID_CANON ${SP_FFA_UUID_CANON}
+	SP_BIN_UUID_CANON ${SP_BIN_UUID_CANON}
 	SP_NAME ${SP_NAME}
 	DTS_IN ${CMAKE_CURRENT_LIST_DIR}/default_${SP_NAME}.dts.in
-	DTS_MEM_REGIONS ${SP_UUID_CANON}_memory_regions.dtsi
+	DTS_MEM_REGIONS ${SP_BIN_UUID_CANON}_memory_regions.dtsi
 	JSON_IN ${TS_ROOT}/environments/sp/sp_pkg.json.in
 )
diff --git a/deployments/internal-trusted-storage/config/shared-flash-opteesp/CMakeLists.txt b/deployments/internal-trusted-storage/config/shared-flash-opteesp/CMakeLists.txt
index 3d99833..7a0c209 100644
--- a/deployments/internal-trusted-storage/config/shared-flash-opteesp/CMakeLists.txt
+++ b/deployments/internal-trusted-storage/config/shared-flash-opteesp/CMakeLists.txt
@@ -17,7 +17,9 @@
 project(trusted-services LANGUAGES C ASM)
 add_executable(internal-trusted-storage)
 target_include_directories(internal-trusted-storage PRIVATE "${TOP_LEVEL_INCLUDE_DIRS}")
-set(SP_UUID_CANON "dc1eef48-b17a-4ccf-ac8b-dfcff7711b14")
+set(SP_BIN_UUID_CANON "dc1eef48-b17a-4ccf-ac8b-dfcff7711b14")
+set(SP_FFA_UUID_CANON "${TS_RPC_UUID_CANON}")
+
 set(SP_HEAP_SIZE "32 * 1024" CACHE STRING "SP heap size in bytes")
 set(TRACE_PREFIX "ITS" CACHE STRING "Trace prefix")
 
@@ -30,6 +32,7 @@
 #  access to a storage partition in a shared secure flash device.
 #
 #-------------------------------------------------------------------------------
+
 add_components(TARGET "internal-trusted-storage"
 	BASE_DIR ${TS_ROOT}
 	COMPONENTS
@@ -69,7 +72,8 @@
 
 include(${TS_ROOT}/tools/cmake/common/ExportSp.cmake)
 export_sp(
-	SP_UUID_CANON ${SP_UUID_CANON}
+	SP_FFA_UUID_CANON ${SP_FFA_UUID_CANON}
+	SP_BIN_UUID_CANON ${SP_BIN_UUID_CANON}
 	SP_NAME "internal-trusted-storage"
 	MK_IN ${TS_ROOT}/environments/opteesp/sp.mk.in
 	DTS_IN ${CMAKE_CURRENT_LIST_DIR}/default_internal-trusted-storage.dts.in
diff --git a/deployments/internal-trusted-storage/env/commonsp/its_sp.c b/deployments/internal-trusted-storage/env/commonsp/its_sp.c
index a1fe67f..03c98ff 100644
--- a/deployments/internal-trusted-storage/env/commonsp/its_sp.c
+++ b/deployments/internal-trusted-storage/env/commonsp/its_sp.c
@@ -4,10 +4,11 @@
  * SPDX-License-Identifier: BSD-3-Clause
  */
 
-#include "components/rpc/common/endpoint/rpc_interface.h"
-#include "components/rpc/ffarpc/endpoint/ffarpc_call_ep.h"
+#include "components/rpc/common/endpoint/rpc_service_interface.h"
+#include "components/rpc/ts_rpc/endpoint/sp/ts_rpc_endpoint_sp.h"
 #include "components/service/secure_storage/factory/storage_factory.h"
 #include "components/service/secure_storage/frontend/secure_storage_provider/secure_storage_provider.h"
+#include "components/service/secure_storage/frontend/secure_storage_provider/secure_storage_uuid.h"
 #include "sp_api.h"
 #include "sp_discovery.h"
 #include "sp_messaging.h"
@@ -20,13 +21,15 @@
 void sp_main(union ffa_boot_info *boot_info)
 {
 	sp_result result = SP_RESULT_INTERNAL_ERROR;
-	struct rpc_interface *secure_storage_iface = NULL;
-	struct ffa_call_ep ffa_call_ep = { 0 };
+	struct rpc_service_interface *secure_storage_iface = NULL;
+	struct ts_rpc_endpoint_sp rpc_endpoint = { 0 };
 	struct sp_msg req_msg = { 0 };
 	struct sp_msg resp_msg = { 0 };
 	struct secure_storage_provider secure_storage_provider = { 0 };
 	struct storage_backend *storage_backend = NULL;
 	uint16_t own_id = 0;
+	const struct rpc_uuid service_uuid = { .uuid = TS_PSA_INTERNAL_TRUSTED_STORAGE_UUID };
+	rpc_status_t rpc_status = RPC_ERROR_INTERNAL;
 
 	/* Boot */
 	(void)boot_info;
@@ -49,13 +52,24 @@
 		goto fatal_error;
 	}
 
-	secure_storage_iface = secure_storage_provider_init(&secure_storage_provider, storage_backend);
+	secure_storage_iface = secure_storage_provider_init(&secure_storage_provider,
+							    storage_backend, &service_uuid);
 	if (!secure_storage_iface) {
 		EMSG("Failed to init secure storage provider");
 		goto fatal_error;
 	}
 
-	ffa_call_ep_init(&ffa_call_ep, secure_storage_iface, own_id);
+	rpc_status = ts_rpc_endpoint_sp_init(&rpc_endpoint, 1, 16);
+	if (rpc_status != RPC_SUCCESS) {
+		EMSG("Failed to initialize RPC endpoint: %d", rpc_status);
+		goto fatal_error;
+	}
+
+	rpc_status = ts_rpc_endpoint_sp_add_service(&rpc_endpoint, secure_storage_iface);
+	if (rpc_status != RPC_SUCCESS) {
+		EMSG("Failed to add service to RPC endpoint: %d", rpc_status);
+		goto fatal_error;
+	}
 
 	/* End of boot phase */
 	result = sp_msg_wait(&req_msg);
@@ -65,7 +79,7 @@
 	}
 
 	while (1) {
-		ffa_call_ep_receive(&ffa_call_ep, &req_msg, &resp_msg);
+		ts_rpc_endpoint_sp_receive(&rpc_endpoint, &req_msg, &resp_msg);
 
 		result = sp_msg_send_direct_resp(&resp_msg, &req_msg);
 		if (result != SP_RESULT_OK) {
diff --git a/deployments/internal-trusted-storage/env/commonsp/its_sp.cmake b/deployments/internal-trusted-storage/env/commonsp/its_sp.cmake
index 56cefc9..a24dac7 100644
--- a/deployments/internal-trusted-storage/env/commonsp/its_sp.cmake
+++ b/deployments/internal-trusted-storage/env/commonsp/its_sp.cmake
@@ -20,8 +20,10 @@
 		"components/config/ramstore"
 		"components/config/loader/sp"
 		"components/messaging/ffa/libsp"
+		"components/rpc/common/endpoint"
 		"components/rpc/common/interface"
-		"components/rpc/ffarpc/endpoint"
+		"components/rpc/ts_rpc/common"
+		"components/rpc/ts_rpc/endpoint/sp"
 )
 
 target_sources(internal-trusted-storage PRIVATE
diff --git a/deployments/internal-trusted-storage/infra/sfs-shared-flash.cmake b/deployments/internal-trusted-storage/infra/sfs-shared-flash.cmake
index 3f91b10..f518d73 100644
--- a/deployments/internal-trusted-storage/infra/sfs-shared-flash.cmake
+++ b/deployments/internal-trusted-storage/infra/sfs-shared-flash.cmake
@@ -17,7 +17,8 @@
 	COMPONENTS
 		"components/common/uuid"
 		"components/rpc/common/caller"
-		"components/rpc/ffarpc/caller/sp"
+		"components/rpc/ts_rpc/caller/sp"
+		"components/service/common/client"
 		"components/service/locator"
 		"components/service/locator/interface"
 		"components/service/locator/sp"
diff --git a/deployments/internal-trusted-storage/internal-trusted-storage.cmake b/deployments/internal-trusted-storage/internal-trusted-storage.cmake
index 0858000..3da2a0b 100644
--- a/deployments/internal-trusted-storage/internal-trusted-storage.cmake
+++ b/deployments/internal-trusted-storage/internal-trusted-storage.cmake
@@ -10,7 +10,6 @@
 	COMPONENTS
 		components/common/tlv
 		components/service/common/include
-		components/service/common/client
 		components/service/common/provider
 		components/service/secure_storage/include
 		components/service/secure_storage/frontend/secure_storage_provider
diff --git a/deployments/libsp/opteesp/CMakeLists.txt b/deployments/libsp/opteesp/CMakeLists.txt
index 0e83302..a690c0c 100644
--- a/deployments/libsp/opteesp/CMakeLists.txt
+++ b/deployments/libsp/opteesp/CMakeLists.txt
@@ -43,6 +43,7 @@
 	# Environment specific files require this variable to be set.
 	# Set it to a dummy value as we are not going to build these anyways.
 	# The namespace of the function will ensure globas setting is not affected.
+	set(SP_FFA_UUID_CANON "00000000-0000-0000-0000-000000000000")
 	set(SP_HEAP_SIZE 4096)
 	add_library(dummy EXCLUDE_FROM_ALL)
 	add_components(TARGET dummy
diff --git a/deployments/libts/arm-linux/CMakeLists.txt b/deployments/libts/arm-linux/CMakeLists.txt
index 75ce321..1c190a8 100644
--- a/deployments/libts/arm-linux/CMakeLists.txt
+++ b/deployments/libts/arm-linux/CMakeLists.txt
@@ -32,7 +32,7 @@
 	BASE_DIR ${TS_ROOT}
 	COMPONENTS
 		"components/common/utils"
-		"components/rpc/ffarpc/caller/linux"
+		"components/rpc/ts_rpc/caller/linux"
 		"components/rpc/mm_communicate/caller/linux"
 		"components/service/locator/linux"
 		"components/service/locator/linux/ffa"
diff --git a/deployments/libts/libts.cmake b/deployments/libts/libts.cmake
index 9a1b9e1..0f1a022 100644
--- a/deployments/libts/libts.cmake
+++ b/deployments/libts/libts.cmake
@@ -46,6 +46,7 @@
 # Enable exporting interface symbols for library public interface
 target_compile_definitions(ts PRIVATE
 	EXPORT_PUBLIC_INTERFACE_RPC_CALLER
+	EXPORT_PUBLIC_INTERFACE_RPC_SERVICE
 	EXPORT_PUBLIC_INTERFACE_SERVICE_LOCATOR
 )
 
diff --git a/deployments/libts/linux-pc/CMakeLists.txt b/deployments/libts/linux-pc/CMakeLists.txt
index 3db5585..b457593 100644
--- a/deployments/libts/linux-pc/CMakeLists.txt
+++ b/deployments/libts/linux-pc/CMakeLists.txt
@@ -48,7 +48,7 @@
 	BASE_DIR ${TS_ROOT}
 	COMPONENTS
 		"components/rpc/direct"
-		"components/rpc/common/demux"
+		"components/rpc/common/endpoint"
 		"components/common/tlv"
 		"components/common/uuid"
 		"components/common/endian"
@@ -60,8 +60,6 @@
 		"components/service/common/client"
 		"components/service/common/serializer/protobuf"
 		"components/service/common/provider"
-		"components/service/discovery/provider"
-		"components/service/discovery/provider/serializer/packed-c"
 		"components/service/locator/standalone"
 		"components/service/locator/standalone/services/crypto"
 		"components/service/locator/standalone/services/internal-trusted-storage"
@@ -191,8 +189,10 @@
 	COMPONENTS
 		"components/app/test-runner"
 		"components/common/tlv"
+		"components/rpc/common/caller"
+		"components/rpc/common/interface"
+		"components/rpc/common/endpoint"
 		"components/service/common/include"
-		"components/service/discovery/client"
 		"components/service/secure_storage/include"
 		"components/service/secure_storage/test/service"
 		"components/service/secure_storage/frontend/psa/its"
diff --git a/deployments/protected-storage/config/default-opteesp/CMakeLists.txt b/deployments/protected-storage/config/default-opteesp/CMakeLists.txt
index 71ec4a3..7d6e5a0 100644
--- a/deployments/protected-storage/config/default-opteesp/CMakeLists.txt
+++ b/deployments/protected-storage/config/default-opteesp/CMakeLists.txt
@@ -17,7 +17,9 @@
 project(trusted-services LANGUAGES C ASM)
 add_executable(protected-storage)
 target_include_directories(protected-storage PRIVATE "${TOP_LEVEL_INCLUDE_DIRS}")
-set(SP_UUID_CANON "751bf801-3dde-4768-a514-0f10aeed1790")
+set(SP_BIN_UUID_CANON "751bf801-3dde-4768-a514-0f10aeed1790")
+set(SP_FFA_UUID_CANON "${TS_RPC_UUID_CANON}")
+
 set(SP_HEAP_SIZE "32 * 1024" CACHE STRING "SP heap size in bytes")
 set(TRACE_PREFIX "PS" CACHE STRING "Trace prefix")
 
@@ -30,6 +32,7 @@
 #  ram backed storage for SFS.
 #
 #-------------------------------------------------------------------------------
+
 add_components(TARGET "protected-storage"
 	BASE_DIR ${TS_ROOT}
 	COMPONENTS
@@ -68,7 +71,8 @@
 
 include(${TS_ROOT}/tools/cmake/common/ExportSp.cmake)
 export_sp(
-	SP_UUID_CANON ${SP_UUID_CANON}
+	SP_FFA_UUID_CANON ${SP_FFA_UUID_CANON}
+	SP_BIN_UUID_CANON ${SP_BIN_UUID_CANON}
 	SP_NAME "protected-storage"
 	MK_IN ${TS_ROOT}/environments/opteesp/sp.mk.in
 	DTS_IN ${CMAKE_CURRENT_LIST_DIR}/default_protected-storage.dts.in
diff --git a/deployments/protected-storage/config/default-sp/CMakeLists.txt b/deployments/protected-storage/config/default-sp/CMakeLists.txt
index 75ea700..1c85ef1 100644
--- a/deployments/protected-storage/config/default-sp/CMakeLists.txt
+++ b/deployments/protected-storage/config/default-sp/CMakeLists.txt
@@ -20,7 +20,8 @@
 add_executable(protected-storage)
 target_include_directories(protected-storage PRIVATE "${TOP_LEVEL_INCLUDE_DIRS}")
 set(SP_NAME "protected-storage")
-set(SP_UUID_CANON "751bf801-3dde-4768-a514-0f10aeed1790")
+set(SP_BIN_UUID_CANON "751bf801-3dde-4768-a514-0f10aeed1790")
+set(SP_FFA_UUID_CANON "${TS_RPC_UUID_CANON}")
 set(TRACE_PREFIX "PS" CACHE STRING "Trace prefix")
 set(SP_STACK_SIZE "64 * 1024" CACHE STRING "Stack size")
 set(SP_HEAP_SIZE "32 * 1024" CACHE STRING "Heap size")
@@ -55,11 +56,11 @@
 
 endif()
 
-compiler_generate_binary_output(TARGET protected-storage NAME "${SP_UUID_CANON}.bin" SP_BINARY)
-install(FILES ${CMAKE_CURRENT_BINARY_DIR}/${SP_UUID_CANON}.bin DESTINATION ${TS_ENV}/bin)
+compiler_generate_binary_output(TARGET protected-storage NAME "${SP_BIN_UUID_CANON}.bin" SP_BINARY)
+install(FILES ${CMAKE_CURRENT_BINARY_DIR}/${SP_BIN_UUID_CANON}.bin DESTINATION ${TS_ENV}/bin)
 
 include(${TS_ROOT}/tools/cmake/common/ExportMemoryRegionsToManifest.cmake REQUIRED)
-export_memory_regions_to_manifest(TARGET protected-storage NAME "${SP_UUID_CANON}_memory_regions.dtsi" RES EXPORT_MEMORY_REGIONS_DTSI)
+export_memory_regions_to_manifest(TARGET protected-storage NAME "${SP_BIN_UUID_CANON}_memory_regions.dtsi" RES EXPORT_MEMORY_REGIONS_DTSI)
 
 #-------------------------------------------------------------------------------
 #  Deployment specific install options
@@ -75,9 +76,10 @@
 
 include(${TS_ROOT}/tools/cmake/common/ExportSp.cmake REQUIRED)
 export_sp(
-	SP_UUID_CANON ${SP_UUID_CANON}
+	SP_FFA_UUID_CANON ${SP_FFA_UUID_CANON}
+	SP_BIN_UUID_CANON ${SP_BIN_UUID_CANON}
 	SP_NAME ${SP_NAME}
 	DTS_IN ${CMAKE_CURRENT_LIST_DIR}/default_${SP_NAME}.dts.in
-	DTS_MEM_REGIONS ${SP_UUID_CANON}_memory_regions.dtsi
+	DTS_MEM_REGIONS ${SP_BIN_UUID_CANON}_memory_regions.dtsi
 	JSON_IN ${TS_ROOT}/environments/sp/sp_pkg.json.in
 )
diff --git a/deployments/protected-storage/config/shared-flash-opteesp/CMakeLists.txt b/deployments/protected-storage/config/shared-flash-opteesp/CMakeLists.txt
index c9ecf3a..1a3480d 100644
--- a/deployments/protected-storage/config/shared-flash-opteesp/CMakeLists.txt
+++ b/deployments/protected-storage/config/shared-flash-opteesp/CMakeLists.txt
@@ -17,7 +17,9 @@
 project(trusted-services LANGUAGES C ASM)
 add_executable(protected-storage)
 target_include_directories(protected-storage PRIVATE "${TOP_LEVEL_INCLUDE_DIRS}")
-set(SP_UUID_CANON "751bf801-3dde-4768-a514-0f10aeed1790")
+set(SP_BIN_UUID_CANON "751bf801-3dde-4768-a514-0f10aeed1790")
+set(SP_FFA_UUID_CANON "${TS_RPC_UUID_CANON}")
+
 set(SP_HEAP_SIZE "32 * 1024" CACHE STRING "SP heap size in bytes")
 set(TRACE_PREFIX "PS" CACHE STRING "Trace prefix")
 
@@ -68,7 +70,8 @@
 
 include(${TS_ROOT}/tools/cmake/common/ExportSp.cmake)
 export_sp(
-	SP_UUID_CANON ${SP_UUID_CANON}
+	SP_FFA_UUID_CANON ${SP_FFA_UUID_CANON}
+	SP_BIN_UUID_CANON ${SP_BIN_UUID_CANON}
 	SP_NAME "protected-storage"
 	MK_IN ${TS_ROOT}/environments/opteesp/sp.mk.in
 	DTS_IN ${CMAKE_CURRENT_LIST_DIR}/default_protected-storage.dts.in
diff --git a/deployments/protected-storage/env/commonsp/ps_sp.c b/deployments/protected-storage/env/commonsp/ps_sp.c
index acd651b..c77d9fd 100644
--- a/deployments/protected-storage/env/commonsp/ps_sp.c
+++ b/deployments/protected-storage/env/commonsp/ps_sp.c
@@ -4,10 +4,11 @@
  * SPDX-License-Identifier: BSD-3-Clause
  */
 
-#include "components/rpc/common/endpoint/rpc_interface.h"
-#include "components/rpc/ffarpc/endpoint/ffarpc_call_ep.h"
+#include "components/rpc/common/endpoint/rpc_service_interface.h"
+#include "components/rpc/ts_rpc/endpoint/sp/ts_rpc_endpoint_sp.h"
 #include "components/service/secure_storage/factory/storage_factory.h"
 #include "components/service/secure_storage/frontend/secure_storage_provider/secure_storage_provider.h"
+#include "components/service/secure_storage/frontend/secure_storage_provider/secure_storage_uuid.h"
 #include "sp_api.h"
 #include "sp_discovery.h"
 #include "sp_messaging.h"
@@ -20,13 +21,15 @@
 void sp_main(union ffa_boot_info *boot_info)
 {
 	sp_result result = SP_RESULT_INTERNAL_ERROR;
-	struct rpc_interface *secure_storage_iface = NULL;
-	struct ffa_call_ep ffa_call_ep = { 0 };
+	struct rpc_service_interface *secure_storage_iface = NULL;
+	struct ts_rpc_endpoint_sp rpc_endpoint = { 0 };
 	struct sp_msg req_msg = { 0 };
 	struct sp_msg resp_msg = { 0 };
 	struct secure_storage_provider secure_storage_provider = { 0 };
 	struct storage_backend *storage_backend = NULL;
 	uint16_t own_id = 0;
+	const struct rpc_uuid service_uuid = { .uuid = TS_PSA_PROTECTED_STORAGE_UUID };
+	rpc_status_t rpc_status = RPC_ERROR_INTERNAL;
 
 	/* Boot */
 	(void)boot_info;
@@ -50,13 +53,23 @@
 	}
 
 	secure_storage_iface = secure_storage_provider_init(&secure_storage_provider,
-							    storage_backend);
+							    storage_backend, &service_uuid);
 	if (!secure_storage_iface) {
 		EMSG("Failed to init secure storage provider");
 		goto fatal_error;
 	}
 
-	ffa_call_ep_init(&ffa_call_ep, secure_storage_iface, own_id);
+	rpc_status = ts_rpc_endpoint_sp_init(&rpc_endpoint, 1, 16);
+	if (rpc_status != RPC_SUCCESS) {
+		EMSG("Failed to initialize RPC endpoint: %d", rpc_status);
+		goto fatal_error;
+	}
+
+	rpc_status = ts_rpc_endpoint_sp_add_service(&rpc_endpoint, secure_storage_iface);
+	if (rpc_status != RPC_SUCCESS) {
+		EMSG("Failed to add service to RPC endpoint: %d", rpc_status);
+		goto fatal_error;
+	}
 
 	/* End of boot phase */
 	result = sp_msg_wait(&req_msg);
@@ -66,7 +79,7 @@
 	}
 
 	while (1) {
-		ffa_call_ep_receive(&ffa_call_ep, &req_msg, &resp_msg);
+		ts_rpc_endpoint_sp_receive(&rpc_endpoint, &req_msg, &resp_msg);
 
 		result = sp_msg_send_direct_resp(&resp_msg, &req_msg);
 		if (result != SP_RESULT_OK) {
diff --git a/deployments/protected-storage/env/commonsp/ps_sp.cmake b/deployments/protected-storage/env/commonsp/ps_sp.cmake
index 55ac94b..c613f22 100644
--- a/deployments/protected-storage/env/commonsp/ps_sp.cmake
+++ b/deployments/protected-storage/env/commonsp/ps_sp.cmake
@@ -20,8 +20,10 @@
 		"components/config/ramstore"
 		"components/config/loader/sp"
 		"components/messaging/ffa/libsp"
+		"components/rpc/common/endpoint"
 		"components/rpc/common/interface"
-		"components/rpc/ffarpc/endpoint"
+		"components/rpc/ts_rpc/common"
+		"components/rpc/ts_rpc/endpoint/sp"
 )
 
 target_sources(protected-storage PRIVATE
diff --git a/deployments/protected-storage/infra/sfs-shared-flash.cmake b/deployments/protected-storage/infra/sfs-shared-flash.cmake
index 6674e16..6642e0d 100644
--- a/deployments/protected-storage/infra/sfs-shared-flash.cmake
+++ b/deployments/protected-storage/infra/sfs-shared-flash.cmake
@@ -17,7 +17,8 @@
 	COMPONENTS
 		"components/common/uuid"
 		"components/rpc/common/caller"
-		"components/rpc/ffarpc/caller/sp"
+		"components/rpc/ts_rpc/caller/sp"
+		"components/service/common/client"
 		"components/service/locator"
 		"components/service/locator/interface"
 		"components/service/locator/sp"
diff --git a/deployments/protected-storage/protected-storage.cmake b/deployments/protected-storage/protected-storage.cmake
index 5822b57..b08fbb0 100644
--- a/deployments/protected-storage/protected-storage.cmake
+++ b/deployments/protected-storage/protected-storage.cmake
@@ -10,7 +10,6 @@
 	COMPONENTS
 		components/common/tlv
 		components/service/common/include
-		components/service/common/client
 		components/service/common/provider
 		components/service/secure_storage/include
 		components/service/secure_storage/frontend/secure_storage_provider
diff --git a/deployments/psa-api-test/arch_test_runner.c b/deployments/psa-api-test/arch_test_runner.c
index e8745d8..8fd3dac 100644
--- a/deployments/psa-api-test/arch_test_runner.c
+++ b/deployments/psa-api-test/arch_test_runner.c
@@ -10,9 +10,7 @@
 #include <stdio.h>
 #include <string.h>
 #include <stdlib.h>
-#include "rpc/common/logging/logging_caller.h"
 #include "service_under_test.h"
-#include "service_locator.h"
 
 #define TEST_ID_OFFSET      (5)
 #define TEST_POSTFIX_OFFSET (8)
@@ -118,11 +116,6 @@
 {
     int rval = -1;
     int option_index = 0;
-    struct logging_caller *selected_call_logger = NULL;
-    struct logging_caller call_logger;
-
-    logging_caller_init(&call_logger, stdout);
-    service_locator_init();
 
      /* Print available tests */
     if (option_selected("-l", argc, argv, &option_index)) {
@@ -149,10 +142,6 @@
         pal_set_custom_test_list(test_list_values);
     }
 
-    /* Setup verbose mode */
-    if (option_selected("-v", argc, argv, &option_index))
-        selected_call_logger = &call_logger;
-
     /* Print help */
     if (option_selected("-h", argc, argv, &option_index)) {
         print_help();
@@ -160,7 +149,7 @@
     }
 
     /* Locate service under test */
-    rval = locate_service_under_test(selected_call_logger);
+    rval = locate_service_under_test();
 
     /* Run tests */
     if (!rval) {
@@ -174,7 +163,5 @@
         printf("Failed to locate service under test.  Error code: %d\n", rval);
     }
 
-    logging_caller_deinit(&call_logger);
-
     return rval;
 }
diff --git a/deployments/psa-api-test/crypto/crypto_locator.c b/deployments/psa-api-test/crypto/crypto_locator.c
index 7f58d4a..c57a501 100644
--- a/deployments/psa-api-test/crypto/crypto_locator.c
+++ b/deployments/psa-api-test/crypto/crypto_locator.c
@@ -7,42 +7,31 @@
 #include <stddef.h>
 #include <service_locator.h>
 #include <service/crypto/client/psa/psa_crypto_client.h>
-#include <service/discovery/client/discovery_client.h>
 #include <protocols/rpc/common/packed-c/encoding.h>
 #include "../service_under_test.h"
 
 /* RPC context */
-static rpc_session_handle session_handle = NULL;
-static struct service_context *crypto_service_context = NULL;
+static struct rpc_caller_session *session = NULL;
+static struct service_context *attestation_service_context = NULL;
 
-int locate_service_under_test(struct logging_caller *call_logger)
+int locate_service_under_test(void)
 {
 	int status = -1;
 
-	if (!session_handle && !crypto_service_context) {
+	if (!session && !attestation_service_context) {
 
-		struct rpc_caller *caller;
+		service_locator_init();
 
-		crypto_service_context =
-			service_locator_query("sn:trustedfirmware.org:crypto:0", &status);
+		attestation_service_context =
+			service_locator_query("sn:trustedfirmware.org:crypto:0");
 
-		if (crypto_service_context) {
+		if (attestation_service_context) {
 
-			session_handle =
-				service_context_open(crypto_service_context, TS_RPC_ENCODING_PACKED_C, &caller);
+			session = service_context_open(attestation_service_context);
 
-			if (session_handle) {
+			if (session) {
 
-				if (call_logger) {
-
-					psa_crypto_client_init(logging_caller_attach(call_logger, caller));
-				}
-				else {
-
-					psa_crypto_client_init(caller);
-				}
-
-				discovery_client_get_service_info(psa_crypto_client_base());
+				psa_crypto_client_init(session);
 
 				status = 0;
 			}
@@ -57,19 +46,21 @@
 	return status;
 }
 
-void relinquish_service_under_test(void)
+int relinquish_service_under_test(void)
 {
 	psa_crypto_client_deinit();
 
-	if (crypto_service_context && session_handle) {
+	if (attestation_service_context && session) {
 
-		service_context_close(crypto_service_context, session_handle);
-		session_handle = NULL;
+		service_context_close(attestation_service_context, session);
+		session = NULL;
 	}
 
-	if (crypto_service_context) {
+	if (attestation_service_context) {
 
-		service_context_relinquish(crypto_service_context);
-		crypto_service_context = NULL;
+		service_context_relinquish(attestation_service_context);
+		attestation_service_context = NULL;
 	}
+
+	return 0;
 }
diff --git a/deployments/psa-api-test/initial_attestation/iat_locator.c b/deployments/psa-api-test/initial_attestation/iat_locator.c
index 8859497..1852fea 100644
--- a/deployments/psa-api-test/initial_attestation/iat_locator.c
+++ b/deployments/psa-api-test/initial_attestation/iat_locator.c
@@ -13,42 +13,31 @@
 #include "../service_under_test.h"
 
 /* RPC context */
-static rpc_session_handle session_handle = NULL;
-static struct service_context *crypto_service_context = NULL;
+static struct rpc_caller_session *session = NULL;
+static struct service_context *attestation_service_context = NULL;
 
-int locate_service_under_test(struct logging_caller *call_logger)
+int locate_service_under_test(void)
 {
 	int status = -1;
 
 	/* Attestation tests depend on PSA crypto so ensure library is initialised */
 	psa_status_t psa_status = psa_crypto_init();
 
-	if ((psa_status == PSA_SUCCESS) && !session_handle && !crypto_service_context) {
+	if ((psa_status == PSA_SUCCESS) && !session && !attestation_service_context) {
 
-		struct rpc_caller *caller;
+		service_locator_init();
 
-		crypto_service_context =
-			service_locator_query("sn:trustedfirmware.org:attestation:0", &status);
+		attestation_service_context =
+			service_locator_query("sn:trustedfirmware.org:attestation:0");
 
-		if (crypto_service_context) {
+		if (attestation_service_context) {
 
-			session_handle =
-				service_context_open(crypto_service_context, TS_RPC_ENCODING_PACKED_C, &caller);
+			session = service_context_open(attestation_service_context);
 
-			if (session_handle) {
+			if (session) {
 
-				if (call_logger) {
-
-					struct rpc_caller *stacked_caller = logging_caller_attach(call_logger, caller);
-
-					psa_iat_client_init(stacked_caller);
-					attest_provision_client_init(stacked_caller);
-				}
-				else {
-
-					psa_iat_client_init(caller);
-					attest_provision_client_init(caller);
-				}
+				psa_iat_client_init(session);
+				attest_provision_client_init(session);
 
 				status = 0;
 			}
@@ -63,20 +52,22 @@
 	return status;
 }
 
-void relinquish_service_under_test(void)
+int relinquish_service_under_test(void)
 {
 	psa_iat_client_deinit();
 	attest_provision_client_deinit();
 
-	if (crypto_service_context && session_handle) {
+	if (attestation_service_context && session) {
 
-		service_context_close(crypto_service_context, session_handle);
-		session_handle = NULL;
+		service_context_close(attestation_service_context, session);
+		session = NULL;
 	}
 
-	if (crypto_service_context) {
+	if (attestation_service_context) {
 
-		service_context_relinquish(crypto_service_context);
-		crypto_service_context = NULL;
+		service_context_relinquish(attestation_service_context);
+		attestation_service_context = NULL;
 	}
+
+	return 0;
 }
diff --git a/deployments/psa-api-test/internal_trusted_storage/its_locator.c b/deployments/psa-api-test/internal_trusted_storage/its_locator.c
index e100328..7119d21 100644
--- a/deployments/psa-api-test/internal_trusted_storage/its_locator.c
+++ b/deployments/psa-api-test/internal_trusted_storage/its_locator.c
@@ -12,40 +12,32 @@
 #include "../service_under_test.h"
 
 /* RPC context */
-static rpc_session_handle session_handle = NULL;
+static struct rpc_caller_session *session = NULL;
 static struct service_context *ps_service_context = NULL;
 static struct secure_storage_client storage_client;
 
-int locate_service_under_test(struct logging_caller *call_logger)
+int locate_service_under_test(void)
 {
 	int status = -1;
 
-	if (!session_handle && !ps_service_context) {
+	service_locator_init();
 
-		struct rpc_caller *caller;
+	if (!session && !ps_service_context) {
 
 		ps_service_context =
-			service_locator_query("sn:trustedfirmware.org:internal-trusted-storage:0", &status);
+			service_locator_query("sn:trustedfirmware.org:internal-trusted-storage:0");
 
 		if (ps_service_context) {
 
-			session_handle =
-				service_context_open(ps_service_context, TS_RPC_ENCODING_PACKED_C, &caller);
+			session =
+				service_context_open(ps_service_context);
 
-			if (session_handle) {
+			if (session) {
 
 				struct storage_backend *storage_backend = NULL;
 				status = -1;
 
-				if (call_logger) {
-
-					storage_backend = secure_storage_client_init(&storage_client,
-						logging_caller_attach(call_logger, caller));
-				}
-				else {
-
-					storage_backend = secure_storage_client_init(&storage_client,  caller);
-				}
+				storage_backend = secure_storage_client_init(&storage_client, session);
 
 				if (storage_backend) {
 
@@ -61,15 +53,15 @@
 	return status;
 }
 
-void relinquish_service_under_test(void)
+int relinquish_service_under_test(void)
 {
 	psa_its_frontend_init(NULL);
 	secure_storage_client_deinit(&storage_client);
 
-	if (ps_service_context && session_handle) {
+	if (ps_service_context && session) {
 
-		service_context_close(ps_service_context, session_handle);
-		session_handle = NULL;
+		service_context_close(ps_service_context, session);
+		session = NULL;
 	}
 
 	if (ps_service_context) {
@@ -77,4 +69,6 @@
 		service_context_relinquish(ps_service_context);
 		ps_service_context = NULL;
 	}
+
+	return 0;
 }
diff --git a/deployments/psa-api-test/protected_storage/ps_locator.c b/deployments/psa-api-test/protected_storage/ps_locator.c
index 3ed35b6..aba8547 100644
--- a/deployments/psa-api-test/protected_storage/ps_locator.c
+++ b/deployments/psa-api-test/protected_storage/ps_locator.c
@@ -12,40 +12,30 @@
 #include "../service_under_test.h"
 
 /* RPC context */
-static rpc_session_handle session_handle = NULL;
+static struct rpc_caller_session *session = NULL;
 static struct service_context *ps_service_context = NULL;
 static struct secure_storage_client storage_client;
 
-int locate_service_under_test(struct logging_caller *call_logger)
+int locate_service_under_test(void)
 {
 	int status = -1;
 
-	if (!session_handle && !ps_service_context) {
+	if (!session && !ps_service_context) {
 
-		struct rpc_caller *caller;
+		service_locator_init();
 
 		ps_service_context =
-			service_locator_query("sn:trustedfirmware.org:protected-storage:0", &status);
+			service_locator_query("sn:trustedfirmware.org:protected-storage:0");
 
 		if (ps_service_context) {
 
-			session_handle =
-				service_context_open(ps_service_context, TS_RPC_ENCODING_PACKED_C, &caller);
+			session = service_context_open(ps_service_context);
 
-			if (session_handle) {
+			if (session) {
 
 				struct storage_backend *storage_backend = NULL;
-				status = -1;
 
-				if (call_logger) {
-
-					storage_backend = secure_storage_client_init(&storage_client,
-						logging_caller_attach(call_logger, caller));
-				}
-				else {
-
-					storage_backend = secure_storage_client_init(&storage_client,  caller);
-				}
+				storage_backend = secure_storage_client_init(&storage_client,  session);
 
 				if (storage_backend) {
 
@@ -61,15 +51,15 @@
 	return status;
 }
 
-void relinquish_service_under_test(void)
+int relinquish_service_under_test(void)
 {
 	psa_ps_frontend_init(NULL);
 	secure_storage_client_deinit(&storage_client);
 
-	if (ps_service_context && session_handle) {
+	if (ps_service_context && session) {
 
-		service_context_close(ps_service_context, session_handle);
-		session_handle = NULL;
+		service_context_close(ps_service_context, session);
+		session = NULL;
 	}
 
 	if (ps_service_context) {
@@ -77,4 +67,6 @@
 		service_context_relinquish(ps_service_context);
 		ps_service_context = NULL;
 	}
-}
+
+	return 0;
+}
\ No newline at end of file
diff --git a/deployments/psa-api-test/psa-api-test.cmake b/deployments/psa-api-test/psa-api-test.cmake
index 5c3469c..739ed26 100644
--- a/deployments/psa-api-test/psa-api-test.cmake
+++ b/deployments/psa-api-test/psa-api-test.cmake
@@ -29,9 +29,6 @@
 		"components/common/tlv"
 		"components/service/common/client"
 		"components/service/common/include"
-		"components/service/discovery/client"
-		"components/rpc/common/caller"
-		"components/rpc/common/logging"
 )
 
 target_sources(${PROJECT_NAME} PRIVATE
diff --git a/deployments/psa-api-test/service_under_test.h b/deployments/psa-api-test/service_under_test.h
index 29f99f7..834384e 100644
--- a/deployments/psa-api-test/service_under_test.h
+++ b/deployments/psa-api-test/service_under_test.h
@@ -7,8 +7,6 @@
 #ifndef SERVICE_UNDER_TEST_H
 #define SERVICE_UNDER_TEST_H
 
-#include <rpc/common/logging/logging_caller.h>
-
 #ifdef __cplusplus
 extern "C" {
 #endif
@@ -19,12 +17,12 @@
  * associate an RPC Caller with the singleton PSA API client used by
  * the API tests.
  */
-int locate_service_under_test(struct logging_caller *call_logger);
+int locate_service_under_test(void);
 
 /**
  * Reliquish the RPC session when the test run is complete.
  */
-void relinquish_service_under_test(void);
+int relinquish_service_under_test(void);
 
 
 #ifdef __cplusplus
diff --git a/deployments/se-proxy/config/corstone1000-opteesp/CMakeLists.txt b/deployments/se-proxy/config/corstone1000-opteesp/CMakeLists.txt
index 8b2e1bd..2c0da0e 100644
--- a/deployments/se-proxy/config/corstone1000-opteesp/CMakeLists.txt
+++ b/deployments/se-proxy/config/corstone1000-opteesp/CMakeLists.txt
@@ -19,7 +19,9 @@
 project(trusted-services LANGUAGES C ASM)
 add_executable(se-proxy)
 target_include_directories(se-proxy PRIVATE "${TOP_LEVEL_INCLUDE_DIRS}")
-set(SP_UUID_CANON "46bb39d1-b4d9-45b5-88ff-040027dab249")
+set(SP_BIN_UUID_CANON "46bb39d1-b4d9-45b5-88ff-040027dab249")
+set(SP_FFA_UUID_CANON "${TS_RPC_UUID_CANON}")
+
 set(SP_HEAP_SIZE "32 * 1024" CACHE STRING "SP heap size in bytes")
 set(TRACE_PREFIX "SEPROXY" CACHE STRING "Trace prefix")
 
@@ -31,6 +33,7 @@
 #  Components that are specific to deployment in the opteesp environment.
 #
 #-------------------------------------------------------------------------------
+
 add_components(TARGET "se-proxy"
 	BASE_DIR ${TS_ROOT}
 	COMPONENTS
@@ -79,7 +82,8 @@
 
 include(${TS_ROOT}/tools/cmake/common/ExportSp.cmake)
 export_sp(
-	SP_UUID_CANON ${SP_UUID_CANON}
+	SP_FFA_UUID_CANON ${SP_FFA_UUID_CANON}
+	SP_BIN_UUID_CANON ${SP_BIN_UUID_CANON}
 	SP_NAME "se-proxy"
 	MK_IN ${TS_ROOT}/environments/opteesp/sp.mk.in
 	DTS_IN ${CMAKE_CURRENT_LIST_DIR}/default_se-proxy.dts.in
diff --git a/deployments/se-proxy/config/default-opteesp/CMakeLists.txt b/deployments/se-proxy/config/default-opteesp/CMakeLists.txt
index acd2fd2..77ea841 100644
--- a/deployments/se-proxy/config/default-opteesp/CMakeLists.txt
+++ b/deployments/se-proxy/config/default-opteesp/CMakeLists.txt
@@ -21,7 +21,9 @@
 project(trusted-services LANGUAGES C ASM)
 add_executable(se-proxy)
 target_include_directories(se-proxy PRIVATE "${TOP_LEVEL_INCLUDE_DIRS}")
-set(SP_UUID_CANON "46bb39d1-b4d9-45b5-88ff-040027dab249")
+set(SP_BIN_UUID_CANON "46bb39d1-b4d9-45b5-88ff-040027dab249")
+set(SP_FFA_UUID_CANON "${TS_RPC_UUID_CANON}")
+
 set(SP_HEAP_SIZE "32 * 1024" CACHE STRING "SP heap size in bytes")
 set(TRACE_PREFIX "SEPROXY" CACHE STRING "Trace prefix")
 
@@ -33,6 +35,7 @@
 #  Components that are specific to deployment in the opteesp environment.
 #
 #-------------------------------------------------------------------------------
+
 add_components(TARGET "se-proxy"
 	BASE_DIR ${TS_ROOT}
 	COMPONENTS
@@ -81,7 +84,8 @@
 
 include(${TS_ROOT}/tools/cmake/common/ExportSp.cmake)
 export_sp(
-	SP_UUID_CANON ${SP_UUID_CANON}
+	SP_FFA_UUID_CANON ${SP_FFA_UUID_CANON}
+	SP_BIN_UUID_CANON ${SP_BIN_UUID_CANON}
 	SP_NAME "se-proxy"
 	MK_IN ${TS_ROOT}/environments/opteesp/sp.mk.in
 	DTS_IN ${CMAKE_CURRENT_LIST_DIR}/default_se-proxy.dts.in
diff --git a/deployments/se-proxy/config/default-sp/CMakeLists.txt b/deployments/se-proxy/config/default-sp/CMakeLists.txt
index 04c40d0..70d4073 100644
--- a/deployments/se-proxy/config/default-sp/CMakeLists.txt
+++ b/deployments/se-proxy/config/default-sp/CMakeLists.txt
@@ -24,7 +24,8 @@
 add_executable(se-proxy)
 target_include_directories(se-proxy PRIVATE "${TOP_LEVEL_INCLUDE_DIRS}")
 set(SP_NAME "se-proxy")
-set(SP_UUID_CANON "46bb39d1-b4d9-45b5-88ff-040027dab249")
+set(SP_BIN_UUID_CANON "46bb39d1-b4d9-45b5-88ff-040027dab249")
+set(SP_FFA_UUID_CANON "${TS_RPC_UUID_CANON}")
 set(TRACE_PREFIX "SEPROXY" CACHE STRING "Trace prefix")
 set(SP_STACK_SIZE "64 * 1024" CACHE STRING "Stack size")
 set(SP_HEAP_SIZE "32 * 1024" CACHE STRING "Heap size")
@@ -63,11 +64,11 @@
 
 endif()
 
-compiler_generate_binary_output(TARGET se-proxy NAME "${SP_UUID_CANON}.bin" SP_BINARY)
-install(FILES ${CMAKE_CURRENT_BINARY_DIR}/${SP_UUID_CANON}.bin DESTINATION ${TS_ENV}/bin)
+compiler_generate_binary_output(TARGET se-proxy NAME "${SP_BIN_UUID_CANON}.bin" SP_BINARY)
+install(FILES ${CMAKE_CURRENT_BINARY_DIR}/${SP_BIN_UUID_CANON}.bin DESTINATION ${TS_ENV}/bin)
 
 include(${TS_ROOT}/tools/cmake/common/ExportMemoryRegionsToManifest.cmake REQUIRED)
-export_memory_regions_to_manifest(TARGET se-proxy NAME "${SP_UUID_CANON}_memory_regions.dtsi" RES EXPORT_MEMORY_REGIONS_DTSI)
+export_memory_regions_to_manifest(TARGET se-proxy NAME "${SP_BIN_UUID_CANON}_memory_regions.dtsi" RES EXPORT_MEMORY_REGIONS_DTSI)
 
 #-------------------------------------------------------------------------------
 #  Deployment specific install options
@@ -82,9 +83,10 @@
 
 include(${TS_ROOT}/tools/cmake/common/ExportSp.cmake REQUIRED)
 export_sp(
-	SP_UUID_CANON ${SP_UUID_CANON}
+	SP_FFA_UUID_CANON ${SP_FFA_UUID_CANON}
+	SP_BIN_UUID_CANON ${SP_BIN_UUID_CANON}
 	SP_NAME ${SP_NAME}
 	DTS_IN ${CMAKE_CURRENT_LIST_DIR}/default_${SP_NAME}.dts.in
-	DTS_MEM_REGIONS ${SP_UUID_CANON}_memory_regions.dtsi
+	DTS_MEM_REGIONS ${SP_BIN_UUID_CANON}_memory_regions.dtsi
 	JSON_IN ${TS_ROOT}/environments/sp/sp_pkg.json.in
 )
diff --git a/deployments/se-proxy/env/commonsp/se_proxy_sp.c b/deployments/se-proxy/env/commonsp/se_proxy_sp.c
index 5990bb2..155e948 100644
--- a/deployments/se-proxy/env/commonsp/se_proxy_sp.c
+++ b/deployments/se-proxy/env/commonsp/se_proxy_sp.c
@@ -3,8 +3,8 @@
  * Copyright (c) 2021-2022, Arm Limited and Contributors. All rights reserved.
  */
 
-#include "rpc/ffarpc/endpoint/ffarpc_call_ep.h"
-#include "rpc/common/demux/rpc_demux.h"
+#include "components/rpc/common/endpoint/rpc_service_interface.h"
+#include "components/rpc/ts_rpc/endpoint/sp/ts_rpc_endpoint_sp.h"
 #include "config/ramstore/config_ramstore.h"
 #include "config/loader/sp/sp_config_loader.h"
 #include "sp_api.h"
@@ -18,13 +18,13 @@
 
 void __noreturn sp_main(union ffa_boot_info *boot_info)
 {
-	struct ffa_call_ep ffarpc_call_ep = { 0 };
+	struct ts_rpc_endpoint_sp rpc_endpoint = { 0 };
 	struct sp_msg req_msg = { 0 };
 	struct sp_msg resp_msg = { 0 };
-	struct rpc_demux rpc_demux = { 0 };
-	struct rpc_interface *rpc_iface = NULL;
+	struct rpc_service_interface *rpc_iface = NULL;
 	uint16_t own_id = 0;
 	sp_result result = SP_RESULT_INTERNAL_ERROR;
+	rpc_status_t rpc_status = RPC_ERROR_INTERNAL;
 
 	/* Boot phase */
 	if (!sp_init(&own_id)) {
@@ -39,14 +39,12 @@
 		goto fatal_error;
 	}
 
-	rpc_iface = rpc_demux_init(&rpc_demux);
-	if (!rpc_iface) {
-		EMSG("Failed to initialize RPC demux");
+	rpc_status = ts_rpc_endpoint_sp_init(&rpc_endpoint, 4, 16);
+	if (rpc_status != RPC_SUCCESS) {
+		EMSG("Failed to initialize RPC endpoint: %d", rpc_status);
 		goto fatal_error;
 	}
 
-	ffa_call_ep_init(&ffarpc_call_ep, rpc_iface, own_id);
-
 	/* Create service proxies */
 	rpc_iface = its_proxy_create();
 	if (!rpc_iface) {
@@ -54,28 +52,47 @@
 		goto fatal_error;
 	}
 
-	rpc_demux_attach(&rpc_demux, SE_PROXY_INTERFACE_ID_ITS, rpc_iface);
+	rpc_status = ts_rpc_endpoint_sp_add_service(&rpc_endpoint, rpc_iface);
+	if (rpc_status != RPC_SUCCESS) {
+		EMSG("Failed to add service to RPC endpoint: %d", rpc_status);
+		goto fatal_error;
+	}
 
 	rpc_iface = ps_proxy_create();
 	if (!rpc_iface) {
 		EMSG("Failed to create PS proxy");
 		goto fatal_error;
 	}
-	rpc_demux_attach(&rpc_demux, SE_PROXY_INTERFACE_ID_PS, rpc_iface);
+
+	rpc_status = ts_rpc_endpoint_sp_add_service(&rpc_endpoint, rpc_iface);
+	if (rpc_status != RPC_SUCCESS) {
+		EMSG("Failed to add service to RPC endpoint: %d", rpc_status);
+		goto fatal_error;
+	}
 
 	rpc_iface = crypto_proxy_create();
 	if (!rpc_iface) {
 		EMSG("Failed to create Crypto proxy");
 		goto fatal_error;
 	}
-	rpc_demux_attach(&rpc_demux, SE_PROXY_INTERFACE_ID_CRYPTO, rpc_iface);
+
+	rpc_status = ts_rpc_endpoint_sp_add_service(&rpc_endpoint, rpc_iface);
+	if (rpc_status != RPC_SUCCESS) {
+		EMSG("Failed to add service to RPC endpoint: %d", rpc_status);
+		goto fatal_error;
+	}
 
 	rpc_iface = attest_proxy_create();
 	if (!rpc_iface) {
 		EMSG("Failed to create Attestation proxy");
 		goto fatal_error;
 	}
-	rpc_demux_attach(&rpc_demux, SE_PROXY_INTERFACE_ID_ATTEST, rpc_iface);
+
+	rpc_status = ts_rpc_endpoint_sp_add_service(&rpc_endpoint, rpc_iface);
+	if (rpc_status != RPC_SUCCESS) {
+		EMSG("Failed to add service to RPC endpoint: %d", rpc_status);
+		goto fatal_error;
+	}
 
 	/* End of boot phase */
 	result = sp_msg_wait(&req_msg);
@@ -85,7 +102,7 @@
 	}
 
 	while (1) {
-		ffa_call_ep_receive(&ffarpc_call_ep, &req_msg, &resp_msg);
+		ts_rpc_endpoint_sp_receive(&rpc_endpoint, &req_msg, &resp_msg);
 
 		result = sp_msg_send_direct_resp(&resp_msg, &req_msg);
 		if (result != SP_RESULT_OK) {
diff --git a/deployments/se-proxy/env/commonsp/se_proxy_sp.cmake b/deployments/se-proxy/env/commonsp/se_proxy_sp.cmake
index 32bb8e9..c052f42 100644
--- a/deployments/se-proxy/env/commonsp/se_proxy_sp.cmake
+++ b/deployments/se-proxy/env/commonsp/se_proxy_sp.cmake
@@ -20,7 +20,8 @@
 		"components/config/ramstore"
 		"components/config/loader/sp"
 		"components/messaging/ffa/libsp"
-		"components/rpc/ffarpc/endpoint"
+		"components/rpc/ts_rpc/common"
+		"components/rpc/ts_rpc/endpoint/sp"
 )
 
 target_sources(se-proxy PRIVATE
diff --git a/deployments/se-proxy/infra/corstone1000/service_proxy_factory.c b/deployments/se-proxy/infra/corstone1000/service_proxy_factory.c
index bacab1d..6885f92 100644
--- a/deployments/se-proxy/infra/corstone1000/service_proxy_factory.c
+++ b/deployments/se-proxy/infra/corstone1000/service_proxy_factory.c
@@ -7,12 +7,13 @@
 
 #include <stddef.h>
 #include <psa/sid.h>
-#include <rpc/common/endpoint/rpc_interface.h>
+#include "rpc/common/endpoint/rpc_service_interface.h"
 #include <rpc/psa_ipc/caller/sp/psa_ipc_caller.h>
 #include <service/attestation/provider/attest_provider.h>
 #include <service/attestation/provider/serializer/packed-c/packedc_attest_provider_serializer.h>
 #include <service/crypto/factory/crypto_provider_factory.h>
 #include <service/secure_storage/frontend/secure_storage_provider/secure_storage_provider.h>
+#include "service/secure_storage/frontend/secure_storage_provider/secure_storage_uuid.h"
 #include <trace.h>
 
 /* backends */
@@ -20,41 +21,55 @@
 #include <service/secure_storage/backend/secure_storage_ipc/secure_storage_ipc.h>
 #include <service/attestation/client/psa/iat_client.h>
 
-struct psa_ipc_caller psa_ipc;
+static const struct rpc_uuid dummy_uuid = { 0 };
 
-struct rpc_interface *attest_proxy_create(void)
+struct rpc_service_interface *attest_proxy_create(void)
 {
-	struct rpc_interface *attest_iface;
-	struct rpc_caller *attest_caller;
+	struct rpc_service_interface *attest_iface = NULL;
+	rpc_status_t rpc_status = RPC_ERROR_INTERNAL;
 
 	/* Static objects for proxy instance */
-	static struct attest_provider attest_provider;
+	static struct rpc_caller_interface psa_ipc = { 0 };
+	static struct rpc_caller_session rpc_session = { 0 };
+	static struct attest_provider attest_provider = { 0 };
 
-	attest_caller = psa_ipc_caller_init(&psa_ipc);
-	if (!attest_caller)
+	rpc_status = psa_ipc_caller_init(&psa_ipc);
+	if (rpc_status != RPC_SUCCESS)
+		return NULL;
+
+	rpc_status = rpc_caller_session_open(&rpc_session, &psa_ipc, &dummy_uuid, 0, 0);
+	if (rpc_status != RPC_SUCCESS)
 		return NULL;
 
 	/* Initialize the service provider */
 	attest_iface = attest_provider_init(&attest_provider);
-	psa_iat_client_init(&psa_ipc.rpc_caller);
+	psa_iat_client_init(&rpc_session);
 
 	attest_provider_register_serializer(&attest_provider,
-		TS_RPC_ENCODING_PACKED_C, packedc_attest_provider_serializer_instance());
+					    packedc_attest_provider_serializer_instance());
 
 	return attest_iface;
 }
 
-struct rpc_interface *crypto_proxy_create(void)
+struct rpc_service_interface *crypto_proxy_create(void)
 {
-	struct rpc_interface *crypto_iface = NULL;
+	struct rpc_service_interface *crypto_iface = NULL;
 	struct crypto_provider *crypto_provider;
-	struct rpc_caller *crypto_caller;
+	rpc_status_t rpc_status = RPC_ERROR_INTERNAL;
 
-	crypto_caller = psa_ipc_caller_init(&psa_ipc);
-	if (!crypto_caller)
+	/* Static objects for proxy instance */
+	static struct rpc_caller_interface psa_ipc = { 0 };
+	static struct rpc_caller_session rpc_session = { 0 };
+
+	rpc_status = psa_ipc_caller_init(&psa_ipc);
+	if (rpc_status != RPC_SUCCESS)
 		return NULL;
 
-	if (crypto_ipc_backend_init(&psa_ipc.rpc_caller) != PSA_SUCCESS)
+	rpc_status = rpc_caller_session_open(&rpc_session, &psa_ipc, &dummy_uuid, 0, 0);
+	if (rpc_status != RPC_SUCCESS)
+		return NULL;
+
+	if (crypto_ipc_backend_init(&rpc_session) != PSA_SUCCESS)
 		return NULL;
 
 	crypto_provider = crypto_provider_factory_create();
@@ -63,34 +78,54 @@
 	return crypto_iface;
 }
 
-struct rpc_interface *ps_proxy_create(void)
+struct rpc_service_interface *ps_proxy_create(void)
 {
 	static struct secure_storage_provider ps_provider;
 	static struct secure_storage_ipc ps_backend;
-	struct rpc_caller *storage_caller;
 	struct storage_backend *backend;
+	rpc_status_t rpc_status = RPC_ERROR_INTERNAL;
+	const struct rpc_uuid ps_uuid = { .uuid = TS_PSA_PROTECTED_STORAGE_UUID };
 
-	storage_caller = psa_ipc_caller_init(&psa_ipc);
-	if (!storage_caller)
+	/* Static objects for proxy instance */
+	static struct rpc_caller_interface psa_ipc = { 0 };
+	static struct rpc_caller_session rpc_session = { 0 };
+
+	rpc_status = psa_ipc_caller_init(&psa_ipc);
+	if (rpc_status != RPC_SUCCESS)
 		return NULL;
-	backend = secure_storage_ipc_init(&ps_backend, &psa_ipc.rpc_caller);
+
+	rpc_status = rpc_caller_session_open(&rpc_session, &psa_ipc, &dummy_uuid, 0, 0);
+	if (rpc_status != RPC_SUCCESS)
+		return NULL;
+
+	backend = secure_storage_ipc_init(&ps_backend, &rpc_session);
 	ps_backend.service_handle = TFM_PROTECTED_STORAGE_SERVICE_HANDLE;
 
-	return secure_storage_provider_init(&ps_provider, backend);
+	return secure_storage_provider_init(&ps_provider, backend, &ps_uuid);
 }
 
-struct rpc_interface *its_proxy_create(void)
+struct rpc_service_interface *its_proxy_create(void)
 {
 	static struct secure_storage_provider its_provider;
 	static struct secure_storage_ipc its_backend;
-	struct rpc_caller *storage_caller;
 	struct storage_backend *backend;
+	rpc_status_t rpc_status = RPC_ERROR_INTERNAL;
+	const struct rpc_uuid its_uuid = { .uuid = TS_PSA_INTERNAL_TRUSTED_STORAGE_UUID };
 
-	storage_caller = psa_ipc_caller_init(&psa_ipc);
-	if (!storage_caller)
+	/* Static objects for proxy instance */
+	static struct rpc_caller_interface psa_ipc = { 0 };
+	static struct rpc_caller_session rpc_session = { 0 };
+
+	rpc_status = psa_ipc_caller_init(&psa_ipc);
+	if (rpc_status != RPC_SUCCESS)
 		return NULL;
-	backend = secure_storage_ipc_init(&its_backend, &psa_ipc.rpc_caller);
+
+	rpc_status = rpc_caller_session_open(&rpc_session, &psa_ipc, &dummy_uuid, 0, 0);
+	if (rpc_status != RPC_SUCCESS)
+		return NULL;
+
+	backend = secure_storage_ipc_init(&its_backend, &rpc_session);
 	its_backend.service_handle = TFM_INTERNAL_TRUSTED_STORAGE_SERVICE_HANDLE;
 
-	return secure_storage_provider_init(&its_provider, backend);
+	return secure_storage_provider_init(&its_provider, backend, &its_uuid);
 }
diff --git a/deployments/se-proxy/infra/service_proxy_factory.h b/deployments/se-proxy/infra/service_proxy_factory.h
index 298d407..caaea79 100644
--- a/deployments/se-proxy/infra/service_proxy_factory.h
+++ b/deployments/se-proxy/infra/service_proxy_factory.h
@@ -7,16 +7,16 @@
 #ifndef SERVICE_PROXY_FACTORY_H
 #define SERVICE_PROXY_FACTORY_H
 
-#include <rpc/common/endpoint/rpc_interface.h>
+#include "components/rpc/common/endpoint/rpc_service_interface.h"
 
 #ifdef __cplusplus
 extern "C" {
 #endif
 
-struct rpc_interface *attest_proxy_create(void);
-struct rpc_interface *crypto_proxy_create(void);
-struct rpc_interface *ps_proxy_create(void);
-struct rpc_interface *its_proxy_create(void);
+struct rpc_service_interface *attest_proxy_create(void);
+struct rpc_service_interface *crypto_proxy_create(void);
+struct rpc_service_interface *ps_proxy_create(void);
+struct rpc_service_interface *its_proxy_create(void);
 
 #ifdef __cplusplus
 }
diff --git a/deployments/se-proxy/infra/stub/service_proxy_factory.c b/deployments/se-proxy/infra/stub/service_proxy_factory.c
index acfb6e8..4cec9ce 100644
--- a/deployments/se-proxy/infra/stub/service_proxy_factory.c
+++ b/deployments/se-proxy/infra/stub/service_proxy_factory.c
@@ -5,36 +5,37 @@
  */
 
 #include <stddef.h>
-#include <rpc/common/endpoint/rpc_interface.h>
-#include <service/attestation/provider/attest_provider.h>
-#include <service/attestation/provider/serializer/packed-c/packedc_attest_provider_serializer.h>
-#include <service/crypto/factory/crypto_provider_factory.h>
-#include <service/secure_storage/frontend/secure_storage_provider/secure_storage_provider.h>
+#include "rpc/common/endpoint/rpc_service_interface.h"
+#include "service/attestation/provider/attest_provider.h"
+#include "service/attestation/provider/serializer/packed-c/packedc_attest_provider_serializer.h"
+#include "service/crypto/factory/crypto_provider_factory.h"
+#include "service/secure_storage/frontend/secure_storage_provider/secure_storage_provider.h"
+#include "service/secure_storage/frontend/secure_storage_provider/secure_storage_uuid.h"
 
 /* Stub backends */
 #include <service/crypto/backend/stub/stub_crypto_backend.h>
 #include <service/secure_storage/backend/mock_store/mock_store.h>
 
-struct rpc_interface *attest_proxy_create(void)
+struct rpc_service_interface *attest_proxy_create(void)
 {
-	struct rpc_interface *attest_iface;
+	struct rpc_service_interface *attest_iface = NULL;
 
 	/* Static objects for proxy instance */
-	static struct attest_provider attest_provider;
+	static struct attest_provider attest_provider = { 0 };
 
 	/* Initialize the service provider */
 	attest_iface = attest_provider_init(&attest_provider);
 
 	attest_provider_register_serializer(&attest_provider,
-		TS_RPC_ENCODING_PACKED_C, packedc_attest_provider_serializer_instance());
+					    packedc_attest_provider_serializer_instance());
 
 	return attest_iface;
 }
 
-struct rpc_interface *crypto_proxy_create(void)
+struct rpc_service_interface *crypto_proxy_create(void)
 {
-	struct rpc_interface *crypto_iface = NULL;
-	struct crypto_provider *crypto_provider;
+	struct rpc_service_interface *crypto_iface = NULL;
+	struct crypto_provider *crypto_provider = NULL;
 
 	if (stub_crypto_backend_init() == PSA_SUCCESS) {
 
@@ -45,22 +46,24 @@
 	return crypto_iface;
 }
 
-struct rpc_interface *ps_proxy_create(void)
+struct rpc_service_interface *ps_proxy_create(void)
 {
 	static struct mock_store ps_backend;
 	static struct secure_storage_provider ps_provider;
+	const struct rpc_uuid service_uuid = { .uuid = TS_PSA_PROTECTED_STORAGE_UUID };
 
 	struct storage_backend *backend = mock_store_init(&ps_backend);
 
-	return secure_storage_provider_init(&ps_provider, backend);
+	return secure_storage_provider_init(&ps_provider, backend, &service_uuid);
 }
 
-struct rpc_interface *its_proxy_create(void)
+struct rpc_service_interface *its_proxy_create(void)
 {
 	static struct mock_store its_backend;
 	static struct secure_storage_provider its_provider;
+	const struct rpc_uuid service_uuid = { .uuid = TS_PSA_INTERNAL_TRUSTED_STORAGE_UUID };
 
 	struct storage_backend *backend = mock_store_init(&its_backend);
 
-	return secure_storage_provider_init(&its_provider, backend);
+	return secure_storage_provider_init(&its_provider, backend, &service_uuid);
 }
diff --git a/deployments/se-proxy/se-proxy.cmake b/deployments/se-proxy/se-proxy.cmake
index 2643cfb..53bbf95 100644
--- a/deployments/se-proxy/se-proxy.cmake
+++ b/deployments/se-proxy/se-proxy.cmake
@@ -10,13 +10,11 @@
 	COMPONENTS
 		"components/common/tlv"
 		"components/rpc/common/interface"
-		"components/rpc/common/demux"
+		"components/rpc/common/endpoint"
 		"components/service/common/include"
 		"components/service/common/serializer/protobuf"
 		"components/service/common/client"
 		"components/service/common/provider"
-		"components/service/discovery/provider"
-		"components/service/discovery/provider/serializer/packed-c"
 		"components/service/crypto/client/psa"
 		"components/service/crypto/include"
 		"components/service/crypto/provider"
diff --git a/deployments/sfs-demo/common/sfs_demo_sp.c b/deployments/sfs-demo/common/sfs_demo_sp.c
index d7aaf71..2234ec0 100644
--- a/deployments/sfs-demo/common/sfs_demo_sp.c
+++ b/deployments/sfs-demo/common/sfs_demo_sp.c
@@ -4,7 +4,7 @@
  * SPDX-License-Identifier: BSD-3-Clause
  */
 
-#include "components/rpc/ffarpc/caller/sp/ffarpc_caller.h"
+#include "components/rpc/ts_rpc/caller/sp/ts_rpc_caller_sp.h"
 #include "components/service/secure_storage/frontend/psa/its/its_frontend.h"
 #include "service/secure_storage/backend/secure_storage_client/secure_storage_client.h"
 #include "psa/internal_trusted_storage.h"
@@ -21,7 +21,7 @@
 
 static uint8_t tx_buffer[4096] __aligned(4096);
 static uint8_t rx_buffer[4096] __aligned(4096);
-static const uint8_t its_uuid[] = SP_ITS_UUID_BYTES;
+static const struct rpc_uuid its_uuid = { .uuid = SP_ITS_UUID_BYTES };
 
 static const psa_storage_uid_t test_data_uid = 0x12345678;
 static const uint8_t test_data[] = {
@@ -126,13 +126,11 @@
 
 	sp_result result = SP_RESULT_INTERNAL_ERROR;
 	struct sp_msg req_msg = { 0 };
-	struct rpc_caller *caller = NULL;
-	struct ffarpc_caller ffa_caller = { 0 };
+	struct rpc_caller_interface caller = { 0 };
+	struct rpc_caller_session session = { 0 };
 	struct secure_storage_client secure_storage_client = {0};
 	struct storage_backend *storage_backend = NULL;
-	uint16_t sp_ids[3] = { 0 };
-	uint32_t sp_id_cnt = 0;
-	uint16_t own_id = 0;
+	rpc_status_t rpc_status = RPC_ERROR_INTERNAL;
 	psa_status_t psa_status = PSA_ERROR_GENERIC_ERROR;
 
 	/* Boot */
@@ -145,33 +143,19 @@
 		goto fatal_error;
 	}
 
-	result = sp_discovery_own_id_get(&own_id);
-	if (result != SP_RESULT_OK) {
-		EMSG("Failed to query own ID: %d", result);
+	rpc_status = ts_rpc_caller_sp_init(&caller);
+	if (rpc_status != RPC_SUCCESS) {
+		EMSG("Failed initialize RPC caller");
 		goto fatal_error;
 	}
 
-	IMSG("Test SP ID: 0x%x", own_id);
-
-	caller = ffarpc_caller_init(&ffa_caller, own_id);
-	if (!caller) {
-		EMSG("Failed initialize ffarpc_caller");
+	rpc_status = rpc_caller_session_find_and_open(&session, &caller, &its_uuid, 4096);
+	if (rpc_status != RPC_SUCCESS) {
+		EMSG("Failed to open RPC session");
 		goto fatal_error;
 	}
 
-	sp_id_cnt = ffarpc_caller_discover(its_uuid, sp_ids, 3);
-	if (sp_id_cnt == 0) {
-		EMSG("Failed to discover SPs: %d", sp_id_cnt);
-		goto fatal_error;
-	}
-	IMSG("ITS SP ID: 0x%x", sp_ids[0]);
-
-	if (ffarpc_caller_open(&ffa_caller, sp_ids[0], 0)) {
-		EMSG("Failed to open ffarpc_caller");
-		goto fatal_error;
-	}
-
-	storage_backend = secure_storage_client_init(&secure_storage_client, caller);
+	storage_backend = secure_storage_client_init(&secure_storage_client, &session);
 	if (!storage_backend) {
 		EMSG("Failed to initialize secure storage client");
 		goto fatal_error;
@@ -189,8 +173,15 @@
 	 */
 	run_its_test();
 
-	if (ffarpc_caller_close(&ffa_caller)) {
-		EMSG("Failed to close ffarpc_caller");
+	rpc_status = rpc_caller_session_close(&session);
+	if (rpc_status != RPC_SUCCESS) {
+		EMSG("Failed to close RPC session");
+		goto fatal_error;
+	}
+
+	rpc_status = ts_rpc_caller_sp_deinit(&caller);
+	if (rpc_status != RPC_SUCCESS) {
+		EMSG("Failed to close RPC caller");
 		goto fatal_error;
 	}
 
diff --git a/deployments/sfs-demo/opteesp/CMakeLists.txt b/deployments/sfs-demo/opteesp/CMakeLists.txt
index 22b624c..b283b79 100644
--- a/deployments/sfs-demo/opteesp/CMakeLists.txt
+++ b/deployments/sfs-demo/opteesp/CMakeLists.txt
@@ -16,7 +16,9 @@
 include(${TS_ROOT}/environments/opteesp/env.cmake)
 project(trusted-services LANGUAGES C ASM)
 add_executable(sfs-demo)
-set(SP_UUID_CANON "01109cf8-e5ca-446f-9b55-f3cdc65110c8")
+set(SP_BIN_UUID_CANON "01109cf8-e5ca-446f-9b55-f3cdc65110c8")
+set(SP_FFA_UUID_CANON "${TS_RPC_UUID_CANON}")
+
 set(SP_HEAP_SIZE "32 * 1024" CACHE STRING "SP heap size in bytes")
 set(TRACE_PREFIX "SFSDEMO" CACHE STRING "Trace prefix")
 
@@ -54,7 +56,8 @@
 
 include(${TS_ROOT}/tools/cmake/common/ExportSp.cmake)
 export_sp(
-	SP_UUID_CANON ${SP_UUID_CANON}
+	SP_FFA_UUID_CANON ${SP_FFA_UUID_CANON}
+	SP_BIN_UUID_CANON ${SP_BIN_UUID_CANON}
 	SP_NAME "sfs-demo"
 	MK_IN ${TS_ROOT}/environments/opteesp/sp.mk.in
 	DTS_IN ${CMAKE_CURRENT_LIST_DIR}/default_sfs-demo.dts.in
diff --git a/deployments/sfs-demo/sfs-demo.cmake b/deployments/sfs-demo/sfs-demo.cmake
index bc1cf26..a8fc677 100644
--- a/deployments/sfs-demo/sfs-demo.cmake
+++ b/deployments/sfs-demo/sfs-demo.cmake
@@ -13,7 +13,8 @@
 		components/messaging/ffa/libsp
 		components/rpc/common/interface
 		components/rpc/common/caller
-		components/rpc/ffarpc/caller/sp
+		components/rpc/ts_rpc/common
+		components/rpc/ts_rpc/caller/sp
 		components/service/common/include
 		components/service/common/client
 		components/service/secure_storage/include
diff --git a/deployments/sfs-demo/sp/CMakeLists.txt b/deployments/sfs-demo/sp/CMakeLists.txt
index ba68f5a..897be09 100644
--- a/deployments/sfs-demo/sp/CMakeLists.txt
+++ b/deployments/sfs-demo/sp/CMakeLists.txt
@@ -20,7 +20,8 @@
 add_executable(sfs-demo)
 target_include_directories(sfs-demo PRIVATE "${TOP_LEVEL_INCLUDE_DIRS}")
 set(SP_NAME "sfs-demo")
-set(SP_UUID_CANON "01109cf8-e5ca-446f-9b55-f3cdc65110c8")
+set(SP_BIN_UUID_CANON "01109cf8-e5ca-446f-9b55-f3cdc65110c8")
+set(SP_FFA_UUID_CANON "${TS_RPC_UUID_CANON}")
 set(TRACE_PREFIX "SFSDEMO" CACHE STRING "Trace prefix")
 set(SP_STACK_SIZE "64 * 1024" CACHE STRING "Stack size")
 set(SP_HEAP_SIZE "32 * 1024" CACHE STRING "Heap size")
@@ -44,11 +45,11 @@
 
 endif()
 
-compiler_generate_binary_output(TARGET sfs-demo NAME "${SP_UUID_CANON}.bin" SP_BINARY)
-install(FILES ${CMAKE_CURRENT_BINARY_DIR}/${SP_UUID_CANON}.bin DESTINATION ${TS_ENV}/bin)
+compiler_generate_binary_output(TARGET sfs-demo NAME "${SP_BIN_UUID_CANON}.bin" SP_BINARY)
+install(FILES ${CMAKE_CURRENT_BINARY_DIR}/${SP_BIN_UUID_CANON}.bin DESTINATION ${TS_ENV}/bin)
 
 include(${TS_ROOT}/tools/cmake/common/ExportMemoryRegionsToManifest.cmake REQUIRED)
-export_memory_regions_to_manifest(TARGET sfs-demo NAME "${SP_UUID_CANON}_memory_regions.dtsi" RES EXPORT_MEMORY_REGIONS_DTSI)
+export_memory_regions_to_manifest(TARGET sfs-demo NAME "${SP_BIN_UUID_CANON}_memory_regions.dtsi" RES EXPORT_MEMORY_REGIONS_DTSI)
 
 ######################################## install
 if (CMAKE_INSTALL_PREFIX_INITIALIZED_TO_DEFAULT)
@@ -61,9 +62,10 @@
 
 include(${TS_ROOT}/tools/cmake/common/ExportSp.cmake REQUIRED)
 export_sp(
-	SP_UUID_CANON ${SP_UUID_CANON}
+	SP_FFA_UUID_CANON ${SP_FFA_UUID_CANON}
+	SP_BIN_UUID_CANON ${SP_BIN_UUID_CANON}
 	SP_NAME ${SP_NAME}
 	DTS_IN ${CMAKE_CURRENT_LIST_DIR}/default_${SP_NAME}.dts.in
-	DTS_MEM_REGIONS ${SP_UUID_CANON}_memory_regions.dtsi
+	DTS_MEM_REGIONS ${SP_BIN_UUID_CANON}_memory_regions.dtsi
 	JSON_IN ${TS_ROOT}/environments/sp/sp_pkg.json.in
 )
diff --git a/deployments/smm-gateway/common/smm_gateway.c b/deployments/smm-gateway/common/smm_gateway.c
index 4884a04..86269fa 100644
--- a/deployments/smm-gateway/common/smm_gateway.c
+++ b/deployments/smm-gateway/common/smm_gateway.c
@@ -30,47 +30,43 @@
 	struct secure_storage_client nv_store_client;
 	struct mock_store volatile_store;
 	struct service_context *nv_storage_service_context;
-	rpc_session_handle nv_storage_session_handle;
+	struct rpc_caller_session *nv_storage_session;
 
 } smm_gateway_instance;
 
 
-static struct rpc_caller *locate_nv_store(void)
+struct rpc_service_interface *smm_gateway_create(uint32_t owner_id)
 {
-	int status = 0;
-	struct rpc_caller *caller = NULL;
+	service_locator_envinit();
 
 	/* todo - add option to use configurable service location */
 	smm_gateway_instance.nv_storage_service_context =
-		service_locator_query(SMM_GATEWAY_NV_STORE_SN, &status);
+		service_locator_query(SMM_GATEWAY_NV_STORE_SN);
 
-	if (smm_gateway_instance.nv_storage_service_context) {
+	if (!smm_gateway_instance.nv_storage_service_context)
+		return NULL;
 
-		smm_gateway_instance.nv_storage_session_handle = service_context_open(
-			smm_gateway_instance.nv_storage_service_context,
-			TS_RPC_ENCODING_PACKED_C,
-			&caller);
-	}
+	smm_gateway_instance.nv_storage_session = service_context_open(
+		smm_gateway_instance.nv_storage_service_context);
 
-	return caller;
-}
-
-struct rpc_interface *smm_gateway_create(uint32_t owner_id)
-{
-	service_locator_init();
+	if (!smm_gateway_instance.nv_storage_session)
+		return NULL;
 
 	/* Initialize a storage client to access the remote NV store */
-	struct rpc_caller *nv_store_caller = locate_nv_store();
 	struct storage_backend *persistent_backend = secure_storage_client_init(
 		&smm_gateway_instance.nv_store_client,
-		nv_store_caller);
+		smm_gateway_instance.nv_storage_session);
+	if (!persistent_backend)
+		return NULL;
 
 	/* Initialize the volatile storage backend */
 	struct storage_backend *volatile_backend  = mock_store_init(
 		&smm_gateway_instance.volatile_store);
+	if (!volatile_backend)
+		return NULL;
 
 	/* Initialize the smm_variable service provider */
-	struct rpc_interface *service_iface = smm_variable_provider_init(
+	struct rpc_service_interface *service_iface = smm_variable_provider_init(
 		&smm_gateway_instance.smm_variable_provider,
  		owner_id,
 		SMM_GATEWAY_MAX_UEFI_VARIABLES,
diff --git a/deployments/smm-gateway/common/smm_gateway.h b/deployments/smm-gateway/common/smm_gateway.h
index 71cadaa..4dcb59e 100644
--- a/deployments/smm-gateway/common/smm_gateway.h
+++ b/deployments/smm-gateway/common/smm_gateway.h
@@ -7,7 +7,7 @@
 #ifndef SMM_GATEWAY_H
 #define SMM_GATEWAY_H
 
-#include <rpc/common/endpoint/rpc_interface.h>
+#include "rpc/common/endpoint/rpc_service_interface.h"
 
 #ifdef __cplusplus
 extern "C" {
@@ -25,8 +25,7 @@
  *
  * \return An rpc_interface or NULL on failure
  */
-struct rpc_interface *smm_gateway_create(
- 	uint32_t owner_id);
+struct rpc_service_interface *smm_gateway_create(uint32_t owner_id);
 
 #ifdef __cplusplus
 } /* extern "C" */
diff --git a/deployments/smm-gateway/config/default-opteesp/CMakeLists.txt b/deployments/smm-gateway/config/default-opteesp/CMakeLists.txt
index 03e2e75..0ca4606 100644
--- a/deployments/smm-gateway/config/default-opteesp/CMakeLists.txt
+++ b/deployments/smm-gateway/config/default-opteesp/CMakeLists.txt
@@ -1,5 +1,5 @@
 #-------------------------------------------------------------------------------
-# Copyright (c) 2021-2022, Arm Limited and Contributors. All rights reserved.
+# Copyright (c) 2021-2023, Arm Limited and Contributors. All rights reserved.
 #
 # SPDX-License-Identifier: BSD-3-Clause
 #
@@ -20,7 +20,9 @@
 project(trusted-services LANGUAGES C ASM)
 add_executable(smm-gateway)
 target_include_directories(smm-gateway PRIVATE "${TOP_LEVEL_INCLUDE_DIRS}")
-set(SP_UUID_CANON "ed32d533-99e6-4209-9cc0-2d72cdd998a7")
+set(SP_BIN_UUID_CANON "ed32d533-99e6-4209-9cc0-2d72cdd998a7")
+set(SP_FFA_UUID_CANON "${SP_BIN_UUID_CANON}")
+
 set(SP_HEAP_SIZE "32 * 1024" CACHE STRING "SP heap size in bytes")
 set(TRACE_PREFIX "SMMGW" CACHE STRING "Trace prefix")
 
@@ -36,6 +38,7 @@
 #  Components that are specific to deployment in the opteesp environment.
 #
 #-------------------------------------------------------------------------------
+
 add_components(TARGET "smm-gateway"
 	BASE_DIR ${TS_ROOT}
 	COMPONENTS
@@ -84,7 +87,8 @@
 
 include(${TS_ROOT}/tools/cmake/common/ExportSp.cmake)
 export_sp(
-	SP_UUID_CANON ${SP_UUID_CANON}
+	SP_FFA_UUID_CANON ${SP_FFA_UUID_CANON}
+	SP_BIN_UUID_CANON ${SP_BIN_UUID_CANON}
 	SP_NAME "smm-gateway"
 	MK_IN ${TS_ROOT}/environments/opteesp/sp.mk.in
 	DTS_IN ${CMAKE_CURRENT_LIST_DIR}/default_smm-gateway.dts.in
diff --git a/deployments/smm-gateway/config/default-sp/CMakeLists.txt b/deployments/smm-gateway/config/default-sp/CMakeLists.txt
index 0455619..95c5726 100644
--- a/deployments/smm-gateway/config/default-sp/CMakeLists.txt
+++ b/deployments/smm-gateway/config/default-sp/CMakeLists.txt
@@ -23,7 +23,8 @@
 add_executable(smm-gateway)
 target_include_directories(smm-gateway PRIVATE "${TOP_LEVEL_INCLUDE_DIRS}")
 set(SP_NAME "smm-gateway")
-set(SP_UUID_CANON "ed32d533-99e6-4209-9cc0-2d72cdd998a7")
+set(SP_BIN_UUID_CANON "ed32d533-99e6-4209-9cc0-2d72cdd998a7")
+set(SP_FFA_UUID_CANON "${SP_BIN_UUID_CANON}")
 set(TRACE_PREFIX "SMMGW" CACHE STRING "Trace prefix")
 set(SP_STACK_SIZE "64 * 1024" CACHE STRING "Stack size")
 set(SP_HEAP_SIZE "32 * 1024" CACHE STRING "Heap size")
@@ -66,11 +67,11 @@
 
 endif()
 
-compiler_generate_binary_output(TARGET smm-gateway NAME "${SP_UUID_CANON}.bin" SP_BINARY)
-install(FILES ${CMAKE_CURRENT_BINARY_DIR}/${SP_UUID_CANON}.bin DESTINATION ${TS_ENV}/bin)
+compiler_generate_binary_output(TARGET smm-gateway NAME "${SP_BIN_UUID_CANON}.bin" SP_BINARY)
+install(FILES ${CMAKE_CURRENT_BINARY_DIR}/${SP_BIN_UUID_CANON}.bin DESTINATION ${TS_ENV}/bin)
 
 include(${TS_ROOT}/tools/cmake/common/ExportMemoryRegionsToManifest.cmake REQUIRED)
-export_memory_regions_to_manifest(TARGET smm-gateway NAME "${SP_UUID_CANON}_memory_regions.dtsi" RES EXPORT_MEMORY_REGIONS_DTSI)
+export_memory_regions_to_manifest(TARGET smm-gateway NAME "${SP_BIN_UUID_CANON}_memory_regions.dtsi" RES EXPORT_MEMORY_REGIONS_DTSI)
 
 #-------------------------------------------------------------------------------
 #  Deployment specific install options
@@ -85,9 +86,10 @@
 
 include(${TS_ROOT}/tools/cmake/common/ExportSp.cmake REQUIRED)
 export_sp(
-	SP_UUID_CANON ${SP_UUID_CANON}
+	SP_FFA_UUID_CANON ${SP_FFA_UUID_CANON}
+	SP_BIN_UUID_CANON ${SP_BIN_UUID_CANON}
 	SP_NAME ${SP_NAME}
 	DTS_IN ${CMAKE_CURRENT_LIST_DIR}/default_${SP_NAME}.dts.in
-	DTS_MEM_REGIONS ${SP_UUID_CANON}_memory_regions.dtsi
+	DTS_MEM_REGIONS ${SP_BIN_UUID_CANON}_memory_regions.dtsi
 	JSON_IN ${TS_ROOT}/environments/sp/sp_pkg.json.in
 )
diff --git a/deployments/smm-gateway/env/commonsp/smm_gateway_sp.c b/deployments/smm-gateway/env/commonsp/smm_gateway_sp.c
index 9fbaa87..65f5d01 100644
--- a/deployments/smm-gateway/env/commonsp/smm_gateway_sp.c
+++ b/deployments/smm-gateway/env/commonsp/smm_gateway_sp.c
@@ -3,7 +3,6 @@
  * Copyright (c) 2021-2022, Arm Limited and Contributors. All rights reserved.
  */
 
-#include "rpc/ffarpc/endpoint/ffarpc_call_ep.h"
 #include "deployments/smm-gateway/common/smm_gateway.h"
 #include "config/ramstore/config_ramstore.h"
 #include "config/interface/config_store.h"
@@ -26,7 +25,7 @@
 void __noreturn sp_main(union ffa_boot_info *boot_info)
 {
 	struct memory_region mm_comm_buffer_region = { 0 };
-	struct rpc_interface *gateway_iface = NULL;
+	struct rpc_service_interface *gateway_iface = NULL;
 	struct smm_variable_mm_service smm_var_service = { 0 };
 	struct mm_service_interface *smm_var_service_interface = NULL;
 	struct mm_communicate_ep mm_communicate_call_ep = { 0 };
diff --git a/deployments/smm-gateway/env/commonsp/smm_gateway_sp.cmake b/deployments/smm-gateway/env/commonsp/smm_gateway_sp.cmake
index 1602522..4976bdf 100644
--- a/deployments/smm-gateway/env/commonsp/smm_gateway_sp.cmake
+++ b/deployments/smm-gateway/env/commonsp/smm_gateway_sp.cmake
@@ -20,8 +20,9 @@
 		"components/config/ramstore"
 		"components/config/loader/sp"
 		"components/messaging/ffa/libsp"
-		"components/rpc/ffarpc/endpoint"
-		"components/rpc/ffarpc/caller/sp"
+		"components/rpc/common/endpoint"
+		"components/rpc/ts_rpc/common"
+		"components/rpc/ts_rpc/caller/sp"
 		"components/rpc/mm_communicate/endpoint/sp"
 		"components/service/locator/sp"
 		"components/service/locator/sp/ffa"
diff --git a/deployments/spm-test1/opteesp/CMakeLists.txt b/deployments/spm-test1/opteesp/CMakeLists.txt
index 1a16a98..4558303 100644
--- a/deployments/spm-test1/opteesp/CMakeLists.txt
+++ b/deployments/spm-test1/opteesp/CMakeLists.txt
@@ -13,7 +13,8 @@
 add_executable(spm-test1)
 
 set(SP_BIN_UUID_CANON "5c9edbc3-7b3a-4367-9f83-7c191ae86a37")
-set(SP_UUID_CANON "5c9edbc3-7b3a-4367-9f83-7c191ae86a37")
+set(SP_FFA_UUID_CANON "${SP_BIN_UUID_CANON}")
+set(SP_FFA_UUID_CANON "5c9edbc3-7b3a-4367-9f83-7c191ae86a37")
 set(SP_NUMBER 1)
 set(SP_HEAP_SIZE "32 * 1024" CACHE STRING "SP heap size in bytes")
 set(TRACE_PREFIX "SPM-TEST${SP_NUMBER}" CACHE STRING "Trace prefix")
@@ -25,12 +26,12 @@
 add_components(TARGET "spm-test${SP_NUMBER}"
 	BASE_DIR ${TS_ROOT}
 	COMPONENTS
+		"environments/opteesp"
 		"components/common/fdt"
 		"components/common/trace"
 		"components/common/utils"
 		"components/config/loader/sp"
 		"components/messaging/ffa/libsp"
-		"environments/opteesp"
 )
 
 include(${TS_ROOT}/components/service/spm_test/spm_test.cmake)
diff --git a/deployments/spm-test2/opteesp/CMakeLists.txt b/deployments/spm-test2/opteesp/CMakeLists.txt
index 3caa62b..ea82a4a 100644
--- a/deployments/spm-test2/opteesp/CMakeLists.txt
+++ b/deployments/spm-test2/opteesp/CMakeLists.txt
@@ -13,7 +13,8 @@
 add_executable(spm-test2)
 
 set(SP_BIN_UUID_CANON "7817164c-c40c-4d1a-867a-9bb2278cf41a")
-set(SP_UUID_CANON "7817164c-c40c-4d1a-867a-9bb2278cf41a")
+set(SP_FFA_UUID_CANON "${SP_BIN_UUID_CANON}")
+set(SP_FFA_UUID_CANON "7817164c-c40c-4d1a-867a-9bb2278cf41a")
 set(SP_NUMBER 2)
 set(SP_HEAP_SIZE "32 * 1024" CACHE STRING "SP heap size in bytes")
 set(TRACE_PREFIX "SPM-TEST${SP_NUMBER}" CACHE STRING "Trace prefix")
@@ -25,12 +26,12 @@
 add_components(TARGET "spm-test${SP_NUMBER}"
 	BASE_DIR ${TS_ROOT}
 	COMPONENTS
+		"environments/opteesp"
 		"components/common/fdt"
 		"components/common/trace"
 		"components/common/utils"
 		"components/config/loader/sp"
 		"components/messaging/ffa/libsp"
-		"environments/opteesp"
 )
 
 include(${TS_ROOT}/components/service/spm_test/spm_test.cmake)
diff --git a/deployments/spm-test3/opteesp/CMakeLists.txt b/deployments/spm-test3/opteesp/CMakeLists.txt
index 87c1c1c..c448673 100644
--- a/deployments/spm-test3/opteesp/CMakeLists.txt
+++ b/deployments/spm-test3/opteesp/CMakeLists.txt
@@ -13,7 +13,8 @@
 add_executable(spm-test3)
 
 set(SP_BIN_UUID_CANON "23eb0100-e32a-4497-9052-2f11e584afa6")
-set(SP_UUID_CANON "23eb0100-e32a-4497-9052-2f11e584afa6")
+set(SP_FFA_UUID_CANON "${SP_BIN_UUID_CANON}")
+set(SP_FFA_UUID_CANON "23eb0100-e32a-4497-9052-2f11e584afa6")
 set(SP_NUMBER 3)
 set(SP_HEAP_SIZE "32 * 1024" CACHE STRING "SP heap size in bytes")
 set(TRACE_PREFIX "SPM-TEST${SP_NUMBER}" CACHE STRING "Trace prefix")
@@ -25,12 +26,12 @@
 add_components(TARGET "spm-test${SP_NUMBER}"
 	BASE_DIR ${TS_ROOT}
 	COMPONENTS
+		"environments/opteesp"
 		"components/common/fdt"
 		"components/common/trace"
 		"components/common/utils"
 		"components/config/loader/sp"
 		"components/messaging/ffa/libsp"
-		"environments/opteesp"
 )
 
 include(${TS_ROOT}/components/service/spm_test/spm_test.cmake)
diff --git a/deployments/spm-test4/opteesp/CMakeLists.txt b/deployments/spm-test4/opteesp/CMakeLists.txt
index c0cf298..4e572ec 100644
--- a/deployments/spm-test4/opteesp/CMakeLists.txt
+++ b/deployments/spm-test4/opteesp/CMakeLists.txt
@@ -13,7 +13,8 @@
 add_executable(spm-test4)
 
 set(SP_BIN_UUID_CANON "423762ed-7772-406f-99d8-0c27da0abbf8")
-set(SP_UUID_CANON "23eb0100-e32a-4497-9052-2f11e584afa6")
+set(SP_FFA_UUID_CANON "${SP_BIN_UUID_CANON}")
+set(SP_FFA_UUID_CANON "23eb0100-e32a-4497-9052-2f11e584afa6")
 set(SP_NUMBER 4)
 set(SP_HEAP_SIZE "32 * 1024" CACHE STRING "SP heap size in bytes")
 set(TRACE_PREFIX "SPM-TEST${SP_NUMBER}" CACHE STRING "Trace prefix")
@@ -25,12 +26,12 @@
 add_components(TARGET "spm-test${SP_NUMBER}"
 	BASE_DIR ${TS_ROOT}
 	COMPONENTS
+		"environments/opteesp"
 		"components/common/fdt"
 		"components/common/trace"
 		"components/common/utils"
 		"components/config/loader/sp"
 		"components/messaging/ffa/libsp"
-		"environments/opteesp"
 )
 
 include(${TS_ROOT}/components/service/spm_test/spm_test.cmake)
diff --git a/deployments/ts-demo/ts-demo.cmake b/deployments/ts-demo/ts-demo.cmake
index f276ca1..ce57ca2 100644
--- a/deployments/ts-demo/ts-demo.cmake
+++ b/deployments/ts-demo/ts-demo.cmake
@@ -39,7 +39,6 @@
 		"components/common/tlv"
 		"components/service/common/include"
 		"components/service/common/client"
-		"components/service/discovery/client"
 		"components/service/crypto/client/cpp"
 		"components/service/crypto/client/cpp/protocol/packed-c"
 		"protocols/service/crypto/packed-c"
diff --git a/deployments/ts-demo/ts-demo.cpp b/deployments/ts-demo/ts-demo.cpp
index 7ccd7dd..d2ee2c0 100644
--- a/deployments/ts-demo/ts-demo.cpp
+++ b/deployments/ts-demo/ts-demo.cpp
@@ -18,18 +18,17 @@
 
 	service_locator_init();
 
-	crypto_service_context = service_locator_query("sn:trustedfirmware.org:crypto:0", &status);
+	crypto_service_context = service_locator_query("sn:trustedfirmware.org:crypto:0");
 
 	if (crypto_service_context) {
 
-		struct rpc_caller *caller;
-		rpc_session_handle rpc_session_handle;
+		struct rpc_caller_session *session = NULL;
 
-		rpc_session_handle = service_context_open(crypto_service_context, TS_RPC_ENCODING_PACKED_C, &caller);
+		session = service_context_open(crypto_service_context);
 
-		if (rpc_session_handle) {
+		if (session) {
 
-			packedc_crypto_client crypto_client(caller);
+			packedc_crypto_client crypto_client(session);
 
 			status = run_ts_demo(&crypto_client, true);
 
@@ -37,7 +36,7 @@
 				printf("run_ts_demo failed\n");
 			}
 
-			service_context_close(crypto_service_context, rpc_session_handle);
+			service_context_close(crypto_service_context, session);
 		}
 		else {
 			printf("Failed to open rpc session\n");
diff --git a/deployments/ts-fw-test/ts-fw-test.cmake b/deployments/ts-fw-test/ts-fw-test.cmake
index c4ecd31..41180e2 100644
--- a/deployments/ts-fw-test/ts-fw-test.cmake
+++ b/deployments/ts-fw-test/ts-fw-test.cmake
@@ -34,7 +34,6 @@
 		"components/service/locator"
 		"components/service/locator/interface"
 		"components/service/locator/remote/restapi"
-		"components/service/discovery/client"
 		"components/service/fwu/test/fwu_client/remote"
 		"components/service/fwu/test/fwu_dut"
 		"components/service/fwu/test/fwu_dut/proxy"
diff --git a/deployments/ts-remote-test/ts-remote-test.cpp b/deployments/ts-remote-test/ts-remote-test.cpp
index 1c708f6..6240dfb 100644
--- a/deployments/ts-remote-test/ts-remote-test.cpp
+++ b/deployments/ts-remote-test/ts-remote-test.cpp
@@ -19,18 +19,17 @@
 
 	service_locator_init();
 
-	test_runner_service_context = service_locator_query("sn:trustedfirmware.org:test-runner:0", &status);
+	test_runner_service_context = service_locator_query("sn:trustedfirmware.org:test-runner:0");
 
 	if (test_runner_service_context) {
 
-		struct rpc_caller *caller;
-		rpc_session_handle rpc_session_handle;
+		struct rpc_caller_session *session = NULL;
 
-		rpc_session_handle = service_context_open(test_runner_service_context, TS_RPC_ENCODING_PACKED_C, &caller);
+		session = service_context_open(test_runner_service_context);
 
-		if (rpc_session_handle) {
+		if (session) {
 
-			test_runner_client test_runner_client(caller);
+			test_runner_client test_runner_client(session);
 			remote_test_runner commandline_runner(&test_runner_client);
 
 			status = commandline_runner.execute(argc, argv);
@@ -39,7 +38,7 @@
 				printf("Command failed with test status: %d rpc status: %d\n", status, test_runner_client.err_rpc_status());
 			}
 
-			service_context_close(test_runner_service_context, rpc_session_handle);
+			service_context_close(test_runner_service_context, session);
 		}
 		else {
 			printf("Failed to open rpc session\n");
diff --git a/deployments/ts-service-test/linux-pc/CMakeLists.txt b/deployments/ts-service-test/linux-pc/CMakeLists.txt
index 60db229..51b7ccb 100644
--- a/deployments/ts-service-test/linux-pc/CMakeLists.txt
+++ b/deployments/ts-service-test/linux-pc/CMakeLists.txt
@@ -98,8 +98,6 @@
 		"components/service/block_storage/factory/client"
 		"components/service/block_storage/test/service"
 		"components/service/common/provider"
-		"components/service/discovery/provider"
-		"components/service/discovery/provider/serializer/packed-c"
 		"components/service/fwu/agent"
 		"components/service/fwu/fw_store/banked"
 		"components/service/fwu/fw_store/banked/metadata_serializer/v1"
diff --git a/deployments/ts-service-test/ts-service-test.cmake b/deployments/ts-service-test/ts-service-test.cmake
index 2a0ab69..8cefe30 100644
--- a/deployments/ts-service-test/ts-service-test.cmake
+++ b/deployments/ts-service-test/ts-service-test.cmake
@@ -32,8 +32,6 @@
 		"components/common/uuid"
 		"components/service/common/client"
 		"components/service/common/include"
-		"components/service/discovery/client"
-		"components/service/discovery/test/service"
 		"components/service/crypto/include"
 		"components/service/crypto/test/service"
 		"components/service/crypto/test/service/protobuf"
diff --git a/docs/developer/image/TSProtocolLayers.svg b/docs/developer/image/TSProtocolLayers.svg
new file mode 100644
index 0000000..9ecebde
--- /dev/null
+++ b/docs/developer/image/TSProtocolLayers.svg
@@ -0,0 +1,3 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
+<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1" width="1241px" height="731px" viewBox="-0.5 -0.5 1241 731" style="background-color: rgb(255, 255, 255);"><defs/><g><rect x="630" y="0" width="610" height="100" fill="#fff2cc" stroke="#d6b656" pointer-events="all"/><g transform="translate(-0.5 -0.5)"><switch><foreignObject pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility" style="overflow: visible; text-align: left;"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe flex-start; justify-content: unsafe flex-start; width: 608px; height: 1px; padding-top: 7px; margin-left: 632px;"><div data-drawio-colors="color: rgb(0, 0, 0); " style="box-sizing: border-box; font-size: 0px; text-align: left;"><div style="display: inline-block; font-size: 12px; font-family: Helvetica; color: rgb(0, 0, 0); line-height: 1.2; pointer-events: all; white-space: normal; overflow-wrap: normal;">Service backend</div></div></div></foreignObject><text x="632" y="19" fill="rgb(0, 0, 0)" font-family="Helvetica" font-size="12px">Service backend</text></switch></g><rect x="0" y="0" width="610" height="100" fill="#fff2cc" stroke="#d6b656" pointer-events="all"/><g transform="translate(-0.5 -0.5)"><switch><foreignObject pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility" style="overflow: visible; text-align: left;"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe flex-start; justify-content: unsafe flex-start; width: 608px; height: 1px; padding-top: 7px; margin-left: 2px;"><div data-drawio-colors="color: rgb(0, 0, 0); " style="box-sizing: border-box; font-size: 0px; text-align: left;"><div style="display: inline-block; font-size: 12px; font-family: Helvetica; color: rgb(0, 0, 0); line-height: 1.2; pointer-events: all; white-space: normal; overflow-wrap: normal;">Service client interface</div></div></div></foreignObject><text x="2" y="19" fill="rgb(0, 0, 0)" font-family="Helvetica" font-size="12px">Service client interface</text></switch></g><rect x="0" y="150" width="1240" height="100" fill="#fff2cc" stroke="#d6b656" pointer-events="all"/><g transform="translate(-0.5 -0.5)"><switch><foreignObject pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility" style="overflow: visible; text-align: left;"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe flex-start; justify-content: unsafe flex-start; width: 1238px; height: 1px; padding-top: 157px; margin-left: 2px;"><div data-drawio-colors="color: rgb(0, 0, 0); " style="box-sizing: border-box; font-size: 0px; text-align: left;"><div style="display: inline-block; font-size: 12px; font-family: Helvetica; color: rgb(0, 0, 0); line-height: 1.2; pointer-events: all; white-space: normal; overflow-wrap: normal;">Service layer</div></div></div></foreignObject><text x="2" y="169" fill="rgb(0, 0, 0)" font-family="Helvetica" font-size="12px">Service layer</text></switch></g><rect x="0" y="280" width="1240" height="310" fill="#fff2cc" stroke="#d6b656" pointer-events="all"/><g transform="translate(-0.5 -0.5)"><switch><foreignObject pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility" style="overflow: visible; text-align: left;"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe flex-start; justify-content: unsafe flex-start; width: 1238px; height: 1px; padding-top: 287px; margin-left: 2px;"><div data-drawio-colors="color: rgb(0, 0, 0); " style="box-sizing: border-box; font-size: 0px; text-align: left;"><div style="display: inline-block; font-size: 12px; font-family: Helvetica; color: rgb(0, 0, 0); line-height: 1.2; pointer-events: all; white-space: normal; overflow-wrap: normal;">RPC layer</div></div></div></foreignObject><text x="2" y="299" fill="rgb(0, 0, 0)" font-family="Helvetica" font-size="12px">RPC layer</text></switch></g><rect x="0" y="610" width="1240" height="120" fill="#fff2cc" stroke="#d6b656" pointer-events="all"/><g transform="translate(-0.5 -0.5)"><switch><foreignObject pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility" style="overflow: visible; text-align: left;"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe flex-start; justify-content: unsafe flex-start; width: 1238px; height: 1px; padding-top: 617px; margin-left: 2px;"><div data-drawio-colors="color: rgb(0, 0, 0); " style="box-sizing: border-box; font-size: 0px; text-align: left;"><div style="display: inline-block; font-size: 12px; font-family: Helvetica; color: rgb(0, 0, 0); line-height: 1.2; pointer-events: all; white-space: normal; overflow-wrap: normal;">FF-A layer<br /></div></div></div></foreignObject><text x="2" y="629" fill="rgb(0, 0, 0)" font-family="Helvetica" font-size="12px">FF-A layer&#xa;</text></switch></g><path d="M 705 650 L 763.63 650" fill="none" stroke="rgb(0, 0, 0)" stroke-miterlimit="10" pointer-events="stroke"/><path d="M 768.88 650 L 761.88 653.5 L 763.63 650 L 761.88 646.5 Z" fill="rgb(0, 0, 0)" stroke="rgb(0, 0, 0)" stroke-miterlimit="10" pointer-events="all"/><path d="M 630 630 C 606 630 600 650 619.2 654 C 600 662.8 621.6 682 637.2 674 C 648 690 684 690 696 674 C 720 674 720 658 705 650 C 720 634 696 618 675 626 C 660 614 636 614 630 630 Z" fill="rgb(255, 255, 255)" stroke="rgb(0, 0, 0)" stroke-miterlimit="10" pointer-events="all"/><g transform="translate(-0.5 -0.5)"><switch><foreignObject pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility" style="overflow: visible; text-align: left;"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 118px; height: 1px; padding-top: 650px; margin-left: 601px;"><div data-drawio-colors="color: rgb(0, 0, 0); " style="box-sizing: border-box; font-size: 0px; text-align: center;"><div style="display: inline-block; font-size: 12px; font-family: Helvetica; color: rgb(0, 0, 0); line-height: 1.2; pointer-events: all; white-space: normal; overflow-wrap: normal;">FF-A</div></div></div></foreignObject><text x="660" y="654" fill="rgb(0, 0, 0)" font-family="Helvetica" font-size="12px" text-anchor="middle">FF-A</text></switch></g><path d="M 830 620 L 830 486.37" fill="none" stroke="rgb(0, 0, 0)" stroke-miterlimit="10" pointer-events="stroke"/><path d="M 830 481.12 L 833.5 488.12 L 830 486.37 L 826.5 488.12 Z" fill="rgb(0, 0, 0)" stroke="rgb(0, 0, 0)" stroke-miterlimit="10" pointer-events="all"/><rect x="770" y="620" width="120" height="60" fill="rgb(255, 255, 255)" stroke="rgb(0, 0, 0)" pointer-events="all"/><g transform="translate(-0.5 -0.5)"><switch><foreignObject pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility" style="overflow: visible; text-align: left;"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 118px; height: 1px; padding-top: 650px; margin-left: 771px;"><div data-drawio-colors="color: rgb(0, 0, 0); " style="box-sizing: border-box; font-size: 0px; text-align: center;"><div style="display: inline-block; font-size: 12px; font-family: Helvetica; color: rgb(0, 0, 0); line-height: 1.2; pointer-events: all; white-space: normal; overflow-wrap: normal;">libsp</div></div></div></foreignObject><text x="830" y="654" fill="rgb(0, 0, 0)" font-family="Helvetica" font-size="12px" text-anchor="middle">libsp</text></switch></g><path d="M 550 650 L 575 650 L 575 654 L 612.83 654" fill="none" stroke="rgb(0, 0, 0)" stroke-miterlimit="10" pointer-events="stroke"/><path d="M 618.08 654 L 611.08 657.5 L 612.83 654 L 611.08 650.5 Z" fill="rgb(0, 0, 0)" stroke="rgb(0, 0, 0)" stroke-miterlimit="10" pointer-events="all"/><rect x="440" y="620" width="110" height="60" fill="rgb(255, 255, 255)" stroke="rgb(0, 0, 0)" pointer-events="all"/><g transform="translate(-0.5 -0.5)"><switch><foreignObject pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility" style="overflow: visible; text-align: left;"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 108px; height: 1px; padding-top: 650px; margin-left: 441px;"><div data-drawio-colors="color: rgb(0, 0, 0); " style="box-sizing: border-box; font-size: 0px; text-align: center;"><div style="display: inline-block; font-size: 12px; font-family: Helvetica; color: rgb(0, 0, 0); line-height: 1.2; pointer-events: all; white-space: normal; overflow-wrap: normal;">libsp</div></div></div></foreignObject><text x="495" y="654" fill="rgb(0, 0, 0)" font-family="Helvetica" font-size="12px" text-anchor="middle">libsp</text></switch></g><path d="M 150 680 L 150 720 L 666 720 L 666 692.37" fill="none" stroke="rgb(0, 0, 0)" stroke-miterlimit="10" pointer-events="stroke"/><path d="M 666 687.12 L 669.5 694.12 L 666 692.37 L 662.5 694.12 Z" fill="rgb(0, 0, 0)" stroke="rgb(0, 0, 0)" stroke-miterlimit="10" pointer-events="all"/><rect x="90" y="620" width="120" height="60" fill="rgb(255, 255, 255)" stroke="rgb(0, 0, 0)" pointer-events="all"/><g transform="translate(-0.5 -0.5)"><switch><foreignObject pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility" style="overflow: visible; text-align: left;"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 118px; height: 1px; padding-top: 650px; margin-left: 91px;"><div data-drawio-colors="color: rgb(0, 0, 0); " style="box-sizing: border-box; font-size: 0px; text-align: center;"><div style="display: inline-block; font-size: 12px; font-family: Helvetica; color: rgb(0, 0, 0); line-height: 1.2; pointer-events: all; white-space: normal; overflow-wrap: normal;">Linux FF-A driver</div></div></div></foreignObject><text x="150" y="654" fill="rgb(0, 0, 0)" font-family="Helvetica" font-size="12px" text-anchor="middle">Linux FF-A driver</text></switch></g><path d="M 150 580 L 150 613.63" fill="none" stroke="rgb(0, 0, 0)" stroke-miterlimit="10" pointer-events="stroke"/><path d="M 150 618.88 L 146.5 611.88 L 150 613.63 L 153.5 611.88 Z" fill="rgb(0, 0, 0)" stroke="rgb(0, 0, 0)" stroke-miterlimit="10" pointer-events="all"/><rect x="90" y="520" width="120" height="60" fill="rgb(255, 255, 255)" stroke="rgb(0, 0, 0)" pointer-events="all"/><g transform="translate(-0.5 -0.5)"><switch><foreignObject pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility" style="overflow: visible; text-align: left;"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 118px; height: 1px; padding-top: 550px; margin-left: 91px;"><div data-drawio-colors="color: rgb(0, 0, 0); " style="box-sizing: border-box; font-size: 0px; text-align: center;"><div style="display: inline-block; font-size: 12px; font-family: Helvetica; color: rgb(0, 0, 0); line-height: 1.2; pointer-events: all; white-space: normal; overflow-wrap: normal;">TS TEE driver</div></div></div></foreignObject><text x="150" y="554" fill="rgb(0, 0, 0)" font-family="Helvetica" font-size="12px" text-anchor="middle">TS TEE driver</text></switch></g><path d="M 515 480 L 515 550 L 495 550 L 495 613.63" fill="none" stroke="rgb(0, 0, 0)" stroke-miterlimit="10" pointer-events="stroke"/><path d="M 495 618.88 L 491.5 611.88 L 495 613.63 L 498.5 611.88 Z" fill="rgb(0, 0, 0)" stroke="rgb(0, 0, 0)" stroke-miterlimit="10" pointer-events="all"/><rect x="460" y="420" width="110" height="60" fill="rgb(255, 255, 255)" stroke="rgb(0, 0, 0)" pointer-events="all"/><g transform="translate(-0.5 -0.5)"><switch><foreignObject pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility" style="overflow: visible; text-align: left;"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 108px; height: 1px; padding-top: 450px; margin-left: 461px;"><div data-drawio-colors="color: rgb(0, 0, 0); " style="box-sizing: border-box; font-size: 0px; text-align: center;"><div style="display: inline-block; font-size: 12px; font-family: Helvetica; color: rgb(0, 0, 0); line-height: 1.2; pointer-events: all; white-space: normal; overflow-wrap: normal;">ts_rpc_caller_sp</div></div></div></foreignObject><text x="515" y="454" fill="rgb(0, 0, 0)" font-family="Helvetica" font-size="12px" text-anchor="middle">ts_rpc_caller_sp</text></switch></g><path d="M 800 420 L 800 236.37" fill="none" stroke="rgb(0, 0, 0)" stroke-miterlimit="10" pointer-events="stroke"/><path d="M 800 231.12 L 803.5 238.12 L 800 236.37 L 796.5 238.12 Z" fill="rgb(0, 0, 0)" stroke="rgb(0, 0, 0)" stroke-miterlimit="10" pointer-events="all"/><path d="M 830 420 L 830 270 L 970 270 L 970 236.37" fill="none" stroke="rgb(0, 0, 0)" stroke-miterlimit="10" pointer-events="stroke"/><path d="M 970 231.12 L 973.5 238.12 L 970 236.37 L 966.5 238.12 Z" fill="rgb(0, 0, 0)" stroke="rgb(0, 0, 0)" stroke-miterlimit="10" pointer-events="all"/><path d="M 860 420 L 860 310 L 1110 310 L 1110 236.37" fill="none" stroke="rgb(0, 0, 0)" stroke-miterlimit="10" pointer-events="stroke"/><path d="M 1110 231.12 L 1113.5 238.12 L 1110 236.37 L 1106.5 238.12 Z" fill="rgb(0, 0, 0)" stroke="rgb(0, 0, 0)" stroke-miterlimit="10" pointer-events="all"/><rect x="770" y="420" width="120" height="60" fill="rgb(255, 255, 255)" stroke="rgb(0, 0, 0)" pointer-events="all"/><g transform="translate(-0.5 -0.5)"><switch><foreignObject pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility" style="overflow: visible; text-align: left;"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 118px; height: 1px; padding-top: 450px; margin-left: 771px;"><div data-drawio-colors="color: rgb(0, 0, 0); " style="box-sizing: border-box; font-size: 0px; text-align: center;"><div style="display: inline-block; font-size: 12px; font-family: Helvetica; color: rgb(0, 0, 0); line-height: 1.2; pointer-events: all; white-space: normal; overflow-wrap: normal;">ts_rpc_endpoint_sp</div></div></div></foreignObject><text x="830" y="454" fill="rgb(0, 0, 0)" font-family="Helvetica" font-size="12px" text-anchor="middle">ts_rpc_endpoint_sp</text></switch></g><path d="M 830 170 L 830 86.37" fill="none" stroke="rgb(0, 0, 0)" stroke-miterlimit="10" pointer-events="stroke"/><path d="M 830 81.12 L 833.5 88.12 L 830 86.37 L 826.5 88.12 Z" fill="rgb(0, 0, 0)" stroke="rgb(0, 0, 0)" stroke-miterlimit="10" pointer-events="all"/><rect x="770" y="170" width="120" height="60" fill="rgb(255, 255, 255)" stroke="rgb(0, 0, 0)" pointer-events="all"/><g transform="translate(-0.5 -0.5)"><switch><foreignObject pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility" style="overflow: visible; text-align: left;"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 118px; height: 1px; padding-top: 200px; margin-left: 771px;"><div data-drawio-colors="color: rgb(0, 0, 0); " style="box-sizing: border-box; font-size: 0px; text-align: center;"><div style="display: inline-block; font-size: 12px; font-family: Helvetica; color: rgb(0, 0, 0); line-height: 1.2; pointer-events: all; white-space: normal; overflow-wrap: normal;">Attestation<br />RPC service</div></div></div></foreignObject><text x="830" y="204" fill="rgb(0, 0, 0)" font-family="Helvetica" font-size="12px" text-anchor="middle">Attestation...</text></switch></g><path d="M 970 170 L 970 86.37" fill="none" stroke="rgb(0, 0, 0)" stroke-miterlimit="10" pointer-events="stroke"/><path d="M 970 81.12 L 973.5 88.12 L 970 86.37 L 966.5 88.12 Z" fill="rgb(0, 0, 0)" stroke="rgb(0, 0, 0)" stroke-miterlimit="10" pointer-events="all"/><rect x="910" y="170" width="120" height="60" fill="rgb(255, 255, 255)" stroke="rgb(0, 0, 0)" pointer-events="all"/><g transform="translate(-0.5 -0.5)"><switch><foreignObject pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility" style="overflow: visible; text-align: left;"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 118px; height: 1px; padding-top: 200px; margin-left: 911px;"><div data-drawio-colors="color: rgb(0, 0, 0); " style="box-sizing: border-box; font-size: 0px; text-align: center;"><div style="display: inline-block; font-size: 12px; font-family: Helvetica; color: rgb(0, 0, 0); line-height: 1.2; pointer-events: all; white-space: normal; overflow-wrap: normal;">Crypto<br />RPC service</div></div></div></foreignObject><text x="970" y="204" fill="rgb(0, 0, 0)" font-family="Helvetica" font-size="12px" text-anchor="middle">Crypto...</text></switch></g><path d="M 1110 170 L 1110 86.37" fill="none" stroke="rgb(0, 0, 0)" stroke-miterlimit="10" pointer-events="stroke"/><path d="M 1110 81.12 L 1113.5 88.12 L 1110 86.37 L 1106.5 88.12 Z" fill="rgb(0, 0, 0)" stroke="rgb(0, 0, 0)" stroke-miterlimit="10" pointer-events="all"/><rect x="1050" y="170" width="120" height="60" fill="rgb(255, 255, 255)" stroke="rgb(0, 0, 0)" pointer-events="all"/><g transform="translate(-0.5 -0.5)"><switch><foreignObject pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility" style="overflow: visible; text-align: left;"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 118px; height: 1px; padding-top: 200px; margin-left: 1051px;"><div data-drawio-colors="color: rgb(0, 0, 0); " style="box-sizing: border-box; font-size: 0px; text-align: center;"><div style="display: inline-block; font-size: 12px; font-family: Helvetica; color: rgb(0, 0, 0); line-height: 1.2; pointer-events: all; white-space: normal; overflow-wrap: normal;">Storage<br />RPC service</div></div></div></foreignObject><text x="1110" y="204" fill="rgb(0, 0, 0)" font-family="Helvetica" font-size="12px" text-anchor="middle">Storage...</text></switch></g><path d="M 150 480 L 150 513.63" fill="none" stroke="rgb(0, 0, 0)" stroke-miterlimit="10" pointer-events="stroke"/><path d="M 150 518.88 L 146.5 511.88 L 150 513.63 L 153.5 511.88 Z" fill="rgb(0, 0, 0)" stroke="rgb(0, 0, 0)" stroke-miterlimit="10" pointer-events="all"/><rect x="90" y="420" width="120" height="60" fill="rgb(255, 255, 255)" stroke="rgb(0, 0, 0)" pointer-events="all"/><g transform="translate(-0.5 -0.5)"><switch><foreignObject pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility" style="overflow: visible; text-align: left;"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 118px; height: 1px; padding-top: 450px; margin-left: 91px;"><div data-drawio-colors="color: rgb(0, 0, 0); " style="box-sizing: border-box; font-size: 0px; text-align: center;"><div style="display: inline-block; font-size: 12px; font-family: Helvetica; color: rgb(0, 0, 0); line-height: 1.2; pointer-events: all; white-space: normal; overflow-wrap: normal;">ts_rpc_caller_linux</div></div></div></foreignObject><text x="150" y="454" fill="rgb(0, 0, 0)" font-family="Helvetica" font-size="12px" text-anchor="middle">ts_rpc_caller_linux</text></switch></g><rect x="770" y="20" width="120" height="60" fill="rgb(255, 255, 255)" stroke="rgb(0, 0, 0)" pointer-events="all"/><g transform="translate(-0.5 -0.5)"><switch><foreignObject pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility" style="overflow: visible; text-align: left;"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 118px; height: 1px; padding-top: 50px; margin-left: 771px;"><div data-drawio-colors="color: rgb(0, 0, 0); " style="box-sizing: border-box; font-size: 0px; text-align: center;"><div style="display: inline-block; font-size: 12px; font-family: Helvetica; color: rgb(0, 0, 0); line-height: 1.2; pointer-events: all; white-space: normal; overflow-wrap: normal;">Attestation<br />backend</div></div></div></foreignObject><text x="830" y="54" fill="rgb(0, 0, 0)" font-family="Helvetica" font-size="12px" text-anchor="middle">Attestation...</text></switch></g><rect x="910" y="20" width="120" height="60" fill="rgb(255, 255, 255)" stroke="rgb(0, 0, 0)" pointer-events="all"/><g transform="translate(-0.5 -0.5)"><switch><foreignObject pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility" style="overflow: visible; text-align: left;"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 118px; height: 1px; padding-top: 50px; margin-left: 911px;"><div data-drawio-colors="color: rgb(0, 0, 0); " style="box-sizing: border-box; font-size: 0px; text-align: center;"><div style="display: inline-block; font-size: 12px; font-family: Helvetica; color: rgb(0, 0, 0); line-height: 1.2; pointer-events: all; white-space: normal; overflow-wrap: normal;">Crypto<br />backend</div></div></div></foreignObject><text x="970" y="54" fill="rgb(0, 0, 0)" font-family="Helvetica" font-size="12px" text-anchor="middle">Crypto...</text></switch></g><rect x="1050" y="20" width="120" height="60" fill="rgb(255, 255, 255)" stroke="rgb(0, 0, 0)" pointer-events="all"/><g transform="translate(-0.5 -0.5)"><switch><foreignObject pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility" style="overflow: visible; text-align: left;"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 118px; height: 1px; padding-top: 50px; margin-left: 1051px;"><div data-drawio-colors="color: rgb(0, 0, 0); " style="box-sizing: border-box; font-size: 0px; text-align: center;"><div style="display: inline-block; font-size: 12px; font-family: Helvetica; color: rgb(0, 0, 0); line-height: 1.2; pointer-events: all; white-space: normal; overflow-wrap: normal;">Storage<br />backend</div></div></div></foreignObject><text x="1110" y="54" fill="rgb(0, 0, 0)" font-family="Helvetica" font-size="12px" text-anchor="middle">Storage...</text></switch></g><path d="M 190 230 L 190 265 L 302.5 265 L 302.5 293.63" fill="none" stroke="rgb(0, 0, 0)" stroke-miterlimit="10" pointer-events="stroke"/><path d="M 302.5 298.88 L 299 291.88 L 302.5 293.63 L 306 291.88 Z" fill="rgb(0, 0, 0)" stroke="rgb(0, 0, 0)" stroke-miterlimit="10" pointer-events="all"/><rect x="130" y="170" width="120" height="60" fill="rgb(255, 255, 255)" stroke="rgb(0, 0, 0)" pointer-events="all"/><g transform="translate(-0.5 -0.5)"><switch><foreignObject pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility" style="overflow: visible; text-align: left;"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 118px; height: 1px; padding-top: 200px; margin-left: 131px;"><div data-drawio-colors="color: rgb(0, 0, 0); " style="box-sizing: border-box; font-size: 0px; text-align: center;"><div style="display: inline-block; font-size: 12px; font-family: Helvetica; color: rgb(0, 0, 0); line-height: 1.2; pointer-events: all; white-space: normal; overflow-wrap: normal;">Attestation<br />RPC caller</div></div></div></foreignObject><text x="190" y="204" fill="rgb(0, 0, 0)" font-family="Helvetica" font-size="12px" text-anchor="middle">Attestation...</text></switch></g><path d="M 330 230 L 330 293.63" fill="none" stroke="rgb(0, 0, 0)" stroke-miterlimit="10" pointer-events="stroke"/><path d="M 330 298.88 L 326.5 291.88 L 330 293.63 L 333.5 291.88 Z" fill="rgb(0, 0, 0)" stroke="rgb(0, 0, 0)" stroke-miterlimit="10" pointer-events="all"/><rect x="270" y="170" width="120" height="60" fill="rgb(255, 255, 255)" stroke="rgb(0, 0, 0)" pointer-events="all"/><g transform="translate(-0.5 -0.5)"><switch><foreignObject pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility" style="overflow: visible; text-align: left;"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 118px; height: 1px; padding-top: 200px; margin-left: 271px;"><div data-drawio-colors="color: rgb(0, 0, 0); " style="box-sizing: border-box; font-size: 0px; text-align: center;"><div style="display: inline-block; font-size: 12px; font-family: Helvetica; color: rgb(0, 0, 0); line-height: 1.2; pointer-events: all; white-space: normal; overflow-wrap: normal;">Crypto<br />RPC caller</div></div></div></foreignObject><text x="330" y="204" fill="rgb(0, 0, 0)" font-family="Helvetica" font-size="12px" text-anchor="middle">Crypto...</text></switch></g><path d="M 470 230 L 470 265 L 357.5 265 L 357.5 293.63" fill="none" stroke="rgb(0, 0, 0)" stroke-miterlimit="10" pointer-events="stroke"/><path d="M 357.5 298.88 L 354 291.88 L 357.5 293.63 L 361 291.88 Z" fill="rgb(0, 0, 0)" stroke="rgb(0, 0, 0)" stroke-miterlimit="10" pointer-events="all"/><rect x="410" y="170" width="120" height="60" fill="rgb(255, 255, 255)" stroke="rgb(0, 0, 0)" pointer-events="all"/><g transform="translate(-0.5 -0.5)"><switch><foreignObject pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility" style="overflow: visible; text-align: left;"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 118px; height: 1px; padding-top: 200px; margin-left: 411px;"><div data-drawio-colors="color: rgb(0, 0, 0); " style="box-sizing: border-box; font-size: 0px; text-align: center;"><div style="display: inline-block; font-size: 12px; font-family: Helvetica; color: rgb(0, 0, 0); line-height: 1.2; pointer-events: all; white-space: normal; overflow-wrap: normal;">Storage<br />RPC caller</div></div></div></foreignObject><text x="470" y="204" fill="rgb(0, 0, 0)" font-family="Helvetica" font-size="12px" text-anchor="middle">Storage...</text></switch></g><path d="M 190 80 L 190 163.63" fill="none" stroke="rgb(0, 0, 0)" stroke-miterlimit="10" pointer-events="stroke"/><path d="M 190 168.88 L 186.5 161.88 L 190 163.63 L 193.5 161.88 Z" fill="rgb(0, 0, 0)" stroke="rgb(0, 0, 0)" stroke-miterlimit="10" pointer-events="all"/><rect x="130" y="20" width="120" height="60" fill="rgb(255, 255, 255)" stroke="rgb(0, 0, 0)" pointer-events="all"/><g transform="translate(-0.5 -0.5)"><switch><foreignObject pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility" style="overflow: visible; text-align: left;"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 118px; height: 1px; padding-top: 50px; margin-left: 131px;"><div data-drawio-colors="color: rgb(0, 0, 0); " style="box-sizing: border-box; font-size: 0px; text-align: center;"><div style="display: inline-block; font-size: 12px; font-family: Helvetica; color: rgb(0, 0, 0); line-height: 1.2; pointer-events: all; white-space: normal; overflow-wrap: normal;">Attestation<br />client</div></div></div></foreignObject><text x="190" y="54" fill="rgb(0, 0, 0)" font-family="Helvetica" font-size="12px" text-anchor="middle">Attestation...</text></switch></g><path d="M 330 80 L 330 163.63" fill="none" stroke="rgb(0, 0, 0)" stroke-miterlimit="10" pointer-events="stroke"/><path d="M 330 168.88 L 326.5 161.88 L 330 163.63 L 333.5 161.88 Z" fill="rgb(0, 0, 0)" stroke="rgb(0, 0, 0)" stroke-miterlimit="10" pointer-events="all"/><rect x="270" y="20" width="120" height="60" fill="rgb(255, 255, 255)" stroke="rgb(0, 0, 0)" pointer-events="all"/><g transform="translate(-0.5 -0.5)"><switch><foreignObject pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility" style="overflow: visible; text-align: left;"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 118px; height: 1px; padding-top: 50px; margin-left: 271px;"><div data-drawio-colors="color: rgb(0, 0, 0); " style="box-sizing: border-box; font-size: 0px; text-align: center;"><div style="display: inline-block; font-size: 12px; font-family: Helvetica; color: rgb(0, 0, 0); line-height: 1.2; pointer-events: all; white-space: normal; overflow-wrap: normal;">Crypto<br />client</div></div></div></foreignObject><text x="330" y="54" fill="rgb(0, 0, 0)" font-family="Helvetica" font-size="12px" text-anchor="middle">Crypto...</text></switch></g><path d="M 470 80 L 470 163.63" fill="none" stroke="rgb(0, 0, 0)" stroke-miterlimit="10" pointer-events="stroke"/><path d="M 470 168.88 L 466.5 161.88 L 470 163.63 L 473.5 161.88 Z" fill="rgb(0, 0, 0)" stroke="rgb(0, 0, 0)" stroke-miterlimit="10" pointer-events="all"/><rect x="410" y="20" width="120" height="60" fill="rgb(255, 255, 255)" stroke="rgb(0, 0, 0)" pointer-events="all"/><g transform="translate(-0.5 -0.5)"><switch><foreignObject pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility" style="overflow: visible; text-align: left;"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 118px; height: 1px; padding-top: 50px; margin-left: 411px;"><div data-drawio-colors="color: rgb(0, 0, 0); " style="box-sizing: border-box; font-size: 0px; text-align: center;"><div style="display: inline-block; font-size: 12px; font-family: Helvetica; color: rgb(0, 0, 0); line-height: 1.2; pointer-events: all; white-space: normal; overflow-wrap: normal;">Storage<br />client</div></div></div></foreignObject><text x="470" y="54" fill="rgb(0, 0, 0)" font-family="Helvetica" font-size="12px" text-anchor="middle">Storage...</text></switch></g><rect x="220" y="420" width="110" height="60" fill="#f5f5f5" stroke="#666666" stroke-dasharray="3 3" pointer-events="all"/><g transform="translate(-0.5 -0.5)"><switch><foreignObject pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility" style="overflow: visible; text-align: left;"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 108px; height: 1px; padding-top: 450px; margin-left: 221px;"><div data-drawio-colors="color: #333333; " style="box-sizing: border-box; font-size: 0px; text-align: center;"><div style="display: inline-block; font-size: 12px; font-family: Helvetica; color: rgb(51, 51, 51); line-height: 1.2; pointer-events: all; white-space: normal; overflow-wrap: normal;">direct</div></div></div></foreignObject><text x="275" y="454" fill="#333333" font-family="Helvetica" font-size="12px" text-anchor="middle">direct</text></switch></g><rect x="340" y="420" width="110" height="60" fill="#f5f5f5" stroke="#666666" stroke-dasharray="3 3" pointer-events="all"/><g transform="translate(-0.5 -0.5)"><switch><foreignObject pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility" style="overflow: visible; text-align: left;"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 108px; height: 1px; padding-top: 450px; margin-left: 341px;"><div data-drawio-colors="color: #333333; " style="box-sizing: border-box; font-size: 0px; text-align: center;"><div style="display: inline-block; font-size: 12px; font-family: Helvetica; color: rgb(51, 51, 51); line-height: 1.2; pointer-events: all; white-space: normal; overflow-wrap: normal;">dummy</div></div></div></foreignObject><text x="395" y="454" fill="#333333" font-family="Helvetica" font-size="12px" text-anchor="middle">dummy</text></switch></g><path d="M 302.5 360 L 302.5 390 L 150 390 L 150 413.63" fill="none" stroke="rgb(0, 0, 0)" stroke-miterlimit="10" pointer-events="stroke"/><path d="M 150 418.88 L 146.5 411.88 L 150 413.63 L 153.5 411.88 Z" fill="rgb(0, 0, 0)" stroke="rgb(0, 0, 0)" stroke-miterlimit="10" pointer-events="all"/><path d="M 357.5 360 L 357.5 390 L 515 390 L 515 413.63" fill="none" stroke="rgb(0, 0, 0)" stroke-miterlimit="10" pointer-events="stroke"/><path d="M 515 418.88 L 511.5 411.88 L 515 413.63 L 518.5 411.88 Z" fill="rgb(0, 0, 0)" stroke="rgb(0, 0, 0)" stroke-miterlimit="10" pointer-events="all"/><rect x="275" y="300" width="110" height="60" fill="rgb(255, 255, 255)" stroke="rgb(0, 0, 0)" pointer-events="all"/><g transform="translate(-0.5 -0.5)"><switch><foreignObject pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility" style="overflow: visible; text-align: left;"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 108px; height: 1px; padding-top: 330px; margin-left: 276px;"><div data-drawio-colors="color: rgb(0, 0, 0); " style="box-sizing: border-box; font-size: 0px; text-align: center;"><div style="display: inline-block; font-size: 12px; font-family: Helvetica; color: rgb(0, 0, 0); line-height: 1.2; pointer-events: all; white-space: normal; overflow-wrap: normal;">rpc_caller_session</div></div></div></foreignObject><text x="330" y="334" fill="rgb(0, 0, 0)" font-family="Helvetica" font-size="12px" text-anchor="middle">rpc_caller_session</text></switch></g></g><switch><g requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility"/><a transform="translate(0,-5)" xlink:href="https://www.drawio.com/doc/faq/svg-export-text-problems" target="_blank"><text text-anchor="middle" font-size="10px" x="50%" y="100%">Text is not SVG - cannot display</text></a></switch></svg>
\ No newline at end of file
diff --git a/docs/developer/image/TSServiceDiscovery.svg b/docs/developer/image/TSServiceDiscovery.svg
new file mode 100644
index 0000000..d9e4b7e
--- /dev/null
+++ b/docs/developer/image/TSServiceDiscovery.svg
@@ -0,0 +1,3 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
+<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1" width="1681px" height="661px" viewBox="-0.5 -0.5 1681 661" style="background-color: rgb(255, 255, 255);"><defs/><g><path d="M 1160.05 80 L 1160.1 180 L 840 180 L 840 268.03" fill="none" stroke="#82b366" stroke-width="4" stroke-miterlimit="10" pointer-events="stroke"/><path d="M 840 275.53 L 835 265.53 L 840 268.03 L 845 265.53 Z" fill="#82b366" stroke="#82b366" stroke-width="4" stroke-miterlimit="10" pointer-events="all"/><path d="M 1180 80 L 1180 268.03" fill="none" stroke="#82b366" stroke-width="4" stroke-miterlimit="10" pointer-events="stroke"/><path d="M 1180 275.53 L 1175 265.53 L 1180 268.03 L 1185 265.53 Z" fill="#82b366" stroke="#82b366" stroke-width="4" stroke-miterlimit="10" pointer-events="all"/><path d="M 1199.95 79.04 L 1200 180 L 1520 180 L 1520 268.03" fill="none" stroke="#82b366" stroke-width="4" stroke-miterlimit="10" pointer-events="stroke"/><path d="M 1520 275.53 L 1515 265.53 L 1520 268.03 L 1525 265.53 Z" fill="#82b366" stroke="#82b366" stroke-width="4" stroke-miterlimit="10" pointer-events="all"/><path d="M 1105.75 68.28 L 500 68.3 L 500 273.63" fill="none" stroke="rgb(0, 0, 0)" stroke-miterlimit="10" pointer-events="stroke"/><path d="M 500 278.88 L 496.5 271.88 L 500 273.63 L 503.5 271.88 Z" fill="rgb(0, 0, 0)" stroke="rgb(0, 0, 0)" stroke-miterlimit="10" pointer-events="all"/><path d="M 1075 40 L 160 40 L 160 273.63" fill="none" stroke="rgb(0, 0, 0)" stroke-miterlimit="10" pointer-events="stroke"/><path d="M 160 278.88 L 156.5 271.88 L 160 273.63 L 163.5 271.88 Z" fill="rgb(0, 0, 0)" stroke="rgb(0, 0, 0)" stroke-miterlimit="10" pointer-events="all"/><path d="M 680 330 L 680 280 L 1000 280 L 1000 330" fill="#d5e8d4" stroke="#82b366" stroke-miterlimit="10" pointer-events="all"/><path d="M 680 330 L 680 510 L 1000 510 L 1000 330" fill="none" stroke="#82b366" stroke-miterlimit="10" pointer-events="none"/><path d="M 680 330 L 1000 330" fill="none" stroke="#82b366" stroke-miterlimit="10" pointer-events="none"/><g fill="rgb(0, 0, 0)" font-family="Helvetica" font-weight="bold" pointer-events="none" text-anchor="middle" font-size="12px"><text x="839.5" y="302.5">TS SP</text><text x="839.5" y="316.5">FF-A UUID = bdcd76d7-825e-4751-963b-86d4f84943ac</text></g><rect x="700" y="350" width="280" height="60" fill="rgb(255, 255, 255)" stroke="rgb(0, 0, 0)" pointer-events="none"/><g transform="translate(-0.5 -0.5)"><switch><foreignObject pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility" style="overflow: visible; text-align: left;"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe flex-start; width: 278px; height: 1px; padding-top: 380px; margin-left: 702px;"><div data-drawio-colors="color: rgb(0, 0, 0); " style="box-sizing: border-box; font-size: 0px; text-align: left;"><div style="display: inline-block; font-size: 12px; font-family: Helvetica; color: rgb(0, 0, 0); line-height: 1.2; pointer-events: none; white-space: normal; overflow-wrap: normal;">Attestation service<br />Interface ID = 0<br />UUID = a1baf155-8876-4695-8f7c-54955e8db974</div></div></div></foreignObject><text x="702" y="384" fill="rgb(0, 0, 0)" font-family="Helvetica" font-size="12px">Attestation service...</text></switch></g><rect x="700" y="430" width="280" height="60" fill="rgb(255, 255, 255)" stroke="rgb(0, 0, 0)" pointer-events="none"/><g transform="translate(-0.5 -0.5)"><switch><foreignObject pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility" style="overflow: visible; text-align: left;"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe flex-start; width: 278px; height: 1px; padding-top: 460px; margin-left: 702px;"><div data-drawio-colors="color: rgb(0, 0, 0); " style="box-sizing: border-box; font-size: 0px; text-align: left;"><div style="display: inline-block; font-size: 12px; font-family: Helvetica; color: rgb(0, 0, 0); line-height: 1.2; pointer-events: none; white-space: normal; overflow-wrap: normal;">Crypto service<br />Interface ID = 1<br /><div style=""><span style="background-color: initial;">UUID = d9df52d5-16a2-4bb2-9aa4-d26d3b84e8c0</span></div></div></div></div></foreignObject><text x="702" y="464" fill="rgb(0, 0, 0)" font-family="Helvetica" font-size="12px">Crypto service...</text></switch></g><path d="M 1020 330 L 1020 280 L 1340 280 L 1340 330" fill="#d5e8d4" stroke="#82b366" stroke-miterlimit="10" pointer-events="none"/><path d="M 1020 330 L 1020 510 L 1340 510 L 1340 330" fill="none" stroke="#82b366" stroke-miterlimit="10" pointer-events="none"/><path d="M 1020 330 L 1340 330" fill="none" stroke="#82b366" stroke-miterlimit="10" pointer-events="none"/><g fill="rgb(0, 0, 0)" font-family="Helvetica" font-weight="bold" pointer-events="none" text-anchor="middle" font-size="12px"><text x="1179.5" y="302.5">TS SP</text><text x="1179.5" y="316.5">FF-A UUID = bdcd76d7-825e-4751-963b-86d4f84943ac</text></g><rect x="1040" y="350" width="280" height="60" fill="rgb(255, 255, 255)" stroke="rgb(0, 0, 0)" pointer-events="none"/><g transform="translate(-0.5 -0.5)"><switch><foreignObject pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility" style="overflow: visible; text-align: left;"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe flex-start; width: 278px; height: 1px; padding-top: 380px; margin-left: 1042px;"><div data-drawio-colors="color: rgb(0, 0, 0); " style="box-sizing: border-box; font-size: 0px; text-align: left;"><div style="display: inline-block; font-size: 12px; font-family: Helvetica; color: rgb(0, 0, 0); line-height: 1.2; pointer-events: none; white-space: normal; overflow-wrap: normal;">Protected storage<br />Interface ID = 0<br />UUID = 751bf801-3dde-4768-a514-0f10aeed1790</div></div></div></foreignObject><text x="1042" y="384" fill="rgb(0, 0, 0)" font-family="Helvetica" font-size="12px">Protected storage...</text></switch></g><rect x="1040" y="430" width="280" height="60" fill="#d5e8d4" stroke="#82b366" pointer-events="none"/><g transform="translate(-0.5 -0.5)"><switch><foreignObject pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility" style="overflow: visible; text-align: left;"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe flex-start; width: 278px; height: 1px; padding-top: 460px; margin-left: 1042px;"><div data-drawio-colors="color: rgb(0, 0, 0); " style="box-sizing: border-box; font-size: 0px; text-align: left;"><div style="display: inline-block; font-size: 12px; font-family: Helvetica; color: rgb(0, 0, 0); line-height: 1.2; pointer-events: none; white-space: normal; overflow-wrap: normal;">Internal trusted storage<br />Interface ID = 1<br /><div style=""><span style="background-color: initial;">UUID = dc1eef48-b17a-5ccf-ac8b-dfcff7711b14</span></div></div></div></div></foreignObject><text x="1042" y="464" fill="rgb(0, 0, 0)" font-family="Helvetica" font-size="12px">Internal trusted storage...</text></switch></g><path d="M 1360 330 L 1360 280 L 1680 280 L 1680 330" fill="#d5e8d4" stroke="#82b366" stroke-miterlimit="10" pointer-events="none"/><path d="M 1360 330 L 1360 510 L 1680 510 L 1680 330" fill="none" stroke="#82b366" stroke-miterlimit="10" pointer-events="none"/><path d="M 1360 330 L 1680 330" fill="none" stroke="#82b366" stroke-miterlimit="10" pointer-events="none"/><g fill="rgb(0, 0, 0)" font-family="Helvetica" font-weight="bold" pointer-events="none" text-anchor="middle" font-size="12px"><text x="1519.5" y="302.5">TS SP</text><text x="1519.5" y="316.5">FF-A UUID = bdcd76d7-825e-4751-963b-86d4f84943ac</text></g><rect x="1380" y="350" width="280" height="60" fill="rgb(255, 255, 255)" stroke="rgb(0, 0, 0)" pointer-events="none"/><g transform="translate(-0.5 -0.5)"><switch><foreignObject pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility" style="overflow: visible; text-align: left;"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe flex-start; width: 278px; height: 1px; padding-top: 380px; margin-left: 1382px;"><div data-drawio-colors="color: rgb(0, 0, 0); " style="box-sizing: border-box; font-size: 0px; text-align: left;"><div style="display: inline-block; font-size: 12px; font-family: Helvetica; color: rgb(0, 0, 0); line-height: 1.2; pointer-events: none; white-space: normal; overflow-wrap: normal;">Crypto service<br />Interface ID = 0<br /><div style=""><span style="background-color: initial;">UUID = d9df52d5-16a2-4bb2-9aa4-d26d3b84e8c0</span></div></div></div></div></foreignObject><text x="1382" y="384" fill="rgb(0, 0, 0)" font-family="Helvetica" font-size="12px">Crypto service...</text></switch></g><rect x="340" y="280" width="320" height="50" fill="rgb(255, 255, 255)" stroke="rgb(0, 0, 0)" pointer-events="none"/><g transform="translate(-0.5 -0.5)"><switch><foreignObject pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility" style="overflow: visible; text-align: left;"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 318px; height: 1px; padding-top: 305px; margin-left: 341px;"><div data-drawio-colors="color: rgb(0, 0, 0); " style="box-sizing: border-box; font-size: 0px; text-align: center;"><div style="display: inline-block; font-size: 12px; font-family: Helvetica; color: rgb(0, 0, 0); line-height: 1.2; pointer-events: none; white-space: normal; overflow-wrap: normal;">Non-TS SP<br />FF-A UUID = <span style="background-color: initial;">020b365f-e907-4f7e-999d-20fbb7a03183<br /></span></div></div></div></foreignObject><text x="500" y="309" fill="rgb(0, 0, 0)" font-family="Helvetica" font-size="12px" text-anchor="middle">Non-TS SP...</text></switch></g><rect x="0" y="280" width="320" height="50" fill="rgb(255, 255, 255)" stroke="rgb(0, 0, 0)" pointer-events="none"/><g transform="translate(-0.5 -0.5)"><switch><foreignObject pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility" style="overflow: visible; text-align: left;"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 318px; height: 1px; padding-top: 305px; margin-left: 1px;"><div data-drawio-colors="color: rgb(0, 0, 0); " style="box-sizing: border-box; font-size: 0px; text-align: center;"><div style="display: inline-block; font-size: 12px; font-family: Helvetica; color: rgb(0, 0, 0); line-height: 1.2; pointer-events: none; white-space: normal; overflow-wrap: normal;">Non-TS SP<br />FF-A UUID = <span style="background-color: initial;">444ca317-4205-4a7b-b263-a80ec7b0e776<br /></span></div></div></div></foreignObject><text x="160" y="309" fill="rgb(0, 0, 0)" font-family="Helvetica" font-size="12px" text-anchor="middle">Non-TS SP...</text></switch></g><ellipse cx="1180" cy="40" rx="105" ry="40" fill="rgb(255, 255, 255)" stroke="rgb(0, 0, 0)" pointer-events="none"/><g transform="translate(-0.5 -0.5)"><switch><foreignObject pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility" style="overflow: visible; text-align: left;"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 208px; height: 1px; padding-top: 40px; margin-left: 1076px;"><div data-drawio-colors="color: rgb(0, 0, 0); " style="box-sizing: border-box; font-size: 0px; text-align: center;"><div style="display: inline-block; font-size: 12px; font-family: Helvetica; color: rgb(0, 0, 0); line-height: 1.2; pointer-events: none; white-space: normal; overflow-wrap: normal;">Phase 1.<br />FFA_PARTITION_INFO_GET<br />Select TS SPs by FF-A UUID</div></div></div></foreignObject><text x="1180" y="44" fill="rgb(0, 0, 0)" font-family="Helvetica" font-size="12px" text-anchor="middle">Phase 1....</text></switch></g><path d="M 1180 560 L 1180 501.97" fill="none" stroke="#82b366" stroke-width="4" stroke-miterlimit="10" pointer-events="none"/><path d="M 1180 494.47 L 1185 504.47 L 1180 501.97 L 1175 504.47 Z" fill="#82b366" stroke="#82b366" stroke-width="4" stroke-miterlimit="10" pointer-events="none"/><ellipse cx="1180" cy="610" rx="123" ry="50" fill="rgb(255, 255, 255)" stroke="rgb(0, 0, 0)" pointer-events="none"/><g transform="translate(-0.5 -0.5)"><switch><foreignObject pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility" style="overflow: visible; text-align: left;"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 244px; height: 1px; padding-top: 610px; margin-left: 1058px;"><div data-drawio-colors="color: rgb(0, 0, 0); " style="box-sizing: border-box; font-size: 0px; text-align: center;"><div style="display: inline-block; font-size: 12px; font-family: Helvetica; color: rgb(0, 0, 0); line-height: 1.2; pointer-events: none; white-space: normal; overflow-wrap: normal;">Phase 2.<br />Select service of a TS SP by service UUID (Get service info query)</div></div></div></foreignObject><text x="1180" y="614" fill="rgb(0, 0, 0)" font-family="Helvetica" font-size="12px" text-anchor="middle">Phase 2....</text></switch></g></g><switch><g requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility"/><a transform="translate(0,-5)" xlink:href="https://www.drawio.com/doc/faq/svg-export-text-problems" target="_blank"><text text-anchor="middle" font-size="10px" x="50%" y="100%">Text is not SVG - cannot display</text></a></switch></svg>
\ No newline at end of file
diff --git a/docs/developer/service-access-protocols.rst b/docs/developer/service-access-protocols.rst
index 4161f0d..8a8c8a4 100644
--- a/docs/developer/service-access-protocols.rst
+++ b/docs/developer/service-access-protocols.rst
@@ -10,42 +10,254 @@
     - Message serialization code is decoupled from service provider code using an abstract 'serializer' interface.  Alternative
       concrete serializers may provide implementations of the interface.
 
-RPC Session
------------
-
-Before a client can call trusted service methods, an RPC session must be established where an association is made between an RPC
-Caller and a call endpoint that corresponds to the required service provider instance.  To establish the session, the client
-must provide:
-
-    - An identifier for the service provider instance.
-    - Any client credentials that allow RPC layer access control to be applied if needed.
-
-.. uml:: uml/RpcSessionClassDiagram.puml
-
-Once the RPC session is established, the client may call service methods via an abstract RPC Caller interface that takes the
-following parameters:
-
-    - The opcode that identifies the method to call.
-    - A buffer for the serialized method parameters.
-    - A buffer for the serialized return values.
-
 A deployment independent interface for locating services and establishing RPC sessions is described here: :ref:`Service Locator`
 
+Trusted Services protocol layers
+--------------------------------
+
+.. image:: image/TSProtocolLayers.svg
+
+* Service client interface: This component provides the interface to a given service for a user application, i.e. the PSA
+  Crypto, Internal Trusted Storage, etc. interface.
+
+* Service layer: This layer is responsible for serializing and deserializing the service specific parameters and it provides
+  a transparent interface between the caller and endpoint side.
+
+* RPC layer:
+
+   * RPC caller session: This component provides a session-like object for the service layer. After opening the session, it is
+     tied to the opened service interface of the endpoint. Each service call can use the simple begin/invoke/end interface for
+     requesting a buffer for the call parameters, for invoking the call and for releasing the response buffer.
+
+     The RPC caller session manages the lifetime of the shared memory. Currently it has two options. It either creates the
+     memory on session open and keeps it while the session is open, or it creates the shared buffer for each call and releases
+     it when the call ends (``end()``).
+
+   * RPC caller implementations (`ts_rpc_caller_linux`, `ts_rpc_caller_sp`, etc.): The RPC caller session is built on the
+     primitives of the RPC callers. These primitives allow the caller session finding the remote endpoint, creating and
+     releasing shared memories and doing the actual call.
+
+     The main RPC implementation is the TS RPC which is a TS specific RPC solution over FF-A. The project contains caller
+     implementations for Linux and for S-EL0 SPs. The Linux implementation is split between the user space and a kernel driver.
+
+     There are other RPC caller implementations (dummy, direct) which are used for testing purposes.
+
+   * RPC endpoint (`ts_rpc_endpoint_sp`): This component provides the RPC endpoint which can host multiple services. Once it
+     receives the call from the client, it finds the matching service and forwards the serialized call parameters to it.
+
+* FF-A layer: It is the transport layer of the protocol stack, and it provides interfaces for sending messages and sharing
+  memory between normal world and secure world components.
+
+TS RPC implementation
+---------------------
+
+Generic concepts
+''''''''''''''''
+
+* The requests are always sent by the caller and the endpoint sends a response.
+* The protocol version describes the ABI, the allowed values of the message fields and the behavior of the calls.
+* Service endpoints are provided by FF-A secure partitions.
+* Each endpoint can implement multiple services. The services are identified by their service UUID (**not** FF-A UUID). To
+  avoid including the UUID in each service call, a short interface ID is assigned to each service. The mapping of service
+  UUIDs and interface IDs can be queried by an RPC call. The lifetime of the interface ID is the same as the lifetime of the
+  service. The `0xff` interface ID is used for the management interface.
+* The service calls use shared memory to forward the call payload. It has to be shared via FF-A and then retrieved by the
+  endpoint. The shared memories are tied to an endpoint not to a service.
+* The errors which happen in the RPC layer will result in a RPC status code which indicates an error.
+* The errors which happen in the service handler will result in a service status code which indicates an error. In this case
+  the RPC status code will be `RPC_SUCCESS` as the RPC layer was able to forward the call between the service caller and the
+  service handler.
+
+ABI
+'''
+
+The ABI of the TS RPC protocol uses the 32 bit variants of ``FFA_MSG_SEND_DIRECT_REQ`` and ``FFA_MSG_SEND_DIRECT_RESP``
+interfaces of the FF-A specification. The use of the implementation specific arguments is listed in the table below.
+
+.. list-table:: TS RPC ABI
+  :header-rows: 1
+
+  * - Message name
+    - Short message ID
+    - W3[31:30] - SAP
+    - W3[29:24] - Flags
+    - W3[23:16] - Interface ID
+    - W3[15:0] - Opcode
+    - W4 - Arg1
+    - W5 - Arg2
+    - W6 - Arg3
+    - W7 - Arg4
+  * - RPC protocol version get request
+    - ``VERSION_GET``
+    - ``0b00``
+    - ``0b000000``
+    - ``0xff``
+    - ``0x0000``
+    - Reserved (MBZ)
+    - Reserved (MBZ)
+    - Reserved (MBZ)
+    - Reserved (MBZ)
+  * - RPC protocol version get response
+    - ``VERSION_GET``
+    - ``0b00``
+    - ``0b000000``
+    - ``0xff``
+    - ``0x0000``
+    - Version, starting from ``0x00000001``
+    - Reserved (MBZ)
+    - Reserved (MBZ)
+    - Reserved (MBZ)
+  * - Memory retrieve request
+    - ``MEM_RETRIEVE``
+    - ``0b00``
+    - ``0b000000``
+    - ``0xff``
+    - ``0x0001``
+    - FF-A memory handle LSW
+    - FF-A memory handle MSW
+    - FF-A memory tag LSW
+    - FF-A memory tag MSW
+  * - Memory relinquish request
+    - ``MEM_RELINQUISH``
+    - ``0b00``
+    - ``0b000000``
+    - ``0xff``
+    - ``0x0002``
+    - FF-A memory handle LSW
+    - FF-A memory handle MSW
+    - Reserved (MBZ)
+    - Reserved (MBZ)
+  * - Memory retrieve/relinquish response
+    - ``MEM_RETRIEVE``/``MEM_RELINQUISH``
+    - ``0b00``
+    - ``0b000000``
+    - ``0xff``
+    - ``0x0001``/``0x0002``
+    - TS RPC status
+    - Reserved (MBZ)
+    - Reserved (MBZ)
+    - Reserved (MBZ)
+  * - Service info get request
+    - ``SERVICE_INFO_GET``
+    - ``0b00``
+    - ``0b000000``
+    - ``0xff``
+    - ``0x0003``
+    - Service UUID
+    - Service UUID
+    - Service UUID
+    - Service UUID
+  * - Service info get response
+    - ``SERVICE_INFO_GET``
+    - ``0b00``
+    - ``0b000000``
+    - ``0xff``
+    - ``0x0003``
+    - TS RPC status
+    - ``[31:8]`` Reserved
+
+      ``[7:0]`` Queried service interface ID
+    - Reserved (MBZ)
+    - Reserved (MBZ)
+  * - Service call request
+    -
+    - ``0b00``
+    - ``0b000000``
+    - Service interface ID
+    - Service opcode
+    - FF-A memory handle LSW
+    - FF-A memory handle MSW
+    - Request length
+    - Client ID
+  * - Service call response
+    -
+    - ``0b00``
+    - ``0b000000``
+    - Service interface ID
+    - Service opcode
+    - TS RPC status
+    - Service status
+    - Response length
+    - Reserved
+
+* **RPC protocol version get**
+
+  Queries the RPC protocol version. This message must be available and backwards compatible for all protocol versions.
+
+* **Memory retrieve**
+
+  Requests the endpoint to do an ``FFA_MEM_RETRIEVE_REQ`` call using the forwarded FF-A memory handle and tag.
+
+* **Memory relinquish**
+
+  Requests the endpoint to do an ``FFA_MEM_RELINQUISH`` call using the forwarded FF-A memory handle.
+
+* **Service info get**
+
+  Query service information from the endpoint by the UUID of the service. The UUID is transmitted as defined in SMCCC section
+  5.3 but in registers W4-W7. The returned service interface ID should be used in the service calls. Multiple endpoints can
+  implement the same service but one endpoint can implement a service only once.
+
+* **Service call**
+
+  After creating a shared memory and querying the interface ID for a given service UUID the caller can make a service call. The
+  service opcode and the contents of the shared memory is service specific. The request and response length fields indicate the
+  used area of the shared memory.
+
+  It is allowed to do a limited service call without shared memory, i.e. doorbell call. In this case the FF-A memory ID has to
+  be the invalid handle value ``0xffffffffffffffff``.
+
+Service discovery
+'''''''''''''''''
+
+* Query all TS SPs via ``FFA_PARTITION_INFO_GET`` call made to the SPMC. All TS SPs have the same FF-A UUID:
+  ``bdcd76d7-825e-4751-963b-86d4f84943ac`` If the system setup has fixed SP endpoint IDs, this step can be skipped.
+* Iterate thought the TS SPs and make a "Service info get request" RPC call to the SPs, containing the service UUID. If the
+  RPC status in the "Service info get response" is `RPC_SUCCESS`, the SP implements the service and its interface ID is returned
+  in the response.
+* If there are multiple instances of a service, the selection between these should be done in a service specific way (i.e.
+  query service version, capabilities, etc.).
+
+.. image:: image/TSServiceDiscovery.svg
+
+RPC status code values
+'''''''''''''''''''''''
+
+The status codes for the RPC layer are defined in `components/rpc/common/interface/rpc_status.h`. Currently the following values
+are defined:
+
+.. literalinclude:: ../../components/rpc/common/interface/rpc_status.h
+    :lines: 20-32
+    :language: C
+
+Example TS RPC call
+'''''''''''''''''''
+
+This example shows the full sequence of a service call by opening the RPC session, doing the call (begin/invoke/end) and then
+closing the session. In this case the RPC session it set to create individual shared memory for each call.
+
+.. uml:: uml/TSRPCCall.puml
+
+.. note::
+  Although the TS RPC layer messages use ``FFA_MSG_SEND_DIRECT_REQ``/``FFA_MSG_SEND_DIRECT_RESP`` interface and go through the
+  SPMC their destination is not the SPMC but the RPC endpoint. For simplifying the diagram, these calls are showed as direct
+  calls between the TS RPC caller and the TS RPC endpoint.
+
 Status Codes
 ------------
 
-On returning from a request to invoke a service method, two status codes are returned as follows:
+On returning from a request to invoke a service method, two status codes are returned:
 
   - *RPC status* - A generic status code that corresponds to the RPC call transaction.  RPC status codes are standardized across
-    all services.
-  - *Operation status* - a service specific status code.
+    all services. (See: `RPC status code values`_)
+  - *Service status* - a service specific status code. (See: `Service Status Codes`_ )
 
 Separation of status codes by layer allows service specific status codes to be accommodated while keeping RPC status codes
 common.
 
-A client should only check the returned operation status if the returned RPC status value is RPC_CALL_ACCEPTED.  All other RPC
-status values indicate that an error occurred in delivering the RPC request.  An RPC status of RPC_CALL_ACCEPTED does not
-indicate that the service operation was successful.  It merely indicates that the request was delivered, a suitable handler was
+A client should only check the returned service status if the returned RPC status value is `RPC_SUCCESS`.  All other RPC
+status values indicate that an error occurred in delivering the RPC request.  An RPC status of `RPC_SUCCESS` does not
+indicate that the service was successful. It merely indicates that the request was delivered, a suitable handler was
 identified and the request parameters were understood.
 
 Service Access Protocol Definition Conventions
@@ -62,7 +274,7 @@
 
 It is possible that for certain deployments, it will be necessary to customize which parameter encoding scheme is used.  Many
 schemes are possible such as Protocol Buffers, CBOR, JSON, TLV, TPM commands or packed C structures.  To make scheme
-customization straight forward, serilize/deserialize operations should be encapsulated behind a common interface to decouple
+customization straight forward, serialize/deserialize operations should be encapsulated behind a common interface to decouple
 service provider code from any particular serialization scheme.  A section below describes a pattern for achieving this.
 
 Service Namespace
@@ -122,14 +334,6 @@
 
   protocols/service/crypto/protobuf/export_public_key.proto
 
-RPC Status Codes
-````````````````
-
-Generic RPC status code definitions using different definition schemes are defined here::
-
-  protocols/rpc/common/protobuf/status.proto
-  protocols/rpc/common/packed-c/status.h
-
 Service Status Codes
 ````````````````````
 
@@ -182,21 +386,11 @@
   int serialize_for_method(msg_buffer *buf, in args...);
   int deserialize_for_method(const msg_buffer *buf, out args...);
 
-To extend a service provider to support a new serialization encoding, the following steps are required:
-
-  1. Define a new encoding identifier string if a suitable one doesn't exist.  Currently used identifiers are protobuf and
-     packed-c.  The identifier will be used as a directory name so it needs to be filename-friendly.  Some likely candidate
-     identifiers could be cbor and json.
-  2. Add a new RPC encoding ID to *protocols/rpc/common/packed-c/encoding.h*.  This is used by a caller to identify the encoding
-     used for RPC parameters.  This is analogous to the content-type header parameter used in HTTP.
-  3. Under the protocols parent directory, add a new access protocol definition for the service that needs extending.  This will
-     be a representation of existing service access protocols but using a definition notation compatible with the new encoding.
-  4. Add a new serializer implementation under the service provider's serializer directory e.g. for the crypto service -
-     *components/service/crypto/provider/serializer*.
-  5. Add registration of the new serializer to any deployment initialization code where the new encoding is needed.
+Encoding types are represented as dedicated service interfaces in the RPC protocol and as such are identified by a uniq
+service UUID.
 
 --------------
 
-*Copyright (c) 2020-2021, Arm Limited and Contributors. All rights reserved.*
+*Copyright (c) 2020-2023, Arm Limited and Contributors. All rights reserved.*
 
 SPDX-License-Identifier: BSD-3-Clause
diff --git a/docs/developer/uml/TSRPCCall.puml b/docs/developer/uml/TSRPCCall.puml
new file mode 100644
index 0000000..9359d27
--- /dev/null
+++ b/docs/developer/uml/TSRPCCall.puml
@@ -0,0 +1,107 @@
+'-------------------------------------------------------------------------------
+' Copyright (c) 2023, Arm Limited and Contributors. All rights reserved.
+'
+' SPDX-License-Identifier: BSD-3-Clause
+'
+'-------------------------------------------------------------------------------
+
+@startuml TS RPC call sequence
+
+autoactivate on
+
+participant "Service caller" as service_caller
+participant "RPC caller session" as rpc_session
+participant "TS RPC caller" as rpc_caller
+participant "SPMC" as spmc
+participant "TS RPC endpoint" as endpoint
+participant "Service" as service
+
+service_caller -> rpc_session: open(service_uuid)
+
+' Sesssion open
+rpc_session -> rpc_caller: find_and_open_session(service_uuid)
+
+rpc_caller -> spmc: FFA_PARTITION_INFO_GET(ts_rpc_uuid)
+spmc --> rpc_caller: FF-A endpoint_id
+
+rpc_caller -> endpoint: TS_RPC_VERSION_GET
+endpoint --> rpc_caller: TS RPC protocol version
+
+rpc_caller -> endpoint: TS_RPC_SERVICE_INFO_GET(service_uuid)
+endpoint --> rpc_caller: Service interface_id
+
+rpc_caller --> rpc_session: TS RPC status
+
+rpc_session --> service_caller: TS RPC status
+
+' Begin
+service_caller -> rpc_session: begin(request_length, response_max_length)
+
+rpc_session -> rpc_session: allocate_buffer(MAX(request_length, response_max_length))
+rpc_session --> rpc_session: buffer
+
+rpc_session -> rpc_caller: create_shared_memory(endpoint_id, buffer)
+
+rpc_caller -> spmc: FFA_MEM_SHARE(endpoint_id, buffer)
+spmc --> rpc_caller: memory_handle, memory_tag
+
+rpc_caller -> endpoint: TS_RPC_MEM_RETRIEVE(memory_handle, memory_tag)
+
+endpoint -> spmc: FFA_MEM_RETRIEVE(memory_handle, memory_tag)
+spmc --> endpoint: buffer
+
+endpoint --> rpc_caller: TS RPC status
+
+rpc_caller --> rpc_session: TS RPC status, shared_memory
+
+rpc_session --> service_caller: Request buffer
+
+' Serialize
+service_caller -> service_caller: Serialize parameters to request buffer
+service_caller --> service_caller
+
+' Invoke
+service_caller -> rpc_session: invoke(opcode)
+
+rpc_session -> rpc_caller: call(opcode, shared_memory, request_length)
+
+rpc_caller -> endpoint: service_call(interface_id, opcode, memory_handle, request_length)
+
+endpoint -> service: service_call(opcode, request)
+service --> endpoint: service status, response
+
+endpoint --> rpc_caller: TS RPC status, service status, response length
+
+rpc_caller --> rpc_session: TS RPC status, service status, response length
+
+rpc_session --> service_caller: TS RPC status, service status, response
+
+' Deserialize
+service_caller -> service_caller: Deserialize return values from the response buffer
+service_caller --> service_caller
+
+' End
+service_caller -> rpc_session: end()
+
+rpc_session -> rpc_caller: release_shared_memory(shared_memory)
+
+rpc_caller -> endpoint: TS_RPC_MEM_RELINQUISH(memory_handle)
+
+endpoint -> spmc: FFA_MEMORY_RELINQUISH(memory_handle)
+spmc --> endpoint: FFA_SUCCESS
+
+endpoint --> rpc_caller: TS RPC status
+
+rpc_caller -> spmc: FFA_MEM_RECLAIM(memory_handle)
+spmc --> rpc_caller: FFA_SUCCESS
+
+rpc_caller -> rpc_caller: free(buffer)
+rpc_caller --> rpc_caller
+
+rpc_caller --> rpc_session: TS RPC status
+
+rpc_session --> service_caller: TS RPC status
+
+service_caller -> rpc_session: close()
+rpc_session --> service_caller: TS RPC status
+@enduml
diff --git a/environments/opteesp/component.cmake b/environments/opteesp/component.cmake
index 36cbc20..2b54682 100644
--- a/environments/opteesp/component.cmake
+++ b/environments/opteesp/component.cmake
@@ -15,7 +15,7 @@
 # Ensure elf output naming is symbolize.py compatible.
 # If binary UUID is not defined, fall back to using the SP UUID value.
 if (NOT SP_BIN_UUID_CANON)
-	set(SP_BIN_UUID_CANON "${SP_UUID_CANON}")
+	set(SP_BIN_UUID_CANON "${SP_FFA_UUID_CANON}")
 endif()
 ts_add_uuid_to_exe_name(TGT "${TGT}" UUID "${SP_BIN_UUID_CANON}" )
 
@@ -30,9 +30,10 @@
 
 	include(${TS_ROOT}/tools/cmake/common/TargetCompileDefinitions.cmake)
 	set_target_uuids(
-		SP_UUID ${SP_UUID_CANON}
+		SP_UUID ${SP_FFA_UUID_CANON}
 		TGT ${SP_NAME}
 	)
+
 endif()
 
 target_sources(${TGT} PRIVATE
diff --git a/environments/opteesp/sp_pkg.json.in b/environments/opteesp/sp_pkg.json.in
index 9798c66..02ee474 100644
--- a/environments/opteesp/sp_pkg.json.in
+++ b/environments/opteesp/sp_pkg.json.in
@@ -1,6 +1,7 @@
 {
 	"@EXPORT_SP_NAME@": {
-		"image": "../bin/@EXPORT_SP_UUID_CANON@.stripped.elf",
-		"pm": "../manifest/@EXPORT_SP_UUID_CANON@.dts"
+		"uuid": "@EXPORT_SP_BIN_UUID_CANON@",
+		"image": "../bin/@EXPORT_SP_BIN_UUID_CANON@.stripped.elf",
+		"pm": "../manifest/@EXPORT_SP_BIN_UUID_CANON@.dts"
 	}
-}
\ No newline at end of file
+}
diff --git a/environments/sp/component.cmake b/environments/sp/component.cmake
index 3f3b0b4..35532bd 100644
--- a/environments/sp/component.cmake
+++ b/environments/sp/component.cmake
@@ -6,7 +6,7 @@
 #-------------------------------------------------------------------------------
 
 # Check mandatory variables.
-foreach(_var IN ITEMS TGT TRACE_PREFIX SP_HEAP_SIZE SP_STACK_SIZE SP_UUID_CANON)
+foreach(_var IN ITEMS TGT TRACE_PREFIX SP_HEAP_SIZE SP_STACK_SIZE SP_FFA_UUID_CANON)
 	if (NOT DEFINED ${_var})
 		message(FATAL_ERROR "Mandatory parameter '${_var}' missing.")
 	endif()
@@ -15,7 +15,7 @@
 # Ensure elf output naming is symbolize.py compatible.
 # If binary UUID is not defined, fall back to using the SP UUID value.
 if (NOT SP_BIN_UUID_CANON)
-	set(SP_BIN_UUID_CANON "${SP_UUID_CANON}")
+	set(SP_BIN_UUID_CANON "${SP_FFA_UUID_CANON}")
 endif()
 ts_add_uuid_to_exe_name(TGT "${TGT}" UUID "${SP_BIN_UUID_CANON}" )
 
diff --git a/environments/sp/sp_pkg.json.in b/environments/sp/sp_pkg.json.in
index fbc3a59..23e8805 100644
--- a/environments/sp/sp_pkg.json.in
+++ b/environments/sp/sp_pkg.json.in
@@ -1,6 +1,7 @@
 {
 	"@EXPORT_SP_NAME@": {
-		"image": "../bin/@EXPORT_SP_UUID_CANON@.bin",
-		"pm": "../manifest/@EXPORT_SP_UUID_CANON@.dts"
+		"uuid": "@EXPORT_SP_BIN_UUID_CANON@",
+		"image": "../bin/@EXPORT_SP_BIN_UUID_CANON@.bin",
+		"pm": "../manifest/@EXPORT_SP_BIN_UUID_CANON@.dts"
 	}
 }
\ No newline at end of file
diff --git a/platform/providers/arm/corstone1000/platform.cmake b/platform/providers/arm/corstone1000/platform.cmake
index dbdf109..a3c4209 100644
--- a/platform/providers/arm/corstone1000/platform.cmake
+++ b/platform/providers/arm/corstone1000/platform.cmake
@@ -10,7 +10,6 @@
 include(${TS_ROOT}/platform/drivers/arm/mhu_driver/component.cmake)
 
 target_compile_definitions(${TGT} PRIVATE
-	SMM_GATEWAY_NV_STORE_SN="sn:ffa:46bb39d1-b4d9-45b5-88ff-040027dab249:1"
 	SMM_VARIABLE_INDEX_STORAGE_UID=0x787
 	SMM_GATEWAY_MAX_UEFI_VARIABLES=100
 )
diff --git a/protocols/service/smm_variable/smm_variable_proto.h b/protocols/service/smm_variable/smm_variable_proto.h
index a47be10..a42ff06 100644
--- a/protocols/service/smm_variable/smm_variable_proto.h
+++ b/protocols/service/smm_variable/smm_variable_proto.h
@@ -14,4 +14,6 @@
 #define SMM_VARIABLE_GUID \
 	{0xed32d533, 0x99e6, 0x4209, { 0x9c, 0xc0, 0x2d, 0x72, 0xcd, 0xd9, 0x98, 0xa7 }}
 
+#define SMM_VARIABLE_CANONICAL_GUID	"ed32d533-99e6-4209-9cc0-2d72cdd998a7"
+
 #endif /* TS_SMM_VARIABLE_PROTO_H */
diff --git a/tools/cmake/common/ExportSp.cmake b/tools/cmake/common/ExportSp.cmake
index 1c6d9db..78701b9 100644
--- a/tools/cmake/common/ExportSp.cmake
+++ b/tools/cmake/common/ExportSp.cmake
@@ -13,7 +13,7 @@
 	.. code:: cmake
 
 		export_sp(
-			SP_UUID_CANON <uuid_str_canon>
+			SP_FFA_UUID_CANON <uuid_str_canon>
 			SP_NAME <name> MK_IN <.mk path>
 			DTS_IN <DTS path>
 			DTS_MEM_REGIONS <Memory region manifest path>
@@ -22,12 +22,12 @@
 
 	INPUTS:
 
-	``SP_UUID_CANON``
-	The FF_A UUID of the SP as a canonical string.
+	``SP_FFA_UUID_CANON``
+	The FF-A UUID of the SP as a canonical string.
 
 	``SP_BIN_UUID_CANON``
 	The UUID of the SP binary a canonical string. When not set use the
-	SP_UUID_CANON as the SP_BIN_UUID_CANON.
+	SP_FFA_UUID_CANON as the SP_BIN_UUID_CANON.
 
 	``SP_NAME``
 	The name of the SP.
@@ -47,17 +47,17 @@
 #]===]
 function (export_sp)
 	set(options)
-	set(oneValueArgs SP_UUID_CANON SP_BIN_UUID_CANON SP_UUID_LE SP_NAME MK_IN DTS_IN DTS_MEM_REGIONS JSON_IN)
+	set(oneValueArgs SP_FFA_UUID_CANON SP_BIN_UUID_CANON SP_NAME MK_IN DTS_IN DTS_MEM_REGIONS JSON_IN)
 	set(multiValueArgs)
 	cmake_parse_arguments(EXPORT "${options}" "${oneValueArgs}"
 						"${multiValueArgs}" ${ARGN} )
 
-	if(NOT DEFINED EXPORT_SP_UUID_CANON)
-		message(FATAL_ERROR "export_sp: mandatory parameter SP_UUID_CANON not defined!")
+	if(NOT DEFINED EXPORT_SP_FFA_UUID_CANON)
+		message(FATAL_ERROR "export_sp: mandatory parameter SP_FFA_UUID_CANON not defined!")
 	endif()
 	if(NOT DEFINED EXPORT_SP_BIN_UUID_CANON)
 		# We use the same UUID for the binary and FF-A if the UUID of the SP binary is not set
-		set(EXPORT_SP_BIN_UUID_CANON ${EXPORT_SP_UUID_CANON})
+		set(EXPORT_SP_BIN_UUID_CANON ${EXPORT_SP_FFA_UUID_CANON})
 	endif()
 	if(NOT DEFINED EXPORT_SP_NAME)
 		message(FATAL_ERROR "export_sp: mandatory parameter SP_NAME not defined!")
@@ -73,7 +73,7 @@
 
 	# In the SP manifest DT the UUID format is four uint32 numbers (little-endian)
 	# Create a litte endian 4 digit octests representation.
-	uuid_canon_to_le_words(UUID ${EXPORT_SP_UUID_CANON} RES _le_words)
+	uuid_canon_to_le_words(UUID ${EXPORT_SP_FFA_UUID_CANON} RES _le_words)
 	list(JOIN _le_words " 0x" _uuid_le)
 	set(SP_UUID_LE " 0x${_uuid_le}" PARENT_SCOPE)
 	set(EXPORT_SP_UUID_DT " 0x${_uuid_le}")