summaryrefslogtreecommitdiff
path: root/res
diff options
context:
space:
mode:
authorJoshua Colp <jcolp@digium.com>2013-12-14 17:19:41 +0000
committerJoshua Colp <jcolp@digium.com>2013-12-14 17:19:41 +0000
commit3a5cc054ed3efb0733a70a6945880b71506b5757 (patch)
tree2435f375316c92c0009d51bb9ee1bc12e7ea0810 /res
parent661ac149115dd23c421c1445a1d07f92249db243 (diff)
res_stasis: Expose event for call forwarding and follow forwarded channel.
This change adds an event for when an originated call is redirected to another target. This event contains the original channel and the newly created channel. If a stasis subscription exists on the original originated channel for a stasis application then a new subscription will also be created on the stasis application to the redirected channel. This allows the application to follow the call path completely. (closes issue ASTERISK-22719) Reported by: Joshua Colp Review: https://reviewboard.asterisk.org/r/3054/ ........ Merged revisions 403808 from http://svn.asterisk.org/svn/asterisk/branches/12 git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@403810 65c4cc65-6c06-0410-ace0-fbb531ad65f3
Diffstat (limited to 'res')
-rw-r--r--res/ari/ari_model_validators.c137
-rw-r--r--res/ari/ari_model_validators.h28
-rw-r--r--res/stasis/app.c23
3 files changed, 188 insertions, 0 deletions
diff --git a/res/ari/ari_model_validators.c b/res/ari/ari_model_validators.c
index 7ddef278d..d99240bd8 100644
--- a/res/ari/ari_model_validators.c
+++ b/res/ari/ari_model_validators.c
@@ -2879,6 +2879,137 @@ ari_validator ast_ari_validate_device_state_changed_fn(void)
return ast_ari_validate_device_state_changed;
}
+int ast_ari_validate_dial(struct ast_json *json)
+{
+ int res = 1;
+ struct ast_json_iter *iter;
+ int has_type = 0;
+ int has_application = 0;
+ int has_dialstatus = 0;
+ int has_peer = 0;
+
+ for (iter = ast_json_object_iter(json); iter; iter = ast_json_object_iter_next(json, iter)) {
+ if (strcmp("type", ast_json_object_iter_key(iter)) == 0) {
+ int prop_is_valid;
+ has_type = 1;
+ prop_is_valid = ast_ari_validate_string(
+ ast_json_object_iter_value(iter));
+ if (!prop_is_valid) {
+ ast_log(LOG_ERROR, "ARI Dial field type failed validation\n");
+ res = 0;
+ }
+ } else
+ if (strcmp("application", ast_json_object_iter_key(iter)) == 0) {
+ int prop_is_valid;
+ has_application = 1;
+ prop_is_valid = ast_ari_validate_string(
+ ast_json_object_iter_value(iter));
+ if (!prop_is_valid) {
+ ast_log(LOG_ERROR, "ARI Dial 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 = ast_ari_validate_date(
+ ast_json_object_iter_value(iter));
+ if (!prop_is_valid) {
+ ast_log(LOG_ERROR, "ARI Dial field timestamp failed validation\n");
+ res = 0;
+ }
+ } else
+ if (strcmp("caller", ast_json_object_iter_key(iter)) == 0) {
+ int prop_is_valid;
+ prop_is_valid = ast_ari_validate_channel(
+ ast_json_object_iter_value(iter));
+ if (!prop_is_valid) {
+ ast_log(LOG_ERROR, "ARI Dial field caller failed validation\n");
+ res = 0;
+ }
+ } else
+ if (strcmp("dialstatus", ast_json_object_iter_key(iter)) == 0) {
+ int prop_is_valid;
+ has_dialstatus = 1;
+ prop_is_valid = ast_ari_validate_string(
+ ast_json_object_iter_value(iter));
+ if (!prop_is_valid) {
+ ast_log(LOG_ERROR, "ARI Dial field dialstatus failed validation\n");
+ res = 0;
+ }
+ } else
+ if (strcmp("dialstring", ast_json_object_iter_key(iter)) == 0) {
+ int prop_is_valid;
+ prop_is_valid = ast_ari_validate_string(
+ ast_json_object_iter_value(iter));
+ if (!prop_is_valid) {
+ ast_log(LOG_ERROR, "ARI Dial field dialstring failed validation\n");
+ res = 0;
+ }
+ } else
+ if (strcmp("forward", ast_json_object_iter_key(iter)) == 0) {
+ int prop_is_valid;
+ prop_is_valid = ast_ari_validate_string(
+ ast_json_object_iter_value(iter));
+ if (!prop_is_valid) {
+ ast_log(LOG_ERROR, "ARI Dial field forward failed validation\n");
+ res = 0;
+ }
+ } else
+ if (strcmp("forwarded", ast_json_object_iter_key(iter)) == 0) {
+ int prop_is_valid;
+ prop_is_valid = ast_ari_validate_channel(
+ ast_json_object_iter_value(iter));
+ if (!prop_is_valid) {
+ ast_log(LOG_ERROR, "ARI Dial field forwarded failed validation\n");
+ res = 0;
+ }
+ } else
+ if (strcmp("peer", ast_json_object_iter_key(iter)) == 0) {
+ int prop_is_valid;
+ has_peer = 1;
+ prop_is_valid = ast_ari_validate_channel(
+ ast_json_object_iter_value(iter));
+ if (!prop_is_valid) {
+ ast_log(LOG_ERROR, "ARI Dial field peer failed validation\n");
+ res = 0;
+ }
+ } else
+ {
+ ast_log(LOG_ERROR,
+ "ARI Dial has undocumented field %s\n",
+ ast_json_object_iter_key(iter));
+ res = 0;
+ }
+ }
+
+ if (!has_type) {
+ ast_log(LOG_ERROR, "ARI Dial missing required field type\n");
+ res = 0;
+ }
+
+ if (!has_application) {
+ ast_log(LOG_ERROR, "ARI Dial missing required field application\n");
+ res = 0;
+ }
+
+ if (!has_dialstatus) {
+ ast_log(LOG_ERROR, "ARI Dial missing required field dialstatus\n");
+ res = 0;
+ }
+
+ if (!has_peer) {
+ ast_log(LOG_ERROR, "ARI Dial missing required field peer\n");
+ res = 0;
+ }
+
+ return res;
+}
+
+ari_validator ast_ari_validate_dial_fn(void)
+{
+ return ast_ari_validate_dial;
+}
+
int ast_ari_validate_endpoint_state_change(struct ast_json *json)
{
int res = 1;
@@ -3023,6 +3154,9 @@ int ast_ari_validate_event(struct ast_json *json)
if (strcmp("DeviceStateChanged", discriminator) == 0) {
return ast_ari_validate_device_state_changed(json);
} else
+ if (strcmp("Dial", discriminator) == 0) {
+ return ast_ari_validate_dial(json);
+ } else
if (strcmp("EndpointStateChange", discriminator) == 0) {
return ast_ari_validate_endpoint_state_change(json);
} else
@@ -3173,6 +3307,9 @@ int ast_ari_validate_message(struct ast_json *json)
if (strcmp("DeviceStateChanged", discriminator) == 0) {
return ast_ari_validate_device_state_changed(json);
} else
+ if (strcmp("Dial", discriminator) == 0) {
+ return ast_ari_validate_dial(json);
+ } else
if (strcmp("EndpointStateChange", discriminator) == 0) {
return ast_ari_validate_endpoint_state_change(json);
} else
diff --git a/res/ari/ari_model_validators.h b/res/ari/ari_model_validators.h
index 1f9420cb0..22ab43be8 100644
--- a/res/ari/ari_model_validators.h
+++ b/res/ari/ari_model_validators.h
@@ -791,6 +791,24 @@ int ast_ari_validate_device_state_changed(struct ast_json *json);
ari_validator ast_ari_validate_device_state_changed_fn(void);
/*!
+ * \brief Validator for Dial.
+ *
+ * Dialing state has changed.
+ *
+ * \param json JSON object to validate.
+ * \returns True (non-zero) if valid.
+ * \returns False (zero) if invalid.
+ */
+int ast_ari_validate_dial(struct ast_json *json);
+
+/*!
+ * \brief Function pointer to ast_ari_validate_dial().
+ *
+ * See \ref ast_ari_model_validators.h for more details.
+ */
+ari_validator ast_ari_validate_dial_fn(void);
+
+/*!
* \brief Validator for EndpointStateChange.
*
* Endpoint state changed.
@@ -1187,6 +1205,16 @@ ari_validator ast_ari_validate_application_fn(void);
* - application: string (required)
* - timestamp: Date
* - device_state: DeviceState (required)
+ * Dial
+ * - type: string (required)
+ * - application: string (required)
+ * - timestamp: Date
+ * - caller: Channel
+ * - dialstatus: string (required)
+ * - dialstring: string
+ * - forward: string
+ * - forwarded: Channel
+ * - peer: Channel (required)
* EndpointStateChange
* - type: string (required)
* - application: string (required)
diff --git a/res/stasis/app.c b/res/stasis/app.c
index 8ad41e565..8e9872aec 100644
--- a/res/stasis/app.c
+++ b/res/stasis/app.c
@@ -265,6 +265,25 @@ static void app_dtor(void *obj)
app->data = NULL;
}
+static void call_forwarded_handler(struct stasis_app *app, struct stasis_message *message)
+{
+ struct ast_multi_channel_blob *payload = stasis_message_data(message);
+ struct ast_channel_snapshot *snapshot = ast_multi_channel_blob_get_channel(payload, "forwarded");
+ struct ast_channel *chan;
+
+ if (!snapshot) {
+ return;
+ }
+
+ chan = ast_channel_get_by_name(snapshot->uniqueid);
+ if (!chan) {
+ return;
+ }
+
+ app_subscribe_channel(app, chan);
+ ast_channel_unref(chan);
+}
+
static void sub_default_handler(void *data, struct stasis_subscription *sub,
struct stasis_message *message)
{
@@ -275,6 +294,10 @@ static void sub_default_handler(void *data, struct stasis_subscription *sub,
ao2_cleanup(app);
}
+ if (stasis_message_type(message) == ast_channel_dial_type()) {
+ call_forwarded_handler(app, message);
+ }
+
/* By default, send any message that has a JSON representation */
json = stasis_message_to_json(message, stasis_app_get_sanitizer());
if (!json) {