[Asterisk-code-review] res/res_ari_channels.c: Added new ARI /ari/channels/<channelId>/dump (...asterisk[master])
sungtae kim
asteriskteam at digium.com
Sat Mar 16 16:33:34 CDT 2019
sungtae kim has uploaded this change for review. ( https://gerrit.asterisk.org/c/asterisk/+/11162
Change subject: res/res_ari_channels.c: Added new ARI /ari/channels/<channelId>/dump
......................................................................
res/res_ari_channels.c: Added new ARI /ari/channels/<channelId>/dump
Added new ARI for channel dump. It is replication of app_dumpchan.c.
It will be helpful to check the more detail channel information via
ARI.
ASTERISK-28339
Change-Id: Ie5b6c8b20a2bda5168ea56114f4241bc818cab10
---
M res/ari/ari_model_validators.c
M res/ari/ari_model_validators.h
M res/ari/resource_channels.c
M res/ari/resource_channels.h
M res/res_ari_channels.c
M rest-api/api-docs/channels.json
6 files changed, 1,011 insertions(+), 2 deletions(-)
git pull ssh://gerrit.asterisk.org:29418/asterisk refs/changes/62/11162/1
diff --git a/res/ari/ari_model_validators.c b/res/ari/ari_model_validators.c
index d5f1885..27db9c0 100644
--- a/res/ari/ari_model_validators.c
+++ b/res/ari/ari_model_validators.c
@@ -1261,6 +1261,556 @@
return ast_ari_validate_channel;
}
+int ast_ari_validate_channel_dump(struct ast_json *json)
+{
+ int res = 1;
+ struct ast_json_iter *iter;
+ int has_1st_file_descriptor = 0;
+ int has_answer_time = 0;
+ int has_app_data = 0;
+ int has_app_name = 0;
+ int has_blocking_in = 0;
+ int has_bridge_id = 0;
+ int has_call_group = 0;
+ int has_channel = 0;
+ int has_dnid_number = 0;
+ int has_dnid_plan = 0;
+ int has_elapsed_time = 0;
+ int has_frames_in = 0;
+ int has_frames_in_desc = 0;
+ int has_frames_out = 0;
+ int has_frames_out_desc = 0;
+ int has_hold_state = 0;
+ int has_id = 0;
+ int has_name = 0;
+ int has_native_format = 0;
+ int has_parkinglot = 0;
+ int has_pickup_group = 0;
+ int has_raw_read_format = 0;
+ int has_raw_write_format = 0;
+ int has_rdnis = 0;
+ int has_read_format = 0;
+ int has_read_transcode = 0;
+ int has_read_transcode_path = 0;
+ int has_rings = 0;
+ int has_time_to_hangup = 0;
+ int has_type = 0;
+ int has_write_format = 0;
+ int has_write_transcode = 0;
+ int has_write_transcode_path = 0;
+
+ for (iter = ast_json_object_iter(json); iter; iter = ast_json_object_iter_next(json, iter)) {
+ if (strcmp("1st_file_descriptor", ast_json_object_iter_key(iter)) == 0) {
+ int prop_is_valid;
+ has_1st_file_descriptor = 1;
+ prop_is_valid = ast_ari_validate_long(
+ ast_json_object_iter_value(iter));
+ if (!prop_is_valid) {
+ ast_log(LOG_ERROR, "ARI ChannelDump field 1st_file_descriptor failed validation\n");
+ res = 0;
+ }
+ } else
+ if (strcmp("answer_time", ast_json_object_iter_key(iter)) == 0) {
+ int prop_is_valid;
+ has_answer_time = 1;
+ prop_is_valid = ast_ari_validate_date(
+ ast_json_object_iter_value(iter));
+ if (!prop_is_valid) {
+ ast_log(LOG_ERROR, "ARI ChannelDump field answer_time failed validation\n");
+ res = 0;
+ }
+ } else
+ if (strcmp("app_data", ast_json_object_iter_key(iter)) == 0) {
+ int prop_is_valid;
+ has_app_data = 1;
+ prop_is_valid = ast_ari_validate_string(
+ ast_json_object_iter_value(iter));
+ if (!prop_is_valid) {
+ ast_log(LOG_ERROR, "ARI ChannelDump field app_data failed validation\n");
+ res = 0;
+ }
+ } else
+ if (strcmp("app_name", ast_json_object_iter_key(iter)) == 0) {
+ int prop_is_valid;
+ has_app_name = 1;
+ prop_is_valid = ast_ari_validate_string(
+ ast_json_object_iter_value(iter));
+ if (!prop_is_valid) {
+ ast_log(LOG_ERROR, "ARI ChannelDump field app_name failed validation\n");
+ res = 0;
+ }
+ } else
+ if (strcmp("blocking_in", ast_json_object_iter_key(iter)) == 0) {
+ int prop_is_valid;
+ has_blocking_in = 1;
+ prop_is_valid = ast_ari_validate_string(
+ ast_json_object_iter_value(iter));
+ if (!prop_is_valid) {
+ ast_log(LOG_ERROR, "ARI ChannelDump field blocking_in failed validation\n");
+ res = 0;
+ }
+ } else
+ if (strcmp("bridge_id", ast_json_object_iter_key(iter)) == 0) {
+ int prop_is_valid;
+ has_bridge_id = 1;
+ prop_is_valid = ast_ari_validate_string(
+ ast_json_object_iter_value(iter));
+ if (!prop_is_valid) {
+ ast_log(LOG_ERROR, "ARI ChannelDump field bridge_id failed validation\n");
+ res = 0;
+ }
+ } else
+ if (strcmp("call_group", ast_json_object_iter_key(iter)) == 0) {
+ int prop_is_valid;
+ has_call_group = 1;
+ prop_is_valid = ast_ari_validate_string(
+ ast_json_object_iter_value(iter));
+ if (!prop_is_valid) {
+ ast_log(LOG_ERROR, "ARI ChannelDump field call_group failed validation\n");
+ res = 0;
+ }
+ } else
+ if (strcmp("channel", ast_json_object_iter_key(iter)) == 0) {
+ int prop_is_valid;
+ has_channel = 1;
+ prop_is_valid = ast_ari_validate_channel(
+ ast_json_object_iter_value(iter));
+ if (!prop_is_valid) {
+ ast_log(LOG_ERROR, "ARI ChannelDump field channel failed validation\n");
+ res = 0;
+ }
+ } else
+ if (strcmp("dnid_number", ast_json_object_iter_key(iter)) == 0) {
+ int prop_is_valid;
+ has_dnid_number = 1;
+ prop_is_valid = ast_ari_validate_string(
+ ast_json_object_iter_value(iter));
+ if (!prop_is_valid) {
+ ast_log(LOG_ERROR, "ARI ChannelDump field dnid_number failed validation\n");
+ res = 0;
+ }
+ } else
+ if (strcmp("dnid_plan", ast_json_object_iter_key(iter)) == 0) {
+ int prop_is_valid;
+ has_dnid_plan = 1;
+ prop_is_valid = ast_ari_validate_long(
+ ast_json_object_iter_value(iter));
+ if (!prop_is_valid) {
+ ast_log(LOG_ERROR, "ARI ChannelDump field dnid_plan failed validation\n");
+ res = 0;
+ }
+ } else
+ if (strcmp("elapsed_time", ast_json_object_iter_key(iter)) == 0) {
+ int prop_is_valid;
+ has_elapsed_time = 1;
+ prop_is_valid = ast_ari_validate_string(
+ ast_json_object_iter_value(iter));
+ if (!prop_is_valid) {
+ ast_log(LOG_ERROR, "ARI ChannelDump field elapsed_time failed validation\n");
+ res = 0;
+ }
+ } else
+ if (strcmp("frames_in", ast_json_object_iter_key(iter)) == 0) {
+ int prop_is_valid;
+ has_frames_in = 1;
+ prop_is_valid = ast_ari_validate_long(
+ ast_json_object_iter_value(iter));
+ if (!prop_is_valid) {
+ ast_log(LOG_ERROR, "ARI ChannelDump field frames_in failed validation\n");
+ res = 0;
+ }
+ } else
+ if (strcmp("frames_in_desc", ast_json_object_iter_key(iter)) == 0) {
+ int prop_is_valid;
+ has_frames_in_desc = 1;
+ prop_is_valid = ast_ari_validate_string(
+ ast_json_object_iter_value(iter));
+ if (!prop_is_valid) {
+ ast_log(LOG_ERROR, "ARI ChannelDump field frames_in_desc failed validation\n");
+ res = 0;
+ }
+ } else
+ if (strcmp("frames_out", ast_json_object_iter_key(iter)) == 0) {
+ int prop_is_valid;
+ has_frames_out = 1;
+ prop_is_valid = ast_ari_validate_long(
+ ast_json_object_iter_value(iter));
+ if (!prop_is_valid) {
+ ast_log(LOG_ERROR, "ARI ChannelDump field frames_out failed validation\n");
+ res = 0;
+ }
+ } else
+ if (strcmp("frames_out_desc", ast_json_object_iter_key(iter)) == 0) {
+ int prop_is_valid;
+ has_frames_out_desc = 1;
+ prop_is_valid = ast_ari_validate_string(
+ ast_json_object_iter_value(iter));
+ if (!prop_is_valid) {
+ ast_log(LOG_ERROR, "ARI ChannelDump field frames_out_desc failed validation\n");
+ res = 0;
+ }
+ } else
+ if (strcmp("hold_state", ast_json_object_iter_key(iter)) == 0) {
+ int prop_is_valid;
+ has_hold_state = 1;
+ prop_is_valid = ast_ari_validate_long(
+ ast_json_object_iter_value(iter));
+ if (!prop_is_valid) {
+ ast_log(LOG_ERROR, "ARI ChannelDump field hold_state failed validation\n");
+ res = 0;
+ }
+ } else
+ if (strcmp("id", ast_json_object_iter_key(iter)) == 0) {
+ int prop_is_valid;
+ has_id = 1;
+ prop_is_valid = ast_ari_validate_string(
+ ast_json_object_iter_value(iter));
+ if (!prop_is_valid) {
+ ast_log(LOG_ERROR, "ARI ChannelDump field id failed validation\n");
+ res = 0;
+ }
+ } else
+ if (strcmp("name", ast_json_object_iter_key(iter)) == 0) {
+ int prop_is_valid;
+ has_name = 1;
+ prop_is_valid = ast_ari_validate_string(
+ ast_json_object_iter_value(iter));
+ if (!prop_is_valid) {
+ ast_log(LOG_ERROR, "ARI ChannelDump field name failed validation\n");
+ res = 0;
+ }
+ } else
+ if (strcmp("native_format", ast_json_object_iter_key(iter)) == 0) {
+ int prop_is_valid;
+ has_native_format = 1;
+ prop_is_valid = ast_ari_validate_string(
+ ast_json_object_iter_value(iter));
+ if (!prop_is_valid) {
+ ast_log(LOG_ERROR, "ARI ChannelDump field native_format failed validation\n");
+ res = 0;
+ }
+ } else
+ if (strcmp("parkinglot", ast_json_object_iter_key(iter)) == 0) {
+ int prop_is_valid;
+ has_parkinglot = 1;
+ prop_is_valid = ast_ari_validate_string(
+ ast_json_object_iter_value(iter));
+ if (!prop_is_valid) {
+ ast_log(LOG_ERROR, "ARI ChannelDump field parkinglot failed validation\n");
+ res = 0;
+ }
+ } else
+ if (strcmp("pickup_group", ast_json_object_iter_key(iter)) == 0) {
+ int prop_is_valid;
+ has_pickup_group = 1;
+ prop_is_valid = ast_ari_validate_string(
+ ast_json_object_iter_value(iter));
+ if (!prop_is_valid) {
+ ast_log(LOG_ERROR, "ARI ChannelDump field pickup_group failed validation\n");
+ res = 0;
+ }
+ } else
+ if (strcmp("raw_read_format", ast_json_object_iter_key(iter)) == 0) {
+ int prop_is_valid;
+ has_raw_read_format = 1;
+ prop_is_valid = ast_ari_validate_string(
+ ast_json_object_iter_value(iter));
+ if (!prop_is_valid) {
+ ast_log(LOG_ERROR, "ARI ChannelDump field raw_read_format failed validation\n");
+ res = 0;
+ }
+ } else
+ if (strcmp("raw_write_format", ast_json_object_iter_key(iter)) == 0) {
+ int prop_is_valid;
+ has_raw_write_format = 1;
+ prop_is_valid = ast_ari_validate_string(
+ ast_json_object_iter_value(iter));
+ if (!prop_is_valid) {
+ ast_log(LOG_ERROR, "ARI ChannelDump field raw_write_format failed validation\n");
+ res = 0;
+ }
+ } else
+ if (strcmp("rdnis", ast_json_object_iter_key(iter)) == 0) {
+ int prop_is_valid;
+ has_rdnis = 1;
+ prop_is_valid = ast_ari_validate_string(
+ ast_json_object_iter_value(iter));
+ if (!prop_is_valid) {
+ ast_log(LOG_ERROR, "ARI ChannelDump field rdnis failed validation\n");
+ res = 0;
+ }
+ } else
+ if (strcmp("read_format", ast_json_object_iter_key(iter)) == 0) {
+ int prop_is_valid;
+ has_read_format = 1;
+ prop_is_valid = ast_ari_validate_string(
+ ast_json_object_iter_value(iter));
+ if (!prop_is_valid) {
+ ast_log(LOG_ERROR, "ARI ChannelDump field read_format failed validation\n");
+ res = 0;
+ }
+ } else
+ if (strcmp("read_transcode", ast_json_object_iter_key(iter)) == 0) {
+ int prop_is_valid;
+ has_read_transcode = 1;
+ prop_is_valid = ast_ari_validate_long(
+ ast_json_object_iter_value(iter));
+ if (!prop_is_valid) {
+ ast_log(LOG_ERROR, "ARI ChannelDump field read_transcode failed validation\n");
+ res = 0;
+ }
+ } else
+ if (strcmp("read_transcode_path", ast_json_object_iter_key(iter)) == 0) {
+ int prop_is_valid;
+ has_read_transcode_path = 1;
+ prop_is_valid = ast_ari_validate_string(
+ ast_json_object_iter_value(iter));
+ if (!prop_is_valid) {
+ ast_log(LOG_ERROR, "ARI ChannelDump field read_transcode_path failed validation\n");
+ res = 0;
+ }
+ } else
+ if (strcmp("rings", ast_json_object_iter_key(iter)) == 0) {
+ int prop_is_valid;
+ has_rings = 1;
+ prop_is_valid = ast_ari_validate_long(
+ ast_json_object_iter_value(iter));
+ if (!prop_is_valid) {
+ ast_log(LOG_ERROR, "ARI ChannelDump field rings failed validation\n");
+ res = 0;
+ }
+ } else
+ if (strcmp("time_to_hangup", ast_json_object_iter_key(iter)) == 0) {
+ int prop_is_valid;
+ has_time_to_hangup = 1;
+ prop_is_valid = ast_ari_validate_long(
+ ast_json_object_iter_value(iter));
+ if (!prop_is_valid) {
+ ast_log(LOG_ERROR, "ARI ChannelDump field time_to_hangup failed validation\n");
+ res = 0;
+ }
+ } else
+ if (strcmp("type", ast_json_object_iter_key(iter)) == 0) {
+ int prop_is_valid;
+ has_type = 1;
+ prop_is_valid = ast_ari_validate_string(
+ ast_json_object_iter_value(iter));
+ if (!prop_is_valid) {
+ ast_log(LOG_ERROR, "ARI ChannelDump field type failed validation\n");
+ res = 0;
+ }
+ } else
+ if (strcmp("write_format", ast_json_object_iter_key(iter)) == 0) {
+ int prop_is_valid;
+ has_write_format = 1;
+ prop_is_valid = ast_ari_validate_string(
+ ast_json_object_iter_value(iter));
+ if (!prop_is_valid) {
+ ast_log(LOG_ERROR, "ARI ChannelDump field write_format failed validation\n");
+ res = 0;
+ }
+ } else
+ if (strcmp("write_transcode", ast_json_object_iter_key(iter)) == 0) {
+ int prop_is_valid;
+ has_write_transcode = 1;
+ prop_is_valid = ast_ari_validate_long(
+ ast_json_object_iter_value(iter));
+ if (!prop_is_valid) {
+ ast_log(LOG_ERROR, "ARI ChannelDump field write_transcode failed validation\n");
+ res = 0;
+ }
+ } else
+ if (strcmp("write_transcode_path", ast_json_object_iter_key(iter)) == 0) {
+ int prop_is_valid;
+ has_write_transcode_path = 1;
+ prop_is_valid = ast_ari_validate_string(
+ ast_json_object_iter_value(iter));
+ if (!prop_is_valid) {
+ ast_log(LOG_ERROR, "ARI ChannelDump field write_transcode_path failed validation\n");
+ res = 0;
+ }
+ } else
+ {
+ ast_log(LOG_ERROR,
+ "ARI ChannelDump has undocumented field %s\n",
+ ast_json_object_iter_key(iter));
+ res = 0;
+ }
+ }
+
+ if (!has_1st_file_descriptor) {
+ ast_log(LOG_ERROR, "ARI ChannelDump missing required field 1st_file_descriptor\n");
+ res = 0;
+ }
+
+ if (!has_answer_time) {
+ ast_log(LOG_ERROR, "ARI ChannelDump missing required field answer_time\n");
+ res = 0;
+ }
+
+ if (!has_app_data) {
+ ast_log(LOG_ERROR, "ARI ChannelDump missing required field app_data\n");
+ res = 0;
+ }
+
+ if (!has_app_name) {
+ ast_log(LOG_ERROR, "ARI ChannelDump missing required field app_name\n");
+ res = 0;
+ }
+
+ if (!has_blocking_in) {
+ ast_log(LOG_ERROR, "ARI ChannelDump missing required field blocking_in\n");
+ res = 0;
+ }
+
+ if (!has_bridge_id) {
+ ast_log(LOG_ERROR, "ARI ChannelDump missing required field bridge_id\n");
+ res = 0;
+ }
+
+ if (!has_call_group) {
+ ast_log(LOG_ERROR, "ARI ChannelDump missing required field call_group\n");
+ res = 0;
+ }
+
+ if (!has_channel) {
+ ast_log(LOG_ERROR, "ARI ChannelDump missing required field channel\n");
+ res = 0;
+ }
+
+ if (!has_dnid_number) {
+ ast_log(LOG_ERROR, "ARI ChannelDump missing required field dnid_number\n");
+ res = 0;
+ }
+
+ if (!has_dnid_plan) {
+ ast_log(LOG_ERROR, "ARI ChannelDump missing required field dnid_plan\n");
+ res = 0;
+ }
+
+ if (!has_elapsed_time) {
+ ast_log(LOG_ERROR, "ARI ChannelDump missing required field elapsed_time\n");
+ res = 0;
+ }
+
+ if (!has_frames_in) {
+ ast_log(LOG_ERROR, "ARI ChannelDump missing required field frames_in\n");
+ res = 0;
+ }
+
+ if (!has_frames_in_desc) {
+ ast_log(LOG_ERROR, "ARI ChannelDump missing required field frames_in_desc\n");
+ res = 0;
+ }
+
+ if (!has_frames_out) {
+ ast_log(LOG_ERROR, "ARI ChannelDump missing required field frames_out\n");
+ res = 0;
+ }
+
+ if (!has_frames_out_desc) {
+ ast_log(LOG_ERROR, "ARI ChannelDump missing required field frames_out_desc\n");
+ res = 0;
+ }
+
+ if (!has_hold_state) {
+ ast_log(LOG_ERROR, "ARI ChannelDump missing required field hold_state\n");
+ res = 0;
+ }
+
+ if (!has_id) {
+ ast_log(LOG_ERROR, "ARI ChannelDump missing required field id\n");
+ res = 0;
+ }
+
+ if (!has_name) {
+ ast_log(LOG_ERROR, "ARI ChannelDump missing required field name\n");
+ res = 0;
+ }
+
+ if (!has_native_format) {
+ ast_log(LOG_ERROR, "ARI ChannelDump missing required field native_format\n");
+ res = 0;
+ }
+
+ if (!has_parkinglot) {
+ ast_log(LOG_ERROR, "ARI ChannelDump missing required field parkinglot\n");
+ res = 0;
+ }
+
+ if (!has_pickup_group) {
+ ast_log(LOG_ERROR, "ARI ChannelDump missing required field pickup_group\n");
+ res = 0;
+ }
+
+ if (!has_raw_read_format) {
+ ast_log(LOG_ERROR, "ARI ChannelDump missing required field raw_read_format\n");
+ res = 0;
+ }
+
+ if (!has_raw_write_format) {
+ ast_log(LOG_ERROR, "ARI ChannelDump missing required field raw_write_format\n");
+ res = 0;
+ }
+
+ if (!has_rdnis) {
+ ast_log(LOG_ERROR, "ARI ChannelDump missing required field rdnis\n");
+ res = 0;
+ }
+
+ if (!has_read_format) {
+ ast_log(LOG_ERROR, "ARI ChannelDump missing required field read_format\n");
+ res = 0;
+ }
+
+ if (!has_read_transcode) {
+ ast_log(LOG_ERROR, "ARI ChannelDump missing required field read_transcode\n");
+ res = 0;
+ }
+
+ if (!has_read_transcode_path) {
+ ast_log(LOG_ERROR, "ARI ChannelDump missing required field read_transcode_path\n");
+ res = 0;
+ }
+
+ if (!has_rings) {
+ ast_log(LOG_ERROR, "ARI ChannelDump missing required field rings\n");
+ res = 0;
+ }
+
+ if (!has_time_to_hangup) {
+ ast_log(LOG_ERROR, "ARI ChannelDump missing required field time_to_hangup\n");
+ res = 0;
+ }
+
+ if (!has_type) {
+ ast_log(LOG_ERROR, "ARI ChannelDump missing required field type\n");
+ res = 0;
+ }
+
+ if (!has_write_format) {
+ ast_log(LOG_ERROR, "ARI ChannelDump missing required field write_format\n");
+ res = 0;
+ }
+
+ if (!has_write_transcode) {
+ ast_log(LOG_ERROR, "ARI ChannelDump missing required field write_transcode\n");
+ res = 0;
+ }
+
+ if (!has_write_transcode_path) {
+ ast_log(LOG_ERROR, "ARI ChannelDump missing required field write_transcode_path\n");
+ res = 0;
+ }
+
+ return res;
+}
+
+ari_validator ast_ari_validate_channel_dump_fn(void)
+{
+ return ast_ari_validate_channel_dump;
+}
+
int ast_ari_validate_dialed(struct ast_json *json)
{
int res = 1;
diff --git a/res/ari/ari_model_validators.h b/res/ari/ari_model_validators.h
index 484f9c1..9f6bf96 100644
--- a/res/ari/ari_model_validators.h
+++ b/res/ari/ari_model_validators.h
@@ -442,6 +442,24 @@
ari_validator ast_ari_validate_channel_fn(void);
/*!
+ * \brief Validator for ChannelDump.
+ *
+ * Channel's detail dump info.
+ *
+ * \param json JSON object to validate.
+ * \returns True (non-zero) if valid.
+ * \returns False (zero) if invalid.
+ */
+int ast_ari_validate_channel_dump(struct ast_json *json);
+
+/*!
+ * \brief Function pointer to ast_ari_validate_channel_dump().
+ *
+ * See \ref ast_ari_model_validators.h for more details.
+ */
+ari_validator ast_ari_validate_channel_dump_fn(void);
+
+/*!
* \brief Validator for Dialed.
*
* Dialed channel information.
@@ -1497,6 +1515,40 @@
* - language: string (required)
* - name: string (required)
* - state: string (required)
+ * ChannelDump
+ * - 1st_file_descriptor: long (required)
+ * - answer_time: Date (required)
+ * - app_data: string (required)
+ * - app_name: string (required)
+ * - blocking_in: string (required)
+ * - bridge_id: string (required)
+ * - call_group: string (required)
+ * - channel: Channel (required)
+ * - dnid_number: string (required)
+ * - dnid_plan: long (required)
+ * - elapsed_time: string (required)
+ * - frames_in: long (required)
+ * - frames_in_desc: string (required)
+ * - frames_out: long (required)
+ * - frames_out_desc: string (required)
+ * - hold_state: long (required)
+ * - id: string (required)
+ * - name: string (required)
+ * - native_format: string (required)
+ * - parkinglot: string (required)
+ * - pickup_group: string (required)
+ * - raw_read_format: string (required)
+ * - raw_write_format: string (required)
+ * - rdnis: string (required)
+ * - read_format: string (required)
+ * - read_transcode: long (required)
+ * - read_transcode_path: string (required)
+ * - rings: long (required)
+ * - time_to_hangup: long (required)
+ * - type: string (required)
+ * - write_format: string (required)
+ * - write_transcode: long (required)
+ * - write_transcode_path: string (required)
* Dialed
* DialplanCEP
* - context: string (required)
diff --git a/res/ari/resource_channels.c b/res/ari/resource_channels.c
index eca70ce..9f047ac 100644
--- a/res/ari/resource_channels.c
+++ b/res/ari/resource_channels.c
@@ -43,6 +43,7 @@
#include "asterisk/core_local.h"
#include "asterisk/dial.h"
#include "asterisk/max_forwards.h"
+#include "asterisk/translate.h"
#include "resource_channels.h"
#include <limits.h>
@@ -1966,3 +1967,132 @@
ast_ari_response_no_content(response);
}
+
+static struct ast_json *ari_channel_dump_create(const char *chan_id)
+{
+ struct ast_json *j_res;
+ struct ast_bridge *bridge;
+ char elapsed_time[100];
+ char cgrp[256];
+ char pgrp[256];
+ struct ast_str *format_buf = ast_str_alloca(AST_FORMAT_CAP_NAMES_LEN);
+ struct ast_str *write_transpath = ast_str_alloca(256);
+ struct ast_str *read_transpath = ast_str_alloca(256);
+ long elapsed_seconds;
+ struct ast_channel *chan;
+ struct ast_channel_snapshot *snapshot;
+
+
+ chan = ast_channel_get_by_name(chan_id);
+ if (!chan) {
+ return NULL;
+ }
+
+ snapshot = ast_channel_snapshot_get_latest(chan_id);
+ if (!snapshot) {
+ return NULL;
+ }
+
+ ast_channel_lock(chan);
+ bridge = ast_channel_get_bridge(chan);
+
+ snapshot = ast_channel_snapshot_get_latest(chan_id);
+
+ elapsed_seconds = ast_channel_get_duration(chan);
+ snprintf(elapsed_time, sizeof(elapsed_time), "%02ld:%02ld:%02ld",
+ elapsed_seconds / 3600,
+ (elapsed_seconds % 3600) / 60,
+ elapsed_seconds % 60
+ );
+
+ j_res = ast_json_pack("{"
+ "s: s, s: s, s: s,"
+ "s: o,"
+ "s: s, s: i, s: s,"
+ "s: s, s: i, s: o, s:i,"
+
+ "s: s, s: s, s: s,"
+ "s: s, s: s,"
+ "s: i, s: s, s: i, s: s,"
+ "s: i,"
+
+ "s: i, s: s,"
+ "s: i, s: s,"
+ "s: I, s: s, s: s,"
+ "s: s, s: s,"
+ "s: s, s: s, s: s"
+ "}",
+
+ "id", chan_id,
+ "name", ast_channel_name(chan),
+ "type", ast_channel_tech(chan)->type,
+
+ "channel", ast_channel_snapshot_to_json(snapshot, NULL),
+
+ "dnid_number", S_OR(ast_channel_dialed(chan)->number.str, ""),
+ "dnid_plan", ast_channel_dialed(chan)->number.plan,
+ "rdnis", S_COR(ast_channel_redirecting(chan)->from.number.valid, ast_channel_redirecting(chan)->from.number.str, ""),
+
+ "parkinglot", S_OR(ast_channel_parkinglot(chan), ""),
+ "rings", ast_channel_rings(chan),
+ "answer_time", ast_json_timeval(ast_channel_answertime(chan), NULL),
+ "hold_state", ast_channel_hold_state(chan),
+
+ "native_format", S_OR(ast_format_cap_get_names(ast_channel_nativeformats(chan), &format_buf), ""),
+ "write_format", S_OR(ast_format_get_name(ast_channel_writeformat(chan)), ""),
+ "read_format", S_OR(ast_format_get_name(ast_channel_readformat(chan)), ""),
+
+ "raw_write_format", S_OR(ast_format_get_name(ast_channel_rawwriteformat(chan)), ""),
+ "raw_read_format", S_OR(ast_format_get_name(ast_channel_rawreadformat(chan)), ""),
+
+ "write_transcode", ast_channel_writetrans(chan) ? 1 : 0,
+ "write_transcode_path", S_OR(ast_translate_path_to_str(ast_channel_writetrans(chan), &write_transpath), ""),
+ "read_transcode", ast_channel_readtrans(chan) ? 1 : 0,
+ "read_transcode_path", S_OR(ast_translate_path_to_str(ast_channel_readtrans(chan), &read_transpath), ""),
+
+ "1st_file_descriptor", ast_channel_fd(chan, 0),
+
+
+ "frames_in", ast_channel_fin(chan) & ~DEBUGCHAN_FLAG,
+ "frames_in_desc", S_COR((ast_channel_fin(chan) & DEBUGCHAN_FLAG), "DEBUGGED", ""),
+
+ "frames_out", ast_channel_fout(chan) & ~DEBUGCHAN_FLAG,
+ "frames_out_desc", S_COR((ast_channel_fout(chan) & DEBUGCHAN_FLAG), "DEBUGGED", ""),
+
+ "time_to_hangup", ast_channel_whentohangup(chan)->tv_sec,
+ "elapsed_time", S_OR(elapsed_time, ""),
+ "bridge_id", bridge? bridge->uniqueid : "",
+
+ "call_group", S_OR(ast_print_group(cgrp, sizeof(cgrp), ast_channel_callgroup(chan)), ""),
+ "pickup_group", S_OR(ast_print_group(pgrp, sizeof(pgrp), ast_channel_pickupgroup(chan)), ""),
+
+ "app_name", S_OR(ast_channel_appl(chan), ""),
+ "app_data", S_OR(ast_channel_data(chan), ""),
+ "blocking_in", (ast_test_flag(ast_channel_flags(chan), AST_FLAG_BLOCKING) ? ast_channel_blockproc(chan) : "")
+ );
+ ao2_cleanup(snapshot);
+ ao2_cleanup(bridge);
+ ast_channel_unlock(chan);
+
+ if (!j_res) {
+ ast_log(LOG_WARNING, "Could not pack channel dump info. channel: %s\n", chan_id);
+ return NULL;
+ }
+
+ return j_res;
+}
+
+void ast_ari_channels_get_dump(struct ast_variable *headers,
+ struct ast_ari_channels_get_dump_args *args,
+ struct ast_ari_response *response)
+{
+ struct ast_json *j_dump;
+
+ j_dump = ari_channel_dump_create(args->channel_id);
+ if (!j_dump) {
+ ast_ari_response_error(response, 404, "Not Found", "Channel not found");
+ return;
+ }
+
+ ast_ari_response_ok(response, j_dump);
+}
diff --git a/res/ari/resource_channels.h b/res/ari/resource_channels.h
index fdd7a6b..d8be001 100644
--- a/res/ari/resource_channels.h
+++ b/res/ari/resource_channels.h
@@ -354,6 +354,19 @@
* \param[out] response HTTP response
*/
void ast_ari_channels_ring_stop(struct ast_variable *headers, struct ast_ari_channels_ring_stop_args *args, struct ast_ari_response *response);
+/*! Argument struct for ast_ari_channels_get_dump() */
+struct ast_ari_channels_get_dump_args {
+ /*! Channel's id */
+ const char *channel_id;
+};
+/*!
+ * \brief Returns channel's detail dump.
+ *
+ * \param headers HTTP headers
+ * \param args Swagger parameters
+ * \param[out] response HTTP response
+ */
+void ast_ari_channels_get_dump(struct ast_variable *headers, struct ast_ari_channels_get_dump_args *args, struct ast_ari_response *response);
/*! Argument struct for ast_ari_channels_send_dtmf() */
struct ast_ari_channels_send_dtmf_args {
/*! Channel's id */
diff --git a/res/res_ari_channels.c b/res/res_ari_channels.c
index 3d96d60..e1bfc1e 100644
--- a/res/res_ari_channels.c
+++ b/res/res_ari_channels.c
@@ -1132,6 +1132,64 @@
fin: __attribute__((unused))
return;
}
+/*!
+ * \brief Parameter parsing callback for /channels/{channelId}/dump.
+ * \param get_params GET parameters in the HTTP request.
+ * \param path_vars Path variables extracted from the request.
+ * \param headers HTTP headers.
+ * \param[out] response Response to the HTTP request.
+ */
+static void ast_ari_channels_get_dump_cb(
+ struct ast_tcptls_session_instance *ser,
+ struct ast_variable *get_params, struct ast_variable *path_vars,
+ struct ast_variable *headers, struct ast_json *body, struct ast_ari_response *response)
+{
+ struct ast_ari_channels_get_dump_args args = {};
+ struct ast_variable *i;
+#if defined(AST_DEVMODE)
+ int is_valid;
+ int code;
+#endif /* AST_DEVMODE */
+
+ for (i = path_vars; i; i = i->next) {
+ if (strcmp(i->name, "channelId") == 0) {
+ args.channel_id = (i->value);
+ } else
+ {}
+ }
+ ast_ari_channels_get_dump(headers, &args, response);
+#if defined(AST_DEVMODE)
+ code = response->response_code;
+
+ switch (code) {
+ case 0: /* Implementation is still a stub, or the code wasn't set */
+ is_valid = response->message == NULL;
+ break;
+ case 500: /* Internal Server Error */
+ case 501: /* Not Implemented */
+ case 404: /* Channel not found */
+ is_valid = 1;
+ break;
+ default:
+ if (200 <= code && code <= 299) {
+ is_valid = ast_ari_validate_channel_dump(
+ response->message);
+ } else {
+ ast_log(LOG_ERROR, "Invalid error response %d for /channels/{channelId}/dump\n", code);
+ is_valid = 0;
+ }
+ }
+
+ if (!is_valid) {
+ ast_log(LOG_ERROR, "Response validation failed for /channels/{channelId}/dump\n");
+ ast_ari_response_error(response, 500,
+ "Internal Server Error", "Response validation failed");
+ }
+#endif /* AST_DEVMODE */
+
+fin: __attribute__((unused))
+ return;
+}
int ast_ari_channels_send_dtmf_parse_body(
struct ast_json *body,
struct ast_ari_channels_send_dtmf_args *args)
@@ -2806,6 +2864,15 @@
.children = { }
};
/*! \brief REST handler for /api-docs/channels.json */
+static struct stasis_rest_handlers channels_channelId_dump = {
+ .path_segment = "dump",
+ .callbacks = {
+ [AST_HTTP_GET] = ast_ari_channels_get_dump_cb,
+ },
+ .num_children = 0,
+ .children = { }
+};
+/*! \brief REST handler for /api-docs/channels.json */
static struct stasis_rest_handlers channels_channelId_dtmf = {
.path_segment = "dtmf",
.callbacks = {
@@ -2929,8 +2996,8 @@
[AST_HTTP_POST] = ast_ari_channels_originate_with_id_cb,
[AST_HTTP_DELETE] = ast_ari_channels_hangup_cb,
},
- .num_children = 15,
- .children = { &channels_channelId_continue,&channels_channelId_move,&channels_channelId_redirect,&channels_channelId_answer,&channels_channelId_ring,&channels_channelId_dtmf,&channels_channelId_mute,&channels_channelId_hold,&channels_channelId_moh,&channels_channelId_silence,&channels_channelId_play,&channels_channelId_record,&channels_channelId_variable,&channels_channelId_snoop,&channels_channelId_dial, }
+ .num_children = 16,
+ .children = { &channels_channelId_continue,&channels_channelId_move,&channels_channelId_redirect,&channels_channelId_answer,&channels_channelId_ring,&channels_channelId_dump,&channels_channelId_dtmf,&channels_channelId_mute,&channels_channelId_hold,&channels_channelId_moh,&channels_channelId_silence,&channels_channelId_play,&channels_channelId_record,&channels_channelId_variable,&channels_channelId_snoop,&channels_channelId_dial, }
};
/*! \brief REST handler for /api-docs/channels.json */
static struct stasis_rest_handlers channels = {
diff --git a/rest-api/api-docs/channels.json b/rest-api/api-docs/channels.json
index 6161934..80af694 100644
--- a/rest-api/api-docs/channels.json
+++ b/rest-api/api-docs/channels.json
@@ -718,6 +718,34 @@
]
},
{
+ "path": "/channels/{channelId}/dump",
+ "description": "Get channel info dump",
+ "operations": [
+ {
+ "httpMethod": "GET",
+ "summary": "Returns channel's detail dump.",
+ "nickname": "getDump",
+ "responseClass": "ChannelDump",
+ "parameters": [
+ {
+ "name": "channelId",
+ "description": "Channel's id",
+ "paramType": "path",
+ "required": true,
+ "allowMultiple": false,
+ "dataType": "string"
+ }
+ ],
+ "errorResponses": [
+ {
+ "code": 404,
+ "reason": "Channel not found"
+ }
+ ]
+ }
+ ]
+ },
+ {
"path": "/channels/{channelId}/dtmf",
"description": "Send DTMF to a channel",
"operations": [
@@ -1763,6 +1791,175 @@
}
}
},
+ "ChannelDump": {
+ "id": "ChannelDump",
+ "description": "Channel's detail dump info.",
+ "properties": {
+ "id": {
+ "required": true,
+ "type": "string",
+ "decription": "Channel's id."
+ },
+ "name": {
+ "required": true,
+ "type": "string",
+ "decription": "Name of the channel (i.e. PJSIP/foo-0000a7e3)"
+ },
+ "type": {
+ "required": true,
+ "type": "string",
+ "decription": "Channel's type"
+ },
+ "channel": {
+ "required": true,
+ "type": "Channel",
+ "description": "Channel info."
+ },
+ "dnid_number": {
+ "required": true,
+ "type": "string",
+ "description": "Dialed Number Identifier. Subscriber phone number."
+ },
+ "dnid_plan": {
+ "required": true,
+ "type": "long",
+ "description": "Dialed Number Identifier. Q.931 Type-Of-Number and Numbering-Plan encoded fields."
+ },
+ "rdnis": {
+ "required": true,
+ "type": "string",
+ "description": "Dialed Number Identifier for redirecting. Subscriber phone number."
+ },
+ "parkinglot": {
+ "required": true,
+ "type": "string",
+ "description": "Parkinglot name."
+ },
+ "rings": {
+ "required": true,
+ "type": "long",
+ "description": "Number of rings so far."
+ },
+ "answer_time": {
+ "required": true,
+ "type": "Date",
+ "description": "Answered time."
+ },
+ "hold_state": {
+ "required": true,
+ "type": "long",
+ "description": "Channel's hold state. 16: hold, 17: unhold."
+ },
+ "native_format": {
+ "required": true,
+ "type": "string",
+ "description": "Channel's native codec format. Channel can natively handle this format."
+ },
+ "write_format": {
+ "required": true,
+ "type": "string",
+ "description": "Requested write format (before translation)"
+ },
+ "read_format": {
+ "required": true,
+ "type": "string",
+ "description": "Requested read format (after translation)."
+ },
+ "raw_write_format": {
+ "required": true,
+ "type": "string",
+ "description": "Raw write format (after translation)."
+ },
+ "raw_read_format": {
+ "required": true,
+ "type": "string",
+ "description": "Raw read format (before translation)."
+ },
+ "write_transcode": {
+ "required": true,
+ "type": "long",
+ "description": "If this channel use transcode, sets to 1."
+ },
+ "write_transcode_path": {
+ "required": true,
+ "type": "string",
+ "description": "Write translation path."
+ },
+ "read_transcode": {
+ "required": true,
+ "type": "long",
+ "description": "If this channel use transcode, sets to 1."
+ },
+ "read_transcode_path": {
+ "required": true,
+ "type": "string",
+ "description": "Read translation path."
+ },
+ "1st_file_descriptor": {
+ "required": true,
+ "type": "long",
+ "description": "Channel's first file descriptor."
+ },
+ "frames_in": {
+ "required": true,
+ "type": "long",
+ "description": "Frames in counters."
+ },
+ "frames_in_desc": {
+ "required": true,
+ "type": "string"
+ },
+ "frames_out": {
+ "required": true,
+ "type": "long",
+ "description": "Frames out counters."
+ },
+ "frames_out_desc": {
+ "required": true,
+ "type": "string"
+ },
+ "time_to_hangup": {
+ "required": true,
+ "type": "long",
+ "description": "Time to hangup in second."
+ },
+ "elapsed_time": {
+ "required": true,
+ "type": "string",
+ "description": "Channel elapsed time. hh:mm:ss"
+ },
+ "bridge_id": {
+ "required": true,
+ "type": "string",
+ "description": "Bridge id, if exsits."
+ },
+ "call_group": {
+ "required": true,
+ "type": "string",
+ "description": "Call group for call pickups"
+ },
+ "pickup_group": {
+ "required": true,
+ "type": "string",
+ "description": "Pickup group - which calls groups can be picked up?"
+ },
+ "app_name": {
+ "required": true,
+ "type": "string",
+ "description": "Currentl application name."
+ },
+ "app_data": {
+ "required": true,
+ "type": "string",
+ "description": "Currentl application data."
+ },
+ "blocking_in": {
+ "required": true,
+ "type": "string",
+ "description": "Procedure causing blocking."
+ }
+ }
+ },
"Channel": {
"id": "Channel",
"description": "A specific communication connection between Asterisk and an Endpoint.",
--
To view, visit https://gerrit.asterisk.org/c/asterisk/+/11162
To unsubscribe, or for help writing mail filters, visit https://gerrit.asterisk.org/settings
Gerrit-Project: asterisk
Gerrit-Branch: master
Gerrit-Change-Id: Ie5b6c8b20a2bda5168ea56114f4241bc818cab10
Gerrit-Change-Number: 11162
Gerrit-PatchSet: 1
Gerrit-Owner: sungtae kim <pchero21 at gmail.com>
Gerrit-MessageType: newchange
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.digium.com/pipermail/asterisk-code-review/attachments/20190316/d7ccc616/attachment-0001.html>
More information about the asterisk-code-review
mailing list