summaryrefslogtreecommitdiff
path: root/main/stasis_channels.c
diff options
context:
space:
mode:
Diffstat (limited to 'main/stasis_channels.c')
-rw-r--r--main/stasis_channels.c141
1 files changed, 117 insertions, 24 deletions
diff --git a/main/stasis_channels.c b/main/stasis_channels.c
index 6dddb0a5e..d121279d8 100644
--- a/main/stasis_channels.c
+++ b/main/stasis_channels.c
@@ -32,10 +32,11 @@
ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
-#include "asterisk/stasis.h"
#include "asterisk/astobj2.h"
-#include "asterisk/stasis_channels.h"
+#include "asterisk/json.h"
#include "asterisk/pbx.h"
+#include "asterisk/stasis.h"
+#include "asterisk/stasis_channels.h"
/*** DOCUMENTATION
<managerEvent language="en_US" name="VarSet">
@@ -621,25 +622,25 @@ struct ast_json *ast_channel_snapshot_to_json(const struct ast_channel_snapshot
return NULL;
}
- json_chan = ast_json_pack("{ s: s, s: s, s: s, s: s, s: s, s: s, s: s,"
- " s: s, s: s, s: s, s: s, s: o, s: o, s: o,"
- " s: o"
- "}",
- "name", snapshot->name,
- "state", ast_state2str(snapshot->state),
- "accountcode", snapshot->accountcode,
- "peeraccount", snapshot->peeraccount,
- "userfield", snapshot->userfield,
- "uniqueid", snapshot->uniqueid,
- "linkedid", snapshot->linkedid,
- "parkinglot", snapshot->parkinglot,
- "hangupsource", snapshot->hangupsource,
- "appl", snapshot->appl,
- "data", snapshot->data,
- "dialplan", ast_json_dialplan_cep(snapshot->context, snapshot->exten, snapshot->priority),
- "caller", ast_json_name_number(snapshot->caller_name, snapshot->caller_number),
- "connected", ast_json_name_number(snapshot->connected_name, snapshot->connected_number),
- "creationtime", ast_json_timeval(snapshot->creationtime, NULL));
+ json_chan = ast_json_pack(
+ /* Broken up into groups of three for readability */
+ "{ s: s, s: s, s: s,"
+ " s: o, s: o, s: s,"
+ " s: o, s: o }",
+ /* First line */
+ "id", snapshot->uniqueid,
+ "name", snapshot->name,
+ "state", ast_state2str(snapshot->state),
+ /* Second line */
+ "caller", ast_json_name_number(
+ snapshot->caller_name, snapshot->caller_number),
+ "connected", ast_json_name_number(
+ snapshot->connected_name, snapshot->connected_number),
+ "accountcode", snapshot->accountcode,
+ /* Third line */
+ "dialplan", ast_json_dialplan_cep(
+ snapshot->context, snapshot->exten, snapshot->priority),
+ "creationtime", ast_json_timeval(snapshot->creationtime, NULL));
return ast_json_ref(json_chan);
}
@@ -675,6 +676,91 @@ int ast_channel_snapshot_caller_id_equal(
strcmp(old_snapshot->caller_name, new_snapshot->caller_name) == 0;
}
+static struct ast_json *channel_blob_to_json(struct stasis_message *message,
+ const char *type)
+{
+ RAII_VAR(struct ast_json *, out, NULL, ast_json_unref);
+ struct ast_channel_blob *channel_blob = stasis_message_data(message);
+ struct ast_json *blob = channel_blob->blob;
+ struct ast_channel_snapshot *snapshot = channel_blob->snapshot;
+ const struct timeval *tv = stasis_message_timestamp(message);
+ int res = 0;
+
+ if (blob == NULL || ast_json_is_null(blob)) {
+ out = ast_json_object_create();
+ } else {
+ /* blobs are immutable, so shallow copies are fine */
+ out = ast_json_copy(blob);
+ }
+
+ if (!out) {
+ return NULL;
+ }
+
+ res |= ast_json_object_set(out, "type", ast_json_string_create(type));
+ res |= ast_json_object_set(out, "timestamp",
+ ast_json_timeval(*tv, NULL));
+
+ /* For global channel messages, the snapshot is optional */
+ if (snapshot) {
+ res |= ast_json_object_set(out, "channel",
+ ast_channel_snapshot_to_json(snapshot));
+ }
+
+ if (res != 0) {
+ return NULL;
+ }
+
+ return ast_json_ref(out);
+}
+
+static struct ast_json *dtmf_end_to_json(struct stasis_message *message)
+{
+ struct ast_channel_blob *channel_blob = stasis_message_data(message);
+ struct ast_json *blob = channel_blob->blob;
+ struct ast_channel_snapshot *snapshot = channel_blob->snapshot;
+ const char *direction =
+ ast_json_string_get(ast_json_object_get(blob, "direction"));
+ const struct timeval *tv = stasis_message_timestamp(message);
+
+ /* Only present received DTMF end events as JSON */
+ if (strcasecmp("Received", direction) != 0) {
+ return NULL;
+ }
+
+ return ast_json_pack("{s: s, s: o, s: O, s: O, s: o}",
+ "type", "ChannelDtmfReceived",
+ "timestamp", ast_json_timeval(*tv, NULL),
+ "digit", ast_json_object_get(blob, "digit"),
+ "duration_ms", ast_json_object_get(blob, "duration_ms"),
+ "channel", ast_channel_snapshot_to_json(snapshot));
+}
+
+static struct ast_json *user_event_to_json(struct stasis_message *message)
+{
+ struct ast_channel_blob *channel_blob = stasis_message_data(message);
+ struct ast_json *blob = channel_blob->blob;
+ struct ast_channel_snapshot *snapshot = channel_blob->snapshot;
+ const struct timeval *tv = stasis_message_timestamp(message);
+
+ return ast_json_pack("{s: s, s: o, s: O, s: O, s: o}",
+ "type", "ChannelUserevent",
+ "timestamp", ast_json_timeval(*tv, NULL),
+ "eventname", ast_json_object_get(blob, "eventname"),
+ "userevent", blob,
+ "channel", ast_channel_snapshot_to_json(snapshot));
+}
+
+static struct ast_json *varset_to_json(struct stasis_message *message)
+{
+ return channel_blob_to_json(message, "ChannelVarset");
+}
+
+static struct ast_json *hangup_request_to_json(struct stasis_message *message)
+{
+ return channel_blob_to_json(message, "ChannelHangupRequest");
+}
+
/*!
* @{ \brief Define channel message types.
*/
@@ -682,11 +768,18 @@ STASIS_MESSAGE_TYPE_DEFN(ast_channel_snapshot_type);
STASIS_MESSAGE_TYPE_DEFN(ast_channel_dial_type);
STASIS_MESSAGE_TYPE_DEFN(ast_channel_varset_type,
.to_ami = varset_to_ami,
+ .to_json = varset_to_json,
+ );
+STASIS_MESSAGE_TYPE_DEFN(ast_channel_user_event_type,
+ .to_json = user_event_to_json,
+ );
+STASIS_MESSAGE_TYPE_DEFN(ast_channel_hangup_request_type,
+ .to_json = hangup_request_to_json,
);
-STASIS_MESSAGE_TYPE_DEFN(ast_channel_user_event_type);
-STASIS_MESSAGE_TYPE_DEFN(ast_channel_hangup_request_type);
STASIS_MESSAGE_TYPE_DEFN(ast_channel_dtmf_begin_type);
-STASIS_MESSAGE_TYPE_DEFN(ast_channel_dtmf_end_type);
+STASIS_MESSAGE_TYPE_DEFN(ast_channel_dtmf_end_type,
+ .to_json = dtmf_end_to_json,
+ );
STASIS_MESSAGE_TYPE_DEFN(ast_channel_hold_type);
STASIS_MESSAGE_TYPE_DEFN(ast_channel_unhold_type);
STASIS_MESSAGE_TYPE_DEFN(ast_channel_chanspy_start_type);