[asterisk-commits] jrose: branch jrose/bridge_projects r386146 - in /team/jrose/bridge_projects:...

SVN commits to the Asterisk project asterisk-commits at lists.digium.com
Fri Apr 19 14:05:05 CDT 2013


Author: jrose
Date: Fri Apr 19 14:05:03 2013
New Revision: 386146

URL: http://svnview.digium.com/svn/asterisk?view=rev&rev=386146
Log:
Deal with merging details from bridging_basic commit. Enable automerge. Switch parked call retrieval to use basic bridge. Use basic bridge feature setting functions.

Added:
    team/jrose/bridge_projects/include/asterisk/bridging_basic.h
      - copied unchanged from r386136, team/group/bridge_construction/include/asterisk/bridging_basic.h
    team/jrose/bridge_projects/main/bridging_basic.c
      - copied unchanged from r386136, team/group/bridge_construction/main/bridging_basic.c
Modified:
    team/jrose/bridge_projects/   (props changed)
    team/jrose/bridge_projects/UPGRADE.txt
    team/jrose/bridge_projects/configs/features.conf.sample
    team/jrose/bridge_projects/funcs/func_channel.c
    team/jrose/bridge_projects/include/asterisk/bridging_features.h
    team/jrose/bridge_projects/include/asterisk/features.h
    team/jrose/bridge_projects/main/bridging.c
    team/jrose/bridge_projects/main/features.c
    team/jrose/bridge_projects/res/parking/parking_applications.c
    team/jrose/bridge_projects/res/parking/parking_bridge.c
    team/jrose/bridge_projects/res/parking/parking_controller.c
    team/jrose/bridge_projects/res/parking/res_parking.h

Propchange: team/jrose/bridge_projects/
------------------------------------------------------------------------------
    automerge = *

Propchange: team/jrose/bridge_projects/
------------------------------------------------------------------------------
--- bridge_projects-integrated (original)
+++ bridge_projects-integrated Fri Apr 19 14:05:03 2013
@@ -1,1 +1,1 @@
-/team/group/bridge_construction:1-386058
+/team/group/bridge_construction:1-386141

Modified: team/jrose/bridge_projects/UPGRADE.txt
URL: http://svnview.digium.com/svn/asterisk/team/jrose/bridge_projects/UPGRADE.txt?view=diff&rev=386146&r1=386145&r2=386146
==============================================================================
--- team/jrose/bridge_projects/UPGRADE.txt (original)
+++ team/jrose/bridge_projects/UPGRADE.txt Fri Apr 19 14:05:03 2013
@@ -80,6 +80,12 @@
  - 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
 
 From 10 to 11:
 

Modified: team/jrose/bridge_projects/configs/features.conf.sample
URL: http://svnview.digium.com/svn/asterisk/team/jrose/bridge_projects/configs/features.conf.sample?view=diff&rev=386146&r1=386145&r2=386146
==============================================================================
--- team/jrose/bridge_projects/configs/features.conf.sample (original)
+++ team/jrose/bridge_projects/configs/features.conf.sample Fri Apr 19 14:05:03 2013
@@ -176,10 +176,10 @@
 ;                   application on the same channel that activated the feature. "peer"
 ;                   means run the application on the opposite channel from the one that
 ;                   has activated the feature.
-;  ActivatedBy   -> This is which channel is allowed to activate this feature. Valid
-;                   values are "caller", "callee", and "both". "both" is the default.
-;                   The "caller" is the channel that executed the Dial application, while
-;                   the "callee" is the channel called by the Dial application.
+;  ActivatedBy   -> ActivatedBy 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.
+;                   Historic values are: "caller", "callee", and "both".
 ;  Application   -> This is the application to execute.
 ;  AppArguments  -> These are the arguments to be passed into the application.  If you need
 ;                   commas in your arguments, you should use either the second or third
@@ -194,8 +194,9 @@
 ;   applications. When applications are used in extensions.conf, they are executed
 ;   by the PBX core. In this case, these applications are executed outside of the
 ;   PBX core, so it does *not* make sense to use any application which has any
