[svn-commits] kmoore: branch kmoore/cel_transfers r394857 - in /team/kmoore/cel_transfers: ...

SVN commits to the Digium repositories svn-commits at lists.digium.com
Sat Jul 20 07:42:10 CDT 2013


Author: kmoore
Date: Sat Jul 20 07:42:06 2013
New Revision: 394857

URL: http://svnview.digium.com/svn/asterisk?view=rev&rev=394857
Log:
Bring up to current

Added:
    team/kmoore/cel_transfers/channels/chan_bridge_media.c
      - copied unchanged from r394846, trunk/channels/chan_bridge_media.c
    team/kmoore/cel_transfers/res/res_sip/config_global.c
      - copied unchanged from r394846, trunk/res/res_sip/config_global.c
    team/kmoore/cel_transfers/res/res_sip/config_system.c
      - copied unchanged from r394846, trunk/res/res_sip/config_system.c
    team/kmoore/cel_transfers/res/res_sip/sip_global_headers.c
      - copied unchanged from r394846, trunk/res/res_sip/sip_global_headers.c
Modified:
    team/kmoore/cel_transfers/   (props changed)
    team/kmoore/cel_transfers/apps/app_bridgewait.c
    team/kmoore/cel_transfers/apps/confbridge/conf_chan_announce.c
    team/kmoore/cel_transfers/apps/confbridge/conf_chan_record.c
    team/kmoore/cel_transfers/apps/confbridge/confbridge_manager.c
    team/kmoore/cel_transfers/bridges/bridge_holding.c
    team/kmoore/cel_transfers/bridges/bridge_native_rtp.c
    team/kmoore/cel_transfers/channels/chan_gulp.c
    team/kmoore/cel_transfers/channels/chan_sip.c
    team/kmoore/cel_transfers/include/asterisk/astobj2.h
    team/kmoore/cel_transfers/include/asterisk/audiohook.h
    team/kmoore/cel_transfers/include/asterisk/channel.h
    team/kmoore/cel_transfers/include/asterisk/core_unreal.h
    team/kmoore/cel_transfers/include/asterisk/logger.h
    team/kmoore/cel_transfers/include/asterisk/res_sip.h
    team/kmoore/cel_transfers/include/asterisk/stasis_app.h
    team/kmoore/cel_transfers/include/asterisk/stasis_app_playback.h
    team/kmoore/cel_transfers/include/asterisk/stasis_channels.h
    team/kmoore/cel_transfers/include/asterisk/stasis_system.h
    team/kmoore/cel_transfers/main/audiohook.c
    team/kmoore/cel_transfers/main/bridging.c
    team/kmoore/cel_transfers/main/bridging_roles.c
    team/kmoore/cel_transfers/main/ccss.c
    team/kmoore/cel_transfers/main/cdr.c
    team/kmoore/cel_transfers/main/cel.c
    team/kmoore/cel_transfers/main/channel.c
    team/kmoore/cel_transfers/main/core_unreal.c
    team/kmoore/cel_transfers/main/http.c
    team/kmoore/cel_transfers/main/manager_bridging.c
    team/kmoore/cel_transfers/main/manager_channels.c
    team/kmoore/cel_transfers/main/stasis_cache.c
    team/kmoore/cel_transfers/main/stasis_channels.c
    team/kmoore/cel_transfers/main/stasis_system.c
    team/kmoore/cel_transfers/res/parking/parking_manager.c
    team/kmoore/cel_transfers/res/res_agi.c
    team/kmoore/cel_transfers/res/res_http_websocket.c
    team/kmoore/cel_transfers/res/res_mutestream.c
    team/kmoore/cel_transfers/res/res_sip.c
    team/kmoore/cel_transfers/res/res_sip.exports.in
    team/kmoore/cel_transfers/res/res_sip/config_transport.c
    team/kmoore/cel_transfers/res/res_sip/include/res_sip_private.h
    team/kmoore/cel_transfers/res/res_sip/sip_configuration.c
    team/kmoore/cel_transfers/res/res_sip_caller_id.c
    team/kmoore/cel_transfers/res/res_sip_mwi.c
    team/kmoore/cel_transfers/res/res_sip_one_touch_record_info.c
    team/kmoore/cel_transfers/res/res_sip_pubsub.c
    team/kmoore/cel_transfers/res/res_sip_refer.c
    team/kmoore/cel_transfers/res/res_sip_sdp_rtp.c
    team/kmoore/cel_transfers/res/res_sip_session.c
    team/kmoore/cel_transfers/res/res_stasis.c
    team/kmoore/cel_transfers/res/res_stasis_http_bridges.c
    team/kmoore/cel_transfers/res/res_stasis_http_channels.c
    team/kmoore/cel_transfers/res/res_stasis_http_playback.c
    team/kmoore/cel_transfers/res/res_stasis_playback.c
    team/kmoore/cel_transfers/res/stasis/control.c
    team/kmoore/cel_transfers/res/stasis_http/ari_model_validators.c
    team/kmoore/cel_transfers/res/stasis_http/ari_model_validators.h
    team/kmoore/cel_transfers/res/stasis_http/resource_bridges.c
    team/kmoore/cel_transfers/res/stasis_http/resource_bridges.h
    team/kmoore/cel_transfers/res/stasis_http/resource_channels.c
    team/kmoore/cel_transfers/res/stasis_http/resource_channels.h
    team/kmoore/cel_transfers/rest-api/api-docs/bridges.json
    team/kmoore/cel_transfers/rest-api/api-docs/channels.json
    team/kmoore/cel_transfers/rest-api/api-docs/playback.json
    team/kmoore/cel_transfers/rest-api/api-docs/recordings.json

Propchange: team/kmoore/cel_transfers/
------------------------------------------------------------------------------
    automerge = *

Propchange: team/kmoore/cel_transfers/
------------------------------------------------------------------------------
Binary property 'branch-11-merged' - no diff available.

Propchange: team/kmoore/cel_transfers/
------------------------------------------------------------------------------
--- svnmerge-integrated (original)
+++ svnmerge-integrated Sat Jul 20 07:42:06 2013
@@ -1,1 +1,1 @@
-/trunk:1-394638
+/trunk:1-394856

