]> git.ipfire.org Git - thirdparty/asterisk.git/commitdiff
CEL: Fix incorrect/missing extra field information
authorKinsey Moore <kmoore@digium.com>
Mon, 7 Jul 2014 01:18:58 +0000 (01:18 +0000)
committerKinsey Moore <kmoore@digium.com>
Mon, 7 Jul 2014 01:18:58 +0000 (01:18 +0000)
This corrects two issues with the extra field information in Asterisk
12+ in channel event logs.

It is possible to inject custom values into the dialstatus provided by
ast_channel_dial_type() Stasis messages that fall outside the
enumeration allowed for the DIALSTATUS channel variable. CEL now
filters for the allowed values and ignores other values.

The "hangupsource" extra field key is always blank if the far end
channel is a chan_pjsip channel. This is because the hangupsource is
never set for the pjsip channel driver. This change sets the
hangupsource whenever a hangup is queued for chan_pjsip channels.

This corrects an issue with the pjsip channel driver where the
hangupcause information was not being set properly.

Review: https://reviewboard.asterisk.org/r/3690/

git-svn-id: https://origsvn.digium.com/svn/asterisk/branches/12@418071 65c4cc65-6c06-0410-ace0-fbb531ad65f3

channels/chan_pjsip.c
main/cel.c
res/res_pjsip_session.c
tests/test_cel.c

