Exemplo n.º 1
0
/*! \internal \brief Disable talk detection on the channel */
static int remove_talk_detect(struct ast_channel *chan)
{
	struct ast_datastore *datastore = NULL;
	struct talk_detect_params *td_params;
	SCOPED_CHANNELLOCK(chan_lock, chan);

	datastore = ast_channel_datastore_find(chan, &talk_detect_datastore, NULL);
	if (!datastore) {
		ast_log(AST_LOG_WARNING, "Cannot remove TALK_DETECT from %s: TALK_DETECT not currently enabled\n",
		        ast_channel_name(chan));
		return -1;
	}
	td_params = datastore->data;

	if (ast_audiohook_remove(chan, &td_params->audiohook)) {
		ast_log(AST_LOG_WARNING, "Failed to remove TALK_DETECT audiohook from channel %s\n",
		        ast_channel_name(chan));
		return -1;
	}

	if (ast_channel_datastore_remove(chan, datastore)) {
		ast_log(AST_LOG_WARNING, "Failed to remove TALK_DETECT datastore from channel %s\n",
		        ast_channel_name(chan));
		return -1;
	}
	ast_datastore_free(datastore);

	return 0;
}
Exemplo n.º 2
0
/*! \brief Helper function which gets the format for a Snoop channel based on the channel being snooped on */
static void snoop_determine_format(struct ast_channel *chan, struct stasis_app_snoop *snoop)
{
	SCOPED_CHANNELLOCK(lock, chan);
	unsigned int rate = MAX(ast_format_get_sample_rate(ast_channel_rawwriteformat(chan)),
		ast_format_get_sample_rate(ast_channel_rawreadformat(chan)));

	snoop->spy_format = ast_format_cache_get_slin_by_rate(rate);
}
Exemplo n.º 3
0
static int app_control_unmute(struct stasis_app_control *control,
                              struct ast_channel *chan, void *data)
{
    RAII_VAR(struct stasis_app_control_mute_data *, mute_data, data, ast_free);
    SCOPED_CHANNELLOCK(lockvar, chan);

    ast_channel_unsuppress(control->channel, mute_data->direction, mute_data->frametype);

    return 0;
}
Exemplo n.º 4
0
static int app_control_mute(struct stasis_app_control *control,
	struct ast_channel *chan, void *data)
{
	struct stasis_app_control_mute_data *mute_data = data;
	SCOPED_CHANNELLOCK(lockvar, chan);

	ast_channel_suppress(control->channel, mute_data->direction, mute_data->frametype);

	return 0;
}
Exemplo n.º 5
0
/*! \internal \brief Enable talk detection on the channel */
static int set_talk_detect(struct ast_channel *chan, int dsp_silence_threshold, int dsp_talking_threshold)
{
	struct ast_datastore *datastore = NULL;
	struct talk_detect_params *td_params;
	SCOPED_CHANNELLOCK(chan_lock, chan);

	datastore = ast_channel_datastore_find(chan, &talk_detect_datastore, NULL);
	if (!datastore) {
		datastore = ast_datastore_alloc(&talk_detect_datastore, NULL);
		if (!datastore) {
			return -1;
		}

		td_params = ast_calloc(1, sizeof(*td_params));
		if (!td_params) {
			ast_datastore_free(datastore);
			return -1;
		}

		ast_audiohook_init(&td_params->audiohook,
		                   AST_AUDIOHOOK_TYPE_MANIPULATE,
		                   "TALK_DETECT",
		                   AST_AUDIOHOOK_MANIPULATE_ALL_RATES);
		td_params->audiohook.manipulate_callback = talk_detect_audiohook_cb;
		ast_set_flag(&td_params->audiohook, AST_AUDIOHOOK_TRIGGER_READ);

		td_params->dsp = ast_dsp_new_with_rate(ast_format_get_sample_rate(ast_channel_rawreadformat(chan)));
		if (!td_params->dsp) {
			ast_datastore_free(datastore);
			ast_free(td_params);
			return -1;
		}
		datastore->data = td_params;

		ast_channel_datastore_add(chan, datastore);
		ast_audiohook_attach(chan, &td_params->audiohook);
	} else {
		/* Talk detection already enabled; update existing settings */
		td_params = datastore->data;
	}

	td_params->dsp_talking_threshold = dsp_talking_threshold;
	td_params->dsp_silence_threshold = dsp_silence_threshold;

	ast_dsp_set_threshold(td_params->dsp, td_params->dsp_talking_threshold);

	return 0;
}
Exemplo n.º 6
0
char *stasis_app_control_get_channel_var(struct stasis_app_control *control, const char *variable)
{
	RAII_VAR(struct ast_str *, tmp, ast_str_create(32), ast_free);
	SCOPED_CHANNELLOCK(lockvar, control->channel);

	if (!tmp) {
		return NULL;
	}

	if (variable[strlen(variable) - 1] == ')') {
		if (ast_func_read2(control->channel, variable, &tmp, 0)) {
			return NULL;
		}
	} else {
		if (!ast_str_retrieve_variable(&tmp, 0, control->channel, NULL, variable)) {
			return NULL;
		}
	}

	return ast_strdup(ast_str_buffer(tmp));
}
Exemplo n.º 7
0
int conf_announce_channel_push(struct ast_channel *ast)
{
	struct ast_bridge_features *features;
	struct ast_channel *chan;
	RAII_VAR(struct announce_pvt *, p, NULL, ao2_cleanup);

	{
		SCOPED_CHANNELLOCK(lock, ast);

		p = ast_channel_tech_pvt(ast);
		if (!p) {
			return -1;
		}
		ao2_ref(p, +1);
		chan = p->base.chan;
		if (!chan) {
			return -1;
		}
		ast_channel_ref(chan);
	}

	features = ast_bridge_features_new();
	if (!features) {
		ast_channel_unref(chan);
		return -1;
	}
	ast_set_flag(&features->feature_flags, AST_BRIDGE_CHANNEL_FLAG_IMMOVABLE);

	/* Impart the output channel into the bridge */
	if (ast_bridge_impart(p->bridge, chan, NULL, features,
		AST_BRIDGE_IMPART_CHAN_DEPARTABLE)) {
		ast_bridge_features_destroy(features);
		ast_channel_unref(chan);
		return -1;
	}
	ao2_lock(p);
	ast_set_flag(&p->base, AST_UNREAL_CARETAKER_THREAD);
	ao2_unlock(p);
	return 0;
}
Exemplo n.º 8
0
static int bridge_channel_depart(struct stasis_app_control *control,
                                 struct ast_channel *chan, void *data)
{
    RAII_VAR(struct ast_bridge_channel *, bridge_channel, data, ao2_cleanup);

