[asterisk-commits] qwell: branch qwell/dial_events r389399 - in /team/qwell/dial_events: ./ addo...

SVN commits to the Asterisk project asterisk-commits at lists.digium.com
Tue May 21 13:36:59 CDT 2013


Author: qwell
Date: Tue May 21 13:36:52 2013
New Revision: 389399

URL: http://svnview.digium.com/svn/asterisk?view=rev&rev=389399
Log:
Merge in the bridge_construction branch to make the system use the Bridging API.

Breaks many things until they can be reworked.  A partial list:
chan_agent
chan_dahdi, chan_misdn, chan_iax2 native bridging
app_queue
COLP updates
DTMF attended transfers
Protocol attended transfers
........

Merged revisions 389378 from http://svn.asterisk.org/svn/asterisk/trunk

Added:
    team/qwell/dial_events/apps/app_bridgewait.c
      - copied unchanged from r389378, trunk/apps/app_bridgewait.c
    team/qwell/dial_events/apps/confbridge/conf_chan_announce.c
      - copied unchanged from r389378, trunk/apps/confbridge/conf_chan_announce.c
    team/qwell/dial_events/apps/confbridge/conf_chan_record.c
      - copied unchanged from r389378, trunk/apps/confbridge/conf_chan_record.c
    team/qwell/dial_events/apps/confbridge/confbridge_manager.c
      - copied unchanged from r389378, trunk/apps/confbridge/confbridge_manager.c
    team/qwell/dial_events/bridges/bridge_builtin_interval_features.c
      - copied unchanged from r389378, trunk/bridges/bridge_builtin_interval_features.c
    team/qwell/dial_events/bridges/bridge_holding.c
      - copied unchanged from r389378, trunk/bridges/bridge_holding.c
    team/qwell/dial_events/bridges/bridge_native_rtp.c
      - copied unchanged from r389378, trunk/bridges/bridge_native_rtp.c
    team/qwell/dial_events/configs/res_parking.conf.sample
      - copied unchanged from r389378, trunk/configs/res_parking.conf.sample
    team/qwell/dial_events/include/asterisk/bridging_basic.h
      - copied unchanged from r389378, trunk/include/asterisk/bridging_basic.h
    team/qwell/dial_events/include/asterisk/bridging_roles.h
      - copied unchanged from r389378, trunk/include/asterisk/bridging_roles.h
    team/qwell/dial_events/include/asterisk/core_local.h
      - copied unchanged from r389378, trunk/include/asterisk/core_local.h
    team/qwell/dial_events/include/asterisk/core_unreal.h
      - copied unchanged from r389378, trunk/include/asterisk/core_unreal.h
    team/qwell/dial_events/include/asterisk/parking.h
      - copied unchanged from r389378, trunk/include/asterisk/parking.h
    team/qwell/dial_events/include/asterisk/stasis_bridging.h
      - copied unchanged from r389378, trunk/include/asterisk/stasis_bridging.h
    team/qwell/dial_events/main/bridging_basic.c
      - copied unchanged from r389378, trunk/main/bridging_basic.c
    team/qwell/dial_events/main/bridging_roles.c
      - copied unchanged from r389378, trunk/main/bridging_roles.c
    team/qwell/dial_events/main/core_local.c
      - copied unchanged from r389378, trunk/main/core_local.c
    team/qwell/dial_events/main/core_unreal.c
      - copied unchanged from r389378, trunk/main/core_unreal.c
    team/qwell/dial_events/main/manager_bridging.c
      - copied unchanged from r389378, trunk/main/manager_bridging.c
    team/qwell/dial_events/main/parking.c
      - copied unchanged from r389378, trunk/main/parking.c
    team/qwell/dial_events/main/stasis_bridging.c
      - copied unchanged from r389378, trunk/main/stasis_bridging.c
    team/qwell/dial_events/res/parking/   (props changed)
      - copied from r389378, trunk/res/parking/
    team/qwell/dial_events/res/res_parking.c
      - copied unchanged from r389378, trunk/res/res_parking.c
Removed:
    team/qwell/dial_events/apps/app_parkandannounce.c
    team/qwell/dial_events/bridges/bridge_multiplexed.c
    team/qwell/dial_events/channels/chan_bridge.c
    team/qwell/dial_events/channels/chan_local.c
