2 * @copyright Copyright (c) 2016-2020 TOYOTA MOTOR CORPORATION.
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
8 * http://www.apache.org/licenses/LICENSE-2.0
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
19 * @brief RPC Library Internal Implementation--Event Handling
25 #include <native_service/cl_monitor.h>
27 #include <other_service/rpc.h>
28 #include "rpc_internal.h"
30 /** @ingroup RPClib_in
32 RUNS_IN_READING_THREAD
34 RpcQueueAPIRequestBefore(RpcIdInfo *id, UINT32 size, char **buff) {
35 RPC_THREAD_MUTEX_LOCK(id->thread_info);
37 int n = RPC_apicall_num_queue(id); // LCOV_EXCL_BR_LINE 15: marco defined in rpc_thread.h
39 if (n >= RPC_MAX_APICALL_QUEUE) {
40 RPC_THREAD_MUTEX_UNLOCK(id->thread_info);
41 RPC_LOG_STATE("Returned BUSY.");
44 *buff = rpc_malloc(size);/* malloc */
45 if (*buff == NULL) { // LCOV_EXCL_BR_LINE 5: fail safe for libc function malloc
46 RPC_THREAD_MUTEX_UNLOCK(id->thread_info); // LCOV_EXCL_START 5: fail safe for libc function malloc
47 AGL_ASSERT_NOT_TESTED(); // LCOV_EXCL_LINE 200: test assert
48 RPC_LOG_STATE("queue API request: No Memory");
54 /** @ingroup RPClib_in
56 RUNS_IN_READING_THREAD
58 RpcQueueAPIRequestAfter(RpcIdInfo *id, RPC_ID client,
59 const char *mesg, UINT32 size, char *args) {
60 int n = RPC_apicall_num_queue(id); // LCOV_EXCL_BR_LINE 15: marco defined in rpc_thread.h
63 api_num = (UINT16)strtol(mesg, NULL, 10);
64 memcpy(args, mesg + RPC_APICALL_FORMAT_ARGS_START, size);
65 RPC_ID_COPY(RPC_apicall_queue_client(id, n), client);
66 RPC_apicall_queue_api_num(id, n) = api_num;
67 RPC_apicall_queue_args(id, n) = args;
68 RPC_apicall_queue_args_size(id, n) = size;
69 RPC_apicall_num_queue_inc(id);
72 CL_MonitorSetEntry(CL_MONITOR_TYPE_RPC,
75 (uint32_t)(RPC_apicall_api_timeout_sec(id)),
78 RPC_THREAD_MUTEX_UNLOCK(id->thread_info);
82 /** @ingroup RPClib_in
84 RUNS_IN_CALLERS_THREAD
86 RpcFreeAPIArgsString(char *args_string) {
87 if (args_string != NULL) { // LCOV_EXCL_BR_LINE 5: free the memory, malloced in RpcQueueAPIRequestBefore(...)
88 rpc_free(args_string);/* free */
92 /** @ingroup RPClib_in
94 RUNS_IN_CALLERS_THREAD
96 RpcGetAPIRequest(RpcIdInfo *id, RPC_ID_p client,
97 char **args_string, unsigned int *args_size) {
100 RPC_THREAD_MUTEX_LOCK(id->thread_info);
102 UINT32 n = RPC_apicall_num_queue(id); // LCOV_EXCL_BR_LINE 15: marco defined in rpc_thread.h
104 RPC_ID_COPY(*client, RPC_apicall_queue_client(id, 0));
105 api_num = RPC_apicall_queue_api_num(id, 0);
106 *args_string = RPC_apicall_queue_args(id, 0);
107 /* this string must be freed by the caller using discard_APIcall_return()*/
108 *args_size = RPC_apicall_queue_args_size(id, 0);
111 memmove(&(RPC_apicall_queue(id, 0)), &(RPC_apicall_queue(id, 1)),
112 (n - 1) * sizeof(RPC_apicall_queue(id, 0)));
114 RPC_apicall_num_queue_dec(id);
117 RPC_THREAD_MUTEX_UNLOCK(id->thread_info);
121 /** @ingroup RPClib_in
123 RUNS_IN_READING_THREAD
125 RpcSetAPIcallReturn(RpcIdInfo *id, const char *mesg, UINT32 size) {
126 if (RPC_apicall_return_str(id) != NULL) { // LCOV_EXCL_BR_LINE 6: double check
127 RPC_LOG_STATE("previous APIcall return string was not used"); // LCOV_EXCL_START 6: double check
128 AGL_ASSERT_NOT_TESTED(); // LCOV_EXCL_LINE 200: test assert
129 RpcDiscardAPIcallReturn(id);
131 RPC_THREAD_MUTEX_LOCK(id->thread_info);
133 RPC_apicall_return_str(id) = rpc_malloc(size);/* malloc */
134 if (RPC_apicall_return_str(id) == NULL) { // LCOV_EXCL_BR_LINE 5: fail safe for libc function malloc
135 RPC_THREAD_MUTEX_UNLOCK(id->thread_info); // LCOV_EXCL_START 5: fail safe for libc function malloc
136 AGL_ASSERT_NOT_TESTED(); // LCOV_EXCL_LINE 200: test assert
137 RPC_LOG_STATE("set APIcall return: No Memory");
138 return RPC_ERR_Fatal;
140 RPC_apicall_return_str_len(id) = size;
141 memcpy(RPC_apicall_return_str(id), mesg, size);
142 RPC_THREAD_MUTEX_UNLOCK(id->thread_info);
146 /** @ingroup RPClib_in
148 RUNS_IN_CALLERS_THREAD
150 RpcDiscardAPIcallReturn(RpcIdInfo *id) {
151 RPC_THREAD_MUTEX_LOCK(id->thread_info);
152 if (RPC_apicall_return_str(id) != NULL) { // LCOV_EXCL_BR_LINE 6: double check
153 rpc_free(RPC_apicall_return_str(id));/* free */
154 RPC_apicall_return_str_len(id) = 0;
155 RPC_apicall_return_str(id) = NULL;
157 RPC_THREAD_MUTEX_UNLOCK(id->thread_info);