Commit 21586531 authored by Pekka Pessi's avatar Pekka Pessi

nua: added check_etsi.c with ETSI test cases

darcs-hash:20090121175325-db55f-2ee73a425c50d483913a800ff627081a8a1ef1bf.gz
parent 30e3d69b
......@@ -45,6 +45,7 @@ COVERAGE_INPUT = $(libnua_la_SOURCES) $(include_sofia_HEADERS)
check_nua_SOURCES = check_nua.c check_nua.h \
check_session.c check_register.c \
check_etsi.c \
test_s2.h test_s2.c
check_nua_LDADD = $(nua_libs) @CHECK_LIBS@
......
/*
* This file is part of the Sofia-SIP package
*
* Copyright (C) 2008 Nokia Corporation.
*
* Contact: Pekka Pessi <pekka.pessi@nokia.com>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public License
* as published by the Free Software Foundation; either version 2.1 of
* the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
* 02110-1301 USA
*
*/
/**@CFILE check_session.c
*
* @brief NUA module tests for SIP session handling
*
* @author Pekka Pessi <Pekka.Pessi@nokia.com>
*
* @copyright (C) 2008 Nokia Corporation.
*/
#include "config.h"
#include "check_nua.h"
#include "test_s2.h"
#include <sofia-sip/sip_status.h>
#include <sofia-sip/sip_header.h>
#include <sofia-sip/soa.h>
#include <sofia-sip/su_tagarg.h>
#include <sofia-sip/su_string.h>
#include <sofia-sip/su_tag_io.h>
#include <stdlib.h>
#include <string.h>
#include <assert.h>
/* ====================================================================== */
static nua_t *nua;
static soa_session_t *soa = NULL;
static struct dialog *d1 = NULL;
static struct dialog *d2 = NULL;
#define CRLF "\r\n"
static void etsi_setup(void)
{
nua = s2_nua_setup("ETSI",
NUTAG_OUTBOUND("no-options-keepalive, no-validate"),
TAG_END());
soa = soa_create(NULL, s2->root, NULL);
fail_if(!soa);
soa_set_params(soa,
SOATAG_USER_SDP_STR("m=audio 5008 RTP/AVP 8 0" CRLF
"m=video 5010 RTP/AVP 34" CRLF),
TAG_END());
d1 = su_home_new(sizeof *d1); fail_if(!d1);
d2 = su_home_new(sizeof *d2); fail_if(!d2);
}
static void etsi_teardown(void)
{
s2_teardown_started("ETSI");
mark_point();
nua_shutdown(nua);
fail_unless(s2_check_event(nua_r_shutdown, 200));
s2_nua_teardown();
}
static void save_sdp_to_soa(struct message *message)
{
sip_payload_t *pl;
char const *body;
isize_t bodylen;
fail_if(!message);
fail_if(!message->sip->sip_content_length);
fail_if(!message->sip->sip_content_type);
fail_if(strcmp(message->sip->sip_content_type->c_type,
"application/sdp"));
fail_if(!message->sip->sip_payload);
pl = message->sip->sip_payload;
body = pl->pl_data, bodylen = pl->pl_len;
fail_if(soa_set_remote_sdp(soa, NULL, body, (issize_t)bodylen) < 0);
}
static void process_offer(struct message *message)
{
save_sdp_to_soa(message);
fail_if(soa_generate_answer(soa, NULL) < 0);
}
static void
respond_with_sdp(struct message *request,
struct dialog *dialog,
int status, char const *phrase,
tag_type_t tag, tag_value_t value, ...)
{
ta_list ta;
char const *body;
isize_t bodylen;
fail_if(soa_get_local_sdp(soa, NULL, &body, &bodylen) != 1);
ta_start(ta, tag, value);
s2_respond_to(request, dialog, status, phrase,
SIPTAG_CONTENT_TYPE_STR("application/sdp"),
SIPTAG_PAYLOAD_STR(body),
SIPTAG_CONTENT_DISPOSITION_STR("session"),
ta_tags(ta));
ta_end(ta);
}
static struct message *
invite_sent_by_nua(nua_handle_t *nh,
tag_type_t tag, tag_value_t value, ...)
{
ta_list ta;
ta_start(ta, tag, value);
nua_invite(nh, SOATAG_USER_SDP_STR("m=audio 5004 RTP/AVP 0 8"),
ta_tags(ta));
ta_end(ta);
fail_unless(s2_check_callstate(nua_callstate_calling));
return s2_wait_for_request(SIP_METHOD_INVITE);
}
static void
bye_by_nua(struct dialog *dialog, nua_handle_t *nh,
tag_type_t tag, tag_value_t value, ...)
{
ta_list ta;
struct message *bye;
ta_start(ta, tag, value);
nua_bye(nh, ta_tags(ta));
ta_end(ta);
bye = s2_wait_for_request(SIP_METHOD_BYE);
fail_if(!bye);
s2_respond_to(bye, dialog, SIP_200_OK, TAG_END());
s2_free_message(bye);
fail_unless(s2_check_event(nua_r_bye, 200));
fail_unless(s2_check_callstate(nua_callstate_terminated));
}
/* ====================================================================== */
/* 6 - ETSI cases */
/* 6.1 Call Control - Originating Endpoint - Call Establishment */
START_TEST(SIP_CC_OE_CE_V_019)
{
nua_handle_t *nh;
struct message *invite;
s2_case("6.1.1", "SIP_CC_OE_CE_V_019",
"Ensure that the IUT when an INVITE client transaction "
"is in the Calling state, on receipt of Success (200 OK) "
"responses differing only on the tag in the To header, "
"sends an ACK request with a To header identical to the "
"received one for each received Success (200 OK) responses.");
nh = nua_handle(nua, NULL, SIPTAG_TO(s2->local), TAG_END());
invite = invite_sent_by_nua(nh, TAG_END());
process_offer(invite);
respond_with_sdp(invite, d1, SIP_200_OK, TAG_END());
fail_unless(s2_check_event(nua_r_invite, 200));
fail_unless(s2_check_callstate(nua_callstate_ready));
fail_unless(s2_check_request(SIP_METHOD_ACK));
respond_with_sdp(invite, d2, SIP_200_OK, TAG_END());
s2_free_message(invite);
fail_unless(s2_check_event(nua_i_fork, 200));
fail_unless(s2_check_callstate(nua_callstate_ready));
fail_unless(s2_check_request(SIP_METHOD_ACK));
bye_by_nua(d1, nh, TAG_END());
nua_handle_destroy(nh);
}
END_TEST
START_TEST(SIP_CC_OE_CE_TI_008)
{
nua_handle_t *nh;
struct message *invite;
s2_case("6.1.2", "SIP_CC_OE_CE_TI_008",
"If an unreliable transport is used, ensure that the IUT, "
"when an INVITE client transaction is in the Completed state, "
"on receipt of final responses that matches the transaction, "
"still answer with an ACK request until timer D set to at "
"least 32 second expires.");
nh = nua_handle(nua, NULL, SIPTAG_TO(s2->local), TAG_END());
invite = invite_sent_by_nua(nh, TAG_END());
process_offer(invite);
respond_with_sdp(invite, d1, SIP_200_OK, TAG_END());
fail_unless(s2_check_event(nua_r_invite, 200));
fail_unless(s2_check_callstate(nua_callstate_ready));
fail_unless(s2_check_request(SIP_METHOD_ACK));
respond_with_sdp(invite, d1, SIP_200_OK, TAG_END());
fail_unless(s2_check_request(SIP_METHOD_ACK));
s2_fast_forward(32);
respond_with_sdp(invite, d1, SIP_200_OK, TAG_END());
s2_free_message(invite);
fail_if(s2_check_request_timeout(SIP_METHOD_ACK, 500));
bye_by_nua(d1, nh, TAG_END());
nua_handle_destroy(nh);
}
END_TEST
TCase *sip_cc_oe_ce_tcase(void)
{
TCase *tc = tcase_create("6.1 - ETSI CC OE - Call Establishment");
tcase_add_checked_fixture(tc, etsi_setup, etsi_teardown);
{
tcase_add_test(tc, SIP_CC_OE_CE_TI_008);
tcase_add_test(tc, SIP_CC_OE_CE_V_019);
}
return tc;
}
/* ====================================================================== */
void check_etsi_cases(Suite *suite)
{
suite_add_tcase(suite, sip_cc_oe_ce_tcase());
}
......@@ -111,6 +111,7 @@ int main(int argc, char *argv[])
check_register_cases(suite);
check_session_cases(suite);
check_etsi_cases(suite);
runner = srunner_create(suite);
......
......@@ -10,6 +10,7 @@ void check_nua_tcase_add_test(TCase *, TFun, char const *name);
void check_session_cases(Suite *suite);
void check_register_cases(Suite *suite);
void check_etsi_cases(Suite *suite);
void check_simple_cases(Suite *suite);
#endif
......
......@@ -358,8 +358,15 @@ s2_next_request(void)
struct message *
s2_wait_for_request(sip_method_t method, char const *name)
{
return s2_wait_for_request_timeout(method, name, -1);
}
struct message *
s2_wait_for_request_timeout(sip_method_t method, char const *name, int timeout)
{
struct message *m;
int t = timeout;
for (;;) {
for (m = s2->received; m; m = m->next) {
......@@ -374,6 +381,8 @@ s2_wait_for_request(sip_method_t method, char const *name)
}
su_root_step(s2->root, 100);
if (timeout != -1 && ((t -= 100) <= 0))
break;
}
return NULL;
......@@ -387,6 +396,14 @@ s2_check_request(sip_method_t method, char const *name)
return m != NULL;
}
int
s2_check_request_timeout(sip_method_t method, char const *name, int timeout)
{
struct message *m = s2_wait_for_request_timeout(method, name, timeout);
s2_free_message(m);
return m != NULL;
}
void
s2_save_uas_dialog(struct dialog *d, sip_t *sip)
{
......
......@@ -144,7 +144,10 @@ int s2_check_response(int status, sip_method_t method, char const *name);
struct message *s2_next_request(void);
struct message *s2_wait_for_request(sip_method_t method, char const *name);
struct message *s2_wait_for_request_timeout(sip_method_t, char const *,
int timeout);
int s2_check_request(sip_method_t method, char const *name);
int s2_check_request_timeout(sip_method_t method, char const *, int timeout);
int s2_check_substate(struct event *e, enum nua_substate state);
......
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