Asterisk - The Open Source Telephony Project  21.4.1
Functions | Variables
confbridge_manager.c File Reference

Confbridge manager events for stasis messages. More...

#include "asterisk.h"
#include "asterisk/channel.h"
#include "asterisk/bridge.h"
#include "asterisk/stasis.h"
#include "asterisk/stasis_channels.h"
#include "asterisk/stasis_bridges.h"
#include "asterisk/manager.h"
#include "asterisk/stasis_message_router.h"
#include "include/confbridge.h"
#include "asterisk/message.h"
#include "asterisk/stream.h"

Go to the source code of this file.

Functions

static struct ast_jsonbridge_to_json (struct ast_bridge_snapshot *bridge_snapshot)
 
static struct ast_jsonchannel_to_json (struct ast_channel_snapshot *channel_snapshot, struct ast_json *conf_blob, struct ast_json *labels_blob)
 
void conf_send_event_to_participants (struct confbridge_conference *conference, struct ast_channel *chan, struct stasis_message *msg)
 Send events to bridge participants. More...
 
static void confbridge_atxfer_cb (void *data, struct stasis_subscription *sub, struct stasis_message *message)
 
static void confbridge_end_cb (void *data, struct stasis_subscription *sub, struct stasis_message *message)
 
const char * confbridge_event_type_to_string (struct stasis_message_type *event_type)
 Get the string representation of a confbridge stasis message type. More...
 
static void confbridge_join_cb (void *data, struct stasis_subscription *sub, struct stasis_message *message)
 
static void confbridge_leave_cb (void *data, struct stasis_subscription *sub, struct stasis_message *message)
 
static void confbridge_mute_cb (void *data, struct stasis_subscription *sub, struct stasis_message *message)
 
static void confbridge_publish_manager_event (struct stasis_message *message, struct ast_str *extra_text)
 
static void confbridge_start_cb (void *data, struct stasis_subscription *sub, struct stasis_message *message)
 
static void confbridge_start_record_cb (void *data, struct stasis_subscription *sub, struct stasis_message *message)
 
static void confbridge_stop_record_cb (void *data, struct stasis_subscription *sub, struct stasis_message *message)
 
static void confbridge_talking_cb (void *data, struct stasis_subscription *sub, struct stasis_message *message)
 
static void confbridge_unmute_cb (void *data, struct stasis_subscription *sub, struct stasis_message *message)
 
static int get_admin_header (struct ast_str **extra_text, struct stasis_message *message)
 
static int get_bool_header (struct ast_str **extra_text, struct stasis_message *message, const char *json_key, const char *ami_header)
 
static int get_muted_header (struct ast_str **extra_text, struct stasis_message *message)
 
int manager_confbridge_init (void)
 register stasis message routers to handle manager events for confbridge messages More...
 
void manager_confbridge_shutdown (void)
 unregister stasis message routers to handle manager events for confbridge messages More...
 
static struct ast_jsonpack_bridge_and_channels (struct ast_json *json_bridge, struct ast_json *json_channels, struct stasis_message *msg)
 
static struct ast_jsonpack_snapshots (struct ast_bridge_snapshot *bridge_snapshot, struct ast_channel_snapshot *channel_snapshot, struct ast_json *conf_blob, struct ast_json *labels_blob, struct stasis_message *msg)
 
static void send_message (const char *msg_name, char *conf_name, struct ast_json *json_object, struct ast_channel *chan)
 
 STASIS_MESSAGE_TYPE_DEFN (confbridge_start_type)
 
 STASIS_MESSAGE_TYPE_DEFN (confbridge_end_type)
 
 STASIS_MESSAGE_TYPE_DEFN (confbridge_join_type)
 
 STASIS_MESSAGE_TYPE_DEFN (confbridge_leave_type)
 
 STASIS_MESSAGE_TYPE_DEFN (confbridge_start_record_type)
 
 STASIS_MESSAGE_TYPE_DEFN (confbridge_stop_record_type)
 
 STASIS_MESSAGE_TYPE_DEFN (confbridge_mute_type)
 
 STASIS_MESSAGE_TYPE_DEFN (confbridge_unmute_type)
 
 STASIS_MESSAGE_TYPE_DEFN (confbridge_talking_type)
 
 STASIS_MESSAGE_TYPE_DEFN (confbridge_welcome_type)
 

