Asterisk - The Open Source Telephony Project  GIT-master-a1fa8df
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"

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 the given 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"

◆ CHANNEL_ALL

#define CHANNEL_ALL   "__AST_CHANNEL_ALL_TOPIC"

◆ ENDPOINT_ALL

#define ENDPOINT_ALL   "__AST_ENDPOINT_ALL_TOPIC"

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

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.
Returns
New res_stasis application.
NULL on error.

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

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, forwards_sort(), stasis_app::handler, LOG_WARNING, 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().

916 {
917  RAII_VAR(struct stasis_app *, app, NULL, ao2_cleanup);
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);
926  ast_assert(handler != 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);
1012  if (!ast_context_find(context_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",
1021  context_name, name);
1022  }
1023 
1024  ao2_ref(app, +1);
1025  return app;
1026 }
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.
static void sub_bridge_update_handler(void *data, struct stasis_subscription *sub, struct stasis_message *message)
static const char name[]
Definition: format_mp3.c:68
static void bridge_blind_transfer_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_subscription_change_handler(void *data, struct stasis_subscription *sub, struct stasis_message *message)
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.
static int forwards_sort(const void *obj_left, const void *obj_right, int flags)
static void app_dtor(void *obj)
#define LOG_WARNING
Definition: logger.h:274
struct stasis_message_type * ast_endpoint_snapshot_type(void)
Message type for ast_endpoint_snapshot.
static void bridge_attended_transfer_handler(void *data, struct stasis_subscription *sub, struct stasis_message *message)
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.
#define ao2_alloc_options(data_size, destructor_fn, options)
Definition: astobj2.h:406
#define ast_assert(a)
Definition: utils.h:710
#define ast_strdup(str)
A wrapper for strdup()
Definition: astmm.h:243
static void sub_default_handler(void *data, struct stasis_subscription *sub, struct stasis_message *message)
#define NULL
Definition: resample.c:96
void ast_free_ptr(void *ptr)
free() wrapper
Definition: astmm.c:1771
#define ast_verb(level,...)
Definition: logger.h:455
static const char context_name[]
#define ast_asprintf(ret, fmt,...)
A wrapper for asprintf()
Definition: astmm.h:269
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.
#define ao2_bump(obj)
Definition: astobj2.h:491
#define ast_log
Definition: astobj2.c:42
struct stasis_message_type * ast_bridge_merge_message_type(void)
Message type for ast_bridge_merge_message.
struct ast_context * ast_context_find(const char *name)
Find a context.
Definition: extconf.c:4174
static const char app[]
Definition: app_adsiprog.c:56
#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:911
#define ao2_ref(o, delta)
Definition: astobj2.h:464
struct stasis_topic * stasis_topic_create(const char *name)
Create a new topic.
Definition: stasis.c:618
#define stasis_message_router_create(topic)
struct stasis_message_type * ast_attended_transfer_type(void)
Message type for ast_attended_transfer_message.
#define ast_free(a)
Definition: astmm.h:182
static void bridge_subscription_change_handler(void *data, struct stasis_subscription *sub, struct stasis_message *message)
struct stasis_message_type * ast_channel_snapshot_type(void)
Message type for ast_channel_snapshot_update.
struct stasis_topic * ast_bridge_topic_all(void)
A topic which publishes the events for all bridges.
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:6970
#define ao2_cleanup(obj)
Definition: astobj2.h:1958
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
static void sub_endpoint_update_handler(void *data, struct stasis_subscription *sub, struct stasis_message *message)
struct stasis_message_type * stasis_subscription_change_type(void)
Gets the message type for subscription change notices.
#define ao2_container_alloc_rbtree(ao2_options, container_options, sort_fn, cmp_fn)
Definition: astobj2.h:1358
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:6198
Reject duplicate objects in container.
Definition: astobj2.h:1205
static void bridge_merge_handler(void *data, struct stasis_subscription *sub, struct stasis_message *message)

◆ 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 1066 of file res/stasis/app.c.

References ao2_cleanup, ao2_lock, ao2_unlock, ast_verb, stasis_app::data, stasis_app::handler, stasis_app::name, and NULL.

Referenced by stasis_app_unregister().

1067 {
1068  ao2_lock(app);
1069 
1070  ast_verb(1, "Deactivating Stasis app '%s'\n", app->name);
1071  app->handler = NULL;
1072  ao2_cleanup(app->data);
1073  app->data = NULL;
1074 
1075  ao2_unlock(app);
1076 }
stasis_app_cb handler
#define ao2_unlock(a)
Definition: astobj2.h:730
#define NULL
Definition: resample.c:96
#define ast_verb(level,...)
Definition: logger.h:455
#define ao2_lock(a)
Definition: astobj2.h:718
#define ao2_cleanup(obj)
Definition: astobj2.h:1958

◆ app_dtor()

static void app_dtor ( void *  obj)
static

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

References ao2_cleanup, app, ast_assert, ast_context_destroy_by_name(), ast_json_unref(), ast_verb, stasis_app::bridge_router, context_name, stasis_app::data, stasis_app::endpoint_router, stasis_app::events_allowed, stasis_app::events_disallowed, stasis_app::forwards, stasis_app::name, NULL, stasis_app::router, and stasis_app::topic.

Referenced by app_create().

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);
298 
299  /* If we created a context for this application, remove it */
300  strcpy(context_name, "stasis-");
301  strcat(context_name, app->name);
302  ast_context_destroy_by_name(context_name, "res_stasis");
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 
312  app->events_allowed = NULL;
314  app->events_disallowed = NULL;
315 
316 }
struct ast_json * events_allowed
void ast_json_unref(struct ast_json *value)
Decrease refcount on value. If refcount reaches zero, value is freed.
Definition: json.c:73
#define ast_assert(a)
Definition: utils.h:710
#define NULL
Definition: resample.c:96
#define ast_verb(level,...)
Definition: logger.h:455
static const char context_name[]
int ast_context_destroy_by_name(const char *context, const char *registrar)
Destroy a context by name.
Definition: pbx.c:8244
struct stasis_message_router * endpoint_router
struct ao2_container * forwards
static const char app[]
Definition: app_adsiprog.c:56
struct stasis_message_router * router
struct ast_json * events_disallowed
struct stasis_topic * topic
#define ao2_cleanup(obj)
Definition: astobj2.h:1958
struct stasis_message_router * bridge_router

◆ app_event_filter_matched()

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

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

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

Referenced by stasis_app_event_allowed().

1719 {
1720  struct ast_json *obj;
1721  int i;
1722 
1723  if (!array || !ast_json_array_size(array)) {
1724  return empty;
1725  }
1726 
1727  for (i = 0; i < ast_json_array_size(array) &&
1728  (obj = ast_json_array_get(array, i)); ++i) {
1729 
1731  ast_json_object_string_get(event, "type"))) {
1732  return 1;
1733  }
1734  }
1735 
1736  return 0;
1737 }
#define ast_json_object_string_get(object, key)
Get a string field from a JSON object.
Definition: json.h:573
int ast_strings_equal(const char *str1, const char *str2)
Compare strings for equality checking for NULL.
Definition: strings.c:239
size_t ast_json_array_size(const struct ast_json *array)
Get the size of a JSON array.
Definition: json.c:356
Abstract JSON element (object, array, string, int, ...).
struct ast_json * ast_json_array_get(const struct ast_json *array, size_t index)
Get an element from an array.
Definition: json.c:360

◆ 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 1655 of file res/stasis/app.c.

References ao2_lock, ao2_unlock, 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(), LOG_ERROR, stasis_app::name, and NULL.

Referenced by app_events_allowed_set(), and app_events_disallowed_set().

1657 {
1658  if (filter && ast_json_typeof(filter) == AST_JSON_OBJECT) {
1659  if (!ast_json_object_size(filter)) {
1660  /* If no filters are specified then reset this filter type */
1661  filter = NULL;
1662  } else {
1663  /* Otherwise try to get the filter array for this type */
1664  filter = ast_json_object_get(filter, filter_type);
1665  if (!filter) {
1666  /* A filter type exists, but not this one, so don't update */
1667  return 0;
1668  }
1669  }
1670  }
1671 
1672  /* At this point the filter object should be an array */
1673  if (filter && ast_json_typeof(filter) != AST_JSON_ARRAY) {
1674  ast_log(LOG_ERROR, "Invalid json type event filter - app: %s, filter: %s\n",
1675  app->name, filter_type);
1676  return -1;
1677  }
1678 
1679  if (filter) {
1680  /* Confirm that at least the type names are specified */
1681  struct ast_json *obj;
1682  int i;
1683 
1684  for (i = 0; i < ast_json_array_size(filter) &&
1685  (obj = ast_json_array_get(filter, i)); ++i) {
1686 
1687  if (ast_strlen_zero(ast_json_object_string_get(obj, "type"))) {
1688  ast_log(LOG_ERROR, "Filter event must have a type - app: %s, "
1689  "filter: %s\n", app->name, filter_type);
1690  return -1;
1691  }
1692  }
1693  }
1694 
1695  ao2_lock(app);
1696  ast_json_unref(*member);
1697  *member = filter ? ast_json_ref(filter) : NULL;
1698  ao2_unlock(app);
1699 
1700  return 0;
1701 }
struct ast_json * ast_json_ref(struct ast_json *value)
Increase refcount on value.
Definition: json.c:67
size_t ast_json_object_size(struct ast_json *object)
Get size of JSON object.
Definition: json.c:393
void ast_json_unref(struct ast_json *value)
Decrease refcount on value. If refcount reaches zero, value is freed.
Definition: json.c:73
#define ao2_unlock(a)
Definition: astobj2.h:730
#define NULL
Definition: resample.c:96
#define ast_log
Definition: astobj2.c:42
static force_inline int attribute_pure ast_strlen_zero(const char *s)
Definition: strings.h:65
#define ast_json_object_string_get(object, key)
Get a string field from a JSON object.
Definition: json.h:573
#define ao2_lock(a)
Definition: astobj2.h:718
#define LOG_ERROR
Definition: logger.h:285
enum ast_json_type ast_json_typeof(const struct ast_json *value)
Get the type of value.
Definition: json.c:78
struct ast_json * ast_json_object_get(struct ast_json *object, const char *key)
Get a field from a JSON object.
Definition: json.c:397
size_t ast_json_array_size(const struct ast_json *array)
Get the size of a JSON array.
Definition: json.c:356
Abstract JSON element (object, array, string, int, ...).
struct ast_json * ast_json_array_get(const struct ast_json *array, size_t index)
Get an element from an array.
Definition: json.c:360