Modified:
    team/qwell/dial_events/   (props changed)
    team/qwell/dial_events/CHANGES
    team/qwell/dial_events/UPGRADE.txt
    team/qwell/dial_events/addons/chan_ooh323.c
    team/qwell/dial_events/apps/app_channelredirect.c
    team/qwell/dial_events/apps/app_chanspy.c
    team/qwell/dial_events/apps/app_confbridge.c
    team/qwell/dial_events/apps/app_dial.c
    team/qwell/dial_events/apps/app_dumpchan.c
    team/qwell/dial_events/apps/app_followme.c
    team/qwell/dial_events/apps/app_mixmonitor.c
    team/qwell/dial_events/apps/app_queue.c
    team/qwell/dial_events/apps/confbridge/conf_config_parser.c
    team/qwell/dial_events/apps/confbridge/include/confbridge.h
    team/qwell/dial_events/bridges/bridge_builtin_features.c
    team/qwell/dial_events/bridges/bridge_simple.c
    team/qwell/dial_events/bridges/bridge_softmix.c
    team/qwell/dial_events/channels/chan_agent.c
    team/qwell/dial_events/channels/chan_dahdi.c
    team/qwell/dial_events/channels/chan_gulp.c
    team/qwell/dial_events/channels/chan_h323.c
    team/qwell/dial_events/channels/chan_iax2.c
    team/qwell/dial_events/channels/chan_jingle.c
    team/qwell/dial_events/channels/chan_mgcp.c
    team/qwell/dial_events/channels/chan_misdn.c
    team/qwell/dial_events/channels/chan_motif.c
    team/qwell/dial_events/channels/chan_sip.c
    team/qwell/dial_events/channels/chan_skinny.c
    team/qwell/dial_events/channels/chan_unistim.c
    team/qwell/dial_events/channels/chan_vpb.cc
    team/qwell/dial_events/configs/features.conf.sample
    team/qwell/dial_events/funcs/func_channel.c
    team/qwell/dial_events/funcs/func_frame_trace.c
    team/qwell/dial_events/funcs/func_jitterbuffer.c
    team/qwell/dial_events/include/asterisk/_private.h
    team/qwell/dial_events/include/asterisk/abstract_jb.h
    team/qwell/dial_events/include/asterisk/bridging.h
    team/qwell/dial_events/include/asterisk/bridging_features.h
    team/qwell/dial_events/include/asterisk/bridging_technology.h
    team/qwell/dial_events/include/asterisk/ccss.h
    team/qwell/dial_events/include/asterisk/channel.h
    team/qwell/dial_events/include/asterisk/config_options.h
    team/qwell/dial_events/include/asterisk/frame.h
    team/qwell/dial_events/include/asterisk/framehook.h
    team/qwell/dial_events/include/asterisk/manager.h
    team/qwell/dial_events/include/asterisk/rtp_engine.h
    team/qwell/dial_events/main/abstract_jb.c
    team/qwell/dial_events/main/asterisk.c
    team/qwell/dial_events/main/bridging.c
    team/qwell/dial_events/main/channel.c
    team/qwell/dial_events/main/channel_internal_api.c
    team/qwell/dial_events/main/cli.c
    team/qwell/dial_events/main/config_options.c
    team/qwell/dial_events/main/features.c
    team/qwell/dial_events/main/frame.c
    team/qwell/dial_events/main/manager.c
    team/qwell/dial_events/main/manager_channels.c
    team/qwell/dial_events/main/pbx.c
    team/qwell/dial_events/main/rtp_engine.c
    team/qwell/dial_events/main/strings.c
    team/qwell/dial_events/res/Makefile
    team/qwell/dial_events/res/res_stasis_json_events.c
    team/qwell/dial_events/res/res_stasis_json_events.exports.in
    team/qwell/dial_events/res/stasis_json/resource_events.h
    team/qwell/dial_events/rest-api-templates/res_stasis_json_resource.c.mustache
    team/qwell/dial_events/rest-api-templates/stasis_json_resource.h.mustache
    team/qwell/dial_events/rest-api/api-docs/events.json

Propchange: team/qwell/dial_events/
------------------------------------------------------------------------------
--- svnmerge-integrated (original)
+++ svnmerge-integrated Tue May 21 13:36:52 2013
@@ -1,1 +1,1 @@
-/trunk:1-389345
+/trunk:1-389398

Modified: team/qwell/dial_events/CHANGES
URL: http://svnview.digium.com/svn/asterisk/team/qwell/dial_events/CHANGES?view=diff&rev=389399&r1=389398&r2=389399
==============================================================================
--- team/qwell/dial_events/CHANGES (original)
+++ team/qwell/dial_events/CHANGES Tue May 21 13:36:52 2013
@@ -50,6 +50,19 @@
  * The AMI event 'UserEvent' from app_userevent now contains the channel state
    fields. The channel state fields will come before the body fields.
 
+ * The AMI events 'ParkedCall', 'ParkedCallTimeOut', 'ParkedCallGiveUp', and
+   'UnParkedCall' have changed significantly in the new res_parking module.
+   First, channel snapshot data is included for both the parker and the parkee
+   in lieu of the "From" and "Channel" fields. They follow standard channel
+   snapshot format but each field is suffixed with 'Parker' or 'Parkee'
+   depending on which side it applies to. The 'Exten' field is replaced with
+   'ParkingSpace' since the registration of extensions as for parking spaces
+   is no longer mandatory.
+
+ * The AMI event 'Parkinglot' (response to 'Parkinglots' command) in a similar
+   fashion has changed the field names 'StartExten' and 'StopExten' to
+   'StartSpace' and 'StopSpace' respectively.
+
  * The deprecated use of | (pipe) as a separator in the channelvars setting in
    manager.conf has been removed.
 
@@ -59,8 +72,23 @@
    event, the various ChanVariable fields will contain a suffix that specifies
    which channel they correspond to.
 
+ * The AMI 'Status' response event to the AMI Status action replaces the
+   BridgedChannel and BridgedUniqueid headers with the BridgeID header to
+   indicate what bridge the channel is currently in.
+
 Channel Drivers
 ------------------
+ * When a channel driver is configured to enable jiterbuffers, they are now
+   applied unconditionally when a channel joins a bridge. If a jitterbuffer
+   is already set for that channel when it enters, such as by the JITTERBUFFER
+   function, then the existing jitterbuffer will be used and the one set by
+   the channel driver will not be applied.
+
+chan_local
+------------------
+ * The /b option is removed.
+
+ * chan_local moved into the system core and is no longer a loadable module.
 
 chan_mobile
 ------------------
@@ -86,12 +114,18 @@
 
  * Add support for automixmonitor to the BRIDGE_FEATURES channel variable.
 
- * PARKINGSLOT and PARKEDLOT channel variables will now be set for a parked
-   channel even when comebactoorigin=yes
+ * Parking has been pulled from core and placed into a separate module called
+   res_parking. See Parking changes below for more details.
 
  * You can now have the settings for a channel updated using the FEATURE()
    and FEATUREMAP() functions inherited to child channels by setting
    FEATURE(inherit)=yes.
+
+Functions
+------------------
+ * JITTERBUFFER now accepts an argument of 'disabled' which can be used
+   to remove jitterbuffers previously set on a channel with JITTERBUFFER.
+   The value of this setting is ignored when disabled is used for the argument.
 
 Logging
 -------------------
@@ -109,6 +143,51 @@
   of audio samples in a voice frame will experience significant quality problems
   if a denoiser is attached to the channel; this option gives them the ability
   to remove the denoiser without having to unload func_speex.
