]> git.ipfire.org Git - thirdparty/asterisk.git/commitdiff
res/ari/resource_channels.c: Added hangup reason code for channels
authorsungtae kim <sungtae@messagebird.com>
Mon, 15 Apr 2019 23:26:46 +0000 (01:26 +0200)
committerKevin Harwell <kharwell@digium.com>
Thu, 27 Jun 2019 16:03:08 +0000 (11:03 -0500)
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.
Added reason_code query parameter for that.

ASTERISK-28385

Change-Id: I1cf1d991ffd759d0591b347445a55f416ddc3ff2

res/ari/resource_channels.c
res/ari/resource_channels.h
res/res_ari_channels.c
rest-api/api-docs/channels.json

index c195eef87e3452e35696b5c2427b19b1b8adeb08..1164ab10ed7124a44830b4e4b2ea8930fbc80ab6 100644 (file)
 #include <limits.h>
 
 
+/*! \brief Return the corresponded hangup code of the given reason */
+static int convert_reason_to_hangup_code(const char* reason)
+{
+       if (!strcmp(reason, "normal")) {
+               return AST_CAUSE_NORMAL;
+       } else if (!strcmp(reason, "busy")) {
+               return AST_CAUSE_BUSY;
+       } else if (!strcmp(reason, "congestion")) {
+               return AST_CAUSE_CONGESTION;
+       } else if (!strcmp(reason, "no_answer")) {
+               return AST_CAUSE_NOANSWER;
+       } else if (!strcmp(reason, "timeout")) {
+               return AST_CAUSE_NO_USER_RESPONSE;
+       } else if (!strcmp(reason, "rejected")) {
+               return AST_CAUSE_CALL_REJECTED;
+       } else if (!strcmp(reason, "unallocated")) {
+               return AST_CAUSE_UNALLOCATED;
+       } else if (!strcmp(reason, "normal_unspecified")) {
+               return AST_CAUSE_NORMAL_UNSPECIFIED;
+       } else if (!strcmp(reason, "number_incomplete")) {
+               return AST_CAUSE_INVALID_NUMBER_FORMAT;
+       } else if (!strcmp(reason, "codec_mismatch")) {
+               return AST_CAUSE_BEARERCAPABILITY_NOTAVAIL;
+       } else if (!strcmp(reason, "interworking")) {
+               return AST_CAUSE_INTERWORKING;
+       } else if (!strcmp(reason, "failure")) {
+               return AST_CAUSE_FAILURE;
+       } else if(!strcmp(reason, "answered_elsewhere")) {
+               return AST_CAUSE_ANSWERED_ELSEWHERE;
+       }
+
+       return -1;
+}
+
 /*!
  * \brief Ensure channel is in a state that allows operation to be performed.
  *
@@ -885,39 +919,34 @@ void ast_ari_channels_hangup(struct ast_variable *headers,
                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;
-       } else {
-               ast_ari_response_error(
-                       response, 400, "Invalid Reason",
-                       "Invalid reason for hangup provided");
+       if (!ast_strlen_zero(args->reason) && !ast_strlen_zero(args->reason_code)) {
+               ast_ari_response_error(response, 400, "Bad Request",
+                       "The reason and reason_code can't both be specified");
                return;
        }
 
+       if (!ast_strlen_zero(args->reason_code)) {
+               /* reason_code allows any hangup code */
+               if (sscanf(args->reason_code, "%30d", &cause) != 1) {
+                       ast_ari_response_error(
+                               response, 400, "Invalid Reason Code",
+                               "Invalid reason for hangup reason code provided");
+                       return;
+               }
+       } else if (!ast_strlen_zero(args->reason)) {
+               /* reason allows only listed hangup reason */
+               cause = convert_reason_to_hangup_code(args->reason);
+               if (cause == -1) {
+                       ast_ari_response_error(
+                               response, 400, "Invalid Reason",
+                               "Invalid reason for hangup reason provided");
+                       return;
+               }
+       } else {
+               /* not specified. set default hangup */
+               cause = AST_CAUSE_NORMAL;
+       }
+
        ast_channel_hangupcause_set(chan, cause);
        ast_softhangup(chan, AST_SOFTHANGUP_EXPLICIT);
 
index 401c8a5651a1933b1e129ded841621b38dde9ba4..8aefb40479e6f2fc57afc0809052c7e2e37e638d 100644 (file)
@@ -207,7 +207,9 @@ void ast_ari_channels_originate_with_id(struct ast_variable *headers, struct ast
 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 for detail use. Mutually exclusive with 'reason'. See detail hangup codes at here. https://wiki.asterisk.org/wiki/display/AST/Hangup+Cause+Mappings */
+       const char *reason_code;
+       /*! Reason for hanging up the channel for simple use. Mutually exclusive with 'reason_code'. */
        const char *reason;
 };
 /*!
index 73d1e4b2df25841694ba5f77bf098d6b90afd6c6..825d4c2704014bd12ea69382f153ab4c3985fb4f 100644 (file)
@@ -598,6 +598,10 @@ int ast_ari_channels_hangup_parse_body(
 {
        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_string_get(field);
+       }
        field = ast_json_object_get(body, "reason");
        if (field) {
                args->reason = ast_json_string_get(field);
@@ -625,6 +629,9 @@ static void ast_ari_channels_hangup_cb(
 #endif /* AST_DEVMODE */
 
        for (i = get_params; i; i = i->next) {
+               if (strcmp(i->name, "reason_code") == 0) {
+                       args.reason_code = (i->value);
+               } else
                if (strcmp(i->name, "reason") == 0) {
                        args.reason = (i->value);
                } else
index 4ea5f5647cce6819e46fec995b7b3c26ad32f963..77412695bd9e816b24c35224efa12d4503e19200 100644 (file)
                                                        "allowMultiple": false,
                                                        "dataType": "string"
                                                },
+                                               {
+                                                       "name": "reason_code",
+                                                       "description": "The reason code for hanging up the channel for detail use. Mutually exclusive with 'reason'. See detail hangup codes at here. https://wiki.asterisk.org/wiki/display/AST/Hangup+Cause+Mappings",
+                                                       "paramType": "query",
+                                                       "required": false,
+                                                       "allowMultiple": false,
+                                                       "dataType": "string"
+                                               },
                                                {
                                                        "name": "reason",
-                                                       "description": "Reason for hanging up the channel",
+                                                       "description": "Reason for hanging up the channel for simple use. Mutually exclusive with 'reason_code'.",
                                                        "paramType": "query",
                                                        "required": false,
                                                        "allowMultiple": false,
                                                        "dataType": "string",
-                                                       "defalutValue": "normal",
                                                        "allowableValues": {
                                                                "valueType": "LIST",
                                                                "values": [