    {
        SCOPED_CHANNELLOCK(lock, chan);

        if (bridge_channel != ast_channel_internal_bridge_channel(chan)) {
            ast_debug(3, "%s: Channel is no longer in departable state\n",
                      ast_channel_uniqueid(chan));
            return -1;
        }
    }

    ast_debug(3, "%s: Channel departing bridge\n",
              ast_channel_uniqueid(chan));

    ast_bridge_depart(chan);

    return 0;
}
static enum set_touch_variables_res set_touch_variables(struct ast_channel *chan, int is_mixmonitor, char **touch_format, char **touch_monitor, char **touch_monitor_prefix)
{
	enum set_touch_variables_res res = SET_TOUCH_UNSET;
	const char *var_format;
	const char *var_monitor;
	const char *var_prefix;

	SCOPED_CHANNELLOCK(lock, chan);

	if (is_mixmonitor) {
		var_format = "TOUCH_MIXMONITOR_FORMAT";
		var_monitor = "TOUCH_MIXMONITOR";
		var_prefix = "TOUCH_MIXMONITOR_PREFIX";
	} else {
		var_format = "TOUCH_MONITOR_FORMAT";
		var_monitor = "TOUCH_MONITOR";
		var_prefix = "TOUCH_MONITOR_PREFIX";
	}
	set_touch_variable(&res, chan, var_format, touch_format);
	set_touch_variable(&res, chan, var_monitor, touch_monitor);
	set_touch_variable(&res, chan, var_prefix, touch_monitor_prefix);

	return res;
}
Exemplo n.º 10
0
int ast_unreal_channel_push_to_bridge(struct ast_channel *ast, struct ast_bridge *bridge, unsigned int flags)
{
	struct ast_bridge_features *features;
	struct ast_channel *chan;
	struct ast_channel *owner;
	RAII_VAR(struct ast_unreal_pvt *, p, NULL, ao2_cleanup);

	RAII_VAR(struct ast_callid *, bridge_callid, NULL, ast_callid_cleanup);

	ast_bridge_lock(bridge);
	bridge_callid = bridge->callid ? ast_callid_ref(bridge->callid) : NULL;
	ast_bridge_unlock(bridge);

	{
		SCOPED_CHANNELLOCK(lock, ast);
		p = ast_channel_tech_pvt(ast);
		if (!p) {
			return -1;
		}
		ao2_ref(p, +1);
	}

	{
		SCOPED_AO2LOCK(lock, p);
		chan = p->chan;
		if (!chan) {
			return -1;
		}

		owner = p->owner;
		if (!owner) {
			return -1;
		}

		ast_channel_ref(chan);
		ast_channel_ref(owner);
	}

	if (bridge_callid) {
		struct ast_callid *chan_callid;
		struct ast_callid *owner_callid;

		/* chan side call ID setting */
		ast_channel_lock(chan);

		chan_callid = ast_channel_callid(chan);
		if (!chan_callid) {
			ast_channel_callid_set(chan, bridge_callid);
		}
		ast_channel_unlock(chan);
		ast_callid_cleanup(chan_callid);

		/* owner side call ID setting */
		ast_channel_lock(owner);

		owner_callid = ast_channel_callid(owner);
		if (!owner_callid) {
			ast_channel_callid_set(owner, bridge_callid);
		}

		ast_channel_unlock(owner);
		ast_callid_cleanup(owner_callid);
	}

	/* We are done with the owner now that its call ID matches the bridge */
	ast_channel_unref(owner);
	owner = NULL;

	features = ast_bridge_features_new();
	if (!features) {
		ast_channel_unref(chan);
		return -1;
	}

	ast_set_flag(&features->feature_flags, flags);

	/* Impart the semi2 channel into the bridge */
	if (ast_bridge_impart(bridge, chan, NULL, features,
		AST_BRIDGE_IMPART_CHAN_INDEPENDENT)) {
		ast_bridge_features_destroy(features);
		ast_channel_unref(chan);
		return -1;
	}

	ao2_lock(p);
	ast_set_flag(p, AST_UNREAL_CARETAKER_THREAD);
	ao2_unlock(p);
	ast_channel_unref(chan);

	return 0;
}