◆ app_events_allowed_set()

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

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

References app_event_filter_set(), and stasis_app::events_allowed.

Referenced by stasis_app_event_filter_set().

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

◆ app_events_disallowed_set()

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

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

References app_event_filter_set(), and stasis_app::events_disallowed.

Referenced by stasis_app_event_filter_set().

1709 {
1710  return app_event_filter_set(app, &app->events_disallowed, filter, "disallowed");
1711 }
static int app_event_filter_set(struct stasis_app *app, struct ast_json **member, struct ast_json *filter, const char *filter_type)
struct ast_json * events_disallowed

◆ app_is_active()

int app_is_active ( struct stasis_app app)

Checks whether an app is active.

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

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

References ao2_lock, ao2_unlock, stasis_app::handler, and NULL.

Referenced by stasis_app_exec().

1095 {
1096  int ret;
1097 
1098  ao2_lock(app);
1099  ret = app->handler != NULL;
1100  ao2_unlock(app);
1101 
1102  return ret;
1103 }
stasis_app_cb handler
#define ao2_unlock(a)
Definition: astobj2.h:730
#define NULL
Definition: resample.c:96
#define ao2_lock(a)
Definition: astobj2.h:718

◆ app_is_finished()

int app_is_finished ( struct stasis_app app)

Checks whether a deactivated app has no channels.

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

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

References ao2_container_count(), ao2_lock, ao2_unlock, stasis_app::forwards, stasis_app::handler, and NULL.

Referenced by app_shutdown(), and cleanup_cb().

1106 {
1107  int ret;
1108 
1109  ao2_lock(app);
1110  ret = app->handler == NULL && ao2_container_count(app->forwards) == 0;
1111  ao2_unlock(app);
1112 
1113  return ret;
1114 }
int ao2_container_count(struct ao2_container *c)
Returns the number of elements in a container.
stasis_app_cb handler
#define ao2_unlock(a)
Definition: astobj2.h:730
#define NULL
Definition: resample.c:96
struct ao2_container * forwards
#define ao2_lock(a)
Definition: astobj2.h:718

◆ 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.
Returns
True (non-zero) if bridge is subscribed to app.
False (zero) if bridge is not subscribed.

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

References ao2_cleanup, ao2_find, ast_strlen_zero(), BRIDGE_ALL, stasis_app::forwards, NULL, and OBJ_SEARCH_KEY.

1505 {
1506  struct app_forwards *forwards;
1507 
1508  if (ast_strlen_zero(bridge_id)) {
1509  bridge_id = BRIDGE_ALL;
1510  }
1511 
1512  forwards = ao2_find(app->forwards, bridge_id, OBJ_SEARCH_KEY);
1513  ao2_cleanup(forwards);
1514 
1515  return forwards != NULL;
1516 }
The arg parameter is a search key, but is not an object.
Definition: astobj2.h:1105
#define NULL
Definition: resample.c:96
struct ao2_container * forwards
static force_inline int attribute_pure ast_strlen_zero(const char *s)
Definition: strings.h:65
#define ao2_find(container, arg, flags)
Definition: astobj2.h:1756
#define ao2_cleanup(obj)
Definition: astobj2.h:1958
#define BRIDGE_ALL

◆ 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.
Returns
True (non-zero) if channel is subscribed to app.
False (zero) if channel is not subscribed.

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

References ao2_cleanup, ao2_find, ast_strlen_zero(), CHANNEL_ALL, stasis_app::forwards, NULL, and OBJ_SEARCH_KEY.

1403 {
1404  struct app_forwards *forwards;
1405 
1406  if (ast_strlen_zero(channel_id)) {
1407  channel_id = CHANNEL_ALL;
1408  }
1409  forwards = ao2_find(app->forwards, channel_id, OBJ_SEARCH_KEY);
1410  ao2_cleanup(forwards);
1411 
1412  return forwards != NULL;
1413 }
#define CHANNEL_ALL
The arg parameter is a search key, but is not an object.
Definition: astobj2.h:1105
#define NULL
Definition: resample.c:96
struct ao2_container * forwards
static force_inline int attribute_pure ast_strlen_zero(const char *s)
Definition: strings.h:65
#define ao2_find(container, arg, flags)
Definition: astobj2.h:1756
#define ao2_cleanup(obj)
Definition: astobj2.h:1958

◆ 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.
Returns
True (non-zero) if endpoint is subscribed to app.
False (zero) if endpoint is not subscribed.

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

References ao2_cleanup, ao2_find, ast_strlen_zero(), ENDPOINT_ALL, stasis_app::forwards, NULL, and OBJ_SEARCH_KEY.

1602 {
1603  struct app_forwards *forwards;
1604 
1605  if (ast_strlen_zero(endpoint_id)) {
1606  endpoint_id = ENDPOINT_ALL;
1607  }
1608  forwards = ao2_find(app->forwards, endpoint_id, OBJ_SEARCH_KEY);
1609  ao2_cleanup(forwards);
1610 
1611  return forwards != NULL;
1612 }
The arg parameter is a search key, but is not an object.
Definition: astobj2.h:1105
#define NULL
Definition: resample.c:96
struct ao2_container * forwards
static force_inline int attribute_pure ast_strlen_zero(const char *s)
Definition: strings.h:65
#define ao2_find(container, arg, flags)
Definition: astobj2.h:1756
#define ao2_cleanup(obj)
Definition: astobj2.h:1958
#define ENDPOINT_ALL

◆ app_send()

void app_send ( struct stasis_app app,
struct ast_json message 
)

Send a message to the given application.

Send a message to an application.

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

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

References ao2_bump, ao2_cleanup, ao2_lock, ao2_unlock, 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, stasis_app::data, stasis_app::handler, and stasis_app::name.

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

1039 {
1041  char eid[20];
1042  void *data;
1043 
1044  if (ast_json_object_set(message, "asterisk_id", ast_json_string_create(
1045  ast_eid_to_str(eid, sizeof(eid), &ast_eid_default)))) {
1046  ast_log(AST_LOG_WARNING, "Failed to append EID to outgoing event %s\n",
1047  ast_json_string_get(ast_json_object_get(message, "type")));
1048  }
1049 
1050  /* Copy off mutable state with lock held */
1051  ao2_lock(app);
1052  handler = app->handler;
1053  data = ao2_bump(app->data);
1054  ao2_unlock(app);
1055  /* Name is immutable; no need to copy */
1056 
1057  if (handler) {
1058  handler(data, app->name, message);
1059  } else {
1060  ast_verb(3,
1061  "Inactive Stasis app '%s' missed message\n", app->name);
1062  }
1063  ao2_cleanup(data);
1064 }
char * ast_eid_to_str(char *s, int maxlen, struct ast_eid *eid)
Convert an EID to a string.
Definition: main/utils.c:2587
#define AST_LOG_WARNING
Definition: logger.h:279
stasis_app_cb handler
#define ao2_unlock(a)
Definition: astobj2.h:730
#define ast_verb(level,...)
Definition: logger.h:455
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:404
#define ao2_bump(obj)
Definition: astobj2.h:491
#define ast_log
Definition: astobj2.c:42
struct ast_json * ast_json_string_create(const char *value)
Construct a JSON string from value.
Definition: json.c:268
#define ao2_lock(a)
Definition: astobj2.h:718
const char * ast_json_string_get(const struct ast_json *string)
Get the value of a JSON string.
Definition: json.c:273
void(* stasis_app_cb)(void *data, const char *app_name, struct ast_json *message)
Callback for Stasis application handler.
Definition: stasis_app.h:67
struct ast_eid ast_eid_default
Global EID.
Definition: options.c:93
#define ao2_cleanup(obj)
Definition: astobj2.h:1958
struct ast_json * ast_json_object_get(struct ast_json *object, const char *key)
Get a field from a JSON object.
Definition: json.c:397
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

◆ 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 1078 of file res/stasis/app.c.

