diff options
-rw-r--r-- | main/cdr.c | 5 | ||||
-rw-r--r-- | tests/test_cdr.c | 103 |
2 files changed, 107 insertions, 1 deletions
diff --git a/main/cdr.c b/main/cdr.c index dbce8e5c4..d2e033839 100644 --- a/main/cdr.c +++ b/main/cdr.c @@ -1601,6 +1601,11 @@ static int dial_state_process_bridge_enter(struct cdr_object *cdr, struct ast_br continue; } + /* If we don't have a Party B (originated channel), skip it */ + if (!cdr->party_b.snapshot) { + continue; + } + /* Skip any records that aren't our Party B */ if (strcmp(cdr->party_b.snapshot->name, cand_cdr->party_a.snapshot->name)) { continue; diff --git a/tests/test_cdr.c b/tests/test_cdr.c index c9621a450..a60f78e2c 100644 --- a/tests/test_cdr.c +++ b/tests/test_cdr.c @@ -494,6 +494,102 @@ AST_TEST_DEFINE(test_cdr_unanswered_outbound_call) return result; } +AST_TEST_DEFINE(test_cdr_outbound_bridged_call) +{ + RAII_VAR(struct ast_channel *, chan_alice, NULL, safe_channel_release); + RAII_VAR(struct ast_channel *, chan_bob, NULL, safe_channel_release); + RAII_VAR(struct ast_bridge *, bridge, NULL, ao2_cleanup); + RAII_VAR(struct ast_cdr_config *, config, ao2_alloc(sizeof(*config), NULL), + ao2_cleanup); + struct timespec to_sleep = {1, 0}; + enum ast_test_result_state result = AST_TEST_NOT_RUN; + + struct ast_party_caller caller = ALICE_CALLERID; + struct ast_cdr alice_expected = { + .clid = "\"Alice\" <100>", + .src = "100", + .dst = "100", + .dcontext = "default", + .channel = CHANNEL_TECH_NAME "/Alice", + .dstchannel = CHANNEL_TECH_NAME "/Bob", + .lastapp = "", + .lastdata = "", + .amaflags = AST_AMA_DOCUMENTATION, + .billsec = 1, + .disposition = AST_CDR_ANSWERED, + .accountcode = "100", + .peeraccount = "200", + }; + struct ast_cdr bob_expected = { + .clid = "\"\" <>", + .src = "", + .dst = "s", + .dcontext = "default", + .channel = CHANNEL_TECH_NAME "/Bob", + .dstchannel = "", + .lastapp = "AppDial", + .lastdata = "(Outgoing Line)", + .amaflags = AST_AMA_DOCUMENTATION, + .billsec = 1, + .disposition = AST_CDR_ANSWERED, + .accountcode = "200", + .peeraccount = "", + .next = &alice_expected, + }; + + switch (cmd) { + case TEST_INIT: + info->name = __func__; + info->category = TEST_CATEGORY; + info->summary = "Test dialing, answering, and going into a 2-party bridge"; + info->description = + "The most 'basic' of scenarios\n"; + return AST_TEST_NOT_RUN; + case TEST_EXECUTE: + break; + } + + SWAP_CONFIG(config, debug_cdr_config); + + CREATE_ALICE_CHANNEL(chan_alice, &caller, &alice_expected); + ast_channel_state_set(chan_alice, AST_STATE_UP); + + bridge = ast_bridge_basic_new(); + ast_test_validate(test, bridge != NULL); + while ((nanosleep(&to_sleep, &to_sleep) == -1) && (errno == EINTR)); + + ast_bridge_impart(bridge, chan_alice, NULL, NULL, 0); + + chan_bob = ast_channel_alloc(0, AST_STATE_DOWN, NULL, NULL, "200", NULL, NULL, ast_channel_linkedid(chan_alice), 0, CHANNEL_TECH_NAME "/Bob"); + ast_copy_string(bob_expected.linkedid, ast_channel_linkedid(chan_bob), sizeof(bob_expected.linkedid)); + ast_copy_string(bob_expected.uniqueid, ast_channel_uniqueid(chan_bob), sizeof(bob_expected.uniqueid)); + ast_set_flag(ast_channel_flags(chan_bob), AST_FLAG_OUTGOING); + ast_set_flag(ast_channel_flags(chan_bob), AST_FLAG_ORIGINATED); + EMULATE_APP_DATA(chan_bob, 0, "AppDial", "(Outgoing Line)"); + + ast_channel_publish_dial(NULL, chan_bob, "Bob", NULL); + ast_channel_state_set(chan_bob, AST_STATE_RINGING); + ast_channel_publish_dial(NULL, chan_bob, NULL, "ANSWER"); + + ast_channel_state_set(chan_bob, AST_STATE_UP); + + while ((nanosleep(&to_sleep, &to_sleep) == -1) && (errno == EINTR)); + + ast_bridge_impart(bridge, chan_bob, NULL, NULL, 0); + + while ((nanosleep(&to_sleep, &to_sleep) == -1) && (errno == EINTR)); + + ast_bridge_depart(chan_bob); + ast_bridge_depart(chan_alice); + + HANGUP_CHANNEL(chan_bob, AST_CAUSE_NORMAL); + HANGUP_CHANNEL(chan_alice, AST_CAUSE_NORMAL); + + result = verify_mock_cdr_record(test, &bob_expected, 2); + return result; +} + + AST_TEST_DEFINE(test_cdr_single_party) { RAII_VAR(struct ast_channel *, chan, NULL, safe_channel_release); @@ -511,7 +607,7 @@ AST_TEST_DEFINE(test_cdr_single_party) .lastapp = "VoiceMailMain", .lastdata = "1", .billsec = 1, - .amaflags = AST_AMA_DOCUMENTATION, + .amaflags = AST_AMA_DOCUMENTATION, .disposition = AST_CDR_ANSWERED, .accountcode = "100", }; @@ -2338,6 +2434,7 @@ static int unload_module(void) AST_TEST_UNREGISTER(test_cdr_channel_creation); AST_TEST_UNREGISTER(test_cdr_unanswered_inbound_call); AST_TEST_UNREGISTER(test_cdr_unanswered_outbound_call); + AST_TEST_UNREGISTER(test_cdr_single_party); AST_TEST_UNREGISTER(test_cdr_single_bridge); AST_TEST_UNREGISTER(test_cdr_single_bridge_continue); @@ -2345,6 +2442,8 @@ static int unload_module(void) AST_TEST_UNREGISTER(test_cdr_single_twoparty_bridge_b); AST_TEST_UNREGISTER(test_cdr_single_multiparty_bridge); + AST_TEST_UNREGISTER(test_cdr_outbound_bridged_call); + AST_TEST_UNREGISTER(test_cdr_dial_unanswered); AST_TEST_UNREGISTER(test_cdr_dial_congestion); AST_TEST_UNREGISTER(test_cdr_dial_busy); @@ -2384,6 +2483,8 @@ static int load_module(void) AST_TEST_REGISTER(test_cdr_single_twoparty_bridge_b); AST_TEST_REGISTER(test_cdr_single_multiparty_bridge); + AST_TEST_REGISTER(test_cdr_outbound_bridged_call); + AST_TEST_REGISTER(test_cdr_dial_unanswered); AST_TEST_REGISTER(test_cdr_dial_congestion); AST_TEST_REGISTER(test_cdr_dial_busy); |