Add service locator component
Change-Id: I58ad588deff3c0904b3ba8b9162b20440e9ff7d3
Signed-off-by: Julian Hall <julian.hall@arm.com>
diff --git a/components/service/locator/standalone/component.cmake b/components/service/locator/standalone/component.cmake
new file mode 100644
index 0000000..cb75c82
--- /dev/null
+++ b/components/service/locator/standalone/component.cmake
@@ -0,0 +1,17 @@
+#-------------------------------------------------------------------------------
+# 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}/standalone_env.cpp"
+ "${CMAKE_CURRENT_LIST_DIR}/standalone_service_context.cpp"
+ "${CMAKE_CURRENT_LIST_DIR}/standalone_service_registry.cpp"
+ "${CMAKE_CURRENT_LIST_DIR}/standalone_location_strategy.cpp"
+ )
+
diff --git a/components/service/locator/standalone/services/crypto/component.cmake b/components/service/locator/standalone/services/crypto/component.cmake
new file mode 100644
index 0000000..0e5529b
--- /dev/null
+++ b/components/service/locator/standalone/services/crypto/component.cmake
@@ -0,0 +1,14 @@
+#-------------------------------------------------------------------------------
+# 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}/crypto_service_context.cpp"
+ )
+
diff --git a/components/service/locator/standalone/services/crypto/crypto_service_context.cpp b/components/service/locator/standalone/services/crypto/crypto_service_context.cpp
new file mode 100644
index 0000000..e3bc2e8
--- /dev/null
+++ b/components/service/locator/standalone/services/crypto/crypto_service_context.cpp
@@ -0,0 +1,36 @@
+/*
+ * Copyright (c) 2020, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include "crypto_service_context.h"
+
+crypto_service_context::crypto_service_context(const char *sn) :
+ standalone_service_context(sn),
+ m_crypto_provider(),
+ m_storage_provider(),
+ m_storage_caller()
+{
+
+}
+
+crypto_service_context::~crypto_service_context()
+{
+
+}
+
+void crypto_service_context::do_init()
+{
+ struct call_ep *storage_ep = sfs_provider_init(&m_storage_provider);
+ struct rpc_caller *storage_caller = direct_caller_init_default(&m_storage_caller, storage_ep);
+ struct call_ep *crypto_ep = mbed_crypto_provider_init(&m_crypto_provider, storage_caller);
+
+ standalone_service_context::set_call_ep(crypto_ep);
+}
+
+void crypto_service_context::do_deinit()
+{
+ mbed_crypto_provider_deinit(&m_crypto_provider);
+ direct_caller_deinit(&m_storage_caller);
+}
diff --git a/components/service/locator/standalone/services/crypto/crypto_service_context.h b/components/service/locator/standalone/services/crypto/crypto_service_context.h
new file mode 100644
index 0000000..6e79163
--- /dev/null
+++ b/components/service/locator/standalone/services/crypto/crypto_service_context.h
@@ -0,0 +1,31 @@
+/*
+ * Copyright (c) 2020, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef STANDALONE_CRYPTO_SERVICE_CONTEXT_H
+#define STANDALONE_CRYPTO_SERVICE_CONTEXT_H
+
+#include <service/locator/standalone/standalone_service_context.h>
+#include <rpc/direct/direct_caller.h>
+#include <service/crypto/provider/mbedcrypto/crypto_provider.h>
+#include <service/secure_storage/provider/secure_flash_store/sfs_provider.h>
+
+class crypto_service_context : public standalone_service_context
+{
+public:
+ crypto_service_context(const char *sn);
+ virtual ~crypto_service_context();
+
+private:
+
+ void do_init();
+ void do_deinit();
+
+ struct mbed_crypto_provider m_crypto_provider;
+ struct sfs_provider m_storage_provider;
+ struct direct_caller m_storage_caller;
+};
+
+#endif /* STANDALONE_CRYPTO_SERVICE_CONTEXT_H */
diff --git a/components/service/locator/standalone/standalone_env.cpp b/components/service/locator/standalone/standalone_env.cpp
new file mode 100644
index 0000000..80d1777
--- /dev/null
+++ b/components/service/locator/standalone/standalone_env.cpp
@@ -0,0 +1,17 @@
+/*
+ * Copyright (c) 2020, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <service_locator.h>
+#include <service/locator/standalone/services/crypto/crypto_service_context.h>
+#include "standalone_location_strategy.h"
+#include "standalone_service_registry.h"
+
+void service_locator_envinit(void)
+{
+ static crypto_service_context crypto_context("sn:trustedfirmware.org:crypto:0");
+ standalone_service_registry::instance()->regsiter_service_instance(&crypto_context);
+ service_locator_register_strategy(standalone_location_strategy());
+}
\ No newline at end of file
diff --git a/components/service/locator/standalone/standalone_location_strategy.cpp b/components/service/locator/standalone/standalone_location_strategy.cpp
new file mode 100644
index 0000000..57e370c
--- /dev/null
+++ b/components/service/locator/standalone/standalone_location_strategy.cpp
@@ -0,0 +1,29 @@
+/*
+ * Copyright (c) 2020, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include "standalone_location_strategy.h"
+#include "standalone_service_registry.h"
+#include "standalone_service_context.h"
+
+static struct service_context *query(const char *sn, int *status)
+{
+ struct service_context *result = NULL;
+ standalone_service_registry *registry = standalone_service_registry::instance();
+ standalone_service_context *query_result = registry->query(sn, status);
+
+ if (query_result) {
+
+ result = query_result->get_service_context();
+ }
+
+ return result;
+}
+
+const struct service_location_strategy *standalone_location_strategy(void)
+{
+ static const struct service_location_strategy strategy = { query };
+ return &strategy;
+}
diff --git a/components/service/locator/standalone/standalone_location_strategy.h b/components/service/locator/standalone/standalone_location_strategy.h
new file mode 100644
index 0000000..7ea57ea
--- /dev/null
+++ b/components/service/locator/standalone/standalone_location_strategy.h
@@ -0,0 +1,27 @@
+/*
+ * Copyright (c) 2020, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef STANDALONE_LOCATION_STRATEGY_H
+#define STANDALONE_LOCATION_STRATEGY_H
+
+#include <service_locator.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+ * Returns a service_location_strategy for locating a service instance
+ * from a bundle of standalone service instances that are part of the
+ * client execution context.
+ */
+const struct service_location_strategy *standalone_location_strategy(void);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* STANDALONE_LOCATION_STRATEGY_H */
\ No newline at end of file
diff --git a/components/service/locator/standalone/standalone_service_context.cpp b/components/service/locator/standalone/standalone_service_context.cpp
new file mode 100644
index 0000000..5e53ebe
--- /dev/null
+++ b/components/service/locator/standalone/standalone_service_context.cpp
@@ -0,0 +1,117 @@
+/*
+ * Copyright (c) 2020, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include "standalone_service_context.h"
+#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 void standalone_service_context_relinquish(void *context);
+
+
+standalone_service_context::standalone_service_context(const char *sn) :
+ m_sn(sn),
+ m_ref_count(0),
+ m_service_context(),
+ m_call_ep(NULL)
+{
+ m_service_context.context = this;
+ m_service_context.open = standalone_service_context_open;
+ m_service_context.close = standalone_service_context_close;
+ m_service_context.relinquish = standalone_service_context_relinquish;
+}
+
+standalone_service_context::~standalone_service_context()
+{
+
+}
+
+void standalone_service_context::init()
+{
+ assert(m_ref_count >= 0);
+
+ if (!m_ref_count) do_init();
+ ++m_ref_count;
+}
+
+void standalone_service_context::deinit()
+{
+ assert(m_ref_count > 0);
+
+ --m_ref_count;
+ if (!m_ref_count) do_deinit();
+}
+
+rpc_session_handle standalone_service_context::open(struct rpc_caller **caller)
+{
+ struct rpc_session *session = new rpc_session(m_call_ep);
+ *caller = session->m_rpc_caller;
+ return static_cast<rpc_session_handle>(session);
+}
+
+void standalone_service_context::close(rpc_session_handle session_handle)
+{
+ struct rpc_session *session = reinterpret_cast<struct rpc_session*>(session_handle);
+ delete session;
+}
+
+const std::string &standalone_service_context::get_service_name() const
+{
+ return m_sn;
+}
+
+struct service_context *standalone_service_context::get_service_context()
+{
+ return &m_service_context;
+}
+
+void standalone_service_context::set_call_ep(call_ep *ep)
+{
+ m_call_ep = ep;
+}
+
+standalone_service_context::rpc_session::rpc_session(struct call_ep *call_ep) :
+ m_direct_caller(),
+ m_rpc_caller()
+{
+ m_rpc_caller = direct_caller_init_default(&m_direct_caller, call_ep);
+}
+
+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);
+ }
+
+ return handle;
+}
+
+static void standalone_service_context_close(void *context, rpc_session_handle session_handle)
+{
+ standalone_service_context *this_context = reinterpret_cast<standalone_service_context*>(context);
+
+ if (this_context) {
+ this_context->close(session_handle);
+ }
+}
+
+static void standalone_service_context_relinquish(void *context)
+{
+ standalone_service_context *this_context = reinterpret_cast<standalone_service_context*>(context);
+
+ if (this_context) {
+ this_context->deinit();
+ }
+}
diff --git a/components/service/locator/standalone/standalone_service_context.h b/components/service/locator/standalone/standalone_service_context.h
new file mode 100644
index 0000000..d8ebb1f
--- /dev/null
+++ b/components/service/locator/standalone/standalone_service_context.h
@@ -0,0 +1,53 @@
+/*
+ * Copyright (c) 2020, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef STANDALONE_SERVICE_CONTEXT_H
+#define STANDALONE_SERVICE_CONTEXT_H
+
+#include <service_locator.h>
+#include <rpc/common/endpoint/call_ep.h>
+#include <rpc/direct/direct_caller.h>
+#include <string>
+
+class standalone_service_context
+{
+public:
+ standalone_service_context(const char *sn);
+ virtual ~standalone_service_context();
+
+ void init();
+ void deinit();
+
+ rpc_session_handle open(struct rpc_caller **caller);
+ void close(rpc_session_handle session_handle);
+
+ const std::string &get_service_name() const;
+ struct service_context *get_service_context();
+
+protected:
+ void set_call_ep(call_ep *ep);
+
+ virtual void do_init() {}
+ virtual void do_deinit() {}
+
+private:
+
+ struct rpc_session
+ {
+ rpc_session(struct call_ep *call_ep);
+ ~rpc_session();
+
+ struct direct_caller m_direct_caller;
+ struct rpc_caller *m_rpc_caller;
+ };
+
+ std::string m_sn;
+ int m_ref_count;
+ struct service_context m_service_context;
+ struct call_ep *m_call_ep;
+};
+
+#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
new file mode 100644
index 0000000..5625bc0
--- /dev/null
+++ b/components/service/locator/standalone/standalone_service_registry.cpp
@@ -0,0 +1,83 @@
+/*
+ * Copyright (c) 2020, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include "standalone_service_registry.h"
+
+standalone_service_registry::standalone_service_registry() :
+ m_service_instances()
+{
+
+}
+
+standalone_service_registry::~standalone_service_registry()
+{
+
+}
+
+standalone_service_registry *standalone_service_registry::instance()
+{
+ static standalone_service_registry singleton_instance;
+ return &singleton_instance;
+}
+
+void standalone_service_registry::regsiter_service_instance(standalone_service_context *service_context)
+{
+ size_t index;
+
+ if (find_context_index(service_context->get_service_name().c_str(), &index)) {
+
+ m_service_instances[index] = service_context;
+ }
+ else {
+
+ m_service_instances.push_back(service_context);
+ }
+}
+
+standalone_service_context *standalone_service_registry::deregsiter_service_instance(const char *sn)
+{
+ size_t index;
+ standalone_service_context *context = NULL;
+
+ if (find_context_index(sn, &index)) {
+
+ context = m_service_instances[index];
+ m_service_instances.erase(m_service_instances.begin() + index);
+ }
+
+ return context;
+}
+
+standalone_service_context *standalone_service_registry::query(const char *sn, int *status)
+{
+ size_t index;
+ standalone_service_context *context = NULL;
+ (void)status;
+
+ if (find_context_index(sn, &index)) {
+
+ context = m_service_instances[index];
+ context->init();
+ }
+
+ return context;
+}
+
+bool standalone_service_registry::find_context_index(const char *sn, size_t *index) const
+{
+ bool found = false;
+
+ for (size_t i = 0; !found && i < m_service_instances.size(); i++) {
+
+ if (m_service_instances[i]->get_service_name().compare(sn) == 0) {
+
+ *index = i;
+ found = true;
+ }
+ }
+
+ return found;
+}
\ No newline at end of file
diff --git a/components/service/locator/standalone/standalone_service_registry.h b/components/service/locator/standalone/standalone_service_registry.h
new file mode 100644
index 0000000..7a76aeb
--- /dev/null
+++ b/components/service/locator/standalone/standalone_service_registry.h
@@ -0,0 +1,40 @@
+/*
+ * Copyright (c) 2020, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef STANDALONE_SERVICE_REGISTRY_H
+#define STANDALONE_SERVICE_REGISTRY_H
+
+#include "standalone_service_context.h"
+#include <vector>
+
+/*
+ * The standalone_service_registry supports a set of standalone
+ * service instances that are deployed as part of a standalone exectable
+ * or library. A standalone deployment of service providers should only
+ * be used for test and development. Because service provider instances
+ * are running within the same execution context as the client, a
+ * standalone deployment offers no isolation from the client.
+ */
+class standalone_service_registry
+{
+public:
+ standalone_service_registry();
+ virtual ~standalone_service_registry();
+
+ static standalone_service_registry *instance();
+
+ 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);
+
+private:
+ bool find_context_index(const char *sn, size_t *index) const;
+
+ std::vector<standalone_service_context*> m_service_instances;
+};
+
+#endif /* STANDALONE_SERVICE_REGISTRY_H */
\ No newline at end of file