]> git.ipfire.org Git - thirdparty/freeswitch.git/commitdiff
FS-9952: Intermediate commit for a fresh point to start retrofitting the jsonrpc...
authorShane Bryldt <astaelan@gmail.com>
Tue, 28 Feb 2017 23:37:19 +0000 (23:37 +0000)
committerMike Jerris <mike@jerris.com>
Wed, 22 Mar 2017 21:42:50 +0000 (17:42 -0400)
libs/libblade/src/blade_protocol.c
libs/libblade/src/blade_session.c
libs/libblade/src/blade_stack.c
libs/libblade/src/include/blade_protocol.h
libs/libblade/src/include/blade_stack.h
libs/libblade/src/include/blade_types.h

index 4a3c0715944d32e706033187cec077efa787b5f1..830be262f0c860b15c86a4022c200c9b4d1a3d0d 100644 (file)
@@ -1,23 +1,23 @@
 /*
  * Copyright (c) 2017, Shane Bryldt
  * All rights reserved.
- * 
+ *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
  * are met:
- * 
+ *
  * * Redistributions of source code must retain the above copyright
  * notice, this list of conditions and the following disclaimer.
- * 
+ *
  * * Redistributions in binary form must reproduce the above copyright
  * notice, this list of conditions and the following disclaimer in the
  * documentation and/or other materials provided with the distribution.
- * 
+ *
  * * Neither the name of the original author; nor the names of any contributors
  * may be used to endorse or promote products derived from this software
  * without specific prior written permission.
- * 
- * 
+ *
+ *
  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 
 #include "blade.h"
 
-KS_DECLARE(ks_status_t) blade_request_create(blade_request_t **breqP, ks_pool_t *pool, const char *session_id, cJSON *json /*, response_callback*/)
+KS_DECLARE(ks_status_t) blade_request_create(blade_request_t **breqP, blade_handle_t *bh, const char *session_id, cJSON *json)
 {
        blade_request_t *breq = NULL;
+       ks_pool_t *pool = NULL;
 
        ks_assert(breqP);
-       ks_assert(pool);
+       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->refs = 1;
        breq->session_id = ks_pstrdup(pool, session_id);
        breq->message = json;
        breq->message_id = cJSON_GetObjectCstr(json, "id");
-       //breq->response_callback = response_callback;
+
        *breqP = breq;
 
        return KS_STATUS_SUCCESS;
@@ -72,6 +76,51 @@ 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)
+{
+       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 = json;
+
+       *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;
+}
+
+
 /* For Emacs:
  * Local Variables:
  * mode:c
index d5037bfcadbba43c3cde08a77e3a79f9626fc38d..58c9b323d15ef1ebd3d7c95712a05daa4700cf8d 100644 (file)
@@ -485,11 +485,20 @@ ks_status_t blade_session_state_on_ready(blade_session_t *bs)
 
 KS_DECLARE(ks_status_t) blade_session_send(blade_session_t *bs, cJSON *json)
 {
+       blade_request_t *request = NULL;
+       const char *method = NULL;
+
        ks_assert(bs);
        ks_assert(json);
 
-       // @todo check json for "method", if this is an outgoing request then build up the data for a response to lookup the message id and get back to the request
-       // this can reuse blade_request_t so that when the blade_response_t is passed up the blade_request_t within it is familiar from inbound requests
+       method = cJSON_GetObjectCstr(json, "method");
+       if (method) {
+               blade_request_create(&request, bs->handle, bs->id, json);
+               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);
+       }
 
        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
@@ -508,6 +517,11 @@ KS_DECLARE(ks_status_t) blade_session_send(blade_session_t *bs, cJSON *json)
 ks_status_t blade_session_process(blade_session_t *bs, cJSON *json)
 {
        ks_status_t ret = KS_STATUS_SUCCESS;
+       blade_request_t *breq = NULL;
+       blade_response_t *bres = NULL;
+       const char *jsonrpc = NULL;
+       const char *id = NULL;
+       const char *method = NULL;
 
        ks_assert(bs);
        ks_assert(json);
@@ -515,6 +529,50 @@ ks_status_t blade_session_process(blade_session_t *bs, cJSON *json)
        ks_log(KS_LOG_DEBUG, "Session (%s) processing\n", bs->id);
 
        // @todo teardown the message, convert into a blade_request_t or blade_response_t
+       // @todo validate the jsonrpc fields
+
+       jsonrpc = cJSON_GetObjectCstr(json, "jsonrpc");
+       if (!jsonrpc || strcmp(jsonrpc, "2.0")) {
+        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;
+       }
+
+       id = cJSON_GetObjectCstr(json, "id");
+       if (!id) {
+        ks_log(KS_LOG_DEBUG, "Received 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) {
+               // @todo use method to find RPC callbacks
+
+               blade_request_create(&breq, bs->handle, bs->id, json);
+               ks_assert(breq);
+
+               // @todo call request callback handler
+       } else {
+               breq = blade_handle_requests_get(bs->handle, id);
+               if (!breq) {
+                       // @todo hangup session entirely?
+                       return KS_STATUS_FAIL;
+               }
+               blade_handle_requests_remove(breq);
+
+               method = cJSON_GetObjectCstr(breq->message, "method");
+               ks_assert(method);
+
+               // @todo use method to find RPC callbacks
+
+               blade_response_create(&bres, bs->handle, bs->id, breq, json);
+               ks_assert(bres);
+
+               // @todo call response callback handler
+       }
 
        return ret;
 }
index 1a680a0ff512e6e4cd61994b2ecd7858781c52a0..56357344ced5cf1c1942e93e762b2d719e8c8a08 100644 (file)
@@ -1,23 +1,23 @@
 /*
  * Copyright (c) 2007-2014, Anthony Minessale II
  * All rights reserved.
- * 
+ *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
  * are met:
- * 
+ *
  * * Redistributions of source code must retain the above copyright
  * notice, this list of conditions and the following disclaimer.
- * 
+ *
  * * Redistributions in binary form must reproduce the above copyright
  * notice, this list of conditions and the following disclaimer in the
  * documentation and/or other materials provided with the distribution.
- * 
+ *
  * * Neither the name of the original author; nor the names of any contributors
  * may be used to endorse or promote products derived from this software
  * without specific prior written permission.
- * 
- * 
+ *
+ *
  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
@@ -43,7 +43,7 @@ struct blade_handle_s {
        bhpvt_flag_t flags;
        ks_pool_t *pool;
        ks_thread_pool_t *tpool;
-       
+
        config_setting_t *config_directory;
        config_setting_t *config_datastore;
 
@@ -125,7 +125,7 @@ KS_DECLARE(ks_status_t) blade_handle_create(blade_handle_t **bhP, ks_pool_t *poo
                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;
@@ -133,7 +133,7 @@ KS_DECLARE(ks_status_t) blade_handle_create(blade_handle_t **bhP, ks_pool_t *poo
 
        ks_hash_create(&bh->transports, KS_HASH_MODE_CASE_INSENSITIVE, KS_HASH_FLAG_NOLOCK | KS_HASH_FLAG_DUP_CHECK, bh->pool);
        ks_assert(bh->transports);
-       
+
        ks_hash_create(&bh->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);
@@ -141,7 +141,7 @@ KS_DECLARE(ks_status_t) blade_handle_create(blade_handle_t **bhP, ks_pool_t *poo
        // @todo decide if this is uint32_t or uuid string, prefer uuid string to avoid needing another lock and variable for next id
        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;
 
        return KS_STATUS_SUCCESS;
@@ -185,21 +185,21 @@ ks_status_t blade_handle_config(blade_handle_t *bh, config_setting_t *config)
 {
        config_setting_t *directory = NULL;
        config_setting_t *datastore = NULL;
-       
+
        ks_assert(bh);
 
        if (!config) return KS_STATUS_FAIL;
     if (!config_setting_is_group(config)) return KS_STATUS_FAIL;
 
        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;
 }
 
@@ -222,7 +222,7 @@ KS_DECLARE(ks_status_t) blade_handle_startup(blade_handle_t *bh, config_setting_
        }
 
        // @todo load DSOs
-       
+
        // @todo call onload and onstartup callbacks for modules from DSOs
 
        return KS_STATUS_SUCCESS;
@@ -237,20 +237,20 @@ KS_DECLARE(ks_status_t) blade_handle_shutdown(blade_handle_t *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->requests, key);
-               
+
                blade_session_hangup(value);
        }
        while (ks_hash_count(bh->sessions) > 0) ks_sleep_ms(100);
@@ -280,7 +280,7 @@ KS_DECLARE(ks_status_t) blade_handle_transport_register(blade_handle_t *bh, blad
 {
        blade_handle_transport_registration_t *bhtr = NULL;
        blade_handle_transport_registration_t *bhtr_old = NULL;
-       
+
        ks_assert(bh);
        ks_assert(bm);
        ks_assert(name);
@@ -326,7 +326,7 @@ KS_DECLARE(ks_status_t) blade_handle_connect(blade_handle_t *bh, blade_connectio
        ks_status_t ret = KS_STATUS_SUCCESS;
        blade_handle_transport_registration_t *bhtr = NULL;
        const char *tname = NULL;
-       
+
        ks_assert(bh);
        ks_assert(target);
 
@@ -482,6 +482,55 @@ KS_DECLARE(ks_status_t) blade_handle_sessions_remove(blade_session_t *bs)
 }
 
 
+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)
 {
@@ -499,7 +548,7 @@ KS_DECLARE(ks_status_t) blade_handle_datastore_store(blade_handle_t *bh, const v
        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);
 }
 
@@ -513,9 +562,9 @@ KS_DECLARE(ks_status_t) blade_handle_datastore_fetch(blade_handle_t *bh,
        ks_assert(callback);
        ks_assert(key);
        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);
 }
 
index fcd89cc01a2add30bc33b59aec76ec2f7bce0998..ddc4a3cdee4088d6876cb626d41077e326d2dffc 100644 (file)
@@ -1,23 +1,23 @@
 /*
  * Copyright (c) 2017, Shane Bryldt
  * All rights reserved.
- * 
+ *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
  * are met:
- * 
+ *
  * * Redistributions of source code must retain the above copyright
  * notice, this list of conditions and the following disclaimer.
- * 
+ *
  * * Redistributions in binary form must reproduce the above copyright
  * notice, this list of conditions and the following disclaimer in the
  * documentation and/or other materials provided with the distribution.
- * 
+ *
  * * Neither the name of the original author; nor the names of any contributors
  * may be used to endorse or promote products derived from this software
  * without specific prior written permission.
- * 
- * 
+ *
+ *
  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 #include <blade.h>
 
 KS_BEGIN_EXTERN_C
-KS_DECLARE(ks_status_t) blade_request_create(blade_request_t **breqP, ks_pool_t *pool, const char *session_id, cJSON *json /*, response_callback*/);
+KS_DECLARE(ks_status_t) blade_request_create(blade_request_t **breqP, blade_handle_t *bh, const char *session_id, cJSON *json);
 KS_DECLARE(ks_status_t) blade_request_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_END_EXTERN_C
 
 #endif