Modified: team/kmoore/cel_transfers/apps/app_bridgewait.c
URL: http://svnview.digium.com/svn/asterisk/team/kmoore/cel_transfers/apps/app_bridgewait.c?view=diff&rev=394857&r1=394856&r2=394857
==============================================================================
--- team/kmoore/cel_transfers/apps/app_bridgewait.c (original)
+++ team/kmoore/cel_transfers/apps/app_bridgewait.c Sat Jul 20 07:42:06 2013
@@ -54,26 +54,44 @@
 			Put a call into the holding bridge.
 		</synopsis>
 		<syntax>
+			<parameter name="role" required="false">
+				<para>Defines the channel's purpose for entering the holding bridge. Values are case sensitive.
+				</para>
+				<enumlist>
+					<enum name="participant">
+						<para>The channel will enter the holding bridge to be placed on hold
+						until it is removed from the bridge for some reason. (default)</para>
+					</enum>
+					<enum name="announcer">
+						<para>The channel will enter the holding bridge to make announcements
+						to channels that are currently in the holding bridge. While an
+						announcer is present, holding for the participants will be
+						suspended.</para>
+					</enum>
+				</enumlist>
+			</parameter>
 			<parameter name="options">
 				<optionlist>
-					<option name="A">
-						<para>The channel will join the holding bridge as an
-						announcer</para>
+					<option name="m">
+						<argument name="class" required="true" />
+						<para>The specified MOH class will be used/suggested for
+						music on hold operations. This option will only be useful for
+						entertainment modes that use it (m and h).</para>
 					</option>
-					<option name="m">
-						<argument name="class" required="false" />
-						<para>Play music on hold to the entering channel while it is
-						on hold. If the <emphasis>class</emphasis> is included, then
-						that class of music on hold will take priority over the
-						channel default.</para>
-					</option>
-					<option name="r">
-						<para>Play a ringing tone to the entering channel while it is
-						on hold.</para>
+					<option name="e">
+						<para>Which entertainment mechanism should be used while on hold
+						in the holding bridge. Only the first letter is read.</para>
+						<enumlist>
+							<enum name="m"><para>Play music on hold (default)</para></enum>
+							<enum name="r"><para>Ring without pause</para></enum>
+							<enum name="s"><para>Generate silent audio</para></enum>
+							<enum name="h"><para>Put the channel on hold</para></enum>
+							<enum name="n"><para>No entertainment</para></enum>
+						</enumlist>
 					</option>
 					<option name="S">
 						<argument name="duration" required="true" />
-						<para>Automatically end the hold and return to the PBX after
+						<para>Automatically exit the bridge and return to the PBX after
 						<emphasis>duration</emphasis> seconds.</para>
 					</option>
 				</optionlist>
@@ -87,12 +105,8 @@
 	</application>
  ***/
 /* BUGBUG Add bridge name/id parameter to specify which holding bridge to join (required) */
-/* BUGBUG Add h(moh-class) option to put channel on hold using AST_CONTROL_HOLD/AST_CONTROL_UNHOLD while in bridge */
-/* BUGBUG Add s option to send silence media frames to channel while in bridge (uses a silence generator) */
-/* BUGBUG Add n option to send no media to channel while in bridge (Channel should not be answered yet) */
 /* BUGBUG The channel may or may not be answered with the r option. */
 /* BUGBUG You should not place an announcer into a holding bridge with unanswered channels. */
-/* BUGBUG Not supplying any option flags will assume the m option with the default music class. */
 
 static char *app = "BridgeWait";
 static struct ast_bridge *holding_bridge;
@@ -100,22 +114,21 @@
 AST_MUTEX_DEFINE_STATIC(bridgewait_lock);
 
 enum bridgewait_flags {
-	MUXFLAG_PLAYMOH = (1 << 0),
-	MUXFLAG_RINGING = (1 << 1),
+	MUXFLAG_MOHCLASS = (1 << 0),
+	MUXFLAG_ENTERTAINMENT = (1 << 1),
 	MUXFLAG_TIMEOUT = (1 << 2),
-	MUXFLAG_ANNOUNCER = (1 << 3),
 };
 
 enum bridgewait_args {
+	OPT_ARG_ENTERTAINMENT,
 	OPT_ARG_MOHCLASS,
 	OPT_ARG_TIMEOUT,
 	OPT_ARG_ARRAY_SIZE, /* Always the last element of the enum */
 };
 
 AST_APP_OPTIONS(bridgewait_opts, {
-	AST_APP_OPTION('A', MUXFLAG_ANNOUNCER),
-	AST_APP_OPTION('r', MUXFLAG_RINGING),
-	AST_APP_OPTION_ARG('m', MUXFLAG_PLAYMOH, OPT_ARG_MOHCLASS),
+	AST_APP_OPTION_ARG('e', MUXFLAG_ENTERTAINMENT, OPT_ARG_ENTERTAINMENT),
+	AST_APP_OPTION_ARG('m', MUXFLAG_MOHCLASS, OPT_ARG_MOHCLASS),
 	AST_APP_OPTION_ARG('S', MUXFLAG_TIMEOUT, OPT_ARG_TIMEOUT),
 });
 
@@ -147,18 +160,38 @@
 	return 0;
 }
 