References ao2_lock, ao2_unlock, app_is_finished(), ast_assert, stasis_app::bridge_router, stasis_app::endpoint_router, NULL, stasis_app::router, and stasis_message_router_unsubscribe().

Referenced by cleanup_cb().

1079 {
1080  ao2_lock(app);
1081 
1083 
1085  app->router = NULL;
1087  app->bridge_router = NULL;
1089  app->endpoint_router = NULL;
1090 
1091  ao2_unlock(app);
1092 }
#define ast_assert(a)
Definition: utils.h:710
#define ao2_unlock(a)
Definition: astobj2.h:730
#define NULL
Definition: resample.c:96
struct stasis_message_router * endpoint_router
#define ao2_lock(a)
Definition: astobj2.h:718
int app_is_finished(struct stasis_app *app)
Checks whether a deactivated app has no channels.
struct stasis_message_router * router
void stasis_message_router_unsubscribe(struct stasis_message_router *router)
Unsubscribe the router from the upstream topic.
struct stasis_message_router * bridge_router

◆ 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.
Returns
0 on success.
Non-zero on error.

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

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

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

1429 {
1430  struct app_forwards *forwards;
1431 
1432  if (!app) {
1433  return -1;
1434  }
1435 
1436  ao2_lock(app->forwards);
1437  /* If subscribed to all, don't subscribe again */
1438  forwards = ao2_find(app->forwards, BRIDGE_ALL, OBJ_SEARCH_KEY | OBJ_NOLOCK);
1439  if (forwards) {
1440  ao2_unlock(app->forwards);
1441  ao2_ref(forwards, -1);
1442 
1443  return 0;
1444  }
1445 
1446  forwards = ao2_find(app->forwards,
1447  bridge ? bridge->uniqueid : BRIDGE_ALL,
1449  if (!forwards) {
1450  int res;
1451 
1452  /* Forwards not found, create one */
1453  forwards = forwards_create_bridge(app, bridge);
1454  if (!forwards) {
1455  ao2_unlock(app->forwards);
1456 
1457  return -1;
1458  }
1459 
1460  res = ao2_link_flags(app->forwards, forwards, OBJ_NOLOCK);
1461  if (!res) {
1462  ao2_unlock(app->forwards);
1463  ao2_ref(forwards, -1);
1464 
1465  return -1;
1466  }
1467  }
1468 
1469  ++forwards->interested;
1470  ast_debug(3, "Bridge '%s' is %d interested in %s\n",
1471  bridge ? bridge->uniqueid : "ALL",
1472  forwards->interested,
1473  app->name);
1474 
1475  ao2_unlock(app->forwards);
1476  ao2_ref(forwards, -1);
1477 
1478  return 0;
1479 }
static struct app_forwards * forwards_create_bridge(struct stasis_app *app, struct ast_bridge *bridge)
const ast_string_field uniqueid
Definition: bridge.h:409
The arg parameter is a search key, but is not an object.
Definition: astobj2.h:1105
Assume that the ao2_container is already locked.
Definition: astobj2.h:1067
#define ao2_link_flags(container, obj, flags)
Definition: astobj2.h:1572
#define ao2_unlock(a)
Definition: astobj2.h:730
struct ao2_container * forwards
#define ast_debug(level,...)
Log a DEBUG message.
Definition: logger.h:444
#define ao2_ref(o, delta)
Definition: astobj2.h:464
#define ao2_lock(a)
Definition: astobj2.h:718
#define ao2_find(container, arg, flags)
Definition: astobj2.h:1756
#define BRIDGE_ALL

◆ 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.
Returns
0 on success.
Non-zero on error.

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

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

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

1282 {
1283  struct app_forwards *forwards;
1284 
1285  if (!app) {
1286  return -1;
1287  }
1288 
1289  ao2_lock(app->forwards);
1290  /* If subscribed to all, don't subscribe again */
1291  forwards = ao2_find(app->forwards, CHANNEL_ALL, OBJ_SEARCH_KEY | OBJ_NOLOCK);
1292  if (forwards) {
1293  ao2_unlock(app->forwards);
1294  ao2_ref(forwards, -1);
1295 
1296  return 0;
1297  }
1298 
1299  forwards = ao2_find(app->forwards,
1300  chan ? ast_channel_uniqueid(chan) : CHANNEL_ALL,
1302  if (!forwards) {
1303  int res;
1304 
1305  /* Forwards not found, create one */
1306  forwards = forwards_create_channel(app, chan);
1307  if (!forwards) {
1308  ao2_unlock(app->forwards);
1309 
1310  return -1;
1311  }
1312 
1313  res = ao2_link_flags(app->forwards, forwards, OBJ_NOLOCK);
1314  if (!res) {
1315  ao2_unlock(app->forwards);
1316  ao2_ref(forwards, -1);
1317 
1318  return -1;
1319  }
1320  }
1321 
1322  ++forwards->interested;
1323  ast_debug(3, "Channel '%s' is %d interested in %s\n",
1324  chan ? ast_channel_uniqueid(chan) : "ALL",
1325  forwards->interested,
1326  app->name);
1327 
1328  ao2_unlock(app->forwards);
1329  ao2_ref(forwards, -1);
1330 
1331  return 0;
1332 }
#define CHANNEL_ALL
The arg parameter is a search key, but is not an object.
Definition: astobj2.h:1105
Assume that the ao2_container is already locked.
Definition: astobj2.h:1067
#define ao2_link_flags(container, obj, flags)
Definition: astobj2.h:1572
#define ao2_unlock(a)
Definition: astobj2.h:730
struct ao2_container * forwards
#define ast_debug(level,...)
Log a DEBUG message.
Definition: logger.h:444
#define ao2_ref(o, delta)
Definition: astobj2.h:464
#define ao2_lock(a)
Definition: astobj2.h:718
const char * ast_channel_uniqueid(const struct ast_channel *chan)
#define ao2_find(container, arg, flags)
Definition: astobj2.h:1756
static struct app_forwards * forwards_create_channel(struct stasis_app *app, struct ast_channel *chan)

◆ app_subscribe_endpoint()

int app_subscribe_endpoint ( struct stasis_app app,
struct ast_endpoint endpoint 
)

Subscribes an application to a endpoint.

Parameters
appApplication.
chanEndpoint to subscribe to.
Returns
0 on success.
Non-zero on error.

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

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

Referenced by subscribe_endpoint().

1532 {
1533  struct app_forwards *forwards;
1534 
1535  if (!app) {
1536  return -1;
1537  }
1538 
1539  ao2_lock(app->forwards);
1540  /* If subscribed to all, don't subscribe again */
1542  if (forwards) {
1543  ao2_unlock(app->forwards);
1544  ao2_ref(forwards, -1);
1545 
1546  return 0;
1547  }
1548 
1549  forwards = ao2_find(app->forwards,
1550  endpoint ? ast_endpoint_get_id(endpoint) : ENDPOINT_ALL,
1552  if (!forwards) {
1553  int res;
1554 
1555  /* Forwards not found, create one */
1556  forwards = forwards_create_endpoint(app, endpoint);
1557  if (!forwards) {
1558  ao2_unlock(app->forwards);
1559 
1560  return -1;
1561  }
1562 
1563  res = ao2_link_flags(app->forwards, forwards, OBJ_NOLOCK);
1564  if (!res) {
1565  ao2_unlock(app->forwards);
1566  ao2_ref(forwards, -1);
1567 
1568  return -1;
1569  }
1570 
1571  /* Subscribe for messages */
1573  }
1574 
1575  ++forwards->interested;
1576  ast_debug(3, "Endpoint '%s' is %d interested in %s\n",
1577  endpoint ? ast_endpoint_get_id(endpoint) : "ALL",
1578  forwards->interested,
1579  app->name);
1580 
1581  ao2_unlock(app->forwards);
1582  ao2_ref(forwards, -1);
1583 
1584  return 0;
1585 }
The arg parameter is a search key, but is not an object.
Definition: astobj2.h:1105
Assume that the ao2_container is already locked.
Definition: astobj2.h:1067
#define ao2_link_flags(container, obj, flags)
Definition: astobj2.h:1572
#define ao2_unlock(a)
Definition: astobj2.h:730
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
struct ao2_container * forwards
#define ast_debug(level,...)
Log a DEBUG message.
Definition: logger.h:444
static struct app_forwards * forwards_create_endpoint(struct stasis_app *app, struct ast_endpoint *endpoint)
#define ao2_ref(o, delta)
Definition: astobj2.h:464
#define ao2_lock(a)
Definition: astobj2.h:718
static int message_received_handler(const char *endpoint_id, struct ast_json *json_msg, void *pvt)
#define ao2_find(container, arg, flags)
Definition: astobj2.h:1756
const char * ast_endpoint_get_id(const struct ast_endpoint *endpoint)
Gets the tech/resource id of the given endpoint.
#define ENDPOINT_ALL

◆ 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
NULL on error

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

References ao2_iterator_destroy(), ao2_iterator_init(), ao2_iterator_next, ao2_ref, 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, stasis_app::forwards, app_forwards::id, LOG_ERROR, stasis_app::name, and NULL.

Referenced by stasis_app_object_to_json().

1229 {
1230  struct ast_json *json;
1231  struct ast_json *channels;
1232  struct ast_json *bridges;
1233  struct ast_json *endpoints;
1234  struct ao2_iterator i;
1235  struct app_forwards *forwards;
1236 
1237  json = ast_json_pack("{s: s, s: [], s: [], s: []}",
1238  "name", app->name,
1239  "channel_ids", "bridge_ids", "endpoint_ids");
1240  if (!json) {
1241  return NULL;
1242  }
1243  channels = ast_json_object_get(json, "channel_ids");
1244  bridges = ast_json_object_get(json, "bridge_ids");
1245  endpoints = ast_json_object_get(json, "endpoint_ids");
1246 
1247  i = ao2_iterator_init(app->forwards, 0);
1248  while ((forwards = ao2_iterator_next(&i))) {
1249  struct ast_json *array = NULL;
1250  int append_res;
1251 
1252  switch (forwards->forward_type) {
1253  case FORWARD_CHANNEL:
1254  array = channels;
1255  break;
1256  case FORWARD_BRIDGE:
1257  array = bridges;
1258  break;
1259  case FORWARD_ENDPOINT:
1260  array = endpoints;
1261  break;
1262  }
1263 
1264  /* If forward_type value is unexpected this will safely return an error. */
1265  append_res = ast_json_array_append(array, ast_json_string_create(forwards->id));
1266  ao2_ref(forwards, -1);
1267 
1268  if (append_res != 0) {
1269  ast_log(LOG_ERROR, "Error building response\n");
1271  ast_json_unref(json);
1272 
1273  return NULL;
1274  }
1275  }
1277 
1278  return json;
1279 }
struct ast_json * ast_json_pack(char const *format,...)
Helper for creating complex JSON values.
Definition: json.c:591
void ast_json_unref(struct ast_json *value)
Decrease refcount on value. If refcount reaches zero, value is freed.
Definition: json.c:73
void ao2_iterator_destroy(struct ao2_iterator *iter)
Destroy a container iterator.
#define NULL
Definition: resample.c:96
enum forward_type forward_type
struct ao2_container * forwards
#define ast_log
Definition: astobj2.c:42
struct ast_json * ast_json_string_create(const char *value)
Construct a JSON string from value.
Definition: json.c:268
static struct ao2_container * endpoints
#define ao2_ref(o, delta)
Definition: astobj2.h:464
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:368
#define LOG_ERROR
Definition: logger.h:285
static int array(struct ast_channel *chan, const char *cmd, char *var, const char *value)
#define ao2_iterator_next(iter)
Definition: astobj2.h:1933
static struct ao2_container * bridges
Definition: bridge.c:123
When we need to walk through a container, we use an ao2_iterator to keep track of the current positio...
Definition: astobj2.h:1841
struct ast_json * ast_json_object_get(struct ast_json *object, const char *key)
Get a field from a JSON object.
Definition: json.c:397
Abstract JSON element (object, array, string, int, ...).
struct ao2_iterator ao2_iterator_init(struct ao2_container *c, int flags) attribute_warn_unused_result
Create an iterator for a container.

◆ app_unsubscribe_bridge()

int app_unsubscribe_bridge ( struct stasis_app app,
struct ast_bridge bridge 
)

Cancel the bridge subscription for an application.

Parameters
forwardsReturn from app_subscribe_channel().
bridgeBridge to subscribe to.
Returns
0 on success.
Non-zero on error.

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

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

Referenced by internal_bridge_after_cb(), and stasis_app_exec().

1487 {
1488  if (!app) {
1489  return -1;
1490  }
1491 
1492  return app_unsubscribe_bridge_id(app, bridge ? bridge->uniqueid : BRIDGE_ALL);
1493 }
const ast_string_field uniqueid
Definition: bridge.h:409
int app_unsubscribe_bridge_id(struct stasis_app *app, const char *bridge_id)
Cancel the subscription an app has for a bridge.
#define BRIDGE_ALL

◆ 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.
Returns
0 on success.
Non-zero on error.

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

References unsubscribe().

Referenced by app_unsubscribe_bridge().

1496 {
1497  if (!app) {
1498  return -1;
1499  }
1500 
1501  return unsubscribe(app, "bridge", bridge_id, 0);
1502 }
static int unsubscribe(struct stasis_app *app, const char *kind, const char *id, int terminate)

◆ 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.
Returns
0 on success.
Non-zero on error.

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

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

Referenced by app_send_end_msg().

1385 {
1386  if (!app) {
1387  return -1;
1388  }
1389 
1390  return app_unsubscribe_channel_id(app, chan ? ast_channel_uniqueid(chan) : CHANNEL_ALL);
1391 }
#define CHANNEL_ALL
int app_unsubscribe_channel_id(struct stasis_app *app, const char *channel_id)
Cancel the subscription an app has for a channel.
const char * ast_channel_uniqueid(const struct ast_channel *chan)

◆ 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.
Returns
0 on success.
Non-zero on error.

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

References unsubscribe().

Referenced by app_unsubscribe_channel(), and send_start_msg_snapshots().

1394 {
1395  if (!app) {
1396  return -1;
1397  }
1398 
1399  return unsubscribe(app, "channel", channel_id, 0);
1400 }
static int unsubscribe(struct stasis_app *app, const char *kind, const char *id, int terminate)

◆ 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.
Returns
0 on success.
Non-zero on error.

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

References unsubscribe().

1593 {
1594  if (!app) {
1595  return -1;
1596  }
1597 
1598  return unsubscribe(app, "endpoint", endpoint_id, 0);
1599 }
static int unsubscribe(struct stasis_app *app, const char *kind, const char *id, int terminate)

◆ 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 1116 of file res/stasis/app.c.

References ao2_lock, ao2_replace, ao2_unlock, app_send(), ast_json_pack(), ast_json_timeval(), ast_json_unref(), ast_tvnow(), ast_verb, stasis_app::data, stasis_app::handler, stasis_app::name, and NULL.

Referenced by __stasis_app_register().

1117 {
1118  ao2_lock(app);
1119  if (app->handler && app->data) {
1120  struct ast_json *msg;
1121 
1122  ast_verb(1, "Replacing Stasis app '%s'\n", app->name);
1123 
1124  msg = ast_json_pack("{s: s, s: o?, s: s}",
1125  "type", "ApplicationReplaced",
1126  "timestamp", ast_json_timeval(ast_tvnow(), NULL),
1127  "application", app->name);
1128  if (msg) {
1129  /*
1130  * The app must be unlocked before calling 'send' since a handler may
1131  * subsequently attempt to grab the app lock after first obtaining a
1132  * lock for another object, thus causing a deadlock.
1133  */
1134  ao2_unlock(app);
1135  app_send(app, msg);
1136  ao2_lock(app);
1137  ast_json_unref(msg);
1138  if (!app->handler) {
1139  /*
1140  * If the handler disappeared then the app was deactivated. In that
1141  * case don't replace. Re-activation will reset the handler later.
1142  */
1143  ao2_unlock(app);
1144  return;
1145  }
1146  }
1147  } else {
1148  ast_verb(1, "Activating Stasis app '%s'\n", app->name);
1149  }
1150 
1151  app->handler = handler;
1152  ao2_replace(app->data, data);
1153  ao2_unlock(app);
1154 }
struct ast_json * ast_json_pack(char const *format,...)
Helper for creating complex JSON values.
Definition: json.c:591
void ast_json_unref(struct ast_json *value)
Decrease refcount on value. If refcount reaches zero, value is freed.
Definition: json.c:73
stasis_app_cb handler
struct timeval ast_tvnow(void)
Returns current timeval. Meant to replace calls to gettimeofday().
Definition: time.h:150
#define ao2_unlock(a)
Definition: astobj2.h:730
#define NULL
Definition: resample.c:96
#define ast_verb(level,...)
Definition: logger.h:455
#define ao2_lock(a)
Definition: astobj2.h:718
struct ast_json * ast_json_timeval(const struct timeval tv, const char *zone)
Construct a timeval as JSON.
Definition: json.c:649
void app_send(struct stasis_app *app, struct ast_json *message)
Send a message to the given application.
#define ao2_replace(dst, src)
Definition: astobj2.h:517
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
Abstract JSON element (object, array, string, int, ...).

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

References stasis_app::topic.

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

1029 {
1030  return app->topic;
1031 }
struct stasis_topic * topic

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

References ao2_find, ao2_ref, stasis_app::forwards, NULL, and OBJ_SEARCH_KEY.

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

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 }
The arg parameter is a search key, but is not an object.
Definition: astobj2.h:1105
#define NULL
Definition: resample.c:96
struct ao2_container * forwards
#define ao2_ref(o, delta)
Definition: astobj2.h:464
#define ao2_find(container, arg, flags)
Definition: astobj2.h:1756

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

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

Referenced by bridge_attended_transfer_handler(), and bridge_blind_transfer_handler().

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  }
768  ao2_iterator_destroy(&iter);
769 
770  return subscribed;
771 }
struct ao2_container * channels
Definition: bridge.h:339
void ao2_iterator_destroy(struct ao2_iterator *iter)
Destroy a container iterator.
#define ao2_ref(o, delta)
Definition: astobj2.h:464
static int subscribed
Definition: manager.c:1476
#define ao2_iterator_next(iter)
Definition: astobj2.h:1933
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:336
When we need to walk through a container, we use an ao2_iterator to keep track of the current positio...
Definition: astobj2.h:1841
struct ao2_iterator ao2_iterator_init(struct ao2_container *c, int flags) attribute_warn_unused_result
Create an iterator for a container.

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

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, stasis_app::topic, and ast_channel_snapshot_base::uniqueid.

