]> git.ipfire.org Git - thirdparty/asterisk.git/commitdiff
AMI actions DAHDIHangup and DAHDITransfer have no effect.
authorRichard Mudgett <rmudgett@digium.com>
Fri, 12 Aug 2011 17:47:57 +0000 (17:47 +0000)
committerRichard Mudgett <rmudgett@digium.com>
Fri, 12 Aug 2011 17:47:57 +0000 (17:47 +0000)
The AMI actions DAHDIHangup and DAHDITransfer have no effect on a DAHDI
channel.  These two AMI actions are highly specialized to analog channels
and appear to make the channel behave like a jack port for headsets.

* Made the faked DAHDI event get processed before a normal media stream
read in dahdi_read() instead of trying to trigger an exception read by
setting the AST_FLAG_EXCEPTION flag.  Apparently a change was made long
ago that changed how AST_FLAG_EXCEPTION is processed in the core.
Unfortunately, the faked DAHDI events no longer worked when that happened.

* Updated the DAHDI AMI action documentation for the following actions:
DAHDITransfer, DAHDIHangup, DAHDIDialOffhook, DAHDIDNDon, DAHDIDNDoff,
DAHDIShowChannels, and DAHDIRestart.

* Made use sscanf() instead of atoi() for better error checking of the
DAHDIChannel header string.

JIRA AST-620
JIRA SWP-3616

git-svn-id: https://origsvn.digium.com/svn/asterisk/branches/1.8@331714 65c4cc65-6c06-0410-ace0-fbb531ad65f3

channels/chan_dahdi.c

index 818f41257e13bff4f784bd7d3360c89230af03b8..7c9ff1eba73620637856aad488b491c17a61e80f 100644 (file)
@@ -175,11 +175,12 @@ ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
                <syntax>
                        <xi:include xpointer="xpointer(/docs/manager[@name='Login']/syntax/parameter[@name='ActionID'])" />
                        <parameter name="DAHDIChannel" required="true">
-                               <para>DAHDI channel name to transfer.</para>
+                               <para>DAHDI channel number to transfer.</para>
                        </parameter>
                </syntax>
                <description>
-                       <para>Transfer a DAHDI channel.</para>
+                       <para>Simulate a flash hook event by the user connected to the channel.</para>
+                       <note><para>Valid only for analog channels.</para></note>
                </description>
        </manager>
        <manager name="DAHDIHangup" language="en_US">
@@ -189,11 +190,12 @@ ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
                <syntax>
                        <xi:include xpointer="xpointer(/docs/manager[@name='Login']/syntax/parameter[@name='ActionID'])" />
                        <parameter name="DAHDIChannel" required="true">
-                               <para>DAHDI channel name to hangup.</para>
+                               <para>DAHDI channel number to hangup.</para>
                        </parameter>
                </syntax>
                <description>
-                       <para>Hangup a DAHDI channel.</para>
+                       <para>Simulate an on-hook event by the user connected to the channel.</para>
+                       <note><para>Valid only for analog channels.</para></note>
                </description>
        </manager>
        <manager name="DAHDIDialOffhook" language="en_US">
@@ -202,10 +204,15 @@ ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
                </synopsis>
                <syntax>
                        <xi:include xpointer="xpointer(/docs/manager[@name='Login']/syntax/parameter[@name='ActionID'])" />
-                       <parameter name="DAHDIChannel" required="true" />
-                       <parameter name="Number" required="true" />
+                       <parameter name="DAHDIChannel" required="true">
+                               <para>DAHDI channel number to dial digits.</para>
+                       </parameter>
+                       <parameter name="Number" required="true">
+                               <para>Digits to dial.</para>
+                       </parameter>
                </syntax>
                <description>
+                       <para>Generate DTMF control frames to the bridged peer.</para>
                </description>
        </manager>
        <manager name="DAHDIDNDon" language="en_US">
@@ -214,9 +221,13 @@ ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
                </synopsis>
                <syntax>
                        <xi:include xpointer="xpointer(/docs/manager[@name='Login']/syntax/parameter[@name='ActionID'])" />
-                       <parameter name="DAHDIChannel" required="true" />
+                       <parameter name="DAHDIChannel" required="true">
+                               <para>DAHDI channel number to set DND on.</para>
+                       </parameter>
                </syntax>
                <description>
