summaryrefslogtreecommitdiff
path: root/main/channel.c
diff options
context:
space:
mode:
authorDavid M. Lee <dlee@digium.com>2013-04-15 16:22:03 +0000
committerDavid M. Lee <dlee@digium.com>2013-04-15 16:22:03 +0000
commit2450722f52401b8537e9c0ffb1192f38b7dd146d (patch)
tree2a798888a6601082b150a2eada805b0b82aadaa4 /main/channel.c
parentc6cf12408edc133c229b323a9039e04f3c12c248 (diff)
DTMF events are now published on a channel's stasis_topic. AMI was
refactored to use these events rather than producing the events directly in channel.c. Finally, the code was added to app_stasis to produce DTMF events on the WebSocket. The AMI events are completely backward compatible, including sending events on transmitted DTMF, and sending DTMF start events. The Stasis-HTTP events are somewhat simplified. Since DTMF start and DTMF send events are generally less useful, Stasis-HTTP will only send events on received DTMF end. (closes issue ASTERISK-21282) (closes issue ASTERISK-21359) Review: https://reviewboard.asterisk.org/r/2439 git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@385734 65c4cc65-6c06-0410-ace0-fbb531ad65f3
Diffstat (limited to 'main/channel.c')
-rw-r--r--main/channel.c92
1 files changed, 53 insertions, 39 deletions
diff --git a/main/channel.c b/main/channel.c
index a9bcf4481..415af35e2 100644
--- a/main/channel.c
+++ b/main/channel.c
@@ -3714,42 +3714,56 @@ int ast_waitfordigit_full(struct ast_channel *c, int timeout_ms, int audiofd, in
return 0; /* Time is up */
}
-static void send_dtmf_event(struct ast_channel *chan, const char *direction, const char digit, const char *begin, const char *end)
+enum DtmfDirection {
+ DTMF_RECEIVED,
+ DTMF_SENT
+};
+
+static const char *dtmf_direction_to_string(enum DtmfDirection direction)
{
- /*** DOCUMENTATION
- <managerEventInstance>
- <synopsis>Raised when a DTMF digit has started or ended on a channel.</synopsis>
- <syntax>
- <parameter name="Direction">
- <enumlist>
- <enum name="Received"/>
- <enum name="Sent"/>
- </enumlist>
- </parameter>
- <parameter name="Begin">
- <enumlist>
- <enum name="Yes"/>
- <enum name="No"/>
- </enumlist>
- </parameter>
- <parameter name="End">
- <enumlist>
- <enum name="Yes"/>
- <enum name="No"/>
- </enumlist>
- </parameter>
- </syntax>
- </managerEventInstance>
- ***/
- ast_manager_event(chan, EVENT_FLAG_DTMF,
- "DTMF",
- "Channel: %s\r\n"
- "Uniqueid: %s\r\n"
- "Digit: %c\r\n"
- "Direction: %s\r\n"
- "Begin: %s\r\n"
- "End: %s\r\n",
- ast_channel_name(chan), ast_channel_uniqueid(chan), digit, direction, begin, end);
+ switch (direction) {
+ case DTMF_RECEIVED:
+ return "Received";
+ case DTMF_SENT:
+ return "Sent";
+ }
+
+ return "?";
+}
+
+static void send_dtmf_begin_event(struct ast_channel *chan,
+ enum DtmfDirection direction, const char digit)
+{
+ RAII_VAR(struct ast_json *, blob, NULL, ast_json_unref);
+ char digit_str[] = { digit, '\0' };
+
+ blob = ast_json_pack("{ s: s, s: s, s: s }",
+ "type", "dtmf_begin",
+ "digit", digit_str,
+ "direction", dtmf_direction_to_string(direction));
+ if (!blob) {
+ return;
+ }
+
+ publish_channel_blob(chan, blob);
+}
+
+static void send_dtmf_end_event(struct ast_channel *chan,
+ enum DtmfDirection direction, const char digit, long duration_ms)
+{
+ RAII_VAR(struct ast_json *, blob, NULL, ast_json_unref);
+ char digit_str[] = { digit, '\0' };
+
+ blob = ast_json_pack("{ s: s, s: s, s: s, s: i }",
+ "type", "dtmf_end",
+ "digit", digit_str,
+ "direction", dtmf_direction_to_string(direction),
+ "duration_ms", duration_ms);
+ if (!blob) {
+ return;
+ }
+
+ publish_channel_blob(chan, blob);
}
static void ast_read_generator_actions(struct ast_channel *chan, struct ast_frame *f)
@@ -4104,7 +4118,7 @@ static struct ast_frame *__ast_read(struct ast_channel *chan, int dropaudio)
}
break;
case AST_FRAME_DTMF_END:
- send_dtmf_event(chan, "Received", f->subclass.integer, "No", "Yes");
+ send_dtmf_end_event(chan, DTMF_RECEIVED, f->subclass.integer, f->len);
ast_log(LOG_DTMF, "DTMF end '%c' received on %s, duration %ld ms\n", f->subclass.integer, ast_channel_name(chan), f->len);
/* Queue it up if DTMF is deferred, or if DTMF emulation is forced. */
if (ast_test_flag(ast_channel_flags(chan), AST_FLAG_DEFER_DTMF) || ast_test_flag(ast_channel_flags(chan), AST_FLAG_EMULATE_DTMF)) {
@@ -4190,7 +4204,7 @@ static struct ast_frame *__ast_read(struct ast_channel *chan, int dropaudio)
}
break;
case AST_FRAME_DTMF_BEGIN:
- send_dtmf_event(chan, "Received", f->subclass.integer, "Yes", "No");
+ send_dtmf_begin_event(chan, DTMF_RECEIVED, f->subclass.integer);
ast_log(LOG_DTMF, "DTMF begin '%c' received on %s\n", f->subclass.integer, ast_channel_name(chan));
if (ast_test_flag(ast_channel_flags(chan), AST_FLAG_DEFER_DTMF | AST_FLAG_END_DTMF_ONLY | AST_FLAG_EMULATE_DTMF) ||
(!ast_tvzero(*ast_channel_dtmf_tv(chan)) &&
@@ -5042,7 +5056,7 @@ int ast_write(struct ast_channel *chan, struct ast_frame *fr)
if (old_frame != fr)
f = fr;
}
- send_dtmf_event(chan, "Sent", fr->subclass.integer, "Yes", "No");
+ send_dtmf_begin_event(chan, DTMF_SENT, fr->subclass.integer);
ast_clear_flag(ast_channel_flags(chan), AST_FLAG_BLOCKING);
ast_channel_unlock(chan);
res = ast_senddigit_begin(chan, fr->subclass.integer);
@@ -5058,7 +5072,7 @@ int ast_write(struct ast_channel *chan, struct ast_frame *fr)
ast_frfree(new_frame);
}
}
- send_dtmf_event(chan, "Sent", fr->subclass.integer, "No", "Yes");
+ send_dtmf_end_event(chan, DTMF_SENT, fr->subclass.integer, fr->len);
ast_clear_flag(ast_channel_flags(chan), AST_FLAG_BLOCKING);
ast_channel_unlock(chan);
res = ast_senddigit_end(chan, fr->subclass.integer, fr->len);