Variables

static struct stasis_message_routerbridge_state_router
 
static struct stasis_message_routerchannel_state_router
 

Detailed Description

Confbridge manager events for stasis messages.

Author
Jonathan Rose jrose.nosp@m.@dig.nosp@m.ium.c.nosp@m.om

Definition in file confbridge_manager.c.

Function Documentation

void conf_send_event_to_participants ( struct confbridge_conference conference,
struct ast_channel chan,
struct stasis_message msg 
)

Send events to bridge participants.

Since
15.7
16.1
Parameters
conferenceThe conference bridge
chanThe channel triggering the action
msgThe stasis message describing the event

Definition at line 414 of file confbridge_manager.c.

References confbridge_conference::active_list, ao2_ref, ast_channel_snapshot_get_latest(), ast_debug, ast_json_array_append(), ast_json_array_create(), ast_json_object_get(), ast_json_string_set(), ast_json_unref(), AST_LIST_TRAVERSE, ast_bridge_blob::blob, ast_bridge_blob::bridge, confbridge_user::chan, ast_bridge_blob::channel, conf_find_user_profile(), confbridge_event_type_to_string(), confbridge_user::list, confbridge_conference::name, stasis_message_data(), stasis_message_type(), and confbridge_user::u_profile.

416 {
417  struct ast_bridge_blob *obj = stasis_message_data(msg);
418  struct ast_json *extras = obj->blob;
419  struct user_profile u_profile = {{0}};
420  int source_send_events = 0;
421  int source_echo_events = 0;
422  struct ast_json* json_channels = NULL;
423  struct confbridge_user *user;
424  const char *msg_name = confbridge_event_type_to_string(stasis_message_type(msg));
425 
426  ast_debug(3, "Distributing %s event to participants\n", msg_name);
427 
428  /* This could be a channel level event or a bridge level event */
429  if (chan) {
430  if (!conf_find_user_profile(chan, NULL, &u_profile)) {
431  ast_log(LOG_ERROR, "Unable to retrieve user profile for channel '%s'\n",
432  ast_channel_name(chan));
433  return;
434  }
435  source_send_events = ast_test_flag(&u_profile, USER_OPT_SEND_EVENTS);
436  source_echo_events = ast_test_flag(&u_profile, USER_OPT_ECHO_EVENTS);
437  ast_debug(3, "send_events: %d echo_events: %d for profile %s\n",
438  source_send_events, source_echo_events, u_profile.name);
439  }
440 
441  /* Now send a message to the participants with the json string. */
442  ao2_lock(conference);
443  AST_LIST_TRAVERSE(&conference->active_list, user, list) {
444  struct ast_json *json_object;
445 
446  /*
447  * If the msg type is join, we need to capture all targets channel info so we can
448  * send a welcome message to the source channel with all current participants.
449  */
450  if (source_send_events && stasis_message_type(msg) == confbridge_join_type()) {
451  struct ast_channel_snapshot *target_snapshot;
452  struct ast_json *target_json_channel;
453 
454  target_snapshot = ast_channel_snapshot_get_latest(ast_channel_uniqueid(user->chan));
455  if (!target_snapshot) {
456  ast_log(LOG_ERROR, "Unable to get a channel snapshot for '%s'\n",
457  ast_channel_name(user->chan));
458  continue;
459  }
460 
461  target_json_channel = channel_to_json(target_snapshot, extras, NULL);
462  ao2_ref(target_snapshot, -1);
463 
464  if (!json_channels) {
465  json_channels = ast_json_array_create();
466  if (!json_channels) {
467  ast_log(LOG_ERROR, "Unable to allocate json array\n");
468  ast_json_unref(target_json_channel);
469  return;
470  }
471  }
472 
473  ast_json_array_append(json_channels, target_json_channel);
474  }
475 
476  /* Don't send a message to the user that triggered the event. */
477  if (!source_echo_events && user->chan == chan) {
478  ast_debug(3, "Skipping queueing %s message to '%s'. Same channel.\n", msg_name,
479  ast_channel_name(user->chan));
480  continue;
481  }
482 
483  /* Don't send a message to users in profiles not sending events. */
484  if (!ast_test_flag(&user->u_profile, USER_OPT_SEND_EVENTS)) {
485  ast_debug(3, "Skipping queueing %s message to '%s'. Not receiving events.\n", msg_name,
486  ast_channel_name(user->chan));
487  continue;
488  }
489 
490  json_object = pack_snapshots(obj->bridge, obj->channel, extras, NULL, msg);
491 
492  if (!json_object) {
493  ast_log(LOG_ERROR, "Unable to convert %s message to json\n", msg_name);
494  continue;
495  }
496 
497  send_message(msg_name, conference->name, json_object, user->chan);
498  ast_json_unref(json_object);
499  }
500  ao2_unlock(conference);
501 
502  /*
503  * If this is a join event, send the welcome message to just the joining user
504  * if it's not audio-only or otherwise restricted.
505  */
506  if (source_send_events && json_channels
507  && stasis_message_type(msg) == confbridge_join_type()) {
508  struct ast_json *json_object;
509  struct ast_json *json_bridge;
510  const char *welcome_msg_name = confbridge_event_type_to_string(confbridge_welcome_type());
511 
512  json_bridge = bridge_to_json(obj->bridge);
513  json_object = pack_bridge_and_channels(json_bridge, json_channels, msg);
514  if (!json_object) {
515  ast_log(LOG_ERROR, "Unable to convert ConfbridgeWelcome message to json\n");
516  return;
517  }
518  ast_json_string_set(ast_json_object_get(json_object, "type"), welcome_msg_name);
519 
520  send_message(welcome_msg_name, conference->name, json_object, chan);
521  ast_json_unref(json_object);
522  }
523 }
struct ast_channel * chan
Definition: confbridge.h:279
struct ast_channel_snapshot * channel
void ast_json_unref(struct ast_json *value)
Decrease refcount on value. If refcount reaches zero, value is freed.
Definition: json.c:73
const struct user_profile * conf_find_user_profile(struct ast_channel *chan, const char *user_profile_name, struct user_profile *result)
find a user profile given a user profile's name and store that profile in result structure.
Structure representing a snapshot of channel state.
struct ast_json * blob
struct stasis_message_type * stasis_message_type(const struct stasis_message *msg)
Get the message type for a stasis_message.
struct confbridge_user::@94 list
struct confbridge_conference::@90 active_list
struct ast_bridge_snapshot * bridge
#define ao2_ref(o, delta)
Reference/unreference an object and return the old refcount.
Definition: astobj2.h:459
#define ast_debug(level,...)
Log a DEBUG message.
Blob of data associated with a bridge.
struct ast_json * ast_json_array_create(void)
Create a empty JSON array.
Definition: json.c:362
int ast_json_array_append(struct ast_json *array, struct ast_json *value)
Append to an array.
Definition: json.c:378
void * stasis_message_data(const struct stasis_message *msg)
Get the data contained in a message.
#define AST_LIST_TRAVERSE(head, var, field)
Loops over (traverses) the entries in a list.
Definition: linkedlists.h:491
const char * confbridge_event_type_to_string(struct stasis_message_type *event_type)
Get the string representation of a confbridge stasis message type.
structure to hold users read from users.conf
struct ast_channel_snapshot * ast_channel_snapshot_get_latest(const char *uniqueid)
Obtain the latest ast_channel_snapshot from the Stasis Message Bus API cache. This is an ao2 object...
struct ast_json * ast_json_object_get(struct ast_json *object, const char *key)
Get a field from a JSON object.
Definition: json.c:407
Abstract JSON element (object, array, string, int, ...).
The structure that represents a conference bridge user.
Definition: confbridge.h:273
struct user_profile u_profile
Definition: confbridge.h:276
int ast_json_string_set(struct ast_json *string, const char *value)
Change the value of a JSON string.
Definition: json.c:288
char name[MAX_CONF_NAME]
Definition: confbridge.h:247
const char* confbridge_event_type_to_string ( struct stasis_message_type event_type)