-;   concept of dialplan flow. Examples of this would be things like Macro, Goto,
-;   Background, WaitExten, and many more.
+;   concept of dialplan flow. Examples of this would be things like Goto,
+;   Background, WaitExten, and many more.  The exceptions to this are Gosub and
+;   Macro routines which must complete for the call to continue.
 ;
 ; Enabling these features means that the PBX needs to stay in the media flow and
 ; media will not be re-directed if DTMF is sent in the media stream.

Modified: team/jrose/bridge_projects/funcs/func_channel.c
URL: http://svnview.digium.com/svn/asterisk/team/jrose/bridge_projects/funcs/func_channel.c?view=diff&rev=386146&r1=386145&r2=386146
==============================================================================
--- team/jrose/bridge_projects/funcs/func_channel.c (original)
+++ team/jrose/bridge_projects/funcs/func_channel.c Fri Apr 19 14:05:03 2013
@@ -346,6 +346,8 @@
 /*
  * BUGBUG add CHANNEL(after_bridge_goto)=<parseable-goto> Sets an after bridge goto datastore property on the channel.
  * CHANNEL(after_bridge_goto)=<empty> Deletes any after bridge goto datastore property on the channel.
+ *
+ * BUGBUG add CHANNEL(dtmf_features)=tkhwx sets channel dtmf features to specified. (transfer, park, hangup, monitor, mixmonitor)
  */
 
 #define locked_copy_string(chan, dest, source, len) \

Modified: team/jrose/bridge_projects/include/asterisk/bridging_features.h
URL: http://svnview.digium.com/svn/asterisk/team/jrose/bridge_projects/include/asterisk/bridging_features.h?view=diff&rev=386146&r1=386145&r2=386146
==============================================================================
--- team/jrose/bridge_projects/include/asterisk/bridging_features.h (original)
+++ team/jrose/bridge_projects/include/asterisk/bridging_features.h Fri Apr 19 14:05:03 2013
@@ -145,7 +145,7 @@
 /*!
  * \brief Maximum length of a DTMF feature string
  */
-#define MAXIMUM_DTMF_FEATURE_STRING 8
+#define MAXIMUM_DTMF_FEATURE_STRING (11 + 1)
 
 /*! Extra parameters for a DTMF feature hook. */
 struct ast_bridge_hook_dtmf {

Modified: team/jrose/bridge_projects/include/asterisk/features.h
URL: http://svnview.digium.com/svn/asterisk/team/jrose/bridge_projects/include/asterisk/features.h?view=diff&rev=386146&r1=386145&r2=386146
==============================================================================
--- team/jrose/bridge_projects/include/asterisk/features.h (original)
+++ team/jrose/bridge_projects/include/asterisk/features.h Fri Apr 19 14:05:03 2013
@@ -182,18 +182,6 @@
  */
 void ast_bridge_end_dtmf(struct ast_channel *chan, char digit, struct timeval start, const char *why);
 
-/*!
- * \brief Setup bridge channel features.
- * \since 12.0.0
- *
- * \param features Bridge features to setup.
- * \param flags DTMF features to enable.
- *
- * \retval 0 on success.
- * \retval -1 on failure.
- */
-int ast_setup_bridge_channel_features(struct ast_bridge_features *features, struct ast_flags *flags);
-
 /*! \brief Bridge a call, optionally allowing redirection */
 int ast_bridge_call(struct ast_channel *chan, struct ast_channel *peer,struct ast_bridge_config *config);
 

Modified: team/jrose/bridge_projects/main/bridging.c
URL: http://svnview.digium.com/svn/asterisk/team/jrose/bridge_projects/main/bridging.c?view=diff&rev=386146&r1=386145&r2=386146
==============================================================================
--- team/jrose/bridge_projects/main/bridging.c (original)
+++ team/jrose/bridge_projects/main/bridging.c Fri Apr 19 14:05:03 2013
@@ -40,8 +40,9 @@
 #include "asterisk/lock.h"
 #include "asterisk/linkedlists.h"
 #include "asterisk/bridging.h"
+#include "asterisk/bridging_basic.h"
+#include "asterisk/bridging_technology.h"
 #include "asterisk/stasis_bridging.h"
-#include "asterisk/bridging_technology.h"
 #include "asterisk/app.h"
 #include "asterisk/file.h"
 #include "asterisk/module.h"
@@ -4611,6 +4612,8 @@
 		return -1;
 	}
 
