예제 #1
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;

	/* 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;
}
예제 #2
0
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;
}
예제 #3
0
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;
}
예제 #4
0
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);
}
예제 #5
0
/*!
 * \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);
}
예제 #6
0
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;
}
예제 #7
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;
}
예제 #8
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;
}
예제 #9
0
파일: control.c 프로젝트: vzar/asterisk
int stasis_app_control_add_role(struct stasis_app_control *control, const char *role)
{
    return ast_channel_add_bridge_role(control->channel, role);
}