Referenced by app_create().

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

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

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(), stasis_app::topic, ast_blind_transfer_message::transferer, and ast_channel_snapshot_base::uniqueid.

Referenced by app_create().

775 {
776  struct stasis_app *app = data;
777  struct ast_blind_transfer_message *transfer_msg = stasis_message_data(message);
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 }
struct ast_channel_snapshot_base * base
Message published during a blind transfer.
Structure that contains a snapshot of information about a bridge.
Definition: bridge.h:322
const ast_string_field uniqueid
static const char app[]
Definition: app_adsiprog.c:56
struct ast_bridge_snapshot * bridge
struct ast_channel_snapshot * transferer
void * stasis_message_data(const struct stasis_message *msg)
Get the data contained in a message.
struct stasis_topic * topic
void stasis_publish(struct stasis_topic *topic, struct stasis_message *message)
Publish a message to a topic&#39;s subscribers.
Definition: stasis.c:1511
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.
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.

◆ bridge_find()

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

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

References stasis_app_bridge_find_by_id().

1519 {
1520  return stasis_app_bridge_find_by_id(id);
1521 }
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

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

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

Referenced by app_create().

735 {
736  struct stasis_app *app = data;
737  struct ast_bridge_merge_message *merge;
738 
739  merge = stasis_message_data(message);
740 
741  /* Find out if we're subscribed to either bridge */
742  if (bridge_app_subscribed(app, merge->from->uniqueid) ||
743  bridge_app_subscribed(app, merge->to->uniqueid)) {
744  /* Forward the message to the app */
745  stasis_publish(app->topic, message);
746  }
747 }
static const char app[]
Definition: app_adsiprog.c:56
void * stasis_message_data(const struct stasis_message *msg)
Get the data contained in a message.
struct stasis_topic * topic
void stasis_publish(struct stasis_topic *topic, struct stasis_message *message)
Publish a message to a topic&#39;s subscribers.
Definition: stasis.c:1511
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:336
struct ast_bridge_snapshot * from
Message representing the merge of two bridges.
struct ast_bridge_snapshot * to

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

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