+	ast_bridging_init_basic();
+
 /* BUGBUG need AMI action equivalents to the CLI commands. */
 	ast_cli_register_multiple(bridge_cli, ARRAY_LEN(bridge_cli));
 

Modified: team/jrose/bridge_projects/main/features.c
URL: http://svnview.digium.com/svn/asterisk/team/jrose/bridge_projects/main/features.c?view=diff&rev=386146&r1=386145&r2=386146
==============================================================================
--- team/jrose/bridge_projects/main/features.c (original)
+++ team/jrose/bridge_projects/main/features.c Fri Apr 19 14:05:03 2013
@@ -73,6 +73,7 @@
 #include "asterisk/cel.h"
 #include "asterisk/test.h"
 #include "asterisk/bridging.h"
+#include "asterisk/bridging_basic.h"
 
 /*
  * Party A - transferee
@@ -3626,6 +3627,9 @@
 {
 	int x;
 
+/* BUGBUG there is code that checks AST_BRIDGE_IGNORE_SIGS but no code to set it. */
+/* BUGBUG there is code that checks AST_BRIDGE_REC_CHANNEL_0 but no code to set it. */
+/* BUGBUG there is code that checks AST_BRIDGE_REC_CHANNEL_1 but no code to set it. */
 	ast_clear_flag(config, AST_FLAGS_ALL);
 
 	ast_rdlock_call_features();
@@ -4136,67 +4140,238 @@
 		digit, ast_channel_name(chan), why, duration);
 }
 