Get the string representation of a confbridge stasis message type.

Since
15.5
Parameters
event_typeThe confbridge event type such as 'confbridge_welcome_type()'
Return values
Thestring representation of the message type
unknownif not found

Definition at line 249 of file confbridge_manager.c.

Referenced by conf_send_event_to_participants().

250 {
251  if (event_type == confbridge_start_type()) {
252  return "ConfbridgeStart";
253  } else if (event_type == confbridge_end_type()) {
254  return "ConfbridgeEnd";
255  } else if (event_type == confbridge_join_type()) {
256  return "ConfbridgeJoin";
257  } else if (event_type == confbridge_leave_type()) {
258  return "ConfbridgeLeave";
259  } else if (event_type == confbridge_start_record_type()) {
260  return "ConfbridgeRecord";
261  } else if (event_type == confbridge_stop_record_type()) {
262  return "ConfbridgeStopRecord";
263  } else if (event_type == confbridge_mute_type()) {
264  return "ConfbridgeMute";
265  } else if (event_type == confbridge_unmute_type()) {
266  return "ConfbridgeUnmute";
267  } else if (event_type == confbridge_talking_type()) {
268  return "ConfbridgeTalking";
269  } else if (event_type == confbridge_welcome_type()) {
270  return "ConfbridgeWelcome";
271  } else {
272  return "unknown";
273  }
274 }
int manager_confbridge_init ( void  )

