[asterisk-commits] mjordan: branch mjordan/longcat r378644 - in /team/mjordan/longcat: apps/ inc...
SVN commits to the Asterisk project
asterisk-commits at lists.digium.com
Sun Jan 6 19:51:38 CST 2013
Author: mjordan
Date: Sun Jan 6 19:51:32 2013
New Revision: 378644
URL: http://svnview.digium.com/svn/asterisk?view=rev&rev=378644
Log:
Add an AMI command to control the playback
As Richard pointed out, this is all that's needed. The AGI command
should just be removed - that keeps the modifications in the train
wreck that is res_agi's handling of multiple AGI variants to a minimum.
Modified:
team/mjordan/longcat/apps/app_controlplayback.c
team/mjordan/longcat/apps/app_playback.c
team/mjordan/longcat/include/asterisk/frame.h
team/mjordan/longcat/res/res_agi.c
Modified: team/mjordan/longcat/apps/app_controlplayback.c
URL: http://svnview.digium.com/svn/asterisk/team/mjordan/longcat/apps/app_controlplayback.c?view=diff&rev=378644&r1=378643&r2=378644
==============================================================================
--- team/mjordan/longcat/apps/app_controlplayback.c (original)
+++ team/mjordan/longcat/apps/app_controlplayback.c Sun Jan 6 19:51:32 2013
@@ -36,6 +36,9 @@
#include "asterisk/pbx.h"
#include "asterisk/app.h"
#include "asterisk/module.h"
+#include "asterisk/manager.h"
+#include "asterisk/utils.h"
+#include "asterisk/astobj2.h"
/*** DOCUMENTATION
<application name="ControlPlayback" language="en_US">
@@ -82,6 +85,7 @@
<para>Contains the status of the attempt as a text string</para>
<value name="SUCCESS" />
<value name="USERSTOPPED" />
+ <value name="REMOTESTOPPED" />
<value name="ERROR" />
</variable>
<variable name="CPLAYBACKOFFSET">
@@ -95,6 +99,60 @@
</variablelist>
</description>
</application>
+ <manager name="ControlPlayback" language="en_US">
+ <synopsis>
+ Control the playback of a file being played to a channel.
+ </synopsis>
+ <syntax>
+ <xi:include xpointer="xpointer(/docs/manager[@name='Login']/syntax/parameter[@name='ActionID'])" />
+ <parameter name="Channel" required="true">
+ <para>The name of the channel that currently has a file being played back to it.</para>
+ </parameter>
+ <parameter name="Control" required="true">
+ <enumlist>
+ <enum name="stop">
+ <para>Stop the playback operation.</para>
+ </enum>
+ <enum name="forward">
+ <para>Move the current position in the media forward. The amount
+ of time that the stream moves forward is determined by the
+ <replaceable>skipms</replaceable> value passed to the application
+ that initiated the playback.</para>
+ <note>
+ <para>The default skipms value is <literal>3000</literal> ms.</para>
+ </note>
+ </enum>
+ <enum name="reverse">
+ <para>Move the current position in the media backward. The amount
+ of time that the stream moves backward is determined by the
+ <replaceable>skipms</replaceable> value passed to the application
+ that initiated the playback.</para>
+ <note>
+ <para>The default skipms value is <literal>3000</literal> ms.</para>
+ </note>
+ </enum>
+ <enum name="pause">
+ <para>Pause/unpause the playback operation.</para>
+ </enum>
+ <enum name="restart">
+ <para>Restart the playback operation.</para>
+ </enum>
+ </enumlist>
+ </parameter>
+ </syntax>
+ <description>
+ <para>Control the operation of a media file being played back to a channel.
+ Note that this AMI action does not initiate playback of media to channel, but
+ rather controls the operation of a media operation that was already initiated
+ on the channel.</para>
+ </description>
+ <see-also>
+ <ref type="application">Playback</ref>
+ <ref type="application">ControlPlayback</ref>
+ <ref type="agi">stream file</ref>
+ <ref type="agi">control stream file</ref>
+ </see-also>
+ </manager>
***/
static const char app[] = "ControlPlayback";
@@ -201,6 +259,9 @@
snprintf(stopkeybuf, sizeof(stopkeybuf), "%c", res);
pbx_builtin_setvar_helper(chan, "CPLAYBACKSTOPKEY", stopkeybuf);
res = 0;
+ } else if (res > 0 && res == AST_CONTROL_STREAM_STOP) {
+ pbx_builtin_setvar_helper(chan, "CPLAYBACKSTATUS", "REMOTESTOPPED");
+ res = 0;
} else {
if (res < 0) {
res = 0;
@@ -215,16 +276,80 @@
return res;
}
+static int controlplayback_manager(struct mansession *s, const struct message *m)
+{
+ const char *channel_name = astman_get_header(m, "Channel");
+ const char *control_type = astman_get_header(m, "Control");
+ struct ast_channel *chan;
+
+ if (ast_strlen_zero(channel_name)) {
+ astman_send_error(s, m, "Channel not specified");
+ return 0;
+ }
+
+ if (ast_strlen_zero(control_type)) {
+ astman_send_error(s, m, "Control not specified");
+ return 0;
+ }
+
+ chan = ast_channel_get_by_name(channel_name);
+ if (!chan) {
+ astman_send_error(s, m, "No such channel");
+ return 0;
+ }
+
+ /* At least make sure that before we send the control signal there is
+ * something streamed to the channel. The playback could still end before
+ * the frame is serviced, but it's something.
+ */
+ ast_channel_lock(chan);
+ if (!ast_channel_stream(chan)) {
+ ast_channel_unlock(chan);
+ chan = ast_channel_unref(chan);
+ astman_send_error(s, m, "Nothing being played back to channel");
+ return 0;
+ }
+ ast_channel_unlock(chan);
+
+ if (!strcmp(control_type, "stop")) {
+ ast_indicate(chan, AST_CONTROL_STREAM_STOP);
+ } else if (!strcmp(control_type, "forward")) {
+ ast_indicate(chan, AST_CONTROL_STREAM_FORWARD);
+ } else if (!strcmp(control_type, "reverse")) {
+ ast_indicate(chan, AST_CONTROL_STREAM_REVERSE);
+ } else if (!strcmp(control_type, "pause")) {
+ ast_indicate(chan, AST_CONTROL_STREAM_SUSPEND);
+ } else if (!strcmp(control_type, "restart")) {
+ ast_indicate(chan, AST_CONTROL_STREAM_RESTART);
+ } else {
+ astman_send_error(s, m, "Unknown control type");
+ chan = ast_channel_unref(chan);
+ return 0;
+ }
+
+ chan = ast_channel_unref(chan);
+ astman_send_ack(s, m, NULL);
+ return 0;
+}
+
static int unload_module(void)
{
- int res;
- res = ast_unregister_application(app);
+ int res = 0;
+
+ res |= ast_unregister_application(app);
+ res |= ast_manager_unregister("ControlPlayback");
+
return res;
}
static int load_module(void)
{
- return ast_register_application_xml(app, controlplayback_exec);
+ int res = 0;
+
+ res |= ast_register_application_xml(app, controlplayback_exec);
+ res |= ast_manager_register_xml("ControlPlayback", EVENT_FLAG_CALL, controlplayback_manager);
+
+ return res;
}
AST_MODULE_INFO_STANDARD(ASTERISK_GPL_KEY, "Control Playback Application");
Modified: team/mjordan/longcat/apps/app_playback.c
URL: http://svnview.digium.com/svn/asterisk/team/mjordan/longcat/apps/app_playback.c?view=diff&rev=378644&r1=378643&r2=378644
==============================================================================
--- team/mjordan/longcat/apps/app_playback.c (original)
+++ team/mjordan/longcat/apps/app_playback.c Sun Jan 6 19:51:32 2013
@@ -82,6 +82,14 @@
<para>See Also: Background (application) -- for playing sound files that are interruptible</para>
<para>WaitExten (application) -- wait for digits from caller, optionally play music on hold</para>
</description>
+ <see-also>
+ <ref type="application">Background</ref>
+ <ref type="application">WaitExten</ref>
+ <ref type="application">ControlPlayback</ref>
+ <ref type="agi">stream file</ref>
+ <ref type="agi">control stream file</ref>
+ <ref type="manager">ControlPlayback</ref>
+ </see-also>
</application>
***/
Modified: team/mjordan/longcat/include/asterisk/frame.h
URL: http://svnview.digium.com/svn/asterisk/team/mjordan/longcat/include/asterisk/frame.h?view=diff&rev=378644&r1=378643&r2=378644
==============================================================================
--- team/mjordan/longcat/include/asterisk/frame.h (original)
+++ team/mjordan/longcat/include/asterisk/frame.h Sun Jan 6 19:51:32 2013
@@ -267,12 +267,15 @@
AST_CONTROL_MCID = 31, /*!< Indicate that the caller is being malicious. */
AST_CONTROL_UPDATE_RTP_PEER = 32, /*!< Interrupt the bridge and have it update the peer */
AST_CONTROL_PVT_CAUSE_CODE = 33, /*!< Contains an update to the protocol-specific cause-code stored for branching dials */
- /* Control frames used to manipulate a stream on a channel */
- AST_CONTROL_STREAM_STOP = 1000,
- AST_CONTROL_STREAM_SUSPEND = 1001,
- AST_CONTROL_STREAM_RESTART = 1002,
- AST_CONTROL_STREAM_REVERSE = 1003,
- AST_CONTROL_STREAM_FORWARD = 1004,
+
+ /* Control frames used to manipulate a stream on a channel. The values for these
+ * must be greater than the allowed value for a 8-bit char, so that they avoid
+ * conflicts with DTMF values. */
+ AST_CONTROL_STREAM_STOP = 1000, /*!< Indicate to a channel in playback to stop the stream */
+ AST_CONTROL_STREAM_SUSPEND = 1001, /*!< Indicate to a channel in playback to suspend the stream */
+ 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 */
};
Modified: team/mjordan/longcat/res/res_agi.c
URL: http://svnview.digium.com/svn/asterisk/team/mjordan/longcat/res/res_agi.c?view=diff&rev=378644&r1=378643&r2=378644
==============================================================================
--- team/mjordan/longcat/res/res_agi.c (original)
+++ team/mjordan/longcat/res/res_agi.c Sun Jan 6 19:51:32 2013
@@ -187,6 +187,24 @@
permitted. Returns <literal>0</literal> if playback completes without a digit
being pressed, or the ASCII numerical value of the digit if one was pressed,
or <literal>-1</literal> on error or if the channel was disconnected.</para>
+ <para>It sets the following channel variables upon completion:</para>
+ <variablelist>
+ <variable name="CPLAYBACKSTATUS">
+ <para>Contains the status of the attempt as a text string</para>
+ <value name="SUCCESS" />
+ <value name="USERSTOPPED" />
+ <value name="REMOTESTOPPED" />
+ <value name="ERROR" />
+ </variable>
+ <variable name="CPLAYBACKOFFSET">
+ <para>Contains the offset in ms into the file where playback
+ was at when it stopped. <literal>-1</literal> is end of file.</para>
+ </variable>
+ <variable name="CPLAYBACKSTOPKEY">
+ <para>If the playback is stopped by the user this variable contains
+ the key that was pressed.</para>
+ </variable>
+ </variablelist>
</description>
</agi>
<agi name="database del" language="en_US">
@@ -2040,6 +2058,9 @@
{
int res = 0, skipms = 3000;
const char *fwd = "#", *rev = "*", *suspend = NULL, *stop = NULL; /* Default values */
+ char stopkeybuf[2];
+ long offsetms = 0;
+ char offsetbuf[20];
if (argc < 5 || argc > 9) {
return RESULT_SHOWUSAGE;
@@ -2066,6 +2087,25 @@
}
res = ast_control_streamfile(chan, argv[3], fwd, rev, stop, suspend, NULL, skipms, NULL);
+
+ /* If we stopped on one of our stop keys, return 0 */
+ if (res > 0 && stop && strchr(stop, res)) {
+ pbx_builtin_setvar_helper(chan, "CPLAYBACKSTATUS", "USERSTOPPED");
+ snprintf(stopkeybuf, sizeof(stopkeybuf), "%c", res);
+ pbx_builtin_setvar_helper(chan, "CPLAYBACKSTOPKEY", stopkeybuf);
+ } else if (res > 0 && res == AST_CONTROL_STREAM_STOP) {
+ pbx_builtin_setvar_helper(chan, "CPLAYBACKSTATUS", "REMOTESTOPPED");
+ res = 0;
+ } else {
+ if (res < 0) {
+ pbx_builtin_setvar_helper(chan, "CPLAYBACKSTATUS", "ERROR");
+ } else {
+ pbx_builtin_setvar_helper(chan, "CPLAYBACKSTATUS", "SUCCESS");
+ }
+ }
+
+ snprintf(offsetbuf, sizeof(offsetbuf), "%ld", offsetms);
+ pbx_builtin_setvar_helper(chan, "CPLAYBACKOFFSET", offsetbuf);
ast_agi_send(agi->fd, chan, "200 result=%d\n", res);
More information about the asterisk-commits
mailing list