static struct ast_channel *announce_request(const char *type, struct ast_format_cap *cap, const struct ast_assigned_ids *assignedids, const struct ast_channel *requestor, const char *data, int *cause) { struct ast_channel *chan; const char *conf_name = data; /* Allocate a new private structure and then Asterisk channels */ struct announce_pvt *pvt = (struct announce_pvt *) ast_unreal_alloc(sizeof(*pvt), announce_pvt_destructor, cap); if (!pvt) { return NULL; } ast_set_flag(&pvt->base, AST_UNREAL_NO_OPTIMIZATION); ast_copy_string(pvt->base.name, conf_name, sizeof(pvt->base.name)); #if !defined(CS_AST_CHANNEL_CALLID_TYPEDEF) chan = ast_unreal_new_channels(&pvt->base, sccpconf_announce_get_tech(), AST_STATE_UP, AST_STATE_UP, NULL, NULL, assignedids, requestor, NULL); #else chan = ast_unreal_new_channels(&pvt->base, sccpconf_announce_get_tech(), AST_STATE_UP, AST_STATE_UP, NULL, NULL, assignedids, requestor, 0); #endif if (chan) { ast_answer(pvt->base.owner); ast_answer(pvt->base.chan); if (ast_channel_add_bridge_role(pvt->base.chan, "announcer")) { ast_hangup(chan); chan = NULL; } } ao2_cleanup(pvt); return chan; }
static struct ast_channel *media_request_helper(struct ast_format_cap *cap, const struct ast_assigned_ids *assignedids, const struct ast_channel *requestor, const char *data, struct ast_channel_tech *tech, const char *role) { struct ast_channel *chan; ast_callid callid; RAII_VAR(struct ast_unreal_pvt *, pvt, NULL, ao2_cleanup); if (!(pvt = ast_unreal_alloc(sizeof(*pvt), ast_unreal_destructor, cap))) { return NULL; } ast_copy_string(pvt->name, data, sizeof(pvt->name)); ast_set_flag(pvt, AST_UNREAL_NO_OPTIMIZATION); callid = ast_read_threadstorage_callid(); chan = ast_unreal_new_channels(pvt, tech, AST_STATE_UP, AST_STATE_UP, NULL, NULL, assignedids, requestor, callid); if (!chan) { return NULL; } ast_answer(pvt->owner); ast_answer(pvt->chan); if (ast_channel_add_bridge_role(pvt->chan, role)) { ast_hangup(chan); return NULL; } return chan; }
static struct ast_channel *rec_request(const char *type, struct ast_format_cap *cap, const struct ast_channel *requestor, const char *data, int *cause) { struct ast_channel *chan; struct ast_format format; const char *conf_name = data; chan = ast_channel_alloc(1, AST_STATE_UP, NULL, NULL, NULL, NULL, NULL, NULL, 0, "CBRec/conf-%s-uid-%d", conf_name, (int) ast_random()); if (!chan) { return NULL; } if (ast_channel_add_bridge_role(chan, "recorder")) { ast_channel_release(chan); return NULL; } ast_format_set(&format, AST_FORMAT_SLINEAR, 0); ast_channel_tech_set(chan, conf_record_get_tech()); ast_format_cap_add_all(ast_channel_nativeformats(chan)); ast_format_copy(ast_channel_writeformat(chan), &format); ast_format_copy(ast_channel_rawwriteformat(chan), &format); ast_format_copy(ast_channel_readformat(chan), &format); ast_format_copy(ast_channel_rawreadformat(chan), &format); return chan; }
static int app_control_add_role(struct stasis_app_control *control, struct ast_channel *chan, void *data) { char *role = data; return ast_channel_add_bridge_role(chan, role); }
/*! * \internal * \brief Push this channel into the Stasis bridge. * \since 12.5.0 * * \param self Bridge to operate upon. * \param bridge_channel Bridge channel to push. * \param swap Bridge channel to swap places with if not NULL. * * \note On entry, self is already locked. * * \retval 0 on success. * \retval -1 on failure. The channel did not get pushed. */ static int bridge_stasis_push(struct ast_bridge *self, struct ast_bridge_channel *bridge_channel, struct ast_bridge_channel *swap) { struct stasis_app_control *control = stasis_app_control_find_by_channel(bridge_channel->chan); if (!control && !stasis_app_channel_is_internal(bridge_channel->chan)) { /* channel not in Stasis(), get it there */ ast_debug(1, "Bridge %s: pushing non-stasis %p(%s) setup to come back in under stasis\n", self->uniqueid, bridge_channel, ast_channel_name(bridge_channel->chan)); /* Attach after-bridge callback and pass ownership of swap_app to it */ if (ast_bridge_set_after_callback(bridge_channel->chan, bridge_stasis_run_cb, NULL, NULL)) { ast_log(LOG_ERROR, "Failed to set after bridge callback for bridge %s non-stasis push of %s\n", self->uniqueid, ast_channel_name(bridge_channel->chan)); return -1; } bridge_stasis_queue_join_action(self, bridge_channel, swap); /* Return -1 so the push fails and the after-bridge callback gets called * This keeps the bridging framework from putting the channel into the bridge * until the Stasis thread gets started, and then the channel is put into the bridge. */ return -1; } /* * If going into a holding bridge, default the role to participant, if * it has no compatible role currently */ if ((self->technology->capabilities & AST_BRIDGE_CAPABILITY_HOLDING) && !ast_channel_has_role(bridge_channel->chan, "announcer") && !ast_channel_has_role(bridge_channel->chan, "holding_participant")) { if (ast_channel_add_bridge_role(bridge_channel->chan, "holding_participant")) { ast_log(LOG_ERROR, "Failed to set holding participant on %s\n", ast_channel_name(bridge_channel->chan)); return -1; } if (ast_channel_set_bridge_role_option(bridge_channel->chan, "holding_participant", "idle_mode", "none")) { ast_log(LOG_ERROR, "Failed to set holding participant mode on %s\n", ast_channel_name(bridge_channel->chan)); return -1; } } ao2_cleanup(control); if (self->allowed_capabilities & STASIS_BRIDGE_MIXING_CAPABILITIES) { ast_bridge_channel_update_linkedids(bridge_channel, swap); if (ast_test_flag(&self->feature_flags, AST_BRIDGE_FLAG_SMART)) { ast_bridge_channel_update_accountcodes(bridge_channel, swap); } } return ast_bridge_base_v_table.push(self, bridge_channel, swap); }
static int process_options(struct ast_channel *chan, struct ast_flags *flags, char **opts, struct ast_bridge_features *features, enum wait_bridge_roles role) { if (ast_test_flag(flags, MUXFLAG_TIMEOUT)) { if (apply_option_timeout(features, opts[OPT_ARG_TIMEOUT])) { return -1; } } switch (role) { case ROLE_PARTICIPANT: if (ast_channel_add_bridge_role(chan, "holding_participant")) { return -1; } if (ast_test_flag(flags, MUXFLAG_MOHCLASS)) { if (apply_option_moh(chan, opts[OPT_ARG_MOHCLASS])) { return -1; } } if (ast_test_flag(flags, MUXFLAG_ENTERTAINMENT)) { if (apply_option_entertainment(chan, opts[OPT_ARG_ENTERTAINMENT])) { return -1; } } break; case ROLE_ANNOUNCER: if (ast_channel_add_bridge_role(chan, "announcer")) { return -1; } break; case ROLE_INVALID: ast_assert(0); return -1; } return 0; }
int parking_channel_set_roles(struct ast_channel *chan, struct parking_lot *lot, int force_ringing) { if (ast_channel_add_bridge_role(chan, "holding_participant")) { return -1; } if (force_ringing) { if (ast_channel_set_bridge_role_option(chan, "holding_participant", "idle_mode", "ringing")) { return -1; } } else { if (ast_channel_set_bridge_role_option(chan, "holding_participant", "idle_mode", "musiconhold")) { return -1; } if (!ast_strlen_zero(lot->cfg->mohclass)) { if (ast_channel_set_bridge_role_option(chan, "holding_participant", "moh_class", lot->cfg->mohclass)) { return -1; } } } return 0; }
static struct ast_channel *announce_request(const char *type, struct ast_format_cap *cap, const struct ast_assigned_ids *assignedids, const struct ast_channel *requestor, const char *data, int *cause) { struct ast_channel *chan; const char *conf_name = data; RAII_VAR(struct confbridge_conference *, conference, NULL, ao2_cleanup); RAII_VAR(struct announce_pvt *, pvt, NULL, ao2_cleanup); conference = ao2_find(conference_bridges, conf_name, OBJ_KEY); if (!conference) { return NULL; } ast_assert(conference->bridge != NULL); /* Allocate a new private structure and then Asterisk channels */ pvt = (struct announce_pvt *) ast_unreal_alloc(sizeof(*pvt), announce_pvt_destructor, cap); if (!pvt) { return NULL; } ast_set_flag(&pvt->base, AST_UNREAL_NO_OPTIMIZATION); ast_copy_string(pvt->base.name, conf_name, sizeof(pvt->base.name)); pvt->bridge = conference->bridge; ao2_ref(pvt->bridge, +1); chan = ast_unreal_new_channels(&pvt->base, conf_announce_get_tech(), AST_STATE_UP, AST_STATE_UP, NULL, NULL, assignedids, requestor, 0); if (chan) { ast_answer(pvt->base.owner); ast_answer(pvt->base.chan); if (ast_channel_add_bridge_role(pvt->base.chan, "announcer")) { ast_hangup(chan); chan = NULL; } } return chan; }
int stasis_app_control_add_role(struct stasis_app_control *control, const char *role) { return ast_channel_add_bridge_role(control->channel, role); }