Skip to content
This repository was archived by the owner on May 22, 2025. It is now read-only.

Commit 3f87807

Browse files
committed
update cmake config file; change json-rpc mid-layer
1 parent 890e0da commit 3f87807

File tree

15 files changed

+369
-401
lines changed

15 files changed

+369
-401
lines changed

3rd/s2j/CMakeLists.txt

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,5 +3,3 @@ project(s2j)
33
add_library(${PROJECT_NAME} SHARED s2j.c)
44

55
target_link_libraries(${PROJECT_NAME} cjson)
6-
7-
target_include_directories(${PROJECT_NAME} PUBLIC ../cjson)

CMakeLists.txt

Lines changed: 4 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,6 @@
11
cmake_minimum_required(VERSION 3.5)
22
project(UV-Master)
33

4-
set(CMAKE_SYSTEM_NAME Linux)
5-
set(CMAKE_SYSTEM_PROCESSOR arm)
6-
7-
if(NOT CMAKE_C_COMPILER)
8-
set(CMAKE_C_COMPILER arm-linux-gnueabihf-gcc)
9-
endif()
10-
if(NOT CMAKE_CXX_COMPILER)
11-
set(CMAKE_CXX_COMPILER arm-linux-gnueabihf-g++)
12-
endif()
13-
144
set(CMAKE_VERBOSE_MAKEFILE ON)
155

166
set(CMAKE_C_STANDARD 11)
@@ -26,6 +16,10 @@ endif()
2616
set(CMAKE_C_FLAGS_DEBUG "-O0 -g -Wall")
2717
set(CMAKE_C_FLAGS_RELEASE "-O3 -w -DNDEBUG")
2818

19+
include_directories(3rd/cjson
20+
3rd/clog
21+
3rd/s2j)
22+
2923
add_subdirectory(3rd)
3024
add_subdirectory(hal)
3125
add_subdirectory(cal)

cal/CMakeLists.txt

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2,13 +2,9 @@ project(uvm-cal)
22

33
add_library(${PROJECT_NAME} SHARED
44
uvm_cal.c
5-
rpc_cjson.c
5+
mjsonrpc.c
66
tcp_server.c)
77

88
target_link_libraries(${PROJECT_NAME}
99
cjson
1010
pthread)
11-
12-
target_include_directories(${PROJECT_NAME} PUBLIC
13-
../3rd/cjson
14-
../3rd/clog)

cal/mjsonrpc.c

