1 /*
2  * Copyright (c) 2020-2022, Arm Limited and Contributors. All rights reserved.
3  *
4  * SPDX-License-Identifier: BSD-3-Clause
5  */
6 
7 #include "linuxffa_service_context.h"
8 #include "components/rpc/ts_rpc/caller/linux/ts_rpc_caller_linux.h"
9 #include <stdlib.h>
10 #include <string.h>
11 
12 struct linux_ts_service_context
13 {
14     struct service_context service_context;
15     struct rpc_caller_interface caller;
16     struct rpc_uuid service_uuid;
17 };
18 
19 /* Concrete service_context methods */
20 static struct rpc_caller_session *linux_ts_service_context_open(void *context);
21 static void linux_ts_service_context_close(void *context, struct rpc_caller_session *session);
22 static void linux_ts_service_context_relinquish(void *context);
23 
24 
linux_ts_service_context_create(const struct rpc_uuid * service_uuid)25 struct linux_ts_service_context *linux_ts_service_context_create(const struct rpc_uuid *service_uuid)
26 
27 {
28 	struct linux_ts_service_context *new_context = NULL;
29 	rpc_status_t rpc_status = RPC_ERROR_INTERNAL;
30 
31 	if (!service_uuid)
32 		return NULL;
33 
34 	new_context = (struct linux_ts_service_context *)
35 		calloc(1, sizeof(struct linux_ts_service_context));
36 	if (!new_context)
37 		return NULL;
38 
39 	rpc_status = ts_rpc_caller_linux_init(&new_context->caller);
40 	if (rpc_status != RPC_SUCCESS) {
41 		free(new_context);
42 		return NULL;
43 	}
44 
45 	memcpy(&new_context->service_uuid, service_uuid, sizeof(new_context->service_uuid));
46 
47 	new_context->service_context.context = new_context;
48 	new_context->service_context.open = linux_ts_service_context_open;
49 	new_context->service_context.close = linux_ts_service_context_close;
50 	new_context->service_context.relinquish = linux_ts_service_context_relinquish;
51 
52 	return new_context;
53 }
54 
linux_ts_service_context_open(void * context)55 static struct rpc_caller_session *linux_ts_service_context_open(void *context)
56 {
57 	struct linux_ts_service_context *this_context = (struct linux_ts_service_context *)context;
58 	struct rpc_caller_session *session = NULL;
59 	rpc_status_t rpc_status = RPC_ERROR_INTERNAL;
60 
61 	if (!context)
62 		return NULL;
63 
64 	session = (struct rpc_caller_session *)calloc(1, sizeof(struct rpc_caller_session));
65 	if (!session)
66 		return NULL;
67 
68 	rpc_status = rpc_caller_session_find_and_open(session, &this_context->caller,
69 						      &this_context->service_uuid, 8192);
70 	if (rpc_status != RPC_SUCCESS) {
71 		free(session);
72 		return NULL;
73 	}
74 
75 	return session;
76 }
77 
linux_ts_service_context_close(void * context,struct rpc_caller_session * session)78 static void linux_ts_service_context_close(void *context, struct rpc_caller_session *session)
79 {
80 	(void)context;
81 
82 	if (!session)
83 		return;
84 
85 	rpc_caller_session_close(session);
86 	free(session);
87 }
88 
linux_ts_service_context_relinquish(void * context)89 static void linux_ts_service_context_relinquish(void *context)
90 {
91 	struct linux_ts_service_context *this_context = (struct linux_ts_service_context *)context;
92 
93 	if (!context)
94 		return;
95 
96 	ts_rpc_caller_linux_deinit(&this_context->caller);
97 	free(context);
98 }