Commit b9441e98 authored by Pekka Pessi's avatar Pekka Pessi

Added test proxy to nua module.

darcs-hash:20051107205311-65a35-ce5f38773231451b1a9061c40bf6872fc3c3093c.gz
parent 2256126f
......@@ -60,6 +60,8 @@ LDADD = libnua.la \
test_nua_LDFLAGS = -static
test_nua_SOURCES = test_nua.c test_proxy.h test_proxy.c
# ----------------------------------------------------------------------
# Install and distribution rules
......
......@@ -60,6 +60,8 @@ struct call;
#include <su_tagarg.h>
#include <su_tag_io.h>
#include <test_proxy.h>
extern su_log_t nua_log[];
extern su_log_t soa_log[];
extern su_log_t nta_log[];
......@@ -106,6 +108,9 @@ void printer_function(nua_event_t event,
sip_t const *sip,
tagi_t tags[]);
struct proxy_transaction;
struct registration_entry;
struct context
{
su_home_t home[1];
......@@ -135,7 +140,7 @@ struct context
struct event *head, **tail;
} events;
char const *sdp;
} call[1];
} call[1], reg[1];
/* State flags for complex scenarios */
union {
......@@ -147,6 +152,8 @@ struct context
} flags;
} a, b, c;
struct proxy *p;
};
struct event
......@@ -662,7 +669,7 @@ int test_params(struct context *ctx)
if (print_headings)
printf("TEST NUA-2.0: PARAMETERS\n");
ctx->root = su_root_create(ctx); TEST_1(ctx->root);
ctx->root = su_root_create(NULL); TEST_1(ctx->root);
/* Disable threading by command line switch? */
su_root_threading(ctx->root, ctx->threading);
......@@ -1027,6 +1034,8 @@ int test_params(struct context *ctx)
END();
}
/* ======================================================================== */
int test_init(struct context *ctx, char *argv[])
{
BEGIN();
......@@ -1034,15 +1043,24 @@ int test_init(struct context *ctx, char *argv[])
sip_contact_t const *m = NULL;
sip_from_t const *sipaddress = NULL;
ctx->root = su_root_create(ctx); TEST_1(ctx->root);
ctx->root = su_root_create(NULL); TEST_1(ctx->root);
/* Disable threading by command line switch? */
su_root_threading(ctx->root, ctx->threading);
if (print_headings)
printf("TEST NUA-3.0.0: init proxy P\n");
ctx->p = test_proxy_create(ctx->root);
if (print_headings)
printf("TEST NUA-3.0.0: PASSED\n");
if (print_headings)
printf("TEST NUA-3.0.1: init endpoint A\n");
ctx->a.nua = nua_create(ctx->root, a_callback, ctx,
NUTAG_PROXY(ctx->p->uri),
SIPTAG_FROM_STR("sip:alice@example.com"),
NUTAG_URL("sip:*:*"),
SOATAG_USER_SDP_STR("m=audio 5004 RTP/AVP 0 8"),
......@@ -1068,6 +1086,7 @@ int test_init(struct context *ctx, char *argv[])
printf("TEST NUA-3.0.2: init endpoint B\n");
ctx->b.nua = nua_create(ctx->root, b_callback, ctx,
NUTAG_PROXY(ctx->p->uri),
SIPTAG_FROM_STR("sip:bob@example.org"),
NUTAG_URL("sip:*:*"),
SOATAG_USER_SDP_STR("m=audio 5006 RTP/AVP 8 0"),
......@@ -1092,6 +1111,7 @@ int test_init(struct context *ctx, char *argv[])
printf("TEST NUA-3.0.3: init endpoint C\n");
ctx->c.nua = nua_create(ctx->root, c_callback, ctx,
NUTAG_PROXY(ctx->p->uri),
SIPTAG_FROM_STR("sip:charlie@example.net"),
NUTAG_URL("sip:*:*"),
SOATAG_USER_SDP_STR("m=audio 5400 RTP/AVP 8 0"),
......@@ -1108,13 +1128,125 @@ int test_init(struct context *ctx, char *argv[])
TEST_1(ctx->c.contact = sip_contact_dup(ctx->home, m));
TEST_1(ctx->c.to = sip_to_dup(ctx->home, sipaddress));
free_events_in_list(ctx, ctx->c.call);
if (print_headings)
printf("TEST NUA-3.0.3: PASSED\n");
END();
}
/* ======================================================================== */
/* Test REGISTER */
int test_register(struct context *ctx)
{
BEGIN();
struct endpoint *a = &ctx->a, *b = &ctx->b, *c = &ctx->c;
struct call *a_call = a->reg, *b_call = b->reg, *c_call = c->reg;
/* REGISTER test
A B
|------REGISTER----->|
|<-------200---------|
| |
*/
if (print_headings)
printf("TEST NUA-3.1.1: REGISTER a\n");
TEST_1(a_call->nh = nua_handle(a->nua, a_call, TAG_END()));
do_register(a, a_call, a_call->nh, SIPTAG_TO(a->to), TAG_END());
run_a_until(ctx, -1, until_final_response);
if (print_headings)
printf("TEST NUA-3.1.1: PASSED\n");
if (print_headings)
printf("TEST NUA-3.1.1: REGISTER b\n");
TEST_1(b_call->nh = nua_handle(b->nua, b_call, TAG_END()));
do_register(b, b_call, b_call->nh, SIPTAG_TO(b->to), TAG_END());
run_b_until(ctx, -1, until_final_response);
if (print_headings)
printf("TEST NUA-3.1.1: PASSED\n");
if (print_headings)
printf("TEST NUA-3.1.1: REGISTER c\n");
TEST_1(c_call->nh = nua_handle(c->nua, c_call, TAG_END()));
do_register(c, c_call, c_call->nh, SIPTAG_TO(c->to), TAG_END());
run_c_until(ctx, -1, until_final_response);
if (print_headings)
printf("TEST NUA-3.1.1: PASSED\n");
END();
}
int test_unregister(struct context *ctx)
{
BEGIN();
struct endpoint *a = &ctx->a, *b = &ctx->b, *c = &ctx->c;
/* un-REGISTER test
A B
|----un-REGISTER---->|
|<-------200---------|
| |
*/
if (print_headings)
printf("TEST NUA-3.1.1: REGISTER a\n");
if (a->reg->nh) {
unregister(a, NULL, a->reg->nh, TAG_END());
run_a_until(ctx, -1, until_final_response);
nua_handle_destroy(a->reg->nh), a->reg->nh = NULL;
}
if (print_headings)
printf("TEST NUA-3.1.1: PASSED\n");
if (print_headings)
printf("TEST NUA-3.1.1: REGISTER b\n");
if (b->reg->nh) {
unregister(b, NULL, b->reg->nh, TAG_END());
run_b_until(ctx, -1, until_final_response);
nua_handle_destroy(b->reg->nh), b->reg->nh = NULL;
}
if (print_headings)
printf("TEST NUA-3.1.1: PASSED\n");
if (print_headings)
printf("TEST NUA-3.1.1: REGISTER c\n");
if (c->reg->nh) {
unregister(c, NULL, c->reg->nh, TAG_END());
run_c_until(ctx, -1, until_final_response);
nua_handle_destroy(c->reg->nh), c->reg->nh = NULL;
}
if (print_headings)
printf("TEST NUA-3.1.1: PASSED\n");
END();
}
/* ======================================================================== */
CONDITION_FUNCTION(save_events)
{
return save_event_in_list(ctx, event, ep, ep->call) > 0;
......@@ -1307,7 +1439,7 @@ int test_basic_call(struct context *ctx)
TEST_1(a_call->nh = nua_handle(a->nua, a_call, SIPTAG_TO(b->to), TAG_END()));
invite(a, a_call, a_call->nh, NUTAG_URL(b->contact->m_url),
invite(a, a_call, a_call->nh, /* NUTAG_URL(b->contact->m_url), */
SOATAG_USER_SDP_STR(a_call->sdp),
TAG_END());
......@@ -1445,7 +1577,7 @@ int test_reject_a(struct context *ctx)
b_call->sdp = "m=audio 5010 RTP/AVP 0 8";
TEST_1(a_call->nh = nua_handle(a->nua, a_call, SIPTAG_TO(b->to), TAG_END()));
invite(a, a_call, a_call->nh, NUTAG_URL(b->contact->m_url),
invite(a, a_call, a_call->nh, /* NUTAG_URL(b->contact->m_url), */
SIPTAG_SUBJECT_STR("reject-1"),
SOATAG_USER_SDP_STR(a_call->sdp),
TAG_END());
......@@ -1551,7 +1683,7 @@ int test_reject_b(struct context *ctx)
/* Make call reject-2 */
TEST_1(a_call->nh = nua_handle(a->nua, a_call, SIPTAG_TO(b->to), TAG_END()));
invite(a, a_call, a_call->nh, NUTAG_URL(b->contact->m_url),
invite(a, a_call, a_call->nh, /* NUTAG_URL(b->contact->m_url), */
SIPTAG_SUBJECT_STR("reject-2"),
SOATAG_USER_SDP_STR(a_call->sdp),
TAG_END());
......@@ -1687,7 +1819,7 @@ int test_reject_302(struct context *ctx)
b_call->sdp = "m=audio 5010 RTP/AVP 0 8";
TEST_1(a_call->nh = nua_handle(a->nua, a_call, SIPTAG_TO(b->to), TAG_END()));
invite(a, a_call, a_call->nh, NUTAG_URL(b->contact->m_url),
invite(a, a_call, a_call->nh, /* NUTAG_URL(b->contact->m_url), */
SIPTAG_SUBJECT_STR("reject-3"),
SOATAG_USER_SDP_STR(a_call->sdp),
TAG_END());
......@@ -1918,7 +2050,7 @@ int test_reject_401(struct context *ctx)
b_call->sdp = "m=audio 5010 RTP/AVP 0 8";
TEST_1(a_call->nh = nua_handle(a->nua, a_call, SIPTAG_TO(b->to), TAG_END()));
invite(a, a_call, a_call->nh, NUTAG_URL(b->contact->m_url),
invite(a, a_call, a_call->nh, /* NUTAG_URL(b->contact->m_url), */
SIPTAG_SUBJECT_STR("reject-401"),
SOATAG_USER_SDP_STR(a_call->sdp),
TAG_END());
......@@ -2115,7 +2247,7 @@ int test_call_cancel(struct context *ctx)
TEST_1(a_call->nh = nua_handle(a->nua, a_call, SIPTAG_TO(b->to), TAG_END()));
invite(a, a_call, a_call->nh, NUTAG_URL(b->contact->m_url),
invite(a, a_call, a_call->nh, /* NUTAG_URL(b->contact->m_url), */
SOATAG_USER_SDP_STR(a_call->sdp),
TAG_END());
......@@ -2168,7 +2300,7 @@ int test_call_cancel(struct context *ctx)
TEST_1(a_call->nh = nua_handle(a->nua, a_call, SIPTAG_TO(b->to), TAG_END()));
invite(a, a_call, a_call->nh, NUTAG_URL(b->contact->m_url),
invite(a, a_call, a_call->nh, /* NUTAG_URL(b->contact->m_url), */
SOATAG_USER_SDP_STR(a_call->sdp),
SIPTAG_REJECT_CONTACT_STR("*;audio=FALSE"),
TAG_END());
......@@ -2288,7 +2420,7 @@ int test_early_bye(struct context *ctx)
TEST_1(a_call->nh = nua_handle(a->nua, a_call, SIPTAG_TO(b->to), TAG_END()));
invite(a, a_call, a_call->nh, NUTAG_URL(b->contact->m_url),
invite(a, a_call, a_call->nh, /* NUTAG_URL(b->contact->m_url), */
SOATAG_USER_SDP_STR(a_call->sdp),
TAG_END());
......@@ -2413,7 +2545,7 @@ int test_call_hold(struct context *ctx)
"a=rtcp:6011\n";
TEST_1(a_call->nh = nua_handle(a->nua, a_call, SIPTAG_TO(b->to), TAG_END()));
invite(a, a_call, a_call->nh, NUTAG_URL(b->contact->m_url),
invite(a, a_call, a_call->nh, /* NUTAG_URL(b->contact->m_url), */
SOATAG_USER_SDP_STR(a_call->sdp),
TAG_END());
......@@ -2890,7 +3022,7 @@ int test_session_timer(struct context *ctx)
TEST_1(a_call->nh = nua_handle(a->nua, a_call, SIPTAG_TO(b->to), TAG_END()));
invite(a, a_call, a_call->nh, NUTAG_URL(b->contact->m_url),
invite(a, a_call, a_call->nh, /* NUTAG_URL(b->contact->m_url), */
SOATAG_USER_SDP_STR(a_call->sdp),
NUTAG_SESSION_TIMER(15),
NUTAG_MIN_SE(5),
......@@ -3093,7 +3225,7 @@ int test_refer(struct context *ctx)
TEST_1(a_call->nh = nua_handle(a->nua, a_call, SIPTAG_TO(b->to), TAG_END()));
invite(a, a_call, a_call->nh, NUTAG_URL(b->contact->m_url),
invite(a, a_call, a_call->nh, /* NUTAG_URL(b->contact->m_url), */
SOATAG_USER_SDP_STR(a_call->sdp),
TAG_END());
......@@ -3241,7 +3373,7 @@ int test_refer(struct context *ctx)
TEST_1(a_c2->nh = nua_handle(a->nua, a_c2, SIPTAG_TO(to), TAG_END()));
invite(a, a_c2, a_c2->nh, NUTAG_URL(refer_to->r_url),
invite(a, a_c2, a_c2->nh, /* NUTAG_URL(refer_to->r_url), */
NUTAG_REFER_EVENT(r_event),
NUTAG_NOTIFY_REFER(a_call->nh),
SOATAG_USER_SDP_STR(a_c2->sdp),
......@@ -3446,7 +3578,7 @@ int test_methods(struct context *ctx)
TEST_1(a_call->nh = nua_handle(a->nua, a_call, SIPTAG_TO(b->to), TAG_END()));
message(a, a_call, a_call->nh, NUTAG_URL(b->contact->m_url),
message(a, a_call, a_call->nh, /* NUTAG_URL(b->contact->m_url), */
SIPTAG_SUBJECT_STR("Hello"),
SIPTAG_CONTENT_TYPE_STR("text/plain"),
SIPTAG_PAYLOAD_STR("Hello hellO!\n"),
......@@ -3497,7 +3629,7 @@ int test_methods(struct context *ctx)
TEST_1(a_call->nh = nua_handle(a->nua, a_call, SIPTAG_TO(a->to), TAG_END()));
message(a, a_call, a_call->nh, NUTAG_URL(a->contact->m_url),
message(a, a_call, a_call->nh, /* NUTAG_URL(a->contact->m_url), */
SIPTAG_SUBJECT_STR("Hello"),
SIPTAG_CONTENT_TYPE_STR("text/plain"),
SIPTAG_PAYLOAD_STR("Hello hellO!\n"),
......@@ -3537,7 +3669,7 @@ int test_methods(struct context *ctx)
TEST_1(a_call->nh = nua_handle(a->nua, a_call, SIPTAG_TO(b->to), TAG_END()));
options(a, a_call, a_call->nh, NUTAG_URL(b->contact->m_url),
options(a, a_call, a_call->nh, /* NUTAG_URL(b->contact->m_url), */
TAG_END());
run_ab_until(ctx, -1, save_until_final_response, -1, save_until_received);
......@@ -3587,7 +3719,7 @@ int test_methods(struct context *ctx)
TEST_1(a_call->nh = nua_handle(a->nua, a_call, SIPTAG_TO(b->to), TAG_END()));
publish(a, a_call, a_call->nh, NUTAG_URL(b->contact->m_url),
publish(a, a_call, a_call->nh, /* NUTAG_URL(b->contact->m_url), */
SIPTAG_EVENT_STR("presence"),
SIPTAG_CONTENT_TYPE_STR("text/urllist"),
SIPTAG_PAYLOAD_STR("sip:example.com\n"),
......@@ -3622,7 +3754,7 @@ int test_methods(struct context *ctx)
TEST_1(a_call->nh = nua_handle(a->nua, a_call, SIPTAG_TO(b->to), TAG_END()));
publish(a, a_call, a_call->nh, NUTAG_URL(b->contact->m_url),
publish(a, a_call, a_call->nh, /* NUTAG_URL(b->contact->m_url), */
SIPTAG_EVENT_STR("presence"),
SIPTAG_CONTENT_TYPE_STR("text/urllist"),
SIPTAG_PAYLOAD_STR("sip:example.com\n"),
......@@ -3792,7 +3924,7 @@ int test_events(struct context *ctx)
TAG_END());
run_b_until(ctx, nua_r_notifier, until_final_response);
subscribe(a, a_call, a_call->nh, NUTAG_URL(b->contact->m_url),
subscribe(a, a_call, a_call->nh, NUTAG_URL(b->contact->m_url),
SIPTAG_EVENT_STR("presence"),
SIPTAG_ACCEPT_STR("application/xpidf, application/pidf+xml"),
TAG_END());
......@@ -4080,6 +4212,8 @@ int test_deinit(struct context *ctx)
run_c_until(ctx, nua_r_shutdown, until_final_response);
nua_destroy(ctx->c.nua), ctx->c.nua = NULL;
test_proxy_destroy(ctx->p), ctx->p = NULL;
su_root_destroy(ctx->root);
END();
......@@ -4247,19 +4381,25 @@ int main(int argc, char *argv[])
if (o_events_c)
ctx->c.printer = print_event;
retval |= test_basic_call(ctx); SINGLE_FAILURE_CHECK();
retval |= test_reject_a(ctx); SINGLE_FAILURE_CHECK();
retval |= test_reject_b(ctx); SINGLE_FAILURE_CHECK();
retval |= test_reject_302(ctx); SINGLE_FAILURE_CHECK();
retval |= test_reject_401(ctx); SINGLE_FAILURE_CHECK();
retval |= test_call_cancel(ctx); SINGLE_FAILURE_CHECK();
retval |= test_early_bye(ctx); SINGLE_FAILURE_CHECK();
retval |= test_call_hold(ctx); SINGLE_FAILURE_CHECK();
retval |= test_session_timer(ctx); SINGLE_FAILURE_CHECK();
retval |= test_refer(ctx); SINGLE_FAILURE_CHECK();
/* retval |= test_100rel(ctx); SINGLE_FAILURE_CHECK(); */
retval |= test_methods(ctx); SINGLE_FAILURE_CHECK();
retval |= test_events(ctx); SINGLE_FAILURE_CHECK();
retval |= test_register(ctx); SINGLE_FAILURE_CHECK();
if (retval == 0) {
retval |= test_basic_call(ctx); SINGLE_FAILURE_CHECK();
retval |= test_reject_a(ctx); SINGLE_FAILURE_CHECK();
retval |= test_reject_b(ctx); SINGLE_FAILURE_CHECK();
retval |= test_reject_302(ctx); SINGLE_FAILURE_CHECK();
retval |= test_reject_401(ctx); SINGLE_FAILURE_CHECK();
retval |= test_call_cancel(ctx); SINGLE_FAILURE_CHECK();
retval |= test_early_bye(ctx); SINGLE_FAILURE_CHECK();
retval |= test_call_hold(ctx); SINGLE_FAILURE_CHECK();
retval |= test_session_timer(ctx); SINGLE_FAILURE_CHECK();
retval |= test_refer(ctx); SINGLE_FAILURE_CHECK();
/* retval |= test_100rel(ctx); SINGLE_FAILURE_CHECK(); */
retval |= test_methods(ctx); SINGLE_FAILURE_CHECK();
retval |= test_events(ctx); SINGLE_FAILURE_CHECK();
}
retval |= test_unregister(ctx); SINGLE_FAILURE_CHECK();
}
retval |= test_deinit(ctx); SINGLE_FAILURE_CHECK();
......
/*
* This file is part of the Sofia-SIP package
*
* Copyright (C) 2005 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 test_proxy.c
* @brief Extremely simple proxy and registrar for testing nua
*
* @author Pekka Pessi <Pekka.Pessi@nokia.com>
*
* @date Created: Thu Nov 3 22:49:46 EET 2005
*/
#include "config.h"
#include <string.h>
struct proxy;
struct proxy_transaction;
struct registration_entry;
#define SU_ROOT_MAGIC_T struct proxy
#define NTA_LEG_MAGIC_T struct proxy
#define NTA_OUTGOING_MAGIC_T struct proxy_transaction
#define NTA_INCOMING_MAGIC_T struct proxy_transaction
#include <su_wait.h>
#include <nta.h>
#include <sip_header.h>
#include <sip_status.h>
#include <sip_util.h>
#define LIST_PROTOS(STORAGE, PREFIX, T) \
STORAGE void PREFIX ##_insert(T **list, T *node), \
PREFIX ##_remove(T *node)
#define LIST_BODIES(STORAGE, PREFIX, T, NEXT, PREV) \
STORAGE void PREFIX ##_insert(T **list, T *node) \
{ \
if ((node->NEXT = *list)) { \
node->PREV = node->NEXT->PREV; \
node->NEXT->PREV = &node->NEXT; \
} \
else \
node->PREV = list; \
*list = node; \
} \
STORAGE void PREFIX ##_remove(T *node) \
{ \
if (node->PREV) \
if ((*node->PREV = node->NEXT)) \
node->NEXT->PREV = node->PREV; \
node->PREV = NULL; \
} \
extern int LIST_DUMMY_VARIABLE
#include <test_proxy.h>
LIST_PROTOS(static, registration_entry, struct registration_entry);
static struct registration_entry *
registration_entry_new(struct proxy *, url_t const *);
static void registration_entry_destroy(struct registration_entry *e);
struct registration_entry
{
struct registration_entry *next, **prev;
struct proxy *proxy; /* backpointer */
url_t *aor; /* address-of-record */
sip_contact_t *binding; /* bindings */
};
LIST_PROTOS(static, proxy_transaction, struct proxy_transaction);
struct proxy_transaction *proxy_transaction_new(struct proxy *);
static void proxy_transaction_destroy(struct proxy_transaction *t);
struct proxy_transaction
{
struct proxy_transaction *next, **prev;
struct proxy *proxy; /* backpointer */
sip_request_t *rq; /* request line */
nta_incoming_t *server; /* server transaction */
nta_outgoing_t *client; /* client transaction */
};
static int proxy_request(struct proxy *proxy,
nta_leg_t *leg,
nta_incoming_t *irq,
sip_t const *sip);
static int proxy_ack_cancel(struct proxy_transaction *t,
nta_incoming_t *irq,
sip_t const *sip);
static int proxy_response(struct proxy_transaction *t,
nta_outgoing_t *client,
sip_t const *sip);
static int process_register(struct proxy *proxy,
nta_incoming_t *irq,
sip_t const *sip);
static struct registration_entry *
registration_entry_find(struct proxy const *proxy, url_t const *uri);
/* Proxy entry point */
static int
test_proxy_init(su_root_t *root, struct proxy *proxy)
{
proxy->root = root;
proxy->agent = nta_agent_create(root,
URL_STRING_MAKE("sip:*:*"),
NULL, NULL,
NTATAG_UA(0),
TAG_END());
proxy->defleg = nta_leg_tcreate(proxy->agent,
proxy_request,
proxy,
NTATAG_NO_DIALOG(1),
TAG_END());
if (!proxy->defleg)
return -1;
proxy->uri = nta_agent_contact(proxy->agent)->m_url;
return 0;
}
static void
test_proxy_deinit(su_root_t *root, struct proxy *proxy)
{
nta_agent_destroy(proxy->agent);
}
/* Create tst proxy object */
struct proxy *test_proxy_create(su_root_t *root)
{
struct proxy *p = su_home_new(sizeof *p);
if (p) {
if (su_clone_start(root,
p->clone,
p,
test_proxy_init,
test_proxy_deinit) == -1)
su_home_unref(p->home), p = NULL;
}
return p;
}
void test_proxy_destroy(struct proxy *p)
{
if (p) {
su_clone_stop(p->clone);
su_home_unref(p->home);
}
}
/** Forward request */
static
int proxy_request(struct proxy *proxy,
nta_leg_t *leg,