summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--CHANGES20
-rw-r--r--main/stasis_endpoints.c78
-rw-r--r--res/ari/ari_model_validators.c359
-rw-r--r--res/ari/ari_model_validators.h95
-rw-r--r--rest-api-templates/ari_model_validators.c.mustache2
-rw-r--r--rest-api/api-docs/events.json99
6 files changed, 641 insertions, 12 deletions
diff --git a/CHANGES b/CHANGES
index 8c8329cb0..9d599f432 100644
--- a/CHANGES
+++ b/CHANGES
@@ -189,6 +189,26 @@ Dialplan Functions
return the SIP Call-ID associated with the INVITE request that established
the PJSIP channel.
+ARI
+------------------
+ * Two new endpoint related events are now available: PeerStatusChange and
+ ContactStatusChange. In particular, these events are useful when subscribing
+ to all event sources, as they provide additional endpoint related
+ information beyond the addition/removal of channels from an endpoint.
+
+ * Added the ability to subscribe to all ARI events in Asterisk, regardless
+ of whether the application 'controls' the resource. This is useful for
+ scenarios where an ARI application merely wants to observe the system,
+ as opposed to control it. There are two ways to accomplish this:
+ (1) Via the WebSocket connection URI. A new query paramter, 'subscribeAll',
+ has been added that, when present and True, will subscribe all
+ specified applications to all ARI event sources in Asterisk.
+ (2) Via the applications resource. An ARI client can, at any time, subscribe
+ to all resources in an event source merely by not providing an explicit
+ resource. For example, subscribing to an event source of 'channels:'
+ as opposed to 'channels:12345' will subscribe the application to all
+ channels.
+
------------------------------------------------------------------------------
--- Functionality changes from Asterisk 13.4.0 to Asterisk 13.5.0 ------------
------------------------------------------------------------------------------
diff --git a/main/stasis_endpoints.c b/main/stasis_endpoints.c
index da6505355..f44ce4229 100644
--- a/main/stasis_endpoints.c
+++ b/main/stasis_endpoints.c
@@ -124,12 +124,7 @@ struct stasis_topic *ast_endpoint_topic_all_cached(void)
return stasis_cp_all_topic_cached(endpoint_cache_all);
}
-static struct ast_manager_event_blob *peerstatus_to_ami(struct stasis_message *msg);
-
STASIS_MESSAGE_TYPE_DEFN(ast_endpoint_snapshot_type);
-STASIS_MESSAGE_TYPE_DEFN(ast_endpoint_state_type,
- .to_ami = peerstatus_to_ami,
-);
static struct ast_manager_event_blob *peerstatus_to_ami(struct stasis_message *msg)
{
@@ -166,10 +161,44 @@ static struct ast_manager_event_blob *peerstatus_to_ami(struct stasis_message *m
ast_str_buffer(peerstatus_event_string));
}
-static struct ast_manager_event_blob *contactstatus_to_ami(struct stasis_message *msg);
+static struct ast_json *peerstatus_to_json(struct stasis_message *msg, const struct stasis_message_sanitizer *sanitize)
+{
+ struct ast_endpoint_blob *obj = stasis_message_data(msg);
+ struct ast_json *json_endpoint;
+ struct ast_json *json_peer;
+ struct ast_json *json_final;
+ const struct timeval *tv = stasis_message_timestamp(msg);
-STASIS_MESSAGE_TYPE_DEFN(ast_endpoint_contact_state_type,
- .to_ami = contactstatus_to_ami,
+ json_endpoint = ast_endpoint_snapshot_to_json(obj->snapshot, NULL);
+ if (!json_endpoint) {
+ return NULL;
+ }
+
+ json_peer = ast_json_object_create();
+ if (!json_peer) {
+ ast_json_unref(json_endpoint);
+ return NULL;
+ }
+
+ /* Copy all fields from the blob */
+ ast_json_object_update(json_peer, obj->blob);
+
+ json_final = ast_json_pack("{s: s, s: o, s: o, s: o }",
+ "type", "PeerStatusChange",
+ "timestamp", ast_json_timeval(*tv, NULL),
+ "endpoint", json_endpoint,
+ "peer", json_peer);
+ if (!json_final) {
+ ast_json_unref(json_endpoint);
+ ast_json_unref(json_peer);
+ }
+
+ return json_final;
+}
+
+STASIS_MESSAGE_TYPE_DEFN(ast_endpoint_state_type,
+ .to_ami = peerstatus_to_ami,
+ .to_json = peerstatus_to_json,
);
static struct ast_manager_event_blob *contactstatus_to_ami(struct stasis_message *msg)
@@ -206,6 +235,39 @@ static struct ast_manager_event_blob *contactstatus_to_ami(struct stasis_message
"%s", ast_str_buffer(contactstatus_event_string));
}
+static struct ast_json *contactstatus_to_json(struct stasis_message *msg, const struct stasis_message_sanitizer *sanitize)
+{
+ struct ast_endpoint_blob *obj = stasis_message_data(msg);
+ struct ast_json *json_endpoint;
+ struct ast_json *json_final;
+ const struct timeval *tv = stasis_message_timestamp(msg);
+
+ json_endpoint = ast_endpoint_snapshot_to_json(obj->snapshot, NULL);
+ if (!json_endpoint) {
+ return NULL;
+ }
+
+ json_final = ast_json_pack("{s: s, s: o, s: o, s: { s: s, s: s, s: s } } ",
+ "type", "ContactStatusChange",
+ "timestamp", ast_json_timeval(*tv, NULL),
+ "endpoint", json_endpoint,
+ "contact_info",
+ "uri", ast_json_string_get(ast_json_object_get(obj->blob, "uri")),
+ "contact_status", ast_json_string_get(ast_json_object_get(obj->blob, "contact_status")),
+ "aor", ast_json_string_get(ast_json_object_get(obj->blob, "aor")),
+ "roundtrip_usec", ast_json_string_get(ast_json_object_get(obj->blob, "roundtrip_usec")));
+ if (!json_final) {
+ ast_json_unref(json_endpoint);
+ }
+
+ return json_final;
+}
+
+STASIS_MESSAGE_TYPE_DEFN(ast_endpoint_contact_state_type,
+ .to_ami = contactstatus_to_ami,
+ .to_json = contactstatus_to_json
+);
+
static void endpoint_blob_dtor(void *obj)
{
struct ast_endpoint_blob *event = obj;
diff --git a/res/ari/ari_model_validators.c b/res/ari/ari_model_validators.c
index 0a5c7606f..623d5b541 100644
--- a/res/ari/ari_model_validators.c
+++ b/res/ari/ari_model_validators.c
@@ -4180,6 +4180,180 @@ ari_validator ast_ari_validate_channel_varset_fn(void)
return ast_ari_validate_channel_varset;
}
+int ast_ari_validate_contact_info(struct ast_json *json)
+{
+ int res = 1;
+ struct ast_json_iter *iter;
+ int has_aor = 0;
+ int has_contact_status = 0;
+ int has_uri = 0;
+
+ for (iter = ast_json_object_iter(json); iter; iter = ast_json_object_iter_next(json, iter)) {
+ if (strcmp("aor", ast_json_object_iter_key(iter)) == 0) {
+ int prop_is_valid;
+ has_aor = 1;
+ prop_is_valid = ast_ari_validate_string(
+ ast_json_object_iter_value(iter));
+ if (!prop_is_valid) {
+ ast_log(LOG_ERROR, "ARI ContactInfo field aor failed validation\n");
+ res = 0;
+ }
+ } else
+ if (strcmp("contact_status", ast_json_object_iter_key(iter)) == 0) {
+ int prop_is_valid;
+ has_contact_status = 1;
+ prop_is_valid = ast_ari_validate_string(
+ ast_json_object_iter_value(iter));
+ if (!prop_is_valid) {
+ ast_log(LOG_ERROR, "ARI ContactInfo field contact_status failed validation\n");
+ res = 0;
+ }
+ } else
+ if (strcmp("roundtrip_usec", 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 ContactInfo field roundtrip_usec failed validation\n");
+ res = 0;
+ }
+ } else
+ if (strcmp("uri", ast_json_object_iter_key(iter)) == 0) {
+ int prop_is_valid;
+ has_uri = 1;
+ prop_is_valid = ast_ari_validate_string(
+ ast_json_object_iter_value(iter));
+ if (!prop_is_valid) {
+ ast_log(LOG_ERROR, "ARI ContactInfo field uri failed validation\n");
+ res = 0;
+ }
+ } else
+ {
+ ast_log(LOG_ERROR,
+ "ARI ContactInfo has undocumented field %s\n",
+ ast_json_object_iter_key(iter));
+ res = 0;
+ }
+ }
+
+ if (!has_aor) {
+ ast_log(LOG_ERROR, "ARI ContactInfo missing required field aor\n");
+ res = 0;
+ }
+
+ if (!has_contact_status) {
+ ast_log(LOG_ERROR, "ARI ContactInfo missing required field contact_status\n");
+ res = 0;
+ }
+
+ if (!has_uri) {
+ ast_log(LOG_ERROR, "ARI ContactInfo missing required field uri\n");
+ res = 0;
+ }
+
+ return res;
+}
+
+ari_validator ast_ari_validate_contact_info_fn(void)
+{
+ return ast_ari_validate_contact_info;
+}
+
+int ast_ari_validate_contact_status_change(struct ast_json *json)
+{
+ int res = 1;
+ struct ast_json_iter *iter;
+ int has_type = 0;
+ int has_application = 0;
+ int has_contact_info = 0;
+ int has_endpoint = 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 ContactStatusChange 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 ContactStatusChange 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 ContactStatusChange field timestamp failed validation\n");
+ res = 0;
+ }
+ } else
+ if (strcmp("contact_info", ast_json_object_iter_key(iter)) == 0) {
+ int prop_is_valid;
+ has_contact_info = 1;
+ prop_is_valid = ast_ari_validate_contact_info(
+ ast_json_object_iter_value(iter));
+ if (!prop_is_valid) {
+ ast_log(LOG_ERROR, "ARI ContactStatusChange field contact_info failed validation\n");
+ res = 0;
+ }
+ } else
+ if (strcmp("endpoint", ast_json_object_iter_key(iter)) == 0) {
+ int prop_is_valid;
+ has_endpoint = 1;
+ prop_is_valid = ast_ari_validate_endpoint(
+ ast_json_object_iter_value(iter));
+ if (!prop_is_valid) {
+ ast_log(LOG_ERROR, "ARI ContactStatusChange field endpoint failed validation\n");
+ res = 0;
+ }
+ } else
+ {
+ ast_log(LOG_ERROR,
+ "ARI ContactStatusChange has undocumented field %s\n",
+ ast_json_object_iter_key(iter));
+ res = 0;
+ }
+ }
+
+ if (!has_type) {
+ ast_log(LOG_ERROR, "ARI ContactStatusChange missing required field type\n");
+ res = 0;
+ }
+
+ if (!has_application) {
+ ast_log(LOG_ERROR, "ARI ContactStatusChange missing required field application\n");
+ res = 0;
+ }
+
+ if (!has_contact_info) {
+ ast_log(LOG_ERROR, "ARI ContactStatusChange missing required field contact_info\n");
+ res = 0;
+ }
+
+ if (!has_endpoint) {
+ ast_log(LOG_ERROR, "ARI ContactStatusChange missing required field endpoint\n");
+ res = 0;
+ }
+
+ return res;
+}
+
+ari_validator ast_ari_validate_contact_status_change_fn(void)
+{
+ return ast_ari_validate_contact_status_change;
+}
+
int ast_ari_validate_device_state_changed(struct ast_json *json)
{
int res = 1;
@@ -4479,7 +4653,7 @@ int ast_ari_validate_event(struct ast_json *json)
discriminator = ast_json_string_get(ast_json_object_get(json, "type"));
if (!discriminator) {
- ast_log(LOG_ERROR, "ARI Event missing required field type");
+ ast_log(LOG_ERROR, "ARI Event missing required field type\n");
return 0;
}
@@ -4552,6 +4726,9 @@ int ast_ari_validate_event(struct ast_json *json)
if (strcmp("ChannelVarset", discriminator) == 0) {
return ast_ari_validate_channel_varset(json);
} else
+ if (strcmp("ContactStatusChange", discriminator) == 0) {
+ return ast_ari_validate_contact_status_change(json);
+ } else
if (strcmp("DeviceStateChanged", discriminator) == 0) {
return ast_ari_validate_device_state_changed(json);
} else
@@ -4561,6 +4738,9 @@ int ast_ari_validate_event(struct ast_json *json)
if (strcmp("EndpointStateChange", discriminator) == 0) {
return ast_ari_validate_endpoint_state_change(json);
} else
+ if (strcmp("PeerStatusChange", discriminator) == 0) {
+ return ast_ari_validate_peer_status_change(json);
+ } else
if (strcmp("PlaybackFinished", discriminator) == 0) {
return ast_ari_validate_playback_finished(json);
} else
@@ -4656,7 +4836,7 @@ int ast_ari_validate_message(struct ast_json *json)
discriminator = ast_json_string_get(ast_json_object_get(json, "type"));
if (!discriminator) {
- ast_log(LOG_ERROR, "ARI Message missing required field type");
+ ast_log(LOG_ERROR, "ARI Message missing required field type\n");
return 0;
}
@@ -4729,6 +4909,9 @@ int ast_ari_validate_message(struct ast_json *json)
if (strcmp("ChannelVarset", discriminator) == 0) {
return ast_ari_validate_channel_varset(json);
} else
+ if (strcmp("ContactStatusChange", discriminator) == 0) {
+ return ast_ari_validate_contact_status_change(json);
+ } else
if (strcmp("DeviceStateChanged", discriminator) == 0) {
return ast_ari_validate_device_state_changed(json);
} else
@@ -4744,6 +4927,9 @@ int ast_ari_validate_message(struct ast_json *json)
if (strcmp("MissingParams", discriminator) == 0) {
return ast_ari_validate_missing_params(json);
} else
+ if (strcmp("PeerStatusChange", discriminator) == 0) {
+ return ast_ari_validate_peer_status_change(json);
+ } else
if (strcmp("PlaybackFinished", discriminator) == 0) {
return ast_ari_validate_playback_finished(json);
} else
@@ -4861,6 +5047,175 @@ ari_validator ast_ari_validate_missing_params_fn(void)
return ast_ari_validate_missing_params;
}
+int ast_ari_validate_peer(struct ast_json *json)
+{
+ int res = 1;
+ struct ast_json_iter *iter;
+ int has_peer_status = 0;
+
+ for (iter = ast_json_object_iter(json); iter; iter = ast_json_object_iter_next(json, iter)) {
+ if (strcmp("address", 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 Peer field address failed validation\n");
+ res = 0;
+ }
+ } else
+ if (strcmp("cause", 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 Peer field cause failed validation\n");
+ res = 0;
+ }
+ } else
+ if (strcmp("peer_status", ast_json_object_iter_key(iter)) == 0) {
+ int prop_is_valid;
+ has_peer_status = 1;
+ prop_is_valid = ast_ari_validate_string(
+ ast_json_object_iter_value(iter));
+ if (!prop_is_valid) {
+ ast_log(LOG_ERROR, "ARI Peer field peer_status failed validation\n");
+ res = 0;
+ }
+ } else
+ if (strcmp("port", 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 Peer field port failed validation\n");
+ res = 0;
+ }
+ } else
+ if (strcmp("time", 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 Peer field time failed validation\n");
+ res = 0;
+ }
+ } else
+ {
+ ast_log(LOG_ERROR,
+ "ARI Peer has undocumented field %s\n",
+ ast_json_object_iter_key(iter));
+ res = 0;
+ }
+ }
+
+ if (!has_peer_status) {
+ ast_log(LOG_ERROR, "ARI Peer missing required field peer_status\n");
+ res = 0;
+ }
+
+ return res;
+}
+
+ari_validator ast_ari_validate_peer_fn(void)
+{
+ return ast_ari_validate_peer;
+}
+
+int ast_ari_validate_peer_status_change(struct ast_json *json)
+{
+ int res = 1;
+ struct ast_json_iter *iter;
+ int has_type = 0;
+ int has_application = 0;
+ int has_endpoint = 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 PeerStatusChange 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 PeerStatusChange 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 PeerStatusChange field timestamp failed validation\n");
+ res = 0;
+ }
+ } else
+ if (strcmp("endpoint", ast_json_object_iter_key(iter)) == 0) {
+ int prop_is_valid;
+ has_endpoint = 1;
+ prop_is_valid = ast_ari_validate_endpoint(
+ ast_json_object_iter_value(iter));
+ if (!prop_is_valid) {
+ ast_log(LOG_ERROR, "ARI PeerStatusChange field endpoint 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_peer(
+ ast_json_object_iter_value(iter));
+ if (!prop_is_valid) {
+ ast_log(LOG_ERROR, "ARI PeerStatusChange field peer failed validation\n");
+ res = 0;
+ }
+ } else
+ {
+ ast_log(LOG_ERROR,
+ "ARI PeerStatusChange has undocumented field %s\n",
+ ast_json_object_iter_key(iter));
+ res = 0;
+ }
+ }
+
+ if (!has_type) {
+ ast_log(LOG_ERROR, "ARI PeerStatusChange missing required field type\n");
+ res = 0;
+ }
+
+ if (!has_application) {
+ ast_log(LOG_ERROR, "ARI PeerStatusChange missing required field application\n");
+ res = 0;
+ }
+
+ if (!has_endpoint) {
+ ast_log(LOG_ERROR, "ARI PeerStatusChange missing required field endpoint\n");
+ res = 0;
+ }
+
+ if (!has_peer) {
+ ast_log(LOG_ERROR, "ARI PeerStatusChange missing required field peer\n");
+ res = 0;
+ }
+
+ return res;
+}
+
+ari_validator ast_ari_validate_peer_status_change_fn(void)
+{
+ return ast_ari_validate_peer_status_change;
+}
+
int ast_ari_validate_playback_finished(struct ast_json *json)
{
int res = 1;
diff --git a/res/ari/ari_model_validators.h b/res/ari/ari_model_validators.h
index 1803f57c9..0bcdb0fa2 100644
--- a/res/ari/ari_model_validators.h
+++ b/res/ari/ari_model_validators.h
@@ -1007,6 +1007,42 @@ int ast_ari_validate_channel_varset(struct ast_json *json);
ari_validator ast_ari_validate_channel_varset_fn(void);
/*!
+ * \brief Validator for ContactInfo.
+ *
+ * Detailed information about a contact on an endpoint.
+ *
+ * \param json JSON object to validate.
+ * \returns True (non-zero) if valid.
+ * \returns False (zero) if invalid.
+ */
+int ast_ari_validate_contact_info(struct ast_json *json);
+
+/*!
+ * \brief Function pointer to ast_ari_validate_contact_info().
+ *
+ * See \ref ast_ari_model_validators.h for more details.
+ */
+ari_validator ast_ari_validate_contact_info_fn(void);
+
+/*!
+ * \brief Validator for ContactStatusChange.
+ *
+ * The state of a contact on an endpoint has changed.
+ *
+ * \param json JSON object to validate.
+ * \returns True (non-zero) if valid.
+ * \returns False (zero) if invalid.
+ */
+int ast_ari_validate_contact_status_change(struct ast_json *json);
+
+/*!
+ * \brief Function pointer to ast_ari_validate_contact_status_change().
+ *
+ * See \ref ast_ari_model_validators.h for more details.
+ */
+ari_validator ast_ari_validate_contact_status_change_fn(void);
+
+/*!
* \brief Validator for DeviceStateChanged.
*
* Notification that a device state has changed.
@@ -1115,6 +1151,42 @@ int ast_ari_validate_missing_params(struct ast_json *json);
ari_validator ast_ari_validate_missing_params_fn(void);
/*!
+ * \brief Validator for Peer.
+ *
+ * Detailed information about a remote peer that communicates with Asterisk.
+ *
+ * \param json JSON object to validate.
+ * \returns True (non-zero) if valid.
+ * \returns False (zero) if invalid.
+ */
+int ast_ari_validate_peer(struct ast_json *json);
+
+/*!
+ * \brief Function pointer to ast_ari_validate_peer().
+ *
+ * See \ref ast_ari_model_validators.h for more details.
+ */
+ari_validator ast_ari_validate_peer_fn(void);
+
+/*!
+ * \brief Validator for PeerStatusChange.
+ *
+ * The state of a peer associated with an endpoint has changed.
+ *
+ * \param json JSON object to validate.
+ * \returns True (non-zero) if valid.
+ * \returns False (zero) if invalid.
+ */
+int ast_ari_validate_peer_status_change(struct ast_json *json);
+
+/*!
+ * \brief Function pointer to ast_ari_validate_peer_status_change().
+ *
+ * See \ref ast_ari_model_validators.h for more details.
+ */
+ari_validator ast_ari_validate_peer_status_change_fn(void);
+
+/*!
* \brief Validator for PlaybackFinished.
*
* Event showing the completion of a media playback operation.
@@ -1546,6 +1618,17 @@ ari_validator ast_ari_validate_application_fn(void);
* - channel: Channel
* - value: string (required)
* - variable: string (required)
+ * ContactInfo
+ * - aor: string (required)
+ * - contact_status: string (required)
+ * - roundtrip_usec: string
+ * - uri: string (required)
+ * ContactStatusChange
+ * - type: string (required)
+ * - application: string (required)
+ * - timestamp: Date
+ * - contact_info: ContactInfo (required)
+ * - endpoint: Endpoint (required)
* DeviceStateChanged
* - type: string (required)
* - application: string (required)
@@ -1575,6 +1658,18 @@ ari_validator ast_ari_validate_application_fn(void);
* MissingParams
* - type: string (required)
* - params: List[string] (required)
+ * Peer
+ * - address: string
+ * - cause: string
+ * - peer_status: string (required)
+ * - port: string
+ * - time: string
+ * PeerStatusChange
+ * - type: string (required)
+ * - application: string (required)
+ * - timestamp: Date
+ * - endpoint: Endpoint (required)
+ * - peer: Peer (required)
* PlaybackFinished
* - type: string (required)
* - application: string (required)
diff --git a/rest-api-templates/ari_model_validators.c.mustache b/rest-api-templates/ari_model_validators.c.mustache
index 0ca3d26ca..78f19bf66 100644
--- a/rest-api-templates/ari_model_validators.c.mustache
+++ b/rest-api-templates/ari_model_validators.c.mustache
@@ -50,7 +50,7 @@ int ast_ari_validate_{{c_id}}(struct ast_json *json)
discriminator = ast_json_string_get(ast_json_object_get(json, "{{discriminator.name}}"));
if (!discriminator) {
- ast_log(LOG_ERROR, "ARI {{id}} missing required field {{discriminator.name}}");
+ ast_log(LOG_ERROR, "ARI {{id}} missing required field {{discriminator.name}}\n");
return 0;
}
diff --git a/rest-api/api-docs/events.json b/rest-api/api-docs/events.json
index 392b0ac70..54269a407 100644
--- a/rest-api/api-docs/events.json
+++ b/rest-api/api-docs/events.json
@@ -163,14 +163,83 @@
"ChannelTalkingFinished",
"ChannelHold",
"ChannelUnhold",
+ "ContactStatusChange",
"EndpointStateChange",
"Dial",
"StasisEnd",
"StasisStart",
"TextMessageReceived",
- "ChannelConnectedLine"
+ "ChannelConnectedLine",
+ "PeerStatusChange"
]
},
+ "ContactInfo": {
+ "id": "ContactInfo",
+ "description": "Detailed information about a contact on an endpoint.",
+ "properties": {
+ "uri": {
+ "type": "string",
+ "description": "The location of the contact.",
+ "required": true
+ },
+ "contact_status": {
+ "type": "string",
+ "description": "The current status of the contact.",
+ "required": true,
+ "allowableValues": {
+ "valueType": "LIST",
+ "values": [
+ "Unreachable",
+ "Reachable",
+ "Unknown",
+ "Created",
+ "Removed"
+ ]
+ }
+ },
+ "aor": {
+ "type": "string",
+ "description": "The Address of Record this contact belongs to.",
+ "required": true
+ },
+ "roundtrip_usec": {
+ "type": "string",
+ "description": "Current round trip time, in microseconds, for the contact.",
+ "required": false
+ }
+ }
+ },
+ "Peer": {
+ "id": "Peer",
+ "description": "Detailed information about a remote peer that communicates with Asterisk.",
+ "properties": {
+ "peer_status": {
+ "type": "string",
+ "description": "The current state of the peer. Note that the values of the status are dependent on the underlying peer technology.",
+ "required": true
+ },
+ "cause": {
+ "type": "string",
+ "description": "An optional reason associated with the change in peer_status.",
+ "required": false
+ },
+ "address": {
+ "type": "string",
+ "description": "The IP address of the peer.",
+ "required": false
+ },
+ "port": {
+ "type": "string",
+ "description": "The port of the peer.",
+ "required": false
+ },
+ "time": {
+ "type": "string",
+ "description": "The last known time the peer was contacted.",
+ "required": false
+ }
+ }
+ },
"DeviceStateChanged": {
"id": "DeviceStateChanged",
"description": "Notification that a device state has changed.",
@@ -654,6 +723,34 @@
}
}
},
+ "ContactStatusChange": {
+ "id": "ContactStatusChange",
+ "description": "The state of a contact on an endpoint has changed.",
+ "properties": {
+ "endpoint": {
+ "required": true,
+ "type": "Endpoint"
+ },
+ "contact_info": {
+ "required": true,
+ "type": "ContactInfo"
+ }
+ }
+ },
+ "PeerStatusChange": {
+ "id": "PeerStatusChange",
+ "description": "The state of a peer associated with an endpoint has changed.",
+ "properties": {
+ "endpoint": {
+ "required": true,
+ "type": "Endpoint"
+ },
+ "peer": {
+ "required": true,
+ "type": "Peer"
+ }
+ }
+ },
"EndpointStateChange": {
"id": "EndpointStateChange",
"description": "Endpoint state changed.",