40 #include <sys/types.h>
52 HOLDING_ROLE_PARTICIPANT,
53 HOLDING_ROLE_ANNOUNCER,
67 enum holding_roles role;
68 enum idle_modes idle_mode;
80 static void deferred_action(
struct ast_bridge_channel *bridge_channel,
const void *payload,
size_t payload_size);
93 static int defer_action(
struct ast_bridge_channel *bridge_channel, deferred_cb callback)
101 ast_log(LOG_WARNING,
"Bridge %s: Could not defer action on %s.\n",
119 ast_assert(hc != NULL);
121 if (ast_strlen_zero(idle_mode)) {
122 hc->idle_mode = IDLE_MODE_MOH;
123 }
else if (!strcmp(idle_mode,
"musiconhold")) {
124 hc->idle_mode = IDLE_MODE_MOH;
125 }
else if (!strcmp(idle_mode,
"ringing")) {
126 hc->idle_mode = IDLE_MODE_RINGING;
127 }
else if (!strcmp(idle_mode,
"none")) {
128 hc->idle_mode = IDLE_MODE_NONE;
129 }
else if (!strcmp(idle_mode,
"silence")) {
130 hc->idle_mode = IDLE_MODE_SILENCE;
131 }
else if (!strcmp(idle_mode,
"hold")) {
132 hc->idle_mode = IDLE_MODE_HOLD;
135 ast_debug(1,
"channel %s idle mode '%s' doesn't match any defined idle mode\n",
136 ast_channel_name(bridge_channel->
chan), idle_mode);
145 ast_assert(hc != NULL);
153 switch (hc->idle_mode) {
157 case IDLE_MODE_RINGING:
162 case IDLE_MODE_SILENCE:
163 if (hc->silence_generator) {
165 hc->silence_generator = NULL;
174 static void participant_reaction_announcer_join(
struct ast_bridge_channel *bridge_channel)
178 chan = bridge_channel->
chan;
179 participant_entertainment_stop(bridge_channel);
181 ast_log(LOG_WARNING,
"Could not make participant %s compatible.\n", ast_channel_name(chan));
186 static void participant_entertainment_start(
struct ast_bridge_channel *bridge_channel)
189 const char *moh_class;
192 ast_assert(hc != NULL);
200 participant_idle_mode_setup(bridge_channel);
201 switch(hc->idle_mode) {
205 ast_log(LOG_WARNING,
"Failed to start moh, starting silence generator instead\n");
206 hc->idle_mode = IDLE_MODE_SILENCE;
210 case IDLE_MODE_RINGING:
215 case IDLE_MODE_SILENCE:
220 moh_length = moh_class ? strlen(moh_class + 1) : 0;
231 if (!announcer_channel) {
232 defer_action(bridge_channel, participant_entertainment_start);
238 ast_log(LOG_WARNING,
"Could not make participant %s compatible.\n", ast_channel_name(us));
249 ast_assert(bridge_channel->
tech_pvt == NULL);
258 announcer_channel = bridge->
tech_pvt;
261 if (announcer_channel) {
265 ast_log(LOG_WARNING,
"Bridge %s: Channel %s tried to be an announcer. Bridge already has one.\n",
266 bridge->
uniqueid, ast_channel_name(bridge_channel->
chan));
271 hc->role = HOLDING_ROLE_ANNOUNCER;
275 ast_log(LOG_ERROR,
"Could not make announcer %s compatible.\n", ast_channel_name(us));
281 if (bridge_channel == other_channel) {
284 defer_action(other_channel, participant_reaction_announcer_join);
290 hc->role = HOLDING_ROLE_PARTICIPANT;
291 handle_participant_join(bridge_channel, announcer_channel);
295 static void participant_reaction_announcer_leave(
struct ast_bridge_channel *bridge_channel)
298 participant_entertainment_start(bridge_channel);
311 case HOLDING_ROLE_ANNOUNCER:
317 defer_action(other_channel, participant_reaction_announcer_leave);
322 participant_entertainment_stop(bridge_channel);
340 case HOLDING_ROLE_ANNOUNCER:
361 case HOLDING_ROLE_PARTICIPANT:
362 participant_entertainment_stop(bridge_channel);
379 case HOLDING_ROLE_PARTICIPANT:
380 if (announcer_channel) {
385 participant_entertainment_start(bridge_channel);
393 .
name =
"holding_bridge",
395 .preference = AST_BRIDGE_PREFERENCE_BASE_HOLDING,
396 .write = holding_bridge_write,
397 .join = holding_bridge_join,
398 .leave = holding_bridge_leave,
399 .suspend = holding_bridge_suspend,
400 .unsuspend = holding_bridge_unsuspend,
412 static void deferred_action(
struct ast_bridge_channel *bridge_channel,
const void *payload,
size_t payload_size)
427 static int unload_module(
void)
433 static int load_module(
void)
int ast_bridge_channel_has_role(struct ast_bridge_channel *bridge_channel, const char *role_name)
Check to see if a bridge channel inherited a specific role from its channel.
Main Channel structure associated with a channel.
Asterisk main include file. File version handling, generic pbx functions.
const ast_string_field uniqueid
int ast_indicate(struct ast_channel *chan, int condition)
Indicates condition of channel.
int ast_indicate_data(struct ast_channel *chan, int condition, const void *data, size_t datalen)
Indicates condition of channel, with payload.
int ast_bridge_queue_everyone_else(struct ast_bridge *bridge, struct ast_bridge_channel *bridge_channel, struct ast_frame *frame)
Queue the given frame to everyone else.
void ast_moh_stop(struct ast_channel *chan)
Turn off music on hold on a given channel.
struct ast_bridge * bridge
Bridge this channel is participating in.
struct ast_bridge_technology * technology
struct ast_bridge_channel * bridge_channel
General Asterisk PBX channel definitions.
Structure which contains per-channel role information.
int ast_set_read_format(struct ast_channel *chan, struct ast_format *format)
Sets read format on channel chan.
Asterisk internal frame definitions.
#define ast_debug(level,...)
Log a DEBUG message.
int ast_set_write_format(struct ast_channel *chan, struct ast_format *format)
Sets write format on channel chan.
#define ast_bridge_technology_register(technology)
See __ast_bridge_technology_register()
struct ast_silence_generator * ast_channel_start_silence_generator(struct ast_channel *chan)
Starts a silence generator on the given channel.
Structure that contains information about a bridge.
int ast_bridge_technology_unregister(struct ast_bridge_technology *technology)
Unregister a bridge technology from use.
int ast_moh_start(struct ast_channel *chan, const char *mclass, const char *interpclass)
Turn on music on hold on a given channel.
int ast_bridge_channel_queue_callback(struct ast_bridge_channel *bridge_channel, enum ast_bridge_channel_custom_callback_option flags, ast_bridge_custom_callback_fn callback, const void *payload, size_t payload_size)
Queue a bridge action custom callback frame onto the bridge channel.
struct ast_bridge * bridge
#define AST_LIST_TRAVERSE(head, var, field)
Loops over (traverses) the entries in a list.
void ast_channel_stop_silence_generator(struct ast_channel *chan, struct ast_silence_generator *state)
Stops a previously-started silence generator on the given channel.
#define ast_bridge_unlock(bridge)
Unlock the bridge.
#define ast_calloc(num, len)
A wrapper for calloc()
Module has failed to load, may be in an inconsistent state.
void * tech_pvt
Private information unique to the bridge technology.
struct ast_bridge_channels_list channels
struct ast_channel * chan
Structure that contains information regarding a channel in a bridge.
void ast_bridge_channel_lock_bridge(struct ast_bridge_channel *bridge_channel)
Lock the bridge associated with the bridge channel.
Structure that is the essence of a bridge technology.
Data structure associated with a single frame of data.
void ast_bridge_channel_restore_formats(struct ast_bridge_channel *bridge_channel)
Restore the formats of a bridge channel's channel to how they were before bridge_channel_internal_joi...
#define ASTERISK_GPL_KEY
The text the key() function should return.
Asterisk module definitions.
const char * ast_bridge_channel_get_role_option(struct ast_bridge_channel *bridge_channel, const char *role_name, const char *option)
Retrieve the value of a requested role option from a bridge channel.
unsigned int entertainment_active