Asterisk - The Open Source Telephony Project GIT-master-55f4e6d
Data Structures | Macros | Typedefs | Enumerations | Functions | Variables
res/stasis/app.c File Reference

Stasis application support. More...

#include "asterisk.h"
#include "app.h"
#include "control.h"
#include "messaging.h"
#include "asterisk/callerid.h"
#include "asterisk/cli.h"
#include "asterisk/stasis_app.h"
#include "asterisk/stasis_bridges.h"
#include "asterisk/stasis_channels.h"
#include "asterisk/stasis_endpoints.h"
#include "asterisk/stasis_message_router.h"
Include dependency graph for res/stasis/app.c:

Go to the source code of this file.

Data Structures

struct  app_forwards
 
struct  stasis_app
 

Macros

#define BRIDGE_ALL   "__AST_BRIDGE_ALL_TOPIC"
 
#define CHANNEL_ALL   "__AST_CHANNEL_ALL_TOPIC"
 
#define ENDPOINT_ALL   "__AST_ENDPOINT_ALL_TOPIC"
 

Typedefs

typedef 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. More...
 

Enumerations

enum  forward_type { FORWARD_CHANNEL , FORWARD_BRIDGE , FORWARD_ENDPOINT }
 

Functions

struct stasis_appapp_create (const char *name, stasis_app_cb handler, void *data, enum stasis_app_subscription_model subscription_model)
 Create a res_stasis application. More...
 
void app_deactivate (struct stasis_app *app)
 Deactivates an application. More...
 
static void app_dtor (void *obj)
 
static int app_event_filter_matched (struct ast_json *array, struct ast_json *event, int empty)
 
static int app_event_filter_set (struct stasis_app *app, struct ast_json **member, struct ast_json *filter, const char *filter_type)
 
static int app_events_allowed_set (struct stasis_app *app, struct ast_json *filter)
 
static int app_events_disallowed_set (struct stasis_app *app, struct ast_json *filter)
 
int app_is_active (struct stasis_app *app)
 Checks whether an app is active. More...
 
int app_is_finished (struct stasis_app *app)
 Checks whether a deactivated app has no channels. More...
 
int app_is_subscribed_bridge_id (struct stasis_app *app, const char *bridge_id)
 Test if an app is subscribed to a bridge. More...
 
int app_is_subscribed_channel_id (struct stasis_app *app, const char *channel_id)
 Test if an app is subscribed to a channel. More...
 
int app_is_subscribed_endpoint_id (struct stasis_app *app, const char *endpoint_id)
 Test if an app is subscribed to a endpoint. More...
 
void app_send (struct stasis_app *app, struct ast_json *message)
 Send a message to an application. More...
 
void app_shutdown (struct stasis_app *app)
 Tears down an application. More...
 
int app_subscribe_bridge (struct stasis_app *app, struct ast_bridge *bridge)
 Add a bridge subscription to an existing channel subscription. More...
 
int app_subscribe_channel (struct stasis_app *app, struct ast_channel *chan)
 Subscribes an application to a channel. More...
 
int app_subscribe_endpoint (struct stasis_app *app, struct ast_endpoint *endpoint)
 Subscribes an application to a endpoint. More...
 
struct ast_jsonapp_to_json (const struct stasis_app *app)
 Create a JSON representation of a stasis_app. More...
 
int app_unsubscribe_bridge (struct stasis_app *app, struct ast_bridge *bridge)
 Cancel the bridge subscription for an application. More...
 
int app_unsubscribe_bridge_id (struct stasis_app *app, const char *bridge_id)
 Cancel the subscription an app has for a bridge. More...
 
int app_unsubscribe_channel (struct stasis_app *app, struct ast_channel *chan)
 Cancel the subscription an app has for a channel. More...
 
int app_unsubscribe_channel_id (struct stasis_app *app, const char *channel_id)
 Cancel the subscription an app has for a channel. More...
 
int app_unsubscribe_endpoint_id (struct stasis_app *app, const char *endpoint_id)
 Cancel the subscription an app has for a endpoint. More...
 
void app_update (struct stasis_app *app, stasis_app_cb handler, void *data)
 Update the handler and data for a res_stasis application. More...
 
struct stasis_topicast_app_get_topic (struct stasis_app *app)
 Returns the stasis topic for an app. More...
 
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. More...
 
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. More...
 
static void bridge_attended_transfer_handler (void *data, struct stasis_subscription *sub, struct stasis_message *message)
 
static void bridge_blind_transfer_handler (void *data, struct stasis_subscription *sub, struct stasis_message *message)
 
static void * bridge_find (const struct stasis_app *app, const char *id)
 
static void bridge_merge_handler (void *data, struct stasis_subscription *sub, struct stasis_message *message)
 
static void bridge_subscription_change_handler (void *data, struct stasis_subscription *sub, struct stasis_message *message)
 
static void call_forwarded_handler (struct stasis_app *app, struct stasis_message *message)
 
static struct ast_jsonchannel_callerid (struct ast_channel_snapshot *old_snapshot, struct ast_channel_snapshot *new_snapshot, const struct timeval *tv)
 
static struct ast_jsonchannel_connected_line (struct ast_channel_snapshot *old_snapshot, struct ast_channel_snapshot *new_snapshot, const struct timeval *tv)
 
static struct ast_jsonchannel_created_event (struct ast_channel_snapshot *snapshot, const struct timeval *tv)
 
static struct ast_jsonchannel_destroyed_event (struct ast_channel_snapshot *snapshot, const struct timeval *tv)
 
static struct ast_jsonchannel_dialplan (struct ast_channel_snapshot *old_snapshot, struct ast_channel_snapshot *new_snapshot, const struct timeval *tv)
 
static void * channel_find (const struct stasis_app *app, const char *id)
 
static struct ast_jsonchannel_state (struct ast_channel_snapshot *old_snapshot, struct ast_channel_snapshot *new_snapshot, const struct timeval *tv)
 Handle channel state changes. More...
 
static struct ast_jsonchannel_state_change_event (struct ast_channel_snapshot *snapshot, const struct timeval *tv)
 
static void * endpoint_find (const struct stasis_app *app, const char *id)
 
static void endpoint_state_cb (void *data, struct stasis_subscription *sub, struct stasis_message *message)
 
static struct app_forwardsforwards_create (struct stasis_app *app, const char *id)
 
static struct app_forwardsforwards_create_bridge (struct stasis_app *app, struct ast_bridge *bridge)
 
static struct app_forwardsforwards_create_channel (struct stasis_app *app, struct ast_channel *chan)
 
static struct app_forwardsforwards_create_endpoint (struct stasis_app *app, struct ast_endpoint *endpoint)
 
static void forwards_dtor (void *obj)
 
static int forwards_filter_by_type (void *obj, void *arg, int flags)
 
static int forwards_sort (const void *obj_left, const void *obj_right, int flags)
 
static void forwards_unsubscribe (struct app_forwards *forwards)
 
static int message_received_handler (const char *endpoint_id, struct ast_json *json_msg, void *pvt)
 
static struct ast_jsonsimple_bridge_event (const char *type, struct ast_bridge_snapshot *snapshot, const struct timeval *tv)
 
static struct ast_jsonsimple_channel_event (const char *type, struct ast_channel_snapshot *snapshot, const struct timeval *tv)
 
static struct ast_jsonsimple_endpoint_event (const char *type, struct ast_endpoint_snapshot *snapshot, const struct timeval *tv)
 
int stasis_app_event_allowed (const char *app_name, struct ast_json *event)
 Check if the given event should be filtered. More...
 
int stasis_app_event_filter_set (struct stasis_app *app, struct ast_json *filter)
 Set the application's event type filter. More...
 
struct ast_jsonstasis_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. More...
 
int stasis_app_get_debug (struct stasis_app *app)
 Get debug status of an application. More...
 
int stasis_app_get_debug_by_name (const char *app_name)
 Get debug status of an application. More...
 
const char * stasis_app_name (const struct stasis_app *app)
 Retrieve an application's name. More...
 
void stasis_app_register_event_sources (void)
 Register core event sources. More...
 
void stasis_app_set_debug (struct stasis_app *app, int debug)
 Enable/disable request/response and event logging on an application. More...
 
void stasis_app_set_debug_by_name (const char *app_name, int debug)
 Enable/disable request/response and event logging on an application. More...
 
void stasis_app_set_global_debug (int debug)
 Enable/disable request/response and event logging on all applications. More...
 
void stasis_app_to_cli (const struct stasis_app *app, struct ast_cli_args *a)
 Dump properties of a stasis_app to the CLI. More...
 
void stasis_app_unregister_event_sources (void)
 Unregister core event sources. More...
 
static void sub_bridge_update_handler (void *data, struct stasis_subscription *sub, struct stasis_message *message)
 
static void sub_channel_update_handler (void *data, struct stasis_subscription *sub, struct stasis_message *message)
 
static void sub_default_handler (void *data, struct stasis_subscription *sub, struct stasis_message *message)
 
static void sub_endpoint_update_handler (void *data, struct stasis_subscription *sub, struct stasis_message *message)
 
static void sub_subscription_change_handler (void *data, struct stasis_subscription *sub, struct stasis_message *message)
 
static int subscribe_bridge (struct stasis_app *app, void *obj)
 
static int subscribe_channel (struct stasis_app *app, void *obj)
 
static int subscribe_endpoint (struct stasis_app *app, void *obj)
 
static int unsubscribe (struct stasis_app *app, const char *kind, const char *id, int terminate)
 

Variables

struct stasis_app_event_source bridge_event_source
 
struct stasis_app_event_source channel_event_source
 
static channel_snapshot_monitor channel_monitors []
 
struct stasis_app_event_source endpoint_event_source
 
int global_debug
 

Detailed Description

Stasis application support.

Author
David M. Lee, II dlee@.nosp@m.digi.nosp@m.um.co.nosp@m.m

Definition in file res/stasis/app.c.

Macro Definition Documentation

◆ BRIDGE_ALL

#define BRIDGE_ALL   "__AST_BRIDGE_ALL_TOPIC"

Definition at line 40 of file res/stasis/app.c.

◆ CHANNEL_ALL

#define CHANNEL_ALL   "__AST_CHANNEL_ALL_TOPIC"

Definition at line 41 of file res/stasis/app.c.

◆ ENDPOINT_ALL

#define ENDPOINT_ALL   "__AST_ENDPOINT_ALL_TOPIC"

Definition at line 42 of file res/stasis/app.c.

Typedef Documentation

◆ channel_snapshot_monitor

typedef 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.

Definition at line 347 of file res/stasis/app.c.

Enumeration Type Documentation

◆ forward_type

Enumerator
FORWARD_CHANNEL 
FORWARD_BRIDGE 
FORWARD_ENDPOINT 

Definition at line 76 of file res/stasis/app.c.

76 {
80};
@ FORWARD_CHANNEL
@ FORWARD_ENDPOINT
@ FORWARD_BRIDGE

Function Documentation

◆ app_create()

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.

Parameters
nameName of the application.
handlerCallback for messages sent to the application.
dataData pointer provided to the callback.
subscription_model
Returns
New res_stasis application.
Return values
NULLon error.

Definition at line 915 of file res/stasis/app.c.

