[Asterisk-code-review] res/ari/resource_channels.c: Added detail hangup reason (...asterisk[master])

sungtae kim asteriskteam at digium.com
Mon Apr 15 18:28:12 CDT 2019


sungtae kim has uploaded this change for review. ( https://gerrit.asterisk.org/c/asterisk/+/11287


Change subject: res/ari/resource_channels.c: Added detail hangup reason
......................................................................

res/ari/resource_channels.c: Added detail hangup reason

Currently, DELETE /ari/channels/<channelID> supports only few hangup reasons.
It's good enough for simple use, but when it needs to set the detail reason,
it comes challenges.
And setting reason text is not clear to use. Because of the Asterisk uses
numbers for ChannelDestroyed event, use the reason code is easier to use.
Added reason_code query parameter for that.

ASTERISK-28385

Change-Id: I1cf1d991ffd759d0591b347445a55f416ddc3ff2
---
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, 165 insertions(+), 36 deletions(-)



  git pull ssh://gerrit.asterisk.org:29418/asterisk refs/changes/87/11287/1

diff --git a/res/ari/ari_model_validators.c b/res/ari/ari_model_validators.c
index e3ca10a..8910bbb 100644
--- a/res/ari/ari_model_validators.c
+++ b/res/ari/ari_model_validators.c
@@ -2455,6 +2455,7 @@
 	struct ast_json_iter *iter;
 	int has_type = 0;
 	int has_application = 0;
+	int has_timestamp = 0;
 	int has_args = 0;
 	int has_channel = 0;
 	int has_destination = 0;
@@ -2491,6 +2492,7 @@
 		} else
 		if (strcmp("timestamp", ast_json_object_iter_key(iter)) == 0) {
 			int prop_is_valid;
+			has_timestamp = 1;
 			prop_is_valid = ast_ari_validate_date(
 				ast_json_object_iter_value(iter));
 			if (!prop_is_valid) {
@@ -2547,6 +2549,11 @@
 		res = 0;
 	}
 
+	if (!has_timestamp) {
+		ast_log(LOG_ERROR, "ARI ApplicationMoveFailed missing required field timestamp\n");
+		res = 0;
+	}
+
 	if (!has_args) {
 		ast_log(LOG_ERROR, "ARI ApplicationMoveFailed missing required field args\n");
 		res = 0;
diff --git a/res/ari/ari_model_validators.h b/res/ari/ari_model_validators.h
index adf3e1a..f9285b4 100644
--- a/res/ari/ari_model_validators.h
+++ b/res/ari/ari_model_validators.h
@@ -1603,7 +1603,7 @@
  * - asterisk_id: string
  * - type: string (required)
  * - application: string (required)
- * - timestamp: Date
+ * - timestamp: Date (required)
  * - args: List[string] (required)
  * - channel: Channel (required)
  * - destination: string (required)
diff --git a/res/ari/resource_channels.c b/res/ari/resource_channels.c
index c195eef..24ab511 100644
--- a/res/ari/resource_channels.c
+++ b/res/ari/resource_channels.c
@@ -48,6 +48,94 @@
 
 #include <limits.h>
 
+struct causes_map {
+	int cause;
+	const char *name;
+};
+
+static const struct causes_map causes[] = {
+	{ AST_CAUSE_NOTDEFINED, "not_defined" },
+	{ AST_CAUSE_UNALLOCATED, "unallocated" },
+	{ AST_CAUSE_NO_ROUTE_TRANSIT_NET, "no_route_transit_network" },
+	{ AST_CAUSE_NO_ROUTE_DESTINATION, "no_route_destination" },
+	{ AST_CAUSE_MISDIALLED_TRUNK_PREFIX, "misdialed_trunk_prefix" },
+	{ AST_CAUSE_CHANNEL_UNACCEPTABLE, "channel_unacceptable" },
+	{ AST_CAUSE_CALL_AWARDED_DELIVERED, "call_awarded_delivered" },
+	{ AST_CAUSE_PRE_EMPTED, "pre_empted" },
+	{ AST_CAUSE_NUMBER_PORTED_NOT_HERE, "number_ported_not_here" },
+	{ AST_CAUSE_NORMAL_CLEARING, "normal" },
+	{ AST_CAUSE_USER_BUSY, "busy" },
+	{ AST_CAUSE_NO_USER_RESPONSE, "timeout" },
+	{ AST_CAUSE_NO_ANSWER, "no_answer" },
+	{ AST_CAUSE_SUBSCRIBER_ABSENT, "subscriber_absent" },
+	{ AST_CAUSE_CALL_REJECTED, "rejected" },
+	{ AST_CAUSE_NUMBER_CHANGED, "number_changed" },
+	{ AST_CAUSE_REDIRECTED_TO_NEW_DESTINATION, "redirected_to_new_destination" },
+	{ AST_CAUSE_ANSWERED_ELSEWHERE, "answered_elsewhere" },
+	{ AST_CAUSE_DESTINATION_OUT_OF_ORDER, "destination_out_of_order" },
+	{ AST_CAUSE_INVALID_NUMBER_FORMAT, "number_incomplete" },
+	{ AST_CAUSE_FACILITY_REJECTED, "facility_rejected" },
+	{ AST_CAUSE_RESPONSE_TO_STATUS_ENQUIRY, "response_to_status_enquiry" },
+	{ AST_CAUSE_NORMAL_UNSPECIFIED, "normal_unspecified" },
+	{ AST_CAUSE_NORMAL_CIRCUIT_CONGESTION, "congestion" },
+	{ AST_CAUSE_NETWORK_OUT_OF_ORDER, "failure" },
+	{ AST_CAUSE_NORMAL_TEMPORARY_FAILURE, "normal_temporary_failure" },
+	{ AST_CAUSE_SWITCH_CONGESTION, "switch_congestion" },
+	{ AST_CAUSE_ACCESS_INFO_DISCARDED, "access_info_discarded" },
+	{ AST_CAUSE_REQUESTED_CHAN_UNAVAIL, "requested_chan_unavailable" },
+	{ AST_CAUSE_FACILITY_NOT_SUBSCRIBED, "facility_not_subscribed" },
+	{ AST_CAUSE_OUTGOING_CALL_BARRED, "outgoing_call_barred" },
+	{ AST_CAUSE_INCOMING_CALL_BARRED, "incoming_call_barred" },
+	{ AST_CAUSE_BEARERCAPABILITY_NOTAUTH, "bearercapability_not_auth" },
+	{ AST_CAUSE_BEARERCAPABILITY_NOTAVAIL, "codec_mismatch" },
+	{ AST_CAUSE_BEARERCAPABILITY_NOTIMPL, "bearercapability_not_implemented" },
+	{ AST_CAUSE_CHAN_NOT_IMPLEMENTED, "channel_not_implemented" },
+	{ AST_CAUSE_FACILITY_NOT_IMPLEMENTED, "facility_not_implemented" },
+	{ AST_CAUSE_INVALID_CALL_REFERENCE, "invalid_call_reference" },
+	{ AST_CAUSE_INCOMPATIBLE_DESTINATION, "incompatible_destination" },
+	{ AST_CAUSE_INVALID_MSG_UNSPECIFIED, "invalid_msg_unspecified" },
+	{ AST_CAUSE_MANDATORY_IE_MISSING, "mandatory_ie_missing" },
+	{ AST_CAUSE_MESSAGE_TYPE_NONEXIST, "message_type_nonexist" },
+	{ AST_CAUSE_WRONG_MESSAGE, "wrong_message" },
+	{ AST_CAUSE_IE_NONEXIST, "ie_nonexist" },
+	{ AST_CAUSE_INVALID_IE_CONTENTS, "invalid_ie_contents" },
+	{ AST_CAUSE_WRONG_CALL_STATE, "wrong_call_state" },
+	{ AST_CAUSE_RECOVERY_ON_TIMER_EXPIRE, "recovery_on_timer_expire" },
+	{ AST_CAUSE_MANDATORY_IE_LENGTH_ERROR, "mandatory_ie_length_error" },
+	{ AST_CAUSE_PROTOCOL_ERROR, "protocol_error" },
+	{ AST_CAUSE_INTERWORKING, "interworking" },
+};
+
+
+/*! \brief Return reason code if the given cause is correct reason code.
+ * Otherwise return -1.
+ */
+static int get_available_reason_code(int cause)
+{
+	int x;
+
+	for (x = 0; x < ARRAY_LEN(causes); x++) {
+		if (causes[x].cause == cause)
+			return causes[x].cause;
+	}
+
+	return -1;
+}
+
+/*! \brief Return 1 if the given cause is correct reason code */
+static int get_reason_to_code(const char* reason)
+{
+	int x;
+
+	for (x = 0; x < ARRAY_LEN(causes); x++) {
+		if (!strcmp(causes[x].name, reason)) {
+			return causes[x].cause;
+		}
+	}
+
+	return -1;
+}
+
 
 /*!
  * \brief Ensure channel is in a state that allows operation to be performed.
@@ -885,33 +973,13 @@
 		return;
 	}
 
-	if (ast_strlen_zero(args->reason) || !strcmp(args->reason, "normal")) {
-		cause = AST_CAUSE_NORMAL;
-	} else if (!strcmp(args->reason, "busy")) {
-		cause = AST_CAUSE_BUSY;
-	} else if (!strcmp(args->reason, "congestion")) {
-		cause = AST_CAUSE_CONGESTION;
-	} else if (!strcmp(args->reason, "no_answer")) {
-		cause = AST_CAUSE_NOANSWER;
-	} else if (!strcmp(args->reason, "timeout")) {
-		cause = AST_CAUSE_NO_USER_RESPONSE;
-	} else if (!strcmp(args->reason, "rejected")) {
-		cause = AST_CAUSE_CALL_REJECTED;
-	} else if (!strcmp(args->reason, "unallocated")) {
-		cause = AST_CAUSE_UNALLOCATED;
-	} else if (!strcmp(args->reason, "normal_unspecified")) {
-		cause = AST_CAUSE_NORMAL_UNSPECIFIED;
-	} else if (!strcmp(args->reason, "number_incomplete")) {
-		cause = AST_CAUSE_INVALID_NUMBER_FORMAT;
-	} else if (!strcmp(args->reason, "codec_mismatch")) {
-		cause = AST_CAUSE_BEARERCAPABILITY_NOTAVAIL;
-	} else if (!strcmp(args->reason, "interworking")) {
-		cause = AST_CAUSE_INTERWORKING;
-	} else if (!strcmp(args->reason, "failure")) {
-		cause = AST_CAUSE_FAILURE;
-	} else if(!strcmp(args->reason, "answered_elsewhere")) {
-		cause = AST_CAUSE_ANSWERED_ELSEWHERE;
+	if (!ast_strlen_zero(args->reason)) {
+		cause = get_reason_to_code(args->reason);
 	} else {
+		cause = get_available_reason_code(args->reason_code);
+	}
+
+	if (cause < 0) {
 		ast_ari_response_error(
 			response, 400, "Invalid Reason",
 			"Invalid reason for hangup provided");
diff --git a/res/ari/resource_channels.h b/res/ari/resource_channels.h
index 401c8a5..fcd5e7d 100644
--- a/res/ari/resource_channels.h
+++ b/res/ari/resource_channels.h
@@ -207,7 +207,9 @@
 struct ast_ari_channels_hangup_args {
 	/*! Channel's id */
 	const char *channel_id;
-	/*! Reason for hanging up the channel */
+	/*! The reason code for hanging up the channel. If the reason is set, this will be ignored. See detail hangup codes at here. https://wiki.asterisk.org/wiki/display/AST/Hangup+Cause+Mappings */
+	int reason_code;
+	/*! Reason for hanging up the channel. See detail hangup code at here. https://wiki.asterisk.org/wiki/display/AST/Hangup+Cause+Mappings */
 	const char *reason;
 };
 /*!
diff --git a/res/res_ari_channels.c b/res/res_ari_channels.c
index 73d1e4b..f6ac3cc 100644
--- a/res/res_ari_channels.c
+++ b/res/res_ari_channels.c
@@ -598,6 +598,10 @@
 {
 	struct ast_json *field;
 	/* Parse query parameters out of it */
+	field = ast_json_object_get(body, "reason_code");
+	if (field) {
+		args->reason_code = ast_json_integer_get(field);
+	}
 	field = ast_json_object_get(body, "reason");
 	if (field) {
 		args->reason = ast_json_string_get(field);
@@ -625,6 +629,9 @@
 #endif /* AST_DEVMODE */
 
 	for (i = get_params; i; i = i->next) {
+		if (strcmp(i->name, "reason_code") == 0) {
+			args.reason_code = atoi(i->value);
+		} else
 		if (strcmp(i->name, "reason") == 0) {
 			args.reason = (i->value);
 		} else
diff --git a/rest-api/api-docs/channels.json b/rest-api/api-docs/channels.json
index 4ea5f56..da0c6eb 100644
--- a/rest-api/api-docs/channels.json
+++ b/rest-api/api-docs/channels.json
@@ -407,8 +407,17 @@
 							"dataType": "string"
 						},
 						{
+							"name": "reason_code",
+							"description": "The reason code for hanging up the channel. If the reason is set, this will be ignored. See detail hangup codes at here. https://wiki.asterisk.org/wiki/display/AST/Hangup+Cause+Mappings",
+							"paramType": "query",
+							"required": false,
+							"allowMultiple": false,
+							"dataType": "int",
+							"defalutValue": 0
+						},
+						{
 							"name": "reason",
-							"description": "Reason for hanging up the channel",
+							"description": "Reason for hanging up the channel. See detail hangup code at here. https://wiki.asterisk.org/wiki/display/AST/Hangup+Cause+Mappings",
 							"paramType": "query",
 							"required": false,
 							"allowMultiple": false,
@@ -417,19 +426,55 @@
 							"allowableValues": {
 								"valueType": "LIST",
 								"values": [
+									"not_defined",
+									"unallocated",
+									"no_route_transit_network",
+									"no_route_destination",
+									"misdialed_trunk_prefix",
+									"channel_unacceptable",
+									"call_awarded_delivered",
+									"pre_empted",
+									"number_ported_not_here",
 									"normal",
 									"busy",
-									"congestion",
-									"no_answer",
 									"timeout",
+									"no_answer",
+									"subscriber_absent",
 									"rejected",
-									"unallocated",
-									"normal_unspecified",
+									"number_changed",
+									"redirected_to_new_destination",
+									"answered_elsewhere",
+									"destination_out_of_order",
 									"number_incomplete",
-									"codec_mismatch",
-									"interworking",
+									"facility_rejected",
+									"response_to_status_enquiry",
+									"congestion",
 									"failure",
-									"answered_elsewhere"
+									"normal_temporary_failure",
+									"switch_congestion",
+									"access_info_discarded",
+									"requested_chan_unavailable",
+									"facility_not_subscribed",
+									"outgoing_call_barred",
+									"incoming_call_barred",
+									"bearercapability_not_auth",
+									"codec_mismatch",
+									"bearercapability_not_implemented",
+									"channel_not_implemented",
+									"facility_not_implemented",
+									"invalid_call_reference",
+									"incompatible_destination",
+									"invalid_msg_unspecified",
+									"mandatory_ie_missing",
+									"message_type_nonexist",
+									"wrong_message",
+									"ie_nonexist",
+									"invalid_ie_contents",
+									"wrong_call_state",
+									"recovery_on_timer_expire",
+									"mandatory_ie_length_error",
+									"protocol_error",
+									"interworking"
 								]
 							}
 						}

-- 
To view, visit https://gerrit.asterisk.org/c/asterisk/+/11287
To unsubscribe, or for help writing mail filters, visit https://gerrit.asterisk.org/settings

Gerrit-Project: asterisk
Gerrit-Branch: master
Gerrit-Change-Id: I1cf1d991ffd759d0591b347445a55f416ddc3ff2
Gerrit-Change-Number: 11287
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/20190415/aefd9e06/attachment-0001.html>


More information about the asterisk-code-review mailing list