示例#1
0
/*! \brief Helper Function to walk through ALL channels checking NAME and STATE */
static struct ast_channel *my_ast_get_channel_by_name_locked(const char *channame)
{
	char *chkchan;
	struct pickup_by_name_args pickup_args;

	/* Check if channel name contains a '-'.
	 * In this case the channel name will be interpreted as full channel name.
	 */
	if (strchr(channame, '-')) {
		/* check full channel name */
		pickup_args.len = strlen(channame);
		pickup_args.name = channame;
	} else {
		/* need to append a '-' for the comparison so we check full channel name,
		 * i.e SIP/hgc- , use a temporary variable so original stays the same for
		 * debugging.
		 */
		pickup_args.len = strlen(channame) + 1;
		chkchan = ast_alloca(pickup_args.len + 1);
		strcpy(chkchan, channame);
		strcat(chkchan, "-");
		pickup_args.name = chkchan;
	}

	return ast_channel_callback(pickup_by_name_cb, NULL, &pickup_args, 0);
}
示例#2
0
struct ast_channel *ast_pickup_find_by_group(struct ast_channel *chan)
{
	struct ao2_container *candidates;/*!< Candidate channels found to pickup. */
	struct ast_channel *target;/*!< Potential pickup target */

	candidates = ao2_container_alloc_options(AO2_ALLOC_OPT_LOCK_NOLOCK, 1, NULL, NULL);
	if (!candidates) {
		return NULL;
	}

	/* Find all candidate targets by group. */
	ast_channel_callback(find_channel_by_group, chan, candidates, 0);

	/* Find the oldest pickup target candidate */
	target = NULL;
	for (;;) {
		struct ast_channel *candidate;/*!< Potential new older target */
		struct ao2_iterator iter;

		iter = ao2_iterator_init(candidates, 0);
		while ((candidate = ao2_iterator_next(&iter))) {
			if (!target) {
				/* First target. */
				target = candidate;
				continue;
			}
			if (ast_tvcmp(ast_channel_creationtime(candidate), ast_channel_creationtime(target)) < 0) {
				/* We have a new target. */
				ast_channel_unref(target);
				target = candidate;
				continue;
			}
			ast_channel_unref(candidate);
		}
		ao2_iterator_destroy(&iter);
		if (!target) {
			/* No candidates found. */
			break;
		}

		/* The found channel must be locked and ref'd. */
		ast_channel_lock(target);

		/* Recheck pickup ability */
		if (ast_can_pickup(target)) {
			/* This is the channel to pickup. */
			break;
		}

		/* Someone else picked it up or the call went away. */
		ast_channel_unlock(target);
		ao2_unlink(candidates, target);
		target = ast_channel_unref(target);
	}
	ao2_ref(candidates, -1);

	return target;
}
/* Find channel for pick up specified by partial channel name */
static struct ast_channel *find_by_part(struct ast_channel *chan, const char *part)
{
	struct ast_channel *target;
	struct pickup_by_name_args pickup_args;

	pickup_args.chan = chan;

	/* Try a partial channel name search. */
	pickup_args.name = part;
	pickup_args.len = strlen(part);
	target = ast_channel_callback(find_by_name, NULL, &pickup_args, 0);
	if (target) {
		return target;
	}

	/* Now try a search for uniqueid. */
	pickup_args.name = part;
	pickup_args.len = 0;
	return ast_channel_callback(find_by_uniqueid, NULL, &pickup_args, 0);
}
/*! \brief Helper Function to walk through ALL channels checking NAME and STATE */
static struct ast_channel *find_by_channel(struct ast_channel *chan, const char *channame)
{
	struct ast_channel *target;
	char *chkchan;
	struct pickup_by_name_args pickup_args;

	pickup_args.chan = chan;

	if (strchr(channame, '-')) {
		/*
		 * Use the given channel name string as-is.  This allows a full channel
		 * name with a typical sequence number to be used as well as still
		 * allowing the odd partial channel name that has a '-' in it to still
		 * work, i.e. Local/bob@en-phone.
		 */
		pickup_args.len = strlen(channame);
		pickup_args.name = channame;
	} else {
		/*
		 * Append a '-' for the comparison so we check the channel name less
		 * a sequence number, i.e Find SIP/bob- and not SIP/bobby.
		 */
		pickup_args.len = strlen(channame) + 1;
		chkchan = ast_alloca(pickup_args.len + 1);
		strcpy(chkchan, channame);/* Safe */
		strcat(chkchan, "-");
		pickup_args.name = chkchan;
	}
	target = ast_channel_callback(find_by_name, NULL, &pickup_args, 0);
	if (target) {
		return target;
	}

	/* Now try a search for uniqueid. */
	pickup_args.name = channame;
	pickup_args.len = 0;
	return ast_channel_callback(find_by_uniqueid, NULL, &pickup_args, 0);
}
示例#5
0
/* Attempt to pick up specified by partial channel name */ 
static int pickup_by_part(struct ast_channel *chan, const char *part)
{
	struct ast_channel *target;/*!< Potential pickup target */
	int res = -1;

	/* The found channel is already locked. */
	target = ast_channel_callback(find_by_part, NULL, (char *) part, 0);
	if (target) {
		res = ast_do_pickup(chan, target);
		ast_channel_unlock(target);
		target = ast_channel_unref(target);
	}

	return res;
}
static int pickup_by_group(struct ast_channel *chan)
{
	struct ast_channel *target;/*!< Potential pickup target */
	int res = -1;

	/* The found channel is already locked. */
	target = ast_channel_callback(find_channel_by_group, NULL, chan, 0);
	if (target) {
		ast_log(LOG_NOTICE, "pickup %s attempt by %s\n", target->name, chan->name);
		res = ast_do_pickup(chan, target);
		ast_channel_unlock(target);
		target = ast_channel_unref(target);
	}

	return res;
}
示例#7
0
文件: cel.c 项目: RoyalG41/Asterisk
void ast_cel_check_retire_linkedid(struct ast_channel *chan)
{
	const char *linkedid = chan->linkedid;
	struct channel_find_data find_dat;

	/* make sure we need to do all this work */

	if (!ast_strlen_zero(linkedid) && ast_cel_track_event(AST_CEL_LINKEDID_END)) {
		struct ast_channel *tmp = NULL;
		find_dat.chan = chan;
		find_dat.linkedid = linkedid;
		if ((tmp = ast_channel_callback(linkedid_match, NULL, &find_dat, 0))) {
			tmp = ast_channel_unref(tmp);
		} else {
			ast_cel_report_event(chan, AST_CEL_LINKEDID_END, NULL, NULL, NULL);
		}
	}
}