register stasis message routers to handle manager events for confbridge messages

Since
12.0
Return values
0success
non-zerofailure

Definition at line 721 of file confbridge_manager.c.

References ast_bridge_topic_all(), ast_channel_topic_all(), manager_confbridge_shutdown(), stasis_message_router_add(), and STASIS_MESSAGE_TYPE_INIT.

Referenced by load_module().

722 {
723  STASIS_MESSAGE_TYPE_INIT(confbridge_start_type);
724  STASIS_MESSAGE_TYPE_INIT(confbridge_end_type);
725  STASIS_MESSAGE_TYPE_INIT(confbridge_join_type);
726  STASIS_MESSAGE_TYPE_INIT(confbridge_leave_type);
727  STASIS_MESSAGE_TYPE_INIT(confbridge_start_record_type);
728  STASIS_MESSAGE_TYPE_INIT(confbridge_stop_record_type);
729  STASIS_MESSAGE_TYPE_INIT(confbridge_mute_type);
730  STASIS_MESSAGE_TYPE_INIT(confbridge_unmute_type);
731  STASIS_MESSAGE_TYPE_INIT(confbridge_talking_type);
732  STASIS_MESSAGE_TYPE_INIT(confbridge_welcome_type);
733 
734  bridge_state_router = stasis_message_router_create(
736 
737  if (!bridge_state_router) {
738  return -1;
739  }
740 
742  confbridge_start_type(),
743  confbridge_start_cb,
744  NULL)) {
746  return -1;
747  }
749  confbridge_end_type(),
750  confbridge_end_cb,
751  NULL)) {
753  return -1;
754  }
756  confbridge_join_type(),
757  confbridge_join_cb,
758  NULL)) {
760  return -1;
761  }
763  ast_attended_transfer_type(),
764  confbridge_atxfer_cb,
765  NULL)) {
767  return -1;
768  }
770  confbridge_leave_type(),
771  confbridge_leave_cb,
772  NULL)) {
774  return -1;
775  }
777  confbridge_start_record_type(),
778  confbridge_start_record_cb,
779  NULL)) {
781  return -1;
782  }
784  confbridge_stop_record_type(),
785  confbridge_stop_record_cb,
786  NULL)) {
788  return -1;
789  }
791  confbridge_mute_type(),
792  confbridge_mute_cb,
793  NULL)) {
795  return -1;
796  }
798  confbridge_unmute_type(),
799  confbridge_unmute_cb,
800  NULL)) {
802  return -1;
803  }
805  confbridge_talking_type(),
806  confbridge_talking_cb,
807  NULL)) {
809  return -1;
810  }
811 
812  channel_state_router = stasis_message_router_create(
814 
815  if (!channel_state_router) {
817  return -1;
818  }
819 
820  if (stasis_message_router_add(channel_state_router,
821  confbridge_start_type(),
822  confbridge_start_cb,
823  NULL)) {
825  return -1;
826  }
827  if (stasis_message_router_add(channel_state_router,
828  confbridge_end_type(),
829  confbridge_end_cb,
830  NULL)) {
832  return -1;
833  }
834  if (stasis_message_router_add(channel_state_router,
835  confbridge_join_type(),
836  confbridge_join_cb,
837  NULL)) {
839  return -1;
840  }
841  if (stasis_message_router_add(channel_state_router,
842  confbridge_leave_type(),
843  confbridge_leave_cb,
844  NULL)) {
846  return -1;
847  }
848  if (stasis_message_router_add(channel_state_router,
849  confbridge_start_record_type(),
850  confbridge_start_record_cb,
851  NULL)) {
853  return -1;
854  }
855  if (stasis_message_router_add(channel_state_router,
856  confbridge_stop_record_type(),
857  confbridge_stop_record_cb,
858  NULL)) {
860  return -1;
861  }
862  if (stasis_message_router_add(channel_state_router,
863  confbridge_mute_type(),
864  confbridge_mute_cb,
865  NULL)) {
867  return -1;
868  }
869  if (stasis_message_router_add(channel_state_router,
870  confbridge_unmute_type(),
871  confbridge_unmute_cb,
872  NULL)) {
874  return -1;
875  }
876  if (stasis_message_router_add(channel_state_router,
877  confbridge_talking_type(),
878  confbridge_talking_cb,
879  NULL)) {
881  return -1;
882  }
883 
884  /* FYI: confbridge_welcome_type is never routed */
885 
886  return 0;
887 }
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.
#define STASIS_MESSAGE_TYPE_INIT(name)
Boiler-plate messaging macro for initializing message types.
Definition: stasis.h:1493
struct stasis_topic * ast_bridge_topic_all(void)
A topic which publishes the events for all bridges.
struct stasis_topic * ast_channel_topic_all(void)
A topic which publishes the events for all channels.
void manager_confbridge_shutdown(void)
unregister stasis message routers to handle manager events for confbridge messages ...
static struct stasis_message_router * bridge_state_router
Message router for cached bridge state snapshot updates.
void manager_confbridge_shutdown ( void  )

