* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
+/*
+ * Usage notes
+ *
+ * ks_rpcmessaging_handle_t *handle;
+ *
+ * ks_rpcmessage_init(pool, &handle);
+ *
+ * ks_rpcmessage_version(handle, version);
+ * ks_rpcmessage_namespace(handle, application_namespace);
+ * ks_rpcmessage_register_function(handle, "invite", handle_invite_message);
+ * ks_rpcmessage_register_function(handle, "media", handle_media_message);
+ *
+ * ...
+ * cJSON* request = NULL;
+ * cJSON* parms = NULL;
+ * cJSON* response = NULL;
+ *
+ * request = ks_rpcmessage_create_request(h, "invite", &parms, &request);
+ * cJSON_AddStringToObject(parms, "hello", "cruel world");
+ * ... and send
+ *
+ *
+ * static ks_status_t handle_..._message(ks_rpcmessaging_handle_t* handle, cJSON *msg, cJSON **response)
+ * {
+ * cJSON *respvalue = cJSON_CreateNumber(1);
+ * cJSON *x = *response = ks_rpcmessage_create_response(h, msg, &respvalue, response);
+ * if ( x == NULL) {
+ * return KS_STATUS_FAIL;
+ * }
+ * ...
+ * return KS_STATUS_SUCCESS;
+ * }
+
+ *
+ *
+ *
+ *
+ *
+ *
+ * ...
+ * ks_rpcmessage_deinit(&handle);
+ *
+ */
+
+
+
+
#ifndef _KS_RPCMESSAGE_H_
#define _KS_RPCMESSAGE_H_
typedef struct ks_rpcmessaging_handle_s ks_rpcmessaging_handle_t;
+typedef uint32_t ks_rpcmessage_id;
-
-typedef ks_status_t (*jrpc_func_t)(ks_rpcmessaging_handle_t* handle, cJSON *params, cJSON **responseP);
-
+typedef ks_status_t (*jrpc_func_t)(ks_rpcmessaging_handle_t* handle, cJSON *request, cJSON **responseP);
+typedef ks_status_t (*jrpc_resp_func_t)(ks_rpcmessaging_handle_t* handle, cJSON *response);
KS_DECLARE(ks_rpcmessaging_handle_t *) ks_rpcmessage_init(ks_pool_t* pool, ks_rpcmessaging_handle_t** handleP);
KS_DECLARE(void) ks_rpcmessage_deinit(ks_rpcmessaging_handle_t** handleP);
-KS_DECLARE(cJSON *)ks_rpcmessage_new_request(ks_rpcmessaging_handle_t* handle,
+KS_DECLARE(ks_status_t)ks_rpcmessage_namespace(ks_rpcmessaging_handle_t* handle, const char* namespace, const char* version);
+
+KS_DECLARE(ks_rpcmessage_id)ks_rpcmessage_create_request(ks_rpcmessaging_handle_t* handle,
const char *method,
cJSON **parmsP,
cJSON **requestP);
-KS_DECLARE(cJSON *)ks_rpcmessage_new_response(ks_rpcmessaging_handle_t* handle,
+KS_DECLARE(ks_rpcmessage_id)ks_rpcmessage_create_response(ks_rpcmessaging_handle_t* handle,
const cJSON *request,
- cJSON *result,
+ cJSON **resultP,
cJSON **responseP);
+KS_DECLARE(ks_rpcmessage_id)ks_rpcmessage_create_errorresponse(ks_rpcmessaging_handle_t* handle,
+ const cJSON *request,
+ cJSON **errorP,
+ cJSON **responseP);
-KS_DECLARE(ks_status_t)ks_rpcmessage_namespace(ks_rpcmessaging_handle_t* handle, const char* namespace);
+KS_DECLARE(ks_status_t)ks_rpcmessage_register_function(ks_rpcmessaging_handle_t* handle,
+ const char *command,
+ jrpc_func_t func,
+ jrpc_resp_func_t respfunc);
-KS_DECLARE(ks_status_t)ks_rpcmessage_register_function(ks_rpcmessaging_handle_t* handle, const char *command, jrpc_func_t func);
KS_DECLARE(jrpc_func_t) ks_rpcmessage_find_function(ks_rpcmessaging_handle_t* handle, const char *command);
+KS_DECLARE(jrpc_resp_func_t) ks_rpcmessage_find_response_function(ks_rpcmessaging_handle_t* handle, const char *command);
-KS_DECLARE(ks_status_t) ks_rpcmessage_process_request(ks_rpcmessaging_handle_t* handle,
+KS_DECLARE(ks_status_t) ks_rpcmessage_process_message(ks_rpcmessaging_handle_t* handle,
uint8_t *data,
ks_size_t size,
cJSON **responseP);
-KS_DECLARE(ks_status_t) ks_rpcmessage_process_jsonrequest(ks_rpcmessaging_handle_t* handle, cJSON *request, cJSON **responseP);
+KS_DECLARE(ks_status_t) ks_rpcmessage_process_jsonmessage(ks_rpcmessaging_handle_t* handle, cJSON *request, cJSON **responseP);
KS_END_EXTERN_C
#include <ks_rpcmessage.h>
#define KS_RPCMESSAGE_NAMESPACE_LENGTH 16
-
+#define KS_PRCMESSAGE_COMMAND_LENGTH 238
+#define KS_PRCMESSAGE_FQCOMMAND_LENGTH KS_RPCMESSAGE_NAMESPACE_LENGTH + 1 + KS_PRCMESSAGE_COMMAND_LENGTH
+#define KS_RPCMESSAGE_VERSION_LENGTH 9
struct ks_rpcmessaging_handle_s
{
ks_pool_t *pool;
char namespace[KS_RPCMESSAGE_NAMESPACE_LENGTH+2];
+ char version[KS_RPCMESSAGE_VERSION_LENGTH+1]; /* nnn.nn.nn */
};
+typedef struct ks_rpcmessage_callbackpair_s
+{
+ jrpc_func_t request_func;
+ jrpc_resp_func_t response_func;
+ uint16_t command_length;
+ char command[1];
+} ks_rpcmessage_callbackpair_t;
+
static uint32_t ks_rpcmessage_next_id(ks_rpcmessaging_handle_t* handle)
{
ks_hash_create(&handle->method_hash,
KS_HASH_MODE_CASE_SENSITIVE,
- KS_HASH_FLAG_RWLOCK + KS_HASH_FLAG_DUP_CHECK + KS_HASH_FLAG_FREE_KEY,
+ KS_HASH_FLAG_RWLOCK + KS_HASH_FLAG_DUP_CHECK + KS_HASH_FLAG_FREE_VALUE,
pool);
ks_mutex_create(&handle->id_mutex, KS_MUTEX_FLAG_DEFAULT, pool);
return obj;
}
+static ks_bool_t ks_rpcmessage_isrequest(cJSON *msg)
+{
+ //cJSON *params = cJSON_GetObjectItem(msg, "param");
+ cJSON *result = cJSON_GetObjectItem(msg, "result");
+ cJSON *error = cJSON_GetObjectItem(msg, "error");
+
+ if (result || error) {
+ return KS_FALSE;
+ }
+
+ return KS_TRUE;
+}
+
-KS_DECLARE(cJSON *) ks_rpcmessage_new_request(ks_rpcmessaging_handle_t* handle,
+
+KS_DECLARE(ks_rpcmessage_id) ks_rpcmessage_create_request(ks_rpcmessaging_handle_t* handle,
const char *command,
cJSON **paramsP,
- cJSON **request)
+ cJSON **requestP)
{
cJSON *msg, *params = NULL;
- *request = NULL;
+ *requestP = NULL;
if (!ks_rpcmessage_find_function(handle, command)) {
ks_log(KS_LOG_ERROR, "Attempt to create unknown message type : %s, namespace %s\n", command, handle->namespace);
- return NULL;
+ return 0;
}
- msg = ks_rpcmessage_new(ks_rpcmessage_next_id(handle));
+ ks_rpcmessage_id msgid = ks_rpcmessage_next_id(handle);
+ msg = ks_rpcmessage_new(msgid);
if (paramsP && *paramsP) {
params = *paramsP;
params = cJSON_CreateObject();
}
- cJSON_AddItemToObject(msg, "method", cJSON_CreateString(command));
+ char fqcommand[KS_PRCMESSAGE_FQCOMMAND_LENGTH];
+ memset(fqcommand, 0, sizeof(fqcommand));
+
+ if (handle->namespace[0] != 0) {
+ strcpy(fqcommand, handle->namespace);
+ }
+
+ strcat(fqcommand, command);
+
+ cJSON_AddItemToObject(msg, "method", cJSON_CreateString(fqcommand));
cJSON_AddItemToObject(msg, "params", params);
+ if (handle->version[0] != 0) {
+ cJSON_AddItemToObject(msg, "version", cJSON_CreateString(handle->version));
+ }
+
if (paramsP) {
*paramsP = params;
}
- return msg;
+ *requestP = msg;
+ return msgid;
}
-KS_DECLARE(cJSON *) ks_rpcmessage_new_response(ks_rpcmessaging_handle_t* handle,
- const cJSON *request,
- cJSON *result,
- cJSON **pmsg)
+static ks_rpcmessage_id ks_rpcmessage_get_messageid(const cJSON *msg, cJSON **cmsgidP)
{
- cJSON *respmsg = NULL;
- cJSON *msgid = cJSON_GetObjectItem(request, "id");
- cJSON *command = cJSON_GetObjectItem(request, "method");
-
- if (!msgid || !command) {
- return NULL;
+ uint32_t msgid = 0;
+
+ cJSON *cmsgid = cJSON_GetObjectItem(msg, "id");
+
+ if (cmsgid->type == cJSON_Number) {
+ msgid = (uint32_t) cmsgid->valueint;
}
-
- *pmsg = respmsg = ks_rpcmessage_dup(msgid);
+
+ *cmsgidP = cmsgid;
+
+ return msgid;
+}
+
+
+static ks_rpcmessage_id ks_rpcmessage_new_response(ks_rpcmessaging_handle_t* handle,
+ const cJSON *request,
+ cJSON *result,
+ cJSON **pmsg)
+{
+ cJSON *respmsg = NULL;
+ cJSON *cmsgid = NULL;
+ cJSON *command = cJSON_GetObjectItem(request, "method");
+
+ ks_rpcmessage_id msgid = ks_rpcmessage_get_messageid(request, &cmsgid );
+
+ if (!msgid || !command) {
+ return 0;
+ }
+
+ *pmsg = respmsg = ks_rpcmessage_dup(cmsgid);
cJSON_AddItemToObject(respmsg, "method", cJSON_Duplicate(command, 0));
- if (result) {
- cJSON_AddItemToObject(respmsg, "result", result);
+ if (handle->version[0] != 0) {
+ cJSON_AddItemToObject(respmsg, "version", cJSON_CreateString(handle->version));
+ }
+
+ if (result) {
+ cJSON_AddItemToObject(respmsg, "result", result);
+ }
+
+ return msgid;
+}
+
+
+KS_DECLARE(ks_rpcmessage_id) ks_rpcmessage_create_response(ks_rpcmessaging_handle_t* handle,
+ const cJSON *request,
+ cJSON **resultP,
+ cJSON **responseP)
+{
+ ks_rpcmessage_id msgid = ks_rpcmessage_new_response(handle, request, *resultP, responseP);
+ cJSON *respmsg = *responseP;
+
+ if (msgid) {
+
+ if (*resultP == NULL) {
+ *resultP = cJSON_CreateObject();
+ cJSON_AddItemToObject(respmsg, "result", *resultP);
+ }
}
- return respmsg;
+ return msgid;
}
-KS_DECLARE(ks_status_t) ks_rpcmessage_namespace(ks_rpcmessaging_handle_t* handle, const char* namespace)
+KS_DECLARE(ks_rpcmessage_id) ks_rpcmessage_create_errorresponse(ks_rpcmessaging_handle_t* handle,
+ const cJSON *request,
+ cJSON **errorP,
+ cJSON **responseP)
+{
+ ks_rpcmessage_id msgid = ks_rpcmessage_new_response(handle, request, *errorP, responseP);
+ cJSON *respmsg = *responseP;
+
+ if (msgid) {
+
+ if (*errorP == NULL) {
+ *errorP = cJSON_CreateObject();
+ cJSON_AddItemToObject(respmsg, "error", *errorP);
+ }
+ }
+
+ return msgid;
+}
+
+KS_DECLARE(ks_status_t) ks_rpcmessage_namespace(ks_rpcmessaging_handle_t* handle, const char* namespace, const char* version)
{
+ memset(handle->namespace, 0, sizeof(handle->namespace));
+ memset(handle->version, 0, sizeof(handle->version));
- strncpy(handle->namespace, namespace, sizeof(KS_RPCMESSAGE_NAMESPACE_LENGTH));
- handle->namespace[KS_RPCMESSAGE_NAMESPACE_LENGTH] = 0;
- ks_log(KS_LOG_DEBUG, "Setting message namespace value %s", handle->namespace);
+ strncpy(handle->namespace, namespace, KS_RPCMESSAGE_NAMESPACE_LENGTH);
+ strncpy(handle->version, version, KS_RPCMESSAGE_VERSION_LENGTH);
+ handle->namespace[sizeof(handle->namespace) - 1] = 0;
+ handle->version[sizeof(handle->version) -1] = 0;
+
+ ks_log(KS_LOG_DEBUG, "Setting message namespace value %s, version %s", handle->namespace, handle->version);
strcat( handle->namespace, ".");
return KS_STATUS_SUCCESS;
}
-KS_DECLARE(ks_status_t) ks_rpcmessage_register_function(ks_rpcmessaging_handle_t* handle, const char *command, jrpc_func_t func)
+KS_DECLARE(ks_status_t) ks_rpcmessage_register_function(ks_rpcmessaging_handle_t* handle,
+ const char *command,
+ jrpc_func_t func,
+ jrpc_resp_func_t respfunc)
{
- char fqcommand[256];
+ if (!func && !respfunc) {
+ return KS_STATUS_FAIL;
+ }
+
+ char fqcommand[KS_PRCMESSAGE_FQCOMMAND_LENGTH];
memset(fqcommand, 0, sizeof(fqcommand));
if (handle->namespace[0] != 0) {
lkey = 16;
}
- char *key = (char*)ks_pool_alloc(handle->pool, lkey);
- strcpy(key, fqcommand);
+ ks_rpcmessage_callbackpair_t* callbacks =
+ (ks_rpcmessage_callbackpair_t*)ks_pool_alloc(handle->pool, lkey + sizeof(ks_rpcmessage_callbackpair_t));
+
+ strcpy(callbacks->command, fqcommand);
+ callbacks->command_length = lkey;
+ callbacks->request_func = func;
+ callbacks->response_func = respfunc;
ks_hash_write_lock(handle->method_hash);
- ks_hash_insert(handle->method_hash, key, (void *) (intptr_t)func);
+ ks_hash_insert(handle->method_hash, callbacks->command, (void *) callbacks);
+
ks_hash_write_unlock(handle->method_hash);
ks_log(KS_LOG_DEBUG, "Message %s registered (%s)\n", command, fqcommand);
return KS_STATUS_SUCCESS;
}
+static ks_rpcmessage_callbackpair_t* ks_rpcmessage_find_function_ex(ks_rpcmessaging_handle_t* handle, char *command)
+{
+ ks_hash_read_lock(handle->method_hash);
+
+ ks_rpcmessage_callbackpair_t* callbacks = ks_hash_search(handle->method_hash, command, KS_UNLOCKED);
+
+ ks_hash_read_unlock(handle->method_hash);
+
+ return callbacks;
+}
+
KS_DECLARE(jrpc_func_t) ks_rpcmessage_find_function(ks_rpcmessaging_handle_t* handle, const char *command)
{
- char fqcommand[256];
- memset(fqcommand, 0, sizeof(fqcommand));
+ char fqcommand[KS_PRCMESSAGE_FQCOMMAND_LENGTH];
+ memset(fqcommand, 0, sizeof(fqcommand));
if (handle->namespace[0] != 0) {
strcpy(fqcommand, handle->namespace);
+ strcat(fqcommand, command);
}
-
- strcat(fqcommand, command);
+ else {
+ strcpy(fqcommand, command);
+ }
- ks_hash_read_lock(handle->method_hash);
- jrpc_func_t func = (jrpc_func_t) (intptr_t) ks_hash_search(handle->method_hash, fqcommand, KS_UNLOCKED);
+ ks_rpcmessage_callbackpair_t* callbacks = ks_rpcmessage_find_function_ex(handle, (char *)fqcommand);
- ks_hash_read_unlock(handle->method_hash);
+ if (!callbacks) {
+ return NULL;
+ }
- return func;
+ return callbacks->request_func;
}
-KS_DECLARE(ks_status_t) ks_rpcmessage_process_jsonrequest(ks_rpcmessaging_handle_t* handle, cJSON *request, cJSON **responseP)
+KS_DECLARE(jrpc_resp_func_t) ks_rpcmessage_find_response_function(ks_rpcmessaging_handle_t* handle, const char *command)
+{
+ char fqcommand[KS_PRCMESSAGE_FQCOMMAND_LENGTH];
+ memset(fqcommand, 0, sizeof(fqcommand));
+
+ if (handle->namespace[0] != 0) {
+ strcpy(fqcommand, handle->namespace);
+ strcat(fqcommand, command);
+ }
+ else {
+ strcpy(fqcommand, command);
+ }
+
+ ks_rpcmessage_callbackpair_t* callbacks = ks_rpcmessage_find_function_ex(handle, (char *)fqcommand);
+
+ return callbacks->response_func;
+}
+
+
+KS_DECLARE(ks_status_t) ks_rpcmessage_process_jsonmessage(ks_rpcmessaging_handle_t* handle, cJSON *request, cJSON **responseP)
{
const char *command = cJSON_GetObjectCstr(request, "method");
cJSON *error = NULL;
//todo - add more checks ?
if (error) {
- *responseP = response = ks_rpcmessage_new_request(handle, 0, &error, &response);
+ ks_rpcmessage_create_request(handle, 0, &error, &response);
return KS_STATUS_FAIL;
}
- jrpc_func_t func = ks_rpcmessage_find_function(handle, command);
- if (!func) {
+
+ ks_rpcmessage_callbackpair_t* callbacks = ks_rpcmessage_find_function_ex(handle, (char *)command);
+
+ if (!callbacks) {
error = cJSON_CreateString("Command not supported");
+ return KS_STATUS_FAIL;
+ }
+
+ ks_bool_t isrequest = ks_rpcmessage_isrequest(request);
+
+ if (isrequest && callbacks->request_func) {
+ return callbacks->request_func(handle, request, responseP);
+ }
+ else if (!isrequest && callbacks->response_func) {
+ return callbacks->response_func(handle, request);
}
- return func(handle, request, responseP);
+ return KS_STATUS_FAIL;
}
-KS_DECLARE(ks_status_t) ks_rpcmessage_process_request(ks_rpcmessaging_handle_t* handle,
+KS_DECLARE(ks_status_t) ks_rpcmessage_process_message(ks_rpcmessaging_handle_t* handle,
uint8_t *data,
ks_size_t size,
cJSON **responseP)
if (!request) {
error = cJSON_CreateString("Invalid json format");
- *responseP = response = ks_rpcmessage_new_request(handle, 0, &error, &response);
+ ks_rpcmessage_create_request(handle, 0, &error, &response);
return KS_STATUS_FAIL;
}
- ks_status_t status = ks_rpcmessage_process_jsonrequest(handle, request, responseP);
+ ks_status_t status = ks_rpcmessage_process_jsonmessage(handle, request, responseP);
cJSON_Delete(request);
--- /dev/null
+#pragma GCC diagnostic ignored "-Wunused-but-set-variable"
+#pragma GCC diagnostic ignored "-Wunused-variable"
+#pragma GCC diagnostic ignored "-Wunused-function"
+
+#include "../src/include/ks_rpcmessage.h"
+
+#pragma GCC optimize ("O0")
+
+
+ks_pool_t *pool;
+ks_thread_pool_t *tpool;
+
+ks_rpcmessaging_handle_t *h;
+
+static ks_thread_t *threads[10];
+
+static char idbuffer[51];
+
+
+static ks_status_t process_wombat_response(ks_rpcmessaging_handle_t* handle, cJSON *msg)
+{
+ printf("entering process_wombat_response\n");
+ printf("exiting process_wombat_response\n");
+ return KS_STATUS_FAIL;
+}
+
+static ks_status_t process_wombat(ks_rpcmessaging_handle_t* handle, cJSON *msg, cJSON **response)
+{
+ printf("entering process_wombat\n");
+
+ char *b0 = cJSON_Print(msg);
+ printf("Request: %s\n", b0);
+ free(b0);
+
+ cJSON *msg_id = cJSON_GetObjectItem(msg, "id");
+ if (msg_id) {
+ if (msg_id->type == cJSON_Number) {
+ printf("Number int %d double %f\n", msg_id->valueint, msg_id->valuedouble);
+ }
+ }
+
+ cJSON *respvalue = cJSON_CreateNumber(1);
+
+ ks_rpcmessage_id msgid = ks_rpcmessage_create_response(h, msg, &respvalue, response);
+
+ char *b1 = cJSON_Print(*response); //(*response);
+ printf("Response: msgid %d\n%s\n", msgid, b1);
+ free(b1);
+
+ printf("exiting process_wombat\n");
+
+ return KS_STATUS_SUCCESS;
+}
+
+static ks_status_t process_badbunny(ks_rpcmessaging_handle_t* handle, cJSON *msg, cJSON **response)
+{
+ printf("entering process_badbunny\n");
+
+ char *b0 = cJSON_Print(msg);
+ printf("Request: %s\n", b0);
+ free(b0);
+
+ cJSON *msg_id = cJSON_GetObjectItem(msg, "id");
+ if (msg_id) {
+ if (msg_id->type == cJSON_Number) {
+ printf("Number int %d double %f\n", msg_id->valueint, msg_id->valuedouble);
+ }
+ }
+
+ cJSON *respvalue;
+
+ ks_rpcmessage_id msgid = ks_rpcmessage_create_errorresponse(h, msg, &respvalue, response);
+
+ char *b2 = cJSON_Print(*response);
+ printf("Request: msgid %d\n%s\n", msgid, b2);
+ free(b2);
+
+ //cJSON *respvalue = cJSON_CreateNumber(1);
+
+
+ char *b1 = cJSON_Print(*response); //(*response);
+ printf("Response: %s\n", b1);
+ free(b1);
+
+ printf("exiting process_badbunny\n");
+
+
+ return KS_STATUS_SUCCESS;
+}
+
+
+void test01()
+{
+ printf("**** testrpcmessages - test01 start\n"); fflush(stdout);
+
+ ks_rpcmessage_register_function(h, "wombat", process_wombat, process_wombat_response);
+ ks_rpcmessage_register_function(h, "badbunny", process_badbunny, NULL);
+ ks_rpcmessage_register_function(h, "onewaywombat", NULL, process_wombat_response);
+
+ cJSON* request = NULL;
+ cJSON* parms = NULL;
+ cJSON* response = NULL;
+
+ /* try an invalid message */
+
+ ks_rpcmessage_id msgid = ks_rpcmessage_create_request(h, "colm", &parms, &request);
+ if (msgid != 0) {
+ printf("invalid message created %d\n", msgid);
+ printf("request:\n%s\n", cJSON_Print(request));
+ }
+
+ /* try a basic message */
+
+ msgid = ks_rpcmessage_create_request(h, "wombat", &parms, &request);
+ if (msgid == 0) {
+ printf("failed to create a wombat\n");
+ return;
+ }
+
+ cJSON_AddStringToObject(parms, "hello", "cruel world");
+ char* data = cJSON_PrintUnformatted(request);
+
+ printf("\ntest01 request: %d\n%s\n\n", msgid, data);
+
+ /* process message */
+
+ ks_size_t size = strlen(data);
+ ks_status_t status = ks_rpcmessage_process_message(h, (uint8_t*)data, size, &response);
+
+ char* data1 = cJSON_Print(response);
+ ks_size_t size1 = strlen(data1);
+ printf("\ntest01i response: %d\n%s\n\n", msgid, data1);
+
+ /* process response */
+
+ ks_status_t status1 = ks_rpcmessage_process_message(h, (uint8_t*)data1, size1, &response);
+
+ free(data);
+ free(data1);
+ cJSON_Delete(request);
+
+ /* create message 2 */
+
+ cJSON *parms1 = cJSON_CreateNumber(1);
+ cJSON *request1 = NULL;
+
+ msgid = ks_rpcmessage_create_request(h, "badbunny", &parms1, &request1);
+
+ data = cJSON_PrintUnformatted(request1);
+ printf("\ntest01i request: %d\n%s\n\n", msgid, data);
+
+ /* process message 2 */
+
+ size = strlen(data);
+ status = ks_rpcmessage_process_message(h, (uint8_t*)data, size, &response);
+
+ data1 = cJSON_PrintUnformatted(response);
+ printf("\ntest01 response: %d\n%s\n\n", msgid, data1);
+
+ /* process response 2 - no handler so this should fail */
+
+ size1 = strlen(data1);
+
+ status = ks_rpcmessage_process_message(h, (uint8_t*)data1, size1, &response);
+
+ if (status != KS_STATUS_FAIL) {
+ printf("badbunny found a response handler ?\n");
+ }
+
+ free(data);
+ free(data1);
+ cJSON_Delete(request1);
+
+
+ printf("**** testrpcmessages - test01 complete\n\n\n"); fflush(stdout);
+}
+
+void test02()
+{
+ printf("**** testmessages - test02 start\n"); fflush(stdout);
+
+ printf("**** testmessages - test02 finished\n"); fflush(stdout);
+
+ return;
+}
+
+
+
+
+/* test06 */
+/* ------ */
+
+static void *testnodelocking_ex1(ks_thread_t *thread, void *data)
+{
+ return NULL;
+}
+
+static void *testnodelocking_ex2(ks_thread_t *thread, void *data)
+{
+ return NULL;
+}
+
+
+void test06()
+{
+ printf("**** testmessages - test06 start\n"); fflush(stdout);
+
+ ks_thread_t *t0;
+ ks_thread_create(&t0, testnodelocking_ex1, NULL, pool);
+
+ ks_thread_t *t1;
+ ks_thread_create(&t1, testnodelocking_ex2, NULL, pool);
+
+ ks_thread_join(t1);
+ ks_thread_join(t0);
+
+ printf("\n\n* **testmessages - test06 -- threads complete\n\n"); fflush(stdout);
+
+ printf("**** testmessages - test06 start\n"); fflush(stdout);
+
+ return;
+}
+
+
+
+int main(int argc, char *argv[]) {
+
+ printf("testmessages - start\n");
+
+ int tests[100];
+ if (argc == 0) {
+ tests[0] = 1;
+ tests[1] = 2;
+ tests[2] = 3;
+ tests[3] = 4;
+ tests[4] = 5;
+ }
+ else {
+ for(int tix=1; tix<100 && tix<argc; ++tix) {
+ long i = strtol(argv[tix], NULL, 0);
+ tests[tix] = i;
+ }
+ }
+
+ ks_init();
+ ks_global_set_default_logger(7);
+
+
+ ks_status_t status;
+
+ status = ks_pool_open(&pool);
+
+
+ for (int tix=0; tix<argc; ++tix) {
+
+ if (tests[tix] == 1) {
+ ks_rpcmessage_init(pool, &h);
+ test01();
+ ks_rpcmessage_deinit(&h);
+ continue;
+ }
+
+ if (tests[tix] == 2) {
+ ks_rpcmessage_init(pool, &h);
+ test02();
+ ks_rpcmessage_deinit(&h);
+ continue;
+ }
+
+ }
+
+ return 0;
+}