1 /*
2  * Copyright (c) 2020-2021, Arm Limited and Contributors. All rights reserved.
3  *
4  * SPDX-License-Identifier: BSD-3-Clause
5  */
6 
7 #include "standalone_service_context.h"
8 #include <cassert>
9 
10 /* Concrete C service_context methods */
11 static struct rpc_caller_session *standalone_service_context_open(void *context);
12 static void standalone_service_context_close(void *context, rpc_caller_session *session_handle);
13 static void standalone_service_context_relinquish(void *context);
14 
15 
standalone_service_context(const char * sn)16 standalone_service_context::standalone_service_context(const char *sn) :
17 	m_sn(sn),
18 	m_ref_count(0),
19 	m_rpc_buffer_size_override(0),
20 	m_service_context(),
21 	m_rpc_interface(NULL)
22 {
23 	m_service_context.context = this;
24 	m_service_context.open = standalone_service_context_open;
25 	m_service_context.close = standalone_service_context_close;
26 	m_service_context.relinquish = standalone_service_context_relinquish;
27 }
28 
standalone_service_context(const char * sn,size_t rpc_buffer_size_override)29 standalone_service_context::standalone_service_context(
30 	const char *sn,
31 	size_t rpc_buffer_size_override) :
32 	m_sn(sn),
33 	m_ref_count(0),
34 	m_rpc_buffer_size_override(rpc_buffer_size_override),
35 	m_service_context(),
36 	m_rpc_interface(NULL)
37 {
38 	m_service_context.context = this;
39 	m_service_context.open = standalone_service_context_open;
40 	m_service_context.close = standalone_service_context_close;
41 	m_service_context.relinquish = standalone_service_context_relinquish;
42 }
43 
~standalone_service_context()44 standalone_service_context::~standalone_service_context()
45 {
46 
47 }
48 
init()49 void standalone_service_context::init()
50 {
51 	assert(m_ref_count >= 0);
52 
53 	if (!m_ref_count) do_init();
54 	++m_ref_count;
55 }
56 
deinit()57 void standalone_service_context::deinit()
58 {
59 	assert(m_ref_count > 0);
60 
61 	--m_ref_count;
62 	if (!m_ref_count) do_deinit();
63 }
64 
open()65 struct rpc_caller_session *standalone_service_context::open()
66 {
67 	rpc_status_t status = RPC_ERROR_INTERNAL;
68 	struct rpc_caller_interface *caller = NULL;
69 	struct rpc_caller_session *session = NULL;
70 
71 	caller = (struct rpc_caller_interface *)calloc(1, sizeof(struct rpc_caller_interface));
72 	if (!caller)
73 		return NULL;
74 
75 	session = (struct rpc_caller_session *)calloc(1, sizeof(struct rpc_caller_session));
76 	if (!session) {
77 		free(caller);
78 		return NULL;
79 	}
80 
81 	status = direct_caller_init(caller, m_rpc_interface);
82 	if (status != RPC_SUCCESS) {
83 		free(caller);
84 		free(session);
85 		return NULL;
86 	}
87 
88 	status = rpc_caller_session_open(session, caller, &m_rpc_interface->uuid, 0, 0x8000);
89 	if (status != RPC_SUCCESS) {
90 		direct_caller_deinit(caller);
91 		free(caller);
92 		free(session);
93 		return NULL;
94 	}
95 
96 	return session;
97 }
98 
close(rpc_caller_session * session)99 void standalone_service_context::close(rpc_caller_session *session)
100 {
101 	rpc_caller_session_close(session);
102 	direct_caller_deinit(session->caller);
103 	free(session->caller);
104 	free(session);
105 }
106 
get_service_name() const107 const std::string &standalone_service_context::get_service_name() const
108 {
109 	return m_sn;
110 }
111 
get_service_context()112 struct service_context *standalone_service_context::get_service_context()
113 {
114 	return &m_service_context;
115 }
116 
set_rpc_interface(rpc_service_interface * iface)117 void standalone_service_context::set_rpc_interface(rpc_service_interface *iface)
118 {
119 	m_rpc_interface = iface;
120 }
121 
standalone_service_context_open(void * context)122 static struct rpc_caller_session *standalone_service_context_open(void *context)
123 {
124 	standalone_service_context *this_context = reinterpret_cast<standalone_service_context*>(context);
125 
126 	if (!this_context)
127 		return NULL;
128 
129 	return this_context->open();
130 }
131 
standalone_service_context_close(void * context,struct rpc_caller_session * session_handle)132 static void standalone_service_context_close(void *context, struct rpc_caller_session *session_handle)
133 {
134 	standalone_service_context *this_context = reinterpret_cast<standalone_service_context*>(context);
135 
136 	if (this_context) {
137 		this_context->close(session_handle);
138 	}
139 }
140 
standalone_service_context_relinquish(void * context)141 static void standalone_service_context_relinquish(void *context)
142 {
143 	standalone_service_context *this_context = reinterpret_cast<standalone_service_context*>(context);
144 
145 	if (this_context) {
146 		this_context->deinit();
147 	}
148 }
149