916{
918 size_t size;
919 int res = 0;
920 size_t context_size = strlen("stasis-") + strlen(name) + 1;
921 char context_name[context_size];
922 char *topic_name;
923 int ret;
924
925 ast_assert(name != NULL);
927
928 ast_verb(1, "Creating Stasis app '%s'\n", name);
929
930 size = sizeof(*app) + strlen(name) + 1;
932 if (!app) {
933 return NULL;
934 }
935 app->subscription_model = subscription_model;
936
940 if (!app->forwards) {
941 return NULL;
942 }
943
944 ret = ast_asprintf(&topic_name, "ari:application/%s", name);
945 if (ret < 0) {
946 return NULL;
947 }
948
949 app->topic = stasis_topic_create(topic_name);
950 ast_free(topic_name);
951 if (!app->topic) {
952 return NULL;
953 }
954
956 if (!app->bridge_router) {
957 return NULL;
958 }
959
960 res |= stasis_message_router_add(app->bridge_router,
962
963 res |= stasis_message_router_add(app->bridge_router,
965
966 res |= stasis_message_router_add(app->bridge_router,
968
969 res |= stasis_message_router_add(app->bridge_router,
971
972 if (res != 0) {
973 return NULL;
974 }
975 /* Bridge router holds a reference */
976 ao2_ref(app, +1);
977
978 app->router = stasis_message_router_create(app->topic);
979 if (!app->router) {
980 return NULL;
981 }
982
983 res |= stasis_message_router_add(app->router,
985
986 res |= stasis_message_router_add(app->router,
988
991
992 res |= stasis_message_router_add(app->router,
994
997
998 if (res != 0) {
999 return NULL;
1000 }
1001 /* Router holds a reference */
1002 ao2_ref(app, +1);
1003
1004 strncpy(app->name, name, size - sizeof(*app));
1005 app->handler = handler;
1006 app->data = ao2_bump(data);
1007
1008 /* Create a context, a match-all extension, and a 'h' extension for this application. Note that
1009 * this should only be done if a context does not already exist. */
1010 strcpy(context_name, "stasis-");
1011 strcat(context_name, name);
1013 if (!ast_context_find_or_create(NULL, NULL, context_name, "res_stasis")) {
1014 ast_log(LOG_WARNING, "Could not create context '%s' for Stasis application '%s'\n", context_name, name);
1015 } else {
1016 ast_add_extension(context_name, 0, "_.", 1, NULL, NULL, "Stasis", ast_strdup(name), ast_free_ptr, "res_stasis");
1017 ast_add_extension(context_name, 0, "h", 1, NULL, NULL, "NoOp", NULL, NULL, "res_stasis");
1018 }
1019 } else {
1020 ast_log(LOG_WARNING, "Not creating context '%s' for Stasis application '%s' because it already exists\n",
1022 }
1023
1024 ao2_ref(app, +1);
1025 return app;
1026}
static const char app[]
Definition: app_adsiprog.c:56
#define ast_free(a)
Definition: astmm.h:180
#define ast_strdup(str)
A wrapper for strdup()
Definition: astmm.h:241
void ast_free_ptr(void *ptr)
free() wrapper
Definition: astmm.c:1739
#define ast_asprintf(ret, fmt,...)
A wrapper for asprintf()
Definition: astmm.h:267
#define ast_log
Definition: astobj2.c:42
@ AO2_ALLOC_OPT_LOCK_MUTEX
Definition: astobj2.h:363
#define ao2_cleanup(obj)
Definition: astobj2.h:1934
#define ao2_container_alloc_rbtree(ao2_options, container_options, sort_fn, cmp_fn)
Allocate and initialize a red-black tree container.
Definition: astobj2.h:1349
#define ao2_ref(o, delta)
Reference/unreference an object and return the old refcount.
Definition: astobj2.h:459
#define ao2_alloc_options(data_size, destructor_fn, options)
Definition: astobj2.h:404
#define ao2_bump(obj)
Bump refcount on an AO2 object by one, returning the object.
Definition: astobj2.h:480
@ AO2_CONTAINER_ALLOC_OPT_DUPS_OBJ_REJECT
Reject duplicate objects in container.
Definition: astobj2.h:1201
static const char name[]
Definition: format_mp3.c:68
static const char context_name[]
struct stasis_message_type * ast_endpoint_snapshot_type(void)
Message type for ast_endpoint_snapshot.
struct stasis_message_type * stasis_subscription_change_type(void)
Gets the message type for subscription change notices.
struct stasis_message_type * ast_channel_snapshot_type(void)
Message type for ast_channel_snapshot_update.
#define ast_verb(level,...)
#define LOG_WARNING
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.
Definition: pbx.c:6928
struct ast_context * ast_context_find(const char *name)
Find a context.
Definition: extconf.c:4172
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.
Definition: pbx.c:6149
static void sub_endpoint_update_handler(void *data, struct stasis_subscription *sub, struct stasis_message *message)
static void app_dtor(void *obj)
static void sub_subscription_change_handler(void *data, struct stasis_subscription *sub, struct stasis_message *message)
static void sub_default_handler(void *data, struct stasis_subscription *sub, struct stasis_message *message)
static void bridge_subscription_change_handler(void *data, struct stasis_subscription *sub, struct stasis_message *message)
static void bridge_blind_transfer_handler(void *data, struct stasis_subscription *sub, struct stasis_message *message)
static void bridge_attended_transfer_handler(void *data, struct stasis_subscription *sub, struct stasis_message *message)
static void bridge_merge_handler(void *data, struct stasis_subscription *sub, struct stasis_message *message)
static void sub_bridge_update_handler(void *data, struct stasis_subscription *sub, struct stasis_message *message)
static void sub_channel_update_handler(void *data, struct stasis_subscription *sub, struct stasis_message *message)
static int forwards_sort(const void *obj_left, const void *obj_right, int flags)
#define NULL
Definition: resample.c:96
struct stasis_topic * stasis_topic_create(const char *name)
Create a new topic.
Definition: stasis.c:617
@ STASIS_SUBSCRIPTION_FORMATTER_JSON
Definition: stasis.h:310
struct stasis_message_type * ast_bridge_snapshot_type(void)
Message type for ast_bridge_snapshot.
struct stasis_message_type * ast_blind_transfer_type(void)
Message type for ast_blind_transfer_message.
struct stasis_message_type * ast_attended_transfer_type(void)
Message type for ast_attended_transfer_message.
struct stasis_message_type * ast_bridge_merge_message_type(void)
Message type for ast_bridge_merge_message.
struct stasis_topic * ast_bridge_topic_all(void)
A topic which publishes the events for all bridges.
#define stasis_message_router_create(topic)
Create a new message router object.
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.
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.
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.
static void handler(const char *name, int response_code, struct ast_variable *get_params, struct ast_variable *path_vars, struct ast_variable *headers, struct ast_json *body, struct ast_ari_response *response)
Definition: test_ari.c:59
#define RAII_VAR(vartype, varname, initval, dtor)
Declare a variable that will call a destructor function when it goes out of scope.
Definition: utils.h:941
#define ast_assert(a)
Definition: utils.h:739

References AO2_ALLOC_OPT_LOCK_MUTEX, ao2_alloc_options, ao2_bump, ao2_cleanup, AO2_CONTAINER_ALLOC_OPT_DUPS_OBJ_REJECT, ao2_container_alloc_rbtree, ao2_ref, app, app_dtor(), ast_add_extension(), ast_asprintf, ast_assert, ast_attended_transfer_type(), ast_blind_transfer_type(), ast_bridge_merge_message_type(), ast_bridge_snapshot_type(), ast_bridge_topic_all(), ast_channel_snapshot_type(), ast_context_find(), ast_context_find_or_create(), ast_endpoint_snapshot_type(), ast_free, ast_free_ptr(), ast_log, ast_strdup, ast_verb, bridge_attended_transfer_handler(), bridge_blind_transfer_handler(), bridge_merge_handler(), bridge_subscription_change_handler(), context_name, stasis_app::data, forwards_sort(), handler(), LOG_WARNING, name, NULL, RAII_VAR, stasis_message_router_add(), stasis_message_router_add_cache_update(), stasis_message_router_create, stasis_message_router_set_formatters_default(), stasis_subscription_change_type(), STASIS_SUBSCRIPTION_FORMATTER_JSON, stasis_topic_create(), sub_bridge_update_handler(), sub_channel_update_handler(), sub_default_handler(), sub_endpoint_update_handler(), sub_subscription_change_handler(), and stasis_app::subscription_model.

Referenced by __stasis_app_register().

◆ app_deactivate()

void app_deactivate ( struct stasis_app app)

Deactivates an application.

Any channels currently in the application remain active (since the app might come back), but new channels are rejected.

Parameters
appApplication to deactivate.

Definition at line 1061 of file res/stasis/app.c.

1062{
1063 ao2_lock(app);
1064
1065 ast_verb(1, "Deactivating Stasis app '%s'\n", app->name);
1066 app->handler = NULL;
1067 ao2_cleanup(app->data);
1068 app->data = NULL;
1069
1070 ao2_unlock(app);
1071}
#define ao2_unlock(a)
Definition: astobj2.h:729
#define ao2_lock(a)
Definition: astobj2.h:717

References ao2_cleanup, ao2_lock, ao2_unlock, app, ast_verb, and NULL.

Referenced by stasis_app_unregister().

◆ app_dtor()

static void app_dtor ( void *  obj)
static

Definition at line 287 of file res/stasis/app.c.

288{
289 struct stasis_app *app = obj;
290 size_t size = strlen("stasis-") + strlen(app->name) + 1;
291 char context_name[size];
292
293 ast_verb(1, "Destroying Stasis app %s\n", app->name);
294
295 ast_assert(app->router == NULL);
296 ast_assert(app->bridge_router == NULL);
297 ast_assert(app->endpoint_router == NULL);
298
299 /* If we created a context for this application, remove it */
300 strcpy(context_name, "stasis-");
301 strcat(context_name, app->name);
303
304 ao2_cleanup(app->topic);
305 app->topic = NULL;
306 ao2_cleanup(app->forwards);
307 app->forwards = NULL;
308 ao2_cleanup(app->data);
309 app->data = NULL;
310
311 ast_json_unref(app->events_allowed);
312 app->events_allowed = NULL;
313 ast_json_unref(app->events_disallowed);
314 app->events_disallowed = NULL;
315
316}
void ast_json_unref(struct ast_json *value)
Decrease refcount on value. If refcount reaches zero, value is freed.
Definition: json.c:73
int ast_context_destroy_by_name(const char *context, const char *registrar)
Destroy a context by name.
Definition: pbx.c:8205

References ao2_cleanup, app, ast_assert, ast_context_destroy_by_name(), ast_json_unref(), ast_verb, context_name, and NULL.

Referenced by app_create().

◆ app_event_filter_matched()

static int app_event_filter_matched ( struct ast_json array,
struct ast_json event,
int  empty 
)
static

Definition at line 1713 of file res/stasis/app.c.

1714{
1715 struct ast_json *obj;
1716 int i;
1717
1718 if (!array || !ast_json_array_size(array)) {
1719 return empty;
1720 }
1721
1722 for (i = 0; i < ast_json_array_size(array) &&
1723 (obj = ast_json_array_get(array, i)); ++i) {
1724
1727 return 1;
1728 }
1729 }
1730
1731 return 0;
1732}
static int array(struct ast_channel *chan, const char *cmd, char *var, const char *value)
#define ast_json_object_string_get(object, key)
Get a string field from a JSON object.
Definition: json.h:600
struct ast_json * ast_json_array_get(const struct ast_json *array, size_t index)
Get an element from an array.
Definition: json.c:370
size_t ast_json_array_size(const struct ast_json *array)
Get the size of a JSON array.
Definition: json.c:366
int ast_strings_equal(const char *str1, const char *str2)
Compare strings for equality checking for NULL.
Definition: strings.c:238
Abstract JSON element (object, array, string, int, ...).
Definition: astman.c:222

References array(), ast_json_array_get(), ast_json_array_size(), ast_json_object_string_get, and ast_strings_equal().

Referenced by stasis_app_event_allowed().

◆ app_event_filter_set()

static int app_event_filter_set ( struct stasis_app app,
struct ast_json **  member,
struct ast_json filter,
const char *  filter_type 
)
static

Definition at line 1650 of file res/stasis/app.c.

1652{
1655 /* If no filters are specified then reset this filter type */
1656 filter = NULL;
1657 } else {
1658 /* Otherwise try to get the filter array for this type */
1659 filter = ast_json_object_get(filter, filter_type);
1660 if (!filter) {
1661 /* A filter type exists, but not this one, so don't update */
1662 return 0;
1663 }
1664 }
1665 }
1666
1667 /* At this point the filter object should be an array */
1669 ast_log(LOG_ERROR, "Invalid json type event filter - app: %s, filter: %s\n",
1670 app->name, filter_type);
1671 return -1;
1672 }
1673
1674 if (filter) {
1675 /* Confirm that at least the type names are specified */
1676 struct ast_json *obj;
1677 int i;
1678
1679 for (i = 0; i < ast_json_array_size(filter) &&
1680 (obj = ast_json_array_get(filter, i)); ++i) {
1681
1682 if (ast_strlen_zero(ast_json_object_string_get(obj, "type"))) {
1683 ast_log(LOG_ERROR, "Filter event must have a type - app: %s, "
1684 "filter: %s\n", app->name, filter_type);
1685 return -1;
1686 }
1687 }
1688 }
1689
1690 ao2_lock(app);
1693 ao2_unlock(app);
1694
1695 return 0;
1696}
static int filter(struct ast_channel *chan, const char *cmd, char *parse, char *buf, size_t len)
Definition: func_strings.c:807
#define LOG_ERROR
enum ast_json_type ast_json_typeof(const struct ast_json *value)
Get the type of value.
Definition: json.c:78
size_t ast_json_object_size(struct ast_json *object)
Get size of JSON object.
Definition: json.c:403
@ AST_JSON_ARRAY
Definition: json.h:165
@ AST_JSON_OBJECT
Definition: json.h:164
struct ast_json * ast_json_ref(struct ast_json *value)
Increase refcount on value.
Definition: json.c:67
struct ast_json * ast_json_object_get(struct ast_json *object, const char *key)
Get a field from a JSON object.
Definition: json.c:407
static force_inline int attribute_pure ast_strlen_zero(const char *s)
Definition: strings.h:65

References ao2_lock, ao2_unlock, app, AST_JSON_ARRAY, ast_json_array_get(), ast_json_array_size(), AST_JSON_OBJECT, ast_json_object_get(), ast_json_object_size(), ast_json_object_string_get, ast_json_ref(), ast_json_typeof(), ast_json_unref(), ast_log, ast_strlen_zero(), filter(), LOG_ERROR, and NULL.

Referenced by app_events_allowed_set(), and app_events_disallowed_set().

◆ app_events_allowed_set()

static int app_events_allowed_set ( struct stasis_app app,
struct ast_json filter 
)
static

Definition at line 1698 of file res/stasis/app.c.

1699{
1700 return app_event_filter_set(app, &app->events_allowed, filter, "allowed");
1701}
static int app_event_filter_set(struct stasis_app *app, struct ast_json **member, struct ast_json *filter, const char *filter_type)

References app, app_event_filter_set(), and filter().

Referenced by stasis_app_event_filter_set().

◆ app_events_disallowed_set()

static int app_events_disallowed_set ( struct stasis_app app,
struct ast_json filter 
)
static

Definition at line 1703 of file res/stasis/app.c.

1704{
1705 return app_event_filter_set(app, &app->events_disallowed, filter, "disallowed");
1706}

References app, app_event_filter_set(), and filter().

Referenced by stasis_app_event_filter_set().

◆ app_is_active()

int app_is_active ( struct stasis_app app)

Checks whether an app is active.

Parameters
appApplication to check.
Return values
True(non-zero) if app is active.
False(zero) if app has been deactivated.

Definition at line 1089 of file res/stasis/app.c.

1090{
1091 int ret;
1092
1093 ao2_lock(app);
1094 ret = app->handler != NULL;
1095 ao2_unlock(app);
1096
1097 return ret;
1098}

References ao2_lock, ao2_unlock, app, and NULL.

Referenced by stasis_app_exec().

◆ app_is_finished()

int app_is_finished ( struct stasis_app app)

Checks whether a deactivated app has no channels.

Parameters
appApplication to check.
Return values
True(non-zero) if app is deactivated, and has no associated channels.
False(zero) otherwise.

Definition at line 1100 of file res/stasis/app.c.

1101{
1102 int ret;
1103
1104 ao2_lock(app);
1105 ret = app->handler == NULL && ao2_container_count(app->forwards) == 0;
1106 ao2_unlock(app);
1107
1108 return ret;
1109}
int ao2_container_count(struct ao2_container *c)
Returns the number of elements in a container.

References ao2_container_count(), ao2_lock, ao2_unlock, app, and NULL.

Referenced by app_shutdown(), and cleanup_cb().

◆ app_is_subscribed_bridge_id()

int app_is_subscribed_bridge_id ( struct stasis_app app,
const char *  bridge_id 
)

Test if an app is subscribed to a bridge.

Parameters
appSubscribing application.
bridge_idId of bridge to check.
Return values
True(non-zero) if bridge is subscribed to app.
False(zero) if bridge is not subscribed.

Definition at line 1499 of file res/stasis/app.c.

1500{
1501 struct app_forwards *forwards;
1502
1503 if (ast_strlen_zero(bridge_id)) {
1504 bridge_id = BRIDGE_ALL;
1505 }
1506
1507 forwards = ao2_find(app->forwards, bridge_id, OBJ_SEARCH_KEY);
1508 ao2_cleanup(forwards);
1509
1510 return forwards != NULL;
1511}
#define ao2_find(container, arg, flags)
Definition: astobj2.h:1736
@ OBJ_SEARCH_KEY
The arg parameter is a search key, but is not an object.
Definition: astobj2.h:1101
#define BRIDGE_ALL

References ao2_cleanup, ao2_find, app, ast_strlen_zero(), BRIDGE_ALL, NULL, and OBJ_SEARCH_KEY.

◆ app_is_subscribed_channel_id()

int app_is_subscribed_channel_id ( struct stasis_app app,
const char *  channel_id 
)

Test if an app is subscribed to a channel.

Parameters
appSubscribing application.
channel_idId of channel to check.
Return values
True(non-zero) if channel is subscribed to app.
False(zero) if channel is not subscribed.

Definition at line 1397 of file res/stasis/app.c.

1398{
1399 struct app_forwards *forwards;
1400
1401 if (ast_strlen_zero(channel_id)) {
1402 channel_id = CHANNEL_ALL;
1403 }
1404 forwards = ao2_find(app->forwards, channel_id, OBJ_SEARCH_KEY);
1405 ao2_cleanup(forwards);
1406
1407 return forwards != NULL;
1408}
#define CHANNEL_ALL

References ao2_cleanup, ao2_find, app, ast_strlen_zero(), CHANNEL_ALL, NULL, and OBJ_SEARCH_KEY.

◆ app_is_subscribed_endpoint_id()

int app_is_subscribed_endpoint_id ( struct stasis_app app,
const char *  endpoint_id 
)

Test if an app is subscribed to a endpoint.

Parameters
appSubscribing application.
endpoint_idId of endpoint to check.
Return values
True(non-zero) if endpoint is subscribed to app.
False(zero) if endpoint is not subscribed.

Definition at line 1596 of file res/stasis/app.c.

1597{
1598 struct app_forwards *forwards;
1599
1600 if (ast_strlen_zero(endpoint_id)) {
1601 endpoint_id = ENDPOINT_ALL;
1602 }
1603 forwards = ao2_find(app->forwards, endpoint_id, OBJ_SEARCH_KEY);
1604 ao2_cleanup(forwards);
1605
1606 return forwards != NULL;
1607}
#define ENDPOINT_ALL

References ao2_cleanup, ao2_find, app, ast_strlen_zero(), ENDPOINT_ALL, NULL, and OBJ_SEARCH_KEY.

◆ app_send()

void app_send ( struct stasis_app app,
struct ast_json message 
)

Send a message to an application.

Parameters
appApp to send the message to.
messageMessage to send.

Definition at line 1033 of file res/stasis/app.c.

1034{
1036 char eid[20];
1037 void *data;
1038
1040 ast_eid_to_str(eid, sizeof(eid), &ast_eid_default)))) {
1041 ast_log(AST_LOG_WARNING, "Failed to append EID to outgoing event %s\n",
1043 }
1044
1045 /* Copy off mutable state with lock held */
1046 ao2_lock(app);
1047 handler = app->handler;
1048 data = ao2_bump(app->data);
1049 ao2_unlock(app);
1050 /* Name is immutable; no need to copy */
1051
1052 if (handler) {
1053 handler(data, app->name, message);
1054 } else {
1055 ast_verb(3,
1056 "Inactive Stasis app '%s' missed message\n", app->name);
1057 }
1058 ao2_cleanup(data);
1059}
#define AST_LOG_WARNING
struct ast_json * ast_json_string_create(const char *value)
Construct a JSON string from value.
Definition: json.c:278
int ast_json_object_set(struct ast_json *object, const char *key, struct ast_json *value)
Set a field in a JSON object.
Definition: json.c:414
const char * ast_json_string_get(const struct ast_json *string)
Get the value of a JSON string.
Definition: json.c:283
void(* stasis_app_cb)(void *data, const char *app_name, struct ast_json *message)
Callback for Stasis application handler.
Definition: stasis_app.h:67
char * ast_eid_to_str(char *s, int maxlen, struct ast_eid *eid)
Convert an EID to a string.
Definition: utils.c:2839
struct ast_eid ast_eid_default
Global EID.
Definition: options.c:93

References ao2_bump, ao2_cleanup, ao2_lock, ao2_unlock, app, ast_eid_default, ast_eid_to_str(), ast_json_object_get(), ast_json_object_set(), ast_json_string_create(), ast_json_string_get(), ast_log, AST_LOG_WARNING, ast_verb, and handler().

Referenced by app_update(), message_received_handler(), stasis_app_exec(), stasis_app_send(), sub_bridge_update_handler(), sub_channel_update_handler(), and sub_endpoint_update_handler().

◆ app_shutdown()

void app_shutdown ( struct stasis_app app)

Tears down an application.

It should be finished before calling this.

Parameters
appApplication to unsubscribe.

Definition at line 1073 of file res/stasis/app.c.

1074{
1075 ao2_lock(app);
1076
1078
1080 app->router = NULL;
1081 stasis_message_router_unsubscribe(app->bridge_router);
1082 app->bridge_router = NULL;
1083 stasis_message_router_unsubscribe(app->endpoint_router);
1084 app->endpoint_router = NULL;
1085
1086 ao2_unlock(app);
1087}
int app_is_finished(struct stasis_app *app)
Checks whether a deactivated app has no channels.
void stasis_message_router_unsubscribe(struct stasis_message_router *router)
Unsubscribe the router from the upstream topic.

References ao2_lock, ao2_unlock, app, app_is_finished(), ast_assert, NULL, and stasis_message_router_unsubscribe().

Referenced by cleanup_cb().

◆ app_subscribe_bridge()

int app_subscribe_bridge ( struct stasis_app app,
struct ast_bridge bridge 
)

Add a bridge subscription to an existing channel subscription.

Parameters
appApplication.
bridgeBridge to subscribe to.
Return values
0on success.
Non-zeroon error.

Definition at line 1423 of file res/stasis/app.c.

1424{
1425 struct app_forwards *forwards;
1426
1427 if (!app) {
1428 return -1;
1429 }
1430
1431 ao2_lock(app->forwards);
1432 /* If subscribed to all, don't subscribe again */
1433 forwards = ao2_find(app->forwards, BRIDGE_ALL, OBJ_SEARCH_KEY | OBJ_NOLOCK);
1434 if (forwards) {
1435 ao2_unlock(app->forwards);
1436 ao2_ref(forwards, -1);
1437
1438 return 0;
1439 }
1440
1441 forwards = ao2_find(app->forwards,
1442 bridge ? bridge->uniqueid : BRIDGE_ALL,
1444 if (!forwards) {
1445 int res;
1446
1447 /* Forwards not found, create one */
1448 forwards = forwards_create_bridge(app, bridge);
1449 if (!forwards) {
1450 ao2_unlock(app->forwards);
1451
1452 return -1;
1453 }
1454
1455 res = ao2_link_flags(app->forwards, forwards, OBJ_NOLOCK);
1456 if (!res) {
1457 ao2_unlock(app->forwards);
1458 ao2_ref(forwards, -1);
1459
1460 return -1;
1461 }
1462 }
1463
1464 ++forwards->interested;
1465 ast_debug(3, "Bridge '%s' is %d interested in %s\n",
1466 bridge ? bridge->uniqueid : "ALL",
1467 forwards->interested,
1468 app->name);
1469
1470 ao2_unlock(app->forwards);
1471 ao2_ref(forwards, -1);
1472
1473 return 0;
1474}
#define ao2_link_flags(container, obj, flags)
Add an object to a container.
Definition: astobj2.h:1554
@ OBJ_NOLOCK
Assume that the ao2_container is already locked.
Definition: astobj2.h:1063
#define ast_debug(level,...)
Log a DEBUG message.
static struct app_forwards * forwards_create_bridge(struct stasis_app *app, struct ast_bridge *bridge)
const ast_string_field uniqueid
Definition: bridge.h:401

References ao2_find, ao2_link_flags, ao2_lock, ao2_ref, ao2_unlock, app, ast_debug, BRIDGE_ALL, forwards_create_bridge(), app_forwards::interested, OBJ_NOLOCK, OBJ_SEARCH_KEY, and ast_bridge::uniqueid.

Referenced by control_swap_channel_in_bridge(), stasis_app_exec(), and subscribe_bridge().

◆ app_subscribe_channel()

int app_subscribe_channel ( struct stasis_app app,
struct ast_channel chan 
)

Subscribes an application to a channel.

Parameters
appApplication.
chanChannel to subscribe to.
Return values
0on success.
Non-zeroon error.

Definition at line 1276 of file res/stasis/app.c.

1277{
1278 struct app_forwards *forwards;
1279
1280 if (!app) {
1281 return -1;
1282 }
1283
1284 ao2_lock(app->forwards);
1285 /* If subscribed to all, don't subscribe again */
1286 forwards = ao2_find(app->forwards, CHANNEL_ALL, OBJ_SEARCH_KEY | OBJ_NOLOCK);
1287 if (forwards) {
1288 ao2_unlock(app->forwards);
1289 ao2_ref(forwards, -1);
1290
1291 return 0;
1292 }
1293
1294 forwards = ao2_find(app->forwards,
1295 chan ? ast_channel_uniqueid(chan) : CHANNEL_ALL,
1297 if (!forwards) {
1298 int res;
1299
1300 /* Forwards not found, create one */
1301 forwards = forwards_create_channel(app, chan);
1302 if (!forwards) {
1303 ao2_unlock(app->forwards);
1304
1305 return -1;
1306 }
1307
1308 res = ao2_link_flags(app->forwards, forwards, OBJ_NOLOCK);
1309 if (!res) {
1310 ao2_unlock(app->forwards);
1311 ao2_ref(forwards, -1);
1312
1313 return -1;
1314 }
1315 }
1316
1317 ++forwards->interested;
1318 ast_debug(3, "Channel '%s' is %d interested in %s\n",
1319 chan ? ast_channel_uniqueid(chan) : "ALL",
1320 forwards->interested,
1321 app->name);
1322
1323 ao2_unlock(app->forwards);
1324 ao2_ref(forwards, -1);
1325
1326 return 0;
1327}
const char * ast_channel_uniqueid(const struct ast_channel *chan)
static struct app_forwards * forwards_create_channel(struct stasis_app *app, struct ast_channel *chan)

References ao2_find, ao2_link_flags, ao2_lock, ao2_ref, ao2_unlock, app, ast_channel_uniqueid(), ast_debug, CHANNEL_ALL, forwards_create_channel(), app_forwards::interested, OBJ_NOLOCK, and OBJ_SEARCH_KEY.

Referenced by call_forwarded_handler(), send_start_msg_snapshots(), stasis_app_subscribe_channel(), and subscribe_channel().

◆ app_subscribe_endpoint()

int app_subscribe_endpoint ( struct stasis_app app,
struct ast_endpoint endpoint 
)

Subscribes an application to a endpoint.

Parameters
appApplication.
endpointEndpoint to subscribe to.
Return values
0on success.
Non-zeroon error.

Definition at line 1526 of file res/stasis/app.c.

1527{
1528 struct app_forwards *forwards;
1529
1530 if (!app) {
1531 return -1;
1532 }
1533
1534 ao2_lock(app->forwards);
1535 /* If subscribed to all, don't subscribe again */
1536 forwards = ao2_find(app->forwards, ENDPOINT_ALL, OBJ_SEARCH_KEY | OBJ_NOLOCK);
1537 if (forwards) {
1538 ao2_unlock(app->forwards);
1539 ao2_ref(forwards, -1);
1540
1541 return 0;
1542 }
1543
1544 forwards = ao2_find(app->forwards,
1545 endpoint ? ast_endpoint_get_id(endpoint) : ENDPOINT_ALL,
1547 if (!forwards) {
1548 int res;
1549
1550 /* Forwards not found, create one */
1551 forwards = forwards_create_endpoint(app, endpoint);
1552 if (!forwards) {
1553 ao2_unlock(app->forwards);
1554
1555 return -1;
1556 }
1557
1558 res = ao2_link_flags(app->forwards, forwards, OBJ_NOLOCK);
1559 if (!res) {
1560 ao2_unlock(app->forwards);
1561 ao2_ref(forwards, -1);
1562
1563 return -1;
1564 }
1565
1566 /* Subscribe for messages */
1568 }
1569
1570 ++forwards->interested;
1571 ast_debug(3, "Endpoint '%s' is %d interested in %s\n",
1572 endpoint ? ast_endpoint_get_id(endpoint) : "ALL",
1573 forwards->interested,
1574 app->name);
1575
1576 ao2_unlock(app->forwards);
1577 ao2_ref(forwards, -1);
1578
1579 return 0;
1580}
const char * ast_endpoint_get_id(const struct ast_endpoint *endpoint)
Gets the tech/resource id of the given endpoint.
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.
Definition: messaging.c:493
static int message_received_handler(const char *endpoint_id, struct ast_json *json_msg, void *pvt)
static struct app_forwards * forwards_create_endpoint(struct stasis_app *app, struct ast_endpoint *endpoint)

References ao2_find, ao2_link_flags, ao2_lock, ao2_ref, ao2_unlock, app, ast_debug, ast_endpoint_get_id(), ENDPOINT_ALL, forwards_create_endpoint(), app_forwards::interested, message_received_handler(), messaging_app_subscribe_endpoint(), OBJ_NOLOCK, and OBJ_SEARCH_KEY.

Referenced by subscribe_endpoint().

◆ app_to_json()

struct ast_json * app_to_json ( const struct stasis_app app)

Create a JSON representation of a stasis_app.

Parameters
appThe application
Returns
JSON blob on success
Return values
NULLon error

Definition at line 1223 of file res/stasis/app.c.

1224{
1225 struct ast_json *json;
1226 struct ast_json *channels;
1227 struct ast_json *bridges;
1228 struct ast_json *endpoints;
1229 struct ao2_iterator i;
1230 struct app_forwards *forwards;
1231
1232 json = ast_json_pack("{s: s, s: [], s: [], s: []}",
1233 "name", app->name,
1234 "channel_ids", "bridge_ids", "endpoint_ids");
1235 if (!json) {
1236 return NULL;
1237 }
1238 channels = ast_json_object_get(json, "channel_ids");
1239 bridges = ast_json_object_get(json, "bridge_ids");
1240 endpoints = ast_json_object_get(json, "endpoint_ids");
1241
1242 i = ao2_iterator_init(app->forwards, 0);
1243 while ((forwards = ao2_iterator_next(&i))) {
1244 struct ast_json *array = NULL;
1245 int append_res;
1246
1247 switch (forwards->forward_type) {
1248 case FORWARD_CHANNEL:
1249 array = channels;
1250 break;
1251 case FORWARD_BRIDGE:
1252 array = bridges;
1253 break;
1254 case FORWARD_ENDPOINT:
1255 array = endpoints;
1256 break;
1257 }
1258
1259 /* If forward_type value is unexpected this will safely return an error. */
1260 append_res = ast_json_array_append(array, ast_json_string_create(forwards->id));
1261 ao2_ref(forwards, -1);
1262
1263 if (append_res != 0) {
1264 ast_log(LOG_ERROR, "Error building response\n");
1266 ast_json_unref(json);
1267
1268 return NULL;
1269 }
1270 }
1272
1273 return json;
1274}
#define ao2_iterator_next(iter)
Definition: astobj2.h:1911
struct ao2_iterator ao2_iterator_init(struct ao2_container *c, int flags) attribute_warn_unused_result
Create an iterator for a container.
void ao2_iterator_destroy(struct ao2_iterator *iter)
Destroy a container iterator.
static struct ao2_container * bridges
Definition: bridge.c:123
static struct channel_usage channels
int ast_json_array_append(struct ast_json *array, struct ast_json *value)
Append to an array.
Definition: json.c:378
struct ast_json * ast_json_pack(char const *format,...)
Helper for creating complex JSON values.
Definition: json.c:612
static struct ao2_container * endpoints
When we need to walk through a container, we use an ao2_iterator to keep track of the current positio...
Definition: astobj2.h:1821
enum forward_type forward_type

References ao2_iterator_destroy(), ao2_iterator_init(), ao2_iterator_next, ao2_ref, app, array(), ast_json_array_append(), ast_json_object_get(), ast_json_pack(), ast_json_string_create(), ast_json_unref(), ast_log, bridges, channels, endpoints, FORWARD_BRIDGE, FORWARD_CHANNEL, FORWARD_ENDPOINT, app_forwards::forward_type, app_forwards::id, LOG_ERROR, and NULL.

Referenced by stasis_app_object_to_json().

◆ app_unsubscribe_bridge()

int app_unsubscribe_bridge ( struct stasis_app app,
struct ast_bridge bridge 
)

Cancel the bridge subscription for an application.

Parameters
appSubscribing application.
bridgeBridge to subscribe to.
Return values
0on success.
Non-zeroon error.

Definition at line 1481 of file res/stasis/app.c.

1482{
1483 if (!app) {
1484 return -1;
1485 }
1486
1487 return app_unsubscribe_bridge_id(app, bridge ? bridge->uniqueid : BRIDGE_ALL);
1488}
int app_unsubscribe_bridge_id(struct stasis_app *app, const char *bridge_id)
Cancel the subscription an app has for a bridge.

References app, app_unsubscribe_bridge_id(), BRIDGE_ALL, and ast_bridge::uniqueid.

Referenced by internal_bridge_after_cb(), and stasis_app_exec().

◆ app_unsubscribe_bridge_id()

int app_unsubscribe_bridge_id ( struct stasis_app app,
const char *  bridge_id 
)

Cancel the subscription an app has for a bridge.

Parameters
appSubscribing application.
bridge_idId of bridge to unsubscribe from.
Return values
0on success.
Non-zeroon error.

Definition at line 1490 of file res/stasis/app.c.

1491{
1492 if (!app) {
1493 return -1;
1494 }
1495
1496 return unsubscribe(app, "bridge", bridge_id, 0);
1497}
static int unsubscribe(struct stasis_app *app, const char *kind, const char *id, int terminate)

References app, and unsubscribe().

Referenced by app_unsubscribe_bridge().

◆ app_unsubscribe_channel()

int app_unsubscribe_channel ( struct stasis_app app,
struct ast_channel chan 
)

Cancel the subscription an app has for a channel.

Parameters
appSubscribing application.
chanChannel to unsubscribe from.
Return values
0on success.
Non-zeroon error.

Definition at line 1379 of file res/stasis/app.c.

1380{
1381 if (!app) {
1382 return -1;
1383 }
1384
1386}
int app_unsubscribe_channel_id(struct stasis_app *app, const char *channel_id)
Cancel the subscription an app has for a channel.

References app, app_unsubscribe_channel_id(), ast_channel_uniqueid(), and CHANNEL_ALL.

Referenced by app_send_end_msg().

◆ app_unsubscribe_channel_id()

int app_unsubscribe_channel_id ( struct stasis_app app,
const char *  channel_id 
)

Cancel the subscription an app has for a channel.

Parameters
appSubscribing application.
channel_idId of channel to unsubscribe from.
Return values
0on success.
Non-zeroon error.

Definition at line 1388 of file res/stasis/app.c.

1389{
1390 if (!app) {
1391 return -1;
1392 }
1393
1394 return unsubscribe(app, "channel", channel_id, 0);
1395}

References app, and unsubscribe().

Referenced by app_unsubscribe_channel(), and send_start_msg_snapshots().

◆ app_unsubscribe_endpoint_id()

int app_unsubscribe_endpoint_id ( struct stasis_app app,
const char *  endpoint_id 
)

Cancel the subscription an app has for a endpoint.

Parameters
appSubscribing application.
endpoint_idId of endpoint to unsubscribe from.
Return values
0on success.
Non-zeroon error.

Definition at line 1587 of file res/stasis/app.c.

1588{
1589 if (!app) {
1590 return -1;
1591 }
1592
1593 return unsubscribe(app, "endpoint", endpoint_id, 0);
1594}

References app, and unsubscribe().

◆ app_update()

void app_update ( struct stasis_app app,
stasis_app_cb  handler,
void *  data 
)

Update the handler and data for a res_stasis application.

If app has been deactivated, this will reactivate it.

Parameters
appApplication to update.
handlerNew application callback.
dataNew data pointer for the callback.

Definition at line 1111 of file res/stasis/app.c.

1112{
1113 ao2_lock(app);
1114 if (app->handler && app->data) {
1115 struct ast_json *msg;
1116
1117 ast_verb(1, "Replacing Stasis app '%s'\n", app->name);
1118
1119 msg = ast_json_pack("{s: s, s: o?, s: s}",
1120 "type", "ApplicationReplaced",
1121 "timestamp", ast_json_timeval(ast_tvnow(), NULL),
1122 "application", app->name);
1123 if (msg) {
1124 /*
1125 * The app must be unlocked before calling 'send' since a handler may
1126 * subsequently attempt to grab the app lock after first obtaining a
1127 * lock for another object, thus causing a deadlock.
1128 */
1129 ao2_unlock(app);
1130 app_send(app, msg);
1131 ao2_lock(app);
1132 ast_json_unref(msg);
1133 if (!app->handler) {
1134 /*
1135 * If the handler disappeared then the app was deactivated. In that
1136 * case don't replace. Re-activation will reset the handler later.
1137 */
1138 ao2_unlock(app);
1139 return;
1140 }
1141 }
1142 } else {
1143 ast_verb(1, "Activating Stasis app '%s'\n", app->name);
1144 }
1145
1146 app->handler = handler;
1147 ao2_replace(app->data, data);
1148 ao2_unlock(app);
1149}
#define ao2_replace(dst, src)
Replace one object reference with another cleaning up the original.
Definition: astobj2.h:501
struct ast_json * ast_json_timeval(const struct timeval tv, const char *zone)
Construct a timeval as JSON.
Definition: json.c:670
void app_send(struct stasis_app *app, struct ast_json *message)
Send a message to an application.
struct timeval ast_tvnow(void)
Returns current timeval. Meant to replace calls to gettimeofday().
Definition: time.h:159

References ao2_lock, ao2_replace, ao2_unlock, app, app_send(), ast_json_pack(), ast_json_timeval(), ast_json_unref(), ast_tvnow(), ast_verb, handler(), and NULL.

Referenced by __stasis_app_register().

◆ ast_app_get_topic()

struct stasis_topic * ast_app_get_topic ( struct stasis_app app)

Returns the stasis topic for an app.

Parameters
appStasis app to get topic of

Definition at line 1028 of file res/stasis/app.c.

1029{
1030 return app->topic;
1031}

References app.

Referenced by app_send_end_msg(), send_start_msg_snapshots(), and stasis_app_user_event().

◆ bridge_app_subscribed()

static int bridge_app_subscribed ( struct stasis_app app,
const char *  uniqueid 
)
static

Helper function for determining if the application is subscribed to a given entity.

Definition at line 720 of file res/stasis/app.c.

721{
722 struct app_forwards *forwards = NULL;
723
724 forwards = ao2_find(app->forwards, uniqueid, OBJ_SEARCH_KEY);
725 if (!forwards) {
726 return 0;
727 }
728
729 ao2_ref(forwards, -1);
730 return 1;
731}

References ao2_find, ao2_ref, app, NULL, and OBJ_SEARCH_KEY.

Referenced by bridge_app_subscribed_involved(), bridge_attended_transfer_handler(), bridge_blind_transfer_handler(), and bridge_merge_handler().

◆ bridge_app_subscribed_involved()

static int bridge_app_subscribed_involved ( struct stasis_app app,
struct ast_bridge_snapshot snapshot 
)
static

Callback function for checking if channels in a bridge are subscribed to.

Definition at line 750 of file res/stasis/app.c.

751{
752 int subscribed = 0;
753 struct ao2_iterator iter;
754 char *uniqueid;
755
756 if (bridge_app_subscribed(app, snapshot->uniqueid)) {
757 return 1;
758 }
759
760 iter = ao2_iterator_init(snapshot->channels, 0);
761 for (; (uniqueid = ao2_iterator_next(&iter)); ao2_ref(uniqueid, -1)) {
762 if (bridge_app_subscribed(app, uniqueid)) {
763 subscribed = 1;
764 ao2_ref(uniqueid, -1);
765 break;
766 }
767 }
769
770 return subscribed;
771}
static int subscribed
Definition: manager.c:1629
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.
const ast_string_field uniqueid
Definition: bridge.h:328
struct ao2_container * channels
Definition: bridge.h:331

References ao2_iterator_destroy(), ao2_iterator_init(), ao2_iterator_next, ao2_ref, app, bridge_app_subscribed(), ast_bridge_snapshot::channels, subscribed, and ast_bridge_snapshot::uniqueid.

Referenced by bridge_attended_transfer_handler(), and bridge_blind_transfer_handler().

◆ bridge_attended_transfer_handler()

static void bridge_attended_transfer_handler ( void *  data,
struct stasis_subscription sub,
struct stasis_message message 
)
static

Definition at line 786 of file res/stasis/app.c.

788{
789 struct stasis_app *app = data;
791 int subscribed = 0;
792
794 if (!subscribed) {
796 }
797 if (!subscribed && transfer_msg->to_transferee.bridge_snapshot) {
799 }
800 if (!subscribed && transfer_msg->to_transfer_target.bridge_snapshot) {
802 }
803
804 if (!subscribed) {
805 switch (transfer_msg->dest_type) {
808 break;
811 if (!subscribed) {
813 }
814 break;
815 break;
818 if (!subscribed) {
820 }
821 break;
822 default:
823 break;
824 }
825 }
826
827 if (subscribed) {
828 stasis_publish(app->topic, message);
829 }
830}
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.
void * stasis_message_data(const struct stasis_message *msg)
Get the data contained in a message.
void stasis_publish(struct stasis_topic *topic, struct stasis_message *message)
Publish a message to a topic's subscribers.
Definition: stasis.c:1511
@ AST_ATTENDED_TRANSFER_DEST_BRIDGE_MERGE
@ AST_ATTENDED_TRANSFER_DEST_LINK
@ AST_ATTENDED_TRANSFER_DEST_THREEWAY
Message representing attended transfer.
union ast_attended_transfer_message::@284 dest
enum ast_attended_transfer_dest_type dest_type
struct ast_channel_snapshot * links[2]
struct ast_bridge_channel_snapshot_pair to_transfer_target
struct ast_bridge_channel_snapshot_pair threeway
struct ast_bridge_channel_snapshot_pair to_transferee
char bridge[AST_UUID_STR_LEN]
struct ast_bridge_snapshot * bridge_snapshot
struct ast_channel_snapshot * channel_snapshot
const ast_string_field uniqueid
struct ast_channel_snapshot_base * base

References app, AST_ATTENDED_TRANSFER_DEST_BRIDGE_MERGE, AST_ATTENDED_TRANSFER_DEST_LINK, AST_ATTENDED_TRANSFER_DEST_THREEWAY, ast_channel_snapshot::base, ast_attended_transfer_message::bridge, bridge_app_subscribed(), bridge_app_subscribed_involved(), ast_bridge_channel_snapshot_pair::bridge_snapshot, ast_bridge_channel_snapshot_pair::channel_snapshot, stasis_app::data, ast_attended_transfer_message::dest, ast_attended_transfer_message::dest_type, ast_attended_transfer_message::links, stasis_message_data(), stasis_publish(), subscribed, ast_attended_transfer_message::threeway, ast_attended_transfer_message::to_transfer_target, ast_attended_transfer_message::to_transferee, and ast_channel_snapshot_base::uniqueid.

Referenced by app_create().

◆ bridge_blind_transfer_handler()

static void bridge_blind_transfer_handler ( void *  data,
struct stasis_subscription sub,
struct stasis_message message 
)
static

Definition at line 773 of file res/stasis/app.c.

775{
776 struct stasis_app *app = data;
778 struct ast_bridge_snapshot *bridge = transfer_msg->bridge;
779
780 if (bridge_app_subscribed(app, transfer_msg->transferer->base->uniqueid) ||
781 (bridge && bridge_app_subscribed_involved(app, bridge))) {
782 stasis_publish(app->topic, message);
783 }
784}
Message published during a blind transfer.
struct ast_bridge_snapshot * bridge
struct ast_channel_snapshot * transferer
Structure that contains a snapshot of information about a bridge.
Definition: bridge.h:314

References app, ast_channel_snapshot::base, ast_blind_transfer_message::bridge, bridge_app_subscribed(), bridge_app_subscribed_involved(), stasis_app::data, stasis_message_data(), stasis_publish(), ast_blind_transfer_message::transferer, and ast_channel_snapshot_base::uniqueid.

Referenced by app_create().

◆ bridge_find()

static void * bridge_find ( const struct stasis_app app,
const char *  id 
)
static

Definition at line 1513 of file res/stasis/app.c.

1514{
1516}
struct ast_bridge * stasis_app_bridge_find_by_id(const char *bridge_id)
Returns the bridge with the given id.
Definition: res_stasis.c:774

References stasis_app_bridge_find_by_id().

◆ bridge_merge_handler()

static void bridge_merge_handler ( void *  data,
struct stasis_subscription sub,
struct stasis_message message 
)
static

Definition at line 733 of file res/stasis/app.c.

735{
736 struct stasis_app *app = data;
737 struct ast_bridge_merge_message *merge;
738
740
741 /* Find out if we're subscribed to either bridge */
742 if (bridge_app_subscribed(app, merge->from->uniqueid) ||
744 /* Forward the message to the app */
745 stasis_publish(app->topic, message);
746 }
747}
Message representing the merge of two bridges.
struct ast_bridge_snapshot * from
struct ast_bridge_snapshot * to

References app, bridge_app_subscribed(), stasis_app::data, ast_bridge_merge_message::from, stasis_message_data(), stasis_publish(), ast_bridge_merge_message::to, and ast_bridge_snapshot::uniqueid.

Referenced by app_create().

◆ bridge_subscription_change_handler()

static void bridge_subscription_change_handler ( void *  data,
struct stasis_subscription sub,
struct stasis_message message 
)
static

Definition at line 832 of file res/stasis/app.c.

834{
835 struct stasis_app *app = data;
836
839 }
840}
struct stasis_forward * sub
Definition: res_corosync.c:240
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.
Definition: stasis.c:1174

References ao2_cleanup, app, stasis_app::data, stasis_subscription_final_message(), and sub.

Referenced by app_create().

◆ call_forwarded_handler()

static void call_forwarded_handler ( struct stasis_app app,
struct stasis_message message 
)
static

Definition at line 318 of file res/stasis/app.c.

319{
321 struct ast_channel_snapshot *snapshot = ast_multi_channel_blob_get_channel(payload, "forwarded");
322 struct ast_channel *chan;
323
324 if (!snapshot) {
325 return;
326 }
327
329 if (!chan) {
330 return;
331 }
332
334 ast_channel_unref(chan);
335}
#define ast_channel_unref(c)
Decrease channel reference count.
Definition: channel.h:2958
struct ast_channel * ast_channel_get_by_name(const char *name)
Find a channel by name.
Definition: channel.c:1454
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.
int app_subscribe_channel(struct stasis_app *app, struct ast_channel *chan)
Subscribes an application to a channel.
Structure representing a snapshot of channel state.
Main Channel structure associated with a channel.
struct ast_channel_snapshot * snapshot
A multi channel blob data structure for multi_channel_blob stasis messages.

References app, app_subscribe_channel(), ast_channel_get_by_name(), ast_channel_unref, ast_multi_channel_blob_get_channel(), ast_channel_snapshot::base, ast_channel::snapshot, stasis_message_data(), and ast_channel_snapshot_base::uniqueid.

◆ channel_callerid()

static struct ast_json * channel_callerid ( struct ast_channel_snapshot old_snapshot,
struct ast_channel_snapshot new_snapshot,
const struct timeval *  tv 
)
static

Definition at line 479 of file res/stasis/app.c.

483{
484 struct ast_json *json_channel;
485
486 /* No NewCallerid event on first channel snapshot */
487 if (!old_snapshot) {
488 return NULL;
489 }
490
491 if (ast_channel_snapshot_caller_id_equal(old_snapshot, new_snapshot)) {
492 return NULL;
493 }
494
495 json_channel = ast_channel_snapshot_to_json(new_snapshot, stasis_app_get_sanitizer());
496 if (!json_channel) {
497 return NULL;
498 }
499
500 return ast_json_pack("{s: s, s: o, s: i, s: s, s: o}",
501 "type", "ChannelCallerId",
502 "timestamp", ast_json_timeval(*tv, NULL),
503 "caller_presentation", new_snapshot->caller->pres,
504 "caller_presentation_txt", ast_describe_caller_presentation(
505 new_snapshot->caller->pres),
506 "channel", json_channel);
507}
const char * ast_describe_caller_presentation(int data)
Convert caller ID pres value to explanatory string.
Definition: callerid.c:1364
struct stasis_message_sanitizer * stasis_app_get_sanitizer(void)
Get the Stasis message sanitizer for app_stasis applications.
Definition: res_stasis.c:2271
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.
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 ast_channel_snapshot_caller * caller

References ast_channel_snapshot_caller_id_equal(), ast_channel_snapshot_to_json(), ast_describe_caller_presentation(), ast_json_pack(), ast_json_timeval(), ast_channel_snapshot::caller, NULL, ast_channel_snapshot_caller::pres, and stasis_app_get_sanitizer().

◆ channel_connected_line()

static struct ast_json * channel_connected_line ( struct ast_channel_snapshot old_snapshot,
struct ast_channel_snapshot new_snapshot,
const struct timeval *  tv 
)
static

Definition at line 509 of file res/stasis/app.c.

513{
514 struct ast_json *json_channel;
515
516 /* No ChannelConnectedLine event on first channel snapshot */
517 if (!old_snapshot) {
518 return NULL;
519 }
520
521 if (ast_channel_snapshot_connected_line_equal(old_snapshot, new_snapshot)) {
522 return NULL;
523 }
524
525 json_channel = ast_channel_snapshot_to_json(new_snapshot, stasis_app_get_sanitizer());
526 if (!json_channel) {
527 return NULL;
528 }
529
530 return ast_json_pack("{s: s, s: o, s: o}",
531 "type", "ChannelConnectedLine",
532 "timestamp", ast_json_timeval(*tv, NULL),
533 "channel", json_channel);
534}
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.

References ast_channel_snapshot_connected_line_equal(), ast_channel_snapshot_to_json(), ast_json_pack(), ast_json_timeval(), NULL, and stasis_app_get_sanitizer().

◆ channel_created_event()

static struct ast_json * channel_created_event ( struct ast_channel_snapshot snapshot,
const struct timeval *  tv 
)
static

Definition at line 393 of file res/stasis/app.c.

396{
397 return simple_channel_event("ChannelCreated", snapshot, tv);
398}
static struct ast_json * simple_channel_event(const char *type, struct ast_channel_snapshot *snapshot, const struct timeval *tv)

References simple_channel_event().

Referenced by channel_state().

◆ channel_destroyed_event()

static struct ast_json * channel_destroyed_event ( struct ast_channel_snapshot snapshot,
const struct timeval *  tv 
)
static

Definition at line 400 of file res/stasis/app.c.

403{
404 struct ast_json *json_channel = ast_channel_snapshot_to_json(snapshot, stasis_app_get_sanitizer());
405
406 if (!json_channel) {
407 return NULL;
408 }
409
410 return ast_json_pack("{s: s, s: o, s: i, s: s, s: o}",
411 "type", "ChannelDestroyed",
412 "timestamp", ast_json_timeval(*tv, NULL),
413 "cause", snapshot->hangup->cause,
414 "cause_txt", ast_cause2str(snapshot->hangup->cause),
415 "channel", json_channel);
416}
const char * ast_cause2str(int cause) attribute_pure
Gives the string form of a given cause code.
Definition: channel.c:612
struct ast_channel_snapshot_hangup * hangup

References ast_cause2str(), ast_channel_snapshot_to_json(), ast_json_pack(), ast_json_timeval(), ast_channel_snapshot_hangup::cause, ast_channel_snapshot::hangup, NULL, and stasis_app_get_sanitizer().

Referenced by channel_state().

◆ channel_dialplan()

static struct ast_json * channel_dialplan ( struct ast_channel_snapshot old_snapshot,
struct ast_channel_snapshot new_snapshot,
const struct timeval *  tv 
)
static

Definition at line 445 of file res/stasis/app.c.

449{
450 struct ast_json *json_channel;
451
452 /* No Newexten event on first channel snapshot */
453 if (!old_snapshot) {
454 return NULL;
455 }
456
457 /* Empty application is not valid for a Newexten event */
458 if (ast_strlen_zero(new_snapshot->dialplan->appl)) {
459 return NULL;
460 }
461
462 if (ast_channel_snapshot_cep_equal(old_snapshot, new_snapshot)) {
463 return NULL;
464 }
465
466 json_channel = ast_channel_snapshot_to_json(new_snapshot, stasis_app_get_sanitizer());
467 if (!json_channel) {
468 return NULL;
469 }
470
471 return ast_json_pack("{s: s, s: o, s: s, s: s, s: o}",
472 "type", "ChannelDialplan",
473 "timestamp", ast_json_timeval(*tv, NULL),
474 "dialplan_app", new_snapshot->dialplan->appl,
475 "dialplan_app_data", AST_JSON_UTF8_VALIDATE(new_snapshot->dialplan->data),
476 "channel", json_channel);
477}
#define AST_JSON_UTF8_VALIDATE(str)
Check str for UTF-8 and replace with an empty string if fails the check.
Definition: json.h:224
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.
const ast_string_field data
const ast_string_field appl
struct ast_channel_snapshot_dialplan * dialplan

References ast_channel_snapshot_dialplan::appl, ast_channel_snapshot_cep_equal(), ast_channel_snapshot_to_json(), ast_json_pack(), ast_json_timeval(), AST_JSON_UTF8_VALIDATE, ast_strlen_zero(), ast_channel_snapshot_dialplan::data, ast_channel_snapshot::dialplan, NULL, and stasis_app_get_sanitizer().

◆ channel_find()

static void * channel_find ( const struct stasis_app app,
const char *  id 
)
static

Definition at line 1410 of file res/stasis/app.c.

1411{
1412 return ast_channel_get_by_name(id);
1413}

References ast_channel_get_by_name().

◆ channel_state()

static struct ast_json * channel_state ( struct ast_channel_snapshot old_snapshot,
struct ast_channel_snapshot new_snapshot,
const struct timeval *  tv 
)
static

Handle channel state changes.

Definition at line 426 of file res/stasis/app.c.

430{
431 struct ast_channel_snapshot *snapshot = new_snapshot ?
432 new_snapshot : old_snapshot;
433
434 if (!old_snapshot) {
435 return channel_created_event(snapshot, tv);
436 } else if (ast_test_flag(&new_snapshot->flags, AST_FLAG_DEAD)) {
437 return channel_destroyed_event(snapshot, tv);
438 } else if (old_snapshot->state != new_snapshot->state) {
439 return channel_state_change_event(snapshot, tv);
440 }
441
442 return NULL;
443}
@ AST_FLAG_DEAD
Definition: channel.h:1045
static struct ast_json * channel_destroyed_event(struct ast_channel_snapshot *snapshot, const struct timeval *tv)
static struct ast_json * channel_created_event(struct ast_channel_snapshot *snapshot, const struct timeval *tv)
static struct ast_json * channel_state_change_event(struct ast_channel_snapshot *snapshot, const struct timeval *tv)
enum ast_channel_state state
struct ast_flags flags
#define ast_test_flag(p, flag)
Definition: utils.h:63

References AST_FLAG_DEAD, ast_test_flag, channel_created_event(), channel_destroyed_event(), channel_state_change_event(), ast_channel_snapshot::flags, NULL, and ast_channel_snapshot::state.

◆ channel_state_change_event()

static struct ast_json * channel_state_change_event ( struct ast_channel_snapshot snapshot,
const struct timeval *  tv 
)
static

Definition at line 418 of file res/stasis/app.c.

421{
422 return simple_channel_event("ChannelStateChange", snapshot, tv);
423}

References simple_channel_event().

Referenced by channel_state().

◆ endpoint_find()

static void * endpoint_find ( const struct stasis_app app,
const char *  id 
)
static

Definition at line 1609 of file res/stasis/app.c.

1610{
1611 return ast_endpoint_find_by_id(id);
1612}
struct ast_endpoint * ast_endpoint_find_by_id(const char *id)
Finds the endpoint with the given tech[/resource] id.

References ast_endpoint_find_by_id().

◆ endpoint_state_cb()

static void endpoint_state_cb ( void *  data,
struct stasis_subscription sub,
struct stasis_message message 
)
static

Definition at line 190 of file res/stasis/app.c.

192{
193 struct stasis_app *app = data;
194
195 stasis_publish(app->topic, message);
196}

References app, stasis_app::data, and stasis_publish().

Referenced by forwards_create_endpoint().

◆ forwards_create()

static struct app_forwards * forwards_create ( struct stasis_app app,
const char *  id 
)
static

Definition at line 116 of file res/stasis/app.c.

118{
119 struct app_forwards *forwards;
120
121 if (!app || ast_strlen_zero(id)) {
122 return NULL;
123 }
124
125 forwards = ao2_t_alloc(sizeof(*forwards) + strlen(id) + 1, forwards_dtor, id);
126 if (!forwards) {
127 return NULL;
128 }
129
130 strcpy(forwards->id, id); /* SAFE */
131
132 return forwards;
133}
#define ao2_t_alloc(data_size, destructor_fn, debug_msg)
Definition: astobj2.h:407
static void forwards_dtor(void *obj)

References ao2_t_alloc, app, ast_strlen_zero(), forwards_dtor(), app_forwards::id, and NULL.

Referenced by forwards_create_bridge(), forwards_create_channel(), and forwards_create_endpoint().

◆ forwards_create_bridge()

static struct app_forwards * forwards_create_bridge ( struct stasis_app app,
struct ast_bridge bridge 
)
static

Forward a bridge's topics to an app

Definition at line 164 of file res/stasis/app.c.

166{
167 struct app_forwards *forwards;
168
169 if (!app) {
170 return NULL;
171 }
172
173 forwards = forwards_create(app, bridge ? bridge->uniqueid : BRIDGE_ALL);
174 if (!forwards) {
175 return NULL;
176 }
177
178 forwards->forward_type = FORWARD_BRIDGE;
179 forwards->topic_forward = stasis_forward_all(ast_bridge_topic(bridge), app->topic);
180
181 if (!forwards->topic_forward && bridge) {
182 forwards_unsubscribe(forwards);
183 ao2_ref(forwards, -1);
184 return NULL;
185 }
186
187 return forwards;
188}
static void forwards_unsubscribe(struct app_forwards *forwards)
static struct app_forwards * forwards_create(struct stasis_app *app, const char *id)
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.
Definition: stasis.c:1578
struct stasis_topic * ast_bridge_topic(struct ast_bridge *bridge)
A topic which publishes the events for a particular bridge.
struct stasis_forward * topic_forward

References ao2_ref, app, ast_bridge_topic(), BRIDGE_ALL, FORWARD_BRIDGE, app_forwards::forward_type, forwards_create(), forwards_unsubscribe(), NULL, stasis_forward_all(), app_forwards::topic_forward, and ast_bridge::uniqueid.

Referenced by app_subscribe_bridge().

◆ forwards_create_channel()

static struct app_forwards * forwards_create_channel ( struct stasis_app app,
struct ast_channel chan 
)
static

Forward a channel's topics to an app

Definition at line 136 of file res/stasis/app.c.

138{
139 struct app_forwards *forwards;
140
141 if (!app) {
142 return NULL;
143 }
144
145 forwards = forwards_create(app, chan ? ast_channel_uniqueid(chan) : CHANNEL_ALL);
146 if (!forwards) {
147 return NULL;
148 }
149
150 forwards->forward_type = FORWARD_CHANNEL;
153 app->topic);
154
155 if (!forwards->topic_forward) {
156 ao2_ref(forwards, -1);
157 return NULL;
158 }
159
160 return forwards;
161}
struct stasis_topic * ast_channel_topic(struct ast_channel *chan)
A topic which publishes the events for a particular channel.
struct stasis_topic * ast_channel_topic_all(void)
A topic which publishes the events for all channels.

References ao2_ref, app, ast_channel_topic(), ast_channel_topic_all(), ast_channel_uniqueid(), CHANNEL_ALL, FORWARD_CHANNEL, app_forwards::forward_type, forwards_create(), NULL, stasis_forward_all(), and app_forwards::topic_forward.

Referenced by app_subscribe_channel().

◆ forwards_create_endpoint()

static struct app_forwards * forwards_create_endpoint ( struct stasis_app app,
struct ast_endpoint endpoint 
)
static

Forward a endpoint's topics to an app

Definition at line 199 of file res/stasis/app.c.

201{
202 struct app_forwards *forwards;
203 int ret = 0;
204
205 if (!app) {
206 return NULL;
207 }
208
209 forwards = forwards_create(app, endpoint ? ast_endpoint_get_id(endpoint) : ENDPOINT_ALL);
210 if (!forwards) {
211 return NULL;
212 }
213
214 forwards->forward_type = FORWARD_ENDPOINT;
215 if (endpoint) {
217 app->topic);
219 ast_endpoint_topic_cached(endpoint), app->topic);
220
221 if (!forwards->topic_forward || !forwards->topic_cached_forward) {
222 /* Half-subscribed is a bad thing */
223 forwards_unsubscribe(forwards);
224 ao2_ref(forwards, -1);
225 return NULL;
226 }
227 } else {
228 /* Since endpoint subscriptions also subscribe to channels, in the case
229 * of all endpoint subscriptions, we only want messages for the endpoints.
230 * As such, we route those particular messages and then re-publish them
231 * on the app's topic.
232 */
233 ast_assert(app->endpoint_router == NULL);
235 if (!app->endpoint_router) {
236 forwards_unsubscribe(forwards);
237 ao2_ref(forwards, -1);
238 return NULL;
239 }
240
241 ret |= stasis_message_router_add(app->endpoint_router,
243 ret |= stasis_message_router_add(app->endpoint_router,
245
246 if (ret) {
247 ao2_ref(app->endpoint_router, -1);
248 app->endpoint_router = NULL;
249 ao2_ref(forwards, -1);
250 return NULL;
251 }
252 }
253
254 return forwards;
255}
struct stasis_topic * ast_endpoint_topic_cached(struct ast_endpoint *endpoint)
Returns the topic for a specific endpoint.
struct stasis_message_type * ast_endpoint_contact_state_type(void)
Message type for endpoint contact state changes.
struct stasis_topic * ast_endpoint_topic(struct ast_endpoint *endpoint)
Returns the topic for a specific endpoint.
struct stasis_topic * ast_endpoint_topic_all_cached(void)
Cached topic for all endpoint related messages.
struct stasis_message_type * ast_endpoint_state_type(void)
Message type for endpoint state changes.
static void endpoint_state_cb(void *data, struct stasis_subscription *sub, struct stasis_message *message)
struct stasis_forward * topic_cached_forward

References ao2_ref, app, ast_assert, ast_endpoint_contact_state_type(), ast_endpoint_get_id(), ast_endpoint_state_type(), ast_endpoint_topic(), ast_endpoint_topic_all_cached(), ast_endpoint_topic_cached(), ENDPOINT_ALL, endpoint_state_cb(), FORWARD_ENDPOINT, app_forwards::forward_type, forwards_create(), forwards_unsubscribe(), NULL, stasis_forward_all(), stasis_message_router_add(), stasis_message_router_create, app_forwards::topic_cached_forward, and app_forwards::topic_forward.

Referenced by app_subscribe_endpoint().

◆ forwards_dtor()

static void forwards_dtor ( void *  obj)
static

Definition at line 98 of file res/stasis/app.c.

99{
100#ifdef AST_DEVMODE
101 struct app_forwards *forwards = obj;
102#endif /* AST_DEVMODE */
103
104 ast_assert(forwards->topic_forward == NULL);
106}

References ast_assert, NULL, app_forwards::topic_cached_forward, and app_forwards::topic_forward.

Referenced by forwards_create().

◆ forwards_filter_by_type()

static int forwards_filter_by_type ( void *  obj,
void *  arg,
int  flags 
)
static

Definition at line 1156 of file res/stasis/app.c.

1157{
1158 struct app_forwards *forward = obj;
1159 enum forward_type *forward_type = arg;
1160
1161 if (forward->forward_type == *forward_type) {
1162 return CMP_MATCH;
1163 }
1164
1165 return 0;
1166}
@ CMP_MATCH
Definition: astobj2.h:1027
forward_type

References CMP_MATCH, and app_forwards::forward_type.

Referenced by stasis_app_to_cli().

◆ forwards_sort()

static int forwards_sort ( const void *  obj_left,
const void *  obj_right,
int  flags 
)
static

Definition at line 257 of file res/stasis/app.c.

258{
259 const struct app_forwards *object_left = obj_left;
260 const struct app_forwards *object_right = obj_right;
261 const char *right_key = obj_right;
262 int cmp;
263
264 switch (flags & (OBJ_POINTER | OBJ_KEY | OBJ_PARTIAL_KEY)) {
265 case OBJ_POINTER:
266 right_key = object_right->id;
267 /* Fall through */
268 case OBJ_KEY:
269 cmp = strcmp(object_left->id, right_key);
270 break;
271 case OBJ_PARTIAL_KEY:
272 /*
273 * We could also use a partial key struct containing a length
274 * so strlen() does not get called for every comparison instead.
275 */
276 cmp = strncmp(object_left->id, right_key, strlen(right_key));
277 break;
278 default:
279 /* Sort can only work on something with a full or partial key. */
280 ast_assert(0);
281 cmp = 0;
282 break;
283 }
284 return cmp;
285}
#define OBJ_KEY
Definition: astobj2.h:1151
#define OBJ_POINTER
Definition: astobj2.h:1150
#define OBJ_PARTIAL_KEY
Definition: astobj2.h:1152

References ast_assert, app_forwards::id, OBJ_KEY, OBJ_PARTIAL_KEY, and OBJ_POINTER.

Referenced by app_create().

◆ forwards_unsubscribe()

static void forwards_unsubscribe ( struct app_forwards forwards)
static

Definition at line 108 of file res/stasis/app.c.

109{
111 forwards->topic_forward = NULL;
113 forwards->topic_cached_forward = NULL;
114}
struct stasis_forward * stasis_forward_cancel(struct stasis_forward *forward)
Definition: stasis.c:1548

References NULL, stasis_forward_cancel(), app_forwards::topic_cached_forward, and app_forwards::topic_forward.

Referenced by forwards_create_bridge(), forwards_create_endpoint(), and unsubscribe().

◆ message_received_handler()

static int message_received_handler ( const char *  endpoint_id,
struct ast_json json_msg,
void *  pvt 
)
static

Definition at line 584 of file res/stasis/app.c.

585{
586 struct ast_endpoint_snapshot *snapshot;
587 struct ast_json *json_endpoint;
588 struct ast_json *message;
589 struct stasis_app *app = pvt;
590 char *tech;
591 char *resource;
592
593 tech = ast_strdupa(endpoint_id);
594 resource = strchr(tech, '/');
595 if (resource) {
596 resource[0] = '\0';
597 resource++;
598 }
599
600 if (ast_strlen_zero(tech) || ast_strlen_zero(resource)) {
601 return -1;
602 }
603
604 snapshot = ast_endpoint_latest_snapshot(tech, resource);
605 if (!snapshot) {
606 return -1;
607 }
608
609 json_endpoint = ast_endpoint_snapshot_to_json(snapshot, stasis_app_get_sanitizer());
610 ao2_ref(snapshot, -1);
611 if (!json_endpoint) {
612 return -1;
613 }
614
615 message = ast_json_pack("{s: s, s: o, s: o, s: o}",
616 "type", "TextMessageReceived",
617 "timestamp", ast_json_timeval(ast_tvnow(), NULL),
618 "endpoint", json_endpoint,
619 "message", ast_json_ref(json_msg));
620 if (message) {
623 }
624
625 return 0;
626}
#define ast_strdupa(s)
duplicate a string in memory from the stack
Definition: astmm.h:298
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.
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.
A snapshot of an endpoint's state.

References ao2_ref, app, app_send(), ast_endpoint_latest_snapshot(), ast_endpoint_snapshot_to_json(), ast_json_pack(), ast_json_ref(), ast_json_timeval(), ast_json_unref(), ast_strdupa, ast_strlen_zero(), ast_tvnow(), NULL, and stasis_app_get_sanitizer().

Referenced by app_subscribe_endpoint().

◆ simple_bridge_event()

static struct ast_json * simple_bridge_event ( const char *  type,
struct ast_bridge_snapshot snapshot,
const struct timeval *  tv 
)
static

Definition at line 666 of file res/stasis/app.c.

670{
671 struct ast_json *json_bridge = ast_bridge_snapshot_to_json(snapshot, stasis_app_get_sanitizer());
672 if (!json_bridge) {
673 return NULL;
674 }
675
676 return ast_json_pack("{s: s, s: o, s: o}",
677 "type", type,
678 "timestamp", ast_json_timeval(*tv, NULL),
679 "bridge", json_bridge);
680}
static const char type[]
Definition: chan_ooh323.c:109
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.

References ast_bridge_snapshot_to_json(), ast_json_pack(), ast_json_timeval(), NULL, stasis_app_get_sanitizer(), and type.

Referenced by sub_bridge_update_handler().

◆ simple_channel_event()

static struct ast_json * simple_channel_event ( const char *  type,
struct ast_channel_snapshot snapshot,
const struct timeval *  tv 
)
static

Definition at line 376 of file res/stasis/app.c.

380{
381 struct ast_json *json_channel = ast_channel_snapshot_to_json(snapshot, stasis_app_get_sanitizer());
382
383 if (!json_channel) {
384 return NULL;
385 }
386
387 return ast_json_pack("{s: s, s: o, s: o}",
388 "type", type,
389 "timestamp", ast_json_timeval(*tv, NULL),
390 "channel", json_channel);
391}

References ast_channel_snapshot_to_json(), ast_json_pack(), ast_json_timeval(), NULL, stasis_app_get_sanitizer(), and type.

Referenced by channel_created_event(), and channel_state_change_event().

◆ simple_endpoint_event()

static struct ast_json * simple_endpoint_event ( const char *  type,
struct ast_endpoint_snapshot snapshot,
const struct timeval *  tv 
)
static

Definition at line 567 of file res/stasis/app.c.

571{
572 struct ast_json *json_endpoint = ast_endpoint_snapshot_to_json(snapshot, stasis_app_get_sanitizer());
573
574 if (!json_endpoint) {
575 return NULL;
576 }
577
578 return ast_json_pack("{s: s, s: o, s: o}",
579 "type", type,
580 "timestamp", ast_json_timeval(*tv, NULL),
581 "endpoint", json_endpoint);
582}

References ast_endpoint_snapshot_to_json(), ast_json_pack(), ast_json_timeval(), NULL, stasis_app_get_sanitizer(), and type.

Referenced by sub_endpoint_update_handler().

◆ stasis_app_event_allowed()

int stasis_app_event_allowed ( const char *  app_name,
struct ast_json event 
)

Check if the given event should be filtered.

Attempts first to find the event in the application's disallowed events list. If found then the event won't be sent to the remote. If not found in the disallowed list then a search is done to see if it can be found in the allowed list. If found the event message is sent, otherwise it is not sent.

Parameters
app_nameThe application name
eventThe event to check
Returns
True if allowed, false otherwise

Definition at line 1734 of file res/stasis/app.c.

1735{
1737 int res;
1738
1739 if (!app) {
1740 return 0;
1741 }
1742
1743 ao2_lock(app);
1744 res = !app_event_filter_matched(app->events_disallowed, event, 0) &&
1745 app_event_filter_matched(app->events_allowed, event, 1);
1746 ao2_unlock(app);
1747 ao2_ref(app, -1);
1748
1749 return res;
1750}
const char * app_name(struct ast_app *app)
Definition: pbx_app.c:463
static int app_event_filter_matched(struct ast_json *array, struct ast_json *event, int empty)
struct stasis_app * stasis_app_get_by_name(const char *name)
Retrieve a handle to a Stasis application by its name.
Definition: res_stasis.c:1701

References ao2_lock, ao2_ref, ao2_unlock, app, app_event_filter_matched(), app_name(), and stasis_app_get_by_name().

Referenced by stasis_app_message_handler().

◆ stasis_app_event_filter_set()

int stasis_app_event_filter_set ( struct stasis_app app,
struct ast_json filter 
)

Set the application's event type filter.

Parameters
appThe application
filterThe allowed and/or disallowed event filter
Returns
0 if successfully set

Definition at line 1708 of file res/stasis/app.c.

1709{
1711}
static int app_events_allowed_set(struct stasis_app *app, struct ast_json *filter)
static int app_events_disallowed_set(struct stasis_app *app, struct ast_json *filter)

References app, app_events_allowed_set(), app_events_disallowed_set(), and filter().

Referenced by ast_ari_applications_filter().

◆ stasis_app_event_filter_to_json()

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.

Parameters
appThe application
jsonThe json object to add the filter data to
Returns
The given json object

Definition at line 1636 of file res/stasis/app.c.

1637{
1638 if (!app || !json) {
1639 return json;
1640 }
1641
1642 ast_json_object_set(json, "events_allowed", app->events_allowed ?
1643 ast_json_ref(app->events_allowed) : ast_json_array_create());
1644 ast_json_object_set(json, "events_disallowed", app->events_disallowed ?
1645 ast_json_ref(app->events_disallowed) : ast_json_array_create());
1646
1647 return json;
1648}
struct ast_json * ast_json_array_create(void)
Create a empty JSON array.
Definition: json.c:362

References app, ast_json_array_create(), ast_json_object_set(), and ast_json_ref().

Referenced by stasis_app_object_to_json().

◆ stasis_app_get_debug()

int stasis_app_get_debug ( struct stasis_app app)

Get debug status of an application.

Parameters
appThe app to check
Returns
The debug flag for the app || the global debug flag

Definition at line 863 of file res/stasis/app.c.

864{
865 return (app ? app->debug : 0) || global_debug;
866}
int global_debug

References app, and global_debug.

◆ stasis_app_get_debug_by_name()

int stasis_app_get_debug_by_name ( const char *  app_name)

Get debug status of an application.

Parameters
app_nameThe app_name to check
Returns
The debug flag for the app || the global debug flag

Definition at line 868 of file res/stasis/app.c.

869{
870 int debug_enabled = 0;
871
872 if (global_debug) {
873 debug_enabled = 1;
874 } else {
876
877 if (app) {
878 if (app->debug) {
879 debug_enabled = 1;
880 }
881 ao2_ref(app, -1);
882 }
883 }
884 return debug_enabled;
885}

References ao2_ref, app, app_name(), global_debug, and stasis_app_get_by_name().

Referenced by ast_ari_callback(), and stasis_app_message_handler().

◆ stasis_app_name()

const char * stasis_app_name ( const struct stasis_app app)

Retrieve an application's name.

Parameters
appAn application
Returns
The name of the application.

Definition at line 1151 of file res/stasis/app.c.

1152{
1153 return app->name;
1154}

References app.

Referenced by app_compare(), app_hash(), app_send_end_msg(), app_subscribe(), app_unsubscribe(), append_name(), ari_set_debug(), bridge_stasis_push_peek(), cleanup_cb(), device_state_subscription_create(), devices_to_json(), find_device_state_subscription(), send_start_msg_snapshots(), stasis_app_exec(), and subscribe_device_state().

◆ stasis_app_register_event_sources()

void stasis_app_register_event_sources ( void  )

Register core event sources.

Definition at line 1622 of file res/stasis/app.c.

1623{
1627}
struct stasis_app_event_source bridge_event_source
struct stasis_app_event_source channel_event_source
struct stasis_app_event_source endpoint_event_source
void stasis_app_register_event_source(struct stasis_app_event_source *obj)
Register an application event source.
Definition: res_stasis.c:1823

References bridge_event_source, channel_event_source, endpoint_event_source, and stasis_app_register_event_source().

Referenced by load_module().

◆ stasis_app_set_debug()

void stasis_app_set_debug ( struct stasis_app app,
int  debug 
)

Enable/disable request/response and event logging on an application.

Parameters
appThe app to debug
debugIf non-zero, enable debugging. If zero, disable.

Definition at line 842 of file res/stasis/app.c.

843{
844 if (!app) {
845 return;
846 }
847
848 app->debug = debug;
849}
static int debug
Global debug status.
Definition: res_xmpp.c:441

References app, and debug.

Referenced by ari_set_debug(), and stasis_app_set_global_debug().

◆ stasis_app_set_debug_by_name()

void stasis_app_set_debug_by_name ( const char *  app_name,
int  debug 
)

Enable/disable request/response and event logging on an application.

Parameters
app_nameThe app name to debug
debugIf non-zero, enable debugging. If zero, disable.

Definition at line 851 of file res/stasis/app.c.

852{
854
855 if (!app) {
856 return;
857 }
858
859 app->debug = debug;
861}

References ao2_cleanup, app, app_name(), debug, and stasis_app_get_by_name().

◆ stasis_app_set_global_debug()

void stasis_app_set_global_debug ( int  debug)

Enable/disable request/response and event logging on all applications.

Parameters
debugIf non-zero, enable debugging. If zero, disable.

Definition at line 887 of file res/stasis/app.c.

888{
890 if (!global_debug) {
891 struct ao2_container *app_names = stasis_app_get_all();
892 struct ao2_iterator it_app_names;
893 char *app_name;
894 struct stasis_app *app;
895
896 if (!app_names || !ao2_container_count(app_names)) {
897 ao2_cleanup(app_names);
898 return;
899 }
900
901 it_app_names = ao2_iterator_init(app_names, 0);
902 while ((app_name = ao2_iterator_next(&it_app_names))) {
905 }
906
909 }
910 ao2_iterator_cleanup(&it_app_names);
911 ao2_cleanup(app_names);
912 }
913}
void ao2_iterator_cleanup(struct ao2_iterator *iter)
void stasis_app_set_debug(struct stasis_app *app, int debug)
Enable/disable request/response and event logging on an application.
struct ao2_container * stasis_app_get_all(void)
Gets the names of all registered Stasis applications.
Definition: res_stasis.c:1715
Generic container type.

References ao2_cleanup, ao2_container_count(), ao2_iterator_cleanup(), ao2_iterator_init(), ao2_iterator_next, app, app_name(), debug, global_debug, stasis_app_get_all(), stasis_app_get_by_name(), and stasis_app_set_debug().

Referenced by ari_set_debug().

◆ stasis_app_to_cli()

void stasis_app_to_cli ( const struct stasis_app app,
struct ast_cli_args a 
)

Dump properties of a stasis_app to the CLI.

Parameters
appThe application
aThe CLI arguments

Definition at line 1168 of file res/stasis/app.c.

1169{
1170 struct ao2_iterator *channels;
1171 struct ao2_iterator *endpoints;
1172 struct ao2_iterator *bridges;
1173 struct app_forwards *forward;
1175
1176 ast_cli(a->fd, "Name: %s\n"
1177 " Debug: %s\n"
1178 " Subscription Model: %s\n",
1179 app->name,
1180 app->debug ? "Yes" : "No",
1181 app->subscription_model == STASIS_APP_SUBSCRIBE_ALL ?
1182 "Global Resource Subscription" :
1183 "Application/Explicit Resource Subscription");
1184 ast_cli(a->fd, " Subscriptions: %d\n", ao2_container_count(app->forwards));
1185
1186 ast_cli(a->fd, " Channels:\n");
1190 if (channels) {
1191 while ((forward = ao2_iterator_next(channels))) {
1192 ast_cli(a->fd, " %s (%d)\n", forward->id, forward->interested);
1193 ao2_ref(forward, -1);
1194 }
1196 }
1197
1198 ast_cli(a->fd, " Bridges:\n");
1200 bridges = ao2_callback(app->forwards, OBJ_MULTIPLE,
1202 if (bridges) {
1203 while ((forward = ao2_iterator_next(bridges))) {
1204 ast_cli(a->fd, " %s (%d)\n", forward->id, forward->interested);
1205 ao2_ref(forward, -1);
1206 }
1208 }
1209
1210 ast_cli(a->fd, " Endpoints:\n");
1214 if (endpoints) {
1215 while ((forward = ao2_iterator_next(endpoints))) {
1216 ast_cli(a->fd, " %s (%d)\n", forward->id, forward->interested);
1217 ao2_ref(forward, -1);
1218 }
1220 }
1221}
#define ao2_callback(c, flags, cb_fn, arg)
ao2_callback() is a generic function that applies cb_fn() to all objects in a container,...
Definition: astobj2.h:1693
@ OBJ_MULTIPLE
Definition: astobj2.h:1049
void ast_cli(int fd, const char *fmt,...)
Definition: clicompat.c:6
static int forwards_filter_by_type(void *obj, void *arg, int flags)
@ STASIS_APP_SUBSCRIBE_ALL
An application is automatically subscribed to all resources in Asterisk, even if it does not control ...
static struct test_val a

References a, ao2_callback, ao2_container_count(), ao2_iterator_destroy(), ao2_iterator_next, ao2_ref, app, ast_cli(), bridges, channels, endpoints, FORWARD_BRIDGE, FORWARD_CHANNEL, FORWARD_ENDPOINT, forwards_filter_by_type(), app_forwards::id, app_forwards::interested, OBJ_MULTIPLE, and STASIS_APP_SUBSCRIBE_ALL.

Referenced by ari_show_app().

◆ stasis_app_unregister_event_sources()

void stasis_app_unregister_event_sources ( void  )

Unregister core event sources.

Definition at line 1629 of file res/stasis/app.c.

1630{
1634}
void stasis_app_unregister_event_source(struct stasis_app_event_source *obj)
Unregister an application event source.
Definition: res_stasis.c:1830

References bridge_event_source, channel_event_source, endpoint_event_source, and stasis_app_unregister_event_source().

Referenced by unload_module().

◆ sub_bridge_update_handler()

static void sub_bridge_update_handler ( void *  data,
struct stasis_subscription sub,
struct stasis_message message 
)
static

Definition at line 682 of file res/stasis/app.c.

685{
686 struct ast_json *json = NULL;
687 struct stasis_app *app = data;
689 const struct timeval *tv;
690
692
694
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
700 && strcmp(update->new_snapshot->video_source_id, update->old_snapshot->video_source_id)) {
701 json = simple_bridge_event("BridgeVideoSourceChanged", update->new_snapshot, tv);
702 if (json && !ast_strlen_zero(update->old_snapshot->video_source_id)) {
703 ast_json_object_set(json, "old_video_source_id",
704 ast_json_string_create(update->old_snapshot->video_source_id));
705 }
706 }
707
708 if (json) {
709 app_send(app, json);
710 ast_json_unref(json);
711 }
712
713 if (!update->new_snapshot && update->old_snapshot) {
714 unsubscribe(app, "bridge", update->old_snapshot->uniqueid, 1);
715 }
716}
static void update(int code_size, int y, int wi, int fi, int dq, int sr, int dqsez, struct g726_state *state_ptr)
Definition: codec_g726.c:367
static struct ast_json * simple_bridge_event(const char *type, struct ast_bridge_snapshot *snapshot, const struct timeval *tv)
const struct timeval * stasis_message_timestamp(const struct stasis_message *msg)
Get the time when a message was created.

References app, app_send(), ast_json_object_set(), ast_json_string_create(), ast_json_unref(), ast_strlen_zero(), stasis_app::data, NULL, simple_bridge_event(), stasis_message_data(), stasis_message_timestamp(), unsubscribe(), and update().

Referenced by app_create().

◆ sub_channel_update_handler()

static void sub_channel_update_handler ( void *  data,
struct stasis_subscription sub,
struct stasis_message message 
)
static

Definition at line 543 of file res/stasis/app.c.

546{
547 struct stasis_app *app = data;
549 int i;
550
551 for (i = 0; i < ARRAY_LEN(channel_monitors); ++i) {
552 struct ast_json *msg;
553
554 msg = channel_monitors[i](update->old_snapshot, update->new_snapshot,
556 if (msg) {
557 app_send(app, msg);
558 ast_json_unref(msg);
559 }
560 }
561
562 if (ast_test_flag(&update->new_snapshot->flags, AST_FLAG_DEAD)) {
563 unsubscribe(app, "channel", update->new_snapshot->base->uniqueid, 1);
564 }
565}
static channel_snapshot_monitor channel_monitors[]
Structure representing a change of snapshot of channel state.
#define ARRAY_LEN(a)
Definition: utils.h:666

References app, app_send(), ARRAY_LEN, AST_FLAG_DEAD, ast_json_unref(), ast_test_flag, channel_monitors, stasis_app::data, stasis_message_data(), stasis_message_timestamp(), unsubscribe(), and update().

Referenced by app_create().

◆ sub_default_handler()

static void sub_default_handler ( void *  data,
struct stasis_subscription sub,
struct stasis_message message 
)
static

Definition at line 347 of file res/stasis/app.c.

349{
350 struct stasis_app *app = data;
351 struct ast_json *json;
352
353 /* The dial type can be converted to JSON so it will always be passed
354 * here.
355 */
358 }
359
360 /* By default, send any message that has a JSON representation */
362 if (!json) {
363 return;
364 }
365
366 app_send(app, json);
367 ast_json_unref(json);
368}
struct stasis_message_type * ast_channel_dial_type(void)
Message type for when a channel dials another channel.
static void call_forwarded_handler(struct stasis_app *app, struct stasis_message *message)
struct stasis_message_type * stasis_message_type(const struct stasis_message *msg)
Get the message type for a stasis_message.
struct ast_json * stasis_message_to_json(struct stasis_message *msg, struct stasis_message_sanitizer *sanitize)
Build the JSON representation of the message.

Referenced by app_create().

◆ sub_endpoint_update_handler()

static void sub_endpoint_update_handler ( void *  data,
struct stasis_subscription sub,
struct stasis_message message 
)
static

Definition at line 628 of file res/stasis/app.c.

631{
632 struct stasis_app *app = data;
634 struct ast_endpoint_snapshot *new_snapshot;
635 struct ast_endpoint_snapshot *old_snapshot;
636 const struct timeval *tv;
637
639
641
643
644 new_snapshot = stasis_message_data(update->new_snapshot);
645 old_snapshot = stasis_message_data(update->old_snapshot);
646
647 if (new_snapshot) {
648 struct ast_json *json;
649
650 tv = stasis_message_timestamp(update->new_snapshot);
651
652 json = simple_endpoint_event("EndpointStateChange", new_snapshot, tv);
653 if (!json) {
654 return;
655 }
656
657 app_send(app, json);
658 ast_json_unref(json);
659 }
660
661 if (!new_snapshot && old_snapshot) {
662 unsubscribe(app, "endpoint", old_snapshot->id, 1);
663 }
664}
struct stasis_message_type * stasis_cache_update_type(void)
Message type for cache update messages.
static struct ast_json * simple_endpoint_event(const char *type, struct ast_endpoint_snapshot *snapshot, const struct timeval *tv)
const ast_string_field id
Cache update message.
Definition: stasis.h:965

References app, app_send(), ast_assert, ast_endpoint_snapshot_type(), ast_json_unref(), stasis_app::data, ast_endpoint_snapshot::id, simple_endpoint_event(), stasis_cache_update_type(), stasis_message_data(), stasis_message_timestamp(), stasis_message_type(), unsubscribe(), and update().

Referenced by app_create().

◆ sub_subscription_change_handler()

static void sub_subscription_change_handler ( void *  data,
struct stasis_subscription sub,
struct stasis_message message 
)
static

Definition at line 337 of file res/stasis/app.c.

339{
340 struct stasis_app *app = data;
341
344 }
345}

