Skip to content
Snippets Groups Projects
bridge.c 162 KiB
Newer Older
/*
 * Asterisk -- An open source telephony toolkit.
 *
 * Copyright (C) 2007 - 2009, Digium, Inc.
 *
 * Joshua Colp <jcolp@digium.com>
 *
 * See http://www.asterisk.org for more information about
 * the Asterisk project. Please do not directly contact
 * any of the maintainers of this project for assistance;
 * the project provides a web site, mailing lists and IRC
 * channels for your use.
 *
 * This program is free software, distributed under the terms of
 * the GNU General Public License Version 2. See the LICENSE file
 * at the top of the source tree.
 */

/*! \file
 *
 * \brief Bridging API
 *
 * \author Joshua Colp <jcolp@digium.com>
 */

/*** MODULEINFO
	<support_level>core</support_level>
 ***/

/*** DOCUMENTATION
	<manager name="BridgeTechnologyList" language="en_US">
		<synopsis>
			List available bridging technologies and their statuses.
		</synopsis>
		<syntax>
			<xi:include xpointer="xpointer(/docs/manager[@name='Login']/syntax/parameter[@name='ActionID'])" />
		</syntax>
		<description>
			<para>Returns detailed information about the available bridging technologies.</para>
		</description>
		<see-also>
			<ref type="manager">BridgeTechnologySuspend</ref>
			<ref type="manager">BridgeTechnologyUnsuspend</ref>
		</see-also>
	</manager>
	<manager name="BridgeTechnologySuspend" language="en_US">
		<synopsis>
			Suspend a bridging technology.
		</synopsis>
		<syntax>
			<xi:include xpointer="xpointer(/docs/manager[@name='Login']/syntax/parameter[@name='ActionID'])" />
			<parameter name="BridgeTechnology" required="true">
				<para>The name of the bridging technology to suspend.</para>
			</parameter>
		</syntax>
		<description>
			<para>Marks a bridging technology as suspended, which prevents subsequently created bridges from using it.</para>
		</description>
		<see-also>
			<ref type="manager">BridgeTechnologySuspend</ref>
			<ref type="manager">BridgeTechnologyUnsuspend</ref>
		</see-also>
	</manager>
	<manager name="BridgeTechnologyUnsuspend" language="en_US">
		<synopsis>
			Unsuspend a bridging technology.
		</synopsis>
		<syntax>
			<xi:include xpointer="xpointer(/docs/manager[@name='Login']/syntax/parameter[@name='ActionID'])" />
			<parameter name="BridgeTechnology" required="true">
				<para>The name of the bridging technology to unsuspend.</para>
			</parameter>
		</syntax>
		<description>
			<para>Clears a previously suspended bridging technology, which allows subsequently created bridges to use it.</para>
		</description>
		<see-also>
			<ref type="manager">BridgeTechnologyList</ref>
			<ref type="manager">BridgeTechnologySuspend</ref>
		</see-also>
#include "asterisk.h"

ASTERISK_FILE_VERSION(__FILE__, "$Revision$")

#include "asterisk/logger.h"
#include "asterisk/channel.h"
#include "asterisk/options.h"
#include "asterisk/utils.h"
#include "asterisk/lock.h"
#include "asterisk/linkedlists.h"
#include "asterisk/bridge.h"
#include "asterisk/bridge_internal.h"
#include "asterisk/bridge_channel_internal.h"
#include "asterisk/bridge_features.h"
#include "asterisk/bridge_basic.h"
#include "asterisk/bridge_technology.h"
#include "asterisk/bridge_channel.h"
#include "asterisk/bridge_after.h"
#include "asterisk/stasis_bridges.h"
#include "asterisk/stasis_channels.h"
#include "asterisk/stasis_cache_pattern.h"
#include "asterisk/app.h"
#include "asterisk/file.h"
#include "asterisk/module.h"
#include "asterisk/astobj2.h"
#include "asterisk/_private.h"
#include "asterisk/heap.h"
#include "asterisk/say.h"
#include "asterisk/timing.h"
#include "asterisk/stringfields.h"
#include "asterisk/musiconhold.h"
#include "asterisk/features.h"
#include "asterisk/cli.h"
#include "asterisk/parking.h"

/*! All bridges container. */
static struct ao2_container *bridges;

static AST_RWLIST_HEAD_STATIC(bridge_technologies, ast_bridge_technology);

static unsigned int optimization_id;

/* Initial starting point for the bridge array of channels */
#define BRIDGE_ARRAY_START 128

/* Grow rate of bridge array of channels */
#define BRIDGE_ARRAY_GROW 32

/* Variable name - stores peer information about the most recent blind transfer */
#define BLINDTRANSFER "BLINDTRANSFER"

/* Variable name - stores peer information about the most recent attended transfer */
#define ATTENDEDTRANSFER "ATTENDEDTRANSFER"

static void cleanup_video_mode(struct ast_bridge *bridge);

/*! Default DTMF keys for built in features */
static char builtin_features_dtmf[AST_BRIDGE_BUILTIN_END][MAXIMUM_DTMF_FEATURE_STRING];

/*! Function handlers for the built in features */
static ast_bridge_hook_callback builtin_features_handlers[AST_BRIDGE_BUILTIN_END];
/*! Function handlers for built in interval features */
static ast_bridge_builtin_set_limits_fn builtin_interval_handlers[AST_BRIDGE_BUILTIN_INTERVAL_END];

/*! Bridge manager service request */
struct bridge_manager_request {
	/*! List of bridge service requests. */
	AST_LIST_ENTRY(bridge_manager_request) node;
	/*! Refed bridge requesting service. */
	struct ast_bridge *bridge;
};

struct bridge_manager_controller {
	/*! Condition, used to wake up the bridge manager thread. */
	ast_cond_t cond;
	/*! Queue of bridge service requests. */
	AST_LIST_HEAD_NOLOCK(, bridge_manager_request) service_requests;
	/*! Manager thread */
	pthread_t thread;
	/*! TRUE if the manager needs to stop. */
	unsigned int stop:1;
};

/*! Bridge manager controller. */
static struct bridge_manager_controller *bridge_manager;

/*!
 * \internal
 * \brief Request service for a bridge from the bridge manager.
 * \since 12.0.0
 *
 * \param bridge Requesting service.
 *
 * \return Nothing
 */
static void bridge_manager_service_req(struct ast_bridge *bridge)
{
	struct bridge_manager_request *request;

	ao2_lock(bridge_manager);
	if (bridge_manager->stop) {
		ao2_unlock(bridge_manager);
		return;
	}

	/* Create the service request. */
	request = ast_calloc(1, sizeof(*request));
	if (!request) {
		/* Well. This isn't good. */
		ao2_unlock(bridge_manager);
		return;
Loading
Loading full blame...