+
+Parking
+-------------------
+ * Parking is now implemented as a module instead of as core functionality.
+   The preferred way to configure parking is now through res_parking.conf while
+   configuration through features.conf is not currently supported.
+
+ * Parked calls are now placed in bridges. This is a largely architectural change,
+   but it could have some implications in allowing for new parked call retrieval
+   methods and the contents of parking lots will be visible though certain bridge
+   commands.
+
+ * The order of arguments for the new parking applications are different from the
+   old ones to be more intuitive. Timeout and return context/exten/priority are now
+   implemented as options. parking_lot_name is now the first parameter. See the
+   application documentation for Park, ParkedCall, and ParkAndAnnounce for more
+   in-depth information as well as syntax.
+
+ * Extensions are no longer automatically created in the dialplan to park calls,
+   pickup parked calls, etc by default.
+
+ * adsipark is no longer supported under the new parking model
+
+ * The PARKINGSLOT channel variable has been deprecated in favor of PARKING_SPACE
+   to match the naming scheme of the new system.
+
+ * PARKING_SPACE and PARKEDLOT channel variables will now be set for a parked
+   channel even when comebactoorigin=yes
+
+ * New CLI command 'parking show' allows you to inspect the currently in use
+   parking lots. 'parking show <parkinglot>' will also show the parked calls
+   in that specific parking lot.
+
+ * The CLI command 'parkedcalls' is now deprecated in favor of
+   'parking show <parkinglot>'.
+
+ * The AMI command 'ParkedCalls' will now accept a 'ParkingLot' argument which
+   can be used to get a list of parked calls only for a specific parking lot.
+
+ * The ParkAndAnnounce application is now provided through res_parking instead
+   of through the separate app_parkandannounce module.
+
+ * ParkAndAnnounce will no longer go to the next position in dialplan on timeout
+   by default. Instead, it will follow the timeout rules of the parking lot. The
+   old behavior can be reproduced by using the 'c' option.
 
 Queue
 -------------------

Modified: team/qwell/dial_events/UPGRADE.txt
URL: http://svnview.digium.com/svn/asterisk/team/qwell/dial_events/UPGRADE.txt?view=diff&rev=389399&r1=389398&r2=389399
==============================================================================
--- team/qwell/dial_events/UPGRADE.txt (original)
+++ team/qwell/dial_events/UPGRADE.txt Tue May 21 13:36:52 2013
@@ -69,6 +69,9 @@
    pauses dialing for one second.
  - The default for inband_on_proceeding has changed to no.
 
+chan_local:
+ - The /b option is removed.
+
 Dialplan:
  - All channel and global variable names are evaluated in a case-sensitive manner.
    In previous versions of Asterisk, variables created and evaluated in the
@@ -80,6 +83,18 @@
  - BRIDGE_FEATURES channel variable is now casesensitive for feature letter codes.
    Uppercase variants apply them to the calling party while lowercase variants
    apply them to the called party.
+
+Features:
+ - The features.conf [applicationmap] <FeatureName>  ActivatedBy option is
+   no longer honored.  The feature is activated by which channel
+   DYNAMIC_FEATURES includes the feature is on.  Use predial to set different
+   values of DYNAMIC_FEATURES on the channels
+
+Parking:
+ - The arguments for the Park, ParkedCall, and ParkAndAnnounce applications have
+   been modified significantly. See the application documents for specific details.
+   Also parking lot configuration is now done in res_parking.conf instead of
+   features.conf
 
 From 10 to 11:
 

Modified: team/qwell/dial_events/addons/chan_ooh323.c
URL: http://svnview.digium.com/svn/asterisk/team/qwell/dial_events/addons/chan_ooh323.c?view=diff&rev=389399&r1=389398&r2=389399
==============================================================================
--- team/qwell/dial_events/addons/chan_ooh323.c (original)
+++ team/qwell/dial_events/addons/chan_ooh323.c Tue May 21 13:36:52 2013
@@ -117,7 +117,6 @@
 	.fixup = ooh323_fixup,
 	.send_html = 0,
 	.queryoption = ooh323_queryoption,
-	.bridge = ast_rtp_instance_bridge,		/* XXX chan unlocked ? */
 	.early_bridge = ast_rtp_instance_early_bridge,
 	.func_channel_read = function_ooh323_read,
 	.func_channel_write = function_ooh323_write,

Modified: team/qwell/dial_events/apps/app_channelredirect.c
URL: http://svnview.digium.com/svn/asterisk/team/qwell/dial_events/apps/app_channelredirect.c?view=diff&rev=389399&r1=389398&r2=389399
==============================================================================
--- team/qwell/dial_events/apps/app_channelredirect.c (original)
+++ team/qwell/dial_events/apps/app_channelredirect.c Tue May 21 13:36:52 2013
@@ -96,10 +96,6 @@
 		return 0;
 	}
 
-	if (ast_channel_pbx(chan2)) {
-		ast_set_flag(ast_channel_flags(chan2), AST_FLAG_BRIDGE_HANGUP_DONT); /* don't let the after-bridge code run the h-exten */
-	}
-
 	res = ast_async_parseable_goto(chan2, args.label);
 
 	chan2 = ast_channel_unref(chan2);