Referenced by app_create().

834 {
835  struct stasis_app *app = data;
836 
837  if (stasis_subscription_final_message(sub, message)) {
838  ao2_cleanup(app);
839  }
840 }
static const char app[]
Definition: app_adsiprog.c:56
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:1176
#define ao2_cleanup(obj)
Definition: astobj2.h:1958

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

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

Referenced by sub_default_handler().

319 {
320  struct ast_multi_channel_blob *payload = stasis_message_data(message);
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 
328  chan = ast_channel_get_by_name(snapshot->base->uniqueid);
329  if (!chan) {
330  return;
331  }
332 
333  app_subscribe_channel(app, chan);
334  ast_channel_unref(chan);
335 }
Main Channel structure associated with a channel.
struct ast_channel_snapshot_base * base
#define ast_channel_unref(c)
Decrease channel reference count.
Definition: channel.h:2949
Structure representing a snapshot of channel state.
const ast_string_field uniqueid
void * stasis_message_data(const struct stasis_message *msg)
Get the data contained in a message.
struct ast_channel_snapshot * ast_multi_channel_blob_get_channel(struct ast_multi_channel_blob *obj, const char *role)
Retrieve a channel snapshot associated with a specific role from a ast_multi_channel_blob.
A multi channel blob data structure for multi_channel_blob stasis messages.
int app_subscribe_channel(struct stasis_app *app, struct ast_channel *chan)
Subscribes an application to a channel.
struct ast_channel * ast_channel_get_by_name(const char *name)
Find a channel by name.
Definition: channel.c:1450

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

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().

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 }
struct ast_json * ast_json_pack(char const *format,...)
Helper for creating complex JSON values.
Definition: json.c:591
const char * ast_describe_caller_presentation(int data)
Convert caller ID pres value to explanatory string.
Definition: callerid.c:1164
#define NULL
Definition: resample.c:96
struct ast_json * ast_json_timeval(const struct timeval tv, const char *zone)
Construct a timeval as JSON.
Definition: json.c:649
struct ast_channel_snapshot_caller * caller
struct stasis_message_sanitizer * stasis_app_get_sanitizer(void)
Get the Stasis message sanitizer for app_stasis applications.
Definition: res_stasis.c:2264
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_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.
Abstract JSON element (object, array, string, int, ...).

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

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

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 }
struct ast_json * ast_json_pack(char const *format,...)
Helper for creating complex JSON values.
Definition: json.c:591
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.
#define NULL
Definition: resample.c:96
struct ast_json * ast_json_timeval(const struct timeval tv, const char *zone)
Construct a timeval as JSON.
Definition: json.c:649
struct stasis_message_sanitizer * stasis_app_get_sanitizer(void)
Get the Stasis message sanitizer for app_stasis applications.
Definition: res_stasis.c:2264
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.
Abstract JSON element (object, array, string, int, ...).

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

References simple_channel_event().

Referenced by channel_state().

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)

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

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().

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 }
struct ast_json * ast_json_pack(char const *format,...)
Helper for creating complex JSON values.
Definition: json.c:591
#define NULL
Definition: resample.c:96
struct ast_channel_snapshot_hangup * hangup
struct ast_json * ast_json_timeval(const struct timeval tv, const char *zone)
Construct a timeval as JSON.
Definition: json.c:649
struct stasis_message_sanitizer * stasis_app_get_sanitizer(void)
Get the Stasis message sanitizer for app_stasis applications.
Definition: res_stasis.c:2264
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.
const char * ast_cause2str(int state) attribute_pure
Gives the string form of a given cause code.
Definition: channel.c:608
Abstract JSON element (object, array, string, int, ...).

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

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().

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 }
const ast_string_field data
struct ast_json * ast_json_pack(char const *format,...)
Helper for creating complex JSON values.
Definition: json.c:591
#define NULL
Definition: resample.c:96
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.
struct ast_channel_snapshot_dialplan * dialplan
const ast_string_field appl
static force_inline int attribute_pure ast_strlen_zero(const char *s)
Definition: strings.h:65
struct ast_json * ast_json_timeval(const struct timeval tv, const char *zone)
Construct a timeval as JSON.
Definition: json.c:649
struct stasis_message_sanitizer * stasis_app_get_sanitizer(void)
Get the Stasis message sanitizer for app_stasis applications.
Definition: res_stasis.c:2264
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.
Abstract JSON element (object, array, string, int, ...).
#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

◆ channel_find()

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

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

References ast_channel_get_by_name().

1416 {
1417  return ast_channel_get_by_name(id);
1418 }
struct ast_channel * ast_channel_get_by_name(const char *name)
Find a channel by name.
Definition: channel.c:1450

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

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.

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 }
#define ast_test_flag(p, flag)
Definition: utils.h:63
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)
Structure representing a snapshot of channel state.
#define NULL
Definition: resample.c:96
static struct ast_json * channel_destroyed_event(struct ast_channel_snapshot *snapshot, const struct timeval *tv)
enum ast_channel_state state
struct ast_flags flags

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

References simple_channel_event().

Referenced by channel_state().

421 {
422  return simple_channel_event("ChannelStateChange", snapshot, tv);
423 }
static struct ast_json * simple_channel_event(const char *type, struct ast_channel_snapshot *snapshot, const struct timeval *tv)

◆ endpoint_find()

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

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

References ast_endpoint_find_by_id().

1615 {
1616  return ast_endpoint_find_by_id(id);
1617 }
struct ast_endpoint * ast_endpoint_find_by_id(const char *id)
Finds the endpoint with the given tech[/resource] 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.

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

Referenced by forwards_create_endpoint().

192 {
193  struct stasis_app *app = data;
194 
195  stasis_publish(app->topic, message);
196 }
static const char app[]
Definition: app_adsiprog.c:56
struct stasis_topic * topic
void stasis_publish(struct stasis_topic *topic, struct stasis_message *message)
Publish a message to a topic&#39;s subscribers.
Definition: stasis.c:1511

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

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

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

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:409
static void forwards_dtor(void *obj)
#define NULL
Definition: resample.c:96
static force_inline int attribute_pure ast_strlen_zero(const char *s)
Definition: strings.h:65

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

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

Referenced by app_subscribe_bridge().

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 }
const ast_string_field uniqueid
Definition: bridge.h:409
#define NULL
Definition: resample.c:96
enum forward_type forward_type
#define ao2_ref(o, delta)
Definition: astobj2.h:464
static void forwards_unsubscribe(struct app_forwards *forwards)
struct stasis_topic * topic
struct stasis_forward * topic_forward
static struct app_forwards * forwards_create(struct stasis_app *app, const char *id)
#define BRIDGE_ALL
struct stasis_topic * ast_bridge_topic(struct ast_bridge *bridge)
A topic which publishes the events for a particular bridge.
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

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

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

