[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