freeswitch/libs/libblade/test/testcon.c

418 lines
9.9 KiB
C

#include "blade.h"
#include "tap.h"
#define CONSOLE_INPUT_MAX 512
ks_bool_t g_shutdown = KS_FALSE;
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 }
};
struct testproto_s {
blade_handle_t *handle;
ks_pool_t *pool;
ks_hash_t *participants;
};
typedef struct testproto_s testproto_t;
static void testproto_cleanup(ks_pool_t *pool, void *ptr, void *arg, ks_pool_cleanup_action_t action, ks_pool_cleanup_type_t type)
{
//testproto_t *test = (testproto_t *)ptr;
//ks_assert(test);
switch (action) {
case KS_MPCL_ANNOUNCE:
break;
case KS_MPCL_TEARDOWN:
break;
case KS_MPCL_DESTROY:
break;
}
}
ks_status_t testproto_create(testproto_t **testP, blade_handle_t *bh)
{
testproto_t *test = NULL;
ks_pool_t *pool = NULL;
ks_assert(testP);
ks_assert(bh);
ks_pool_open(&pool);
ks_assert(pool);
test = ks_pool_alloc(pool, sizeof(testproto_t));
test->handle = bh;
test->pool = pool;
ks_hash_create(&test->participants, KS_HASH_MODE_CASE_INSENSITIVE, KS_HASH_FLAG_RWLOCK | KS_HASH_FLAG_DUP_CHECK | KS_HASH_FLAG_FREE_KEY, pool);
ks_pool_set_cleanup(pool, test, NULL, testproto_cleanup);
*testP = test;
return KS_STATUS_SUCCESS;
}
ks_status_t testproto_destroy(testproto_t **testP)
{
testproto_t *test = NULL;
ks_pool_t *pool = NULL;
ks_assert(testP);
ks_assert(*testP);
test = *testP;
pool = test->pool;
ks_pool_close(&pool);
*testP = NULL;
return KS_STATUS_SUCCESS;
}
ks_bool_t test_publish_response_handler(blade_rpc_response_t *brpcres, void *data)
{
//testproto_t *test = NULL;
blade_handle_t *bh = NULL;
blade_session_t *bs = NULL;
ks_assert(brpcres);
ks_assert(data);
//test = (testproto_t *)data;
bh = blade_rpc_response_handle_get(brpcres);
ks_assert(bh);
bs = blade_sessionmgr_session_lookup(blade_handle_sessionmgr_get(bh), blade_rpc_response_sessionid_get(brpcres));
ks_assert(bs);
ks_log(KS_LOG_DEBUG, "Session (%s) publish response processing\n", blade_session_id_get(bs));
blade_session_read_unlock(bs);
return KS_FALSE;
}
ks_bool_t test_join_request_handler(blade_rpc_request_t *brpcreq, void *data)
{
testproto_t *test = NULL;
blade_handle_t *bh = NULL;
blade_session_t *bs = NULL;
const char *requester_nodeid = NULL;
const char *key = NULL;
cJSON *params = NULL;
cJSON *result = NULL;
ks_assert(brpcreq);
ks_assert(data);
test = (testproto_t *)data;
bh = blade_rpc_request_handle_get(brpcreq);
ks_assert(bh);
bs = blade_sessionmgr_session_lookup(blade_handle_sessionmgr_get(bh), blade_rpc_request_sessionid_get(brpcreq));
ks_assert(bs);
requester_nodeid = blade_rpcexecute_request_requester_nodeid_get(brpcreq);
ks_assert(requester_nodeid);
params = blade_rpcexecute_request_params_get(brpcreq);
ks_assert(params);
ks_log(KS_LOG_DEBUG, "Session (%s) test.join request processing\n", blade_session_id_get(bs));
key = ks_pstrdup(test->pool, requester_nodeid);
ks_assert(key);
ks_hash_write_lock(test->participants);
ks_hash_insert(test->participants, (void *)key, (void *)KS_TRUE);
ks_hash_write_unlock(test->participants);
blade_session_read_unlock(bs);
result = cJSON_CreateObject();
blade_rpcexecute_response_send(brpcreq, result);
params = cJSON_CreateObject();
blade_handle_rpcbroadcast(bh, requester_nodeid, "test.join", "test", "mydomain.com", params, NULL, NULL);
return KS_FALSE;
}
ks_bool_t test_leave_request_handler(blade_rpc_request_t *brpcreq, void *data)
{
testproto_t *test = NULL;
blade_handle_t *bh = NULL;
blade_session_t *bs = NULL;
const char *requester_nodeid = NULL;
//const char *key = NULL;
cJSON *params = NULL;
cJSON *result = NULL;
ks_assert(brpcreq);
ks_assert(data);
test = (testproto_t *)data;
bh = blade_rpc_request_handle_get(brpcreq);
ks_assert(bh);
bs = blade_sessionmgr_session_lookup(blade_handle_sessionmgr_get(bh), blade_rpc_request_sessionid_get(brpcreq));
ks_assert(bs);
requester_nodeid = blade_rpcexecute_request_requester_nodeid_get(brpcreq);
ks_assert(requester_nodeid);
params = blade_rpcexecute_request_params_get(brpcreq);
ks_assert(params);
ks_log(KS_LOG_DEBUG, "Session (%s) test.leave (%s) request processing\n", blade_session_id_get(bs), requester_nodeid);
ks_hash_write_lock(test->participants);
ks_hash_remove(test->participants, (void *)requester_nodeid);
ks_hash_write_unlock(test->participants);
blade_session_read_unlock(bs);
result = cJSON_CreateObject();
blade_rpcexecute_response_send(brpcreq, result);
params = cJSON_CreateObject();
blade_handle_rpcbroadcast(bh, requester_nodeid, "test.leave", "test", "mydomain.com", params, NULL, NULL);
return KS_FALSE;
}
ks_bool_t test_talk_request_handler(blade_rpc_request_t *brpcreq, void *data)
{
//testproto_t *test = NULL;
blade_handle_t *bh = NULL;
blade_session_t *bs = NULL;
const char *requester_nodeid = NULL;
const char *text = NULL;
cJSON *params = NULL;
cJSON *result = NULL;
ks_assert(brpcreq);
ks_assert(data);
//test = (testproto_t *)data;
bh = blade_rpc_request_handle_get(brpcreq);
ks_assert(bh);
bs = blade_sessionmgr_session_lookup(blade_handle_sessionmgr_get(bh), blade_rpc_request_sessionid_get(brpcreq));
ks_assert(bs);
requester_nodeid = blade_rpcexecute_request_requester_nodeid_get(brpcreq);
ks_assert(requester_nodeid);
params = blade_rpcexecute_request_params_get(brpcreq);
ks_assert(params);
text = cJSON_GetObjectCstr(params, "text");
ks_assert(text);
ks_log(KS_LOG_DEBUG, "Session (%s) test.talk (%s) request processing\n", blade_session_id_get(bs), requester_nodeid);
blade_session_read_unlock(bs);
result = cJSON_CreateObject();
blade_rpcexecute_response_send(brpcreq, result);
params = cJSON_CreateObject();
cJSON_AddStringToObject(params, "text", text);
blade_handle_rpcbroadcast(bh, requester_nodeid, "test.talk", "test", "mydomain.com", params, NULL, NULL);
return KS_FALSE;
}
int main(int argc, char **argv)
{
blade_handle_t *bh = NULL;
ks_pool_t *pool = NULL;
config_t config;
config_setting_t *config_blade = NULL;
const char *cfgpath = "testcon.cfg";
const char *autoconnect = NULL;
testproto_t *test = NULL;
ks_global_set_default_logger(KS_LOG_LEVEL_DEBUG);
blade_init();
blade_handle_create(&bh);
ks_assert(bh);
pool = blade_handle_pool_get(bh);
ks_assert(pool);
if (argc > 1) autoconnect = 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;
}
testproto_create(&test, bh);
if (autoconnect) {
blade_connection_t *bc = NULL;
blade_identity_t *target = NULL;
ks_bool_t connected = KS_FALSE;
blade_rpc_t *brpc = NULL;
blade_identity_create(&target, blade_handle_pool_get(bh));
if (blade_identity_parse(target, autoconnect) == KS_STATUS_SUCCESS) connected = blade_handle_connect(bh, &bc, target, NULL) == KS_STATUS_SUCCESS;
blade_identity_destroy(&target);
if (connected) {
// @todo use session state change callback to know when the session is ready and the realm(s) available from blade.connect, this hack temporarily ensures it's ready before trying to publish upstream
ks_sleep_ms(3000);
blade_rpc_create(&brpc, bh, "test.join", "test", "mydomain.com", test_join_request_handler, test);
blade_rpcmgr_protocolrpc_add(blade_handle_rpcmgr_get(bh), brpc);
blade_rpc_create(&brpc, bh, "test.leave", "test", "mydomain.com", test_leave_request_handler, test);
blade_rpcmgr_protocolrpc_add(blade_handle_rpcmgr_get(bh), brpc);
blade_rpc_create(&brpc, bh, "test.talk", "test", "mydomain.com", test_talk_request_handler, test);
blade_rpcmgr_protocolrpc_add(blade_handle_rpcmgr_get(bh), brpc);
blade_handle_rpcpublish(bh, "test", "mydomain.com", test_publish_response_handler, test);
}
}
loop(bh);
blade_handle_destroy(&bh);
testproto_destroy(&test);
config_destroy(&config);
blade_shutdown();
return 0;
}
void loop(blade_handle_t *bh)
{
char buf[CONSOLE_INPUT_MAX];
while (!g_shutdown) {
if (!fgets(buf, CONSOLE_INPUT_MAX, stdin)) break;
for (int index = 0; buf[index]; ++index) {
if (buf[index] == '\r' || buf[index] == '\n') {
buf[index] = '\0';
break;
}
}
process_console_input(bh, buf);
}
}
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;
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);
g_shutdown = KS_TRUE;
}
/* 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:
*/