Add service discovery provider
Adds a partial implementation of the discovery provider to
enable clients to discover information about a service instance.
An instance of the discovery provider will be integrated into
each service provider to implement common operations for
information discovery. This is initially needed to discover
the maximum request length to support multi-step crypto
operations.
Signed-off-by: Julian Hall <julian.hall@arm.com>
Change-Id: Ib068a02ba9e77f8b893e1da9f1e36edb48ced182
diff --git a/components/service/crypto/provider/crypto_provider.c b/components/service/crypto/provider/crypto_provider.c
index 394f493..89fc86d 100644
--- a/components/service/crypto/provider/crypto_provider.c
+++ b/components/service/crypto/provider/crypto_provider.c
@@ -11,7 +11,6 @@
#include <psa/crypto.h>
/* Service request handlers */
-static rpc_status_t nop_handler(void *context, struct call_req* req);
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);
@@ -28,7 +27,6 @@
/* Handler mapping table for service */
static const struct service_handler handler_table[] = {
- {TS_CRYPTO_OPCODE_NOP, nop_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},
@@ -85,18 +83,6 @@
return serializer;
}
-static rpc_status_t nop_handler(void *context, struct call_req* req)
-{
- /* Responds to a request by returning success */
- rpc_status_t rpc_status = TS_RPC_CALL_ACCEPTED;
- psa_status_t psa_status = PSA_SUCCESS;
-
- (void)context;
- call_req_set_opstatus(req, psa_status);
-
- return rpc_status;
-}
-
static rpc_status_t generate_key_handler(void *context, struct call_req* req)
{
rpc_status_t rpc_status = TS_RPC_ERROR_SERIALIZATION_NOT_SUPPORTED;
diff --git a/components/service/discovery/provider/component.cmake b/components/service/discovery/provider/component.cmake
new file mode 100644
index 0000000..85dfa85
--- /dev/null
+++ b/components/service/discovery/provider/component.cmake
@@ -0,0 +1,13 @@
+#-------------------------------------------------------------------------------
+# 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
new file mode 100644
index 0000000..33ef5c9
--- /dev/null
+++ b/components/service/discovery/provider/discovery_info.h
@@ -0,0 +1,50 @@
+/*
+ * 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 <stdint.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * Information about the service deployment.
+ */
+struct discovery_deployment_info
+{
+ uint16_t interface_id;
+ uint16_t instance;
+ uint32_t max_req_size;
+};
+
+/**
+ * Information about service identity
+ */
+struct discovery_identity_info
+{
+ const char *name_authority;
+ const char *service_name;
+};
+
+/**
+ * Aggregate of all discovery info
+ */
+struct discovery_info
+{
+ struct discovery_deployment_info deployment;
+ struct discovery_identity_info identity;
+
+ 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
new file mode 100644
index 0000000..d32e8f5
--- /dev/null
+++ b/components/service/discovery/provider/discovery_provider.c
@@ -0,0 +1,107 @@
+/*
+ * 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);
+
+/* 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}
+};
+
+
+struct rpc_interface *discovery_provider_init(
+ struct discovery_provider *context,
+ const struct discovery_deployment_info *deployment_info,
+ const struct discovery_identity_info *identity_info)
+{
+ 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));
+
+ context->info.deployment = *deployment_info;
+ context->info.identity = *identity_info;
+
+ context->info.supported_encodings = 0;
+
+ return service_provider_get_rpc_interface(&context->base_provider);
+}
+
+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);
+}
+
+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) {
+
+ struct call_param_buf *resp_buf = call_req_get_resp_buf(req);
+
+ rpc_status = serializer->serialize_get_service_info_resp(resp_buf, &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;
+ (void)req;
+ 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;
+ (void)req;
+ call_req_set_opstatus(req, PSA_ERROR_NOT_SUPPORTED);
+ return TS_RPC_CALL_ACCEPTED;
+}
diff --git a/components/service/discovery/provider/discovery_provider.h b/components/service/discovery/provider/discovery_provider.h
new file mode 100644
index 0000000..f2b3ccf
--- /dev/null
+++ b/components/service/discovery/provider/discovery_provider.h
@@ -0,0 +1,68 @@
+/*
+ * 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 <rpc/common/endpoint/rpc_interface.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.
+ */
+struct rpc_interface *discovery_provider_init(
+ struct discovery_provider *context,
+ const struct discovery_deployment_info *deployment_info,
+ const struct discovery_identity_info *identity_info);
+
+/**
+ * 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);
+
+
+#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
new file mode 100644
index 0000000..643bab1
--- /dev/null
+++ b/components/service/discovery/provider/serializer/discovery_provider_serializer.h
@@ -0,0 +1,26 @@
+/*
+ * 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 <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,
+ 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
new file mode 100644
index 0000000..319f062
--- /dev/null
+++ b/components/service/discovery/provider/serializer/packed-c/component.cmake
@@ -0,0 +1,13 @@
+#-------------------------------------------------------------------------------
+# 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
new file mode 100644
index 0000000..69362f9
--- /dev/null
+++ b/components/service/discovery/provider/serializer/packed-c/packedc_discovery_provider_serializer.c
@@ -0,0 +1,75 @@
+/*
+ * Copyright (c) 2021, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+#include <string.h>
+#include <stdlib.h>
+#include <common/tlv/tlv.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,
+ 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_req_size = info->deployment.max_req_size;
+ resp_msg.supported_encodings = info->supported_encodings;
+
+ if (fixed_len <= resp_buf->size) {
+
+ struct tlv_record out_record;
+ struct tlv_iterator resp_iter;
+ int encoded_tlv_count = 0;
+
+ memcpy(resp_buf->data, &resp_msg, fixed_len);
+ resp_buf->data_len = fixed_len;
+
+ tlv_iterator_begin(&resp_iter,
+ (uint8_t*)resp_buf->data + fixed_len,
+ resp_buf->size - fixed_len);
+
+ out_record.tag = TS_DISOVERY_GET_SERVICE_INFO_OUT_TAG_NAME_AUTHORITY;
+ out_record.length = strlen(info->identity.name_authority) + 1;
+ out_record.value = info->identity.name_authority;
+
+ if (tlv_encode(&resp_iter, &out_record)) {
+
+ resp_buf->data_len += tlv_required_space(out_record.length);
+ ++encoded_tlv_count;
+ }
+
+ out_record.tag = TS_DISOVERY_GET_SERVICE_INFO_OUT_TAG_SERVICE_NAME;
+ out_record.length = strlen(info->identity.service_name) + 1;
+ out_record.value = info->identity.service_name;
+
+ if (tlv_encode(&resp_iter, &out_record)) {
+
+ resp_buf->data_len += 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;
+ }
+
+ 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
new file mode 100644
index 0000000..8bfd68a
--- /dev/null
+++ b/components/service/discovery/provider/serializer/packed-c/packedc_discovery_provider_serializer.h
@@ -0,0 +1,26 @@
+/*
+ * 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 */