-int ast_setup_bridge_channel_features(struct ast_bridge_features *features, struct ast_flags *flags)
-{
-	struct ast_call_feature *dtmf;
-	int res = 0;
-
-	/* Always pass through any DTMF digits. */
-	features->dtmf_passthrough = 1;
-
+/*!
+ * \internal
+ * \brief Setup bridge builtin features.
+ * \since 12.0.0
+ *
+ * \param features Bridge features to setup.
+ * \param chan Get features from this channel.
+ *
+ * \retval 0 on success.
+ * \retval -1 on error.
+ */
+static int setup_bridge_features_builtin(struct ast_bridge_features *features, struct ast_channel *chan)
+{
+	struct ast_flags *flags;
+	char dtmf[FEATURE_MAX_LEN];
+	int res;
+
+	ast_channel_lock(chan);
+	flags = ast_bridge_features_ds_get(chan);
+	ast_channel_unlock(chan);
+	if (!flags) {
+		return 0;
+	}
+
+	res = 0;
+	ast_rdlock_call_features();
 	if (ast_test_flag(flags, AST_FEATURE_REDIRECT)) {
 		/* Add atxfer and blind transfer. */
-		ast_rwlock_rdlock(&features_lock);
-		dtmf = ast_find_call_feature("blindxfer");
-		if (dtmf && !ast_strlen_zero(dtmf->exten)) {
+		builtin_feature_get_exten(chan, "blindxfer", dtmf, sizeof(dtmf));
+		if (!ast_strlen_zero(dtmf)) {
 /* BUGBUG need to supply a blind transfer structure and destructor to use other than defaults */
-			res |= ast_bridge_features_enable(features, AST_BRIDGE_BUILTIN_BLINDTRANSFER, dtmf->exten, NULL, NULL, 0);
-		}
-		dtmf = ast_find_call_feature("atxfer");
-		if (dtmf && !ast_strlen_zero(dtmf->exten)) {
+			res |= ast_bridge_features_enable(features, AST_BRIDGE_BUILTIN_BLINDTRANSFER, dtmf, NULL, NULL, 1);
+		}
+		builtin_feature_get_exten(chan, "atxfer", dtmf, sizeof(dtmf));
+		if (!ast_strlen_zero(dtmf)) {
 /* BUGBUG need to supply an attended transfer structure and destructor to use other than defaults */
-			res |= ast_bridge_features_enable(features, AST_BRIDGE_BUILTIN_ATTENDEDTRANSFER, dtmf->exten, NULL, NULL, 0);
-		}
-		ast_rwlock_unlock(&features_lock);
+			res |= ast_bridge_features_enable(features, AST_BRIDGE_BUILTIN_ATTENDEDTRANSFER, dtmf, NULL, NULL, 1);
+		}
 	}
 	if (ast_test_flag(flags, AST_FEATURE_DISCONNECT)) {
-		ast_rwlock_rdlock(&features_lock);
-		dtmf = ast_find_call_feature("disconnect");
-		if (dtmf && !ast_strlen_zero(dtmf->exten)) {
-			res |= ast_bridge_features_enable(features, AST_BRIDGE_BUILTIN_HANGUP, dtmf->exten, NULL, NULL, 0);
-		}
-		ast_rwlock_unlock(&features_lock);
+		builtin_feature_get_exten(chan, "disconnect", dtmf, sizeof(dtmf));
+		if (ast_strlen_zero(dtmf)) {
+			res |= ast_bridge_features_enable(features, AST_BRIDGE_BUILTIN_HANGUP, dtmf, NULL, NULL, 1);
+		}
 	}
 	if (ast_test_flag(flags, AST_FEATURE_PARKCALL)) {
-		ast_rwlock_rdlock(&features_lock);
-		dtmf = ast_find_call_feature("parkcall");
-		if (dtmf && !ast_strlen_zero(dtmf->exten)) {
-			res |= ast_bridge_features_enable(features, AST_BRIDGE_BUILTIN_PARKCALL, dtmf->exten, NULL, NULL, 0);
-		}
-		ast_rwlock_unlock(&features_lock);
+		builtin_feature_get_exten(chan, "parkcall", dtmf, sizeof(dtmf));
+		if (!ast_strlen_zero(dtmf)) {
+			res |= ast_bridge_features_enable(features, AST_BRIDGE_BUILTIN_PARKCALL, dtmf, NULL, NULL, 1);
+		}
 	}
 	if (ast_test_flag(flags, AST_FEATURE_AUTOMON)) {
-		ast_rwlock_rdlock(&features_lock);
-		dtmf = ast_find_call_feature("automon");
-		if (dtmf && !ast_strlen_zero(dtmf->exten)) {
-			res |= ast_bridge_features_enable(features, AST_BRIDGE_BUILTIN_AUTOMON, dtmf->exten, NULL, NULL, 0);
-		}
-		ast_rwlock_unlock(&features_lock);
+		builtin_feature_get_exten(chan, "automon", dtmf, sizeof(dtmf));
+		if (!ast_strlen_zero(dtmf)) {
+			res |= ast_bridge_features_enable(features, AST_BRIDGE_BUILTIN_AUTOMON, dtmf, NULL, NULL, 1);
+		}
 	}
 	if (ast_test_flag(flags, AST_FEATURE_AUTOMIXMON)) {
-		ast_rwlock_rdlock(&features_lock);
-		dtmf = ast_find_call_feature("automixmon");
-		if (dtmf && !ast_strlen_zero(dtmf->exten)) {
-			res |= ast_bridge_features_enable(features, AST_BRIDGE_BUILTIN_AUTOMIXMON, dtmf->exten, NULL, NULL, 0);
-		}
-		ast_rwlock_unlock(&features_lock);
-	}
+		builtin_feature_get_exten(chan, "automixmon", dtmf, sizeof(dtmf));
+		if (!ast_strlen_zero(dtmf)) {
+			res |= ast_bridge_features_enable(features, AST_BRIDGE_BUILTIN_AUTOMIXMON, dtmf, NULL, NULL, 1);
+		}
+	}
+	ast_unlock_call_features();
 
 #if 0	/* BUGBUG don't report errors untill all of the builtin features are supported. */
 	return res ? -1 : 0;
 #else
 	return 0;
 #endif
+}
+
+struct dtmf_hook_run_app {
+	/*! Which side of bridge to run app (AST_FEATURE_FLAG_ONSELF/AST_FEATURE_FLAG_ONPEER) */
+	unsigned int flags;
+	/*! Offset into app_name[] where the MOH class name starts.  (zero if no MOH) */
+	int moh_offset;
+	/*! Offset into app_name[] where the application argument string starts. (zero if no arguments) */
+	int app_args_offset;
+	/*! Application name to run. */
+	char app_name[0];
+};
+
+/*!
+ * \internal
+ * \brief Setup bridge dynamic features.
+ * \since 12.0.0
+ *
+ * \param bridge The bridge that the channel is part of
+ * \param bridge_channel Channel executing the feature
+ * \param hook_pvt Private data passed in when the hook was created
+ *
+ * \retval 0 Keep the callback hook.
+ * \retval -1 Remove the callback hook.
+ */
+static int app_dtmf_feature_hook(struct ast_bridge *bridge, struct ast_bridge_channel *bridge_channel, void *hook_pvt)
+{
+	struct dtmf_hook_run_app *pvt = hook_pvt;
+	void (*run_it)(struct ast_bridge_channel *bridge_channel, const char *app_name, const char *app_args, const char *moh_class);
+
+	if (ast_test_flag(pvt, AST_FEATURE_FLAG_ONPEER)) {
+		run_it = ast_bridge_channel_write_app;
+	} else {
+		run_it = ast_bridge_channel_run_app;
+	}
+
+/*
+ * BUGBUG need to pass to run_it the triggering channel name so DYNAMIC_WHO_TRIGGERED can be set on the channel when it is run.
+ *
+ * This would replace DYNAMIC_PEERNAME which is redundant with
+ * BRIDGEPEER anyway.  The value of DYNAMIC_WHO_TRIGGERED is
+ * really useful in the case of a multi-party bridge.
+ */
+	run_it(bridge_channel, pvt->app_name,
+		pvt->app_args_offset ? &pvt->app_name[pvt->app_args_offset] : NULL,
+		pvt->moh_offset ? &pvt->app_name[pvt->moh_offset] : NULL);
+	return 0;
+}
+
+/*!
+ * \internal
+ * \brief Add a dynamic DTMF feature hook to the bridge features.
+ * \since 12.0.0
+ *
+ * \param features Bridge features to setup.
+ * \param flags Which side of bridge to run app (AST_FEATURE_FLAG_ONSELF/AST_FEATURE_FLAG_ONPEER).
+ * \param dtmf DTMF trigger sequence.
+ * \param app_name Dialplan application name to run.
+ * \param app_args Dialplan application arguments. (Empty or NULL if no arguments)
+ * \param moh_class MOH class to play to peer. (Empty or NULL if no MOH played)
+ *
+ * \retval 0 on success.
+ * \retval -1 on error.
+ */
+static int add_dynamic_dtmf_hook(struct ast_bridge_features *features, unsigned int flags, const char *dtmf, const char *app_name, const char *app_args, const char *moh_class)
+{
+	struct dtmf_hook_run_app *app_data;
+	size_t len_name = strlen(app_name) + 1;
+	size_t len_args = ast_strlen_zero(app_args) ? 0 : strlen(app_args) + 1;
+	size_t len_moh = ast_strlen_zero(moh_class) ? 0 : strlen(moh_class) + 1;
+	size_t len_data = sizeof(*app_data) + len_name + len_args + len_moh;
+
+	/* Fill in application run hook data. */
+	app_data = ast_malloc(len_data);
+	if (!app_data) {
+		return -1;
+	}
+	app_data->flags = flags;
+	app_data->app_args_offset = len_args ? len_name : 0;
+	app_data->moh_offset = len_moh ? len_name + len_args : 0;
+	strcpy(app_data->app_name, app_name);/* Safe */
+	if (len_args) {
+		strcpy(&app_data->app_name[app_data->app_args_offset], app_args);/* Safe */
+	}
+	if (len_moh) {
+		strcpy(&app_data->app_name[app_data->moh_offset], moh_class);/* Safe */
+	}
+
+	return ast_bridge_dtmf_hook(features, dtmf, app_dtmf_feature_hook,
+		app_data, ast_free_ptr, 1);
+}
+
+/*!
+ * \internal
+ * \brief Setup bridge dynamic features.
+ * \since 12.0.0
+ *
+ * \param features Bridge features to setup.
+ * \param chan Get features from this channel.
+ *
+ * \retval 0 on success.
+ * \retval -1 on error.
+ */
+static int setup_bridge_features_dynamic(struct ast_bridge_features *features, struct ast_channel *chan)
+{
+	const char *feat;
+	char *dynamic_features = NULL;
+	char *tok;
+	int res;
+
+	ast_channel_lock(chan);
+	feat = pbx_builtin_getvar_helper(chan, "DYNAMIC_FEATURES");
+	if (!ast_strlen_zero(feat)) {
+		dynamic_features = ast_strdupa(feat);
+	}
+	ast_channel_unlock(chan);
+	if (!dynamic_features) {
+		return 0;
+	}
+
+/* BUGBUG need to pass to add_dynamic_dtmf_hook the applicationmap name (feature->sname) so the DYNAMIC_FEATURENAME can be set on the channel when it is run. */
+	res = 0;
+	while ((tok = strsep(&dynamic_features, "#"))) {
+		struct feature_group *fg;
+		struct ast_call_feature *feature;
+
+		AST_RWLIST_RDLOCK(&feature_groups);
+		fg = find_group(tok);
+		if (fg) {
+			struct feature_group_exten *fge;
+
+			AST_LIST_TRAVERSE(&fg->features, fge, entry) {
+				res |= add_dynamic_dtmf_hook(features, fge->feature->flags, fge->exten,
+					fge->feature->app, fge->feature->app_args, fge->feature->moh_class);
+			}
+		}
+		AST_RWLIST_UNLOCK(&feature_groups);
+
+		ast_rdlock_call_features();
+		feature = find_dynamic_feature(tok);
+		if (feature) {
+			res |= add_dynamic_dtmf_hook(features, feature->flags, feature->exten,
+				feature->app, feature->app_args, feature->moh_class);
+		}
+		ast_unlock_call_features();
+	}
+	return res;
+}
+
+/* BUGBUG struct ast_call_feature needs to be made an ao2 object so the basic bridge class can own the code setting up it's DTMF hooks. */
+/* BUGBUG this really should be made a private function of bridging_basic.c after struct ast_call_feature is made an ao2 object. */
+int ast_bridge_channel_setup_features(struct ast_bridge_channel *bridge_channel)
+{
+	int res = 0;
+
+	/* Always pass through any DTMF digits. */
+	bridge_channel->features->dtmf_passthrough = 1;
+
+	res |= setup_bridge_features_builtin(bridge_channel->features, bridge_channel->chan);
+	res |= setup_bridge_features_dynamic(bridge_channel->features, bridge_channel->chan);
+
+	return res;
 }
 
 static void bridge_config_set_limits_warning_values(struct ast_bridge_config *config, struct ast_bridge_features_limits *limits)