unregister stasis message routers to handle manager events for confbridge messages

Since
12.0

Definition at line 698 of file confbridge_manager.c.

References stasis_message_router_unsubscribe(), and STASIS_MESSAGE_TYPE_CLEANUP.

Referenced by manager_confbridge_init(), and unload_module().

698  {
699  STASIS_MESSAGE_TYPE_CLEANUP(confbridge_start_type);
700  STASIS_MESSAGE_TYPE_CLEANUP(confbridge_end_type);
701  STASIS_MESSAGE_TYPE_CLEANUP(confbridge_join_type);
702  STASIS_MESSAGE_TYPE_CLEANUP(confbridge_leave_type);
703  STASIS_MESSAGE_TYPE_CLEANUP(confbridge_start_record_type);
704  STASIS_MESSAGE_TYPE_CLEANUP(confbridge_stop_record_type);
705  STASIS_MESSAGE_TYPE_CLEANUP(confbridge_mute_type);
706  STASIS_MESSAGE_TYPE_CLEANUP(confbridge_unmute_type);
707  STASIS_MESSAGE_TYPE_CLEANUP(confbridge_talking_type);
708  STASIS_MESSAGE_TYPE_CLEANUP(confbridge_welcome_type);
709 
710  if (bridge_state_router) {
712  bridge_state_router = NULL;
713  }
714 
715  if (channel_state_router) {
716  stasis_message_router_unsubscribe(channel_state_router);
717  channel_state_router = NULL;
718  }
719 }
#define STASIS_MESSAGE_TYPE_CLEANUP(name)
Boiler-plate messaging macro for cleaning up message types.
Definition: stasis.h:1515
void stasis_message_router_unsubscribe(struct stasis_message_router *router)
Unsubscribe the router from the upstream topic.
static struct stasis_message_router * bridge_state_router
Message router for cached bridge state snapshot updates.