References ao2_cleanup, app, stasis_app::data, stasis_subscription_final_message(), and sub.

Referenced by app_create().

◆ subscribe_bridge()

static int subscribe_bridge ( struct stasis_app app,
void *  obj 
)
static

Definition at line 1476 of file res/stasis/app.c.

1477{
1478 return app_subscribe_bridge(app, obj);
1479}
int app_subscribe_bridge(struct stasis_app *app, struct ast_bridge *bridge)
Add a bridge subscription to an existing channel subscription.

References app, and app_subscribe_bridge().

◆ subscribe_channel()

static int subscribe_channel ( struct stasis_app app,
void *  obj 
)
static

Definition at line 1329 of file res/stasis/app.c.

1330{
1331 return app_subscribe_channel(app, obj);
1332}

References app, and app_subscribe_channel().

◆ subscribe_endpoint()

static int subscribe_endpoint ( struct stasis_app app,
void *  obj 
)
static

Definition at line 1582 of file res/stasis/app.c.

1583{
1584 return app_subscribe_endpoint(app, obj);
1585}
int app_subscribe_endpoint(struct stasis_app *app, struct ast_endpoint *endpoint)
Subscribes an application to a endpoint.

References app, and app_subscribe_endpoint().

◆ unsubscribe()

static int unsubscribe ( struct stasis_app app,
const char *  kind,
const char *  id,
int  terminate 
)
static