-static void apply_option_moh(struct ast_channel *chan, char *class_arg)
-{
-	ast_channel_set_bridge_role_option(chan, "holding_participant", "idle_mode", "musiconhold");
-	ast_channel_set_bridge_role_option(chan, "holding_participant", "moh_class", class_arg);
-}
-
-static void apply_option_ringing(struct ast_channel *chan)
-{
-	ast_channel_set_bridge_role_option(chan, "holding_participant", "idle_mode", "ringing");
-}
-
-static int process_options(struct ast_channel *chan, struct ast_flags *flags, char **opts, struct ast_bridge_features *features)
+static int apply_option_moh(struct ast_channel *chan, const char *class_arg)
+{
+	return ast_channel_set_bridge_role_option(chan, "holding_participant", "moh_class", class_arg);
+}
+
+static int apply_option_entertainment(struct ast_channel *chan, const char *entertainment_arg)
+{
+	char entertainment = entertainment_arg[0];
+	switch (entertainment) {
+	case 'm':
+		return ast_channel_set_bridge_role_option(chan, "holding_participant", "idle_mode", "musiconhold");
+	case 'r':
+		return ast_channel_set_bridge_role_option(chan, "holding_participant", "idle_mode", "ringing");
+	case 's':
+		return ast_channel_set_bridge_role_option(chan, "holding_participant", "idle_mode", "silence");
+	case 'h':
+		return ast_channel_set_bridge_role_option(chan, "holding_participant", "idle_mode", "hold");
+	case 'n':
+		return ast_channel_set_bridge_role_option(chan, "holding_participant", "idle_mode", "none");
+	default:
+		ast_log(LOG_ERROR, "Invalid argument for BridgeWait entertainment '%s'\n", entertainment_arg);
+		return -1;
+	}
+}
+
+enum wait_bridge_roles {
+	ROLE_PARTICIPANT = 0,
+	ROLE_ANNOUNCER,
+	ROLE_INVALID,
+};
+
+static int process_options(struct ast_channel *chan, struct ast_flags *flags, char **opts, struct ast_bridge_features *features, enum wait_bridge_roles role)
 {
 	if (ast_test_flag(flags, MUXFLAG_TIMEOUT)) {
 		if (apply_option_timeout(features, opts[OPT_ARG_TIMEOUT])) {
@@ -166,21 +199,47 @@
 		}
 	}
 
-	if (ast_test_flag(flags, MUXFLAG_ANNOUNCER)) {
-		/* Announcer specific stuff */
-		ast_channel_add_bridge_role(chan, "announcer");
+	switch (role) {
+	case ROLE_PARTICIPANT:
+		if (ast_channel_add_bridge_role(chan, "holding_participant")) {
+			return -1;
+		}
+
+		if (ast_test_flag(flags, MUXFLAG_MOHCLASS)) {
+			if (apply_option_moh(chan, opts[OPT_ARG_MOHCLASS])) {
+				return -1;
+			}
+		}
+
+		if (ast_test_flag(flags, MUXFLAG_ENTERTAINMENT)) {
+			if (apply_option_entertainment(chan, opts[OPT_ARG_ENTERTAINMENT])) {
+				return -1;
+			}
+		}
+
+		break;
+	case ROLE_ANNOUNCER:
+		if (ast_channel_add_bridge_role(chan, "announcer")) {
+			return -1;
+		}
+		break;
+	case ROLE_INVALID:
+		ast_assert(0);
+		return -1;
+	}
+
+	return 0;
+}
+
+static enum wait_bridge_roles validate_role(const char *role)
+{
+	if (!strcmp(role, "participant")) {
+		return ROLE_PARTICIPANT;
+	} else if (!strcmp(role, "announcer")) {
+		return ROLE_ANNOUNCER;
 	} else {
-		/* Non Announcer specific stuff */
-		ast_channel_add_bridge_role(chan, "holding_participant");
-
-		if (ast_test_flag(flags, MUXFLAG_PLAYMOH)) {
-			apply_option_moh(chan, opts[OPT_ARG_MOHCLASS]);
-		} else if (ast_test_flag(flags, MUXFLAG_RINGING)) {
-			apply_option_ringing(chan);
-		}
-	}
-
-	return 0;
+		return ROLE_INVALID;
+	}
 }
 
 static int bridgewait_exec(struct ast_channel *chan, const char *data)
@@ -188,8 +247,11 @@
 	struct ast_bridge_features chan_features;
 	struct ast_flags flags = { 0 };
 	char *parse;
+	enum wait_bridge_roles role = ROLE_PARTICIPANT;
+	char *opts[OPT_ARG_ARRAY_SIZE] = { NULL, };
 
 	AST_DECLARE_APP_ARGS(args,
+		AST_APP_ARG(role);
 		AST_APP_ARG(options);
 		AST_APP_ARG(other);		/* Any remaining unused arguments */
 	);
@@ -209,18 +271,26 @@
 	parse = ast_strdupa(data);
 	AST_STANDARD_APP_ARGS(args, parse);
 
+	if (!ast_strlen_zero(args.role)) {
+		role = validate_role(args.role);
+		if (role == ROLE_INVALID) {
+			ast_log(LOG_ERROR, "Requested waiting bridge role '%s' is invalid.\n", args.role);
+			return -1;
+		}
+	}
+
 	if (ast_bridge_features_init(&chan_features)) {
 		ast_bridge_features_cleanup(&chan_features);
 		return -1;
 	}
 
 	if (args.options) {
-		char *opts[OPT_ARG_ARRAY_SIZE] = { NULL, };
 		ast_app_parse_options(bridgewait_opts, &flags, opts, args.options);
-		if (process_options(chan, &flags, opts, &chan_features)) {
-			ast_bridge_features_cleanup(&chan_features);
-			return -1;
-		}
+	}
+
+	if (process_options(chan, &flags, opts, &chan_features, role)) {
+		ast_bridge_features_cleanup(&chan_features);
+		return -1;
 	}
 
 	ast_bridge_join(holding_bridge, chan, NULL, &chan_features, NULL, 0);

Modified: team/kmoore/cel_transfers/apps/confbridge/conf_chan_announce.c
URL: http://svnview.digium.com/svn/asterisk/team/kmoore/cel_transfers/apps/confbridge/conf_chan_announce.c?view=diff&rev=394857&r1=394856&r2=394857
==============================================================================
--- team/kmoore/cel_transfers/apps/confbridge/conf_chan_announce.c (original)
+++ team/kmoore/cel_transfers/apps/confbridge/conf_chan_announce.c Sat Jul 20 07:42:06 2013
@@ -134,6 +134,7 @@
 	.send_text = ast_unreal_sendtext,
 	.queryoption = ast_unreal_queryoption,
 	.setoption = ast_unreal_setoption,
+	.properties = AST_CHAN_TP_ANNOUNCER,
 };
 
 struct ast_channel_tech *conf_announce_get_tech(void)