Referenced by app_subscribe_channel().

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;
151  forwards->topic_forward = stasis_forward_all(
152  chan ? ast_channel_topic(chan) : ast_channel_topic_all(),
153  app->topic);
154 
155  if (!forwards->topic_forward) {
156  ao2_ref(forwards, -1);
157  return NULL;
158  }
159 
160  return forwards;
161 }
#define CHANNEL_ALL
#define NULL
Definition: resample.c:96
enum forward_type forward_type
struct stasis_topic * ast_channel_topic_all(void)
A topic which publishes the events for all channels.
#define ao2_ref(o, delta)
Definition: astobj2.h:464
const char * ast_channel_uniqueid(const struct ast_channel *chan)
struct stasis_topic * ast_channel_topic(struct ast_channel *chan)
A topic which publishes the events for a particular channel.
struct stasis_topic * topic
struct stasis_forward * topic_forward
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

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

References ao2_ref, 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, stasis_app::endpoint_router, endpoint_state_cb(), FORWARD_ENDPOINT, app_forwards::forward_type, stasis_app::forwards, forwards_create(), forwards_unsubscribe(), NULL, stasis_forward_all(), stasis_message_router_add(), stasis_message_router_create, stasis_app::topic, app_forwards::topic_cached_forward, and app_forwards::topic_forward.

Referenced by app_subscribe_endpoint().

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  */
235  if (!app->endpoint_router) {
236  forwards_unsubscribe(forwards);
237  ao2_ref(forwards, -1);
238  return NULL;
239  }
240 
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 }
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.
struct stasis_topic * ast_endpoint_topic(struct ast_endpoint *endpoint)
Returns the topic for a specific endpoint.
#define ast_assert(a)
Definition: utils.h:710
static void endpoint_state_cb(void *data, struct stasis_subscription *sub, struct stasis_message *message)
#define NULL
Definition: resample.c:96
struct stasis_forward * topic_cached_forward
struct stasis_topic * ast_endpoint_topic_all_cached(void)
Cached topic for all endpoint related messages.
struct stasis_message_router * endpoint_router
enum forward_type forward_type
#define ao2_ref(o, delta)
Definition: astobj2.h:464
#define stasis_message_router_create(topic)
struct stasis_topic * ast_endpoint_topic_cached(struct ast_endpoint *endpoint)
Returns the topic for a specific endpoint.
struct stasis_message_type * ast_endpoint_state_type(void)
Message type for endpoint state changes.
static void forwards_unsubscribe(struct app_forwards *forwards)
struct stasis_topic * topic
struct stasis_forward * topic_forward
static struct app_forwards * forwards_create(struct stasis_app *app, const char *id)
struct stasis_message_type * ast_endpoint_contact_state_type(void)
Message type for endpoint contact state changes.
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
const char * ast_endpoint_get_id(const struct ast_endpoint *endpoint)
Gets the tech/resource id of the given endpoint.
#define ENDPOINT_ALL

◆ forwards_dtor()

static void forwards_dtor ( void *  obj)
static

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

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

Referenced by forwards_create().

99 {
100 #ifdef AST_DEVMODE
101  struct app_forwards *forwards = obj;
102 #endif /* AST_DEVMODE */
103 
104  ast_assert(forwards->topic_forward == NULL);
105  ast_assert(forwards->topic_cached_forward == NULL);
106 }
#define ast_assert(a)
Definition: utils.h:710
#define NULL
Definition: resample.c:96
struct stasis_forward * topic_cached_forward
struct stasis_forward * topic_forward

◆ forwards_filter_by_type()

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

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

References CMP_MATCH, and app_forwards::forward_type.

Referenced by stasis_app_to_cli().

1162 {
1163  struct app_forwards *forward = obj;
1164  enum forward_type *forward_type = arg;
1165 
1166  if (forward->forward_type == *forward_type) {
1167  return CMP_MATCH;
1168  }
1169 
1170  return 0;
1171 }
enum forward_type forward_type
forward_type

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

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

Referenced by app_create().

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:1155
#define OBJ_POINTER
Definition: astobj2.h:1154
#define ast_assert(a)
Definition: utils.h:710
#define OBJ_PARTIAL_KEY
Definition: astobj2.h:1156

◆ forwards_unsubscribe()

static void forwards_unsubscribe ( struct app_forwards forwards)
static

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

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().

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

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

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().

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) {
621  app_send(app, message);
622  ast_json_unref(message);
623  }
624 
625  return 0;
626 }
struct ast_json * ast_json_ref(struct ast_json *value)
Increase refcount on value.
Definition: json.c:67
struct ast_json * ast_json_pack(char const *format,...)
Helper for creating complex JSON values.
Definition: json.c:591
void ast_json_unref(struct ast_json *value)
Decrease refcount on value. If refcount reaches zero, value is freed.
Definition: json.c:73
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 timeval ast_tvnow(void)
Returns current timeval. Meant to replace calls to gettimeofday().
Definition: time.h:150
#define NULL
Definition: resample.c:96
static const char app[]
Definition: app_adsiprog.c:56
static force_inline int attribute_pure ast_strlen_zero(const char *s)
Definition: strings.h:65
#define ao2_ref(o, delta)
Definition: astobj2.h:464
#define ast_strdupa(s)
duplicate a string in memory from the stack
Definition: astmm.h:300
struct ast_json * ast_json_timeval(const struct timeval tv, const char *zone)
Construct a timeval as JSON.
Definition: json.c:649
A snapshot of an endpoint&#39;s state.
void app_send(struct stasis_app *app, struct ast_json *message)
Send a message to the given application.
struct stasis_message_sanitizer * stasis_app_get_sanitizer(void)
Get the Stasis message sanitizer for app_stasis applications.
Definition: res_stasis.c:2264
Abstract JSON element (object, array, string, int, ...).
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.

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

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

Referenced by sub_bridge_update_handler().

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_json_pack(char const *format,...)
Helper for creating complex JSON values.
Definition: json.c:591
#define NULL
Definition: resample.c:96
struct ast_json * ast_json_timeval(const struct timeval tv, const char *zone)
Construct a timeval as JSON.
Definition: json.c:649
struct stasis_message_sanitizer * stasis_app_get_sanitizer(void)
Get the Stasis message sanitizer for app_stasis applications.
Definition: res_stasis.c:2264
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.
Abstract JSON element (object, array, string, int, ...).

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

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

Referenced by channel_created_event(), and channel_state_change_event().

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 }
static const char type[]
Definition: chan_ooh323.c:109
struct ast_json * ast_json_pack(char const *format,...)
Helper for creating complex JSON values.
Definition: json.c:591
#define NULL
Definition: resample.c:96
struct ast_json * ast_json_timeval(const struct timeval tv, const char *zone)
Construct a timeval as JSON.
Definition: json.c:649
struct stasis_message_sanitizer * stasis_app_get_sanitizer(void)
Get the Stasis message sanitizer for app_stasis applications.
Definition: res_stasis.c:2264
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.
Abstract JSON element (object, array, string, int, ...).

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

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

Referenced by sub_endpoint_update_handler().

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 }
static const char type[]
Definition: chan_ooh323.c:109
struct ast_json * ast_json_pack(char const *format,...)
Helper for creating complex JSON values.
Definition: json.c:591
#define NULL
Definition: resample.c:96
struct ast_json * ast_json_timeval(const struct timeval tv, const char *zone)
Construct a timeval as JSON.
Definition: json.c:649
struct stasis_message_sanitizer * stasis_app_get_sanitizer(void)
Get the Stasis message sanitizer for app_stasis applications.
Definition: res_stasis.c:2264
Abstract JSON element (object, array, string, int, ...).
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.

◆ 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 1739 of file res/stasis/app.c.

References ao2_lock, ao2_ref, ao2_unlock, app, app_event_filter_matched(), stasis_app::events_allowed, stasis_app::events_disallowed, and stasis_app_get_by_name().

Referenced by stasis_app_message_handler().

1740 {
1742  int res;
1743 
1744  if (!app) {
1745  return 0;
1746  }
1747 
1748  ao2_lock(app);
1749  res = !app_event_filter_matched(app->events_disallowed, event, 0) &&
1750  app_event_filter_matched(app->events_allowed, event, 1);
1751  ao2_unlock(app);
1752  ao2_ref(app, -1);
1753 
1754  return res;
1755 }
struct ast_json * events_allowed
struct stasis_app * stasis_app_get_by_name(const char *name)
Retrieve a handle to a Stasis application by its name.
Definition: res_stasis.c:1694
#define ao2_unlock(a)
Definition: astobj2.h:730
static const char app[]
Definition: app_adsiprog.c:56
#define ao2_ref(o, delta)
Definition: astobj2.h:464
#define ao2_lock(a)
Definition: astobj2.h:718
const char * app_name(struct ast_app *app)
Definition: pbx_app.c:463
struct ast_json * events_disallowed
static int app_event_filter_matched(struct ast_json *array, struct ast_json *event, int empty)

◆ 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 1713 of file res/stasis/app.c.

References app_events_allowed_set(), and app_events_disallowed_set().

Referenced by ast_ari_applications_filter().

1714 {
1715  return app_events_disallowed_set(app, filter) || app_events_allowed_set(app, filter);
1716 }
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)

◆ 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 1641 of file res/stasis/app.c.

References ast_json_array_create(), ast_json_object_set(), ast_json_ref(), stasis_app::events_allowed, and stasis_app::events_disallowed.

Referenced by stasis_app_object_to_json().

1642 {
1643  if (!app || !json) {
1644  return json;
1645  }
1646 
1647  ast_json_object_set(json, "events_allowed", app->events_allowed ?
1649  ast_json_object_set(json, "events_disallowed", app->events_disallowed ?
1651 
1652  return json;
1653 }
struct ast_json * events_allowed
struct ast_json * ast_json_ref(struct ast_json *value)
Increase refcount on value.
Definition: json.c:67
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:404
struct ast_json * ast_json_array_create(void)
Create a empty JSON array.
Definition: json.c:352
struct ast_json * events_disallowed

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

References stasis_app::debug, and global_debug.

864 {
865  return (app ? app->debug : 0) || global_debug;
866 }
int 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.

References ao2_ref, app, stasis_app::debug, global_debug, and stasis_app_get_by_name().

Referenced by ast_ari_callback(), and stasis_app_message_handler().

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 }
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:1694
static const char app[]
Definition: app_adsiprog.c:56
#define ao2_ref(o, delta)
Definition: astobj2.h:464
int global_debug
const char * app_name(struct ast_app *app)
Definition: pbx_app.c:463

◆ 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 1156 of file res/stasis/app.c.

References stasis_app::name.

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().

1157 {
1158  return app->name;
1159 }

◆ stasis_app_register_event_sources()

void stasis_app_register_event_sources ( void  )

Register core event sources.

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

References stasis_app_register_event_source().

Referenced by load_module().

1628 {
1632 }
struct stasis_app_event_source bridge_event_source
struct stasis_app_event_source endpoint_event_source
struct stasis_app_event_source channel_event_source
void stasis_app_register_event_source(struct stasis_app_event_source *obj)
Register an application event source.
Definition: res_stasis.c:1816

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

References stasis_app::debug.

Referenced by ari_set_debug(), and stasis_app_set_global_debug().

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

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

References ao2_cleanup, app, stasis_app::debug, and stasis_app_get_by_name().

852 {
854 
855  if (!app) {
856  return;
857  }
858 
859  app->debug = debug;
860  ao2_cleanup(app);
861 }
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:1694
static int debug
Global debug status.
Definition: res_xmpp.c:435
static const char app[]
Definition: app_adsiprog.c:56
const char * app_name(struct ast_app *app)
Definition: pbx_app.c:463
#define ao2_cleanup(obj)
Definition: astobj2.h:1958

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

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

Referenced by ari_set_debug().

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))) {
903  if ((app = stasis_app_get_by_name(app_name))) {
904  stasis_app_set_debug(app, 0);
905  }
906 
907  ao2_cleanup(app_name);
908  ao2_cleanup(app);
909  }
910  ao2_iterator_cleanup(&it_app_names);
911  ao2_cleanup(app_names);
912  }
913 }
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:1694
int ao2_container_count(struct ao2_container *c)
Returns the number of elements in a container.
static int debug
Global debug status.
Definition: res_xmpp.c:435
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.
static const char app[]
Definition: app_adsiprog.c:56
int global_debug
const char * app_name(struct ast_app *app)
Definition: pbx_app.c:463
#define ao2_iterator_next(iter)
Definition: astobj2.h:1933
struct ao2_container * stasis_app_get_all(void)
Gets the names of all registered Stasis applications.
Definition: res_stasis.c:1708
When we need to walk through a container, we use an ao2_iterator to keep track of the current positio...
Definition: astobj2.h:1841
#define ao2_cleanup(obj)
Definition: astobj2.h:1958
Generic container type.
struct ao2_iterator ao2_iterator_init(struct ao2_container *c, int flags) attribute_warn_unused_result
Create an iterator for a container.

◆ 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 1173 of file res/stasis/app.c.

References ao2_callback, ao2_container_count(), ao2_iterator_destroy(), ao2_iterator_next, ao2_ref, ast_cli(), bridges, channels, stasis_app::debug, endpoints, ast_cli_args::fd, FORWARD_BRIDGE, FORWARD_CHANNEL, FORWARD_ENDPOINT, stasis_app::forwards, forwards_filter_by_type(), app_forwards::id, app_forwards::interested, stasis_app::name, OBJ_MULTIPLE, STASIS_APP_SUBSCRIBE_ALL, and stasis_app::subscription_model.

Referenced by ari_show_app().

1174 {
1175  struct ao2_iterator *channels;
1176  struct ao2_iterator *endpoints;
1177  struct ao2_iterator *bridges;
1178  struct app_forwards *forward;
1180 
1181  ast_cli(a->fd, "Name: %s\n"
1182  " Debug: %s\n"
1183  " Subscription Model: %s\n",
1184  app->name,
1185  app->debug ? "Yes" : "No",
1187  "Global Resource Subscription" :
1188  "Application/Explicit Resource Subscription");
1189  ast_cli(a->fd, " Subscriptions: %d\n", ao2_container_count(app->forwards));
1190 
1191  ast_cli(a->fd, " Channels:\n");
1192  forward_type = FORWARD_CHANNEL;
1193  channels = ao2_callback(app->forwards, OBJ_MULTIPLE,
1194  forwards_filter_by_type, &forward_type);
1195  if (channels) {
1196  while ((forward = ao2_iterator_next(channels))) {
1197  ast_cli(a->fd, " %s (%d)\n", forward->id, forward->interested);
1198  ao2_ref(forward, -1);
1199  }
1200  ao2_iterator_destroy(channels);
1201  }
1202 
1203  ast_cli(a->fd, " Bridges:\n");
1204  forward_type = FORWARD_BRIDGE;
1205  bridges = ao2_callback(app->forwards, OBJ_MULTIPLE,
1206  forwards_filter_by_type, &forward_type);
1207  if (bridges) {
1208  while ((forward = ao2_iterator_next(bridges))) {
1209  ast_cli(a->fd, " %s (%d)\n", forward->id, forward->interested);
1210  ao2_ref(forward, -1);
1211  }
1212  ao2_iterator_destroy(bridges);
1213  }
1214 
1215  ast_cli(a->fd, " Endpoints:\n");
1216  forward_type = FORWARD_ENDPOINT;
1217  endpoints = ao2_callback(app->forwards, OBJ_MULTIPLE,
1218  forwards_filter_by_type, &forward_type);
1219  if (endpoints) {
1220  while ((forward = ao2_iterator_next(endpoints))) {
1221  ast_cli(a->fd, " %s (%d)\n", forward->id, forward->interested);
1222  ao2_ref(forward, -1);
1223  }
1224  ao2_iterator_destroy(endpoints);
1225  }
1226 }
int ao2_container_count(struct ao2_container *c)
Returns the number of elements in a container.
static int forwards_filter_by_type(void *obj, void *arg, int flags)
#define ao2_callback(c, flags, cb_fn, arg)
Definition: astobj2.h:1716
void ao2_iterator_destroy(struct ao2_iterator *iter)
Destroy a container iterator.
void ast_cli(int fd, const char *fmt,...)
Definition: clicompat.c:6
struct ao2_container * forwards
const int fd
Definition: cli.h:159
static struct ao2_container * endpoints
#define ao2_ref(o, delta)
Definition: astobj2.h:464
static struct channel_usage channels
#define ao2_iterator_next(iter)
Definition: astobj2.h:1933
static struct ao2_container * bridges
Definition: bridge.c:123
When we need to walk through a container, we use an ao2_iterator to keep track of the current positio...
Definition: astobj2.h:1841
forward_type
enum stasis_app_subscription_model subscription_model

◆ stasis_app_unregister_event_sources()

void stasis_app_unregister_event_sources ( void  )

Unregister core event sources.

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

References stasis_app_unregister_event_source().

Referenced by unload_module().

1635 {
1639 }
struct stasis_app_event_source bridge_event_source
struct stasis_app_event_source endpoint_event_source
void stasis_app_unregister_event_source(struct stasis_app_event_source *obj)
Unregister an application event source.
Definition: res_stasis.c:1823
struct stasis_app_event_source channel_event_source

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

References app, app_send(), ast_json_object_set(), ast_json_string_create(), ast_json_unref(), ast_strlen_zero(), stasis_app::data, ast_bridge_snapshot_update::new_snapshot, NULL, ast_bridge_snapshot_update::old_snapshot, simple_bridge_event(), stasis_message_data(), stasis_message_timestamp(), ast_bridge_snapshot::uniqueid, unsubscribe(), update(), and ast_bridge_snapshot::video_source_id.

Referenced by app_create().