Definition at line 1334 of file res/stasis/app.c.

1335{
1336 struct app_forwards *forwards;
1337
1338 if (!id) {
1339 if (!strcmp(kind, "bridge")) {
1340 id = BRIDGE_ALL;
1341 } else if (!strcmp(kind, "channel")) {
1342 id = CHANNEL_ALL;
1343 } else if (!strcmp(kind, "endpoint")) {
1344 id = ENDPOINT_ALL;
1345 } else {
1346 ast_log(LOG_WARNING, "Unknown subscription kind '%s'\n", kind);
1347 return -1;
1348 }
1349 }
1350
1351 ao2_lock(app->forwards);
1352 forwards = ao2_find(app->forwards, id, OBJ_SEARCH_KEY | OBJ_NOLOCK);
1353 if (!forwards) {
1354 ao2_unlock(app->forwards);
1355 ast_debug(3, "App '%s' not subscribed to %s '%s'\n", app->name, kind, id);
1356 return -1;
1357 }
1358 forwards->interested--;
1359
1360 ast_debug(3, "%s '%s': is %d interested in %s\n", kind, id, forwards->interested, app->name);
1361 if (forwards->interested == 0 || terminate) {
1362 /* No one is interested any more; unsubscribe */
1363 ast_debug(3, "%s '%s' unsubscribed from %s\n", kind, id, app->name);
1364 forwards_unsubscribe(forwards);
1365 ao2_find(app->forwards, forwards,
1367 OBJ_NODATA);
1368
1369 if (!strcmp(kind, "endpoint")) {
1371 }
1372 }
1373 ao2_unlock(app->forwards);
1374 ao2_ref(forwards, -1);
1375
1376 return 0;
1377}
@ OBJ_NODATA
Definition: astobj2.h:1044
@ OBJ_UNLINK
Definition: astobj2.h:1039
void messaging_app_unsubscribe_endpoint(const char *app_name, const char *endpoint_id)
Subscribe for messages from a particular endpoint.
Definition: messaging.c:423