@@ -4370,12 +4545,22 @@
 	clear_dialed_interfaces(chan);
 	clear_dialed_interfaces(peer);
 
-	/* Setup DTMF features. */
+	res = 0;
+	ast_channel_lock(chan);
+	res |= ast_bridge_features_ds_set(chan, &config->features_caller);
+	ast_channel_unlock(chan);
+	ast_channel_lock(peer);
+	res |= ast_bridge_features_ds_set(peer, &config->features_callee);
+	ast_channel_unlock(peer);
+	if (res) {
+		bridge_failed_peer_goto(chan, peer);
+		return -1;
+	}
+
+	/* Setup features. */
 	res = ast_bridge_features_init(&chan_features);
 	peer_features = ast_bridge_features_new();
-	if (res || !peer_features
-		|| ast_setup_bridge_channel_features(peer_features, &config->features_callee)
-		|| ast_setup_bridge_channel_features(&chan_features, &config->features_caller)) {
+	if (res || !peer_features) {
 		ast_bridge_features_destroy(peer_features);
 		ast_bridge_features_cleanup(&chan_features);
 		bridge_failed_peer_goto(chan, peer);
@@ -4429,10 +4614,7 @@
 	}
 
 	/* Create bridge */
-/* BUGBUG need to create the basic bridge class that will manage the DTMF feature hooks. */
-	bridge = ast_bridge_base_new(
-		AST_BRIDGE_CAPABILITY_NATIVE | AST_BRIDGE_CAPABILITY_1TO1MIX | AST_BRIDGE_CAPABILITY_MULTIMIX,
-		AST_BRIDGE_FLAG_DISSOLVE_HANGUP | AST_BRIDGE_FLAG_DISSOLVE_EMPTY | AST_BRIDGE_FLAG_SMART);
+	bridge = ast_bridge_basic_new();
 	if (!bridge) {
 		ast_bridge_features_destroy(peer_features);
 		ast_bridge_features_cleanup(&chan_features);
@@ -5351,6 +5533,10 @@
 		return;
 	}
 
+	/*
+	 * We will parse and require correct syntax for the ActivatedBy
+	 * option, but the ActivatedBy option is not honored anymore.
+	 */
 	if (ast_strlen_zero(args.activatedby)) {
 		ast_set_flag(feature, AST_FEATURE_FLAG_BYBOTH);
 	} else if (!strcasecmp(args.activatedby, "caller")) {

Modified: team/jrose/bridge_projects/res/parking/parking_applications.c
URL: http://svnview.digium.com/svn/asterisk/team/jrose/bridge_projects/res/parking/parking_applications.c?view=diff&rev=386146&r1=386145&r2=386146
==============================================================================
--- team/jrose/bridge_projects/res/parking/parking_applications.c (original)
+++ team/jrose/bridge_projects/res/parking/parking_applications.c Fri Apr 19 14:05:03 2013
@@ -38,6 +38,7 @@
 #include "asterisk/app.h"
 #include "asterisk/say.h"
 #include "asterisk/features.h"
+#include "asterisk/bridging_basic.h"
 
 /*** DOCUMENTATION
 	<application name="Park" language="en_US">
@@ -423,9 +424,7 @@
 	pu->retriever = ast_channel_snapshot_create(chan);
 
 	/* Create bridge */
-	retrieval_bridge = ast_bridge_base_new(
-		AST_BRIDGE_CAPABILITY_NATIVE | AST_BRIDGE_CAPABILITY_1TO1MIX | AST_BRIDGE_CAPABILITY_MULTIMIX,
-		AST_BRIDGE_FLAG_DISSOLVE_HANGUP | AST_BRIDGE_FLAG_SMART);
+	retrieval_bridge = ast_bridge_basic_new();
 	if (!retrieval_bridge) {
 		return -1;
 	}
@@ -444,7 +443,7 @@
 	}
 
 	/* Set the features */
-	parked_call_retrieve_enable_features(&chan_features, lot_state, AST_FEATURE_FLAG_BYCALLER);
+	parked_call_retrieve_enable_features(chan, lot_state, AST_FEATURE_FLAG_BYCALLER);
 
 	/* If the parkedplay option is set for the caller to hear, play that tone now. */
 	if (lot_state->parkedplay & AST_FEATURE_FLAG_BYCALLER) {

Modified: team/jrose/bridge_projects/res/parking/parking_bridge.c
URL: http://svnview.digium.com/svn/asterisk/team/jrose/bridge_projects/res/parking/parking_bridge.c?view=diff&rev=386146&r1=386145&r2=386146
==============================================================================
--- team/jrose/bridge_projects/res/parking/parking_bridge.c (original)
+++ team/jrose/bridge_projects/res/parking/parking_bridge.c Fri Apr 19 14:05:03 2013
@@ -167,7 +167,6 @@
 static void bridge_parking_pull(struct ast_bridge_parking *self, struct ast_bridge_channel *bridge_channel)
 {
 	RAII_VAR(struct parked_user *, pu, NULL, ao2_cleanup);
-	struct ast_bridge_features *features = bridge_channel->features;
 	ast_bridge_base_v_table.pull(&self->base, bridge_channel);
 
 	/* Take over the bridge channel's pu reference. It will be released when we are done. */
@@ -206,7 +205,7 @@
 		/* If answered or forced, the channel should be pulled from the bridge as part of that process and unlinked from
 		 * the parking lot afterwards. We do need to apply bridge features though and play the courtesy tone if set. */
 		publish_parked_call(pu, PARKED_CALL_UNPARKED);
-		parked_call_retrieve_enable_features(features, pu->lot_state, AST_FEATURE_FLAG_BYCALLEE);
+		parked_call_retrieve_enable_features(bridge_channel->chan, pu->lot_state, AST_FEATURE_FLAG_BYCALLEE);
 
 		if (pu->lot_state->parkedplay & AST_FEATURE_FLAG_BYCALLEE) {
 			ast_bridge_channel_queue_playfile(bridge_channel, NULL, pu->lot_state->courtesytone, NULL);

Modified: team/jrose/bridge_projects/res/parking/parking_controller.c
URL: http://svnview.digium.com/svn/asterisk/team/jrose/bridge_projects/res/parking/parking_controller.c?view=diff&rev=386146&r1=386145&r2=386146
==============================================================================
--- team/jrose/bridge_projects/res/parking/parking_controller.c (original)
+++ team/jrose/bridge_projects/res/parking/parking_controller.c Fri Apr 19 14:05:03 2013
@@ -31,6 +31,7 @@
 #include "asterisk/manager.h"
 #include "asterisk/test.h"
 #include "asterisk/features.h"
+#include "asterisk/bridging_basic.h"
 
 struct ast_bridge *parking_lot_state_get_bridge(struct parking_lot_state *state)
 {
@@ -195,9 +196,15 @@
 	return user;
 }
 
-void parked_call_retrieve_enable_features(struct ast_bridge_features *features, struct parking_lot_state *lot_state, int recipient_mode)
-{
+void parked_call_retrieve_enable_features(struct ast_channel *chan, struct parking_lot_state *lot_state, int recipient_mode)
+{
+	/* Enabling features here should be additive to features that are already on the channel. */
 	struct ast_flags feature_flags = { 0 };
+	struct ast_flags *existing_features = ast_bridge_features_ds_get(chan);
+
+	if (existing_features) {
+		feature_flags = *existing_features;
+	}
 
 	if (lot_state->parkedcalltransfers & recipient_mode) {
 		ast_set_flag(&feature_flags, AST_FEATURE_REDIRECT);
@@ -217,11 +224,7 @@
 		ast_set_flag(&feature_flags, AST_FEATURE_AUTOMIXMON);
 	}
 
-	if (ast_setup_bridge_channel_features(features, &feature_flags)) {
-		/* Some features were applied that weren't explicitly mapped. We can safely ignore this. */
-		ast_debug(10, "One or more features could not be applied because they weren't mapped. "
-			"Check debug output for ast_bridge_features_enable in bridging.c to see which ones.\n");
-	}
+	ast_bridge_features_ds_set(chan, &feature_flags);
 
 	return;
 }

Modified: team/jrose/bridge_projects/res/parking/res_parking.h
URL: http://svnview.digium.com/svn/asterisk/team/jrose/bridge_projects/res/parking/res_parking.h?view=diff&rev=386146&r1=386145&r2=386146
==============================================================================
--- team/jrose/bridge_projects/res/parking/res_parking.h (original)
+++ team/jrose/bridge_projects/res/parking/res_parking.h Fri Apr 19 14:05:03 2013
@@ -213,12 +213,12 @@
  * \since 12
  * \brief Apply features based on the parking lot feature options
  *
- * \param features Which feature set is being modified
+ * \param chan Which channel's feature set is being modified
  * \param lot_state parking lot state which establishes the features used
  * \param recipient_mode AST_FEATURE_FLAG_BYCALLER if the user is the retriever
  *                       AST_FEATURE_FLAG_BYCALLEE if the user is the parkee
  */
-void parked_call_retrieve_enable_features(struct ast_bridge_features *features, struct parking_lot_state *lot_state, int recipient_mode);
+void parked_call_retrieve_enable_features(struct ast_channel *chan, struct parking_lot_state *lot_state, int recipient_mode);
 
 /*!
  * \since 12




More information about the asterisk-commits mailing list