Lines changed: 246 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,246 @@
1+
/*
2+
MIT License
3+
4+
Copyright (c) 2024 Xiao
5+
6+
Permission is hereby granted, free of charge, to any person obtaining a copy
7+
of this software and associated documentation files (the "Software"), to deal
8+
in the Software without restriction, including without limitation the rights
9+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10+
copies of the Software, and to permit persons to whom the Software is
11+
furnished to do so, subject to the following conditions:
12+
13+
The above copyright notice and this permission notice shall be included in all
14+
copies or substantial portions of the Software.
15+
16+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22+
SOFTWARE.
23+
*/
24+
25+
#include <stdlib.h>
26+
#include <string.h>
27+
28+
#include "mjsonrpc.h"
29+
30+
#define JRPC_VERSION "2.0"
31+
32+
int mjrpc_add_method(mjrpc_handle_t *handle, mjrpc_function function_pointer, char *name, void *data)
33+
{
34+
int i = handle->info_count++;
35+
if (!handle->infos)
36+
handle->infos = malloc(sizeof(struct mjrpc_cb_info));
37+
else
38+
{
39+
struct mjrpc_cb_info *ptr = realloc(handle->infos,
40+
sizeof(struct mjrpc_cb_info) * handle->info_count);
41+
if (!ptr)
42+
return MJRPC_ERROR_MEM_ALLOC_FAILED;
43+
handle->infos = ptr;
44+
}
45+
if ((handle->infos[i].name = strdup(name)) == NULL)
46+
return MJRPC_ERROR_MEM_ALLOC_FAILED;
47+
handle->infos[i].function = function_pointer;
48+
handle->infos[i].data = data;
49+
return MJRPC_OK;
50+
}
51+
52+
static void cb_info_destroy(struct mjrpc_cb_info *info)
53+
{
54+
if (info->name)
55+
{
56+
free(info->name);
57+
info->name = NULL;
58+
}
59+
if (info->data)
60+
{
61+
free(info->data);
62+
info->data = NULL;
63+
}
64+
}
65+
66+
int mjrpc_del_method(mjrpc_handle_t *handle, char *name)
67+
{
68+
int i;
69+
int found = 0;
70+
if (handle->infos)
71+
{
72+
for (i = 0; i < handle->info_count; i++)
73+
{
74+
if (found)
75+
handle->infos[i - 1] = handle->infos[i];
76+
else if (!strcmp(name, handle->infos[i].name))
77+
{
78+
found = 1;
79+
cb_info_destroy(&(handle->infos[i]));
80+
}
81+
}
82+
if (found)
83+
{
84+
handle->info_count--;
85+
if (handle->info_count)
86+
{
87+
struct mjrpc_cb_info *ptr = realloc(handle->infos,
88+
sizeof(struct mjrpc_cb_info) * handle->info_count);
89+
if (!ptr)
90+
return MJRPC_ERROR_MEM_ALLOC_FAILED;
91+
handle->infos = ptr;
92+
}
93+
else
94+
handle->infos = NULL;
95+
}
96+
}
97+
else
98+
return MJRPC_ERROR_NOT_FOUND;
99+
return MJRPC_OK;
100+
}
101+
102+
static cJSON *rpc_err(mjrpc_handle_t *handle, int code, char *message, cJSON *id)
103+
{
104+
cJSON *result_root = cJSON_CreateObject();
105+
cJSON *error_root = cJSON_CreateObject();
106+
if (result_root == NULL || error_root == NULL)
107+
return NULL;
108+
109+
cJSON_AddNumberToObject(error_root, "code", code);
110+
if (message)
111+
{
112+
cJSON_AddStringToObject(error_root, "message", message);
113+
free(message);
114+
}
115+
116+
cJSON_AddStringToObject(result_root, "jsonrpc", JRPC_VERSION);
117+
118+
cJSON_AddItemToObject(result_root, "error", error_root);
119+
120+
if (id)
121+
cJSON_AddItemToObject(result_root, "id", id);
122+
else
123+
cJSON_AddItemToObject(result_root, "id", cJSON_CreateNull());
124+
125+
return result_root;
126+
}
127+
128+
static cJSON *rpc_ok(cJSON *result, cJSON *id)
129+
{
130+
cJSON *result_root = cJSON_CreateObject();
131+
132+
cJSON_AddStringToObject(result_root, "jsonrpc", JRPC_VERSION);
133+
134+
cJSON_AddItemToObject(result_root, "result", result);
135+
136+
if (id)
137+
cJSON_AddItemToObject(result_root, "id", id);
138+
else
139+
cJSON_AddItemToObject(result_root, "id", cJSON_CreateNull());
140+
141+
return result_root;
142+
}
143+
144+
static cJSON *invoke_procedure(mjrpc_handle_t *handle, char *name, cJSON *params, cJSON *id)
145+
{
146+
cJSON *returned = NULL;
147+
int procedure_found = 0;
148+
mjrpc_ctx_t ctx;
149+
ctx.error_code = 0;
150+
ctx.error_message = NULL;
151+
int i = handle->info_count;
152+
while (i--)
153+
{
154+
if (!strcmp(handle->infos[i].name, name))
155+
{
156+
procedure_found = 1;
157+
ctx.data = handle->infos[i].data;
158+
returned = handle->infos[i].function(&ctx, params, id);
159+
break;
160+
}
161+
}
162+
if (!procedure_found)
163+
return rpc_err(handle, JRPC_METHOD_NOT_FOUND, strdup("Method not found."), id);
164+
else
165+
{
166+
if (ctx.error_code)
167+
return rpc_err(handle, ctx.error_code, ctx.error_message, id);
168+
else
169+
return rpc_ok(returned, id);
170+
}
171+
}
172+
173+
static cJSON *rpc_invoke_method(mjrpc_handle_t *handle, cJSON *request)
174+
{
175+
cJSON *method, *params, *id;
176+
177+
if (strcmp("2.0", cJSON_GetObjectItem(request, "jsonrpc")->valuestring) != 0)
178+
return rpc_err(handle, JRPC_INVALID_REQUEST, strdup("Valid request received: JSONRPC version error."), NULL);
179+
180+
method = cJSON_GetObjectItem(request, "method");
181+
if (method != NULL && method->type == cJSON_String)
182+
{
183+
params = cJSON_GetObjectItem(request, "params");
184+
185+
id = cJSON_GetObjectItem(request, "id");
186+
if (id->type == cJSON_NULL || id->type == cJSON_String || id->type == cJSON_Int)
187+
{
188+
// We have to copy ID because using it on the reply and deleting the response Object will also delete ID
189+
cJSON *id_copy = NULL;
190+
if (id != NULL)
191+
id_copy =
192+
(id->type == cJSON_String) ? cJSON_CreateString(
193+
id->valuestring)
194+
: cJSON_CreateNumber(id->valueint);
195+
return invoke_procedure(handle, method->valuestring, params, id_copy);
196+
}
197+
return rpc_err(handle, JRPC_INVALID_REQUEST, strdup("Valid request received: No 'id' member or wrong type"), NULL);
198+
}
199+
return rpc_err(handle, JRPC_INVALID_REQUEST, strdup("Valid request received: No 'method' member or wrong type"), NULL);
200+
}
201+
202+
static cJSON *rpc_invoke_method_array(mjrpc_handle_t *handle, cJSON *request)
203+
{
204+
int array_size = cJSON_GetArraySize(request);
205+
if (array_size <= 0)
206+
return rpc_err(handle, JRPC_INVALID_REQUEST, strdup("Valid request received: Empty JSON array."), NULL);
207+
208+
cJSON *return_json_array = cJSON_CreateArray();
209+
for (int i = 0; i < array_size; i++)
210+
cJSON_AddItemToArray(return_json_array, rpc_invoke_method(handle, cJSON_GetArrayItem(request, i)));
211+
212+
return return_json_array;
213+
}
214+
215+
int mjrpc_process(mjrpc_handle_t *handle, const char *json_reqeust, char **json_return_ptr)
216+
{
217+
if (json_reqeust == NULL)
218+
return MJRPC_ERROR_EMPTY_REQUST;
219+
220+
cJSON *request = cJSON_Parse(json_reqeust);
221+
if (request == NULL)
222+
{
223+
*json_return_ptr = cJSON_PrintUnformatted(rpc_err(handle, JRPC_PARSE_ERROR, strdup("Parse error: Not in JSON format."), NULL));
224+
return MJRPC_ERROR_PARSE_FAILED;
225+
}
226+
227+
cJSON *cjson_return = NULL;
228+
if (request->type == cJSON_Array)
229+
{
230+
cjson_return = rpc_invoke_method_array(handle, request);
231+
}
232+
else if (request->type == cJSON_Object)
233+
{
234+
cjson_return = rpc_invoke_method(handle, request);
235+
}
236+
else
237+
{
238+
cjson_return = rpc_err(handle, JRPC_INVALID_REQUEST, strdup("Valid request received: Not a JSON object or array."), NULL);
239+
}
240+
241+
*json_return_ptr = cJSON_PrintUnformatted(cjson_return);
242+
cJSON_Delete(cjson_return);
243+
cJSON_Delete(request);
244+
245+
return MJRPC_OK;
246+
}