Modified: team/kmoore/cel_transfers/apps/confbridge/conf_chan_record.c
URL: http://svnview.digium.com/svn/asterisk/team/kmoore/cel_transfers/apps/confbridge/conf_chan_record.c?view=diff&rev=394857&r1=394856&r2=394857
==============================================================================
--- team/kmoore/cel_transfers/apps/confbridge/conf_chan_record.c (original)
+++ team/kmoore/cel_transfers/apps/confbridge/conf_chan_record.c Sat Jul 20 07:42:06 2013
@@ -86,6 +86,7 @@
 	.call = rec_call,
 	.read = rec_read,
 	.write = rec_write,
+	.properties = AST_CHAN_TP_RECORDER,
 };
 
 struct ast_channel_tech *conf_record_get_tech(void)

Modified: team/kmoore/cel_transfers/apps/confbridge/confbridge_manager.c
URL: http://svnview.digium.com/svn/asterisk/team/kmoore/cel_transfers/apps/confbridge/confbridge_manager.c?view=diff&rev=394857&r1=394856&r2=394857
==============================================================================
--- team/kmoore/cel_transfers/apps/confbridge/confbridge_manager.c (original)
+++ team/kmoore/cel_transfers/apps/confbridge/confbridge_manager.c Sat Jul 20 07:42:06 2013
@@ -195,13 +195,16 @@
 {
 	struct ast_bridge_blob *blob = stasis_message_data(message);
 	const char *conference_name;
-	RAII_VAR(struct ast_str *, bridge_text,
-		ast_manager_build_bridge_state_string(blob->bridge, ""),
-		ast_free);
+	RAII_VAR(struct ast_str *, bridge_text, NULL, ast_free);
 	RAII_VAR(struct ast_str *, channel_text, NULL, ast_free);
 
 	ast_assert(blob != NULL);
 	ast_assert(event != NULL);
+
+	bridge_text = ast_manager_build_bridge_state_string(blob->bridge, "");
+	if (!bridge_text) {
+		return;
+	}
 
 	conference_name = ast_json_string_get(ast_json_object_get(blob->blob, "conference"));
 	ast_assert(conference_name != NULL);

Modified: team/kmoore/cel_transfers/bridges/bridge_holding.c
URL: http://svnview.digium.com/svn/asterisk/team/kmoore/cel_transfers/bridges/bridge_holding.c?view=diff&rev=394857&r1=394856&r2=394857
==============================================================================
--- team/kmoore/cel_transfers/bridges/bridge_holding.c (original)
+++ team/kmoore/cel_transfers/bridges/bridge_holding.c Sat Jul 20 07:42:06 2013
@@ -54,18 +54,18 @@
 	HOLDING_ROLE_ANNOUNCER = (1 << 1),
 };
 
-/* BUGBUG Add IDLE_MODE_HOLD option to put channel on hold using AST_CONTROL_HOLD/AST_CONTROL_UNHOLD while in bridge */
-/* BUGBUG Add IDLE_MODE_SILENCE to send silence media frames to channel while in bridge (uses a silence generator) */
-/* BUGBUG A channel without the holding_participant role will assume IDLE_MODE_MOH with the default music class. */
 enum idle_modes {
 	IDLE_MODE_NONE = 0,
 	IDLE_MODE_MOH,
 	IDLE_MODE_RINGING,
+	IDLE_MODE_SILENCE,
+	IDLE_MODE_HOLD,
 };
 
 /*! \brief Structure which contains per-channel role information */
 struct holding_channel {
 	struct ast_flags holding_roles;
+	struct ast_silence_generator *silence_generator;
 	enum idle_modes idle_mode;
 };
 
@@ -84,6 +84,15 @@
 		ast_indicate(bridge_channel->chan, -1);
 		break;
 	case IDLE_MODE_NONE:
+		break;
+	case IDLE_MODE_SILENCE:
+		if (hc->silence_generator) {
+			ast_channel_stop_silence_generator(bridge_channel->chan, hc->silence_generator);
+			hc->silence_generator = NULL;
+		}
+		break;
+	case IDLE_MODE_HOLD:
+		ast_bridge_channel_queue_control_data(bridge_channel, AST_CONTROL_UNHOLD, NULL, 0);
 		break;
 	}
 }
@@ -103,6 +112,7 @@
 {
 	struct holding_channel *hc = bridge_channel->tech_pvt;
 	const char *moh_class;
+	size_t moh_length;
 
 	if (!hc) {
 		return;
@@ -118,6 +128,14 @@
 		break;
 	case IDLE_MODE_NONE:
 		break;
+	case IDLE_MODE_SILENCE:
+		hc->silence_generator = ast_channel_start_silence_generator(bridge_channel->chan);
+		break;
+	case IDLE_MODE_HOLD:
+		moh_class = ast_bridge_channel_get_role_option(bridge_channel, "holding_participant", "moh_class");
+		moh_length = moh_class ? strlen(moh_class + 1) : 0;
+		ast_bridge_channel_queue_control_data(bridge_channel, AST_CONTROL_HOLD, moh_class, moh_length);
+		break;
 	}
 }
 
@@ -133,11 +151,17 @@
 	}
 
 	if (ast_strlen_zero(idle_mode)) {
-		hc->idle_mode = IDLE_MODE_NONE;
+		hc->idle_mode = IDLE_MODE_MOH;
 	} else if (!strcmp(idle_mode, "musiconhold")) {
 		hc->idle_mode = IDLE_MODE_MOH;
 	} else if (!strcmp(idle_mode, "ringing")) {
 		hc->idle_mode = IDLE_MODE_RINGING;
+	} else if (!strcmp(idle_mode, "none")) {
+		hc->idle_mode = IDLE_MODE_NONE;
+	} else if (!strcmp(idle_mode, "silence")) {
+		hc->idle_mode = IDLE_MODE_SILENCE;
+	} else if (!strcmp(idle_mode, "hold")) {
+		hc->idle_mode = IDLE_MODE_HOLD;
 	} else {
 		ast_debug(2, "channel %s idle mode '%s' doesn't match any expected idle mode\n", ast_channel_name(us), idle_mode);
 	}

