]> git.ipfire.org Git - thirdparty/freeswitch.git/commitdiff
FS-9952: Add blade extention to rpc messages
authorcolm <colm@freeswitch1>
Tue, 14 Feb 2017 20:40:00 +0000 (15:40 -0500)
committerMike Jerris <mike@jerris.com>
Wed, 22 Mar 2017 21:42:49 +0000 (17:42 -0400)
libs/libblade/src/blade_rpcproto.c
libs/libblade/src/include/blade_rpcproto.h
libs/libblade/test/testrpcproto.c
libs/libks/src/include/ks_rpcmessage.h
libs/libks/src/ks_rpcmessage.c
libs/libks/test/testmessages.c

index 53b546663c7e5cd367a9827b01742fd42a9f70e8..e955fffb56e111774eb0d8dba50f78706f02774a 100644 (file)
@@ -34,7 +34,6 @@
 #pragma GCC optimize ("O0")
 
 #include <blade_rpcproto.h>
-#include <blade_message.h>
 
 /* 
  * internal shared structure grounded in global 
@@ -700,6 +699,172 @@ KS_DECLARE(ks_status_t)blade_rpc_inherit_template(char *namespace, char* templat
 }
                
 
+/*
+ * create a request message
+ */
+KS_DECLARE(ks_rpcmessageid_t) blade_rpc_create_request(char *namespace,
+                                                    char *method,
+                                                    blade_rpc_fields_t* fields,
+                                                    cJSON **paramsP,
+                                                    cJSON **requestP)
+{
+       cJSON *jversion = NULL;
+       blade_rpc_callbackpair_t* callbacks = NULL;
+
+       *requestP = NULL;
+
+    ks_hash_read_lock(g_handle->namespace_hash);
+    blade_rpc_namespace_t *n =  ks_hash_search(g_handle->namespace_hash, namespace, KS_UNLOCKED);
+
+       if (n) {
+               ks_hash_read_lock(n->method_hash);
+               callbacks = ks_hash_search(n->method_hash, method, KS_UNLOCKED);                                
+               if (callbacks) {
+                       jversion = cJSON_CreateString(n->version);
+               }
+               ks_hash_read_unlock(n->method_hash);
+       }
+
+       ks_hash_read_unlock(g_handle->namespace_hash);
+
+       if (!n) {
+               ks_log(KS_LOG_ERROR, "No namespace %s found\n", namespace);
+               return 0;
+       }       
+
+       if (!callbacks) {
+        ks_log(KS_LOG_ERROR, "No method %s.%s found\n", namespace, method);
+        return 0;
+       }
+
+       ks_rpcmessageid_t msgid = ks_rpcmessage_create_request(namespace, method, paramsP, requestP);
+       
+       if (!msgid || *requestP == NULL) {
+               ks_log(KS_LOG_ERROR, "Unable to create rpc message for method %s.%s\n", namespace, method);
+               return 0;               
+       }
+  
+       cJSON *jfields = cJSON_CreateObject();
+
+       cJSON_AddItemToObject(jfields, "version", jversion);
+
+       if (fields->to) {
+               cJSON_AddStringToObject(jfields, "to", fields->to);
+       }
+
+       if (fields->from) {
+               cJSON_AddStringToObject(jfields, "from", fields->from);
+       }
+
+    if (fields->token) {
+        cJSON_AddStringToObject(jfields, "token", fields->token);
+    }
+
+        cJSON_AddItemToObject(*requestP, "blade", jfields);
+
+       return msgid;
+}
+
+KS_DECLARE(ks_rpcmessageid_t) blade_rpc_create_response(cJSON *request,
+                                                    cJSON **replyP,
+                                                    cJSON **responseP)
+{
+       cJSON *jfields = cJSON_GetObjectItem(request, "blade");
+
+       if (!jfields) {
+               ks_log(KS_LOG_ERROR, "No blade routing info found.  Unable to create response\n");
+               return 0;       
+       }
+
+       ks_rpcmessageid_t msgid = ks_rpcmessage_create_response(request, replyP, responseP);
+
+       if (!msgid || *responseP == NULL) {
+               ks_log(KS_LOG_ERROR, "Unable to create rpc response message\n");  //TODO : Add namespace, method from request 
+               return 0;
+       }
+
+       const char *to =    cJSON_GetObjectCstr(jfields, "to");
+       const char *from =  cJSON_GetObjectCstr(jfields, "from");
+       const char *token = cJSON_GetObjectCstr(jfields, "token");
+       const char *version =  cJSON_GetObjectCstr(jfields, "version");
+
+       cJSON *blade = cJSON_CreateObject(); 
+
+       if (to) {
+        cJSON_AddStringToObject(blade, "to", from);
+    }
+
+       if (from) {
+               cJSON_AddStringToObject(blade, "from", to);
+       }
+
+       if (token) {
+               cJSON_AddStringToObject(blade, "token", token);
+       }
+
+    if (version) {
+        cJSON_AddStringToObject(blade, "version", version);
+    }
+
+       cJSON_AddItemToObject(*responseP, "blade", blade);
+
+       return msgid;
+}
+
+const char BLADE_JRPC_METHOD[] = "method";
+const char BLADE_JRPC_FIELDS[] = "blade";
+const char BLADE_JRPC_TO[]     = "to";
+const char BLADE_JRPC_FROM[]   = "from";
+const char BLADE_JRPC_TOKEN[]  = "token";
+const char BLADE_JRPC_VERSION[] = "version";
+
+KS_DECLARE(ks_status_t) blade_rpc_parse_message(cJSON *message,
+                                                                                                       char **namespaceP,
+                                                                                                       char **methodP,
+                                                                                                       char **versionP,
+                                                                                                       blade_rpc_fields_t **fieldsP)
+{
+       const char *m = cJSON_GetObjectCstr(message, BLADE_JRPC_METHOD);
+       cJSON *blade  = cJSON_GetObjectItem(message, BLADE_JRPC_FIELDS);
+
+       *fieldsP    = NULL;
+       *namespaceP = NULL;
+       *versionP   = NULL;
+       *methodP    = NULL;
+
+       if (!m || !blade) {
+               const char *buffer = cJSON_PrintUnformatted(message);
+               ks_log(KS_LOG_ERROR, "Unable to locate necessary fields in message:\n%s\n", buffer);
+               ks_pool_free(g_handle->pool, buffer);
+               return KS_STATUS_FAIL;  
+       }
+
+       ks_size_t len = KS_RPCMESSAGE_COMMAND_LENGTH   + 1 + 
+                                       KS_RPCMESSAGE_NAMESPACE_LENGTH + 1 +
+                                       KS_RPCMESSAGE_VERSION_LENGTH   + 1 +
+                                       sizeof(blade_rpc_fields_t) + 1;
+
+       blade_rpc_fields_t *fields =  (blade_rpc_fields_t *)ks_pool_alloc(g_handle->pool, len);
+       
+       fields->to = cJSON_GetObjectCstr(blade, BLADE_JRPC_TO);
+       fields->from = cJSON_GetObjectCstr(blade, BLADE_JRPC_FROM);
+       fields->from = cJSON_GetObjectCstr(blade, BLADE_JRPC_TOKEN);
+       
+       char *namespace = (char*)fields + sizeof(blade_rpc_fields_t);
+       char *command   = namespace + KS_RPCMESSAGE_NAMESPACE_LENGTH + 1; 
+       char *version   = command + KS_RPCMESSAGE_COMMAND_LENGTH + 1;
+
+    blade_rpc_parse_fqcommand(m, namespace, command);
+       
+       strcpy(version, cJSON_GetObjectCstr(blade, BLADE_JRPC_VERSION));
+
+       *fieldsP    = fields;   
+       *namespaceP = namespace;
+       *methodP    = command;
+
+       return KS_STATUS_SUCCESS;
+}
+
 
 /*
  * send message
@@ -769,7 +934,7 @@ static ks_status_t blade_rpc_process_jsonmessage_all(cJSON *request)
        if (!fqcommand) {
                error = cJSON_CreateObject();
                cJSON_AddStringToObject(error, "errormessage", "Command not specified");
-        ks_rpcmessage_create_request("rpcprotocol", "unknowncommand", NULL, NULL,  &error, &responseP);
+        ks_rpcmessage_create_request("rpcprotocol", "unknowncommand", &error, &responseP);
                blade_rpc_write_json(responseP);
         return KS_STATUS_FAIL;
        }
@@ -907,23 +1072,23 @@ KS_DECLARE(ks_status_t) blade_rpc_process_data(const uint8_t *data,
        return KS_STATUS_FAIL;
 }
 
-KS_DECLARE(ks_status_t) blade_rpc_process_blademessage(blade_message_t *message)
-{
-       uint8_t* data = NULL;
-       ks_size_t size = 0;
-
-       blade_message_get(message, (void **)&data, &size);
-
-       if (data && size>0) {
-               ks_status_t s = blade_rpc_process_data(data, size);
-               blade_message_discard(&message);
-               return s;
-       } 
-       
-       ks_log(KS_LOG_ERROR, "Message read failed\n");
-       return KS_STATUS_FAIL;
-
-}
+//KS_DECLARE(ks_status_t) blade_rpc_process_blademessage(blade_message_t *message)
+//{
+//     uint8_t* data = NULL;
+//     ks_size_t size = 0;
+//
+//     blade_message_get(message, (void **)&data, &size);
+//
+//     if (data && size>0) {
+//             ks_status_t s = blade_rpc_process_data(data, size);
+//             blade_message_discard(&message);
+//             return s;
+//     } 
+//     
+//     ks_log(KS_LOG_ERROR, "Message read failed\n");
+//     return KS_STATUS_FAIL;
+//
+//}
 
 
 /* For Emacs:
index 862ccd9f00f5ab176b5b103a9b7170ab4548f6c8..193c8604ab0b7229bf71f2daa9651fade5c6628f 100644 (file)
@@ -39,7 +39,6 @@
 
 // temp typedefs to get compile going 
 //typedef struct blade_peer_s  blade_peer_t;
-//typedef struct blade_message_s blade_message_t;
 //typedef struct blade_event_s blade_event_t;
 
 #define KS_RPCMESSAGE_NAMESPACE_LENGTH 16
 #define KS_RPCMESSAGE_VERSION_LENGTH 9
 
 
+/* 
+ *  contents to add to the "blade" field in rpc
+ */
+
+typedef struct blade_rpc_fields_s {
+
+       const char *to;
+       const char *from;
+       const char *token;
+
+}  blade_rpc_fields_t;
+
+
+
 enum jrpc_status_t { 
        JRPC_PASS = (1 << 0), 
        JRPC_SEND = (1 << 1),
@@ -101,6 +114,24 @@ KS_DECLARE(ks_status_t)blade_rpc_register_template_function(char *name,
 KS_DECLARE(ks_status_t)blade_rpc_inherit_template(char *namespace, char* template);
 
 
+/*
+ * create a request message
+ */
+KS_DECLARE(ks_rpcmessageid_t) blade_rpc_create_request(char *namespace,
+                                                                                                       char *method,
+                                                                                                       blade_rpc_fields_t* fields,
+                                                                                                       cJSON **paramsP,
+                                                                                                       cJSON **requestP);
+
+KS_DECLARE(ks_rpcmessageid_t) blade_rpc_create_response(cJSON *request,
+                                                                                                       cJSON **reply,
+                                                                                                       cJSON **response);
+
+KS_DECLARE(ks_status_t) blade_rpc_parse_message(cJSON *message,
+                                                                                                       char **namespace,
+                                                                                                       char **method,
+                                                                                                       char **version, 
+                                                                                                       blade_rpc_fields_t **fieldsP);
 
 /*
  * peer create/destroy
@@ -121,7 +152,6 @@ KS_DECLARE(ks_status_t) blade_rpc_write_json(cJSON* json);
  * process inbound message
  * -----------------------
  */
-KS_DECLARE(ks_status_t) blade_rpc_process_blademessage(blade_message_t *message);
 KS_DECLARE(ks_status_t) blade_rpc_process_data(const uint8_t *data, ks_size_t size);
 
 KS_DECLARE(ks_status_t) blade_rpc_process_jsonmessage(cJSON *request);
index b479d07033dc15b4a359074bfb2e6527dd5ce7e4..4679a7f27714d27cee2bdb2fb59d7fc87d955a2a 100644 (file)
@@ -29,7 +29,7 @@ static enum jrpc_status_t  process_widget(cJSON *msg, cJSON **response)
     cJSON *resp = cJSON_CreateObject();
     cJSON_AddNumberToObject(resp, "code", 199);
 
-    ks_rpcmessage_id msgid = ks_rpcmessage_create_response(msg, &resp, response);
+    ks_rpcmessageid_t msgid = ks_rpcmessage_create_response(msg, &resp, response);
 
     char *b1 = cJSON_PrintUnformatted(*response);   //(*response);
     printf("Response: msgid %d\n%s\n", msgid, b1);
@@ -62,7 +62,8 @@ static enum jrpc_status_t  process_wombat(cJSON *msg, cJSON **replyP)
        cJSON_AddNumberToObject(result, "code", 99);
        cJSON *response;
 
-    ks_rpcmessage_id msgid = ks_rpcmessage_create_response(msg, &result, &response);
+//    ks_rpcmessageid_t msgid = ks_rpcmessage_create_response(msg, &result, &response);
+       ks_rpcmessageid_t msgid = blade_rpc_create_response(msg, &result, &response);
 
        cJSON *response_copy = cJSON_Duplicate(response, 1);
     blade_rpc_process_jsonmessage(response_copy);
@@ -80,7 +81,18 @@ static enum jrpc_status_t  process_wombat(cJSON *msg, cJSON **replyP)
 
 
        cJSON *parms2 = NULL;
-       msgid = ks_rpcmessage_create_request("app1", "widget", "99", "1.0", &parms2, replyP);
+
+    char to[] = "tony@freeswitch.com/laptop?transport=wss&host=server1.freeswitch.com&port=1234";
+    char from[] = "colm@freeswitch.com/laptop?transport=wss&host=server2.freeswitch.com&port=4321";
+    char token[] = "abcdefhgjojklmnopqrst";
+
+    blade_rpc_fields_t  fields;
+    fields.to = to;
+    fields.from = from;
+    fields.token = token;
+
+//     msgid = ks_rpcmessage_create_request("app1", "widget", &parms2, replyP);
+       msgid = blade_rpc_create_request("app1", "widget", &fields, &parms2, replyP);
 
     printf("\n\nexiting process_wombat with a reply to send\n");
 
@@ -120,7 +132,7 @@ static enum jrpc_status_t  process_wombat_preresponse(cJSON *request, cJSON **ms
 
        cJSON *parms2 = NULL;
 
-       //ks_rpcmessage_id msgid = ks_rpcmessage_create_request("app1", "widget", "99", "1.0", &parms2, msg);   
+       //ks_rpcmessageid_t msgid = ks_rpcmessage_create_request("app1", "widget", &parms2, msg);       
 
     printf("exiting process_wombat_preresponse\n");
     return JRPC_SEND;
@@ -146,7 +158,7 @@ static enum jrpc_status_t  process_badbunny( cJSON *msg, cJSON **response)
 
     cJSON *respvalue;
 
-    ks_rpcmessage_id msgid = ks_rpcmessage_create_errorresponse(msg, &respvalue, response);
+    ks_rpcmessageid_t msgid = ks_rpcmessage_create_errorresponse(msg, &respvalue, response);
 
     char *b2 = cJSON_PrintUnformatted(*response);
     printf("\nRequest: msgid %d\n%s\n\n", msgid, b2);
@@ -187,9 +199,9 @@ void test01()
     cJSON* request1 = NULL;
     cJSON* parms1   = NULL;
 
-       printf("\n\n\n - message1 - basic message\n\n\n");
+       printf("\n\n\n - test01 message1 - basic message\n\n\n");
 
-       ks_rpcmessage_id msgid = ks_rpcmessage_create_request("app1", "wombat", "99", "1.0", &parms1, &request1);
+       ks_rpcmessageid_t msgid = ks_rpcmessage_create_request("app1", "wombat", &parms1, &request1);
        if (msgid == 0) {
                printf("test01.1: unable to create message 1\n");
                return;
@@ -200,6 +212,8 @@ void test01()
                return;
        }
 
+    cJSON_AddStringToObject(parms1, "hello", "cruel world");
+
        char *pdata = cJSON_PrintUnformatted(request1);
 
        if (!pdata) {
@@ -207,9 +221,8 @@ void test01()
                return;
        }
 
-       printf("request:\n%s\n", pdata);
+       printf("test01 request:\n%s\n", pdata);
 
-    cJSON_AddStringToObject(parms1, "hello", "cruel world");
 
        blade_rpc_process_jsonmessage(request1);
 
@@ -223,14 +236,16 @@ void test01()
        /* message 2 */
        /* --------- */
 
-    printf("\n\n\n - message2 - test inherit\n\n\n");
+    printf("\n\n\n test01 - message2 - test inherit\n\n\n");
 
        blade_rpc_inherit_template("app1", "temp1");
 
     cJSON* request2 = NULL;
-    cJSON* parms2   = NULL;
+    cJSON* parms2   = cJSON_CreateObject();
 
-    msgid = ks_rpcmessage_create_request("app1", "temp1.widget", "99", "1.0", &parms2, &request2); 
+    cJSON_AddStringToObject(parms2, "hello2", "cruel world once again");
+
+    msgid = ks_rpcmessage_create_request("app1", "temp1.widget", &parms2, &request2); 
        if (msgid == 0) {
                printf("test01.2: failed to create a wombat\n");
                return;
@@ -248,9 +263,7 @@ void test01()
                return;
        }
 
-    printf("request:\n%s\n", pdata);
-
-    cJSON_AddStringToObject(parms2, "hello2", "cruel world2");
+    printf("\ntest01 request:\n%s\n\n\n", pdata);
 
     blade_rpc_process_jsonmessage(request2);
 
@@ -265,14 +278,318 @@ void test01()
 
 void test02()
 {
-       printf("**** testmessages - test02 start\n"); fflush(stdout);
+       printf("**** testrpcmessages - test02 start\n"); fflush(stdout);
+
+    blade_rpc_declare_namespace("app2", "1.0");
+
+    blade_rpc_register_function("app2", "wombat", process_wombat, process_wombat_response);
+
+    blade_rpc_inherit_template("app2", "temp1");
+
+    blade_rpc_register_custom_request_function("app2", "wombat", process_wombat_prerequest, process_wombat_postresponse);
+    blade_rpc_register_custom_response_function("app2", "wombat", process_wombat_preresponse, process_wombat_postresponse);
+
+    blade_rpc_register_function("app2", "bunny", process_badbunny, NULL);
+
+       char to[] = "tony@freeswitch.com/laptop?transport=wss&host=server1.freeswitch.com&port=1234";
+       char from[] = "colm@freeswitch.com/laptop?transport=wss&host=server2.freeswitch.com&port=4321";
+       char token[] = "abcdefhgjojklmnopqrst";
+
+       blade_rpc_fields_t  fields;
+       fields.to = to;
+       fields.from = from;
+       fields.token = token;
+
+
+       /* test the 4 different ways to handle param messages */
+
+       cJSON *params1 = NULL;
+       cJSON *request1;
+
+       ks_rpcmessageid_t msgid =  blade_rpc_create_request("app2", "temp1.widget2", &fields, &params1, &request1); 
+
+       if (!msgid) {
+                printf("test02.1: create_request failed\n");
+               return;
+       }
+
+    cJSON_AddStringToObject(params1, "hello", "cruel world");
+
+    char *pdata = cJSON_PrintUnformatted(request1);
+
+    if (!pdata) {
+        printf("test02.1: unable to parse cJSON object\n");
+        return;
+    }
+
+       printf("\ntest02.1 request:\n\n%s\n\n\n", pdata);
+
+       printf("\n\n -----------------------------------------\n\n");
+
+       ks_status_t s1 = blade_rpc_process_jsonmessage(request1);
+       if (s1 == KS_STATUS_FAIL) {
+               printf("test02.1:  process request1 failed\n");
+               return;
+       }
+       printf(" -----------------------------------------\n\n\n\n");
+
+       ks_pool_free(pool, &pdata);
+
+       cJSON *reply1 = NULL;
+       cJSON *response1 = NULL;
+
+       ks_rpcmessageid_t msgid2 = blade_rpc_create_response(request1, &reply1, &response1);
+
+       if (!msgid2) {
+               printf("test02.1: create_response failed\n");
+               return;
+       }
+
+       cJSON_AddNumberToObject(reply1, "code", 10);
+       cJSON_AddStringToObject(reply1, "farewell", "cruel server");
+
+       pdata = cJSON_PrintUnformatted(response1);
+
+       if (!pdata) {
+        printf("test02.1: unable to parse cJSON response object\n");
+        return;
+       }
 
-       printf("****  testmessages - test02 finished\n"); fflush(stdout);
+    printf("\ntest02.1 response:\n\n%s\n\n\n", pdata);
+
+    printf("\n\n -----------------------------------------\n\n");
+
+    s1 = blade_rpc_process_jsonmessage(response1);
+    if (s1 == KS_STATUS_FAIL) {
+        printf("test02.1:  process request1 failed\n");
+        return;
+    }
+
+    printf(" -----------------------------------------\n\n\n\n");
+
+
+       ks_pool_free(pool, &pdata);
+
+       printf("****  testrpcmessages - test02 finished\n"); fflush(stdout);
 
        return;
 }
 
 
+void test02a()
+{
+       printf("**** testrpcmessages - test02a start\n"); fflush(stdout);
+
+       char to[] = "tony@freeswitch.com/laptop?transport=wss&host=server1.freeswitch.com&port=1234";
+       char from[] = "colm@freeswitch.com/laptop?transport=wss&host=server2.freeswitch.com&port=4321";
+       char token[] = "abcdefhgjojklmnopqrst";
+
+       blade_rpc_fields_t  fields;
+       fields.to = to;
+       fields.from = from;
+       fields.token = token;
+
+
+       /* test the 4 different ways to handle param messages */
+
+       cJSON *request1;
+
+       ks_rpcmessageid_t msgid =  blade_rpc_create_request("app2", "wombat", &fields, NULL, &request1);
+
+       if (!msgid) {
+               printf("test02.1: create_request failed\n");
+               return;
+       }
+
+       char *pdata = cJSON_PrintUnformatted(request1);
+
+       if (!pdata) {
+               printf("test02.1: unable to parse cJSON object\n");
+               return;
+       }
+
+       printf("\ntest02.1 request:\n\n%s\n\n\n", pdata);
+
+    printf("\n\n -----------------------------------------\n\n");
+
+    ks_status_t s1 = blade_rpc_process_jsonmessage(request1);
+    if (s1 == KS_STATUS_FAIL) {
+        printf("test02.1:  process request1 failed\n");
+        return;
+    }
+
+    printf(" -----------------------------------------\n\n\n\n");
+
+
+
+       
+       ks_pool_free(pool, &pdata);
+
+       cJSON *response1 = NULL;
+
+       ks_rpcmessageid_t msgid2 = blade_rpc_create_response(request1, NULL, &response1);
+
+       if (!msgid2) {
+               printf("test02.1: create_response failed\n");
+               return;
+       }
+
+       pdata = cJSON_PrintUnformatted(response1);
+
+       printf("\ntest02.1 response:\n\n%s\n\n\n", pdata);
+
+       ks_pool_free(pool, &pdata);
+
+       printf("****  testrpcmessages - test02a finished\n\n\n"); fflush(stdout);
+
+       return;
+}
+
+
+void test02b()
+{
+    printf("**** testrpcmessages - test02b start\n"); fflush(stdout);
+
+    char to[] = "tony@freeswitch.com/laptop?transport=wss&host=server1.freeswitch.com&port=1234";
+    char from[] = "colm@freeswitch.com/laptop?transport=wss&host=server2.freeswitch.com&port=4321";
+    char token[] = "abcdefhgjojklmnopqrst";
+
+    blade_rpc_fields_t  fields;
+    fields.to = to;
+    fields.from = from;
+    fields.token = token;
+
+
+    /* test the 4 different ways to handle param messages */
+
+    cJSON *params1 = cJSON_CreateNumber(4321);
+    cJSON *request1;
+
+    ks_rpcmessageid_t msgid =  blade_rpc_create_request("app2", "temp1.widget", &fields, &params1, &request1);
+
+    if (!msgid) {
+         printf("test02.1: create_request failed\n");
+        return;
+    }
+
+    char *pdata = cJSON_PrintUnformatted(request1);
+
+    if (!pdata) {
+        printf("test02.1: unable to parse cJSON object\n");
+        return;
+    }
+
+    printf("\ntest02.1 request:\n\n%s\n\n\n", pdata);
+       
+           ks_pool_free(pool, &pdata);
+
+    cJSON *reply1 = cJSON_CreateString("successful");
+    cJSON *response1 = NULL;
+
+    ks_rpcmessageid_t msgid2 = blade_rpc_create_response(request1, &reply1, &response1);
+
+    if (!msgid2) {
+        printf("test02.1: create_response failed\n");
+        return;
+    }
+
+     pdata = cJSON_PrintUnformatted(response1);
+
+    printf("\ntest02.1 response:\n\n%s\n\n\n", pdata);
+
+    ks_pool_free(pool, &pdata);
+
+    printf("****  testrpcmessages - test02b finished\n"); fflush(stdout);
+
+    return;
+}
+
+
+void test02c() 
+{
+
+    printf("**** testrpcmessages - test02c start\n"); fflush(stdout);
+
+    char to[] = "tony@freeswitch.com/laptop?transport=wss&host=server1.freeswitch.com&port=1234";
+    char from[] = "colm@freeswitch.com/laptop?transport=wss&host=server2.freeswitch.com&port=4321";
+    char token[] = "abcdefhgjojklmnopqrst";
+
+    blade_rpc_fields_t  fields;
+    fields.to    = to;
+    fields.from  = from;
+    fields.token = token;
+
+
+    /* test the 4 different ways to handle param messages */
+
+    cJSON *params1 = cJSON_CreateObject();
+
+       cJSON_AddStringToObject(params1, "string1", "here is a string");
+       cJSON_AddNumberToObject(params1, "number1", 4242);
+
+    cJSON *request1;
+
+    ks_rpcmessageid_t msgid =  blade_rpc_create_request("app2", "bunny", &fields, &params1, &request1);
+
+    if (!msgid) {
+         printf("test02.1: create_request failed\n");
+        return;
+    }
+
+    cJSON_AddStringToObject(params1, "hello", "cruel world");
+
+    char *pdata = cJSON_PrintUnformatted(request1);
+
+    if (!pdata) {
+        printf("test02.1: unable to parse cJSON object\n");
+        return;
+    }
+
+    printf("\ntest02.1 request:\n\n%s\n\n\n", pdata);
+       
+           ks_pool_free(pool, &pdata);
+
+
+    cJSON *reply1 = cJSON_CreateObject();
+    cJSON_AddNumberToObject(reply1, "code", 10);
+    cJSON_AddStringToObject(reply1, "farewell", "cruel server");
+
+
+    cJSON *response1 = NULL;
+
+    ks_rpcmessageid_t msgid2 = blade_rpc_create_response(request1, &reply1, &response1);
+
+    if (!msgid2) {
+        printf("test02.1: create_response failed\n");
+        return;
+    }
+
+
+     pdata = cJSON_PrintUnformatted(response1);
+
+    printf("\ntest02.1 response:\n\n%s\n\n\n", pdata);
+
+    ks_pool_free(pool, &pdata);
+
+    printf("****  testrpcmessages - test02c finished\n"); fflush(stdout);
+
+    return;
+}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
 
 
 /* test06  */
@@ -340,6 +657,13 @@ int main(int argc, char *argv[]) {
 
        blade_rpc_init(pool);
 
+    blade_rpc_declare_template("temp1", "1.0");
+
+    blade_rpc_register_template_function("temp1", "widget", process_widget, process_widget_response);
+    blade_rpc_register_template_function("temp1", "widget2", process_widget, process_widget_response);
+    blade_rpc_register_template_function("temp1", "widget3", process_widget, process_widget_response);
+
+
        for (int tix=0; tix<argc; ++tix) {
 
 
@@ -350,6 +674,13 @@ int main(int argc, char *argv[]) {
 
                if (tests[tix] == 2) {
                        test02();
+                       printf("\n\n");
+                       test02a();
+            printf("\n\n");
+                       test02b();
+            printf("\n\n");
+                       test02c();
+            printf("\n\n");
                        continue;
                }
 
index 832a6f32175af7960e1ad06a094c492b7bd0e21b..da2157e9d09aa50b0efa4fbf11b9692356668eb3 100644 (file)
@@ -45,7 +45,7 @@ KS_BEGIN_EXTERN_C
 #define KS_RPCMESSAGE_VERSION_LENGTH 9
 
 
-typedef uint32_t ks_rpcmessage_id;
+typedef uint32_t ks_rpcmessageid_t;
 
 
 KS_DECLARE(void) ks_rpcmessage_init(ks_pool_t *pool);
@@ -54,26 +54,22 @@ KS_DECLARE(void*) ks_json_pool_alloc(ks_size_t size);
 KS_DECLARE(void) ks_json_pool_free(void *ptr);
 
 
-KS_DECLARE(ks_rpcmessage_id) ks_rpcmessage_create_request(char *namespace, 
+KS_DECLARE(ks_rpcmessageid_t) ks_rpcmessage_create_request(char *namespace, 
                                                                                        char *method,
-                                                                                       char *sessionid,
-                                                                                       char *version, 
-                                                                                       cJSON **parmsP,
+                                                                                       cJSON **paramsP,
                                                                                        cJSON **requestP);
 
 KS_DECLARE(ks_size_t) ks_rpc_create_buffer(char *namespace,
                                             char *method,
-                                                                                       char *sessionid,
-                                                                                       char *version,
-                                            cJSON **parmsP,
+                                            cJSON **paramsP,
                                             ks_buffer_t *buffer);
 
-KS_DECLARE(ks_rpcmessage_id) ks_rpcmessage_create_response( 
+KS_DECLARE(ks_rpcmessageid_t) ks_rpcmessage_create_response( 
                                                                                        const cJSON *request, 
                                                                                        cJSON **resultP, 
                                                                                        cJSON **responseP);
 
-KS_DECLARE(ks_rpcmessage_id) ks_rpcmessage_create_errorresponse(
+KS_DECLARE(ks_rpcmessageid_t) ks_rpcmessage_create_errorresponse(
                                             const cJSON *request,
                                             cJSON **errorP,
                                             cJSON **responseP);
index 41e327bcc88a109a966d437510748e13d3d3b8ba..1b5e48754e346ae90867ccca2e2b57b23580100b 100644 (file)
@@ -48,6 +48,16 @@ struct
 
 } handle = {NULL, 0, NULL};
 
+const char PROTOCOL[] = "jsonrpc";
+const char PROTOCOL_VERSION[] = "2.0";
+const char ID[]      = "id";
+const char METHOD[]  = "method";
+const char PARAMS[]  = "params";
+const char ERROR[]   = "error";
+const char RESULT[]  = "result";
+
+
+
 KS_DECLARE(void*) ks_json_pool_alloc(ks_size_t size)
 {
        return ks_pool_alloc(handle.pool, size);
@@ -96,10 +106,10 @@ static uint32_t ks_rpcmessage_next_id()
 static cJSON *ks_rpcmessage_new(uint32_t id)
 {
     cJSON *obj = cJSON_CreateObject();
-    cJSON_AddItemToObject(obj, "jsonrpc", cJSON_CreateString("2.0"));
+    cJSON_AddItemToObject(obj, PROTOCOL, cJSON_CreateString(PROTOCOL_VERSION));
 
     if (id) {
-        cJSON_AddItemToObject(obj, "id", cJSON_CreateNumber(id));
+        cJSON_AddItemToObject(obj, ID, cJSON_CreateNumber(id));
     }
 
     return obj;
@@ -108,10 +118,10 @@ static cJSON *ks_rpcmessage_new(uint32_t id)
 static cJSON *ks_rpcmessage_dup(cJSON *msgid)
 {
     cJSON *obj = cJSON_CreateObject();
-    cJSON_AddItemToObject(obj, "jsonrpc", cJSON_CreateString("2.0"));
+    cJSON_AddItemToObject(obj, PROTOCOL, cJSON_CreateString(PROTOCOL_VERSION));
 
     if (msgid) {
-        cJSON_AddItemToObject(obj, "id",  cJSON_Duplicate(msgid, 0));
+        cJSON_AddItemToObject(obj, ID,  cJSON_Duplicate(msgid, 0));
     }
 
     return obj;
@@ -119,8 +129,8 @@ static cJSON *ks_rpcmessage_dup(cJSON *msgid)
 
 KS_DECLARE(ks_bool_t) ks_rpcmessage_isrequest(cJSON *msg)
 {
-    cJSON *result = cJSON_GetObjectItem(msg, "result");
-    cJSON *error  = cJSON_GetObjectItem(msg, "error");
+    cJSON *result = cJSON_GetObjectItem(msg, RESULT);
+    cJSON *error  = cJSON_GetObjectItem(msg, ERROR);
 
        if (result || error) {
                return  KS_FALSE;
@@ -131,7 +141,7 @@ KS_DECLARE(ks_bool_t) ks_rpcmessage_isrequest(cJSON *msg)
 
 KS_DECLARE(ks_bool_t) ks_rpcmessage_isrpc(cJSON *msg)
 {
-    cJSON *rpc = cJSON_GetObjectItem(msg, "json-rpc");
+    cJSON *rpc = cJSON_GetObjectItem(msg, PROTOCOL);
 
     if (rpc) {
         return  KS_FALSE;
@@ -143,51 +153,28 @@ KS_DECLARE(ks_bool_t) ks_rpcmessage_isrpc(cJSON *msg)
 
 
 
-KS_DECLARE(ks_rpcmessage_id) ks_rpcmessage_create_request(char *namespace,
+KS_DECLARE(ks_rpcmessageid_t) ks_rpcmessage_create_request(char *namespace,
                                                                                                char *command,
-                                                                                               char *sessionid,
-                                                                                               char *version,
                                                                                                cJSON **paramsP,
                                                                                                cJSON **requestP)
 {
     cJSON *msg, *params = NULL;
        *requestP = NULL;
 
-       ks_rpcmessage_id msgid = ks_rpcmessage_next_id();
+       ks_rpcmessageid_t msgid = ks_rpcmessage_next_id();
     msg = ks_rpcmessage_new(msgid);
 
-    if (paramsP && *paramsP) {   /* parameters have been passed */
+    if (paramsP) {
 
-               cJSON *p = *paramsP;
-               
-               if (p->type != cJSON_Object) {    /* need to wrap this in a param field */
-                       params = cJSON_CreateObject();
-                       cJSON_AddItemToObject(params, "param", p);
-               }
-               else {
+               if (*paramsP) {   /* parameters have been passed */
                        params = *paramsP;
                }
-
-               cJSON *v = cJSON_GetObjectItem(params, "version");
-
-               if (!v) {                /* add version if needed  */
-                        cJSON_AddStringToObject(params, "version", version);
-               }
                else {
-                       cJSON_AddStringToObject(params, "version", "0");
-               }
-    }
-
-    if (!params) {
-        params = cJSON_CreateObject();
-
-               if (version && version[0] != 0) {               
-                       cJSON_AddStringToObject(params, "version", version);
-               }
-               else {
-                       cJSON_AddStringToObject(params, "version", "0");
+                       params = cJSON_CreateObject();
+                       *paramsP = params;
                }
 
+               cJSON_AddItemToObject(msg, PARAMS, params);
     }
 
     char fqcommand[KS_RPCMESSAGE_FQCOMMAND_LENGTH];
@@ -195,17 +182,7 @@ KS_DECLARE(ks_rpcmessage_id) ks_rpcmessage_create_request(char *namespace,
 
        sprintf(fqcommand, "%s.%s", namespace, command);
 
-    cJSON_AddItemToObject(msg, "method", cJSON_CreateString(fqcommand));
-
-       if (sessionid && sessionid[0] != 0) {
-               cJSON_AddStringToObject(params, "sessionid", sessionid);
-       }
-
-    cJSON_AddItemToObject(msg, "params", params);
-
-    if (paramsP) {
-        *paramsP = params;
-    }
+    cJSON_AddItemToObject(msg, METHOD, cJSON_CreateString(fqcommand));
 
        *requestP = msg;
     return msgid;
@@ -213,19 +190,22 @@ KS_DECLARE(ks_rpcmessage_id) ks_rpcmessage_create_request(char *namespace,
 
 KS_DECLARE(ks_size_t) ks_rpc_create_buffer(char *namespace,
                                             char *method,
-                                                                                       char *sessionid,
-                                                                                       char *version,
-                                            cJSON **parms,
+                                            cJSON **params,
                                             ks_buffer_t *buffer)
 {
+
        cJSON *message;
 
-       ks_rpcmessage_id msgid = ks_rpcmessage_create_request(namespace, method, sessionid, version, parms, &message);
+       ks_rpcmessageid_t msgid = ks_rpcmessage_create_request(namespace, method, params, &message);
 
        if (!msgid) {
                return 0;
        }
 
+       if ( (*params)->child == NULL) {
+               cJSON_AddNullToObject(*params, "bladenull");
+       }
+
        const char* b = cJSON_PrintUnformatted(message);
        ks_size_t size = strlen(b);
 
@@ -236,14 +216,14 @@ KS_DECLARE(ks_size_t) ks_rpc_create_buffer(char *namespace,
 }
 
 
-static ks_rpcmessage_id ks_rpcmessage_get_messageid(const cJSON *msg, cJSON **cmsgidP)
+static ks_rpcmessageid_t ks_rpcmessage_get_messageid(const cJSON *msg, cJSON **cmsgidP)
 {
-       uint32_t msgid = 0;
+       ks_rpcmessageid_t msgid = 0;
 
-       cJSON *cmsgid = cJSON_GetObjectItem(msg, "id");
+       cJSON *cmsgid = cJSON_GetObjectItem(msg, ID);
 
        if (cmsgid->type == cJSON_Number) {
-               msgid = (uint32_t) cmsgid->valueint;
+               msgid = (ks_rpcmessageid_t) cmsgid->valueint;
        }
        
        *cmsgidP = cmsgid;      
@@ -252,24 +232,17 @@ static ks_rpcmessage_id ks_rpcmessage_get_messageid(const cJSON *msg, cJSON **cm
 } 
 
 
-static ks_rpcmessage_id ks_rpcmessage_new_response(
+static ks_rpcmessageid_t ks_rpcmessage_new_response(
                                                 const cJSON *request,
-                                                cJSON *result,
+                                                cJSON **result,
                                                 cJSON **pmsg)
 {
     cJSON *respmsg = NULL;
     cJSON *cmsgid  = NULL;
-       cJSON *version = NULL;
-       cJSON *sessionid = NULL;
 
-    cJSON *command = cJSON_GetObjectItem(request, "method");
-       cJSON *params =  cJSON_GetObjectItem(request, "params");
+    cJSON *command = cJSON_GetObjectItem(request, METHOD);
 
-       if (params) {
-               version = cJSON_GetObjectItem(request, "version");
-       }
-
-       ks_rpcmessage_id msgid = ks_rpcmessage_get_messageid(request, &cmsgid );
+       ks_rpcmessageid_t msgid = ks_rpcmessage_get_messageid(request, &cmsgid );
 
     if (!msgid || !command) {
         return 0;
@@ -277,91 +250,51 @@ static ks_rpcmessage_id ks_rpcmessage_new_response(
 
     *pmsg = respmsg = ks_rpcmessage_dup(cmsgid);
 
-    cJSON_AddItemToObject(respmsg, "method", cJSON_Duplicate(command, 0));
-
-    if (result) {
-
-           cJSON *params =  cJSON_GetObjectItem(request, "params");
-
-               if (params) {
-                       version = cJSON_GetObjectItem(params, "version");
+    cJSON_AddItemToObject(respmsg, METHOD, cJSON_Duplicate(command, 0));
 
-                       if (version) {
-                               cJSON_AddItemToObject(result, "version", cJSON_Duplicate(version, 0));
-                       }
-               
-                       sessionid = cJSON_GetObjectItem(params, "sessionid");
-
-            if (sessionid) {
-                cJSON_AddItemToObject(result, "sessionid", cJSON_Duplicate(sessionid, 0));
-            }
-
-               }
-               
-        cJSON_AddItemToObject(respmsg, "result", result);
+    if (result && *result) {
+        cJSON_AddItemToObject(respmsg, RESULT, *result);
     }
 
     return msgid;
 }
 
 
-KS_DECLARE(ks_rpcmessage_id) ks_rpcmessage_create_response(
+KS_DECLARE(ks_rpcmessageid_t) ks_rpcmessage_create_response(
                                                                                                const cJSON *request,
                                                                                                cJSON **resultP,
                                                                                                cJSON **responseP)
 {
-       ks_rpcmessage_id msgid = ks_rpcmessage_new_response(request, *resultP, responseP);
+       ks_rpcmessageid_t msgid = ks_rpcmessage_new_response(request, resultP, responseP);
 
        cJSON *respmsg = *responseP;
 
     if (msgid) {
 
-               if (*resultP == NULL) {
-                       *resultP = cJSON_CreateObject();
-                       cJSON *result = *resultP;
-
-                   cJSON *params =  cJSON_GetObjectItem(request, "params");
-
-                       if (params) {
-                               cJSON *version = cJSON_GetObjectItem(request, "version");
-                               cJSON *sessionid = cJSON_GetObjectItem(request, "sessionid");
-
-                               if (version) {
-                                       cJSON_AddItemToObject(result, "version", cJSON_Duplicate(version, 0));
-                               }
-                               else {
-                                       cJSON_AddStringToObject(result, "version", "0");
-                               }
-
-                               if (sessionid) {
-                                       cJSON_AddItemToObject(result, "sessionid", cJSON_Duplicate(sessionid, 0));
-                               }
-                               
-                       }
-                       else {
-                               cJSON_AddStringToObject(result, "version", "0");
-                       }
-
-                       cJSON_AddItemToObject(respmsg, "result", result);
+               if (resultP && *resultP == NULL) {
+                       cJSON *result = cJSON_CreateObject();
+                       *resultP = result;
+                       cJSON_AddItemToObject(respmsg, RESULT, result);
                }
        }
 
     return msgid;
 }
 
-KS_DECLARE(ks_rpcmessage_id) ks_rpcmessage_create_errorresponse( 
+KS_DECLARE(ks_rpcmessageid_t) ks_rpcmessage_create_errorresponse( 
                                                                                                const cJSON *request, 
                                                                                                cJSON **errorP, 
                                                                                                cJSON **responseP)
 {
-       ks_rpcmessage_id msgid = ks_rpcmessage_new_response(request, *errorP, responseP);
+       ks_rpcmessageid_t msgid = ks_rpcmessage_new_response(request, errorP, responseP);
        cJSON *respmsg = *responseP;
 
        if (msgid) { 
-  
-               if (*errorP == NULL) {
-                       *errorP = cJSON_CreateObject();
-                       cJSON_AddItemToObject(respmsg, "error", *errorP);
+
+               if (errorP && *errorP == NULL) {
+                       cJSON *error = cJSON_CreateObject();
+                       *errorP = error;
+                       cJSON_AddItemToObject(respmsg, ERROR, error);
                }
        }
 
index 1849a58494ed08f2923dc95ae5391e3872270751..22dd092aa2569b3b42388f9958144201781de88e 100644 (file)
@@ -18,8 +18,8 @@ void test01()
        cJSON* parms1    = NULL;
     cJSON* response1 = NULL;
 
-                                                                                                                /*namespace, method, sessionid, version, params, **request */  
-       ks_rpcmessage_id msgid = ks_rpcmessage_create_request("app1",     "func1", "s001",   "1.0",   &parms1, &request1);
+                                                                                                                /*namespace, method,  params, **request */     
+       ks_rpcmessageid_t msgid = ks_rpcmessage_create_request("app1",     "func1", &parms1, &request1);
        if (msgid == 0) {
                printf("message create failed %d\n", msgid);
        }       
@@ -37,7 +37,7 @@ void test01()
 
        ks_buffer_create(&buffer, 256, 256, 1024);
 
-    ks_size_t n = ks_rpc_create_buffer("app2", "func2", "s002", "1.1", &parms2, buffer);
+    ks_size_t n = ks_rpc_create_buffer("app2", "func2", &parms2, buffer);
 
        ks_size_t size =  ks_buffer_len(buffer);
        char *b = (char *)ks_pool_alloc(pool, size+1);
@@ -51,7 +51,7 @@ void test01()
        cJSON *parms3 = cJSON_CreateNumber(1);
     cJSON *request3  = NULL;
 
-    msgid = ks_rpcmessage_create_request("app1", "badbunny",  "s002",   "1.1",  &parms3, &request3);
+    msgid = ks_rpcmessage_create_request("app1", "badbunny",  &parms3, &request3);
        data = cJSON_PrintUnformatted(request3);
        printf("\ntest01i request: %d\n%s\n\n", msgid, data);