cal/mjsonrpc.h

Lines changed: 98 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,98 @@
1+
/*
2+
MIT License
3+
4+
Copyright (c) 2024 Xiao
5+
6+
Permission is hereby granted, free of charge, to any person obtaining a copy
7+
of this software and associated documentation files (the "Software"), to deal
8+
in the Software without restriction, including without limitation the rights
9+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10+
copies of the Software, and to permit persons to whom the Software is
11+
furnished to do so, subject to the following conditions:
12+
13+
The above copyright notice and this permission notice shall be included in all
14+
copies or substantial portions of the Software.
15+
16+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22+
SOFTWARE.
23+
*/
24+
25+
#ifndef MJSONRPC_H
26+
#define MJSONRPC_H
27+
28+
#include "cJSON.h"
29+
30+
#define JRPC_PARSE_ERROR -32700
31+
#define JRPC_INVALID_REQUEST -32600
32+
#define JRPC_METHOD_NOT_FOUND -32601
33+
#define JRPC_INVALID_PARAMS -32603
34+
#define JRPC_INTERNAL_ERROR -32693
35+
36+
// -32000 to -32099 Reserved for implementation-defined server-errors.
37+
38+
enum mjrpc_error_return
39+
{
40+
MJRPC_OK,
41+
MJRPC_ERROR_MEM_ALLOC_FAILED,
42+
MJRPC_ERROR_NOT_FOUND,
43+
MJRPC_ERROR_EMPTY_REQUST,
44+
MJRPC_ERROR_PARSE_FAILED,
45+
};
46+
47+
typedef struct
48+
{
49+
void *data;
50+
int error_code;
51+
char *error_message;
52+
} mjrpc_ctx_t;
53+
54+
typedef cJSON *(*mjrpc_function)(mjrpc_ctx_t *context,
55+
cJSON *params,
56+
cJSON *id);
57+
58+
struct mjrpc_cb_info
59+
{
60+
char *name;
61+
mjrpc_function function;
62+
void *data;
63+
};
64+
65+
typedef struct rpc_handle
66+
{
67+
int info_count;
68+
struct mjrpc_cb_info *infos;
69+
} mjrpc_handle_t;
70+
71+
/**
72+
* @brief Used to add the callback function
73+
* @param handle Operation handle
74+
* @param function_pointer Function to be called
75+
* @param name Method name
76+
* @param data Data passed to the function when called
77+
* @return Returns the mjrpc error code
78+
*/
79+
int mjrpc_add_method(mjrpc_handle_t *handle, mjrpc_function function_pointer, char *name, void *data);
80+
81+
/**
82+
* @brief Used to delete the callback function
83+
* @param handle Operation handle
84+
* @param name Method name
85+
* @return Returns the mjrpc error code
86+
*/
87+
int mjrpc_del_method(mjrpc_handle_t *handle, char *name);
88+
89+
/**
90+
* @brief Function for processing RPC request strings
91+
* @param handle Operation handle
92+
* @param json_request Request string
93+
* @param json_return_ptr Pointer to receive the response string
94+
* @return Returns the mjrpc error code
95+
*/
96+
int mjrpc_process(mjrpc_handle_t *handle, const char *json_reqeust, char **json_return_ptr);
97+
98+
#endif

0 commit comments

Comments
 (0)