Modified: team/kmoore/cel_transfers/bridges/bridge_native_rtp.c
URL: http://svnview.digium.com/svn/asterisk/team/kmoore/cel_transfers/bridges/bridge_native_rtp.c?view=diff&rev=394857&r1=394856&r2=394857
==============================================================================
--- team/kmoore/cel_transfers/bridges/bridge_native_rtp.c (original)
+++ team/kmoore/cel_transfers/bridges/bridge_native_rtp.c Sat Jul 20 07:42:06 2013
@@ -45,7 +45,6 @@
 #include "asterisk/bridging_technology.h"
 #include "asterisk/frame.h"
 #include "asterisk/rtp_engine.h"
-#include "asterisk/audiohook.h"
 
 /*! \brief Forward declarations for frame hook usage */
 static int native_rtp_bridge_join(struct ast_bridge *bridge, struct ast_bridge_channel *bridge_channel);
@@ -85,13 +84,7 @@
 /*! \brief Internal helper function which checks whether the channels are compatible with our native bridging */
 static int native_rtp_bridge_capable(struct ast_channel *chan)
 {
-	if (ast_channel_monitor(chan) || (ast_channel_audiohooks(chan) &&
-		!ast_audiohook_write_list_empty(ast_channel_audiohooks(chan))) ||
-		!ast_framehook_list_contains_no_active(ast_channel_framehooks(chan))) {
-		return 0;
-	} else {
-		return 1;
-	}
+	return ast_channel_has_audio_frame_or_monitor(chan);
 }
 
 /*! \brief Internal helper function which gets all RTP information (glue and instances) relating to the given channels */

Modified: team/kmoore/cel_transfers/channels/chan_gulp.c
URL: http://svnview.digium.com/svn/asterisk/team/kmoore/cel_transfers/channels/chan_gulp.c?view=diff&rev=394857&r1=394856&r2=394857
==============================================================================
--- team/kmoore/cel_transfers/channels/chan_gulp.c (original)
+++ team/kmoore/cel_transfers/channels/chan_gulp.c Sat Jul 20 07:42:06 2013
@@ -56,6 +56,7 @@
 #include "asterisk/dsp.h"
 #include "asterisk/stasis_endpoints.h"
 #include "asterisk/stasis_channels.h"
+#include "asterisk/indications.h"
 
 #include "asterisk/res_sip.h"
 #include "asterisk/res_sip_session.h"
@@ -600,6 +601,18 @@
 
 	ast_channel_named_callgroups_set(chan, session->endpoint->named_callgroups);
 	ast_channel_named_pickupgroups_set(chan, session->endpoint->named_pickupgroups);
+
+	if (!ast_strlen_zero(session->endpoint->language)) {
+		ast_channel_language_set(chan, session->endpoint->language);
+	}
+
+	if (!ast_strlen_zero(session->endpoint->zone)) {
+		struct ast_tone_zone *zone = ast_get_indication_zone(session->endpoint->zone);
+		if (!zone) {
+			ast_log(LOG_ERROR, "Unknown country code '%s' for tonezone. Check indications.conf for available country codes.\n", session->endpoint->zone);
+		}
+		ast_channel_zone_set(chan, zone);
+	}
 
 	ast_endpoint_add_channel(session->endpoint->persistent, chan);
 

Modified: team/kmoore/cel_transfers/channels/chan_sip.c
URL: http://svnview.digium.com/svn/asterisk/team/kmoore/cel_transfers/channels/chan_sip.c?view=diff&rev=394857&r1=394856&r2=394857
==============================================================================
--- team/kmoore/cel_transfers/channels/chan_sip.c (original)
+++ team/kmoore/cel_transfers/channels/chan_sip.c Sat Jul 20 07:42:06 2013
@@ -8043,7 +8043,7 @@
 		return NULL;
 	}
 
