Commit 6dc2de30 authored by Pekka Pessi's avatar Pekka Pessi

test_call_hold.c: added more cases for hairy call termination.

darcs-hash:20080307164551-65a35-e95707755c1f96684229a6f272be12d85e8b933f.gz
parent 60d50ab9
......@@ -43,7 +43,10 @@
#define __func__ "test_call_hold"
#endif
int ack_when_completing(CONDITION_PARAMS);
int complete_call(CONDITION_PARAMS);
int until_complete(CONDITION_PARAMS);
int invite_responded(CONDITION_PARAMS);
static size_t remove_first_ack(void *_once, void *message, size_t len);
/* ======================================================================== */
/* test_call_hold message sequence looks like this:
......@@ -88,6 +91,9 @@ int test_call_hold(struct context *ctx)
struct endpoint *a = &ctx->a, *b = &ctx->b;
struct call *a_call = a->call, *b_call = b->call;
struct event *e;
sip_t *sip;
int zero = 0;
struct nat_filter *f;
a_call->sdp =
"m=audio 5008 RTP/AVP 0 8\n"
......@@ -476,7 +482,7 @@ int test_call_hold(struct context *ctx)
INVITE(b, b_call, b_call->nh, SOATAG_HOLD(""),
SIPTAG_SUBJECT_STR("TEST NUA-7.6: re-INVITE without auto-ack"),
TAG_END());
run_ab_until(ctx, -1, until_ready, -1, ack_when_completing);
run_ab_until(ctx, -1, until_complete, -1, complete_call);
/* Client transitions:
READY -(C1)-> CALLING: nua_invite(), nua_i_state
......@@ -492,9 +498,8 @@ int test_call_hold(struct context *ctx)
TEST_1(is_answer_recv(e->data->e_tags));
TEST(audio_activity(e->data->e_tags), SOA_ACTIVE_SENDRECV);
TEST(video_activity(e->data->e_tags), SOA_ACTIVE_SENDRECV);
TEST_1(e = e->next); TEST_E(e->data->e_event, nua_i_state);
TEST(callstate(e->data->e_tags), nua_callstate_ready); /* READY */
TEST_1(!e->next);
free_events_in_list(ctx, b->events);
/*
......@@ -508,7 +513,19 @@ int test_call_hold(struct context *ctx)
TEST(callstate(e->data->e_tags), nua_callstate_completed); /* COMPLETED */
TEST_1(is_answer_sent(e->data->e_tags));
TEST(audio_activity(e->data->e_tags), SOA_ACTIVE_SENDRECV);
TEST_1(e = e->next); TEST_E(e->data->e_event, nua_i_ack);
TEST_1(!e->next);
free_events_in_list(ctx, a->events);
ACK(b, b_call, b_call->nh, TAG_END());
run_ab_until(ctx, -1, until_ready, -1, until_ready);
TEST_1(e = b->events->head); TEST_E(e->data->e_event, nua_i_state);
TEST(callstate(e->data->e_tags), nua_callstate_ready); /* READY */
TEST_1(!e->next);
free_events_in_list(ctx, b->events);
TEST_1(e = a->events->head); TEST_E(e->data->e_event, nua_i_ack);
TEST_1(e = e->next); TEST_E(e->data->e_event, nua_i_state);
TEST(callstate(e->data->e_tags), nua_callstate_ready); /* READY */
TEST(audio_activity(e->data->e_tags), SOA_ACTIVE_SENDRECV);
......@@ -519,6 +536,95 @@ int test_call_hold(struct context *ctx)
if (print_headings)
printf("TEST NUA-7.6.1: PASSED\n");
/* ------------------------------------------------------------------------ */
/*
: :
|<------INVITE-------|
|--------200-------->|
|<--------ACK--------|
: :
*/
if (ctx->proxy_tests && ctx->nat) {
if (print_headings)
printf("TEST NUA-7.6.2: almost overlapping re-INVITE\n");
/* Turn off auto-ack */
nua_set_hparams(b_call->nh, NUTAG_AUTOACK(0), TAG_END());
run_b_until(ctx, nua_r_set_params, until_final_response);
INVITE(b, b_call, b_call->nh, SOATAG_HOLD("#"),
SIPTAG_SUBJECT_STR("TEST NUA-7.6.2: re-INVITE"),
TAG_END());
run_ab_until(ctx, -1, until_complete, -1, complete_call);
/* Client transitions:
READY -(C1)-> CALLING: nua_invite(), nua_i_state
CALLING -(C3a)-> COMPLETING: nua_r_invite, nua_i_state
COMPLETING -(C4)-> READY: nua_ack(), nua_i_state
*/
TEST_1(e = b->events->head); TEST_E(e->data->e_event, nua_i_state);
TEST(callstate(e->data->e_tags), nua_callstate_calling); /* CALLING */
TEST_1(is_offer_sent(e->data->e_tags));
TEST_1(e = e->next); TEST_E(e->data->e_event, nua_r_invite);
TEST_1(e = e->next); TEST_E(e->data->e_event, nua_i_state);
TEST(callstate(e->data->e_tags), nua_callstate_completing); /* COMPLETING */
TEST_1(is_answer_recv(e->data->e_tags));
TEST(audio_activity(e->data->e_tags), SOA_ACTIVE_INACTIVE);
TEST(video_activity(e->data->e_tags), SOA_ACTIVE_INACTIVE);
TEST_1(!e->next);
free_events_in_list(ctx, b->events);
/*
Server transitions:
READY -(S3a)-> COMPLETED: nua_i_invite, <auto-answer>, nua_i_state
COMPLETED -(S4)-> READY: nua_i_ack, nua_i_state
*/
TEST_1(e = a->events->head); TEST_E(e->data->e_event, nua_i_invite);
TEST(e->data->e_status, 200);
TEST_1(e = e->next); TEST_E(e->data->e_event, nua_i_state);
TEST(callstate(e->data->e_tags), nua_callstate_completed); /* COMPLETED */
TEST_1(is_answer_sent(e->data->e_tags));
TEST(audio_activity(e->data->e_tags), SOA_ACTIVE_INACTIVE);
TEST_1(!e->next);
free_events_in_list(ctx, a->events);
f = test_nat_add_filter(ctx->nat, remove_first_ack, &zero, nat_inbound);
ACK(b, b_call, b_call->nh, TAG_END());
INVITE(b, b_call, b_call->nh, SOATAG_HOLD("*"),
SIPTAG_SUBJECT_STR("TEST NUA-7.6.2: almost overlapping re-INVITE"),
NUTAG_AUTOACK(1),
TAG_END());
run_ab_until(ctx, -1, until_ready, -1, invite_responded);
TEST_1(e = b->events->head); TEST_E(e->data->e_event, nua_i_state);
TEST(callstate(e->data->e_tags), nua_callstate_ready); /* READY */
TEST_1(e = e->next); TEST_E(e->data->e_event, nua_i_state);
TEST(callstate(e->data->e_tags), nua_callstate_calling); /* CALLING */
TEST_1(e = e->next); TEST_E(e->data->e_event, nua_r_invite);
TEST(e->data->e_status, 100);
TEST_1(sip = sip_object(e->data->e_msg));
TEST_1(sip->sip_retry_after);
TEST_1(!e->next);
free_events_in_list(ctx, b->events);
TEST_1(e = a->events->head); TEST_E(e->data->e_event, nua_i_ack);
TEST_1(e = e->next); TEST_E(e->data->e_event, nua_i_state);
TEST(callstate(e->data->e_tags), nua_callstate_ready); /* READY */
TEST(audio_activity(e->data->e_tags), SOA_ACTIVE_INACTIVE);
TEST(video_activity(e->data->e_tags), SOA_ACTIVE_INACTIVE);
TEST_1(!e->next);
free_events_in_list(ctx, a->events);
test_nat_remove_filter(ctx->nat, f);
if (print_headings)
printf("TEST NUA-7.6.2: PASSED\n");
}
/* ---------------------------------------------------------------------- */
/*
......@@ -528,7 +634,7 @@ int test_call_hold(struct context *ctx)
*/
if (print_headings)
printf("TEST NUA-7.6.2: terminate call\n");
printf("TEST NUA-7.6.3: terminate call\n");
BYE(a, a_call, a_call->nh, TAG_END());
run_ab_until(ctx, -1, until_terminated, -1, until_terminated);
......@@ -549,13 +655,17 @@ int test_call_hold(struct context *ctx)
*/
TEST_1(e = b->events->head); TEST_E(e->data->e_event, nua_i_bye);
TEST(e->data->e_status, 200);
if (ctx->proxy_tests && ctx->nat) {
TEST_1(e = e->next); TEST_E(e->data->e_event, nua_r_invite);
TEST(e->data->e_status, 481);
}
TEST_1(e = e->next); TEST_E(e->data->e_event, nua_i_state);
TEST(callstate(e->data->e_tags), nua_callstate_terminated); /* TERMINATED */
TEST_1(!e->next);
free_events_in_list(ctx, b->events);
if (print_headings)
printf("TEST NUA-7.6.2: PASSED\n");
printf("TEST NUA-7.6.3: PASSED\n");
nua_handle_destroy(a_call->nh), a_call->nh = NULL;
nua_handle_destroy(b_call->nh), b_call->nh = NULL;
......@@ -572,7 +682,7 @@ int test_call_hold(struct context *ctx)
| |
|---------ACK------->|
*/
int ack_when_completing(CONDITION_PARAMS)
int complete_call(CONDITION_PARAMS)
{
if (!(check_handle(ep, call, nh, SIP_500_INTERNAL_SERVER_ERROR)))
return 0;
......@@ -581,8 +691,33 @@ int ack_when_completing(CONDITION_PARAMS)
switch (callstate(tags)) {
case nua_callstate_completing:
ACK(ep, call, nh, TAG_END());
return 1;
case nua_callstate_ready:
return 1;
case nua_callstate_terminated:
if (call)
nua_handle_destroy(call->nh), call->nh = NULL;
return 1;
default:
return 0;
}
}
/*
X INVITE
| |
|-------INVITE------>|
|<--------200--------|
*/
int until_complete(CONDITION_PARAMS)
{
if (!(check_handle(ep, call, nh, SIP_500_INTERNAL_SERVER_ERROR)))
return 0;
save_event_in_list(ctx, event, ep, call);
switch (callstate(tags)) {
case nua_callstate_completed:
case nua_callstate_ready:
return 1;
case nua_callstate_terminated:
......@@ -594,6 +729,22 @@ int ack_when_completing(CONDITION_PARAMS)
}
}
static size_t remove_first_ack(void *_once, void *message, size_t len)
{
int *once = _once;
if (*once)
return len;
if (strncmp("ACK ", message, 4) == 0) {
printf("FILTERING %.*s\n", strcspn(message, "\r\n"), (char *)message);
*once = 1;
return 0;
}
return len;
}
/* ======================================================================== */
/* test_reinvite message sequence looks like this:
......@@ -986,6 +1137,17 @@ int until_ready2(CONDITION_PARAMS)
}
}
int invite_responded(CONDITION_PARAMS)
{
if (!(check_handle(ep, call, nh, SIP_500_INTERNAL_SERVER_ERROR)))
return 0;
save_event_in_list(ctx, event, ep, call);
return event == nua_r_invite && status >= 100;
}
int test_reinvites(struct context *ctx)
{
int retval = 0;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment