diff options
Diffstat (limited to 'res')
42 files changed, 4878 insertions, 2320 deletions
diff --git a/res/Makefile b/res/Makefile index c69862802..1310dae3a 100644 --- a/res/Makefile +++ b/res/Makefile @@ -83,5 +83,8 @@ $(subst .c,.o,$(wildcard parking/*.c)): _ASTCFLAGS+=$(call MOD_ASTCFLAGS,res_par res_stasis_http.so: stasis_http/ari_websockets.o stasis_http/ari_websockets.o: _ASTCFLAGS+=$(call MOD_ASTCFLAGS,res_stasis_http_asterisk) +res_ari_model.so: stasis_http/ari_model_validators.o +stasis_http/ari_model_validators.o: _ASTCFLAGS+=$(call MOD_ASTCFLAGS,res_ari_model) + # Dependencies for res_stasis_http_*.so are generated, so they're in this file include stasis_http.make diff --git a/res/res_ari_model.c b/res/res_ari_model.c new file mode 100644 index 000000000..fd2ec6493 --- /dev/null +++ b/res/res_ari_model.c @@ -0,0 +1,207 @@ +/* + * Asterisk -- An open source telephony toolkit. + * + * Copyright (C) 2013, Digium, Inc. + * + * David M. Lee, II <dlee@digium.com> + * + * See http://www.asterisk.org for more information about + * the Asterisk project. Please do not directly contact + * any of the maintainers of this project for assistance; + * the project provides a web site, mailing lists and IRC + * channels for your use. + * + * This program is free software, distributed under the terms of + * the GNU General Public License Version 2. See the LICENSE file + * at the top of the source tree. + */ + +/*! \file + * + * \brief Implementation Swagger validators. + * + * \author David M. Lee, II <dlee@digium.com> + */ + +/*** MODULEINFO + <support_level>core</support_level> + ***/ + +#include "asterisk.h" + +ASTERISK_FILE_VERSION(__FILE__, "$Revision$") + +#include "stasis_http/ari_model_validators.h" +#include "asterisk/logger.h" +#include "asterisk/module.h" +#include "asterisk/utils.h" + +#include <regex.h> + +/* Regex to match date strings */ +static regex_t date_regex; + +/* Regex for YYYY-MM-DD */ +#define REGEX_YMD "[0-9]{4}-[01][0-9]-[0-3][0-9]" + +/* Regex for hh:mm(:ss(.s)); seconds and subseconds optional + * Handles the probably impossible case of a leap second, too */ +#define REGEX_HMS "[0-2][0-9]:[0-5][0-9](:[0-6][0-9](.[0-9]+)?)?" + +/* Regex for timezone: (+|-)hh(:mm), with optional colon. */ +#define REGEX_TZ "(Z|[-+][0-2][0-9](:?[0-5][0-9])?)" + +/* REGEX for ISO 8601, the time specifier optional */ +#define ISO8601_PATTERN "^" REGEX_YMD "(T" REGEX_HMS REGEX_TZ ")?$" + +static int check_type(struct ast_json *json, enum ast_json_type expected) +{ + enum ast_json_type actual; + + if (!json) { + ast_log(LOG_ERROR, "Expected type %s, was NULL\n", + ast_json_typename(expected)); + return 0; + } + + actual = ast_json_typeof(json); + if (expected != actual) { + ast_log(LOG_ERROR, "Expected type %s, was %s\n", + ast_json_typename(expected), ast_json_typename(actual)); + return 0; + } + return 1; +} + +static int check_range(intmax_t minval, intmax_t maxval, struct ast_json *json) +{ + intmax_t v; + + if (!check_type(json, AST_JSON_INTEGER)) { + return 0; + } + + v = ast_json_integer_get(json); + + if (v < minval || maxval < v) { + ast_log(LOG_ERROR, "Value out of range. Expected %jd <= %jd <= %jd\n", minval, v, maxval); + return 0; + } + return 1; +} + +int ari_validate_void(struct ast_json *json) +{ + return check_type(json, AST_JSON_NULL); +} + +int ari_validate_byte(struct ast_json *json) +{ + /* Java bytes are signed, which accounts for great fun for all */ + return check_range(-128, 255, json); +} + +int ari_validate_boolean(struct ast_json *json) +{ + enum ast_json_type actual = ast_json_typeof(json); + switch (actual) { + case AST_JSON_TRUE: + case AST_JSON_FALSE: + return 1; + default: + ast_log(LOG_ERROR, "Expected type boolean, was %s\n", + ast_json_typename(actual)); + return 0; + } +} + +int ari_validate_int(struct ast_json *json) +{ + /* Swagger int's are 32-bit */ + return check_range(-2147483648, 2147483647, json); +} + +int ari_validate_long(struct ast_json *json) +{ + /* All integral values are valid longs. No need for range check. */ + return check_type(json, AST_JSON_INTEGER); +} + +int ari_validate_float(struct ast_json *json) +{ + return check_type(json, AST_JSON_REAL); +} + +int ari_validate_double(struct ast_json *json) +{ + return check_type(json, AST_JSON_REAL); +} + +int ari_validate_string(struct ast_json *json) +{ + return check_type(json, AST_JSON_STRING); +} + +int ari_validate_date(struct ast_json *json) +{ + /* Dates are ISO-8601 strings */ + const char *str; + if (!check_type(json, AST_JSON_STRING)) { + return 0; + } + str = ast_json_string_get(json); + ast_assert(str != NULL); + if (regexec(&date_regex, str, 0, NULL, 0) != 0) { + ast_log(LOG_ERROR, "Date field is malformed: '%s'\n", str); + return 0; + } + return 1; +} + +int ari_validate_list(struct ast_json *json, int (*fn)(struct ast_json *)) +{ + int res = 1; + size_t i; + + if (!check_type(json, AST_JSON_ARRAY)) { + return 0; + } + + for (i = 0; i < ast_json_array_size(json); ++i) { + int member_res; + member_res = fn(ast_json_array_get(json, i)); + if (!member_res) { + ast_log(LOG_ERROR, + "Array member %zd failed validation\n", i); + res = 0; + } + } + + return res; +} + +static int load_module(void) +{ + int res; + res = regcomp(&date_regex, ISO8601_PATTERN, + REG_EXTENDED | REG_ICASE | REG_NOSUB); + + if (res != 0) { + return AST_MODULE_LOAD_FAILURE; + } + return AST_MODULE_LOAD_SUCCESS; +} + +static int unload_module(void) +{ + regfree(&date_regex); + return 0; +} + +AST_MODULE_INFO(ASTERISK_GPL_KEY, + AST_MODFLAG_LOAD_ORDER | AST_MODFLAG_GLOBAL_SYMBOLS, + "ARI Model validators", + .load = load_module, + .unload = unload_module, + .load_pri = AST_MODPRI_APP_DEPEND, + ); diff --git a/res/res_ari_model.exports.in b/res/res_ari_model.exports.in new file mode 100644 index 000000000..160e23f43 --- /dev/null +++ b/res/res_ari_model.exports.in @@ -0,0 +1,6 @@ +{ + global: + LINKER_SYMBOL_PREFIXari_*; + local: + *; +}; diff --git a/res/res_stasis.c b/res/res_stasis.c index de432e409..ed3823051 100644 --- a/res/res_stasis.c +++ b/res/res_stasis.c @@ -48,7 +48,6 @@ */ /*** MODULEINFO - <depend>res_stasis_json_events</depend> <support_level>core</support_level> ***/ @@ -66,7 +65,6 @@ ASTERISK_FILE_VERSION(__FILE__, "$Revision$") #include "asterisk/strings.h" #include "stasis/app.h" #include "stasis/control.h" -#include "stasis_json/resource_events.h" /*! Time to wait for a frame in the application */ #define MAX_WAIT_MS 200 @@ -233,28 +231,60 @@ static struct ao2_container *get_apps_watching_channel(const char *uniqueid) /*! \brief Typedef for callbacks that get called on channel snapshot updates */ typedef struct ast_json *(*channel_snapshot_monitor)( struct ast_channel_snapshot *old_snapshot, - struct ast_channel_snapshot *new_snapshot); + struct ast_channel_snapshot *new_snapshot, + const struct timeval *tv); + +static struct ast_json *simple_channel_event( + const char *type, + struct ast_channel_snapshot *snapshot, + const struct timeval *tv) +{ + return ast_json_pack("{s: s, s: o, s: o}", + "type", type, + "timestamp", ast_json_timeval(*tv, NULL), + "channel", ast_channel_snapshot_to_json(snapshot)); +} + +static struct ast_json *channel_created_event( + struct ast_channel_snapshot *snapshot, + const struct timeval *tv) +{ + return simple_channel_event("ChannelCreated", snapshot, tv); +} + +static struct ast_json *channel_destroyed_event( + struct ast_channel_snapshot *snapshot, + const struct timeval *tv) +{ + return ast_json_pack("{s: s, s: o, s: i, s: s, s: o}", + "type", "ChannelDestroyed", + "timestamp", ast_json_timeval(*tv, NULL), + "cause", snapshot->hangupcause, + "cause_txt", ast_cause2str(snapshot->hangupcause), + "channel", ast_channel_snapshot_to_json(snapshot)); +} + +static struct ast_json *channel_state_change_event( + struct ast_channel_snapshot *snapshot, + const struct timeval *tv) +{ + return simple_channel_event("ChannelStateChange", snapshot, tv); +} /*! \brief Handle channel state changes */ static struct ast_json *channel_state( struct ast_channel_snapshot *old_snapshot, - struct ast_channel_snapshot *new_snapshot) + struct ast_channel_snapshot *new_snapshot, + const struct timeval *tv) { - RAII_VAR(struct ast_json *, json, NULL, ast_json_unref); struct ast_channel_snapshot *snapshot = new_snapshot ? new_snapshot : old_snapshot; if (!old_snapshot) { - return stasis_json_event_channel_created_create(snapshot); + return channel_created_event(snapshot, tv); } else if (!new_snapshot) { - json = ast_json_pack("{s: i, s: s}", - "cause", snapshot->hangupcause, - "cause_txt", ast_cause2str(snapshot->hangupcause)); - if (!json) { - return NULL; - } - return stasis_json_event_channel_destroyed_create(snapshot, json); + return channel_destroyed_event(snapshot, tv); } else if (old_snapshot->state != new_snapshot->state) { - return stasis_json_event_channel_state_change_create(snapshot); + return channel_state_change_event(snapshot, tv); } return NULL; @@ -262,7 +292,8 @@ static struct ast_json *channel_state( static struct ast_json *channel_dialplan( struct ast_channel_snapshot *old_snapshot, - struct ast_channel_snapshot *new_snapshot) + struct ast_channel_snapshot *new_snapshot, + const struct timeval *tv) { RAII_VAR(struct ast_json *, json, NULL, ast_json_unref); @@ -280,19 +311,18 @@ static struct ast_json *channel_dialplan( return NULL; } - json = ast_json_pack("{s: s, s: s}", - "application", new_snapshot->appl, - "application_data", new_snapshot->data); - if (!json) { - return NULL; - } - - return stasis_json_event_channel_dialplan_create(new_snapshot, json); + return ast_json_pack("{s: s, s: o, s: s, s: s, s: o}", + "type", "ChannelDialplan", + "timestamp", ast_json_timeval(*tv, NULL), + "dialplan_app", new_snapshot->appl, + "dialplan_app_data", new_snapshot->data, + "channel", ast_channel_snapshot_to_json(new_snapshot)); } static struct ast_json *channel_callerid( struct ast_channel_snapshot *old_snapshot, - struct ast_channel_snapshot *new_snapshot) + struct ast_channel_snapshot *new_snapshot, + const struct timeval *tv) { RAII_VAR(struct ast_json *, json, NULL, ast_json_unref); @@ -305,29 +335,16 @@ static struct ast_json *channel_callerid( return NULL; } - json = ast_json_pack("{s: i, s: s}", + return ast_json_pack("{s: s, s: o, s: i, s: s, s: o}", + "type", "ChannelCallerId", + "timestamp", ast_json_timeval(*tv, NULL), "caller_presentation", new_snapshot->caller_pres, - "caller_presentation_txt", ast_describe_caller_presentation(new_snapshot->caller_pres)); - if (!json) { - return NULL; - } - - return stasis_json_event_channel_caller_id_create(new_snapshot, json); -} - -static struct ast_json *channel_snapshot( - struct ast_channel_snapshot *old_snapshot, - struct ast_channel_snapshot *new_snapshot) -{ - if (!new_snapshot) { - return NULL; - } - - return stasis_json_event_channel_snapshot_create(new_snapshot); + "caller_presentation_txt", ast_describe_caller_presentation( + new_snapshot->caller_pres), + "channel", ast_channel_snapshot_to_json(new_snapshot)); } channel_snapshot_monitor channel_monitors[] = { - channel_snapshot, channel_state, channel_dialplan, channel_callerid @@ -351,6 +368,9 @@ static void sub_channel_snapshot_handler(void *data, struct stasis_cache_update *update = stasis_message_data(message); struct ast_channel_snapshot *new_snapshot = stasis_message_data(update->new_snapshot); struct ast_channel_snapshot *old_snapshot = stasis_message_data(update->old_snapshot); + /* Pull timestamp from the new snapshot, or from the update message + * when there isn't one. */ + const struct timeval *tv = update->new_snapshot ? stasis_message_timestamp(update->new_snapshot) : stasis_message_timestamp(message); int i; watching_apps = get_apps_watching_channel(new_snapshot ? new_snapshot->uniqueid : old_snapshot->uniqueid); @@ -361,7 +381,7 @@ static void sub_channel_snapshot_handler(void *data, for (i = 0; i < ARRAY_LEN(channel_monitors); ++i) { RAII_VAR(struct ast_json *, msg, NULL, ast_json_unref); - msg = channel_monitors[i](old_snapshot, new_snapshot); + msg = channel_monitors[i](old_snapshot, new_snapshot, tv); if (msg) { ao2_callback(watching_apps, OBJ_NODATA, app_send_cb, msg); } @@ -373,22 +393,26 @@ static void distribute_message(struct ao2_container *apps, struct ast_json *msg) ao2_callback(apps, OBJ_NODATA, app_send_cb, msg); } -static void generic_blob_handler(struct ast_channel_blob *obj, channel_blob_handler_cb handler_cb) +static void sub_channel_blob_handler(void *data, + struct stasis_subscription *sub, + struct stasis_topic *topic, + struct stasis_message *message) { RAII_VAR(struct ast_json *, msg, NULL, ast_json_unref); RAII_VAR(struct ao2_container *, watching_apps, NULL, ao2_cleanup); + struct ast_channel_blob *obj = stasis_message_data(message); if (!obj->snapshot) { return; } - watching_apps = get_apps_watching_channel(obj->snapshot->uniqueid); - if (!watching_apps) { + msg = stasis_message_to_json(message); + if (!msg) { return; } - msg = handler_cb(obj); - if (!msg) { + watching_apps = get_apps_watching_channel(obj->snapshot->uniqueid); + if (!watching_apps) { return; } @@ -446,7 +470,6 @@ int app_send_start_msg(struct app *app, struct ast_channel *chan, int argc, char *argv[]) { RAII_VAR(struct ast_json *, msg, NULL, ast_json_unref); - RAII_VAR(struct ast_json *, blob, NULL, ast_json_unref); RAII_VAR(struct ast_channel_snapshot *, snapshot, NULL, ao2_cleanup); struct ast_json *json_args; @@ -460,13 +483,16 @@ int app_send_start_msg(struct app *app, struct ast_channel *chan, return -1; } - blob = ast_json_pack("{s: []}", "args"); - if (!blob) { + msg = ast_json_pack("{s: s, s: [], s: o}", + "type", "StasisStart", + "args", + "channel", ast_channel_snapshot_to_json(snapshot)); + if (!msg) { return -1; } /* Append arguments to args array */ - json_args = ast_json_object_get(blob, "args"); + json_args = ast_json_object_get(msg, "args"); ast_assert(json_args != NULL); for (i = 0; i < argc; ++i) { int r = ast_json_array_append(json_args, @@ -477,11 +503,6 @@ int app_send_start_msg(struct app *app, struct ast_channel *chan, } } - msg = stasis_json_event_stasis_start_create(snapshot, blob); - if (!msg) { - return -1; - } - app_send(app, msg); return 0; } @@ -499,7 +520,9 @@ int app_send_end_msg(struct app *app, struct ast_channel *chan) return -1; } - msg = stasis_json_event_stasis_end_create(snapshot); + msg = ast_json_pack("{s: s, s: o}", + "type", "StasisEnd", + "channel", ast_channel_snapshot_to_json(snapshot)); if (!msg) { return -1; } @@ -633,15 +656,13 @@ int stasis_app_register(const char *app_name, stasis_app_cb handler, void *data) app = ao2_find(apps_registry, app_name, OBJ_KEY | OBJ_NOLOCK); if (app) { - RAII_VAR(struct ast_json *, blob, NULL, ast_json_unref); RAII_VAR(struct ast_json *, msg, NULL, ast_json_unref); - blob = ast_json_pack("{s: s}", "application", app_name); - if (blob) { - msg = stasis_json_event_application_replaced_create(blob); - if (msg) { - app_send(app, msg); - } + msg = ast_json_pack("{s: s, s: s}", + "type", "ApplicationReplaced", + "application", app_name); + if (msg) { + app_send(app, msg); } app_update(app, handler, data); @@ -665,82 +686,6 @@ void stasis_app_unregister(const char *app_name) } } -static struct ast_json *handle_blob_dtmf(struct ast_channel_blob *obj) -{ - RAII_VAR(struct ast_json *, extra, NULL, ast_json_unref); - RAII_VAR(struct ast_json *, msg, NULL, ast_json_unref); - const char *direction; - - /* To simplify events, we'll only generate on receive */ - direction = ast_json_string_get( - ast_json_object_get(obj->blob, "direction")); - - if (strcmp("Received", direction) != 0) { - return NULL; - } - - extra = ast_json_pack( - "{s: o}", - "digit", ast_json_ref(ast_json_object_get(obj->blob, "digit"))); - if (!extra) { - return NULL; - } - - return stasis_json_event_channel_dtmf_received_create(obj->snapshot, extra); -} - -/* To simplify events, we'll only generate on DTMF end (dtmf_end type) */ -static void sub_dtmf_handler(void *data, - struct stasis_subscription *sub, - struct stasis_topic *topic, - struct stasis_message *message) -{ - struct ast_channel_blob *obj = stasis_message_data(message); - generic_blob_handler(obj, handle_blob_dtmf); -} - -static struct ast_json *handle_blob_userevent(struct ast_channel_blob *obj) -{ - return stasis_json_event_channel_userevent_create(obj->snapshot, obj->blob); -} - -static void sub_userevent_handler(void *data, - struct stasis_subscription *sub, - struct stasis_topic *topic, - struct stasis_message *message) -{ - struct ast_channel_blob *obj = stasis_message_data(message); - generic_blob_handler(obj, handle_blob_userevent); -} - -static struct ast_json *handle_blob_hangup_request(struct ast_channel_blob *obj) -{ - return stasis_json_event_channel_hangup_request_create(obj->snapshot, obj->blob); -} - -static void sub_hangup_request_handler(void *data, - struct stasis_subscription *sub, - struct stasis_topic *topic, - struct stasis_message *message) -{ - struct ast_channel_blob *obj = stasis_message_data(message); - generic_blob_handler(obj, handle_blob_hangup_request); -} - -static struct ast_json *handle_blob_varset(struct ast_channel_blob *obj) -{ - return stasis_json_event_channel_varset_create(obj->snapshot, obj->blob); -} - -static void sub_varset_handler(void *data, - struct stasis_subscription *sub, - struct stasis_topic *topic, - struct stasis_message *message) -{ - struct ast_channel_blob *obj = stasis_message_data(message); - generic_blob_handler(obj, handle_blob_varset); -} - void stasis_app_ref(void) { ast_module_ref(ast_module_info->self); @@ -788,6 +733,30 @@ static int remove_bridge_cb(void *obj, void *arg, int flags) return 0; } +static struct ast_json *simple_bridge_event( + const char *type, + struct ast_bridge_snapshot *snapshot, + const struct timeval *tv) +{ + return ast_json_pack("{s: s, s: o, s: o}", + "type", type, + "timestamp", ast_json_timeval(*tv, NULL), + "bridge", ast_bridge_snapshot_to_json(snapshot)); +} + +static struct ast_json *simple_bridge_channel_event( + const char *type, + struct ast_bridge_snapshot *bridge_snapshot, + struct ast_channel_snapshot *channel_snapshot, + const struct timeval *tv) +{ + return ast_json_pack("{s: s, s: o, s: o}", + "type", type, + "timestamp", ast_json_timeval(*tv, NULL), + "bridge", ast_bridge_snapshot_to_json(bridge_snapshot), + "channel", ast_channel_snapshot_to_json(channel_snapshot)); +} + static void sub_bridge_snapshot_handler(void *data, struct stasis_subscription *sub, struct stasis_topic *topic, @@ -797,6 +766,8 @@ static void sub_bridge_snapshot_handler(void *data, struct stasis_cache_update *update = stasis_message_data(message); struct ast_bridge_snapshot *new_snapshot = stasis_message_data(update->new_snapshot); struct ast_bridge_snapshot *old_snapshot = stasis_message_data(update->old_snapshot); + const struct timeval *tv = update->new_snapshot ? stasis_message_timestamp(update->new_snapshot) : stasis_message_timestamp(message); + RAII_VAR(struct ast_json *, msg, NULL, ast_json_unref); watching_apps = get_apps_watching_bridge(new_snapshot ? new_snapshot->uniqueid : old_snapshot->uniqueid); @@ -810,11 +781,11 @@ static void sub_bridge_snapshot_handler(void *data, /* The bridge has gone away. Create the message, make sure no apps are * watching this bridge anymore, and destroy the bridge's control * structure */ - msg = stasis_json_event_bridge_destroyed_create(old_snapshot); + msg = simple_bridge_event("BridgeDestroyed", old_snapshot, tv); ao2_callback(watching_apps, OBJ_NODATA, remove_bridge_cb, bridge_id); stasis_app_bridge_destroy(old_snapshot->uniqueid); } else if (!old_snapshot) { - msg = stasis_json_event_bridge_created_create(old_snapshot); + msg = simple_bridge_event("BridgeCreated", old_snapshot, tv); } if (!msg) { @@ -865,6 +836,7 @@ static void sub_bridge_merge_handler(void *data, struct ast_bridge_merge_message *merge = stasis_message_data(message); RAII_VAR(struct ast_json *, msg, NULL, ast_json_unref); RAII_VAR(struct ast_json *, blob, NULL, ast_json_unref); + const struct timeval *tv = stasis_message_timestamp(message); watching_apps_to = get_apps_watching_bridge(merge->to->uniqueid); if (watching_apps_to) { @@ -881,16 +853,16 @@ static void sub_bridge_merge_handler(void *data, return; } - /* The secondary bridge has to be packed into JSON by hand because the auto-generated - * JSON event generator can only handle one instance of a given snapshot type in an - * elegant way */ - blob = ast_json_pack("{s: o}", "bridge_from", ast_bridge_snapshot_to_json(merge->from)); - if (!blob) { + msg = ast_json_pack("{s: s, s: o, s: o, s: o}", + "type", "BridgeMerged", + "timestamp", ast_json_timeval(*tv, NULL), + "bridge", ast_bridge_snapshot_to_json(merge->to), + "bridge_from", ast_bridge_snapshot_to_json(merge->from)); + + if (!msg) { return; } - msg = stasis_json_event_bridge_merged_create(merge->to, blob); - distribute_message(watching_apps_all, msg); } @@ -920,7 +892,8 @@ static void sub_bridge_enter_handler(void *data, return; } - msg = stasis_json_event_channel_entered_bridge_create(obj->bridge, obj->channel); + msg = simple_bridge_channel_event("ChannelEnteredBridge", obj->bridge, + obj->channel, stasis_message_timestamp(message)); distribute_message(watching_apps_all, msg); } @@ -939,7 +912,8 @@ static void sub_bridge_leave_handler(void *data, return; } - msg = stasis_json_event_channel_left_bridge_create(obj->bridge, obj->channel); + msg = simple_bridge_channel_event("ChannelLeftBridge", obj->bridge, + obj->channel, stasis_message_timestamp(message)); distribute_message(watching_apps_bridge, msg); } @@ -972,10 +946,16 @@ static int load_module(void) } r |= stasis_message_router_add(channel_router, stasis_cache_update_type(), sub_channel_snapshot_handler, NULL); - r |= stasis_message_router_add(channel_router, ast_channel_user_event_type(), sub_userevent_handler, NULL); - r |= stasis_message_router_add(channel_router, ast_channel_varset_type(), sub_varset_handler, NULL); - r |= stasis_message_router_add(channel_router, ast_channel_dtmf_begin_type(), sub_dtmf_handler, NULL); - r |= stasis_message_router_add(channel_router, ast_channel_hangup_request_type(), sub_hangup_request_handler, NULL); + /* TODO: This could be handled a lot better. Instead of subscribing to + * the one caching topic and filtering out messages by channel id, we + * should have individual caching topics per-channel, with a shared + * back-end cache. That would simplify a lot of what's going on right + * here. + */ + r |= stasis_message_router_add(channel_router, ast_channel_user_event_type(), sub_channel_blob_handler, NULL); + r |= stasis_message_router_add(channel_router, ast_channel_varset_type(), sub_channel_blob_handler, NULL); + r |= stasis_message_router_add(channel_router, ast_channel_dtmf_end_type(), sub_channel_blob_handler, NULL); + r |= stasis_message_router_add(channel_router, ast_channel_hangup_request_type(), sub_channel_blob_handler, NULL); if (r) { return AST_MODULE_LOAD_FAILURE; } diff --git a/res/res_stasis_http.c b/res/res_stasis_http.c index fce108146..3ff6482b5 100644 --- a/res/res_stasis_http.c +++ b/res/res_stasis_http.c @@ -324,7 +324,7 @@ void stasis_http_response_ok(struct stasis_http_response *response, void stasis_http_response_no_content(struct stasis_http_response *response) { - response->message = NULL; + response->message = ast_json_null(); response->response_code = 204; response->response_text = "No Content"; } @@ -386,9 +386,7 @@ static void handle_options(struct stasis_rest_handlers *handler, /* Regular OPTIONS response */ add_allow_header(handler, response); - response->response_code = 204; - response->response_text = "No Content"; - response->message = NULL; + stasis_http_response_no_content(response); /* Parse CORS headers */ for (header = headers; header != NULL; header = header->next) { @@ -797,6 +795,11 @@ static void process_cors_request(struct ast_variable *headers, */ } +enum ast_json_encoding_format stasis_http_json_format(void) +{ + RAII_VAR(struct conf *, cfg, ao2_global_obj_ref(confs), ao2_cleanup); + return cfg->global->format; +} /*! * \internal @@ -819,7 +822,6 @@ static int stasis_http_callback(struct ast_tcptls_session_instance *ser, struct ast_variable *get_params, struct ast_variable *headers) { - RAII_VAR(struct conf *, cfg, ao2_global_obj_ref(confs), ao2_cleanup); RAII_VAR(struct ast_str *, response_headers, ast_str_create(40), ast_free); RAII_VAR(struct ast_str *, response_body, ast_str_create(256), ast_free); struct stasis_http_response response = {}; @@ -859,11 +861,10 @@ static int stasis_http_callback(struct ast_tcptls_session_instance *ser, return 0; } - /* Leaving message unset is only allowed for 204 (No Content). - * If you explicitly want to have no content for a different return - * code, set message to ast_json_null(). + /* If you explicitly want to have no content, set message to + * ast_json_null(). */ - ast_assert(response.response_code == 204 || response.message != NULL); + ast_assert(response.message != NULL); ast_assert(response.response_code > 0); ast_str_append(&response_headers, 0, "%s", ast_str_buffer(response.headers)); @@ -874,7 +875,7 @@ static int stasis_http_callback(struct ast_tcptls_session_instance *ser, if (response.message && !ast_json_is_null(response.message)) { ast_str_append(&response_headers, 0, "Content-type: application/json\r\n"); - if (ast_json_dump_str_format(response.message, &response_body, cfg->global->format) != 0) { + if (ast_json_dump_str_format(response.message, &response_body, stasis_http_json_format()) != 0) { /* Error encoding response */ response.response_code = 500; response.response_text = "Internal Server Error"; diff --git a/res/res_stasis_http_asterisk.c b/res/res_stasis_http_asterisk.c index 9f4fd63e1..01f082ad6 100644 --- a/res/res_stasis_http_asterisk.c +++ b/res/res_stasis_http_asterisk.c @@ -44,6 +44,9 @@ ASTERISK_FILE_VERSION(__FILE__, "$Revision$") #include "asterisk/module.h" #include "asterisk/stasis_app.h" #include "stasis_http/resource_asterisk.h" +#if defined(AST_DEVMODE) +#include "stasis_http/ari_model_validators.h" +#endif /*! * \brief Parameter parsing callback for /asterisk/info. @@ -53,9 +56,14 @@ ASTERISK_FILE_VERSION(__FILE__, "$Revision$") * \param[out] response Response to the HTTP request. */ static void stasis_http_get_asterisk_info_cb( - struct ast_variable *get_params, struct ast_variable *path_vars, - struct ast_variable *headers, struct stasis_http_response *response) + struct ast_variable *get_params, struct ast_variable *path_vars, + struct ast_variable *headers, struct stasis_http_response *response) { +#if defined(AST_DEVMODE) + int is_valid; + int code; +#endif /* AST_DEVMODE */ + struct ast_get_asterisk_info_args args = {}; struct ast_variable *i; @@ -66,6 +74,29 @@ static void stasis_http_get_asterisk_info_cb( {} } stasis_http_get_asterisk_info(headers, &args, response); +#if defined(AST_DEVMODE) + code = response->response_code; + + switch (code) { + case 500: /* Internal server error */ + is_valid = 1; + break; + default: + if (200 <= code && code <= 299) { + is_valid = ari_validate_asterisk_info( + response->message); + } else { + ast_log(LOG_ERROR, "Invalid error response %d for /asterisk/info\n", code); + is_valid = 0; + } + } + + if (!is_valid) { + ast_log(LOG_ERROR, "Response validation failed for /asterisk/info\n"); + stasis_http_response_error(response, 500, + "Internal Server Error", "Response validation failed"); + } +#endif /* AST_DEVMODE */ } /*! \brief REST handler for /api-docs/asterisk.{format} */ diff --git a/res/res_stasis_http_bridges.c b/res/res_stasis_http_bridges.c index 717b2f83f..a4801df13 100644 --- a/res/res_stasis_http_bridges.c +++ b/res/res_stasis_http_bridges.c @@ -44,6 +44,9 @@ ASTERISK_FILE_VERSION(__FILE__, "$Revision$") #include "asterisk/module.h" #include "asterisk/stasis_app.h" #include "stasis_http/resource_bridges.h" +#if defined(AST_DEVMODE) +#include "stasis_http/ari_model_validators.h" +#endif /*! * \brief Parameter parsing callback for /bridges. @@ -53,11 +56,39 @@ ASTERISK_FILE_VERSION(__FILE__, "$Revision$") * \param[out] response Response to the HTTP request. */ static void stasis_http_get_bridges_cb( - struct ast_variable *get_params, struct ast_variable *path_vars, - struct ast_variable *headers, struct stasis_http_response *response) + struct ast_variable *get_params, struct ast_variable *path_vars, + struct ast_variable *headers, struct stasis_http_response *response) { +#if defined(AST_DEVMODE) + int is_valid; + int code; +#endif /* AST_DEVMODE */ + struct ast_get_bridges_args args = {}; stasis_http_get_bridges(headers, &args, response); +#if defined(AST_DEVMODE) + code = response->response_code; + + switch (code) { + case 500: /* Internal server error */ + is_valid = 1; + break; + default: + if (200 <= code && code <= 299) { + is_valid = ari_validate_list(response->message, + ari_validate_bridge); + } else { + ast_log(LOG_ERROR, "Invalid error response %d for /bridges\n", code); + is_valid = 0; + } + } + + if (!is_valid) { + ast_log(LOG_ERROR, "Response validation failed for /bridges\n"); + stasis_http_response_error(response, 500, + "Internal Server Error", "Response validation failed"); + } +#endif /* AST_DEVMODE */ } /*! * \brief Parameter parsing callback for /bridges. @@ -67,9 +98,14 @@ static void stasis_http_get_bridges_cb( * \param[out] response Response to the HTTP request. */ static void stasis_http_new_bridge_cb( - struct ast_variable *get_params, struct ast_variable *path_vars, - struct ast_variable *headers, struct stasis_http_response *response) + struct ast_variable *get_params, struct ast_variable *path_vars, + struct ast_variable *headers, struct stasis_http_response *response) { +#if defined(AST_DEVMODE) + int is_valid; + int code; +#endif /* AST_DEVMODE */ + struct ast_new_bridge_args args = {}; struct ast_variable *i; @@ -80,6 +116,29 @@ static void stasis_http_new_bridge_cb( {} } stasis_http_new_bridge(headers, &args, response); +#if defined(AST_DEVMODE) + code = response->response_code; + + switch (code) { + case 500: /* Internal server error */ + is_valid = 1; + break; + default: + if (200 <= code && code <= 299) { + is_valid = ari_validate_bridge( + response->message); + } else { + ast_log(LOG_ERROR, "Invalid error response %d for /bridges\n", code); + is_valid = 0; + } + } + + if (!is_valid) { + ast_log(LOG_ERROR, "Response validation failed for /bridges\n"); + stasis_http_response_error(response, 500, + "Internal Server Error", "Response validation failed"); + } +#endif /* AST_DEVMODE */ } /*! * \brief Parameter parsing callback for /bridges/{bridgeId}. @@ -89,9 +148,14 @@ static void stasis_http_new_bridge_cb( * \param[out] response Response to the HTTP request. */ static void stasis_http_get_bridge_cb( - struct ast_variable *get_params, struct ast_variable *path_vars, - struct ast_variable *headers, struct stasis_http_response *response) + struct ast_variable *get_params, struct ast_variable *path_vars, + struct ast_variable *headers, struct stasis_http_response *response) { +#if defined(AST_DEVMODE) + int is_valid; + int code; +#endif /* AST_DEVMODE */ + struct ast_get_bridge_args args = {}; struct ast_variable *i; @@ -102,6 +166,30 @@ static void stasis_http_get_bridge_cb( {} } stasis_http_get_bridge(headers, &args, response); +#if defined(AST_DEVMODE) + code = response->response_code; + + switch (code) { + case 500: /* Internal server error */ + case 404: /* Bridge not found */ + is_valid = 1; + break; + default: + if (200 <= code && code <= 299) { + is_valid = ari_validate_bridge( + response->message); + } else { + ast_log(LOG_ERROR, "Invalid error response %d for /bridges/{bridgeId}\n", code); + is_valid = 0; + } + } + + if (!is_valid) { + ast_log(LOG_ERROR, "Response validation failed for /bridges/{bridgeId}\n"); + stasis_http_response_error(response, 500, + "Internal Server Error", "Response validation failed"); + } +#endif /* AST_DEVMODE */ } /*! * \brief Parameter parsing callback for /bridges/{bridgeId}. @@ -111,9 +199,14 @@ static void stasis_http_get_bridge_cb( * \param[out] response Response to the HTTP request. */ static void stasis_http_delete_bridge_cb( - struct ast_variable *get_params, struct ast_variable *path_vars, - struct ast_variable *headers, struct stasis_http_response *response) + struct ast_variable *get_params, struct ast_variable *path_vars, + struct ast_variable *headers, struct stasis_http_response *response) { +#if defined(AST_DEVMODE) + int is_valid; + int code; +#endif /* AST_DEVMODE */ + struct ast_delete_bridge_args args = {}; struct ast_variable *i; @@ -124,6 +217,30 @@ static void stasis_http_delete_bridge_cb( {} } stasis_http_delete_bridge(headers, &args, response); +#if defined(AST_DEVMODE) + code = response->response_code; + + switch (code) { + case 500: /* Internal server error */ + case 404: /* Bridge not found */ + is_valid = 1; + break; + default: + if (200 <= code && code <= 299) { + is_valid = ari_validate_void( + response->message); + } else { + ast_log(LOG_ERROR, "Invalid error response %d for /bridges/{bridgeId}\n", code); + is_valid = 0; + } + } + + if (!is_valid) { + ast_log(LOG_ERROR, "Response validation failed for /bridges/{bridgeId}\n"); + stasis_http_response_error(response, 500, + "Internal Server Error", "Response validation failed"); + } +#endif /* AST_DEVMODE */ } /*! * \brief Parameter parsing callback for /bridges/{bridgeId}/addChannel. @@ -133,9 +250,14 @@ static void stasis_http_delete_bridge_cb( * \param[out] response Response to the HTTP request. */ static void stasis_http_add_channel_to_bridge_cb( - struct ast_variable *get_params, struct ast_variable *path_vars, - struct ast_variable *headers, struct stasis_http_response *response) + struct ast_variable *get_params, struct ast_variable *path_vars, + struct ast_variable *headers, struct stasis_http_response *response) { +#if defined(AST_DEVMODE) + int is_valid; + int code; +#endif /* AST_DEVMODE */ + struct ast_add_channel_to_bridge_args args = {}; struct ast_variable *i; @@ -152,6 +274,32 @@ static void stasis_http_add_channel_to_bridge_cb( {} } stasis_http_add_channel_to_bridge(headers, &args, response); +#if defined(AST_DEVMODE) + code = response->response_code; + + switch (code) { + case 500: /* Internal server error */ + case 404: /* Bridge not found */ + case 409: /* Bridge not in Stasis application */ + case 422: /* Channel not found, or not in Stasis application */ + is_valid = 1; + break; + default: + if (200 <= code && code <= 299) { + is_valid = ari_validate_void( + response->message); + } else { + ast_log(LOG_ERROR, "Invalid error response %d for /bridges/{bridgeId}/addChannel\n", code); + is_valid = 0; + } + } + + if (!is_valid) { + ast_log(LOG_ERROR, "Response validation failed for /bridges/{bridgeId}/addChannel\n"); + stasis_http_response_error(response, 500, + "Internal Server Error", "Response validation failed"); + } +#endif /* AST_DEVMODE */ } /*! * \brief Parameter parsing callback for /bridges/{bridgeId}/removeChannel. @@ -161,9 +309,14 @@ static void stasis_http_add_channel_to_bridge_cb( * \param[out] response Response to the HTTP request. */ static void stasis_http_remove_channel_from_bridge_cb( - struct ast_variable *get_params, struct ast_variable *path_vars, - struct ast_variable *headers, struct stasis_http_response *response) + struct ast_variable *get_params, struct ast_variable *path_vars, + struct ast_variable *headers, struct stasis_http_response *response) { +#if defined(AST_DEVMODE) + int is_valid; + int code; +#endif /* AST_DEVMODE */ + struct ast_remove_channel_from_bridge_args args = {}; struct ast_variable *i; @@ -180,6 +333,29 @@ static void stasis_http_remove_channel_from_bridge_cb( {} } stasis_http_remove_channel_from_bridge(headers, &args, response); +#if defined(AST_DEVMODE) + code = response->response_code; + + switch (code) { + case 500: /* Internal server error */ + is_valid = 1; + break; + default: + if (200 <= code && code <= 299) { + is_valid = ari_validate_void( + response->message); + } else { + ast_log(LOG_ERROR, "Invalid error response %d for /bridges/{bridgeId}/removeChannel\n", code); + is_valid = 0; + } + } + + if (!is_valid) { + ast_log(LOG_ERROR, "Response validation failed for /bridges/{bridgeId}/removeChannel\n"); + stasis_http_response_error(response, 500, + "Internal Server Error", "Response validation failed"); + } +#endif /* AST_DEVMODE */ } /*! * \brief Parameter parsing callback for /bridges/{bridgeId}/record. @@ -189,9 +365,14 @@ static void stasis_http_remove_channel_from_bridge_cb( * \param[out] response Response to the HTTP request. */ static void stasis_http_record_bridge_cb( - struct ast_variable *get_params, struct ast_variable *path_vars, - struct ast_variable *headers, struct stasis_http_response *response) + struct ast_variable *get_params, struct ast_variable *path_vars, + struct ast_variable *headers, struct stasis_http_response *response) { +#if defined(AST_DEVMODE) + int is_valid; + int code; +#endif /* AST_DEVMODE */ + struct ast_record_bridge_args args = {}; struct ast_variable *i; @@ -223,6 +404,29 @@ static void stasis_http_record_bridge_cb( {} } stasis_http_record_bridge(headers, &args, response); +#if defined(AST_DEVMODE) + code = response->response_code; + + switch (code) { + case 500: /* Internal server error */ + is_valid = 1; + break; + default: + if (200 <= code && code <= 299) { + is_valid = ari_validate_live_recording( + response->message); + } else { + ast_log(LOG_ERROR, "Invalid error response %d for /bridges/{bridgeId}/record\n", code); + is_valid = 0; + } + } + + if (!is_valid) { + ast_log(LOG_ERROR, "Response validation failed for /bridges/{bridgeId}/record\n"); + stasis_http_response_error(response, 500, + "Internal Server Error", "Response validation failed"); + } +#endif /* AST_DEVMODE */ } /*! \brief REST handler for /api-docs/bridges.{format} */ diff --git a/res/res_stasis_http_channels.c b/res/res_stasis_http_channels.c index c865b3931..ebcc9e880 100644 --- a/res/res_stasis_http_channels.c +++ b/res/res_stasis_http_channels.c @@ -44,6 +44,9 @@ ASTERISK_FILE_VERSION(__FILE__, "$Revision$") #include "asterisk/module.h" #include "asterisk/stasis_app.h" #include "stasis_http/resource_channels.h" +#if defined(AST_DEVMODE) +#include "stasis_http/ari_model_validators.h" +#endif /*! * \brief Parameter parsing callback for /channels. @@ -53,11 +56,39 @@ ASTERISK_FILE_VERSION(__FILE__, "$Revision$") * \param[out] response Response to the HTTP request. */ static void stasis_http_get_channels_cb( - struct ast_variable *get_params, struct ast_variable *path_vars, - struct ast_variable *headers, struct stasis_http_response *response) + struct ast_variable *get_params, struct ast_variable *path_vars, + struct ast_variable *headers, struct stasis_http_response *response) { +#if defined(AST_DEVMODE) + int is_valid; + int code; +#endif /* AST_DEVMODE */ + struct ast_get_channels_args args = {}; stasis_http_get_channels(headers, &args, response); +#if defined(AST_DEVMODE) + code = response->response_code; + + switch (code) { + case 500: /* Internal server error */ + is_valid = 1; + break; + default: + if (200 <= code && code <= 299) { + is_valid = ari_validate_list(response->message, + ari_validate_channel); + } else { + ast_log(LOG_ERROR, "Invalid error response %d for /channels\n", code); + is_valid = 0; + } + } + + if (!is_valid) { + ast_log(LOG_ERROR, "Response validation failed for /channels\n"); + stasis_http_response_error(response, 500, + "Internal Server Error", "Response validation failed"); + } +#endif /* AST_DEVMODE */ } /*! * \brief Parameter parsing callback for /channels. @@ -67,9 +98,14 @@ static void stasis_http_get_channels_cb( * \param[out] response Response to the HTTP request. */ static void stasis_http_originate_cb( - struct ast_variable *get_params, struct ast_variable *path_vars, - struct ast_variable *headers, struct stasis_http_response *response) + struct ast_variable *get_params, struct ast_variable *path_vars, + struct ast_variable *headers, struct stasis_http_response *response) { +#if defined(AST_DEVMODE) + int is_valid; + int code; +#endif /* AST_DEVMODE */ + struct ast_originate_args args = {}; struct ast_variable *i; @@ -101,6 +137,29 @@ static void stasis_http_originate_cb( {} } stasis_http_originate(headers, &args, response); +#if defined(AST_DEVMODE) + code = response->response_code; + + switch (code) { + case 500: /* Internal server error */ + is_valid = 1; + break; + default: + if (200 <= code && code <= 299) { + is_valid = ari_validate_void( + response->message); + } else { + ast_log(LOG_ERROR, "Invalid error response %d for /channels\n", code); + is_valid = 0; + } + } + + if (!is_valid) { + ast_log(LOG_ERROR, "Response validation failed for /channels\n"); + stasis_http_response_error(response, 500, + "Internal Server Error", "Response validation failed"); + } +#endif /* AST_DEVMODE */ } /*! * \brief Parameter parsing callback for /channels/{channelId}. @@ -110,9 +169,14 @@ static void stasis_http_originate_cb( * \param[out] response Response to the HTTP request. */ static void stasis_http_get_channel_cb( - struct ast_variable *get_params, struct ast_variable *path_vars, - struct ast_variable *headers, struct stasis_http_response *response) + struct ast_variable *get_params, struct ast_variable *path_vars, + struct ast_variable *headers, struct stasis_http_response *response) { +#if defined(AST_DEVMODE) + int is_valid; + int code; +#endif /* AST_DEVMODE */ + struct ast_get_channel_args args = {}; struct ast_variable *i; @@ -123,6 +187,30 @@ static void stasis_http_get_channel_cb( {} } stasis_http_get_channel(headers, &args, response); +#if defined(AST_DEVMODE) + code = response->response_code; + + switch (code) { + case 500: /* Internal server error */ + case 404: /* Channel not found */ + is_valid = 1; + break; + default: + if (200 <= code && code <= 299) { + is_valid = ari_validate_channel( + response->message); + } else { + ast_log(LOG_ERROR, "Invalid error response %d for /channels/{channelId}\n", code); + is_valid = 0; + } + } + + if (!is_valid) { + ast_log(LOG_ERROR, "Response validation failed for /channels/{channelId}\n"); + stasis_http_response_error(response, 500, + "Internal Server Error", "Response validation failed"); + } +#endif /* AST_DEVMODE */ } /*! * \brief Parameter parsing callback for /channels/{channelId}. @@ -132,9 +220,14 @@ static void stasis_http_get_channel_cb( * \param[out] response Response to the HTTP request. */ static void stasis_http_delete_channel_cb( - struct ast_variable *get_params, struct ast_variable *path_vars, - struct ast_variable *headers, struct stasis_http_response *response) + struct ast_variable *get_params, struct ast_variable *path_vars, + struct ast_variable *headers, struct stasis_http_response *response) { +#if defined(AST_DEVMODE) + int is_valid; + int code; +#endif /* AST_DEVMODE */ + struct ast_delete_channel_args args = {}; struct ast_variable *i; @@ -145,6 +238,30 @@ static void stasis_http_delete_channel_cb( {} } stasis_http_delete_channel(headers, &args, response); +#if defined(AST_DEVMODE) + code = response->response_code; + + switch (code) { + case 500: /* Internal server error */ + case 404: /* Channel not found */ + is_valid = 1; + break; + default: + if (200 <= code && code <= 299) { + is_valid = ari_validate_void( + response->message); + } else { + ast_log(LOG_ERROR, "Invalid error response %d for /channels/{channelId}\n", code); + is_valid = 0; + } + } + + if (!is_valid) { + ast_log(LOG_ERROR, "Response validation failed for /channels/{channelId}\n"); + stasis_http_response_error(response, 500, + "Internal Server Error", "Response validation failed"); + } +#endif /* AST_DEVMODE */ } /*! * \brief Parameter parsing callback for /channels/{channelId}/dial. @@ -154,9 +271,14 @@ static void stasis_http_delete_channel_cb( * \param[out] response Response to the HTTP request. */ static void stasis_http_dial_cb( - struct ast_variable *get_params, struct ast_variable *path_vars, - struct ast_variable *headers, struct stasis_http_response *response) + struct ast_variable *get_params, struct ast_variable *path_vars, + struct ast_variable *headers, struct stasis_http_response *response) { +#if defined(AST_DEVMODE) + int is_valid; + int code; +#endif /* AST_DEVMODE */ + struct ast_dial_args args = {}; struct ast_variable *i; @@ -182,6 +304,31 @@ static void stasis_http_dial_cb( {} } stasis_http_dial(headers, &args, response); +#if defined(AST_DEVMODE) + code = response->response_code; + + switch (code) { + case 500: /* Internal server error */ + case 404: /* Channel not found */ + case 409: /* Channel not in a Stasis application */ + is_valid = 1; + break; + default: + if (200 <= code && code <= 299) { + is_valid = ari_validate_dialed( + response->message); + } else { + ast_log(LOG_ERROR, "Invalid error response %d for /channels/{channelId}/dial\n", code); + is_valid = 0; + } + } + + if (!is_valid) { + ast_log(LOG_ERROR, "Response validation failed for /channels/{channelId}/dial\n"); + stasis_http_response_error(response, 500, + "Internal Server Error", "Response validation failed"); + } +#endif /* AST_DEVMODE */ } /*! * \brief Parameter parsing callback for /channels/{channelId}/continue. @@ -191,9 +338,14 @@ static void stasis_http_dial_cb( * \param[out] response Response to the HTTP request. */ static void stasis_http_continue_in_dialplan_cb( - struct ast_variable *get_params, struct ast_variable *path_vars, - struct ast_variable *headers, struct stasis_http_response *response) + struct ast_variable *get_params, struct ast_variable *path_vars, + struct ast_variable *headers, struct stasis_http_response *response) { +#if defined(AST_DEVMODE) + int is_valid; + int code; +#endif /* AST_DEVMODE */ + struct ast_continue_in_dialplan_args args = {}; struct ast_variable *i; @@ -216,6 +368,31 @@ static void stasis_http_continue_in_dialplan_cb( {} } stasis_http_continue_in_dialplan(headers, &args, response); +#if defined(AST_DEVMODE) + code = response->response_code; + + switch (code) { + case 500: /* Internal server error */ + case 404: /* Channel not found */ + case 409: /* Channel not in a Stasis application */ + is_valid = 1; + break; + default: + if (200 <= code && code <= 299) { + is_valid = ari_validate_void( + response->message); + } else { + ast_log(LOG_ERROR, "Invalid error response %d for /channels/{channelId}/continue\n", code); + is_valid = 0; + } + } + + if (!is_valid) { + ast_log(LOG_ERROR, "Response validation failed for /channels/{channelId}/continue\n"); + stasis_http_response_error(response, 500, + "Internal Server Error", "Response validation failed"); + } +#endif /* AST_DEVMODE */ } /*! * \brief Parameter parsing callback for /channels/{channelId}/answer. @@ -225,9 +402,14 @@ static void stasis_http_continue_in_dialplan_cb( * \param[out] response Response to the HTTP request. */ static void stasis_http_answer_channel_cb( - struct ast_variable *get_params, struct ast_variable *path_vars, - struct ast_variable *headers, struct stasis_http_response *response) + struct ast_variable *get_params, struct ast_variable *path_vars, + struct ast_variable *headers, struct stasis_http_response *response) { +#if defined(AST_DEVMODE) + int is_valid; + int code; +#endif /* AST_DEVMODE */ + struct ast_answer_channel_args args = {}; struct ast_variable *i; @@ -238,6 +420,31 @@ static void stasis_http_answer_channel_cb( {} } stasis_http_answer_channel(headers, &args, response); +#if defined(AST_DEVMODE) + code = response->response_code; + + switch (code) { + case 500: /* Internal server error */ + case 404: /* Channel not found */ + case 409: /* Channel not in a Stasis application */ + is_valid = 1; + break; + default: + if (200 <= code && code <= 299) { + is_valid = ari_validate_void( + response->message); + } else { + ast_log(LOG_ERROR, "Invalid error response %d for /channels/{channelId}/answer\n", code); + is_valid = 0; + } + } + + if (!is_valid) { + ast_log(LOG_ERROR, "Response validation failed for /channels/{channelId}/answer\n"); + stasis_http_response_error(response, 500, + "Internal Server Error", "Response validation failed"); + } +#endif /* AST_DEVMODE */ } /*! * \brief Parameter parsing callback for /channels/{channelId}/mute. @@ -247,9 +454,14 @@ static void stasis_http_answer_channel_cb( * \param[out] response Response to the HTTP request. */ static void stasis_http_mute_channel_cb( - struct ast_variable *get_params, struct ast_variable *path_vars, - struct ast_variable *headers, struct stasis_http_response *response) + struct ast_variable *get_params, struct ast_variable *path_vars, + struct ast_variable *headers, struct stasis_http_response *response) { +#if defined(AST_DEVMODE) + int is_valid; + int code; +#endif /* AST_DEVMODE */ + struct ast_mute_channel_args args = {}; struct ast_variable *i; @@ -266,6 +478,31 @@ static void stasis_http_mute_channel_cb( {} } stasis_http_mute_channel(headers, &args, response); +#if defined(AST_DEVMODE) + code = response->response_code; + + switch (code) { + case 500: /* Internal server error */ + case 404: /* Channel not found */ + case 409: /* Channel not in a Stasis application */ + is_valid = 1; + break; + default: + if (200 <= code && code <= 299) { + is_valid = ari_validate_void( + response->message); + } else { + ast_log(LOG_ERROR, "Invalid error response %d for /channels/{channelId}/mute\n", code); + is_valid = 0; + } + } + + if (!is_valid) { + ast_log(LOG_ERROR, "Response validation failed for /channels/{channelId}/mute\n"); + stasis_http_response_error(response, 500, + "Internal Server Error", "Response validation failed"); + } +#endif /* AST_DEVMODE */ } /*! * \brief Parameter parsing callback for /channels/{channelId}/unmute. @@ -275,9 +512,14 @@ static void stasis_http_mute_channel_cb( * \param[out] response Response to the HTTP request. */ static void stasis_http_unmute_channel_cb( - struct ast_variable *get_params, struct ast_variable *path_vars, - struct ast_variable *headers, struct stasis_http_response *response) + struct ast_variable *get_params, struct ast_variable *path_vars, + struct ast_variable *headers, struct stasis_http_response *response) { +#if defined(AST_DEVMODE) + int is_valid; + int code; +#endif /* AST_DEVMODE */ + struct ast_unmute_channel_args args = {}; struct ast_variable *i; @@ -294,6 +536,31 @@ static void stasis_http_unmute_channel_cb( {} } stasis_http_unmute_channel(headers, &args, response); +#if defined(AST_DEVMODE) + code = response->response_code; + + switch (code) { + case 500: /* Internal server error */ + case 404: /* Channel not found */ + case 409: /* Channel not in a Stasis application */ + is_valid = 1; + break; + default: + if (200 <= code && code <= 299) { + is_valid = ari_validate_void( + response->message); + } else { + ast_log(LOG_ERROR, "Invalid error response %d for /channels/{channelId}/unmute\n", code); + is_valid = 0; + } + } + + if (!is_valid) { + ast_log(LOG_ERROR, "Response validation failed for /channels/{channelId}/unmute\n"); + stasis_http_response_error(response, 500, + "Internal Server Error", "Response validation failed"); + } +#endif /* AST_DEVMODE */ } /*! * \brief Parameter parsing callback for /channels/{channelId}/hold. @@ -303,9 +570,14 @@ static void stasis_http_unmute_channel_cb( * \param[out] response Response to the HTTP request. */ static void stasis_http_hold_channel_cb( - struct ast_variable *get_params, struct ast_variable *path_vars, - struct ast_variable *headers, struct stasis_http_response *response) + struct ast_variable *get_params, struct ast_variable *path_vars, + struct ast_variable *headers, struct stasis_http_response *response) { +#if defined(AST_DEVMODE) + int is_valid; + int code; +#endif /* AST_DEVMODE */ + struct ast_hold_channel_args args = {}; struct ast_variable *i; @@ -316,6 +588,31 @@ static void stasis_http_hold_channel_cb( {} } stasis_http_hold_channel(headers, &args, response); +#if defined(AST_DEVMODE) + code = response->response_code; + + switch (code) { + case 500: /* Internal server error */ + case 404: /* Channel not found */ + case 409: /* Channel not in a Stasis application */ + is_valid = 1; + break; + default: + if (200 <= code && code <= 299) { + is_valid = ari_validate_void( + response->message); + } else { + ast_log(LOG_ERROR, "Invalid error response %d for /channels/{channelId}/hold\n", code); + is_valid = 0; + } + } + + if (!is_valid) { + ast_log(LOG_ERROR, "Response validation failed for /channels/{channelId}/hold\n"); + stasis_http_response_error(response, 500, + "Internal Server Error", "Response validation failed"); + } +#endif /* AST_DEVMODE */ } /*! * \brief Parameter parsing callback for /channels/{channelId}/unhold. @@ -325,9 +622,14 @@ static void stasis_http_hold_channel_cb( * \param[out] response Response to the HTTP request. */ static void stasis_http_unhold_channel_cb( - struct ast_variable *get_params, struct ast_variable *path_vars, - struct ast_variable *headers, struct stasis_http_response *response) + struct ast_variable *get_params, struct ast_variable *path_vars, + struct ast_variable *headers, struct stasis_http_response *response) { +#if defined(AST_DEVMODE) + int is_valid; + int code; +#endif /* AST_DEVMODE */ + struct ast_unhold_channel_args args = {}; struct ast_variable *i; @@ -338,6 +640,31 @@ static void stasis_http_unhold_channel_cb( {} } stasis_http_unhold_channel(headers, &args, response); +#if defined(AST_DEVMODE) + code = response->response_code; + + switch (code) { + case 500: /* Internal server error */ + case 404: /* Channel not found */ + case 409: /* Channel not in a Stasis application */ + is_valid = 1; + break; + default: + if (200 <= code && code <= 299) { + is_valid = ari_validate_void( + response->message); + } else { + ast_log(LOG_ERROR, "Invalid error response %d for /channels/{channelId}/unhold\n", code); + is_valid = 0; + } + } + + if (!is_valid) { + ast_log(LOG_ERROR, "Response validation failed for /channels/{channelId}/unhold\n"); + stasis_http_response_error(response, 500, + "Internal Server Error", "Response validation failed"); + } +#endif /* AST_DEVMODE */ } /*! * \brief Parameter parsing callback for /channels/{channelId}/play. @@ -347,9 +674,14 @@ static void stasis_http_unhold_channel_cb( * \param[out] response Response to the HTTP request. */ static void stasis_http_play_on_channel_cb( - struct ast_variable *get_params, struct ast_variable *path_vars, - struct ast_variable *headers, struct stasis_http_response *response) + struct ast_variable *get_params, struct ast_variable *path_vars, + struct ast_variable *headers, struct stasis_http_response *response) { +#if defined(AST_DEVMODE) + int is_valid; + int code; +#endif /* AST_DEVMODE */ + struct ast_play_on_channel_args args = {}; struct ast_variable *i; @@ -375,6 +707,31 @@ static void stasis_http_play_on_channel_cb( {} } stasis_http_play_on_channel(headers, &args, response); +#if defined(AST_DEVMODE) + code = response->response_code; + + switch (code) { + case 500: /* Internal server error */ + case 404: /* Channel not found */ + case 409: /* Channel not in a Stasis application */ + is_valid = 1; + break; + default: + if (200 <= code && code <= 299) { + is_valid = ari_validate_playback( + response->message); + } else { + ast_log(LOG_ERROR, "Invalid error response %d for /channels/{channelId}/play\n", code); + is_valid = 0; + } + } + + if (!is_valid) { + ast_log(LOG_ERROR, "Response validation failed for /channels/{channelId}/play\n"); + stasis_http_response_error(response, 500, + "Internal Server Error", "Response validation failed"); + } +#endif /* AST_DEVMODE */ } /*! * \brief Parameter parsing callback for /channels/{channelId}/record. @@ -384,9 +741,14 @@ static void stasis_http_play_on_channel_cb( * \param[out] response Response to the HTTP request. */ static void stasis_http_record_channel_cb( - struct ast_variable *get_params, struct ast_variable *path_vars, - struct ast_variable *headers, struct stasis_http_response *response) + struct ast_variable *get_params, struct ast_variable *path_vars, + struct ast_variable *headers, struct stasis_http_response *response) { +#if defined(AST_DEVMODE) + int is_valid; + int code; +#endif /* AST_DEVMODE */ + struct ast_record_channel_args args = {}; struct ast_variable *i; @@ -421,6 +783,31 @@ static void stasis_http_record_channel_cb( {} } stasis_http_record_channel(headers, &args, response); +#if defined(AST_DEVMODE) + code = response->response_code; + + switch (code) { + case 500: /* Internal server error */ + case 404: /* Channel not found */ + case 409: /* Channel is not in a Stasis application, or the channel is currently bridged with other channels. */ + is_valid = 1; + break; + default: + if (200 <= code && code <= 299) { + is_valid = ari_validate_void( + response->message); + } else { + ast_log(LOG_ERROR, "Invalid error response %d for /channels/{channelId}/record\n", code); + is_valid = 0; + } + } + + if (!is_valid) { + ast_log(LOG_ERROR, "Response validation failed for /channels/{channelId}/record\n"); + stasis_http_response_error(response, 500, + "Internal Server Error", "Response validation failed"); + } +#endif /* AST_DEVMODE */ } /*! \brief REST handler for /api-docs/channels.{format} */ diff --git a/res/res_stasis_http_endpoints.c b/res/res_stasis_http_endpoints.c index 81cdfeb0f..332333030 100644 --- a/res/res_stasis_http_endpoints.c +++ b/res/res_stasis_http_endpoints.c @@ -44,6 +44,9 @@ ASTERISK_FILE_VERSION(__FILE__, "$Revision$") #include "asterisk/module.h" #include "asterisk/stasis_app.h" #include "stasis_http/resource_endpoints.h" +#if defined(AST_DEVMODE) +#include "stasis_http/ari_model_validators.h" +#endif /*! * \brief Parameter parsing callback for /endpoints. @@ -53,11 +56,39 @@ ASTERISK_FILE_VERSION(__FILE__, "$Revision$") * \param[out] response Response to the HTTP request. */ static void stasis_http_get_endpoints_cb( - struct ast_variable *get_params, struct ast_variable *path_vars, - struct ast_variable *headers, struct stasis_http_response *response) + struct ast_variable *get_params, struct ast_variable *path_vars, + struct ast_variable *headers, struct stasis_http_response *response) { +#if defined(AST_DEVMODE) + int is_valid; + int code; +#endif /* AST_DEVMODE */ + struct ast_get_endpoints_args args = {}; stasis_http_get_endpoints(headers, &args, response); +#if defined(AST_DEVMODE) + code = response->response_code; + + switch (code) { + case 500: /* Internal server error */ + is_valid = 1; + break; + default: + if (200 <= code && code <= 299) { + is_valid = ari_validate_list(response->message, + ari_validate_endpoint); + } else { + ast_log(LOG_ERROR, "Invalid error response %d for /endpoints\n", code); + is_valid = 0; + } + } + + if (!is_valid) { + ast_log(LOG_ERROR, "Response validation failed for /endpoints\n"); + stasis_http_response_error(response, 500, + "Internal Server Error", "Response validation failed"); + } +#endif /* AST_DEVMODE */ } /*! * \brief Parameter parsing callback for /endpoints/{tech}. @@ -67,9 +98,14 @@ static void stasis_http_get_endpoints_cb( * \param[out] response Response to the HTTP request. */ static void stasis_http_get_endpoints_by_tech_cb( - struct ast_variable *get_params, struct ast_variable *path_vars, - struct ast_variable *headers, struct stasis_http_response *response) + struct ast_variable *get_params, struct ast_variable *path_vars, + struct ast_variable *headers, struct stasis_http_response *response) { +#if defined(AST_DEVMODE) + int is_valid; + int code; +#endif /* AST_DEVMODE */ + struct ast_get_endpoints_by_tech_args args = {}; struct ast_variable *i; @@ -80,6 +116,29 @@ static void stasis_http_get_endpoints_by_tech_cb( {} } stasis_http_get_endpoints_by_tech(headers, &args, response); +#if defined(AST_DEVMODE) + code = response->response_code; + + switch (code) { + case 500: /* Internal server error */ + is_valid = 1; + break; + default: + if (200 <= code && code <= 299) { + is_valid = ari_validate_list(response->message, + ari_validate_endpoint); + } else { + ast_log(LOG_ERROR, "Invalid error response %d for /endpoints/{tech}\n", code); + is_valid = 0; + } + } + + if (!is_valid) { + ast_log(LOG_ERROR, "Response validation failed for /endpoints/{tech}\n"); + stasis_http_response_error(response, 500, + "Internal Server Error", "Response validation failed"); + } +#endif /* AST_DEVMODE */ } /*! * \brief Parameter parsing callback for /endpoints/{tech}/{resource}. @@ -89,9 +148,14 @@ static void stasis_http_get_endpoints_by_tech_cb( * \param[out] response Response to the HTTP request. */ static void stasis_http_get_endpoint_cb( - struct ast_variable *get_params, struct ast_variable *path_vars, - struct ast_variable *headers, struct stasis_http_response *response) + struct ast_variable *get_params, struct ast_variable *path_vars, + struct ast_variable *headers, struct stasis_http_response *response) { +#if defined(AST_DEVMODE) + int is_valid; + int code; +#endif /* AST_DEVMODE */ + struct ast_get_endpoint_args args = {}; struct ast_variable *i; @@ -105,6 +169,29 @@ static void stasis_http_get_endpoint_cb( {} } stasis_http_get_endpoint(headers, &args, response); +#if defined(AST_DEVMODE) + code = response->response_code; + + switch (code) { + case 500: /* Internal server error */ + is_valid = 1; + break; + default: + if (200 <= code && code <= 299) { + is_valid = ari_validate_endpoint( + response->message); + } else { + ast_log(LOG_ERROR, "Invalid error response %d for /endpoints/{tech}/{resource}\n", code); + is_valid = 0; + } + } + + if (!is_valid) { + ast_log(LOG_ERROR, "Response validation failed for /endpoints/{tech}/{resource}\n"); + stasis_http_response_error(response, 500, + "Internal Server Error", "Response validation failed"); + } +#endif /* AST_DEVMODE */ } /*! \brief REST handler for /api-docs/endpoints.{format} */ diff --git a/res/res_stasis_http_events.c b/res/res_stasis_http_events.c index 909c2d659..421726312 100644 --- a/res/res_stasis_http_events.c +++ b/res/res_stasis_http_events.c @@ -44,6 +44,9 @@ ASTERISK_FILE_VERSION(__FILE__, "$Revision$") #include "asterisk/module.h" #include "asterisk/stasis_app.h" #include "stasis_http/resource_events.h" +#if defined(AST_DEVMODE) +#include "stasis_http/ari_model_validators.h" +#endif static void stasis_http_event_websocket_ws_cb(struct ast_websocket *ws_session, struct ast_variable *get_params, struct ast_variable *headers) @@ -59,7 +62,12 @@ static void stasis_http_event_websocket_ws_cb(struct ast_websocket *ws_session, } else {} } - session = ari_websocket_session_create(ws_session); +#if defined(AST_DEVMODE) + session = ari_websocket_session_create(ws_session, + ari_validate_event); +#else + session = ari_websocket_session_create(ws_session, NULL); +#endif if (!session) { ast_log(LOG_ERROR, "Failed to create ARI session\n"); return; diff --git a/res/res_stasis_http_playback.c b/res/res_stasis_http_playback.c index 4608686bc..0e56e6229 100644 --- a/res/res_stasis_http_playback.c +++ b/res/res_stasis_http_playback.c @@ -44,6 +44,9 @@ ASTERISK_FILE_VERSION(__FILE__, "$Revision$") #include "asterisk/module.h" #include "asterisk/stasis_app.h" #include "stasis_http/resource_playback.h" +#if defined(AST_DEVMODE) +#include "stasis_http/ari_model_validators.h" +#endif /*! * \brief Parameter parsing callback for /playback/{playbackId}. @@ -53,9 +56,14 @@ ASTERISK_FILE_VERSION(__FILE__, "$Revision$") * \param[out] response Response to the HTTP request. */ static void stasis_http_get_playback_cb( - struct ast_variable *get_params, struct ast_variable *path_vars, - struct ast_variable *headers, struct stasis_http_response *response) + struct ast_variable *get_params, struct ast_variable *path_vars, + struct ast_variable *headers, struct stasis_http_response *response) { +#if defined(AST_DEVMODE) + int is_valid; + int code; +#endif /* AST_DEVMODE */ + struct ast_get_playback_args args = {}; struct ast_variable *i; @@ -66,6 +74,29 @@ static void stasis_http_get_playback_cb( {} } stasis_http_get_playback(headers, &args, response); +#if defined(AST_DEVMODE) + code = response->response_code; + + switch (code) { + case 500: /* Internal server error */ + is_valid = 1; + break; + default: + if (200 <= code && code <= 299) { + is_valid = ari_validate_playback( + response->message); + } else { + ast_log(LOG_ERROR, "Invalid error response %d for /playback/{playbackId}\n", code); + is_valid = 0; + } + } + + if (!is_valid) { + ast_log(LOG_ERROR, "Response validation failed for /playback/{playbackId}\n"); + stasis_http_response_error(response, 500, + "Internal Server Error", "Response validation failed"); + } +#endif /* AST_DEVMODE */ } /*! * \brief Parameter parsing callback for /playback/{playbackId}. @@ -75,9 +106,14 @@ static void stasis_http_get_playback_cb( * \param[out] response Response to the HTTP request. */ static void stasis_http_stop_playback_cb( - struct ast_variable *get_params, struct ast_variable *path_vars, - struct ast_variable *headers, struct stasis_http_response *response) + struct ast_variable *get_params, struct ast_variable *path_vars, + struct ast_variable *headers, struct stasis_http_response *response) { +#if defined(AST_DEVMODE) + int is_valid; + int code; +#endif /* AST_DEVMODE */ + struct ast_stop_playback_args args = {}; struct ast_variable *i; @@ -88,6 +124,29 @@ static void stasis_http_stop_playback_cb( {} } stasis_http_stop_playback(headers, &args, response); +#if defined(AST_DEVMODE) + code = response->response_code; + + switch (code) { + case 500: /* Internal server error */ + is_valid = 1; + break; + default: + if (200 <= code && code <= 299) { + is_valid = ari_validate_playback( + response->message); + } else { + ast_log(LOG_ERROR, "Invalid error response %d for /playback/{playbackId}\n", code); + is_valid = 0; + } + } + + if (!is_valid) { + ast_log(LOG_ERROR, "Response validation failed for /playback/{playbackId}\n"); + stasis_http_response_error(response, 500, + "Internal Server Error", "Response validation failed"); + } +#endif /* AST_DEVMODE */ } /*! * \brief Parameter parsing callback for /playback/{playbackId}/control. @@ -97,9 +156,14 @@ static void stasis_http_stop_playback_cb( * \param[out] response Response to the HTTP request. */ static void stasis_http_control_playback_cb( - struct ast_variable *get_params, struct ast_variable *path_vars, - struct ast_variable *headers, struct stasis_http_response *response) + struct ast_variable *get_params, struct ast_variable *path_vars, + struct ast_variable *headers, struct stasis_http_response *response) { +#if defined(AST_DEVMODE) + int is_valid; + int code; +#endif /* AST_DEVMODE */ + struct ast_control_playback_args args = {}; struct ast_variable *i; @@ -116,6 +180,32 @@ static void stasis_http_control_playback_cb( {} } stasis_http_control_playback(headers, &args, response); +#if defined(AST_DEVMODE) + code = response->response_code; + + switch (code) { + case 500: /* Internal server error */ + case 400: /* The provided operation parameter was invalid */ + case 404: /* The playback cannot be found */ + case 409: /* The operation cannot be performed in the playback's current state */ + is_valid = 1; + break; + default: + if (200 <= code && code <= 299) { + is_valid = ari_validate_playback( + response->message); + } else { + ast_log(LOG_ERROR, "Invalid error response %d for /playback/{playbackId}/control\n", code); + is_valid = 0; + } + } + + if (!is_valid) { + ast_log(LOG_ERROR, "Response validation failed for /playback/{playbackId}/control\n"); + stasis_http_response_error(response, 500, + "Internal Server Error", "Response validation failed"); + } +#endif /* AST_DEVMODE */ } /*! \brief REST handler for /api-docs/playback.{format} */ diff --git a/res/res_stasis_http_recordings.c b/res/res_stasis_http_recordings.c index 7d89393bc..4aa43c9be 100644 --- a/res/res_stasis_http_recordings.c +++ b/res/res_stasis_http_recordings.c @@ -44,22 +44,11 @@ ASTERISK_FILE_VERSION(__FILE__, "$Revision$") #include "asterisk/module.h" #include "asterisk/stasis_app.h" #include "stasis_http/resource_recordings.h" +#if defined(AST_DEVMODE) +#include "stasis_http/ari_model_validators.h" +#endif /*! - * \brief Parameter parsing callback for /recordings. - * \param get_params GET parameters in the HTTP request. - * \param path_vars Path variables extracted from the request. - * \param headers HTTP headers. - * \param[out] response Response to the HTTP request. - */ -static void stasis_http_get_recordings_cb( - struct ast_variable *get_params, struct ast_variable *path_vars, - struct ast_variable *headers, struct stasis_http_response *response) -{ - struct ast_get_recordings_args args = {}; - stasis_http_get_recordings(headers, &args, response); -} -/*! * \brief Parameter parsing callback for /recordings/stored. * \param get_params GET parameters in the HTTP request. * \param path_vars Path variables extracted from the request. @@ -67,11 +56,39 @@ static void stasis_http_get_recordings_cb( * \param[out] response Response to the HTTP request. */ static void stasis_http_get_stored_recordings_cb( - struct ast_variable *get_params, struct ast_variable *path_vars, - struct ast_variable *headers, struct stasis_http_response *response) + struct ast_variable *get_params, struct ast_variable *path_vars, + struct ast_variable *headers, struct stasis_http_response *response) { +#if defined(AST_DEVMODE) + int is_valid; + int code; +#endif /* AST_DEVMODE */ + struct ast_get_stored_recordings_args args = {}; stasis_http_get_stored_recordings(headers, &args, response); +#if defined(AST_DEVMODE) + code = response->response_code; + + switch (code) { + case 500: /* Internal server error */ + is_valid = 1; + break; + default: + if (200 <= code && code <= 299) { + is_valid = ari_validate_list(response->message, + ari_validate_stored_recording); + } else { + ast_log(LOG_ERROR, "Invalid error response %d for /recordings/stored\n", code); + is_valid = 0; + } + } + + if (!is_valid) { + ast_log(LOG_ERROR, "Response validation failed for /recordings/stored\n"); + stasis_http_response_error(response, 500, + "Internal Server Error", "Response validation failed"); + } +#endif /* AST_DEVMODE */ } /*! * \brief Parameter parsing callback for /recordings/stored/{recordingId}. @@ -81,9 +98,14 @@ static void stasis_http_get_stored_recordings_cb( * \param[out] response Response to the HTTP request. */ static void stasis_http_get_stored_recording_cb( - struct ast_variable *get_params, struct ast_variable *path_vars, - struct ast_variable *headers, struct stasis_http_response *response) + struct ast_variable *get_params, struct ast_variable *path_vars, + struct ast_variable *headers, struct stasis_http_response *response) { +#if defined(AST_DEVMODE) + int is_valid; + int code; +#endif /* AST_DEVMODE */ + struct ast_get_stored_recording_args args = {}; struct ast_variable *i; @@ -94,6 +116,29 @@ static void stasis_http_get_stored_recording_cb( {} } stasis_http_get_stored_recording(headers, &args, response); +#if defined(AST_DEVMODE) + code = response->response_code; + + switch (code) { + case 500: /* Internal server error */ + is_valid = 1; + break; + default: + if (200 <= code && code <= 299) { + is_valid = ari_validate_stored_recording( + response->message); + } else { + ast_log(LOG_ERROR, "Invalid error response %d for /recordings/stored/{recordingId}\n", code); + is_valid = 0; + } + } + + if (!is_valid) { + ast_log(LOG_ERROR, "Response validation failed for /recordings/stored/{recordingId}\n"); + stasis_http_response_error(response, 500, + "Internal Server Error", "Response validation failed"); + } +#endif /* AST_DEVMODE */ } /*! * \brief Parameter parsing callback for /recordings/stored/{recordingId}. @@ -103,9 +148,14 @@ static void stasis_http_get_stored_recording_cb( * \param[out] response Response to the HTTP request. */ static void stasis_http_delete_stored_recording_cb( - struct ast_variable *get_params, struct ast_variable *path_vars, - struct ast_variable *headers, struct stasis_http_response *response) + struct ast_variable *get_params, struct ast_variable *path_vars, + struct ast_variable *headers, struct stasis_http_response *response) { +#if defined(AST_DEVMODE) + int is_valid; + int code; +#endif /* AST_DEVMODE */ + struct ast_delete_stored_recording_args args = {}; struct ast_variable *i; @@ -116,6 +166,29 @@ static void stasis_http_delete_stored_recording_cb( {} } stasis_http_delete_stored_recording(headers, &args, response); +#if defined(AST_DEVMODE) + code = response->response_code; + + switch (code) { + case 500: /* Internal server error */ + is_valid = 1; + break; + default: + if (200 <= code && code <= 299) { + is_valid = ari_validate_void( + response->message); + } else { + ast_log(LOG_ERROR, "Invalid error response %d for /recordings/stored/{recordingId}\n", code); + is_valid = 0; + } + } + + if (!is_valid) { + ast_log(LOG_ERROR, "Response validation failed for /recordings/stored/{recordingId}\n"); + stasis_http_response_error(response, 500, + "Internal Server Error", "Response validation failed"); + } +#endif /* AST_DEVMODE */ } /*! * \brief Parameter parsing callback for /recordings/live. @@ -125,11 +198,39 @@ static void stasis_http_delete_stored_recording_cb( * \param[out] response Response to the HTTP request. */ static void stasis_http_get_live_recordings_cb( - struct ast_variable *get_params, struct ast_variable *path_vars, - struct ast_variable *headers, struct stasis_http_response *response) + struct ast_variable *get_params, struct ast_variable *path_vars, + struct ast_variable *headers, struct stasis_http_response *response) { +#if defined(AST_DEVMODE) + int is_valid; + int code; +#endif /* AST_DEVMODE */ + struct ast_get_live_recordings_args args = {}; stasis_http_get_live_recordings(headers, &args, response); +#if defined(AST_DEVMODE) + code = response->response_code; + + switch (code) { + case 500: /* Internal server error */ + is_valid = 1; + break; + default: + if (200 <= code && code <= 299) { + is_valid = ari_validate_list(response->message, + ari_validate_live_recording); + } else { + ast_log(LOG_ERROR, "Invalid error response %d for /recordings/live\n", code); + is_valid = 0; + } + } + + if (!is_valid) { + ast_log(LOG_ERROR, "Response validation failed for /recordings/live\n"); + stasis_http_response_error(response, 500, + "Internal Server Error", "Response validation failed"); + } +#endif /* AST_DEVMODE */ } /*! * \brief Parameter parsing callback for /recordings/live/{recordingId}. @@ -139,9 +240,14 @@ static void stasis_http_get_live_recordings_cb( * \param[out] response Response to the HTTP request. */ static void stasis_http_get_live_recording_cb( - struct ast_variable *get_params, struct ast_variable *path_vars, - struct ast_variable *headers, struct stasis_http_response *response) + struct ast_variable *get_params, struct ast_variable *path_vars, + struct ast_variable *headers, struct stasis_http_response *response) { +#if defined(AST_DEVMODE) + int is_valid; + int code; +#endif /* AST_DEVMODE */ + struct ast_get_live_recording_args args = {}; struct ast_variable *i; @@ -152,6 +258,29 @@ static void stasis_http_get_live_recording_cb( {} } stasis_http_get_live_recording(headers, &args, response); +#if defined(AST_DEVMODE) + code = response->response_code; + + switch (code) { + case 500: /* Internal server error */ + is_valid = 1; + break; + default: + if (200 <= code && code <= 299) { + is_valid = ari_validate_live_recording( + response->message); + } else { + ast_log(LOG_ERROR, "Invalid error response %d for /recordings/live/{recordingId}\n", code); + is_valid = 0; + } + } + + if (!is_valid) { + ast_log(LOG_ERROR, "Response validation failed for /recordings/live/{recordingId}\n"); + stasis_http_response_error(response, 500, + "Internal Server Error", "Response validation failed"); + } +#endif /* AST_DEVMODE */ } /*! * \brief Parameter parsing callback for /recordings/live/{recordingId}. @@ -161,9 +290,14 @@ static void stasis_http_get_live_recording_cb( * \param[out] response Response to the HTTP request. */ static void stasis_http_cancel_recording_cb( - struct ast_variable *get_params, struct ast_variable *path_vars, - struct ast_variable *headers, struct stasis_http_response *response) + struct ast_variable *get_params, struct ast_variable *path_vars, + struct ast_variable *headers, struct stasis_http_response *response) { +#if defined(AST_DEVMODE) + int is_valid; + int code; +#endif /* AST_DEVMODE */ + struct ast_cancel_recording_args args = {}; struct ast_variable *i; @@ -174,6 +308,29 @@ static void stasis_http_cancel_recording_cb( {} } stasis_http_cancel_recording(headers, &args, response); +#if defined(AST_DEVMODE) + code = response->response_code; + + switch (code) { + case 500: /* Internal server error */ + is_valid = 1; + break; + default: + if (200 <= code && code <= 299) { + is_valid = ari_validate_void( + response->message); + } else { + ast_log(LOG_ERROR, "Invalid error response %d for /recordings/live/{recordingId}\n", code); + is_valid = 0; + } + } + + if (!is_valid) { + ast_log(LOG_ERROR, "Response validation failed for /recordings/live/{recordingId}\n"); + stasis_http_response_error(response, 500, + "Internal Server Error", "Response validation failed"); + } +#endif /* AST_DEVMODE */ } /*! * \brief Parameter parsing callback for /recordings/live/{recordingId}/stop. @@ -183,9 +340,14 @@ static void stasis_http_cancel_recording_cb( * \param[out] response Response to the HTTP request. */ static void stasis_http_stop_recording_cb( - struct ast_variable *get_params, struct ast_variable *path_vars, - struct ast_variable *headers, struct stasis_http_response *response) + struct ast_variable *get_params, struct ast_variable *path_vars, + struct ast_variable *headers, struct stasis_http_response *response) { +#if defined(AST_DEVMODE) + int is_valid; + int code; +#endif /* AST_DEVMODE */ + struct ast_stop_recording_args args = {}; struct ast_variable *i; @@ -196,6 +358,29 @@ static void stasis_http_stop_recording_cb( {} } stasis_http_stop_recording(headers, &args, response); +#if defined(AST_DEVMODE) + code = response->response_code; + + switch (code) { + case 500: /* Internal server error */ + is_valid = 1; + break; + default: + if (200 <= code && code <= 299) { + is_valid = ari_validate_void( + response->message); + } else { + ast_log(LOG_ERROR, "Invalid error response %d for /recordings/live/{recordingId}/stop\n", code); + is_valid = 0; + } + } + + if (!is_valid) { + ast_log(LOG_ERROR, "Response validation failed for /recordings/live/{recordingId}/stop\n"); + stasis_http_response_error(response, 500, + "Internal Server Error", "Response validation failed"); + } +#endif /* AST_DEVMODE */ } /*! * \brief Parameter parsing callback for /recordings/live/{recordingId}/pause. @@ -205,9 +390,14 @@ static void stasis_http_stop_recording_cb( * \param[out] response Response to the HTTP request. */ static void stasis_http_pause_recording_cb( - struct ast_variable *get_params, struct ast_variable *path_vars, - struct ast_variable *headers, struct stasis_http_response *response) + struct ast_variable *get_params, struct ast_variable *path_vars, + struct ast_variable *headers, struct stasis_http_response *response) { +#if defined(AST_DEVMODE) + int is_valid; + int code; +#endif /* AST_DEVMODE */ + struct ast_pause_recording_args args = {}; struct ast_variable *i; @@ -218,6 +408,29 @@ static void stasis_http_pause_recording_cb( {} } stasis_http_pause_recording(headers, &args, response); +#if defined(AST_DEVMODE) + code = response->response_code; + + switch (code) { + case 500: /* Internal server error */ + is_valid = 1; + break; + default: + if (200 <= code && code <= 299) { + is_valid = ari_validate_void( + response->message); + } else { + ast_log(LOG_ERROR, "Invalid error response %d for /recordings/live/{recordingId}/pause\n", code); + is_valid = 0; + } + } + + if (!is_valid) { + ast_log(LOG_ERROR, "Response validation failed for /recordings/live/{recordingId}/pause\n"); + stasis_http_response_error(response, 500, + "Internal Server Error", "Response validation failed"); + } +#endif /* AST_DEVMODE */ } /*! * \brief Parameter parsing callback for /recordings/live/{recordingId}/unpause. @@ -227,9 +440,14 @@ static void stasis_http_pause_recording_cb( * \param[out] response Response to the HTTP request. */ static void stasis_http_unpause_recording_cb( - struct ast_variable *get_params, struct ast_variable *path_vars, - struct ast_variable *headers, struct stasis_http_response *response) + struct ast_variable *get_params, struct ast_variable *path_vars, + struct ast_variable *headers, struct stasis_http_response *response) { +#if defined(AST_DEVMODE) + int is_valid; + int code; +#endif /* AST_DEVMODE */ + struct ast_unpause_recording_args args = {}; struct ast_variable *i; @@ -240,6 +458,29 @@ static void stasis_http_unpause_recording_cb( {} } stasis_http_unpause_recording(headers, &args, response); +#if defined(AST_DEVMODE) + code = response->response_code; + + switch (code) { + case 500: /* Internal server error */ + is_valid = 1; + break; + default: + if (200 <= code && code <= 299) { + is_valid = ari_validate_void( + response->message); + } else { + ast_log(LOG_ERROR, "Invalid error response %d for /recordings/live/{recordingId}/unpause\n", code); + is_valid = 0; + } + } + + if (!is_valid) { + ast_log(LOG_ERROR, "Response validation failed for /recordings/live/{recordingId}/unpause\n"); + stasis_http_response_error(response, 500, + "Internal Server Error", "Response validation failed"); + } +#endif /* AST_DEVMODE */ } /*! * \brief Parameter parsing callback for /recordings/live/{recordingId}/mute. @@ -249,9 +490,14 @@ static void stasis_http_unpause_recording_cb( * \param[out] response Response to the HTTP request. */ static void stasis_http_mute_recording_cb( - struct ast_variable *get_params, struct ast_variable *path_vars, - struct ast_variable *headers, struct stasis_http_response *response) + struct ast_variable *get_params, struct ast_variable *path_vars, + struct ast_variable *headers, struct stasis_http_response *response) { +#if defined(AST_DEVMODE) + int is_valid; + int code; +#endif /* AST_DEVMODE */ + struct ast_mute_recording_args args = {}; struct ast_variable *i; @@ -262,6 +508,29 @@ static void stasis_http_mute_recording_cb( {} } stasis_http_mute_recording(headers, &args, response); +#if defined(AST_DEVMODE) + code = response->response_code; + + switch (code) { + case 500: /* Internal server error */ + is_valid = 1; + break; + default: + if (200 <= code && code <= 299) { + is_valid = ari_validate_void( + response->message); + } else { + ast_log(LOG_ERROR, "Invalid error response %d for /recordings/live/{recordingId}/mute\n", code); + is_valid = 0; + } + } + + if (!is_valid) { + ast_log(LOG_ERROR, "Response validation failed for /recordings/live/{recordingId}/mute\n"); + stasis_http_response_error(response, 500, + "Internal Server Error", "Response validation failed"); + } +#endif /* AST_DEVMODE */ } /*! * \brief Parameter parsing callback for /recordings/live/{recordingId}/unmute. @@ -271,9 +540,14 @@ static void stasis_http_mute_recording_cb( * \param[out] response Response to the HTTP request. */ static void stasis_http_unmute_recording_cb( - struct ast_variable *get_params, struct ast_variable *path_vars, - struct ast_variable *headers, struct stasis_http_response *response) + struct ast_variable *get_params, struct ast_variable *path_vars, + struct ast_variable *headers, struct stasis_http_response *response) { +#if defined(AST_DEVMODE) + int is_valid; + int code; +#endif /* AST_DEVMODE */ + struct ast_unmute_recording_args args = {}; struct ast_variable *i; @@ -284,6 +558,29 @@ static void stasis_http_unmute_recording_cb( {} } stasis_http_unmute_recording(headers, &args, response); +#if defined(AST_DEVMODE) + code = response->response_code; + + switch (code) { + case 500: /* Internal server error */ + is_valid = 1; + break; + default: + if (200 <= code && code <= 299) { + is_valid = ari_validate_void( + response->message); + } else { + ast_log(LOG_ERROR, "Invalid error response %d for /recordings/live/{recordingId}/unmute\n", code); + is_valid = 0; + } + } + + if (!is_valid) { + ast_log(LOG_ERROR, "Response validation failed for /recordings/live/{recordingId}/unmute\n"); + stasis_http_response_error(response, 500, + "Internal Server Error", "Response validation failed"); + } +#endif /* AST_DEVMODE */ } /*! \brief REST handler for /api-docs/recordings.{format} */ @@ -375,7 +672,6 @@ static struct stasis_rest_handlers recordings_live = { static struct stasis_rest_handlers recordings = { .path_segment = "recordings", .callbacks = { - [AST_HTTP_GET] = stasis_http_get_recordings_cb, }, .num_children = 2, .children = { &recordings_stored,&recordings_live, } diff --git a/res/res_stasis_http_sounds.c b/res/res_stasis_http_sounds.c index 975ca0388..da0206223 100644 --- a/res/res_stasis_http_sounds.c +++ b/res/res_stasis_http_sounds.c @@ -44,6 +44,9 @@ ASTERISK_FILE_VERSION(__FILE__, "$Revision$") #include "asterisk/module.h" #include "asterisk/stasis_app.h" #include "stasis_http/resource_sounds.h" +#if defined(AST_DEVMODE) +#include "stasis_http/ari_model_validators.h" +#endif /*! * \brief Parameter parsing callback for /sounds. @@ -53,9 +56,14 @@ ASTERISK_FILE_VERSION(__FILE__, "$Revision$") * \param[out] response Response to the HTTP request. */ static void stasis_http_get_sounds_cb( - struct ast_variable *get_params, struct ast_variable *path_vars, - struct ast_variable *headers, struct stasis_http_response *response) + struct ast_variable *get_params, struct ast_variable *path_vars, + struct ast_variable *headers, struct stasis_http_response *response) { +#if defined(AST_DEVMODE) + int is_valid; + int code; +#endif /* AST_DEVMODE */ + struct ast_get_sounds_args args = {}; struct ast_variable *i; @@ -69,6 +77,29 @@ static void stasis_http_get_sounds_cb( {} } stasis_http_get_sounds(headers, &args, response); +#if defined(AST_DEVMODE) + code = response->response_code; + + switch (code) { + case 500: /* Internal server error */ + is_valid = 1; + break; + default: + if (200 <= code && code <= 299) { + is_valid = ari_validate_list(response->message, + ari_validate_sound); + } else { + ast_log(LOG_ERROR, "Invalid error response %d for /sounds\n", code); + is_valid = 0; + } + } + + if (!is_valid) { + ast_log(LOG_ERROR, "Response validation failed for /sounds\n"); + stasis_http_response_error(response, 500, + "Internal Server Error", "Response validation failed"); + } +#endif /* AST_DEVMODE */ } /*! * \brief Parameter parsing callback for /sounds/{soundId}. @@ -78,9 +109,14 @@ static void stasis_http_get_sounds_cb( * \param[out] response Response to the HTTP request. */ static void stasis_http_get_stored_sound_cb( - struct ast_variable *get_params, struct ast_variable *path_vars, - struct ast_variable *headers, struct stasis_http_response *response) + struct ast_variable *get_params, struct ast_variable *path_vars, + struct ast_variable *headers, struct stasis_http_response *response) { +#if defined(AST_DEVMODE) + int is_valid; + int code; +#endif /* AST_DEVMODE */ + struct ast_get_stored_sound_args args = {}; struct ast_variable *i; @@ -91,6 +127,29 @@ static void stasis_http_get_stored_sound_cb( {} } stasis_http_get_stored_sound(headers, &args, response); +#if defined(AST_DEVMODE) + code = response->response_code; + + switch (code) { + case 500: /* Internal server error */ + is_valid = 1; + break; + default: + if (200 <= code && code <= 299) { + is_valid = ari_validate_sound( + response->message); + } else { + ast_log(LOG_ERROR, "Invalid error response %d for /sounds/{soundId}\n", code); + is_valid = 0; + } + } + + if (!is_valid) { + ast_log(LOG_ERROR, "Response validation failed for /sounds/{soundId}\n"); + stasis_http_response_error(response, 500, + "Internal Server Error", "Response validation failed"); + } +#endif /* AST_DEVMODE */ } /*! \brief REST handler for /api-docs/sounds.{format} */ diff --git a/res/res_stasis_json_asterisk.c b/res/res_stasis_json_asterisk.c deleted file mode 100644 index 830a2cfab..000000000 --- a/res/res_stasis_json_asterisk.c +++ /dev/null @@ -1,59 +0,0 @@ -/* - * Asterisk -- An open source telephony toolkit. - * - * Copyright (C) 2012 - 2013, Digium, Inc. - * - * David M. Lee, II <dlee@digium.com> - * - * See http://www.asterisk.org for more information about - * the Asterisk project. Please do not directly contact - * any of the maintainers of this project for assistance; - * the project provides a web site, mailing lists and IRC - * channels for your use. - * - * This program is free software, distributed under the terms of - * the GNU General Public License Version 2. See the LICENSE file - * at the top of the source tree. - */ - -/* - * !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! - * !!!!! DO NOT EDIT !!!!! - * !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! - * This file is generated by a mustache template. Please see the original - * template in rest-api-templates/res_stasis_http_resource.c.mustache - */ - -/*! \file - * - * \brief Asterisk resources - * - * \author David M. Lee, II <dlee@digium.com> - */ - -/*** MODULEINFO - <support_level>core</support_level> - ***/ - -#include "asterisk.h" - -ASTERISK_FILE_VERSION(__FILE__, "$Revision$") - -#include "asterisk/module.h" -#include "asterisk/json.h" -#include "stasis_json/resource_asterisk.h" -static int load_module(void) -{ - return 0; -} - -static int unload_module(void) -{ - return 0; -} - -AST_MODULE_INFO(ASTERISK_GPL_KEY, AST_MODFLAG_GLOBAL_SYMBOLS | AST_MODFLAG_LOAD_ORDER, "Stasis JSON Generators and Validators - Asterisk resources", - .load = load_module, - .unload = unload_module, - .load_pri = AST_MODPRI_DEFAULT, - ); diff --git a/res/res_stasis_json_asterisk.exports.in b/res/res_stasis_json_asterisk.exports.in deleted file mode 100644 index 5e767549c..000000000 --- a/res/res_stasis_json_asterisk.exports.in +++ /dev/null @@ -1,4 +0,0 @@ -{ - local: - *; -}; diff --git a/res/res_stasis_json_bridges.c b/res/res_stasis_json_bridges.c deleted file mode 100644 index 90977bff4..000000000 --- a/res/res_stasis_json_bridges.c +++ /dev/null @@ -1,59 +0,0 @@ -/* - * Asterisk -- An open source telephony toolkit. - * - * Copyright (C) 2012 - 2013, Digium, Inc. - * - * David M. Lee, II <dlee@digium.com> - * - * See http://www.asterisk.org for more information about - * the Asterisk project. Please do not directly contact - * any of the maintainers of this project for assistance; - * the project provides a web site, mailing lists and IRC - * channels for your use. - * - * This program is free software, distributed under the terms of - * the GNU General Public License Version 2. See the LICENSE file - * at the top of the source tree. - */ - -/* - * !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! - * !!!!! DO NOT EDIT !!!!! - * !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! - * This file is generated by a mustache template. Please see the original - * template in rest-api-templates/res_stasis_http_resource.c.mustache - */ - -/*! \file - * - * \brief Bridge resources - * - * \author David M. Lee, II <dlee@digium.com> - */ - -/*** MODULEINFO - <support_level>core</support_level> - ***/ - -#include "asterisk.h" - -ASTERISK_FILE_VERSION(__FILE__, "$Revision$") - -#include "asterisk/module.h" -#include "asterisk/json.h" -#include "stasis_json/resource_bridges.h" -static int load_module(void) -{ - return 0; -} - -static int unload_module(void) -{ - return 0; -} - -AST_MODULE_INFO(ASTERISK_GPL_KEY, AST_MODFLAG_GLOBAL_SYMBOLS | AST_MODFLAG_LOAD_ORDER, "Stasis JSON Generators and Validators - Bridge resources", - .load = load_module, - .unload = unload_module, - .load_pri = AST_MODPRI_DEFAULT, - ); diff --git a/res/res_stasis_json_bridges.exports.in b/res/res_stasis_json_bridges.exports.in deleted file mode 100644 index 5e767549c..000000000 --- a/res/res_stasis_json_bridges.exports.in +++ /dev/null @@ -1,4 +0,0 @@ -{ - local: - *; -}; diff --git a/res/res_stasis_json_channels.c b/res/res_stasis_json_channels.c deleted file mode 100644 index 3f85736b3..000000000 --- a/res/res_stasis_json_channels.c +++ /dev/null @@ -1,59 +0,0 @@ -/* - * Asterisk -- An open source telephony toolkit. - * - * Copyright (C) 2012 - 2013, Digium, Inc. - * - * David M. Lee, II <dlee@digium.com> - * - * See http://www.asterisk.org for more information about - * the Asterisk project. Please do not directly contact - * any of the maintainers of this project for assistance; - * the project provides a web site, mailing lists and IRC - * channels for your use. - * - * This program is free software, distributed under the terms of - * the GNU General Public License Version 2. See the LICENSE file - * at the top of the source tree. - */ - -/* - * !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! - * !!!!! DO NOT EDIT !!!!! - * !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! - * This file is generated by a mustache template. Please see the original - * template in rest-api-templates/res_stasis_http_resource.c.mustache - */ - -/*! \file - * - * \brief Channel resources - * - * \author David M. Lee, II <dlee@digium.com> - */ - -/*** MODULEINFO - <support_level>core</support_level> - ***/ - -#include "asterisk.h" - -ASTERISK_FILE_VERSION(__FILE__, "$Revision$") - -#include "asterisk/module.h" -#include "asterisk/json.h" -#include "stasis_json/resource_channels.h" -static int load_module(void) -{ - return 0; -} - -static int unload_module(void) -{ - return 0; -} - -AST_MODULE_INFO(ASTERISK_GPL_KEY, AST_MODFLAG_GLOBAL_SYMBOLS | AST_MODFLAG_LOAD_ORDER, "Stasis JSON Generators and Validators - Channel resources", - .load = load_module, - .unload = unload_module, - .load_pri = AST_MODPRI_DEFAULT, - ); diff --git a/res/res_stasis_json_channels.exports.in b/res/res_stasis_json_channels.exports.in deleted file mode 100644 index 5e767549c..000000000 --- a/res/res_stasis_json_channels.exports.in +++ /dev/null @@ -1,4 +0,0 @@ -{ - local: - *; -}; diff --git a/res/res_stasis_json_endpoints.c b/res/res_stasis_json_endpoints.c deleted file mode 100644 index be214e038..000000000 --- a/res/res_stasis_json_endpoints.c +++ /dev/null @@ -1,59 +0,0 @@ -/* - * Asterisk -- An open source telephony toolkit. - * - * Copyright (C) 2012 - 2013, Digium, Inc. - * - * David M. Lee, II <dlee@digium.com> - * - * See http://www.asterisk.org for more information about - * the Asterisk project. Please do not directly contact - * any of the maintainers of this project for assistance; - * the project provides a web site, mailing lists and IRC - * channels for your use. - * - * This program is free software, distributed under the terms of - * the GNU General Public License Version 2. See the LICENSE file - * at the top of the source tree. - */ - -/* - * !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! - * !!!!! DO NOT EDIT !!!!! - * !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! - * This file is generated by a mustache template. Please see the original - * template in rest-api-templates/res_stasis_http_resource.c.mustache - */ - -/*! \file - * - * \brief Endpoint resources - * - * \author David M. Lee, II <dlee@digium.com> - */ - -/*** MODULEINFO - <support_level>core</support_level> - ***/ - -#include "asterisk.h" - -ASTERISK_FILE_VERSION(__FILE__, "$Revision$") - -#include "asterisk/module.h" -#include "asterisk/json.h" -#include "stasis_json/resource_endpoints.h" -static int load_module(void) -{ - return 0; -} - -static int unload_module(void) -{ - return 0; -} - -AST_MODULE_INFO(ASTERISK_GPL_KEY, AST_MODFLAG_GLOBAL_SYMBOLS | AST_MODFLAG_LOAD_ORDER, "Stasis JSON Generators and Validators - Endpoint resources", - .load = load_module, - .unload = unload_module, - .load_pri = AST_MODPRI_DEFAULT, - ); diff --git a/res/res_stasis_json_endpoints.exports.in b/res/res_stasis_json_endpoints.exports.in deleted file mode 100644 index 5e767549c..000000000 --- a/res/res_stasis_json_endpoints.exports.in +++ /dev/null @@ -1,4 +0,0 @@ -{ - local: - *; -}; diff --git a/res/res_stasis_json_events.c b/res/res_stasis_json_events.c deleted file mode 100644 index 4b966e235..000000000 --- a/res/res_stasis_json_events.c +++ /dev/null @@ -1,818 +0,0 @@ -/* - * Asterisk -- An open source telephony toolkit. - * - * Copyright (C) 2012 - 2013, Digium, Inc. - * - * David M. Lee, II <dlee@digium.com> - * - * See http://www.asterisk.org for more information about - * the Asterisk project. Please do not directly contact - * any of the maintainers of this project for assistance; - * the project provides a web site, mailing lists and IRC - * channels for your use. - * - * This program is free software, distributed under the terms of - * the GNU General Public License Version 2. See the LICENSE file - * at the top of the source tree. - */ - -/* - * !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! - * !!!!! DO NOT EDIT !!!!! - * !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! - * This file is generated by a mustache template. Please see the original - * template in rest-api-templates/res_stasis_http_resource.c.mustache - */ - -/*! \file - * - * \brief WebSocket resource - * - * \author David M. Lee, II <dlee@digium.com> - */ - -/*** MODULEINFO - <support_level>core</support_level> - ***/ - -#include "asterisk.h" - -ASTERISK_FILE_VERSION(__FILE__, "$Revision$") - -#include "asterisk/module.h" -#include "asterisk/json.h" -#include "stasis_json/resource_events.h" -#include "asterisk/stasis_channels.h" -#include "asterisk/stasis_bridging.h" - -struct ast_json *stasis_json_event_channel_userevent_create( - struct ast_channel_snapshot *channel_snapshot, - struct ast_json *blob - ) -{ - RAII_VAR(struct ast_json *, message, NULL, ast_json_unref); - RAII_VAR(struct ast_json *, event, NULL, ast_json_unref); - struct ast_json *validator; - int ret; - - ast_assert(channel_snapshot != NULL); - ast_assert(blob != NULL); - ast_assert(ast_json_object_get(blob, "channel") == NULL); - ast_assert(ast_json_object_get(blob, "type") == NULL); - - validator = ast_json_object_get(blob, "eventname"); - if (validator) { - /* do validation? XXX */ - } else { - /* fail message generation if the required parameter doesn't exist */ - return NULL; - } - - event = ast_json_deep_copy(blob); - if (!event) { - return NULL; - } - - ret = ast_json_object_set(event, - "channel", ast_channel_snapshot_to_json(channel_snapshot)); - if (ret) { - return NULL; - } - - message = ast_json_pack("{s: o}", "channel_userevent", ast_json_ref(event)); - if (!message) { - return NULL; - } - - return ast_json_ref(message); -} - -struct ast_json *stasis_json_event_bridge_created_create( - struct ast_bridge_snapshot *bridge_snapshot - ) -{ - RAII_VAR(struct ast_json *, message, NULL, ast_json_unref); - RAII_VAR(struct ast_json *, event, NULL, ast_json_unref); - int ret; - - ast_assert(bridge_snapshot != NULL); - - event = ast_json_object_create(); - if (!event) { - return NULL; - } - - ret = ast_json_object_set(event, - "bridge", ast_bridge_snapshot_to_json(bridge_snapshot)); - if (ret) { - return NULL; - } - - message = ast_json_pack("{s: o}", "bridge_created", ast_json_ref(event)); - if (!message) { - return NULL; - } - - return ast_json_ref(message); -} - -struct ast_json *stasis_json_event_playback_finished_create( - struct ast_json *blob - ) -{ - RAII_VAR(struct ast_json *, message, NULL, ast_json_unref); - RAII_VAR(struct ast_json *, event, NULL, ast_json_unref); - struct ast_json *validator; - - ast_assert(blob != NULL); - ast_assert(ast_json_object_get(blob, "type") == NULL); - - validator = ast_json_object_get(blob, "playback"); - if (validator) { - /* do validation? XXX */ - } else { - /* fail message generation if the required parameter doesn't exist */ - return NULL; - } - - event = ast_json_deep_copy(blob); - if (!event) { - return NULL; - } - - message = ast_json_pack("{s: o}", "playback_finished", ast_json_ref(event)); - if (!message) { - return NULL; - } - - return ast_json_ref(message); -} - -struct ast_json *stasis_json_event_channel_snapshot_create( - struct ast_channel_snapshot *channel_snapshot - ) -{ - RAII_VAR(struct ast_json *, message, NULL, ast_json_unref); - RAII_VAR(struct ast_json *, event, NULL, ast_json_unref); - int ret; - - ast_assert(channel_snapshot != NULL); - - event = ast_json_object_create(); - if (!event) { - return NULL; - } - - ret = ast_json_object_set(event, - "channel", ast_channel_snapshot_to_json(channel_snapshot)); - if (ret) { - return NULL; - } - - message = ast_json_pack("{s: o}", "channel_snapshot", ast_json_ref(event)); - if (!message) { - return NULL; - } - - return ast_json_ref(message); -} - -struct ast_json *stasis_json_event_channel_caller_id_create( - struct ast_channel_snapshot *channel_snapshot, - struct ast_json *blob - ) -{ - RAII_VAR(struct ast_json *, message, NULL, ast_json_unref); - RAII_VAR(struct ast_json *, event, NULL, ast_json_unref); - struct ast_json *validator; - int ret; - - ast_assert(channel_snapshot != NULL); - ast_assert(blob != NULL); - ast_assert(ast_json_object_get(blob, "channel") == NULL); - ast_assert(ast_json_object_get(blob, "type") == NULL); - - validator = ast_json_object_get(blob, "caller_presentation_txt"); - if (validator) { - /* do validation? XXX */ - } else { - /* fail message generation if the required parameter doesn't exist */ - return NULL; - } - - validator = ast_json_object_get(blob, "caller_presentation"); - if (validator) { - /* do validation? XXX */ - } else { - /* fail message generation if the required parameter doesn't exist */ - return NULL; - } - - event = ast_json_deep_copy(blob); - if (!event) { - return NULL; - } - - ret = ast_json_object_set(event, - "channel", ast_channel_snapshot_to_json(channel_snapshot)); - if (ret) { - return NULL; - } - - message = ast_json_pack("{s: o}", "channel_caller_id", ast_json_ref(event)); - if (!message) { - return NULL; - } - - return ast_json_ref(message); -} - -struct ast_json *stasis_json_event_playback_started_create( - struct ast_json *blob - ) -{ - RAII_VAR(struct ast_json *, message, NULL, ast_json_unref); - RAII_VAR(struct ast_json *, event, NULL, ast_json_unref); - struct ast_json *validator; - - ast_assert(blob != NULL); - ast_assert(ast_json_object_get(blob, "type") == NULL); - - validator = ast_json_object_get(blob, "playback"); - if (validator) { - /* do validation? XXX */ - } else { - /* fail message generation if the required parameter doesn't exist */ - return NULL; - } - - event = ast_json_deep_copy(blob); - if (!event) { - return NULL; - } - - message = ast_json_pack("{s: o}", "playback_started", ast_json_ref(event)); - if (!message) { - return NULL; - } - - return ast_json_ref(message); -} - -struct ast_json *stasis_json_event_channel_varset_create( - struct ast_channel_snapshot *channel_snapshot, - struct ast_json *blob - ) -{ - RAII_VAR(struct ast_json *, message, NULL, ast_json_unref); - RAII_VAR(struct ast_json *, event, NULL, ast_json_unref); - struct ast_json *validator; - int ret; - - ast_assert(channel_snapshot != NULL); - ast_assert(blob != NULL); - ast_assert(ast_json_object_get(blob, "channel") == NULL); - ast_assert(ast_json_object_get(blob, "type") == NULL); - - validator = ast_json_object_get(blob, "variable"); - if (validator) { - /* do validation? XXX */ - } else { - /* fail message generation if the required parameter doesn't exist */ - return NULL; - } - - validator = ast_json_object_get(blob, "value"); - if (validator) { - /* do validation? XXX */ - } else { - /* fail message generation if the required parameter doesn't exist */ - return NULL; - } - - event = ast_json_deep_copy(blob); - if (!event) { - return NULL; - } - - ret = ast_json_object_set(event, - "channel", ast_channel_snapshot_to_json(channel_snapshot)); - if (ret) { - return NULL; - } - - message = ast_json_pack("{s: o}", "channel_varset", ast_json_ref(event)); - if (!message) { - return NULL; - } - - return ast_json_ref(message); -} - -struct ast_json *stasis_json_event_bridge_destroyed_create( - struct ast_bridge_snapshot *bridge_snapshot - ) -{ - RAII_VAR(struct ast_json *, message, NULL, ast_json_unref); - RAII_VAR(struct ast_json *, event, NULL, ast_json_unref); - int ret; - - ast_assert(bridge_snapshot != NULL); - - event = ast_json_object_create(); - if (!event) { - return NULL; - } - - ret = ast_json_object_set(event, - "bridge", ast_bridge_snapshot_to_json(bridge_snapshot)); - if (ret) { - return NULL; - } - - message = ast_json_pack("{s: o}", "bridge_destroyed", ast_json_ref(event)); - if (!message) { - return NULL; - } - - return ast_json_ref(message); -} - -struct ast_json *stasis_json_event_application_replaced_create( - struct ast_json *blob - ) -{ - RAII_VAR(struct ast_json *, message, NULL, ast_json_unref); - RAII_VAR(struct ast_json *, event, NULL, ast_json_unref); - struct ast_json *validator; - - ast_assert(blob != NULL); - ast_assert(ast_json_object_get(blob, "type") == NULL); - - validator = ast_json_object_get(blob, "application"); - if (validator) { - /* do validation? XXX */ - } else { - /* fail message generation if the required parameter doesn't exist */ - return NULL; - } - - event = ast_json_deep_copy(blob); - if (!event) { - return NULL; - } - - message = ast_json_pack("{s: o}", "application_replaced", ast_json_ref(event)); - if (!message) { - return NULL; - } - - return ast_json_ref(message); -} - -struct ast_json *stasis_json_event_channel_destroyed_create( - struct ast_channel_snapshot *channel_snapshot, - struct ast_json *blob - ) -{ - RAII_VAR(struct ast_json *, message, NULL, ast_json_unref); - RAII_VAR(struct ast_json *, event, NULL, ast_json_unref); - struct ast_json *validator; - int ret; - - ast_assert(channel_snapshot != NULL); - ast_assert(blob != NULL); - ast_assert(ast_json_object_get(blob, "channel") == NULL); - ast_assert(ast_json_object_get(blob, "type") == NULL); - - validator = ast_json_object_get(blob, "cause"); - if (validator) { - /* do validation? XXX */ - } else { - /* fail message generation if the required parameter doesn't exist */ - return NULL; - } - - validator = ast_json_object_get(blob, "cause_txt"); - if (validator) { - /* do validation? XXX */ - } else { - /* fail message generation if the required parameter doesn't exist */ - return NULL; - } - - event = ast_json_deep_copy(blob); - if (!event) { - return NULL; - } - - ret = ast_json_object_set(event, - "channel", ast_channel_snapshot_to_json(channel_snapshot)); - if (ret) { - return NULL; - } - - message = ast_json_pack("{s: o}", "channel_destroyed", ast_json_ref(event)); - if (!message) { - return NULL; - } - - return ast_json_ref(message); -} - -struct ast_json *stasis_json_event_bridge_merged_create( - struct ast_bridge_snapshot *bridge_snapshot, - struct ast_json *blob - ) -{ - RAII_VAR(struct ast_json *, message, NULL, ast_json_unref); - RAII_VAR(struct ast_json *, event, NULL, ast_json_unref); - struct ast_json *validator; - int ret; - - ast_assert(bridge_snapshot != NULL); - ast_assert(blob != NULL); - ast_assert(ast_json_object_get(blob, "bridge") == NULL); - ast_assert(ast_json_object_get(blob, "type") == NULL); - - validator = ast_json_object_get(blob, "bridge_from"); - if (validator) { - /* do validation? XXX */ - } else { - /* fail message generation if the required parameter doesn't exist */ - return NULL; - } - - event = ast_json_deep_copy(blob); - if (!event) { - return NULL; - } - - ret = ast_json_object_set(event, - "bridge", ast_bridge_snapshot_to_json(bridge_snapshot)); - if (ret) { - return NULL; - } - - message = ast_json_pack("{s: o}", "bridge_merged", ast_json_ref(event)); - if (!message) { - return NULL; - } - - return ast_json_ref(message); -} - -struct ast_json *stasis_json_event_channel_left_bridge_create( - struct ast_bridge_snapshot *bridge_snapshot, - struct ast_channel_snapshot *channel_snapshot - ) -{ - RAII_VAR(struct ast_json *, message, NULL, ast_json_unref); - RAII_VAR(struct ast_json *, event, NULL, ast_json_unref); - int ret; - - ast_assert(channel_snapshot != NULL); - ast_assert(bridge_snapshot != NULL); - - event = ast_json_object_create(); - if (!event) { - return NULL; - } - - ret = ast_json_object_set(event, - "channel", ast_channel_snapshot_to_json(channel_snapshot)); - if (ret) { - return NULL; - } - - ret = ast_json_object_set(event, - "bridge", ast_bridge_snapshot_to_json(bridge_snapshot)); - if (ret) { - return NULL; - } - - message = ast_json_pack("{s: o}", "channel_left_bridge", ast_json_ref(event)); - if (!message) { - return NULL; - } - - return ast_json_ref(message); -} - -struct ast_json *stasis_json_event_channel_created_create( - struct ast_channel_snapshot *channel_snapshot - ) -{ - RAII_VAR(struct ast_json *, message, NULL, ast_json_unref); - RAII_VAR(struct ast_json *, event, NULL, ast_json_unref); - int ret; - - ast_assert(channel_snapshot != NULL); - - event = ast_json_object_create(); - if (!event) { - return NULL; - } - - ret = ast_json_object_set(event, - "channel", ast_channel_snapshot_to_json(channel_snapshot)); - if (ret) { - return NULL; - } - - message = ast_json_pack("{s: o}", "channel_created", ast_json_ref(event)); - if (!message) { - return NULL; - } - - return ast_json_ref(message); -} - -struct ast_json *stasis_json_event_stasis_start_create( - struct ast_channel_snapshot *channel_snapshot, - struct ast_json *blob - ) -{ - RAII_VAR(struct ast_json *, message, NULL, ast_json_unref); - RAII_VAR(struct ast_json *, event, NULL, ast_json_unref); - struct ast_json *validator; - int ret; - - ast_assert(channel_snapshot != NULL); - ast_assert(blob != NULL); - ast_assert(ast_json_object_get(blob, "channel") == NULL); - ast_assert(ast_json_object_get(blob, "type") == NULL); - - validator = ast_json_object_get(blob, "args"); - if (validator) { - /* do validation? XXX */ - } else { - /* fail message generation if the required parameter doesn't exist */ - return NULL; - } - - event = ast_json_deep_copy(blob); - if (!event) { - return NULL; - } - - ret = ast_json_object_set(event, - "channel", ast_channel_snapshot_to_json(channel_snapshot)); - if (ret) { - return NULL; - } - - message = ast_json_pack("{s: o}", "stasis_start", ast_json_ref(event)); - if (!message) { - return NULL; - } - - return ast_json_ref(message); -} - -struct ast_json *stasis_json_event_channel_dialplan_create( - struct ast_channel_snapshot *channel_snapshot, - struct ast_json *blob - ) -{ - RAII_VAR(struct ast_json *, message, NULL, ast_json_unref); - RAII_VAR(struct ast_json *, event, NULL, ast_json_unref); - struct ast_json *validator; - int ret; - - ast_assert(channel_snapshot != NULL); - ast_assert(blob != NULL); - ast_assert(ast_json_object_get(blob, "channel") == NULL); - ast_assert(ast_json_object_get(blob, "type") == NULL); - - validator = ast_json_object_get(blob, "application"); - if (validator) { - /* do validation? XXX */ - } else { - /* fail message generation if the required parameter doesn't exist */ - return NULL; - } - - validator = ast_json_object_get(blob, "application_data"); - if (validator) { - /* do validation? XXX */ - } else { - /* fail message generation if the required parameter doesn't exist */ - return NULL; - } - - event = ast_json_deep_copy(blob); - if (!event) { - return NULL; - } - - ret = ast_json_object_set(event, - "channel", ast_channel_snapshot_to_json(channel_snapshot)); - if (ret) { - return NULL; - } - - message = ast_json_pack("{s: o}", "channel_dialplan", ast_json_ref(event)); - if (!message) { - return NULL; - } - - return ast_json_ref(message); -} - -struct ast_json *stasis_json_event_channel_state_change_create( - struct ast_channel_snapshot *channel_snapshot - ) -{ - RAII_VAR(struct ast_json *, message, NULL, ast_json_unref); - RAII_VAR(struct ast_json *, event, NULL, ast_json_unref); - int ret; - - ast_assert(channel_snapshot != NULL); - - event = ast_json_object_create(); - if (!event) { - return NULL; - } - - ret = ast_json_object_set(event, - "channel", ast_channel_snapshot_to_json(channel_snapshot)); - if (ret) { - return NULL; - } - - message = ast_json_pack("{s: o}", "channel_state_change", ast_json_ref(event)); - if (!message) { - return NULL; - } - - return ast_json_ref(message); -} - -struct ast_json *stasis_json_event_channel_hangup_request_create( - struct ast_channel_snapshot *channel_snapshot, - struct ast_json *blob - ) -{ - RAII_VAR(struct ast_json *, message, NULL, ast_json_unref); - RAII_VAR(struct ast_json *, event, NULL, ast_json_unref); - struct ast_json *validator; - int ret; - - ast_assert(channel_snapshot != NULL); - ast_assert(blob != NULL); - ast_assert(ast_json_object_get(blob, "channel") == NULL); - ast_assert(ast_json_object_get(blob, "type") == NULL); - - validator = ast_json_object_get(blob, "soft"); - if (validator) { - /* do validation? XXX */ - } - - validator = ast_json_object_get(blob, "cause"); - if (validator) { - /* do validation? XXX */ - } - - event = ast_json_deep_copy(blob); - if (!event) { - return NULL; - } - - ret = ast_json_object_set(event, - "channel", ast_channel_snapshot_to_json(channel_snapshot)); - if (ret) { - return NULL; - } - - message = ast_json_pack("{s: o}", "channel_hangup_request", ast_json_ref(event)); - if (!message) { - return NULL; - } - - return ast_json_ref(message); -} - -struct ast_json *stasis_json_event_channel_entered_bridge_create( - struct ast_bridge_snapshot *bridge_snapshot, - struct ast_channel_snapshot *channel_snapshot - ) -{ - RAII_VAR(struct ast_json *, message, NULL, ast_json_unref); - RAII_VAR(struct ast_json *, event, NULL, ast_json_unref); - int ret; - - ast_assert(channel_snapshot != NULL); - ast_assert(bridge_snapshot != NULL); - - event = ast_json_object_create(); - if (!event) { - return NULL; - } - - ret = ast_json_object_set(event, - "channel", ast_channel_snapshot_to_json(channel_snapshot)); - if (ret) { - return NULL; - } - - ret = ast_json_object_set(event, - "bridge", ast_bridge_snapshot_to_json(bridge_snapshot)); - if (ret) { - return NULL; - } - - message = ast_json_pack("{s: o}", "channel_entered_bridge", ast_json_ref(event)); - if (!message) { - return NULL; - } - - return ast_json_ref(message); -} - -struct ast_json *stasis_json_event_channel_dtmf_received_create( - struct ast_channel_snapshot *channel_snapshot, - struct ast_json *blob - ) -{ - RAII_VAR(struct ast_json *, message, NULL, ast_json_unref); - RAII_VAR(struct ast_json *, event, NULL, ast_json_unref); - struct ast_json *validator; - int ret; - - ast_assert(channel_snapshot != NULL); - ast_assert(blob != NULL); - ast_assert(ast_json_object_get(blob, "channel") == NULL); - ast_assert(ast_json_object_get(blob, "type") == NULL); - - validator = ast_json_object_get(blob, "digit"); - if (validator) { - /* do validation? XXX */ - } else { - /* fail message generation if the required parameter doesn't exist */ - return NULL; - } - - event = ast_json_deep_copy(blob); - if (!event) { - return NULL; - } - - ret = ast_json_object_set(event, - "channel", ast_channel_snapshot_to_json(channel_snapshot)); - if (ret) { - return NULL; - } - - message = ast_json_pack("{s: o}", "channel_dtmf_received", ast_json_ref(event)); - if (!message) { - return NULL; - } - - return ast_json_ref(message); -} - -struct ast_json *stasis_json_event_stasis_end_create( - struct ast_channel_snapshot *channel_snapshot - ) -{ - RAII_VAR(struct ast_json *, message, NULL, ast_json_unref); - RAII_VAR(struct ast_json *, event, NULL, ast_json_unref); - int ret; - - ast_assert(channel_snapshot != NULL); - - event = ast_json_object_create(); - if (!event) { - return NULL; - } - - ret = ast_json_object_set(event, - "channel", ast_channel_snapshot_to_json(channel_snapshot)); - if (ret) { - return NULL; - } - - message = ast_json_pack("{s: o}", "stasis_end", ast_json_ref(event)); - if (!message) { - return NULL; - } - - return ast_json_ref(message); -} - -static int load_module(void) -{ - return 0; -} - -static int unload_module(void) -{ - return 0; -} - -AST_MODULE_INFO(ASTERISK_GPL_KEY, AST_MODFLAG_GLOBAL_SYMBOLS | AST_MODFLAG_LOAD_ORDER, "Stasis JSON Generators and Validators - WebSocket resource", - .load = load_module, - .unload = unload_module, - .load_pri = AST_MODPRI_DEFAULT, - ); diff --git a/res/res_stasis_json_events.exports.in b/res/res_stasis_json_events.exports.in deleted file mode 100644 index 5865c026b..000000000 --- a/res/res_stasis_json_events.exports.in +++ /dev/null @@ -1,25 +0,0 @@ -{ - global: - LINKER_SYMBOL_PREFIXstasis_json_event_channel_userevent_create; - LINKER_SYMBOL_PREFIXstasis_json_event_bridge_created_create; - LINKER_SYMBOL_PREFIXstasis_json_event_playback_finished_create; - LINKER_SYMBOL_PREFIXstasis_json_event_channel_snapshot_create; - LINKER_SYMBOL_PREFIXstasis_json_event_channel_caller_id_create; - LINKER_SYMBOL_PREFIXstasis_json_event_playback_started_create; - LINKER_SYMBOL_PREFIXstasis_json_event_channel_varset_create; - LINKER_SYMBOL_PREFIXstasis_json_event_bridge_destroyed_create; - LINKER_SYMBOL_PREFIXstasis_json_event_application_replaced_create; - LINKER_SYMBOL_PREFIXstasis_json_event_channel_destroyed_create; - LINKER_SYMBOL_PREFIXstasis_json_event_bridge_merged_create; - LINKER_SYMBOL_PREFIXstasis_json_event_channel_left_bridge_create; - LINKER_SYMBOL_PREFIXstasis_json_event_channel_created_create; - LINKER_SYMBOL_PREFIXstasis_json_event_stasis_start_create; - LINKER_SYMBOL_PREFIXstasis_json_event_channel_dialplan_create; - LINKER_SYMBOL_PREFIXstasis_json_event_channel_state_change_create; - LINKER_SYMBOL_PREFIXstasis_json_event_channel_hangup_request_create; - LINKER_SYMBOL_PREFIXstasis_json_event_channel_entered_bridge_create; - LINKER_SYMBOL_PREFIXstasis_json_event_channel_dtmf_received_create; - LINKER_SYMBOL_PREFIXstasis_json_event_stasis_end_create; - local: - *; -}; diff --git a/res/res_stasis_json_playback.c b/res/res_stasis_json_playback.c deleted file mode 100644 index 16218c92d..000000000 --- a/res/res_stasis_json_playback.c +++ /dev/null @@ -1,59 +0,0 @@ -/* - * Asterisk -- An open source telephony toolkit. - * - * Copyright (C) 2012 - 2013, Digium, Inc. - * - * David M. Lee, II <dlee@digium.com> - * - * See http://www.asterisk.org for more information about - * the Asterisk project. Please do not directly contact - * any of the maintainers of this project for assistance; - * the project provides a web site, mailing lists and IRC - * channels for your use. - * - * This program is free software, distributed under the terms of - * the GNU General Public License Version 2. See the LICENSE file - * at the top of the source tree. - */ - -/* - * !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! - * !!!!! DO NOT EDIT !!!!! - * !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! - * This file is generated by a mustache template. Please see the original - * template in rest-api-templates/res_stasis_http_resource.c.mustache - */ - -/*! \file - * - * \brief Playback control resources - * - * \author David M. Lee, II <dlee@digium.com> - */ - -/*** MODULEINFO - <support_level>core</support_level> - ***/ - -#include "asterisk.h" - -ASTERISK_FILE_VERSION(__FILE__, "$Revision$") - -#include "asterisk/module.h" -#include "asterisk/json.h" -#include "stasis_json/resource_playback.h" -static int load_module(void) -{ - return 0; -} - -static int unload_module(void) -{ - return 0; -} - -AST_MODULE_INFO(ASTERISK_GPL_KEY, AST_MODFLAG_GLOBAL_SYMBOLS | AST_MODFLAG_LOAD_ORDER, "Stasis JSON Generators and Validators - Playback control resources", - .load = load_module, - .unload = unload_module, - .load_pri = AST_MODPRI_DEFAULT, - ); diff --git a/res/res_stasis_json_playback.exports.in b/res/res_stasis_json_playback.exports.in deleted file mode 100644 index 5e767549c..000000000 --- a/res/res_stasis_json_playback.exports.in +++ /dev/null @@ -1,4 +0,0 @@ -{ - local: - *; -}; diff --git a/res/res_stasis_json_recordings.c b/res/res_stasis_json_recordings.c deleted file mode 100644 index 73935dede..000000000 --- a/res/res_stasis_json_recordings.c +++ /dev/null @@ -1,59 +0,0 @@ -/* - * Asterisk -- An open source telephony toolkit. - * - * Copyright (C) 2012 - 2013, Digium, Inc. - * - * David M. Lee, II <dlee@digium.com> - * - * See http://www.asterisk.org for more information about - * the Asterisk project. Please do not directly contact - * any of the maintainers of this project for assistance; - * the project provides a web site, mailing lists and IRC - * channels for your use. - * - * This program is free software, distributed under the terms of - * the GNU General Public License Version 2. See the LICENSE file - * at the top of the source tree. - */ - -/* - * !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! - * !!!!! DO NOT EDIT !!!!! - * !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! - * This file is generated by a mustache template. Please see the original - * template in rest-api-templates/res_stasis_http_resource.c.mustache - */ - -/*! \file - * - * \brief Recording resources - * - * \author David M. Lee, II <dlee@digium.com> - */ - -/*** MODULEINFO - <support_level>core</support_level> - ***/ - -#include "asterisk.h" - -ASTERISK_FILE_VERSION(__FILE__, "$Revision$") - -#include "asterisk/module.h" -#include "asterisk/json.h" -#include "stasis_json/resource_recordings.h" -static int load_module(void) -{ - return 0; -} - -static int unload_module(void) -{ - return 0; -} - -AST_MODULE_INFO(ASTERISK_GPL_KEY, AST_MODFLAG_GLOBAL_SYMBOLS | AST_MODFLAG_LOAD_ORDER, "Stasis JSON Generators and Validators - Recording resources", - .load = load_module, - .unload = unload_module, - .load_pri = AST_MODPRI_DEFAULT, - ); diff --git a/res/res_stasis_json_recordings.exports.in b/res/res_stasis_json_recordings.exports.in deleted file mode 100644 index 5e767549c..000000000 --- a/res/res_stasis_json_recordings.exports.in +++ /dev/null @@ -1,4 +0,0 @@ -{ - local: - *; -}; diff --git a/res/res_stasis_json_sounds.c b/res/res_stasis_json_sounds.c deleted file mode 100644 index cc6d5ae17..000000000 --- a/res/res_stasis_json_sounds.c +++ /dev/null @@ -1,59 +0,0 @@ -/* - * Asterisk -- An open source telephony toolkit. - * - * Copyright (C) 2012 - 2013, Digium, Inc. - * - * David M. Lee, II <dlee@digium.com> - * - * See http://www.asterisk.org for more information about - * the Asterisk project. Please do not directly contact - * any of the maintainers of this project for assistance; - * the project provides a web site, mailing lists and IRC - * channels for your use. - * - * This program is free software, distributed under the terms of - * the GNU General Public License Version 2. See the LICENSE file - * at the top of the source tree. - */ - -/* - * !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! - * !!!!! DO NOT EDIT !!!!! - * !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! - * This file is generated by a mustache template. Please see the original - * template in rest-api-templates/res_stasis_http_resource.c.mustache - */ - -/*! \file - * - * \brief Sound resources - * - * \author David M. Lee, II <dlee@digium.com> - */ - -/*** MODULEINFO - <support_level>core</support_level> - ***/ - -#include "asterisk.h" - -ASTERISK_FILE_VERSION(__FILE__, "$Revision$") - -#include "asterisk/module.h" -#include "asterisk/json.h" -#include "stasis_json/resource_sounds.h" -static int load_module(void) -{ - return 0; -} - -static int unload_module(void) -{ - return 0; -} - -AST_MODULE_INFO(ASTERISK_GPL_KEY, AST_MODFLAG_GLOBAL_SYMBOLS | AST_MODFLAG_LOAD_ORDER, "Stasis JSON Generators and Validators - Sound resources", - .load = load_module, - .unload = unload_module, - .load_pri = AST_MODPRI_DEFAULT, - ); diff --git a/res/res_stasis_json_sounds.exports.in b/res/res_stasis_json_sounds.exports.in deleted file mode 100644 index 5e767549c..000000000 --- a/res/res_stasis_json_sounds.exports.in +++ /dev/null @@ -1,4 +0,0 @@ -{ - local: - *; -}; diff --git a/res/stasis_http/ari_model_validators.c b/res/stasis_http/ari_model_validators.c new file mode 100644 index 000000000..b41c15473 --- /dev/null +++ b/res/stasis_http/ari_model_validators.c @@ -0,0 +1,2567 @@ +/* + * Asterisk -- An open source telephony toolkit. + * + * Copyright (C) 2013, Digium, Inc. + * + * See http://www.asterisk.org for more information about + * the Asterisk project. Please do not directly contact + * any of the maintainers of this project for assistance; + * the project provides a web site, mailing lists and IRC + * channels for your use. + * + * This program is free software, distributed under the terms of + * the GNU General Public License Version 2. See the LICENSE file + * at the top of the source tree. + */ + +/*! \file + * + * \brief Generated file - Build validators for ARI model objects. + */ + + /* + * !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + * !!!!! DO NOT EDIT !!!!! + * !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + * This file is generated by a mustache template. Please see the original + * template in rest-api-templates/ari_model_validators.h.mustache + */ + +#include "asterisk.h" + +ASTERISK_FILE_VERSION(__FILE__, "$Revision$") + +#include "asterisk/logger.h" +#include "asterisk/module.h" +#include "ari_model_validators.h" + +int ari_validate_asterisk_info(struct ast_json *json) +{ + int res = 1; + struct ast_json_iter *iter; + + for (iter = ast_json_object_iter(json); iter; iter = ast_json_object_iter_next(json, iter)) { + { + ast_log(LOG_ERROR, + "ARI AsteriskInfo has undocumented field %s\n", + ast_json_object_iter_key(iter)); + res = 0; + } + } + + return res; +} + +int ari_validate_endpoint(struct ast_json *json) +{ + int res = 1; + struct ast_json_iter *iter; + int has_channel_ids = 0; + int has_resource = 0; + int has_technology = 0; + + for (iter = ast_json_object_iter(json); iter; iter = ast_json_object_iter_next(json, iter)) { + if (strcmp("channel_ids", ast_json_object_iter_key(iter)) == 0) { + int prop_is_valid; + has_channel_ids = 1; + prop_is_valid = ari_validate_list( + ast_json_object_iter_value(iter), + ari_validate_string); + if (!prop_is_valid) { + ast_log(LOG_ERROR, "ARI Endpoint field channel_ids failed validation\n"); + res = 0; + } + } else + if (strcmp("resource", ast_json_object_iter_key(iter)) == 0) { + int prop_is_valid; + has_resource = 1; + prop_is_valid = ari_validate_string( + ast_json_object_iter_value(iter)); + if (!prop_is_valid) { + ast_log(LOG_ERROR, "ARI Endpoint field resource failed validation\n"); + res = 0; + } + } else + if (strcmp("state", ast_json_object_iter_key(iter)) == 0) { + int prop_is_valid; + prop_is_valid = ari_validate_string( + ast_json_object_iter_value(iter)); + if (!prop_is_valid) { + ast_log(LOG_ERROR, "ARI Endpoint field state failed validation\n"); + res = 0; + } + } else + if (strcmp("technology", ast_json_object_iter_key(iter)) == 0) { + int prop_is_valid; + has_technology = 1; + prop_is_valid = ari_validate_string( + ast_json_object_iter_value(iter)); + if (!prop_is_valid) { + ast_log(LOG_ERROR, "ARI Endpoint field technology failed validation\n"); + res = 0; + } + } else + { + ast_log(LOG_ERROR, + "ARI Endpoint has undocumented field %s\n", + ast_json_object_iter_key(iter)); + res = 0; + } + } + + if (!has_channel_ids) { + ast_log(LOG_ERROR, "ARI Endpoint missing required field channel_ids\n"); + res = 0; + } + + if (!has_resource) { + ast_log(LOG_ERROR, "ARI Endpoint missing required field resource\n"); + res = 0; + } + + if (!has_technology) { + ast_log(LOG_ERROR, "ARI Endpoint missing required field technology\n"); + res = 0; + } + + return res; +} + +int ari_validate_caller_id(struct ast_json *json) +{ + int res = 1; + struct ast_json_iter *iter; + int has_name = 0; + int has_number = 0; + + for (iter = ast_json_object_iter(json); iter; iter = ast_json_object_iter_next(json, iter)) { + if (strcmp("name", ast_json_object_iter_key(iter)) == 0) { + int prop_is_valid; + has_name = 1; + prop_is_valid = ari_validate_string( + ast_json_object_iter_value(iter)); + if (!prop_is_valid) { + ast_log(LOG_ERROR, "ARI CallerID field name failed validation\n"); + res = 0; + } + } else + if (strcmp("number", ast_json_object_iter_key(iter)) == 0) { + int prop_is_valid; + has_number = 1; + prop_is_valid = ari_validate_string( + ast_json_object_iter_value(iter)); + if (!prop_is_valid) { + ast_log(LOG_ERROR, "ARI CallerID field number failed validation\n"); + res = 0; + } + } else + { + ast_log(LOG_ERROR, + "ARI CallerID has undocumented field %s\n", + ast_json_object_iter_key(iter)); + res = 0; + } + } + + if (!has_name) { + ast_log(LOG_ERROR, "ARI CallerID missing required field name\n"); + res = 0; + } + + if (!has_number) { + ast_log(LOG_ERROR, "ARI CallerID missing required field number\n"); + res = 0; + } + + return res; +} + +int ari_validate_channel(struct ast_json *json) +{ + int res = 1; + struct ast_json_iter *iter; + int has_accountcode = 0; + int has_caller = 0; + int has_connected = 0; + int has_creationtime = 0; + int has_dialplan = 0; + int has_id = 0; + int has_name = 0; + int has_state = 0; + + for (iter = ast_json_object_iter(json); iter; iter = ast_json_object_iter_next(json, iter)) { + if (strcmp("accountcode", ast_json_object_iter_key(iter)) == 0) { + int prop_is_valid; + has_accountcode = 1; + prop_is_valid = ari_validate_string( + ast_json_object_iter_value(iter)); + if (!prop_is_valid) { + ast_log(LOG_ERROR, "ARI Channel field accountcode failed validation\n"); + res = 0; + } + } else + if (strcmp("caller", ast_json_object_iter_key(iter)) == 0) { + int prop_is_valid; + has_caller = 1; + prop_is_valid = ari_validate_caller_id( + ast_json_object_iter_value(iter)); + if (!prop_is_valid) { + ast_log(LOG_ERROR, "ARI Channel field caller failed validation\n"); + res = 0; + } + } else + if (strcmp("connected", ast_json_object_iter_key(iter)) == 0) { + int prop_is_valid; + has_connected = 1; + prop_is_valid = ari_validate_caller_id( + ast_json_object_iter_value(iter)); + if (!prop_is_valid) { + ast_log(LOG_ERROR, "ARI Channel field connected failed validation\n"); + res = 0; + } + } else + if (strcmp("creationtime", ast_json_object_iter_key(iter)) == 0) { + int prop_is_valid; + has_creationtime = 1; + prop_is_valid = ari_validate_date( + ast_json_object_iter_value(iter)); + if (!prop_is_valid) { + ast_log(LOG_ERROR, "ARI Channel field creationtime failed validation\n"); + res = 0; + } + } else + if (strcmp("dialplan", ast_json_object_iter_key(iter)) == 0) { + int prop_is_valid; + has_dialplan = 1; + prop_is_valid = ari_validate_dialplan_cep( + ast_json_object_iter_value(iter)); + if (!prop_is_valid) { + ast_log(LOG_ERROR, "ARI Channel field dialplan failed validation\n"); + res = 0; + } + } else + if (strcmp("id", ast_json_object_iter_key(iter)) == 0) { + int prop_is_valid; + has_id = 1; + prop_is_valid = ari_validate_string( + ast_json_object_iter_value(iter)); + if (!prop_is_valid) { + ast_log(LOG_ERROR, "ARI Channel field id failed validation\n"); + res = 0; + } + } else + if (strcmp("name", ast_json_object_iter_key(iter)) == 0) { + int prop_is_valid; + has_name = 1; + prop_is_valid = ari_validate_string( + ast_json_object_iter_value(iter)); + if (!prop_is_valid) { + ast_log(LOG_ERROR, "ARI Channel field name failed validation\n"); + res = 0; + } + } else + if (strcmp("state", ast_json_object_iter_key(iter)) == 0) { + int prop_is_valid; + has_state = 1; + prop_is_valid = ari_validate_string( + ast_json_object_iter_value(iter)); + if (!prop_is_valid) { + ast_log(LOG_ERROR, "ARI Channel field state failed validation\n"); + res = 0; + } + } else + { + ast_log(LOG_ERROR, + "ARI Channel has undocumented field %s\n", + ast_json_object_iter_key(iter)); + res = 0; + } + } + + if (!has_accountcode) { + ast_log(LOG_ERROR, "ARI Channel missing required field accountcode\n"); + res = 0; + } + + if (!has_caller) { + ast_log(LOG_ERROR, "ARI Channel missing required field caller\n"); + res = 0; + } + + if (!has_connected) { + ast_log(LOG_ERROR, "ARI Channel missing required field connected\n"); + res = 0; + } + + if (!has_creationtime) { + ast_log(LOG_ERROR, "ARI Channel missing required field creationtime\n"); + res = 0; + } + + if (!has_dialplan) { + ast_log(LOG_ERROR, "ARI Channel missing required field dialplan\n"); + res = 0; + } + + if (!has_id) { + ast_log(LOG_ERROR, "ARI Channel missing required field id\n"); + res = 0; + } + + if (!has_name) { + ast_log(LOG_ERROR, "ARI Channel missing required field name\n"); + res = 0; + } + + if (!has_state) { + ast_log(LOG_ERROR, "ARI Channel missing required field state\n"); + res = 0; + } + + return res; +} + +int ari_validate_dialed(struct ast_json *json) +{ + int res = 1; + struct ast_json_iter *iter; + + for (iter = ast_json_object_iter(json); iter; iter = ast_json_object_iter_next(json, iter)) { + { + ast_log(LOG_ERROR, + "ARI Dialed has undocumented field %s\n", + ast_json_object_iter_key(iter)); + res = 0; + } + } + + return res; +} + +int ari_validate_dialplan_cep(struct ast_json *json) +{ + int res = 1; + struct ast_json_iter *iter; + int has_context = 0; + int has_exten = 0; + int has_priority = 0; + + for (iter = ast_json_object_iter(json); iter; iter = ast_json_object_iter_next(json, iter)) { + if (strcmp("context", ast_json_object_iter_key(iter)) == 0) { + int prop_is_valid; + has_context = 1; + prop_is_valid = ari_validate_string( + ast_json_object_iter_value(iter)); + if (!prop_is_valid) { + ast_log(LOG_ERROR, "ARI DialplanCEP field context failed validation\n"); + res = 0; + } + } else + if (strcmp("exten", ast_json_object_iter_key(iter)) == 0) { + int prop_is_valid; + has_exten = 1; + prop_is_valid = ari_validate_string( + ast_json_object_iter_value(iter)); + if (!prop_is_valid) { + ast_log(LOG_ERROR, "ARI DialplanCEP field exten failed validation\n"); + res = 0; + } + } else + if (strcmp("priority", ast_json_object_iter_key(iter)) == 0) { + int prop_is_valid; + has_priority = 1; + prop_is_valid = ari_validate_long( + ast_json_object_iter_value(iter)); + if (!prop_is_valid) { + ast_log(LOG_ERROR, "ARI DialplanCEP field priority failed validation\n"); + res = 0; + } + } else + { + ast_log(LOG_ERROR, + "ARI DialplanCEP has undocumented field %s\n", + ast_json_object_iter_key(iter)); + res = 0; + } + } + + if (!has_context) { + ast_log(LOG_ERROR, "ARI DialplanCEP missing required field context\n"); + res = 0; + } + + if (!has_exten) { + ast_log(LOG_ERROR, "ARI DialplanCEP missing required field exten\n"); + res = 0; + } + + if (!has_priority) { + ast_log(LOG_ERROR, "ARI DialplanCEP missing required field priority\n"); + res = 0; + } + + return res; +} + +int ari_validate_bridge(struct ast_json *json) +{ + int res = 1; + struct ast_json_iter *iter; + int has_bridge_class = 0; + int has_bridge_type = 0; + int has_channels = 0; + int has_id = 0; + int has_technology = 0; + + for (iter = ast_json_object_iter(json); iter; iter = ast_json_object_iter_next(json, iter)) { + if (strcmp("bridge_class", ast_json_object_iter_key(iter)) == 0) { + int prop_is_valid; + has_bridge_class = 1; + prop_is_valid = ari_validate_string( + ast_json_object_iter_value(iter)); + if (!prop_is_valid) { + ast_log(LOG_ERROR, "ARI Bridge field bridge_class failed validation\n"); + res = 0; + } + } else + if (strcmp("bridge_type", ast_json_object_iter_key(iter)) == 0) { + int prop_is_valid; + has_bridge_type = 1; + prop_is_valid = ari_validate_string( + ast_json_object_iter_value(iter)); + if (!prop_is_valid) { + ast_log(LOG_ERROR, "ARI Bridge field bridge_type failed validation\n"); + res = 0; + } + } else + if (strcmp("channels", ast_json_object_iter_key(iter)) == 0) { + int prop_is_valid; + has_channels = 1; + prop_is_valid = ari_validate_list( + ast_json_object_iter_value(iter), + ari_validate_string); + if (!prop_is_valid) { + ast_log(LOG_ERROR, "ARI Bridge field channels failed validation\n"); + res = 0; + } + } else + if (strcmp("id", ast_json_object_iter_key(iter)) == 0) { + int prop_is_valid; + has_id = 1; + prop_is_valid = ari_validate_string( + ast_json_object_iter_value(iter)); + if (!prop_is_valid) { + ast_log(LOG_ERROR, "ARI Bridge field id failed validation\n"); + res = 0; + } + } else + if (strcmp("technology", ast_json_object_iter_key(iter)) == 0) { + int prop_is_valid; + has_technology = 1; + prop_is_valid = ari_validate_string( + ast_json_object_iter_value(iter)); + if (!prop_is_valid) { + ast_log(LOG_ERROR, "ARI Bridge field technology failed validation\n"); + res = 0; + } + } else + { + ast_log(LOG_ERROR, + "ARI Bridge has undocumented field %s\n", + ast_json_object_iter_key(iter)); + res = 0; + } + } + + if (!has_bridge_class) { + ast_log(LOG_ERROR, "ARI Bridge missing required field bridge_class\n"); + res = 0; + } + + if (!has_bridge_type) { + ast_log(LOG_ERROR, "ARI Bridge missing required field bridge_type\n"); + res = 0; + } + + if (!has_channels) { + ast_log(LOG_ERROR, "ARI Bridge missing required field channels\n"); + res = 0; + } + + if (!has_id) { + ast_log(LOG_ERROR, "ARI Bridge missing required field id\n"); + res = 0; + } + + if (!has_technology) { + ast_log(LOG_ERROR, "ARI Bridge missing required field technology\n"); + res = 0; + } + + return res; +} + +int ari_validate_live_recording(struct ast_json *json) +{ + int res = 1; + struct ast_json_iter *iter; + int has_id = 0; + + for (iter = ast_json_object_iter(json); iter; iter = ast_json_object_iter_next(json, iter)) { + if (strcmp("id", ast_json_object_iter_key(iter)) == 0) { + int prop_is_valid; + has_id = 1; + prop_is_valid = ari_validate_string( + ast_json_object_iter_value(iter)); + if (!prop_is_valid) { + ast_log(LOG_ERROR, "ARI LiveRecording field id failed validation\n"); + res = 0; + } + } else + { + ast_log(LOG_ERROR, + "ARI LiveRecording has undocumented field %s\n", + ast_json_object_iter_key(iter)); + res = 0; + } + } + + if (!has_id) { + ast_log(LOG_ERROR, "ARI LiveRecording missing required field id\n"); + res = 0; + } + + return res; +} + +int ari_validate_stored_recording(struct ast_json *json) +{ + int res = 1; + struct ast_json_iter *iter; + int has_formats = 0; + int has_id = 0; + + for (iter = ast_json_object_iter(json); iter; iter = ast_json_object_iter_next(json, iter)) { + if (strcmp("duration_seconds", ast_json_object_iter_key(iter)) == 0) { + int prop_is_valid; + prop_is_valid = ari_validate_int( + ast_json_object_iter_value(iter)); + if (!prop_is_valid) { + ast_log(LOG_ERROR, "ARI StoredRecording field duration_seconds failed validation\n"); + res = 0; + } + } else + if (strcmp("formats", ast_json_object_iter_key(iter)) == 0) { + int prop_is_valid; + has_formats = 1; + prop_is_valid = ari_validate_list( + ast_json_object_iter_value(iter), + ari_validate_string); + if (!prop_is_valid) { + ast_log(LOG_ERROR, "ARI StoredRecording field formats failed validation\n"); + res = 0; + } + } else + if (strcmp("id", ast_json_object_iter_key(iter)) == 0) { + int prop_is_valid; + has_id = 1; + prop_is_valid = ari_validate_string( + ast_json_object_iter_value(iter)); + if (!prop_is_valid) { + ast_log(LOG_ERROR, "ARI StoredRecording field id failed validation\n"); + res = 0; + } + } else + if (strcmp("time", ast_json_object_iter_key(iter)) == 0) { + int prop_is_valid; + prop_is_valid = ari_validate_date( + ast_json_object_iter_value(iter)); + if (!prop_is_valid) { + ast_log(LOG_ERROR, "ARI StoredRecording field time failed validation\n"); + res = 0; + } + } else + { + ast_log(LOG_ERROR, + "ARI StoredRecording has undocumented field %s\n", + ast_json_object_iter_key(iter)); + res = 0; + } + } + + if (!has_formats) { + ast_log(LOG_ERROR, "ARI StoredRecording missing required field formats\n"); + res = 0; + } + + if (!has_id) { + ast_log(LOG_ERROR, "ARI StoredRecording missing required field id\n"); + res = 0; + } + + return res; +} + +int ari_validate_format_lang_pair(struct ast_json *json) +{ + int res = 1; + struct ast_json_iter *iter; + int has_format = 0; + int has_language = 0; + + for (iter = ast_json_object_iter(json); iter; iter = ast_json_object_iter_next(json, iter)) { + if (strcmp("format", ast_json_object_iter_key(iter)) == 0) { + int prop_is_valid; + has_format = 1; + prop_is_valid = ari_validate_string( + ast_json_object_iter_value(iter)); + if (!prop_is_valid) { + ast_log(LOG_ERROR, "ARI FormatLangPair field format failed validation\n"); + res = 0; + } + } else + if (strcmp("language", ast_json_object_iter_key(iter)) == 0) { + int prop_is_valid; + has_language = 1; + prop_is_valid = ari_validate_string( + ast_json_object_iter_value(iter)); + if (!prop_is_valid) { + ast_log(LOG_ERROR, "ARI FormatLangPair field language failed validation\n"); + res = 0; + } + } else + { + ast_log(LOG_ERROR, + "ARI FormatLangPair has undocumented field %s\n", + ast_json_object_iter_key(iter)); + res = 0; + } + } + + if (!has_format) { + ast_log(LOG_ERROR, "ARI FormatLangPair missing required field format\n"); + res = 0; + } + + if (!has_language) { + ast_log(LOG_ERROR, "ARI FormatLangPair missing required field language\n"); + res = 0; + } + + return res; +} + +int ari_validate_sound(struct ast_json *json) +{ + int res = 1; + struct ast_json_iter *iter; + int has_formats = 0; + int has_id = 0; + + for (iter = ast_json_object_iter(json); iter; iter = ast_json_object_iter_next(json, iter)) { + if (strcmp("formats", ast_json_object_iter_key(iter)) == 0) { + int prop_is_valid; + has_formats = 1; + prop_is_valid = ari_validate_list( + ast_json_object_iter_value(iter), + ari_validate_format_lang_pair); + if (!prop_is_valid) { + ast_log(LOG_ERROR, "ARI Sound field formats failed validation\n"); + res = 0; + } + } else + if (strcmp("id", ast_json_object_iter_key(iter)) == 0) { + int prop_is_valid; + has_id = 1; + prop_is_valid = ari_validate_string( + ast_json_object_iter_value(iter)); + if (!prop_is_valid) { + ast_log(LOG_ERROR, "ARI Sound field id failed validation\n"); + res = 0; + } + } else + if (strcmp("text", ast_json_object_iter_key(iter)) == 0) { + int prop_is_valid; + prop_is_valid = ari_validate_string( + ast_json_object_iter_value(iter)); + if (!prop_is_valid) { + ast_log(LOG_ERROR, "ARI Sound field text failed validation\n"); + res = 0; + } + } else + { + ast_log(LOG_ERROR, + "ARI Sound has undocumented field %s\n", + ast_json_object_iter_key(iter)); + res = 0; + } + } + + if (!has_formats) { + ast_log(LOG_ERROR, "ARI Sound missing required field formats\n"); + res = 0; + } + + if (!has_id) { + ast_log(LOG_ERROR, "ARI Sound missing required field id\n"); + res = 0; + } + + return res; +} + +int ari_validate_playback(struct ast_json *json) +{ + int res = 1; + struct ast_json_iter *iter; + int has_id = 0; + int has_media_uri = 0; + int has_state = 0; + int has_target_uri = 0; + + for (iter = ast_json_object_iter(json); iter; iter = ast_json_object_iter_next(json, iter)) { + if (strcmp("id", ast_json_object_iter_key(iter)) == 0) { + int prop_is_valid; + has_id = 1; + prop_is_valid = ari_validate_string( + ast_json_object_iter_value(iter)); + if (!prop_is_valid) { + ast_log(LOG_ERROR, "ARI Playback field id failed validation\n"); + res = 0; + } + } else + if (strcmp("language", ast_json_object_iter_key(iter)) == 0) { + int prop_is_valid; + prop_is_valid = ari_validate_string( + ast_json_object_iter_value(iter)); + if (!prop_is_valid) { + ast_log(LOG_ERROR, "ARI Playback field language failed validation\n"); + res = 0; + } + } else + if (strcmp("media_uri", ast_json_object_iter_key(iter)) == 0) { + int prop_is_valid; + has_media_uri = 1; + prop_is_valid = ari_validate_string( + ast_json_object_iter_value(iter)); + if (!prop_is_valid) { + ast_log(LOG_ERROR, "ARI Playback field media_uri failed validation\n"); + res = 0; + } + } else + if (strcmp("state", ast_json_object_iter_key(iter)) == 0) { + int prop_is_valid; + has_state = 1; + prop_is_valid = ari_validate_string( + ast_json_object_iter_value(iter)); + if (!prop_is_valid) { + ast_log(LOG_ERROR, "ARI Playback field state failed validation\n"); + res = 0; + } + } else + if (strcmp("target_uri", ast_json_object_iter_key(iter)) == 0) { + int prop_is_valid; + has_target_uri = 1; + prop_is_valid = ari_validate_string( + ast_json_object_iter_value(iter)); + if (!prop_is_valid) { + ast_log(LOG_ERROR, "ARI Playback field target_uri failed validation\n"); + res = 0; + } + } else + { + ast_log(LOG_ERROR, + "ARI Playback has undocumented field %s\n", + ast_json_object_iter_key(iter)); + res = 0; + } + } + + if (!has_id) { + ast_log(LOG_ERROR, "ARI Playback missing required field id\n"); + res = 0; + } + + if (!has_media_uri) { + ast_log(LOG_ERROR, "ARI Playback missing required field media_uri\n"); + res = 0; + } + + if (!has_state) { + ast_log(LOG_ERROR, "ARI Playback missing required field state\n"); + res = 0; + } + + if (!has_target_uri) { + ast_log(LOG_ERROR, "ARI Playback missing required field target_uri\n"); + res = 0; + } + + return res; +} + +int ari_validate_application_replaced(struct ast_json *json) +{ + int res = 1; + struct ast_json_iter *iter; + int has_application = 0; + int has_type = 0; + + for (iter = ast_json_object_iter(json); iter; iter = ast_json_object_iter_next(json, iter)) { + if (strcmp("application", ast_json_object_iter_key(iter)) == 0) { + int prop_is_valid; + has_application = 1; + prop_is_valid = ari_validate_string( + ast_json_object_iter_value(iter)); + if (!prop_is_valid) { + ast_log(LOG_ERROR, "ARI ApplicationReplaced field application failed validation\n"); + res = 0; + } + } else + if (strcmp("timestamp", ast_json_object_iter_key(iter)) == 0) { + int prop_is_valid; + prop_is_valid = ari_validate_date( + ast_json_object_iter_value(iter)); + if (!prop_is_valid) { + ast_log(LOG_ERROR, "ARI ApplicationReplaced field timestamp failed validation\n"); + res = 0; + } + } else + if (strcmp("type", ast_json_object_iter_key(iter)) == 0) { + int prop_is_valid; + has_type = 1; + prop_is_valid = ari_validate_string( + ast_json_object_iter_value(iter)); + if (!prop_is_valid) { + ast_log(LOG_ERROR, "ARI ApplicationReplaced field type failed validation\n"); + res = 0; + } + } else + { + ast_log(LOG_ERROR, + "ARI ApplicationReplaced has undocumented field %s\n", + ast_json_object_iter_key(iter)); + res = 0; + } + } + + if (!has_application) { + ast_log(LOG_ERROR, "ARI ApplicationReplaced missing required field application\n"); + res = 0; + } + + if (!has_type) { + ast_log(LOG_ERROR, "ARI ApplicationReplaced missing required field type\n"); + res = 0; + } + + return res; +} + +int ari_validate_bridge_created(struct ast_json *json) +{ + int res = 1; + struct ast_json_iter *iter; + int has_application = 0; + int has_type = 0; + int has_bridge = 0; + + for (iter = ast_json_object_iter(json); iter; iter = ast_json_object_iter_next(json, iter)) { + if (strcmp("application", ast_json_object_iter_key(iter)) == 0) { + int prop_is_valid; + has_application = 1; + prop_is_valid = ari_validate_string( + ast_json_object_iter_value(iter)); + if (!prop_is_valid) { + ast_log(LOG_ERROR, "ARI BridgeCreated field application failed validation\n"); + res = 0; + } + } else + if (strcmp("timestamp", ast_json_object_iter_key(iter)) == 0) { + int prop_is_valid; + prop_is_valid = ari_validate_date( + ast_json_object_iter_value(iter)); + if (!prop_is_valid) { + ast_log(LOG_ERROR, "ARI BridgeCreated field timestamp failed validation\n"); + res = 0; + } + } else + if (strcmp("type", ast_json_object_iter_key(iter)) == 0) { + int prop_is_valid; + has_type = 1; + prop_is_valid = ari_validate_string( + ast_json_object_iter_value(iter)); + if (!prop_is_valid) { + ast_log(LOG_ERROR, "ARI BridgeCreated field type failed validation\n"); + res = 0; + } + } else + if (strcmp("bridge", ast_json_object_iter_key(iter)) == 0) { + int prop_is_valid; + has_bridge = 1; + prop_is_valid = ari_validate_bridge( + ast_json_object_iter_value(iter)); + if (!prop_is_valid) { + ast_log(LOG_ERROR, "ARI BridgeCreated field bridge failed validation\n"); + res = 0; + } + } else + { + ast_log(LOG_ERROR, + "ARI BridgeCreated has undocumented field %s\n", + ast_json_object_iter_key(iter)); + res = 0; + } + } + + if (!has_application) { + ast_log(LOG_ERROR, "ARI BridgeCreated missing required field application\n"); + res = 0; + } + + if (!has_type) { + ast_log(LOG_ERROR, "ARI BridgeCreated missing required field type\n"); + res = 0; + } + + if (!has_bridge) { + ast_log(LOG_ERROR, "ARI BridgeCreated missing required field bridge\n"); + res = 0; + } + + return res; +} + +int ari_validate_bridge_destroyed(struct ast_json *json) +{ + int res = 1; + struct ast_json_iter *iter; + int has_application = 0; + int has_type = 0; + int has_bridge = 0; + + for (iter = ast_json_object_iter(json); iter; iter = ast_json_object_iter_next(json, iter)) { + if (strcmp("application", ast_json_object_iter_key(iter)) == 0) { + int prop_is_valid; + has_application = 1; + prop_is_valid = ari_validate_string( + ast_json_object_iter_value(iter)); + if (!prop_is_valid) { + ast_log(LOG_ERROR, "ARI BridgeDestroyed field application failed validation\n"); + res = 0; + } + } else + if (strcmp("timestamp", ast_json_object_iter_key(iter)) == 0) { + int prop_is_valid; + prop_is_valid = ari_validate_date( + ast_json_object_iter_value(iter)); + if (!prop_is_valid) { + ast_log(LOG_ERROR, "ARI BridgeDestroyed field timestamp failed validation\n"); + res = 0; + } + } else + if (strcmp("type", ast_json_object_iter_key(iter)) == 0) { + int prop_is_valid; + has_type = 1; + prop_is_valid = ari_validate_string( + ast_json_object_iter_value(iter)); + if (!prop_is_valid) { + ast_log(LOG_ERROR, "ARI BridgeDestroyed field type failed validation\n"); + res = 0; + } + } else + if (strcmp("bridge", ast_json_object_iter_key(iter)) == 0) { + int prop_is_valid; + has_bridge = 1; + prop_is_valid = ari_validate_bridge( + ast_json_object_iter_value(iter)); + if (!prop_is_valid) { + ast_log(LOG_ERROR, "ARI BridgeDestroyed field bridge failed validation\n"); + res = 0; + } + } else + { + ast_log(LOG_ERROR, + "ARI BridgeDestroyed has undocumented field %s\n", + ast_json_object_iter_key(iter)); + res = 0; + } + } + + if (!has_application) { + ast_log(LOG_ERROR, "ARI BridgeDestroyed missing required field application\n"); + res = 0; + } + + if (!has_type) { + ast_log(LOG_ERROR, "ARI BridgeDestroyed missing required field type\n"); + res = 0; + } + + if (!has_bridge) { + ast_log(LOG_ERROR, "ARI BridgeDestroyed missing required field bridge\n"); + res = 0; + } + + return res; +} + +int ari_validate_bridge_merged(struct ast_json *json) +{ + int res = 1; + struct ast_json_iter *iter; + int has_application = 0; + int has_type = 0; + int has_bridge = 0; + int has_bridge_from = 0; + + for (iter = ast_json_object_iter(json); iter; iter = ast_json_object_iter_next(json, iter)) { + if (strcmp("application", ast_json_object_iter_key(iter)) == 0) { + int prop_is_valid; + has_application = 1; + prop_is_valid = ari_validate_string( + ast_json_object_iter_value(iter)); + if (!prop_is_valid) { + ast_log(LOG_ERROR, "ARI BridgeMerged field application failed validation\n"); + res = 0; + } + } else + if (strcmp("timestamp", ast_json_object_iter_key(iter)) == 0) { + int prop_is_valid; + prop_is_valid = ari_validate_date( + ast_json_object_iter_value(iter)); + if (!prop_is_valid) { + ast_log(LOG_ERROR, "ARI BridgeMerged field timestamp failed validation\n"); + res = 0; + } + } else + if (strcmp("type", ast_json_object_iter_key(iter)) == 0) { + int prop_is_valid; + has_type = 1; + prop_is_valid = ari_validate_string( + ast_json_object_iter_value(iter)); + if (!prop_is_valid) { + ast_log(LOG_ERROR, "ARI BridgeMerged field type failed validation\n"); + res = 0; + } + } else + if (strcmp("bridge", ast_json_object_iter_key(iter)) == 0) { + int prop_is_valid; + has_bridge = 1; + prop_is_valid = ari_validate_bridge( + ast_json_object_iter_value(iter)); + if (!prop_is_valid) { + ast_log(LOG_ERROR, "ARI BridgeMerged field bridge failed validation\n"); + res = 0; + } + } else + if (strcmp("bridge_from", ast_json_object_iter_key(iter)) == 0) { + int prop_is_valid; + has_bridge_from = 1; + prop_is_valid = ari_validate_bridge( + ast_json_object_iter_value(iter)); + if (!prop_is_valid) { + ast_log(LOG_ERROR, "ARI BridgeMerged field bridge_from failed validation\n"); + res = 0; + } + } else + { + ast_log(LOG_ERROR, + "ARI BridgeMerged has undocumented field %s\n", + ast_json_object_iter_key(iter)); + res = 0; + } + } + + if (!has_application) { + ast_log(LOG_ERROR, "ARI BridgeMerged missing required field application\n"); + res = 0; + } + + if (!has_type) { + ast_log(LOG_ERROR, "ARI BridgeMerged missing required field type\n"); + res = 0; + } + + if (!has_bridge) { + ast_log(LOG_ERROR, "ARI BridgeMerged missing required field bridge\n"); + res = 0; + } + + if (!has_bridge_from) { + ast_log(LOG_ERROR, "ARI BridgeMerged missing required field bridge_from\n"); + res = 0; + } + + return res; +} + +int ari_validate_channel_caller_id(struct ast_json *json) +{ + int res = 1; + struct ast_json_iter *iter; + int has_application = 0; + int has_type = 0; + int has_caller_presentation = 0; + int has_caller_presentation_txt = 0; + int has_channel = 0; + + for (iter = ast_json_object_iter(json); iter; iter = ast_json_object_iter_next(json, iter)) { + if (strcmp("application", ast_json_object_iter_key(iter)) == 0) { + int prop_is_valid; + has_application = 1; + prop_is_valid = ari_validate_string( + ast_json_object_iter_value(iter)); + if (!prop_is_valid) { + ast_log(LOG_ERROR, "ARI ChannelCallerId field application failed validation\n"); + res = 0; + } + } else + if (strcmp("timestamp", ast_json_object_iter_key(iter)) == 0) { + int prop_is_valid; + prop_is_valid = ari_validate_date( + ast_json_object_iter_value(iter)); + if (!prop_is_valid) { + ast_log(LOG_ERROR, "ARI ChannelCallerId field timestamp failed validation\n"); + res = 0; + } + } else + if (strcmp("type", ast_json_object_iter_key(iter)) == 0) { + int prop_is_valid; + has_type = 1; + prop_is_valid = ari_validate_string( + ast_json_object_iter_value(iter)); + if (!prop_is_valid) { + ast_log(LOG_ERROR, "ARI ChannelCallerId field type failed validation\n"); + res = 0; + } + } else + if (strcmp("caller_presentation", ast_json_object_iter_key(iter)) == 0) { + int prop_is_valid; + has_caller_presentation = 1; + prop_is_valid = ari_validate_int( + ast_json_object_iter_value(iter)); + if (!prop_is_valid) { + ast_log(LOG_ERROR, "ARI ChannelCallerId field caller_presentation failed validation\n"); + res = 0; + } + } else + if (strcmp("caller_presentation_txt", ast_json_object_iter_key(iter)) == 0) { + int prop_is_valid; + has_caller_presentation_txt = 1; + prop_is_valid = ari_validate_string( + ast_json_object_iter_value(iter)); + if (!prop_is_valid) { + ast_log(LOG_ERROR, "ARI ChannelCallerId field caller_presentation_txt failed validation\n"); + res = 0; + } + } else + if (strcmp("channel", ast_json_object_iter_key(iter)) == 0) { + int prop_is_valid; + has_channel = 1; + prop_is_valid = ari_validate_channel( + ast_json_object_iter_value(iter)); + if (!prop_is_valid) { + ast_log(LOG_ERROR, "ARI ChannelCallerId field channel failed validation\n"); + res = 0; + } + } else + { + ast_log(LOG_ERROR, + "ARI ChannelCallerId has undocumented field %s\n", + ast_json_object_iter_key(iter)); + res = 0; + } + } + + if (!has_application) { + ast_log(LOG_ERROR, "ARI ChannelCallerId missing required field application\n"); + res = 0; + } + + if (!has_type) { + ast_log(LOG_ERROR, "ARI ChannelCallerId missing required field type\n"); + res = 0; + } + + if (!has_caller_presentation) { + ast_log(LOG_ERROR, "ARI ChannelCallerId missing required field caller_presentation\n"); + res = 0; + } + + if (!has_caller_presentation_txt) { + ast_log(LOG_ERROR, "ARI ChannelCallerId missing required field caller_presentation_txt\n"); + res = 0; + } + + if (!has_channel) { + ast_log(LOG_ERROR, "ARI ChannelCallerId missing required field channel\n"); + res = 0; + } + + return res; +} + +int ari_validate_channel_created(struct ast_json *json) +{ + int res = 1; + struct ast_json_iter *iter; + int has_application = 0; + int has_type = 0; + int has_channel = 0; + + for (iter = ast_json_object_iter(json); iter; iter = ast_json_object_iter_next(json, iter)) { + if (strcmp("application", ast_json_object_iter_key(iter)) == 0) { + int prop_is_valid; + has_application = 1; + prop_is_valid = ari_validate_string( + ast_json_object_iter_value(iter)); + if (!prop_is_valid) { + ast_log(LOG_ERROR, "ARI ChannelCreated field application failed validation\n"); + res = 0; + } + } else + if (strcmp("timestamp", ast_json_object_iter_key(iter)) == 0) { + int prop_is_valid; + prop_is_valid = ari_validate_date( + ast_json_object_iter_value(iter)); + if (!prop_is_valid) { + ast_log(LOG_ERROR, "ARI ChannelCreated field timestamp failed validation\n"); + res = 0; + } + } else + if (strcmp("type", ast_json_object_iter_key(iter)) == 0) { + int prop_is_valid; + has_type = 1; + prop_is_valid = ari_validate_string( + ast_json_object_iter_value(iter)); + if (!prop_is_valid) { + ast_log(LOG_ERROR, "ARI ChannelCreated field type failed validation\n"); + res = 0; + } + } else + if (strcmp("channel", ast_json_object_iter_key(iter)) == 0) { + int prop_is_valid; + has_channel = 1; + prop_is_valid = ari_validate_channel( + ast_json_object_iter_value(iter)); + if (!prop_is_valid) { + ast_log(LOG_ERROR, "ARI ChannelCreated field channel failed validation\n"); + res = 0; + } + } else + { + ast_log(LOG_ERROR, + "ARI ChannelCreated has undocumented field %s\n", + ast_json_object_iter_key(iter)); + res = 0; + } + } + + if (!has_application) { + ast_log(LOG_ERROR, "ARI ChannelCreated missing required field application\n"); + res = 0; + } + + if (!has_type) { + ast_log(LOG_ERROR, "ARI ChannelCreated missing required field type\n"); + res = 0; + } + + if (!has_channel) { + ast_log(LOG_ERROR, "ARI ChannelCreated missing required field channel\n"); + res = 0; + } + + return res; +} + +int ari_validate_channel_destroyed(struct ast_json *json) +{ + int res = 1; + struct ast_json_iter *iter; + int has_application = 0; + int has_type = 0; + int has_cause = 0; + int has_cause_txt = 0; + int has_channel = 0; + + for (iter = ast_json_object_iter(json); iter; iter = ast_json_object_iter_next(json, iter)) { + if (strcmp("application", ast_json_object_iter_key(iter)) == 0) { + int prop_is_valid; + has_application = 1; + prop_is_valid = ari_validate_string( + ast_json_object_iter_value(iter)); + if (!prop_is_valid) { + ast_log(LOG_ERROR, "ARI ChannelDestroyed field application failed validation\n"); + res = 0; + } + } else + if (strcmp("timestamp", ast_json_object_iter_key(iter)) == 0) { + int prop_is_valid; + prop_is_valid = ari_validate_date( + ast_json_object_iter_value(iter)); + if (!prop_is_valid) { + ast_log(LOG_ERROR, "ARI ChannelDestroyed field timestamp failed validation\n"); + res = 0; + } + } else + if (strcmp("type", ast_json_object_iter_key(iter)) == 0) { + int prop_is_valid; + has_type = 1; + prop_is_valid = ari_validate_string( + ast_json_object_iter_value(iter)); + if (!prop_is_valid) { + ast_log(LOG_ERROR, "ARI ChannelDestroyed field type failed validation\n"); + res = 0; + } + } else + if (strcmp("cause", ast_json_object_iter_key(iter)) == 0) { + int prop_is_valid; + has_cause = 1; + prop_is_valid = ari_validate_int( + ast_json_object_iter_value(iter)); + if (!prop_is_valid) { + ast_log(LOG_ERROR, "ARI ChannelDestroyed field cause failed validation\n"); + res = 0; + } + } else + if (strcmp("cause_txt", ast_json_object_iter_key(iter)) == 0) { + int prop_is_valid; + has_cause_txt = 1; + prop_is_valid = ari_validate_string( + ast_json_object_iter_value(iter)); + if (!prop_is_valid) { + ast_log(LOG_ERROR, "ARI ChannelDestroyed field cause_txt failed validation\n"); + res = 0; + } + } else + if (strcmp("channel", ast_json_object_iter_key(iter)) == 0) { + int prop_is_valid; + has_channel = 1; + prop_is_valid = ari_validate_channel( + ast_json_object_iter_value(iter)); + if (!prop_is_valid) { + ast_log(LOG_ERROR, "ARI ChannelDestroyed field channel failed validation\n"); + res = 0; + } + } else + { + ast_log(LOG_ERROR, + "ARI ChannelDestroyed has undocumented field %s\n", + ast_json_object_iter_key(iter)); + res = 0; + } + } + + if (!has_application) { + ast_log(LOG_ERROR, "ARI ChannelDestroyed missing required field application\n"); + res = 0; + } + + if (!has_type) { + ast_log(LOG_ERROR, "ARI ChannelDestroyed missing required field type\n"); + res = 0; + } + + if (!has_cause) { + ast_log(LOG_ERROR, "ARI ChannelDestroyed missing required field cause\n"); + res = 0; + } + + if (!has_cause_txt) { + ast_log(LOG_ERROR, "ARI ChannelDestroyed missing required field cause_txt\n"); + res = 0; + } + + if (!has_channel) { + ast_log(LOG_ERROR, "ARI ChannelDestroyed missing required field channel\n"); + res = 0; + } + + return res; +} + +int ari_validate_channel_dialplan(struct ast_json *json) +{ + int res = 1; + struct ast_json_iter *iter; + int has_application = 0; + int has_type = 0; + int has_channel = 0; + int has_dialplan_app = 0; + int has_dialplan_app_data = 0; + + for (iter = ast_json_object_iter(json); iter; iter = ast_json_object_iter_next(json, iter)) { + if (strcmp("application", ast_json_object_iter_key(iter)) == 0) { + int prop_is_valid; + has_application = 1; + prop_is_valid = ari_validate_string( + ast_json_object_iter_value(iter)); + if (!prop_is_valid) { + ast_log(LOG_ERROR, "ARI ChannelDialplan field application failed validation\n"); + res = 0; + } + } else + if (strcmp("timestamp", ast_json_object_iter_key(iter)) == 0) { + int prop_is_valid; + prop_is_valid = ari_validate_date( + ast_json_object_iter_value(iter)); + if (!prop_is_valid) { + ast_log(LOG_ERROR, "ARI ChannelDialplan field timestamp failed validation\n"); + res = 0; + } + } else + if (strcmp("type", ast_json_object_iter_key(iter)) == 0) { + int prop_is_valid; + has_type = 1; + prop_is_valid = ari_validate_string( + ast_json_object_iter_value(iter)); + if (!prop_is_valid) { + ast_log(LOG_ERROR, "ARI ChannelDialplan field type failed validation\n"); + res = 0; + } + } else + if (strcmp("channel", ast_json_object_iter_key(iter)) == 0) { + int prop_is_valid; + has_channel = 1; + prop_is_valid = ari_validate_channel( + ast_json_object_iter_value(iter)); + if (!prop_is_valid) { + ast_log(LOG_ERROR, "ARI ChannelDialplan field channel failed validation\n"); + res = 0; + } + } else + if (strcmp("dialplan_app", ast_json_object_iter_key(iter)) == 0) { + int prop_is_valid; + has_dialplan_app = 1; + prop_is_valid = ari_validate_string( + ast_json_object_iter_value(iter)); + if (!prop_is_valid) { + ast_log(LOG_ERROR, "ARI ChannelDialplan field dialplan_app failed validation\n"); + res = 0; + } + } else + if (strcmp("dialplan_app_data", ast_json_object_iter_key(iter)) == 0) { + int prop_is_valid; + has_dialplan_app_data = 1; + prop_is_valid = ari_validate_string( + ast_json_object_iter_value(iter)); + if (!prop_is_valid) { + ast_log(LOG_ERROR, "ARI ChannelDialplan field dialplan_app_data failed validation\n"); + res = 0; + } + } else + { + ast_log(LOG_ERROR, + "ARI ChannelDialplan has undocumented field %s\n", + ast_json_object_iter_key(iter)); + res = 0; + } + } + + if (!has_application) { + ast_log(LOG_ERROR, "ARI ChannelDialplan missing required field application\n"); + res = 0; + } + + if (!has_type) { + ast_log(LOG_ERROR, "ARI ChannelDialplan missing required field type\n"); + res = 0; + } + + if (!has_channel) { + ast_log(LOG_ERROR, "ARI ChannelDialplan missing required field channel\n"); + res = 0; + } + + if (!has_dialplan_app) { + ast_log(LOG_ERROR, "ARI ChannelDialplan missing required field dialplan_app\n"); + res = 0; + } + + if (!has_dialplan_app_data) { + ast_log(LOG_ERROR, "ARI ChannelDialplan missing required field dialplan_app_data\n"); + res = 0; + } + + return res; +} + +int ari_validate_channel_dtmf_received(struct ast_json *json) +{ + int res = 1; + struct ast_json_iter *iter; + int has_application = 0; + int has_type = 0; + int has_channel = 0; + int has_digit = 0; + int has_duration_ms = 0; + + for (iter = ast_json_object_iter(json); iter; iter = ast_json_object_iter_next(json, iter)) { + if (strcmp("application", ast_json_object_iter_key(iter)) == 0) { + int prop_is_valid; + has_application = 1; + prop_is_valid = ari_validate_string( + ast_json_object_iter_value(iter)); + if (!prop_is_valid) { + ast_log(LOG_ERROR, "ARI ChannelDtmfReceived field application failed validation\n"); + res = 0; + } + } else + if (strcmp("timestamp", ast_json_object_iter_key(iter)) == 0) { + int prop_is_valid; + prop_is_valid = ari_validate_date( + ast_json_object_iter_value(iter)); + if (!prop_is_valid) { + ast_log(LOG_ERROR, "ARI ChannelDtmfReceived field timestamp failed validation\n"); + res = 0; + } + } else + if (strcmp("type", ast_json_object_iter_key(iter)) == 0) { + int prop_is_valid; + has_type = 1; + prop_is_valid = ari_validate_string( + ast_json_object_iter_value(iter)); + if (!prop_is_valid) { + ast_log(LOG_ERROR, "ARI ChannelDtmfReceived field type failed validation\n"); + res = 0; + } + } else + if (strcmp("channel", ast_json_object_iter_key(iter)) == 0) { + int prop_is_valid; + has_channel = 1; + prop_is_valid = ari_validate_channel( + ast_json_object_iter_value(iter)); + if (!prop_is_valid) { + ast_log(LOG_ERROR, "ARI ChannelDtmfReceived field channel failed validation\n"); + res = 0; + } + } else + if (strcmp("digit", ast_json_object_iter_key(iter)) == 0) { + int prop_is_valid; + has_digit = 1; + prop_is_valid = ari_validate_string( + ast_json_object_iter_value(iter)); + if (!prop_is_valid) { + ast_log(LOG_ERROR, "ARI ChannelDtmfReceived field digit failed validation\n"); + res = 0; + } + } else + if (strcmp("duration_ms", ast_json_object_iter_key(iter)) == 0) { + int prop_is_valid; + has_duration_ms = 1; + prop_is_valid = ari_validate_int( + ast_json_object_iter_value(iter)); + if (!prop_is_valid) { + ast_log(LOG_ERROR, "ARI ChannelDtmfReceived field duration_ms failed validation\n"); + res = 0; + } + } else + { + ast_log(LOG_ERROR, + "ARI ChannelDtmfReceived has undocumented field %s\n", + ast_json_object_iter_key(iter)); + res = 0; + } + } + + if (!has_application) { + ast_log(LOG_ERROR, "ARI ChannelDtmfReceived missing required field application\n"); + res = 0; + } + + if (!has_type) { + ast_log(LOG_ERROR, "ARI ChannelDtmfReceived missing required field type\n"); + res = 0; + } + + if (!has_channel) { + ast_log(LOG_ERROR, "ARI ChannelDtmfReceived missing required field channel\n"); + res = 0; + } + + if (!has_digit) { + ast_log(LOG_ERROR, "ARI ChannelDtmfReceived missing required field digit\n"); + res = 0; + } + + if (!has_duration_ms) { + ast_log(LOG_ERROR, "ARI ChannelDtmfReceived missing required field duration_ms\n"); + res = 0; + } + + return res; +} + +int ari_validate_channel_entered_bridge(struct ast_json *json) +{ + int res = 1; + struct ast_json_iter *iter; + int has_application = 0; + int has_type = 0; + int has_bridge = 0; + + for (iter = ast_json_object_iter(json); iter; iter = ast_json_object_iter_next(json, iter)) { + if (strcmp("application", ast_json_object_iter_key(iter)) == 0) { + int prop_is_valid; + has_application = 1; + prop_is_valid = ari_validate_string( + ast_json_object_iter_value(iter)); + if (!prop_is_valid) { + ast_log(LOG_ERROR, "ARI ChannelEnteredBridge field application failed validation\n"); + res = 0; + } + } else + if (strcmp("timestamp", ast_json_object_iter_key(iter)) == 0) { + int prop_is_valid; + prop_is_valid = ari_validate_date( + ast_json_object_iter_value(iter)); + if (!prop_is_valid) { + ast_log(LOG_ERROR, "ARI ChannelEnteredBridge field timestamp failed validation\n"); + res = 0; + } + } else + if (strcmp("type", ast_json_object_iter_key(iter)) == 0) { + int prop_is_valid; + has_type = 1; + prop_is_valid = ari_validate_string( + ast_json_object_iter_value(iter)); + if (!prop_is_valid) { + ast_log(LOG_ERROR, "ARI ChannelEnteredBridge field type failed validation\n"); + res = 0; + } + } else + if (strcmp("bridge", ast_json_object_iter_key(iter)) == 0) { + int prop_is_valid; + has_bridge = 1; + prop_is_valid = ari_validate_bridge( + ast_json_object_iter_value(iter)); + if (!prop_is_valid) { + ast_log(LOG_ERROR, "ARI ChannelEnteredBridge field bridge failed validation\n"); + res = 0; + } + } else + if (strcmp("channel", ast_json_object_iter_key(iter)) == 0) { + int prop_is_valid; + prop_is_valid = ari_validate_channel( + ast_json_object_iter_value(iter)); + if (!prop_is_valid) { + ast_log(LOG_ERROR, "ARI ChannelEnteredBridge field channel failed validation\n"); + res = 0; + } + } else + { + ast_log(LOG_ERROR, + "ARI ChannelEnteredBridge has undocumented field %s\n", + ast_json_object_iter_key(iter)); + res = 0; + } + } + + if (!has_application) { + ast_log(LOG_ERROR, "ARI ChannelEnteredBridge missing required field application\n"); + res = 0; + } + + if (!has_type) { + ast_log(LOG_ERROR, "ARI ChannelEnteredBridge missing required field type\n"); + res = 0; + } + + if (!has_bridge) { + ast_log(LOG_ERROR, "ARI ChannelEnteredBridge missing required field bridge\n"); + res = 0; + } + + return res; +} + +int ari_validate_channel_hangup_request(struct ast_json *json) +{ + int res = 1; + struct ast_json_iter *iter; + int has_application = 0; + int has_type = 0; + int has_channel = 0; + + for (iter = ast_json_object_iter(json); iter; iter = ast_json_object_iter_next(json, iter)) { + if (strcmp("application", ast_json_object_iter_key(iter)) == 0) { + int prop_is_valid; + has_application = 1; + prop_is_valid = ari_validate_string( + ast_json_object_iter_value(iter)); + if (!prop_is_valid) { + ast_log(LOG_ERROR, "ARI ChannelHangupRequest field application failed validation\n"); + res = 0; + } + } else + if (strcmp("timestamp", ast_json_object_iter_key(iter)) == 0) { + int prop_is_valid; + prop_is_valid = ari_validate_date( + ast_json_object_iter_value(iter)); + if (!prop_is_valid) { + ast_log(LOG_ERROR, "ARI ChannelHangupRequest field timestamp failed validation\n"); + res = 0; + } + } else + if (strcmp("type", ast_json_object_iter_key(iter)) == 0) { + int prop_is_valid; + has_type = 1; + prop_is_valid = ari_validate_string( + ast_json_object_iter_value(iter)); + if (!prop_is_valid) { + ast_log(LOG_ERROR, "ARI ChannelHangupRequest field type failed validation\n"); + res = 0; + } + } else + if (strcmp("cause", ast_json_object_iter_key(iter)) == 0) { + int prop_is_valid; + prop_is_valid = ari_validate_int( + ast_json_object_iter_value(iter)); + if (!prop_is_valid) { + ast_log(LOG_ERROR, "ARI ChannelHangupRequest field cause failed validation\n"); + res = 0; + } + } else + if (strcmp("channel", ast_json_object_iter_key(iter)) == 0) { + int prop_is_valid; + has_channel = 1; + prop_is_valid = ari_validate_channel( + ast_json_object_iter_value(iter)); + if (!prop_is_valid) { + ast_log(LOG_ERROR, "ARI ChannelHangupRequest field channel failed validation\n"); + res = 0; + } + } else + if (strcmp("soft", ast_json_object_iter_key(iter)) == 0) { + int prop_is_valid; + prop_is_valid = ari_validate_boolean( + ast_json_object_iter_value(iter)); + if (!prop_is_valid) { + ast_log(LOG_ERROR, "ARI ChannelHangupRequest field soft failed validation\n"); + res = 0; + } + } else + { + ast_log(LOG_ERROR, + "ARI ChannelHangupRequest has undocumented field %s\n", + ast_json_object_iter_key(iter)); + res = 0; + } + } + + if (!has_application) { + ast_log(LOG_ERROR, "ARI ChannelHangupRequest missing required field application\n"); + res = 0; + } + + if (!has_type) { + ast_log(LOG_ERROR, "ARI ChannelHangupRequest missing required field type\n"); + res = 0; + } + + if (!has_channel) { + ast_log(LOG_ERROR, "ARI ChannelHangupRequest missing required field channel\n"); + res = 0; + } + + return res; +} + +int ari_validate_channel_left_bridge(struct ast_json *json) +{ + int res = 1; + struct ast_json_iter *iter; + int has_application = 0; + int has_type = 0; + int has_bridge = 0; + int has_channel = 0; + + for (iter = ast_json_object_iter(json); iter; iter = ast_json_object_iter_next(json, iter)) { + if (strcmp("application", ast_json_object_iter_key(iter)) == 0) { + int prop_is_valid; + has_application = 1; + prop_is_valid = ari_validate_string( + ast_json_object_iter_value(iter)); + if (!prop_is_valid) { + ast_log(LOG_ERROR, "ARI ChannelLeftBridge field application failed validation\n"); + res = 0; + } + } else + if (strcmp("timestamp", ast_json_object_iter_key(iter)) == 0) { + int prop_is_valid; + prop_is_valid = ari_validate_date( + ast_json_object_iter_value(iter)); + if (!prop_is_valid) { + ast_log(LOG_ERROR, "ARI ChannelLeftBridge field timestamp failed validation\n"); + res = 0; + } + } else + if (strcmp("type", ast_json_object_iter_key(iter)) == 0) { + int prop_is_valid; + has_type = 1; + prop_is_valid = ari_validate_string( + ast_json_object_iter_value(iter)); + if (!prop_is_valid) { + ast_log(LOG_ERROR, "ARI ChannelLeftBridge field type failed validation\n"); + res = 0; + } + } else + if (strcmp("bridge", ast_json_object_iter_key(iter)) == 0) { + int prop_is_valid; + has_bridge = 1; + prop_is_valid = ari_validate_bridge( + ast_json_object_iter_value(iter)); + if (!prop_is_valid) { + ast_log(LOG_ERROR, "ARI ChannelLeftBridge field bridge failed validation\n"); + res = 0; + } + } else + if (strcmp("channel", ast_json_object_iter_key(iter)) == 0) { + int prop_is_valid; + has_channel = 1; + prop_is_valid = ari_validate_channel( + ast_json_object_iter_value(iter)); + if (!prop_is_valid) { + ast_log(LOG_ERROR, "ARI ChannelLeftBridge field channel failed validation\n"); + res = 0; + } + } else + { + ast_log(LOG_ERROR, + "ARI ChannelLeftBridge has undocumented field %s\n", + ast_json_object_iter_key(iter)); + res = 0; + } + } + + if (!has_application) { + ast_log(LOG_ERROR, "ARI ChannelLeftBridge missing required field application\n"); + res = 0; + } + + if (!has_type) { + ast_log(LOG_ERROR, "ARI ChannelLeftBridge missing required field type\n"); + res = 0; + } + + if (!has_bridge) { + ast_log(LOG_ERROR, "ARI ChannelLeftBridge missing required field bridge\n"); + res = 0; + } + + if (!has_channel) { + ast_log(LOG_ERROR, "ARI ChannelLeftBridge missing required field channel\n"); + res = 0; + } + + return res; +} + +int ari_validate_channel_state_change(struct ast_json *json) +{ + int res = 1; + struct ast_json_iter *iter; + int has_application = 0; + int has_type = 0; + int has_channel = 0; + + for (iter = ast_json_object_iter(json); iter; iter = ast_json_object_iter_next(json, iter)) { + if (strcmp("application", ast_json_object_iter_key(iter)) == 0) { + int prop_is_valid; + has_application = 1; + prop_is_valid = ari_validate_string( + ast_json_object_iter_value(iter)); + if (!prop_is_valid) { + ast_log(LOG_ERROR, "ARI ChannelStateChange field application failed validation\n"); + res = 0; + } + } else + if (strcmp("timestamp", ast_json_object_iter_key(iter)) == 0) { + int prop_is_valid; + prop_is_valid = ari_validate_date( + ast_json_object_iter_value(iter)); + if (!prop_is_valid) { + ast_log(LOG_ERROR, "ARI ChannelStateChange field timestamp failed validation\n"); + res = 0; + } + } else + if (strcmp("type", ast_json_object_iter_key(iter)) == 0) { + int prop_is_valid; + has_type = 1; + prop_is_valid = ari_validate_string( + ast_json_object_iter_value(iter)); + if (!prop_is_valid) { + ast_log(LOG_ERROR, "ARI ChannelStateChange field type failed validation\n"); + res = 0; + } + } else + if (strcmp("channel", ast_json_object_iter_key(iter)) == 0) { + int prop_is_valid; + has_channel = 1; + prop_is_valid = ari_validate_channel( + ast_json_object_iter_value(iter)); + if (!prop_is_valid) { + ast_log(LOG_ERROR, "ARI ChannelStateChange field channel failed validation\n"); + res = 0; + } + } else + { + ast_log(LOG_ERROR, + "ARI ChannelStateChange has undocumented field %s\n", + ast_json_object_iter_key(iter)); + res = 0; + } + } + + if (!has_application) { + ast_log(LOG_ERROR, "ARI ChannelStateChange missing required field application\n"); + res = 0; + } + + if (!has_type) { + ast_log(LOG_ERROR, "ARI ChannelStateChange missing required field type\n"); + res = 0; + } + + if (!has_channel) { + ast_log(LOG_ERROR, "ARI ChannelStateChange missing required field channel\n"); + res = 0; + } + + return res; +} + +int ari_validate_channel_userevent(struct ast_json *json) +{ + int res = 1; + struct ast_json_iter *iter; + int has_application = 0; + int has_type = 0; + int has_channel = 0; + int has_eventname = 0; + + for (iter = ast_json_object_iter(json); iter; iter = ast_json_object_iter_next(json, iter)) { + if (strcmp("application", ast_json_object_iter_key(iter)) == 0) { + int prop_is_valid; + has_application = 1; + prop_is_valid = ari_validate_string( + ast_json_object_iter_value(iter)); + if (!prop_is_valid) { + ast_log(LOG_ERROR, "ARI ChannelUserevent field application failed validation\n"); + res = 0; + } + } else + if (strcmp("timestamp", ast_json_object_iter_key(iter)) == 0) { + int prop_is_valid; + prop_is_valid = ari_validate_date( + ast_json_object_iter_value(iter)); + if (!prop_is_valid) { + ast_log(LOG_ERROR, "ARI ChannelUserevent field timestamp failed validation\n"); + res = 0; + } + } else + if (strcmp("type", ast_json_object_iter_key(iter)) == 0) { + int prop_is_valid; + has_type = 1; + prop_is_valid = ari_validate_string( + ast_json_object_iter_value(iter)); + if (!prop_is_valid) { + ast_log(LOG_ERROR, "ARI ChannelUserevent field type failed validation\n"); + res = 0; + } + } else + if (strcmp("channel", ast_json_object_iter_key(iter)) == 0) { + int prop_is_valid; + has_channel = 1; + prop_is_valid = ari_validate_channel( + ast_json_object_iter_value(iter)); + if (!prop_is_valid) { + ast_log(LOG_ERROR, "ARI ChannelUserevent field channel failed validation\n"); + res = 0; + } + } else + if (strcmp("eventname", ast_json_object_iter_key(iter)) == 0) { + int prop_is_valid; + has_eventname = 1; + prop_is_valid = ari_validate_string( + ast_json_object_iter_value(iter)); + if (!prop_is_valid) { + ast_log(LOG_ERROR, "ARI ChannelUserevent field eventname failed validation\n"); + res = 0; + } + } else + { + ast_log(LOG_ERROR, + "ARI ChannelUserevent has undocumented field %s\n", + ast_json_object_iter_key(iter)); + res = 0; + } + } + + if (!has_application) { + ast_log(LOG_ERROR, "ARI ChannelUserevent missing required field application\n"); + res = 0; + } + + if (!has_type) { + ast_log(LOG_ERROR, "ARI ChannelUserevent missing required field type\n"); + res = 0; + } + + if (!has_channel) { + ast_log(LOG_ERROR, "ARI ChannelUserevent missing required field channel\n"); + res = 0; + } + + if (!has_eventname) { + ast_log(LOG_ERROR, "ARI ChannelUserevent missing required field eventname\n"); + res = 0; + } + + return res; +} + +int ari_validate_channel_varset(struct ast_json *json) +{ + int res = 1; + struct ast_json_iter *iter; + int has_application = 0; + int has_type = 0; + int has_value = 0; + int has_variable = 0; + + for (iter = ast_json_object_iter(json); iter; iter = ast_json_object_iter_next(json, iter)) { + if (strcmp("application", ast_json_object_iter_key(iter)) == 0) { + int prop_is_valid; + has_application = 1; + prop_is_valid = ari_validate_string( + ast_json_object_iter_value(iter)); + if (!prop_is_valid) { + ast_log(LOG_ERROR, "ARI ChannelVarset field application failed validation\n"); + res = 0; + } + } else + if (strcmp("timestamp", ast_json_object_iter_key(iter)) == 0) { + int prop_is_valid; + prop_is_valid = ari_validate_date( + ast_json_object_iter_value(iter)); + if (!prop_is_valid) { + ast_log(LOG_ERROR, "ARI ChannelVarset field timestamp failed validation\n"); + res = 0; + } + } else + if (strcmp("type", ast_json_object_iter_key(iter)) == 0) { + int prop_is_valid; + has_type = 1; + prop_is_valid = ari_validate_string( + ast_json_object_iter_value(iter)); + if (!prop_is_valid) { + ast_log(LOG_ERROR, "ARI ChannelVarset field type failed validation\n"); + res = 0; + } + } else + if (strcmp("channel", ast_json_object_iter_key(iter)) == 0) { + int prop_is_valid; + prop_is_valid = ari_validate_channel( + ast_json_object_iter_value(iter)); + if (!prop_is_valid) { + ast_log(LOG_ERROR, "ARI ChannelVarset field channel failed validation\n"); + res = 0; + } + } else + if (strcmp("value", ast_json_object_iter_key(iter)) == 0) { + int prop_is_valid; + has_value = 1; + prop_is_valid = ari_validate_string( + ast_json_object_iter_value(iter)); + if (!prop_is_valid) { + ast_log(LOG_ERROR, "ARI ChannelVarset field value failed validation\n"); + res = 0; + } + } else + if (strcmp("variable", ast_json_object_iter_key(iter)) == 0) { + int prop_is_valid; + has_variable = 1; + prop_is_valid = ari_validate_string( + ast_json_object_iter_value(iter)); + if (!prop_is_valid) { + ast_log(LOG_ERROR, "ARI ChannelVarset field variable failed validation\n"); + res = 0; + } + } else + { + ast_log(LOG_ERROR, + "ARI ChannelVarset has undocumented field %s\n", + ast_json_object_iter_key(iter)); + res = 0; + } + } + + if (!has_application) { + ast_log(LOG_ERROR, "ARI ChannelVarset missing required field application\n"); + res = 0; + } + + if (!has_type) { + ast_log(LOG_ERROR, "ARI ChannelVarset missing required field type\n"); + res = 0; + } + + if (!has_value) { + ast_log(LOG_ERROR, "ARI ChannelVarset missing required field value\n"); + res = 0; + } + + if (!has_variable) { + ast_log(LOG_ERROR, "ARI ChannelVarset missing required field variable\n"); + res = 0; + } + + return res; +} + +int ari_validate_event(struct ast_json *json) +{ + int res = 1; + struct ast_json_iter *iter; + int has_application = 0; + int has_type = 0; + const char *discriminator; + + discriminator = ast_json_string_get(ast_json_object_get(json, "type")); + if (!discriminator) { + ast_log(LOG_ERROR, "ARI Event missing required field type"); + return 0; + } + + if (strcmp("Event", discriminator) == 0) { + /* Self type; fall through */ + } else + if (strcmp("ApplicationReplaced", discriminator) == 0) { + return ari_validate_application_replaced(json); + } else + if (strcmp("BridgeCreated", discriminator) == 0) { + return ari_validate_bridge_created(json); + } else + if (strcmp("BridgeDestroyed", discriminator) == 0) { + return ari_validate_bridge_destroyed(json); + } else + if (strcmp("BridgeMerged", discriminator) == 0) { + return ari_validate_bridge_merged(json); + } else + if (strcmp("ChannelCallerId", discriminator) == 0) { + return ari_validate_channel_caller_id(json); + } else + if (strcmp("ChannelCreated", discriminator) == 0) { + return ari_validate_channel_created(json); + } else + if (strcmp("ChannelDestroyed", discriminator) == 0) { + return ari_validate_channel_destroyed(json); + } else + if (strcmp("ChannelDialplan", discriminator) == 0) { + return ari_validate_channel_dialplan(json); + } else + if (strcmp("ChannelDtmfReceived", discriminator) == 0) { + return ari_validate_channel_dtmf_received(json); + } else + if (strcmp("ChannelEnteredBridge", discriminator) == 0) { + return ari_validate_channel_entered_bridge(json); + } else + if (strcmp("ChannelHangupRequest", discriminator) == 0) { + return ari_validate_channel_hangup_request(json); + } else + if (strcmp("ChannelLeftBridge", discriminator) == 0) { + return ari_validate_channel_left_bridge(json); + } else + if (strcmp("ChannelStateChange", discriminator) == 0) { + return ari_validate_channel_state_change(json); + } else + if (strcmp("ChannelUserevent", discriminator) == 0) { + return ari_validate_channel_userevent(json); + } else + if (strcmp("ChannelVarset", discriminator) == 0) { + return ari_validate_channel_varset(json); + } else + if (strcmp("PlaybackFinished", discriminator) == 0) { + return ari_validate_playback_finished(json); + } else + if (strcmp("PlaybackStarted", discriminator) == 0) { + return ari_validate_playback_started(json); + } else + if (strcmp("StasisEnd", discriminator) == 0) { + return ari_validate_stasis_end(json); + } else + if (strcmp("StasisStart", discriminator) == 0) { + return ari_validate_stasis_start(json); + } else + { + ast_log(LOG_ERROR, "ARI Event has undocumented subtype %s\n", + discriminator); + res = 0; + } + + for (iter = ast_json_object_iter(json); iter; iter = ast_json_object_iter_next(json, iter)) { + if (strcmp("application", ast_json_object_iter_key(iter)) == 0) { + int prop_is_valid; + has_application = 1; + prop_is_valid = ari_validate_string( + ast_json_object_iter_value(iter)); + if (!prop_is_valid) { + ast_log(LOG_ERROR, "ARI Event field application failed validation\n"); + res = 0; + } + } else + if (strcmp("timestamp", ast_json_object_iter_key(iter)) == 0) { + int prop_is_valid; + prop_is_valid = ari_validate_date( + ast_json_object_iter_value(iter)); + if (!prop_is_valid) { + ast_log(LOG_ERROR, "ARI Event field timestamp failed validation\n"); + res = 0; + } + } else + if (strcmp("type", ast_json_object_iter_key(iter)) == 0) { + int prop_is_valid; + has_type = 1; + prop_is_valid = ari_validate_string( + ast_json_object_iter_value(iter)); + if (!prop_is_valid) { + ast_log(LOG_ERROR, "ARI Event field type failed validation\n"); + res = 0; + } + } else + { + ast_log(LOG_ERROR, + "ARI Event has undocumented field %s\n", + ast_json_object_iter_key(iter)); + res = 0; + } + } + + if (!has_application) { + ast_log(LOG_ERROR, "ARI Event missing required field application\n"); + res = 0; + } + + if (!has_type) { + ast_log(LOG_ERROR, "ARI Event missing required field type\n"); + res = 0; + } + + return res; +} + +int ari_validate_playback_finished(struct ast_json *json) +{ + int res = 1; + struct ast_json_iter *iter; + int has_application = 0; + int has_type = 0; + int has_playback = 0; + + for (iter = ast_json_object_iter(json); iter; iter = ast_json_object_iter_next(json, iter)) { + if (strcmp("application", ast_json_object_iter_key(iter)) == 0) { + int prop_is_valid; + has_application = 1; + prop_is_valid = ari_validate_string( + ast_json_object_iter_value(iter)); + if (!prop_is_valid) { + ast_log(LOG_ERROR, "ARI PlaybackFinished field application failed validation\n"); + res = 0; + } + } else + if (strcmp("timestamp", ast_json_object_iter_key(iter)) == 0) { + int prop_is_valid; + prop_is_valid = ari_validate_date( + ast_json_object_iter_value(iter)); + if (!prop_is_valid) { + ast_log(LOG_ERROR, "ARI PlaybackFinished field timestamp failed validation\n"); + res = 0; + } + } else + if (strcmp("type", ast_json_object_iter_key(iter)) == 0) { + int prop_is_valid; + has_type = 1; + prop_is_valid = ari_validate_string( + ast_json_object_iter_value(iter)); + if (!prop_is_valid) { + ast_log(LOG_ERROR, "ARI PlaybackFinished field type failed validation\n"); + res = 0; + } + } else + if (strcmp("playback", ast_json_object_iter_key(iter)) == 0) { + int prop_is_valid; + has_playback = 1; + prop_is_valid = ari_validate_playback( + ast_json_object_iter_value(iter)); + if (!prop_is_valid) { + ast_log(LOG_ERROR, "ARI PlaybackFinished field playback failed validation\n"); + res = 0; + } + } else + { + ast_log(LOG_ERROR, + "ARI PlaybackFinished has undocumented field %s\n", + ast_json_object_iter_key(iter)); + res = 0; + } + } + + if (!has_application) { + ast_log(LOG_ERROR, "ARI PlaybackFinished missing required field application\n"); + res = 0; + } + + if (!has_type) { + ast_log(LOG_ERROR, "ARI PlaybackFinished missing required field type\n"); + res = 0; + } + + if (!has_playback) { + ast_log(LOG_ERROR, "ARI PlaybackFinished missing required field playback\n"); + res = 0; + } + + return res; +} + +int ari_validate_playback_started(struct ast_json *json) +{ + int res = 1; + struct ast_json_iter *iter; + int has_application = 0; + int has_type = 0; + int has_playback = 0; + + for (iter = ast_json_object_iter(json); iter; iter = ast_json_object_iter_next(json, iter)) { + if (strcmp("application", ast_json_object_iter_key(iter)) == 0) { + int prop_is_valid; + has_application = 1; + prop_is_valid = ari_validate_string( + ast_json_object_iter_value(iter)); + if (!prop_is_valid) { + ast_log(LOG_ERROR, "ARI PlaybackStarted field application failed validation\n"); + res = 0; + } + } else + if (strcmp("timestamp", ast_json_object_iter_key(iter)) == 0) { + int prop_is_valid; + prop_is_valid = ari_validate_date( + ast_json_object_iter_value(iter)); + if (!prop_is_valid) { + ast_log(LOG_ERROR, "ARI PlaybackStarted field timestamp failed validation\n"); + res = 0; + } + } else + if (strcmp("type", ast_json_object_iter_key(iter)) == 0) { + int prop_is_valid; + has_type = 1; + prop_is_valid = ari_validate_string( + ast_json_object_iter_value(iter)); + if (!prop_is_valid) { + ast_log(LOG_ERROR, "ARI PlaybackStarted field type failed validation\n"); + res = 0; + } + } else + if (strcmp("playback", ast_json_object_iter_key(iter)) == 0) { + int prop_is_valid; + has_playback = 1; + prop_is_valid = ari_validate_playback( + ast_json_object_iter_value(iter)); + if (!prop_is_valid) { + ast_log(LOG_ERROR, "ARI PlaybackStarted field playback failed validation\n"); + res = 0; + } + } else + { + ast_log(LOG_ERROR, + "ARI PlaybackStarted has undocumented field %s\n", + ast_json_object_iter_key(iter)); + res = 0; + } + } + + if (!has_application) { + ast_log(LOG_ERROR, "ARI PlaybackStarted missing required field application\n"); + res = 0; + } + + if (!has_type) { + ast_log(LOG_ERROR, "ARI PlaybackStarted missing required field type\n"); + res = 0; + } + + if (!has_playback) { + ast_log(LOG_ERROR, "ARI PlaybackStarted missing required field playback\n"); + res = 0; + } + + return res; +} + +int ari_validate_stasis_end(struct ast_json *json) +{ + int res = 1; + struct ast_json_iter *iter; + int has_application = 0; + int has_type = 0; + int has_channel = 0; + + for (iter = ast_json_object_iter(json); iter; iter = ast_json_object_iter_next(json, iter)) { + if (strcmp("application", ast_json_object_iter_key(iter)) == 0) { + int prop_is_valid; + has_application = 1; + prop_is_valid = ari_validate_string( + ast_json_object_iter_value(iter)); + if (!prop_is_valid) { + ast_log(LOG_ERROR, "ARI StasisEnd field application failed validation\n"); + res = 0; + } + } else + if (strcmp("timestamp", ast_json_object_iter_key(iter)) == 0) { + int prop_is_valid; + prop_is_valid = ari_validate_date( + ast_json_object_iter_value(iter)); + if (!prop_is_valid) { + ast_log(LOG_ERROR, "ARI StasisEnd field timestamp failed validation\n"); + res = 0; + } + } else + if (strcmp("type", ast_json_object_iter_key(iter)) == 0) { + int prop_is_valid; + has_type = 1; + prop_is_valid = ari_validate_string( + ast_json_object_iter_value(iter)); + if (!prop_is_valid) { + ast_log(LOG_ERROR, "ARI StasisEnd field type failed validation\n"); + res = 0; + } + } else + if (strcmp("channel", ast_json_object_iter_key(iter)) == 0) { + int prop_is_valid; + has_channel = 1; + prop_is_valid = ari_validate_channel( + ast_json_object_iter_value(iter)); + if (!prop_is_valid) { + ast_log(LOG_ERROR, "ARI StasisEnd field channel failed validation\n"); + res = 0; + } + } else + { + ast_log(LOG_ERROR, + "ARI StasisEnd has undocumented field %s\n", + ast_json_object_iter_key(iter)); + res = 0; + } + } + + if (!has_application) { + ast_log(LOG_ERROR, "ARI StasisEnd missing required field application\n"); + res = 0; + } + + if (!has_type) { + ast_log(LOG_ERROR, "ARI StasisEnd missing required field type\n"); + res = 0; + } + + if (!has_channel) { + ast_log(LOG_ERROR, "ARI StasisEnd missing required field channel\n"); + res = 0; + } + + return res; +} + +int ari_validate_stasis_start(struct ast_json *json) +{ + int res = 1; + struct ast_json_iter *iter; + int has_application = 0; + int has_type = 0; + int has_args = 0; + int has_channel = 0; + + for (iter = ast_json_object_iter(json); iter; iter = ast_json_object_iter_next(json, iter)) { + if (strcmp("application", ast_json_object_iter_key(iter)) == 0) { + int prop_is_valid; + has_application = 1; + prop_is_valid = ari_validate_string( + ast_json_object_iter_value(iter)); + if (!prop_is_valid) { + ast_log(LOG_ERROR, "ARI StasisStart field application failed validation\n"); + res = 0; + } + } else + if (strcmp("timestamp", ast_json_object_iter_key(iter)) == 0) { + int prop_is_valid; + prop_is_valid = ari_validate_date( + ast_json_object_iter_value(iter)); + if (!prop_is_valid) { + ast_log(LOG_ERROR, "ARI StasisStart field timestamp failed validation\n"); + res = 0; + } + } else + if (strcmp("type", ast_json_object_iter_key(iter)) == 0) { + int prop_is_valid; + has_type = 1; + prop_is_valid = ari_validate_string( + ast_json_object_iter_value(iter)); + if (!prop_is_valid) { + ast_log(LOG_ERROR, "ARI StasisStart field type failed validation\n"); + res = 0; + } + } else + if (strcmp("args", ast_json_object_iter_key(iter)) == 0) { + int prop_is_valid; + has_args = 1; + prop_is_valid = ari_validate_list( + ast_json_object_iter_value(iter), + ari_validate_string); + if (!prop_is_valid) { + ast_log(LOG_ERROR, "ARI StasisStart field args failed validation\n"); + res = 0; + } + } else + if (strcmp("channel", ast_json_object_iter_key(iter)) == 0) { + int prop_is_valid; + has_channel = 1; + prop_is_valid = ari_validate_channel( + ast_json_object_iter_value(iter)); + if (!prop_is_valid) { + ast_log(LOG_ERROR, "ARI StasisStart field channel failed validation\n"); + res = 0; + } + } else + { + ast_log(LOG_ERROR, + "ARI StasisStart has undocumented field %s\n", + ast_json_object_iter_key(iter)); + res = 0; + } + } + + if (!has_application) { + ast_log(LOG_ERROR, "ARI StasisStart missing required field application\n"); + res = 0; + } + + if (!has_type) { + ast_log(LOG_ERROR, "ARI StasisStart missing required field type\n"); + res = 0; + } + + if (!has_args) { + ast_log(LOG_ERROR, "ARI StasisStart missing required field args\n"); + res = 0; + } + + if (!has_channel) { + ast_log(LOG_ERROR, "ARI StasisStart missing required field channel\n"); + res = 0; + } + + return res; +} diff --git a/res/stasis_http/ari_model_validators.h b/res/stasis_http/ari_model_validators.h new file mode 100644 index 000000000..c4d0f27c2 --- /dev/null +++ b/res/stasis_http/ari_model_validators.h @@ -0,0 +1,659 @@ +/* + * Asterisk -- An open source telephony toolkit. + * + * Copyright (C) 2013, Digium, Inc. + * + * See http://www.asterisk.org for more information about + * the Asterisk project. Please do not directly contact + * any of the maintainers of this project for assistance; + * the project provides a web site, mailing lists and IRC + * channels for your use. + * + * This program is free software, distributed under the terms of + * the GNU General Public License Version 2. See the LICENSE file + * at the top of the source tree. + */ + +/*! \file + * + * \brief Generated file - Build validators for ARI model objects. + */ + + /* + * !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + * !!!!! DO NOT EDIT !!!!! + * !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + * This file is generated by a mustache template. Please see the original + * template in rest-api-templates/ari_model_validators.h.mustache + */ + +#ifndef _ASTERISK_ARI_MODEL_H +#define _ASTERISK_ARI_MODEL_H + +#include "asterisk/json.h" + +/*! @{ */ + +/*! + * \brief Validator for native Swagger void. + * + * \param json JSON object to validate. + * \returns True (non-zero) if valid. + * \returns False (zero) if invalid. + */ +int ari_validate_void(struct ast_json *json); + +/*! + * \brief Validator for native Swagger byte. + * + * \param json JSON object to validate. + * \returns True (non-zero) if valid. + * \returns False (zero) if invalid. + */ +int ari_validate_byte(struct ast_json *json); + +/*! + * \brief Validator for native Swagger boolean. + * + * \param json JSON object to validate. + * \returns True (non-zero) if valid. + * \returns False (zero) if invalid. + */ +int ari_validate_boolean(struct ast_json *json); + +/*! + * \brief Validator for native Swagger int. + * + * \param json JSON object to validate. + * \returns True (non-zero) if valid. + * \returns False (zero) if invalid. + */ +int ari_validate_int(struct ast_json *json); + +/*! + * \brief Validator for native Swagger long. + * + * \param json JSON object to validate. + * \returns True (non-zero) if valid. + * \returns False (zero) if invalid. + */ +int ari_validate_long(struct ast_json *json); + +/*! + * \brief Validator for native Swagger float. + * + * \param json JSON object to validate. + * \returns True (non-zero) if valid. + * \returns False (zero) if invalid. + */ +int ari_validate_float(struct ast_json *json); + +/*! + * \brief Validator for native Swagger double. + * + * \param json JSON object to validate. + * \returns True (non-zero) if valid. + * \returns False (zero) if invalid. + */ +int ari_validate_double(struct ast_json *json); + +/*! + * \brief Validator for native Swagger string. + * + * \param json JSON object to validate. + * \returns True (non-zero) if valid. + * \returns False (zero) if invalid. + */ +int ari_validate_string(struct ast_json *json); + +/*! + * \brief Validator for native Swagger date. + * + * \param json JSON object to validate. + * \returns True (non-zero) if valid. + * \returns False (zero) if invalid. + */ +int ari_validate_date(struct ast_json *json); + +/*! + * \brief Validator for a Swagger List[]/JSON array. + * + * \param json JSON object to validate. + * \param fn Validator to call on every element in the array. + * \returns True (non-zero) if valid. + * \returns False (zero) if invalid. + */ +int ari_validate_list(struct ast_json *json, int (*fn)(struct ast_json *)); + +/*! @} */ + +/*! + * \brief Validator for AsteriskInfo. + * + * Asterisk system information + * + * \param json JSON object to validate. + * \returns True (non-zero) if valid. + * \returns False (zero) if invalid. + */ +int ari_validate_asterisk_info(struct ast_json *json); + +/*! + * \brief Validator for Endpoint. + * + * An external device that may offer/accept calls to/from Asterisk. + * + * Unlike most resources, which have a single unique identifier, an endpoint is uniquely identified by the technology/resource pair. + * + * \param json JSON object to validate. + * \returns True (non-zero) if valid. + * \returns False (zero) if invalid. + */ +int ari_validate_endpoint(struct ast_json *json); + +/*! + * \brief Validator for CallerID. + * + * Caller identification + * + * \param json JSON object to validate. + * \returns True (non-zero) if valid. + * \returns False (zero) if invalid. + */ +int ari_validate_caller_id(struct ast_json *json); + +/*! + * \brief Validator for Channel. + * + * A specific communication connection between Asterisk and an Endpoint. + * + * \param json JSON object to validate. + * \returns True (non-zero) if valid. + * \returns False (zero) if invalid. + */ +int ari_validate_channel(struct ast_json *json); + +/*! + * \brief Validator for Dialed. + * + * Dialed channel information. + * + * \param json JSON object to validate. + * \returns True (non-zero) if valid. + * \returns False (zero) if invalid. + */ +int ari_validate_dialed(struct ast_json *json); + +/*! + * \brief Validator for DialplanCEP. + * + * Dialplan location (context/extension/priority) + * + * \param json JSON object to validate. + * \returns True (non-zero) if valid. + * \returns False (zero) if invalid. + */ +int ari_validate_dialplan_cep(struct ast_json *json); + +/*! + * \brief Validator for Bridge. + * + * The merging of media from one or more channels. + * + * Everyone on the bridge receives the same audio. + * + * \param json JSON object to validate. + * \returns True (non-zero) if valid. + * \returns False (zero) if invalid. + */ +int ari_validate_bridge(struct ast_json *json); + +/*! + * \brief Validator for LiveRecording. + * + * A recording that is in progress + * + * \param json JSON object to validate. + * \returns True (non-zero) if valid. + * \returns False (zero) if invalid. + */ +int ari_validate_live_recording(struct ast_json *json); + +/*! + * \brief Validator for StoredRecording. + * + * A past recording that may be played back. + * + * \param json JSON object to validate. + * \returns True (non-zero) if valid. + * \returns False (zero) if invalid. + */ +int ari_validate_stored_recording(struct ast_json *json); + +/*! + * \brief Validator for FormatLangPair. + * + * Identifies the format and language of a sound file + * + * \param json JSON object to validate. + * \returns True (non-zero) if valid. + * \returns False (zero) if invalid. + */ +int ari_validate_format_lang_pair(struct ast_json *json); + +/*! + * \brief Validator for Sound. + * + * A media file that may be played back. + * + * \param json JSON object to validate. + * \returns True (non-zero) if valid. + * \returns False (zero) if invalid. + */ +int ari_validate_sound(struct ast_json *json); + +/*! + * \brief Validator for Playback. + * + * Object representing the playback of media to a channel + * + * \param json JSON object to validate. + * \returns True (non-zero) if valid. + * \returns False (zero) if invalid. + */ +int ari_validate_playback(struct ast_json *json); + +/*! + * \brief Validator for ApplicationReplaced. + * + * Notification that another WebSocket has taken over for an application. + * + * An application may only be subscribed to by a single WebSocket at a time. If multiple WebSockets attempt to subscribe to the same application, the newer WebSocket wins, and the older one receives this event. + * + * \param json JSON object to validate. + * \returns True (non-zero) if valid. + * \returns False (zero) if invalid. + */ +int ari_validate_application_replaced(struct ast_json *json); + +/*! + * \brief Validator for BridgeCreated. + * + * Notification that a bridge has been created. + * + * \param json JSON object to validate. + * \returns True (non-zero) if valid. + * \returns False (zero) if invalid. + */ +int ari_validate_bridge_created(struct ast_json *json); + +/*! + * \brief Validator for BridgeDestroyed. + * + * Notification that a bridge has been destroyed. + * + * \param json JSON object to validate. + * \returns True (non-zero) if valid. + * \returns False (zero) if invalid. + */ +int ari_validate_bridge_destroyed(struct ast_json *json); + +/*! + * \brief Validator for BridgeMerged. + * + * Notification that one bridge has merged into another. + * + * \param json JSON object to validate. + * \returns True (non-zero) if valid. + * \returns False (zero) if invalid. + */ +int ari_validate_bridge_merged(struct ast_json *json); + +/*! + * \brief Validator for ChannelCallerId. + * + * Channel changed Caller ID. + * + * \param json JSON object to validate. + * \returns True (non-zero) if valid. + * \returns False (zero) if invalid. + */ +int ari_validate_channel_caller_id(struct ast_json *json); + +/*! + * \brief Validator for ChannelCreated. + * + * Notification that a channel has been created. + * + * \param json JSON object to validate. + * \returns True (non-zero) if valid. + * \returns False (zero) if invalid. + */ +int ari_validate_channel_created(struct ast_json *json); + +/*! + * \brief Validator for ChannelDestroyed. + * + * Notification that a channel has been destroyed. + * + * \param json JSON object to validate. + * \returns True (non-zero) if valid. + * \returns False (zero) if invalid. + */ +int ari_validate_channel_destroyed(struct ast_json *json); + +/*! + * \brief Validator for ChannelDialplan. + * + * Channel changed location in the dialplan. + * + * \param json JSON object to validate. + * \returns True (non-zero) if valid. + * \returns False (zero) if invalid. + */ +int ari_validate_channel_dialplan(struct ast_json *json); + +/*! + * \brief Validator for ChannelDtmfReceived. + * + * DTMF received on a channel. + * + * This event is sent when the DTMF ends. There is no notification about the start of DTMF + * + * \param json JSON object to validate. + * \returns True (non-zero) if valid. + * \returns False (zero) if invalid. + */ +int ari_validate_channel_dtmf_received(struct ast_json *json); + +/*! + * \brief Validator for ChannelEnteredBridge. + * + * Notification that a channel has entered a bridge. + * + * \param json JSON object to validate. + * \returns True (non-zero) if valid. + * \returns False (zero) if invalid. + */ +int ari_validate_channel_entered_bridge(struct ast_json *json); + +/*! + * \brief Validator for ChannelHangupRequest. + * + * A hangup was requested on the channel. + * + * \param json JSON object to validate. + * \returns True (non-zero) if valid. + * \returns False (zero) if invalid. + */ +int ari_validate_channel_hangup_request(struct ast_json *json); + +/*! + * \brief Validator for ChannelLeftBridge. + * + * Notification that a channel has left a bridge. + * + * \param json JSON object to validate. + * \returns True (non-zero) if valid. + * \returns False (zero) if invalid. + */ +int ari_validate_channel_left_bridge(struct ast_json *json); + +/*! + * \brief Validator for ChannelStateChange. + * + * Notification of a channel's state change. + * + * \param json JSON object to validate. + * \returns True (non-zero) if valid. + * \returns False (zero) if invalid. + */ +int ari_validate_channel_state_change(struct ast_json *json); + +/*! + * \brief Validator for ChannelUserevent. + * + * User-generated event with additional user-defined fields in the object. + * + * \param json JSON object to validate. + * \returns True (non-zero) if valid. + * \returns False (zero) if invalid. + */ +int ari_validate_channel_userevent(struct ast_json *json); + +/*! + * \brief Validator for ChannelVarset. + * + * Channel variable changed. + * + * \param json JSON object to validate. + * \returns True (non-zero) if valid. + * \returns False (zero) if invalid. + */ +int ari_validate_channel_varset(struct ast_json *json); + +/*! + * \brief Validator for Event. + * + * Base type for asynchronous events from Asterisk. + * + * \param json JSON object to validate. + * \returns True (non-zero) if valid. + * \returns False (zero) if invalid. + */ +int ari_validate_event(struct ast_json *json); + +/*! + * \brief Validator for PlaybackFinished. + * + * Event showing the completion of a media playback operation. + * + * \param json JSON object to validate. + * \returns True (non-zero) if valid. + * \returns False (zero) if invalid. + */ +int ari_validate_playback_finished(struct ast_json *json); + +/*! + * \brief Validator for PlaybackStarted. + * + * Event showing the start of a media playback operation. + * + * \param json JSON object to validate. + * \returns True (non-zero) if valid. + * \returns False (zero) if invalid. + */ +int ari_validate_playback_started(struct ast_json *json); + +/*! + * \brief Validator for StasisEnd. + * + * Notification that a channel has left a Stasis appliction. + * + * \param json JSON object to validate. + * \returns True (non-zero) if valid. + * \returns False (zero) if invalid. + */ +int ari_validate_stasis_end(struct ast_json *json); + +/*! + * \brief Validator for StasisStart. + * + * Notification that a channel has entered a Stasis appliction. + * + * \param json JSON object to validate. + * \returns True (non-zero) if valid. + * \returns False (zero) if invalid. + */ +int ari_validate_stasis_start(struct ast_json *json); + +/* + * JSON models + * + * AsteriskInfo + * Endpoint + * - channel_ids: List[string] (required) + * - resource: string (required) + * - state: string + * - technology: string (required) + * CallerID + * - name: string (required) + * - number: string (required) + * Channel + * - accountcode: string (required) + * - caller: CallerID (required) + * - connected: CallerID (required) + * - creationtime: Date (required) + * - dialplan: DialplanCEP (required) + * - id: string (required) + * - name: string (required) + * - state: string (required) + * Dialed + * DialplanCEP + * - context: string (required) + * - exten: string (required) + * - priority: long (required) + * Bridge + * - bridge_class: string (required) + * - bridge_type: string (required) + * - channels: List[string] (required) + * - id: string (required) + * - technology: string (required) + * LiveRecording + * - id: string (required) + * StoredRecording + * - duration_seconds: int + * - formats: List[string] (required) + * - id: string (required) + * - time: Date + * FormatLangPair + * - format: string (required) + * - language: string (required) + * Sound + * - formats: List[FormatLangPair] (required) + * - id: string (required) + * - text: string + * Playback + * - id: string (required) + * - language: string + * - media_uri: string (required) + * - state: string (required) + * - target_uri: string (required) + * ApplicationReplaced + * - application: string (required) + * - timestamp: Date + * - type: string (required) + * BridgeCreated + * - application: string (required) + * - timestamp: Date + * - type: string (required) + * - bridge: Bridge (required) + * BridgeDestroyed + * - application: string (required) + * - timestamp: Date + * - type: string (required) + * - bridge: Bridge (required) + * BridgeMerged + * - application: string (required) + * - timestamp: Date + * - type: string (required) + * - bridge: Bridge (required) + * - bridge_from: Bridge (required) + * ChannelCallerId + * - application: string (required) + * - timestamp: Date + * - type: string (required) + * - caller_presentation: int (required) + * - caller_presentation_txt: string (required) + * - channel: Channel (required) + * ChannelCreated + * - application: string (required) + * - timestamp: Date + * - type: string (required) + * - channel: Channel (required) + * ChannelDestroyed + * - application: string (required) + * - timestamp: Date + * - type: string (required) + * - cause: int (required) + * - cause_txt: string (required) + * - channel: Channel (required) + * ChannelDialplan + * - application: string (required) + * - timestamp: Date + * - type: string (required) + * - channel: Channel (required) + * - dialplan_app: string (required) + * - dialplan_app_data: string (required) + * ChannelDtmfReceived + * - application: string (required) + * - timestamp: Date + * - type: string (required) + * - channel: Channel (required) + * - digit: string (required) + * - duration_ms: int (required) + * ChannelEnteredBridge + * - application: string (required) + * - timestamp: Date + * - type: string (required) + * - bridge: Bridge (required) + * - channel: Channel + * ChannelHangupRequest + * - application: string (required) + * - timestamp: Date + * - type: string (required) + * - cause: int + * - channel: Channel (required) + * - soft: boolean + * ChannelLeftBridge + * - application: string (required) + * - timestamp: Date + * - type: string (required) + * - bridge: Bridge (required) + * - channel: Channel (required) + * ChannelStateChange + * - application: string (required) + * - timestamp: Date + * - type: string (required) + * - channel: Channel (required) + * ChannelUserevent + * - application: string (required) + * - timestamp: Date + * - type: string (required) + * - channel: Channel (required) + * - eventname: string (required) + * ChannelVarset + * - application: string (required) + * - timestamp: Date + * - type: string (required) + * - channel: Channel + * - value: string (required) + * - variable: string (required) + * Event + * - application: string (required) + * - timestamp: Date + * - type: string (required) + * PlaybackFinished + * - application: string (required) + * - timestamp: Date + * - type: string (required) + * - playback: Playback (required) + * PlaybackStarted + * - application: string (required) + * - timestamp: Date + * - type: string (required) + * - playback: Playback (required) + * StasisEnd + * - application: string (required) + * - timestamp: Date + * - type: string (required) + * - channel: Channel (required) + * StasisStart + * - application: string (required) + * - timestamp: Date + * - type: string (required) + * - args: List[string] (required) + * - channel: Channel (required) + */ + +#endif /* _ASTERISK_ARI_MODEL_H */ diff --git a/res/stasis_http/ari_websockets.c b/res/stasis_http/ari_websockets.c index e6b316b57..60a184657 100644 --- a/res/stasis_http/ari_websockets.c +++ b/res/stasis_http/ari_websockets.c @@ -31,6 +31,7 @@ ASTERISK_FILE_VERSION(__FILE__, "$Revision$") struct ari_websocket_session { struct ast_websocket *ws_session; + int (*validator)(struct ast_json *); }; static void websocket_session_dtor(void *obj) @@ -41,8 +42,16 @@ static void websocket_session_dtor(void *obj) session->ws_session = NULL; } +/*! + * \brief Validator that always succeeds. + */ +static int null_validator(struct ast_json *json) +{ + return 1; +} + struct ari_websocket_session *ari_websocket_session_create( - struct ast_websocket *ws_session) + struct ast_websocket *ws_session, int (*validator)(struct ast_json *)) { RAII_VAR(struct ari_websocket_session *, session, NULL, ao2_cleanup); @@ -50,6 +59,10 @@ struct ari_websocket_session *ari_websocket_session_create( return NULL; } + if (validator == NULL) { + validator = null_validator; + } + if (ast_websocket_set_nonblock(ws_session) != 0) { ast_log(LOG_ERROR, "Stasis web socket failed to set nonblock; closing\n"); @@ -63,6 +76,7 @@ struct ari_websocket_session *ari_websocket_session_create( ao2_ref(ws_session, +1); session->ws_session = ws_session; + session->validator = validator; ao2_ref(session, +1); return session; @@ -109,10 +123,24 @@ struct ast_json *ari_websocket_session_read( return ast_json_ref(message); } +#define VALIDATION_FAILED \ + "{ \"error\": \"Outgoing message failed validation\" }" + int ari_websocket_session_write(struct ari_websocket_session *session, struct ast_json *message) { - RAII_VAR(char *, str, ast_json_dump_string(message), ast_free); + RAII_VAR(char *, str, NULL, ast_free); + +#ifdef AST_DEVMODE + if (!session->validator(message)) { + ast_log(LOG_ERROR, "Outgoing message failed validation\n"); + return ast_websocket_write(session->ws_session, + AST_WEBSOCKET_OPCODE_TEXT, VALIDATION_FAILED, + strlen(VALIDATION_FAILED)); + } +#endif + + str = ast_json_dump_string_format(message, stasis_http_json_format()); if (str == NULL) { ast_log(LOG_ERROR, "Failed to encode JSON object\n"); diff --git a/res/stasis_http/resource_recordings.c b/res/stasis_http/resource_recordings.c index 2400a6876..7d31c42aa 100644 --- a/res/stasis_http/resource_recordings.c +++ b/res/stasis_http/resource_recordings.c @@ -29,10 +29,6 @@ ASTERISK_FILE_VERSION(__FILE__, "$Revision$") #include "resource_recordings.h" -void stasis_http_get_recordings(struct ast_variable *headers, struct ast_get_recordings_args *args, struct stasis_http_response *response) -{ - ast_log(LOG_ERROR, "TODO: stasis_http_get_recordings\n"); -} void stasis_http_get_stored_recordings(struct ast_variable *headers, struct ast_get_stored_recordings_args *args, struct stasis_http_response *response) { ast_log(LOG_ERROR, "TODO: stasis_http_get_stored_recordings\n"); diff --git a/res/stasis_http/resource_recordings.h b/res/stasis_http/resource_recordings.h index ee48e43b7..acccc124b 100644 --- a/res/stasis_http/resource_recordings.h +++ b/res/stasis_http/resource_recordings.h @@ -39,17 +39,6 @@ #include "asterisk/stasis_http.h" -/*! \brief Argument struct for stasis_http_get_recordings() */ -struct ast_get_recordings_args { -}; -/*! - * \brief List all recordings. - * - * \param headers HTTP headers - * \param args Swagger parameters - * \param[out] response HTTP response - */ -void stasis_http_get_recordings(struct ast_variable *headers, struct ast_get_recordings_args *args, struct stasis_http_response *response); /*! \brief Argument struct for stasis_http_get_stored_recordings() */ struct ast_get_stored_recordings_args { }; diff --git a/res/stasis_json/resource_asterisk.h b/res/stasis_json/resource_asterisk.h deleted file mode 100644 index 5a717d005..000000000 --- a/res/stasis_json/resource_asterisk.h +++ /dev/null @@ -1,46 +0,0 @@ -/* - * Asterisk -- An open source telephony toolkit. - * - * Copyright (C) 2012 - 2013, Digium, Inc. - * - * David M. Lee, II <dlee@digium.com> - * - * See http://www.asterisk.org for more information about - * the Asterisk project. Please do not directly contact - * any of the maintainers of this project for assistance; - * the project provides a web site, mailing lists and IRC - * channels for your use. - * - * This program is free software, distributed under the terms of - * the GNU General Public License Version 2. See the LICENSE file - * at the top of the source tree. - */ - -/*! \file - * - * \brief Generated file - declares stubs to be implemented in - * res/stasis_json/resource_asterisk.c - * - * Asterisk resources - * - * \author David M. Lee, II <dlee@digium.com> - */ - -/* - * !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! - * !!!!! DO NOT EDIT !!!!! - * !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! - * This file is generated by a mustache template. Please see the original - * template in rest-api-templates/stasis_http_resource.h.mustache - */ - -#ifndef _ASTERISK_RESOURCE_ASTERISK_H -#define _ASTERISK_RESOURCE_ASTERISK_H - -/* - * JSON models - * - * AsteriskInfo - */ - -#endif /* _ASTERISK_RESOURCE_ASTERISK_H */ diff --git a/res/stasis_json/resource_bridges.h b/res/stasis_json/resource_bridges.h deleted file mode 100644 index cf2d03dc7..000000000 --- a/res/stasis_json/resource_bridges.h +++ /dev/null @@ -1,48 +0,0 @@ -/* - * Asterisk -- An open source telephony toolkit. - * - * Copyright (C) 2012 - 2013, Digium, Inc. - * - * David M. Lee, II <dlee@digium.com> - * - * See http://www.asterisk.org for more information about - * the Asterisk project. Please do not directly contact - * any of the maintainers of this project for assistance; - * the project provides a web site, mailing lists and IRC - * channels for your use. - * - * This program is free software, distributed under the terms of - * the GNU General Public License Version 2. See the LICENSE file - * at the top of the source tree. - */ - -/*! \file - * - * \brief Generated file - declares stubs to be implemented in - * res/stasis_json/resource_bridges.c - * - * Bridge resources - * - * \author David M. Lee, II <dlee@digium.com> - */ - -/* - * !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! - * !!!!! DO NOT EDIT !!!!! - * !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! - * This file is generated by a mustache template. Please see the original - * template in rest-api-templates/stasis_http_resource.h.mustache - */ - -#ifndef _ASTERISK_RESOURCE_BRIDGES_H -#define _ASTERISK_RESOURCE_BRIDGES_H - -/* - * JSON models - * - * Bridge - * - channels: List[string] (required) - * - bridgeType: string (required) - */ - -#endif /* _ASTERISK_RESOURCE_BRIDGES_H */ diff --git a/res/stasis_json/resource_channels.h b/res/stasis_json/resource_channels.h deleted file mode 100644 index c98743c36..000000000 --- a/res/stasis_json/resource_channels.h +++ /dev/null @@ -1,75 +0,0 @@ -/* - * Asterisk -- An open source telephony toolkit. - * - * Copyright (C) 2012 - 2013, Digium, Inc. - * - * David M. Lee, II <dlee@digium.com> - * - * See http://www.asterisk.org for more information about - * the Asterisk project. Please do not directly contact - * any of the maintainers of this project for assistance; - * the project provides a web site, mailing lists and IRC - * channels for your use. - * - * This program is free software, distributed under the terms of - * the GNU General Public License Version 2. See the LICENSE file - * at the top of the source tree. - */ - -/*! \file - * - * \brief Generated file - declares stubs to be implemented in - * res/stasis_json/resource_channels.c - * - * Channel resources - * - * \author David M. Lee, II <dlee@digium.com> - */ - -/* - * !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! - * !!!!! DO NOT EDIT !!!!! - * !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! - * This file is generated by a mustache template. Please see the original - * template in rest-api-templates/stasis_http_resource.h.mustache - */ - -#ifndef _ASTERISK_RESOURCE_CHANNELS_H -#define _ASTERISK_RESOURCE_CHANNELS_H - -/* - * JSON models - * - * DialplanCEP - * - priority: long (required) - * - exten: string (required) - * - context: string (required) - * Playback - * - language: string - * - media_uri: string (required) - * - id: string (required) - * - target_uri: string (required) - * - state: string (required) - * Channel - * - accountcode: string (required) - * - linkedid: string (required) - * - name: string (required) - * - userfield: string (required) - * - caller: CallerID (required) - * - creationtime: Date (required) - * - state: string (required) - * - parkinglot: string (required) - * - peeraccount: string (required) - * - appl: string (required) - * - connected: CallerID (required) - * - uniqueid: string (required) - * - hangupsource: string (required) - * - dialplan: DialplanCEP (required) - * - data: string (required) - * CallerID - * - name: string (required) - * - number: string (required) - * Dialed - */ - -#endif /* _ASTERISK_RESOURCE_CHANNELS_H */ diff --git a/res/stasis_json/resource_endpoints.h b/res/stasis_json/resource_endpoints.h deleted file mode 100644 index 7f2e4233c..000000000 --- a/res/stasis_json/resource_endpoints.h +++ /dev/null @@ -1,48 +0,0 @@ -/* - * Asterisk -- An open source telephony toolkit. - * - * Copyright (C) 2012 - 2013, Digium, Inc. - * - * David M. Lee, II <dlee@digium.com> - * - * See http://www.asterisk.org for more information about - * the Asterisk project. Please do not directly contact - * any of the maintainers of this project for assistance; - * the project provides a web site, mailing lists and IRC - * channels for your use. - * - * This program is free software, distributed under the terms of - * the GNU General Public License Version 2. See the LICENSE file - * at the top of the source tree. - */ - -/*! \file - * - * \brief Generated file - declares stubs to be implemented in - * res/stasis_json/resource_endpoints.c - * - * Endpoint resources - * - * \author David M. Lee, II <dlee@digium.com> - */ - -/* - * !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! - * !!!!! DO NOT EDIT !!!!! - * !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! - * This file is generated by a mustache template. Please see the original - * template in rest-api-templates/stasis_http_resource.h.mustache - */ - -#ifndef _ASTERISK_RESOURCE_ENDPOINTS_H -#define _ASTERISK_RESOURCE_ENDPOINTS_H - -/* - * JSON models - * - * Endpoint - * - resource: string (required) - * - technology: string (required) - */ - -#endif /* _ASTERISK_RESOURCE_ENDPOINTS_H */ diff --git a/res/stasis_json/resource_events.h b/res/stasis_json/resource_events.h deleted file mode 100644 index a2af30daa..000000000 --- a/res/stasis_json/resource_events.h +++ /dev/null @@ -1,386 +0,0 @@ -/* - * Asterisk -- An open source telephony toolkit. - * - * Copyright (C) 2012 - 2013, Digium, Inc. - * - * David M. Lee, II <dlee@digium.com> - * - * See http://www.asterisk.org for more information about - * the Asterisk project. Please do not directly contact - * any of the maintainers of this project for assistance; - * the project provides a web site, mailing lists and IRC - * channels for your use. - * - * This program is free software, distributed under the terms of - * the GNU General Public License Version 2. See the LICENSE file - * at the top of the source tree. - */ - -/*! \file - * - * \brief Generated file - declares stubs to be implemented in - * res/stasis_json/resource_events.c - * - * WebSocket resource - * - * \author David M. Lee, II <dlee@digium.com> - */ - -/* - * !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! - * !!!!! DO NOT EDIT !!!!! - * !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! - * This file is generated by a mustache template. Please see the original - * template in rest-api-templates/stasis_http_resource.h.mustache - */ - -#ifndef _ASTERISK_RESOURCE_EVENTS_H -#define _ASTERISK_RESOURCE_EVENTS_H - -struct ast_channel_snapshot; -struct ast_bridge_snapshot; - -/*! - * \brief User-generated event with additional user-defined fields in the object. - * - * \param channel The channel that signaled the user event. - * \param blob JSON blob containing the following parameters: - * - eventname: string - The name of the user event. (required) - * - * \retval NULL on error - * \retval JSON (ast_json) describing the event - */ -struct ast_json *stasis_json_event_channel_userevent_create( - struct ast_channel_snapshot *channel_snapshot, - struct ast_json *blob - ); - -/*! - * \brief Notification that a bridge has been created. - * - * \param bridge The bridge to be used to generate this event - * - * \retval NULL on error - * \retval JSON (ast_json) describing the event - */ -struct ast_json *stasis_json_event_bridge_created_create( - struct ast_bridge_snapshot *bridge_snapshot - ); - -/*! - * \brief Event showing the completion of a media playback operation. - * - * \param blob JSON blob containing the following parameters: - * - playback: Playback - Playback control object (required) - * - * \retval NULL on error - * \retval JSON (ast_json) describing the event - */ -struct ast_json *stasis_json_event_playback_finished_create( - struct ast_json *blob - ); - -/*! - * \brief Some part of channel state changed. - * - * \param channel The channel to be used to generate this event - * - * \retval NULL on error - * \retval JSON (ast_json) describing the event - */ -struct ast_json *stasis_json_event_channel_snapshot_create( - struct ast_channel_snapshot *channel_snapshot - ); - -/*! - * \brief Channel changed Caller ID. - * - * \param channel The channel that changed Caller ID. - * \param blob JSON blob containing the following parameters: - * - caller_presentation_txt: string - The text representation of the Caller Presentation value. (required) - * - caller_presentation: integer - The integer representation of the Caller Presentation value. (required) - * - * \retval NULL on error - * \retval JSON (ast_json) describing the event - */ -struct ast_json *stasis_json_event_channel_caller_id_create( - struct ast_channel_snapshot *channel_snapshot, - struct ast_json *blob - ); - -/*! - * \brief Event showing the start of a media playback operation. - * - * \param blob JSON blob containing the following parameters: - * - playback: Playback - Playback control object (required) - * - * \retval NULL on error - * \retval JSON (ast_json) describing the event - */ -struct ast_json *stasis_json_event_playback_started_create( - struct ast_json *blob - ); - -/*! - * \brief Channel variable changed. - * - * \param channel The channel on which the variable was set. - * \param blob JSON blob containing the following parameters: - * - variable: string - The variable that changed. (required) - * - value: string - The new value of the variable. (required) - * - * \retval NULL on error - * \retval JSON (ast_json) describing the event - */ -struct ast_json *stasis_json_event_channel_varset_create( - struct ast_channel_snapshot *channel_snapshot, - struct ast_json *blob - ); - -/*! - * \brief Notification that a bridge has been destroyed. - * - * \param bridge The bridge to be used to generate this event - * - * \retval NULL on error - * \retval JSON (ast_json) describing the event - */ -struct ast_json *stasis_json_event_bridge_destroyed_create( - struct ast_bridge_snapshot *bridge_snapshot - ); - -/*! - * \brief Notification that another WebSocket has taken over for an application. - * - * \param blob JSON blob containing the following parameters: - * - application: string (required) - * - * \retval NULL on error - * \retval JSON (ast_json) describing the event - */ -struct ast_json *stasis_json_event_application_replaced_create( - struct ast_json *blob - ); - -/*! - * \brief Notification that a channel has been destroyed. - * - * \param channel The channel to be used to generate this event - * \param blob JSON blob containing the following parameters: - * - cause: integer - Integer representation of the cause of the hangup (required) - * - cause_txt: string - Text representation of the cause of the hangup (required) - * - * \retval NULL on error - * \retval JSON (ast_json) describing the event - */ -struct ast_json *stasis_json_event_channel_destroyed_create( - struct ast_channel_snapshot *channel_snapshot, - struct ast_json *blob - ); - -/*! - * \brief Notification that one bridge has merged into another. - * - * \param bridge The bridge to be used to generate this event - * \param blob JSON blob containing the following parameters: - * - bridge_from: Bridge (required) - * - * \retval NULL on error - * \retval JSON (ast_json) describing the event - */ -struct ast_json *stasis_json_event_bridge_merged_create( - struct ast_bridge_snapshot *bridge_snapshot, - struct ast_json *blob - ); - -/*! - * \brief Notification that a channel has left a bridge. - * - * \param channel The channel to be used to generate this event - * \param bridge The bridge to be used to generate this event - * - * \retval NULL on error - * \retval JSON (ast_json) describing the event - */ -struct ast_json *stasis_json_event_channel_left_bridge_create( - struct ast_bridge_snapshot *bridge_snapshot, - struct ast_channel_snapshot *channel_snapshot - ); - -/*! - * \brief Notification that a channel has been created. - * - * \param channel The channel to be used to generate this event - * - * \retval NULL on error - * \retval JSON (ast_json) describing the event - */ -struct ast_json *stasis_json_event_channel_created_create( - struct ast_channel_snapshot *channel_snapshot - ); - -/*! - * \brief Notification that a channel has entered a Stasis appliction. - * - * \param channel The channel to be used to generate this event - * \param blob JSON blob containing the following parameters: - * - args: List[string] - Arguments to the application (required) - * - * \retval NULL on error - * \retval JSON (ast_json) describing the event - */ -struct ast_json *stasis_json_event_stasis_start_create( - struct ast_channel_snapshot *channel_snapshot, - struct ast_json *blob - ); - -/*! - * \brief Channel changed location in the dialplan. - * - * \param channel The channel that changed dialplan location. - * \param blob JSON blob containing the following parameters: - * - application: string - The application that the channel is currently in. (required) - * - application_data: string - The data that was passed to the application when it was invoked. (required) - * - * \retval NULL on error - * \retval JSON (ast_json) describing the event - */ -struct ast_json *stasis_json_event_channel_dialplan_create( - struct ast_channel_snapshot *channel_snapshot, - struct ast_json *blob - ); - -/*! - * \brief Notification of a channel's state change. - * - * \param channel The channel to be used to generate this event - * - * \retval NULL on error - * \retval JSON (ast_json) describing the event - */ -struct ast_json *stasis_json_event_channel_state_change_create( - struct ast_channel_snapshot *channel_snapshot - ); - -/*! - * \brief A hangup was requested on the channel. - * - * \param channel The channel on which the hangup was requested. - * \param blob JSON blob containing the following parameters: - * - soft: boolean - Whether the hangup request was a soft hangup request. - * - cause: integer - Integer representation of the cause of the hangup. - * - * \retval NULL on error - * \retval JSON (ast_json) describing the event - */ -struct ast_json *stasis_json_event_channel_hangup_request_create( - struct ast_channel_snapshot *channel_snapshot, - struct ast_json *blob - ); - -/*! - * \brief Notification that a channel has entered a bridge. - * - * \param channel The channel to be used to generate this event - * \param bridge The bridge to be used to generate this event - * - * \retval NULL on error - * \retval JSON (ast_json) describing the event - */ -struct ast_json *stasis_json_event_channel_entered_bridge_create( - struct ast_bridge_snapshot *bridge_snapshot, - struct ast_channel_snapshot *channel_snapshot - ); - -/*! - * \brief DTMF received on a channel. - * - * \param channel The channel on which DTMF was received - * \param blob JSON blob containing the following parameters: - * - digit: string - DTMF digit received (0-9, A-E, # or *) (required) - * - * \retval NULL on error - * \retval JSON (ast_json) describing the event - */ -struct ast_json *stasis_json_event_channel_dtmf_received_create( - struct ast_channel_snapshot *channel_snapshot, - struct ast_json *blob - ); - -/*! - * \brief Notification that a channel has left a Stasis appliction. - * - * \param channel The channel to be used to generate this event - * - * \retval NULL on error - * \retval JSON (ast_json) describing the event - */ -struct ast_json *stasis_json_event_stasis_end_create( - struct ast_channel_snapshot *channel_snapshot - ); - -/* - * JSON models - * - * ChannelUserevent - * - eventname: string (required) - * BridgeCreated - * PlaybackFinished - * - playback: Playback (required) - * ChannelSnapshot - * ChannelCallerId - * - caller_presentation_txt: string (required) - * - caller_presentation: integer (required) - * PlaybackStarted - * - playback: Playback (required) - * ChannelVarset - * - variable: string (required) - * - value: string (required) - * BridgeDestroyed - * ApplicationReplaced - * - application: string (required) - * ChannelDestroyed - * - cause: integer (required) - * - cause_txt: string (required) - * BridgeMerged - * - bridge_from: Bridge (required) - * ChannelLeftBridge - * ChannelCreated - * StasisStart - * - args: List[string] (required) - * ChannelDialplan - * - application: string (required) - * - application_data: string (required) - * ChannelStateChange - * ChannelHangupRequest - * - soft: boolean - * - cause: integer - * ChannelEnteredBridge - * ChannelDtmfReceived - * - digit: string (required) - * Event - * - channel_varset: ChannelVarset - * - channel_created: ChannelCreated - * - channel_destroyed: ChannelDestroyed - * - channel_entered_bridge: ChannelEnteredBridge - * - channel_left_bridge: ChannelLeftBridge - * - bridge_merged: BridgeMerged - * - channel_dialplan: ChannelDialplan - * - application_replaced: ApplicationReplaced - * - channel_state_change: ChannelStateChange - * - bridge_created: BridgeCreated - * - application: string (required) - * - channel_hangup_request: ChannelHangupRequest - * - channel_userevent: ChannelUserevent - * - stasis_start: StasisStart - * - channel_snapshot: ChannelSnapshot - * - channel_dtmf_received: ChannelDtmfReceived - * - channel_caller_id: ChannelCallerId - * - bridge_destroyed: BridgeDestroyed - * - playback_started: PlaybackStarted - * - playback_finished: PlaybackFinished - * - stasis_end: StasisEnd - * StasisEnd - */ - -#endif /* _ASTERISK_RESOURCE_EVENTS_H */ diff --git a/res/stasis_json/resource_playback.h b/res/stasis_json/resource_playback.h deleted file mode 100644 index e84e6de0d..000000000 --- a/res/stasis_json/resource_playback.h +++ /dev/null @@ -1,47 +0,0 @@ -/* - * Asterisk -- An open source telephony toolkit. - * - * Copyright (C) 2012 - 2013, Digium, Inc. - * - * David M. Lee, II <dlee@digium.com> - * - * See http://www.asterisk.org for more information about - * the Asterisk project. Please do not directly contact - * any of the maintainers of this project for assistance; - * the project provides a web site, mailing lists and IRC - * channels for your use. - * - * This program is free software, distributed under the terms of - * the GNU General Public License Version 2. See the LICENSE file - * at the top of the source tree. - */ - -/*! \file - * - * \brief Generated file - declares stubs to be implemented in - * res/stasis_json/resource_playback.c - * - * Playback control resources - * - * \author David M. Lee, II <dlee@digium.com> - */ - -/* - * !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! - * !!!!! DO NOT EDIT !!!!! - * !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! - * This file is generated by a mustache template. Please see the original - * template in rest-api-templates/stasis_http_resource.h.mustache - */ - -#ifndef _ASTERISK_RESOURCE_PLAYBACK_H -#define _ASTERISK_RESOURCE_PLAYBACK_H - -/* - * JSON models - * - * Playback - * - id: string (required) - */ - -#endif /* _ASTERISK_RESOURCE_PLAYBACK_H */ diff --git a/res/stasis_json/resource_recordings.h b/res/stasis_json/resource_recordings.h deleted file mode 100644 index b460fb769..000000000 --- a/res/stasis_json/resource_recordings.h +++ /dev/null @@ -1,54 +0,0 @@ -/* - * Asterisk -- An open source telephony toolkit. - * - * Copyright (C) 2012 - 2013, Digium, Inc. - * - * David M. Lee, II <dlee@digium.com> - * - * See http://www.asterisk.org for more information about - * the Asterisk project. Please do not directly contact - * any of the maintainers of this project for assistance; - * the project provides a web site, mailing lists and IRC - * channels for your use. - * - * This program is free software, distributed under the terms of - * the GNU General Public License Version 2. See the LICENSE file - * at the top of the source tree. - */ - -/*! \file - * - * \brief Generated file - declares stubs to be implemented in - * res/stasis_json/resource_recordings.c - * - * Recording resources - * - * \author David M. Lee, II <dlee@digium.com> - */ - -/* - * !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! - * !!!!! DO NOT EDIT !!!!! - * !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! - * This file is generated by a mustache template. Please see the original - * template in rest-api-templates/stasis_http_resource.h.mustache - */ - -#ifndef _ASTERISK_RESOURCE_RECORDINGS_H -#define _ASTERISK_RESOURCE_RECORDINGS_H - -/* - * JSON models - * - * Recording - * - id: string (required) - * StoredRecording - * - durationSeconds: int - * - time: Date - * - id: string (required) - * - formats: List[string] (required) - * LiveRecording - * - id: string (required) - */ - -#endif /* _ASTERISK_RESOURCE_RECORDINGS_H */ diff --git a/res/stasis_json/resource_sounds.h b/res/stasis_json/resource_sounds.h deleted file mode 100644 index d7f8714e6..000000000 --- a/res/stasis_json/resource_sounds.h +++ /dev/null @@ -1,52 +0,0 @@ -/* - * Asterisk -- An open source telephony toolkit. - * - * Copyright (C) 2012 - 2013, Digium, Inc. - * - * David M. Lee, II <dlee@digium.com> - * - * See http://www.asterisk.org for more information about - * the Asterisk project. Please do not directly contact - * any of the maintainers of this project for assistance; - * the project provides a web site, mailing lists and IRC - * channels for your use. - * - * This program is free software, distributed under the terms of - * the GNU General Public License Version 2. See the LICENSE file - * at the top of the source tree. - */ - -/*! \file - * - * \brief Generated file - declares stubs to be implemented in - * res/stasis_json/resource_sounds.c - * - * Sound resources - * - * \author David M. Lee, II <dlee@digium.com> - */ - -/* - * !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! - * !!!!! DO NOT EDIT !!!!! - * !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! - * This file is generated by a mustache template. Please see the original - * template in rest-api-templates/stasis_http_resource.h.mustache - */ - -#ifndef _ASTERISK_RESOURCE_SOUNDS_H -#define _ASTERISK_RESOURCE_SOUNDS_H - -/* - * JSON models - * - * Sound - * - text: string - * - id: string (required) - * - formats: List[FormatLangPair] (required) - * FormatLangPair - * - language: string (required) - * - format: string (required) - */ - -#endif /* _ASTERISK_RESOURCE_SOUNDS_H */ |