index ee033b5113c758ebb23ce22c3c03809d3d674da9..e55c4883565f928e63aee61d3382a3d6a505e132 100644 (file)
@@ -1510,6 +1510,7 @@ static int call(void *data)
        int res = ast_sip_session_create_invite(session, &tdata);
 
        if (res) {
+               ast_set_hangupsource(session->channel, ast_channel_name(session->channel), 0);
                ast_queue_hangup(session->channel);
        } else {
                update_initial_connected_line(session);
@@ -1945,6 +1946,7 @@ static void chan_pjsip_session_end(struct ast_sip_session *session)
 
        chan_pjsip_remove_hold(ast_channel_uniqueid(session->channel));
 
+       ast_set_hangupsource(session->channel, ast_channel_name(session->channel), 0);
        if (!ast_channel_hangupcause(session->channel) && session->inv_session) {
                int cause = hangup_sip2cause(session->inv_session->cause);
 
@@ -2072,6 +2074,8 @@ static struct ast_sip_session_supplement pbx_start_supplement = {
 static void chan_pjsip_incoming_response(struct ast_sip_session *session, struct pjsip_rx_data *rdata)
 {
        struct pjsip_status_line status = rdata->msg_info.msg->line.status;
+       struct ast_control_pvt_cause_code *cause_code;
+       int data_size = sizeof(*cause_code);
 
        if (!session->channel) {
                return;
@@ -2095,6 +2099,21 @@ static void chan_pjsip_incoming_response(struct ast_sip_session *session, struct
        default:
                break;
        }
+
+       /* Build and send the tech-specific cause information */
+       /* size of the string making up the cause code is "SIP " number + " " + reason length */
+       data_size += 4 + 4 + pj_strlen(&status.reason);
+       cause_code = ast_alloca(data_size);
+       memset(cause_code, 0, data_size);
+
+       ast_copy_string(cause_code->chan_name, ast_channel_name(session->channel), AST_CHANNEL_NAME);
+
+       snprintf(cause_code->code, data_size - sizeof(*cause_code) + 1, "SIP %d %.*s", status.code,
+               (int) pj_strlen(&status.reason), pj_strbuf(&status.reason));
+
+       cause_code->ast_cause = hangup_sip2cause(status.code);
+       ast_queue_control_data(session->channel, AST_CONTROL_PVT_CAUSE_CODE, cause_code, data_size);
+       ast_channel_hangupcause_hash_set(session->channel, cause_code, data_size);
 }
 
 static int chan_pjsip_incoming_ack(struct ast_sip_session *session, struct pjsip_rx_data *rdata)
index c7f4fc36653be3ccfb5ccdc183f1f312b5c2c4a8..9a919a47ace7f82568143a7dfc2478004ba999be 100644 (file)
@@ -1266,6 +1266,35 @@ static void save_dialstatus(struct ast_multi_channel_blob *blob)
        }
 }
 
+static int is_valid_dialstatus(struct ast_multi_channel_blob *blob)
+{
+       const char *dialstatus = get_blob_variable(blob, "dialstatus");
+       int res = 0;
+
+       if (ast_strlen_zero(dialstatus)) {
+               res = 0;
+       } else if (!strcasecmp(dialstatus, "CHANUNAVAIL")) {
+               res = 1;
+       } else if (!strcasecmp(dialstatus, "CONGESTION")) {
+               res = 1;
+       } else if (!strcasecmp(dialstatus, "NOANSWER")) {
+               res = 1;
+       } else if (!strcasecmp(dialstatus, "BUSY")) {
+               res = 1;
+       } else if (!strcasecmp(dialstatus, "ANSWER")) {
+               res = 1;
+       } else if (!strcasecmp(dialstatus, "CANCEL")) {
+               res = 1;
+       } else if (!strcasecmp(dialstatus, "DONTCALL")) {
+               res = 1;
+       } else if (!strcasecmp(dialstatus, "TORTURE")) {
+               res = 1;
+       } else if (!strcasecmp(dialstatus, "INVALIDARGS")) {
+               res = 1;
+       }
+       return res;
+}
+
 static void cel_dial_cb(void *data, struct stasis_subscription *sub,
        struct stasis_message *message)
 {
@@ -1294,11 +1323,9 @@ static void cel_dial_cb(void *data, struct stasis_subscription *sub,
                }
        }
 
-       if (ast_strlen_zero(get_blob_variable(blob, "dialstatus"))) {
-               return;
+       if (is_valid_dialstatus(blob)) {
+               save_dialstatus(blob);
        }
-
-       save_dialstatus(blob);
 }
 
 static void cel_generic_cb(
index a721612a4efc8de8fa57f8ebc7a77b30704f5a2b..336122040419c9c629f46b213885a16551caedf7 100644 (file)
@@ -2134,6 +2134,7 @@ static void session_inv_on_media_update(pjsip_inv_session *inv, pj_status_t stat
        if ((status != PJ_SUCCESS) || (pjmedia_sdp_neg_get_active_local(inv->neg, &local) != PJ_SUCCESS) ||
                (pjmedia_sdp_neg_get_active_remote(inv->neg, &remote) != PJ_SUCCESS)) {
                ast_channel_hangupcause_set(session->channel, AST_CAUSE_BEARERCAPABILITY_NOTAVAIL);
+               ast_set_hangupsource(session->channel, ast_channel_name(session->channel), 0);
                ast_queue_hangup(session->channel);
                return;
        }
index 501b99fab1d054bc0219a1cb8fb0b1120871ae3a..2f76ac457ac2cb8e958101c10507447935c87a07 100644 (file)
@@ -773,6 +773,40 @@ AST_TEST_DEFINE(test_cel_dial_unanswered)
        return AST_TEST_PASS;
 }
 
+AST_TEST_DEFINE(test_cel_dial_unanswered_filter)
+{
+       RAII_VAR(struct ast_channel *, chan_caller, NULL, safe_channel_release);
+       RAII_VAR(struct ast_channel *, chan_callee, NULL, safe_channel_release);
+       struct ast_party_caller caller = ALICE_CALLERID;
+
+       switch (cmd) {
+       case TEST_INIT:
+               info->name = __func__;
+               info->category = TEST_CATEGORY;
+               info->summary = "Test CEL for a dial that isn't answered";
+               info->description =
+                       "Test CEL records for a channel that\n"
+                       "performs a dial operation that isn't answered\n";
+               return AST_TEST_NOT_RUN;
+       case TEST_EXECUTE:
+               break;
+       }
+
+       CREATE_ALICE_CHANNEL(chan_caller, &caller);
+
+       EMULATE_DIAL(chan_caller, CHANNEL_TECH_NAME "/Bob");
+
+       START_DIALED(chan_caller, chan_callee);
+
+       ast_channel_state_set(chan_caller, AST_STATE_RINGING);
+       ast_channel_publish_dial(chan_caller, chan_callee, NULL, "NOT A VALID DIAL STATUS");
+       ast_channel_publish_dial(chan_caller, chan_callee, NULL, "NOANSWER");
+
+       HANGUP_CHANNEL(chan_caller, AST_CAUSE_NO_ANSWER, "NOANSWER");
+       HANGUP_CHANNEL(chan_callee, AST_CAUSE_NO_ANSWER, "");
+
+       return AST_TEST_PASS;
+}
 
 AST_TEST_DEFINE(test_cel_dial_busy)
 {
@@ -2040,6 +2074,7 @@ static int unload_module(void)
 #endif
 
        AST_TEST_UNREGISTER(test_cel_dial_unanswered);
+       AST_TEST_UNREGISTER(test_cel_dial_unanswered_filter);
        AST_TEST_UNREGISTER(test_cel_dial_congestion);
        AST_TEST_UNREGISTER(test_cel_dial_busy);
        AST_TEST_UNREGISTER(test_cel_dial_unavailable);
@@ -2114,6 +2149,7 @@ static int load_module(void)
 #endif
 
        AST_TEST_REGISTER(test_cel_dial_unanswered);
+       AST_TEST_REGISTER(test_cel_dial_unanswered_filter);
        AST_TEST_REGISTER(test_cel_dial_congestion);
        AST_TEST_REGISTER(test_cel_dial_busy);
        AST_TEST_REGISTER(test_cel_dial_unavailable);