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 ...]

--
_____________________________________________________________________
-- Bandwidth and Colocation Provided by http://www.api-digital.com --

svn-commits mailing list
To UNSUBSCRIBE or update options visit:
   http://lists.digium.com/mailman/listinfo/svn-commits

Reply via email to