]> git.ipfire.org Git - thirdparty/freeswitch.git/commitdiff
FS-11893 [core] add switch_dial_handle_create_json() and switch_dial_handle_serialize...
authorChris Rienzo <chris@signalwire.com>
Tue, 18 Jun 2019 14:56:57 +0000 (14:56 +0000)
committerAndrey Volk <andywolk@gmail.com>
Wed, 17 Jul 2019 20:09:20 +0000 (00:09 +0400)
src/include/switch_ivr.h
src/switch_ivr_originate.c
tests/unit/switch_ivr_originate.c

index 061da0705b57095add97d552f54098112269da14..ab01aa49c0fe610e627fab84263103879be58ab2 100644 (file)
@@ -1036,7 +1036,11 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_video_write_overlay_session(switch_co
 SWITCH_DECLARE(switch_status_t) switch_ivr_capture_text(switch_core_session_t *session, switch_bool_t on);
 
 SWITCH_DECLARE(switch_status_t) switch_dial_handle_create(switch_dial_handle_t **handle);
+SWITCH_DECLARE(switch_status_t) switch_dial_handle_create_json_obj(switch_dial_handle_t **handle, cJSON *json);
+SWITCH_DECLARE(switch_status_t) switch_dial_handle_create_json(switch_dial_handle_t **handle, const char *handle_string);
 SWITCH_DECLARE(void) switch_dial_handle_destroy(switch_dial_handle_t **handle);
+SWITCH_DECLARE(switch_status_t) switch_dial_handle_serialize_json_obj(switch_dial_handle_t *handle, cJSON **json);
+SWITCH_DECLARE(switch_status_t) switch_dial_handle_serialize_json(switch_dial_handle_t *handle, char **str);
 SWITCH_DECLARE(void) switch_dial_handle_add_leg_list(switch_dial_handle_t *handle, switch_dial_leg_list_t **leg_listP);
 SWITCH_DECLARE(void) switch_dial_leg_list_add_leg(switch_dial_leg_list_t *parent, switch_dial_leg_t **legP, const char *dial_string);
 SWITCH_DECLARE(void) switch_dial_leg_list_add_leg_printf(switch_dial_leg_list_t *parent, switch_dial_leg_t **legP, const char *fmt, ...);
index bb3bf27abf4ba85cfe975f848db0eb49ac06861c..0ed6f0644f8609a2f0e5af17eddab9c5be96a0a4 100644 (file)
@@ -4384,6 +4384,168 @@ SWITCH_DECLARE(switch_event_t *) switch_dial_leg_get_vars(switch_dial_leg_t *leg
 }
 
 
+static switch_status_t vars_serialize_json_obj(switch_event_t *event, cJSON **json)
+{
+       switch_event_header_t *hp;
+       *json = cJSON_CreateObject();
+       for (hp = event->headers; hp; hp = hp->next) {
+               if (hp->name && hp->value) {
+                       cJSON_AddItemToObject(*json, hp->name, cJSON_CreateString(hp->value));
+               }
+       }
+       return SWITCH_STATUS_SUCCESS;
+}
+
+
+static switch_status_t leg_serialize_json_obj(switch_dial_leg_t *leg, cJSON **json)
+{
+       cJSON *vars_json = NULL;
+       *json = cJSON_CreateObject();
+       if (leg->dial_string) {
+               cJSON_AddStringToObject(*json, "dial_string", leg->dial_string);
+       }
+       if (leg->leg_vars && vars_serialize_json_obj(leg->leg_vars, &vars_json) == SWITCH_STATUS_SUCCESS && vars_json) {
+               cJSON_AddItemToObject(*json, "vars", vars_json);
+       }
+       return SWITCH_STATUS_SUCCESS;
+}
+
+
+static switch_status_t leg_list_serialize_json_obj(switch_dial_leg_list_t *ll, cJSON **json)
+{
+       int i;
+       cJSON *legs_json = cJSON_CreateArray();
+       *json = cJSON_CreateObject();
+       cJSON_AddItemToObject(*json, "legs", legs_json);
+       for (i = 0; i < ll->leg_idx; i++) {
+               switch_dial_leg_t *leg = ll->legs[i];
+               cJSON *leg_json = NULL;
+               if (leg_serialize_json_obj(leg, &leg_json) == SWITCH_STATUS_SUCCESS && leg_json) {
+                       cJSON_AddItemToArray(legs_json, leg_json);
+               }
+       }
+       return SWITCH_STATUS_SUCCESS;
+}
+
+
+SWITCH_DECLARE(switch_status_t) switch_dial_handle_serialize_json_obj(switch_dial_handle_t *handle, cJSON **json)
+{
+       int i;
+       cJSON *global_vars_json = NULL;
+       cJSON *leg_lists_json = NULL;
+       if (!handle) {
+               return SWITCH_STATUS_FALSE;
+       }
+       *json = cJSON_CreateObject();
+       if (handle->global_vars && vars_serialize_json_obj(handle->global_vars, &global_vars_json) == SWITCH_STATUS_SUCCESS && global_vars_json) {
+               cJSON_AddItemToObject(*json, "vars", global_vars_json);
+       }
+
+       leg_lists_json = cJSON_CreateArray();
+       cJSON_AddItemToObject(*json, "leg_lists", leg_lists_json);
+       for (i = 0; i < handle->leg_list_idx; i++) {
+               switch_dial_leg_list_t *ll = handle->leg_lists[i];
+               cJSON *leg_list_json = NULL;
+               if (leg_list_serialize_json_obj(ll, &leg_list_json) == SWITCH_STATUS_SUCCESS && leg_list_json) {
+                       cJSON_AddItemToArray(leg_lists_json, leg_list_json);
+               }
+       }
+
+       return SWITCH_STATUS_SUCCESS;
+}
+
+
+SWITCH_DECLARE(switch_status_t) switch_dial_handle_serialize_json(switch_dial_handle_t *handle, char **str)
+{
+       cJSON *json = NULL;
+       if (switch_dial_handle_serialize_json_obj(handle, &json) == SWITCH_STATUS_SUCCESS && json) {
+               *str = cJSON_PrintUnformatted(json);
+               cJSON_Delete(json);
+               return SWITCH_STATUS_SUCCESS;
+       }
+       return SWITCH_STATUS_FALSE;
+}
+
+
+SWITCH_DECLARE(switch_status_t) switch_dial_handle_create_json_obj(switch_dial_handle_t **handle, cJSON *json)
+{
+       cJSON *vars_json = NULL;
+       cJSON *var_json = NULL;
+       cJSON *leg_lists_json = NULL;
+       if (!json) {
+               return SWITCH_STATUS_FALSE;
+       }
+       switch_dial_handle_create(handle);
+
+       leg_lists_json = cJSON_GetObjectItem(json, "leg_lists");
+       if (leg_lists_json && leg_lists_json->type == cJSON_Array) {
+               cJSON *leg_list_json = NULL;
+               cJSON_ArrayForEach(leg_list_json, leg_lists_json) {
+                       cJSON *legs_json = cJSON_GetObjectItem(leg_list_json, "legs");
+                       cJSON *leg_json = NULL;
+                       switch_dial_leg_list_t *ll = NULL;
+                       if (!legs_json || legs_json->type != cJSON_Array) {
+                               continue;
+                       }
+                       switch_dial_handle_add_leg_list(*handle, &ll);
+                       cJSON_ArrayForEach(leg_json, legs_json) {
+                               switch_dial_leg_t *leg = NULL;
+                               const char *dial_string = NULL;
+                               if (!leg_json || leg_json->type != cJSON_Object) {
+                                       continue;
+                               }
+                               dial_string = cJSON_GetObjectCstr(leg_json, "dial_string");
+                               if (!dial_string) {
+                                       continue;
+                               }
+                               switch_dial_leg_list_add_leg(ll, &leg, dial_string);
+
+                               vars_json = cJSON_GetObjectItem(leg_json, "vars");
+                               if (vars_json && vars_json->type == cJSON_Object) {
+                                       cJSON_ArrayForEach(var_json, vars_json) {
+                                               if (!var_json || var_json->type != cJSON_String || !var_json->valuestring || !var_json->string) {
+                                                       continue;
+                                               }
+                                               switch_dial_handle_add_leg_var(leg, var_json->string, var_json->valuestring);
+                                       }
+                               }
+                       }
+               }
+       }
+
+       vars_json = cJSON_GetObjectItem(json, "vars");
+       if (vars_json && vars_json->type == cJSON_Object) {
+               cJSON_ArrayForEach(var_json, vars_json) {
+                       if (!var_json || var_json->type != cJSON_String || !var_json->valuestring || !var_json->string) {
+                               continue;
+                       }
+                       switch_dial_handle_add_global_var(*handle, var_json->string, var_json->valuestring);
+               }
+       }
+       return SWITCH_STATUS_SUCCESS;
+}
+
+
+SWITCH_DECLARE(switch_status_t) switch_dial_handle_create_json(switch_dial_handle_t **handle, const char *handle_string)
+{
+       switch_status_t status;
+       cJSON *handle_json = NULL;
+
+       if (zstr(handle_string)) {
+               return SWITCH_STATUS_FALSE;
+       }
+
+       handle_json = cJSON_Parse(handle_string);
+       if (!handle_json) {
+               return SWITCH_STATUS_FALSE;
+       }
+
+       status = switch_dial_handle_create_json_obj(handle, handle_json);
+       cJSON_Delete(handle_json);
+       return status;
+}
+
+
 static switch_status_t o_bridge_on_dtmf(switch_core_session_t *session, void *input, switch_input_type_t itype, void *buf, unsigned int buflen)
 {
        char *str = (char *) buf;
index 1b7ff19a4a5ae391bfef8a68a5393bf45088a91b..8cbdfa2a9d0439a4ba22b940e4f7398ea097f23f 100644 (file)
@@ -137,6 +137,66 @@ FST_CORE_BEGIN("./conf")
                        fst_check(destroy == 2);
                }
                FST_TEST_END()
+
+               FST_TEST_BEGIN(dial_handle_create_json)
+               {
+                       const char *dh_str = "{\n"
+                       "    \"vars\": {\n"
+                       "        \"foo\": \"bar\",\n"
+                       "        \"absolute_codec_string\": \"opus,pcmu,pcma\",\n"
+                       "        \"ignore_early_media\": \"true\"\n"
+                       "    },\n"
+                       "    \"leg_lists\": [\n"
+                       "        { \"legs\": [\n"
+                       "            { \n"
+                       "                \"dial_string\": \"loopback/dest\", \n"
+                       "                \"vars\": {\n"
+                       "                    \"bar\": \"bar\"\n"
+                       "                }\n"
+                       "            },\n"
+                       "            { \n"
+                       "                \"dial_string\": \"sofia/gateway/gw/12345\"\n"
+                       "            }\n"
+                       "        ] },\n"
+                       "        { \"legs\": [\n"
+                       "            {\n"
+                       "                \"dial_string\": \"sofia/external/foo@example.com^5551231234\",\n"
+                       "                \"vars\": {\n"
+                       "                    \"sip_h_X-Custom\": \"my val\"\n"
+                       "                }\n"
+                       "            }\n"
+                       "        ] },\n"
+                       "        { \"legs\": [\n"
+                       "            {\n"
+                       "                \"dial_string\": \"group/my_group\"\n"
+                       "            }\n"
+                       "        ] }\n"
+                       "    ]\n"
+                       "}";
+
+                       // create dial handle from json string, convert back to json and compare
+                       switch_dial_handle_t *dh = NULL;
+                       char *dh_str2 = NULL;
+                       char *dh_str3 = NULL;
+                       cJSON *dh_json = NULL;
+                       fst_requires(switch_dial_handle_create_json(&dh, dh_str) == SWITCH_STATUS_SUCCESS);
+                       fst_requires(dh != NULL);
+                       fst_requires(switch_dial_handle_serialize_json_obj(dh, &dh_json) == SWITCH_STATUS_SUCCESS);
+                       fst_requires(dh_json != NULL);
+                       fst_requires(switch_dial_handle_serialize_json(dh, &dh_str2) == SWITCH_STATUS_SUCCESS);
+                       fst_requires(dh_str2 != NULL);
+                       fst_check_string_equals(dh_str2, "{\"vars\":{\"foo\":\"bar\",\"absolute_codec_string\":\"opus,pcmu,pcma\",\"ignore_early_media\":\"true\"},\"leg_lists\":[{\"legs\":[{\"dial_string\":\"loopback/dest\",\"vars\":{\"bar\":\"bar\"}},{\"dial_string\":\"sofia/gateway/gw/12345\"}]},{\"legs\":[{\"dial_string\":\"sofia/external/foo@example.com^5551231234\",\"vars\":{\"sip_h_X-Custom\":\"my val\"}}]},{\"legs\":[{\"dial_string\":\"group/my_group\"}]}]}");
+
+                       dh_str3 = cJSON_PrintUnformatted(dh_json);
+                       fst_requires(dh_str3);
+                       fst_check_string_equals(dh_str2, dh_str3);
+
+                       switch_safe_free(dh_str2);
+                       switch_safe_free(dh_str3);
+                       cJSON_Delete(dh_json);
+                       switch_dial_handle_destroy(&dh);
+               }
+               FST_TEST_END();
        }
        FST_SUITE_END()
 }