[asterisk-commits] dlee: branch dlee/ASTERISK-22243 r396335 - in /team/dlee/ASTERISK-22243: ./ a...

SVN commits to the Asterisk project asterisk-commits at lists.digium.com
Tue Aug 6 09:48:14 CDT 2013


Author: dlee
Date: Tue Aug  6 09:48:12 2013
New Revision: 396335

URL: http://svnview.digium.com/svn/asterisk?view=rev&rev=396335
Log:
Merged revisions 396175-396331 from http://svn.asterisk.org/svn/asterisk/trunk

Added:
    team/dlee/ASTERISK-22243/res/parking/parking_tests.c
      - copied unchanged from r396331, trunk/res/parking/parking_tests.c
Modified:
    team/dlee/ASTERISK-22243/   (props changed)
    team/dlee/ASTERISK-22243/UPGRADE-11.txt
    team/dlee/ASTERISK-22243/apps/app_minivm.c
    team/dlee/ASTERISK-22243/apps/app_playback.c
    team/dlee/ASTERISK-22243/apps/app_stack.c
    team/dlee/ASTERISK-22243/apps/app_voicemail.c
    team/dlee/ASTERISK-22243/bridges/bridge_holding.c
    team/dlee/ASTERISK-22243/channels/chan_sip.c
    team/dlee/ASTERISK-22243/funcs/func_frame_trace.c
    team/dlee/ASTERISK-22243/funcs/func_global.c
    team/dlee/ASTERISK-22243/funcs/func_strings.c
    team/dlee/ASTERISK-22243/include/asterisk/app.h
    team/dlee/ASTERISK-22243/include/asterisk/bridge_basic.h
    team/dlee/ASTERISK-22243/include/asterisk/bridge_roles.h
    team/dlee/ASTERISK-22243/include/asterisk/frame.h
    team/dlee/ASTERISK-22243/include/asterisk/stasis.h
    team/dlee/ASTERISK-22243/include/asterisk/stasis_app.h
    team/dlee/ASTERISK-22243/include/asterisk/stasis_app_recording.h
    team/dlee/ASTERISK-22243/main/app.c
    team/dlee/ASTERISK-22243/main/bridge_basic.c
    team/dlee/ASTERISK-22243/main/bridge_roles.c
    team/dlee/ASTERISK-22243/main/cdr.c
    team/dlee/ASTERISK-22243/main/channel.c
    team/dlee/ASTERISK-22243/main/features.c
    team/dlee/ASTERISK-22243/main/pbx.c
    team/dlee/ASTERISK-22243/main/stasis_cache.c
    team/dlee/ASTERISK-22243/main/stasis_cache_pattern.c
    team/dlee/ASTERISK-22243/pbx/pbx_dundi.c
    team/dlee/ASTERISK-22243/pbx/pbx_loopback.c
    team/dlee/ASTERISK-22243/res/ari/resource_bridges.c
    team/dlee/ASTERISK-22243/res/ari/resource_bridges.h
    team/dlee/ASTERISK-22243/res/ari/resource_recordings.c
    team/dlee/ASTERISK-22243/res/ari/resource_recordings.h
    team/dlee/ASTERISK-22243/res/parking/parking_bridge.c
    team/dlee/ASTERISK-22243/res/parking/res_parking.h
    team/dlee/ASTERISK-22243/res/res_ari_bridges.c
    team/dlee/ASTERISK-22243/res/res_ari_recordings.c
    team/dlee/ASTERISK-22243/res/res_parking.c
    team/dlee/ASTERISK-22243/res/res_pjsip.c
    team/dlee/ASTERISK-22243/res/res_pjsip/config_system.c
    team/dlee/ASTERISK-22243/res/res_pjsip/include/res_pjsip_private.h
    team/dlee/ASTERISK-22243/res/res_pjsip_exten_state.c
    team/dlee/ASTERISK-22243/res/res_pjsip_messaging.c
    team/dlee/ASTERISK-22243/res/res_pjsip_notify.c
    team/dlee/ASTERISK-22243/res/res_pjsip_outbound_registration.c
    team/dlee/ASTERISK-22243/res/res_stasis_recording.c
    team/dlee/ASTERISK-22243/res/stasis/control.c
    team/dlee/ASTERISK-22243/rest-api/api-docs/bridges.json
    team/dlee/ASTERISK-22243/rest-api/api-docs/recordings.json
    team/dlee/ASTERISK-22243/tests/test_stasis.c
    team/dlee/ASTERISK-22243/utils/extconf.c

Propchange: team/dlee/ASTERISK-22243/
------------------------------------------------------------------------------
Binary property 'branch-11-merged' - no diff available.

Propchange: team/dlee/ASTERISK-22243/
------------------------------------------------------------------------------
--- svnmerge-integrated (original)
+++ svnmerge-integrated Tue Aug  6 09:48:12 2013
@@ -1,1 +1,1 @@
-/trunk:1-396167
+/trunk:1-396334

Modified: team/dlee/ASTERISK-22243/UPGRADE-11.txt
URL: http://svnview.digium.com/svn/asterisk/team/dlee/ASTERISK-22243/UPGRADE-11.txt?view=diff&rev=396335&r1=396334&r2=396335
==============================================================================
--- team/dlee/ASTERISK-22243/UPGRADE-11.txt (original)
+++ team/dlee/ASTERISK-22243/UPGRADE-11.txt Tue Aug  6 09:48:12 2013
@@ -19,6 +19,11 @@
 === UPGRADE-10.txt -- Upgrade info for 1.8 to 10
 ===
 ===========================================================
+From 11.5 to 11.6:
+* res_agi will now properly indicate if there was an error in streaming an
+  audio file.  The result code will be -1 and the result returned from the
+  the function will be RESULT_FAILURE instead of the prior behavior of always
+  returning RESULT_SUCCESS even if there was an error.
 
 From 11.4 to 11.5:
 * The default settings for chan_sip are now overriden properly by the general