References ao2_find, ao2_lock, ao2_ref, ao2_unlock, app, ast_debug, ast_log, BRIDGE_ALL, CHANNEL_ALL, ENDPOINT_ALL, forwards_unsubscribe(), app_forwards::interested, LOG_WARNING, messaging_app_unsubscribe_endpoint(), OBJ_NODATA, OBJ_NOLOCK, OBJ_POINTER, OBJ_SEARCH_KEY, and OBJ_UNLINK.

Referenced by app_unsubscribe_bridge_id(), app_unsubscribe_channel_id(), app_unsubscribe_endpoint_id(), sub_bridge_update_handler(), sub_channel_update_handler(), and sub_endpoint_update_handler().

Variable Documentation

◆ bridge_event_source

struct stasis_app_event_source bridge_event_source

◆ channel_event_source

struct stasis_app_event_source channel_event_source

◆ channel_monitors

channel_snapshot_monitor channel_monitors[]
static

Definition at line 536 of file res/stasis/app.c.

Referenced by sub_channel_update_handler().

◆ endpoint_event_source

struct stasis_app_event_source endpoint_event_source

◆ global_debug

int global_debug

Global debug flag. No need for locking

Definition at line 45 of file res/stasis/app.c.

Referenced by stasis_app_get_debug(), stasis_app_get_debug_by_name(), and stasis_app_set_global_debug().