Esempio n. 1
0
/*!
 * \brief handle for orgination app or exten.
 * \param e pointer to the CLI structure to initialize
 * \param cmd operation to execute
 * \param a structure that contains either application or extension arguments
 * \retval CLI_SUCCESS on success.
 * \retval CLI_SHOWUSAGE on failure.
*/
static char *handle_orig(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
{
	static char *choices[] = { "application", "extension", NULL };
	char *res;
	switch (cmd) {
	case CLI_INIT:
		e->command = "channel originate";
		e->usage = 
			"  There are two ways to use this command. A call can be originated between a\n"
			"channel and a specific application, or between a channel and an extension in\n"
			"the dialplan. This is similar to call files or the manager originate action.\n"
			"Calls originated with this command are given a timeout of 30 seconds.\n\n"

			"Usage1: channel originate <tech/data> application <appname> [appdata]\n"
			"  This will originate a call between the specified channel tech/data and the\n"
			"given application. Arguments to the application are optional. If the given\n"
			"arguments to the application include spaces, all of the arguments to the\n"
			"application need to be placed in quotation marks.\n\n"

			"Usage2: channel originate <tech/data> extension [exten@][context]\n"
			"  This will originate a call between the specified channel tech/data and the\n"
			"given extension. If no context is specified, the 'default' context will be\n"
			"used. If no extension is given, the 's' extension will be used.\n";
		return NULL;
	case CLI_GENERATE:
		if (a->pos != 3)
			return NULL;

		/* ugly, can be removed when CLI entries have ast_module pointers */
		ast_module_ref(ast_module_info->self);
		res = ast_cli_complete(a->word, choices, a->n);
		ast_module_unref(ast_module_info->self);

		return res;
	}

	if (ast_strlen_zero(a->argv[2]) || ast_strlen_zero(a->argv[3]))
		return CLI_SHOWUSAGE;

	/* ugly, can be removed when CLI entries have ast_module pointers */
	ast_module_ref(ast_module_info->self);

	if (!strcasecmp("application", a->argv[3])) {
		res = orig_app(a->fd, a->argv[2], a->argv[4], a->argv[5]);	
	} else if (!strcasecmp("extension", a->argv[3])) {
		res = orig_exten(a->fd, a->argv[2], a->argv[4]);
	} else {
		ast_log(LOG_WARNING, "else");
		res = CLI_SHOWUSAGE;
	}

	ast_module_unref(ast_module_info->self);

	return res;
}
Esempio n. 2
0
int ooh323c_start_call_thread(ooCallData *call) {
 char c = 'c';
 struct callthread *cur = callThreads;

 ast_mutex_lock(&callThreadsLock);
 while (cur != NULL && (cur->inUse || ast_mutex_trylock(&cur->lock))) {
	cur = cur->next;
 }
 ast_mutex_unlock(&callThreadsLock);

 if (cur != NULL) {
   if (cur->inUse || write(cur->thePipe[1], &c, 1) < 0) {
	ast_mutex_unlock(&cur->lock);
	cur = NULL;
   }
 }

/* make new thread */
 if (cur == NULL) {
	if (!(cur = ast_calloc(1, sizeof(struct callthread)))) {
		ast_log(LOG_ERROR, "Unable to allocate thread structure for call %s\n",
							call->callToken);
		return -1;
	}

	ast_module_ref(myself);
	if ((socketpair(PF_LOCAL, SOCK_STREAM, 0, cur->thePipe)) == -1) {
		ast_log(LOG_ERROR, "Can't create thread pipe for call %s\n", call->callToken);
		ast_free(cur);
		return -1;
	}
	cur->inUse = TRUE;
	cur->call = call;

	ast_mutex_init(&cur->lock);

	if (gH323Debug)
		ast_debug(1,"new call thread created for call %s\n", call->callToken);

	if(ast_pthread_create_detached_background(&call->callThread, NULL, ooh323c_call_thread, cur) < 0)
 	{
  		ast_log(LOG_ERROR, "Unable to start ooh323c call thread for call %s\n",
					call->callToken);
		ast_mutex_destroy(&cur->lock);
		close(cur->thePipe[0]);
		close(cur->thePipe[1]);
		ast_free(cur);
  		return -1;
 	}

 } else {
	if (gH323Debug)
		ast_debug(1,"using existing call thread for call %s\n", call->callToken);
	cur->inUse = TRUE;
	cur->call = call;
	ast_mutex_unlock(&cur->lock);

 }
 return 0;
}
Esempio n. 3
0
struct ast_datastore *__ast_datastore_alloc(
	const struct ast_datastore_info *info, const char *uid, struct ast_module *mod,
	const char *file, int line, const char *function)
{
	struct ast_datastore *datastore = NULL;

	/* Make sure we at least have type so we can identify this */
	if (!info) {
		return NULL;
	}

	datastore = __ast_calloc(1, sizeof(*datastore), file, line, function);
	if (!datastore) {
		return NULL;
	}

	datastore->info = info;
	datastore->mod = mod;

	if (!ast_strlen_zero(uid) && !(datastore->uid = ast_strdup(uid))) {
		ast_free(datastore);
		datastore = NULL;
	}

	ast_module_ref(mod);

	return datastore;
}
Esempio n. 4
0
struct ast_timer *ast_timer_open(void)
{
	int fd = -1;
	struct timing_holder *h;
	struct ast_timer *t = NULL;

	ast_heap_rdlock(timing_interfaces);

	if ((h = ast_heap_peek(timing_interfaces, 1))) {
		fd = h->iface->timer_open();
		ast_module_ref(h->mod);
	}

	if (fd != -1) {
		if (!(t = ast_calloc(1, sizeof(*t)))) {
			h->iface->timer_close(fd);
		} else {
			t->fd = fd;
			t->holder = h;
		}
	}

	ast_heap_unlock(timing_interfaces);

	return t;
}
Esempio n. 5
0
struct csel * csel_create (const char *strategy,
						   const char *params,
						   occupy_func occupy,
						   free_func   free)
{
	struct csel *cs;
	int i = 0;

	if (strategy && *strategy) {
		for (; i < (sizeof(strategies) / sizeof(struct strategy)); ++i) {
			if (!strcasecmp(strategies[i].name, strategy))
				break;
		}
		if (i == (sizeof(strategies) / sizeof(struct strategy))) {
			ast_log(LOG_WARNING, "csel: unknown strategy: %s, falling back to: %s\n", strategy, strategies[0].name);
			i = 0;
		}
	}

	cs = calloc(1, sizeof(struct csel));

	cs->occupy = occupy;
	cs->m = &strategies[i];

	if (cs->m->init(cs, params)) {
		free(cs);
		return NULL;
	}
	
	ast_mutex_init(&cs->lock);

	ast_module_ref(ast_module_info->self);

	return cs;
}
Esempio n. 6
0
struct ast_timer *ast_timer_open(void)
{
	void *data = NULL;
	struct timing_holder *h;
	struct ast_timer *t = NULL;

	ast_heap_rdlock(timing_interfaces);

	if ((h = ast_heap_peek(timing_interfaces, 1))) {
		data = h->iface->timer_open();
		ast_module_ref(h->mod);
	}

	if (data) {
		if (!(t = ast_calloc(1, sizeof(*t)))) {
			h->iface->timer_close(data);
		} else {
			t->data = data;
			t->holder = h;
		}
	}

	ast_heap_unlock(timing_interfaces);

	return t;
}
static int bridge_builtin_set_limits(struct ast_bridge_features *features,
	struct ast_bridge_features_limits *limits,
	enum ast_bridge_hook_remove_flags remove_flags)
{
	RAII_VAR(struct ast_bridge_features_limits *, feature_limits, NULL, ao2_cleanup);

	if (!limits->duration) {
		return -1;
	}

	/* Create limits hook_pvt data. */
	ast_module_ref(ast_module_info->self);
	feature_limits = ao2_alloc_options(sizeof(*feature_limits),
		bridge_features_limits_dtor, AO2_ALLOC_OPT_LOCK_NOLOCK);
	if (!feature_limits) {
		ast_module_unref(ast_module_info->self);
		return -1;
	}
	if (ast_bridge_features_limits_construct(feature_limits)) {
		return -1;
	}
	bridge_features_limits_copy(feature_limits, limits);
	feature_limits->quitting_time = ast_tvadd(ast_tvnow(),
		ast_samp2tv(feature_limits->duration, 1000));

	/* Install limit hooks. */
	ao2_ref(feature_limits, +1);
	if (ast_bridge_interval_hook(features, AST_BRIDGE_HOOK_TIMER_OPTION_MEDIA,
		feature_limits->duration,
		bridge_features_duration_callback, feature_limits, __ao2_cleanup, remove_flags)) {
		ast_log(LOG_ERROR, "Failed to schedule the duration limiter to the bridge channel.\n");
		ao2_ref(feature_limits, -1);
		return -1;
	}
	if (!ast_strlen_zero(feature_limits->connect_sound)) {
		ao2_ref(feature_limits, +1);
		if (ast_bridge_interval_hook(features, AST_BRIDGE_HOOK_TIMER_OPTION_MEDIA, 1,
			bridge_features_connect_callback, feature_limits, __ao2_cleanup, remove_flags)) {
			ast_log(LOG_WARNING, "Failed to schedule connect sound to the bridge channel.\n");
			ao2_ref(feature_limits, -1);
		}
	}
	if (feature_limits->warning && feature_limits->warning < feature_limits->duration) {
		ao2_ref(feature_limits, +1);
		if (ast_bridge_interval_hook(features, AST_BRIDGE_HOOK_TIMER_OPTION_MEDIA,
			feature_limits->duration - feature_limits->warning,
			bridge_features_warning_callback, feature_limits, __ao2_cleanup, remove_flags)) {
			ast_log(LOG_WARNING, "Failed to schedule warning sound playback to the bridge channel.\n");
			ao2_ref(feature_limits, -1);
		}
	}

	return 0;
}
static int load_module(void)
{
	ast_bridge_features_register(AST_BRIDGE_BUILTIN_HANGUP, feature_hangup, NULL);
	ast_bridge_features_register(AST_BRIDGE_BUILTIN_AUTOMON, feature_automonitor, NULL);
	ast_bridge_features_register(AST_BRIDGE_BUILTIN_AUTOMIXMON, feature_automixmonitor, NULL);

	/* Bump up our reference count so we can't be unloaded */
	ast_module_ref(ast_module_info->self);

	return AST_MODULE_LOAD_SUCCESS;
}
Esempio n. 9
0
static int load_module(void)
{
	ast_bridge_features_register(AST_BRIDGE_BUILTIN_BLINDTRANSFER, feature_blind_transfer, NULL);
	ast_bridge_features_register(AST_BRIDGE_BUILTIN_ATTENDEDTRANSFER, feature_attended_transfer, NULL);
	ast_bridge_features_register(AST_BRIDGE_BUILTIN_HANGUP, feature_hangup, NULL);

	/* Bump up our reference count so we can't be unloaded */
	ast_module_ref(ast_module_info->self);

	return AST_MODULE_LOAD_SUCCESS;
}
Esempio n. 10
0
/*! \brief Add or activate mute audiohook on channel
	Assumes channel is locked
*/
static int mute_add_audiohook(struct ast_channel *chan, struct mute_information *mute, struct ast_datastore *datastore)
{
	/* Activate the settings */
	ast_channel_datastore_add(chan, datastore);
	if (ast_audiohook_attach(chan, &mute->audiohook)) {
		ast_log(LOG_ERROR, "Failed to attach audiohook for muting channel %s\n", ast_channel_name(chan));
		return -1;
	}
	ast_module_ref(ast_module_info->self);
	ast_debug(2, "Initialized audiohook on channel %s\n", ast_channel_name(chan));
	return 0;
}
Esempio n. 11
0
int ast_ari_add_handler(struct stasis_rest_handlers *handler)
{
	RAII_VAR(struct stasis_rest_handlers *, new_handler, NULL, ao2_cleanup);
	size_t old_size, new_size;

	SCOPED_MUTEX(lock, &root_handler_lock);

	old_size = sizeof(*new_handler) + root_handler->num_children * sizeof(handler);
	new_size = old_size + sizeof(handler);

	new_handler = ao2_alloc(new_size, NULL);
	if (!new_handler) {
		return -1;
	}
	memcpy(new_handler, root_handler, old_size);
	new_handler->children[new_handler->num_children++] = handler;

	ao2_cleanup(root_handler);
	ao2_ref(new_handler, +1);
	root_handler = new_handler;
	ast_module_ref(ast_module_info->self);
	return 0;
}
Esempio n. 12
0
static void *hook_launch_thread(void *data)
{
	struct hook_thread_arg *arg = data;
	struct ast_variable hook_id = {
		.name = "HOOK_ID",
		.value = arg->hook_id,
	};
	struct ast_variable chan_name_var = {
		.name = "HOOK_CHANNEL",
		.value = arg->chan_name,
		.next = &hook_id,
	};

	ast_pbx_outgoing_exten("Local", NULL, full_exten_name, 60,
			arg->context, arg->exten, 1, NULL, AST_OUTGOING_NO_WAIT,
			NULL, NULL, &chan_name_var, NULL, NULL, 1, NULL);

	hook_thread_arg_destroy(arg);

	return NULL;
}

static struct hook_thread_arg *hook_thread_arg_alloc(struct ast_channel *chan,
		struct hook_state *state)
{
	struct hook_thread_arg *arg;

	if (!(arg = ast_calloc(1, sizeof(*arg)))) {
		return NULL;
	}

	ast_channel_lock(chan);
	arg->chan_name = ast_strdup(ast_channel_name(chan));
	ast_channel_unlock(chan);
	if (!arg->chan_name) {
		hook_thread_arg_destroy(arg);
		return NULL;
	}

	if (ast_asprintf(&arg->hook_id, "%u", state->hook_id) == -1) {
		hook_thread_arg_destroy(arg);
		return NULL;
	}

	if (!(arg->context = ast_strdup(state->context))) {
		hook_thread_arg_destroy(arg);
		return NULL;
	}

	if (!(arg->exten = ast_strdup(state->exten))) {
		hook_thread_arg_destroy(arg);
		return NULL;
	}

	return arg;
}

static int do_hook(struct ast_channel *chan, struct hook_state *state)
{
	pthread_t t;
	struct hook_thread_arg *arg;
	int res;

	if (!(arg = hook_thread_arg_alloc(chan, state))) {
		return -1;
	}

	/*
	 * We don't want to block normal frame processing *at all* while we kick
	 * this off, so do it in a new thread.
	 */
	res = ast_pthread_create_detached_background(&t, NULL, hook_launch_thread, arg);
	if (res != 0) {
		hook_thread_arg_destroy(arg);
	}

	return res;
}

static int hook_callback(struct ast_audiohook *audiohook, struct ast_channel *chan,
		struct ast_frame *frame, enum ast_audiohook_direction direction)
{
	struct hook_state *state = (struct hook_state *) audiohook; /* trust me. */
	struct timeval now;
	int res = 0;

	if (audiohook->status == AST_AUDIOHOOK_STATUS_DONE || state->disabled) {
		return 0;
	}

	now = ast_tvnow();
	if (ast_tvdiff_ms(now, state->last_hook) > state->interval * 1000) {
		if ((res = do_hook(chan, state))) {
			const char *name;
			ast_channel_lock(chan);
			name = ast_strdupa(ast_channel_name(chan));
			ast_channel_unlock(chan);
			ast_log(LOG_WARNING, "Failed to run hook on '%s'\n", name);
		}
		state->last_hook = now;
	}

	return res;
}

static struct hook_state *hook_state_alloc(const char *context, const char *exten,
		unsigned int interval, unsigned int hook_id)
{
	struct hook_state *state;

	if (!(state = ast_calloc(1, sizeof(*state)))) {
		return NULL;
	}

	state->context = ast_strdup(context);
	state->exten = ast_strdup(exten);
	state->interval = interval;
	state->hook_id = hook_id;

	ast_audiohook_init(&state->audiohook, AST_AUDIOHOOK_TYPE_MANIPULATE,
			AST_MODULE, AST_AUDIOHOOK_MANIPULATE_ALL_RATES);
	state->audiohook.manipulate_callback = hook_callback;

	return state;
}

static int init_hook(struct ast_channel *chan, const char *context, const char *exten,
		unsigned int interval, unsigned int hook_id)
{
	struct hook_state *state;
	struct ast_datastore *datastore;
	char uid[32];

	snprintf(uid, sizeof(uid), "%u", hook_id);

	if (!(datastore = ast_datastore_alloc(&hook_datastore, uid))) {
		return -1;
	}
	ast_module_ref(ast_module_info->self);
	if (!(state = hook_state_alloc(context, exten, interval, hook_id))) {
		ast_datastore_free(datastore);
		return -1;
	}
	datastore->data = state;

	ast_channel_lock(chan);
	ast_channel_datastore_add(chan, datastore);
	ast_audiohook_attach(chan, &state->audiohook);
	ast_channel_unlock(chan);

	return 0;
}

static int hook_on(struct ast_channel *chan, const char *data, unsigned int hook_id)
{
	char *parse = ast_strdupa(S_OR(data, ""));
	AST_DECLARE_APP_ARGS(args,
		AST_APP_ARG(context);
		AST_APP_ARG(exten);
		AST_APP_ARG(interval);
	);
Esempio n. 13
0
/*! 
 * \brief Convert a file from one format to another 
 * \param e CLI entry
 * \param cmd command number
 * \param a list of cli arguments
 * \retval CLI_SUCCESS on success.
 * \retval CLI_SHOWUSAGE or CLI_FAILURE on failure.
*/
static char *handle_cli_file_convert(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
{
	char *ret = CLI_FAILURE;
	struct ast_filestream *fs_in = NULL, *fs_out = NULL;
	struct ast_frame *f;
	struct timeval start;
	int cost;
	char *file_in = NULL, *file_out = NULL;
	char *name_in, *ext_in, *name_out, *ext_out;

	switch (cmd) {
	case CLI_INIT:
		e->command = "file convert";
		e->usage =
			"Usage: file convert <file_in> <file_out>\n"
			"       Convert from file_in to file_out. If an absolute path\n"
			"       is not given, the default Asterisk sounds directory\n"
			"       will be used.\n\n"
			"       Example:\n"
			"           file convert tt-weasels.gsm tt-weasels.ulaw\n";
		return NULL;
	case CLI_GENERATE:
		return NULL;
	}
	
	/* ugly, can be removed when CLI entries have ast_module pointers */
	ast_module_ref(ast_module_info->self);

	if (a->argc != 4 || ast_strlen_zero(a->argv[2]) || ast_strlen_zero(a->argv[3])) {
		ret = CLI_SHOWUSAGE;
		goto fail_out;	
	}

	file_in = ast_strdupa(a->argv[2]);
	file_out = ast_strdupa(a->argv[3]);

	if (split_ext(file_in, &name_in, &ext_in)) {
		ast_cli(a->fd, "'%s' is an invalid filename!\n", a->argv[2]);
		goto fail_out;
	}
	if (!(fs_in = ast_readfile(name_in, ext_in, NULL, O_RDONLY, 0, 0))) {
		ast_cli(a->fd, "Unable to open input file: %s\n", a->argv[2]);
		goto fail_out;
	}
	
	if (split_ext(file_out, &name_out, &ext_out)) {
		ast_cli(a->fd, "'%s' is an invalid filename!\n", a->argv[3]);
		goto fail_out;
	}
	if (!(fs_out = ast_writefile(name_out, ext_out, NULL, O_CREAT|O_TRUNC|O_WRONLY, 0, AST_FILE_MODE))) {
		ast_cli(a->fd, "Unable to open output file: %s\n", a->argv[3]);
		goto fail_out;
	}

	start = ast_tvnow();
	
	while ((f = ast_readframe(fs_in))) {
		if (ast_writestream(fs_out, f)) {
			ast_frfree(f);
			ast_cli(a->fd, "Failed to convert %s.%s to %s.%s!\n", name_in, ext_in, name_out, ext_out);
			goto fail_out;
		}
		ast_frfree(f);
	}

	cost = ast_tvdiff_ms(ast_tvnow(), start);
	ast_cli(a->fd, "Converted %s.%s to %s.%s in %dms\n", name_in, ext_in, name_out, ext_out, cost);
	ret = CLI_SUCCESS;

fail_out:
	if (fs_out) {
		ast_closestream(fs_out);
		if (ret != CLI_SUCCESS)
			ast_filedelete(name_out, ext_out);
	}

	if (fs_in) 
		ast_closestream(fs_in);

	ast_module_unref(ast_module_info->self);

	return ret;
}
Esempio n. 14
0
struct ast_websocket_server *AST_OPTIONAL_API_NAME(ast_websocket_server_create)(void)
{
	ast_module_ref(ast_module_info->self);
	return websocket_server_create_impl(websocket_server_dtor);
}
Esempio n. 15
0
void ast_mwi_external_ref(void)
{
	ast_module_ref(ast_module_info->self);
}