index dd1affb71d28c9f7e37d23e2d7ab104594ef10c1..ff86af388e4c44c49b48b1a3a537ff3944cec0c5 100644 (file)
@@ -1,23 +1,23 @@
 /*
  * Copyright (c) 2007-2014, Anthony Minessale II
  * All rights reserved.
- * 
+ *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
  * are met:
- * 
+ *
  * * Redistributions of source code must retain the above copyright
  * notice, this list of conditions and the following disclaimer.
- * 
+ *
  * * Redistributions in binary form must reproduce the above copyright
  * notice, this list of conditions and the following disclaimer in the
  * documentation and/or other materials provided with the distribution.
- * 
+ *
  * * Neither the name of the original author; nor the names of any contributors
  * may be used to endorse or promote products derived from this software
  * without specific prior written permission.
- * 
- * 
+ *
+ *
  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
@@ -55,11 +55,15 @@ KS_DECLARE(ks_status_t) blade_handle_connect(blade_handle_t *bh, blade_connectio
 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(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_fetch(blade_handle_t *bh,
index 66e8ea0d01771476a800a2dd225b7e2353eba99e..295217979dd0b69a9d82019c5014e6545567b87a 100644 (file)
@@ -1,23 +1,23 @@
 /*
  * Copyright (c) 2007-2014, Anthony Minessale II
  * All rights reserved.
- * 
+ *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
  * are met:
- * 
+ *
  * * Redistributions of source code must retain the above copyright
  * notice, this list of conditions and the following disclaimer.
- * 
+ *
  * * Redistributions in binary form must reproduce the above copyright
  * notice, this list of conditions and the following disclaimer in the
  * documentation and/or other materials provided with the distribution.
- * 
+ *
  * * Neither the name of the original author; nor the names of any contributors
  * may be used to endorse or promote products derived from this software
  * without specific prior written permission.
- * 
- * 
+ *
+ *
  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
@@ -141,8 +141,8 @@ struct blade_transport_callbacks_s {
 
 
 struct blade_request_s {
+       blade_handle_t *handle;
        ks_pool_t *pool;
-       uint32_t refs;
        const char *session_id;
 
        cJSON *message;
@@ -152,8 +152,8 @@ struct blade_request_s {
 };
 
 struct blade_response_s {
+       blade_handle_t *handle;
        ks_pool_t *pool;
-       uint32_t refs;
        const char *session_id;
        blade_request_t *request;