mirror of
https://github.com/signalwire/freeswitch.git
synced 2025-04-13 15:50:59 +00:00
FS-9952: Big commit, first registered jsonrpc echo call successful, lots of cleanup remaining
This commit is contained in:
parent
fd49aebb1d
commit
8f569f715b
@ -11,23 +11,20 @@ libunqlite_la_CFLAGS = -DUNQLITE_ENABLE_THREADS
|
||||
libunqlite_la_LIBADD = -lpthread
|
||||
|
||||
lib_LTLIBRARIES = libblade.la
|
||||
libblade_la_SOURCES = src/blade.c src/blade_stack.c src/bpcp.c src/blade_datastore.c
|
||||
libblade_la_SOURCES += src/blade_rpcproto.c
|
||||
libblade_la_SOURCES += src/blade_identity.c src/blade_module.c src/blade_connection.c src/blade_module_wss.c
|
||||
libblade_la_SOURCES += src/blade_session.c src/blade_protocol.c
|
||||
libblade_la_SOURCES = src/blade.c src/blade_stack.c
|
||||
libblade_la_SOURCES += src/blade_datastore.c
|
||||
libblade_la_SOURCES += src/blade_identity.c src/blade_module.c src/blade_connection.c
|
||||
libblade_la_SOURCES += src/blade_session.c src/blade_protocol.c src/blade_space.c src/blade_method.c
|
||||
libblade_la_SOURCES += src/blade_module_wss.c
|
||||
libblade_la_CFLAGS = $(AM_CFLAGS) $(AM_CPPFLAGS)
|
||||
libblade_la_LDFLAGS = -version-info 0:1:0 -lncurses -lpthread -lm -lconfig $(AM_LDFLAGS)
|
||||
libblade_la_LIBADD = libunqlite.la
|
||||
library_includedir = $(prefix)/include
|
||||
library_include_HEADERS = src/include/blade.h src/include/blade_types.h src/include/blade_stack.h
|
||||
library_include_HEADERS += src/include/bpcp.h src/include/blade_datastore.h src/include/blade_rpcproto.h
|
||||
library_include_HEADERS += src/include/blade_identity.h src/include/blade_module.h src/include/blade_connection.h
|
||||
library_include_HEADERS += src/include/blade_session.h src/include/blade_protocol.h
|
||||
library_include_HEADERS += src/include/blade_datastore.h
|
||||
library_include_HEADERS += src/include/blade_identity.h src/include/blade_module.h src/include/blade_connection.h
|
||||
library_include_HEADERS += src/include/blade_session.h src/include/blade_protocol.h src/include/blade_space.h src/include/blade_method.h
|
||||
library_include_HEADERS += src/include/unqlite.h test/tap.h
|
||||
|
||||
tests: libblade.la
|
||||
$(MAKE) -C test tests
|
||||
|
||||
|
||||
|
||||
|
||||
|
@ -495,6 +495,7 @@ ks_status_t blade_connection_state_on_ready(blade_connection_t *bc)
|
||||
blade_transport_state_callback_t callback = NULL;
|
||||
blade_connection_state_hook_t hook = BLADE_CONNECTION_STATE_HOOK_SUCCESS;
|
||||
cJSON *json = NULL;
|
||||
blade_session_t *bs = NULL;
|
||||
ks_bool_t done = KS_FALSE;
|
||||
|
||||
ks_assert(bc);
|
||||
@ -514,14 +515,18 @@ ks_status_t blade_connection_state_on_ready(blade_connection_t *bc)
|
||||
blade_connection_disconnect(bc);
|
||||
break;
|
||||
}
|
||||
|
||||
if (!(done = (json == NULL))) {
|
||||
blade_session_t *bs = blade_handle_sessions_get(bc->handle, bc->session);
|
||||
ks_assert(bs);
|
||||
if (!bs) {
|
||||
bs = blade_handle_sessions_get(bc->handle, bc->session);
|
||||
ks_assert(bs);
|
||||
}
|
||||
blade_session_receiving_push(bs, json);
|
||||
cJSON_Delete(json);
|
||||
json = NULL;
|
||||
}
|
||||
}
|
||||
if (bs) blade_session_read_unlock(bs);
|
||||
|
||||
callback = blade_connection_state_callback_lookup(bc, BLADE_CONNECTION_STATE_READY);
|
||||
if (callback) hook = callback(bc, BLADE_CONNECTION_STATE_CONDITION_POST);
|
||||
|
118
libs/libblade/src/blade_method.c
Normal file
118
libs/libblade/src/blade_method.c
Normal file
@ -0,0 +1,118 @@
|
||||
/*
|
||||
* Copyright (c) 2017, Shane Bryldt
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
*
|
||||
* * Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* * Neither the name of the original author; nor the names of any contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
|
||||
* OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include "blade.h"
|
||||
|
||||
struct blade_method_s {
|
||||
blade_handle_t *handle;
|
||||
ks_pool_t *pool;
|
||||
|
||||
blade_space_t *space;
|
||||
const char *name;
|
||||
|
||||
blade_request_callback_t callback;
|
||||
// @todo more fun descriptive information about the call for remote registrations
|
||||
};
|
||||
|
||||
|
||||
KS_DECLARE(ks_status_t) blade_method_create(blade_method_t **bmP, blade_space_t *bs, const char *name, blade_request_callback_t callback)
|
||||
{
|
||||
blade_handle_t *bh = NULL;
|
||||
blade_method_t *bm = NULL;
|
||||
ks_pool_t *pool = NULL;
|
||||
|
||||
ks_assert(bmP);
|
||||
ks_assert(bs);
|
||||
ks_assert(name);
|
||||
|
||||
bh = blade_space_handle_get(bs);
|
||||
ks_assert(bh);
|
||||
|
||||
pool = blade_handle_pool_get(bh);
|
||||
ks_assert(pool);
|
||||
|
||||
bm = ks_pool_alloc(pool, sizeof(blade_method_t));
|
||||
bm->handle = bh;
|
||||
bm->pool = pool;
|
||||
bm->space = bs;
|
||||
bm->name = name; // @todo dup and keep copy? should mostly be literals
|
||||
bm->callback = callback;
|
||||
|
||||
*bmP = bm;
|
||||
|
||||
ks_log(KS_LOG_DEBUG, "Method Created: %s.%s\n", blade_space_path_get(bs), name);
|
||||
|
||||
return KS_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
KS_DECLARE(ks_status_t) blade_method_destroy(blade_method_t **bmP)
|
||||
{
|
||||
blade_method_t *bm = NULL;
|
||||
|
||||
ks_assert(bmP);
|
||||
ks_assert(*bmP);
|
||||
|
||||
bm = *bmP;
|
||||
|
||||
ks_log(KS_LOG_DEBUG, "Method Destroyed: %s.%s\n", blade_space_path_get(bm->space), bm->name);
|
||||
|
||||
ks_pool_free(bm->pool, bmP);
|
||||
|
||||
return KS_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
KS_DECLARE(const char *) blade_method_name_get(blade_method_t *bm)
|
||||
{
|
||||
ks_assert(bm);
|
||||
|
||||
return bm->name;
|
||||
}
|
||||
|
||||
KS_DECLARE(blade_request_callback_t) blade_method_callback_get(blade_method_t *bm)
|
||||
{
|
||||
ks_assert(bm);
|
||||
|
||||
return bm->callback;
|
||||
}
|
||||
|
||||
|
||||
/* For Emacs:
|
||||
* Local Variables:
|
||||
* mode:c
|
||||
* indent-tabs-mode:t
|
||||
* tab-width:4
|
||||
* c-basic-offset:4
|
||||
* End:
|
||||
* For VIM:
|
||||
* vim:set softtabstop=4 shiftwidth=4 tabstop=4 noet:
|
||||
*/
|
@ -111,8 +111,10 @@ blade_connection_state_hook_t blade_transport_wss_on_state_connect_inbound(blade
|
||||
blade_connection_state_hook_t blade_transport_wss_on_state_connect_outbound(blade_connection_t *bc, blade_connection_state_condition_t condition);
|
||||
blade_connection_state_hook_t blade_transport_wss_on_state_attach_inbound(blade_connection_t *bc, blade_connection_state_condition_t condition);
|
||||
blade_connection_state_hook_t blade_transport_wss_on_state_attach_outbound(blade_connection_t *bc, blade_connection_state_condition_t condition);
|
||||
blade_connection_state_hook_t blade_transport_wss_on_state_detach(blade_connection_t *bc, blade_connection_state_condition_t condition);
|
||||
blade_connection_state_hook_t blade_transport_wss_on_state_ready(blade_connection_t *bc, blade_connection_state_condition_t condition);
|
||||
blade_connection_state_hook_t blade_transport_wss_on_state_detach_inbound(blade_connection_t *bc, blade_connection_state_condition_t condition);
|
||||
blade_connection_state_hook_t blade_transport_wss_on_state_detach_outbound(blade_connection_t *bc, blade_connection_state_condition_t condition);
|
||||
blade_connection_state_hook_t blade_transport_wss_on_state_ready_inbound(blade_connection_t *bc, blade_connection_state_condition_t condition);
|
||||
blade_connection_state_hook_t blade_transport_wss_on_state_ready_outbound(blade_connection_t *bc, blade_connection_state_condition_t condition);
|
||||
|
||||
|
||||
|
||||
@ -120,6 +122,9 @@ ks_status_t blade_transport_wss_init_create(blade_transport_wss_init_t **bt_wssi
|
||||
ks_status_t blade_transport_wss_init_destroy(blade_transport_wss_init_t **bt_wssiP);
|
||||
|
||||
|
||||
ks_bool_t blade_test_echo_request_handler(blade_request_t *breq);
|
||||
ks_bool_t blade_test_echo_response_handler(blade_response_t *bres);
|
||||
|
||||
|
||||
static blade_module_callbacks_t g_module_wss_callbacks =
|
||||
{
|
||||
@ -144,10 +149,10 @@ static blade_transport_callbacks_t g_transport_wss_callbacks =
|
||||
blade_transport_wss_on_state_connect_outbound,
|
||||
blade_transport_wss_on_state_attach_inbound,
|
||||
blade_transport_wss_on_state_attach_outbound,
|
||||
blade_transport_wss_on_state_detach,
|
||||
blade_transport_wss_on_state_detach,
|
||||
blade_transport_wss_on_state_ready,
|
||||
blade_transport_wss_on_state_ready,
|
||||
blade_transport_wss_on_state_detach_inbound,
|
||||
blade_transport_wss_on_state_detach_outbound,
|
||||
blade_transport_wss_on_state_ready_inbound,
|
||||
blade_transport_wss_on_state_ready_outbound,
|
||||
};
|
||||
|
||||
|
||||
@ -385,6 +390,8 @@ ks_status_t blade_module_wss_config(blade_module_wss_t *bm_wss, config_setting_t
|
||||
KS_DECLARE(ks_status_t) blade_module_wss_on_startup(blade_module_t *bm, config_setting_t *config)
|
||||
{
|
||||
blade_module_wss_t *bm_wss = NULL;
|
||||
blade_space_t *space = NULL;
|
||||
blade_method_t *method = NULL;
|
||||
|
||||
ks_assert(bm);
|
||||
ks_assert(config);
|
||||
@ -419,6 +426,17 @@ KS_DECLARE(ks_status_t) blade_module_wss_on_startup(blade_module_t *bm, config_s
|
||||
|
||||
blade_handle_transport_register(bm_wss->handle, bm, BLADE_MODULE_WSS_TRANSPORT_NAME, bm_wss->transport_callbacks);
|
||||
|
||||
|
||||
blade_space_create(&space, bm_wss->handle, "blade.test");
|
||||
ks_assert(space);
|
||||
|
||||
blade_method_create(&method, space, "echo", blade_test_echo_request_handler);
|
||||
ks_assert(method);
|
||||
|
||||
blade_space_methods_add(space, method);
|
||||
|
||||
blade_handle_space_register(space);
|
||||
|
||||
ks_log(KS_LOG_DEBUG, "Started\n");
|
||||
|
||||
return KS_STATUS_SUCCESS;
|
||||
@ -428,6 +446,7 @@ KS_DECLARE(ks_status_t) blade_module_wss_on_shutdown(blade_module_t *bm)
|
||||
{
|
||||
blade_module_wss_t *bm_wss = NULL;
|
||||
blade_connection_t *bc = NULL;
|
||||
ks_bool_t stopped = KS_FALSE;
|
||||
|
||||
ks_assert(bm);
|
||||
|
||||
@ -440,6 +459,7 @@ KS_DECLARE(ks_status_t) blade_module_wss_on_shutdown(blade_module_t *bm)
|
||||
ks_thread_join(bm_wss->listeners_thread);
|
||||
ks_pool_free(bm_wss->pool, &bm_wss->listeners_thread);
|
||||
bm_wss->shutdown = KS_FALSE;
|
||||
stopped = KS_TRUE;
|
||||
}
|
||||
|
||||
for (int32_t index = 0; index < bm_wss->listeners_count; ++index) {
|
||||
@ -461,7 +481,7 @@ KS_DECLARE(ks_status_t) blade_module_wss_on_shutdown(blade_module_t *bm)
|
||||
while (list_size(&bm_wss->connected) > 0) ks_sleep_ms(100);
|
||||
}
|
||||
|
||||
ks_log(KS_LOG_DEBUG, "Stopped\n");
|
||||
if (stopped) ks_log(KS_LOG_DEBUG, "Stopped\n");
|
||||
|
||||
return KS_STATUS_SUCCESS;
|
||||
}
|
||||
@ -751,7 +771,6 @@ ks_status_t blade_transport_wss_write(blade_transport_wss_t *bt_wss, cJSON *json
|
||||
|
||||
ks_status_t blade_transport_wss_on_send(blade_connection_t *bc, cJSON *json)
|
||||
{
|
||||
ks_status_t ret = KS_STATUS_SUCCESS;
|
||||
blade_transport_wss_t *bt_wss = NULL;
|
||||
|
||||
ks_assert(bc);
|
||||
@ -759,11 +778,7 @@ ks_status_t blade_transport_wss_on_send(blade_connection_t *bc, cJSON *json)
|
||||
|
||||
bt_wss = (blade_transport_wss_t *)blade_connection_transport_get(bc);
|
||||
|
||||
ret = blade_transport_wss_write(bt_wss, json);
|
||||
|
||||
cJSON_Delete(json);
|
||||
|
||||
return ret;
|
||||
return blade_transport_wss_write(bt_wss, json);
|
||||
}
|
||||
|
||||
ks_status_t blade_transport_wss_read(blade_transport_wss_t *bt_wss, cJSON **json)
|
||||
@ -814,6 +829,29 @@ ks_status_t blade_transport_wss_on_receive(blade_connection_t *bc, cJSON **json)
|
||||
return blade_transport_wss_read(bt_wss, json);
|
||||
}
|
||||
|
||||
ks_status_t blade_transport_wss_rpc_error_send(blade_connection_t *bc, const char *id, int32_t code, const char *message)
|
||||
{
|
||||
ks_status_t ret = KS_STATUS_SUCCESS;
|
||||
blade_transport_wss_t *bt_wss = NULL;
|
||||
cJSON *json = NULL;
|
||||
|
||||
ks_assert(bc);
|
||||
ks_assert(id);
|
||||
ks_assert(message);
|
||||
|
||||
bt_wss = (blade_transport_wss_t *)blade_connection_transport_get(bc);
|
||||
|
||||
blade_rpc_error_create(blade_connection_pool_get(bc), &json, NULL, id, code, message);
|
||||
|
||||
if (blade_transport_wss_write(bt_wss, json) != KS_STATUS_SUCCESS) {
|
||||
ks_log(KS_LOG_DEBUG, "Failed to write error message\n");
|
||||
ret = KS_STATUS_FAIL;
|
||||
}
|
||||
|
||||
cJSON_Delete(json);
|
||||
return ret;
|
||||
}
|
||||
|
||||
blade_connection_state_hook_t blade_transport_wss_on_state_disconnect(blade_connection_t *bc, blade_connection_state_condition_t condition)
|
||||
{
|
||||
blade_transport_wss_t *bt_wss = NULL;
|
||||
@ -924,10 +962,11 @@ blade_connection_state_hook_t blade_transport_wss_on_state_attach_inbound(blade_
|
||||
{
|
||||
blade_connection_state_hook_t ret = BLADE_CONNECTION_STATE_HOOK_SUCCESS;
|
||||
blade_transport_wss_t *bt_wss = NULL;
|
||||
ks_pool_t *pool = NULL;
|
||||
cJSON *json_req = NULL;
|
||||
cJSON *json_res = NULL;
|
||||
cJSON *params = NULL;
|
||||
cJSON *result = NULL;
|
||||
cJSON *json_params = NULL;
|
||||
cJSON *json_result = NULL;
|
||||
//cJSON *error = NULL;
|
||||
blade_session_t *bs = NULL;
|
||||
blade_handle_t *bh = NULL;
|
||||
@ -948,6 +987,8 @@ blade_connection_state_hook_t blade_transport_wss_on_state_attach_inbound(blade_
|
||||
|
||||
bt_wss = (blade_transport_wss_t *)blade_connection_transport_get(bc);
|
||||
|
||||
pool = blade_connection_pool_get(bc);
|
||||
|
||||
// @todo very temporary, really need monotonic clock and get timeout delay and sleep delay from config
|
||||
timeout = ks_time_now() + (5 * KS_USEC_PER_SEC);
|
||||
while (blade_transport_wss_read(bt_wss, &json_req) == KS_STATUS_SUCCESS) {
|
||||
@ -958,6 +999,7 @@ blade_connection_state_hook_t blade_transport_wss_on_state_attach_inbound(blade_
|
||||
|
||||
if (!json_req) {
|
||||
ks_log(KS_LOG_DEBUG, "Failed to receive message before timeout\n");
|
||||
blade_transport_wss_rpc_error_send(bc, NULL, -32600, "Timeout while expecting request");
|
||||
ret = BLADE_CONNECTION_STATE_HOOK_DISCONNECT;
|
||||
goto done;
|
||||
}
|
||||
@ -966,7 +1008,7 @@ blade_connection_state_hook_t blade_transport_wss_on_state_attach_inbound(blade_
|
||||
jsonrpc = cJSON_GetObjectCstr(json_req, "jsonrpc"); // @todo check for definitions of these keys and fixed values
|
||||
if (!jsonrpc || strcmp(jsonrpc, "2.0")) {
|
||||
ks_log(KS_LOG_DEBUG, "Received message is not the expected protocol\n");
|
||||
// @todo send error response before disconnecting, code = -32600 (invalid request)
|
||||
blade_transport_wss_rpc_error_send(bc, NULL, -32600, "Invalid request, missing 'jsonrpc' field");
|
||||
ret = BLADE_CONNECTION_STATE_HOOK_DISCONNECT;
|
||||
goto done;
|
||||
}
|
||||
@ -974,7 +1016,7 @@ blade_connection_state_hook_t blade_transport_wss_on_state_attach_inbound(blade_
|
||||
id = cJSON_GetObjectCstr(json_req, "id"); // @todo switch to number if we are not using a uuid for message id
|
||||
if (!id) {
|
||||
ks_log(KS_LOG_DEBUG, "Received message is missing 'id'\n");
|
||||
// @todo send error response before disconnecting, code = -32600 (invalid request)
|
||||
blade_transport_wss_rpc_error_send(bc, NULL, -32600, "Invalid request, missing 'id' field");
|
||||
ret = BLADE_CONNECTION_STATE_HOOK_DISCONNECT;
|
||||
goto done;
|
||||
}
|
||||
@ -982,14 +1024,14 @@ blade_connection_state_hook_t blade_transport_wss_on_state_attach_inbound(blade_
|
||||
method = cJSON_GetObjectCstr(json_req, "method");
|
||||
if (!method || strcasecmp(method, "blade.session.attach")) {
|
||||
ks_log(KS_LOG_DEBUG, "Received message is missing 'method' or is an unexpected method\n");
|
||||
// @todo send error response before disconnecting, code = -32601 (method not found)
|
||||
blade_transport_wss_rpc_error_send(bc, id, -32601, "Missing or unexpected 'method' field");
|
||||
ret = BLADE_CONNECTION_STATE_HOOK_DISCONNECT;
|
||||
goto done;
|
||||
}
|
||||
|
||||
params = cJSON_GetObjectItem(json_req, "params");
|
||||
if (params) {
|
||||
sid = cJSON_GetObjectCstr(params, "session-id");
|
||||
json_params = cJSON_GetObjectItem(json_req, "params");
|
||||
if (json_params) {
|
||||
sid = cJSON_GetObjectCstr(json_params, "session-id");
|
||||
if (sid) {
|
||||
// @todo validate uuid format by parsing, not currently available in uuid functions, send -32602 (invalid params) if invalid
|
||||
ks_log(KS_LOG_DEBUG, "Session (%s) requested\n", sid);
|
||||
@ -1019,7 +1061,7 @@ blade_connection_state_hook_t blade_transport_wss_on_state_attach_inbound(blade_
|
||||
|
||||
if (blade_session_startup(bs) != KS_STATUS_SUCCESS) {
|
||||
ks_log(KS_LOG_DEBUG, "Session (%s) startup failed\n", blade_session_id_get(bs));
|
||||
// @todo send error response before disconnecting, code = -32603 (internal error)
|
||||
blade_transport_wss_rpc_error_send(bc, id, -32603, "Internal error, session could not be started");
|
||||
blade_session_read_unlock(bs);
|
||||
blade_session_destroy(&bs);
|
||||
ret = BLADE_CONNECTION_STATE_HOOK_DISCONNECT;
|
||||
@ -1030,17 +1072,14 @@ blade_connection_state_hook_t blade_transport_wss_on_state_attach_inbound(blade_
|
||||
}
|
||||
|
||||
// @todo wrapper to generate request and response
|
||||
json_res = cJSON_CreateObject();
|
||||
cJSON_AddStringToObject(json_res, "jsonrpc", "2.0");
|
||||
cJSON_AddStringToObject(json_res, "id", id);
|
||||
blade_rpc_response_create(pool, &json_res, &json_result, id);
|
||||
ks_assert(json_res);
|
||||
|
||||
result = cJSON_CreateObject();
|
||||
cJSON_AddStringToObject(result, "session-id", blade_session_id_get(bs));
|
||||
cJSON_AddItemToObject(json_res, "result", result);
|
||||
cJSON_AddStringToObject(json_result, "session-id", blade_session_id_get(bs));
|
||||
|
||||
// @todo send response
|
||||
if (blade_transport_wss_write(bt_wss, json_res) != KS_STATUS_SUCCESS) {
|
||||
ks_log(KS_LOG_DEBUG, "Failed to write message\n");
|
||||
ks_log(KS_LOG_DEBUG, "Failed to write response message\n");
|
||||
ret = BLADE_CONNECTION_STATE_HOOK_DISCONNECT;
|
||||
goto done;
|
||||
}
|
||||
@ -1064,14 +1103,14 @@ blade_connection_state_hook_t blade_transport_wss_on_state_attach_outbound(blade
|
||||
blade_transport_wss_init_t *bt_wss_init = NULL;
|
||||
ks_pool_t *pool = NULL;
|
||||
cJSON *json_req = NULL;
|
||||
cJSON *json_params = NULL;
|
||||
cJSON *json_res = NULL;
|
||||
uuid_t msgid;
|
||||
const char *mid = NULL;
|
||||
ks_time_t timeout;
|
||||
const char *jsonrpc = NULL;
|
||||
const char *id = NULL;
|
||||
cJSON *error = NULL;
|
||||
cJSON *result = NULL;
|
||||
cJSON *json_error = NULL;
|
||||
cJSON *json_result = NULL;
|
||||
const char *sid = NULL;
|
||||
blade_session_t *bs = NULL;
|
||||
|
||||
@ -1087,25 +1126,15 @@ blade_connection_state_hook_t blade_transport_wss_on_state_attach_outbound(blade
|
||||
pool = blade_connection_pool_get(bc);
|
||||
|
||||
|
||||
// @todo wrapper to build a request and response/error
|
||||
json_req = cJSON_CreateObject();
|
||||
cJSON_AddStringToObject(json_req, "jsonrpc", "2.0");
|
||||
cJSON_AddStringToObject(json_req, "method", "blade.session.attach");
|
||||
blade_rpc_request_create(pool, &json_req, &json_params, &mid, "blade.session.attach");
|
||||
ks_assert(json_req);
|
||||
|
||||
ks_uuid(&msgid);
|
||||
mid = ks_uuid_str(pool, &msgid);
|
||||
cJSON_AddStringToObject(json_req, "id", mid);
|
||||
|
||||
if (bt_wss_init->session_id) {
|
||||
cJSON *params = cJSON_CreateObject();
|
||||
cJSON_AddStringToObject(params, "session-id", bt_wss_init->session_id);
|
||||
cJSON_AddItemToObject(json_req, "params", params);
|
||||
}
|
||||
if (bt_wss_init->session_id) cJSON_AddStringToObject(json_params, "session-id", bt_wss_init->session_id);
|
||||
|
||||
ks_log(KS_LOG_DEBUG, "Session (%s) requested\n", (bt_wss_init->session_id ? bt_wss_init->session_id : "none"));
|
||||
|
||||
if (blade_transport_wss_write(bt_wss, json_req) != KS_STATUS_SUCCESS) {
|
||||
ks_log(KS_LOG_DEBUG, "Failed to write message\n");
|
||||
ks_log(KS_LOG_DEBUG, "Failed to write request message\n");
|
||||
ret = BLADE_CONNECTION_STATE_HOOK_DISCONNECT;
|
||||
goto done;
|
||||
}
|
||||
@ -1134,26 +1163,26 @@ blade_connection_state_hook_t blade_transport_wss_on_state_attach_outbound(blade
|
||||
|
||||
id = cJSON_GetObjectCstr(json_res, "id"); // @todo switch to number if we are not using a uuid for message id
|
||||
if (!id || strcasecmp(mid, id)) {
|
||||
ks_log(KS_LOG_DEBUG, "Received message is missing 'id'\n");
|
||||
ks_log(KS_LOG_DEBUG, "Received message has missing or unexpected 'id'\n");
|
||||
ret = BLADE_CONNECTION_STATE_HOOK_DISCONNECT;
|
||||
goto done;
|
||||
}
|
||||
|
||||
error = cJSON_GetObjectItem(json_res, "error");
|
||||
if (error) {
|
||||
json_error = cJSON_GetObjectItem(json_res, "error");
|
||||
if (json_error) {
|
||||
ks_log(KS_LOG_DEBUG, "Error message ... add the details\n");
|
||||
ret = BLADE_CONNECTION_STATE_HOOK_DISCONNECT;
|
||||
goto done;
|
||||
}
|
||||
|
||||
result = cJSON_GetObjectItem(json_res, "result");
|
||||
if (!result) {
|
||||
json_result = cJSON_GetObjectItem(json_res, "result");
|
||||
if (!json_result) {
|
||||
ks_log(KS_LOG_DEBUG, "Received message is missing 'result'\n");
|
||||
ret = BLADE_CONNECTION_STATE_HOOK_DISCONNECT;
|
||||
goto done;
|
||||
}
|
||||
|
||||
sid = cJSON_GetObjectCstr(result, "session-id");
|
||||
sid = cJSON_GetObjectCstr(json_result, "session-id");
|
||||
if (!sid) {
|
||||
ks_log(KS_LOG_DEBUG, "Received message 'result' is missing 'session-id'\n");
|
||||
ret = BLADE_CONNECTION_STATE_HOOK_DISCONNECT;
|
||||
@ -1192,13 +1221,12 @@ blade_connection_state_hook_t blade_transport_wss_on_state_attach_outbound(blade
|
||||
blade_connection_session_set(bc, blade_session_id_get(bs));
|
||||
|
||||
done:
|
||||
if (mid) ks_pool_free(pool, &mid);
|
||||
if (json_req) cJSON_Delete(json_req);
|
||||
if (json_res) cJSON_Delete(json_res);
|
||||
return ret;
|
||||
}
|
||||
|
||||
blade_connection_state_hook_t blade_transport_wss_on_state_detach(blade_connection_t *bc, blade_connection_state_condition_t condition)
|
||||
blade_connection_state_hook_t blade_transport_wss_on_state_detach_inbound(blade_connection_t *bc, blade_connection_state_condition_t condition)
|
||||
{
|
||||
ks_assert(bc);
|
||||
|
||||
@ -1207,7 +1235,16 @@ blade_connection_state_hook_t blade_transport_wss_on_state_detach(blade_connecti
|
||||
return BLADE_CONNECTION_STATE_HOOK_SUCCESS;
|
||||
}
|
||||
|
||||
blade_connection_state_hook_t blade_transport_wss_on_state_ready(blade_connection_t *bc, blade_connection_state_condition_t condition)
|
||||
blade_connection_state_hook_t blade_transport_wss_on_state_detach_outbound(blade_connection_t *bc, blade_connection_state_condition_t condition)
|
||||
{
|
||||
ks_assert(bc);
|
||||
|
||||
ks_log(KS_LOG_DEBUG, "State Callback: %d\n", (int32_t)condition);
|
||||
|
||||
return BLADE_CONNECTION_STATE_HOOK_SUCCESS;
|
||||
}
|
||||
|
||||
blade_connection_state_hook_t blade_transport_wss_on_state_ready_inbound(blade_connection_t *bc, blade_connection_state_condition_t condition)
|
||||
{
|
||||
ks_assert(bc);
|
||||
|
||||
@ -1217,6 +1254,60 @@ blade_connection_state_hook_t blade_transport_wss_on_state_ready(blade_connectio
|
||||
return BLADE_CONNECTION_STATE_HOOK_SUCCESS;
|
||||
}
|
||||
|
||||
blade_connection_state_hook_t blade_transport_wss_on_state_ready_outbound(blade_connection_t *bc, blade_connection_state_condition_t condition)
|
||||
{
|
||||
ks_assert(bc);
|
||||
|
||||
ks_log(KS_LOG_DEBUG, "State Callback: %d\n", (int32_t)condition);
|
||||
|
||||
if (condition == BLADE_CONNECTION_STATE_CONDITION_PRE) {
|
||||
blade_session_t *bs = NULL;
|
||||
cJSON *req = NULL;
|
||||
|
||||
bs = blade_handle_sessions_get(blade_connection_handle_get(bc), blade_connection_session_get(bc));
|
||||
ks_assert(bs);
|
||||
|
||||
blade_rpc_request_create(blade_connection_pool_get(bc), &req, NULL, NULL, "blade.test.echo");
|
||||
blade_session_send(bs, req, blade_test_echo_response_handler);
|
||||
|
||||
blade_session_read_unlock(bs);
|
||||
}
|
||||
|
||||
ks_sleep_ms(1000);
|
||||
return BLADE_CONNECTION_STATE_HOOK_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
|
||||
ks_bool_t blade_test_echo_request_handler(blade_request_t *breq)
|
||||
{
|
||||
blade_session_t *bs = NULL;
|
||||
cJSON *res = NULL;
|
||||
|
||||
ks_assert(breq);
|
||||
|
||||
ks_log(KS_LOG_DEBUG, "Request Received!\n");
|
||||
|
||||
bs = blade_handle_sessions_get(breq->handle, breq->session_id);
|
||||
ks_assert(bs);
|
||||
|
||||
blade_rpc_response_create(breq->pool, &res, NULL, breq->message_id);
|
||||
blade_session_send(bs, res, NULL);
|
||||
|
||||
blade_session_read_unlock(bs);
|
||||
|
||||
return KS_FALSE;
|
||||
}
|
||||
|
||||
ks_bool_t blade_test_echo_response_handler(blade_response_t *bres)
|
||||
{
|
||||
ks_assert(bres);
|
||||
|
||||
ks_log(KS_LOG_DEBUG, "Response Received!\n");
|
||||
|
||||
return KS_FALSE;
|
||||
}
|
||||
|
||||
/* For Emacs:
|
||||
* Local Variables:
|
||||
* mode:c
|
||||
|
@ -33,7 +33,11 @@
|
||||
|
||||
#include "blade.h"
|
||||
|
||||
KS_DECLARE(ks_status_t) blade_request_create(blade_request_t **breqP, blade_handle_t *bh, const char *session_id, cJSON *json)
|
||||
KS_DECLARE(ks_status_t) blade_request_create(blade_request_t **breqP,
|
||||
blade_handle_t *bh,
|
||||
const char *session_id,
|
||||
cJSON *json,
|
||||
blade_response_callback_t callback)
|
||||
{
|
||||
blade_request_t *breq = NULL;
|
||||
ks_pool_t *pool = NULL;
|
||||
@ -50,8 +54,9 @@ KS_DECLARE(ks_status_t) blade_request_create(blade_request_t **breqP, blade_hand
|
||||
breq->handle = bh;
|
||||
breq->pool = pool;
|
||||
breq->session_id = ks_pstrdup(pool, session_id);
|
||||
breq->message = json;
|
||||
breq->message = cJSON_Duplicate(json, 1);
|
||||
breq->message_id = cJSON_GetObjectCstr(json, "id");
|
||||
breq->callback = callback;
|
||||
|
||||
*breqP = breq;
|
||||
|
||||
@ -95,7 +100,7 @@ KS_DECLARE(ks_status_t) blade_response_create(blade_response_t **bresP, blade_ha
|
||||
bres->pool = pool;
|
||||
bres->session_id = ks_pstrdup(pool, session_id);
|
||||
bres->request = breq;
|
||||
bres->message = json;
|
||||
bres->message = cJSON_Duplicate(json, 1);
|
||||
|
||||
*bresP = bres;
|
||||
|
||||
@ -120,6 +125,88 @@ KS_DECLARE(ks_status_t) blade_response_destroy(blade_response_t **bresP)
|
||||
return KS_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
KS_DECLARE(ks_status_t) blade_rpc_request_create(ks_pool_t *pool, cJSON **json, cJSON **params, const char **id, const char *method)
|
||||
{
|
||||
cJSON *root = NULL;
|
||||
cJSON *p = NULL;
|
||||
uuid_t msgid;
|
||||
const char *mid = NULL;
|
||||
|
||||
ks_assert(pool);
|
||||
ks_assert(json);
|
||||
ks_assert(method);
|
||||
|
||||
root = cJSON_CreateObject();
|
||||
|
||||
cJSON_AddStringToObject(root, "jsonrpc", "2.0");
|
||||
|
||||
ks_uuid(&msgid);
|
||||
mid = ks_uuid_str(pool, &msgid);
|
||||
cJSON_AddStringToObject(root, "id", mid);
|
||||
ks_pool_free(pool, &mid);
|
||||
|
||||
cJSON_AddStringToObject(root, "method", method);
|
||||
|
||||
p = cJSON_CreateObject();
|
||||
cJSON_AddItemToObject(root, "params", p);
|
||||
|
||||
*json = root;
|
||||
if (params) *params = p;
|
||||
if (id) *id = cJSON_GetObjectCstr(root, "id");
|
||||
|
||||
return KS_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
KS_DECLARE(ks_status_t) blade_rpc_response_create(ks_pool_t *pool, cJSON **json, cJSON **result, const char *id)
|
||||
{
|
||||
cJSON *root = NULL;
|
||||
cJSON *r = NULL;
|
||||
|
||||
ks_assert(pool);
|
||||
ks_assert(json);
|
||||
ks_assert(id);
|
||||
|
||||
root = cJSON_CreateObject();
|
||||
|
||||
cJSON_AddStringToObject(root, "jsonrpc", "2.0");
|
||||
|
||||
cJSON_AddStringToObject(root, "id", id);
|
||||
|
||||
r = cJSON_CreateObject();
|
||||
cJSON_AddItemToObject(root, "result", r);
|
||||
|
||||
*json = root;
|
||||
if (result) *result = r;
|
||||
|
||||
return KS_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
KS_DECLARE(ks_status_t) blade_rpc_error_create(ks_pool_t *pool, cJSON **json, cJSON **error, const char *id, int32_t code, const char *message)
|
||||
{
|
||||
cJSON *root = NULL;
|
||||
cJSON *e = NULL;
|
||||
|
||||
ks_assert(pool);
|
||||
ks_assert(json);
|
||||
ks_assert(id);
|
||||
ks_assert(message);
|
||||
|
||||
root = cJSON_CreateObject();
|
||||
|
||||
cJSON_AddStringToObject(root, "jsonrpc", "2.0");
|
||||
|
||||
cJSON_AddStringToObject(root, "id", id);
|
||||
|
||||
e = cJSON_CreateObject();
|
||||
cJSON_AddNumberToObject(e, "code", code);
|
||||
cJSON_AddStringToObject(e, "message", message);
|
||||
cJSON_AddItemToObject(root, "error", e);
|
||||
|
||||
*json = root;
|
||||
if (error) *error = e;
|
||||
|
||||
return KS_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
/* For Emacs:
|
||||
* Local Variables:
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -430,6 +430,7 @@ ks_status_t blade_session_state_on_destroy(blade_session_t *bs)
|
||||
ks_assert(bs);
|
||||
|
||||
ks_log(KS_LOG_DEBUG, "Session (%s) state destroy\n", bs->id);
|
||||
|
||||
blade_handle_sessions_remove(bs);
|
||||
blade_session_destroy(&bs);
|
||||
|
||||
@ -483,21 +484,31 @@ ks_status_t blade_session_state_on_ready(blade_session_t *bs)
|
||||
}
|
||||
|
||||
|
||||
KS_DECLARE(ks_status_t) blade_session_send(blade_session_t *bs, cJSON *json)
|
||||
KS_DECLARE(ks_status_t) blade_session_send(blade_session_t *bs, cJSON *json, blade_response_callback_t callback)
|
||||
{
|
||||
blade_request_t *request = NULL;
|
||||
const char *method = NULL;
|
||||
const char *id = NULL;
|
||||
|
||||
ks_assert(bs);
|
||||
ks_assert(json);
|
||||
|
||||
method = cJSON_GetObjectCstr(json, "method");
|
||||
id = cJSON_GetObjectCstr(json, "id");
|
||||
if (method) {
|
||||
blade_request_create(&request, bs->handle, bs->id, json);
|
||||
// @note This is scenario 1
|
||||
// 1) Sending a request (client: method caller or consumer)
|
||||
ks_log(KS_LOG_DEBUG, "Session (%s) sending request (%s) for %s\n", bs->id, id, method);
|
||||
|
||||
blade_request_create(&request, bs->handle, bs->id, json, callback);
|
||||
ks_assert(request);
|
||||
|
||||
// @todo set request TTL and figure out when requests are checked for expiration (separate thread in the handle?)
|
||||
blade_handle_requests_add(request);
|
||||
} else {
|
||||
// @note This is scenario 3
|
||||
// 3) Sending a response or error (server: method callee or provider)
|
||||
ks_log(KS_LOG_DEBUG, "Session (%s) sending response (%s)\n", bs->id, id);
|
||||
}
|
||||
|
||||
if (list_empty(&bs->connections)) {
|
||||
@ -516,20 +527,18 @@ KS_DECLARE(ks_status_t) blade_session_send(blade_session_t *bs, cJSON *json)
|
||||
|
||||
ks_status_t blade_session_process(blade_session_t *bs, cJSON *json)
|
||||
{
|
||||
ks_status_t ret = KS_STATUS_SUCCESS;
|
||||
blade_request_t *breq = NULL;
|
||||
blade_response_t *bres = NULL;
|
||||
const char *jsonrpc = NULL;
|
||||
const char *id = NULL;
|
||||
const char *method = NULL;
|
||||
ks_bool_t disconnect = KS_FALSE;
|
||||
|
||||
ks_assert(bs);
|
||||
ks_assert(json);
|
||||
|
||||
ks_log(KS_LOG_DEBUG, "Session (%s) processing\n", bs->id);
|
||||
|
||||
// @todo teardown the message, convert into a blade_request_t or blade_response_t
|
||||
// @todo validate the jsonrpc fields
|
||||
|
||||
jsonrpc = cJSON_GetObjectCstr(json, "jsonrpc");
|
||||
if (!jsonrpc || strcmp(jsonrpc, "2.0")) {
|
||||
@ -549,13 +558,50 @@ ks_status_t blade_session_process(blade_session_t *bs, cJSON *json)
|
||||
|
||||
method = cJSON_GetObjectCstr(json, "method");
|
||||
if (method) {
|
||||
// @todo use method to find RPC callbacks
|
||||
// @note This is scenario 2
|
||||
// 2) Receiving a request (server: method callee or provider)
|
||||
blade_space_t *tmp_space = NULL;
|
||||
blade_method_t *tmp_method = NULL;
|
||||
blade_request_callback_t callback = NULL;
|
||||
char *space_name = ks_pstrdup(bs->pool, method);
|
||||
char *method_name = strrchr(space_name, '.');
|
||||
|
||||
blade_request_create(&breq, bs->handle, bs->id, json);
|
||||
ks_log(KS_LOG_DEBUG, "Session (%s) receiving request (%s) for %s\n", bs->id, id, method);
|
||||
|
||||
if (!method_name || method_name == space_name) {
|
||||
ks_pool_free(bs->pool, (void **)&space_name);
|
||||
// @todo send error response, code = -32601 (method not found)
|
||||
// @todo hangup session entirely?
|
||||
return KS_STATUS_FAIL;
|
||||
}
|
||||
*method_name = '\0';
|
||||
method_name++; // @todo check if can be postfixed safely on previous assignment, can't recall
|
||||
|
||||
tmp_space = blade_handle_space_lookup(bs->handle, space_name);
|
||||
if (tmp_space) tmp_method = blade_space_methods_get(tmp_space, method_name);
|
||||
|
||||
ks_pool_free(bs->pool, (void **)&space_name);
|
||||
|
||||
if (!tmp_method) {
|
||||
// @todo send error response, code = -32601 (method not found)
|
||||
// @todo hangup session entirely?
|
||||
return KS_STATUS_FAIL;
|
||||
}
|
||||
callback = blade_method_callback_get(tmp_method);
|
||||
ks_assert(callback);
|
||||
|
||||
blade_request_create(&breq, bs->handle, bs->id, json, NULL);
|
||||
ks_assert(breq);
|
||||
|
||||
// @todo call request callback handler
|
||||
disconnect = callback(breq);
|
||||
|
||||
blade_request_destroy(&breq);
|
||||
} else {
|
||||
// @note This is scenario 4
|
||||
// 4) Receiving a response or error (client: method caller or consumer)
|
||||
|
||||
ks_log(KS_LOG_DEBUG, "Session (%s) receiving response (%s)\n", bs->id, id);
|
||||
|
||||
breq = blade_handle_requests_get(bs->handle, id);
|
||||
if (!breq) {
|
||||
// @todo hangup session entirely?
|
||||
@ -563,18 +609,20 @@ ks_status_t blade_session_process(blade_session_t *bs, cJSON *json)
|
||||
}
|
||||
blade_handle_requests_remove(breq);
|
||||
|
||||
method = cJSON_GetObjectCstr(breq->message, "method");
|
||||
ks_assert(method);
|
||||
|
||||
// @todo use method to find RPC callbacks
|
||||
|
||||
blade_response_create(&bres, bs->handle, bs->id, breq, json);
|
||||
ks_assert(bres);
|
||||
|
||||
// @todo call response callback handler
|
||||
disconnect = breq->callback(bres);
|
||||
|
||||
blade_response_destroy(&bres);
|
||||
}
|
||||
|
||||
return ret;
|
||||
if (disconnect) {
|
||||
// @todo hangup session entirely?
|
||||
return KS_STATUS_FAIL;
|
||||
}
|
||||
|
||||
return KS_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
/* For Emacs:
|
||||
|
176
libs/libblade/src/blade_space.c
Normal file
176
libs/libblade/src/blade_space.c
Normal file
@ -0,0 +1,176 @@
|
||||
/*
|
||||
* Copyright (c) 2017, Shane Bryldt
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
*
|
||||
* * Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* * Neither the name of the original author; nor the names of any contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
|
||||
* OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include "blade.h"
|
||||
|
||||
struct blade_space_s {
|
||||
blade_handle_t *handle;
|
||||
ks_pool_t *pool;
|
||||
|
||||
const char *path;
|
||||
ks_hash_t *methods;
|
||||
};
|
||||
|
||||
|
||||
KS_DECLARE(ks_status_t) blade_space_create(blade_space_t **bsP, blade_handle_t *bh, const char *path)
|
||||
{
|
||||
blade_space_t *bs = NULL;
|
||||
ks_pool_t *pool = NULL;
|
||||
|
||||
ks_assert(bsP);
|
||||
ks_assert(bh);
|
||||
ks_assert(path);
|
||||
|
||||
pool = blade_handle_pool_get(bh);
|
||||
|
||||
bs = ks_pool_alloc(pool, sizeof(blade_space_t));
|
||||
bs->handle = bh;
|
||||
bs->pool = pool;
|
||||
bs->path = path; // @todo dup and keep copy? should mostly be literals
|
||||
ks_hash_create(&bs->methods, KS_HASH_MODE_CASE_INSENSITIVE, KS_HASH_FLAG_NOLOCK | KS_HASH_FLAG_DUP_CHECK, bs->pool);
|
||||
ks_assert(bs);
|
||||
|
||||
*bsP = bs;
|
||||
|
||||
ks_log(KS_LOG_DEBUG, "Space Created: %s\n", path);
|
||||
|
||||
return KS_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
KS_DECLARE(ks_status_t) blade_space_destroy(blade_space_t **bsP)
|
||||
{
|
||||
blade_space_t *bs = NULL;
|
||||
ks_hash_iterator_t *it = NULL;
|
||||
|
||||
ks_assert(bsP);
|
||||
ks_assert(*bsP);
|
||||
|
||||
bs = *bsP;
|
||||
|
||||
for (it = ks_hash_first(bs->methods, KS_UNLOCKED); it; it = ks_hash_next(&it)) {
|
||||
void *key = NULL;
|
||||
blade_method_t *value = NULL;
|
||||
|
||||
ks_hash_this(it, (const void **)&key, NULL, (void **)&value);
|
||||
blade_method_destroy(&value);
|
||||
}
|
||||
|
||||
ks_hash_destroy(&bs->methods);
|
||||
|
||||
ks_log(KS_LOG_DEBUG, "Space Destroyed: %s\n", bs->path);
|
||||
|
||||
ks_pool_free(bs->pool, bsP);
|
||||
|
||||
return KS_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
KS_DECLARE(blade_handle_t *) blade_space_handle_get(blade_space_t *bs)
|
||||
{
|
||||
ks_assert(bs);
|
||||
|
||||
return bs->handle;
|
||||
}
|
||||
|
||||
KS_DECLARE(const char *) blade_space_path_get(blade_space_t *bs)
|
||||
{
|
||||
ks_assert(bs);
|
||||
|
||||
return bs->path;
|
||||
}
|
||||
|
||||
KS_DECLARE(ks_status_t) blade_space_methods_add(blade_space_t *bs, blade_method_t *bm)
|
||||
{
|
||||
ks_status_t ret = KS_STATUS_SUCCESS;
|
||||
const char *name = NULL;
|
||||
blade_method_t *bm_old = NULL;
|
||||
|
||||
ks_assert(bs);
|
||||
ks_assert(bm);
|
||||
|
||||
name = blade_method_name_get(bm);
|
||||
ks_assert(name);
|
||||
|
||||
ks_hash_write_lock(bs->methods);
|
||||
bm_old = ks_hash_search(bs->methods, (void *)name, KS_UNLOCKED);
|
||||
if (bm_old) ks_hash_remove(bs->methods, (void *)name);
|
||||
ret = ks_hash_insert(bs->methods, (void *)name, (void *)bm);
|
||||
ks_hash_write_unlock(bs->methods);
|
||||
|
||||
if (bm_old) blade_method_destroy(&bm_old);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
KS_DECLARE(ks_status_t) blade_space_methods_remove(blade_space_t *bs, blade_method_t *bm)
|
||||
{
|
||||
ks_status_t ret = KS_STATUS_SUCCESS;
|
||||
const char *name = NULL;
|
||||
|
||||
ks_assert(bs);
|
||||
ks_assert(bm);
|
||||
|
||||
name = blade_method_name_get(bm);
|
||||
ks_assert(name);
|
||||
|
||||
ks_hash_write_lock(bs->methods);
|
||||
ks_hash_remove(bs->methods, (void *)name);
|
||||
ks_hash_write_unlock(bs->methods);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
KS_DECLARE(blade_method_t *) blade_space_methods_get(blade_space_t *bs, const char *name)
|
||||
{
|
||||
blade_method_t *bm = NULL;
|
||||
|
||||
ks_assert(bs);
|
||||
ks_assert(name);
|
||||
|
||||
ks_hash_read_lock(bs->methods);
|
||||
bm = ks_hash_search(bs->methods, (void *)name, KS_UNLOCKED);
|
||||
ks_hash_read_unlock(bs->methods);
|
||||
|
||||
return bm;
|
||||
}
|
||||
|
||||
|
||||
/* For Emacs:
|
||||
* Local Variables:
|
||||
* mode:c
|
||||
* indent-tabs-mode:t
|
||||
* tab-width:4
|
||||
* c-basic-offset:4
|
||||
* End:
|
||||
* For VIM:
|
||||
* vim:set softtabstop=4 shiftwidth=4 tabstop=4 noet:
|
||||
*/
|
@ -48,6 +48,7 @@ struct blade_handle_s {
|
||||
config_setting_t *config_datastore;
|
||||
|
||||
ks_hash_t *transports; // registered transports exposed by modules, NOT active connections
|
||||
ks_hash_t *spaces; // registered method spaces exposed by modules
|
||||
|
||||
//blade_identity_t *identity;
|
||||
blade_datastore_t *datastore;
|
||||
@ -69,6 +70,7 @@ struct blade_handle_transport_registration_s {
|
||||
blade_transport_callbacks_t *callbacks;
|
||||
};
|
||||
|
||||
|
||||
KS_DECLARE(ks_status_t) blade_handle_transport_registration_create(blade_handle_transport_registration_t **bhtrP,
|
||||
ks_pool_t *pool,
|
||||
blade_module_t *module,
|
||||
@ -133,6 +135,8 @@ KS_DECLARE(ks_status_t) blade_handle_create(blade_handle_t **bhP, ks_pool_t *poo
|
||||
|
||||
ks_hash_create(&bh->transports, KS_HASH_MODE_CASE_INSENSITIVE, KS_HASH_FLAG_NOLOCK | KS_HASH_FLAG_DUP_CHECK, bh->pool);
|
||||
ks_assert(bh->transports);
|
||||
ks_hash_create(&bh->spaces, KS_HASH_MODE_CASE_INSENSITIVE, KS_HASH_FLAG_NOLOCK | KS_HASH_FLAG_DUP_CHECK, bh->pool);
|
||||
ks_assert(bh->spaces);
|
||||
|
||||
ks_hash_create(&bh->connections, KS_HASH_MODE_CASE_INSENSITIVE, KS_HASH_FLAG_NOLOCK | KS_HASH_FLAG_DUP_CHECK, bh->pool);
|
||||
ks_assert(bh->connections);
|
||||
@ -144,6 +148,8 @@ KS_DECLARE(ks_status_t) blade_handle_create(blade_handle_t **bhP, ks_pool_t *poo
|
||||
|
||||
*bhP = bh;
|
||||
|
||||
ks_log(KS_LOG_DEBUG, "Created\n");
|
||||
|
||||
return KS_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
@ -168,10 +174,13 @@ KS_DECLARE(ks_status_t) blade_handle_destroy(blade_handle_t **bhP)
|
||||
ks_hash_destroy(&bh->requests);
|
||||
ks_hash_destroy(&bh->sessions);
|
||||
ks_hash_destroy(&bh->connections);
|
||||
ks_hash_destroy(&bh->spaces);
|
||||
ks_hash_destroy(&bh->transports);
|
||||
|
||||
if (bh->tpool && (flags & BH_MYTPOOL)) ks_thread_pool_destroy(&bh->tpool);
|
||||
|
||||
ks_log(KS_LOG_DEBUG, "Destroyed\n");
|
||||
|
||||
ks_pool_free(bh->pool, &bh);
|
||||
|
||||
if (pool && (flags & BH_MYPOOL)) {
|
||||
@ -249,13 +258,22 @@ KS_DECLARE(ks_status_t) blade_handle_shutdown(blade_handle_t *bh)
|
||||
blade_session_t *value = NULL;
|
||||
|
||||
ks_hash_this(it, (const void **)&key, NULL, (void **)&value);
|
||||
ks_hash_remove(bh->requests, key);
|
||||
//ks_hash_remove(bh->sessions, key);
|
||||
|
||||
blade_session_hangup(value);
|
||||
}
|
||||
while (ks_hash_count(bh->sessions) > 0) ks_sleep_ms(100);
|
||||
|
||||
// @todo call onshutdown and onunload callbacks for modules from DSOs, which will unregister transports and disconnect remaining unattached connections
|
||||
// @todo call onshutdown and onunload callbacks for modules from DSOs, which will unregister transports and spaces, and will disconnect remaining
|
||||
// unattached connections
|
||||
|
||||
for (it = ks_hash_first(bh->spaces, KS_UNLOCKED); it; it = ks_hash_next(&it)) {
|
||||
void *key = NULL;
|
||||
blade_space_t *value = NULL;
|
||||
|
||||
ks_hash_this(it, (const void **)&key, NULL, (void **)&value);
|
||||
blade_handle_space_unregister(value);
|
||||
}
|
||||
|
||||
// @todo unload DSOs
|
||||
|
||||
@ -316,11 +334,81 @@ KS_DECLARE(ks_status_t) blade_handle_transport_unregister(blade_handle_t *bh, co
|
||||
if (bhtr) ks_hash_remove(bh->transports, (void *)name);
|
||||
ks_hash_write_unlock(bh->transports);
|
||||
|
||||
if (bhtr) blade_handle_transport_registration_destroy(&bhtr);
|
||||
if (bhtr) {
|
||||
blade_handle_transport_registration_destroy(&bhtr);
|
||||
ks_log(KS_LOG_DEBUG, "Transport Unregistered: %s\n", name);
|
||||
}
|
||||
|
||||
return KS_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
KS_DECLARE(ks_status_t) blade_handle_space_register(blade_space_t *bs)
|
||||
{
|
||||
blade_handle_t *bh = NULL;
|
||||
const char *path = NULL;
|
||||
blade_space_t *bs_old = NULL;
|
||||
|
||||
ks_assert(bs);
|
||||
|
||||
bh = blade_space_handle_get(bs);
|
||||
ks_assert(bh);
|
||||
|
||||
path = blade_space_path_get(bs);
|
||||
ks_assert(path);
|
||||
|
||||
ks_hash_write_lock(bh->spaces);
|
||||
bs_old = ks_hash_search(bh->spaces, (void *)path, KS_UNLOCKED);
|
||||
if (bs_old) ks_hash_remove(bh->spaces, (void *)path);
|
||||
ks_hash_insert(bh->spaces, (void *)path, bs);
|
||||
ks_hash_write_unlock(bh->spaces);
|
||||
|
||||
if (bs_old) blade_space_destroy(&bs_old);
|
||||
|
||||
ks_log(KS_LOG_DEBUG, "Space Registered: %s\n", path);
|
||||
|
||||
return KS_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
KS_DECLARE(ks_status_t) blade_handle_space_unregister(blade_space_t *bs)
|
||||
{
|
||||
blade_handle_t *bh = NULL;
|
||||
const char *path = NULL;
|
||||
|
||||
ks_assert(bs);
|
||||
|
||||
bh = blade_space_handle_get(bs);
|
||||
ks_assert(bh);
|
||||
|
||||
path = blade_space_path_get(bs);
|
||||
ks_assert(path);
|
||||
|
||||
ks_hash_write_lock(bh->spaces);
|
||||
bs = ks_hash_search(bh->spaces, (void *)path, KS_UNLOCKED);
|
||||
if (bs) ks_hash_remove(bh->spaces, (void *)path);
|
||||
ks_hash_write_unlock(bh->spaces);
|
||||
|
||||
if (bs) {
|
||||
blade_space_destroy(&bs);
|
||||
ks_log(KS_LOG_DEBUG, "Space Unregistered: %s\n", path);
|
||||
}
|
||||
|
||||
return KS_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
KS_DECLARE(blade_space_t *) blade_handle_space_lookup(blade_handle_t *bh, const char *path)
|
||||
{
|
||||
blade_space_t *bs = NULL;
|
||||
|
||||
ks_assert(bh);
|
||||
ks_assert(path);
|
||||
|
||||
ks_hash_read_lock(bh->spaces);
|
||||
bs = ks_hash_search(bh->spaces, (void *)path, KS_UNLOCKED);
|
||||
ks_hash_read_unlock(bh->spaces);
|
||||
|
||||
return bs;
|
||||
}
|
||||
|
||||
KS_DECLARE(ks_status_t) blade_handle_connect(blade_handle_t *bh, blade_connection_t **bcP, blade_identity_t *target, const char *session_id)
|
||||
{
|
||||
ks_status_t ret = KS_STATUS_SUCCESS;
|
||||
|
@ -1,108 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2007-2014, Anthony Minessale II
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
*
|
||||
* * Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* * Neither the name of the original author; nor the names of any contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
|
||||
* OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include "blade.h"
|
||||
|
||||
|
||||
/*
|
||||
|
||||
Find bootstrap addr.
|
||||
Make a WSS connection to get validated and get group keys.
|
||||
Broadcast/Announce existence.
|
||||
|
||||
|
||||
HEADER
|
||||
|
||||
0 1 2 3
|
||||
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
|
||||
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||
| Ver |r|R|U|U| Channel no | Packet Length |
|
||||
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||
| SEQ |
|
||||
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||
| PAYLOAD ...... |
|
||||
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||
|
||||
r = IS Response
|
||||
R = IS Retransmission
|
||||
U = Unused
|
||||
|
||||
PAYLOAD
|
||||
|
||||
0 1 2 3
|
||||
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
|
||||
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||
| Instruction | Datatype | Length |
|
||||
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||
| PAYLOAD ..... |
|
||||
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||
|
||||
|
||||
*/
|
||||
|
||||
|
||||
typedef struct bpcp_header_s {
|
||||
uint32_t header;
|
||||
uint64_t seq;
|
||||
} bpcp_header_t;
|
||||
|
||||
typedef struct bpcp_channel_nfo_s {
|
||||
char *channel_name;
|
||||
unsigned char key[crypto_generichash_BYTES];
|
||||
uint32_t ttl;
|
||||
} bpcp_channel_nfo_t;
|
||||
|
||||
typedef struct bpcp_handle_s {
|
||||
ks_socket_t sock;
|
||||
ks_sockaddr_t local_addr;
|
||||
ks_sockaddr_t bootstrap_addr;
|
||||
ks_hash_t *channel_nfo_hash;
|
||||
} bpcp_handle_t;
|
||||
|
||||
KS_DECLARE(ks_status_t) bpcp_create(bpcp_handle_t **handle,
|
||||
const char *local_addr, ks_port_t local_port,
|
||||
const char *bootstrap_addr, ks_port_t bootstrap_port)
|
||||
{
|
||||
return KS_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
/* For Emacs:
|
||||
* Local Variables:
|
||||
* mode:c
|
||||
* indent-tabs-mode:t
|
||||
* tab-width:4
|
||||
* c-basic-offset:4
|
||||
* End:
|
||||
* For VIM:
|
||||
* vim:set softtabstop=4 shiftwidth=4 tabstop=4 noet:
|
||||
*/
|
@ -1,23 +1,23 @@
|
||||
/*
|
||||
* Copyright (c) 2007-2014, Anthony Minessale II
|
||||
* All rights reserved.
|
||||
*
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
*
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
*
|
||||
*
|
||||
* * Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
*
|
||||
* * Neither the name of the original author; nor the names of any contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
*
|
||||
*
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
@ -46,7 +46,8 @@
|
||||
#include "blade_session.h"
|
||||
#include "blade_protocol.h"
|
||||
#include "blade_datastore.h"
|
||||
#include "bpcp.h"
|
||||
#include "blade_space.h"
|
||||
#include "blade_method.h"
|
||||
|
||||
KS_BEGIN_EXTERN_C
|
||||
|
||||
|
@ -1,23 +1,23 @@
|
||||
/*
|
||||
* Copyright (c) 2007-2014, Anthony Minessale II
|
||||
* Copyright (c) 2017, Shane Bryldt
|
||||
* All rights reserved.
|
||||
*
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
*
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
*
|
||||
*
|
||||
* * Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
*
|
||||
* * Neither the name of the original author; nor the names of any contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
*
|
||||
*
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
@ -31,12 +31,15 @@
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#ifndef _BPCP_H_
|
||||
#define _BPCP_H_
|
||||
#ifndef _BLADE_METHOD_H_
|
||||
#define _BLADE_METHOD_H_
|
||||
#include <blade.h>
|
||||
|
||||
KS_BEGIN_EXTERN_C
|
||||
|
||||
KS_DECLARE(ks_status_t) blade_method_create(blade_method_t **bmP, blade_space_t *bs, const char *name, blade_request_callback_t callback);
|
||||
KS_DECLARE(ks_status_t) blade_method_destroy(blade_method_t **bmP);
|
||||
KS_DECLARE(const char *) blade_method_name_get(blade_method_t *bm);
|
||||
KS_DECLARE(blade_request_callback_t) blade_method_callback_get(blade_method_t *bm);
|
||||
KS_END_EXTERN_C
|
||||
|
||||
#endif
|
@ -36,10 +36,17 @@
|
||||
#include <blade.h>
|
||||
|
||||
KS_BEGIN_EXTERN_C
|
||||
KS_DECLARE(ks_status_t) blade_request_create(blade_request_t **breqP, blade_handle_t *bh, const char *session_id, cJSON *json);
|
||||
KS_DECLARE(ks_status_t) blade_request_create(blade_request_t **breqP,
|
||||
blade_handle_t *bh,
|
||||
const char *session_id,
|
||||
cJSON *json,
|
||||
blade_response_callback_t callback);
|
||||
KS_DECLARE(ks_status_t) blade_request_destroy(blade_request_t **breqP);
|
||||
KS_DECLARE(ks_status_t) blade_response_create(blade_response_t **bresP, blade_handle_t *bh, const char *session_id, blade_request_t *breq, cJSON *json);
|
||||
KS_DECLARE(ks_status_t) blade_response_destroy(blade_response_t **bresP);
|
||||
KS_DECLARE(ks_status_t) blade_rpc_request_create(ks_pool_t *pool, cJSON **json, cJSON **params, const char **id, const char *method);
|
||||
KS_DECLARE(ks_status_t) blade_rpc_response_create(ks_pool_t *pool, cJSON **json, cJSON **result, const char *id);
|
||||
KS_DECLARE(ks_status_t) blade_rpc_error_create(ks_pool_t *pool, cJSON **json, cJSON **error, const char *id, int32_t code, const char *message);
|
||||
KS_END_EXTERN_C
|
||||
|
||||
#endif
|
||||
|
@ -1,166 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2017, FreeSWITCH LLC
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
*
|
||||
* * Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* * Neither the name of the original author; nor the names of any contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
|
||||
* OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#ifndef _BLADE_RPCPROTO_H_
|
||||
#define _BLADE_RPCPROTO_H_
|
||||
|
||||
#include <ks_rpcmessage.h>
|
||||
#include <blade_types.h>
|
||||
|
||||
// temp typedefs to get compile going
|
||||
//typedef struct blade_peer_s blade_peer_t;
|
||||
//typedef struct blade_event_s blade_event_t;
|
||||
|
||||
#define KS_RPCMESSAGE_NAMESPACE_LENGTH 16
|
||||
#define KS_RPCMESSAGE_COMMAND_LENGTH 238
|
||||
#define KS_RPCMESSAGE_FQCOMMAND_LENGTH (KS_RPCMESSAGE_NAMESPACE_LENGTH+KS_RPCMESSAGE_COMMAND_LENGTH+1)
|
||||
#define KS_RPCMESSAGE_VERSION_LENGTH 9
|
||||
|
||||
|
||||
/*
|
||||
* contents to add to the "blade" field in rpc
|
||||
*/
|
||||
|
||||
typedef struct blade_rpc_fields_s {
|
||||
|
||||
const char *to;
|
||||
const char *from;
|
||||
const char *token;
|
||||
|
||||
} blade_rpc_fields_t;
|
||||
|
||||
|
||||
|
||||
enum jrpc_status_t {
|
||||
JRPC_PASS = (1 << 0),
|
||||
JRPC_SEND = (1 << 1),
|
||||
JRPC_EXIT = (1 << 2),
|
||||
JRPC_SEND_EXIT = JRPC_SEND + JRPC_EXIT,
|
||||
JRPC_ERROR = (1 << 3)
|
||||
};
|
||||
|
||||
|
||||
typedef enum jrpc_status_t (*jrpc_func_t) (cJSON *request, cJSON **replyP);
|
||||
|
||||
|
||||
/*
|
||||
* setup
|
||||
* -----
|
||||
*/
|
||||
|
||||
KS_DECLARE(ks_status_t) blade_rpc_init(ks_pool_t *pool);
|
||||
|
||||
|
||||
/*
|
||||
* namespace and call back registration
|
||||
* ------------------------------------
|
||||
*/
|
||||
KS_DECLARE(ks_status_t) blade_rpc_declare_namespace(char* namespace, const char* version);
|
||||
KS_DECLARE(ks_status_t) blade_rpc_register_function(char* namespace,
|
||||
char *command,
|
||||
jrpc_func_t func,
|
||||
jrpc_func_t respfunc);
|
||||
KS_DECLARE(ks_status_t) blade_rpc_register_custom_request_function(char* namespace,
|
||||
char *command,
|
||||
jrpc_func_t prefix_func,
|
||||
jrpc_func_t postfix_func);
|
||||
KS_DECLARE(ks_status_t) blade_rpc_register_custom_response_function(char *namespace,
|
||||
char *command,
|
||||
jrpc_func_t prefix_func,
|
||||
jrpc_func_t postfix_func);
|
||||
KS_DECLARE(void) blade_rpc_remove_namespace(char* namespace);
|
||||
|
||||
/*
|
||||
* template registration and inheritance
|
||||
* -------------------------------------
|
||||
*/
|
||||
KS_DECLARE(ks_status_t) blade_rpc_declare_template(char* templatename, const char* version);
|
||||
|
||||
KS_DECLARE(ks_status_t)blade_rpc_register_template_function(char *name,
|
||||
char *command,
|
||||
jrpc_func_t func,
|
||||
jrpc_func_t respfunc);
|
||||
|
||||
KS_DECLARE(ks_status_t)blade_rpc_inherit_template(char *namespace, char* template);
|
||||
|
||||
|
||||
/*
|
||||
* create a request message
|
||||
*/
|
||||
KS_DECLARE(ks_rpcmessageid_t) blade_rpc_create_request(char *namespace,
|
||||
char *method,
|
||||
blade_rpc_fields_t* fields,
|
||||
cJSON **paramsP,
|
||||
cJSON **requestP);
|
||||
|
||||
KS_DECLARE(ks_rpcmessageid_t) blade_rpc_create_response(cJSON *request,
|
||||
cJSON **reply,
|
||||
cJSON **response);
|
||||
|
||||
KS_DECLARE(ks_rpcmessageid_t) blade_rpc_create_errorresponse(cJSON *request,
|
||||
cJSON **reply,
|
||||
cJSON **response);
|
||||
|
||||
KS_DECLARE(ks_status_t) blade_rpc_parse_message(cJSON *message,
|
||||
char **namespace,
|
||||
char **method,
|
||||
char **version,
|
||||
uint32_t *idP,
|
||||
blade_rpc_fields_t **fieldsP);
|
||||
|
||||
/*
|
||||
* peer create/destroy
|
||||
* -------------------
|
||||
*/
|
||||
//KS_DECLARE(ks_status_t) blade_rpc_onconnect(ks_pool_t *pool, blade_peer_t* peer);
|
||||
//KS_DECLARE(ks_status_t) blade_rpc_disconnect(blade_peer_t* peer);
|
||||
|
||||
/*
|
||||
* send message
|
||||
* ------------
|
||||
*/
|
||||
KS_DECLARE(ks_status_t) blade_rpc_write(char *sessionid, char* data, uint32_t size); //uuid_t ?
|
||||
KS_DECLARE(ks_status_t) blade_rpc_write_json(cJSON* json);
|
||||
|
||||
|
||||
/*
|
||||
* process inbound message
|
||||
* -----------------------
|
||||
*/
|
||||
KS_DECLARE(ks_status_t) blade_rpc_process_data(const uint8_t *data, ks_size_t size);
|
||||
|
||||
KS_DECLARE(ks_status_t) blade_rpc_process_jsonmessage(cJSON *request);
|
||||
|
||||
|
||||
#endif
|
||||
|
@ -1,23 +1,23 @@
|
||||
/*
|
||||
* Copyright (c) 2017, Shane Bryldt
|
||||
* All rights reserved.
|
||||
*
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
*
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
*
|
||||
*
|
||||
* * Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
*
|
||||
* * Neither the name of the original author; nor the names of any contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
*
|
||||
*
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
@ -52,7 +52,7 @@ KS_DECLARE(void) blade_session_hangup(blade_session_t *bs);
|
||||
KS_DECLARE(ks_bool_t) blade_session_terminating(blade_session_t *bs);
|
||||
KS_DECLARE(ks_status_t) blade_session_connections_add(blade_session_t *bs, const char *id);
|
||||
KS_DECLARE(ks_status_t) blade_session_connections_remove(blade_session_t *bs, const char *id);
|
||||
KS_DECLARE(ks_status_t) blade_session_send(blade_session_t *bs, cJSON *json);
|
||||
KS_DECLARE(ks_status_t) blade_session_send(blade_session_t *bs, cJSON *json, blade_response_callback_t callback);
|
||||
KS_DECLARE(ks_status_t) blade_session_sending_push(blade_session_t *bs, cJSON *json);
|
||||
KS_DECLARE(ks_status_t) blade_session_sending_pop(blade_session_t *bs, cJSON **json);
|
||||
KS_DECLARE(ks_status_t) blade_session_receiving_push(blade_session_t *bs, cJSON *json);
|
||||
|
@ -1,23 +1,23 @@
|
||||
/*
|
||||
* Copyright (c) 2017, FreeSWITCH Solutions LLC
|
||||
* Copyright (c) 2017, Shane Bryldt
|
||||
* All rights reserved.
|
||||
*
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
*
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
*
|
||||
*
|
||||
* * Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
*
|
||||
* * Neither the name of the original author; nor the names of any contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
*
|
||||
*
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
@ -31,56 +31,21 @@
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
|
||||
#ifndef _KS_RPCMESSAGE_H_
|
||||
#define _KS_RPCMESSAGE_H_
|
||||
|
||||
#include "ks.h"
|
||||
#ifndef _BLADE_SPACE_H_
|
||||
#define _BLADE_SPACE_H_
|
||||
#include <blade.h>
|
||||
|
||||
KS_BEGIN_EXTERN_C
|
||||
|
||||
#define KS_RPCMESSAGE_NAMESPACE_LENGTH 16
|
||||
#define KS_RPCMESSAGE_COMMAND_LENGTH 238
|
||||
#define KS_RPCMESSAGE_FQCOMMAND_LENGTH (KS_RPCMESSAGE_NAMESPACE_LENGTH+KS_RPCMESSAGE_COMMAND_LENGTH+1)
|
||||
#define KS_RPCMESSAGE_VERSION_LENGTH 9
|
||||
|
||||
|
||||
typedef uint32_t ks_rpcmessageid_t;
|
||||
|
||||
|
||||
KS_DECLARE(void) ks_rpcmessage_init(ks_pool_t *pool);
|
||||
|
||||
KS_DECLARE(void*) ks_json_pool_alloc(ks_size_t size);
|
||||
KS_DECLARE(void) ks_json_pool_free(void *ptr);
|
||||
|
||||
|
||||
KS_DECLARE(ks_rpcmessageid_t) ks_rpcmessage_create_request(char *namespace,
|
||||
char *method,
|
||||
cJSON **paramsP,
|
||||
cJSON **requestP);
|
||||
|
||||
KS_DECLARE(ks_size_t) ks_rpc_create_buffer(char *namespace,
|
||||
char *method,
|
||||
cJSON **paramsP,
|
||||
ks_buffer_t *buffer);
|
||||
|
||||
KS_DECLARE(ks_rpcmessageid_t) ks_rpcmessage_create_response(
|
||||
const cJSON *request,
|
||||
cJSON **resultP,
|
||||
cJSON **responseP);
|
||||
|
||||
KS_DECLARE(ks_rpcmessageid_t) ks_rpcmessage_create_errorresponse(
|
||||
const cJSON *request,
|
||||
cJSON **errorP,
|
||||
cJSON **responseP);
|
||||
|
||||
KS_DECLARE(ks_bool_t) ks_rpcmessage_isrequest(cJSON *msg);
|
||||
|
||||
KS_DECLARE(ks_bool_t) ks_rpcmessage_isrpc(cJSON *msg);
|
||||
|
||||
KS_DECLARE(ks_status_t) blade_space_create(blade_space_t **bsP, blade_handle_t *bh, const char *path);
|
||||
KS_DECLARE(ks_status_t) blade_space_destroy(blade_space_t **bsP);
|
||||
KS_DECLARE(blade_handle_t *) blade_space_handle_get(blade_space_t *bs);
|
||||
KS_DECLARE(const char *) blade_space_path_get(blade_space_t *bs);
|
||||
KS_DECLARE(ks_status_t) blade_space_methods_add(blade_space_t *bs, blade_method_t *bm);
|
||||
KS_DECLARE(ks_status_t) blade_space_methods_remove(blade_space_t *bs, blade_method_t *bm);
|
||||
KS_DECLARE(blade_method_t *) blade_space_methods_get(blade_space_t *bs, const char *name);
|
||||
KS_END_EXTERN_C
|
||||
|
||||
#endif /* defined(_KS_RPCMESSAGE_H_) */
|
||||
#endif
|
||||
|
||||
/* For Emacs:
|
||||
* Local Variables:
|
@ -50,6 +50,11 @@ KS_DECLARE(ks_thread_pool_t *) blade_handle_tpool_get(blade_handle_t *bh);
|
||||
|
||||
KS_DECLARE(ks_status_t) blade_handle_transport_register(blade_handle_t *bh, blade_module_t *bm, const char *name, blade_transport_callbacks_t *callbacks);
|
||||
KS_DECLARE(ks_status_t) blade_handle_transport_unregister(blade_handle_t *bh, const char *name);
|
||||
|
||||
KS_DECLARE(ks_status_t) blade_handle_space_register(blade_space_t *bs);
|
||||
KS_DECLARE(ks_status_t) blade_handle_space_unregister(blade_space_t *bs);
|
||||
KS_DECLARE(blade_space_t *) blade_handle_space_lookup(blade_handle_t *bh, const char *path);
|
||||
|
||||
KS_DECLARE(ks_status_t) blade_handle_connect(blade_handle_t *bh, blade_connection_t **bcP, blade_identity_t *target, const char *session_id);
|
||||
|
||||
KS_DECLARE(blade_connection_t *) blade_handle_connections_get(blade_handle_t *bh, const char *cid);
|
||||
|
@ -47,6 +47,12 @@ typedef struct blade_connection_s blade_connection_t;
|
||||
typedef struct blade_session_s blade_session_t;
|
||||
typedef struct blade_request_s blade_request_t;
|
||||
typedef struct blade_response_s blade_response_t;
|
||||
typedef struct blade_space_s blade_space_t;
|
||||
typedef struct blade_method_s blade_method_t;
|
||||
|
||||
|
||||
typedef ks_bool_t (*blade_request_callback_t)(blade_request_t *breq);
|
||||
typedef ks_bool_t (*blade_response_callback_t)(blade_response_t *bres);
|
||||
|
||||
typedef struct blade_datastore_s blade_datastore_t;
|
||||
|
||||
@ -147,6 +153,7 @@ struct blade_request_s {
|
||||
|
||||
cJSON *message;
|
||||
const char *message_id; // pulled from message for easier keying
|
||||
blade_response_callback_t callback;
|
||||
// @todo ttl to wait for response before injecting an error response locally
|
||||
// @todo rpc response callback
|
||||
};
|
||||
|
@ -1,13 +1,8 @@
|
||||
AM_CFLAGS += -I$(abs_top_srcdir)/src/include -g -ggdb -O0
|
||||
AM_CFLAGS += -I$(abs_top_srcdir)/src/include -g -ggdb -O0
|
||||
TEST_LDADD = $(abs_top_builddir)/libblade.la -lconfig -lm -lpthread
|
||||
check_PROGRAMS =
|
||||
|
||||
|
||||
check_PROGRAMS += testrpcproto
|
||||
testrpcproto_SOURCES = testrpcproto.c tap.c
|
||||
testrpcproto_CFLAGS = $(AM_CFLAGS)
|
||||
testrpcproto_LDADD = $(TEST_LDADD)
|
||||
|
||||
check_PROGRAMS += testbuild
|
||||
testbuild_SOURCES = testbuild.c tap.c
|
||||
testbuild_CFLAGS = $(AM_CFLAGS)
|
||||
|
@ -1,724 +0,0 @@
|
||||
#pragma GCC diagnostic ignored "-Wunused-but-set-variable"
|
||||
#pragma GCC diagnostic ignored "-Wunused-variable"
|
||||
#pragma GCC diagnostic ignored "-Wunused-function"
|
||||
|
||||
|
||||
#include <blade_rpcproto.h>
|
||||
|
||||
#pragma GCC optimize ("O0")
|
||||
|
||||
|
||||
ks_pool_t *pool;
|
||||
ks_thread_pool_t *tpool;
|
||||
|
||||
|
||||
static ks_thread_t *threads[10];
|
||||
|
||||
static char idbuffer[51];
|
||||
|
||||
|
||||
|
||||
static enum jrpc_status_t process_widget(cJSON *msg, cJSON **response)
|
||||
{
|
||||
printf("entering process_widget\n");
|
||||
|
||||
char *b0 = cJSON_PrintUnformatted(msg);
|
||||
printf("Request: %s\n", b0);
|
||||
ks_pool_free(pool, &b0);
|
||||
|
||||
cJSON *resp = cJSON_CreateObject();
|
||||
cJSON_AddNumberToObject(resp, "code", 199);
|
||||
|
||||
//ks_rpcmessageid_t msgid = ks_rpcmessage_create_response(msg, &resp, response);
|
||||
ks_rpcmessageid_t msgid = blade_rpc_create_response(msg, &resp, response);
|
||||
|
||||
char *b1 = cJSON_PrintUnformatted(*response); //(*response);
|
||||
printf("Response: msgid %d\n%s\n", msgid, b1);
|
||||
ks_pool_free(pool, &b1);
|
||||
|
||||
printf("exiting process_wombat\n");
|
||||
|
||||
return JRPC_SEND;
|
||||
}
|
||||
|
||||
|
||||
static enum jrpc_status_t process_widget_response(cJSON *request, cJSON **msg)
|
||||
{
|
||||
printf("entering process_widget_response\n");
|
||||
printf("exiting process_widget_response\n");
|
||||
return JRPC_PASS;
|
||||
}
|
||||
|
||||
|
||||
|
||||
static enum jrpc_status_t process_wombat(cJSON *msg, cJSON **replyP)
|
||||
{
|
||||
printf("entering process_wombat\n");
|
||||
|
||||
char *b0 = cJSON_PrintUnformatted(msg);
|
||||
printf("\nRequest: %s\n\n", b0);
|
||||
ks_pool_free(pool, &b0);
|
||||
|
||||
cJSON *result = cJSON_CreateObject();
|
||||
cJSON_AddNumberToObject(result, "code", 99);
|
||||
cJSON *response;
|
||||
|
||||
// ks_rpcmessageid_t msgid = ks_rpcmessage_create_response(msg, &result, &response);
|
||||
ks_rpcmessageid_t msgid = blade_rpc_create_response(msg, &result, &response);
|
||||
|
||||
cJSON *response_copy = cJSON_Duplicate(response, 1);
|
||||
blade_rpc_process_jsonmessage(response_copy);
|
||||
|
||||
if (msgid != 0) {
|
||||
char *b1 = cJSON_PrintUnformatted(response); //(*response);
|
||||
printf("\nResponse: msgid %d\n%s\n\n", msgid, b1);
|
||||
blade_rpc_write_json(response);
|
||||
ks_pool_free(pool, &b1);
|
||||
}
|
||||
else {
|
||||
printf("process_wombat: unable to create response \n");
|
||||
return JRPC_ERROR;
|
||||
}
|
||||
|
||||
blade_rpc_fields_t *r_fields;
|
||||
|
||||
char *r_method;
|
||||
char *r_namespace;
|
||||
char *r_version;
|
||||
uint32_t r_id;
|
||||
|
||||
ks_status_t s1 = blade_rpc_parse_message(msg, &r_namespace, &r_method, &r_version, &r_id, &r_fields);
|
||||
|
||||
if (s1 == KS_STATUS_FAIL) {
|
||||
printf("process_wombat: blade_rpc_parse_message failed\n");
|
||||
return JRPC_ERROR;
|
||||
}
|
||||
|
||||
printf("\nprocess_wombat: blade_rpc_parse_message namespace %s, method %s, id %d, version %s, to %s, from %s, token %s\n\n",
|
||||
r_namespace, r_method, r_id, r_version,
|
||||
r_fields->to, r_fields->from, r_fields->token);
|
||||
|
||||
cJSON *parms2 = NULL;
|
||||
|
||||
char to[] = "tony@freeswitch.com/laptop?transport=wss&host=server1.freeswitch.com&port=1234";
|
||||
char from[] = "colm@freeswitch.com/laptop?transport=wss&host=server2.freeswitch.com&port=4321";
|
||||
char token[] = "abcdefhgjojklmnopqrst";
|
||||
|
||||
blade_rpc_fields_t fields;
|
||||
fields.to = to;
|
||||
fields.from = from;
|
||||
fields.token = token;
|
||||
|
||||
// msgid = ks_rpcmessage_create_request("app1", "widget", &parms2, replyP);
|
||||
msgid = blade_rpc_create_request(r_namespace, r_method, &fields, NULL, replyP);
|
||||
|
||||
if (!msgid) {
|
||||
printf("process wombat: create of next request failed\n");
|
||||
return JRPC_ERROR;
|
||||
}
|
||||
|
||||
b0 = cJSON_PrintUnformatted(*replyP);
|
||||
|
||||
if (!b0) {
|
||||
printf("process wombat: create of next request cannot be formatted\n");
|
||||
return JRPC_ERROR;
|
||||
}
|
||||
|
||||
|
||||
printf("\nprocess wombat: next request\n%s\n\n", b0);
|
||||
|
||||
|
||||
printf("\n\nexiting process_wombat with a reply to send\n");
|
||||
|
||||
return JRPC_SEND;
|
||||
}
|
||||
|
||||
static enum jrpc_status_t process_wombat_prerequest(cJSON *request, cJSON **msg)
|
||||
{
|
||||
printf("entering process_wombat_prerequest\n");
|
||||
printf("exiting process_wombat_prerequest\n");
|
||||
return JRPC_SEND;
|
||||
}
|
||||
|
||||
static enum jrpc_status_t process_wombat_postrequest(cJSON *request, cJSON **msg)
|
||||
{
|
||||
printf("entering process_wombat_postrequest\n");
|
||||
printf("exiting process_wombat_postrequest\n");
|
||||
return JRPC_PASS;
|
||||
}
|
||||
|
||||
|
||||
|
||||
static enum jrpc_status_t process_wombat_response(cJSON *request, cJSON **msg)
|
||||
{
|
||||
printf("entering process_wombat_response\n");
|
||||
printf("exiting process_wombat_response\n");
|
||||
return JRPC_PASS;
|
||||
}
|
||||
|
||||
static enum jrpc_status_t process_wombat_preresponse(cJSON *request, cJSON **msg)
|
||||
{
|
||||
|
||||
printf("entering process_wombat_preresponse\n");
|
||||
|
||||
cJSON *response = NULL;
|
||||
cJSON *result = NULL;
|
||||
|
||||
cJSON *parms2 = NULL;
|
||||
|
||||
//ks_rpcmessageid_t msgid = ks_rpcmessage_create_request("app1", "widget", &parms2, msg);
|
||||
|
||||
printf("exiting process_wombat_preresponse\n");
|
||||
return JRPC_SEND;
|
||||
}
|
||||
|
||||
static enum jrpc_status_t process_wombat_postresponse(cJSON *request, cJSON **msg)
|
||||
{
|
||||
printf("entering process_postwombat_response\n");
|
||||
printf("exiting process_postwombat_response\n");
|
||||
return JRPC_PASS;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
static enum jrpc_status_t process_badbunny( cJSON *msg, cJSON **response)
|
||||
{
|
||||
printf("entering process_badbunny\n");
|
||||
|
||||
char *b0 = cJSON_PrintUnformatted(msg);
|
||||
printf("\nRequest: %s\n\n", b0);
|
||||
ks_pool_free(pool, &b0);
|
||||
|
||||
cJSON *respvalue;
|
||||
|
||||
ks_rpcmessageid_t msgid = ks_rpcmessage_create_errorresponse(msg, &respvalue, response);
|
||||
|
||||
char *b2 = cJSON_PrintUnformatted(*response);
|
||||
printf("\nRequest: msgid %d\n%s\n\n", msgid, b2);
|
||||
ks_pool_free(pool, &b2);
|
||||
|
||||
//cJSON *respvalue = cJSON_CreateNumber(1);
|
||||
|
||||
|
||||
char *b1 = cJSON_PrintUnformatted(*response); //(*response);
|
||||
printf("\nResponse: %s\n\n", b1);
|
||||
ks_pool_free(pool, &b1);
|
||||
|
||||
printf("exiting process_badbunny\n");
|
||||
|
||||
|
||||
return JRPC_SEND;
|
||||
}
|
||||
|
||||
|
||||
void test01()
|
||||
{
|
||||
printf("**** testrpcmessages - test01 start\n"); fflush(stdout);
|
||||
|
||||
blade_rpc_declare_template("temp1", "1.0");
|
||||
|
||||
blade_rpc_register_template_function("temp1", "widget", process_widget, process_widget_response);
|
||||
|
||||
blade_rpc_declare_namespace("app1", "1.0");
|
||||
|
||||
blade_rpc_register_function("app1", "wombat", process_wombat, process_wombat_response);
|
||||
|
||||
blade_rpc_register_custom_request_function("app1", "wombat", process_wombat_prerequest, process_wombat_postresponse);
|
||||
blade_rpc_register_custom_response_function("app1", "wombat", process_wombat_preresponse, process_wombat_postresponse);
|
||||
|
||||
|
||||
/* message 1 */
|
||||
/* --------- */
|
||||
cJSON* request1 = NULL;
|
||||
cJSON* parms1 = NULL;
|
||||
|
||||
printf("\n\n\n - test01 message1 - basic message\n\n\n");
|
||||
|
||||
ks_rpcmessageid_t msgid = ks_rpcmessage_create_request("app1", "wombat", &parms1, &request1);
|
||||
if (msgid == 0) {
|
||||
printf("test01.1: unable to create message 1\n");
|
||||
return;
|
||||
}
|
||||
|
||||
if (!request1) {
|
||||
printf("test01.1: No json returned from create request 1\n");
|
||||
return;
|
||||
}
|
||||
|
||||
cJSON_AddStringToObject(parms1, "hello", "cruel world");
|
||||
|
||||
char *pdata = cJSON_PrintUnformatted(request1);
|
||||
|
||||
if (!pdata) {
|
||||
printf("test01.1: unable to parse cJSON object\n");
|
||||
return;
|
||||
}
|
||||
|
||||
printf("test01 request:\n%s\n", pdata);
|
||||
|
||||
|
||||
blade_rpc_process_jsonmessage(request1);
|
||||
|
||||
cJSON_Delete(request1);
|
||||
|
||||
ks_pool_free(pool, &pdata);
|
||||
|
||||
printf("\ntest01.1 complete\n");
|
||||
|
||||
|
||||
/* message 2 */
|
||||
/* --------- */
|
||||
|
||||
printf("\n\n\n test01 - message2 - test inherit\n\n\n");
|
||||
|
||||
blade_rpc_inherit_template("app1", "temp1");
|
||||
|
||||
cJSON* request2 = NULL;
|
||||
cJSON* parms2 = cJSON_CreateObject();
|
||||
|
||||
cJSON_AddStringToObject(parms2, "hello2", "cruel world once again");
|
||||
|
||||
msgid = ks_rpcmessage_create_request("app1", "temp1.widget", &parms2, &request2);
|
||||
if (msgid == 0) {
|
||||
printf("test01.2: failed to create a wombat\n");
|
||||
return;
|
||||
}
|
||||
|
||||
if (!request2) {
|
||||
printf("test01.2: No json returned from create request 1\n");
|
||||
return;
|
||||
}
|
||||
|
||||
pdata = cJSON_PrintUnformatted(request2);
|
||||
|
||||
if (!pdata) {
|
||||
printf("test01.2: unable to parse cJSON object\n");
|
||||
return;
|
||||
}
|
||||
|
||||
printf("\ntest01 request:\n%s\n\n\n", pdata);
|
||||
|
||||
blade_rpc_process_jsonmessage(request2);
|
||||
|
||||
cJSON_Delete(request2);
|
||||
ks_pool_free(pool, &pdata);
|
||||
|
||||
printf("\ntest01.2 complete\n");
|
||||
|
||||
return;
|
||||
|
||||
}
|
||||
|
||||
void test02()
|
||||
{
|
||||
printf("**** testrpcmessages - test02 start\n"); fflush(stdout);
|
||||
|
||||
blade_rpc_declare_namespace("app2", "1.0");
|
||||
|
||||
blade_rpc_register_function("app2", "wombat", process_wombat, process_wombat_response);
|
||||
|
||||
blade_rpc_inherit_template("app2", "temp1");
|
||||
|
||||
blade_rpc_register_custom_request_function("app2", "wombat", process_wombat_prerequest, process_wombat_postresponse);
|
||||
blade_rpc_register_custom_response_function("app2", "wombat", process_wombat_preresponse, process_wombat_postresponse);
|
||||
|
||||
blade_rpc_register_function("app2", "bunny", process_badbunny, NULL);
|
||||
|
||||
char to[] = "tony@freeswitch.com/laptop?transport=wss&host=server1.freeswitch.com&port=1234";
|
||||
char from[] = "colm@freeswitch.com/laptop?transport=wss&host=server2.freeswitch.com&port=4321";
|
||||
char token[] = "abcdefhgjojklmnopqrst";
|
||||
|
||||
blade_rpc_fields_t fields;
|
||||
fields.to = to;
|
||||
fields.from = from;
|
||||
fields.token = token;
|
||||
|
||||
|
||||
/* test the 4 different ways to handle param messages */
|
||||
|
||||
cJSON *params1 = NULL;
|
||||
cJSON *request1;
|
||||
|
||||
ks_rpcmessageid_t msgid = blade_rpc_create_request("app2", "temp1.widget2", &fields, ¶ms1, &request1);
|
||||
|
||||
if (!msgid) {
|
||||
printf("test02.1: create_request failed\n");
|
||||
return;
|
||||
}
|
||||
|
||||
cJSON_AddStringToObject(params1, "hello", "cruel world");
|
||||
|
||||
char *pdata = cJSON_PrintUnformatted(request1);
|
||||
|
||||
if (!pdata) {
|
||||
printf("test02.1: unable to parse cJSON object\n");
|
||||
return;
|
||||
}
|
||||
|
||||
printf("\ntest02.1 request:\n\n%s\n\n\n", pdata);
|
||||
|
||||
printf("\n\n -----------------------------------------\n\n");
|
||||
|
||||
ks_status_t s1 = blade_rpc_process_jsonmessage(request1);
|
||||
if (s1 == KS_STATUS_FAIL) {
|
||||
printf("test02.1: process request1 failed\n");
|
||||
return;
|
||||
}
|
||||
|
||||
printf(" -----------------------------------------\n\n\n\n");
|
||||
|
||||
ks_pool_free(pool, &pdata);
|
||||
|
||||
cJSON *reply1 = NULL;
|
||||
cJSON *response1 = NULL;
|
||||
|
||||
ks_rpcmessageid_t msgid2 = blade_rpc_create_response(request1, &reply1, &response1);
|
||||
|
||||
if (!msgid2) {
|
||||
printf("test02.1: create_response failed\n");
|
||||
return;
|
||||
}
|
||||
|
||||
cJSON_AddNumberToObject(reply1, "code", 10);
|
||||
cJSON_AddStringToObject(reply1, "farewell", "cruel server");
|
||||
|
||||
pdata = cJSON_PrintUnformatted(response1);
|
||||
|
||||
if (!pdata) {
|
||||
printf("test02.1: unable to parse cJSON response object\n");
|
||||
return;
|
||||
}
|
||||
|
||||
printf("\ntest02.1 response:\n\n%s\n\n\n", pdata);
|
||||
|
||||
printf("\n\n -----------------------------------------\n\n");
|
||||
|
||||
s1 = blade_rpc_process_jsonmessage(response1);
|
||||
if (s1 == KS_STATUS_FAIL) {
|
||||
printf("test02.1: process request1 failed\n");
|
||||
return;
|
||||
}
|
||||
|
||||
printf(" -----------------------------------------\n\n\n\n");
|
||||
|
||||
|
||||
ks_pool_free(pool, &pdata);
|
||||
|
||||
printf("**** testrpcmessages - test02 finished\n"); fflush(stdout);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
void test02a()
|
||||
{
|
||||
printf("**** testrpcmessages - test02a start\n"); fflush(stdout);
|
||||
|
||||
char to[] = "tony@freeswitch.com/laptop?transport=wss&host=server1.freeswitch.com&port=1234";
|
||||
char from[] = "colm@freeswitch.com/laptop?transport=wss&host=server2.freeswitch.com&port=4321";
|
||||
char token[] = "abcdefhgjojklmnopqrst";
|
||||
|
||||
blade_rpc_fields_t fields;
|
||||
fields.to = to;
|
||||
fields.from = from;
|
||||
fields.token = token;
|
||||
|
||||
|
||||
/* test the 4 different ways to handle param messages */
|
||||
|
||||
cJSON *request1;
|
||||
|
||||
ks_rpcmessageid_t msgid = blade_rpc_create_request("app2", "wombat", &fields, NULL, &request1);
|
||||
|
||||
if (!msgid) {
|
||||
printf("test02.1: create_request failed\n");
|
||||
return;
|
||||
}
|
||||
|
||||
char *pdata = cJSON_PrintUnformatted(request1);
|
||||
|
||||
if (!pdata) {
|
||||
printf("test02.1: unable to parse cJSON object\n");
|
||||
return;
|
||||
}
|
||||
|
||||
printf("\ntest02.1 request:\n\n%s\n\n\n", pdata);
|
||||
|
||||
printf("\n\n -----------------------------------------\n\n");
|
||||
|
||||
ks_status_t s1 = blade_rpc_process_jsonmessage(request1);
|
||||
if (s1 == KS_STATUS_FAIL) {
|
||||
printf("test02.1: process request1 failed\n");
|
||||
return;
|
||||
}
|
||||
|
||||
printf(" -----------------------------------------\n\n\n\n");
|
||||
|
||||
|
||||
|
||||
|
||||
ks_pool_free(pool, &pdata);
|
||||
|
||||
cJSON *response1 = NULL;
|
||||
|
||||
ks_rpcmessageid_t msgid2 = blade_rpc_create_response(request1, NULL, &response1);
|
||||
|
||||
if (!msgid2) {
|
||||
printf("test02.1: create_response failed\n");
|
||||
return;
|
||||
}
|
||||
|
||||
pdata = cJSON_PrintUnformatted(response1);
|
||||
|
||||
printf("\ntest02.1 response:\n\n%s\n\n\n", pdata);
|
||||
|
||||
ks_pool_free(pool, &pdata);
|
||||
|
||||
printf("**** testrpcmessages - test02a finished\n\n\n"); fflush(stdout);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
void test02b()
|
||||
{
|
||||
printf("**** testrpcmessages - test02b start\n"); fflush(stdout);
|
||||
|
||||
char to[] = "tony@freeswitch.com/laptop?transport=wss&host=server1.freeswitch.com&port=1234";
|
||||
char from[] = "colm@freeswitch.com/laptop?transport=wss&host=server2.freeswitch.com&port=4321";
|
||||
char token[] = "abcdefhgjojklmnopqrst";
|
||||
|
||||
blade_rpc_fields_t fields;
|
||||
fields.to = to;
|
||||
fields.from = from;
|
||||
fields.token = token;
|
||||
|
||||
|
||||
/* test the 4 different ways to handle param messages */
|
||||
|
||||
cJSON *params1 = cJSON_CreateNumber(4321);
|
||||
cJSON *request1;
|
||||
|
||||
ks_rpcmessageid_t msgid = blade_rpc_create_request("app2", "temp1.widget", &fields, ¶ms1, &request1);
|
||||
|
||||
if (!msgid) {
|
||||
printf("test02.1: create_request failed\n");
|
||||
return;
|
||||
}
|
||||
|
||||
char *pdata = cJSON_PrintUnformatted(request1);
|
||||
|
||||
if (!pdata) {
|
||||
printf("test02.1: unable to parse cJSON object\n");
|
||||
return;
|
||||
}
|
||||
|
||||
printf("\ntest02.1 request:\n\n%s\n\n\n", pdata);
|
||||
|
||||
ks_pool_free(pool, &pdata);
|
||||
|
||||
cJSON *reply1 = cJSON_CreateString("successful");
|
||||
cJSON *response1 = NULL;
|
||||
|
||||
ks_rpcmessageid_t msgid2 = blade_rpc_create_response(request1, &reply1, &response1);
|
||||
|
||||
if (!msgid2) {
|
||||
printf("test02.1: create_response failed\n");
|
||||
return;
|
||||
}
|
||||
|
||||
pdata = cJSON_PrintUnformatted(response1);
|
||||
|
||||
printf("\ntest02.1 response:\n\n%s\n\n\n", pdata);
|
||||
|
||||
ks_pool_free(pool, &pdata);
|
||||
|
||||
printf("**** testrpcmessages - test02b finished\n"); fflush(stdout);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
void test02c()
|
||||
{
|
||||
|
||||
printf("**** testrpcmessages - test02c start\n"); fflush(stdout);
|
||||
|
||||
char to[] = "tony@freeswitch.com/laptop?transport=wss&host=server1.freeswitch.com&port=1234";
|
||||
char from[] = "colm@freeswitch.com/laptop?transport=wss&host=server2.freeswitch.com&port=4321";
|
||||
char token[] = "abcdefhgjojklmnopqrst";
|
||||
|
||||
blade_rpc_fields_t fields;
|
||||
fields.to = to;
|
||||
fields.from = from;
|
||||
fields.token = token;
|
||||
|
||||
|
||||
/* test the 4 different ways to handle param messages */
|
||||
|
||||
cJSON *params1 = cJSON_CreateObject();
|
||||
|
||||
cJSON_AddStringToObject(params1, "string1", "here is a string");
|
||||
cJSON_AddNumberToObject(params1, "number1", 4242);
|
||||
|
||||
cJSON *request1;
|
||||
|
||||
ks_rpcmessageid_t msgid = blade_rpc_create_request("app2", "bunny", &fields, ¶ms1, &request1);
|
||||
|
||||
if (!msgid) {
|
||||
printf("test02.1: create_request failed\n");
|
||||
return;
|
||||
}
|
||||
|
||||
cJSON_AddStringToObject(params1, "hello", "cruel world");
|
||||
|
||||
char *pdata = cJSON_PrintUnformatted(request1);
|
||||
|
||||
if (!pdata) {
|
||||
printf("test02.1: unable to parse cJSON object\n");
|
||||
return;
|
||||
}
|
||||
|
||||
printf("\ntest02.1 request:\n\n%s\n\n\n", pdata);
|
||||
|
||||
ks_pool_free(pool, &pdata);
|
||||
|
||||
|
||||
cJSON *reply1 = cJSON_CreateObject();
|
||||
cJSON_AddNumberToObject(reply1, "code", 10);
|
||||
cJSON_AddStringToObject(reply1, "farewell", "cruel server");
|
||||
|
||||
|
||||
cJSON *response1 = NULL;
|
||||
|
||||
ks_rpcmessageid_t msgid2 = blade_rpc_create_response(request1, &reply1, &response1);
|
||||
|
||||
if (!msgid2) {
|
||||
printf("test02.1: create_response failed\n");
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
pdata = cJSON_PrintUnformatted(response1);
|
||||
|
||||
printf("\ntest02.1 response:\n\n%s\n\n\n", pdata);
|
||||
|
||||
ks_pool_free(pool, &pdata);
|
||||
|
||||
printf("**** testrpcmessages - test02c finished\n"); fflush(stdout);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/* test06 */
|
||||
/* ------ */
|
||||
|
||||
static void *testnodelocking_ex1(ks_thread_t *thread, void *data)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static void *testnodelocking_ex2(ks_thread_t *thread, void *data)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
void test06()
|
||||
{
|
||||
printf("**** testmessages - test06 start\n"); fflush(stdout);
|
||||
|
||||
ks_thread_t *t0;
|
||||
ks_thread_create(&t0, testnodelocking_ex1, NULL, pool);
|
||||
|
||||
ks_thread_t *t1;
|
||||
ks_thread_create(&t1, testnodelocking_ex2, NULL, pool);
|
||||
|
||||
ks_thread_join(t1);
|
||||
ks_thread_join(t0);
|
||||
|
||||
printf("\n\n* **testmessages - test06 -- threads complete\n\n"); fflush(stdout);
|
||||
|
||||
printf("**** testmessages - test06 start\n"); fflush(stdout);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
|
||||
int main(int argc, char *argv[]) {
|
||||
|
||||
printf("testmessages - start\n");
|
||||
|
||||
int tests[100];
|
||||
if (argc == 0) {
|
||||
tests[0] = 1;
|
||||
tests[1] = 2;
|
||||
tests[2] = 3;
|
||||
tests[3] = 4;
|
||||
tests[4] = 5;
|
||||
}
|
||||
else {
|
||||
for(int tix=1; tix<100 && tix<argc; ++tix) {
|
||||
long i = strtol(argv[tix], NULL, 0);
|
||||
tests[tix] = i;
|
||||
}
|
||||
}
|
||||
|
||||
ks_init();
|
||||
ks_global_set_default_logger(7);
|
||||
|
||||
|
||||
ks_status_t status;
|
||||
|
||||
status = ks_pool_open(&pool);
|
||||
|
||||
blade_rpc_init(pool);
|
||||
|
||||
blade_rpc_declare_template("temp1", "1.0");
|
||||
|
||||
blade_rpc_register_template_function("temp1", "widget", process_widget, process_widget_response);
|
||||
blade_rpc_register_template_function("temp1", "widget2", process_widget, process_widget_response);
|
||||
blade_rpc_register_template_function("temp1", "widget3", process_widget, process_widget_response);
|
||||
|
||||
|
||||
for (int tix=0; tix<argc; ++tix) {
|
||||
|
||||
|
||||
if (tests[tix] == 1) {
|
||||
test01();
|
||||
continue;
|
||||
}
|
||||
|
||||
if (tests[tix] == 2) {
|
||||
test02();
|
||||
printf("\n\n");
|
||||
test02a();
|
||||
printf("\n\n");
|
||||
test02b();
|
||||
printf("\n\n");
|
||||
test02c();
|
||||
printf("\n\n");
|
||||
continue;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
@ -10,13 +10,13 @@ lib_LTLIBRARIES = libks.la
|
||||
libks_la_SOURCES = src/ks.c src/ks_string.c src/ks_json.c src/cJSON.c src/cJSON_Utils.c src/ks_thread.c src/ks_thread_pool.c src/ks_mutex.c src/ks_config.c
|
||||
libks_la_SOURCES += src/ks_log.c src/ks_socket.c src/ks_buffer.c src/ks_pool.c src/simclist.c
|
||||
libks_la_SOURCES += src/ks_time.c src/ks_printf.c src/ks_hash.c src/ks_q.c src/ks_dso.c # src/ks_dht.c
|
||||
libks_la_SOURCES += src/ks_ssl.c src/kws.c src/ks_rng.c src/ks_rpcmessage.c src/ks_base64.c
|
||||
libks_la_SOURCES += src/ks_ssl.c src/kws.c src/ks_rng.c src/ks_base64.c
|
||||
libks_la_SOURCES += src/utp/utp_api.cpp src/utp/utp_callbacks.cpp src/utp/utp_hash.cpp src/utp/utp_internal.cpp
|
||||
libks_la_SOURCES += src/utp/utp_packedsockaddr.cpp src/utp/utp_utils.cpp src/ks_bencode.c
|
||||
libks_la_SOURCES += src/dht/ks_dht.c src/dht/ks_dht_datagram.c src/dht/ks_dht_endpoint.c src/dht/ks_dht_message.c src/dht/ks_dht_transaction.c
|
||||
libks_la_SOURCES += src/dht/ks_dht_job.c src/dht/ks_dht_search.c src/dht/ks_dht_publish.c src/dht/ks_dht_distribute.c src/dht/ks_dht_storageitem.c
|
||||
libks_la_SOURCES += src/dht/ks_dht_bucket.c
|
||||
libks_la_SOURCES += crypt/aeskey.c crypt/aestab.c crypt/sha2.c crypt/twofish.c crypt/aes_modes.c crypt/aescrypt.c crypt/twofish_cfb.c
|
||||
libks_la_SOURCES += crypt/aeskey.c crypt/aestab.c crypt/sha2.c crypt/twofish.c crypt/aes_modes.c crypt/aescrypt.c crypt/twofish_cfb.c
|
||||
#aes.h aescpp.h brg_endian.h aesopt.h aestab.h brg_types.h sha2.h twofish.h
|
||||
libks_la_SOURCES += src/ks_acl.c
|
||||
|
||||
@ -29,14 +29,10 @@ library_include_HEADERS = src/include/ks_config.h src/include/ks.h src/include/k
|
||||
library_include_HEADERS += src/include/ks_thread_pool.h src/include/ks_cJSON.h src/include/ks_cJSON_Utils.h
|
||||
library_include_HEADERS += src/include/ks_pool.h src/include/simclist.h src/include/ks_time.h src/include/ks_q.h src/include/ks_socket.h
|
||||
library_include_HEADERS += src/include/ks_dso.h src/include/ks_platform.h src/include/ks_types.h # src/include/ks_rng.h src/include/ks_dht.h
|
||||
library_include_HEADERS += src/include/ks_printf.h src/include/ks_hash.h src/include/ks_ssl.h src/include/kws.h
|
||||
library_include_HEADERS += src/include/ks_rpcmessage.h src/include/ks_base64.h
|
||||
library_include_HEADERS += src/include/ks_printf.h src/include/ks_hash.h src/include/ks_ssl.h src/include/kws.h
|
||||
library_include_HEADERS += src/include/ks_base64.h
|
||||
library_include_HEADERS += src/utp/utp_internal.h src/utp/utp.h src/utp/utp_types.h src/utp/utp_callbacks.h src/utp/utp_templates.h
|
||||
library_include_HEADERS += src/utp/utp_hash.h src/utp/utp_packedsockaddr.h src/utp/utp_utils.h src/include/ks_utp.h src/include/ks_acl.h
|
||||
|
||||
tests: libks.la
|
||||
$(MAKE) -C test tests
|
||||
|
||||
|
||||
|
||||
|
||||
|
@ -1,23 +1,23 @@
|
||||
/*
|
||||
* Copyright (c) 2007-2014, Anthony Minessale II
|
||||
* All rights reserved.
|
||||
*
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
*
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
*
|
||||
*
|
||||
* * Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
*
|
||||
* * Neither the name of the original author; nor the names of any contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
*
|
||||
*
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
@ -137,7 +137,6 @@ KS_DECLARE(void) ks_random_string(char *buf, uint16_t len, char *set);
|
||||
#include "ks_bencode.h"
|
||||
#include "ks_rng.h"
|
||||
#include "ks_acl.h"
|
||||
#include "ks_rpcmessage.h"
|
||||
#include "ks_base64.h"
|
||||
|
||||
KS_END_EXTERN_C
|
||||
|
@ -1,317 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2017 FreeSWITCH Solutions LLC
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
*
|
||||
* * Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* * Neither the name of the original author; nor the names of any contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
|
||||
* OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#pragma GCC optimize ("O0")
|
||||
|
||||
|
||||
#include <ks.h>
|
||||
#include <ks_rpcmessage.h>
|
||||
#include <ks_buffer.h>
|
||||
|
||||
struct
|
||||
{
|
||||
|
||||
ks_mutex_t *id_mutex;
|
||||
uint32_t message_id;
|
||||
|
||||
ks_pool_t *pool;
|
||||
|
||||
} handle = {NULL, 0, NULL};
|
||||
|
||||
const char PROTOCOL[] = "jsonrpc";
|
||||
const char PROTOCOL_VERSION[] = "2.0";
|
||||
const char ID[] = "id";
|
||||
const char METHOD[] = "method";
|
||||
const char PARAMS[] = "params";
|
||||
const char ERROR[] = "error";
|
||||
const char RESULT[] = "result";
|
||||
|
||||
|
||||
|
||||
KS_DECLARE(void*) ks_json_pool_alloc(ks_size_t size)
|
||||
{
|
||||
return ks_pool_alloc(handle.pool, size);
|
||||
}
|
||||
|
||||
KS_DECLARE(void) ks_json_pool_free(void *ptr)
|
||||
{
|
||||
ks_pool_free(handle.pool, &ptr);
|
||||
}
|
||||
|
||||
|
||||
KS_DECLARE(void) ks_rpcmessage_init(ks_pool_t* pool)
|
||||
{
|
||||
if (!handle.id_mutex) {
|
||||
ks_mutex_create(&handle.id_mutex, KS_MUTEX_FLAG_DEFAULT, pool);
|
||||
handle.pool = pool;
|
||||
|
||||
cJSON_Hooks hooks;
|
||||
hooks.malloc_fn = ks_json_pool_alloc;
|
||||
hooks.free_fn = ks_json_pool_free;
|
||||
cJSON_InitHooks(&hooks);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
static uint32_t ks_rpcmessage_next_id()
|
||||
{
|
||||
uint32_t message_id;
|
||||
|
||||
ks_mutex_lock(handle.id_mutex);
|
||||
|
||||
++handle.message_id;
|
||||
|
||||
if (!handle.message_id) {
|
||||
++handle.message_id;
|
||||
}
|
||||
|
||||
message_id = handle.message_id;
|
||||
|
||||
ks_mutex_unlock(handle.id_mutex);
|
||||
|
||||
return message_id;
|
||||
}
|
||||
|
||||
|
||||
static cJSON *ks_rpcmessage_new(uint32_t id)
|
||||
{
|
||||
cJSON *obj = cJSON_CreateObject();
|
||||
cJSON_AddItemToObject(obj, PROTOCOL, cJSON_CreateString(PROTOCOL_VERSION));
|
||||
|
||||
if (id) {
|
||||
cJSON_AddItemToObject(obj, ID, cJSON_CreateNumber(id));
|
||||
}
|
||||
|
||||
return obj;
|
||||
}
|
||||
|
||||
static cJSON *ks_rpcmessage_dup(cJSON *msgid)
|
||||
{
|
||||
cJSON *obj = cJSON_CreateObject();
|
||||
cJSON_AddItemToObject(obj, PROTOCOL, cJSON_CreateString(PROTOCOL_VERSION));
|
||||
|
||||
if (msgid) {
|
||||
cJSON_AddItemToObject(obj, ID, cJSON_Duplicate(msgid, 0));
|
||||
}
|
||||
|
||||
return obj;
|
||||
}
|
||||
|
||||
KS_DECLARE(ks_bool_t) ks_rpcmessage_isrequest(cJSON *msg)
|
||||
{
|
||||
cJSON *result = cJSON_GetObjectItem(msg, RESULT);
|
||||
cJSON *error = cJSON_GetObjectItem(msg, ERROR);
|
||||
|
||||
if (result || error) {
|
||||
return KS_FALSE;
|
||||
}
|
||||
|
||||
return KS_TRUE;
|
||||
}
|
||||
|
||||
KS_DECLARE(ks_bool_t) ks_rpcmessage_isrpc(cJSON *msg)
|
||||
{
|
||||
cJSON *rpc = cJSON_GetObjectItem(msg, PROTOCOL);
|
||||
|
||||
if (rpc) {
|
||||
return KS_FALSE;
|
||||
}
|
||||
|
||||
return KS_TRUE;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
KS_DECLARE(ks_rpcmessageid_t) ks_rpcmessage_create_request(char *namespace,
|
||||
char *command,
|
||||
cJSON **paramsP,
|
||||
cJSON **requestP)
|
||||
{
|
||||
cJSON *msg, *params = NULL;
|
||||
*requestP = NULL;
|
||||
|
||||
ks_rpcmessageid_t msgid = ks_rpcmessage_next_id();
|
||||
msg = ks_rpcmessage_new(msgid);
|
||||
|
||||
if (paramsP) {
|
||||
|
||||
if (*paramsP) { /* parameters have been passed */
|
||||
params = *paramsP;
|
||||
}
|
||||
else {
|
||||
params = cJSON_CreateObject();
|
||||
*paramsP = params;
|
||||
}
|
||||
|
||||
cJSON_AddItemToObject(msg, PARAMS, params);
|
||||
}
|
||||
|
||||
char fqcommand[KS_RPCMESSAGE_FQCOMMAND_LENGTH];
|
||||
memset(fqcommand, 0, sizeof(fqcommand));
|
||||
|
||||
sprintf(fqcommand, "%s.%s", namespace, command);
|
||||
|
||||
cJSON_AddItemToObject(msg, METHOD, cJSON_CreateString(fqcommand));
|
||||
|
||||
*requestP = msg;
|
||||
return msgid;
|
||||
}
|
||||
|
||||
KS_DECLARE(ks_size_t) ks_rpc_create_buffer(char *namespace,
|
||||
char *method,
|
||||
cJSON **params,
|
||||
ks_buffer_t *buffer)
|
||||
{
|
||||
|
||||
cJSON *message;
|
||||
|
||||
ks_rpcmessageid_t msgid = ks_rpcmessage_create_request(namespace, method, params, &message);
|
||||
|
||||
if (!msgid) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
if ( (*params)->child == NULL) {
|
||||
cJSON_AddNullToObject(*params, "bladenull");
|
||||
}
|
||||
|
||||
const char* b = cJSON_PrintUnformatted(message);
|
||||
ks_size_t size = strlen(b);
|
||||
|
||||
ks_buffer_write(buffer, b, size);
|
||||
cJSON_Delete(message);
|
||||
|
||||
return size;
|
||||
}
|
||||
|
||||
|
||||
static ks_rpcmessageid_t ks_rpcmessage_get_messageid(const cJSON *msg, cJSON **cmsgidP)
|
||||
{
|
||||
ks_rpcmessageid_t msgid = 0;
|
||||
|
||||
cJSON *cmsgid = cJSON_GetObjectItem(msg, ID);
|
||||
|
||||
if (cmsgid->type == cJSON_Number) {
|
||||
msgid = (ks_rpcmessageid_t) cmsgid->valueint;
|
||||
}
|
||||
|
||||
*cmsgidP = cmsgid;
|
||||
|
||||
return msgid;
|
||||
}
|
||||
|
||||
|
||||
static ks_rpcmessageid_t ks_rpcmessage_new_response(
|
||||
const cJSON *request,
|
||||
cJSON **result,
|
||||
cJSON **pmsg)
|
||||
{
|
||||
cJSON *respmsg = NULL;
|
||||
cJSON *cmsgid = NULL;
|
||||
|
||||
cJSON *command = cJSON_GetObjectItem(request, METHOD);
|
||||
|
||||
ks_rpcmessageid_t msgid = ks_rpcmessage_get_messageid(request, &cmsgid );
|
||||
|
||||
if (!msgid || !command) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
*pmsg = respmsg = ks_rpcmessage_dup(cmsgid);
|
||||
|
||||
cJSON_AddItemToObject(respmsg, METHOD, cJSON_Duplicate(command, 0));
|
||||
|
||||
if (result && *result) {
|
||||
cJSON_AddItemToObject(respmsg, RESULT, *result);
|
||||
}
|
||||
|
||||
return msgid;
|
||||
}
|
||||
|
||||
|
||||
KS_DECLARE(ks_rpcmessageid_t) ks_rpcmessage_create_response(
|
||||
const cJSON *request,
|
||||
cJSON **resultP,
|
||||
cJSON **responseP)
|
||||
{
|
||||
ks_rpcmessageid_t msgid = ks_rpcmessage_new_response(request, resultP, responseP);
|
||||
|
||||
cJSON *respmsg = *responseP;
|
||||
|
||||
if (msgid) {
|
||||
|
||||
if (resultP && *resultP == NULL) {
|
||||
cJSON *result = cJSON_CreateObject();
|
||||
*resultP = result;
|
||||
cJSON_AddItemToObject(respmsg, RESULT, result);
|
||||
}
|
||||
}
|
||||
|
||||
return msgid;
|
||||
}
|
||||
|
||||
KS_DECLARE(ks_rpcmessageid_t) ks_rpcmessage_create_errorresponse(
|
||||
const cJSON *request,
|
||||
cJSON **errorP,
|
||||
cJSON **responseP)
|
||||
{
|
||||
ks_rpcmessageid_t msgid = ks_rpcmessage_new_response(request, NULL, responseP);
|
||||
cJSON *respmsg = *responseP;
|
||||
|
||||
if (msgid) {
|
||||
|
||||
if (errorP && *errorP == NULL) {
|
||||
cJSON *error = cJSON_CreateObject();
|
||||
*errorP = error;
|
||||
cJSON_AddItemToObject(respmsg, ERROR, error);
|
||||
}
|
||||
else if (errorP && *errorP) {
|
||||
cJSON_AddItemToObject(*responseP, ERROR, *errorP);
|
||||
}
|
||||
}
|
||||
|
||||
return msgid;
|
||||
}
|
||||
|
||||
|
||||
/* For Emacs:
|
||||
* Local Variables:
|
||||
* mode:c
|
||||
* indent-tabs-mode:t
|
||||
* tab-width:4
|
||||
* c-basic-offset:4
|
||||
* End:
|
||||
* For VIM:
|
||||
* vim:set softtabstop=4 shiftwidth=4 tabstop=4 noet:
|
||||
*/
|
@ -1,14 +1,9 @@
|
||||
AM_CFLAGS += -I$(abs_top_srcdir)/src/include -g -ggdb -O0 $(openssl_CFLAGS)
|
||||
TEST_LDADD = $(abs_top_builddir)/libks.la $(openssl_LIBS)
|
||||
check_PROGRAMS =
|
||||
check_PROGRAMS =
|
||||
|
||||
EXTRA_DIST = tap.h
|
||||
|
||||
check_PROGRAMS += testmessages
|
||||
testmessages_SOURCES = testmessages.c tap.c
|
||||
testmessages_CFLAGS = $(AM_CFLAGS)
|
||||
testmessages_LDADD = $(TEST_LDADD)
|
||||
|
||||
check_PROGRAMS += testbuckets
|
||||
testbuckets_SOURCES = testbuckets.c tap.c
|
||||
testbuckets_CFLAGS = $(AM_CFLAGS)
|
||||
@ -96,7 +91,7 @@ nodeidgen_LDADD = $(TEST_LDADD)
|
||||
|
||||
#check_PROGRAMS += libtorrent_example
|
||||
#libtorrent_example_SOURCES = libtorrent-example.c
|
||||
#libtorrent_example_CFLAGS = $(AM_CFLAGS)
|
||||
#libtorrent_example_CFLAGS = $(AM_CFLAGS)
|
||||
#libtorrent_example_LDADD = $(abs_top_builddir)/libks.la $(abs_top_builddir)/test/libtorrent.so /usr/lib/x86_64-linux-gnu/libboost_system.a $(openssl_LIBS) -ledit -lpthread -ltorrent-rasterbar -lstdc++
|
||||
|
||||
TESTS=$(check_PROGRAMS)
|
||||
@ -108,4 +103,3 @@ $(abs_top_builddir)/test/libtorrent.so: $(abs_top_builddir)/test/libtorrent.o
|
||||
|
||||
$(abs_top_builddir)/test/libtorrent.o: $(abs_top_builddir)/test/libtorrent.cpp
|
||||
g++ -c -fPIC -o $(abs_top_builddir)/test/libtorrent.o -I$(abs_top_builddir)/test/ $(abs_top_builddir)/test/libtorrent.cpp
|
||||
|
||||
|
@ -1,124 +0,0 @@
|
||||
#pragma GCC diagnostic ignored "-Wunused-but-set-variable"
|
||||
#pragma GCC diagnostic ignored "-Wunused-variable"
|
||||
#pragma GCC diagnostic ignored "-Wunused-function"
|
||||
|
||||
#include "../src/include/ks_rpcmessage.h"
|
||||
|
||||
#pragma GCC optimize ("O0")
|
||||
|
||||
|
||||
ks_pool_t *pool;
|
||||
|
||||
|
||||
void test01()
|
||||
{
|
||||
printf("**** testrpcmessages - test01 start\n\n"); fflush(stdout);
|
||||
|
||||
cJSON* request1 = NULL;
|
||||
cJSON* parms1 = NULL;
|
||||
cJSON* response1 = NULL;
|
||||
|
||||
/*namespace, method, params, **request */
|
||||
ks_rpcmessageid_t msgid = ks_rpcmessage_create_request("app1", "func1", &parms1, &request1);
|
||||
if (msgid == 0) {
|
||||
printf("message create failed %d\n", msgid);
|
||||
}
|
||||
|
||||
cJSON_AddStringToObject(parms1, "hello", "cruel world");
|
||||
char* data = cJSON_PrintUnformatted(request1);
|
||||
|
||||
printf("test01 request1: %d\n%s\n\n", msgid, data);
|
||||
ks_json_pool_free(data);
|
||||
|
||||
|
||||
/* convert to buffer */
|
||||
cJSON* parms2 = NULL;
|
||||
ks_buffer_t *buffer;
|
||||
|
||||
ks_buffer_create(&buffer, 256, 256, 1024);
|
||||
|
||||
ks_size_t n = ks_rpc_create_buffer("app2", "func2", &parms2, buffer);
|
||||
|
||||
ks_size_t size = ks_buffer_len(buffer);
|
||||
char *b = (char *)ks_pool_alloc(pool, size+1);
|
||||
ks_buffer_read(buffer, b, size);
|
||||
|
||||
printf("test01 request2: %zd %zd from ks_buffer\n%s\n\n\n", n, size, b);
|
||||
|
||||
|
||||
/* create message 3 */
|
||||
|
||||
cJSON *parms3 = cJSON_CreateNumber(1);
|
||||
cJSON *request3 = NULL;
|
||||
|
||||
msgid = ks_rpcmessage_create_request("app1", "badbunny", &parms3, &request3);
|
||||
data = cJSON_PrintUnformatted(request3);
|
||||
printf("\ntest01i request: %d\n%s\n\n", msgid, data);
|
||||
|
||||
cJSON *response3 = NULL;
|
||||
|
||||
ks_rpcmessage_create_response(request3, NULL, &response3);
|
||||
|
||||
data = cJSON_PrintUnformatted(response3);
|
||||
printf("\ntest01 response3: %d\n%s\n\n", msgid, data);
|
||||
|
||||
ks_json_pool_free(data);
|
||||
cJSON_Delete(request3);
|
||||
cJSON_Delete(response3);
|
||||
|
||||
printf("**** testrpcmessages - test01 complete\n\n\n"); fflush(stdout);
|
||||
}
|
||||
|
||||
void test02()
|
||||
{
|
||||
printf("**** testmessages - test02 start\n"); fflush(stdout);
|
||||
|
||||
printf("**** testmessages - test02 finished\n"); fflush(stdout);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
|
||||
int main(int argc, char *argv[]) {
|
||||
|
||||
printf("testmessages - start\n");
|
||||
|
||||
int tests[100];
|
||||
if (argc == 1) {
|
||||
tests[0] = 1;
|
||||
}
|
||||
else {
|
||||
for(int tix=1; tix<100 && tix<argc; ++tix) {
|
||||
long i = strtol(argv[tix], NULL, 0);
|
||||
tests[tix] = i;
|
||||
}
|
||||
}
|
||||
|
||||
ks_init();
|
||||
ks_global_set_default_logger(7);
|
||||
|
||||
|
||||
ks_status_t status;
|
||||
|
||||
status = ks_pool_open(&pool);
|
||||
|
||||
|
||||
for (int tix=0; tix<argc; ++tix) {
|
||||
|
||||
if (tests[tix] == 1) {
|
||||
ks_rpcmessage_init(pool);
|
||||
test01();
|
||||
continue;
|
||||
}
|
||||
|
||||
if (tests[tix] == 2) {
|
||||
ks_rpcmessage_init(pool);
|
||||
test02();
|
||||
continue;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user