Modified: team/dlee/ASTERISK-22243/apps/app_minivm.c
URL: http://svnview.digium.com/svn/asterisk/team/dlee/ASTERISK-22243/apps/app_minivm.c?view=diff&rev=396335&r1=396334&r2=396335
==============================================================================
--- team/dlee/ASTERISK-22243/apps/app_minivm.c (original)
+++ team/dlee/ASTERISK-22243/apps/app_minivm.c Tue Aug  6 09:48:12 2013
@@ -1674,7 +1674,7 @@
 				ast_channel_setoption(chan, AST_OPTION_RXGAIN, &record_gain, sizeof(record_gain), 0);
 			if (ast_test_flag(vmu, MVM_OPERATOR))
 				canceldtmf = "0";
-			cmd = ast_play_and_record_full(chan, playfile, recordfile, maxtime, fmt, duration, sound_duration, global_silencethreshold, global_maxsilence, unlockdir, acceptdtmf, canceldtmf, 0, AST_RECORD_IF_EXISTS_OVERWRITE);
+			cmd = ast_play_and_record_full(chan, playfile, recordfile, maxtime, fmt, duration, sound_duration, 0, global_silencethreshold, global_maxsilence, unlockdir, acceptdtmf, canceldtmf, 0, AST_RECORD_IF_EXISTS_OVERWRITE);
 			if (record_gain)
 				ast_channel_setoption(chan, AST_OPTION_RXGAIN, &zero_gain, sizeof(zero_gain), 0);
 			if (cmd == -1) /* User has hung up, no options to give */

Modified: team/dlee/ASTERISK-22243/apps/app_playback.c
URL: http://svnview.digium.com/svn/asterisk/team/dlee/ASTERISK-22243/apps/app_playback.c?view=diff&rev=396335&r1=396334&r2=396335
==============================================================================
--- team/dlee/ASTERISK-22243/apps/app_playback.c (original)
+++ team/dlee/ASTERISK-22243/apps/app_playback.c Tue Aug  6 09:48:12 2013
@@ -220,6 +220,10 @@
 		s = x + 1;
 	ast_debug(2, "value is <%s>\n", s);
 	n = ast_var_assign("SAY", s);
+	if (!n) {
+		ast_log(LOG_ERROR, "Memory allocation error in do_say\n");
+		return -1;
+	}
 	AST_LIST_INSERT_HEAD(&head, n, entries);
 
 	/* scan the body, one piece at a time */

Modified: team/dlee/ASTERISK-22243/apps/app_stack.c
URL: http://svnview.digium.com/svn/asterisk/team/dlee/ASTERISK-22243/apps/app_stack.c?view=diff&rev=396335&r1=396334&r2=396335
==============================================================================
--- team/dlee/ASTERISK-22243/apps/app_stack.c (original)
+++ team/dlee/ASTERISK-22243/apps/app_stack.c Tue Aug  6 09:48:12 2013
@@ -273,8 +273,9 @@
 	}
 
 	if (!found) {
-		variables = ast_var_assign(var, "");
-		AST_LIST_INSERT_HEAD(&frame->varshead, variables, entries);
+		if ((variables = ast_var_assign(var, ""))) {
+			AST_LIST_INSERT_HEAD(&frame->varshead, variables, entries);
+		}
 		pbx_builtin_pushvar_helper(chan, var, value);
 	} else {
 		pbx_builtin_setvar_helper(chan, var, value);

Modified: team/dlee/ASTERISK-22243/apps/app_voicemail.c
URL: http://svnview.digium.com/svn/asterisk/team/dlee/ASTERISK-22243/apps/app_voicemail.c?view=diff&rev=396335&r1=396334&r2=396335
==============================================================================
--- team/dlee/ASTERISK-22243/apps/app_voicemail.c (original)
+++ team/dlee/ASTERISK-22243/apps/app_voicemail.c Tue Aug  6 09:48:12 2013
@@ -14682,7 +14682,7 @@
 				ast_channel_setoption(chan, AST_OPTION_RXGAIN, &record_gain, sizeof(record_gain), 0);
 			if (ast_test_flag(vmu, VM_OPERATOR))
 				canceldtmf = "0";
-			cmd = ast_play_and_record_full(chan, playfile, tempfile, maxtime, fmt, duration, sound_duration, silencethreshold, maxsilence, unlockdir, acceptdtmf, canceldtmf, 0, AST_RECORD_IF_EXISTS_OVERWRITE);
+			cmd = ast_play_and_record_full(chan, playfile, tempfile, maxtime, fmt, duration, sound_duration, 0, silencethreshold, maxsilence, unlockdir, acceptdtmf, canceldtmf, 0, AST_RECORD_IF_EXISTS_OVERWRITE);
 			if (strchr(canceldtmf, cmd)) {
 			/* need this flag here to distinguish between pressing '0' during message recording or after */
 				canceleddtmf = 1;

Modified: team/dlee/ASTERISK-22243/bridges/bridge_holding.c
URL: http://svnview.digium.com/svn/asterisk/team/dlee/ASTERISK-22243/bridges/bridge_holding.c?view=diff&rev=396335&r1=396334&r2=396335
==============================================================================
--- team/dlee/ASTERISK-22243/bridges/bridge_holding.c (original)
+++ team/dlee/ASTERISK-22243/bridges/bridge_holding.c Tue Aug  6 09:48:12 2013
@@ -81,7 +81,7 @@
 		ast_moh_stop(bridge_channel->chan);
 		break;
 	case IDLE_MODE_RINGING:
-		ast_indicate(bridge_channel->chan, -1);
+		ast_bridge_channel_queue_control_data(bridge_channel, -1, NULL, 0);
 		break;
 	case IDLE_MODE_NONE:
 		break;
@@ -124,7 +124,7 @@
 		ast_moh_start(bridge_channel->chan, ast_strlen_zero(moh_class) ? NULL : moh_class, NULL);
 		break;
 	case IDLE_MODE_RINGING:
-		ast_indicate(bridge_channel->chan, AST_CONTROL_RINGING);
+		ast_bridge_channel_queue_control_data(bridge_channel, AST_CONTROL_RINGING, NULL, 0);
 		break;
 	case IDLE_MODE_NONE:
 		break;
@@ -302,6 +302,44 @@
 	return 0;
 }
 
+static void holding_bridge_suspend(struct ast_bridge *bridge, struct ast_bridge_channel *bridge_channel)
+{
+	struct holding_channel *hc = bridge_channel ? bridge_channel->tech_pvt : NULL;
+
+	if (!hc) {
+		return;
+	}
+
+	if (!ast_test_flag(&hc->holding_roles, HOLDING_ROLE_PARTICIPANT)) {
+		return;
+	}
+
+	participant_stop_hold_audio(bridge_channel);
+}
+
+static void holding_bridge_unsuspend(struct ast_bridge *bridge, struct ast_bridge_channel *bridge_channel)
+{
+	struct holding_channel *hc = bridge_channel ? bridge_channel->tech_pvt : NULL;
+	struct ast_bridge_channel *announcer_channel = bridge->tech_pvt;
+
+	if (!hc) {
+		return;
+	}
+
+	/* If the bridge channel being unsuspended is not a participant, no need to do anything. */
+	if (!ast_test_flag(&hc->holding_roles, HOLDING_ROLE_PARTICIPANT)) {
+		return;
+	}
+
+	/* If there is currently an announcer channel in the bridge, there is also no need to do anything. */
+	if (announcer_channel) {
+		return;
+	}
+
+	/* Otherwise we need to resume the entertainment. */
+	participant_start_hold_audio(bridge_channel);
+}
+
 static struct ast_bridge_technology holding_bridge = {
 	.name = "holding_bridge",
 	.capabilities = AST_BRIDGE_CAPABILITY_HOLDING,
@@ -309,6 +347,8 @@
 	.write = holding_bridge_write,
 	.join = holding_bridge_join,
 	.leave = holding_bridge_leave,
+	.suspend = holding_bridge_suspend,
+	.unsuspend = holding_bridge_unsuspend,
 };
 
 static int unload_module(void)

Modified: team/dlee/ASTERISK-22243/channels/chan_sip.c
URL: http://svnview.digium.com/svn/asterisk/team/dlee/ASTERISK-22243/channels/chan_sip.c?view=diff&rev=396335&r1=396334&r2=396335
==============================================================================
--- team/dlee/ASTERISK-22243/channels/chan_sip.c (original)
+++ team/dlee/ASTERISK-22243/channels/chan_sip.c Tue Aug  6 09:48:12 2013
@@ -15272,6 +15272,8 @@
 			append_history(p, "RegistryInit", "Account: %s@%s", r->username, r->hostname);
 		}
 