685 {
686  struct ast_json *json = NULL;
687  struct stasis_app *app = data;
689  const struct timeval *tv;
690 
691  update = stasis_message_data(message);
692 
693  tv = stasis_message_timestamp(message);
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",
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
void ast_json_unref(struct ast_json *value)
Decrease refcount on value. If refcount reaches zero, value is freed.
Definition: json.c:73
const ast_string_field video_source_id
Definition: bridge.h:336
#define NULL
Definition: resample.c:96
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:404
static const char app[]
Definition: app_adsiprog.c:56
struct ast_json * ast_json_string_create(const char *value)
Construct a JSON string from value.
Definition: json.c:268
static force_inline int attribute_pure ast_strlen_zero(const char *s)
Definition: strings.h:65
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.
static int unsubscribe(struct stasis_app *app, const char *kind, const char *id, int terminate)
struct ast_bridge_snapshot * old_snapshot
void app_send(struct stasis_app *app, struct ast_json *message)
Send a message to the given application.
void * stasis_message_data(const struct stasis_message *msg)
Get the data contained in a message.
const ast_string_field uniqueid
Definition: bridge.h:336
struct ast_bridge_snapshot * new_snapshot
Abstract JSON element (object, array, string, int, ...).

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

References app, app_send(), ARRAY_LEN, AST_FLAG_DEAD, ast_json_unref(), ast_test_flag, ast_channel_snapshot::base, channel_monitors, stasis_app::data, ast_channel_snapshot::flags, ast_channel_snapshot_update::new_snapshot, ast_channel_snapshot_update::old_snapshot, stasis_message_data(), stasis_message_timestamp(), ast_channel_snapshot_base::uniqueid, unsubscribe(), and update().

Referenced by app_create().

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,
555  stasis_message_timestamp(message));
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 }
struct ast_channel_snapshot_base * base
#define ast_test_flag(p, flag)
Definition: utils.h:63
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
void ast_json_unref(struct ast_json *value)
Decrease refcount on value. If refcount reaches zero, value is freed.
Definition: json.c:73
const ast_string_field uniqueid
Structure representing a change of snapshot of channel state.
static channel_snapshot_monitor channel_monitors[]
static const char app[]
Definition: app_adsiprog.c:56
const struct timeval * stasis_message_timestamp(const struct stasis_message *msg)
Get the time when a message was created.
static int unsubscribe(struct stasis_app *app, const char *kind, const char *id, int terminate)
#define ARRAY_LEN(a)
Definition: utils.h:639
void app_send(struct stasis_app *app, struct ast_json *message)
Send a message to the given application.
void * stasis_message_data(const struct stasis_message *msg)
Get the data contained in a message.
struct ast_channel_snapshot * new_snapshot
struct ast_channel_snapshot * old_snapshot
struct ast_flags flags
Abstract JSON element (object, array, string, int, ...).

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

References app, app_send(), ast_channel_dial_type(), ast_json_unref(), call_forwarded_handler(), stasis_app::data, stasis_app_get_sanitizer(), stasis_message_to_json(), and stasis_message_type().

Referenced by app_create().

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  */
356  if (stasis_message_type(message) == ast_channel_dial_type()) {
357  call_forwarded_handler(app, message);
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 }
void ast_json_unref(struct ast_json *value)
Decrease refcount on value. If refcount reaches zero, value is freed.
Definition: json.c:73
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.
static const char app[]
Definition: app_adsiprog.c:56
static void call_forwarded_handler(struct stasis_app *app, struct stasis_message *message)
void app_send(struct stasis_app *app, struct ast_json *message)
Send a message to the given application.
struct stasis_message_sanitizer * stasis_app_get_sanitizer(void)
Get the Stasis message sanitizer for app_stasis applications.
Definition: res_stasis.c:2264
Abstract JSON element (object, array, string, int, ...).
struct stasis_message_type * ast_channel_dial_type(void)
Message type for when a channel dials another channel.

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

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

Referenced by app_create().

631 {
632  struct stasis_app *app = data;
633  struct stasis_cache_update *update;
634  struct ast_endpoint_snapshot *new_snapshot;
635  struct ast_endpoint_snapshot *old_snapshot;
636  const struct timeval *tv;
637 
639 
640  update = stasis_message_data(message);
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 
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 * old_snapshot
Old value from the cache.
Definition: stasis.h:971
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
void ast_json_unref(struct ast_json *value)
Decrease refcount on value. If refcount reaches zero, value is freed.
Definition: json.c:73
struct stasis_message_type * ast_endpoint_snapshot_type(void)
Message type for ast_endpoint_snapshot.
struct stasis_message_type * stasis_message_type(const struct stasis_message *msg)
Get the message type for a stasis_message.
#define ast_assert(a)
Definition: utils.h:710
const ast_string_field id
static const char app[]
Definition: app_adsiprog.c:56
const struct timeval * stasis_message_timestamp(const struct stasis_message *msg)
Get the time when a message was created.
struct stasis_message_type * stasis_cache_update_type(void)
Message type for cache update messages.
static int unsubscribe(struct stasis_app *app, const char *kind, const char *id, int terminate)
Cache update message.
Definition: stasis.h:967
A snapshot of an endpoint&#39;s state.
struct stasis_message * new_snapshot
New value.
Definition: stasis.h:973
static struct ast_json * simple_endpoint_event(const char *type, struct ast_endpoint_snapshot *snapshot, const struct timeval *tv)
void app_send(struct stasis_app *app, struct ast_json *message)
Send a message to the given application.
void * stasis_message_data(const struct stasis_message *msg)
Get the data contained in a message.
struct stasis_message_type * type
Convenience reference to snapshot type.
Definition: stasis.h:969
Abstract JSON element (object, array, string, int, ...).

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

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

Referenced by app_create().

339 {
340  struct stasis_app *app = data;
341 
342  if (stasis_subscription_final_message(sub, message)) {
343  ao2_cleanup(app);
344  }
345 }
static const char app[]
Definition: app_adsiprog.c:56
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:1176
#define ao2_cleanup(obj)
Definition: astobj2.h:1958

◆ subscribe_bridge()

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

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

References app_subscribe_bridge().

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

◆ subscribe_channel()

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

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

References app_subscribe_channel().

1335 {
1336  return app_subscribe_channel(app, obj);
1337 }
int app_subscribe_channel(struct stasis_app *app, struct ast_channel *chan)
Subscribes an application to a channel.

◆ subscribe_endpoint()

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

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

References app_subscribe_endpoint().

1588 {
1589  return app_subscribe_endpoint(app, obj);
1590 }
int app_subscribe_endpoint(struct stasis_app *app, struct ast_endpoint *endpoint)
Subscribes an application to a endpoint.

◆ unsubscribe()

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

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

References ao2_find, ao2_lock, ao2_ref, ao2_unlock, ast_debug, ast_log, BRIDGE_ALL, CHANNEL_ALL, ENDPOINT_ALL, stasis_app::forwards, forwards_unsubscribe(), app_forwards::interested, LOG_WARNING, messaging_app_unsubscribe_endpoint(), stasis_app::name, 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().

1340 {
1341  struct app_forwards *forwards;
1342 
1343  if (!id) {
1344  if (!strcmp(kind, "bridge")) {
1345  id = BRIDGE_ALL;
1346  } else if (!strcmp(kind, "channel")) {
1347  id = CHANNEL_ALL;
1348  } else if (!strcmp(kind, "endpoint")) {
1349  id = ENDPOINT_ALL;
1350  } else {
1351  ast_log(LOG_WARNING, "Unknown subscription kind '%s'\n", kind);
1352  return -1;
1353  }
1354  }
1355 
1356  ao2_lock(app->forwards);
1357  forwards = ao2_find(app->forwards, id, OBJ_SEARCH_KEY | OBJ_NOLOCK);
1358  if (!forwards) {
1359  ao2_unlock(app->forwards);
1360  ast_debug(3, "App '%s' not subscribed to %s '%s'\n", app->name, kind, id);
1361  return -1;
1362  }
1363  forwards->interested--;
1364 
1365  ast_debug(3, "%s '%s': is %d interested in %s\n", kind, id, forwards->interested, app->name);
1366  if (forwards->interested == 0 || terminate) {
1367  /* No one is interested any more; unsubscribe */
1368  ast_debug(3, "%s '%s' unsubscribed from %s\n", kind, id, app->name);
1369  forwards_unsubscribe(forwards);
1370  ao2_find(app->forwards, forwards,
1372  OBJ_NODATA);
1373 
1374  if (!strcmp(kind, "endpoint")) {
1376  }
1377  }
1378  ao2_unlock(app->forwards);
1379  ao2_ref(forwards, -1);
1380 
1381  return 0;
1382 }
#define CHANNEL_ALL
The arg parameter is a search key, but is not an object.
Definition: astobj2.h:1105
#define OBJ_POINTER
Definition: astobj2.h:1154
#define LOG_WARNING
Definition: logger.h:274
Assume that the ao2_container is already locked.
Definition: astobj2.h:1067
#define ao2_unlock(a)
Definition: astobj2.h:730
struct ao2_container * forwards
#define ast_debug(level,...)
Log a DEBUG message.
Definition: logger.h:444
#define ast_log
Definition: astobj2.c:42
#define ao2_ref(o, delta)
Definition: astobj2.h:464
#define ao2_lock(a)
Definition: astobj2.h:718
static void forwards_unsubscribe(struct app_forwards *forwards)
#define ao2_find(container, arg, flags)
Definition: astobj2.h:1756
#define BRIDGE_ALL
void messaging_app_unsubscribe_endpoint(const char *app_name, const char *endpoint_id)
Subscribe for messages from a particular endpoint.
Definition: messaging.c:423
#define ENDPOINT_ALL

Variable Documentation

◆ bridge_event_source

struct stasis_app_event_source bridge_event_source

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

◆ channel_event_source

struct stasis_app_event_source channel_event_source

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

◆ 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

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

◆ 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().