+                       <para>Equivalent to the CLI command "dahdi set dnd <variable>channel</variable> on".</para>
+                       <note><para>Feature only supported by analog channels.</para></note>
                </description>
        </manager>
        <manager name="DAHDIDNDoff" language="en_US">
@@ -225,22 +236,27 @@ ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
                </synopsis>
                <syntax>
                        <xi:include xpointer="xpointer(/docs/manager[@name='Login']/syntax/parameter[@name='ActionID'])" />
-                       <parameter name="DAHDIChannel" required="true" />
+                       <parameter name="DAHDIChannel" required="true">
+                               <para>DAHDI channel number to set DND off.</para>
+                       </parameter>
                </syntax>
                <description>
+                       <para>Equivalent to the CLI command "dahdi set dnd <variable>channel</variable> off".</para>
+                       <note><para>Feature only supported by analog channels.</para></note>
                </description>
        </manager>
        <manager name="DAHDIShowChannels" language="en_US">
                <synopsis>
-                       Show status DAHDI channels.
+                       Show status of DAHDI channels.
                </synopsis>
                <syntax>
                        <xi:include xpointer="xpointer(/docs/manager[@name='Login']/syntax/parameter[@name='ActionID'])" />
                        <parameter name="DAHDIChannel">
-                               <para>Specify the specific channel to show.  Show all channels if zero or not present.</para>
+                               <para>Specify the specific channel number to show.  Show all channels if zero or not present.</para>
                        </parameter>
                </syntax>
                <description>
+                       <para>Similar to the CLI command "dahdi show channels".</para>
                </description>
        </manager>
        <manager name="DAHDIRestart" language="en_US">
@@ -251,6 +267,7 @@ ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
                        <xi:include xpointer="xpointer(/docs/manager[@name='Login']/syntax/parameter[@name='ActionID'])" />
                </syntax>
                <description>
+                       <para>Equivalent to the CLI command "dahdi restart".</para>
                </description>
        </manager>
  ***/
@@ -8910,6 +8927,19 @@ static struct ast_frame *dahdi_read(struct ast_channel *ast)
                return &p->subs[idx].f;
        }
 
+       /* If we have a fake_event, fake an exception to handle it */
+       if (p->fake_event) {
+               if (analog_lib_handles(p->sig, p->radio, p->oprmode)) {
+                       struct analog_pvt *analog_p = p->sig_pvt;
+
+                       f = analog_exception(analog_p, ast);
+               } else {
+                       f = __dahdi_exception(ast);
+               }
+               ast_mutex_unlock(&p->lock);
+               return f;
+       }
+
        if (ast->rawreadformat == AST_FORMAT_SLINEAR) {
                if (!p->subs[idx].linear) {
                        p->subs[idx].linear = 1;
@@ -9141,10 +9171,6 @@ static struct ast_frame *dahdi_read(struct ast_channel *ast)
                }
        }
 
-       /* If we have a fake_event, trigger exception to handle it */
-       if (p->fake_event)
-               ast_set_flag(ast, AST_FLAG_EXCEPTION);
-
        ast_mutex_unlock(&p->lock);
        return f;
 }
@@ -15665,16 +15691,37 @@ static struct dahdi_pvt *find_channel(int channel)
        return p;
 }
 
