FS-11893 [core] add switch_dial_handle_create_json() and switch_dial_handle_serialize_json() for dial handle/json conversions

This commit is contained in:
Chris Rienzo 2019-06-18 14:56:57 +00:00 committed by Andrey Volk
parent 6c1948e370
commit fb695c528e
3 changed files with 226 additions and 0 deletions

View 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, ...);

View 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;

View 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()
}