diff --git a/channels/chan_dahdi.c b/channels/chan_dahdi.c
index 81a9ce06c3..813bcadb3a 100644
--- a/channels/chan_dahdi.c
+++ b/channels/chan_dahdi.c
@@ -175,11 +175,12 @@ ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
- DAHDI channel name to transfer.
+ DAHDI channel number to transfer.
- Transfer a DAHDI channel.
+ Simulate a flash hook event by the user connected to the channel.
+ Valid only for analog channels.
@@ -189,11 +190,12 @@ ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
- DAHDI channel name to hangup.
+ DAHDI channel number to hangup.
- Hangup a DAHDI channel.
+ Simulate an on-hook event by the user connected to the channel.
+ Valid only for analog channels.
@@ -202,10 +204,15 @@ ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
-
-
+
+ DAHDI channel number to dial digits.
+
+
+ Digits to dial.
+
+ Generate DTMF control frames to the bridged peer.
@@ -214,9 +221,13 @@ ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
-
+
+ DAHDI channel number to set DND on.
+
+ Equivalent to the CLI command "dahdi set dnd channel on".
+ Feature only supported by analog channels.
@@ -225,22 +236,27 @@ ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
-
+
+ DAHDI channel number to set DND off.
+
+ Equivalent to the CLI command "dahdi set dnd channel off".
+ Feature only supported by analog channels.
- Show status DAHDI channels.
+ Show status of DAHDI channels.
- Specify the specific channel to show. Show all channels if zero or not present.
+ Specify the specific channel number to show. Show all channels if zero or not present.
+ Similar to the CLI command "dahdi show channels".
@@ -251,6 +267,7 @@ ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
+ Equivalent to the CLI command "dahdi restart".
@@ -264,6 +281,7 @@ ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
+ Similar to the CLI command "pri show spans".
***/
@@ -8992,6 +9010,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.id == AST_FORMAT_SLINEAR) {
if (!p->subs[idx].linear) {
p->subs[idx].linear = 1;
@@ -9223,10 +9254,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;
}
@@ -15777,16 +15804,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;
@@ -15798,14 +15846,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;
@@ -15817,18 +15865,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;
@@ -15836,18 +15888,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;
@@ -15855,7 +15911,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;
@@ -15868,7 +15924,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;
@@ -15892,9 +15948,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");