Modified: team/qwell/dial_events/apps/app_chanspy.c
URL: http://svnview.digium.com/svn/asterisk/team/qwell/dial_events/apps/app_chanspy.c?view=diff&rev=389399&r1=389398&r2=389399
==============================================================================
--- team/qwell/dial_events/apps/app_chanspy.c (original)
+++ team/qwell/dial_events/apps/app_chanspy.c Tue May 21 13:36:52 2013
@@ -482,15 +482,18 @@
 static int start_spying(struct ast_autochan *autochan, const char *spychan_name, struct ast_audiohook *audiohook)
 {
 	int res = 0;
-	struct ast_channel *peer = NULL;
 
 	ast_log(LOG_NOTICE, "Attaching %s to %s\n", spychan_name, ast_channel_name(autochan->chan));
 
 	ast_set_flag(audiohook, AST_AUDIOHOOK_TRIGGER_SYNC | AST_AUDIOHOOK_SMALL_QUEUE);
 	res = ast_audiohook_attach(autochan->chan, audiohook);
 
-	if (!res && ast_test_flag(ast_channel_flags(autochan->chan), AST_FLAG_NBRIDGE) && (peer = ast_bridged_channel(autochan->chan))) {
-		ast_softhangup(peer, AST_SOFTHANGUP_UNBRIDGE);
+	if (!res) {
+		ast_channel_lock(autochan->chan);
+		if (ast_channel_is_bridged(autochan->chan)) {
+			ast_softhangup_nolock(autochan->chan, AST_SOFTHANGUP_UNBRIDGE);
+		}
+		ast_channel_unlock(autochan->chan);
 	}
 	return res;
 }

Modified: team/qwell/dial_events/apps/app_confbridge.c
URL: http://svnview.digium.com/svn/asterisk/team/qwell/dial_events/apps/app_confbridge.c?view=diff&rev=389399&r1=389398&r2=389399
==============================================================================
--- team/qwell/dial_events/apps/app_confbridge.c (original)
+++ team/qwell/dial_events/apps/app_confbridge.c Tue May 21 13:36:52 2013
@@ -67,6 +67,9 @@
 #include "asterisk/paths.h"
 #include "asterisk/manager.h"
 #include "asterisk/test.h"
+#include "asterisk/stasis.h"
+#include "asterisk/stasis_bridging.h"
+#include "asterisk/json.h"
 
 /*** DOCUMENTATION
 	<application name="ConfBridge" language="en_US">
@@ -303,7 +306,7 @@
 };
 
 /*! \brief Container to hold all conference bridges in progress */
-static struct ao2_container *conference_bridges;
+struct ao2_container *conference_bridges;
 
 static void leave_conference(struct confbridge_user *user);
 static int play_sound_number(struct confbridge_conference *conference, int say_number);
@@ -412,221 +415,77 @@
 	return "";
 }
 
