Ejemplo n.º 1
0
static int do_pause_or_unpause(struct mansession *s, struct message *m, int action)
{
	struct ast_channel *c = NULL;
	char *name = astman_get_header(m, "Channel");
	
	if (IS_NULL_STRING(name)) {
		astman_send_error(s, m, "No channel specified");
		return -1;
	}
	
	c = ast_get_channel_by_name_locked(name);
	if (!c) {
		astman_send_error(s, m, "No such channel");
		return -1;
	}

	if (action == MONITOR_ACTION_PAUSE)
		ast_monitor_pause(c);
	else
		ast_monitor_unpause(c);
	
	ast_channel_unlock(c);
	astman_send_ack(s, m, "Paused monitoring of the channel");
	return 0;	
}
static int action_setcdruserfield(struct mansession *s, struct message *m)
{
	struct ast_channel *c = NULL;
	char *userfield = astman_get_header(m, "UserField");
	char *channel = astman_get_header(m, "Channel");
	char *append = astman_get_header(m, "Append");

	if (ast_strlen_zero(channel)) {
		astman_send_error(s, m, "No Channel specified");
		return 0;
	}
	if (ast_strlen_zero(userfield)) {
		astman_send_error(s, m, "No UserField specified");
		return 0;
	}
	c = ast_get_channel_by_name_locked(channel);
	if (!c) {
		astman_send_error(s, m, "No such channel");
		return 0;
	}
	if (ast_true(append))
		ast_cdr_appenduserfield(c, userfield);
	else
		ast_cdr_setuserfield(c, userfield);
	ast_mutex_unlock(&c->lock);
	astman_send_ack(s, m, "CDR Userfield Set");
	return 0;
}
Ejemplo n.º 3
0
static int change_monitor_action(struct mansession *s, struct message *m)
{
	struct ast_channel *c = NULL;
	char *name = astman_get_header(m, "Channel");
	char *fname = astman_get_header(m, "File");
	if (ast_strlen_zero(name)) {
		astman_send_error(s, m, "No channel specified");
		return 0;
	}
	if (ast_strlen_zero(fname)) {
		astman_send_error(s, m, "No filename specified");
		return 0;
	}
	c = ast_get_channel_by_name_locked(name);
	if (!c) {
		astman_send_error(s, m, "No such channel");
		return 0;
	}
	if (ast_monitor_change_fname(c, fname, 1)) {
		astman_send_error(s, m, "Could not change monitored filename of channel");
		ast_channel_unlock(c);
		return 0;
	}
	ast_channel_unlock(c);
	astman_send_ack(s, m, "Changed monitor filename");
	return 0;
}
static int start_monitor_action(struct mansession *s, struct message *m)
{
	struct ast_channel *c = NULL;
	char *name = astman_get_header(m, "Channel");
	char *fname = astman_get_header(m, "File");
	char *format = astman_get_header(m, "Format");
	char *mix = astman_get_header(m, "Mix");
	char *d;
	
	if (ast_strlen_zero(name)) {
		astman_send_error(s, m, "No channel specified");
		return 0;
	}
	c = ast_get_channel_by_name_locked(name);
	if (!c) {
		astman_send_error(s, m, "No such channel");
		return 0;
	}

	if (ast_strlen_zero(fname)) {
		/* No filename base specified, default to channel name as per CLI */
		fname = malloc (FILENAME_MAX);
		if (!fname) {
			astman_send_error(s, m, "Could not start monitoring channel");
			ast_mutex_unlock(&c->lock);
			return 0;
		}
		memset(fname, 0, FILENAME_MAX);
		ast_copy_string(fname, c->name, FILENAME_MAX);
		/* Channels have the format technology/channel_name - have to replace that /  */
		if ((d=strchr(fname, '/'))) *d='-';
	}
	
	if (ast_monitor_start(c, format, fname, 1)) {
		if (ast_monitor_change_fname(c, fname, 1)) {
			astman_send_error(s, m, "Could not start monitoring channel");
			ast_mutex_unlock(&c->lock);
			return 0;
		}
	}

	if (ast_true(mix)) {
		ast_monitor_setjoinfiles(c, 1);
	}

	ast_mutex_unlock(&c->lock);
	astman_send_ack(s, m, "Started monitoring channel");
	return 0;
}
Ejemplo n.º 5
0
static char *handle_redirect(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
{
	const char *name, *dest;
	struct ast_channel *chan;
	int res;

	switch (cmd) {
	case CLI_INIT:
		e->command = "channel redirect";
		e->usage = ""
		"Usage: channel redirect <channel> <[[context,]exten,]priority>\n"
		"    Redirect an active channel to a specified extension.\n";
		/*! \todo It would be nice to be able to redirect 2 channels at the same
		 *  time like you can with AMI redirect.  However, it is not possible to acquire
		 *  two channels without the potential for a deadlock with how ast_channel structs
		 *  are managed today.  Once ast_channel is a refcounted object, this command
		 *  will be able to support that. */
		return NULL;
	case CLI_GENERATE:
		return ast_complete_channels(a->line, a->word, a->pos, a->n, 2);
	}

	if (a->argc != e->args + 2) {
		return CLI_SHOWUSAGE;
	}

	name = a->argv[2];
	dest = a->argv[3];

	chan = ast_get_channel_by_name_locked(name);
	if (!chan) {
		ast_cli(a->fd, "Channel '%s' not found\n", name);
		return CLI_FAILURE;
	}

	res = ast_async_parseable_goto(chan, dest);

	ast_channel_unlock(chan);

	if (!res) {
		ast_cli(a->fd, "Channel '%s' successfully redirected to %s\n", name, dest);
	} else {
		ast_cli(a->fd, "Channel '%s' failed to be redirected to %s\n", name, dest);
	}

	return res ? CLI_FAILURE : CLI_SUCCESS;
}
Ejemplo n.º 6
0
static int stop_monitor_action(struct mansession *s, struct message *m)
{
	struct ast_channel *c = NULL;
	char *name = astman_get_header(m, "Channel");
	int res;
	if (ast_strlen_zero(name)) {
		astman_send_error(s, m, "No channel specified");
		return 0;
	}
	c = ast_get_channel_by_name_locked(name);
	if (!c) {
		astman_send_error(s, m, "No such channel");
		return 0;
	}
	res = ast_monitor_stop(c, 1);
	ast_channel_unlock(c);
	if (res) {
		astman_send_error(s, m, "Could not stop monitoring channel");
		return 0;
	}
	astman_send_ack(s, m, "Stopped monitoring channel");
	return 0;
}
Ejemplo n.º 7
0
static int manager_play_dtmf(struct mansession *s, const struct message *m)
{
	const char *channel = astman_get_header(m, "Channel");
	const char *digit = astman_get_header(m, "Digit");
	struct ast_channel *chan = ast_get_channel_by_name_locked(channel);
	
	if (!chan) {
		astman_send_error(s, m, "Channel not specified");
		return 0;
	}
	if (ast_strlen_zero(digit)) {
		astman_send_error(s, m, "No digit specified");
		ast_mutex_unlock(&chan->lock);
		return 0;
	}

	ast_senddigit(chan, *digit);

	ast_mutex_unlock(&chan->lock);
	astman_send_ack(s, m, "DTMF successfully queued");
	
	return 0;
}
static int pickup_exec(struct ast_channel *chan, void *data)
{
	int res = 0;
	struct localuser *u = NULL;
	struct ast_channel *origin = NULL, *target = NULL;
	char *tmp = NULL, *exten = NULL, *context = NULL, *rest=data;
	char workspace[256] = "";
	const char *tmp2 = NULL;

	if (ast_strlen_zero(data)) {
		ast_log(LOG_WARNING, "Pickup requires an argument (extension) !\n");
		return -1;	
	}

	LOCAL_USER_ADD(u);
	
	while (!target && (exten = rest) ) {
		res = 0;
		rest = strchr(exten, '&');
		if (rest)
			*rest++ = 0;

		/* Get the extension and context if present */
		context = strchr(exten, '@');
		if (context)
			*context++ = '\0';

		/* If the context is the pickup mark, iterate through all channels finding the right origin one */
		if (!strcmp(context, PICKUPMARK)) {
			while ((origin = ast_channel_walk_locked(origin))) {
				if (origin) {
					tmp2 = pbx_builtin_getvar_helper(origin, PICKUPMARK);
					if (tmp2 && !strcmp(tmp2, exten))
						break;
					ast_mutex_unlock(&origin->lock);
				}
			}
		} else {
			/* Use the classic mode of searching */
			origin = ast_get_channel_by_exten_locked(exten, context);
		}

		if (origin) {
			ast_cdr_getvar(origin->cdr, "dstchannel", &tmp, workspace,
					sizeof(workspace), 0, 0);
			if (tmp) {
				/* We have a possible channel... now we need to find it! */
				target = ast_get_channel_by_name_locked(tmp);
			} else {
				ast_log(LOG_NOTICE, "No target channel found for %s.\n", exten);
				res = -1;
			}
			ast_mutex_unlock(&origin->lock);

		} else {
			ast_log(LOG_DEBUG, "No originating channel found.\n");
		}

		if (res)
			continue;

		if (target && (!target->pbx) && ((target->_state == AST_STATE_RINGING) || (target->_state == AST_STATE_RING) ) ) {
			ast_log(LOG_DEBUG, "Call pickup on chan '%s' by '%s'\n", target->name,
					chan->name);
			res = ast_answer(chan);
			if (res) {
				ast_log(LOG_WARNING, "Unable to answer '%s'\n", chan->name);
				res = -1;
				break;
			}
			res = ast_queue_control(chan, AST_CONTROL_ANSWER);
			if (res) {
				ast_log(LOG_WARNING, "Unable to queue answer on '%s'\n",
						chan->name);
				res = -1;
				break;
			}
			res = ast_channel_masquerade(target, chan);
			if (res) {
				ast_log(LOG_WARNING, "Unable to masquerade '%s' into '%s'\n", chan->name, target->name);
				res = -1;
				break;
			}
		} else {
			ast_log(LOG_NOTICE, "No call pickup possible for %s...\n", exten);
			res = -1;
		}
	}
	if (target) 
		ast_mutex_unlock(&target->lock);
	
	LOCAL_USER_REMOVE(u);

	return res;
}
Ejemplo n.º 9
0
static struct ast_channel *get_dahdi_channel_locked(int num) {
	char name[80];
	
	snprintf(name, sizeof(name), "DAHDI/%d-1", num);
	return ast_get_channel_by_name_locked(name);
}
static int pickup_exec(struct ast_channel *chan, void *data)
{
	int res = 0;
	struct localuser *u = NULL;
	struct ast_channel *origin = NULL, *target = NULL;
	char *tmp = NULL, *exten = NULL, *context = NULL;
	char workspace[256] = "";

	if (ast_strlen_zero(data)) {
		ast_log(LOG_WARNING, "Pickup requires an argument (extension) !\n");
		return -1;	
	}

	LOCAL_USER_ADD(u);
	
	/* Get the extension and context if present */
	exten = data;
	context = strchr(data, '@');
	if (context) {
		*context = '\0';
		context++;
	}

	/* Find a channel to pickup */
	origin = ast_get_channel_by_exten_locked(exten, context);
	if (origin && origin->cdr) {
		ast_cdr_getvar(origin->cdr, "dstchannel", &tmp, workspace,
			       sizeof(workspace), 0);
		if (tmp) {
			/* We have a possible channel... now we need to find it! */
			target = ast_get_channel_by_name_locked(tmp);
		} else {
			ast_log(LOG_DEBUG, "No target channel found.\n");
			res = -1;
		}
		ast_mutex_unlock(&origin->lock);
	} else {
		if (origin)
			ast_mutex_unlock(&origin->lock);
		ast_log(LOG_DEBUG, "No originating channel found.\n");
	}
	
	if (res)
		goto out;

	if (target && (!target->pbx) && ((target->_state == AST_STATE_RINGING) || (target->_state == AST_STATE_RING))) {
		ast_log(LOG_DEBUG, "Call pickup on chan '%s' by '%s'\n", target->name,
			chan->name);
		res = ast_answer(chan);
		if (res) {
			ast_log(LOG_WARNING, "Unable to answer '%s'\n", chan->name);
			res = -1;
			goto out;
		}
		res = ast_queue_control(chan, AST_CONTROL_ANSWER);
		if (res) {
			ast_log(LOG_WARNING, "Unable to queue answer on '%s'\n",
				chan->name);
			res = -1;
			goto out;
		}
		res = ast_channel_masquerade(target, chan);
		if (res) {
			ast_log(LOG_WARNING, "Unable to masquerade '%s' into '%s'\n", chan->name, target->name);
			res = -1;
			goto out;
		}
	} else {
		ast_log(LOG_DEBUG, "No call pickup possible...\n");
		res = -1;
	}
	/* Done */
 out:
	if (target) 
		ast_mutex_unlock(&target->lock);
	
	LOCAL_USER_REMOVE(u);

	return res;
}