summaryrefslogtreecommitdiff
path: root/channels/chan_dahdi.c
diff options
context:
space:
mode:
Diffstat (limited to 'channels/chan_dahdi.c')
-rw-r--r--channels/chan_dahdi.c283
1 files changed, 219 insertions, 64 deletions
diff --git a/channels/chan_dahdi.c b/channels/chan_dahdi.c
index 24337e385..b22e73800 100644
--- a/channels/chan_dahdi.c
+++ b/channels/chan_dahdi.c
@@ -131,6 +131,7 @@ ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
#include "asterisk/data.h"
#include "asterisk/features_config.h"
#include "asterisk/bridging.h"
+#include "asterisk/stasis_channels.h"
/*** DOCUMENTATION
<application name="DAHDISendKeypadFacility" language="en_US">
@@ -296,6 +297,85 @@ ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
<para>Similar to the CLI command "pri show spans".</para>
</description>
</manager>
+ <managerEvent language="en_US" name="AlarmClear">
+ <managerEventInstance class="EVENT_FLAG_SYSTEM">
+ <synopsis>Raised when an alarm is cleared on a DAHDI channel.</synopsis>
+ <syntax>
+ <parameter name="DAHDIChannel">
+ <para>The DAHDI channel on which the alarm was cleared.</para>
+ <note><para>This is not an Asterisk channel identifier.</para></note>
+ </parameter>
+ </syntax>
+ </managerEventInstance>
+ </managerEvent>
+ <managerEvent language="en_US" name="SpanAlarmClear">
+ <managerEventInstance class="EVENT_FLAG_SYSTEM">
+ <synopsis>Raised when an alarm is cleared on a DAHDI span.</synopsis>
+ <syntax>
+ <parameter name="Span">
+ <para>The span on which the alarm was cleared.</para>
+ </parameter>
+ </syntax>
+ </managerEventInstance>
+ </managerEvent>
+ <managerEvent language="en_US" name="DNDState">
+ <managerEventInstance class="EVENT_FLAG_SYSTEM">
+ <synopsis>Raised when the Do Not Disturb state is changed on a DAHDI channel.</synopsis>
+ <syntax>
+ <parameter name="DAHDIChannel">
+ <para>The DAHDI channel on which DND status changed.</para>
+ <note><para>This is not an Asterisk channel identifier.</para></note>
+ </parameter>
+ <parameter name="Status">
+ <enumlist>
+ <enum name="enabled"/>
+ <enum name="disabled"/>
+ </enumlist>
+ </parameter>
+ </syntax>
+ </managerEventInstance>
+ </managerEvent>
+ <managerEvent language="en_US" name="Alarm">
+ <managerEventInstance class="EVENT_FLAG_SYSTEM">
+ <synopsis>Raised when an alarm is set on a DAHDI channel.</synopsis>
+ <syntax>
+ <parameter name="DAHDIChannel">
+ <para>The channel on which the alarm occurred.</para>
+ <note><para>This is not an Asterisk channel identifier.</para></note>
+ </parameter>
+ <parameter name="Alarm">
+ <para>A textual description of the alarm that occurred.</para>
+ </parameter>
+ </syntax>
+ </managerEventInstance>
+ </managerEvent>
+ <managerEvent language="en_US" name="SpanAlarm">
+ <managerEventInstance class="EVENT_FLAG_SYSTEM">
+ <synopsis>Raised when an alarm is set on a DAHDI span.</synopsis>
+ <syntax>
+ <parameter name="Span">
+ <para>The span on which the alarm occurred.</para>
+ </parameter>
+ <parameter name="Alarm">
+ <para>A textual description of the alarm that occurred.</para>
+ </parameter>
+ </syntax>
+ </managerEventInstance>
+ </managerEvent>
+ <managerEvent language="en_US" name="DAHDIChannel">
+ <managerEventInstance class="EVENT_FLAG_CALL">
+ <synopsis>Raised when a DAHDI channel is created or an underlying technology is associated with a DAHDI channel.</synopsis>
+ <syntax>
+ <xi:include xpointer="xpointer(/docs/managerEvent[@name='Newchannel']/managerEventInstance/syntax/parameter)" />
+ <parameter name="DAHDISpan">
+ <para>The DAHDI span associated with this channel.</para>
+ </parameter>
+ <parameter name="DAHDIChannel">
+ <para>The DAHDI channel associated with this channel.</para>
+ </parameter>
+ </syntax>
+ </managerEventInstance>
+ </managerEvent>
***/
#define SMDI_MD_WAIT_TIMEOUT 1500 /* 1.5 seconds */
@@ -2270,6 +2350,50 @@ static void my_deadlock_avoidance_private(void *pvt)
DEADLOCK_AVOIDANCE(&p->lock);
}
+static struct ast_manager_event_blob *dahdichannel_to_ami(struct stasis_message *msg)
+{
+ RAII_VAR(struct ast_str *, channel_string, NULL, ast_free);
+ struct ast_channel_blob *obj = stasis_message_data(msg);
+ struct ast_json *span, *channel;
+
+ channel_string = ast_manager_build_channel_state_string(obj->snapshot);
+ if (!channel_string) {
+ return NULL;
+ }
+
+ span = ast_json_object_get(obj->blob, "span");
+ channel = ast_json_object_get(obj->blob, "channel");
+
+ return ast_manager_event_blob_create(EVENT_FLAG_CALL, "DAHDIChannel",
+ "%s"
+ "DAHDISpan: %d\r\n"
+ "DAHDIChannel: %s\r\n",
+ ast_str_buffer(channel_string),
+ (unsigned int)ast_json_integer_get(span),
+ ast_json_string_get(channel));
+}
+
+STASIS_MESSAGE_TYPE_DEFN_LOCAL(dahdichannel_type,
+ .to_ami = dahdichannel_to_ami,
+ );
+
+/*! \brief Sends a DAHDIChannel channel blob used to produce DAHDIChannel AMI messages */
+static void publish_dahdichannel(struct ast_channel *chan, int span, const char *dahdi_channel)
+{
+ RAII_VAR(struct ast_json *, blob, NULL, ast_json_unref);
+
+ ast_assert(dahdi_channel != NULL);
+
+ blob = ast_json_pack("{s: i, s: s}",
+ "span", span,
+ "channel", dahdi_channel);
+ if (!blob) {
+ return;
+ }
+
+ ast_channel_publish_blob(chan, dahdichannel_type(), blob);
+}
+
/*!
* \internal
* \brief Post an AMI DAHDI channel association event.
@@ -2294,20 +2418,7 @@ static void dahdi_ami_channel_event(struct dahdi_pvt *p, struct ast_channel *cha
/* Real channel */
snprintf(ch_name, sizeof(ch_name), "%d", p->channel);
}
- /*** DOCUMENTATION
- <managerEventInstance>
- <synopsis>Raised when a DAHDI channel is created or an underlying technology is associated with a DAHDI channel.</synopsis>
- </managerEventInstance>
- ***/
- ast_manager_event(chan, EVENT_FLAG_CALL, "DAHDIChannel",
- "Channel: %s\r\n"
- "Uniqueid: %s\r\n"
- "DAHDISpan: %d\r\n"
- "DAHDIChannel: %s\r\n",
- ast_channel_name(chan),
- ast_channel_uniqueid(chan),
- p->span,
- ch_name);
+ publish_dahdichannel(chan, p->span, ch_name);
}
#ifdef HAVE_PRI
@@ -3956,6 +4067,37 @@ static void dahdi_queue_frame(struct dahdi_pvt *p, struct ast_frame *f)
}
}
+static void publish_channel_alarm_clear(int channel)
+{
+ RAII_VAR(struct ast_json *, body, NULL, ast_json_unref);
+ RAII_VAR(struct ast_str *, dahdi_chan, ast_str_create(32), ast_free);
+ if (!dahdi_chan) {
+ return;
+ }
+
+ ast_str_set(&dahdi_chan, 0, "%d", channel);
+ ast_log(LOG_NOTICE, "Alarm cleared on channel DAHDI/%d\n", channel);
+ body = ast_json_pack("{s: s}", "DAHDIChannel", ast_str_buffer(dahdi_chan));
+ if (!body) {
+ return;
+ }
+
+ ast_manager_publish_event("AlarmClear", EVENT_FLAG_SYSTEM, body);
+}
+
+static void publish_span_alarm_clear(int span)
+{
+ RAII_VAR(struct ast_json *, body, NULL, ast_json_unref);
+
+ ast_log(LOG_NOTICE, "Alarm cleared on span %d\n", span);
+ body = ast_json_pack("{s: i}", "Span", span);
+ if (!body) {
+ return;
+ }
+
+ ast_manager_publish_event("SpanAlarmClear", EVENT_FLAG_SYSTEM, body);
+}
+
static void handle_clear_alarms(struct dahdi_pvt *p)
{
#if defined(HAVE_PRI)
@@ -3965,22 +4107,10 @@ static void handle_clear_alarms(struct dahdi_pvt *p)
#endif /* defined(HAVE_PRI) */
if (report_alarms & REPORT_CHANNEL_ALARMS) {
- ast_log(LOG_NOTICE, "Alarm cleared on channel %d\n", p->channel);
- /*** DOCUMENTATION
- <managerEventInstance>
- <synopsis>Raised when an alarm is cleared on a DAHDI channel.</synopsis>
- </managerEventInstance>
- ***/
- manager_event(EVENT_FLAG_SYSTEM, "AlarmClear", "Channel: %d\r\n", p->channel);
+ publish_channel_alarm_clear(p->channel);
}
if (report_alarms & REPORT_SPAN_ALARMS && p->manages_span_alarms) {
- ast_log(LOG_NOTICE, "Alarm cleared on span %d\n", p->span);
- /*** DOCUMENTATION
- <managerEventInstance>
- <synopsis>Raised when an alarm is cleared on a DAHDI span.</synopsis>
- </managerEventInstance>
- ***/
- manager_event(EVENT_FLAG_SYSTEM, "SpanAlarmClear", "Span: %d\r\n", p->span);
+ publish_span_alarm_clear(p->span);
}
}
@@ -8037,6 +8167,39 @@ static void dahdi_handle_dtmf(struct ast_channel *ast, int idx, struct ast_frame
}
}
+static void publish_span_alarm(int span, const char *alarm_txt)
+{
+ RAII_VAR(struct ast_json *, body, NULL, ast_json_unref);
+
+ body = ast_json_pack("{s: i, s: s}",
+ "Span", span,
+ "Alarm", alarm_txt);
+ if (!body) {
+ return;
+ }
+
+ ast_manager_publish_event("SpanAlarm", EVENT_FLAG_SYSTEM, body);
+}
+
+static void publish_channel_alarm(int channel, const char *alarm_txt)
+{
+ RAII_VAR(struct ast_json *, body, NULL, ast_json_unref);
+ RAII_VAR(struct ast_str *, dahdi_chan, ast_str_create(32), ast_free);
+ if (!dahdi_chan) {
+ return;
+ }
+
+ ast_str_set(&dahdi_chan, 0, "%d", channel);
+ body = ast_json_pack("{s: s, s: s}",
+ "DAHDIChannel", ast_str_buffer(dahdi_chan),
+ "Alarm", alarm_txt);
+ if (!body) {
+ return;
+ }
+
+ ast_manager_publish_event("Alarm", EVENT_FLAG_SYSTEM, body);
+}
+
static void handle_alarms(struct dahdi_pvt *p, int alms)
{
const char *alarm_str;
@@ -8050,28 +8213,12 @@ static void handle_alarms(struct dahdi_pvt *p, int alms)
alarm_str = alarm2str(alms);
if (report_alarms & REPORT_CHANNEL_ALARMS) {
ast_log(LOG_WARNING, "Detected alarm on channel %d: %s\n", p->channel, alarm_str);
- /*** DOCUMENTATION
- <managerEventInstance>
- <synopsis>Raised when an alarm is set on a DAHDI channel.</synopsis>
- </managerEventInstance>
- ***/
- manager_event(EVENT_FLAG_SYSTEM, "Alarm",
- "Alarm: %s\r\n"
- "Channel: %d\r\n",
- alarm_str, p->channel);
+ publish_channel_alarm(p->channel, alarm_str);
}
if (report_alarms & REPORT_SPAN_ALARMS && p->manages_span_alarms) {
ast_log(LOG_WARNING, "Detected alarm on span %d: %s\n", p->span, alarm_str);
- /*** DOCUMENTATION
- <managerEventInstance>
- <synopsis>Raised when an alarm is set on a DAHDI span.</synopsis>
- </managerEventInstance>
- ***/
- manager_event(EVENT_FLAG_SYSTEM, "SpanAlarm",
- "Alarm: %s\r\n"
- "Span: %d\r\n",
- alarm_str, p->span);
+ publish_span_alarm(p->span, alarm_str);
}
}
@@ -10083,6 +10230,26 @@ static int dahdi_wink(struct dahdi_pvt *p, int idx)
return 0;
}
+static void publish_dnd_state(int channel, const char *status)
+{
+ RAII_VAR(struct ast_json *, body, NULL, ast_json_unref);
+ RAII_VAR(struct ast_str *, dahdichan, ast_str_create(32), ast_free);
+ if (!dahdichan) {
+ return;
+ }
+
+ ast_str_set(&dahdichan, 0, "%d", channel);
+
+ body = ast_json_pack("{s: s, s: s}",
+ "DAHDIChannel", ast_str_buffer(dahdichan),
+ "Status", status);
+ if (!body) {
+ return;
+ }
+
+ ast_manager_publish_event("DNDState", EVENT_FLAG_SYSTEM, body);
+}
+
/*! \brief enable or disable the chan_dahdi Do-Not-Disturb mode for a DAHDI channel
* \param dahdichan "Physical" DAHDI channel (e.g: DAHDI/5)
* \param flag on 1 to enable, 0 to disable, -1 return dnd value
@@ -10107,24 +10274,7 @@ static int dahdi_dnd(struct dahdi_pvt *dahdichan, int flag)
ast_verb(3, "%s DND on channel %d\n",
flag? "Enabled" : "Disabled",
dahdichan->channel);
- /*** DOCUMENTATION
- <managerEventInstance>
- <synopsis>Raised when the Do Not Disturb state is changed on a DAHDI channel.</synopsis>
- <syntax>
- <parameter name="Status">
- <enumlist>
- <enum name="enabled"/>
- <enum name="disabled"/>
- </enumlist>
- </parameter>
- </syntax>
- </managerEventInstance>
- ***/
- manager_event(EVENT_FLAG_SYSTEM, "DNDState",
- "Channel: DAHDI/%d\r\n"
- "Status: %s\r\n", dahdichan->channel,
- flag? "enabled" : "disabled");
-
+ publish_dnd_state(dahdichan->channel, flag ? "enabled" : "disabled");
return 0;
}
@@ -17154,6 +17304,7 @@ static int __unload_module(void)
ast_cond_destroy(&ss_thread_complete);
dahdi_tech.capabilities = ast_format_cap_destroy(dahdi_tech.capabilities);
+ STASIS_MESSAGE_TYPE_CLEANUP(dahdichannel_type);
return 0;
}
@@ -19154,6 +19305,10 @@ static int load_module(void)
int y;
#endif /* defined(HAVE_PRI) || defined(HAVE_SS7) */
+ if (STASIS_MESSAGE_TYPE_INIT(dahdichannel_type)) {
+ return AST_MODULE_LOAD_FAILURE;
+ }
+
if (!(dahdi_tech.capabilities = ast_format_cap_alloc())) {
return AST_MODULE_LOAD_FAILURE;
}