summaryrefslogtreecommitdiff
path: root/res
diff options
context:
space:
mode:
Diffstat (limited to 'res')
-rw-r--r--res/Makefile3
-rw-r--r--res/res_ari_model.c207
-rw-r--r--res/res_ari_model.exports.in6
-rw-r--r--res/res_stasis.c294
-rw-r--r--res/res_stasis_http.c21
-rw-r--r--res/res_stasis_http_asterisk.c35
-rw-r--r--res/res_stasis_http_bridges.c232
-rw-r--r--res/res_stasis_http_channels.c439
-rw-r--r--res/res_stasis_http_endpoints.c99
-rw-r--r--res/res_stasis_http_events.c10
-rw-r--r--res/res_stasis_http_playback.c102
-rw-r--r--res/res_stasis_http_recordings.c370
-rw-r--r--res/res_stasis_http_sounds.c67
-rw-r--r--res/res_stasis_json_asterisk.c59
-rw-r--r--res/res_stasis_json_asterisk.exports.in4
-rw-r--r--res/res_stasis_json_bridges.c59
-rw-r--r--res/res_stasis_json_bridges.exports.in4
-rw-r--r--res/res_stasis_json_channels.c59
-rw-r--r--res/res_stasis_json_channels.exports.in4
-rw-r--r--res/res_stasis_json_endpoints.c59
-rw-r--r--res/res_stasis_json_endpoints.exports.in4
-rw-r--r--res/res_stasis_json_events.c818
-rw-r--r--res/res_stasis_json_events.exports.in25
-rw-r--r--res/res_stasis_json_playback.c59
-rw-r--r--res/res_stasis_json_playback.exports.in4
-rw-r--r--res/res_stasis_json_recordings.c59
-rw-r--r--res/res_stasis_json_recordings.exports.in4
-rw-r--r--res/res_stasis_json_sounds.c59
-rw-r--r--res/res_stasis_json_sounds.exports.in4
-rw-r--r--res/stasis_http/ari_model_validators.c2567
-rw-r--r--res/stasis_http/ari_model_validators.h659
-rw-r--r--res/stasis_http/ari_websockets.c32
-rw-r--r--res/stasis_http/resource_recordings.c4
-rw-r--r--res/stasis_http/resource_recordings.h11
-rw-r--r--res/stasis_json/resource_asterisk.h46
-rw-r--r--res/stasis_json/resource_bridges.h48
-rw-r--r--res/stasis_json/resource_channels.h75
-rw-r--r--res/stasis_json/resource_endpoints.h48
-rw-r--r--res/stasis_json/resource_events.h386
-rw-r--r--res/stasis_json/resource_playback.h47
-rw-r--r--res/stasis_json/resource_recordings.h54
-rw-r--r--res/stasis_json/resource_sounds.h52
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 */