-static void send_conf_start_event(const char *conf_name)
-{
-	/*** DOCUMENTATION
-		<managerEventInstance>
-			<synopsis>Raised when a conference starts.</synopsis>
-			<syntax>
-				<parameter name="Conference">
-					<para>The name of the Confbridge conference.</para>
-				</parameter>
-			</syntax>
-			<see-also>
-				<ref type="managerEvent">ConfbridgeEnd</ref>
-				<ref type="application">ConfBridge</ref>
-			</see-also>
-		</managerEventInstance>
-	***/
-	manager_event(EVENT_FLAG_CALL, "ConfbridgeStart", "Conference: %s\r\n", conf_name);
-}
-
-static void send_conf_end_event(const char *conf_name)
-{
-	/*** DOCUMENTATION
-		<managerEventInstance>
-			<synopsis>Raised when a conference ends.</synopsis>
-			<syntax>
-				<xi:include xpointer="xpointer(/docs/managerEvent[@name='ConfbridgeStart']/managerEventInstance/syntax/parameter[@name='Conference'])" />
-			</syntax>
-			<see-also>
-				<ref type="managerEvent">ConfbridgeStart</ref>
-			</see-also>
-		</managerEventInstance>
-	***/
-	manager_event(EVENT_FLAG_CALL, "ConfbridgeEnd", "Conference: %s\r\n", conf_name);
-}
-
-static void send_join_event(struct ast_channel *chan, const char *conf_name)
-{
-	/*** DOCUMENTATION
-		<managerEventInstance>
-			<synopsis>Raised when a channel joins a Confbridge conference.</synopsis>
-			<syntax>
-				<xi:include xpointer="xpointer(/docs/managerEvent[@name='ConfbridgeStart']/managerEventInstance/syntax/parameter[@name='Conference'])" />
-			</syntax>
-			<see-also>
-				<ref type="managerEvent">ConfbridgeLeave</ref>
-				<ref type="application">ConfBridge</ref>
-			</see-also>
-		</managerEventInstance>
-	***/
-	ast_manager_event(chan, EVENT_FLAG_CALL, "ConfbridgeJoin",
-		"Channel: %s\r\n"
-		"Uniqueid: %s\r\n"
-		"Conference: %s\r\n"
-		"CallerIDnum: %s\r\n"
-		"CallerIDname: %s\r\n",
-		ast_channel_name(chan),
-		ast_channel_uniqueid(chan),
-		conf_name,
-		S_COR(ast_channel_caller(chan)->id.number.valid, ast_channel_caller(chan)->id.number.str, "<unknown>"),
-		S_COR(ast_channel_caller(chan)->id.name.valid, ast_channel_caller(chan)->id.name.str, "<unknown>")
-	);
-}
-
-static void send_leave_event(struct ast_channel *chan, const char *conf_name)
-{
-	/*** DOCUMENTATION
-		<managerEventInstance>
-			<synopsis>Raised when a channel leaves a Confbridge conference.</synopsis>
-			<syntax>
-				<xi:include xpointer="xpointer(/docs/managerEvent[@name='ConfbridgeStart']/managerEventInstance/syntax/parameter[@name='Conference'])" />
-			</syntax>
-			<see-also>
-				<ref type="managerEvent">ConfbridgeJoin</ref>
-			</see-also>
-		</managerEventInstance>
-	***/
-	ast_manager_event(chan, EVENT_FLAG_CALL, "ConfbridgeLeave",
-		"Channel: %s\r\n"
-		"Uniqueid: %s\r\n"
-		"Conference: %s\r\n"
-		"CallerIDnum: %s\r\n"
-		"CallerIDname: %s\r\n",
-		ast_channel_name(chan),
-		ast_channel_uniqueid(chan),
-		conf_name,
-		S_COR(ast_channel_caller(chan)->id.number.valid, ast_channel_caller(chan)->id.number.str, "<unknown>"),
-		S_COR(ast_channel_caller(chan)->id.name.valid, ast_channel_caller(chan)->id.name.str, "<unknown>")
-	);
-}
-
-static void send_start_record_event(const char *conf_name)
-{
-	/*** DOCUMENTATION
-		<managerEventInstance>
-			<synopsis>Raised when a conference recording starts.</synopsis>
-			<syntax>
-				<xi:include xpointer="xpointer(/docs/managerEvent[@name='ConfbridgeStart']/managerEventInstance/syntax/parameter[@name='Conference'])" />
-			</syntax>
-			<see-also>
-				<ref type="managerEvent">ConfbridgeStopRecord</ref>
-				<ref type="application">ConfBridge</ref>
-			</see-also>
-		</managerEventInstance>
-	***/
-
-	manager_event(EVENT_FLAG_CALL, "ConfbridgeStartRecord", "Conference: %s\r\n", conf_name);
-}
-
-static void send_stop_record_event(const char *conf_name)
-{
-	/*** DOCUMENTATION
-		<managerEventInstance>
-			<synopsis>Raised when a conference recording stops.</synopsis>
-			<syntax>
-				<xi:include xpointer="xpointer(/docs/managerEvent[@name='ConfbridgeStart']/managerEventInstance/syntax/parameter[@name='Conference'])" />
-			</syntax>
-			<see-also>
-				<ref type="managerEvent">ConfbridgeStartRecord</ref>
-			</see-also>
-		</managerEventInstance>
-	***/
-	manager_event(EVENT_FLAG_CALL, "ConfbridgeStopRecord", "Conference: %s\r\n", conf_name);
-}
-
-static void send_mute_event(struct ast_channel *chan, const char *conf_name)
-{
-	/*** DOCUMENTATION
-		<managerEventInstance>
-			<synopsis>Raised when a Confbridge participant mutes.</synopsis>
-			<syntax>
-				<xi:include xpointer="xpointer(/docs/managerEvent[@name='ConfbridgeStart']/managerEventInstance/syntax/parameter[@name='Conference'])" />
-			</syntax>
-			<see-also>
-				<ref type="managerEvent">ConfbridgeUnmute</ref>
-				<ref type="application">ConfBridge</ref>
-			</see-also>
-		</managerEventInstance>
-	***/
-	ast_manager_event(chan, EVENT_FLAG_CALL, "ConfbridgeMute",
-		"Channel: %s\r\n"
-		"Uniqueid: %s\r\n"
-		"Conference: %s\r\n"
-		"CallerIDnum: %s\r\n"
-		"CallerIDname: %s\r\n",
-		ast_channel_name(chan),
-		ast_channel_uniqueid(chan),
-		conf_name,
-		S_COR(ast_channel_caller(chan)->id.number.valid, ast_channel_caller(chan)->id.number.str, "<unknown>"),
-		S_COR(ast_channel_caller(chan)->id.name.valid, ast_channel_caller(chan)->id.name.str, "<unknown>")
-	);
-}
-
-static void send_unmute_event(struct ast_channel *chan, const char *conf_name)
-{
-	/*** DOCUMENTATION
-		<managerEventInstance>
-			<synopsis>Raised when a Confbridge participant unmutes.</synopsis>
-			<syntax>
-				<xi:include xpointer="xpointer(/docs/managerEvent[@name='ConfbridgeStart']/managerEventInstance/syntax/parameter[@name='Conference'])" />
-			</syntax>
-			<see-also>
-				<ref type="managerEvent">ConfbridgeMute</ref>
-			</see-also>
-		</managerEventInstance>
-	***/
-	ast_manager_event(chan, EVENT_FLAG_CALL, "ConfbridgeUnmute",
-		"Channel: %s\r\n"
-		"Uniqueid: %s\r\n"
-		"Conference: %s\r\n"
-		"CallerIDnum: %s\r\n"
-		"CallerIDname: %s\r\n",
-		ast_channel_name(chan),
-		ast_channel_uniqueid(chan),
-		conf_name,
-		S_COR(ast_channel_caller(chan)->id.number.valid, ast_channel_caller(chan)->id.number.str, "<unknown>"),
-		S_COR(ast_channel_caller(chan)->id.name.valid, ast_channel_caller(chan)->id.name.str, "<unknown>")
-	);
-}
-
-
-static struct ast_frame *rec_read(struct ast_channel *ast)
-{
-	return &ast_null_frame;
-}
-static int rec_write(struct ast_channel *ast, struct ast_frame *f)
-{
-	return 0;
-}
-static struct ast_channel *rec_request(const char *type, struct ast_format_cap *cap, const struct ast_channel *requestor, const char *data, int *cause);
-static struct ast_channel_tech record_tech = {
-	.type = "ConfBridgeRec",
-	.description = "Conference Bridge Recording Channel",
-	.requester = rec_request,
-	.read = rec_read,
-	.write = rec_write,
-};
-static struct ast_channel *rec_request(const char *type, struct ast_format_cap *cap, const struct ast_channel *requestor, const char *data, int *cause)
-{
-	struct ast_channel *tmp;
-	struct ast_format fmt;
-	const char *conf_name = data;
-	if (!(tmp = ast_channel_alloc(1, AST_STATE_UP, 0, 0, "", "", "", NULL, 0,
-		"ConfBridgeRecorder/conf-%s-uid-%d",
-		conf_name,
-		(int) ast_random()))) {
-		return NULL;
-	}
-	ast_format_set(&fmt, AST_FORMAT_SLINEAR, 0);
-	ast_channel_tech_set(tmp, &record_tech);
-	ast_format_cap_add_all(ast_channel_nativeformats(tmp));
-	ast_format_copy(ast_channel_writeformat(tmp), &fmt);
-	ast_format_copy(ast_channel_rawwriteformat(tmp), &fmt);
-	ast_format_copy(ast_channel_readformat(tmp), &fmt);
-	ast_format_copy(ast_channel_rawreadformat(tmp), &fmt);
-	return tmp;
+static void send_conf_stasis(struct confbridge_conference *conference, struct ast_channel *chan, const char *type, struct ast_json *extras, int channel_topic)
+{
+	RAII_VAR(struct stasis_message *, msg, NULL, ao2_cleanup);
+	RAII_VAR(struct ast_json *, json_object, NULL, ast_json_unref);
+
+	json_object = ast_json_pack("{s: s, s: s}",
+		"type", type,
+		"conference", conference->name);
+
+	if (!json_object) {
+		return;
+	}
+
+	if (extras) {
+		ast_json_object_update(json_object, extras);
+	}
+
+	msg = ast_bridge_blob_create(confbridge_message_type(),
+					 conference->bridge,
+					 chan,
+					 json_object);
+	if (!msg) {
+		return;
+	}
+
+	if (channel_topic) {
+		stasis_publish(ast_channel_topic(chan), msg);
+	} else {
+		stasis_publish(ast_bridge_topic(conference->bridge), msg);
+	}
+
+}
+
+static void send_conf_start_event(struct confbridge_conference *conference)
+{
+	send_conf_stasis(conference, NULL, "confbridge_start", NULL, 0);
+}
+
+static void send_conf_end_event(struct confbridge_conference *conference)
+{
+	send_conf_stasis(conference, NULL, "confbridge_end", NULL, 0);
+}
+
+static void send_join_event(struct ast_channel *chan, struct confbridge_conference *conference)
+{
+	send_conf_stasis(conference, chan, "confbridge_join", NULL, 0);
+}
+
+static void send_leave_event(struct ast_channel *chan, struct confbridge_conference *conference)
+{
+	send_conf_stasis(conference, chan, "confbridge_leave", NULL, 0);
+}
+
+static void send_start_record_event(struct confbridge_conference *conference)
+{
+	send_conf_stasis(conference, NULL, "confbridge_record", NULL, 0);
+}
+
+static void send_stop_record_event(struct confbridge_conference *conference)
+{
+	send_conf_stasis(conference, NULL, "confbridge_stop_record", NULL, 0);
+}
+
+static void send_mute_event(struct ast_channel *chan, struct confbridge_conference *conference)
+{
+	send_conf_stasis(conference, chan, "confbridge_mute", NULL, 1);
+}
+
+static void send_unmute_event(struct ast_channel *chan, struct confbridge_conference *conference)
+{
+	send_conf_stasis(conference, chan, "confbridge_unmute", NULL, 1);
 }
 
 static void set_rec_filename(struct confbridge_conference *conference, struct ast_str **filename, int is_new)
@@ -682,6 +541,7 @@
 	struct ast_channel *chan;
 	struct ast_str *filename = ast_str_alloca(PATH_MAX);
 	struct ast_str *orig_rec_file = NULL;
+	struct ast_bridge_features features;
 
 	ast_mutex_lock(&conference->record_lock);
 	if (!mixmonapp) {
@@ -691,20 +551,29 @@
 		ao2_ref(conference, -1);
 		return NULL;
 	}
+	if (ast_bridge_features_init(&features)) {
+		ast_bridge_features_cleanup(&features);
+		conference->record_thread = AST_PTHREADT_NULL;
+		ast_mutex_unlock(&conference->record_lock);
+		ao2_ref(conference, -1);
+		return NULL;
+	}
+	ast_set_flag(&features.feature_flags, AST_BRIDGE_CHANNEL_FLAG_IMMOVABLE);
 
 	/* XXX If we get an EXIT right here, START will essentially be a no-op */
 	while (conference->record_state != CONF_RECORD_EXIT) {
 		set_rec_filename(conference, &filename,
-				 is_new_rec_file(conference->b_profile.rec_file, &orig_rec_file));
+			is_new_rec_file(conference->b_profile.rec_file, &orig_rec_file));
 		chan = ast_channel_ref(conference->record_chan);
 		ast_answer(chan);
 		pbx_exec(chan, mixmonapp, ast_str_buffer(filename));
-		ast_bridge_join(conference->bridge, chan, NULL, NULL, NULL);
+		ast_bridge_join(conference->bridge, chan, NULL, &features, NULL, 0);
 
 		ast_hangup(chan); /* This will eat this thread's reference to the channel as well */
 		/* STOP has been called. Wait for either a START or an EXIT */
 		ast_cond_wait(&conference->record_cond, &conference->record_lock);
 	}
