mirror of
https://github.com/signalwire/freeswitch.git
synced 2025-04-16 16:58:35 +00:00
Merge pull request #1234 in FS/freeswitch from feature/FS-9952-implementing-a-syncronized-scalable to master
* commit '7742dffae4192e73c258493a7320eb11b6437b8a': (34 commits) FS-9952: Initial implementation of a very basic text chat system which introduced a number of supporting subsystems FS-9952: Added support to default ks_log system for including optional prefixes as desired, also added thread and time prefix options FS-9952: Big commit, first registered jsonrpc echo call successful, lots of cleanup remaining FS-9952: Intermediate commit for a fresh point to start retrofitting the jsonrpc code that is incomplete FS-9952: Some code refactoring and added TTL for sessions, currently harcoded at 5 seconds for testing purposes only and should come from config FS-9952: Preliminary session negotiations done, added a bunch of logging, fixed up cleanup code, needs more testing and more error handling FS-9952: Added the first half of the session negotations for the server side, untested as it requires the second half coming soon for client side FS-9952: A bunch of cleanup and shifting connections towards ID based passing instead of pointers, will replicate and adjust for session system next FS-9952: Add blade rpc error response creation FS-9952: Fix compile errors in test 64bit build FS-9952: Committing to show problem with ks_pool_resize FS-9952: Add query & tests for blade extention to rpc messages FS-9952: Add blade extention to rpc messages FS-9952: Some work towards client connectivity support, commit is to remove blade_message_t and get RPC stuff updated, code does not compile currently FS-9952: Added initial support for registering transports, and initial untested code for parsing identities FS-9952: Updated bladec test, it successfully listens for connections, further testing required FS-9952: Added envelope to queue sending messages, prepping for initial server transport testing FS-9952: Add rpc h files to ks FS-9952: Update for compile issues FS-9952: More work on the connection and transport code, couple things left to do but nearly ready for testing upto starting session negotiations ...
This commit is contained in:
commit
716f02897a
@ -11,18 +11,20 @@ libunqlite_la_CFLAGS = -DUNQLITE_ENABLE_THREADS
|
|||||||
libunqlite_la_LIBADD = -lpthread
|
libunqlite_la_LIBADD = -lpthread
|
||||||
|
|
||||||
lib_LTLIBRARIES = libblade.la
|
lib_LTLIBRARIES = libblade.la
|
||||||
libblade_la_SOURCES = src/blade.c src/blade_stack.c src/blade_peer.c src/bpcp.c src/blade_datastore.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 src/blade_module_chat.c
|
||||||
libblade_la_CFLAGS = $(AM_CFLAGS) $(AM_CPPFLAGS)
|
libblade_la_CFLAGS = $(AM_CFLAGS) $(AM_CPPFLAGS)
|
||||||
libblade_la_LDFLAGS = -version-info 0:1:0 -lncurses -lpthread -lm $(AM_LDFLAGS)
|
libblade_la_LDFLAGS = -version-info 0:1:0 -lncurses -lpthread -lm -lconfig $(AM_LDFLAGS)
|
||||||
libblade_la_LIBADD = libunqlite.la
|
libblade_la_LIBADD = libunqlite.la
|
||||||
library_includedir = $(prefix)/include
|
library_includedir = $(prefix)/include
|
||||||
library_include_HEADERS = src/include/blade.h src/include/blade_types.h src/include/blade_stack.h src/include/blade_peer.h src/include/bpcp.h
|
library_include_HEADERS = src/include/blade.h src/include/blade_types.h src/include/blade_stack.h
|
||||||
library_include_HEADERS += src/include/blade_datastore.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
|
library_include_HEADERS += src/include/unqlite.h test/tap.h
|
||||||
|
|
||||||
tests: libblade.la
|
tests: libblade.la
|
||||||
$(MAKE) -C test tests
|
$(MAKE) -C test tests
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
550
libs/libblade/src/blade_connection.c
Normal file
550
libs/libblade/src/blade_connection.c
Normal file
@ -0,0 +1,550 @@
|
|||||||
|
/*
|
||||||
|
* 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_connection_s {
|
||||||
|
blade_handle_t *handle;
|
||||||
|
ks_pool_t *pool;
|
||||||
|
|
||||||
|
void *transport_init_data;
|
||||||
|
void *transport_data;
|
||||||
|
blade_transport_callbacks_t *transport_callbacks;
|
||||||
|
|
||||||
|
ks_bool_t shutdown;
|
||||||
|
blade_connection_direction_t direction;
|
||||||
|
ks_thread_t *state_thread;
|
||||||
|
blade_connection_state_t state;
|
||||||
|
|
||||||
|
const char *id;
|
||||||
|
ks_rwl_t *lock;
|
||||||
|
|
||||||
|
ks_q_t *sending;
|
||||||
|
|
||||||
|
const char *session;
|
||||||
|
};
|
||||||
|
|
||||||
|
void *blade_connection_state_thread(ks_thread_t *thread, void *data);
|
||||||
|
ks_status_t blade_connection_state_on_disconnect(blade_connection_t *bc);
|
||||||
|
ks_status_t blade_connection_state_on_new(blade_connection_t *bc);
|
||||||
|
ks_status_t blade_connection_state_on_connect(blade_connection_t *bc);
|
||||||
|
ks_status_t blade_connection_state_on_attach(blade_connection_t *bc);
|
||||||
|
ks_status_t blade_connection_state_on_detach(blade_connection_t *bc);
|
||||||
|
ks_status_t blade_connection_state_on_ready(blade_connection_t *bc);
|
||||||
|
|
||||||
|
|
||||||
|
KS_DECLARE(ks_status_t) blade_connection_create(blade_connection_t **bcP,
|
||||||
|
blade_handle_t *bh,
|
||||||
|
void *transport_init_data,
|
||||||
|
blade_transport_callbacks_t *transport_callbacks)
|
||||||
|
{
|
||||||
|
blade_connection_t *bc = NULL;
|
||||||
|
ks_pool_t *pool = NULL;
|
||||||
|
uuid_t id;
|
||||||
|
|
||||||
|
ks_assert(bcP);
|
||||||
|
ks_assert(bh);
|
||||||
|
ks_assert(transport_callbacks);
|
||||||
|
|
||||||
|
pool = blade_handle_pool_get(bh);
|
||||||
|
|
||||||
|
bc = ks_pool_alloc(pool, sizeof(blade_connection_t));
|
||||||
|
bc->handle = bh;
|
||||||
|
bc->pool = pool;
|
||||||
|
bc->transport_init_data = transport_init_data;
|
||||||
|
bc->transport_callbacks = transport_callbacks;
|
||||||
|
|
||||||
|
ks_uuid(&id);
|
||||||
|
bc->id = ks_uuid_str(pool, &id);
|
||||||
|
ks_assert(bc->id);
|
||||||
|
|
||||||
|
ks_rwl_create(&bc->lock, pool);
|
||||||
|
ks_assert(bc->lock);
|
||||||
|
|
||||||
|
ks_q_create(&bc->sending, pool, 0);
|
||||||
|
ks_assert(bc->sending);
|
||||||
|
|
||||||
|
*bcP = bc;
|
||||||
|
|
||||||
|
ks_log(KS_LOG_DEBUG, "Created\n");
|
||||||
|
|
||||||
|
return KS_STATUS_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
KS_DECLARE(ks_status_t) blade_connection_destroy(blade_connection_t **bcP)
|
||||||
|
{
|
||||||
|
blade_connection_t *bc = NULL;
|
||||||
|
|
||||||
|
ks_assert(bcP);
|
||||||
|
ks_assert(*bcP);
|
||||||
|
|
||||||
|
bc = *bcP;
|
||||||
|
|
||||||
|
blade_connection_shutdown(bc);
|
||||||
|
|
||||||
|
ks_q_destroy(&bc->sending);
|
||||||
|
|
||||||
|
ks_rwl_destroy(&bc->lock);
|
||||||
|
|
||||||
|
ks_pool_free(bc->pool, &bc->id);
|
||||||
|
|
||||||
|
ks_pool_free(bc->pool, bcP);
|
||||||
|
|
||||||
|
ks_log(KS_LOG_DEBUG, "Destroyed\n");
|
||||||
|
|
||||||
|
return KS_STATUS_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
KS_DECLARE(ks_status_t) blade_connection_startup(blade_connection_t *bc, blade_connection_direction_t direction)
|
||||||
|
{
|
||||||
|
ks_assert(bc);
|
||||||
|
|
||||||
|
bc->direction = direction;
|
||||||
|
blade_connection_state_set(bc, BLADE_CONNECTION_STATE_NONE);
|
||||||
|
|
||||||
|
if (ks_thread_create_ex(&bc->state_thread,
|
||||||
|
blade_connection_state_thread,
|
||||||
|
bc,
|
||||||
|
KS_THREAD_FLAG_DEFAULT,
|
||||||
|
KS_THREAD_DEFAULT_STACK,
|
||||||
|
KS_PRI_NORMAL,
|
||||||
|
bc->pool) != KS_STATUS_SUCCESS) {
|
||||||
|
// @todo error logging
|
||||||
|
return KS_STATUS_FAIL;
|
||||||
|
}
|
||||||
|
|
||||||
|
ks_log(KS_LOG_DEBUG, "Started\n");
|
||||||
|
|
||||||
|
return KS_STATUS_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
KS_DECLARE(ks_status_t) blade_connection_shutdown(blade_connection_t *bc)
|
||||||
|
{
|
||||||
|
cJSON *json = NULL;
|
||||||
|
|
||||||
|
ks_assert(bc);
|
||||||
|
|
||||||
|
if (bc->state_thread) {
|
||||||
|
bc->shutdown = KS_TRUE;
|
||||||
|
ks_thread_join(bc->state_thread);
|
||||||
|
ks_pool_free(bc->pool, &bc->state_thread);
|
||||||
|
bc->shutdown = KS_FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (bc->session) ks_pool_free(bc->pool, &bc->session);
|
||||||
|
|
||||||
|
while (ks_q_trypop(bc->sending, (void **)&json) == KS_STATUS_SUCCESS && json) cJSON_Delete(json);
|
||||||
|
|
||||||
|
ks_log(KS_LOG_DEBUG, "Stopped\n");
|
||||||
|
|
||||||
|
return KS_STATUS_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
KS_DECLARE(blade_handle_t *) blade_connection_handle_get(blade_connection_t *bc)
|
||||||
|
{
|
||||||
|
ks_assert(bc);
|
||||||
|
|
||||||
|
return bc->handle;
|
||||||
|
}
|
||||||
|
|
||||||
|
KS_DECLARE(ks_pool_t *) blade_connection_pool_get(blade_connection_t *bc)
|
||||||
|
{
|
||||||
|
ks_assert(bc);
|
||||||
|
|
||||||
|
return bc->pool;
|
||||||
|
}
|
||||||
|
|
||||||
|
KS_DECLARE(const char *) blade_connection_id_get(blade_connection_t *bc)
|
||||||
|
{
|
||||||
|
ks_assert(bc);
|
||||||
|
|
||||||
|
return bc->id;
|
||||||
|
}
|
||||||
|
|
||||||
|
KS_DECLARE(ks_status_t) blade_connection_read_lock(blade_connection_t *bc, ks_bool_t block)
|
||||||
|
{
|
||||||
|
ks_status_t ret = KS_STATUS_SUCCESS;
|
||||||
|
|
||||||
|
ks_assert(bc);
|
||||||
|
|
||||||
|
if (block) ret = ks_rwl_read_lock(bc->lock);
|
||||||
|
else ret = ks_rwl_try_read_lock(bc->lock);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
KS_DECLARE(ks_status_t) blade_connection_read_unlock(blade_connection_t *bc)
|
||||||
|
{
|
||||||
|
ks_assert(bc);
|
||||||
|
|
||||||
|
return ks_rwl_read_unlock(bc->lock);
|
||||||
|
}
|
||||||
|
|
||||||
|
KS_DECLARE(ks_status_t) blade_connection_write_lock(blade_connection_t *bc, ks_bool_t block)
|
||||||
|
{
|
||||||
|
ks_status_t ret = KS_STATUS_SUCCESS;
|
||||||
|
|
||||||
|
ks_assert(bc);
|
||||||
|
|
||||||
|
if (block) ret = ks_rwl_write_lock(bc->lock);
|
||||||
|
else ret = ks_rwl_try_write_lock(bc->lock);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
KS_DECLARE(ks_status_t) blade_connection_write_unlock(blade_connection_t *bc)
|
||||||
|
{
|
||||||
|
ks_assert(bc);
|
||||||
|
|
||||||
|
return ks_rwl_write_unlock(bc->lock);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
KS_DECLARE(void *) blade_connection_transport_init_get(blade_connection_t *bc)
|
||||||
|
{
|
||||||
|
ks_assert(bc);
|
||||||
|
|
||||||
|
return bc->transport_init_data;
|
||||||
|
}
|
||||||
|
|
||||||
|
KS_DECLARE(void *) blade_connection_transport_get(blade_connection_t *bc)
|
||||||
|
{
|
||||||
|
ks_assert(bc);
|
||||||
|
|
||||||
|
return bc->transport_data;
|
||||||
|
}
|
||||||
|
|
||||||
|
KS_DECLARE(void) blade_connection_transport_set(blade_connection_t *bc, void *transport_data)
|
||||||
|
{
|
||||||
|
ks_assert(bc);
|
||||||
|
|
||||||
|
bc->transport_data = transport_data;
|
||||||
|
}
|
||||||
|
|
||||||
|
blade_transport_state_callback_t blade_connection_state_callback_lookup(blade_connection_t *bc, blade_connection_state_t state)
|
||||||
|
{
|
||||||
|
blade_transport_state_callback_t callback = NULL;
|
||||||
|
|
||||||
|
ks_assert(bc);
|
||||||
|
|
||||||
|
switch (state) {
|
||||||
|
case BLADE_CONNECTION_STATE_DISCONNECT:
|
||||||
|
if (bc->direction == BLADE_CONNECTION_DIRECTION_INBOUND) callback = bc->transport_callbacks->onstate_disconnect_inbound;
|
||||||
|
else if(bc->direction == BLADE_CONNECTION_DIRECTION_OUTBOUND) callback = bc->transport_callbacks->onstate_disconnect_outbound;
|
||||||
|
break;
|
||||||
|
case BLADE_CONNECTION_STATE_NEW:
|
||||||
|
if (bc->direction == BLADE_CONNECTION_DIRECTION_INBOUND) callback = bc->transport_callbacks->onstate_new_inbound;
|
||||||
|
else if(bc->direction == BLADE_CONNECTION_DIRECTION_OUTBOUND) callback = bc->transport_callbacks->onstate_new_outbound;
|
||||||
|
break;
|
||||||
|
case BLADE_CONNECTION_STATE_CONNECT:
|
||||||
|
if (bc->direction == BLADE_CONNECTION_DIRECTION_INBOUND) callback = bc->transport_callbacks->onstate_connect_inbound;
|
||||||
|
else if(bc->direction == BLADE_CONNECTION_DIRECTION_OUTBOUND) callback = bc->transport_callbacks->onstate_connect_outbound;
|
||||||
|
break;
|
||||||
|
case BLADE_CONNECTION_STATE_ATTACH:
|
||||||
|
if (bc->direction == BLADE_CONNECTION_DIRECTION_INBOUND) callback = bc->transport_callbacks->onstate_attach_inbound;
|
||||||
|
else if(bc->direction == BLADE_CONNECTION_DIRECTION_OUTBOUND) callback = bc->transport_callbacks->onstate_attach_outbound;
|
||||||
|
break;
|
||||||
|
case BLADE_CONNECTION_STATE_DETACH:
|
||||||
|
if (bc->direction == BLADE_CONNECTION_DIRECTION_INBOUND) callback = bc->transport_callbacks->onstate_detach_inbound;
|
||||||
|
else if(bc->direction == BLADE_CONNECTION_DIRECTION_OUTBOUND) callback = bc->transport_callbacks->onstate_detach_outbound;
|
||||||
|
break;
|
||||||
|
case BLADE_CONNECTION_STATE_READY:
|
||||||
|
if (bc->direction == BLADE_CONNECTION_DIRECTION_INBOUND) callback = bc->transport_callbacks->onstate_ready_inbound;
|
||||||
|
else if(bc->direction == BLADE_CONNECTION_DIRECTION_OUTBOUND) callback = bc->transport_callbacks->onstate_ready_outbound;
|
||||||
|
break;
|
||||||
|
default: break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return callback;
|
||||||
|
}
|
||||||
|
|
||||||
|
KS_DECLARE(void) blade_connection_state_set(blade_connection_t *bc, blade_connection_state_t state)
|
||||||
|
{
|
||||||
|
blade_transport_state_callback_t callback = NULL;
|
||||||
|
blade_connection_state_hook_t hook = BLADE_CONNECTION_STATE_HOOK_SUCCESS;
|
||||||
|
|
||||||
|
ks_assert(bc);
|
||||||
|
|
||||||
|
callback = blade_connection_state_callback_lookup(bc, state);
|
||||||
|
|
||||||
|
if (callback) hook = callback(bc, BLADE_CONNECTION_STATE_CONDITION_PRE);
|
||||||
|
|
||||||
|
bc->state = state;
|
||||||
|
|
||||||
|
if (hook == BLADE_CONNECTION_STATE_HOOK_DISCONNECT) blade_connection_disconnect(bc);
|
||||||
|
}
|
||||||
|
|
||||||
|
KS_DECLARE(void) blade_connection_disconnect(blade_connection_t *bc)
|
||||||
|
{
|
||||||
|
ks_assert(bc);
|
||||||
|
|
||||||
|
if (bc->state != BLADE_CONNECTION_STATE_DETACH && bc->state != BLADE_CONNECTION_STATE_DISCONNECT) {
|
||||||
|
ks_log(KS_LOG_DEBUG, "Connection (%s) disconnecting\n", bc->id);
|
||||||
|
blade_connection_state_set(bc, BLADE_CONNECTION_STATE_DETACH);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
KS_DECLARE(ks_status_t) blade_connection_sending_push(blade_connection_t *bc, cJSON *json)
|
||||||
|
{
|
||||||
|
cJSON *json_copy = NULL;
|
||||||
|
|
||||||
|
ks_assert(bc);
|
||||||
|
ks_assert(json);
|
||||||
|
|
||||||
|
json_copy = cJSON_Duplicate(json, 1);
|
||||||
|
return ks_q_push(bc->sending, json_copy);
|
||||||
|
}
|
||||||
|
|
||||||
|
KS_DECLARE(ks_status_t) blade_connection_sending_pop(blade_connection_t *bc, cJSON **json)
|
||||||
|
{
|
||||||
|
ks_assert(bc);
|
||||||
|
ks_assert(json);
|
||||||
|
|
||||||
|
return ks_q_trypop(bc->sending, (void **)json);
|
||||||
|
}
|
||||||
|
|
||||||
|
KS_DECLARE(const char *) blade_connection_session_get(blade_connection_t *bc)
|
||||||
|
{
|
||||||
|
ks_assert(bc);
|
||||||
|
|
||||||
|
return bc->session;
|
||||||
|
}
|
||||||
|
|
||||||
|
KS_DECLARE(void) blade_connection_session_set(blade_connection_t *bc, const char *id)
|
||||||
|
{
|
||||||
|
ks_assert(bc);
|
||||||
|
|
||||||
|
if (bc->session) ks_pool_free(bc->pool, &bc->session);
|
||||||
|
bc->session = ks_pstrdup(bc->pool, id);
|
||||||
|
}
|
||||||
|
|
||||||
|
void *blade_connection_state_thread(ks_thread_t *thread, void *data)
|
||||||
|
{
|
||||||
|
blade_connection_t *bc = NULL;
|
||||||
|
blade_connection_state_t state;
|
||||||
|
|
||||||
|
ks_assert(thread);
|
||||||
|
ks_assert(data);
|
||||||
|
|
||||||
|
bc = (blade_connection_t *)data;
|
||||||
|
|
||||||
|
while (!bc->shutdown) {
|
||||||
|
state = bc->state;
|
||||||
|
|
||||||
|
switch (state) {
|
||||||
|
case BLADE_CONNECTION_STATE_DISCONNECT:
|
||||||
|
blade_connection_state_on_disconnect(bc);
|
||||||
|
break;
|
||||||
|
case BLADE_CONNECTION_STATE_NEW:
|
||||||
|
blade_connection_state_on_new(bc);
|
||||||
|
break;
|
||||||
|
case BLADE_CONNECTION_STATE_CONNECT:
|
||||||
|
blade_connection_state_on_connect(bc);
|
||||||
|
break;
|
||||||
|
case BLADE_CONNECTION_STATE_ATTACH:
|
||||||
|
blade_connection_state_on_attach(bc);
|
||||||
|
break;
|
||||||
|
case BLADE_CONNECTION_STATE_DETACH:
|
||||||
|
blade_connection_state_on_detach(bc);
|
||||||
|
break;
|
||||||
|
case BLADE_CONNECTION_STATE_READY:
|
||||||
|
blade_connection_state_on_ready(bc);
|
||||||
|
break;
|
||||||
|
default: break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (state == BLADE_CONNECTION_STATE_DISCONNECT) break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
ks_status_t blade_connection_state_on_disconnect(blade_connection_t *bc)
|
||||||
|
{
|
||||||
|
blade_transport_state_callback_t callback = NULL;
|
||||||
|
|
||||||
|
ks_assert(bc);
|
||||||
|
|
||||||
|
blade_handle_connections_remove(bc);
|
||||||
|
|
||||||
|
callback = blade_connection_state_callback_lookup(bc, BLADE_CONNECTION_STATE_DISCONNECT);
|
||||||
|
if (callback) callback(bc, BLADE_CONNECTION_STATE_CONDITION_POST);
|
||||||
|
|
||||||
|
blade_connection_destroy(&bc);
|
||||||
|
|
||||||
|
return KS_STATUS_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
ks_status_t blade_connection_state_on_new(blade_connection_t *bc)
|
||||||
|
{
|
||||||
|
blade_transport_state_callback_t callback = NULL;
|
||||||
|
blade_connection_state_hook_t hook = BLADE_CONNECTION_STATE_HOOK_SUCCESS;
|
||||||
|
|
||||||
|
ks_assert(bc);
|
||||||
|
|
||||||
|
callback = blade_connection_state_callback_lookup(bc, BLADE_CONNECTION_STATE_NEW);
|
||||||
|
if (callback) hook = callback(bc, BLADE_CONNECTION_STATE_CONDITION_POST);
|
||||||
|
|
||||||
|
if (hook == BLADE_CONNECTION_STATE_HOOK_DISCONNECT) blade_connection_disconnect(bc);
|
||||||
|
else if (hook == BLADE_CONNECTION_STATE_HOOK_SUCCESS) {
|
||||||
|
blade_connection_state_set(bc, BLADE_CONNECTION_STATE_CONNECT);
|
||||||
|
}
|
||||||
|
|
||||||
|
return KS_STATUS_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
ks_status_t blade_connection_state_on_connect(blade_connection_t *bc)
|
||||||
|
{
|
||||||
|
blade_transport_state_callback_t callback = NULL;
|
||||||
|
blade_connection_state_hook_t hook = BLADE_CONNECTION_STATE_HOOK_SUCCESS;
|
||||||
|
|
||||||
|
ks_assert(bc);
|
||||||
|
|
||||||
|
callback = blade_connection_state_callback_lookup(bc, BLADE_CONNECTION_STATE_CONNECT);
|
||||||
|
if (callback) hook = callback(bc, BLADE_CONNECTION_STATE_CONDITION_POST);
|
||||||
|
|
||||||
|
if (hook == BLADE_CONNECTION_STATE_HOOK_DISCONNECT) blade_connection_disconnect(bc);
|
||||||
|
else if (hook == BLADE_CONNECTION_STATE_HOOK_SUCCESS) {
|
||||||
|
blade_connection_state_set(bc, BLADE_CONNECTION_STATE_ATTACH);
|
||||||
|
}
|
||||||
|
|
||||||
|
return KS_STATUS_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
ks_status_t blade_connection_state_on_attach(blade_connection_t *bc)
|
||||||
|
{
|
||||||
|
blade_transport_state_callback_t callback = NULL;
|
||||||
|
blade_connection_state_hook_t hook = BLADE_CONNECTION_STATE_HOOK_SUCCESS;
|
||||||
|
|
||||||
|
ks_assert(bc);
|
||||||
|
|
||||||
|
callback = blade_connection_state_callback_lookup(bc, BLADE_CONNECTION_STATE_ATTACH);
|
||||||
|
if (callback) hook = callback(bc, BLADE_CONNECTION_STATE_CONDITION_POST);
|
||||||
|
|
||||||
|
if (hook == BLADE_CONNECTION_STATE_HOOK_DISCONNECT) blade_connection_disconnect(bc);
|
||||||
|
else if (hook == BLADE_CONNECTION_STATE_HOOK_SUCCESS) {
|
||||||
|
// @todo this is adding a second lock, since we keep it locked in the callback to allow finishing, we don't want get locking here...
|
||||||
|
// or just try unlocking twice to confirm...
|
||||||
|
blade_session_t *bs = blade_handle_sessions_get(bc->handle, bc->session);
|
||||||
|
ks_assert(bs); // should not happen because bs should still be locked
|
||||||
|
|
||||||
|
blade_session_connections_add(bs, bc->id);
|
||||||
|
|
||||||
|
blade_connection_state_set(bc, BLADE_CONNECTION_STATE_READY);
|
||||||
|
blade_session_state_set(bs, BLADE_SESSION_STATE_READY); // @todo only set this if it's not already in the READY state from prior connection
|
||||||
|
|
||||||
|
blade_session_read_unlock(bs); // unlock the session we locked obtaining it above
|
||||||
|
blade_session_read_unlock(bs); // unlock the session we expect to be locked during the callback to ensure we can finish attaching
|
||||||
|
}
|
||||||
|
|
||||||
|
return KS_STATUS_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
ks_status_t blade_connection_state_on_detach(blade_connection_t *bc)
|
||||||
|
{
|
||||||
|
blade_transport_state_callback_t callback = NULL;
|
||||||
|
|
||||||
|
ks_assert(bc);
|
||||||
|
|
||||||
|
callback = blade_connection_state_callback_lookup(bc, BLADE_CONNECTION_STATE_DETACH);
|
||||||
|
if (callback) callback(bc, BLADE_CONNECTION_STATE_CONDITION_POST);
|
||||||
|
|
||||||
|
if (bc->session) {
|
||||||
|
blade_session_t *bs = blade_handle_sessions_get(bc->handle, bc->session);
|
||||||
|
ks_assert(bs);
|
||||||
|
|
||||||
|
blade_session_connections_remove(bs, bc->id);
|
||||||
|
blade_session_read_unlock(bs);
|
||||||
|
// keep bc->session for later in case something triggers a reconnect later and needs the old session id for a hint
|
||||||
|
}
|
||||||
|
blade_connection_state_set(bc, BLADE_CONNECTION_STATE_DISCONNECT);
|
||||||
|
|
||||||
|
return KS_STATUS_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
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);
|
||||||
|
|
||||||
|
while (blade_connection_sending_pop(bc, &json) == KS_STATUS_SUCCESS && json) {
|
||||||
|
ks_status_t ret = bc->transport_callbacks->onsend(bc, json);
|
||||||
|
cJSON_Delete(json);
|
||||||
|
|
||||||
|
if (ret != KS_STATUS_SUCCESS) {
|
||||||
|
blade_connection_disconnect(bc);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
while (!done) {
|
||||||
|
if (bc->transport_callbacks->onreceive(bc, &json) != KS_STATUS_SUCCESS) {
|
||||||
|
blade_connection_disconnect(bc);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!(done = (json == NULL))) {
|
||||||
|
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);
|
||||||
|
|
||||||
|
if (hook == BLADE_CONNECTION_STATE_HOOK_DISCONNECT) blade_connection_disconnect(bc);
|
||||||
|
else ks_sleep_ms(1);
|
||||||
|
|
||||||
|
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:
|
||||||
|
*/
|
@ -34,14 +34,12 @@
|
|||||||
#include "blade.h"
|
#include "blade.h"
|
||||||
|
|
||||||
|
|
||||||
typedef enum {
|
|
||||||
BDS_NONE = 0,
|
|
||||||
BDS_MYPOOL = (1 << 0),
|
|
||||||
} bdspvt_flag_t;
|
|
||||||
|
|
||||||
struct blade_datastore_s {
|
struct blade_datastore_s {
|
||||||
bdspvt_flag_t flags;
|
|
||||||
ks_pool_t *pool;
|
ks_pool_t *pool;
|
||||||
|
ks_thread_pool_t *tpool;
|
||||||
|
|
||||||
|
const char *config_database_path;
|
||||||
|
|
||||||
unqlite *db;
|
unqlite *db;
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -58,8 +56,6 @@ typedef struct blade_datastore_fetch_userdata_s blade_datastore_fetch_userdata_t
|
|||||||
KS_DECLARE(ks_status_t) blade_datastore_destroy(blade_datastore_t **bdsP)
|
KS_DECLARE(ks_status_t) blade_datastore_destroy(blade_datastore_t **bdsP)
|
||||||
{
|
{
|
||||||
blade_datastore_t *bds = NULL;
|
blade_datastore_t *bds = NULL;
|
||||||
bdspvt_flag_t flags;
|
|
||||||
ks_pool_t *pool;
|
|
||||||
|
|
||||||
ks_assert(bdsP);
|
ks_assert(bdsP);
|
||||||
|
|
||||||
@ -68,41 +64,65 @@ KS_DECLARE(ks_status_t) blade_datastore_destroy(blade_datastore_t **bdsP)
|
|||||||
|
|
||||||
ks_assert(bds);
|
ks_assert(bds);
|
||||||
|
|
||||||
flags = bds->flags;
|
blade_datastore_shutdown(bds);
|
||||||
pool = bds->pool;
|
|
||||||
|
|
||||||
if (bds->db) {
|
|
||||||
unqlite_close(bds->db);
|
|
||||||
bds->db = NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
ks_pool_free(bds->pool, &bds);
|
ks_pool_free(bds->pool, &bds);
|
||||||
|
|
||||||
if (pool && (flags & BDS_MYPOOL)) ks_pool_close(&pool);
|
|
||||||
|
|
||||||
return KS_STATUS_SUCCESS;
|
return KS_STATUS_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
KS_DECLARE(ks_status_t) blade_datastore_create(blade_datastore_t **bdsP, ks_pool_t *pool)
|
KS_DECLARE(ks_status_t) blade_datastore_create(blade_datastore_t **bdsP, ks_pool_t *pool, ks_thread_pool_t *tpool)
|
||||||
{
|
{
|
||||||
bdspvt_flag_t newflags = BDS_NONE;
|
|
||||||
blade_datastore_t *bds = NULL;
|
blade_datastore_t *bds = NULL;
|
||||||
|
|
||||||
if (!pool) {
|
ks_assert(bdsP);
|
||||||
newflags |= BDS_MYPOOL;
|
ks_assert(pool);
|
||||||
ks_pool_open(&pool);
|
ks_assert(tpool);
|
||||||
ks_assert(pool);
|
|
||||||
}
|
|
||||||
|
|
||||||
bds = ks_pool_alloc(pool, sizeof(*bds));
|
bds = ks_pool_alloc(pool, sizeof(*bds));
|
||||||
bds->flags = newflags;
|
|
||||||
bds->pool = pool;
|
bds->pool = pool;
|
||||||
|
bds->tpool = tpool;
|
||||||
*bdsP = bds;
|
*bdsP = bds;
|
||||||
|
|
||||||
if (unqlite_open(&bds->db, NULL, UNQLITE_OPEN_IN_MEMORY) != UNQLITE_OK) {
|
return KS_STATUS_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
ks_status_t blade_datastore_config(blade_datastore_t *bds, config_setting_t *config)
|
||||||
|
{
|
||||||
|
config_setting_t *tmp;
|
||||||
|
config_setting_t *database = NULL;
|
||||||
|
const char *config_database_path = NULL;
|
||||||
|
|
||||||
|
ks_assert(bds);
|
||||||
|
|
||||||
|
if (!config) return KS_STATUS_FAIL;
|
||||||
|
if (!config_setting_is_group(config)) return KS_STATUS_FAIL;
|
||||||
|
|
||||||
|
database = config_setting_get_member(config, "database");
|
||||||
|
if (!database) return KS_STATUS_FAIL;
|
||||||
|
tmp = config_lookup_from(database, "path");
|
||||||
|
if (!tmp) return KS_STATUS_FAIL;
|
||||||
|
if (config_setting_type(tmp) != CONFIG_TYPE_STRING) return KS_STATUS_FAIL;
|
||||||
|
config_database_path = config_setting_get_string(tmp);
|
||||||
|
|
||||||
|
if (bds->config_database_path) ks_pool_free(bds->pool, &bds->config_database_path);
|
||||||
|
bds->config_database_path = ks_pstrdup(bds->pool, config_database_path);
|
||||||
|
|
||||||
|
return KS_STATUS_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
KS_DECLARE(ks_status_t) blade_datastore_startup(blade_datastore_t *bds, config_setting_t *config)
|
||||||
|
{
|
||||||
|
ks_assert(bds);
|
||||||
|
|
||||||
|
// @todo check if already started
|
||||||
|
|
||||||
|
if (blade_datastore_config(bds, config) != KS_STATUS_SUCCESS) return KS_STATUS_FAIL;
|
||||||
|
|
||||||
|
if (unqlite_open(&bds->db, bds->config_database_path, UNQLITE_OPEN_CREATE) != UNQLITE_OK) {
|
||||||
const char *errbuf = NULL;
|
const char *errbuf = NULL;
|
||||||
blade_datastore_error(bds, &errbuf, NULL);
|
blade_datastore_error(bds, &errbuf, NULL);
|
||||||
ks_log(KS_LOG_ERROR, "BDS Error: %s\n", errbuf);
|
ks_log(KS_LOG_ERROR, "BDS Open Error: %s\n", errbuf);
|
||||||
return KS_STATUS_FAIL;
|
return KS_STATUS_FAIL;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -113,12 +133,21 @@ KS_DECLARE(ks_status_t) blade_datastore_create(blade_datastore_t **bdsP, ks_pool
|
|||||||
return KS_STATUS_SUCCESS;
|
return KS_STATUS_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
KS_DECLARE(void) blade_datastore_pulse(blade_datastore_t *bds, int32_t timeout)
|
KS_DECLARE(ks_status_t) blade_datastore_shutdown(blade_datastore_t *bds)
|
||||||
{
|
{
|
||||||
ks_assert(bds);
|
ks_assert(bds);
|
||||||
ks_assert(timeout >= 0);
|
|
||||||
|
if (bds->db) {
|
||||||
|
unqlite_close(bds->db);
|
||||||
|
bds->db = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (bds->config_database_path) ks_pool_free(bds->pool, &bds->config_database_path);
|
||||||
|
|
||||||
|
return KS_STATUS_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
KS_DECLARE(void) blade_datastore_error(blade_datastore_t *bds, const char **buffer, int32_t *buffer_length)
|
KS_DECLARE(void) blade_datastore_error(blade_datastore_t *bds, const char **buffer, int32_t *buffer_length)
|
||||||
{
|
{
|
||||||
ks_assert(bds);
|
ks_assert(bds);
|
||||||
@ -147,7 +176,7 @@ KS_DECLARE(ks_status_t) blade_datastore_store(blade_datastore_t *bds, const void
|
|||||||
else {
|
else {
|
||||||
const char *errbuf;
|
const char *errbuf;
|
||||||
blade_datastore_error(bds, &errbuf, NULL);
|
blade_datastore_error(bds, &errbuf, NULL);
|
||||||
ks_log(KS_LOG_ERROR, "BDS Error: %s\n", errbuf);
|
ks_log(KS_LOG_ERROR, "BDS Store Error: %s\n", errbuf);
|
||||||
|
|
||||||
ret = KS_STATUS_FAIL;
|
ret = KS_STATUS_FAIL;
|
||||||
}
|
}
|
||||||
@ -196,10 +225,11 @@ KS_DECLARE(ks_status_t) blade_datastore_fetch(blade_datastore_t *bds,
|
|||||||
|
|
||||||
if (rc != UNQLITE_OK) {
|
if (rc != UNQLITE_OK) {
|
||||||
if (rc == UNQLITE_BUSY) ret = KS_STATUS_TIMEOUT;
|
if (rc == UNQLITE_BUSY) ret = KS_STATUS_TIMEOUT;
|
||||||
|
else if(rc == UNQLITE_NOTFOUND) ret = KS_STATUS_NOT_FOUND;
|
||||||
else {
|
else {
|
||||||
const char *errbuf;
|
const char *errbuf;
|
||||||
blade_datastore_error(bds, &errbuf, NULL);
|
blade_datastore_error(bds, &errbuf, NULL);
|
||||||
ks_log(KS_LOG_ERROR, "BDS Error: %s\n", errbuf);
|
ks_log(KS_LOG_ERROR, "BDS Fetch Error: %s\n", errbuf);
|
||||||
|
|
||||||
ret = KS_STATUS_FAIL;
|
ret = KS_STATUS_FAIL;
|
||||||
}
|
}
|
||||||
|
158
libs/libblade/src/blade_identity.c
Normal file
158
libs/libblade/src/blade_identity.c
Normal file
@ -0,0 +1,158 @@
|
|||||||
|
/*
|
||||||
|
* 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_identity_s {
|
||||||
|
ks_pool_t *pool;
|
||||||
|
|
||||||
|
const char *uri;
|
||||||
|
|
||||||
|
const char *components;
|
||||||
|
const char *name;
|
||||||
|
const char *domain;
|
||||||
|
const char *resource;
|
||||||
|
ks_hash_t *parameters;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
KS_DECLARE(ks_status_t) blade_identity_create(blade_identity_t **biP, ks_pool_t *pool)
|
||||||
|
{
|
||||||
|
blade_identity_t *bi = NULL;
|
||||||
|
|
||||||
|
ks_assert(biP);
|
||||||
|
ks_assert(pool);
|
||||||
|
|
||||||
|
bi = ks_pool_alloc(pool, sizeof(blade_identity_t));
|
||||||
|
bi->pool = pool;
|
||||||
|
*biP = bi;
|
||||||
|
|
||||||
|
return KS_STATUS_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
KS_DECLARE(ks_status_t) blade_identity_destroy(blade_identity_t **biP)
|
||||||
|
{
|
||||||
|
blade_identity_t *bi = NULL;
|
||||||
|
|
||||||
|
ks_assert(biP);
|
||||||
|
ks_assert(*biP);
|
||||||
|
|
||||||
|
bi = *biP;
|
||||||
|
if (bi->uri) {
|
||||||
|
ks_pool_free(bi->pool, &bi->uri);
|
||||||
|
ks_pool_free(bi->pool, &bi->components);
|
||||||
|
}
|
||||||
|
if (bi->parameters) ks_hash_destroy(&bi->parameters);
|
||||||
|
|
||||||
|
ks_pool_free(bi->pool, biP);
|
||||||
|
|
||||||
|
return KS_STATUS_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
KS_DECLARE(ks_status_t) blade_identity_parse(blade_identity_t *bi, const char *uri)
|
||||||
|
{
|
||||||
|
char *tmp = NULL;
|
||||||
|
char *tmp2 = NULL;
|
||||||
|
|
||||||
|
ks_assert(bi);
|
||||||
|
ks_assert(uri);
|
||||||
|
|
||||||
|
ks_log(KS_LOG_DEBUG, "Parsing URI: %s\n", uri);
|
||||||
|
|
||||||
|
if (bi->uri) {
|
||||||
|
ks_pool_free(bi->pool, &bi->uri);
|
||||||
|
ks_pool_free(bi->pool, &bi->components);
|
||||||
|
}
|
||||||
|
bi->uri = ks_pstrdup(bi->pool, uri);
|
||||||
|
bi->components = tmp = ks_pstrdup(bi->pool, uri);
|
||||||
|
|
||||||
|
bi->name = tmp;
|
||||||
|
if (!(tmp = strchr(tmp, '@'))) return KS_STATUS_FAIL;
|
||||||
|
*tmp++ = '\0';
|
||||||
|
|
||||||
|
bi->domain = tmp2 = tmp;
|
||||||
|
if ((tmp = strchr(tmp, '/'))) {
|
||||||
|
*tmp++ = '\0';
|
||||||
|
bi->resource = tmp2 = tmp;
|
||||||
|
} else tmp = tmp2;
|
||||||
|
|
||||||
|
if ((tmp = strchr(tmp, '?'))) {
|
||||||
|
*tmp++ = '\0';
|
||||||
|
|
||||||
|
while (tmp) {
|
||||||
|
char *key = tmp;
|
||||||
|
char *val = NULL;
|
||||||
|
if (!(tmp = strchr(tmp, '='))) return KS_STATUS_FAIL;
|
||||||
|
*tmp++ = '\0';
|
||||||
|
val = tmp;
|
||||||
|
if ((tmp = strchr(tmp, '&'))) {
|
||||||
|
*tmp++ = '\0';
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!bi->parameters) {
|
||||||
|
ks_hash_create(&bi->parameters, KS_HASH_MODE_CASE_INSENSITIVE, KS_HASH_FLAG_NOLOCK | KS_HASH_FLAG_DUP_CHECK, bi->pool);
|
||||||
|
ks_assert(bi->parameters);
|
||||||
|
}
|
||||||
|
ks_hash_insert(bi->parameters, key, val);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return KS_STATUS_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
KS_DECLARE(const char *) blade_identity_uri(blade_identity_t *bi)
|
||||||
|
{
|
||||||
|
ks_assert(bi);
|
||||||
|
|
||||||
|
return bi->uri;
|
||||||
|
}
|
||||||
|
|
||||||
|
KS_DECLARE(const char *) blade_identity_parameter_get(blade_identity_t *bi, const char *key)
|
||||||
|
{
|
||||||
|
ks_assert(bi);
|
||||||
|
ks_assert(key);
|
||||||
|
|
||||||
|
return (const char *)ks_hash_search(bi->parameters, (void *)key, KS_UNLOCKED);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* 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:
|
||||||
|
*/
|
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:
|
||||||
|
*/
|
105
libs/libblade/src/blade_module.c
Normal file
105
libs/libblade/src/blade_module.c
Normal file
@ -0,0 +1,105 @@
|
|||||||
|
/*
|
||||||
|
* 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_module_s {
|
||||||
|
blade_handle_t *handle;
|
||||||
|
ks_pool_t *pool;
|
||||||
|
|
||||||
|
void *module_data;
|
||||||
|
blade_module_callbacks_t *module_callbacks;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
KS_DECLARE(ks_status_t) blade_module_create(blade_module_t **bmP, blade_handle_t *bh, void *module_data, blade_module_callbacks_t *module_callbacks)
|
||||||
|
{
|
||||||
|
blade_module_t *bm = NULL;
|
||||||
|
ks_pool_t *pool = NULL;
|
||||||
|
|
||||||
|
ks_assert(bmP);
|
||||||
|
ks_assert(bh);
|
||||||
|
ks_assert(module_data);
|
||||||
|
ks_assert(module_callbacks);
|
||||||
|
|
||||||
|
pool = blade_handle_pool_get(bh);
|
||||||
|
|
||||||
|
bm = ks_pool_alloc(pool, sizeof(blade_module_t));
|
||||||
|
bm->handle = bh;
|
||||||
|
bm->pool = pool;
|
||||||
|
bm->module_data = module_data;
|
||||||
|
bm->module_callbacks = module_callbacks;
|
||||||
|
*bmP = bm;
|
||||||
|
|
||||||
|
return KS_STATUS_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
KS_DECLARE(ks_status_t) blade_module_destroy(blade_module_t **bmP)
|
||||||
|
{
|
||||||
|
blade_module_t *bm = NULL;
|
||||||
|
|
||||||
|
ks_assert(bmP);
|
||||||
|
ks_assert(*bmP);
|
||||||
|
|
||||||
|
bm = *bmP;
|
||||||
|
|
||||||
|
ks_pool_free(bm->pool, bmP);
|
||||||
|
|
||||||
|
return KS_STATUS_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
KS_DECLARE(blade_handle_t *) blade_module_handle_get(blade_module_t *bm)
|
||||||
|
{
|
||||||
|
ks_assert(bm);
|
||||||
|
|
||||||
|
return bm->handle;
|
||||||
|
}
|
||||||
|
|
||||||
|
KS_DECLARE(void *) blade_module_data_get(blade_module_t *bm)
|
||||||
|
{
|
||||||
|
ks_assert(bm);
|
||||||
|
|
||||||
|
return bm->module_data;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* 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:
|
||||||
|
*/
|
432
libs/libblade/src/blade_module_chat.c
Normal file
432
libs/libblade/src/blade_module_chat.c
Normal file
@ -0,0 +1,432 @@
|
|||||||
|
/*
|
||||||
|
* 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"
|
||||||
|
|
||||||
|
typedef struct blade_module_chat_s blade_module_chat_t;
|
||||||
|
|
||||||
|
struct blade_module_chat_s {
|
||||||
|
blade_handle_t *handle;
|
||||||
|
ks_pool_t *pool;
|
||||||
|
ks_thread_pool_t *tpool;
|
||||||
|
blade_module_t *module;
|
||||||
|
blade_module_callbacks_t *module_callbacks;
|
||||||
|
|
||||||
|
const char *session_state_callback_id;
|
||||||
|
list_t participants;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
ks_status_t blade_module_chat_create(blade_module_chat_t **bm_chatP, blade_handle_t *bh);
|
||||||
|
ks_status_t blade_module_chat_destroy(blade_module_chat_t **bm_chatP);
|
||||||
|
|
||||||
|
// @todo remove exporting this, it's only temporary until DSO loading is in place so wss module can be loaded
|
||||||
|
KS_DECLARE(ks_status_t) blade_module_chat_on_load(blade_module_t **bmP, blade_handle_t *bh);
|
||||||
|
KS_DECLARE(ks_status_t) blade_module_chat_on_unload(blade_module_t *bm);
|
||||||
|
KS_DECLARE(ks_status_t) blade_module_chat_on_startup(blade_module_t *bm, config_setting_t *config);
|
||||||
|
KS_DECLARE(ks_status_t) blade_module_chat_on_shutdown(blade_module_t *bm);
|
||||||
|
|
||||||
|
void blade_module_chat_on_session_state(blade_session_t *bs, blade_session_state_condition_t condition, void *data);
|
||||||
|
|
||||||
|
ks_bool_t blade_chat_join_request_handler(blade_module_t *bm, blade_request_t *breq);
|
||||||
|
ks_bool_t blade_chat_leave_request_handler(blade_module_t *bm, blade_request_t *breq);
|
||||||
|
ks_bool_t blade_chat_send_request_handler(blade_module_t *bm, blade_request_t *breq);
|
||||||
|
|
||||||
|
static blade_module_callbacks_t g_module_chat_callbacks =
|
||||||
|
{
|
||||||
|
blade_module_chat_on_load,
|
||||||
|
blade_module_chat_on_unload,
|
||||||
|
blade_module_chat_on_startup,
|
||||||
|
blade_module_chat_on_shutdown,
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
ks_status_t blade_module_chat_create(blade_module_chat_t **bm_chatP, blade_handle_t *bh)
|
||||||
|
{
|
||||||
|
blade_module_chat_t *bm_chat = NULL;
|
||||||
|
ks_pool_t *pool = NULL;
|
||||||
|
|
||||||
|
ks_assert(bm_chatP);
|
||||||
|
ks_assert(bh);
|
||||||
|
|
||||||
|
pool = blade_handle_pool_get(bh);
|
||||||
|
|
||||||
|
bm_chat = ks_pool_alloc(pool, sizeof(blade_module_chat_t));
|
||||||
|
bm_chat->handle = bh;
|
||||||
|
bm_chat->pool = pool;
|
||||||
|
bm_chat->tpool = blade_handle_tpool_get(bh);
|
||||||
|
bm_chat->session_state_callback_id = NULL;
|
||||||
|
list_init(&bm_chat->participants);
|
||||||
|
|
||||||
|
blade_module_create(&bm_chat->module, bh, bm_chat, &g_module_chat_callbacks);
|
||||||
|
bm_chat->module_callbacks = &g_module_chat_callbacks;
|
||||||
|
|
||||||
|
*bm_chatP = bm_chat;
|
||||||
|
|
||||||
|
ks_log(KS_LOG_DEBUG, "Created\n");
|
||||||
|
|
||||||
|
return KS_STATUS_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
ks_status_t blade_module_chat_destroy(blade_module_chat_t **bm_chatP)
|
||||||
|
{
|
||||||
|
blade_module_chat_t *bm_chat = NULL;
|
||||||
|
|
||||||
|
ks_assert(bm_chatP);
|
||||||
|
ks_assert(*bm_chatP);
|
||||||
|
|
||||||
|
bm_chat = *bm_chatP;
|
||||||
|
|
||||||
|
blade_module_chat_on_shutdown(bm_chat->module);
|
||||||
|
|
||||||
|
list_destroy(&bm_chat->participants);
|
||||||
|
|
||||||
|
blade_module_destroy(&bm_chat->module);
|
||||||
|
|
||||||
|
ks_pool_free(bm_chat->pool, bm_chatP);
|
||||||
|
|
||||||
|
ks_log(KS_LOG_DEBUG, "Destroyed\n");
|
||||||
|
|
||||||
|
return KS_STATUS_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
KS_DECLARE(ks_status_t) blade_module_chat_on_load(blade_module_t **bmP, blade_handle_t *bh)
|
||||||
|
{
|
||||||
|
blade_module_chat_t *bm_chat = NULL;
|
||||||
|
|
||||||
|
ks_assert(bmP);
|
||||||
|
ks_assert(bh);
|
||||||
|
|
||||||
|
blade_module_chat_create(&bm_chat, bh);
|
||||||
|
ks_assert(bm_chat);
|
||||||
|
|
||||||
|
*bmP = bm_chat->module;
|
||||||
|
|
||||||
|
ks_log(KS_LOG_DEBUG, "Loaded\n");
|
||||||
|
|
||||||
|
return KS_STATUS_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
KS_DECLARE(ks_status_t) blade_module_chat_on_unload(blade_module_t *bm)
|
||||||
|
{
|
||||||
|
blade_module_chat_t *bm_chat = NULL;
|
||||||
|
|
||||||
|
ks_assert(bm);
|
||||||
|
|
||||||
|
bm_chat = blade_module_data_get(bm);
|
||||||
|
|
||||||
|
blade_module_chat_destroy(&bm_chat);
|
||||||
|
|
||||||
|
ks_log(KS_LOG_DEBUG, "Unloaded\n");
|
||||||
|
|
||||||
|
return KS_STATUS_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
ks_status_t blade_module_chat_config(blade_module_chat_t *bm_chat, config_setting_t *config)
|
||||||
|
{
|
||||||
|
config_setting_t *chat = NULL;
|
||||||
|
|
||||||
|
ks_assert(bm_chat);
|
||||||
|
ks_assert(config);
|
||||||
|
|
||||||
|
if (!config_setting_is_group(config)) {
|
||||||
|
ks_log(KS_LOG_DEBUG, "!config_setting_is_group(config)\n");
|
||||||
|
return KS_STATUS_FAIL;
|
||||||
|
}
|
||||||
|
|
||||||
|
chat = config_setting_get_member(config, "chat");
|
||||||
|
if (chat) {
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// Configuration is valid, now assign it to the variables that are used
|
||||||
|
// If the configuration was invalid, then this does not get changed
|
||||||
|
|
||||||
|
ks_log(KS_LOG_DEBUG, "Configured\n");
|
||||||
|
|
||||||
|
return KS_STATUS_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
KS_DECLARE(ks_status_t) blade_module_chat_on_startup(blade_module_t *bm, config_setting_t *config)
|
||||||
|
{
|
||||||
|
blade_module_chat_t *bm_chat = NULL;
|
||||||
|
blade_space_t *space = NULL;
|
||||||
|
blade_method_t *method = NULL;
|
||||||
|
|
||||||
|
ks_assert(bm);
|
||||||
|
ks_assert(config);
|
||||||
|
|
||||||
|
bm_chat = (blade_module_chat_t *)blade_module_data_get(bm);
|
||||||
|
|
||||||
|
if (blade_module_chat_config(bm_chat, config) != KS_STATUS_SUCCESS) {
|
||||||
|
ks_log(KS_LOG_DEBUG, "blade_module_chat_config failed\n");
|
||||||
|
return KS_STATUS_FAIL;
|
||||||
|
}
|
||||||
|
|
||||||
|
blade_space_create(&space, bm_chat->handle, bm, "blade.chat");
|
||||||
|
ks_assert(space);
|
||||||
|
|
||||||
|
blade_method_create(&method, space, "join", blade_chat_join_request_handler);
|
||||||
|
ks_assert(method);
|
||||||
|
blade_space_methods_add(space, method);
|
||||||
|
|
||||||
|
blade_method_create(&method, space, "leave", blade_chat_leave_request_handler);
|
||||||
|
ks_assert(method);
|
||||||
|
blade_space_methods_add(space, method);
|
||||||
|
|
||||||
|
blade_method_create(&method, space, "send", blade_chat_send_request_handler);
|
||||||
|
ks_assert(method);
|
||||||
|
blade_space_methods_add(space, method);
|
||||||
|
|
||||||
|
blade_handle_space_register(space);
|
||||||
|
|
||||||
|
blade_handle_session_state_callback_register(blade_module_handle_get(bm), bm, blade_module_chat_on_session_state, &bm_chat->session_state_callback_id);
|
||||||
|
|
||||||
|
ks_log(KS_LOG_DEBUG, "Started\n");
|
||||||
|
|
||||||
|
return KS_STATUS_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
KS_DECLARE(ks_status_t) blade_module_chat_on_shutdown(blade_module_t *bm)
|
||||||
|
{
|
||||||
|
blade_module_chat_t *bm_chat = NULL;
|
||||||
|
|
||||||
|
ks_assert(bm);
|
||||||
|
|
||||||
|
bm_chat = (blade_module_chat_t *)blade_module_data_get(bm);
|
||||||
|
ks_assert(bm_chat);
|
||||||
|
|
||||||
|
if (bm_chat->session_state_callback_id) blade_handle_session_state_callback_unregister(blade_module_handle_get(bm), bm_chat->session_state_callback_id);
|
||||||
|
bm_chat->session_state_callback_id = NULL;
|
||||||
|
|
||||||
|
ks_log(KS_LOG_DEBUG, "Stopped\n");
|
||||||
|
|
||||||
|
return KS_STATUS_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
void blade_module_chat_on_session_state(blade_session_t *bs, blade_session_state_condition_t condition, void *data)
|
||||||
|
{
|
||||||
|
blade_module_t *bm = NULL;
|
||||||
|
blade_module_chat_t *bm_chat = NULL;
|
||||||
|
|
||||||
|
ks_assert(bs);
|
||||||
|
ks_assert(data);
|
||||||
|
|
||||||
|
bm = (blade_module_t *)data;
|
||||||
|
bm_chat = (blade_module_chat_t *)blade_module_data_get(bm);
|
||||||
|
ks_assert(bm_chat);
|
||||||
|
|
||||||
|
if (blade_session_state_get(bs) == BLADE_SESSION_STATE_HANGUP && condition == BLADE_SESSION_STATE_CONDITION_PRE) {
|
||||||
|
cJSON *props = NULL;
|
||||||
|
|
||||||
|
ks_log(KS_LOG_DEBUG, "Removing session from chat participants if present\n");
|
||||||
|
|
||||||
|
props = blade_session_properties_get(bs);
|
||||||
|
ks_assert(props);
|
||||||
|
|
||||||
|
cJSON_DeleteItemFromObject(props, "blade.chat.participant");
|
||||||
|
|
||||||
|
list_delete(&bm_chat->participants, blade_session_id_get(bs)); // @todo make copy of session id instead and search manually, also free the id
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ks_bool_t blade_chat_join_request_handler(blade_module_t *bm, blade_request_t *breq)
|
||||||
|
{
|
||||||
|
blade_module_chat_t *bm_chat = NULL;
|
||||||
|
blade_session_t *bs = NULL;
|
||||||
|
cJSON *res = NULL;
|
||||||
|
cJSON *props = NULL;
|
||||||
|
cJSON *props_participant = NULL;
|
||||||
|
|
||||||
|
ks_assert(bm);
|
||||||
|
ks_assert(breq);
|
||||||
|
|
||||||
|
ks_log(KS_LOG_DEBUG, "Request Received!\n");
|
||||||
|
|
||||||
|
bm_chat = (blade_module_chat_t *)blade_module_data_get(bm);
|
||||||
|
ks_assert(bm_chat);
|
||||||
|
|
||||||
|
bs = blade_handle_sessions_get(breq->handle, breq->session_id);
|
||||||
|
ks_assert(bs);
|
||||||
|
|
||||||
|
// @todo properties only used to demonstrate a flexible container for session data, should just rely on the participants list/hash
|
||||||
|
blade_session_properties_write_lock(bs, KS_TRUE);
|
||||||
|
|
||||||
|
props = blade_session_properties_get(bs);
|
||||||
|
ks_assert(props);
|
||||||
|
|
||||||
|
props_participant = cJSON_GetObjectItem(props, "blade.chat.participant");
|
||||||
|
if (props_participant && props_participant->type == cJSON_True) {
|
||||||
|
ks_log(KS_LOG_DEBUG, "Session (%s) attempted to join chat but is already a participant\n", blade_session_id_get(bs));
|
||||||
|
blade_rpc_error_create(breq->pool, &res, NULL, breq->message_id, -10000, "Already a participant of chat");
|
||||||
|
} else {
|
||||||
|
ks_log(KS_LOG_DEBUG, "Session (%s) joined chat\n", blade_session_id_get(bs));
|
||||||
|
|
||||||
|
if (props_participant) props_participant->type = cJSON_True;
|
||||||
|
else cJSON_AddTrueToObject(props, "blade.chat.participant");
|
||||||
|
|
||||||
|
list_append(&bm_chat->participants, blade_session_id_get(bs)); // @todo make copy of session id instead and cleanup when removed
|
||||||
|
|
||||||
|
blade_rpc_response_create(breq->pool, &res, NULL, breq->message_id);
|
||||||
|
|
||||||
|
// @todo create an event to send to participants when a session joins and leaves, send after main response though
|
||||||
|
}
|
||||||
|
|
||||||
|
blade_session_properties_write_unlock(bs);
|
||||||
|
|
||||||
|
blade_session_send(bs, res, NULL);
|
||||||
|
|
||||||
|
blade_session_read_unlock(bs);
|
||||||
|
|
||||||
|
cJSON_Delete(res);
|
||||||
|
|
||||||
|
return KS_FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
ks_bool_t blade_chat_leave_request_handler(blade_module_t *bm, blade_request_t *breq)
|
||||||
|
{
|
||||||
|
blade_module_chat_t *bm_chat = NULL;
|
||||||
|
blade_session_t *bs = NULL;
|
||||||
|
cJSON *res = NULL;
|
||||||
|
cJSON *props = NULL;
|
||||||
|
cJSON *props_participant = NULL;
|
||||||
|
|
||||||
|
ks_assert(bm);
|
||||||
|
ks_assert(breq);
|
||||||
|
|
||||||
|
ks_log(KS_LOG_DEBUG, "Request Received!\n");
|
||||||
|
|
||||||
|
bm_chat = (blade_module_chat_t *)blade_module_data_get(bm);
|
||||||
|
ks_assert(bm_chat);
|
||||||
|
|
||||||
|
bs = blade_handle_sessions_get(breq->handle, breq->session_id);
|
||||||
|
ks_assert(bs);
|
||||||
|
|
||||||
|
blade_session_properties_write_lock(bs, KS_TRUE);
|
||||||
|
|
||||||
|
props = blade_session_properties_get(bs);
|
||||||
|
ks_assert(props);
|
||||||
|
|
||||||
|
props_participant = cJSON_GetObjectItem(props, "blade.chat.participant");
|
||||||
|
if (!props_participant || props_participant->type == cJSON_False) {
|
||||||
|
ks_log(KS_LOG_DEBUG, "Session (%s) attempted to leave chat but is not a participant\n", blade_session_id_get(bs));
|
||||||
|
blade_rpc_error_create(breq->pool, &res, NULL, breq->message_id, -10000, "Not a participant of chat");
|
||||||
|
} else {
|
||||||
|
ks_log(KS_LOG_DEBUG, "Session (%s) left chat\n", blade_session_id_get(bs));
|
||||||
|
|
||||||
|
cJSON_DeleteItemFromObject(props, "blade.chat.participant");
|
||||||
|
|
||||||
|
list_delete(&bm_chat->participants, blade_session_id_get(bs)); // @todo make copy of session id instead and search manually, also free the id
|
||||||
|
|
||||||
|
blade_rpc_response_create(breq->pool, &res, NULL, breq->message_id);
|
||||||
|
|
||||||
|
// @todo create an event to send to participants when a session joins and leaves, send after main response though
|
||||||
|
}
|
||||||
|
|
||||||
|
blade_session_properties_write_unlock(bs);
|
||||||
|
|
||||||
|
blade_session_send(bs, res, NULL);
|
||||||
|
|
||||||
|
blade_session_read_unlock(bs);
|
||||||
|
|
||||||
|
cJSON_Delete(res);
|
||||||
|
|
||||||
|
return KS_FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
ks_bool_t blade_chat_send_request_handler(blade_module_t *bm, blade_request_t *breq)
|
||||||
|
{
|
||||||
|
blade_module_chat_t *bm_chat = NULL;
|
||||||
|
blade_session_t *bs = NULL;
|
||||||
|
cJSON *params = NULL;
|
||||||
|
cJSON *res = NULL;
|
||||||
|
cJSON *event = NULL;
|
||||||
|
const char *message = NULL;
|
||||||
|
ks_bool_t sendevent = KS_FALSE;
|
||||||
|
|
||||||
|
ks_assert(bm);
|
||||||
|
ks_assert(breq);
|
||||||
|
|
||||||
|
ks_log(KS_LOG_DEBUG, "Request Received!\n");
|
||||||
|
|
||||||
|
bm_chat = (blade_module_chat_t *)blade_module_data_get(bm);
|
||||||
|
ks_assert(bm_chat);
|
||||||
|
|
||||||
|
params = cJSON_GetObjectItem(breq->message, "params"); // @todo cache this in blade_request_t for quicker/easier access
|
||||||
|
if (!params) {
|
||||||
|
ks_log(KS_LOG_DEBUG, "Session (%s) attempted to send chat message with no 'params' object\n", blade_session_id_get(bs));
|
||||||
|
blade_rpc_error_create(breq->pool, &res, NULL, breq->message_id, -32602, "Missing params object");
|
||||||
|
} else if (!(message = cJSON_GetObjectCstr(params, "message"))) {
|
||||||
|
ks_log(KS_LOG_DEBUG, "Session (%s) attempted to send chat message with no 'message'\n", blade_session_id_get(bs));
|
||||||
|
blade_rpc_error_create(breq->pool, &res, NULL, breq->message_id, -32602, "Missing params message string");
|
||||||
|
}
|
||||||
|
|
||||||
|
bs = blade_handle_sessions_get(breq->handle, breq->session_id);
|
||||||
|
ks_assert(bs);
|
||||||
|
|
||||||
|
if (!res) {
|
||||||
|
blade_rpc_response_create(breq->pool, &res, NULL, breq->message_id);
|
||||||
|
sendevent = KS_TRUE;
|
||||||
|
}
|
||||||
|
blade_session_send(bs, res, NULL);
|
||||||
|
|
||||||
|
blade_session_read_unlock(bs);
|
||||||
|
|
||||||
|
cJSON_Delete(res);
|
||||||
|
|
||||||
|
if (sendevent) {
|
||||||
|
blade_rpc_event_create(breq->pool, &event, &res, "blade.chat.message");
|
||||||
|
ks_assert(event);
|
||||||
|
cJSON_AddStringToObject(res, "from", breq->session_id); // @todo should really be the identity, but we don't have that in place yet
|
||||||
|
cJSON_AddStringToObject(res, "message", message);
|
||||||
|
|
||||||
|
blade_handle_sessions_send(breq->handle, &bm_chat->participants, NULL, event);
|
||||||
|
|
||||||
|
cJSON_Delete(event);
|
||||||
|
}
|
||||||
|
|
||||||
|
return KS_FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* 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:
|
||||||
|
*/
|
1321
libs/libblade/src/blade_module_wss.c
Normal file
1321
libs/libblade/src/blade_module_wss.c
Normal file
File diff suppressed because it is too large
Load Diff
@ -1,150 +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"
|
|
||||||
|
|
||||||
#define KS_DHT_TPOOL_MIN 2
|
|
||||||
#define KS_DHT_TPOOL_MAX 8
|
|
||||||
#define KS_DHT_TPOOL_STACK (1024 * 256)
|
|
||||||
#define KS_DHT_TPOOL_IDLE 10
|
|
||||||
|
|
||||||
typedef enum {
|
|
||||||
BP_NONE = 0,
|
|
||||||
BP_MYPOOL = (1 << 0),
|
|
||||||
BP_MYTPOOL = (1 << 1)
|
|
||||||
} bppvt_flag_t;
|
|
||||||
|
|
||||||
struct blade_peer_s {
|
|
||||||
bppvt_flag_t flags;
|
|
||||||
ks_pool_t *pool;
|
|
||||||
ks_thread_pool_t *tpool;
|
|
||||||
ks_dht_t *dht;
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
KS_DECLARE(ks_status_t) blade_peer_destroy(blade_peer_t **bpP)
|
|
||||||
{
|
|
||||||
blade_peer_t *bp = NULL;
|
|
||||||
bppvt_flag_t flags;
|
|
||||||
ks_pool_t *pool;
|
|
||||||
|
|
||||||
ks_assert(bpP);
|
|
||||||
|
|
||||||
bp = *bpP;
|
|
||||||
*bpP = NULL;
|
|
||||||
|
|
||||||
ks_assert(bp);
|
|
||||||
|
|
||||||
flags = bp->flags;
|
|
||||||
pool = bp->pool;
|
|
||||||
|
|
||||||
if (bp->dht) ks_dht_destroy(&bp->dht);
|
|
||||||
if (bp->tpool && (flags & BP_MYTPOOL)) ks_thread_pool_destroy(&bp->tpool);
|
|
||||||
|
|
||||||
ks_pool_free(bp->pool, &bp);
|
|
||||||
|
|
||||||
if (pool && (flags & BP_MYPOOL)) ks_pool_close(&pool);
|
|
||||||
|
|
||||||
return KS_STATUS_SUCCESS;
|
|
||||||
}
|
|
||||||
|
|
||||||
KS_DECLARE(ks_status_t) blade_peer_create(blade_peer_t **bpP, ks_pool_t *pool, ks_thread_pool_t *tpool, ks_dht_nodeid_t *nodeid)
|
|
||||||
{
|
|
||||||
bppvt_flag_t newflags = BP_NONE;
|
|
||||||
blade_peer_t *bp = NULL;
|
|
||||||
ks_dht_t *dht = NULL;
|
|
||||||
|
|
||||||
if (!pool) {
|
|
||||||
newflags |= BP_MYPOOL;
|
|
||||||
ks_pool_open(&pool);
|
|
||||||
ks_assert(pool);
|
|
||||||
}
|
|
||||||
if (!tpool) {
|
|
||||||
newflags |= BP_MYTPOOL;
|
|
||||||
ks_thread_pool_create(&tpool, BLADE_PEER_TPOOL_MIN, BLADE_PEER_TPOOL_MAX, BLADE_PEER_TPOOL_STACK, KS_PRI_NORMAL, BLADE_PEER_TPOOL_IDLE);
|
|
||||||
ks_assert(tpool);
|
|
||||||
}
|
|
||||||
ks_dht_create(&dht, pool, tpool, nodeid);
|
|
||||||
ks_assert(dht);
|
|
||||||
|
|
||||||
bp = ks_pool_alloc(pool, sizeof(*bp));
|
|
||||||
bp->flags = newflags;
|
|
||||||
bp->pool = pool;
|
|
||||||
bp->tpool = tpool;
|
|
||||||
bp->dht = dht;
|
|
||||||
*bpP = bp;
|
|
||||||
|
|
||||||
return KS_STATUS_SUCCESS;
|
|
||||||
}
|
|
||||||
|
|
||||||
KS_DECLARE(ks_dht_nodeid_t *) blade_peer_myid(blade_peer_t *bp)
|
|
||||||
{
|
|
||||||
ks_assert(bp);
|
|
||||||
ks_assert(bp->dht);
|
|
||||||
|
|
||||||
return &bp->dht->nodeid;
|
|
||||||
}
|
|
||||||
|
|
||||||
KS_DECLARE(void) blade_peer_autoroute(blade_peer_t *bp, ks_bool_t autoroute, ks_port_t port)
|
|
||||||
{
|
|
||||||
ks_assert(bp);
|
|
||||||
|
|
||||||
ks_dht_autoroute(bp->dht, autoroute, port);
|
|
||||||
}
|
|
||||||
|
|
||||||
KS_DECLARE(ks_status_t) blade_peer_bind(blade_peer_t *bp, const ks_sockaddr_t *addr, ks_dht_endpoint_t **endpoint)
|
|
||||||
{
|
|
||||||
ks_assert(bp);
|
|
||||||
ks_assert(addr);
|
|
||||||
|
|
||||||
return ks_dht_bind(bp->dht, addr, endpoint);
|
|
||||||
}
|
|
||||||
|
|
||||||
KS_DECLARE(void) blade_peer_pulse(blade_peer_t *bp, int32_t timeout)
|
|
||||||
{
|
|
||||||
ks_assert(bp);
|
|
||||||
ks_assert(timeout >= 0);
|
|
||||||
|
|
||||||
ks_dht_pulse(bp->dht, timeout);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* 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:
|
|
||||||
*/
|
|
297
libs/libblade/src/blade_protocol.c
Normal file
297
libs/libblade/src/blade_protocol.c
Normal file
@ -0,0 +1,297 @@
|
|||||||
|
/*
|
||||||
|
* 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"
|
||||||
|
|
||||||
|
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;
|
||||||
|
|
||||||
|
ks_assert(breqP);
|
||||||
|
ks_assert(bh);
|
||||||
|
ks_assert(session_id);
|
||||||
|
ks_assert(json);
|
||||||
|
|
||||||
|
pool = blade_handle_pool_get(bh);
|
||||||
|
ks_assert(pool);
|
||||||
|
|
||||||
|
breq = ks_pool_alloc(pool, sizeof(blade_request_t));
|
||||||
|
breq->handle = bh;
|
||||||
|
breq->pool = pool;
|
||||||
|
breq->session_id = ks_pstrdup(pool, session_id);
|
||||||
|
breq->message = cJSON_Duplicate(json, 1);
|
||||||
|
breq->message_id = cJSON_GetObjectCstr(breq->message, "id");
|
||||||
|
breq->callback = callback;
|
||||||
|
|
||||||
|
*breqP = breq;
|
||||||
|
|
||||||
|
return KS_STATUS_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
KS_DECLARE(ks_status_t) blade_request_destroy(blade_request_t **breqP)
|
||||||
|
{
|
||||||
|
blade_request_t *breq = NULL;
|
||||||
|
|
||||||
|
ks_assert(breqP);
|
||||||
|
ks_assert(*breqP);
|
||||||
|
|
||||||
|
breq = *breqP;
|
||||||
|
|
||||||
|
ks_pool_free(breq->pool, (void **)&breq->session_id);
|
||||||
|
cJSON_Delete(breq->message);
|
||||||
|
|
||||||
|
ks_pool_free(breq->pool, breqP);
|
||||||
|
|
||||||
|
return KS_STATUS_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
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)
|
||||||
|
{
|
||||||
|
blade_response_t *bres = NULL;
|
||||||
|
ks_pool_t *pool = NULL;
|
||||||
|
|
||||||
|
ks_assert(bresP);
|
||||||
|
ks_assert(bh);
|
||||||
|
ks_assert(session_id);
|
||||||
|
ks_assert(breq);
|
||||||
|
ks_assert(json);
|
||||||
|
|
||||||
|
pool = blade_handle_pool_get(bh);
|
||||||
|
ks_assert(pool);
|
||||||
|
|
||||||
|
bres = ks_pool_alloc(pool, sizeof(blade_response_t));
|
||||||
|
bres->handle = bh;
|
||||||
|
bres->pool = pool;
|
||||||
|
bres->session_id = ks_pstrdup(pool, session_id);
|
||||||
|
bres->request = breq;
|
||||||
|
bres->message = cJSON_Duplicate(json, 1);
|
||||||
|
|
||||||
|
*bresP = bres;
|
||||||
|
|
||||||
|
return KS_STATUS_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
KS_DECLARE(ks_status_t) blade_response_destroy(blade_response_t **bresP)
|
||||||
|
{
|
||||||
|
blade_response_t *bres = NULL;
|
||||||
|
|
||||||
|
ks_assert(bresP);
|
||||||
|
ks_assert(*bresP);
|
||||||
|
|
||||||
|
bres = *bresP;
|
||||||
|
|
||||||
|
ks_pool_free(bres->pool, (void **)&bres->session_id);
|
||||||
|
blade_request_destroy(&bres->request);
|
||||||
|
cJSON_Delete(bres->message);
|
||||||
|
|
||||||
|
ks_pool_free(bres->pool, bresP);
|
||||||
|
|
||||||
|
return KS_STATUS_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
KS_DECLARE(ks_status_t) blade_event_create(blade_event_t **bevP,
|
||||||
|
blade_handle_t *bh,
|
||||||
|
const char *session_id,
|
||||||
|
cJSON *json)
|
||||||
|
{
|
||||||
|
blade_event_t *bev = NULL;
|
||||||
|
ks_pool_t *pool = NULL;
|
||||||
|
|
||||||
|
ks_assert(bevP);
|
||||||
|
ks_assert(bh);
|
||||||
|
ks_assert(session_id);
|
||||||
|
ks_assert(json);
|
||||||
|
|
||||||
|
pool = blade_handle_pool_get(bh);
|
||||||
|
ks_assert(pool);
|
||||||
|
|
||||||
|
bev = ks_pool_alloc(pool, sizeof(blade_event_t));
|
||||||
|
bev->handle = bh;
|
||||||
|
bev->pool = pool;
|
||||||
|
bev->session_id = ks_pstrdup(pool, session_id);
|
||||||
|
bev->message = cJSON_Duplicate(json, 1);
|
||||||
|
|
||||||
|
*bevP = bev;
|
||||||
|
|
||||||
|
return KS_STATUS_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
KS_DECLARE(ks_status_t) blade_event_destroy(blade_event_t **bevP)
|
||||||
|
{
|
||||||
|
blade_event_t *bev = NULL;
|
||||||
|
|
||||||
|
ks_assert(bevP);
|
||||||
|
ks_assert(*bevP);
|
||||||
|
|
||||||
|
bev = *bevP;
|
||||||
|
|
||||||
|
ks_pool_free(bev->pool, (void **)&bev->session_id);
|
||||||
|
cJSON_Delete(bev->message);
|
||||||
|
|
||||||
|
ks_pool_free(bev->pool, bevP);
|
||||||
|
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
KS_DECLARE(ks_status_t) blade_rpc_event_create(ks_pool_t *pool, cJSON **json, cJSON **result, const char *event)
|
||||||
|
{
|
||||||
|
cJSON *root = NULL;
|
||||||
|
cJSON *b = NULL;
|
||||||
|
cJSON *r = NULL;
|
||||||
|
|
||||||
|
ks_assert(pool);
|
||||||
|
ks_assert(json);
|
||||||
|
ks_assert(event);
|
||||||
|
|
||||||
|
root = cJSON_CreateObject();
|
||||||
|
|
||||||
|
cJSON_AddStringToObject(root, "jsonrpc", "2.0");
|
||||||
|
|
||||||
|
b = cJSON_CreateObject();
|
||||||
|
cJSON_AddStringToObject(b, "event", event);
|
||||||
|
cJSON_AddItemToObject(root, "blade", b);
|
||||||
|
|
||||||
|
if (result) {
|
||||||
|
r = cJSON_CreateObject();
|
||||||
|
cJSON_AddItemToObject(root, "result", r);
|
||||||
|
*result = r;
|
||||||
|
}
|
||||||
|
|
||||||
|
*json = root;
|
||||||
|
|
||||||
|
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:
|
||||||
|
*/
|
748
libs/libblade/src/blade_session.c
Normal file
748
libs/libblade/src/blade_session.c
Normal file
@ -0,0 +1,748 @@
|
|||||||
|
/*
|
||||||
|
* 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_session_s {
|
||||||
|
blade_handle_t *handle;
|
||||||
|
ks_pool_t *pool;
|
||||||
|
|
||||||
|
ks_bool_t shutdown;
|
||||||
|
ks_thread_t *state_thread;
|
||||||
|
blade_session_state_t state;
|
||||||
|
|
||||||
|
const char *id;
|
||||||
|
ks_rwl_t *lock;
|
||||||
|
list_t connections;
|
||||||
|
ks_time_t ttl;
|
||||||
|
|
||||||
|
ks_q_t *sending;
|
||||||
|
ks_q_t *receiving;
|
||||||
|
|
||||||
|
cJSON *properties;
|
||||||
|
ks_rwl_t *properties_lock;
|
||||||
|
};
|
||||||
|
|
||||||
|
void *blade_session_state_thread(ks_thread_t *thread, void *data);
|
||||||
|
ks_status_t blade_session_state_on_destroy(blade_session_t *bs);
|
||||||
|
ks_status_t blade_session_state_on_hangup(blade_session_t *bs);
|
||||||
|
ks_status_t blade_session_state_on_ready(blade_session_t *bs);
|
||||||
|
ks_status_t blade_session_process(blade_session_t *bs, cJSON *json);
|
||||||
|
|
||||||
|
KS_DECLARE(ks_status_t) blade_session_create(blade_session_t **bsP, blade_handle_t *bh)
|
||||||
|
{
|
||||||
|
blade_session_t *bs = NULL;
|
||||||
|
ks_pool_t *pool = NULL;
|
||||||
|
uuid_t id;
|
||||||
|
|
||||||
|
ks_assert(bsP);
|
||||||
|
ks_assert(bh);
|
||||||
|
|
||||||
|
pool = blade_handle_pool_get(bh);
|
||||||
|
|
||||||
|
bs = ks_pool_alloc(pool, sizeof(blade_session_t));
|
||||||
|
bs->handle = bh;
|
||||||
|
bs->pool = pool;
|
||||||
|
|
||||||
|
ks_uuid(&id);
|
||||||
|
bs->id = ks_uuid_str(pool, &id);
|
||||||
|
|
||||||
|
ks_rwl_create(&bs->lock, pool);
|
||||||
|
ks_assert(bs->lock);
|
||||||
|
|
||||||
|
list_init(&bs->connections);
|
||||||
|
ks_q_create(&bs->sending, pool, 0);
|
||||||
|
ks_assert(bs->sending);
|
||||||
|
ks_q_create(&bs->receiving, pool, 0);
|
||||||
|
ks_assert(bs->receiving);
|
||||||
|
|
||||||
|
bs->properties = cJSON_CreateObject();
|
||||||
|
ks_assert(bs->properties);
|
||||||
|
ks_rwl_create(&bs->properties_lock, pool);
|
||||||
|
ks_assert(bs->properties_lock);
|
||||||
|
|
||||||
|
*bsP = bs;
|
||||||
|
|
||||||
|
ks_log(KS_LOG_DEBUG, "Created\n");
|
||||||
|
|
||||||
|
return KS_STATUS_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
KS_DECLARE(ks_status_t) blade_session_destroy(blade_session_t **bsP)
|
||||||
|
{
|
||||||
|
blade_session_t *bs = NULL;
|
||||||
|
|
||||||
|
ks_assert(bsP);
|
||||||
|
ks_assert(*bsP);
|
||||||
|
|
||||||
|
bs = *bsP;
|
||||||
|
|
||||||
|
blade_session_shutdown(bs);
|
||||||
|
|
||||||
|
cJSON_Delete(bs->properties);
|
||||||
|
bs->properties = NULL;
|
||||||
|
ks_rwl_destroy(&bs->properties_lock);
|
||||||
|
|
||||||
|
list_destroy(&bs->connections);
|
||||||
|
ks_q_destroy(&bs->receiving);
|
||||||
|
ks_q_destroy(&bs->sending);
|
||||||
|
|
||||||
|
ks_rwl_destroy(&bs->lock);
|
||||||
|
|
||||||
|
ks_pool_free(bs->pool, &bs->id);
|
||||||
|
|
||||||
|
ks_pool_free(bs->pool, bsP);
|
||||||
|
|
||||||
|
ks_log(KS_LOG_DEBUG, "Destroyed\n");
|
||||||
|
|
||||||
|
return KS_STATUS_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
KS_DECLARE(ks_status_t) blade_session_startup(blade_session_t *bs)
|
||||||
|
{
|
||||||
|
ks_assert(bs);
|
||||||
|
|
||||||
|
blade_session_state_set(bs, BLADE_SESSION_STATE_NONE);
|
||||||
|
|
||||||
|
if (ks_thread_create_ex(&bs->state_thread,
|
||||||
|
blade_session_state_thread,
|
||||||
|
bs,
|
||||||
|
KS_THREAD_FLAG_DEFAULT,
|
||||||
|
KS_THREAD_DEFAULT_STACK,
|
||||||
|
KS_PRI_NORMAL,
|
||||||
|
bs->pool) != KS_STATUS_SUCCESS) {
|
||||||
|
// @todo error logging
|
||||||
|
return KS_STATUS_FAIL;
|
||||||
|
}
|
||||||
|
|
||||||
|
ks_log(KS_LOG_DEBUG, "Started\n");
|
||||||
|
|
||||||
|
return KS_STATUS_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
KS_DECLARE(ks_status_t) blade_session_shutdown(blade_session_t *bs)
|
||||||
|
{
|
||||||
|
cJSON *json = NULL;
|
||||||
|
|
||||||
|
ks_assert(bs);
|
||||||
|
|
||||||
|
if (bs->state_thread) {
|
||||||
|
bs->shutdown = KS_TRUE;
|
||||||
|
ks_thread_join(bs->state_thread);
|
||||||
|
ks_pool_free(bs->pool, &bs->state_thread);
|
||||||
|
bs->shutdown = KS_FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
while (ks_q_trypop(bs->sending, (void **)&json) == KS_STATUS_SUCCESS && json) cJSON_Delete(json);
|
||||||
|
while (ks_q_trypop(bs->receiving, (void **)&json) == KS_STATUS_SUCCESS && json) cJSON_Delete(json);
|
||||||
|
|
||||||
|
list_iterator_start(&bs->connections);
|
||||||
|
while (list_iterator_hasnext(&bs->connections)) {
|
||||||
|
const char *id = (const char *)list_iterator_next(&bs->connections);
|
||||||
|
ks_pool_free(bs->pool, &id);
|
||||||
|
}
|
||||||
|
list_iterator_stop(&bs->connections);
|
||||||
|
list_clear(&bs->connections);
|
||||||
|
|
||||||
|
ks_log(KS_LOG_DEBUG, "Stopped\n");
|
||||||
|
|
||||||
|
return KS_STATUS_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
KS_DECLARE(blade_handle_t *) blade_session_handle_get(blade_session_t *bs)
|
||||||
|
{
|
||||||
|
ks_assert(bs);
|
||||||
|
|
||||||
|
return bs->handle;
|
||||||
|
}
|
||||||
|
|
||||||
|
KS_DECLARE(ks_pool_t *) blade_session_pool_get(blade_session_t *bs)
|
||||||
|
{
|
||||||
|
ks_assert(bs);
|
||||||
|
|
||||||
|
return bs->pool;
|
||||||
|
}
|
||||||
|
|
||||||
|
KS_DECLARE(const char *) blade_session_id_get(blade_session_t *bs)
|
||||||
|
{
|
||||||
|
ks_assert(bs);
|
||||||
|
|
||||||
|
return bs->id;
|
||||||
|
}
|
||||||
|
|
||||||
|
KS_DECLARE(void) blade_session_id_set(blade_session_t *bs, const char *id)
|
||||||
|
{
|
||||||
|
ks_assert(bs);
|
||||||
|
ks_assert(id);
|
||||||
|
|
||||||
|
if (bs->id) ks_pool_free(bs->pool, &bs->id);
|
||||||
|
bs->id = ks_pstrdup(bs->pool, id);
|
||||||
|
}
|
||||||
|
|
||||||
|
KS_DECLARE(blade_session_state_t) blade_session_state_get(blade_session_t *bs)
|
||||||
|
{
|
||||||
|
ks_assert(bs);
|
||||||
|
|
||||||
|
return bs->state;
|
||||||
|
}
|
||||||
|
|
||||||
|
KS_DECLARE(cJSON *) blade_session_properties_get(blade_session_t *bs)
|
||||||
|
{
|
||||||
|
ks_assert(bs);
|
||||||
|
|
||||||
|
return bs->properties;
|
||||||
|
}
|
||||||
|
|
||||||
|
KS_DECLARE(ks_status_t) blade_session_read_lock(blade_session_t *bs, ks_bool_t block)
|
||||||
|
{
|
||||||
|
ks_status_t ret = KS_STATUS_SUCCESS;
|
||||||
|
|
||||||
|
ks_assert(bs);
|
||||||
|
|
||||||
|
if (block) ret = ks_rwl_read_lock(bs->lock);
|
||||||
|
else ret = ks_rwl_try_read_lock(bs->lock);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
KS_DECLARE(ks_status_t) blade_session_read_unlock(blade_session_t *bs)
|
||||||
|
{
|
||||||
|
ks_assert(bs);
|
||||||
|
|
||||||
|
return ks_rwl_read_unlock(bs->lock);
|
||||||
|
}
|
||||||
|
|
||||||
|
KS_DECLARE(ks_status_t) blade_session_write_lock(blade_session_t *bs, ks_bool_t block)
|
||||||
|
{
|
||||||
|
ks_status_t ret = KS_STATUS_SUCCESS;
|
||||||
|
|
||||||
|
ks_assert(bs);
|
||||||
|
|
||||||
|
if (block) ret = ks_rwl_write_lock(bs->lock);
|
||||||
|
else ret = ks_rwl_try_write_lock(bs->lock);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
KS_DECLARE(ks_status_t) blade_session_write_unlock(blade_session_t *bs)
|
||||||
|
{
|
||||||
|
ks_assert(bs);
|
||||||
|
|
||||||
|
return ks_rwl_write_unlock(bs->lock);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
KS_DECLARE(ks_status_t) blade_session_properties_read_lock(blade_session_t *bs, ks_bool_t block)
|
||||||
|
{
|
||||||
|
ks_status_t ret = KS_STATUS_SUCCESS;
|
||||||
|
|
||||||
|
ks_assert(bs);
|
||||||
|
|
||||||
|
if (block) ret = ks_rwl_read_lock(bs->properties_lock);
|
||||||
|
else ret = ks_rwl_try_read_lock(bs->properties_lock);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
KS_DECLARE(ks_status_t) blade_session_properties_read_unlock(blade_session_t *bs)
|
||||||
|
{
|
||||||
|
ks_assert(bs);
|
||||||
|
|
||||||
|
return ks_rwl_read_unlock(bs->properties_lock);
|
||||||
|
}
|
||||||
|
|
||||||
|
KS_DECLARE(ks_status_t) blade_session_properties_write_lock(blade_session_t *bs, ks_bool_t block)
|
||||||
|
{
|
||||||
|
ks_status_t ret = KS_STATUS_SUCCESS;
|
||||||
|
|
||||||
|
ks_assert(bs);
|
||||||
|
|
||||||
|
if (block) ret = ks_rwl_write_lock(bs->properties_lock);
|
||||||
|
else ret = ks_rwl_try_write_lock(bs->properties_lock);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
KS_DECLARE(ks_status_t) blade_session_properties_write_unlock(blade_session_t *bs)
|
||||||
|
{
|
||||||
|
ks_assert(bs);
|
||||||
|
|
||||||
|
return ks_rwl_write_unlock(bs->properties_lock);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
KS_DECLARE(void) blade_session_state_set(blade_session_t *bs, blade_session_state_t state)
|
||||||
|
{
|
||||||
|
ks_assert(bs);
|
||||||
|
|
||||||
|
bs->state = state;
|
||||||
|
|
||||||
|
blade_handle_session_state_callbacks_execute(bs, BLADE_SESSION_STATE_CONDITION_PRE);
|
||||||
|
}
|
||||||
|
|
||||||
|
KS_DECLARE(void) blade_session_hangup(blade_session_t *bs)
|
||||||
|
{
|
||||||
|
ks_assert(bs);
|
||||||
|
|
||||||
|
if (bs->state != BLADE_SESSION_STATE_HANGUP && bs->state != BLADE_SESSION_STATE_DESTROY) {
|
||||||
|
ks_log(KS_LOG_DEBUG, "Session (%s) hanging up\n", bs->id);
|
||||||
|
blade_session_state_set(bs, BLADE_SESSION_STATE_HANGUP);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
KS_DECLARE(ks_bool_t) blade_session_terminating(blade_session_t *bs)
|
||||||
|
{
|
||||||
|
ks_assert(bs);
|
||||||
|
|
||||||
|
return bs->state == BLADE_SESSION_STATE_HANGUP || bs->state == BLADE_SESSION_STATE_DESTROY;
|
||||||
|
}
|
||||||
|
|
||||||
|
KS_DECLARE(ks_status_t) blade_session_connections_add(blade_session_t *bs, const char *id)
|
||||||
|
{
|
||||||
|
ks_status_t ret = KS_STATUS_SUCCESS;
|
||||||
|
const char *cid = NULL;
|
||||||
|
|
||||||
|
ks_assert(bs);
|
||||||
|
|
||||||
|
cid = ks_pstrdup(bs->pool, id);
|
||||||
|
ks_assert(cid);
|
||||||
|
|
||||||
|
list_append(&bs->connections, cid);
|
||||||
|
|
||||||
|
ks_log(KS_LOG_DEBUG, "Session (%s) connection added (%s)\n", bs->id, id);
|
||||||
|
|
||||||
|
bs->ttl = 0;
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
KS_DECLARE(ks_status_t) blade_session_connections_remove(blade_session_t *bs, const char *id)
|
||||||
|
{
|
||||||
|
ks_status_t ret = KS_STATUS_SUCCESS;
|
||||||
|
uint32_t size = 0;
|
||||||
|
|
||||||
|
ks_assert(bs);
|
||||||
|
|
||||||
|
size = list_size(&bs->connections);
|
||||||
|
for (uint32_t i = 0; i < size; ++i) {
|
||||||
|
const char *cid = (const char *)list_get_at(&bs->connections, i);
|
||||||
|
if (!strcasecmp(cid, id)) {
|
||||||
|
ks_log(KS_LOG_DEBUG, "Session (%s) connection removed (%s)\n", bs->id, id);
|
||||||
|
list_delete_at(&bs->connections, i);
|
||||||
|
ks_pool_free(bs->pool, &cid);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (list_size(&bs->connections) == 0) bs->ttl = ks_time_now() + (5 * KS_USEC_PER_SEC);
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
ks_status_t blade_session_connections_choose(blade_session_t *bs, cJSON *json, blade_connection_t **bcP)
|
||||||
|
{
|
||||||
|
blade_connection_t *bc = NULL;
|
||||||
|
const char *cid = NULL;
|
||||||
|
|
||||||
|
ks_assert(bs);
|
||||||
|
ks_assert(json);
|
||||||
|
ks_assert(bcP);
|
||||||
|
|
||||||
|
// @todo may be multiple connections, for now let's just assume there will be only one
|
||||||
|
// later there will need to be a way to pick which connection to use
|
||||||
|
cid = list_get_at(&bs->connections, 0);
|
||||||
|
if (!cid) {
|
||||||
|
// no connections available
|
||||||
|
return KS_STATUS_FAIL;
|
||||||
|
}
|
||||||
|
|
||||||
|
bc = blade_handle_connections_get(bs->handle, cid);
|
||||||
|
if (!bc) {
|
||||||
|
// @todo error logging... this shouldn't happen
|
||||||
|
return KS_STATUS_FAIL;
|
||||||
|
}
|
||||||
|
// @todo make sure the connection is in the READY state before allowing it to be choosen, just in case it is detaching or not quite fully attached
|
||||||
|
|
||||||
|
*bcP = bc;
|
||||||
|
|
||||||
|
return KS_STATUS_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
KS_DECLARE(ks_status_t) blade_session_sending_push(blade_session_t *bs, cJSON *json)
|
||||||
|
{
|
||||||
|
cJSON *json_copy = NULL;
|
||||||
|
|
||||||
|
ks_assert(bs);
|
||||||
|
ks_assert(json);
|
||||||
|
|
||||||
|
json_copy = cJSON_Duplicate(json, 1);
|
||||||
|
return ks_q_push(bs->sending, json_copy);
|
||||||
|
}
|
||||||
|
|
||||||
|
KS_DECLARE(ks_status_t) blade_session_sending_pop(blade_session_t *bs, cJSON **json)
|
||||||
|
{
|
||||||
|
ks_assert(bs);
|
||||||
|
ks_assert(json);
|
||||||
|
|
||||||
|
return ks_q_trypop(bs->sending, (void **)json);
|
||||||
|
}
|
||||||
|
|
||||||
|
KS_DECLARE(ks_status_t) blade_session_receiving_push(blade_session_t *bs, cJSON *json)
|
||||||
|
{
|
||||||
|
cJSON *json_copy = NULL;
|
||||||
|
|
||||||
|
ks_assert(bs);
|
||||||
|
ks_assert(json);
|
||||||
|
|
||||||
|
json_copy = cJSON_Duplicate(json, 1);
|
||||||
|
return ks_q_push(bs->receiving, json_copy);
|
||||||
|
}
|
||||||
|
|
||||||
|
KS_DECLARE(ks_status_t) blade_session_receiving_pop(blade_session_t *bs, cJSON **json)
|
||||||
|
{
|
||||||
|
ks_assert(bs);
|
||||||
|
ks_assert(json);
|
||||||
|
|
||||||
|
return ks_q_trypop(bs->receiving, (void **)json);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void *blade_session_state_thread(ks_thread_t *thread, void *data)
|
||||||
|
{
|
||||||
|
blade_session_t *bs = NULL;
|
||||||
|
blade_session_state_t state;
|
||||||
|
cJSON *json = NULL;
|
||||||
|
|
||||||
|
ks_assert(thread);
|
||||||
|
ks_assert(data);
|
||||||
|
|
||||||
|
bs = (blade_session_t *)data;
|
||||||
|
|
||||||
|
while (!bs->shutdown) {
|
||||||
|
|
||||||
|
state = bs->state;
|
||||||
|
|
||||||
|
if (!list_empty(&bs->connections)) {
|
||||||
|
while (blade_session_sending_pop(bs, &json) == KS_STATUS_SUCCESS && json) {
|
||||||
|
blade_connection_t *bc = NULL;
|
||||||
|
if (blade_session_connections_choose(bs, json, &bc) == KS_STATUS_SUCCESS) {
|
||||||
|
blade_connection_sending_push(bc, json);
|
||||||
|
blade_connection_read_unlock(bc);
|
||||||
|
}
|
||||||
|
cJSON_Delete(json);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
blade_handle_session_state_callbacks_execute(bs, BLADE_SESSION_STATE_CONDITION_POST);
|
||||||
|
|
||||||
|
switch (state) {
|
||||||
|
case BLADE_SESSION_STATE_DESTROY:
|
||||||
|
blade_session_state_on_destroy(bs);
|
||||||
|
return NULL;
|
||||||
|
case BLADE_SESSION_STATE_HANGUP:
|
||||||
|
blade_session_state_on_hangup(bs);
|
||||||
|
break;
|
||||||
|
case BLADE_SESSION_STATE_CONNECT:
|
||||||
|
ks_log(KS_LOG_DEBUG, "Session (%s) state connect\n", bs->id);
|
||||||
|
ks_sleep_ms(1000);
|
||||||
|
break;
|
||||||
|
case BLADE_SESSION_STATE_ATTACH:
|
||||||
|
ks_log(KS_LOG_DEBUG, "Session (%s) state attach\n", bs->id);
|
||||||
|
ks_sleep_ms(1000);
|
||||||
|
break;
|
||||||
|
case BLADE_SESSION_STATE_DETACH:
|
||||||
|
ks_log(KS_LOG_DEBUG, "Session (%s) state detach\n", bs->id);
|
||||||
|
ks_sleep_ms(1000);
|
||||||
|
break;
|
||||||
|
case BLADE_SESSION_STATE_READY:
|
||||||
|
blade_session_state_on_ready(bs);
|
||||||
|
break;
|
||||||
|
default: break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (list_empty(&bs->connections) &&
|
||||||
|
bs->ttl > 0 &&
|
||||||
|
bs->state != BLADE_SESSION_STATE_HANGUP &&
|
||||||
|
bs->state != BLADE_SESSION_STATE_DESTROY &&
|
||||||
|
ks_time_now() >= bs->ttl) {
|
||||||
|
ks_log(KS_LOG_DEBUG, "Session (%s) TTL timeout\n", bs->id);
|
||||||
|
blade_session_hangup(bs);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
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);
|
||||||
|
|
||||||
|
// @todo ignoring returns for now, see what makes sense later
|
||||||
|
return KS_STATUS_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
ks_status_t blade_session_state_on_hangup(blade_session_t *bs)
|
||||||
|
{
|
||||||
|
ks_assert(bs);
|
||||||
|
|
||||||
|
ks_log(KS_LOG_DEBUG, "Session (%s) state hangup\n", bs->id);
|
||||||
|
|
||||||
|
list_iterator_start(&bs->connections);
|
||||||
|
while (list_iterator_hasnext(&bs->connections)) {
|
||||||
|
const char *cid = (const char *)list_iterator_next(&bs->connections);
|
||||||
|
blade_connection_t *bc = blade_handle_connections_get(bs->handle, cid);
|
||||||
|
ks_assert(bc);
|
||||||
|
|
||||||
|
blade_connection_disconnect(bc);
|
||||||
|
blade_connection_read_unlock(bc);
|
||||||
|
}
|
||||||
|
list_iterator_stop(&bs->connections);
|
||||||
|
|
||||||
|
while (!list_empty(&bs->connections)) ks_sleep(100);
|
||||||
|
|
||||||
|
blade_session_state_set(bs, BLADE_SESSION_STATE_DESTROY);
|
||||||
|
|
||||||
|
return KS_STATUS_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
ks_status_t blade_session_state_on_ready(blade_session_t *bs)
|
||||||
|
{
|
||||||
|
cJSON *json = NULL;
|
||||||
|
|
||||||
|
ks_assert(bs);
|
||||||
|
|
||||||
|
//ks_log(KS_LOG_DEBUG, "Session (%s) state ready\n", bs->id);
|
||||||
|
|
||||||
|
// @todo for now only process messages if there is a connection available
|
||||||
|
if (list_size(&bs->connections) > 0) {
|
||||||
|
// @todo may only want to pop once per call to give sending a chance to keep up
|
||||||
|
while (blade_session_receiving_pop(bs, &json) == KS_STATUS_SUCCESS && json) {
|
||||||
|
blade_session_process(bs, json);
|
||||||
|
cJSON_Delete(json);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ks_sleep_ms(1);
|
||||||
|
return KS_STATUS_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
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 (!id) {
|
||||||
|
cJSON *blade = NULL;
|
||||||
|
const char *event = NULL;
|
||||||
|
|
||||||
|
blade = cJSON_GetObjectItem(json, "blade");
|
||||||
|
event = cJSON_GetObjectCstr(blade, "event");
|
||||||
|
|
||||||
|
ks_log(KS_LOG_DEBUG, "Session (%s) sending event (%s)\n", bs->id, event);
|
||||||
|
} else if (method) {
|
||||||
|
// @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)) {
|
||||||
|
// @todo cache the blade_request_t here if it exists to gaurentee it's cached before a response could be received
|
||||||
|
blade_session_sending_push(bs, json);
|
||||||
|
} else {
|
||||||
|
blade_connection_t *bc = NULL;
|
||||||
|
if (blade_session_connections_choose(bs, json, &bc) != KS_STATUS_SUCCESS) return KS_STATUS_FAIL;
|
||||||
|
// @todo cache the blade_request_t here if it exists to gaurentee it's cached before a response could be received
|
||||||
|
blade_connection_sending_push(bc, json);
|
||||||
|
blade_connection_read_unlock(bc);
|
||||||
|
}
|
||||||
|
|
||||||
|
return KS_STATUS_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
ks_status_t blade_session_process(blade_session_t *bs, cJSON *json)
|
||||||
|
{
|
||||||
|
blade_request_t *breq = NULL;
|
||||||
|
blade_response_t *bres = NULL;
|
||||||
|
blade_event_t *bev = NULL;
|
||||||
|
const char *jsonrpc = NULL;
|
||||||
|
cJSON *blade = NULL;
|
||||||
|
const char *blade_event = 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);
|
||||||
|
|
||||||
|
|
||||||
|
jsonrpc = cJSON_GetObjectCstr(json, "jsonrpc");
|
||||||
|
if (!jsonrpc || strcmp(jsonrpc, "2.0")) {
|
||||||
|
ks_log(KS_LOG_DEBUG, "Received message is not the expected protocol\n");
|
||||||
|
// @todo send error response, code = -32600 (invalid request)
|
||||||
|
// @todo hangup session entirely?
|
||||||
|
return KS_STATUS_FAIL;
|
||||||
|
}
|
||||||
|
|
||||||
|
blade = cJSON_GetObjectItem(json, "blade");
|
||||||
|
if (blade) {
|
||||||
|
blade_event = cJSON_GetObjectCstr(blade, "event");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (blade_event) {
|
||||||
|
blade_event_callback_t callback = blade_handle_event_lookup(blade_session_handle_get(bs), blade_event);
|
||||||
|
if (!callback) {
|
||||||
|
ks_log(KS_LOG_DEBUG, "Received event message with no event callback '%s'\n", blade_event);
|
||||||
|
} else {
|
||||||
|
ks_log(KS_LOG_DEBUG, "Session (%s) processing event %s\n", bs->id, blade_event);
|
||||||
|
|
||||||
|
blade_event_create(&bev, bs->handle, bs->id, json);
|
||||||
|
ks_assert(bev);
|
||||||
|
|
||||||
|
disconnect = callback(bev);
|
||||||
|
|
||||||
|
blade_event_destroy(&bev);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
id = cJSON_GetObjectCstr(json, "id");
|
||||||
|
if (!id) {
|
||||||
|
ks_log(KS_LOG_DEBUG, "Received non-event message is missing 'id'\n");
|
||||||
|
// @todo send error response, code = -32600 (invalid request)
|
||||||
|
// @todo hangup session entirely?
|
||||||
|
return KS_STATUS_FAIL;
|
||||||
|
}
|
||||||
|
|
||||||
|
method = cJSON_GetObjectCstr(json, "method");
|
||||||
|
if (method) {
|
||||||
|
// @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, '.');
|
||||||
|
|
||||||
|
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_log(KS_LOG_DEBUG, "Received unparsable method\n");
|
||||||
|
ks_pool_free(bs->pool, (void **)&space_name);
|
||||||
|
// @todo send error response, code = -32601 (method not found)
|
||||||
|
return KS_STATUS_FAIL;
|
||||||
|
}
|
||||||
|
*method_name = '\0';
|
||||||
|
method_name++; // @todo check if can be postfixed safely on previous assignment, can't recall
|
||||||
|
|
||||||
|
ks_log(KS_LOG_DEBUG, "Looking for space %s\n", space_name);
|
||||||
|
|
||||||
|
tmp_space = blade_handle_space_lookup(bs->handle, space_name);
|
||||||
|
if (tmp_space) {
|
||||||
|
ks_log(KS_LOG_DEBUG, "Looking for method %s\n", method_name);
|
||||||
|
tmp_method = blade_space_methods_get(tmp_space, method_name);
|
||||||
|
}
|
||||||
|
|
||||||
|
ks_pool_free(bs->pool, (void **)&space_name);
|
||||||
|
|
||||||
|
if (!tmp_method) {
|
||||||
|
ks_log(KS_LOG_DEBUG, "Received unknown method\n");
|
||||||
|
// @todo send error response, code = -32601 (method not found)
|
||||||
|
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);
|
||||||
|
|
||||||
|
disconnect = callback(blade_space_module_get(tmp_space), 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?
|
||||||
|
return KS_STATUS_FAIL;
|
||||||
|
}
|
||||||
|
blade_handle_requests_remove(breq);
|
||||||
|
|
||||||
|
blade_response_create(&bres, bs->handle, bs->id, breq, json);
|
||||||
|
ks_assert(bres);
|
||||||
|
|
||||||
|
disconnect = breq->callback(bres);
|
||||||
|
|
||||||
|
blade_response_destroy(&bres);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (disconnect) {
|
||||||
|
// @todo hangup session entirely?
|
||||||
|
return KS_STATUS_FAIL;
|
||||||
|
}
|
||||||
|
|
||||||
|
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:
|
||||||
|
*/
|
185
libs/libblade/src/blade_space.c
Normal file
185
libs/libblade/src/blade_space.c
Normal file
@ -0,0 +1,185 @@
|
|||||||
|
/*
|
||||||
|
* 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;
|
||||||
|
blade_module_t *module;
|
||||||
|
|
||||||
|
const char *path;
|
||||||
|
ks_hash_t *methods;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
KS_DECLARE(ks_status_t) blade_space_create(blade_space_t **bsP, blade_handle_t *bh, blade_module_t *bm, 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->module = bm;
|
||||||
|
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(blade_module_t *) blade_space_module_get(blade_space_t *bs)
|
||||||
|
{
|
||||||
|
ks_assert(bs);
|
||||||
|
|
||||||
|
return bs->module;
|
||||||
|
}
|
||||||
|
|
||||||
|
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:
|
||||||
|
*/
|
@ -1,23 +1,23 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2007-2014, Anthony Minessale II
|
* Copyright (c) 2007-2014, Anthony Minessale II
|
||||||
* All rights reserved.
|
* All rights reserved.
|
||||||
*
|
*
|
||||||
* Redistribution and use in source and binary forms, with or without
|
* Redistribution and use in source and binary forms, with or without
|
||||||
* modification, are permitted provided that the following conditions
|
* modification, are permitted provided that the following conditions
|
||||||
* are met:
|
* are met:
|
||||||
*
|
*
|
||||||
* * Redistributions of source code must retain the above copyright
|
* * Redistributions of source code must retain the above copyright
|
||||||
* notice, this list of conditions and the following disclaimer.
|
* notice, this list of conditions and the following disclaimer.
|
||||||
*
|
*
|
||||||
* * Redistributions in binary form must reproduce the above copyright
|
* * Redistributions in binary form must reproduce the above copyright
|
||||||
* notice, this list of conditions and the following disclaimer in the
|
* notice, this list of conditions and the following disclaimer in the
|
||||||
* documentation and/or other materials provided with the distribution.
|
* documentation and/or other materials provided with the distribution.
|
||||||
*
|
*
|
||||||
* * Neither the name of the original author; nor the names of any contributors
|
* * 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
|
* may be used to endorse or promote products derived from this software
|
||||||
* without specific prior written permission.
|
* without specific prior written permission.
|
||||||
*
|
*
|
||||||
*
|
*
|
||||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||||
@ -43,11 +43,180 @@ struct blade_handle_s {
|
|||||||
bhpvt_flag_t flags;
|
bhpvt_flag_t flags;
|
||||||
ks_pool_t *pool;
|
ks_pool_t *pool;
|
||||||
ks_thread_pool_t *tpool;
|
ks_thread_pool_t *tpool;
|
||||||
blade_peer_t *peer;
|
|
||||||
|
config_setting_t *config_directory;
|
||||||
|
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
|
||||||
|
// registered event callback registry
|
||||||
|
// @todo should probably use a blade_handle_event_registration_t and contain optional userdata to pass from registration back into the callback, like
|
||||||
|
// a blade_module_t to get at inner module data for events that service modules may need to subscribe to between each other
|
||||||
|
ks_hash_t *events;
|
||||||
|
|
||||||
|
//blade_identity_t *identity;
|
||||||
blade_datastore_t *datastore;
|
blade_datastore_t *datastore;
|
||||||
|
|
||||||
|
// @todo insert on connection creations, remove on connection destructions, key based on a UUID for the connection
|
||||||
|
ks_hash_t *connections; // active connections keyed by connection id
|
||||||
|
|
||||||
|
// @todo insert on session creations, remove on session destructions, key based on a UUID for the session
|
||||||
|
ks_hash_t *sessions; // active sessions keyed by session id
|
||||||
|
ks_hash_t *session_state_callbacks;
|
||||||
|
|
||||||
|
// @todo another hash with sessions keyed by the remote identity without parameters for quick lookup by target identity on sending?
|
||||||
|
ks_hash_t *requests; // outgoing requests waiting for a response keyed by the message id
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
typedef struct blade_handle_transport_registration_s blade_handle_transport_registration_t;
|
||||||
|
struct blade_handle_transport_registration_s {
|
||||||
|
ks_pool_t *pool;
|
||||||
|
|
||||||
|
blade_module_t *module;
|
||||||
|
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,
|
||||||
|
blade_transport_callbacks_t *callbacks)
|
||||||
|
{
|
||||||
|
blade_handle_transport_registration_t *bhtr = NULL;
|
||||||
|
|
||||||
|
ks_assert(bhtrP);
|
||||||
|
ks_assert(pool);
|
||||||
|
ks_assert(module);
|
||||||
|
ks_assert(callbacks);
|
||||||
|
|
||||||
|
bhtr = ks_pool_alloc(pool, sizeof(blade_handle_transport_registration_t));
|
||||||
|
bhtr->pool = pool;
|
||||||
|
bhtr->module = module;
|
||||||
|
bhtr->callbacks = callbacks;
|
||||||
|
|
||||||
|
*bhtrP = bhtr;
|
||||||
|
|
||||||
|
return KS_STATUS_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
KS_DECLARE(ks_status_t) blade_handle_transport_registration_destroy(blade_handle_transport_registration_t **bhtrP)
|
||||||
|
{
|
||||||
|
blade_handle_transport_registration_t *bhtr = NULL;
|
||||||
|
|
||||||
|
ks_assert(bhtrP);
|
||||||
|
|
||||||
|
bhtr = *bhtrP;
|
||||||
|
*bhtrP = NULL;
|
||||||
|
|
||||||
|
ks_assert(bhtr);
|
||||||
|
|
||||||
|
ks_pool_free(bhtr->pool, &bhtr);
|
||||||
|
|
||||||
|
return KS_STATUS_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
typedef struct blade_handle_session_state_callback_registration_s blade_handle_session_state_callback_registration_t;
|
||||||
|
struct blade_handle_session_state_callback_registration_s {
|
||||||
|
ks_pool_t *pool;
|
||||||
|
|
||||||
|
const char *id;
|
||||||
|
void *data;
|
||||||
|
blade_session_state_callback_t callback;
|
||||||
|
};
|
||||||
|
|
||||||
|
ks_status_t blade_handle_session_state_callback_registration_create(blade_handle_session_state_callback_registration_t **bhsscrP,
|
||||||
|
ks_pool_t *pool,
|
||||||
|
void *data,
|
||||||
|
blade_session_state_callback_t callback)
|
||||||
|
{
|
||||||
|
blade_handle_session_state_callback_registration_t *bhsscr = NULL;
|
||||||
|
uuid_t uuid;
|
||||||
|
|
||||||
|
ks_assert(bhsscrP);
|
||||||
|
ks_assert(pool);
|
||||||
|
ks_assert(callback);
|
||||||
|
|
||||||
|
ks_uuid(&uuid);
|
||||||
|
|
||||||
|
bhsscr = ks_pool_alloc(pool, sizeof(blade_handle_session_state_callback_registration_t));
|
||||||
|
bhsscr->pool = pool;
|
||||||
|
bhsscr->id = ks_uuid_str(pool, &uuid);
|
||||||
|
bhsscr->data = data;
|
||||||
|
bhsscr->callback = callback;
|
||||||
|
|
||||||
|
*bhsscrP = bhsscr;
|
||||||
|
|
||||||
|
return KS_STATUS_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
ks_status_t blade_handle_session_state_callback_registration_destroy(blade_handle_session_state_callback_registration_t **bhsscrP)
|
||||||
|
{
|
||||||
|
blade_handle_session_state_callback_registration_t *bhsscr = NULL;
|
||||||
|
|
||||||
|
ks_assert(bhsscrP);
|
||||||
|
|
||||||
|
bhsscr = *bhsscrP;
|
||||||
|
*bhsscrP = NULL;
|
||||||
|
|
||||||
|
ks_assert(bhsscr);
|
||||||
|
|
||||||
|
ks_pool_free(bhsscr->pool, &bhsscr->id);
|
||||||
|
|
||||||
|
ks_pool_free(bhsscr->pool, &bhsscr);
|
||||||
|
|
||||||
|
return KS_STATUS_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
KS_DECLARE(ks_status_t) blade_handle_create(blade_handle_t **bhP, ks_pool_t *pool, ks_thread_pool_t *tpool)
|
||||||
|
{
|
||||||
|
bhpvt_flag_t newflags = BH_NONE;
|
||||||
|
blade_handle_t *bh = NULL;
|
||||||
|
|
||||||
|
ks_assert(bhP);
|
||||||
|
|
||||||
|
if (!pool) {
|
||||||
|
newflags |= BH_MYPOOL;
|
||||||
|
ks_pool_open(&pool);
|
||||||
|
}
|
||||||
|
if (!tpool) {
|
||||||
|
newflags |= BH_MYTPOOL;
|
||||||
|
ks_thread_pool_create(&tpool, BLADE_HANDLE_TPOOL_MIN, BLADE_HANDLE_TPOOL_MAX, BLADE_HANDLE_TPOOL_STACK, KS_PRI_NORMAL, BLADE_HANDLE_TPOOL_IDLE);
|
||||||
|
ks_assert(tpool);
|
||||||
|
}
|
||||||
|
|
||||||
|
bh = ks_pool_alloc(pool, sizeof(blade_handle_t));
|
||||||
|
bh->flags = newflags;
|
||||||
|
bh->pool = pool;
|
||||||
|
bh->tpool = tpool;
|
||||||
|
|
||||||
|
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->events, KS_HASH_MODE_CASE_INSENSITIVE, KS_HASH_FLAG_NOLOCK | KS_HASH_FLAG_DUP_CHECK, bh->pool);
|
||||||
|
ks_assert(bh->events);
|
||||||
|
|
||||||
|
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);
|
||||||
|
|
||||||
|
ks_hash_create(&bh->sessions, KS_HASH_MODE_CASE_INSENSITIVE, KS_HASH_FLAG_NOLOCK | KS_HASH_FLAG_DUP_CHECK, bh->pool);
|
||||||
|
ks_assert(bh->sessions);
|
||||||
|
ks_hash_create(&bh->session_state_callbacks, KS_HASH_MODE_CASE_INSENSITIVE, KS_HASH_FLAG_NOLOCK | KS_HASH_FLAG_DUP_CHECK, bh->pool);
|
||||||
|
ks_assert(bh->session_state_callbacks);
|
||||||
|
|
||||||
|
ks_hash_create(&bh->requests, KS_HASH_MODE_CASE_INSENSITIVE, KS_HASH_FLAG_NOLOCK | KS_HASH_FLAG_DUP_CHECK, bh->pool);
|
||||||
|
ks_assert(bh->requests);
|
||||||
|
|
||||||
|
*bhP = bh;
|
||||||
|
|
||||||
|
ks_log(KS_LOG_DEBUG, "Created\n");
|
||||||
|
|
||||||
|
return KS_STATUS_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
KS_DECLARE(ks_status_t) blade_handle_destroy(blade_handle_t **bhP)
|
KS_DECLARE(ks_status_t) blade_handle_destroy(blade_handle_t **bhP)
|
||||||
{
|
{
|
||||||
blade_handle_t *bh = NULL;
|
blade_handle_t *bh = NULL;
|
||||||
@ -64,11 +233,20 @@ KS_DECLARE(ks_status_t) blade_handle_destroy(blade_handle_t **bhP)
|
|||||||
flags = bh->flags;
|
flags = bh->flags;
|
||||||
pool = bh->pool;
|
pool = bh->pool;
|
||||||
|
|
||||||
if (bh->datastore) blade_datastore_destroy(&bh->datastore);
|
blade_handle_shutdown(bh);
|
||||||
|
|
||||||
|
ks_hash_destroy(&bh->requests);
|
||||||
|
ks_hash_destroy(&bh->session_state_callbacks);
|
||||||
|
ks_hash_destroy(&bh->sessions);
|
||||||
|
ks_hash_destroy(&bh->connections);
|
||||||
|
ks_hash_destroy(&bh->events);
|
||||||
|
ks_hash_destroy(&bh->spaces);
|
||||||
|
ks_hash_destroy(&bh->transports);
|
||||||
|
|
||||||
blade_peer_destroy(&bh->peer);
|
|
||||||
if (bh->tpool && (flags & BH_MYTPOOL)) ks_thread_pool_destroy(&bh->tpool);
|
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);
|
ks_pool_free(bh->pool, &bh);
|
||||||
|
|
||||||
if (pool && (flags & BH_MYPOOL)) {
|
if (pool && (flags & BH_MYPOOL)) {
|
||||||
@ -78,99 +256,595 @@ KS_DECLARE(ks_status_t) blade_handle_destroy(blade_handle_t **bhP)
|
|||||||
return KS_STATUS_SUCCESS;
|
return KS_STATUS_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
KS_DECLARE(ks_status_t) blade_handle_create(blade_handle_t **bhP, ks_pool_t *pool, ks_thread_pool_t *tpool, const char *nodeid)
|
ks_status_t blade_handle_config(blade_handle_t *bh, config_setting_t *config)
|
||||||
{
|
{
|
||||||
bhpvt_flag_t newflags = BH_NONE;
|
config_setting_t *directory = NULL;
|
||||||
blade_handle_t *bh = NULL;
|
config_setting_t *datastore = NULL;
|
||||||
ks_dht_nodeid_t nid;
|
|
||||||
|
|
||||||
ks_assert(nodeid);
|
ks_assert(bh);
|
||||||
ks_assert(strlen(nodeid) == (KS_DHT_NODEID_SIZE * 2));
|
|
||||||
|
|
||||||
if (!pool) {
|
if (!config) return KS_STATUS_FAIL;
|
||||||
newflags |= BH_MYPOOL;
|
if (!config_setting_is_group(config)) return KS_STATUS_FAIL;
|
||||||
ks_pool_open(&pool);
|
|
||||||
}
|
|
||||||
if (!tpool) {
|
|
||||||
newflags |= BH_MYTPOOL;
|
|
||||||
ks_thread_pool_create(&tpool, BLADE_HANDLE_TPOOL_MIN, BLADE_HANDLE_TPOOL_MAX, BLADE_HANDLE_TPOOL_STACK, KS_PRI_NORMAL, BLADE_HANDLE_TPOOL_IDLE);
|
|
||||||
ks_assert(tpool);
|
|
||||||
}
|
|
||||||
|
|
||||||
bh = ks_pool_alloc(pool, sizeof(*bh));
|
|
||||||
bh->flags = newflags;
|
|
||||||
bh->pool = pool;
|
|
||||||
bh->tpool = tpool;
|
|
||||||
ks_dht_dehex(nid.id, nodeid, KS_DHT_NODEID_SIZE);
|
|
||||||
blade_peer_create(&bh->peer, bh->pool, bh->tpool, &nid);
|
|
||||||
|
|
||||||
*bhP = bh;
|
directory = config_setting_get_member(config, "directory");
|
||||||
|
|
||||||
|
datastore = config_setting_get_member(config, "datastore");
|
||||||
|
//if (datastore && !config_setting_is_group(datastore)) return KS_STATUS_FAIL;
|
||||||
|
|
||||||
|
|
||||||
|
bh->config_directory = directory;
|
||||||
|
bh->config_datastore = datastore;
|
||||||
|
|
||||||
return KS_STATUS_SUCCESS;
|
return KS_STATUS_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
KS_DECLARE(void) blade_handle_myid(blade_handle_t *bh, char *buffer)
|
KS_DECLARE(ks_status_t) blade_handle_startup(blade_handle_t *bh, config_setting_t *config)
|
||||||
{
|
{
|
||||||
ks_dht_nodeid_t *nodeid = NULL;
|
|
||||||
|
|
||||||
ks_assert(bh);
|
ks_assert(bh);
|
||||||
ks_assert(bh->peer);
|
|
||||||
|
|
||||||
nodeid = blade_peer_myid(bh->peer);
|
if (blade_handle_config(bh, config) != KS_STATUS_SUCCESS) {
|
||||||
ks_dht_hex(nodeid->id, buffer, KS_DHT_NODEID_SIZE);
|
ks_log(KS_LOG_DEBUG, "blade_handle_config failed\n");
|
||||||
|
return KS_STATUS_FAIL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (bh->config_datastore && !blade_handle_datastore_available(bh)) {
|
||||||
|
blade_datastore_create(&bh->datastore, bh->pool, bh->tpool);
|
||||||
|
ks_assert(bh->datastore);
|
||||||
|
if (blade_datastore_startup(bh->datastore, bh->config_datastore) != KS_STATUS_SUCCESS) {
|
||||||
|
ks_log(KS_LOG_DEBUG, "blade_datastore_startup failed\n");
|
||||||
|
return KS_STATUS_FAIL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// @todo load DSOs
|
||||||
|
|
||||||
|
// @todo call onload and onstartup callbacks for modules from DSOs
|
||||||
|
|
||||||
|
return KS_STATUS_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
KS_DECLARE(void) blade_handle_autoroute(blade_handle_t *bh, ks_bool_t autoroute, ks_port_t port)
|
KS_DECLARE(ks_status_t) blade_handle_shutdown(blade_handle_t *bh)
|
||||||
{
|
{
|
||||||
ks_assert(bh);
|
ks_hash_iterator_t *it = NULL;
|
||||||
ks_assert(bh->peer);
|
|
||||||
|
|
||||||
blade_peer_autoroute(bh->peer, autoroute, port);
|
ks_assert(bh);
|
||||||
|
|
||||||
|
for (it = ks_hash_first(bh->requests, KS_UNLOCKED); it; it = ks_hash_next(&it)) {
|
||||||
|
void *key = NULL;
|
||||||
|
blade_request_t *value = NULL;
|
||||||
|
|
||||||
|
ks_hash_this(it, (const void **)&key, NULL, (void **)&value);
|
||||||
|
ks_hash_remove(bh->requests, key);
|
||||||
|
|
||||||
|
blade_request_destroy(&value);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (it = ks_hash_first(bh->sessions, KS_UNLOCKED); it; it = ks_hash_next(&it)) {
|
||||||
|
void *key = NULL;
|
||||||
|
blade_session_t *value = NULL;
|
||||||
|
|
||||||
|
ks_hash_this(it, (const void **)&key, NULL, (void **)&value);
|
||||||
|
//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 spaces, and will disconnect remaining
|
||||||
|
// unattached connections
|
||||||
|
|
||||||
|
for (it = ks_hash_first(bh->events, KS_UNLOCKED); it; it = ks_hash_next(&it)) {
|
||||||
|
void *key = NULL;
|
||||||
|
blade_event_callback_t *value = NULL;
|
||||||
|
|
||||||
|
ks_hash_this(it, (const void **)&key, NULL, (void **)&value);
|
||||||
|
blade_handle_event_unregister(bh, (const char *)key);
|
||||||
|
}
|
||||||
|
|
||||||
|
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
|
||||||
|
|
||||||
|
if (blade_handle_datastore_available(bh)) blade_datastore_destroy(&bh->datastore);
|
||||||
|
|
||||||
|
return KS_STATUS_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
KS_DECLARE(ks_status_t) blade_handle_bind(blade_handle_t *bh, const char *ip, ks_port_t port, ks_dht_endpoint_t **endpoint)
|
KS_DECLARE(ks_pool_t *) blade_handle_pool_get(blade_handle_t *bh)
|
||||||
{
|
{
|
||||||
ks_sockaddr_t addr;
|
|
||||||
int family = AF_INET;
|
|
||||||
|
|
||||||
ks_assert(bh);
|
ks_assert(bh);
|
||||||
ks_assert(ip);
|
return bh->pool;
|
||||||
ks_assert(port);
|
|
||||||
|
|
||||||
if (ip[1] != '.' && ip[2] != '.' && ip[3] != '.') family = AF_INET6;
|
|
||||||
|
|
||||||
ks_addr_set(&addr, ip, port, family);
|
|
||||||
return blade_peer_bind(bh->peer, &addr, endpoint);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
KS_DECLARE(void) blade_handle_pulse(blade_handle_t *bh, int32_t timeout)
|
KS_DECLARE(ks_thread_pool_t *) blade_handle_tpool_get(blade_handle_t *bh)
|
||||||
{
|
{
|
||||||
ks_assert(bh);
|
ks_assert(bh);
|
||||||
ks_assert(timeout >= 0);
|
return bh->tpool;
|
||||||
|
}
|
||||||
|
|
||||||
blade_peer_pulse(bh->peer, timeout);
|
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)
|
||||||
if (bh->datastore) blade_datastore_pulse(bh->datastore, timeout);
|
{
|
||||||
|
blade_handle_transport_registration_t *bhtr = NULL;
|
||||||
|
blade_handle_transport_registration_t *bhtr_old = NULL;
|
||||||
|
|
||||||
|
ks_assert(bh);
|
||||||
|
ks_assert(bm);
|
||||||
|
ks_assert(name);
|
||||||
|
ks_assert(callbacks);
|
||||||
|
|
||||||
|
// @todo reduce blade_handle_t parameter, pull from blade_module_t parameter
|
||||||
|
|
||||||
|
blade_handle_transport_registration_create(&bhtr, bh->pool, bm, callbacks);
|
||||||
|
ks_assert(bhtr);
|
||||||
|
|
||||||
|
ks_hash_write_lock(bh->transports);
|
||||||
|
bhtr_old = ks_hash_search(bh->transports, (void *)name, KS_UNLOCKED);
|
||||||
|
if (bhtr_old) ks_hash_remove(bh->transports, (void *)name);
|
||||||
|
ks_hash_insert(bh->transports, (void *)name, bhtr);
|
||||||
|
ks_hash_write_unlock(bh->transports);
|
||||||
|
|
||||||
|
if (bhtr_old) blade_handle_transport_registration_destroy(&bhtr_old);
|
||||||
|
|
||||||
|
ks_log(KS_LOG_DEBUG, "Transport Registered: %s\n", name);
|
||||||
|
|
||||||
|
return KS_STATUS_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
KS_DECLARE(ks_status_t) blade_handle_transport_unregister(blade_handle_t *bh, const char *name)
|
||||||
|
{
|
||||||
|
blade_handle_transport_registration_t *bhtr = NULL;
|
||||||
|
|
||||||
|
ks_assert(bh);
|
||||||
|
ks_assert(name);
|
||||||
|
|
||||||
|
ks_hash_write_lock(bh->transports);
|
||||||
|
bhtr = ks_hash_search(bh->transports, (void *)name, KS_UNLOCKED);
|
||||||
|
if (bhtr) ks_hash_remove(bh->transports, (void *)name);
|
||||||
|
ks_hash_write_unlock(bh->transports);
|
||||||
|
|
||||||
|
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_event_register(blade_handle_t *bh, const char *event, blade_event_callback_t callback)
|
||||||
|
{
|
||||||
|
ks_assert(bh);
|
||||||
|
ks_assert(event);
|
||||||
|
ks_assert(callback);
|
||||||
|
|
||||||
|
ks_hash_write_lock(bh->events);
|
||||||
|
ks_hash_insert(bh->events, (void *)event, (void *)(intptr_t)callback);
|
||||||
|
ks_hash_write_unlock(bh->events);
|
||||||
|
|
||||||
|
ks_log(KS_LOG_DEBUG, "Event Registered: %s\n", event);
|
||||||
|
|
||||||
|
return KS_STATUS_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
KS_DECLARE(ks_status_t) blade_handle_event_unregister(blade_handle_t *bh, const char *event)
|
||||||
|
{
|
||||||
|
ks_bool_t removed = KS_FALSE;
|
||||||
|
|
||||||
|
ks_assert(bh);
|
||||||
|
ks_assert(event);
|
||||||
|
|
||||||
|
ks_hash_write_lock(bh->events);
|
||||||
|
if (ks_hash_remove(bh->events, (void *)event)) removed = KS_TRUE;
|
||||||
|
ks_hash_write_unlock(bh->events);
|
||||||
|
|
||||||
|
if (removed) {
|
||||||
|
ks_log(KS_LOG_DEBUG, "Event Unregistered: %s\n", event);
|
||||||
|
}
|
||||||
|
|
||||||
|
return KS_STATUS_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
KS_DECLARE(blade_event_callback_t) blade_handle_event_lookup(blade_handle_t *bh, const char *event)
|
||||||
|
{
|
||||||
|
blade_event_callback_t callback = NULL;
|
||||||
|
|
||||||
|
ks_assert(bh);
|
||||||
|
ks_assert(event);
|
||||||
|
|
||||||
|
ks_hash_read_lock(bh->events);
|
||||||
|
callback = (blade_event_callback_t)(intptr_t)ks_hash_search(bh->events, (void *)event, KS_UNLOCKED);
|
||||||
|
ks_hash_read_unlock(bh->events);
|
||||||
|
|
||||||
|
return callback;
|
||||||
|
}
|
||||||
|
|
||||||
|
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;
|
||||||
|
blade_handle_transport_registration_t *bhtr = NULL;
|
||||||
|
const char *tname = NULL;
|
||||||
|
|
||||||
|
ks_assert(bh);
|
||||||
|
ks_assert(target);
|
||||||
|
|
||||||
|
// @todo this should take a callback, and push this to a queue to be processed async from another thread on the handle
|
||||||
|
// which will allow the onconnect callback to block while doing things like DNS lookups without having unknown
|
||||||
|
// impact depending on the caller thread
|
||||||
|
|
||||||
|
ks_hash_read_lock(bh->transports);
|
||||||
|
|
||||||
|
tname = blade_identity_parameter_get(target, "transport");
|
||||||
|
if (tname) {
|
||||||
|
bhtr = ks_hash_search(bh->transports, (void *)tname, KS_UNLOCKED);
|
||||||
|
if (!bhtr) {
|
||||||
|
// @todo error logging, target has an explicit transport that is not available in the local transports registry
|
||||||
|
// discuss later whether this scenario should still attempt other transports when target is explicit
|
||||||
|
// @note discussions indicate that by default messages should favor relaying through a master service, unless
|
||||||
|
// an existing direct connection already exists to the target (which if the target is the master node, then there is
|
||||||
|
// no conflict of proper routing). This also applies to routing for identities which relate to groups, relaying should
|
||||||
|
// most often occur through a master service, however there may be scenarios that exist where an existing session
|
||||||
|
// exists dedicated to faster delivery for a group (IE, through an ampq cluster directly, such as master services
|
||||||
|
// syncing with each other through a pub/sub). There is also the potential that instead of a separate session, the
|
||||||
|
// current session with a master service may be able to have another connection attached which represents access through
|
||||||
|
// amqp, which in turn acts as a preferred router for only group identities
|
||||||
|
// This information does not directly apply to connecting, but should be noted for the next level up where you simply
|
||||||
|
// send a message which will not actually connect, only check for existing sessions for the target and master service
|
||||||
|
// @note relaying by master services should take a slightly different path, when they receive something not for the
|
||||||
|
// master service itself, it should relay this on to all other master services, which in turn all including original
|
||||||
|
// receiver pass on to any sessions matching an identity that is part of the group, alternatively they can use a pub/sub
|
||||||
|
// like amqp to relay between the master services more efficiently than using the websocket to send every master service
|
||||||
|
// session the message individually
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
for (ks_hash_iterator_t *it = ks_hash_first(bh->transports, KS_UNLOCKED); it; it = ks_hash_next(&it)) {
|
||||||
|
// @todo use onrank (or replace with whatever method is used for determining what transport to use) and keep highest ranked callbacks
|
||||||
|
}
|
||||||
|
}
|
||||||
|
ks_hash_read_unlock(bh->transports);
|
||||||
|
|
||||||
|
// @todo need to be able to get to the blade_module_t from the callbacks, may require envelope around registration of callbacks to include module
|
||||||
|
// this is required because onconnect transport callback needs to be able to get back to the module data to create the connection being returned
|
||||||
|
if (bhtr) ret = bhtr->callbacks->onconnect(bcP, bhtr->module, target, session_id);
|
||||||
|
else ret = KS_STATUS_FAIL;
|
||||||
|
|
||||||
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
KS_DECLARE(void) blade_handle_datastore_start(blade_handle_t *bh)
|
KS_DECLARE(blade_connection_t *) blade_handle_connections_get(blade_handle_t *bh, const char *cid)
|
||||||
|
{
|
||||||
|
blade_connection_t *bc = NULL;
|
||||||
|
|
||||||
|
ks_assert(bh);
|
||||||
|
ks_assert(cid);
|
||||||
|
|
||||||
|
ks_hash_read_lock(bh->connections);
|
||||||
|
bc = ks_hash_search(bh->connections, (void *)cid, KS_UNLOCKED);
|
||||||
|
if (bc && blade_connection_read_lock(bc, KS_FALSE) != KS_STATUS_SUCCESS) bc = NULL;
|
||||||
|
ks_hash_read_unlock(bh->connections);
|
||||||
|
|
||||||
|
return bc;
|
||||||
|
}
|
||||||
|
|
||||||
|
KS_DECLARE(ks_status_t) blade_handle_connections_add(blade_connection_t *bc)
|
||||||
|
{
|
||||||
|
ks_status_t ret = KS_STATUS_SUCCESS;
|
||||||
|
blade_handle_t *bh = NULL;
|
||||||
|
|
||||||
|
ks_assert(bc);
|
||||||
|
|
||||||
|
bh = blade_connection_handle_get(bc);
|
||||||
|
ks_assert(bh);
|
||||||
|
|
||||||
|
ks_hash_write_lock(bh->connections);
|
||||||
|
ret = ks_hash_insert(bh->connections, (void *)blade_connection_id_get(bc), bc);
|
||||||
|
ks_hash_write_unlock(bh->connections);
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
KS_DECLARE(ks_status_t) blade_handle_connections_remove(blade_connection_t *bc)
|
||||||
|
{
|
||||||
|
ks_status_t ret = KS_STATUS_SUCCESS;
|
||||||
|
blade_handle_t *bh = NULL;
|
||||||
|
|
||||||
|
ks_assert(bc);
|
||||||
|
|
||||||
|
bh = blade_connection_handle_get(bc);
|
||||||
|
ks_assert(bh);
|
||||||
|
|
||||||
|
blade_connection_write_lock(bc, KS_TRUE);
|
||||||
|
|
||||||
|
ks_hash_write_lock(bh->connections);
|
||||||
|
if (ks_hash_remove(bh->connections, (void *)blade_connection_id_get(bc)) == NULL) ret = KS_STATUS_FAIL;
|
||||||
|
ks_hash_write_unlock(bh->connections);
|
||||||
|
|
||||||
|
blade_connection_write_unlock(bc);
|
||||||
|
|
||||||
|
// @todo call bh->connection_callbacks
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
KS_DECLARE(blade_session_t *) blade_handle_sessions_get(blade_handle_t *bh, const char *sid)
|
||||||
|
{
|
||||||
|
blade_session_t *bs = NULL;
|
||||||
|
|
||||||
|
ks_assert(bh);
|
||||||
|
ks_assert(sid);
|
||||||
|
|
||||||
|
ks_hash_read_lock(bh->sessions);
|
||||||
|
bs = ks_hash_search(bh->sessions, (void *)sid, KS_UNLOCKED);
|
||||||
|
if (bs && blade_session_read_lock(bs, KS_FALSE) != KS_STATUS_SUCCESS) bs = NULL;
|
||||||
|
ks_hash_read_unlock(bh->sessions);
|
||||||
|
|
||||||
|
return bs;
|
||||||
|
}
|
||||||
|
|
||||||
|
KS_DECLARE(ks_status_t) blade_handle_sessions_add(blade_session_t *bs)
|
||||||
|
{
|
||||||
|
ks_status_t ret = KS_STATUS_SUCCESS;
|
||||||
|
blade_handle_t *bh = NULL;
|
||||||
|
|
||||||
|
ks_assert(bs);
|
||||||
|
|
||||||
|
bh = blade_session_handle_get(bs);
|
||||||
|
ks_assert(bh);
|
||||||
|
|
||||||
|
ks_hash_write_lock(bh->sessions);
|
||||||
|
ret = ks_hash_insert(bh->sessions, (void *)blade_session_id_get(bs), bs);
|
||||||
|
ks_hash_write_unlock(bh->sessions);
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
KS_DECLARE(ks_status_t) blade_handle_sessions_remove(blade_session_t *bs)
|
||||||
|
{
|
||||||
|
ks_status_t ret = KS_STATUS_SUCCESS;
|
||||||
|
blade_handle_t *bh = NULL;
|
||||||
|
|
||||||
|
ks_assert(bs);
|
||||||
|
|
||||||
|
bh = blade_session_handle_get(bs);
|
||||||
|
ks_assert(bh);
|
||||||
|
|
||||||
|
blade_session_write_lock(bs, KS_TRUE);
|
||||||
|
|
||||||
|
ks_hash_write_lock(bh->sessions);
|
||||||
|
if (ks_hash_remove(bh->sessions, (void *)blade_session_id_get(bs)) == NULL) ret = KS_STATUS_FAIL;
|
||||||
|
ks_hash_write_unlock(bh->sessions);
|
||||||
|
|
||||||
|
blade_session_write_unlock(bs);
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
KS_DECLARE(void) blade_handle_sessions_send(blade_handle_t *bh, list_t *sessions, const char *exclude, cJSON *json)
|
||||||
|
{
|
||||||
|
blade_session_t *bs = NULL;
|
||||||
|
|
||||||
|
ks_assert(bh);
|
||||||
|
ks_assert(sessions);
|
||||||
|
ks_assert(json);
|
||||||
|
|
||||||
|
list_iterator_start(sessions);
|
||||||
|
while (list_iterator_hasnext(sessions)) {
|
||||||
|
const char *sessionid = list_iterator_next(sessions);
|
||||||
|
if (exclude && !strcmp(exclude, sessionid)) continue;
|
||||||
|
bs = blade_handle_sessions_get(bh, sessionid);
|
||||||
|
if (!bs) {
|
||||||
|
ks_log(KS_LOG_DEBUG, "This should not happen\n");
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
blade_session_send(bs, json, NULL);
|
||||||
|
blade_session_read_unlock(bs);
|
||||||
|
}
|
||||||
|
list_iterator_stop(sessions);
|
||||||
|
}
|
||||||
|
|
||||||
|
KS_DECLARE(ks_status_t) blade_handle_session_state_callback_register(blade_handle_t *bh, void *data, blade_session_state_callback_t callback, const char **id)
|
||||||
|
{
|
||||||
|
ks_status_t ret = KS_STATUS_SUCCESS;
|
||||||
|
blade_handle_session_state_callback_registration_t *bhsscr = NULL;
|
||||||
|
|
||||||
|
ks_assert(bh);
|
||||||
|
ks_assert(callback);
|
||||||
|
ks_assert(id);
|
||||||
|
|
||||||
|
blade_handle_session_state_callback_registration_create(&bhsscr, blade_handle_pool_get(bh), data, callback);
|
||||||
|
ks_assert(bhsscr);
|
||||||
|
|
||||||
|
ks_hash_write_lock(bh->session_state_callbacks);
|
||||||
|
ret = ks_hash_insert(bh->session_state_callbacks, (void *)bhsscr->id, bhsscr);
|
||||||
|
ks_hash_write_unlock(bh->session_state_callbacks);
|
||||||
|
|
||||||
|
*id = bhsscr->id;
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
KS_DECLARE(ks_status_t) blade_handle_session_state_callback_unregister(blade_handle_t *bh, const char *id)
|
||||||
|
{
|
||||||
|
ks_status_t ret = KS_STATUS_SUCCESS;
|
||||||
|
blade_handle_session_state_callback_registration_t *bhsscr = NULL;
|
||||||
|
|
||||||
|
ks_assert(bh);
|
||||||
|
ks_assert(id);
|
||||||
|
|
||||||
|
ks_hash_write_lock(bh->session_state_callbacks);
|
||||||
|
bhsscr = (blade_handle_session_state_callback_registration_t *)ks_hash_remove(bh->session_state_callbacks, (void *)id);
|
||||||
|
if (!bhsscr) ret = KS_STATUS_FAIL;
|
||||||
|
ks_hash_write_lock(bh->session_state_callbacks);
|
||||||
|
|
||||||
|
if (bhsscr) blade_handle_session_state_callback_registration_destroy(&bhsscr);
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
KS_DECLARE(void) blade_handle_session_state_callbacks_execute(blade_session_t *bs, blade_session_state_condition_t condition)
|
||||||
|
{
|
||||||
|
blade_handle_t *bh = NULL;
|
||||||
|
ks_hash_iterator_t *it = NULL;
|
||||||
|
|
||||||
|
ks_assert(bs);
|
||||||
|
|
||||||
|
if (blade_session_state_get(bs) == BLADE_SESSION_STATE_NONE) return;
|
||||||
|
|
||||||
|
bh = blade_session_handle_get(bs);
|
||||||
|
ks_assert(bh);
|
||||||
|
|
||||||
|
ks_hash_read_lock(bh->session_state_callbacks);
|
||||||
|
for (it = ks_hash_first(bh->session_state_callbacks, KS_UNLOCKED); it; it = ks_hash_next(&it)) {
|
||||||
|
void *key = NULL;
|
||||||
|
blade_handle_session_state_callback_registration_t *value = NULL;
|
||||||
|
|
||||||
|
ks_hash_this(it, (const void **)&key, NULL, (void **)&value);
|
||||||
|
|
||||||
|
value->callback(bs, condition, value->data);
|
||||||
|
}
|
||||||
|
ks_hash_read_unlock(bh->session_state_callbacks);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
KS_DECLARE(blade_request_t *) blade_handle_requests_get(blade_handle_t *bh, const char *mid)
|
||||||
|
{
|
||||||
|
blade_request_t *br = NULL;
|
||||||
|
|
||||||
|
ks_assert(bh);
|
||||||
|
ks_assert(mid);
|
||||||
|
|
||||||
|
ks_hash_read_lock(bh->requests);
|
||||||
|
br = ks_hash_search(bh->requests, (void *)mid, KS_UNLOCKED);
|
||||||
|
ks_hash_read_unlock(bh->requests);
|
||||||
|
|
||||||
|
return br;
|
||||||
|
}
|
||||||
|
|
||||||
|
KS_DECLARE(ks_status_t) blade_handle_requests_add(blade_request_t *br)
|
||||||
|
{
|
||||||
|
ks_status_t ret = KS_STATUS_SUCCESS;
|
||||||
|
blade_handle_t *bh = NULL;
|
||||||
|
|
||||||
|
ks_assert(br);
|
||||||
|
|
||||||
|
bh = br->handle;
|
||||||
|
ks_assert(bh);
|
||||||
|
|
||||||
|
ks_hash_write_lock(bh->requests);
|
||||||
|
ret = ks_hash_insert(bh->requests, (void *)br->message_id, br);
|
||||||
|
ks_hash_write_unlock(bh->requests);
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
KS_DECLARE(ks_status_t) blade_handle_requests_remove(blade_request_t *br)
|
||||||
|
{
|
||||||
|
ks_status_t ret = KS_STATUS_SUCCESS;
|
||||||
|
blade_handle_t *bh = NULL;
|
||||||
|
|
||||||
|
ks_assert(br);
|
||||||
|
|
||||||
|
bh = br->handle;
|
||||||
|
ks_assert(bh);
|
||||||
|
|
||||||
|
ks_hash_write_lock(bh->requests);
|
||||||
|
if (ks_hash_remove(bh->requests, (void *)br->message_id) == NULL) ret = KS_STATUS_FAIL;
|
||||||
|
ks_hash_write_unlock(bh->requests);
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
KS_DECLARE(ks_bool_t) blade_handle_datastore_available(blade_handle_t *bh)
|
||||||
{
|
{
|
||||||
ks_assert(bh);
|
ks_assert(bh);
|
||||||
|
|
||||||
if (bh->datastore) return;
|
return bh->datastore != NULL;
|
||||||
|
|
||||||
blade_datastore_create(&bh->datastore, bh->pool);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
KS_DECLARE(ks_status_t) blade_handle_datastore_store(blade_handle_t *bh, const void *key, int32_t key_length, const void *data, int64_t data_length)
|
KS_DECLARE(ks_status_t) blade_handle_datastore_store(blade_handle_t *bh, const void *key, int32_t key_length, const void *data, int64_t data_length)
|
||||||
{
|
{
|
||||||
ks_assert(bh);
|
ks_assert(bh);
|
||||||
ks_assert(bh->datastore);
|
|
||||||
ks_assert(key);
|
ks_assert(key);
|
||||||
ks_assert(key_length > 0);
|
ks_assert(key_length > 0);
|
||||||
ks_assert(data);
|
ks_assert(data);
|
||||||
ks_assert(data_length > 0);
|
ks_assert(data_length > 0);
|
||||||
|
|
||||||
|
if (!blade_handle_datastore_available(bh)) return KS_STATUS_INACTIVE;
|
||||||
|
|
||||||
return blade_datastore_store(bh->datastore, key, key_length, data, data_length);
|
return blade_datastore_store(bh->datastore, key, key_length, data, data_length);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -181,11 +855,12 @@ KS_DECLARE(ks_status_t) blade_handle_datastore_fetch(blade_handle_t *bh,
|
|||||||
void *userdata)
|
void *userdata)
|
||||||
{
|
{
|
||||||
ks_assert(bh);
|
ks_assert(bh);
|
||||||
ks_assert(bh->datastore);
|
|
||||||
ks_assert(callback);
|
ks_assert(callback);
|
||||||
ks_assert(key);
|
ks_assert(key);
|
||||||
ks_assert(key_length > 0);
|
ks_assert(key_length > 0);
|
||||||
|
|
||||||
|
if (!blade_handle_datastore_available(bh)) return KS_STATUS_INACTIVE;
|
||||||
|
|
||||||
return blade_datastore_fetch(bh->datastore, callback, key, key_length, userdata);
|
return blade_datastore_fetch(bh->datastore, callback, key, key_length, userdata);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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
|
* Copyright (c) 2007-2014, Anthony Minessale II
|
||||||
* All rights reserved.
|
* All rights reserved.
|
||||||
*
|
*
|
||||||
* Redistribution and use in source and binary forms, with or without
|
* Redistribution and use in source and binary forms, with or without
|
||||||
* modification, are permitted provided that the following conditions
|
* modification, are permitted provided that the following conditions
|
||||||
* are met:
|
* are met:
|
||||||
*
|
*
|
||||||
* * Redistributions of source code must retain the above copyright
|
* * Redistributions of source code must retain the above copyright
|
||||||
* notice, this list of conditions and the following disclaimer.
|
* notice, this list of conditions and the following disclaimer.
|
||||||
*
|
*
|
||||||
* * Redistributions in binary form must reproduce the above copyright
|
* * Redistributions in binary form must reproduce the above copyright
|
||||||
* notice, this list of conditions and the following disclaimer in the
|
* notice, this list of conditions and the following disclaimer in the
|
||||||
* documentation and/or other materials provided with the distribution.
|
* documentation and/or other materials provided with the distribution.
|
||||||
*
|
*
|
||||||
* * Neither the name of the original author; nor the names of any contributors
|
* * 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
|
* may be used to endorse or promote products derived from this software
|
||||||
* without specific prior written permission.
|
* without specific prior written permission.
|
||||||
*
|
*
|
||||||
*
|
*
|
||||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||||
@ -36,12 +36,18 @@
|
|||||||
#include <ks.h>
|
#include <ks.h>
|
||||||
#include <ks_dht.h>
|
#include <ks_dht.h>
|
||||||
#include <sodium.h>
|
#include <sodium.h>
|
||||||
|
#include <libconfig.h>
|
||||||
#include "unqlite.h"
|
#include "unqlite.h"
|
||||||
#include "blade_types.h"
|
#include "blade_types.h"
|
||||||
#include "blade_stack.h"
|
#include "blade_stack.h"
|
||||||
#include "blade_peer.h"
|
#include "blade_identity.h"
|
||||||
|
#include "blade_module.h"
|
||||||
|
#include "blade_connection.h"
|
||||||
|
#include "blade_session.h"
|
||||||
|
#include "blade_protocol.h"
|
||||||
#include "blade_datastore.h"
|
#include "blade_datastore.h"
|
||||||
#include "bpcp.h"
|
#include "blade_space.h"
|
||||||
|
#include "blade_method.h"
|
||||||
|
|
||||||
KS_BEGIN_EXTERN_C
|
KS_BEGIN_EXTERN_C
|
||||||
|
|
||||||
|
76
libs/libblade/src/include/blade_connection.h
Normal file
76
libs/libblade/src/include/blade_connection.h
Normal file
@ -0,0 +1,76 @@
|
|||||||
|
/*
|
||||||
|
* 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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef _BLADE_CONNECTION_H_
|
||||||
|
#define _BLADE_CONNECTION_H_
|
||||||
|
#include <blade.h>
|
||||||
|
|
||||||
|
KS_BEGIN_EXTERN_C
|
||||||
|
KS_DECLARE(ks_status_t) blade_connection_create(blade_connection_t **bcP,
|
||||||
|
blade_handle_t *bh,
|
||||||
|
void *transport_data,
|
||||||
|
blade_transport_callbacks_t *transport_callbacks);
|
||||||
|
KS_DECLARE(ks_status_t) blade_connection_destroy(blade_connection_t **bcP);
|
||||||
|
KS_DECLARE(ks_status_t) blade_connection_startup(blade_connection_t *bc, blade_connection_direction_t direction);
|
||||||
|
KS_DECLARE(ks_status_t) blade_connection_shutdown(blade_connection_t *bc);
|
||||||
|
KS_DECLARE(blade_handle_t *) blade_connection_handle_get(blade_connection_t *bc);
|
||||||
|
KS_DECLARE(ks_pool_t *) blade_connection_pool_get(blade_connection_t *bc);
|
||||||
|
KS_DECLARE(const char *) blade_connection_id_get(blade_connection_t *bc);
|
||||||
|
KS_DECLARE(ks_status_t) blade_connection_read_lock(blade_connection_t *bc, ks_bool_t block);
|
||||||
|
KS_DECLARE(ks_status_t) blade_connection_read_unlock(blade_connection_t *bc);
|
||||||
|
KS_DECLARE(ks_status_t) blade_connection_write_lock(blade_connection_t *bc, ks_bool_t block);
|
||||||
|
KS_DECLARE(ks_status_t) blade_connection_write_unlock(blade_connection_t *bc);
|
||||||
|
KS_DECLARE(void *) blade_connection_transport_init_get(blade_connection_t *bc);
|
||||||
|
KS_DECLARE(void *) blade_connection_transport_get(blade_connection_t *bc);
|
||||||
|
KS_DECLARE(void) blade_connection_transport_set(blade_connection_t *bc, void *transport_data);
|
||||||
|
KS_DECLARE(void) blade_connection_state_set(blade_connection_t *bc, blade_connection_state_t state);
|
||||||
|
KS_DECLARE(void) blade_connection_disconnect(blade_connection_t *bc);
|
||||||
|
KS_DECLARE(blade_connection_rank_t) blade_connection_rank(blade_connection_t *bc, blade_identity_t *target);
|
||||||
|
KS_DECLARE(ks_status_t) blade_connection_sending_push(blade_connection_t *bc, cJSON *json);
|
||||||
|
KS_DECLARE(ks_status_t) blade_connection_sending_pop(blade_connection_t *bc, cJSON **json);
|
||||||
|
KS_DECLARE(const char *) blade_connection_session_get(blade_connection_t *bc);
|
||||||
|
KS_DECLARE(void) blade_connection_session_set(blade_connection_t *bc, const char *id);
|
||||||
|
KS_END_EXTERN_C
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* 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:
|
||||||
|
*/
|
@ -36,9 +36,11 @@
|
|||||||
#include <blade.h>
|
#include <blade.h>
|
||||||
|
|
||||||
KS_BEGIN_EXTERN_C
|
KS_BEGIN_EXTERN_C
|
||||||
KS_DECLARE(ks_status_t) blade_datastore_create(blade_datastore_t **bdsP, ks_pool_t *pool);
|
KS_DECLARE(ks_status_t) blade_datastore_create(blade_datastore_t **bdsP, ks_pool_t *pool, ks_thread_pool_t *tpool);
|
||||||
KS_DECLARE(ks_status_t) blade_datastore_destroy(blade_datastore_t **bdsP);
|
KS_DECLARE(ks_status_t) blade_datastore_destroy(blade_datastore_t **bdsP);
|
||||||
KS_DECLARE(void) blade_datastore_pulse(blade_datastore_t *bds, int32_t timeout);
|
KS_DECLARE(ks_status_t) blade_datastore_startup(blade_datastore_t *bds, config_setting_t *config);
|
||||||
|
KS_DECLARE(ks_status_t) blade_datastore_shutdown(blade_datastore_t *bds);
|
||||||
|
|
||||||
KS_DECLARE(void) blade_datastore_error(blade_datastore_t *bds, const char **buffer, int32_t *buffer_length);
|
KS_DECLARE(void) blade_datastore_error(blade_datastore_t *bds, const char **buffer, int32_t *buffer_length);
|
||||||
KS_DECLARE(ks_status_t) blade_datastore_store(blade_datastore_t *bds, const void *key, int32_t key_length, const void *data, int64_t data_length);
|
KS_DECLARE(ks_status_t) blade_datastore_store(blade_datastore_t *bds, const void *key, int32_t key_length, const void *data, int64_t data_length);
|
||||||
KS_DECLARE(ks_status_t) blade_datastore_fetch(blade_datastore_t *bds,
|
KS_DECLARE(ks_status_t) blade_datastore_fetch(blade_datastore_t *bds,
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2007-2014, Anthony Minessale II
|
* Copyright (c) 2017, Shane Bryldt
|
||||||
* All rights reserved.
|
* All rights reserved.
|
||||||
*
|
*
|
||||||
* Redistribution and use in source and binary forms, with or without
|
* Redistribution and use in source and binary forms, with or without
|
||||||
@ -31,22 +31,16 @@
|
|||||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef _BPCP_H_
|
#ifndef _BLADE_IDENTITY_H_
|
||||||
#define _BPCP_H_
|
#define _BLADE_IDENTITY_H_
|
||||||
#include <blade.h>
|
#include <blade.h>
|
||||||
|
|
||||||
#define BLADE_PEER_TPOOL_MIN 2
|
|
||||||
#define BLADE_PEER_TPOOL_MAX 8
|
|
||||||
#define BLADE_PEER_TPOOL_STACK (1024 * 256)
|
|
||||||
#define BLADE_PEER_TPOOL_IDLE 10
|
|
||||||
|
|
||||||
KS_BEGIN_EXTERN_C
|
KS_BEGIN_EXTERN_C
|
||||||
KS_DECLARE(ks_status_t) blade_peer_create(blade_peer_t **bpP, ks_pool_t *pool, ks_thread_pool_t *tpool, ks_dht_nodeid_t *nodeid);
|
KS_DECLARE(ks_status_t) blade_identity_create(blade_identity_t **biP, ks_pool_t *pool);
|
||||||
KS_DECLARE(ks_status_t) blade_peer_destroy(blade_peer_t **bpP);
|
KS_DECLARE(ks_status_t) blade_identity_destroy(blade_identity_t **biP);
|
||||||
KS_DECLARE(ks_dht_nodeid_t *) blade_peer_myid(blade_peer_t *bp);
|
KS_DECLARE(ks_status_t) blade_identity_parse(blade_identity_t *bi, const char *uri);
|
||||||
KS_DECLARE(void) blade_peer_autoroute(blade_peer_t *bp, ks_bool_t autoroute, ks_port_t port);
|
KS_DECLARE(const char *) blade_identity_uri(blade_identity_t *bi);
|
||||||
KS_DECLARE(ks_status_t) blade_peer_bind(blade_peer_t *bp, const ks_sockaddr_t *addr, ks_dht_endpoint_t **endpoint);
|
KS_DECLARE(const char *) blade_identity_parameter_get(blade_identity_t *bi, const char *key);
|
||||||
KS_DECLARE(void) blade_peer_pulse(blade_peer_t *bp, int32_t timeout);
|
|
||||||
KS_END_EXTERN_C
|
KS_END_EXTERN_C
|
||||||
|
|
||||||
#endif
|
#endif
|
56
libs/libblade/src/include/blade_method.h
Normal file
56
libs/libblade/src/include/blade_method.h
Normal file
@ -0,0 +1,56 @@
|
|||||||
|
/*
|
||||||
|
* 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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#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
|
||||||
|
|
||||||
|
/* 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:
|
||||||
|
*/
|
67
libs/libblade/src/include/blade_module.h
Normal file
67
libs/libblade/src/include/blade_module.h
Normal file
@ -0,0 +1,67 @@
|
|||||||
|
/*
|
||||||
|
* 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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef _BLADE_MODULE_H_
|
||||||
|
#define _BLADE_MODULE_H_
|
||||||
|
#include <blade.h>
|
||||||
|
|
||||||
|
KS_BEGIN_EXTERN_C
|
||||||
|
KS_DECLARE(ks_status_t) blade_module_create(blade_module_t **bmP, blade_handle_t *bh, void *module_data, blade_module_callbacks_t *module_callbacks);
|
||||||
|
KS_DECLARE(ks_status_t) blade_module_destroy(blade_module_t **bmP);
|
||||||
|
KS_DECLARE(blade_handle_t *) blade_module_handle_get(blade_module_t *bm);
|
||||||
|
KS_DECLARE(void *) blade_module_data_get(blade_module_t *bm);
|
||||||
|
|
||||||
|
// @todo very temporary, this is just here to get the wss module loaded until DSO is in place
|
||||||
|
KS_DECLARE(ks_status_t) blade_module_wss_on_load(blade_module_t **bmP, blade_handle_t *bh);
|
||||||
|
KS_DECLARE(ks_status_t) blade_module_wss_on_unload(blade_module_t *bm);
|
||||||
|
KS_DECLARE(ks_status_t) blade_module_wss_on_startup(blade_module_t *bm, config_setting_t *config);
|
||||||
|
KS_DECLARE(ks_status_t) blade_module_wss_on_shutdown(blade_module_t *bm);
|
||||||
|
|
||||||
|
KS_DECLARE(ks_status_t) blade_module_chat_on_load(blade_module_t **bmP, blade_handle_t *bh);
|
||||||
|
KS_DECLARE(ks_status_t) blade_module_chat_on_unload(blade_module_t *bm);
|
||||||
|
KS_DECLARE(ks_status_t) blade_module_chat_on_startup(blade_module_t *bm, config_setting_t *config);
|
||||||
|
KS_DECLARE(ks_status_t) blade_module_chat_on_shutdown(blade_module_t *bm);
|
||||||
|
KS_END_EXTERN_C
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* 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:
|
||||||
|
*/
|
66
libs/libblade/src/include/blade_protocol.h
Normal file
66
libs/libblade/src/include/blade_protocol.h
Normal file
@ -0,0 +1,66 @@
|
|||||||
|
/*
|
||||||
|
* 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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef _BLADE_PROTOCOL_H_
|
||||||
|
#define _BLADE_PROTOCOL_H_
|
||||||
|
#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,
|
||||||
|
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_event_create(blade_event_t **bevP, blade_handle_t *bh, const char *session_id, cJSON *json);
|
||||||
|
KS_DECLARE(ks_status_t) blade_event_destroy(blade_event_t **bevP);
|
||||||
|
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_DECLARE(ks_status_t) blade_rpc_event_create(ks_pool_t *pool, cJSON **json, cJSON **result, const char *event);
|
||||||
|
KS_END_EXTERN_C
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* 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:
|
||||||
|
*/
|
80
libs/libblade/src/include/blade_session.h
Normal file
80
libs/libblade/src/include/blade_session.h
Normal file
@ -0,0 +1,80 @@
|
|||||||
|
/*
|
||||||
|
* 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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef _BLADE_SESSION_H_
|
||||||
|
#define _BLADE_SESSION_H_
|
||||||
|
#include <blade.h>
|
||||||
|
|
||||||
|
KS_BEGIN_EXTERN_C
|
||||||
|
KS_DECLARE(ks_status_t) blade_session_create(blade_session_t **bsP, blade_handle_t *bh);
|
||||||
|
KS_DECLARE(ks_status_t) blade_session_destroy(blade_session_t **bsP);
|
||||||
|
KS_DECLARE(ks_status_t) blade_session_startup(blade_session_t *bs);
|
||||||
|
KS_DECLARE(ks_status_t) blade_session_shutdown(blade_session_t *bs);
|
||||||
|
KS_DECLARE(blade_handle_t *) blade_session_handle_get(blade_session_t *bs);
|
||||||
|
KS_DECLARE(ks_pool_t *) blade_session_pool_get(blade_session_t *bs);
|
||||||
|
KS_DECLARE(const char *) blade_session_id_get(blade_session_t *bs);
|
||||||
|
KS_DECLARE(void) blade_session_id_set(blade_session_t *bs, const char *id);
|
||||||
|
KS_DECLARE(blade_session_state_t) blade_session_state_get(blade_session_t *bs);
|
||||||
|
KS_DECLARE(cJSON *) blade_session_properties_get(blade_session_t *bs);
|
||||||
|
KS_DECLARE(ks_status_t) blade_session_read_lock(blade_session_t *bs, ks_bool_t block);
|
||||||
|
KS_DECLARE(ks_status_t) blade_session_read_unlock(blade_session_t *bs);
|
||||||
|
KS_DECLARE(ks_status_t) blade_session_write_lock(blade_session_t *bs, ks_bool_t block);
|
||||||
|
KS_DECLARE(ks_status_t) blade_session_write_unlock(blade_session_t *bs);
|
||||||
|
KS_DECLARE(ks_status_t) blade_session_properties_read_lock(blade_session_t *bs, ks_bool_t block);
|
||||||
|
KS_DECLARE(ks_status_t) blade_session_properties_read_unlock(blade_session_t *bs);
|
||||||
|
KS_DECLARE(ks_status_t) blade_session_properties_write_lock(blade_session_t *bs, ks_bool_t block);
|
||||||
|
KS_DECLARE(ks_status_t) blade_session_properties_write_unlock(blade_session_t *bs);
|
||||||
|
KS_DECLARE(void) blade_session_state_set(blade_session_t *bs, blade_session_state_t state);
|
||||||
|
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, 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);
|
||||||
|
KS_DECLARE(ks_status_t) blade_session_receiving_pop(blade_session_t *bs, cJSON **json);
|
||||||
|
KS_END_EXTERN_C
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* 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:
|
||||||
|
*/
|
60
libs/libblade/src/include/blade_space.h
Normal file
60
libs/libblade/src/include/blade_space.h
Normal file
@ -0,0 +1,60 @@
|
|||||||
|
/*
|
||||||
|
* 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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef _BLADE_SPACE_H_
|
||||||
|
#define _BLADE_SPACE_H_
|
||||||
|
#include <blade.h>
|
||||||
|
|
||||||
|
KS_BEGIN_EXTERN_C
|
||||||
|
KS_DECLARE(ks_status_t) blade_space_create(blade_space_t **bsP, blade_handle_t *bh, blade_module_t *bm, 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(blade_module_t *) blade_space_module_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
|
||||||
|
|
||||||
|
/* 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
|
* Copyright (c) 2007-2014, Anthony Minessale II
|
||||||
* All rights reserved.
|
* All rights reserved.
|
||||||
*
|
*
|
||||||
* Redistribution and use in source and binary forms, with or without
|
* Redistribution and use in source and binary forms, with or without
|
||||||
* modification, are permitted provided that the following conditions
|
* modification, are permitted provided that the following conditions
|
||||||
* are met:
|
* are met:
|
||||||
*
|
*
|
||||||
* * Redistributions of source code must retain the above copyright
|
* * Redistributions of source code must retain the above copyright
|
||||||
* notice, this list of conditions and the following disclaimer.
|
* notice, this list of conditions and the following disclaimer.
|
||||||
*
|
*
|
||||||
* * Redistributions in binary form must reproduce the above copyright
|
* * Redistributions in binary form must reproduce the above copyright
|
||||||
* notice, this list of conditions and the following disclaimer in the
|
* notice, this list of conditions and the following disclaimer in the
|
||||||
* documentation and/or other materials provided with the distribution.
|
* documentation and/or other materials provided with the distribution.
|
||||||
*
|
*
|
||||||
* * Neither the name of the original author; nor the names of any contributors
|
* * 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
|
* may be used to endorse or promote products derived from this software
|
||||||
* without specific prior written permission.
|
* without specific prior written permission.
|
||||||
*
|
*
|
||||||
*
|
*
|
||||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||||
@ -42,12 +42,42 @@
|
|||||||
|
|
||||||
KS_BEGIN_EXTERN_C
|
KS_BEGIN_EXTERN_C
|
||||||
KS_DECLARE(ks_status_t) blade_handle_destroy(blade_handle_t **bhP);
|
KS_DECLARE(ks_status_t) blade_handle_destroy(blade_handle_t **bhP);
|
||||||
KS_DECLARE(ks_status_t) blade_handle_create(blade_handle_t **bhP, ks_pool_t *pool, ks_thread_pool_t *tpool, const char *nodeid);
|
KS_DECLARE(ks_status_t) blade_handle_create(blade_handle_t **bhP, ks_pool_t *pool, ks_thread_pool_t *tpool);
|
||||||
KS_DECLARE(void) blade_handle_myid(blade_handle_t *bh, char *buffer);
|
KS_DECLARE(ks_status_t) blade_handle_startup(blade_handle_t *bh, config_setting_t *config);
|
||||||
KS_DECLARE(void) blade_handle_autoroute(blade_handle_t *bh, ks_bool_t autoroute, ks_port_t port);
|
KS_DECLARE(ks_status_t) blade_handle_shutdown(blade_handle_t *bh);
|
||||||
KS_DECLARE(ks_status_t) blade_handle_bind(blade_handle_t *bh, const char *ip, ks_port_t port, ks_dht_endpoint_t **endpoint);
|
KS_DECLARE(ks_pool_t *) blade_handle_pool_get(blade_handle_t *bh);
|
||||||
KS_DECLARE(void) blade_handle_pulse(blade_handle_t *bh, int32_t timeout);
|
KS_DECLARE(ks_thread_pool_t *) blade_handle_tpool_get(blade_handle_t *bh);
|
||||||
KS_DECLARE(void) blade_handle_datastore_start(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_event_register(blade_handle_t *bh, const char *event, blade_event_callback_t callback);
|
||||||
|
KS_DECLARE(ks_status_t) blade_handle_event_unregister(blade_handle_t *bh, const char *event);
|
||||||
|
KS_DECLARE(blade_event_callback_t) blade_handle_event_lookup(blade_handle_t *bh, const char *event);
|
||||||
|
|
||||||
|
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);
|
||||||
|
KS_DECLARE(ks_status_t) blade_handle_connections_add(blade_connection_t *bc);
|
||||||
|
KS_DECLARE(ks_status_t) blade_handle_connections_remove(blade_connection_t *bc);
|
||||||
|
|
||||||
|
KS_DECLARE(blade_session_t *) blade_handle_sessions_get(blade_handle_t *bh, const char *sid);
|
||||||
|
KS_DECLARE(ks_status_t) blade_handle_sessions_add(blade_session_t *bs);
|
||||||
|
KS_DECLARE(ks_status_t) blade_handle_sessions_remove(blade_session_t *bs);
|
||||||
|
KS_DECLARE(void) blade_handle_sessions_send(blade_handle_t *bh, list_t *sessions, const char *exclude, cJSON *json);
|
||||||
|
KS_DECLARE(ks_status_t) blade_handle_session_state_callback_register(blade_handle_t *bh, void *data, blade_session_state_callback_t callback, const char **id);
|
||||||
|
KS_DECLARE(ks_status_t) blade_handle_session_state_callback_unregister(blade_handle_t *bh, const char *id);
|
||||||
|
KS_DECLARE(void) blade_handle_session_state_callbacks_execute(blade_session_t *bs, blade_session_state_condition_t condition);
|
||||||
|
|
||||||
|
KS_DECLARE(blade_request_t *) blade_handle_requests_get(blade_handle_t *bh, const char *mid);
|
||||||
|
KS_DECLARE(ks_status_t) blade_handle_requests_add(blade_request_t *br);
|
||||||
|
KS_DECLARE(ks_status_t) blade_handle_requests_remove(blade_request_t *br);
|
||||||
|
|
||||||
|
KS_DECLARE(ks_bool_t) blade_handle_datastore_available(blade_handle_t *bh);
|
||||||
KS_DECLARE(ks_status_t) blade_handle_datastore_store(blade_handle_t *bh, const void *key, int32_t key_length, const void *data, int64_t data_length);
|
KS_DECLARE(ks_status_t) blade_handle_datastore_store(blade_handle_t *bh, const void *key, int32_t key_length, const void *data, int64_t data_length);
|
||||||
KS_DECLARE(ks_status_t) blade_handle_datastore_fetch(blade_handle_t *bh,
|
KS_DECLARE(ks_status_t) blade_handle_datastore_fetch(blade_handle_t *bh,
|
||||||
blade_datastore_fetch_callback_t callback,
|
blade_datastore_fetch_callback_t callback,
|
||||||
|
@ -1,23 +1,23 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2007-2014, Anthony Minessale II
|
* Copyright (c) 2007-2014, Anthony Minessale II
|
||||||
* All rights reserved.
|
* All rights reserved.
|
||||||
*
|
*
|
||||||
* Redistribution and use in source and binary forms, with or without
|
* Redistribution and use in source and binary forms, with or without
|
||||||
* modification, are permitted provided that the following conditions
|
* modification, are permitted provided that the following conditions
|
||||||
* are met:
|
* are met:
|
||||||
*
|
*
|
||||||
* * Redistributions of source code must retain the above copyright
|
* * Redistributions of source code must retain the above copyright
|
||||||
* notice, this list of conditions and the following disclaimer.
|
* notice, this list of conditions and the following disclaimer.
|
||||||
*
|
*
|
||||||
* * Redistributions in binary form must reproduce the above copyright
|
* * Redistributions in binary form must reproduce the above copyright
|
||||||
* notice, this list of conditions and the following disclaimer in the
|
* notice, this list of conditions and the following disclaimer in the
|
||||||
* documentation and/or other materials provided with the distribution.
|
* documentation and/or other materials provided with the distribution.
|
||||||
*
|
*
|
||||||
* * Neither the name of the original author; nor the names of any contributors
|
* * 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
|
* may be used to endorse or promote products derived from this software
|
||||||
* without specific prior written permission.
|
* without specific prior written permission.
|
||||||
*
|
*
|
||||||
*
|
*
|
||||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||||
@ -34,15 +34,157 @@
|
|||||||
#ifndef _BLADE_TYPES_H_
|
#ifndef _BLADE_TYPES_H_
|
||||||
#define _BLADE_TYPES_H_
|
#define _BLADE_TYPES_H_
|
||||||
#include <ks.h>
|
#include <ks.h>
|
||||||
|
#include <libconfig.h>
|
||||||
|
|
||||||
KS_BEGIN_EXTERN_C
|
KS_BEGIN_EXTERN_C
|
||||||
|
|
||||||
typedef struct blade_handle_s blade_handle_t;
|
typedef struct blade_handle_s blade_handle_t;
|
||||||
typedef struct blade_peer_s blade_peer_t;
|
typedef struct blade_identity_s blade_identity_t;
|
||||||
|
typedef struct blade_module_s blade_module_t;
|
||||||
|
typedef struct blade_module_callbacks_s blade_module_callbacks_t;
|
||||||
|
typedef struct blade_transport_callbacks_s blade_transport_callbacks_t;
|
||||||
|
typedef struct blade_session_callbacks_s blade_session_callbacks_t;
|
||||||
|
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_event_s blade_event_t;
|
||||||
|
typedef struct blade_space_s blade_space_t;
|
||||||
|
typedef struct blade_method_s blade_method_t;
|
||||||
|
|
||||||
|
|
||||||
typedef struct blade_datastore_s blade_datastore_t;
|
typedef struct blade_datastore_s blade_datastore_t;
|
||||||
|
|
||||||
|
|
||||||
|
typedef ks_bool_t (*blade_request_callback_t)(blade_module_t *bm, blade_request_t *breq);
|
||||||
|
typedef ks_bool_t (*blade_response_callback_t)(blade_response_t *bres);
|
||||||
|
typedef ks_bool_t (*blade_event_callback_t)(blade_event_t *bev);
|
||||||
|
|
||||||
typedef ks_bool_t (*blade_datastore_fetch_callback_t)(blade_datastore_t *bds, const void *data, uint32_t data_length, void *userdata);
|
typedef ks_bool_t (*blade_datastore_fetch_callback_t)(blade_datastore_t *bds, const void *data, uint32_t data_length, void *userdata);
|
||||||
|
|
||||||
|
|
||||||
|
typedef enum {
|
||||||
|
BLADE_CONNECTION_STATE_NONE,
|
||||||
|
BLADE_CONNECTION_STATE_DISCONNECT,
|
||||||
|
BLADE_CONNECTION_STATE_NEW,
|
||||||
|
BLADE_CONNECTION_STATE_CONNECT,
|
||||||
|
BLADE_CONNECTION_STATE_ATTACH,
|
||||||
|
BLADE_CONNECTION_STATE_DETACH,
|
||||||
|
BLADE_CONNECTION_STATE_READY,
|
||||||
|
} blade_connection_state_t;
|
||||||
|
|
||||||
|
typedef enum {
|
||||||
|
BLADE_CONNECTION_DIRECTION_INBOUND,
|
||||||
|
BLADE_CONNECTION_DIRECTION_OUTBOUND,
|
||||||
|
} blade_connection_direction_t;
|
||||||
|
|
||||||
|
typedef enum {
|
||||||
|
BLADE_CONNECTION_STATE_CONDITION_PRE,
|
||||||
|
BLADE_CONNECTION_STATE_CONDITION_POST,
|
||||||
|
} blade_connection_state_condition_t;
|
||||||
|
|
||||||
|
typedef enum {
|
||||||
|
BLADE_CONNECTION_STATE_HOOK_SUCCESS,
|
||||||
|
BLADE_CONNECTION_STATE_HOOK_DISCONNECT,
|
||||||
|
BLADE_CONNECTION_STATE_HOOK_BYPASS,
|
||||||
|
} blade_connection_state_hook_t;
|
||||||
|
|
||||||
|
typedef enum {
|
||||||
|
BLADE_CONNECTION_RANK_POOR,
|
||||||
|
BLADE_CONNECTION_RANK_AVERAGE,
|
||||||
|
BLADE_CONNECTION_RANK_GOOD,
|
||||||
|
BLADE_CONNECTION_RANK_GREAT,
|
||||||
|
} blade_connection_rank_t;
|
||||||
|
|
||||||
|
|
||||||
|
typedef enum {
|
||||||
|
BLADE_SESSION_STATE_CONDITION_PRE,
|
||||||
|
BLADE_SESSION_STATE_CONDITION_POST,
|
||||||
|
} blade_session_state_condition_t;
|
||||||
|
|
||||||
|
typedef enum {
|
||||||
|
BLADE_SESSION_STATE_NONE,
|
||||||
|
BLADE_SESSION_STATE_DESTROY,
|
||||||
|
BLADE_SESSION_STATE_HANGUP,
|
||||||
|
BLADE_SESSION_STATE_CONNECT,
|
||||||
|
BLADE_SESSION_STATE_ATTACH,
|
||||||
|
BLADE_SESSION_STATE_DETACH,
|
||||||
|
BLADE_SESSION_STATE_READY,
|
||||||
|
} blade_session_state_t;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
typedef ks_status_t (*blade_module_load_callback_t)(blade_module_t **bmP, blade_handle_t *bh);
|
||||||
|
typedef ks_status_t (*blade_module_unload_callback_t)(blade_module_t *bm);
|
||||||
|
typedef ks_status_t (*blade_module_startup_callback_t)(blade_module_t *bm, config_setting_t *config);
|
||||||
|
typedef ks_status_t (*blade_module_shutdown_callback_t)(blade_module_t *bm);
|
||||||
|
|
||||||
|
struct blade_module_callbacks_s {
|
||||||
|
blade_module_load_callback_t onload;
|
||||||
|
blade_module_unload_callback_t onunload;
|
||||||
|
blade_module_startup_callback_t onstartup;
|
||||||
|
blade_module_shutdown_callback_t onshutdown;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
typedef ks_status_t (*blade_transport_connect_callback_t)(blade_connection_t **bcP, blade_module_t *bm, blade_identity_t *target, const char *session_id);
|
||||||
|
typedef blade_connection_rank_t (*blade_transport_rank_callback_t)(blade_connection_t *bc, blade_identity_t *target);
|
||||||
|
typedef ks_status_t (*blade_transport_send_callback_t)(blade_connection_t *bc, cJSON *json);
|
||||||
|
typedef ks_status_t (*blade_transport_receive_callback_t)(blade_connection_t *bc, cJSON **json);
|
||||||
|
typedef blade_connection_state_hook_t (*blade_transport_state_callback_t)(blade_connection_t *bc, blade_connection_state_condition_t condition);
|
||||||
|
|
||||||
|
struct blade_transport_callbacks_s {
|
||||||
|
blade_transport_connect_callback_t onconnect;
|
||||||
|
blade_transport_rank_callback_t onrank;
|
||||||
|
blade_transport_send_callback_t onsend;
|
||||||
|
blade_transport_receive_callback_t onreceive;
|
||||||
|
|
||||||
|
blade_transport_state_callback_t onstate_disconnect_inbound;
|
||||||
|
blade_transport_state_callback_t onstate_disconnect_outbound;
|
||||||
|
blade_transport_state_callback_t onstate_new_inbound;
|
||||||
|
blade_transport_state_callback_t onstate_new_outbound;
|
||||||
|
blade_transport_state_callback_t onstate_connect_inbound;
|
||||||
|
blade_transport_state_callback_t onstate_connect_outbound;
|
||||||
|
blade_transport_state_callback_t onstate_attach_inbound;
|
||||||
|
blade_transport_state_callback_t onstate_attach_outbound;
|
||||||
|
blade_transport_state_callback_t onstate_detach_inbound;
|
||||||
|
blade_transport_state_callback_t onstate_detach_outbound;
|
||||||
|
blade_transport_state_callback_t onstate_ready_inbound;
|
||||||
|
blade_transport_state_callback_t onstate_ready_outbound;
|
||||||
|
};
|
||||||
|
|
||||||
|
typedef void (*blade_session_state_callback_t)(blade_session_t *bs, blade_session_state_condition_t condition, void *data);
|
||||||
|
|
||||||
|
|
||||||
|
struct blade_request_s {
|
||||||
|
blade_handle_t *handle;
|
||||||
|
ks_pool_t *pool;
|
||||||
|
const char *session_id;
|
||||||
|
|
||||||
|
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
|
||||||
|
};
|
||||||
|
|
||||||
|
struct blade_response_s {
|
||||||
|
blade_handle_t *handle;
|
||||||
|
ks_pool_t *pool;
|
||||||
|
const char *session_id;
|
||||||
|
blade_request_t *request;
|
||||||
|
|
||||||
|
cJSON *message;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct blade_event_s {
|
||||||
|
blade_handle_t *handle;
|
||||||
|
ks_pool_t *pool;
|
||||||
|
const char *session_id;
|
||||||
|
|
||||||
|
cJSON *message;
|
||||||
|
};
|
||||||
|
|
||||||
KS_END_EXTERN_C
|
KS_END_EXTERN_C
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -1,7 +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
|
TEST_LDADD = $(abs_top_builddir)/libblade.la -lconfig -lm -lpthread
|
||||||
check_PROGRAMS =
|
check_PROGRAMS =
|
||||||
|
|
||||||
|
|
||||||
check_PROGRAMS += testbuild
|
check_PROGRAMS += testbuild
|
||||||
testbuild_SOURCES = testbuild.c tap.c
|
testbuild_SOURCES = testbuild.c tap.c
|
||||||
testbuild_CFLAGS = $(AM_CFLAGS)
|
testbuild_CFLAGS = $(AM_CFLAGS)
|
||||||
@ -12,6 +13,11 @@ bladec_SOURCES = bladec.c tap.c
|
|||||||
bladec_CFLAGS = $(AM_CFLAGS)
|
bladec_CFLAGS = $(AM_CFLAGS)
|
||||||
bladec_LDADD = $(TEST_LDADD)
|
bladec_LDADD = $(TEST_LDADD)
|
||||||
|
|
||||||
|
check_PROGRAMS += blades
|
||||||
|
blades_SOURCES = blades.c tap.c
|
||||||
|
blades_CFLAGS = $(AM_CFLAGS)
|
||||||
|
blades_LDADD = $(TEST_LDADD)
|
||||||
|
|
||||||
|
|
||||||
TESTS=$(check_PROGRAMS)
|
TESTS=$(check_PROGRAMS)
|
||||||
|
|
||||||
|
@ -26,44 +26,82 @@ struct command_def_s {
|
|||||||
command_callback callback;
|
command_callback callback;
|
||||||
};
|
};
|
||||||
|
|
||||||
void command_test(blade_handle_t *bh, char *args);
|
|
||||||
void command_quit(blade_handle_t *bh, char *args);
|
void command_quit(blade_handle_t *bh, char *args);
|
||||||
void command_myid(blade_handle_t *bh, char *args);
|
void command_connect(blade_handle_t *bh, char *args);
|
||||||
void command_bind(blade_handle_t *bh, char *args);
|
void command_chat(blade_handle_t *bh, char *args);
|
||||||
void command_store(blade_handle_t *bh, char *args);
|
|
||||||
void command_fetch(blade_handle_t *bh, char *args);
|
|
||||||
|
|
||||||
static const struct command_def_s command_defs[] = {
|
static const struct command_def_s command_defs[] = {
|
||||||
{ "test", command_test },
|
|
||||||
{ "quit", command_quit },
|
{ "quit", command_quit },
|
||||||
{ "myid", command_myid },
|
{ "connect", command_connect },
|
||||||
{ "bind", command_bind },
|
{ "chat", command_chat },
|
||||||
{ "store", command_store },
|
|
||||||
{ "fetch", command_fetch },
|
|
||||||
|
|
||||||
{ NULL, NULL }
|
{ NULL, NULL }
|
||||||
};
|
};
|
||||||
|
|
||||||
|
ks_bool_t on_blade_chat_join_response(blade_response_t *bres);
|
||||||
|
ks_bool_t on_blade_chat_message_event(blade_event_t *bev);
|
||||||
|
void on_blade_session_state_callback(blade_session_t *bs, blade_session_state_condition_t condition, void *data);
|
||||||
|
|
||||||
int main(int argc, char **argv)
|
int main(int argc, char **argv)
|
||||||
{
|
{
|
||||||
blade_handle_t *bh = NULL;
|
blade_handle_t *bh = NULL;
|
||||||
const char *nodeid;
|
config_t config;
|
||||||
|
config_setting_t *config_blade = NULL;
|
||||||
ks_assert(argc >= 2);
|
blade_module_t *mod_wss = NULL;
|
||||||
|
//blade_identity_t *id = NULL;
|
||||||
nodeid = argv[1];
|
const char *cfgpath = "bladec.cfg";
|
||||||
|
const char *session_state_callback_id = NULL;
|
||||||
|
|
||||||
ks_global_set_default_logger(KS_LOG_LEVEL_DEBUG);
|
ks_global_set_default_logger(KS_LOG_LEVEL_DEBUG);
|
||||||
|
|
||||||
blade_init();
|
blade_init();
|
||||||
|
|
||||||
blade_handle_create(&bh, NULL, NULL, nodeid);
|
blade_handle_create(&bh, NULL, NULL);
|
||||||
|
|
||||||
blade_handle_autoroute(bh, KS_TRUE, KS_DHT_DEFAULT_PORT);
|
if (argc > 1) cfgpath = argv[1];
|
||||||
|
|
||||||
|
config_init(&config);
|
||||||
|
if (!config_read_file(&config, cfgpath)) {
|
||||||
|
ks_log(KS_LOG_ERROR, "%s:%d - %s\n", config_error_file(&config), config_error_line(&config), config_error_text(&config));
|
||||||
|
config_destroy(&config);
|
||||||
|
return EXIT_FAILURE;
|
||||||
|
}
|
||||||
|
config_blade = config_lookup(&config, "blade");
|
||||||
|
if (!config_blade) {
|
||||||
|
ks_log(KS_LOG_ERROR, "Missing 'blade' config group\n");
|
||||||
|
config_destroy(&config);
|
||||||
|
return EXIT_FAILURE;
|
||||||
|
}
|
||||||
|
if (config_setting_type(config_blade) != CONFIG_TYPE_GROUP) {
|
||||||
|
ks_log(KS_LOG_ERROR, "The 'blade' config setting is not a group\n");
|
||||||
|
return EXIT_FAILURE;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (blade_handle_startup(bh, config_blade) != KS_STATUS_SUCCESS) {
|
||||||
|
ks_log(KS_LOG_ERROR, "Blade startup failed\n");
|
||||||
|
return EXIT_FAILURE;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (blade_module_wss_on_load(&mod_wss, bh) != KS_STATUS_SUCCESS) {
|
||||||
|
ks_log(KS_LOG_ERROR, "Blade WSS module load failed\n");
|
||||||
|
return EXIT_FAILURE;
|
||||||
|
}
|
||||||
|
if (blade_module_wss_on_startup(mod_wss, config_blade) != KS_STATUS_SUCCESS) {
|
||||||
|
ks_log(KS_LOG_ERROR, "Blade WSS module startup failed\n");
|
||||||
|
return EXIT_FAILURE;
|
||||||
|
}
|
||||||
|
|
||||||
|
blade_handle_event_register(bh, "blade.chat.message", on_blade_chat_message_event);
|
||||||
|
blade_handle_session_state_callback_register(bh, NULL, on_blade_session_state_callback, &session_state_callback_id);
|
||||||
|
|
||||||
loop(bh);
|
loop(bh);
|
||||||
|
|
||||||
|
blade_handle_session_state_callback_unregister(bh, session_state_callback_id);
|
||||||
|
|
||||||
|
blade_module_wss_on_shutdown(mod_wss);
|
||||||
|
|
||||||
|
blade_module_wss_on_unload(mod_wss);
|
||||||
|
|
||||||
blade_handle_destroy(&bh);
|
blade_handle_destroy(&bh);
|
||||||
|
|
||||||
blade_shutdown();
|
blade_shutdown();
|
||||||
@ -71,6 +109,38 @@ int main(int argc, char **argv)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ks_bool_t on_blade_chat_message_event(blade_event_t *bev)
|
||||||
|
{
|
||||||
|
cJSON *res = NULL;
|
||||||
|
const char *from = NULL;
|
||||||
|
const char *message = NULL;
|
||||||
|
|
||||||
|
ks_assert(bev);
|
||||||
|
|
||||||
|
res = cJSON_GetObjectItem(bev->message, "result");
|
||||||
|
from = cJSON_GetObjectCstr(res, "from");
|
||||||
|
message = cJSON_GetObjectCstr(res, "message");
|
||||||
|
|
||||||
|
ks_log(KS_LOG_DEBUG, "Received Chat Message Event: (%s) %s\n", from, message);
|
||||||
|
|
||||||
|
return KS_FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
void on_blade_session_state_callback(blade_session_t *bs, blade_session_state_condition_t condition, void *data)
|
||||||
|
{
|
||||||
|
blade_session_state_t state = blade_session_state_get(bs);
|
||||||
|
|
||||||
|
if (condition == BLADE_SESSION_STATE_CONDITION_PRE) {
|
||||||
|
ks_log(KS_LOG_DEBUG, "Blade Session State Changed: %s, %d\n", blade_session_id_get(bs), state);
|
||||||
|
if (state == BLADE_SESSION_STATE_READY) {
|
||||||
|
cJSON *req = NULL;
|
||||||
|
blade_rpc_request_create(blade_session_pool_get(bs), &req, NULL, NULL, "blade.chat.join");
|
||||||
|
blade_session_send(bs, req, on_blade_chat_join_response);
|
||||||
|
cJSON_Delete(req);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void buffer_console_input(void)
|
void buffer_console_input(void)
|
||||||
{
|
{
|
||||||
ssize_t bytes = 0;
|
ssize_t bytes = 0;
|
||||||
@ -121,14 +191,13 @@ void loop(blade_handle_t *bh)
|
|||||||
// @todo lines must not exceed 512 bytes, treat as error and ignore buffer until next new line?
|
// @todo lines must not exceed 512 bytes, treat as error and ignore buffer until next new line?
|
||||||
ks_assert(0);
|
ks_assert(0);
|
||||||
}
|
}
|
||||||
blade_handle_pulse(bh, 1);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void parse_argument(char **input, char **arg, char terminator)
|
void parse_argument(char **input, char **arg, char terminator)
|
||||||
{
|
{
|
||||||
char *tmp;
|
char *tmp;
|
||||||
|
|
||||||
ks_assert(input);
|
ks_assert(input);
|
||||||
ks_assert(*input);
|
ks_assert(*input);
|
||||||
ks_assert(arg);
|
ks_assert(arg);
|
||||||
@ -149,11 +218,11 @@ void process_console_input(blade_handle_t *bh, char *line)
|
|||||||
char *args = line;
|
char *args = line;
|
||||||
char *cmd = NULL;
|
char *cmd = NULL;
|
||||||
ks_bool_t found = KS_FALSE;
|
ks_bool_t found = KS_FALSE;
|
||||||
|
|
||||||
ks_log(KS_LOG_DEBUG, "Output: %s\n", line);
|
ks_log(KS_LOG_DEBUG, "Output: %s\n", line);
|
||||||
|
|
||||||
parse_argument(&args, &cmd, ' ');
|
parse_argument(&args, &cmd, ' ');
|
||||||
|
|
||||||
ks_log(KS_LOG_DEBUG, "Command: %s, Args: %s\n", cmd, args);
|
ks_log(KS_LOG_DEBUG, "Command: %s, Args: %s\n", cmd, args);
|
||||||
|
|
||||||
for (int32_t index = 0; command_defs[index].cmd; ++index) {
|
for (int32_t index = 0; command_defs[index].cmd; ++index) {
|
||||||
@ -165,78 +234,78 @@ void process_console_input(blade_handle_t *bh, char *line)
|
|||||||
if (!found) ks_log(KS_LOG_INFO, "Command '%s' unknown.\n", cmd);
|
if (!found) ks_log(KS_LOG_INFO, "Command '%s' unknown.\n", cmd);
|
||||||
}
|
}
|
||||||
|
|
||||||
void command_test(blade_handle_t *bh, char *args)
|
|
||||||
{
|
|
||||||
ks_log(KS_LOG_DEBUG, "Hello World!\n");
|
|
||||||
}
|
|
||||||
|
|
||||||
void command_quit(blade_handle_t *bh, char *args)
|
void command_quit(blade_handle_t *bh, char *args)
|
||||||
{
|
{
|
||||||
ks_assert(bh);
|
ks_assert(bh);
|
||||||
ks_assert(args);
|
ks_assert(args);
|
||||||
|
|
||||||
ks_log(KS_LOG_DEBUG, "Shutting down\n");
|
ks_log(KS_LOG_DEBUG, "Shutting down\n");
|
||||||
g_shutdown = KS_TRUE;
|
g_shutdown = KS_TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
void command_myid(blade_handle_t *bh, char *args)
|
void command_connect(blade_handle_t *bh, char *args)
|
||||||
{
|
{
|
||||||
char buf[KS_DHT_NODEID_SIZE * 2 + 1];
|
blade_connection_t *bc = NULL;
|
||||||
|
blade_identity_t *target = NULL;
|
||||||
|
|
||||||
ks_assert(bh);
|
ks_assert(bh);
|
||||||
ks_assert(args);
|
ks_assert(args);
|
||||||
|
|
||||||
blade_handle_myid(bh, buf);
|
blade_identity_create(&target, blade_handle_pool_get(bh));
|
||||||
|
|
||||||
ks_log(KS_LOG_INFO, "%s\n", buf);
|
if (blade_identity_parse(target, args) == KS_STATUS_SUCCESS) blade_handle_connect(bh, &bc, target, NULL);
|
||||||
|
|
||||||
|
blade_identity_destroy(&target);
|
||||||
}
|
}
|
||||||
|
|
||||||
void command_bind(blade_handle_t *bh, char *args)
|
ks_bool_t on_blade_chat_join_response(blade_response_t *bres) // @todo this should get userdata passed in from when the callback is registered
|
||||||
{
|
{
|
||||||
char *ip = NULL;
|
ks_log(KS_LOG_DEBUG, "Received Chat Join Response!\n");
|
||||||
char *port = NULL;
|
return KS_FALSE;
|
||||||
ks_port_t p;
|
}
|
||||||
|
|
||||||
|
ks_bool_t on_blade_chat_send_response(blade_response_t *bres) // @todo this should get userdata passed in from when the callback is registered
|
||||||
|
{
|
||||||
|
ks_log(KS_LOG_DEBUG, "Received Chat Send Response!\n");
|
||||||
|
return KS_FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
void command_chat(blade_handle_t *bh, char *args)
|
||||||
|
{
|
||||||
|
char *cmd = NULL;
|
||||||
|
|
||||||
|
ks_assert(bh);
|
||||||
ks_assert(args);
|
ks_assert(args);
|
||||||
|
|
||||||
parse_argument(&args, &ip, ' ');
|
parse_argument(&args, &cmd, ' ');
|
||||||
parse_argument(&args, &port, ' ');
|
ks_log(KS_LOG_DEBUG, "Chat Command: %s, Args: %s\n", cmd, args);
|
||||||
|
|
||||||
p = atoi(port); // @todo use strtol for error handling
|
if (!strcmp(cmd, "leave")) {
|
||||||
|
} else if (!strcmp(cmd, "send")) {
|
||||||
|
char *sid = NULL;
|
||||||
|
blade_session_t *bs = NULL;
|
||||||
|
cJSON *req = NULL;
|
||||||
|
cJSON *params = NULL;
|
||||||
|
|
||||||
blade_handle_bind(bh, ip, p, NULL);
|
parse_argument(&args, &sid, ' ');
|
||||||
}
|
|
||||||
|
bs = blade_handle_sessions_get(bh, sid);
|
||||||
void command_store(blade_handle_t *bh, char *args)
|
if (!bs) {
|
||||||
{
|
ks_log(KS_LOG_DEBUG, "Unknown Session: %s\n", sid);
|
||||||
char *key;
|
return;
|
||||||
char *data;
|
}
|
||||||
|
blade_rpc_request_create(blade_handle_pool_get(bh), &req, ¶ms, NULL, "blade.chat.send");
|
||||||
ks_assert(args);
|
ks_assert(req);
|
||||||
|
ks_assert(params);
|
||||||
blade_handle_datastore_start(bh);
|
|
||||||
|
cJSON_AddStringToObject(params, "message", args);
|
||||||
parse_argument(&args, &key, ' ');
|
|
||||||
parse_argument(&args, &data, ' ');
|
blade_session_send(bs, req, on_blade_chat_send_response);
|
||||||
|
|
||||||
blade_handle_datastore_store(bh, key, strlen(key), data, strlen(data) + 1);
|
blade_session_read_unlock(bs);
|
||||||
}
|
|
||||||
|
cJSON_Delete(req);
|
||||||
ks_bool_t blade_datastore_fetch_callback(blade_datastore_t *bds, const void *data, uint32_t data_length, void *userdata)
|
} else {
|
||||||
{
|
ks_log(KS_LOG_DEBUG, "Unknown Chat Command: %s\n", cmd);
|
||||||
ks_log(KS_LOG_INFO, "%s\n", data);
|
}
|
||||||
return KS_TRUE;
|
|
||||||
}
|
|
||||||
|
|
||||||
void command_fetch(blade_handle_t *bh, char *args)
|
|
||||||
{
|
|
||||||
char *key;
|
|
||||||
|
|
||||||
ks_assert(args);
|
|
||||||
|
|
||||||
blade_handle_datastore_start(bh);
|
|
||||||
|
|
||||||
parse_argument(&args, &key, ' ');
|
|
||||||
|
|
||||||
blade_handle_datastore_fetch(bh, blade_datastore_fetch_callback, key, strlen(key), bh);
|
|
||||||
}
|
}
|
||||||
|
11
libs/libblade/test/bladec.cfg
Normal file
11
libs/libblade/test/bladec.cfg
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
blade:
|
||||||
|
{
|
||||||
|
identity = "peer@domain";
|
||||||
|
datastore:
|
||||||
|
{
|
||||||
|
database:
|
||||||
|
{
|
||||||
|
path = ":mem:";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
207
libs/libblade/test/blades.c
Normal file
207
libs/libblade/test/blades.c
Normal file
@ -0,0 +1,207 @@
|
|||||||
|
#include "blade.h"
|
||||||
|
#include "tap.h"
|
||||||
|
|
||||||
|
#ifdef _WIN32
|
||||||
|
#define STDIO_FD(_fs) _fileno(_fs)
|
||||||
|
#define READ(_fd, _buffer, _count) _read(_fd, _buffer, _count)
|
||||||
|
#else
|
||||||
|
#define STDIO_FD(_fs) fileno(_fs)
|
||||||
|
#define READ(_fd, _buffer, _count) read(_fd, _buffer, _count)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define CONSOLE_INPUT_MAX 512
|
||||||
|
|
||||||
|
ks_bool_t g_shutdown = KS_FALSE;
|
||||||
|
char g_console_input[CONSOLE_INPUT_MAX];
|
||||||
|
size_t g_console_input_length = 0;
|
||||||
|
size_t g_console_input_eol = 0;
|
||||||
|
|
||||||
|
void loop(blade_handle_t *bh);
|
||||||
|
void process_console_input(blade_handle_t *bh, char *line);
|
||||||
|
|
||||||
|
typedef void (*command_callback)(blade_handle_t *bh, char *args);
|
||||||
|
|
||||||
|
struct command_def_s {
|
||||||
|
const char *cmd;
|
||||||
|
command_callback callback;
|
||||||
|
};
|
||||||
|
|
||||||
|
void command_quit(blade_handle_t *bh, char *args);
|
||||||
|
|
||||||
|
static const struct command_def_s command_defs[] = {
|
||||||
|
{ "quit", command_quit },
|
||||||
|
|
||||||
|
{ NULL, NULL }
|
||||||
|
};
|
||||||
|
|
||||||
|
int main(int argc, char **argv)
|
||||||
|
{
|
||||||
|
blade_handle_t *bh = NULL;
|
||||||
|
config_t config;
|
||||||
|
config_setting_t *config_blade = NULL;
|
||||||
|
blade_module_t *mod_wss = NULL;
|
||||||
|
blade_module_t *mod_chat = NULL;
|
||||||
|
//blade_identity_t *id = NULL;
|
||||||
|
const char *cfgpath = "blades.cfg";
|
||||||
|
|
||||||
|
ks_global_set_default_logger(KS_LOG_LEVEL_DEBUG);
|
||||||
|
|
||||||
|
blade_init();
|
||||||
|
|
||||||
|
blade_handle_create(&bh, NULL, NULL);
|
||||||
|
|
||||||
|
if (argc > 1) cfgpath = argv[1];
|
||||||
|
|
||||||
|
config_init(&config);
|
||||||
|
if (!config_read_file(&config, cfgpath)) {
|
||||||
|
ks_log(KS_LOG_ERROR, "%s:%d - %s\n", config_error_file(&config), config_error_line(&config), config_error_text(&config));
|
||||||
|
config_destroy(&config);
|
||||||
|
return EXIT_FAILURE;
|
||||||
|
}
|
||||||
|
config_blade = config_lookup(&config, "blade");
|
||||||
|
if (!config_blade) {
|
||||||
|
ks_log(KS_LOG_ERROR, "Missing 'blade' config group\n");
|
||||||
|
config_destroy(&config);
|
||||||
|
return EXIT_FAILURE;
|
||||||
|
}
|
||||||
|
if (config_setting_type(config_blade) != CONFIG_TYPE_GROUP) {
|
||||||
|
ks_log(KS_LOG_ERROR, "The 'blade' config setting is not a group\n");
|
||||||
|
return EXIT_FAILURE;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (blade_handle_startup(bh, config_blade) != KS_STATUS_SUCCESS) {
|
||||||
|
ks_log(KS_LOG_ERROR, "Blade startup failed\n");
|
||||||
|
return EXIT_FAILURE;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (blade_module_wss_on_load(&mod_wss, bh) != KS_STATUS_SUCCESS) {
|
||||||
|
ks_log(KS_LOG_ERROR, "Blade WSS module load failed\n");
|
||||||
|
return EXIT_FAILURE;
|
||||||
|
}
|
||||||
|
if (blade_module_wss_on_startup(mod_wss, config_blade) != KS_STATUS_SUCCESS) {
|
||||||
|
ks_log(KS_LOG_ERROR, "Blade WSS module startup failed\n");
|
||||||
|
return EXIT_FAILURE;
|
||||||
|
}
|
||||||
|
|
||||||
|
blade_module_chat_on_load(&mod_chat, bh);
|
||||||
|
blade_module_chat_on_startup(mod_chat, config_blade);
|
||||||
|
|
||||||
|
loop(bh);
|
||||||
|
|
||||||
|
blade_module_chat_on_shutdown(mod_chat);
|
||||||
|
blade_module_chat_on_unload(mod_chat);
|
||||||
|
|
||||||
|
blade_module_wss_on_shutdown(mod_wss);
|
||||||
|
|
||||||
|
blade_module_wss_on_unload(mod_wss);
|
||||||
|
|
||||||
|
blade_handle_destroy(&bh);
|
||||||
|
|
||||||
|
blade_shutdown();
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
void buffer_console_input(void)
|
||||||
|
{
|
||||||
|
ssize_t bytes = 0;
|
||||||
|
struct pollfd poll[1];
|
||||||
|
poll[0].fd = STDIO_FD(stdin);
|
||||||
|
poll[0].events = POLLIN | POLLERR;
|
||||||
|
|
||||||
|
if (ks_poll(poll, 1, 1) > 0) {
|
||||||
|
if (poll[0].revents & POLLIN) {
|
||||||
|
if ((bytes = READ(poll[0].fd, g_console_input + g_console_input_length, CONSOLE_INPUT_MAX - g_console_input_length)) <= 0) {
|
||||||
|
// @todo error
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
g_console_input_length += bytes;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void loop(blade_handle_t *bh)
|
||||||
|
{
|
||||||
|
while (!g_shutdown) {
|
||||||
|
ks_bool_t eol = KS_FALSE;
|
||||||
|
buffer_console_input();
|
||||||
|
|
||||||
|
for (; g_console_input_eol < g_console_input_length; ++g_console_input_eol) {
|
||||||
|
char c = g_console_input[g_console_input_eol];
|
||||||
|
if (c == '\r' || c == '\n') {
|
||||||
|
eol = KS_TRUE;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (eol) {
|
||||||
|
g_console_input[g_console_input_eol] = '\0';
|
||||||
|
process_console_input(bh, g_console_input);
|
||||||
|
g_console_input_eol++;
|
||||||
|
for (; g_console_input_eol < g_console_input_length; ++g_console_input_eol) {
|
||||||
|
char c = g_console_input[g_console_input_eol];
|
||||||
|
if (c != '\r' && c != '\n') break;
|
||||||
|
}
|
||||||
|
if (g_console_input_eol == g_console_input_length) g_console_input_eol = g_console_input_length = 0;
|
||||||
|
else {
|
||||||
|
memcpy(g_console_input, g_console_input + g_console_input_eol, g_console_input_length - g_console_input_eol);
|
||||||
|
g_console_input_length -= g_console_input_eol;
|
||||||
|
g_console_input_eol = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (g_console_input_length == CONSOLE_INPUT_MAX) {
|
||||||
|
// @todo lines must not exceed 512 bytes, treat as error and ignore buffer until next new line?
|
||||||
|
ks_assert(0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void parse_argument(char **input, char **arg, char terminator)
|
||||||
|
{
|
||||||
|
char *tmp;
|
||||||
|
|
||||||
|
ks_assert(input);
|
||||||
|
ks_assert(*input);
|
||||||
|
ks_assert(arg);
|
||||||
|
|
||||||
|
tmp = *input;
|
||||||
|
*arg = tmp;
|
||||||
|
|
||||||
|
while (*tmp && *tmp != terminator) ++tmp;
|
||||||
|
if (*tmp == terminator) {
|
||||||
|
*tmp = '\0';
|
||||||
|
++tmp;
|
||||||
|
}
|
||||||
|
*input = tmp;
|
||||||
|
}
|
||||||
|
|
||||||
|
void process_console_input(blade_handle_t *bh, char *line)
|
||||||
|
{
|
||||||
|
char *args = line;
|
||||||
|
char *cmd = NULL;
|
||||||
|
ks_bool_t found = KS_FALSE;
|
||||||
|
|
||||||
|
ks_log(KS_LOG_DEBUG, "Output: %s\n", line);
|
||||||
|
|
||||||
|
parse_argument(&args, &cmd, ' ');
|
||||||
|
|
||||||
|
ks_log(KS_LOG_DEBUG, "Command: %s, Args: %s\n", cmd, args);
|
||||||
|
|
||||||
|
for (int32_t index = 0; command_defs[index].cmd; ++index) {
|
||||||
|
if (!strcmp(command_defs[index].cmd, cmd)) {
|
||||||
|
found = KS_TRUE;
|
||||||
|
command_defs[index].callback(bh, args);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!found) ks_log(KS_LOG_INFO, "Command '%s' unknown.\n", cmd);
|
||||||
|
}
|
||||||
|
|
||||||
|
void command_quit(blade_handle_t *bh, char *args)
|
||||||
|
{
|
||||||
|
ks_assert(bh);
|
||||||
|
ks_assert(args);
|
||||||
|
|
||||||
|
ks_log(KS_LOG_DEBUG, "Shutting down\n");
|
||||||
|
g_shutdown = KS_TRUE;
|
||||||
|
}
|
28
libs/libblade/test/blades.cfg
Normal file
28
libs/libblade/test/blades.cfg
Normal file
@ -0,0 +1,28 @@
|
|||||||
|
blade:
|
||||||
|
{
|
||||||
|
identity = "service@domain";
|
||||||
|
directory:
|
||||||
|
{
|
||||||
|
};
|
||||||
|
datastore:
|
||||||
|
{
|
||||||
|
database:
|
||||||
|
{
|
||||||
|
path = ":mem:";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
wss:
|
||||||
|
{
|
||||||
|
endpoints:
|
||||||
|
{
|
||||||
|
ipv4 = ( { address = "0.0.0.0", port = 2100 } );
|
||||||
|
ipv6 = ( { address = "::", port = 2100 } );
|
||||||
|
backlog = 128;
|
||||||
|
};
|
||||||
|
# SSL group is optional, disabled when absent
|
||||||
|
ssl:
|
||||||
|
{
|
||||||
|
# todo: server SSL stuffs here
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
@ -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.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_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_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
|
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_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/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.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_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 += 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
|
#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
|
libks_la_SOURCES += src/ks_acl.c
|
||||||
|
|
||||||
@ -30,12 +30,9 @@ library_include_HEADERS += src/include/ks_thread_pool.h src/include/ks_cJSON.h s
|
|||||||
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_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_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_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_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
|
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
|
tests: libks.la
|
||||||
$(MAKE) -C test tests
|
$(MAKE) -C test tests
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@ -1,23 +1,23 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2007-2014, Anthony Minessale II
|
* Copyright (c) 2007-2014, Anthony Minessale II
|
||||||
* All rights reserved.
|
* All rights reserved.
|
||||||
*
|
*
|
||||||
* Redistribution and use in source and binary forms, with or without
|
* Redistribution and use in source and binary forms, with or without
|
||||||
* modification, are permitted provided that the following conditions
|
* modification, are permitted provided that the following conditions
|
||||||
* are met:
|
* are met:
|
||||||
*
|
*
|
||||||
* * Redistributions of source code must retain the above copyright
|
* * Redistributions of source code must retain the above copyright
|
||||||
* notice, this list of conditions and the following disclaimer.
|
* notice, this list of conditions and the following disclaimer.
|
||||||
*
|
*
|
||||||
* * Redistributions in binary form must reproduce the above copyright
|
* * Redistributions in binary form must reproduce the above copyright
|
||||||
* notice, this list of conditions and the following disclaimer in the
|
* notice, this list of conditions and the following disclaimer in the
|
||||||
* documentation and/or other materials provided with the distribution.
|
* documentation and/or other materials provided with the distribution.
|
||||||
*
|
*
|
||||||
* * Neither the name of the original author; nor the names of any contributors
|
* * 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
|
* may be used to endorse or promote products derived from this software
|
||||||
* without specific prior written permission.
|
* without specific prior written permission.
|
||||||
*
|
*
|
||||||
*
|
*
|
||||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||||
@ -90,6 +90,8 @@ KS_DECLARE_DATA extern ks_logger_t ks_log;
|
|||||||
KS_DECLARE(void) ks_global_set_logger(ks_logger_t logger);
|
KS_DECLARE(void) ks_global_set_logger(ks_logger_t logger);
|
||||||
/*! Sets the default log level for libks */
|
/*! Sets the default log level for libks */
|
||||||
KS_DECLARE(void) ks_global_set_default_logger(int level);
|
KS_DECLARE(void) ks_global_set_default_logger(int level);
|
||||||
|
/*! Sets the default log prefix for libks */
|
||||||
|
KS_DECLARE(void) ks_global_set_default_logger_prefix(ks_log_prefix_t prefix);
|
||||||
|
|
||||||
KS_DECLARE(size_t) ks_url_encode(const char *url, char *buf, size_t len);
|
KS_DECLARE(size_t) ks_url_encode(const char *url, char *buf, size_t len);
|
||||||
KS_DECLARE(char *) ks_url_decode(char *s);
|
KS_DECLARE(char *) ks_url_decode(char *s);
|
||||||
@ -137,6 +139,7 @@ KS_DECLARE(void) ks_random_string(char *buf, uint16_t len, char *set);
|
|||||||
#include "ks_bencode.h"
|
#include "ks_bencode.h"
|
||||||
#include "ks_rng.h"
|
#include "ks_rng.h"
|
||||||
#include "ks_acl.h"
|
#include "ks_acl.h"
|
||||||
|
#include "ks_base64.h"
|
||||||
|
|
||||||
KS_END_EXTERN_C
|
KS_END_EXTERN_C
|
||||||
|
|
||||||
|
@ -1,23 +1,23 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2007-2014, Anthony Minessale II
|
* Copyright (c) 2017 FreeSWITCH Solutions LLC
|
||||||
* All rights reserved.
|
* All rights reserved.
|
||||||
*
|
*
|
||||||
* Redistribution and use in source and binary forms, with or without
|
* Redistribution and use in source and binary forms, with or without
|
||||||
* modification, are permitted provided that the following conditions
|
* modification, are permitted provided that the following conditions
|
||||||
* are met:
|
* are met:
|
||||||
*
|
*
|
||||||
* * Redistributions of source code must retain the above copyright
|
* * Redistributions of source code must retain the above copyright
|
||||||
* notice, this list of conditions and the following disclaimer.
|
* notice, this list of conditions and the following disclaimer.
|
||||||
*
|
*
|
||||||
* * Redistributions in binary form must reproduce the above copyright
|
* * Redistributions in binary form must reproduce the above copyright
|
||||||
* notice, this list of conditions and the following disclaimer in the
|
* notice, this list of conditions and the following disclaimer in the
|
||||||
* documentation and/or other materials provided with the distribution.
|
* documentation and/or other materials provided with the distribution.
|
||||||
*
|
*
|
||||||
* * Neither the name of the original author; nor the names of any contributors
|
* * 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
|
* may be used to endorse or promote products derived from this software
|
||||||
* without specific prior written permission.
|
* without specific prior written permission.
|
||||||
*
|
*
|
||||||
*
|
*
|
||||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||||
@ -31,13 +31,14 @@
|
|||||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef _BPCP_H_
|
|
||||||
#define _BPCP_H_
|
|
||||||
#include <blade.h>
|
|
||||||
|
|
||||||
KS_BEGIN_EXTERN_C
|
#ifndef _KS_BASE64_H__
|
||||||
|
#define _KS_BASE64_H__
|
||||||
|
|
||||||
KS_END_EXTERN_C
|
#include <ks.h>
|
||||||
|
|
||||||
|
KS_DECLARE(ks_status_t) ks_b64_encode(unsigned char *in, ks_size_t ilen, unsigned char *out, ks_size_t olen);
|
||||||
|
KS_DECLARE(ks_size_t) ks_b64_decode(char *in, char *out, ks_size_t olen);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
@ -1,23 +1,23 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2007-2015, Anthony Minessale II
|
* Copyright (c) 2007-2015, Anthony Minessale II
|
||||||
* All rights reserved.
|
* All rights reserved.
|
||||||
*
|
*
|
||||||
* Redistribution and use in source and binary forms, with or without
|
* Redistribution and use in source and binary forms, with or without
|
||||||
* modification, are permitted provided that the following conditions
|
* modification, are permitted provided that the following conditions
|
||||||
* are met:
|
* are met:
|
||||||
*
|
*
|
||||||
* * Redistributions of source code must retain the above copyright
|
* * Redistributions of source code must retain the above copyright
|
||||||
* notice, this list of conditions and the following disclaimer.
|
* notice, this list of conditions and the following disclaimer.
|
||||||
*
|
*
|
||||||
* * Redistributions in binary form must reproduce the above copyright
|
* * Redistributions in binary form must reproduce the above copyright
|
||||||
* notice, this list of conditions and the following disclaimer in the
|
* notice, this list of conditions and the following disclaimer in the
|
||||||
* documentation and/or other materials provided with the distribution.
|
* documentation and/or other materials provided with the distribution.
|
||||||
*
|
*
|
||||||
* * Neither the name of the original author; nor the names of any contributors
|
* * 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
|
* may be used to endorse or promote products derived from this software
|
||||||
* without specific prior written permission.
|
* without specific prior written permission.
|
||||||
*
|
*
|
||||||
*
|
*
|
||||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||||
@ -103,9 +103,10 @@ KS_BEGIN_EXTERN_C
|
|||||||
#include <sys/socket.h>
|
#include <sys/socket.h>
|
||||||
#include <netinet/in.h>
|
#include <netinet/in.h>
|
||||||
#include <netdb.h>
|
#include <netdb.h>
|
||||||
#include <arpa/inet.h>
|
#include <arpa/inet.h>
|
||||||
|
#include <sys/syscall.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef _MSC_VER
|
#ifdef _MSC_VER
|
||||||
#pragma comment(lib, "Ws2_32.lib")
|
#pragma comment(lib, "Ws2_32.lib")
|
||||||
|
|
||||||
|
@ -45,6 +45,14 @@ KS_BEGIN_EXTERN_C
|
|||||||
#endif
|
#endif
|
||||||
ks_thread_os_handle_t;
|
ks_thread_os_handle_t;
|
||||||
|
|
||||||
|
typedef
|
||||||
|
#ifdef WIN32
|
||||||
|
DWORD
|
||||||
|
#else
|
||||||
|
pid_t
|
||||||
|
#endif
|
||||||
|
ks_pid_t;
|
||||||
|
|
||||||
struct ks_thread {
|
struct ks_thread {
|
||||||
ks_pool_t *pool;
|
ks_pool_t *pool;
|
||||||
#ifdef WIN32
|
#ifdef WIN32
|
||||||
@ -76,6 +84,7 @@ struct ks_thread {
|
|||||||
|
|
||||||
KS_DECLARE(int) ks_thread_set_priority(int nice_val);
|
KS_DECLARE(int) ks_thread_set_priority(int nice_val);
|
||||||
KS_DECLARE(ks_thread_os_handle_t) ks_thread_self(void);
|
KS_DECLARE(ks_thread_os_handle_t) ks_thread_self(void);
|
||||||
|
KS_DECLARE(ks_pid_t) ks_thread_self_id(void);
|
||||||
KS_DECLARE(ks_thread_os_handle_t) ks_thread_os_handle(ks_thread_t *thread);
|
KS_DECLARE(ks_thread_os_handle_t) ks_thread_os_handle(ks_thread_t *thread);
|
||||||
KS_DECLARE(ks_status_t) ks_thread_create_ex(ks_thread_t **thread, ks_thread_function_t func, void *data,
|
KS_DECLARE(ks_status_t) ks_thread_create_ex(ks_thread_t **thread, ks_thread_function_t func, void *data,
|
||||||
uint32_t flags, size_t stack_size, ks_thread_priority_t priority, ks_pool_t *pool);
|
uint32_t flags, size_t stack_size, ks_thread_priority_t priority, ks_pool_t *pool);
|
||||||
|
@ -1,23 +1,23 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2007-2015, Anthony Minessale II
|
* Copyright (c) 2007-2015, Anthony Minessale II
|
||||||
* All rights reserved.
|
* All rights reserved.
|
||||||
*
|
*
|
||||||
* Redistribution and use in source and binary forms, with or without
|
* Redistribution and use in source and binary forms, with or without
|
||||||
* modification, are permitted provided that the following conditions
|
* modification, are permitted provided that the following conditions
|
||||||
* are met:
|
* are met:
|
||||||
*
|
*
|
||||||
* * Redistributions of source code must retain the above copyright
|
* * Redistributions of source code must retain the above copyright
|
||||||
* notice, this list of conditions and the following disclaimer.
|
* notice, this list of conditions and the following disclaimer.
|
||||||
*
|
*
|
||||||
* * Redistributions in binary form must reproduce the above copyright
|
* * Redistributions in binary form must reproduce the above copyright
|
||||||
* notice, this list of conditions and the following disclaimer in the
|
* notice, this list of conditions and the following disclaimer in the
|
||||||
* documentation and/or other materials provided with the distribution.
|
* documentation and/or other materials provided with the distribution.
|
||||||
*
|
*
|
||||||
* * Neither the name of the original author; nor the names of any contributors
|
* * 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
|
* may be used to endorse or promote products derived from this software
|
||||||
* without specific prior written permission.
|
* without specific prior written permission.
|
||||||
*
|
*
|
||||||
*
|
*
|
||||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||||
@ -38,7 +38,7 @@
|
|||||||
|
|
||||||
KS_BEGIN_EXTERN_C
|
KS_BEGIN_EXTERN_C
|
||||||
|
|
||||||
#define KS_STR2ENUM_P(_FUNC1, _FUNC2, _TYPE) KS_DECLARE(_TYPE) _FUNC1 (const char *name); KS_DECLARE(const char *) _FUNC2 (_TYPE type);
|
#define KS_STR2ENUM_P(_FUNC1, _FUNC2, _TYPE) KS_DECLARE(_TYPE) _FUNC1 (const char *name); KS_DECLARE(const char *) _FUNC2 (_TYPE type);
|
||||||
|
|
||||||
#define KS_STR2ENUM(_FUNC1, _FUNC2, _TYPE, _STRINGS, _MAX) \
|
#define KS_STR2ENUM(_FUNC1, _FUNC2, _TYPE, _STRINGS, _MAX) \
|
||||||
KS_DECLARE(_TYPE) _FUNC1 (const char *name) \
|
KS_DECLARE(_TYPE) _FUNC1 (const char *name) \
|
||||||
@ -63,7 +63,7 @@ KS_BEGIN_EXTERN_C
|
|||||||
return _STRINGS[(int)type]; \
|
return _STRINGS[(int)type]; \
|
||||||
} \
|
} \
|
||||||
|
|
||||||
#define KS_ENUM_NAMES(_NAME, _STRINGS) static const char * _NAME [] = { _STRINGS , NULL };
|
#define KS_ENUM_NAMES(_NAME, _STRINGS) static const char * _NAME [] = { _STRINGS , NULL };
|
||||||
|
|
||||||
#define KS_VA_NONE "%s", ""
|
#define KS_VA_NONE "%s", ""
|
||||||
|
|
||||||
@ -142,7 +142,7 @@ KS_BEGIN_EXTERN_C
|
|||||||
/* insert new entries before this */\
|
/* insert new entries before this */\
|
||||||
"COUNT"
|
"COUNT"
|
||||||
|
|
||||||
KS_STR2ENUM_P(ks_str2ks_status, ks_status2str, ks_status_t)
|
KS_STR2ENUM_P(ks_str2ks_status, ks_status2str, ks_status_t)
|
||||||
|
|
||||||
/*! \brief Used internally for truth test */
|
/*! \brief Used internally for truth test */
|
||||||
typedef enum {
|
typedef enum {
|
||||||
@ -173,6 +173,19 @@ KS_BEGIN_EXTERN_C
|
|||||||
#define KS_LOG_ALERT KS_PRE, KS_LOG_LEVEL_ALERT
|
#define KS_LOG_ALERT KS_PRE, KS_LOG_LEVEL_ALERT
|
||||||
#define KS_LOG_EMERG KS_PRE, KS_LOG_LEVEL_EMERG
|
#define KS_LOG_EMERG KS_PRE, KS_LOG_LEVEL_EMERG
|
||||||
|
|
||||||
|
typedef enum {
|
||||||
|
KS_LOG_PREFIX_NONE = 0,
|
||||||
|
|
||||||
|
KS_LOG_PREFIX_LEVEL = 1 << 0,
|
||||||
|
KS_LOG_PREFIX_FILE = 1 << 1,
|
||||||
|
KS_LOG_PREFIX_LINE = 1 << 2,
|
||||||
|
KS_LOG_PREFIX_FUNC = 1 << 3,
|
||||||
|
KS_LOG_PREFIX_THREAD = 1 << 4,
|
||||||
|
KS_LOG_PREFIX_TIME = 1 << 5,
|
||||||
|
|
||||||
|
KS_LOG_PREFIX_ALL = KS_LOG_PREFIX_LEVEL | KS_LOG_PREFIX_FILE | KS_LOG_PREFIX_LINE | KS_LOG_PREFIX_FUNC | KS_LOG_PREFIX_THREAD | KS_LOG_PREFIX_TIME,
|
||||||
|
} ks_log_prefix_t;
|
||||||
|
|
||||||
struct ks_pool_s;
|
struct ks_pool_s;
|
||||||
|
|
||||||
typedef struct ks_pool_s ks_pool_t;
|
typedef struct ks_pool_s ks_pool_t;
|
||||||
|
@ -27,6 +27,7 @@
|
|||||||
extern "C" {
|
extern "C" {
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#include <ks.h>
|
||||||
#include <inttypes.h>
|
#include <inttypes.h>
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
@ -209,7 +210,7 @@ extern "C" {
|
|||||||
* @param l must point to a user-provided memory location
|
* @param l must point to a user-provided memory location
|
||||||
* @return 0 for success. -1 for failure
|
* @return 0 for success. -1 for failure
|
||||||
*/
|
*/
|
||||||
int list_init(list_t *restrict l);
|
KS_DECLARE(int) list_init(list_t *restrict l);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* completely remove the list from memory.
|
* completely remove the list from memory.
|
||||||
@ -220,7 +221,7 @@ extern "C" {
|
|||||||
*
|
*
|
||||||
* @param l list to destroy
|
* @param l list to destroy
|
||||||
*/
|
*/
|
||||||
void list_destroy(list_t *restrict l);
|
KS_DECLARE(void) list_destroy(list_t *restrict l);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* set the comparator function for list elements.
|
* set the comparator function for list elements.
|
||||||
@ -234,7 +235,7 @@ extern "C" {
|
|||||||
*
|
*
|
||||||
* @see element_comparator()
|
* @see element_comparator()
|
||||||
*/
|
*/
|
||||||
int list_attributes_comparator(list_t *restrict l, element_comparator comparator_fun);
|
KS_DECLARE(int) list_attributes_comparator(list_t *restrict l, element_comparator comparator_fun);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* set a seeker function for list elements.
|
* set a seeker function for list elements.
|
||||||
@ -248,7 +249,7 @@ extern "C" {
|
|||||||
*
|
*
|
||||||
* @see element_seeker()
|
* @see element_seeker()
|
||||||
*/
|
*/
|
||||||
int list_attributes_seeker(list_t *restrict l, element_seeker seeker_fun);
|
KS_DECLARE(int) list_attributes_seeker(list_t *restrict l, element_seeker seeker_fun);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* require to free element data when list entry is removed (default: don't free).
|
* require to free element data when list entry is removed (default: don't free).
|
||||||
@ -280,7 +281,7 @@ extern "C" {
|
|||||||
* @see list_meter_double()
|
* @see list_meter_double()
|
||||||
* @see list_meter_string()
|
* @see list_meter_string()
|
||||||
*/
|
*/
|
||||||
int list_attributes_copy(list_t *restrict l, element_meter metric_fun, int copy_data);
|
KS_DECLARE(int) list_attributes_copy(list_t *restrict l, element_meter metric_fun, int copy_data);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* set the element hash computing function for the list elements.
|
* set the element hash computing function for the list elements.
|
||||||
@ -300,7 +301,7 @@ extern "C" {
|
|||||||
*
|
*
|
||||||
* @see element_hash_computer()
|
* @see element_hash_computer()
|
||||||
*/
|
*/
|
||||||
int list_attributes_hash_computer(list_t *restrict l, element_hash_computer hash_computer_fun);
|
KS_DECLARE(int) list_attributes_hash_computer(list_t *restrict l, element_hash_computer hash_computer_fun);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* set the element serializer function for the list elements.
|
* set the element serializer function for the list elements.
|
||||||
@ -321,7 +322,7 @@ extern "C" {
|
|||||||
* @see list_dump_filedescriptor()
|
* @see list_dump_filedescriptor()
|
||||||
* @see list_restore_filedescriptor()
|
* @see list_restore_filedescriptor()
|
||||||
*/
|
*/
|
||||||
int list_attributes_serializer(list_t *restrict l, element_serializer serializer_fun);
|
KS_DECLARE(int) list_attributes_serializer(list_t *restrict l, element_serializer serializer_fun);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* set the element unserializer function for the list elements.
|
* set the element unserializer function for the list elements.
|
||||||
@ -343,7 +344,7 @@ extern "C" {
|
|||||||
* @see list_dump_filedescriptor()
|
* @see list_dump_filedescriptor()
|
||||||
* @see list_restore_filedescriptor()
|
* @see list_restore_filedescriptor()
|
||||||
*/
|
*/
|
||||||
int list_attributes_unserializer(list_t *restrict l, element_unserializer unserializer_fun);
|
KS_DECLARE(int) list_attributes_unserializer(list_t *restrict l, element_unserializer unserializer_fun);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* append data at the end of the list.
|
* append data at the end of the list.
|
||||||
@ -355,7 +356,7 @@ extern "C" {
|
|||||||
*
|
*
|
||||||
* @return 1 for success. < 0 for failure
|
* @return 1 for success. < 0 for failure
|
||||||
*/
|
*/
|
||||||
int list_append(list_t *restrict l, const void *data);
|
KS_DECLARE(int) list_append(list_t *restrict l, const void *data);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* insert data in the head of the list.
|
* insert data in the head of the list.
|
||||||
@ -367,7 +368,7 @@ extern "C" {
|
|||||||
*
|
*
|
||||||
* @return 1 for success. < 0 for failure
|
* @return 1 for success. < 0 for failure
|
||||||
*/
|
*/
|
||||||
int list_prepend(list_t *restrict l, const void *restrict data);
|
KS_DECLARE(int) list_prepend(list_t *restrict l, const void *restrict data);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* extract the element in the top of the list.
|
* extract the element in the top of the list.
|
||||||
@ -377,7 +378,7 @@ extern "C" {
|
|||||||
* @param l list to operate
|
* @param l list to operate
|
||||||
* @return reference to user datum, or NULL on errors
|
* @return reference to user datum, or NULL on errors
|
||||||
*/
|
*/
|
||||||
void *list_fetch(list_t *restrict l);
|
KS_DECLARE(void *) list_fetch(list_t *restrict l);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* retrieve an element at a given position.
|
* retrieve an element at a given position.
|
||||||
@ -386,7 +387,7 @@ extern "C" {
|
|||||||
* @param pos [0,size-1] position index of the element wanted
|
* @param pos [0,size-1] position index of the element wanted
|
||||||
* @return reference to user datum, or NULL on errors
|
* @return reference to user datum, or NULL on errors
|
||||||
*/
|
*/
|
||||||
void *list_get_at(const list_t *restrict l, unsigned int pos);
|
KS_DECLARE(void *) list_get_at(const list_t *restrict l, unsigned int pos);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* return the maximum element of the list.
|
* return the maximum element of the list.
|
||||||
@ -400,7 +401,7 @@ extern "C" {
|
|||||||
* @param l list to operate
|
* @param l list to operate
|
||||||
* @return the reference to the element, or NULL
|
* @return the reference to the element, or NULL
|
||||||
*/
|
*/
|
||||||
void *list_get_max(const list_t *restrict l);
|
KS_DECLARE(void *) list_get_max(const list_t *restrict l);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* return the minimum element of the list.
|
* return the minimum element of the list.
|
||||||
@ -414,7 +415,7 @@ extern "C" {
|
|||||||
* @param l list to operate
|
* @param l list to operate
|
||||||
* @return the reference to the element, or NULL
|
* @return the reference to the element, or NULL
|
||||||
*/
|
*/
|
||||||
void *list_get_min(const list_t *restrict l);
|
KS_DECLARE(void *) list_get_min(const list_t *restrict l);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* retrieve and remove from list an element at a given position.
|
* retrieve and remove from list an element at a given position.
|
||||||
@ -423,7 +424,7 @@ extern "C" {
|
|||||||
* @param pos [0,size-1] position index of the element wanted
|
* @param pos [0,size-1] position index of the element wanted
|
||||||
* @return reference to user datum, or NULL on errors
|
* @return reference to user datum, or NULL on errors
|
||||||
*/
|
*/
|
||||||
void *list_extract_at(list_t *restrict l, unsigned int pos);
|
KS_DECLARE(void *) list_extract_at(list_t *restrict l, unsigned int pos);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* insert an element at a given position.
|
* insert an element at a given position.
|
||||||
@ -433,7 +434,7 @@ extern "C" {
|
|||||||
* @param pos [0,size-1] position index to insert the element at
|
* @param pos [0,size-1] position index to insert the element at
|
||||||
* @return positive value on success. Negative on failure
|
* @return positive value on success. Negative on failure
|
||||||
*/
|
*/
|
||||||
int list_insert_at(list_t *restrict l, const void *data, unsigned int pos);
|
KS_DECLARE(int) list_insert_at(list_t *restrict l, const void *data, unsigned int pos);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* expunge the first found given element from the list.
|
* expunge the first found given element from the list.
|
||||||
@ -450,7 +451,7 @@ extern "C" {
|
|||||||
* @see list_attributes_comparator()
|
* @see list_attributes_comparator()
|
||||||
* @see list_delete_at()
|
* @see list_delete_at()
|
||||||
*/
|
*/
|
||||||
int list_delete(list_t *restrict l, const void *data);
|
KS_DECLARE(int) list_delete(list_t *restrict l, const void *data);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* expunge an element at a given position from the list.
|
* expunge an element at a given position from the list.
|
||||||
@ -459,7 +460,7 @@ extern "C" {
|
|||||||
* @param pos [0,size-1] position index of the element to be deleted
|
* @param pos [0,size-1] position index of the element to be deleted
|
||||||
* @return 0 on success. Negative value on failure
|
* @return 0 on success. Negative value on failure
|
||||||
*/
|
*/
|
||||||
int list_delete_at(list_t *restrict l, unsigned int pos);
|
KS_DECLARE(int) list_delete_at(list_t *restrict l, unsigned int pos);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* expunge an array of elements from the list, given their position range.
|
* expunge an array of elements from the list, given their position range.
|
||||||
@ -469,7 +470,7 @@ extern "C" {
|
|||||||
* @param posend [posstart,size-1] position of the last element to be deleted
|
* @param posend [posstart,size-1] position of the last element to be deleted
|
||||||
* @return the number of elements successfully removed on success, <0 on error
|
* @return the number of elements successfully removed on success, <0 on error
|
||||||
*/
|
*/
|
||||||
int list_delete_range(list_t *restrict l, unsigned int posstart, unsigned int posend);
|
KS_DECLARE(int) list_delete_range(list_t *restrict l, unsigned int posstart, unsigned int posend);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* clear all the elements off of the list.
|
* clear all the elements off of the list.
|
||||||
@ -482,7 +483,7 @@ extern "C" {
|
|||||||
* @param l list to operate
|
* @param l list to operate
|
||||||
* @return the number of elements removed on success, <0 on error
|
* @return the number of elements removed on success, <0 on error
|
||||||
*/
|
*/
|
||||||
int list_clear(list_t *restrict l);
|
KS_DECLARE(int) list_clear(list_t *restrict l);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* inspect the number of elements in the list.
|
* inspect the number of elements in the list.
|
||||||
@ -490,7 +491,7 @@ extern "C" {
|
|||||||
* @param l list to operate
|
* @param l list to operate
|
||||||
* @return number of elements currently held by the list
|
* @return number of elements currently held by the list
|
||||||
*/
|
*/
|
||||||
unsigned int list_size(const list_t *restrict l);
|
KS_DECLARE(unsigned int) list_size(const list_t *restrict l);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* inspect whether the list is empty.
|
* inspect whether the list is empty.
|
||||||
@ -500,7 +501,7 @@ extern "C" {
|
|||||||
*
|
*
|
||||||
* @see list_size()
|
* @see list_size()
|
||||||
*/
|
*/
|
||||||
int list_empty(const list_t *restrict l);
|
KS_DECLARE(int) list_empty(const list_t *restrict l);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* find the position of an element in a list.
|
* find the position of an element in a list.
|
||||||
@ -519,7 +520,7 @@ extern "C" {
|
|||||||
* @see list_attributes_comparator()
|
* @see list_attributes_comparator()
|
||||||
* @see list_get_at()
|
* @see list_get_at()
|
||||||
*/
|
*/
|
||||||
int list_locate(const list_t *restrict l, const void *data);
|
KS_DECLARE(int) list_locate(const list_t *restrict l, const void *data);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* returns an element given an indicator.
|
* returns an element given an indicator.
|
||||||
@ -534,7 +535,7 @@ extern "C" {
|
|||||||
* @param indicator indicator data to pass to the seeker along with elements
|
* @param indicator indicator data to pass to the seeker along with elements
|
||||||
* @return reference to the element accepted by the seeker, or NULL if none found
|
* @return reference to the element accepted by the seeker, or NULL if none found
|
||||||
*/
|
*/
|
||||||
void *list_seek(list_t *restrict l, const void *indicator);
|
KS_DECLARE(void *) list_seek(list_t *restrict l, const void *indicator);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* inspect whether some data is member of the list.
|
* inspect whether some data is member of the list.
|
||||||
@ -555,7 +556,7 @@ extern "C" {
|
|||||||
*
|
*
|
||||||
* @see list_attributes_comparator()
|
* @see list_attributes_comparator()
|
||||||
*/
|
*/
|
||||||
int list_contains(const list_t *restrict l, const void *data);
|
KS_DECLARE(int) list_contains(const list_t *restrict l, const void *data);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* concatenate two lists
|
* concatenate two lists
|
||||||
@ -574,7 +575,7 @@ extern "C" {
|
|||||||
* @param dest reference to the destination list
|
* @param dest reference to the destination list
|
||||||
* @return 0 for success, -1 for errors
|
* @return 0 for success, -1 for errors
|
||||||
*/
|
*/
|
||||||
int list_concat(const list_t *l1, const list_t *l2, list_t *restrict dest);
|
KS_DECLARE(int) list_concat(const list_t *l1, const list_t *l2, list_t *restrict dest);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* sort list elements.
|
* sort list elements.
|
||||||
@ -591,7 +592,7 @@ extern "C" {
|
|||||||
*
|
*
|
||||||
* @see list_attributes_comparator()
|
* @see list_attributes_comparator()
|
||||||
*/
|
*/
|
||||||
int list_sort(list_t *restrict l, int versus);
|
KS_DECLARE(int) list_sort(list_t *restrict l, int versus);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* start an iteration session.
|
* start an iteration session.
|
||||||
@ -603,7 +604,7 @@ extern "C" {
|
|||||||
*
|
*
|
||||||
* @see list_iterator_stop()
|
* @see list_iterator_stop()
|
||||||
*/
|
*/
|
||||||
int list_iterator_start(list_t *restrict l);
|
KS_DECLARE(int) list_iterator_start(list_t *restrict l);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* return the next element in the iteration session.
|
* return the next element in the iteration session.
|
||||||
@ -611,7 +612,7 @@ extern "C" {
|
|||||||
* @param l list to operate
|
* @param l list to operate
|
||||||
* @return element datum, or NULL on errors
|
* @return element datum, or NULL on errors
|
||||||
*/
|
*/
|
||||||
void *list_iterator_next(list_t *restrict l);
|
KS_DECLARE(void *) list_iterator_next(list_t *restrict l);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* inspect whether more elements are available in the iteration session.
|
* inspect whether more elements are available in the iteration session.
|
||||||
@ -619,7 +620,7 @@ extern "C" {
|
|||||||
* @param l list to operate
|
* @param l list to operate
|
||||||
* @return 0 iff no more elements are available.
|
* @return 0 iff no more elements are available.
|
||||||
*/
|
*/
|
||||||
int list_iterator_hasnext(const list_t *restrict l);
|
KS_DECLARE(int) list_iterator_hasnext(const list_t *restrict l);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* end an iteration session.
|
* end an iteration session.
|
||||||
@ -627,7 +628,7 @@ extern "C" {
|
|||||||
* @param l list to operate
|
* @param l list to operate
|
||||||
* @return 0 iff the iteration session cannot be stopped
|
* @return 0 iff the iteration session cannot be stopped
|
||||||
*/
|
*/
|
||||||
int list_iterator_stop(list_t *restrict l);
|
KS_DECLARE(int) list_iterator_stop(list_t *restrict l);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* return the hash of the current status of the list.
|
* return the hash of the current status of the list.
|
||||||
@ -637,7 +638,7 @@ extern "C" {
|
|||||||
*
|
*
|
||||||
* @return 0 for success; <0 for failure
|
* @return 0 for success; <0 for failure
|
||||||
*/
|
*/
|
||||||
int list_hash(const list_t *restrict l, list_hash_t *restrict hash);
|
KS_DECLARE(int) list_hash(const list_t *restrict l, list_hash_t *restrict hash);
|
||||||
|
|
||||||
#ifndef SIMCLIST_NO_DUMPRESTORE
|
#ifndef SIMCLIST_NO_DUMPRESTORE
|
||||||
/**
|
/**
|
||||||
@ -655,7 +656,7 @@ extern "C" {
|
|||||||
*
|
*
|
||||||
* @see list_dump_filedescriptor()
|
* @see list_dump_filedescriptor()
|
||||||
*/
|
*/
|
||||||
int list_dump_getinfo_filedescriptor(int fd, list_dump_info_t *restrict info);
|
KS_DECLARE(int) list_dump_getinfo_filedescriptor(int fd, list_dump_info_t *restrict info);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* get meta informations on a list dump on file.
|
* get meta informations on a list dump on file.
|
||||||
@ -670,7 +671,7 @@ extern "C" {
|
|||||||
*
|
*
|
||||||
* @see list_dump_filedescriptor()
|
* @see list_dump_filedescriptor()
|
||||||
*/
|
*/
|
||||||
int list_dump_getinfo_file(const char *restrict filename, list_dump_info_t *restrict info);
|
KS_DECLARE(int) list_dump_getinfo_file(const char *restrict filename, list_dump_info_t *restrict info);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* dump the list into an open, writable file descriptor.
|
* dump the list into an open, writable file descriptor.
|
||||||
@ -706,7 +707,7 @@ extern "C" {
|
|||||||
* @see list_attributes_copy()
|
* @see list_attributes_copy()
|
||||||
* @see list_attributes_serializer()
|
* @see list_attributes_serializer()
|
||||||
*/
|
*/
|
||||||
int list_dump_filedescriptor(const list_t *restrict l, int fd, size_t *restrict len);
|
KS_DECLARE(int) list_dump_filedescriptor(const list_t *restrict l, int fd, size_t *restrict len);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* dump the list to a file name.
|
* dump the list to a file name.
|
||||||
@ -729,7 +730,7 @@ extern "C" {
|
|||||||
*
|
*
|
||||||
* This function stores a representation of the list
|
* This function stores a representation of the list
|
||||||
*/
|
*/
|
||||||
int list_dump_file(const list_t *restrict l, const char *restrict filename, size_t *restrict len);
|
KS_DECLARE(int) list_dump_file(const list_t *restrict l, const char *restrict filename, size_t *restrict len);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* restore the list from an open, readable file descriptor to memory.
|
* restore the list from an open, readable file descriptor to memory.
|
||||||
@ -749,7 +750,7 @@ extern "C" {
|
|||||||
* @param len location to store the length of the dump read (bytes), or NULL
|
* @param len location to store the length of the dump read (bytes), or NULL
|
||||||
* @return 0 if successful; -1 otherwise
|
* @return 0 if successful; -1 otherwise
|
||||||
*/
|
*/
|
||||||
int list_restore_filedescriptor(list_t *restrict l, int fd, size_t *restrict len);
|
KS_DECLARE(int) list_restore_filedescriptor(list_t *restrict l, int fd, size_t *restrict len);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* restore the list from a file name.
|
* restore the list from a file name.
|
||||||
@ -767,7 +768,7 @@ extern "C" {
|
|||||||
* @param len location to store the length of the dump read (bytes), or NULL
|
* @param len location to store the length of the dump read (bytes), or NULL
|
||||||
* @return 0 if successful; -1 otherwise
|
* @return 0 if successful; -1 otherwise
|
||||||
*/
|
*/
|
||||||
int list_restore_file(list_t *restrict l, const char *restrict filename, size_t *len);
|
KS_DECLARE(int) list_restore_file(list_t *restrict l, const char *restrict filename, size_t *len);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* ready-made comparators, meters and hash computers */
|
/* ready-made comparators, meters and hash computers */
|
||||||
@ -776,201 +777,201 @@ extern "C" {
|
|||||||
* ready-made comparator for int8_t elements.
|
* ready-made comparator for int8_t elements.
|
||||||
* @see list_attributes_comparator()
|
* @see list_attributes_comparator()
|
||||||
*/
|
*/
|
||||||
int list_comparator_int8_t (const void *a, const void *b);
|
KS_DECLARE(int) list_comparator_int8_t (const void *a, const void *b);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* ready-made comparator for int16_t elements.
|
* ready-made comparator for int16_t elements.
|
||||||
* @see list_attributes_comparator()
|
* @see list_attributes_comparator()
|
||||||
*/
|
*/
|
||||||
int list_comparator_int16_t (const void *a, const void *b);
|
KS_DECLARE(int) list_comparator_int16_t (const void *a, const void *b);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* ready-made comparator for int32_t elements.
|
* ready-made comparator for int32_t elements.
|
||||||
* @see list_attributes_comparator()
|
* @see list_attributes_comparator()
|
||||||
*/
|
*/
|
||||||
int list_comparator_int32_t (const void *a, const void *b);
|
KS_DECLARE(int) list_comparator_int32_t (const void *a, const void *b);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* ready-made comparator for int64_t elements.
|
* ready-made comparator for int64_t elements.
|
||||||
* @see list_attributes_comparator()
|
* @see list_attributes_comparator()
|
||||||
*/
|
*/
|
||||||
int list_comparator_int64_t (const void *a, const void *b);
|
KS_DECLARE(int) list_comparator_int64_t (const void *a, const void *b);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* ready-made comparator for uint8_t elements.
|
* ready-made comparator for uint8_t elements.
|
||||||
* @see list_attributes_comparator()
|
* @see list_attributes_comparator()
|
||||||
*/
|
*/
|
||||||
int list_comparator_uint8_t (const void *a, const void *b);
|
KS_DECLARE(int) list_comparator_uint8_t (const void *a, const void *b);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* ready-made comparator for uint16_t elements.
|
* ready-made comparator for uint16_t elements.
|
||||||
* @see list_attributes_comparator()
|
* @see list_attributes_comparator()
|
||||||
*/
|
*/
|
||||||
int list_comparator_uint16_t (const void *a, const void *b);
|
KS_DECLARE(int) list_comparator_uint16_t (const void *a, const void *b);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* ready-made comparator for uint32_t elements.
|
* ready-made comparator for uint32_t elements.
|
||||||
* @see list_attributes_comparator()
|
* @see list_attributes_comparator()
|
||||||
*/
|
*/
|
||||||
int list_comparator_uint32_t (const void *a, const void *b);
|
KS_DECLARE(int) list_comparator_uint32_t (const void *a, const void *b);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* ready-made comparator for uint64_t elements.
|
* ready-made comparator for uint64_t elements.
|
||||||
* @see list_attributes_comparator()
|
* @see list_attributes_comparator()
|
||||||
*/
|
*/
|
||||||
int list_comparator_uint64_t (const void *a, const void *b);
|
KS_DECLARE(int) list_comparator_uint64_t (const void *a, const void *b);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* ready-made comparator for float elements.
|
* ready-made comparator for float elements.
|
||||||
* @see list_attributes_comparator()
|
* @see list_attributes_comparator()
|
||||||
*/
|
*/
|
||||||
int list_comparator_float(const void *a, const void *b);
|
KS_DECLARE(int) list_comparator_float(const void *a, const void *b);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* ready-made comparator for double elements.
|
* ready-made comparator for double elements.
|
||||||
* @see list_attributes_comparator()
|
* @see list_attributes_comparator()
|
||||||
*/
|
*/
|
||||||
int list_comparator_double(const void *a, const void *b);
|
KS_DECLARE(int) list_comparator_double(const void *a, const void *b);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* ready-made comparator for string elements.
|
* ready-made comparator for string elements.
|
||||||
* @see list_attributes_comparator()
|
* @see list_attributes_comparator()
|
||||||
*/
|
*/
|
||||||
int list_comparator_string(const void *a, const void *b);
|
KS_DECLARE(int) list_comparator_string(const void *a, const void *b);
|
||||||
|
|
||||||
/* metric functions */
|
/* metric functions */
|
||||||
/**
|
/**
|
||||||
* ready-made metric function for int8_t elements.
|
* ready-made metric function for int8_t elements.
|
||||||
* @see list_attributes_copy()
|
* @see list_attributes_copy()
|
||||||
*/
|
*/
|
||||||
size_t list_meter_int8_t (const void *el);
|
KS_DECLARE(size_t) list_meter_int8_t (const void *el);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* ready-made metric function for int16_t elements.
|
* ready-made metric function for int16_t elements.
|
||||||
* @see list_attributes_copy()
|
* @see list_attributes_copy()
|
||||||
*/
|
*/
|
||||||
size_t list_meter_int16_t (const void *el);
|
KS_DECLARE(size_t) list_meter_int16_t (const void *el);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* ready-made metric function for int32_t elements.
|
* ready-made metric function for int32_t elements.
|
||||||
* @see list_attributes_copy()
|
* @see list_attributes_copy()
|
||||||
*/
|
*/
|
||||||
size_t list_meter_int32_t (const void *el);
|
KS_DECLARE(size_t) list_meter_int32_t (const void *el);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* ready-made metric function for int64_t elements.
|
* ready-made metric function for int64_t elements.
|
||||||
* @see list_attributes_copy()
|
* @see list_attributes_copy()
|
||||||
*/
|
*/
|
||||||
size_t list_meter_int64_t (const void *el);
|
KS_DECLARE(size_t) list_meter_int64_t (const void *el);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* ready-made metric function for uint8_t elements.
|
* ready-made metric function for uint8_t elements.
|
||||||
* @see list_attributes_copy()
|
* @see list_attributes_copy()
|
||||||
*/
|
*/
|
||||||
size_t list_meter_uint8_t (const void *el);
|
KS_DECLARE(size_t) list_meter_uint8_t (const void *el);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* ready-made metric function for uint16_t elements.
|
* ready-made metric function for uint16_t elements.
|
||||||
* @see list_attributes_copy()
|
* @see list_attributes_copy()
|
||||||
*/
|
*/
|
||||||
size_t list_meter_uint16_t (const void *el);
|
KS_DECLARE(size_t) list_meter_uint16_t (const void *el);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* ready-made metric function for uint32_t elements.
|
* ready-made metric function for uint32_t elements.
|
||||||
* @see list_attributes_copy()
|
* @see list_attributes_copy()
|
||||||
*/
|
*/
|
||||||
size_t list_meter_uint32_t (const void *el);
|
KS_DECLARE(size_t) list_meter_uint32_t (const void *el);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* ready-made metric function for uint64_t elements.
|
* ready-made metric function for uint64_t elements.
|
||||||
* @see list_attributes_copy()
|
* @see list_attributes_copy()
|
||||||
*/
|
*/
|
||||||
size_t list_meter_uint64_t (const void *el);
|
KS_DECLARE(size_t) list_meter_uint64_t (const void *el);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* ready-made metric function for float elements.
|
* ready-made metric function for float elements.
|
||||||
* @see list_attributes_copy()
|
* @see list_attributes_copy()
|
||||||
*/
|
*/
|
||||||
size_t list_meter_float(const void *el);
|
KS_DECLARE(size_t) list_meter_float(const void *el);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* ready-made metric function for double elements.
|
* ready-made metric function for double elements.
|
||||||
* @see list_attributes_copy()
|
* @see list_attributes_copy()
|
||||||
*/
|
*/
|
||||||
size_t list_meter_double(const void *el);
|
KS_DECLARE(size_t) list_meter_double(const void *el);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* ready-made metric function for string elements.
|
* ready-made metric function for string elements.
|
||||||
* @see list_attributes_copy()
|
* @see list_attributes_copy()
|
||||||
*/
|
*/
|
||||||
size_t list_meter_string(const void *el);
|
KS_DECLARE(size_t) list_meter_string(const void *el);
|
||||||
|
|
||||||
/* hash functions */
|
/* hash functions */
|
||||||
/**
|
/**
|
||||||
* ready-made hash function for int8_t elements.
|
* ready-made hash function for int8_t elements.
|
||||||
* @see list_attributes_hash_computer()
|
* @see list_attributes_hash_computer()
|
||||||
*/
|
*/
|
||||||
list_hash_t list_hashcomputer_int8_t(const void *el);
|
KS_DECLARE(list_hash_t) list_hashcomputer_int8_t(const void *el);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* ready-made hash function for int16_t elements.
|
* ready-made hash function for int16_t elements.
|
||||||
* @see list_attributes_hash_computer()
|
* @see list_attributes_hash_computer()
|
||||||
*/
|
*/
|
||||||
list_hash_t list_hashcomputer_int16_t(const void *el);
|
KS_DECLARE(list_hash_t) list_hashcomputer_int16_t(const void *el);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* ready-made hash function for int32_t elements.
|
* ready-made hash function for int32_t elements.
|
||||||
* @see list_attributes_hash_computer()
|
* @see list_attributes_hash_computer()
|
||||||
*/
|
*/
|
||||||
list_hash_t list_hashcomputer_int32_t(const void *el);
|
KS_DECLARE(list_hash_t) list_hashcomputer_int32_t(const void *el);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* ready-made hash function for int64_t elements.
|
* ready-made hash function for int64_t elements.
|
||||||
* @see list_attributes_hash_computer()
|
* @see list_attributes_hash_computer()
|
||||||
*/
|
*/
|
||||||
list_hash_t list_hashcomputer_int64_t(const void *el);
|
KS_DECLARE(list_hash_t) list_hashcomputer_int64_t(const void *el);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* ready-made hash function for uint8_t elements.
|
* ready-made hash function for uint8_t elements.
|
||||||
* @see list_attributes_hash_computer()
|
* @see list_attributes_hash_computer()
|
||||||
*/
|
*/
|
||||||
list_hash_t list_hashcomputer_uint8_t(const void *el);
|
KS_DECLARE(list_hash_t) list_hashcomputer_uint8_t(const void *el);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* ready-made hash function for uint16_t elements.
|
* ready-made hash function for uint16_t elements.
|
||||||
* @see list_attributes_hash_computer()
|
* @see list_attributes_hash_computer()
|
||||||
*/
|
*/
|
||||||
list_hash_t list_hashcomputer_uint16_t(const void *el);
|
KS_DECLARE(list_hash_t) list_hashcomputer_uint16_t(const void *el);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* ready-made hash function for uint32_t elements.
|
* ready-made hash function for uint32_t elements.
|
||||||
* @see list_attributes_hash_computer()
|
* @see list_attributes_hash_computer()
|
||||||
*/
|
*/
|
||||||
list_hash_t list_hashcomputer_uint32_t(const void *el);
|
KS_DECLARE(list_hash_t) list_hashcomputer_uint32_t(const void *el);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* ready-made hash function for uint64_t elements.
|
* ready-made hash function for uint64_t elements.
|
||||||
* @see list_attributes_hash_computer()
|
* @see list_attributes_hash_computer()
|
||||||
*/
|
*/
|
||||||
list_hash_t list_hashcomputer_uint64_t(const void *el);
|
KS_DECLARE(list_hash_t) list_hashcomputer_uint64_t(const void *el);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* ready-made hash function for float elements.
|
* ready-made hash function for float elements.
|
||||||
* @see list_attributes_hash_computer()
|
* @see list_attributes_hash_computer()
|
||||||
*/
|
*/
|
||||||
list_hash_t list_hashcomputer_float(const void *el);
|
KS_DECLARE(list_hash_t) list_hashcomputer_float(const void *el);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* ready-made hash function for double elements.
|
* ready-made hash function for double elements.
|
||||||
* @see list_attributes_hash_computer()
|
* @see list_attributes_hash_computer()
|
||||||
*/
|
*/
|
||||||
list_hash_t list_hashcomputer_double(const void *el);
|
KS_DECLARE(list_hash_t) list_hashcomputer_double(const void *el);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* ready-made hash function for string elements.
|
* ready-made hash function for string elements.
|
||||||
* @see list_attributes_hash_computer()
|
* @see list_attributes_hash_computer()
|
||||||
*/
|
*/
|
||||||
list_hash_t list_hashcomputer_string(const void *el);
|
KS_DECLARE(list_hash_t) list_hashcomputer_string(const void *el);
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
|
130
libs/libks/src/ks_base64.c
Normal file
130
libs/libks/src/ks_base64.c
Normal file
@ -0,0 +1,130 @@
|
|||||||
|
/*
|
||||||
|
* 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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
#include <ks_base64.h>
|
||||||
|
|
||||||
|
|
||||||
|
static const char ks_b64_table[65] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
|
||||||
|
|
||||||
|
|
||||||
|
KS_DECLARE(ks_status_t) ks_b64_encode(unsigned char *in, ks_size_t ilen, unsigned char *out, ks_size_t olen)
|
||||||
|
{
|
||||||
|
int y = 0, bytes = 0;
|
||||||
|
size_t x = 0;
|
||||||
|
unsigned int b = 0, l = 0;
|
||||||
|
|
||||||
|
for (x = 0; x < ilen; x++) {
|
||||||
|
b = (b << 8) + in[x];
|
||||||
|
l += 8;
|
||||||
|
|
||||||
|
while (l >= 6) {
|
||||||
|
out[bytes++] = ks_b64_table[(b >> (l -= 6)) % 64];
|
||||||
|
if (bytes >= (int)olen - 1) {
|
||||||
|
goto end;
|
||||||
|
}
|
||||||
|
if (++y != 72) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
/* out[bytes++] = '\n'; */
|
||||||
|
y = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (l > 0) {
|
||||||
|
out[bytes++] = ks_b64_table[((b % 16) << (6 - l)) % 64];
|
||||||
|
}
|
||||||
|
if (l != 0) {
|
||||||
|
while (l < 6 && bytes < (int)olen - 1) {
|
||||||
|
out[bytes++] = '=', l += 2;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
end:
|
||||||
|
|
||||||
|
out[bytes] = '\0';
|
||||||
|
|
||||||
|
return KS_STATUS_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
KS_DECLARE(ks_size_t) ks_b64_decode(char *in, char *out, ks_size_t olen)
|
||||||
|
{
|
||||||
|
|
||||||
|
char l64[256];
|
||||||
|
int b = 0, c, l = 0, i;
|
||||||
|
char *ip, *op = out;
|
||||||
|
size_t ol = 0;
|
||||||
|
|
||||||
|
for (i = 0; i < 256; i++) {
|
||||||
|
l64[i] = -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (i = 0; i < 64; i++) {
|
||||||
|
l64[(int) ks_b64_table[i]] = (char) i;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (ip = in; ip && *ip; ip++) {
|
||||||
|
c = l64[(int) *ip];
|
||||||
|
if (c == -1) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
b = (b << 6) + c;
|
||||||
|
l += 6;
|
||||||
|
|
||||||
|
while (l >= 8) {
|
||||||
|
op[ol++] = (char) ((b >> (l -= 8)) % 256);
|
||||||
|
if (ol >= olen - 2) {
|
||||||
|
goto end;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
end:
|
||||||
|
|
||||||
|
op[ol++] = '\0';
|
||||||
|
|
||||||
|
return ol;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* 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
|
* Copyright (c) 2007-2014, Anthony Minessale II
|
||||||
* All rights reserved.
|
* All rights reserved.
|
||||||
*
|
*
|
||||||
* Redistribution and use in source and binary forms, with or without
|
* Redistribution and use in source and binary forms, with or without
|
||||||
* modification, are permitted provided that the following conditions
|
* modification, are permitted provided that the following conditions
|
||||||
* are met:
|
* are met:
|
||||||
*
|
*
|
||||||
* * Redistributions of source code must retain the above copyright
|
* * Redistributions of source code must retain the above copyright
|
||||||
* notice, this list of conditions and the following disclaimer.
|
* notice, this list of conditions and the following disclaimer.
|
||||||
*
|
*
|
||||||
* * Redistributions in binary form must reproduce the above copyright
|
* * Redistributions in binary form must reproduce the above copyright
|
||||||
* notice, this list of conditions and the following disclaimer in the
|
* notice, this list of conditions and the following disclaimer in the
|
||||||
* documentation and/or other materials provided with the distribution.
|
* documentation and/or other materials provided with the distribution.
|
||||||
*
|
*
|
||||||
* * Neither the name of the original author; nor the names of any contributors
|
* * 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
|
* may be used to endorse or promote products derived from this software
|
||||||
* without specific prior written permission.
|
* without specific prior written permission.
|
||||||
*
|
*
|
||||||
*
|
*
|
||||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||||
@ -55,6 +55,7 @@ static const char *LEVEL_NAMES[] = {
|
|||||||
};
|
};
|
||||||
|
|
||||||
static int ks_log_level = 7;
|
static int ks_log_level = 7;
|
||||||
|
static ks_log_prefix_t ks_log_prefix = KS_LOG_PREFIX_ALL;
|
||||||
|
|
||||||
static const char *cut_path(const char *in)
|
static const char *cut_path(const char *in)
|
||||||
{
|
{
|
||||||
@ -78,6 +79,9 @@ static void default_logger(const char *file, const char *func, int line, int lev
|
|||||||
char *data;
|
char *data;
|
||||||
va_list ap;
|
va_list ap;
|
||||||
int ret;
|
int ret;
|
||||||
|
char buf[1024];
|
||||||
|
//int remaining = sizeof(buf) - 1;
|
||||||
|
int used = 0;
|
||||||
|
|
||||||
if (level < 0 || level > 7) {
|
if (level < 0 || level > 7) {
|
||||||
level = 7;
|
level = 7;
|
||||||
@ -93,7 +97,33 @@ static void default_logger(const char *file, const char *func, int line, int lev
|
|||||||
ret = ks_vasprintf(&data, fmt, ap);
|
ret = ks_vasprintf(&data, fmt, ap);
|
||||||
|
|
||||||
if (ret != -1) {
|
if (ret != -1) {
|
||||||
fprintf(stderr, "[%s] %s:%d %s() %s", LEVEL_NAMES[level], fp, line, func, data);
|
buf[0] = '\0';
|
||||||
|
used += 1;
|
||||||
|
|
||||||
|
if (ks_log_prefix & KS_LOG_PREFIX_LEVEL) {
|
||||||
|
used += snprintf(buf + used - 1, sizeof(buf) - used, "[%s] ", LEVEL_NAMES[level]);
|
||||||
|
}
|
||||||
|
if (ks_log_prefix & KS_LOG_PREFIX_TIME) {
|
||||||
|
used += snprintf(buf + used - 1, sizeof(buf) - used, "@%lld ", (long long int)ks_time_now());
|
||||||
|
}
|
||||||
|
if (ks_log_prefix & KS_LOG_PREFIX_THREAD) {
|
||||||
|
used += snprintf(buf + used - 1, sizeof(buf) - used, "#%d ", (int32_t)ks_thread_self_id());
|
||||||
|
}
|
||||||
|
if (ks_log_prefix & KS_LOG_PREFIX_FILE) {
|
||||||
|
used += snprintf(buf + used - 1, sizeof(buf) - used, fp);
|
||||||
|
if (ks_log_prefix & KS_LOG_PREFIX_LINE) {
|
||||||
|
used += snprintf(buf + used - 1, sizeof(buf) - used, ":%d", line);
|
||||||
|
}
|
||||||
|
used += snprintf(buf + used - 1, sizeof(buf) - used, " ");
|
||||||
|
}
|
||||||
|
if (ks_log_prefix & KS_LOG_PREFIX_FUNC) {
|
||||||
|
used += snprintf(buf + used - 1, sizeof(buf) - used, "%s() ", func);
|
||||||
|
}
|
||||||
|
|
||||||
|
used += snprintf(buf + used - 1, sizeof(buf) - used, data);
|
||||||
|
|
||||||
|
//fprintf(stderr, "[%s] %s:%d %s() %s", LEVEL_NAMES[level], fp, line, func, data);
|
||||||
|
fprintf(stderr, buf);
|
||||||
free(data);
|
free(data);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -121,3 +151,8 @@ KS_DECLARE(void) ks_global_set_default_logger(int level)
|
|||||||
ks_log = default_logger;
|
ks_log = default_logger;
|
||||||
ks_log_level = level;
|
ks_log_level = level;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
KS_DECLARE(void) ks_global_set_default_logger_prefix(ks_log_prefix_t prefix)
|
||||||
|
{
|
||||||
|
ks_log_prefix = prefix;
|
||||||
|
}
|
||||||
|
@ -121,6 +121,15 @@ KS_DECLARE(ks_status_t) ks_socket_option(ks_socket_t socket, int option_name, ks
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
case IPV6_V6ONLY:
|
||||||
|
#ifdef WIN32
|
||||||
|
#warning make sure windows works like linux for IPV6 to IPV4 automapping stuff
|
||||||
|
result = setsockopt(socket, SOL_IPV6, IPV6_V6ONLY, (char *)&opt, sizeof(opt));
|
||||||
|
#else
|
||||||
|
result = setsockopt(socket, SOL_IPV6, IPV6_V6ONLY, &opt, sizeof(opt));
|
||||||
|
#endif
|
||||||
|
if (!result) status = KS_STATUS_SUCCESS;
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -39,6 +39,17 @@ KS_DECLARE(ks_thread_os_handle_t) ks_thread_self(void)
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
KS_DECLARE(ks_pid_t) ks_thread_self_id(void)
|
||||||
|
{
|
||||||
|
#ifdef WIN32
|
||||||
|
return GetCurrentThreadId();
|
||||||
|
#elseif gettid
|
||||||
|
return gettid();
|
||||||
|
#else
|
||||||
|
return syscall(SYS_gettid);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
static void ks_thread_init_priority(void)
|
static void ks_thread_init_priority(void)
|
||||||
{
|
{
|
||||||
#ifdef WIN32
|
#ifdef WIN32
|
||||||
|
@ -268,7 +268,7 @@ static inline long get_random(void)
|
|||||||
|
|
||||||
|
|
||||||
/* list initialization */
|
/* list initialization */
|
||||||
int list_init(list_t *restrict l)
|
KS_DECLARE(int) list_init(list_t *restrict l)
|
||||||
{
|
{
|
||||||
if (l == NULL)
|
if (l == NULL)
|
||||||
return -1;
|
return -1;
|
||||||
@ -306,7 +306,7 @@ int list_init(list_t *restrict l)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void list_destroy(list_t *restrict l)
|
KS_DECLARE(void) list_destroy(list_t *restrict l)
|
||||||
{
|
{
|
||||||
unsigned int i;
|
unsigned int i;
|
||||||
|
|
||||||
@ -340,7 +340,7 @@ int list_attributes_setdefaults(list_t *restrict l)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* setting list properties */
|
/* setting list properties */
|
||||||
int list_attributes_comparator(list_t *restrict l, element_comparator comparator_fun)
|
KS_DECLARE(int) list_attributes_comparator(list_t *restrict l, element_comparator comparator_fun)
|
||||||
{
|
{
|
||||||
if (l == NULL)
|
if (l == NULL)
|
||||||
return -1;
|
return -1;
|
||||||
@ -352,7 +352,7 @@ int list_attributes_comparator(list_t *restrict l, element_comparator comparator
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int list_attributes_seeker(list_t *restrict l, element_seeker seeker_fun)
|
KS_DECLARE(int) list_attributes_seeker(list_t *restrict l, element_seeker seeker_fun)
|
||||||
{
|
{
|
||||||
if (l == NULL)
|
if (l == NULL)
|
||||||
return -1;
|
return -1;
|
||||||
@ -363,7 +363,7 @@ int list_attributes_seeker(list_t *restrict l, element_seeker seeker_fun)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int list_attributes_copy(list_t *restrict l, element_meter metric_fun, int copy_data)
|
KS_DECLARE(int) list_attributes_copy(list_t *restrict l, element_meter metric_fun, int copy_data)
|
||||||
{
|
{
|
||||||
if (l == NULL || (metric_fun == NULL && copy_data != 0))
|
if (l == NULL || (metric_fun == NULL && copy_data != 0))
|
||||||
return -1;
|
return -1;
|
||||||
@ -376,7 +376,7 @@ int list_attributes_copy(list_t *restrict l, element_meter metric_fun, int copy_
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int list_attributes_hash_computer(list_t *restrict l, element_hash_computer hash_computer_fun)
|
KS_DECLARE(int) list_attributes_hash_computer(list_t *restrict l, element_hash_computer hash_computer_fun)
|
||||||
{
|
{
|
||||||
if (l == NULL)
|
if (l == NULL)
|
||||||
return -1;
|
return -1;
|
||||||
@ -386,7 +386,7 @@ int list_attributes_hash_computer(list_t *restrict l, element_hash_computer hash
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int list_attributes_serializer(list_t *restrict l, element_serializer serializer_fun)
|
KS_DECLARE(int) list_attributes_serializer(list_t *restrict l, element_serializer serializer_fun)
|
||||||
{
|
{
|
||||||
if (l == NULL)
|
if (l == NULL)
|
||||||
return -1;
|
return -1;
|
||||||
@ -396,7 +396,7 @@ int list_attributes_serializer(list_t *restrict l, element_serializer serializer
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int list_attributes_unserializer(list_t *restrict l, element_unserializer unserializer_fun)
|
KS_DECLARE(int) list_attributes_unserializer(list_t *restrict l, element_unserializer unserializer_fun)
|
||||||
{
|
{
|
||||||
if (l == NULL)
|
if (l == NULL)
|
||||||
return -1;
|
return -1;
|
||||||
@ -406,22 +406,22 @@ int list_attributes_unserializer(list_t *restrict l, element_unserializer unseri
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int list_append(list_t *restrict l, const void *data)
|
KS_DECLARE(int) list_append(list_t *restrict l, const void *data)
|
||||||
{
|
{
|
||||||
return list_insert_at(l, data, l->numels);
|
return list_insert_at(l, data, l->numels);
|
||||||
}
|
}
|
||||||
|
|
||||||
int list_prepend(list_t *restrict l, const void *data)
|
KS_DECLARE(int) list_prepend(list_t *restrict l, const void *data)
|
||||||
{
|
{
|
||||||
return list_insert_at(l, data, 0);
|
return list_insert_at(l, data, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
void *list_fetch(list_t *restrict l)
|
KS_DECLARE(void *) list_fetch(list_t *restrict l)
|
||||||
{
|
{
|
||||||
return list_extract_at(l, 0);
|
return list_extract_at(l, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
void *list_get_at(const list_t *restrict l, unsigned int pos)
|
KS_DECLARE(void *) list_get_at(const list_t *restrict l, unsigned int pos)
|
||||||
{
|
{
|
||||||
struct list_entry_s *tmp;
|
struct list_entry_s *tmp;
|
||||||
|
|
||||||
@ -430,12 +430,12 @@ void *list_get_at(const list_t *restrict l, unsigned int pos)
|
|||||||
return (tmp != NULL ? tmp->data : NULL);
|
return (tmp != NULL ? tmp->data : NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
void *list_get_max(const list_t *restrict l)
|
KS_DECLARE(void *) list_get_max(const list_t *restrict l)
|
||||||
{
|
{
|
||||||
return list_get_minmax(l, +1);
|
return list_get_minmax(l, +1);
|
||||||
}
|
}
|
||||||
|
|
||||||
void *list_get_min(const list_t *restrict l)
|
KS_DECLARE(void *) list_get_min(const list_t *restrict l)
|
||||||
{
|
{
|
||||||
return list_get_minmax(l, -1);
|
return list_get_minmax(l, -1);
|
||||||
}
|
}
|
||||||
@ -488,7 +488,7 @@ static inline struct list_entry_s *list_findpos(const list_t *restrict l, int po
|
|||||||
return ptr;
|
return ptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
void *list_extract_at(list_t *restrict l, unsigned int pos)
|
KS_DECLARE(void *) list_extract_at(list_t *restrict l, unsigned int pos)
|
||||||
{
|
{
|
||||||
struct list_entry_s *tmp;
|
struct list_entry_s *tmp;
|
||||||
void *data;
|
void *data;
|
||||||
@ -508,7 +508,7 @@ void *list_extract_at(list_t *restrict l, unsigned int pos)
|
|||||||
return data;
|
return data;
|
||||||
}
|
}
|
||||||
|
|
||||||
int list_insert_at(list_t *restrict l, const void *data, unsigned int pos)
|
KS_DECLARE(int) list_insert_at(list_t *restrict l, const void *data, unsigned int pos)
|
||||||
{
|
{
|
||||||
struct list_entry_s *lent, *succ, *prec;
|
struct list_entry_s *lent, *succ, *prec;
|
||||||
|
|
||||||
@ -561,7 +561,7 @@ int list_insert_at(list_t *restrict l, const void *data, unsigned int pos)
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
int list_delete(list_t *restrict l, const void *data)
|
KS_DECLARE(int) list_delete(list_t *restrict l, const void *data)
|
||||||
{
|
{
|
||||||
int pos, r;
|
int pos, r;
|
||||||
|
|
||||||
@ -578,7 +578,7 @@ int list_delete(list_t *restrict l, const void *data)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int list_delete_at(list_t *restrict l, unsigned int pos)
|
KS_DECLARE(int) list_delete_at(list_t *restrict l, unsigned int pos)
|
||||||
{
|
{
|
||||||
struct list_entry_s *delendo;
|
struct list_entry_s *delendo;
|
||||||
|
|
||||||
@ -598,7 +598,7 @@ int list_delete_at(list_t *restrict l, unsigned int pos)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int list_delete_range(list_t *restrict l, unsigned int posstart, unsigned int posend)
|
KS_DECLARE(int) list_delete_range(list_t *restrict l, unsigned int posstart, unsigned int posend)
|
||||||
{
|
{
|
||||||
struct list_entry_s *lastvalid, *tmp, *tmp2;
|
struct list_entry_s *lastvalid, *tmp, *tmp2;
|
||||||
unsigned int numdel, midposafter, i;
|
unsigned int numdel, midposafter, i;
|
||||||
@ -665,7 +665,7 @@ int list_delete_range(list_t *restrict l, unsigned int posstart, unsigned int po
|
|||||||
return numdel;
|
return numdel;
|
||||||
}
|
}
|
||||||
|
|
||||||
int list_clear(list_t *restrict l)
|
KS_DECLARE(int) list_clear(list_t *restrict l)
|
||||||
{
|
{
|
||||||
struct list_entry_s *s;
|
struct list_entry_s *s;
|
||||||
unsigned int numels;
|
unsigned int numels;
|
||||||
@ -715,17 +715,17 @@ int list_clear(list_t *restrict l)
|
|||||||
return numels;
|
return numels;
|
||||||
}
|
}
|
||||||
|
|
||||||
unsigned int list_size(const list_t *restrict l)
|
KS_DECLARE(unsigned int) list_size(const list_t *restrict l)
|
||||||
{
|
{
|
||||||
return l->numels;
|
return l->numels;
|
||||||
}
|
}
|
||||||
|
|
||||||
int list_empty(const list_t *restrict l)
|
KS_DECLARE(int) list_empty(const list_t *restrict l)
|
||||||
{
|
{
|
||||||
return (l->numels == 0);
|
return (l->numels == 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
int list_locate(const list_t *restrict l, const void *data)
|
KS_DECLARE(int) list_locate(const list_t *restrict l, const void *data)
|
||||||
{
|
{
|
||||||
struct list_entry_s *el;
|
struct list_entry_s *el;
|
||||||
int pos = 0;
|
int pos = 0;
|
||||||
@ -749,7 +749,7 @@ int list_locate(const list_t *restrict l, const void *data)
|
|||||||
return pos;
|
return pos;
|
||||||
}
|
}
|
||||||
|
|
||||||
void *list_seek(list_t *restrict l, const void *indicator)
|
KS_DECLARE(void *) list_seek(list_t *restrict l, const void *indicator)
|
||||||
{
|
{
|
||||||
const struct list_entry_s *iter;
|
const struct list_entry_s *iter;
|
||||||
|
|
||||||
@ -764,12 +764,12 @@ void *list_seek(list_t *restrict l, const void *indicator)
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
int list_contains(const list_t *restrict l, const void *data)
|
KS_DECLARE(int) list_contains(const list_t *restrict l, const void *data)
|
||||||
{
|
{
|
||||||
return (list_locate(l, data) >= 0);
|
return (list_locate(l, data) >= 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
int list_concat(const list_t *l1, const list_t *l2, list_t *restrict dest)
|
KS_DECLARE(int) list_concat(const list_t *l1, const list_t *l2, list_t *restrict dest)
|
||||||
{
|
{
|
||||||
struct list_entry_s *el, *srcel;
|
struct list_entry_s *el, *srcel;
|
||||||
unsigned int cnt;
|
unsigned int cnt;
|
||||||
@ -825,7 +825,7 @@ int list_concat(const list_t *l1, const list_t *l2, list_t *restrict dest)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int list_sort(list_t *restrict l, int versus)
|
KS_DECLARE(int) list_sort(list_t *restrict l, int versus)
|
||||||
{
|
{
|
||||||
if (l->iter_active || l->attrs.comparator == NULL) /* cannot modify list in the middle of an iteration */
|
if (l->iter_active || l->attrs.comparator == NULL) /* cannot modify list in the middle of an iteration */
|
||||||
return -1;
|
return -1;
|
||||||
@ -1005,7 +1005,7 @@ static void list_sort_quicksort(list_t *restrict l, int versus, unsigned int fir
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
int list_iterator_start(list_t *restrict l)
|
KS_DECLARE(int) list_iterator_start(list_t *restrict l)
|
||||||
{
|
{
|
||||||
if (l->iter_active)
|
if (l->iter_active)
|
||||||
return 0;
|
return 0;
|
||||||
@ -1015,7 +1015,7 @@ int list_iterator_start(list_t *restrict l)
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
void *list_iterator_next(list_t *restrict l)
|
KS_DECLARE(void *) list_iterator_next(list_t *restrict l)
|
||||||
{
|
{
|
||||||
void *toret;
|
void *toret;
|
||||||
|
|
||||||
@ -1029,14 +1029,14 @@ void *list_iterator_next(list_t *restrict l)
|
|||||||
return toret;
|
return toret;
|
||||||
}
|
}
|
||||||
|
|
||||||
int list_iterator_hasnext(const list_t *restrict l)
|
KS_DECLARE(int) list_iterator_hasnext(const list_t *restrict l)
|
||||||
{
|
{
|
||||||
if (!l->iter_active)
|
if (!l->iter_active)
|
||||||
return 0;
|
return 0;
|
||||||
return (l->iter_pos < l->numels);
|
return (l->iter_pos < l->numels);
|
||||||
}
|
}
|
||||||
|
|
||||||
int list_iterator_stop(list_t *restrict l)
|
KS_DECLARE(int) list_iterator_stop(list_t *restrict l)
|
||||||
{
|
{
|
||||||
if (!l->iter_active)
|
if (!l->iter_active)
|
||||||
return 0;
|
return 0;
|
||||||
@ -1045,7 +1045,7 @@ int list_iterator_stop(list_t *restrict l)
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
int list_hash(const list_t *restrict l, list_hash_t *restrict hash)
|
KS_DECLARE(int) list_hash(const list_t *restrict l, list_hash_t *restrict hash)
|
||||||
{
|
{
|
||||||
struct list_entry_s *x;
|
struct list_entry_s *x;
|
||||||
list_hash_t tmphash;
|
list_hash_t tmphash;
|
||||||
@ -1083,7 +1083,7 @@ int list_hash(const list_t *restrict l, list_hash_t *restrict hash)
|
|||||||
}
|
}
|
||||||
|
|
||||||
#ifndef SIMCLIST_NO_DUMPRESTORE
|
#ifndef SIMCLIST_NO_DUMPRESTORE
|
||||||
int list_dump_getinfo_filedescriptor(int fd, list_dump_info_t *restrict info)
|
KS_DECLARE(int) list_dump_getinfo_filedescriptor(int fd, list_dump_info_t *restrict info)
|
||||||
{
|
{
|
||||||
int32_t terminator_head, terminator_tail;
|
int32_t terminator_head, terminator_tail;
|
||||||
uint32_t elemlen;
|
uint32_t elemlen;
|
||||||
@ -1148,7 +1148,7 @@ int list_dump_getinfo_filedescriptor(int fd, list_dump_info_t *restrict info)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int list_dump_getinfo_file(const char *restrict filename, list_dump_info_t *restrict info)
|
KS_DECLARE(int) list_dump_getinfo_file(const char *restrict filename, list_dump_info_t *restrict info)
|
||||||
{
|
{
|
||||||
int fd, ret;
|
int fd, ret;
|
||||||
|
|
||||||
@ -1162,7 +1162,7 @@ int list_dump_getinfo_file(const char *restrict filename, list_dump_info_t *rest
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
int list_dump_filedescriptor(const list_t *restrict l, int fd, size_t *restrict len)
|
KS_DECLARE(int) list_dump_filedescriptor(const list_t *restrict l, int fd, size_t *restrict len)
|
||||||
{
|
{
|
||||||
struct list_entry_s *x;
|
struct list_entry_s *x;
|
||||||
void *ser_buf;
|
void *ser_buf;
|
||||||
@ -1311,7 +1311,7 @@ int list_dump_filedescriptor(const list_t *restrict l, int fd, size_t *restrict
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int list_restore_filedescriptor(list_t *restrict l, int fd, size_t *restrict len)
|
KS_DECLARE(int) list_restore_filedescriptor(list_t *restrict l, int fd, size_t *restrict len)
|
||||||
{
|
{
|
||||||
struct list_dump_header_s header;
|
struct list_dump_header_s header;
|
||||||
unsigned long cnt;
|
unsigned long cnt;
|
||||||
@ -1436,7 +1436,7 @@ int list_restore_filedescriptor(list_t *restrict l, int fd, size_t *restrict len
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int list_dump_file(const list_t *restrict l, const char *restrict filename, size_t *restrict len)
|
KS_DECLARE(int) list_dump_file(const list_t *restrict l, const char *restrict filename, size_t *restrict len)
|
||||||
{
|
{
|
||||||
int fd, oflag, mode;
|
int fd, oflag, mode;
|
||||||
|
|
||||||
@ -1457,7 +1457,7 @@ int list_dump_file(const list_t *restrict l, const char *restrict filename, size
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int list_restore_file(list_t *restrict l, const char *restrict filename, size_t *restrict len)
|
KS_DECLARE(int) list_restore_file(list_t *restrict l, const char *restrict filename, size_t *restrict len)
|
||||||
{
|
{
|
||||||
int fd;
|
int fd;
|
||||||
|
|
||||||
@ -1507,38 +1507,38 @@ static int list_drop_elem(list_t *restrict l, struct list_entry_s *tmp, unsigned
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* ready-made comparators and meters */
|
/* ready-made comparators and meters */
|
||||||
#define SIMCLIST_NUMBER_COMPARATOR(type) int list_comparator_##type(const void *a, const void *b) { return( *(type *)a < *(type *)b) - (*(type *)a > *(type *)b); }
|
#define SIMCLIST_NUMBER_COMPARATOR(type) KS_DECLARE(int) list_comparator_##type(const void *a, const void *b) { return( *(type *)a < *(type *)b) - (*(type *)a > *(type *)b); }
|
||||||
|
|
||||||
SIMCLIST_NUMBER_COMPARATOR(int8_t)
|
SIMCLIST_NUMBER_COMPARATOR(int8_t)
|
||||||
SIMCLIST_NUMBER_COMPARATOR(int16_t) SIMCLIST_NUMBER_COMPARATOR(int32_t) SIMCLIST_NUMBER_COMPARATOR(int64_t)
|
SIMCLIST_NUMBER_COMPARATOR(int16_t) SIMCLIST_NUMBER_COMPARATOR(int32_t) SIMCLIST_NUMBER_COMPARATOR(int64_t)
|
||||||
SIMCLIST_NUMBER_COMPARATOR(uint8_t) SIMCLIST_NUMBER_COMPARATOR(uint16_t) SIMCLIST_NUMBER_COMPARATOR(uint32_t) SIMCLIST_NUMBER_COMPARATOR(uint64_t)
|
SIMCLIST_NUMBER_COMPARATOR(uint8_t) SIMCLIST_NUMBER_COMPARATOR(uint16_t) SIMCLIST_NUMBER_COMPARATOR(uint32_t) SIMCLIST_NUMBER_COMPARATOR(uint64_t)
|
||||||
SIMCLIST_NUMBER_COMPARATOR(float) SIMCLIST_NUMBER_COMPARATOR(double)
|
SIMCLIST_NUMBER_COMPARATOR(float) SIMCLIST_NUMBER_COMPARATOR(double)
|
||||||
|
|
||||||
int list_comparator_string(const void *a, const void *b)
|
KS_DECLARE(int) list_comparator_string(const void *a, const void *b)
|
||||||
{
|
{
|
||||||
return strcmp((const char *) b, (const char *) a);
|
return strcmp((const char *) b, (const char *) a);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ready-made metric functions */
|
/* ready-made metric functions */
|
||||||
#define SIMCLIST_METER(type) size_t list_meter_##type(const void *el) { if (el) { /* kill compiler whinge */ } return sizeof(type); }
|
#define SIMCLIST_METER(type) KS_DECLARE(size_t) list_meter_##type(const void *el) { if (el) { /* kill compiler whinge */ } return sizeof(type); }
|
||||||
|
|
||||||
SIMCLIST_METER(int8_t) SIMCLIST_METER(int16_t) SIMCLIST_METER(int32_t) SIMCLIST_METER(int64_t)
|
SIMCLIST_METER(int8_t) SIMCLIST_METER(int16_t) SIMCLIST_METER(int32_t) SIMCLIST_METER(int64_t)
|
||||||
SIMCLIST_METER(uint8_t) SIMCLIST_METER(uint16_t) SIMCLIST_METER(uint32_t) SIMCLIST_METER(uint64_t)
|
SIMCLIST_METER(uint8_t) SIMCLIST_METER(uint16_t) SIMCLIST_METER(uint32_t) SIMCLIST_METER(uint64_t)
|
||||||
SIMCLIST_METER(float) SIMCLIST_METER(double)
|
SIMCLIST_METER(float) SIMCLIST_METER(double)
|
||||||
|
|
||||||
size_t list_meter_string(const void *el)
|
KS_DECLARE(size_t) list_meter_string(const void *el)
|
||||||
{
|
{
|
||||||
return strlen((const char *) el) + 1;
|
return strlen((const char *) el) + 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ready-made hashing functions */
|
/* ready-made hashing functions */
|
||||||
#define SIMCLIST_HASHCOMPUTER(type) list_hash_t list_hashcomputer_##type(const void *el) { return (list_hash_t)(*(type *)el); }
|
#define SIMCLIST_HASHCOMPUTER(type) KS_DECLARE(list_hash_t) list_hashcomputer_##type(const void *el) { return (list_hash_t)(*(type *)el); }
|
||||||
|
|
||||||
SIMCLIST_HASHCOMPUTER(int8_t) SIMCLIST_HASHCOMPUTER(int16_t) SIMCLIST_HASHCOMPUTER(int32_t) SIMCLIST_HASHCOMPUTER(int64_t)
|
SIMCLIST_HASHCOMPUTER(int8_t) SIMCLIST_HASHCOMPUTER(int16_t) SIMCLIST_HASHCOMPUTER(int32_t) SIMCLIST_HASHCOMPUTER(int64_t)
|
||||||
SIMCLIST_HASHCOMPUTER(uint8_t) SIMCLIST_HASHCOMPUTER(uint16_t) SIMCLIST_HASHCOMPUTER(uint32_t) SIMCLIST_HASHCOMPUTER(uint64_t)
|
SIMCLIST_HASHCOMPUTER(uint8_t) SIMCLIST_HASHCOMPUTER(uint16_t) SIMCLIST_HASHCOMPUTER(uint32_t) SIMCLIST_HASHCOMPUTER(uint64_t)
|
||||||
SIMCLIST_HASHCOMPUTER(float) SIMCLIST_HASHCOMPUTER(double)
|
SIMCLIST_HASHCOMPUTER(float) SIMCLIST_HASHCOMPUTER(double)
|
||||||
|
|
||||||
list_hash_t list_hashcomputer_string(const void *el)
|
KS_DECLARE(list_hash_t) list_hashcomputer_string(const void *el)
|
||||||
{
|
{
|
||||||
size_t l;
|
size_t l;
|
||||||
list_hash_t hash = 123;
|
list_hash_t hash = 123;
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
AM_CFLAGS += -I$(abs_top_srcdir)/src/include -g -ggdb -O0 $(openssl_CFLAGS)
|
AM_CFLAGS += -I$(abs_top_srcdir)/src/include -g -ggdb -O0 $(openssl_CFLAGS)
|
||||||
TEST_LDADD = $(abs_top_builddir)/libks.la $(openssl_LIBS)
|
TEST_LDADD = $(abs_top_builddir)/libks.la $(openssl_LIBS)
|
||||||
check_PROGRAMS =
|
check_PROGRAMS =
|
||||||
|
|
||||||
EXTRA_DIST = tap.h
|
EXTRA_DIST = tap.h
|
||||||
|
|
||||||
@ -91,7 +91,7 @@ nodeidgen_LDADD = $(TEST_LDADD)
|
|||||||
|
|
||||||
#check_PROGRAMS += libtorrent_example
|
#check_PROGRAMS += libtorrent_example
|
||||||
#libtorrent_example_SOURCES = libtorrent-example.c
|
#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++
|
#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)
|
TESTS=$(check_PROGRAMS)
|
||||||
@ -103,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
|
$(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
|
g++ -c -fPIC -o $(abs_top_builddir)/test/libtorrent.o -I$(abs_top_builddir)/test/ $(abs_top_builddir)/test/libtorrent.cpp
|
||||||
|
|
||||||
|
@ -1140,11 +1140,9 @@ int main(int argc, char *argv[]) {
|
|||||||
|
|
||||||
ks_init();
|
ks_init();
|
||||||
ks_global_set_default_logger(7);
|
ks_global_set_default_logger(7);
|
||||||
|
|
||||||
ks_dht_nodeid_t homeid;
|
ks_dht_nodeid_t homeid;
|
||||||
memset(homeid.id, 0x01, KS_DHT_NODEID_SIZE);
|
memset(homeid.id, 0x01, KS_DHT_NODEID_SIZE);
|
||||||
|
|
||||||
|
|
||||||
ks_dht_create(&dht, NULL, NULL, &homeid);
|
ks_dht_create(&dht, NULL, NULL, &homeid);
|
||||||
|
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user