35 #include "asterisk/stasis_bridges.h"
36 #include "asterisk/stasis_channels.h"
38 #include "asterisk/stasis_message_router.h"
40 #define BRIDGE_ALL "__AST_BRIDGE_ALL_TOPIC"
41 #define CHANNEL_ALL "__AST_CHANNEL_ALL_TOPIC"
42 #define ENDPOINT_ALL "__AST_ENDPOINT_ALL_TOPIC"
47 static int unsubscribe(
struct stasis_app *app,
const char *kind,
const char *
id,
int terminate);
93 enum forward_type forward_type;
98 static void forwards_dtor(
void *obj)
108 static void forwards_unsubscribe(
struct app_forwards *forwards)
121 if (!app || ast_strlen_zero(
id)) {
125 forwards = ao2_t_alloc(
sizeof(*forwards) + strlen(
id) + 1, forwards_dtor,
id);
130 strcpy(forwards->
id,
id);
145 forwards = forwards_create(app, chan ? ast_channel_uniqueid(chan) : CHANNEL_ALL);
150 forwards->forward_type = FORWARD_CHANNEL;
173 forwards = forwards_create(app, bridge ? bridge->
uniqueid : BRIDGE_ALL);
178 forwards->forward_type = FORWARD_BRIDGE;
182 forwards_unsubscribe(forwards);
214 forwards->forward_type = FORWARD_ENDPOINT;
223 forwards_unsubscribe(forwards);
236 forwards_unsubscribe(forwards);
257 static int forwards_sort(
const void *obj_left,
const void *obj_right,
int flags)
261 const char *right_key = obj_right;
266 right_key = object_right->
id;
269 cmp = strcmp(object_left->
id, right_key);
276 cmp = strncmp(object_left->
id, right_key, strlen(right_key));
287 static void app_dtor(
void *obj)
290 size_t size = strlen(
"stasis-") + strlen(app->
name) + 1;
291 char context_name[size];
293 ast_verb(1,
"Destroying Stasis app %s\n", app->
name);
295 ast_assert(app->
router == NULL);
300 strcpy(context_name,
"stasis-");
301 strcat(context_name, app->
name);
304 ao2_cleanup(app->
topic);
308 ao2_cleanup(app->
data);
357 call_forwarded_handler(app, message);
371 typedef struct ast_json *(*channel_snapshot_monitor)(
374 const struct timeval *tv);
376 static struct ast_json *simple_channel_event(
379 const struct timeval *tv)
390 "channel", json_channel);
393 static struct ast_json *channel_created_event(
395 const struct timeval *tv)
397 return simple_channel_event(
"ChannelCreated", snapshot, tv);
400 static struct ast_json *channel_destroyed_event(
402 const struct timeval *tv)
411 "type",
"ChannelDestroyed",
415 "channel", json_channel);
418 static struct ast_json *channel_state_change_event(
420 const struct timeval *tv)
422 return simple_channel_event(
"ChannelStateChange", snapshot, tv);
429 const struct timeval *tv)
432 new_snapshot : old_snapshot;
435 return channel_created_event(snapshot, tv);
437 return channel_destroyed_event(snapshot, tv);
438 }
else if (old_snapshot->
state != new_snapshot->
state) {
439 return channel_state_change_event(snapshot, tv);
445 static struct ast_json *channel_dialplan(
448 const struct timeval *tv)
472 "type",
"ChannelDialplan",
476 "channel", json_channel);
479 static struct ast_json *channel_callerid(
482 const struct timeval *tv)
501 "type",
"ChannelCallerId",
503 "caller_presentation", new_snapshot->
caller->
pres,
506 "channel", json_channel);
509 static struct ast_json *channel_connected_line(
512 const struct timeval *tv)
531 "type",
"ChannelConnectedLine",
533 "channel", json_channel);
540 channel_connected_line,
543 static void sub_channel_update_handler(
void *data,
551 for (i = 0; i < ARRAY_LEN(channel_monitors); ++i) {
567 static struct ast_json *simple_endpoint_event(
570 const struct timeval *tv)
574 if (!json_endpoint) {
581 "endpoint", json_endpoint);
584 static int message_received_handler(
const char *endpoint_id,
struct ast_json *json_msg,
void *pvt)
594 resource = strchr(tech,
'/');
600 if (ast_strlen_zero(tech) || ast_strlen_zero(resource)) {
611 if (!json_endpoint) {
616 "type",
"TextMessageReceived",
618 "endpoint", json_endpoint,
628 static void sub_endpoint_update_handler(
void *data,
636 const struct timeval *tv;
652 json = simple_endpoint_event(
"EndpointStateChange", new_snapshot, tv);
661 if (!new_snapshot && old_snapshot) {
662 unsubscribe(app,
"endpoint", old_snapshot->
id, 1);
666 static struct ast_json *simple_bridge_event(
669 const struct timeval *tv)
679 "bridge", json_bridge);
682 static void sub_bridge_update_handler(
void *data,
689 const struct timeval *tv;
695 if (!update->new_snapshot) {
696 json = simple_bridge_event(
"BridgeDestroyed", update->old_snapshot, tv);
697 }
else if (!update->old_snapshot) {
698 json = simple_bridge_event(
"BridgeCreated", update->new_snapshot, tv);
699 }
else if (update->new_snapshot && update->old_snapshot
701 json = simple_bridge_event(
"BridgeVideoSourceChanged", update->new_snapshot, tv);
713 if (!update->new_snapshot && update->old_snapshot) {
714 unsubscribe(app,
"bridge", update->old_snapshot->
uniqueid, 1);
761 for (; (uniqueid = ao2_iterator_next(&iter));
ao2_ref(uniqueid, -1)) {
797 if (!subscribed && transfer_msg->
to_transferee.bridge_snapshot) {
806 case AST_ATTENDED_TRANSFER_DEST_BRIDGE_MERGE:
809 case AST_ATTENDED_TRANSFER_DEST_LINK:
816 case AST_ATTENDED_TRANSFER_DEST_THREEWAY:
832 static void bridge_subscription_change_handler(
void *data,
struct stasis_subscription *sub,
870 int debug_enabled = 0;
884 return debug_enabled;
897 ao2_cleanup(app_names);
902 while ((app_name = ao2_iterator_next(&it_app_names))) {
907 ao2_cleanup(app_name);
910 ao2_iterator_cleanup(&it_app_names);
911 ao2_cleanup(app_names);
920 size_t context_size = strlen(
"stasis-") + strlen(name) + 1;
921 char context_name[context_size];
925 ast_assert(name != NULL);
926 ast_assert(handler != NULL);
928 ast_verb(1,
"Creating Stasis app '%s'\n", name);
930 size =
sizeof(*app) + strlen(name) + 1;
939 forwards_sort, NULL);
944 ret =
ast_asprintf(&topic_name,
"ari:application/%s", name);
950 ast_free(topic_name);
961 ast_bridge_merge_message_type(), bridge_merge_handler, app);
964 ast_blind_transfer_type(), bridge_blind_transfer_handler, app);
967 ast_attended_transfer_type(), bridge_attended_transfer_handler, app);
978 app->
router = stasis_message_router_create(app->
topic);
984 ast_bridge_snapshot_type(), sub_bridge_update_handler, app);
1004 strncpy(app->
name, name, size -
sizeof(*app));
1010 strcpy(context_name,
"stasis-");
1011 strcat(context_name, name);
1014 ast_log(LOG_WARNING,
"Could not create context '%s' for Stasis application '%s'\n", context_name, name);
1017 ast_add_extension(context_name, 0,
"h", 1, NULL, NULL,
"NoOp", NULL, NULL,
"res_stasis");
1020 ast_log(LOG_WARNING,
"Not creating context '%s' for Stasis application '%s' because it already exists\n",
1021 context_name, name);
1041 ast_log(AST_LOG_WARNING,
"Failed to append EID to outgoing event %s\n",
1053 handler(data, app->
name, message);
1056 "Inactive Stasis app '%s' missed message\n", app->
name);
1065 ast_verb(1,
"Deactivating Stasis app '%s'\n", app->
name);
1067 ao2_cleanup(app->
data);
1117 ast_verb(1,
"Replacing Stasis app '%s'\n", app->
name);
1120 "type",
"ApplicationReplaced",
1122 "application", app->
name);
1143 ast_verb(1,
"Activating Stasis app '%s'\n", app->
name);
1156 static int forwards_filter_by_type(
void *obj,
void *arg,
int flags)
1159 enum forward_type *forward_type = arg;
1161 if (forward->forward_type == *forward_type) {
1174 enum forward_type forward_type;
1176 ast_cli(a->fd,
"Name: %s\n"
1178 " Subscription Model: %s\n",
1180 app->
debug ?
"Yes" :
"No",
1182 "Global Resource Subscription" :
1183 "Application/Explicit Resource Subscription");
1186 ast_cli(a->fd,
" Channels:\n");
1187 forward_type = FORWARD_CHANNEL;
1189 forwards_filter_by_type, &forward_type);
1191 while ((forward = ao2_iterator_next(channels))) {
1192 ast_cli(a->fd,
" %s (%d)\n", forward->
id, forward->
interested);
1198 ast_cli(a->fd,
" Bridges:\n");
1199 forward_type = FORWARD_BRIDGE;
1201 forwards_filter_by_type, &forward_type);
1203 while ((forward = ao2_iterator_next(bridges))) {
1204 ast_cli(a->fd,
" %s (%d)\n", forward->
id, forward->
interested);
1210 ast_cli(a->fd,
" Endpoints:\n");
1211 forward_type = FORWARD_ENDPOINT;
1213 forwards_filter_by_type, &forward_type);
1215 while ((forward = ao2_iterator_next(endpoints))) {
1216 ast_cli(a->fd,
" %s (%d)\n", forward->
id, forward->
interested);
1234 "channel_ids",
"bridge_ids",
"endpoint_ids");
1243 while ((forwards = ao2_iterator_next(&i))) {
1247 switch (forwards->forward_type) {
1248 case FORWARD_CHANNEL:
1251 case FORWARD_BRIDGE:
1254 case FORWARD_ENDPOINT:
1263 if (append_res != 0) {
1264 ast_log(LOG_ERROR,
"Error building response\n");
1295 chan ? ast_channel_uniqueid(chan) : CHANNEL_ALL,
1318 ast_debug(3,
"Channel '%s' is %d interested in %s\n",
1319 chan ? ast_channel_uniqueid(chan) :
"ALL",
1329 static int subscribe_channel(
struct stasis_app *app,
void *obj)
1334 static int unsubscribe(
struct stasis_app *app,
const char *kind,
const char *
id,
int terminate)
1339 if (!strcmp(kind,
"bridge")) {
1341 }
else if (!strcmp(kind,
"channel")) {
1343 }
else if (!strcmp(kind,
"endpoint")) {
1346 ast_log(LOG_WARNING,
"Unknown subscription kind '%s'\n", kind);
1355 ast_debug(3,
"App '%s' not subscribed to %s '%s'\n", app->
name, kind,
id);
1361 if (forwards->
interested == 0 || terminate) {
1363 ast_debug(3,
"%s '%s' unsubscribed from %s\n", kind,
id, app->
name);
1364 forwards_unsubscribe(forwards);
1369 if (!strcmp(kind,
"endpoint")) {
1394 return unsubscribe(app,
"channel", channel_id, 0);
1401 if (ast_strlen_zero(channel_id)) {
1402 channel_id = CHANNEL_ALL;
1405 ao2_cleanup(forwards);
1407 return forwards != NULL;
1410 static void *channel_find(
const struct stasis_app *app,
const char *
id)
1417 .find = channel_find,
1418 .subscribe = subscribe_channel,
1442 bridge ? bridge->
uniqueid : BRIDGE_ALL,
1465 ast_debug(3,
"Bridge '%s' is %d interested in %s\n",
1476 static int subscribe_bridge(
struct stasis_app *app,
void *obj)
1496 return unsubscribe(app,
"bridge", bridge_id, 0);
1503 if (ast_strlen_zero(bridge_id)) {
1504 bridge_id = BRIDGE_ALL;
1508 ao2_cleanup(forwards);
1510 return forwards != NULL;
1513 static void *bridge_find(
const struct stasis_app *app,
const char *
id)
1520 .find = bridge_find,
1521 .subscribe = subscribe_bridge,
1571 ast_debug(3,
"Endpoint '%s' is %d interested in %s\n",
1582 static int subscribe_endpoint(
struct stasis_app *app,
void *obj)
1593 return unsubscribe(app,
"endpoint", endpoint_id, 0);
1600 if (ast_strlen_zero(endpoint_id)) {
1601 endpoint_id = ENDPOINT_ALL;
1604 ao2_cleanup(forwards);
1606 return forwards != NULL;
1609 static void *endpoint_find(
const struct stasis_app *app,
const char *
id)
1616 .find = endpoint_find,
1617 .subscribe = subscribe_endpoint,
1638 if (!app || !json) {
1669 ast_log(LOG_ERROR,
"Invalid json type event filter - app: %s, filter: %s\n",
1670 app->
name, filter_type);
1683 ast_log(LOG_ERROR,
"Filter event must have a type - app: %s, "
1684 "filter: %s\n", app->
name, filter_type);
1700 return app_event_filter_set(app, &app->
events_allowed, filter,
"allowed");
1703 static int app_events_disallowed_set(
struct stasis_app *app,
struct ast_json *filter)
1705 return app_event_filter_set(app, &app->
events_disallowed, filter,
"disallowed");
1710 return app_events_disallowed_set(app, filter) || app_events_allowed_set(app, filter);
struct ast_json * events_allowed
struct stasis_app * stasis_app_get_by_name(const char *name)
Retrieve a handle to a Stasis application by its name.
static struct app_forwards * forwards_create_bridge(struct stasis_app *app, struct ast_bridge *bridge)
const ast_string_field data
struct ao2_container * channels
Main Channel structure associated with a channel.
struct ast_json * ast_json_ref(struct ast_json *value)
Increase refcount on value.
void stasis_app_set_debug_by_name(const char *app_name, int debug)
Enable/disable request/response and event logging on an application.
struct ast_channel_snapshot_base * base
Asterisk main include file. File version handling, generic pbx functions.
const ast_string_field uniqueid
int ao2_container_count(struct ao2_container *c)
Returns the number of elements in a container.
struct stasis_message * old_snapshot
Old value from the cache.
struct ast_json * ast_json_pack(char const *format,...)
Helper for creating complex JSON values.
int ast_channel_snapshot_cep_equal(const struct ast_channel_snapshot *old_snapshot, const struct ast_channel_snapshot *new_snapshot)
Compares the context, exten and priority of two snapshots.
int stasis_message_router_add(struct stasis_message_router *router, struct stasis_message_type *message_type, stasis_subscription_cb callback, void *data)
Add a route to a message router.
CallerID (and other GR30) management and generation Includes code and algorithms from the Zapata libr...
Message representing attended transfer.
stasis_app_subscription_model
size_t ast_json_object_size(struct ast_json *object)
Get size of JSON object.
char * ast_eid_to_str(char *s, int maxlen, struct ast_eid *eid)
Convert an EID to a string.
#define ast_channel_unref(c)
Decrease channel reference count.
The arg parameter is a search key, but is not an object.
const char * ast_describe_caller_presentation(int data)
Convert caller ID pres value to explanatory string.
int stasis_app_get_debug_by_name(const char *app_name)
Get debug status of an application.
Message published during a blind transfer.
void ast_json_unref(struct ast_json *value)
Decrease refcount on value. If refcount reaches zero, value is freed.
const char * scheme
The scheme to match against on [un]subscribes.
static int debug
Global debug status.
#define ao2_callback(c, flags, cb_fn, arg)
ao2_callback() is a generic function that applies cb_fn() to all objects in a container, as described below.
struct stasis_message_type * ast_endpoint_snapshot_type(void)
Message type for ast_endpoint_snapshot.
struct ast_endpoint_snapshot * ast_endpoint_latest_snapshot(const char *tech, const char *resource)
Retrieve the most recent snapshot for the endpoint with the given name.
Structure that contains a snapshot of information about a bridge.
const ast_string_field video_source_id
void app_deactivate(struct stasis_app *app)
Deactivates an application.
Structure representing a snapshot of channel state.
Assume that the ao2_container is already locked.
struct stasis_message_type * stasis_message_type(const struct stasis_message *msg)
Get the message type for a stasis_message.
void stasis_message_router_set_formatters_default(struct stasis_message_router *router, stasis_subscription_cb callback, void *data, enum stasis_subscription_message_formatters formatters)
Sets the default route of a router with formatters.
struct stasis_topic * ast_endpoint_topic(struct ast_endpoint *endpoint)
Returns the topic for a specific endpoint.
int app_unsubscribe_channel(struct stasis_app *app, struct ast_channel *chan)
Cancel the subscription an app has for a channel.
const ast_string_field uniqueid
struct stasis_topic * ast_bridge_topic_all(void)
A topic which publishes the events for all bridges.
void ao2_iterator_destroy(struct ao2_iterator *iter)
Destroy a container iterator.
const char * ast_cause2str(int cause) attribute_pure
Gives the string form of a given cause code.
int stasis_app_event_filter_set(struct stasis_app *app, struct ast_json *filter)
Set the application's event type filter.
void app_shutdown(struct stasis_app *app)
Tears down an application.
struct timeval ast_tvnow(void)
Returns current timeval. Meant to replace calls to gettimeofday().
#define ao2_link_flags(container, obj, flags)
Add an object to a container.
int app_unsubscribe_bridge_id(struct stasis_app *app, const char *bridge_id)
Cancel the subscription an app has for a bridge.
const ast_string_field id
#define ast_strdup(str)
A wrapper for strdup()
struct ast_endpoint * ast_endpoint_find_by_id(const char *id)
Finds the endpoint with the given tech[/resource] id.
int stasis_message_router_add_cache_update(struct stasis_message_router *router, struct stasis_message_type *message_type, stasis_subscription_cb callback, void *data)
Add a route for stasis_cache_update messages to a message router.
char bridge[AST_UUID_STR_LEN]
struct stasis_forward * topic_cached_forward
void stasis_app_set_debug(struct stasis_app *app, int debug)
Enable/disable request/response and event logging on an application.
Structure representing a change of snapshot of channel state.
void ast_free_ptr(void *ptr)
free() wrapper
struct ast_channel_snapshot_dialplan * dialplan
struct ast_bridge_channel_snapshot_pair to_transferee
int messaging_app_subscribe_endpoint(const char *app_name, struct ast_endpoint *endpoint, message_received_cb callback, void *pvt)
Subscribe an application to an endpoint for messages.
static struct ast_json * channel_state(struct ast_channel_snapshot *old_snapshot, struct ast_channel_snapshot *new_snapshot, const struct timeval *tv)
Handle channel state changes.
int app_is_active(struct stasis_app *app)
Checks whether an app is active.
int app_is_subscribed_channel_id(struct stasis_app *app, const char *channel_id)
Test if an app is subscribed to a channel.
struct stasis_topic * ast_endpoint_topic_all_cached(void)
Cached topic for all endpoint related messages.
struct ast_json * stasis_message_to_json(struct stasis_message *msg, struct stasis_message_sanitizer *sanitize)
Build the JSON representation of the message.
int app_subscribe_bridge(struct stasis_app *app, struct ast_bridge *bridge)
Add a bridge subscription to an existing channel subscription.
int ast_json_object_set(struct ast_json *object, const char *key, struct ast_json *value)
Set a field in a JSON object.
#define ast_asprintf(ret, fmt,...)
A wrapper for asprintf()
int app_is_subscribed_endpoint_id(struct stasis_app *app, const char *endpoint_id)
Test if an app is subscribed to a endpoint.
int ast_context_destroy_by_name(const char *context, const char *registrar)
Destroy a context by name.
int ast_channel_snapshot_caller_id_equal(const struct ast_channel_snapshot *old_snapshot, const struct ast_channel_snapshot *new_snapshot)
Compares the callerid info of two snapshots.
struct stasis_message_router * endpoint_router
#define ao2_bump(obj)
Bump refcount on an AO2 object by one, returning the object.
void stasis_app_to_cli(const struct stasis_app *app, struct ast_cli_args *a)
Dump properties of a stasis_app to the CLI.
struct ast_bridge_channel_snapshot_pair to_transfer_target
struct ao2_container * forwards
struct stasis_topic * ast_channel_topic_all(void)
A topic which publishes the events for all channels.
int stasis_app_event_allowed(const char *app_name, struct ast_json *event)
Check if the given event should be filtered.
void stasis_app_unregister_event_sources(void)
Unregister core event sources.
struct ast_context * ast_context_find(const char *name)
Find a context.
struct ast_json *(* channel_snapshot_monitor)(struct ast_channel_snapshot *old_snapshot, struct ast_channel_snapshot *new_snapshot, const struct timeval *tv)
Typedef for callbacks that get called on channel snapshot updates.
An application is automatically subscribed to all resources in Asterisk, even if it does not control ...
struct ast_channel_snapshot * links[2]
static struct app_forwards * forwards_create_endpoint(struct stasis_app *app, struct ast_endpoint *endpoint)
const ast_string_field appl
struct stasis_app * app_create(const char *name, stasis_app_cb handler, void *data, enum stasis_app_subscription_model subscription_model)
Create a res_stasis application.
struct ast_json * ast_json_string_create(const char *value)
Construct a JSON string from value.
#define ast_strdupa(s)
duplicate a string in memory from the stack
Event source information and callbacks.
const struct timeval * stasis_message_timestamp(const struct stasis_message *msg)
Get the time when a message was created.
#define ao2_ref(o, delta)
Reference/unreference an object and return the old refcount.
#define ast_json_object_string_get(object, key)
Get a string field from a JSON object.
struct stasis_message_type * stasis_cache_update_type(void)
Message type for cache update messages.
struct ast_channel_snapshot_hangup * hangup
const char * ast_json_string_get(const struct ast_json *string)
Get the value of a JSON string.
struct ast_bridge_snapshot * bridge
struct stasis_topic * ast_app_get_topic(struct stasis_app *app)
Returns the stasis topic for an app.
int app_unsubscribe_channel_id(struct stasis_app *app, const char *channel_id)
Cancel the subscription an app has for a channel.
#define ast_debug(level,...)
Log a DEBUG message.
struct stasis_topic * stasis_topic_create(const char *name)
Create a new topic.
const char * stasis_app_name(const struct stasis_app *app)
Retrieve an application's name.
Internal API for the Stasis application controller.
int app_is_finished(struct stasis_app *app)
Checks whether a deactivated app has no channels.
struct ast_json * ast_json_array_create(void)
Create a empty JSON array.
struct ast_json * ast_json_timeval(const struct timeval tv, const char *zone)
Construct a timeval as JSON.
A snapshot of an endpoint's state.
int ast_json_array_append(struct ast_json *array, struct ast_json *value)
Append to an array.
struct stasis_topic * ast_endpoint_topic_cached(struct ast_endpoint *endpoint)
Returns the topic for a specific endpoint.
struct ast_channel_snapshot_caller * caller
enum ast_attended_transfer_dest_type dest_type
void stasis_app_unregister_event_source(struct stasis_app_event_source *obj)
Unregister an application event source.
struct stasis_topic * ast_channel_topic(struct ast_channel *chan)
A topic which publishes the events for a particular channel.
struct stasis_message * new_snapshot
New value.
Structure that contains information about a bridge.
void app_send(struct stasis_app *app, struct ast_json *message)
Send a message to an application.
struct stasis_message_sanitizer * stasis_app_get_sanitizer(void)
Get the Stasis message sanitizer for app_stasis applications.
struct ast_channel_snapshot * transferer
int app_subscribe_endpoint(struct stasis_app *app, struct ast_endpoint *endpoint)
Subscribes an application to a endpoint.
struct stasis_message_router * router
void * stasis_message_data(const struct stasis_message *msg)
Get the data contained in a message.
struct stasis_message_type * ast_endpoint_state_type(void)
Message type for endpoint state changes.
struct ast_bridge * stasis_app_bridge_find_by_id(const char *bridge_id)
Returns the bridge with the given id.
struct stasis_message_type * type
Convenience reference to snapshot type.
int ast_strings_equal(const char *str1, const char *str2)
Compare strings for equality checking for NULL.
const char * app_name(struct ast_app *app)
struct ast_bridge_channel_snapshot_pair threeway
struct ast_json * events_disallowed
static struct ao2_container * bridges
int stasis_subscription_final_message(struct stasis_subscription *sub, struct stasis_message *msg)
Determine whether a message is the final message to be received on a subscription.
struct stasis_topic * topic
struct stasis_forward * topic_forward
static struct stasis_rest_handlers endpoints
REST handler for /api-docs/endpoints.json.
void stasis_publish(struct stasis_topic *topic, struct stasis_message *message)
Publish a message to a topic's subscribers.
struct ao2_container * stasis_app_get_all(void)
Gets the names of all registered Stasis applications.
static int bridge_app_subscribed(struct stasis_app *app, const char *uniqueid)
Helper function for determining if the application is subscribed to a given entity.
enum ast_json_type ast_json_typeof(const struct ast_json *value)
Get the type of value.
struct ast_channel_snapshot * new_snapshot
enum ast_channel_state state
const ast_string_field uniqueid
struct stasis_message_type * ast_channel_snapshot_type(void)
Message type for ast_channel_snapshot_update.
struct ast_channel_snapshot * old_snapshot
int stasis_app_get_debug(struct stasis_app *app)
Get debug status of an application.
void(* stasis_app_cb)(void *data, const char *app_name, struct ast_json *message)
Callback for Stasis application handler.
struct ast_bridge_snapshot * from
struct stasis_topic * ast_bridge_topic(struct ast_bridge *bridge)
A topic which publishes the events for a particular bridge.
struct ast_json * stasis_app_event_filter_to_json(struct stasis_app *app, struct ast_json *json)
Convert and add the app's event type filter(s) to the given json object.
struct ast_eid ast_eid_default
Global EID.
int app_unsubscribe_endpoint_id(struct stasis_app *app, const char *endpoint_id)
Cancel the subscription an app has for a endpoint.
Message representing the merge of two bridges.
void stasis_message_router_unsubscribe(struct stasis_message_router *router)
Unsubscribe the router from the upstream topic.
struct ast_json * app_to_json(const struct stasis_app *app)
Create a JSON representation of a stasis_app.
#define ao2_replace(dst, src)
Replace one object reference with another cleaning up the original.
void stasis_app_set_global_debug(int debug)
Enable/disable request/response and event logging on all applications.
int ast_add_extension(const char *context, int replace, const char *extension, int priority, const char *label, const char *callerid, const char *application, void *data, void(*datad)(void *), const char *registrar)
Add and extension to an extension context.
When we need to walk through a container, we use an ao2_iterator to keep track of the current positio...
Standard Command Line Interface.
struct ast_json * ast_json_object_get(struct ast_json *object, const char *key)
Get a field from a JSON object.
int app_unsubscribe_bridge(struct stasis_app *app, struct ast_bridge *bridge)
Cancel the bridge subscription for an application.
Internal API for the Stasis application controller.
struct ast_channel_snapshot * ast_multi_channel_blob_get_channel(struct ast_multi_channel_blob *obj, const char *role)
Retrieve a channel snapshot associated with a specific role from a ast_multi_channel_blob.
A multi channel blob data structure for multi_channel_blob stasis messages.
void app_update(struct stasis_app *app, stasis_app_cb handler, void *data)
Update the handler and data for a res_stasis application.
void stasis_app_register_event_sources(void)
Register core event sources.
size_t ast_json_array_size(const struct ast_json *array)
Get the size of a JSON array.
void messaging_app_unsubscribe_endpoint(const char *app_name, const char *endpoint_id)
Subscribe for messages from a particular endpoint.
Stasis out-of-call text message support.
struct stasis_message_type * ast_endpoint_contact_state_type(void)
Message type for endpoint contact state changes.
Abstract JSON element (object, array, string, int, ...).
struct ast_json * ast_bridge_snapshot_to_json(const struct ast_bridge_snapshot *snapshot, const struct stasis_message_sanitizer *sanitize)
Build a JSON object from a ast_bridge_snapshot.
int app_subscribe_channel(struct stasis_app *app, struct ast_channel *chan)
Subscribes an application to a channel.
struct stasis_message_type * stasis_subscription_change_type(void)
Gets the message type for subscription change notices.
#define ao2_container_alloc_rbtree(ao2_options, container_options, sort_fn, cmp_fn)
Allocate and initialize a red-black tree container.
struct stasis_message_type * ast_channel_dial_type(void)
Message type for when a channel dials another channel.
int app_is_subscribed_bridge_id(struct stasis_app *app, const char *bridge_id)
Test if an app is subscribed to a bridge.
Stasis Application API. See Stasis Application API for detailed documentation.
int ast_channel_snapshot_connected_line_equal(const struct ast_channel_snapshot *old_snapshot, const struct ast_channel_snapshot *new_snapshot)
Compares the connected line info of two snapshots.
static int filter(struct ast_channel *chan, const char *cmd, char *parse, char *buf, size_t len)
struct ast_context * ast_context_find_or_create(struct ast_context **extcontexts, struct ast_hashtab *exttable, const char *name, const char *registrar)
Register a new context or find an existing one.
struct stasis_forward * stasis_forward_all(struct stasis_topic *from_topic, struct stasis_topic *to_topic)
Create a subscription which forwards all messages from one topic to another.
struct ast_json * ast_channel_snapshot_to_json(const struct ast_channel_snapshot *snapshot, const struct stasis_message_sanitizer *sanitize)
Build a JSON object from a ast_channel_snapshot.
struct ast_channel * ast_channel_get_by_name(const char *name)
Find a channel by name.
enum stasis_app_subscription_model subscription_model
#define RAII_VAR(vartype, varname, initval, dtor)
Declare a variable that will call a destructor function when it goes out of scope.
struct ast_json * ast_json_array_get(const struct ast_json *array, size_t index)
Get an element from an array.
#define AST_JSON_UTF8_VALIDATE(str)
Check str for UTF-8 and replace with an empty string if fails the check.
struct ao2_iterator ao2_iterator_init(struct ao2_container *c, int flags) attribute_warn_unused_result
Create an iterator for a container.
static int bridge_app_subscribed_involved(struct stasis_app *app, struct ast_bridge_snapshot *snapshot)
Callback function for checking if channels in a bridge are subscribed to.
struct ast_json * ast_endpoint_snapshot_to_json(const struct ast_endpoint_snapshot *snapshot, const struct stasis_message_sanitizer *sanitize)
Build a JSON object from a ast_endpoint_snapshot.
Reject duplicate objects in container.
const char * ast_endpoint_get_id(const struct ast_endpoint *endpoint)
Gets the tech/resource id of the given endpoint.
void stasis_app_register_event_source(struct stasis_app_event_source *obj)
Register an application event source.
struct stasis_message_router * bridge_router
static struct app_forwards * forwards_create_channel(struct stasis_app *app, struct ast_channel *chan)
struct ast_bridge_snapshot * to