+	ast_bridge_features_cleanup(&features);
 	ast_free(orig_rec_file);
 	ast_mutex_unlock(&conference->record_lock);
 	ao2_ref(conference, -1);
@@ -739,7 +608,7 @@
 	ast_queue_frame(chan, &ast_null_frame);
 	chan = ast_channel_unref(chan);
 	ast_test_suite_event_notify("CONF_STOP_RECORD", "Message: stopped conference recording channel\r\nConference: %s", conference->b_profile.name);
-	send_stop_record_event(conference->name);
+	send_stop_record_event(conference);
 
 	return 0;
 }
@@ -783,8 +652,7 @@
 static int conf_start_record(struct confbridge_conference *conference)
 {
 	struct ast_format_cap *cap;
-	struct ast_format tmpfmt;
-	int cause;
+	struct ast_format format;
 
 	if (conference->record_state != CONF_RECORD_STOP) {
 		return -1;
@@ -795,25 +663,26 @@
 		return -1;
 	}
 
-	if (!(cap = ast_format_cap_alloc_nolock())) {
+	cap = ast_format_cap_alloc_nolock();
+	if (!cap) {
 		return -1;
 	}
 
-	ast_format_cap_add(cap, ast_format_set(&tmpfmt, AST_FORMAT_SLINEAR, 0));
-
-	if (!(conference->record_chan = ast_request("ConfBridgeRec", cap, NULL, conference->name, &cause))) {
-		cap = ast_format_cap_destroy(cap);
+	ast_format_cap_add(cap, ast_format_set(&format, AST_FORMAT_SLINEAR, 0));
+
+	conference->record_chan = ast_request("CBRec", cap, NULL,
+		conference->name, NULL);
+	cap = ast_format_cap_destroy(cap);
+	if (!conference->record_chan) {
 		return -1;
 	}
-
-	cap = ast_format_cap_destroy(cap);
 
 	conference->record_state = CONF_RECORD_START;
 	ast_mutex_lock(&conference->record_lock);
 	ast_cond_signal(&conference->record_cond);
 	ast_mutex_unlock(&conference->record_lock);
 	ast_test_suite_event_notify("CONF_START_RECORD", "Message: started conference recording channel\r\nConference: %s", conference->b_profile.name);
-	send_start_record_event(conference->name);
+	send_start_record_event(conference);
 
 	return 0;
 }
@@ -1017,10 +886,7 @@
 	ast_debug(1, "Destroying conference bridge '%s'\n", conference->name);
 
 	if (conference->playback_chan) {
-		struct ast_channel *underlying_channel = ast_channel_tech(conference->playback_chan)->bridged_channel(conference->playback_chan, NULL);
-		if (underlying_channel) {
-			ast_hangup(underlying_channel);
-		}
+		conf_announce_channel_depart(conference->playback_chan);
 		ast_hangup(conference->playback_chan);
 		conference->playback_chan = NULL;
 	}
@@ -1252,7 +1118,7 @@
 {
 	/* Called with a reference to conference */
 	ao2_unlink(conference_bridges, conference);
-	send_conf_end_event(conference->name);
+	send_conf_end_event(conference);
 	conf_stop_record_thread(conference);
 }
 
@@ -1314,7 +1180,9 @@
 		conf_bridge_profile_copy(&conference->b_profile, &user->b_profile);
 
 		/* Create an actual bridge that will do the audio mixing */
-		if (!(conference->bridge = ast_bridge_new(AST_BRIDGE_CAPABILITY_MULTIMIX, 0))) {
+		conference->bridge = ast_bridge_base_new(AST_BRIDGE_CAPABILITY_MULTIMIX,
+			AST_BRIDGE_FLAG_MASQUERADE_ONLY | AST_BRIDGE_FLAG_TRANSFER_BRIDGE_ONLY);
+		if (!conference->bridge) {
 			ao2_ref(conference, -1);
 			conference = NULL;
 			ao2_unlock(conference_bridges);
@@ -1351,7 +1219,7 @@
 			ao2_unlock(conference);
 		}
 
-		send_conf_start_event(conference->name);
+		send_conf_start_event(conference);
 		ast_debug(1, "Created conference '%s' and linked to container.\n", conference_name);
 	}
 
@@ -1452,74 +1320,59 @@
 
 /*!
  * \internal
- * \brief allocates playback chan on a channel
+ * \brief Allocate playback channel for a conference.
  * \pre expects conference to be locked before calling this function
  */
 static int alloc_playback_chan(struct confbridge_conference *conference)
 {
-	int cause;
 	struct ast_format_cap *cap;
-	struct ast_format tmpfmt;
-
-	if (conference->playback_chan) {
-		return 0;
-	}
-	if (!(cap = ast_format_cap_alloc_nolock())) {
+	struct ast_format format;
+
+	cap = ast_format_cap_alloc_nolock();
+	if (!cap) {
 		return -1;
 	}
-	ast_format_cap_add(cap, ast_format_set(&tmpfmt, AST_FORMAT_SLINEAR, 0));
-	if (!(conference->playback_chan = ast_request("Bridge", cap, NULL, "", &cause))) {
-		cap = ast_format_cap_destroy(cap);
+	ast_format_cap_add(cap, ast_format_set(&format, AST_FORMAT_SLINEAR, 0));
+	conference->playback_chan = ast_request("CBAnn", cap, NULL,
+		conference->name, NULL);
+	cap = ast_format_cap_destroy(cap);
+	if (!conference->playback_chan) {
 		return -1;
 	}
-	cap = ast_format_cap_destroy(cap);
-
-	ast_channel_internal_bridge_set(conference->playback_chan, conference->bridge);
-
-	if (ast_call(conference->playback_chan, "", 0)) {
-		ast_hangup(conference->playback_chan);
-		conference->playback_chan = NULL;
-		return -1;
-	}
-
-	ast_debug(1, "Created a playback channel to conference bridge '%s'\n", conference->name);
+
+	ast_debug(1, "Created announcer channel '%s' to conference bridge '%s'\n",
+		ast_channel_name(conference->playback_chan), conference->name);
 	return 0;
 }
 
 static int play_sound_helper(struct confbridge_conference *conference, const char *filename, int say_number)
 {
-	struct ast_channel *underlying_channel;
-
 	/* Do not waste resources trying to play files that do not exist */
 	if (!ast_strlen_zero(filename) && !sound_file_exists(filename)) {
 		return 0;
 	}
 
 	ast_mutex_lock(&conference->playback_lock);
-	if (!(conference->playback_chan)) {
-		if (alloc_playback_chan(conference)) {
-			ast_mutex_unlock(&conference->playback_lock);
-			return -1;
-		}
-		underlying_channel = ast_channel_tech(conference->playback_chan)->bridged_channel(conference->playback_chan, NULL);
-	} else {
-		/* Channel was already available so we just need to add it back into the bridge */
-		underlying_channel = ast_channel_tech(conference->playback_chan)->bridged_channel(conference->playback_chan, NULL);
-		if (ast_bridge_impart(conference->bridge, underlying_channel, NULL, NULL, 0)) {
-			ast_mutex_unlock(&conference->playback_lock);
-			return -1;
-		}
+	if (!conference->playback_chan && alloc_playback_chan(conference)) {
+		ast_mutex_unlock(&conference->playback_lock);
+		return -1;
+	}
+	if (conf_announce_channel_push(conference->playback_chan)) {
+		ast_mutex_unlock(&conference->playback_lock);
+		return -1;
 	}
 
 	/* The channel is all under our control, in goes the prompt */
 	if (!ast_strlen_zero(filename)) {
 		ast_stream_and_wait(conference->playback_chan, filename, "");
 	} else if (say_number >= 0) {
-		ast_say_number(conference->playback_chan, say_number, "", ast_channel_language(conference->playback_chan), NULL);
-	}
-
-	ast_debug(1, "Departing underlying channel '%s' from bridge '%p'\n", ast_channel_name(underlying_channel), conference->bridge);
-	ast_bridge_depart(conference->bridge, underlying_channel);
+		ast_say_number(conference->playback_chan, say_number, "",
+			ast_channel_language(conference->playback_chan), NULL);
+	}
+
+	ast_debug(1, "Departing announcer channel '%s' from conference bridge '%s'\n",
+		ast_channel_name(conference->playback_chan), conference->name);
+	conf_announce_channel_depart(conference->playback_chan);
 
 	ast_mutex_unlock(&conference->playback_lock);
 
@@ -1550,43 +1403,25 @@
 	ast_free(pvt_data);
 }
 
-static void conf_handle_talker_cb(struct ast_bridge *bridge, struct ast_bridge_channel *bridge_channel, void *pvt_data)
-{
-	char *conf_name = pvt_data;
-	int talking;
-
-	switch (bridge_channel->state) {
-	case AST_BRIDGE_CHANNEL_STATE_START_TALKING:
-		talking = 1;
-		break;
-	case AST_BRIDGE_CHANNEL_STATE_STOP_TALKING:
-		talking = 0;
-		break;
-	default:
-		return; /* uhh this shouldn't happen, but bail if it does. */
-	}
-
-	/* notify AMI someone is has either started or stopped talking */
-	/*** DOCUMENTATION
-		<managerEventInstance>
-			<synopsis>Raised when a conference participant has started or stopped talking.</synopsis>
-			<syntax>
-				<xi:include xpointer="xpointer(/docs/managerEvent[@name='ConfbridgeStart']/managerEventInstance/syntax/parameter[@name='Conference'])" />
-				<parameter name="TalkingStatus">
-					<enumlist>
-						<enum name="on"/>
-						<enum name="off"/>
-					</enumlist>
-				</parameter>
-			</syntax>
-		</managerEventInstance>
-	***/
-	ast_manager_event(bridge_channel->chan, EVENT_FLAG_CALL, "ConfbridgeTalking",
-	      "Channel: %s\r\n"
-	      "Uniqueid: %s\r\n"
-	      "Conference: %s\r\n"
-	      "TalkingStatus: %s\r\n",
-	      ast_channel_name(bridge_channel->chan), ast_channel_uniqueid(bridge_channel->chan), conf_name, talking ? "on" : "off");
+static void conf_handle_talker_cb(struct ast_bridge_channel *bridge_channel, void *pvt_data, int talking)
+{
+	const char *conf_name = pvt_data;
+	struct confbridge_conference *conference = ao2_find(conference_bridges, conf_name, OBJ_KEY);
+	struct ast_json *talking_extras;
+
+	if (!conference) {
+		return;
+	}
+
+	talking_extras = ast_json_pack("{s: s}",
+					 "talking_status", talking ? "on" : "off");
+
+	if (!talking_extras) {
+		return;
+	}
+
+	send_conf_stasis(conference, bridge_channel->chan, "confbridge_talking", talking_extras, 0);
+	ast_json_unref(talking_extras);
 }
 
 static int conf_get_pin(struct ast_channel *chan, struct confbridge_user *user)
@@ -1681,10 +1516,14 @@
 		AST_APP_ARG(u_profile_name);
 		AST_APP_ARG(menu_name);
 	);
-	ast_bridge_features_init(&user.features);
 
 	if (ast_channel_state(chan) != AST_STATE_UP) {
 		ast_answer(chan);
+	}
+
+	if (ast_bridge_features_init(&user.features)) {
+		res = -1;
+		goto confbridge_cleanup;
 	}
 
 	if (ast_strlen_zero(data)) {
@@ -1832,13 +1671,14 @@
 	conf_moh_unsuspend(&user);
 
 	/* Join our conference bridge for real */
-	send_join_event(user.chan, conference->name);
+	send_join_event(user.chan, conference);
 	ast_bridge_join(conference->bridge,
 		chan,
 		NULL,
 		&user.features,
-		&user.tech_args);
-	send_leave_event(user.chan, conference->name);
+		&user.tech_args,
+		0);
+	send_leave_event(user.chan, conference);
 
 	/* if we're shutting down, don't attempt to do further processing */
 	if (ast_shutting_down()) {
@@ -1905,9 +1745,9 @@
 		user->features.mute = (!user->features.mute ? 1 : 0);
 		ast_test_suite_event_notify("CONF_MUTE", "Message: participant %s %s\r\nConference: %s\r\nChannel: %s", ast_channel_name(chan), user->features.mute ? "muted" : "unmuted", user->b_profile.name, ast_channel_name(chan));
 		if (user->features.mute) {
-			send_mute_event(chan, conference->name);
-		} else { 
-			send_unmute_event(chan, conference->name);
+			send_mute_event(chan, conference);
+		} else {
+			send_unmute_event(chan, conference);
 		}
 	}
 	return ast_stream_and_wait(chan, (user->features.mute ?
@@ -3207,6 +3047,46 @@
 	conference->waitingusers--;
 }
 
+/*!
+ * \internal
+ * \brief Unregister a ConfBridge channel technology.
+ * \since 12.0.0
+ *

[... 18288 lines stripped ...]



More information about the asterisk-commits mailing list