-	if (i->relatedpeer) {
+	if (i->relatedpeer && i->relatedpeer->endpoint) {
 		if (ast_endpoint_add_channel(i->relatedpeer->endpoint, tmp)) {
 			ast_channel_unref(tmp);
 			sip_pvt_lock(i);
@@ -15743,7 +15743,6 @@
 static int expire_register(const void *data)
 {
 	struct sip_peer *peer = (struct sip_peer *)data;
-	RAII_VAR(struct ast_json *, blob, NULL, ast_json_unref);
 
 	if (!peer) {		/* Hmmm. We have no peer. Weird. */
 		return 0;
@@ -15763,11 +15762,14 @@
 		peer->socket.ws_session = NULL;
 	}
 
-	ast_endpoint_set_state(peer->endpoint, AST_ENDPOINT_OFFLINE);
-	blob = ast_json_pack("{s: s, s: s}",
-		"peer_status", "Unregistered",
-		"cause", "Expired");
-	ast_endpoint_blob_publish(peer->endpoint, ast_endpoint_state_type(), blob);
+	if (peer->endpoint) {
+		RAII_VAR(struct ast_json *, blob, NULL, ast_json_unref);
+		ast_endpoint_set_state(peer->endpoint, AST_ENDPOINT_OFFLINE);
+		blob = ast_json_pack("{s: s, s: s}",
+			"peer_status", "Unregistered",
+			"cause", "Expired");
+		ast_endpoint_blob_publish(peer->endpoint, ast_endpoint_state_type(), blob);
+	}
 	register_peer_exten(peer, FALSE);	/* Remove regexten */
 	ast_devstate_changed(AST_DEVICE_UNKNOWN, AST_DEVSTATE_CACHABLE, "SIP/%s", peer->name);
 
@@ -16012,7 +16014,6 @@
 	int start = 0;
 	int wildcard_found = 0;
 	int single_binding_found = 0;
-	RAII_VAR(struct ast_json *, blob, NULL, ast_json_unref);
 
 	ast_copy_string(contact, __get_header(req, "Contact", &start), sizeof(contact));
 
@@ -16200,11 +16201,14 @@
 		ast_db_put("SIP/Registry", peer->name, data);
 	}
 
-	ast_endpoint_set_state(peer->endpoint, AST_ENDPOINT_ONLINE);
-	blob = ast_json_pack("{s: s, s: s}",
-		"peer_status", "Registered",
-		"address", ast_sockaddr_stringify(&peer->addr));
-	ast_endpoint_blob_publish(peer->endpoint, ast_endpoint_state_type(), blob);
+	if (peer->endpoint) {
+		RAII_VAR(struct ast_json *, blob, NULL, ast_json_unref);
+		ast_endpoint_set_state(peer->endpoint, AST_ENDPOINT_ONLINE);
+		blob = ast_json_pack("{s: s, s: s}",
+			"peer_status", "Registered",
+			"address", ast_sockaddr_stringify(&peer->addr));
+		ast_endpoint_blob_publish(peer->endpoint, ast_endpoint_state_type(), blob);
+	}
 
 	/* Is this a new IP address for us? */
 	if (ast_sockaddr_cmp(&peer->addr, &oldsin)) {
@@ -17208,7 +17212,6 @@
 		/* Create peer if we have autocreate mode enabled */
 		peer = temp_peer(name);
 		if (peer) {
-			RAII_VAR(struct ast_json *, blob, NULL, ast_json_unref);
 			ao2_t_link(peers, peer, "link peer into peer table");
 			if (!ast_sockaddr_isnull(&peer->addr)) {
 				ao2_t_link(peers_by_ip, peer, "link peer into peers-by-ip table");
@@ -17237,11 +17240,14 @@
 				ast_string_field_set(p, fullcontact, peer->fullcontact);
 				/* Say OK and ask subsystem to retransmit msg counter */
 				transmit_response_with_date(p, "200 OK", req);
-				ast_endpoint_set_state(peer->endpoint, AST_ENDPOINT_ONLINE);
-				blob = ast_json_pack("{s: s, s: s}",
-					"peer_status", "Registered",
-					"address", ast_sockaddr_stringify(addr));
-				ast_endpoint_blob_publish(peer->endpoint, ast_endpoint_state_type(), blob);
+				if (peer->endpoint) {
+					RAII_VAR(struct ast_json *, blob, NULL, ast_json_unref);
+					ast_endpoint_set_state(peer->endpoint, AST_ENDPOINT_ONLINE);
+					blob = ast_json_pack("{s: s, s: s}",
+						"peer_status", "Registered",
+						"address", ast_sockaddr_stringify(addr));
+					ast_endpoint_blob_publish(peer->endpoint, ast_endpoint_state_type(), blob);
+				}
 				send_mwi = 1;
 				res = 0;
 				break;
@@ -17331,7 +17337,9 @@
 			break;
 		}
 
-		ast_endpoint_blob_publish(peer->endpoint, ast_endpoint_state_type(), blob);
+		if (peer->endpoint) {
+			ast_endpoint_blob_publish(peer->endpoint, ast_endpoint_state_type(), blob);
+		}
 	}
 	if (peer) {
 		sip_unref_peer(peer, "register_verify: sip_unref_peer: tossing stack peer pointer at end of func");
@@ -23814,7 +23822,6 @@
 	if (statechanged) {
 		const char *s = is_reachable ? "Reachable" : "Lagged";
 		char str_lastms[20];
-		RAII_VAR(struct ast_json *, blob, NULL, ast_json_unref);
 
 		snprintf(str_lastms, sizeof(str_lastms), "%d", pingtime);
 
@@ -23824,13 +23831,18 @@
 		if (sip_cfg.peer_rtupdate) {
 			ast_update_realtime(ast_check_realtime("sipregs") ? "sipregs" : "sippeers", "name", peer->name, "lastms", str_lastms, SENTINEL);
 		}
-		ast_endpoint_set_state(peer->endpoint, AST_ENDPOINT_ONLINE);
-		blob = ast_json_pack("{s: s, s: i}",
-			"peer_status", s,
-			"time", pingtime);
-		ast_endpoint_blob_publish(peer->endpoint, ast_endpoint_state_type(), blob);
-		if (is_reachable && sip_cfg.regextenonqualify)
+		if (peer->endpoint) {
+			RAII_VAR(struct ast_json *, blob, NULL, ast_json_unref);
+			ast_endpoint_set_state(peer->endpoint, AST_ENDPOINT_ONLINE);
+			blob = ast_json_pack("{s: s, s: i}",
+				"peer_status", s,
+				"time", pingtime);
+			ast_endpoint_blob_publish(peer->endpoint, ast_endpoint_state_type(), blob);
+		}
+
+		if (is_reachable && sip_cfg.regextenonqualify) {
 			register_peer_exten(peer, TRUE);
+		}
 	}
 
 	pvt_set_needdestroy(p, "got OPTIONS response");
@@ -29142,17 +29154,21 @@
 	peer->pokeexpire = -1;
 
 	if (peer->lastms > -1) {
-		RAII_VAR(struct ast_json *, blob, NULL, ast_json_unref);
 
 		ast_log(LOG_NOTICE, "Peer '%s' is now UNREACHABLE!  Last qualify: %d\n", peer->name, peer->lastms);
 		if (sip_cfg.peer_rtupdate) {
 			ast_update_realtime(ast_check_realtime("sipregs") ? "sipregs" : "sippeers", "name", peer->name, "lastms", "-1", SENTINEL);
 		}
-		ast_endpoint_set_state(peer->endpoint, AST_ENDPOINT_OFFLINE);
-		blob = ast_json_pack("{s: s, s: s}",
-			"peer_status", "Unreachable",
-			"time", "-1");
-		ast_endpoint_blob_publish(peer->endpoint, ast_endpoint_state_type(), blob);
+
+		if (peer->endpoint) {
+			RAII_VAR(struct ast_json *, blob, NULL, ast_json_unref);
+			ast_endpoint_set_state(peer->endpoint, AST_ENDPOINT_OFFLINE);
+			blob = ast_json_pack("{s: s, s: s}",
+				"peer_status", "Unreachable",
+				"time", "-1");
+			ast_endpoint_blob_publish(peer->endpoint, ast_endpoint_state_type(), blob);
+		}
+
 		if (sip_cfg.regextenonqualify) {
 			register_peer_exten(peer, FALSE);
 		}

Modified: team/kmoore/cel_transfers/include/asterisk/astobj2.h
URL: http://svnview.digium.com/svn/asterisk/team/kmoore/cel_transfers/include/asterisk/astobj2.h?view=diff&rev=394857&r1=394856&r2=394857
==============================================================================
--- team/kmoore/cel_transfers/include/asterisk/astobj2.h (original)
+++ team/kmoore/cel_transfers/include/asterisk/astobj2.h Sat Jul 20 07:42:06 2013
@@ -770,12 +770,12 @@
     OBJ_UNLINK - to remove the object, once found, from the container.
     OBJ_NODATA - don't return the object if found (no ref count change)
     OBJ_MULTIPLE - don't stop at first match
-    OBJ_POINTER - if set, 'arg' is an object pointer, and a hash table
+    OBJ_SEARCH_OBJECT - if set, 'arg' is an object pointer, and a hash table
                   search will be done. If not, a traversal is done.
-    OBJ_KEY - if set, 'arg', is a search key item that is not an object.
-              Similar to OBJ_POINTER and mutually exclusive.
-    OBJ_PARTIAL_KEY - if set, 'arg', is a partial search key item that is not an object.
-              Similar to OBJ_KEY and mutually exclusive.
+    OBJ_SEARCH_KEY - if set, 'arg', is a search key item that is not an object.
+              Similar to OBJ_SEARCH_OBJECT and mutually exclusive.
+    OBJ_SEARCH_PARTIAL_KEY - if set, 'arg', is a partial search key item that is not an object.
+              Similar to OBJ_SEARCH_KEY and mutually exclusive.
 
   -  \b ao2_callback(c, flags, fn, arg)
     apply fn(obj, arg) to all objects in the container.
@@ -786,13 +786,13 @@
          OBJ_UNLINK   - to remove the object, once found, from the container.
          OBJ_NODATA   - don't return the object if found (no ref count change)
          OBJ_MULTIPLE - don't stop at first match
-         OBJ_POINTER  - if set, 'arg' is an object pointer, and a hash table
+         OBJ_SEARCH_OBJECT - if set, 'arg' is an object pointer, and a hash table
                         search will be done. If not, a traversal is done through
                         all the hash table 'buckets'..
-         OBJ_KEY      - if set, 'arg', is a search key item that is not an object.
-                        Similar to OBJ_POINTER and mutually exclusive.
-         OBJ_PARTIAL_KEY - if set, 'arg', is a partial search key item that is not an object.
-                        Similar to OBJ_KEY and mutually exclusive.
+         OBJ_SEARCH_KEY - if set, 'arg', is a search key item that is not an object.
+                        Similar to OBJ_SEARCH_OBJECT and mutually exclusive.
+         OBJ_SEARCH_PARTIAL_KEY - if set, 'arg', is a partial search key item that is not an object.
+                        Similar to OBJ_SEARCH_KEY and mutually exclusive.
       - fn is a func that returns int, and takes 3 args:
         (void *obj, void *arg, int flags);
           obj is an object
@@ -859,11 +859,6 @@
 
 /*!
  * \brief Flags passed to ao2_callback_fn(), ao2_hash_fn(), and ao2_sort_fn() to modify behaviour.
- *
- * \todo XXX OBJ_POINTER, OBJ_KEY, and OBJ_PARTIAL_KEY need to
- * be put into a bit field like OBJ_ORDER_MASK since they are
- * mutually exclusive.  This change unfortunately is not
- * backwards compatible.
  */
 enum search_flags {
 	/*!
@@ -881,6 +876,59 @@
 	 * result of of the callback function has the CMP_STOP bit set.
 	 */
 	OBJ_MULTIPLE = (1 << 2),
+	/*!
+	 * \brief Continue if a match is not found.
+	 *
+	 * \details
+	 * This flag forces a whole container search.  The
+	 * OBJ_SEARCH_OBJECT, OBJ_SEARCH_KEY, and OBJ_SEARCH_PARTIAL_KEY
+	 * flags just specify where to start the search in the
+	 * container.  If the search is not stopped early then the
+	 * search _continues_ until the search wraps around to the
+	 * starting point.
+	 *
+	 * Normal searches start where the search key specifies to start
+	 * and end when the search key indicates that the object is not
+	 * in the container.
+	 *
+	 * For hash containers, this tells the ao2_callback() core to
+	 * keep searching through the rest of the buckets if a match is
+	 * not found in the starting bucket defined by the hash value on
+	 * the argument.
+	 *
+	 * For rbtree containers, if the search key is not in the
+	 * container, the search will start either at the first item
+	 * before the search key or the first item after the search key.
+	 *
+	 * \note The supplied ao2_callback_fn is called for every node
+	 * in the container from the starting point.
+	 */
+	OBJ_CONTINUE = (1 << 3),
+	/*!
+	 * \brief Assume that the ao2_container is already locked.
+	 *
+	 * \note For ao2_containers that have mutexes, no locking will
+	 * be done.
+	 *
+	 * \note For ao2_containers that have RWLOCKs, the lock will be
+	 * promoted to write mode as needed.  The lock will be returned
+	 * to the original locked state.
+	 *
+	 * \note Only use this flag if the ao2_container is manually
+	 * locked already.
+	 */
+	OBJ_NOLOCK = (1 << 4),
+
+	/*!
+	 * \brief Search option field mask.
+	 *
+	 * \todo Eventually OBJ_SEARCH_MASK will shrink to a two bit
+	 * field when the codebase is made to use the search field
+	 * values as a field instead of independent bits.
+	 */
+	OBJ_SEARCH_MASK = (0x07 << 5),
+	/*! \brief The arg parameter has no meaning to the astobj2 code. */
+	OBJ_SEARCH_NONE = (0 << 5),
 	/*!
 	 * \brief The arg parameter is an object of the same type.
 	 *
@@ -892,52 +940,8 @@
 	 * \note The supplied ao2_callback_fn is called after the
 	 * container nodes have been filtered by the ao2_hash_fn and/or
 	 * ao2_sort_fn functions.
-	 *
-	 * \note OBJ_POINTER, OBJ_KEY, and OBJ_PARTIAL_KEY are mutually
-	 * exclusive.
-	 */
-	OBJ_POINTER = (1 << 3),
-	/*!
-	 * \brief Continue if a match is not found.
-	 *
-	 * \details
-	 * This flag forces a whole container search.  The OBJ_POINTER,
-	 * OBJ_KEY, and OBJ_PARTIAL_KEY flags just specify where to
-	 * start the search in the container.  If the search is not
-	 * stopped early then the search _continues_ until the search
-	 * wraps around to the starting point.
-	 *
-	 * Normal searches start where the search key specifies to start
-	 * and end when the search key indicates that the object is not
-	 * in the container.
-	 *
-	 * For hash containers, this tells the ao2_callback() core to
-	 * keep searching through the rest of the buckets if a match is
-	 * not found in the starting bucket defined by the hash value on
-	 * the argument.
-	 *
-	 * For rbtree containers, if the search key is not in the
-	 * container, the search will start either at the first item
-	 * before the search key or the first item after the search key.
-	 *
-	 * \note The supplied ao2_callback_fn is called for every node
-	 * in the container from the starting point.
-	 */
-	OBJ_CONTINUE = (1 << 4),
-	/*!
-	 * \brief Assume that the ao2_container is already locked.
-	 *
-	 * \note For ao2_containers that have mutexes, no locking will
-	 * be done.
-	 *
-	 * \note For ao2_containers that have RWLOCKs, the lock will be
-	 * promoted to write mode as needed.  The lock will be returned
-	 * to the original locked state.
-	 *
-	 * \note Only use this flag if the ao2_container is manually
-	 * locked already.
-	 */
-	OBJ_NOLOCK = (1 << 5),
+	 */
+	OBJ_SEARCH_OBJECT = (1 << 5),
 	/*!
 	 * \brief The arg parameter is a search key, but is not an object.
 	 *
@@ -950,13 +954,10 @@
 	 * \note The supplied ao2_callback_fn is called after the
 	 * container nodes have been filtered by the ao2_hash_fn and/or
 	 * ao2_sort_fn functions.
-	 *
-	 * \note OBJ_POINTER, OBJ_KEY, and OBJ_PARTIAL_KEY are mutually
-	 * exclusive.
-	 */
-	OBJ_KEY = (1 << 6),
-	/*!
-	 * \brief The arg parameter is a partial search key similar to OBJ_KEY.
+	 */
+	OBJ_SEARCH_KEY = (2 << 5),
+	/*!
+	 * \brief The arg parameter is a partial search key similar to OBJ_SEARCH_KEY.
 	 *
 	 * \details
 	 * The partial key can be used by the ao2_sort_fn to guide the
@@ -968,11 +969,8 @@
 	 * \note The supplied ao2_callback_fn is called after the
 	 * container nodes have been filtered by the ao2_sort_fn
 	 * function.
-	 *
-	 * \note OBJ_POINTER, OBJ_KEY, and OBJ_PARTIAL_KEY are mutually
-	 * exclusive.
-	 */
-	OBJ_PARTIAL_KEY = (1 << 7),
+	 */
+	OBJ_SEARCH_PARTIAL_KEY = (4 << 5),
 
 	/*! \brief Traverse order option field mask. */
 	OBJ_ORDER_MASK = (0x03 << 8),
@@ -1000,6 +998,16 @@
 	OBJ_ORDER_POST = (3 << 8),
 };
 
+/*
+ * Deprecated backward compatible flag names.
+ *
+ * Note: OBJ_POINTER, OBJ_KEY, and OBJ_PARTIAL_KEY are mutually
+ * exclusive.
+ */
+#define OBJ_POINTER		OBJ_SEARCH_OBJECT		/*!< Deprecated name */
+#define OBJ_KEY			OBJ_SEARCH_KEY			/*!< Deprecated name */
+#define OBJ_PARTIAL_KEY	OBJ_SEARCH_PARTIAL_KEY	/*!< Deprecated name */
+
 /*!
  * \brief Options available when allocating an ao2 container object.
  *
@@ -1065,9 +1073,9 @@
  * \param obj  pointer to the (user-defined part) of an object.
  * \param arg callback argument from ao2_callback()
  * \param flags flags from ao2_callback()
- *   OBJ_POINTER - if set, 'arg', is an object.
- *   OBJ_KEY - if set, 'arg', is a search key item that is not an object.
- *   OBJ_PARTIAL_KEY - if set, 'arg', is a partial search key item that is not an object.
+ *   OBJ_SEARCH_OBJECT - if set, 'arg', is an object.
+ *   OBJ_SEARCH_KEY - if set, 'arg', is a search key item that is not an object.
+ *   OBJ_SEARCH_PARTIAL_KEY - if set, 'arg', is a partial search key item that is not an object.
  *
  * The return values are a combination of enum _cb_results.
  * Callback functions are used to search or manipulate objects in a container.
@@ -1083,9 +1091,9 @@
  * \param arg callback argument from ao2_callback()
  * \param data arbitrary data from ao2_callback()
  * \param flags flags from ao2_callback()
- *   OBJ_POINTER - if set, 'arg', is an object.
- *   OBJ_KEY - if set, 'arg', is a search key item that is not an object.
- *   OBJ_PARTIAL_KEY - if set, 'arg', is a partial search key item that is not an object.
+ *   OBJ_SEARCH_OBJECT - if set, 'arg', is an object.
+ *   OBJ_SEARCH_KEY - if set, 'arg', is a search key item that is not an object.
+ *   OBJ_SEARCH_PARTIAL_KEY - if set, 'arg', is a partial search key item that is not an object.
  *
  * The return values are a combination of enum _cb_results.
  * Callback functions are used to search or manipulate objects in a container.
@@ -1097,8 +1105,8 @@
  *
  * \param obj pointer to the (user-defined part) of an object.
  * \param flags flags from ao2_callback()
- *   OBJ_POINTER - if set, 'obj', is an object.
- *   OBJ_KEY - if set, 'obj', is a search key item that is not an object.
+ *   OBJ_SEARCH_OBJECT - if set, 'obj', is an object.
+ *   OBJ_SEARCH_KEY - if set, 'obj', is a search key item that is not an object.
  *
  * \return Computed hash value.
  */
@@ -1110,9 +1118,9 @@
  * \param obj_left pointer to the (user-defined part) of an object.
  * \param obj_right pointer to the (user-defined part) of an object.
  * \param flags flags from ao2_callback()
- *   OBJ_POINTER - if set, 'obj_right', is an object.
- *   OBJ_KEY - if set, 'obj_right', is a search key item that is not an object.

[... 4209 lines stripped ...]



More information about the svn-commits mailing list