+/*!
+ * \internal
+ * \brief Get private struct using given numeric channel string.
+ *
+ * \param channel Numeric channel number string get private struct.
+ *
+ * \retval pvt on success.
+ * \retval NULL on error.
+ */
+static struct dahdi_pvt *find_channel_from_str(const char *channel)
+{
+       int chan_num;
+
+       if (sscanf(channel, "%30d", &chan_num) != 1) {
+               /* Not numeric string. */
+               return NULL;
+       }
+
+       return find_channel(chan_num);
+}
+
 static int action_dahdidndon(struct mansession *s, const struct message *m)
 {
-       struct dahdi_pvt *p = NULL;
+       struct dahdi_pvt *p;
        const char *channel = astman_get_header(m, "DAHDIChannel");
 
        if (ast_strlen_zero(channel)) {
                astman_send_error(s, m, "No channel specified");
                return 0;
        }
-       p = find_channel(atoi(channel));
+       p = find_channel_from_str(channel);
        if (!p) {
                astman_send_error(s, m, "No such channel");
                return 0;
@@ -15686,14 +15733,14 @@ static int action_dahdidndon(struct mansession *s, const struct message *m)
 
 static int action_dahdidndoff(struct mansession *s, const struct message *m)
 {
-       struct dahdi_pvt *p = NULL;
+       struct dahdi_pvt *p;
        const char *channel = astman_get_header(m, "DAHDIChannel");
 
        if (ast_strlen_zero(channel)) {
                astman_send_error(s, m, "No channel specified");
                return 0;
        }
-       p = find_channel(atoi(channel));
+       p = find_channel_from_str(channel);
        if (!p) {
                astman_send_error(s, m, "No such channel");
                return 0;
@@ -15705,18 +15752,22 @@ static int action_dahdidndoff(struct mansession *s, const struct message *m)
 
 static int action_transfer(struct mansession *s, const struct message *m)
 {
-       struct dahdi_pvt *p = NULL;
+       struct dahdi_pvt *p;
        const char *channel = astman_get_header(m, "DAHDIChannel");
 
        if (ast_strlen_zero(channel)) {
                astman_send_error(s, m, "No channel specified");
                return 0;
        }
-       p = find_channel(atoi(channel));
+       p = find_channel_from_str(channel);
        if (!p) {
                astman_send_error(s, m, "No such channel");
                return 0;
        }
+       if (!analog_lib_handles(p->sig, 0, 0)) {
+               astman_send_error(s, m, "Channel signaling is not analog");
+               return 0;
+       }
        dahdi_fake_event(p,TRANSFER);
        astman_send_ack(s, m, "DAHDITransfer");
        return 0;
@@ -15724,18 +15775,22 @@ static int action_transfer(struct mansession *s, const struct message *m)
 
 static int action_transferhangup(struct mansession *s, const struct message *m)
 {
-       struct dahdi_pvt *p = NULL;
+       struct dahdi_pvt *p;
        const char *channel = astman_get_header(m, "DAHDIChannel");
 
        if (ast_strlen_zero(channel)) {
                astman_send_error(s, m, "No channel specified");
                return 0;
        }
-       p = find_channel(atoi(channel));
+       p = find_channel_from_str(channel);
        if (!p) {
                astman_send_error(s, m, "No such channel");
                return 0;
        }
+       if (!analog_lib_handles(p->sig, 0, 0)) {
+               astman_send_error(s, m, "Channel signaling is not analog");
+               return 0;
+       }
        dahdi_fake_event(p,HANGUP);
        astman_send_ack(s, m, "DAHDIHangup");
        return 0;
@@ -15743,7 +15798,7 @@ static int action_transferhangup(struct mansession *s, const struct message *m)
 
 static int action_dahdidialoffhook(struct mansession *s, const struct message *m)
 {
-       struct dahdi_pvt *p = NULL;
+       struct dahdi_pvt *p;
        const char *channel = astman_get_header(m, "DAHDIChannel");
        const char *number = astman_get_header(m, "Number");
        int i;
@@ -15756,7 +15811,7 @@ static int action_dahdidialoffhook(struct mansession *s, const struct message *m
                astman_send_error(s, m, "No number specified");
                return 0;
        }
-       p = find_channel(atoi(channel));
+       p = find_channel_from_str(channel);
        if (!p) {
                astman_send_error(s, m, "No such channel");
                return 0;
@@ -15780,9 +15835,11 @@ static int action_dahdishowchannels(struct mansession *s, const struct message *
        const char *dahdichannel = astman_get_header(m, "DAHDIChannel");
        char idText[256] = "";
        int channels = 0;
-       int dahdichanquery = -1;
-       if (!ast_strlen_zero(dahdichannel)) {
-               dahdichanquery = atoi(dahdichannel);
+       int dahdichanquery;
+
+       if (!dahdichannel || sscanf(dahdichannel, "%30d", &dahdichanquery) != 1) {
+               /* Not numeric string. */
+               dahdichanquery = -1;
        }
 
        astman_send_ack(s, m, "DAHDI channel status will follow");