+		p->socket.type = r->transport;
+
 		/* Use port number specified if no SRV record was found */
 		if (!ast_sockaddr_isnull(&r->us)) {
 			if (!ast_sockaddr_port(&r->us) && r->portno) {

Modified: team/dlee/ASTERISK-22243/funcs/func_frame_trace.c
URL: http://svnview.digium.com/svn/asterisk/team/dlee/ASTERISK-22243/funcs/func_frame_trace.c?view=diff&rev=396335&r1=396334&r2=396335
==============================================================================
--- team/dlee/ASTERISK-22243/funcs/func_frame_trace.c (original)
+++ team/dlee/ASTERISK-22243/funcs/func_frame_trace.c Tue Aug  6 09:48:12 2013
@@ -343,6 +343,18 @@
 		case AST_CONTROL_STREAM_FORWARD:
 			ast_verbose("SubClass: STREAM_FORWARD\n");
 			break;
+		case AST_CONTROL_RECORD_CANCEL:
+			ast_verbose("SubClass: RECORD_CANCEL\n");
+			break;
+		case AST_CONTROL_RECORD_STOP:
+			ast_verbose("SubClass: RECORD_STOP\n");
+			break;
+		case AST_CONTROL_RECORD_SUSPEND:
+			ast_verbose("SubClass: RECORD_SUSPEND\n");
+			break;
+		case AST_CONTROL_RECORD_MUTE:
+			ast_verbose("SubClass: RECORD_MUTE\n");
+			break;
 		}
 
 		if (frame->subclass.integer == -1) {

Modified: team/dlee/ASTERISK-22243/funcs/func_global.c
URL: http://svnview.digium.com/svn/asterisk/team/dlee/ASTERISK-22243/funcs/func_global.c?view=diff&rev=396335&r1=396334&r2=396335
==============================================================================
--- team/dlee/ASTERISK-22243/funcs/func_global.c (original)
+++ team/dlee/ASTERISK-22243/funcs/func_global.c Tue Aug  6 09:48:12 2013
@@ -282,11 +282,12 @@
 	}
 	AST_LIST_TRAVERSE_SAFE_END;
 
-	var = ast_var_assign(args.var, S_OR(value, ""));
-	AST_LIST_INSERT_HEAD(varshead, var, entries);
-
-	sprintf(shared_buffer, "SHARED(%s)", args.var);
-	ast_channel_publish_varset(chan, shared_buffer, value);
+	if ((var = ast_var_assign(args.var, S_OR(value, "")))) {
+		AST_LIST_INSERT_HEAD(varshead, var, entries);
+
+		sprintf(shared_buffer, "SHARED(%s)", args.var);
+		ast_channel_publish_varset(chan, shared_buffer, value);
+	}
 
 	ast_channel_unlock(chan);
 

Modified: team/dlee/ASTERISK-22243/funcs/func_strings.c
URL: http://svnview.digium.com/svn/asterisk/team/dlee/ASTERISK-22243/funcs/func_strings.c?view=diff&rev=396335&r1=396334&r2=396335
==============================================================================
--- team/dlee/ASTERISK-22243/funcs/func_strings.c (original)
+++ team/dlee/ASTERISK-22243/funcs/func_strings.c Tue Aug  6 09:48:12 2013
@@ -1698,6 +1698,12 @@
 
 	for (i = 0; i < ARRAY_LEN(test_args); i++) {
 		struct ast_var_t *var = ast_var_assign("FIELDS", test_args[i].fields);
+		if (!var) {
+			ast_test_status_update(test, "Out of memory\n");
+			res = AST_TEST_FAIL;
+			break;
+		}
+
 		AST_LIST_INSERT_HEAD(ast_channel_varshead(chan), var, entries);
 
 		snprintf(expression, sizeof(expression), "${FIELDNUM(%s,%s,%s)}", var->name, test_args[i].delim, test_args[i].field);
@@ -1800,6 +1806,13 @@
 		char tmp[512], tmp2[512] = "";
 
 		struct ast_var_t *var = ast_var_assign("test_string", test_strings[i][0]);
+		if (!var) {
+			ast_test_status_update(test, "Unable to allocate variable\n");
+			ast_free(str);
+			ast_channel_release(chan);
+			return AST_TEST_FAIL;
+		}
+			
 		AST_LIST_INSERT_HEAD(ast_channel_varshead(chan), var, entries);
 
 		if (test_strings[i][3]) {

Modified: team/dlee/ASTERISK-22243/include/asterisk/app.h
URL: http://svnview.digium.com/svn/asterisk/team/dlee/ASTERISK-22243/include/asterisk/app.h?view=diff&rev=396335&r1=396334&r2=396335
==============================================================================
--- team/dlee/ASTERISK-22243/include/asterisk/app.h (original)
+++ team/dlee/ASTERISK-22243/include/asterisk/app.h Tue Aug  6 09:48:12 2013
@@ -709,11 +709,12 @@
  *        skip_confirmation_sound is false.
  *
  * \param chan the channel being recorded
- * \param playfile Filename of sound to play before recording begins
+ * \param playfile Filename of sound to play before recording begins. A beep is also played when playfile completes, before the recording begins.
  * \param recordfile Filename to save the recording
  * \param maxtime_sec Longest possible message length in seconds
  * \param fmt string containing all formats to be recorded delimited by '|'
  * \param duration pointer to integer for storing length of the recording
+ * \param beep If true, play a beep before recording begins (and doesn't play \a playfile)
  * \param sound_duration pointer to integer for storing length of the recording minus all silence
  * \param silencethreshold tolerance of noise levels that can be considered silence for the purpose of silence timeout, -1 for default
  * \param maxsilence_ms Length of time in milliseconds which will trigger a timeout from silence, -1 for default
@@ -728,7 +729,7 @@
  * \retval 't' Recording ended from the message exceeding the maximum duration
  * \retval dtmfchar Recording ended via the return value's DTMF character for either cancel or accept.
  */
-int ast_play_and_record_full(struct ast_channel *chan, const char *playfile, const char *recordfile, int maxtime_sec, const char *fmt, int *duration, int *sound_duration, int silencethreshold, int maxsilence_ms, const char *path, const char *acceptdtmf, const char *canceldtmf, int skip_confirmation_sound, enum ast_record_if_exists if_exists);
+int ast_play_and_record_full(struct ast_channel *chan, const char *playfile, const char *recordfile, int maxtime_sec, const char *fmt, int *duration, int *sound_duration, int beep, int silencethreshold, int maxsilence_ms, const char *path, const char *acceptdtmf, const char *canceldtmf, int skip_confirmation_sound, enum ast_record_if_exists if_exists);
 
 /*!
  * \brief Record a file based on input from a channel. Use default accept and cancel DTMF.

Modified: team/dlee/ASTERISK-22243/include/asterisk/bridge_basic.h
URL: http://svnview.digium.com/svn/asterisk/team/dlee/ASTERISK-22243/include/asterisk/bridge_basic.h?view=diff&rev=396335&r1=396334&r2=396335
==============================================================================
--- team/dlee/ASTERISK-22243/include/asterisk/bridge_basic.h (original)
+++ team/dlee/ASTERISK-22243/include/asterisk/bridge_basic.h Tue Aug  6 09:48:12 2013
@@ -89,6 +89,22 @@
 int ast_bridge_features_ds_set(struct ast_channel *chan, struct ast_flags *flags);
 
 /*!
+ * \brief Append basic bridge DTMF feature flags on the channel.
+ * \since 12.0.0
+ *
+ * \param chan Channel to append DTMF features datastore.
+ * \param flags Builtin DTMF feature flags. (ast_bridge_config flags)
+ *
+ * \note The channel must be locked before calling this function.
+ * \note This function differs from ast_bridge_features_ds_set only in that it won't
+ *       remove features already set on the channel.
+ *
+ * \retval 0 on success.
+ * \retval -1 on error.
+ */
+int ast_bridge_features_ds_append(struct ast_channel *chan, struct ast_flags *flags);
+
+/*!
  * \brief Setup DTMF feature hooks using the channel features datastore property.
  * \since 12.0.0
  *

Modified: team/dlee/ASTERISK-22243/include/asterisk/bridge_roles.h
URL: http://svnview.digium.com/svn/asterisk/team/dlee/ASTERISK-22243/include/asterisk/bridge_roles.h?view=diff&rev=396335&r1=396334&r2=396335
==============================================================================
--- team/dlee/ASTERISK-22243/include/asterisk/bridge_roles.h (original)
+++ team/dlee/ASTERISK-22243/include/asterisk/bridge_roles.h Tue Aug  6 09:48:12 2013
@@ -50,6 +50,13 @@
  * \param role_name Name of the role being removed
  */
 void ast_channel_remove_bridge_role(struct ast_channel *chan, const char *role_name);
+
+/*!
+ * \brief Removes all bridge roles currently on a channel
+ *
+ * \param chan Channel the roles are being removed from
+ */
+void ast_channel_clear_bridge_roles(struct ast_channel *chan);
 
 /*!
  * \brief Set a role option on a channel

Modified: team/dlee/ASTERISK-22243/include/asterisk/frame.h
URL: http://svnview.digium.com/svn/asterisk/team/dlee/ASTERISK-22243/include/asterisk/frame.h?view=diff&rev=396335&r1=396334&r2=396335
==============================================================================
--- team/dlee/ASTERISK-22243/include/asterisk/frame.h (original)
+++ team/dlee/ASTERISK-22243/include/asterisk/frame.h Tue Aug  6 09:48:12 2013
@@ -278,7 +278,11 @@
 	AST_CONTROL_STREAM_RESTART = 1002,	/*!< Indicate to a channel in playback to restart the stream */
 	AST_CONTROL_STREAM_REVERSE = 1003,	/*!< Indicate to a channel in playback to rewind */
 	AST_CONTROL_STREAM_FORWARD = 1004,	/*!< Indicate to a channel in playback to fast forward */
-
+	/* Control frames to manipulate recording on a channel. */
+	AST_CONTROL_RECORD_CANCEL = 1100,	/*!< Indicated to a channel in record to stop recording and discard the file */
+	AST_CONTROL_RECORD_STOP = 1101,	/*!< Indicated to a channel in record to stop recording */
+	AST_CONTROL_RECORD_SUSPEND = 1102,	/*!< Indicated to a channel in record to suspend/unsuspend recording */
+	AST_CONTROL_RECORD_MUTE = 1103,	/*!< Indicated to a channel in record to mute/unmute (i.e. write silence) recording */
 };
 
 enum ast_frame_read_action {

Modified: team/dlee/ASTERISK-22243/include/asterisk/stasis.h
URL: http://svnview.digium.com/svn/asterisk/team/dlee/ASTERISK-22243/include/asterisk/stasis.h?view=diff&rev=396335&r1=396334&r2=396335
==============================================================================
--- team/dlee/ASTERISK-22243/include/asterisk/stasis.h (original)
+++ team/dlee/ASTERISK-22243/include/asterisk/stasis.h Tue Aug  6 09:48:12 2013
@@ -110,12 +110,12 @@
  * It's a thread safe container, so freely use the stasis_cache_get() and
  * stasis_cache_dump() to query the cache.
  *
- * The \ref stasis_caching_topic provides a topic that forwards non-cacheable
- * messages unchanged. A cacheable message is wrapped in a \ref
- * stasis_cache_update message which provides the old snapshot (or \c NULL if
- * this is a new cache entry), and the new snapshot (or \c NULL if the entry was
- * removed from the cache). A stasis_cache_clear_create() message must be sent
- * to the topic in order to remove entries from the cache.
+ * The \ref stasis_caching_topic discards non-cacheable messages. A cacheable
+ * message is wrapped in a \ref stasis_cache_update message which provides the
+ * old snapshot (or \c NULL if this is a new cache entry), and the new snapshot
+ * (or \c NULL if the entry was removed from the cache). A
+ * stasis_cache_clear_create() message must be sent to the topic in order to
+ * remove entries from the cache.
  *
  * In order to unsubscribe a \ref stasis_caching_topic from the upstream topic,
  * call stasis_caching_unsubscribe(). Due to cyclic references, the \ref

Modified: team/dlee/ASTERISK-22243/include/asterisk/stasis_app.h
URL: http://svnview.digium.com/svn/asterisk/team/dlee/ASTERISK-22243/include/asterisk/stasis_app.h?view=diff&rev=396335&r1=396334&r2=396335
==============================================================================
--- team/dlee/ASTERISK-22243/include/asterisk/stasis_app.h (original)
+++ team/dlee/ASTERISK-22243/include/asterisk/stasis_app.h Tue Aug  6 09:48:12 2013
@@ -174,6 +174,24 @@
 int stasis_app_control_dial(struct stasis_app_control *control, const char *endpoint, int timeout);
 
 /*!
+ * \brief Apply a bridge role to a channel controlled by a stasis app control
+ *
+ * \param control Control for \c res_stasis
+ * \param role Role to apply
+ *
+ * \return 0 for success
+ * \return -1 for error.
+ */
+int stasis_app_control_add_role(struct stasis_app_control *control, const char *role);
+
+/*!
+ * \brief Clear bridge roles currently applied to a channel controlled by a stasis app control
+ *
+ * \param control Control for \c res_stasis
+ */
+void stasis_app_control_clear_roles(struct stasis_app_control *control);
+
+/*!
  * \brief Exit \c res_stasis and continue execution in the dialplan.
  *
  * If the channel is no longer in \c res_stasis, this function does nothing.

Modified: team/dlee/ASTERISK-22243/include/asterisk/stasis_app_recording.h
URL: http://svnview.digium.com/svn/asterisk/team/dlee/ASTERISK-22243/include/asterisk/stasis_app_recording.h?view=diff&rev=396335&r1=396334&r2=396335
==============================================================================
--- team/dlee/ASTERISK-22243/include/asterisk/stasis_app_recording.h (original)
+++ team/dlee/ASTERISK-22243/include/asterisk/stasis_app_recording.h Tue Aug  6 09:48:12 2013
@@ -44,14 +44,30 @@
 	STASIS_APP_RECORDING_STATE_PAUSED,
 	/*! The media has stopped recording */
 	STASIS_APP_RECORDING_STATE_COMPLETE,
-	/*! The media has stopped playing */
+	/*! The media has stopped recording, with error */
 	STASIS_APP_RECORDING_STATE_FAILED,
+	/*! The media has stopped recording, discard the recording file */
+	STASIS_APP_RECORDING_STATE_CANCELED,
+	/*! Sentinel */
+	STASIS_APP_RECORDING_STATE_MAX,
 };
 
 /*! Valid operation for controlling a recording. */
 enum stasis_app_recording_media_operation {
-	/*! Stop the recording operation. */
+	/*! Stop the recording, deleting the media file(s) */
+	STASIS_APP_RECORDING_CANCEL,
+	/*! Stop the recording. */
 	STASIS_APP_RECORDING_STOP,
+	/*! Pause the recording */
+	STASIS_APP_RECORDING_PAUSE,
+	/*! Unpause the recording */
+	STASIS_APP_RECORDING_UNPAUSE,
+	/*! Mute the recording (record silence) */
+	STASIS_APP_RECORDING_MUTE,
+	/*! Unmute the recording */
+	STASIS_APP_RECORDING_UNMUTE,
+	/*! Sentinel */
+	STASIS_APP_RECORDING_OPER_MAX,
 };
 
 #define STASIS_APP_RECORDING_TERMINATE_INVALID 0

Modified: team/dlee/ASTERISK-22243/main/app.c
URL: http://svnview.digium.com/svn/asterisk/team/dlee/ASTERISK-22243/main/app.c?view=diff&rev=396335&r1=396334&r2=396335
==============================================================================
--- team/dlee/ASTERISK-22243/main/app.c (original)
+++ team/dlee/ASTERISK-22243/main/app.c Tue Aug  6 09:48:12 2013
@@ -1145,6 +1145,78 @@
 	return d;
 }
 
+/*!
+ * \brief Construct a silence frame of the same duration as \a orig.
+ *
+ * The \a orig frame must be \ref AST_FORMAT_SLINEAR.
+ *
+ * \param orig Frame as basis for silence to generate.
+ * \return New frame of silence; free with ast_frfree().
+ * \return \c NULL on error.
+ */
+static struct ast_frame *make_silence(const struct ast_frame *orig)
+{
+	struct ast_frame *silence;
+	size_t size;
+	size_t datalen;
+	size_t samples = 0;
+	struct ast_frame *next;
+
+	if (!orig) {
+		return NULL;
+	}
+
+	if (orig->subclass.format.id != AST_FORMAT_SLINEAR) {
+		ast_log(LOG_WARNING, "Attempting to silence non-slin frame\n");
+		return NULL;
+	}
+
+	for (next = AST_LIST_NEXT(orig, frame_list);
+		 orig;
+		 orig = next, next = orig ? AST_LIST_NEXT(orig, frame_list) : NULL) {
+		samples += orig->samples;
+	}
+
+	ast_verb(4, "Silencing %zd samples\n", samples);
+
+
+	datalen = sizeof(short) * samples;
+	size = sizeof(*silence) + datalen;
+	silence = ast_calloc(1, size);
+	if (!silence) {
+		return NULL;
+	}
+
+	silence->mallocd = AST_MALLOCD_HDR;
+	silence->frametype = AST_FRAME_VOICE;
+	silence->data.ptr = (void *)(silence + 1);
+	silence->samples = samples;
+	silence->datalen = datalen;
+
+	ast_format_set(&silence->subclass.format, AST_FORMAT_SLINEAR, 0);
+
+	return silence;
+}
+
+/*!
+ * \brief Sets a channel's read format to \ref AST_FORMAT_SLINEAR, recording
+ * its original format.
+ *
+ * \param chan Channel to modify.
+ * \param[out] orig_format Output variable to store channel's original read
+ *                         format.
+ * \return 0 on success.
+ * \return -1 on error.
+ */
+static int set_read_to_slin(struct ast_channel *chan, struct ast_format *orig_format)
+{
+	if (!chan || !orig_format) {
+		return -1;
+	}
+	ast_format_copy(orig_format, ast_channel_readformat(chan));
+	return ast_set_read_format_by_id(chan, AST_FORMAT_SLINEAR);
+}
+
 static int global_silence_threshold = 128;
 static int global_maxsilence = 0;
 
@@ -1274,8 +1346,7 @@
 			return -1;
 		}
 		ast_dsp_set_threshold(sildet, silencethreshold);
-		ast_format_copy(&rfmt, ast_channel_readformat(chan));
-		res = ast_set_read_format_by_id(chan, AST_FORMAT_SLINEAR);
+		res = set_read_to_slin(chan, &rfmt);
 		if (res < 0) {
 			ast_log(LOG_WARNING, "Unable to set to linear mode, giving up\n");
 			ast_dsp_free(sildet);
@@ -1293,9 +1364,15 @@
 	}
 
 	if (x == fmtcnt) {
-		/* Loop forever, writing the packets we read to the writer(s), until
-		   we read a digit or get a hangup */
+		/* Loop, writing the packets we read to the writer(s), until
+		 * we have reason to stop. */
 		struct ast_frame *f;
+		int paused = 0;
+		int muted = 0;
+		time_t pause_start = 0;
+		int paused_secs = 0;
+		int pausedsilence = 0;
+
 		for (;;) {
 			if (!(res = ast_waitfor(chan, 2000))) {
 				ast_debug(1, "One waitfor failed, trying another\n");
@@ -1315,11 +1392,29 @@
 			}
 			if (f->frametype == AST_FRAME_VOICE) {
 				/* write each format */
-				for (x = 0; x < fmtcnt; x++) {
-					if (prepend && !others[x]) {
-						break;
+				if (paused) {
+					/* It's all good */
+					res = 0;
+				} else {
+					RAII_VAR(struct ast_frame *, silence, NULL, ast_frame_dtor);
+					struct ast_frame *orig = f;
+
+					if (muted) {
+						silence = make_silence(orig);
+						if (!silence) {
+							ast_log(LOG_WARNING,
+								"Error creating silence\n");
+							break;
+						}
+						f = silence;
 					}
-					res = ast_writestream(others[x], f);
+					for (x = 0; x < fmtcnt; x++) {
+						if (prepend && !others[x]) {
+							break;
+						}
+						res = ast_writestream(others[x], f);
+					}
+					f = orig;
 				}
 
 				/* Silence Detection */
@@ -1330,6 +1425,17 @@
 						totalsilence += olddspsilence;
 					}
 					olddspsilence = dspsilence;
+
+					if (paused) {
+						/* record how much silence there was while we are paused */
+						pausedsilence = dspsilence;
+					} else if (dspsilence > pausedsilence) {
+						/* ignore the paused silence */
+						dspsilence -= pausedsilence;
+					} else {
+						/* dspsilence has reset, reset pausedsilence */
+						pausedsilence = 0;
+					}
 
 					if (dspsilence > maxsilence) {
 						/* Ended happily with silence */
@@ -1362,15 +1468,51 @@
 					break;
 				}
 				if (strchr(canceldtmf, f->subclass.integer)) {
-					ast_verb(3, "User cancelled message by pressing %c\n", f->subclass.integer);
+					ast_verb(3, "User canceled message by pressing %c\n", f->subclass.integer);
 					res = f->subclass.integer;
 					outmsg = 0;
 					break;
 				}
-			}
-			if (maxtime) {
+			} else if (f->frametype == AST_FRAME_CONTROL) {
+				if (f->subclass.integer == AST_CONTROL_RECORD_CANCEL) {
+					ast_verb(3, "Message canceled by control\n");
+					outmsg = 0; /* cancels the recording */
+					res = 0;
+					break;
+				} else if (f->subclass.integer == AST_CONTROL_RECORD_STOP) {
+					ast_verb(3, "Message ended by control\n");
+					res = 0;
+					break;
+				} else if (f->subclass.integer == AST_CONTROL_RECORD_SUSPEND) {
+					paused = !paused;
+					ast_verb(3, "Message %spaused by control\n",
+						paused ? "" : "un");
+					if (paused) {
+						pause_start = time(NULL);
+					} else {
+						paused_secs += time(NULL) - pause_start;
+					}
+				} else if (f->subclass.integer == AST_CONTROL_RECORD_MUTE) {
+					muted = !muted;
+					ast_verb(3, "Message %smuted by control\n",
+						muted ? "" : "un");
+					/* We can only silence slin frames, so
+					 * set the mode, if we haven't already
+					 * for sildet
+					 */
+					if (muted && !rfmt.id) {
+						ast_verb(3, "Setting read format to linear mode\n");
+						res = set_read_to_slin(chan, &rfmt);
+						if (res < 0) {
+							ast_log(LOG_WARNING, "Unable to set to linear mode, giving up\n");
+							break;
+						}
+					}
+				}
+			}
+			if (maxtime && !paused) {
 				end = time(NULL);
-				if (maxtime < (end - start)) {
+				if (maxtime < (end - start - paused_secs)) {
 					ast_verb(3, "Took too long, cutting it short...\n");
 					res = 't';
 					outmsg = 2;
@@ -1493,9 +1635,9 @@
 static const char default_acceptdtmf[] = "#";
 static const char default_canceldtmf[] = "";
 
-int ast_play_and_record_full(struct ast_channel *chan, const char *playfile, const char *recordfile, int maxtime, const char *fmt, int *duration, int *sound_duration, int silencethreshold, int maxsilence, const char *path, const char *acceptdtmf, const char *canceldtmf, int skip_confirmation_sound, enum ast_record_if_exists if_exists)
-{
-	return __ast_play_and_record(chan, playfile, recordfile, maxtime, fmt, duration, sound_duration, 0, silencethreshold, maxsilence, path, 0, S_OR(acceptdtmf, default_acceptdtmf), S_OR(canceldtmf, default_canceldtmf), skip_confirmation_sound, if_exists);
+int ast_play_and_record_full(struct ast_channel *chan, const char *playfile, const char *recordfile, int maxtime, const char *fmt, int *duration, int *sound_duration, int beep, int silencethreshold, int maxsilence, const char *path, const char *acceptdtmf, const char *canceldtmf, int skip_confirmation_sound, enum ast_record_if_exists if_exists)
+{
+	return __ast_play_and_record(chan, playfile, recordfile, maxtime, fmt, duration, sound_duration, beep, silencethreshold, maxsilence, path, 0, S_OR(acceptdtmf, default_acceptdtmf), S_OR(canceldtmf, default_canceldtmf), skip_confirmation_sound, if_exists);
 }
 
 int ast_play_and_record(struct ast_channel *chan, const char *playfile, const char *recordfile, int maxtime, const char *fmt, int *duration, int *sound_duration, int silencethreshold, int maxsilence, const char *path)

Modified: team/dlee/ASTERISK-22243/main/bridge_basic.c
URL: http://svnview.digium.com/svn/asterisk/team/dlee/ASTERISK-22243/main/bridge_basic.c?view=diff&rev=396335&r1=396334&r2=396335
==============================================================================
--- team/dlee/ASTERISK-22243/main/bridge_basic.c (original)
+++ team/dlee/ASTERISK-22243/main/bridge_basic.c Tue Aug  6 09:48:12 2013
@@ -220,7 +220,7 @@
 	return dtmf_features_flags_to_string(&held_copy, buffer, buf_size);
 }
 
-int ast_bridge_features_ds_set(struct ast_channel *chan, struct ast_flags *flags)
+static int bridge_features_ds_set_full(struct ast_channel *chan, struct ast_flags *flags, int replace)
 {
 	struct ast_datastore *datastore;
 	struct ast_flags *ds_flags;
@@ -228,7 +228,12 @@
 	datastore = ast_channel_datastore_find(chan, &dtmf_features_info, NULL);
 	if (datastore) {
 		ds_flags = datastore->data;
-		*ds_flags = *flags;
+		if (replace) {
+			*ds_flags = *flags;
+		} else {
+			flags->flags = flags->flags | ds_flags->flags;
+			*ds_flags = *flags;
+		}
 		return 0;
 	}
 
@@ -247,6 +252,16 @@
 	datastore->data = ds_flags;
 	ast_channel_datastore_add(chan, datastore);
 	return 0;
+}
+
+int ast_bridge_features_ds_set(struct ast_channel *chan, struct ast_flags *flags)
+{
+	return bridge_features_ds_set_full(chan, flags, 1);
+}
+
+int ast_bridge_features_ds_append(struct ast_channel *chan, struct ast_flags *flags)
+{
+	return bridge_features_ds_set_full(chan, flags, 0);
 }
 
 struct ast_flags *ast_bridge_features_ds_get(struct ast_channel *chan)

Modified: team/dlee/ASTERISK-22243/main/bridge_roles.c
URL: http://svnview.digium.com/svn/asterisk/team/dlee/ASTERISK-22243/main/bridge_roles.c?view=diff&rev=396335&r1=396334&r2=396335
==============================================================================
--- team/dlee/ASTERISK-22243/main/bridge_roles.c (original)
+++ team/dlee/ASTERISK-22243/main/bridge_roles.c Tue Aug  6 09:48:12 2013
@@ -355,6 +355,25 @@
 	ast_debug(2, "Role %s did not exist on channel %s\n", role_name, ast_channel_name(chan));
 }
 
+void ast_channel_clear_bridge_roles(struct ast_channel *chan)
+{
+	struct bridge_roles_datastore *roles_datastore = fetch_bridge_roles_datastore(chan);
+	struct bridge_role *role;
+
+	if (!roles_datastore) {
+		/* The roles datastore didn't already exist, so there is no need to remove any roles */
+		ast_debug(2, "Roles did not exist on channel %s\n", ast_channel_name(chan));
+		return;
+	}
+
+	AST_LIST_TRAVERSE_SAFE_BEGIN(&roles_datastore->role_list, role, list) {
+		ast_debug(2, "Removing bridge role %s from channel %s\n", role->role, ast_channel_name(chan));
+		AST_LIST_REMOVE_CURRENT(list);
+		bridge_role_destroy(role);
+	}
+	AST_LIST_TRAVERSE_SAFE_END;
+}
+
 int ast_channel_set_bridge_role_option(struct ast_channel *channel, const char *role_name, const char *option, const char *value)
 {
 	struct bridge_role *role = get_role_from_channel(channel, role_name);

Modified: team/dlee/ASTERISK-22243/main/cdr.c
URL: http://svnview.digium.com/svn/asterisk/team/dlee/ASTERISK-22243/main/cdr.c?view=diff&rev=396335&r1=396334&r2=396335
==============================================================================
--- team/dlee/ASTERISK-22243/main/cdr.c (original)
+++ team/dlee/ASTERISK-22243/main/cdr.c Tue Aug  6 09:48:12 2013
@@ -699,8 +699,8 @@
 	AST_LIST_TRAVERSE(from_list, variables, entries) {
 		if (variables &&
 		    (var = ast_var_name(variables)) && (val = ast_var_value(variables)) &&
-		    !ast_strlen_zero(var) && !ast_strlen_zero(val)) {
-			newvariable = ast_var_assign(var, val);
+		    !ast_strlen_zero(var) && !ast_strlen_zero(val) &&
+		    (newvariable = ast_var_assign(var, val))) {
 			AST_LIST_INSERT_HEAD(to_list, newvariable, entries);
 			x++;
 		}
@@ -1033,8 +1033,7 @@
 	}
 	AST_LIST_TRAVERSE_SAFE_END;
 
-	if (value) {
-		newvariable = ast_var_assign(name, value);
+	if (value && (newvariable = ast_var_assign(name, value))) {
 		AST_LIST_INSERT_HEAD(headp, newvariable, entries);
 	}
 }
@@ -1113,15 +1112,15 @@
 		copy_variables(&cdr_copy->varshead, &it_cdr->party_a.variables);
 		AST_LIST_TRAVERSE(&it_cdr->party_b.variables, it_var, entries) {
 			int found = 0;
+			struct ast_var_t *newvariable;
 			AST_LIST_TRAVERSE(&cdr_copy->varshead, it_copy_var, entries) {
 				if (!strcmp(ast_var_name(it_var), ast_var_name(it_copy_var))) {
 					found = 1;
 					break;
 				}
 			}
-			if (!found) {
-				AST_LIST_INSERT_TAIL(&cdr_copy->varshead, ast_var_assign(ast_var_name(it_var),
-						ast_var_value(it_var)), entries);
+			if (!found && (newvariable = ast_var_assign(ast_var_name(it_var), ast_var_value(it_var)))) {
+				AST_LIST_INSERT_TAIL(&cdr_copy->varshead, newvariable, entries);
 			}
 		}
 
@@ -1482,8 +1481,9 @@
 
 	while ((cand_cdr_master = ao2_iterator_next(it_cdrs))) {
 		struct cdr_object *cand_cdr;
-
-		ao2_lock(cand_cdr_master);
+		RAII_VAR(struct cdr_object *, cdr_cleanup, cand_cdr_master, ao2_cleanup);
+		SCOPED_AO2LOCK(lock, cand_cdr_master);
+
 		for (cand_cdr = cand_cdr_master; cand_cdr; cand_cdr = cand_cdr->next) {
 			/* Skip any records that are not in a bridge or in this bridge.
 			 * I'm not sure how that would happen, but it pays to be careful. */
@@ -1499,8 +1499,6 @@
 			success = 1;
 			break;
 		}
-		ao2_unlock(cand_cdr_master);
-		ao2_t_ref(cand_cdr_master, -1, "Drop iterator reference");
 	}
 	ao2_iterator_destroy(it_cdrs);
 
@@ -1625,8 +1623,9 @@
 
 	while ((cand_cdr_master = ao2_iterator_next(it_cdrs))) {
 		struct cdr_object *cand_cdr;
-
-		ao2_lock(cand_cdr_master);
+		RAII_VAR(struct cdr_object *, cdr_cleanup, cand_cdr_master, ao2_cleanup);
+		SCOPED_AO2LOCK(lock, cand_cdr_master);
+
 		for (cand_cdr = cand_cdr_master; cand_cdr; cand_cdr = cand_cdr->next) {
 			/* Skip any records that are not in a bridge or in this bridge.
 			 * I'm not sure how that would happen, but it pays to be careful. */
@@ -1655,8 +1654,6 @@
 			success = 1;
 			break;
 		}
-		ao2_unlock(cand_cdr_master);
-		ao2_t_ref(cand_cdr_master, -1, "Drop iterator reference");
 	}
 	ao2_iterator_destroy(it_cdrs);
 
@@ -2277,7 +2274,7 @@
 		ao2_cleanup(candidates);
 		return NULL;
 	}
-	while ((cand_cdr_master = ao2_iterator_next(it_cdrs))) {
+	for (; (cand_cdr_master = ao2_iterator_next(it_cdrs)); ao2_cleanup(cand_cdr_master)) {
 		SCOPED_AO2LOCK(lock, cand_cdr_master);
 		add_candidate_for_bridge(bridge->uniqueid, candidates, cand_cdr_master, 1);
 	}
@@ -2291,7 +2288,7 @@
 		ao2_cleanup(candidates);
 		return NULL;
 	}
-	while ((cand_cdr_master = ao2_iterator_next(it_cdrs))) {
+	for (; (cand_cdr_master = ao2_iterator_next(it_cdrs)); ao2_cleanup(cand_cdr_master)) {
 		SCOPED_AO2LOCK(lock, cand_cdr_master);
 		add_candidate_for_bridge(bridge->uniqueid, candidates, cand_cdr_master, 0);
 	}
@@ -2861,7 +2858,7 @@
 		return -1;
 	}
 
-	while ((cdr = ao2_iterator_next(it_cdrs))) {
+	for (; (cdr = ao2_iterator_next(it_cdrs)); ao2_unlock(cdr), ao2_cleanup(cdr)) {
 		ao2_lock(cdr);
 		for (it_cdr = cdr; it_cdr; it_cdr = it_cdr->next) {
 			struct varshead *headp = NULL;
@@ -2877,8 +2874,6 @@
 				set_variable(headp, name, value);
 			}
 		}
-		ao2_unlock(cdr);
-		ao2_ref(cdr, -1);
 	}
 	ao2_iterator_destroy(it_cdrs);
 
@@ -3598,7 +3593,7 @@
 	ast_cli(a->fd, TITLE_STRING, "Channel", "Dst. Channel", "LastApp", "Start", "Answer", "End", "Billsec", "Duration");
 

[... 1408 lines stripped ...]



More information about the asterisk-commits mailing list