sync to current darcs tree:
Tue Nov 20 11:46:34 EST 2007 Pekka Pessi <Pekka.Pessi@nokia.com> * nua_register.c: silenced warning with URL_INIT_AS() on Sun CC Tue Nov 20 11:47:06 EST 2007 Pekka Pessi <Pekka.Pessi@nokia.com> * test_register.c: fixed authentication caching issue Tue Nov 20 12:09:19 EST 2007 Pekka.Pessi@nokia.com * tport: tport_name_is_resolved() now uses host_is_ip_address() Tue Nov 20 12:53:54 EST 2007 Pekka.Pessi@nokia.com * tport.c: fixed EXPENSIVE unresolved bug. Wed Nov 21 07:10:40 EST 2007 Pekka Pessi <Pekka.Pessi@nokia.com> * test_tport.c: skipping tests on TLS if send fails. Wed Nov 21 11:46:42 EST 2007 Pekka.Pessi@nokia.com * test_nta.c: removed dead code Thu Nov 22 08:42:14 EST 2007 Pekka.Pessi@nokia.com * test_nta.c: refactored client side tests Thu Nov 22 09:39:45 EST 2007 Pekka.Pessi@nokia.com * nta: added nta_sip_is_internal(). Tue Nov 27 13:43:41 EST 2007 Pekka.Pessi@nokia.com * test_htable2.c: removed conversion warning Conversion of size_t to isize_t when compiled wihout --disable-size-compat. Wed Nov 21 11:16:04 EST 2007 Daniele Rondina <geaaru at gmail dot com> * nta.c: nta_outgoing_*create() now uses NTATAG_TPORT() even if NTATAG_DEFAULT_PROXY() is set Thu Nov 22 09:36:21 EST 2007 Pekka.Pessi@nokia.com * nta.c: always use tport from NTATAG_TPORT() (even if it is bad) Add tests, too. Thu Nov 22 10:01:33 EST 2007 Pekka.Pessi@nokia.com * nta: added nta_msg_is_internal(). Mon Nov 26 17:08:16 EST 2007 Pekka.Pessi@nokia.com * test_proxy.c: removed memory leaks Mon Nov 26 17:08:35 EST 2007 Pekka.Pessi@nokia.com * test_basic_call.c: fixed --no-proxy tests Mon Nov 26 17:12:27 EST 2007 Pekka.Pessi@nokia.com * sofia-sip/su_wait.h: added su_msg_new(), su_msg_send_to(), su_msg_deinitializer() Reduce overhead from message passing. Mon Nov 26 19:15:41 EST 2007 Pekka Pessi <Pekka.Pessi@nokia.com> * configure.ac: defining HAVE_SOFIA_HTTP Mon Nov 26 19:23:05 EST 2007 Pekka.Pessi@nokia.com * nua: moved message passing into nua_stack.c. Recfactored reference counting. This seems to fix the memory leak within 1.12.7. Wed Nov 28 10:15:07 EST 2007 Pekka.Pessi@nokia.com * test_su.c: removed calls of deprecated (and unimplemented) functions su_clone_pause()/su_clone_resume() Thu Nov 22 09:59:13 EST 2007 Pekka.Pessi@nokia.com * nua_stack.c: more logging on bad authentication Mon Nov 26 19:49:34 EST 2007 Pekka.Pessi@nokia.com * tport.h, tport.c: updated tport_create() docs Thu Nov 29 12:17:40 EST 2007 Pekka Pessi <Pekka.Pessi@nokia.com> * tport: collecting statistics Thu Nov 29 12:21:10 EST 2007 Pekka.Pessi@nokia.com * rules/sofia.am: defining INTERNAL_INCLUDES so it can be used from any subdir utils/Makefile.am, libsofia-sip-ua/nua/Makefile.am: using INCLUDES from sofia.am Thu Nov 29 13:03:44 EST 2007 Pekka.Pessi@nokia.com * nua: moved test_nua contents in ltlibraries Thu Nov 29 13:05:25 EST 2007 Pekka.Pessi@nokia.com * Makefile.am, configure.ac: added subdir tests for Check-based module tests Fri Nov 30 09:03:14 EST 2007 Pekka Pessi <Pekka.Pessi@nokia.com> * nua_session.c: avoid NULL nua_session_state_t pointer in nua_update_client_report Thanks to Fabio Margarido for reporting this problem. git-svn-id: http://svn.freeswitch.org/svn/freeswitch/trunk@6539 d0543943-73ff-0310-b7d9-9358b9ac24b2
This commit is contained in:
parent
3c14db6122
commit
058ab862b3
|
@ -7,7 +7,7 @@
|
|||
|
||||
AUTOMAKE_OPTIONS = foreign 1.7
|
||||
|
||||
SUBDIRS = libsofia-sip-ua $(GLIB_SUBDIRS) utils packages
|
||||
SUBDIRS = libsofia-sip-ua $(GLIB_SUBDIRS) utils packages tests
|
||||
DIST_SUBDIRS = libsofia-sip-ua libsofia-sip-ua-glib utils packages \
|
||||
win32 open_c
|
||||
|
||||
|
|
|
@ -100,6 +100,10 @@ SAC_SOFIA_SU
|
|||
SAC_OPENSSL
|
||||
SAC_TPORT
|
||||
|
||||
dnl Check is used for testing
|
||||
PKG_CHECK_MODULES(CHECK, check >= 0.9.4, have_check="yes", have_check="no")
|
||||
AM_CONDITIONAL(HAVE_CHECK, test x"$have_check" = "xyes")
|
||||
|
||||
### internal modules
|
||||
### ----------------
|
||||
AC_DEFINE([HAVE_SOFIA_SIP], 1, [Define to 1 always])
|
||||
|
@ -122,11 +126,12 @@ fi
|
|||
AM_CONDITIONAL([HAVE_STUN], [test "x$enable_stun" = xyes])
|
||||
|
||||
AC_ARG_ENABLE(nth,
|
||||
[ --disable-nth disable nth and http modules (enabled)],
|
||||
[ --disable-nth disable HTTP-related modules nth and http (enabled)],
|
||||
, enable_nth=yes)
|
||||
AM_CONDITIONAL([HAVE_NTH], [test "x$enable_nth" = xyes])
|
||||
if test x$enable_nth = xyes ; then
|
||||
AC_DEFINE([HAVE_SOFIA_NTH], 1, [Define to 1 if we use NTH library])
|
||||
AC_DEFINE([HAVE_SOFIA_HTTP], 1, [Define to 1 if we use HTTP parser library])
|
||||
fi
|
||||
|
||||
dnl Disable NTLM support by default
|
||||
|
@ -325,6 +330,7 @@ libsofia-sip-ua-glib/su-glib/Makefile
|
|||
libsofia-sip-ua-glib/su-glib/Doxyfile
|
||||
utils/Makefile
|
||||
utils/Doxyfile
|
||||
tests/Makefile
|
||||
win32/Makefile
|
||||
win32/config.h
|
||||
open_c/Makefile
|
||||
|
|
|
@ -2780,12 +2780,26 @@ void nta_msg_discard(nta_agent_t *agent, msg_t *msg)
|
|||
msg_destroy(msg);
|
||||
}
|
||||
|
||||
/** Check if the headers are from response generated locally by NTA. */
|
||||
int nta_sip_is_internal(sip_t const *sip)
|
||||
{
|
||||
return
|
||||
sip == NULL /* No message generated */
|
||||
|| (sip->sip_flags & NTA_INTERNAL_MSG) == NTA_INTERNAL_MSG;
|
||||
}
|
||||
|
||||
/** Check if the message is internally generated by NTA. */
|
||||
int nta_is_internal_msg(msg_t const *msg)
|
||||
int nta_msg_is_internal(msg_t const *msg)
|
||||
{
|
||||
return msg_get_flags(msg, NTA_INTERNAL_MSG) == NTA_INTERNAL_MSG;
|
||||
}
|
||||
|
||||
/** Check if the message is internally generated by NTA.
|
||||
*
|
||||
* @deprecated Use nta_msg_is_internal() instead
|
||||
*/
|
||||
int nta_is_internal_msg(msg_t const *msg) { return nta_msg_is_internal(msg); }
|
||||
|
||||
/* ====================================================================== */
|
||||
/* 5) Stateless operation */
|
||||
|
||||
|
@ -6343,6 +6357,7 @@ static int outgoing_features(nta_agent_t *agent, nta_outgoing_t *orq,
|
|||
msg_t *msg, sip_t *sip,
|
||||
tagi_t *tags);
|
||||
static void outgoing_prepare_send(nta_outgoing_t *orq);
|
||||
static void outgoing_send_via(nta_outgoing_t *orq, tport_t *tp);
|
||||
static void outgoing_send(nta_outgoing_t *orq, int retransmit);
|
||||
static void outgoing_try_tcp_instead(nta_outgoing_t *orq);
|
||||
static void outgoing_try_udp_instead(nta_outgoing_t *orq);
|
||||
|
@ -6884,7 +6899,7 @@ nta_outgoing_t *outgoing_create(nta_agent_t *agent,
|
|||
int invite_100rel = agent->sa_invite_100rel;
|
||||
|
||||
tagi_t const *t;
|
||||
tport_t const *override_tport = NULL;
|
||||
tport_t *override_tport = NULL;
|
||||
|
||||
if (!agent->sa_tport_ip6)
|
||||
res_order = nta_res_ip4_only;
|
||||
|
@ -6988,11 +7003,16 @@ nta_outgoing_t *outgoing_create(nta_agent_t *agent,
|
|||
tpn = tport_name(override_tport);
|
||||
orq->orq_user_tport = 1;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if (route_url) {
|
||||
if (route_url && !orq->orq_user_tport) {
|
||||
invalid = nta_tpn_by_url(home, orq->orq_tpn, &scheme, &port, route_url);
|
||||
|
||||
if (override_tport) { /* Use transport protocol name from transport */
|
||||
if (strcmp(orq->orq_tpn->tpn_proto, "*") == 0)
|
||||
orq->orq_tpn->tpn_proto = tport_name(override_tport)->tpn_proto;
|
||||
}
|
||||
|
||||
resolved = tport_name_is_resolved(orq->orq_tpn);
|
||||
orq->orq_url = url_hdup(home, sip->sip_request->rq_url);
|
||||
if (route_url != (url_string_t *)agent->sa_default_proxy)
|
||||
|
@ -7015,7 +7035,11 @@ nta_outgoing_t *outgoing_create(nta_agent_t *agent,
|
|||
sip_fragment_clear(sip->sip_request->rq_common);
|
||||
}
|
||||
|
||||
orq->orq_tpn->tpn_ident = tp_ident;
|
||||
if (!override_tport)
|
||||
orq->orq_tpn->tpn_ident = tp_ident;
|
||||
else
|
||||
orq->orq_tpn->tpn_ident = tport_name(override_tport)->tpn_ident;
|
||||
|
||||
if (comp == NULL)
|
||||
orq->orq_tpn->tpn_comp = comp;
|
||||
|
||||
|
@ -7100,7 +7124,9 @@ nta_outgoing_t *outgoing_create(nta_agent_t *agent,
|
|||
agent->sa_stats->as_client_tr++;
|
||||
orq->orq_hash = NTA_HASH(sip->sip_call_id, sip->sip_cseq->cs_seq);
|
||||
|
||||
if (resolved)
|
||||
if (orq->orq_user_tport)
|
||||
outgoing_send_via(orq, override_tport);
|
||||
else if (resolved)
|
||||
outgoing_prepare_send(orq);
|
||||
#if HAVE_SOFIA_SRESOLV
|
||||
else
|
||||
|
@ -7146,7 +7172,6 @@ outgoing_prepare_send(nta_outgoing_t *orq)
|
|||
tpn->tpn_port = "";
|
||||
|
||||
tp = tport_by_name(sa->sa_tports, tpn);
|
||||
orq->orq_tport = tport_ref(tp);
|
||||
|
||||
if (tpn->tpn_port[0] == '\0') {
|
||||
if (sips || tport_has_tls(tp))
|
||||
|
@ -7155,17 +7180,28 @@ outgoing_prepare_send(nta_outgoing_t *orq)
|
|||
tpn->tpn_port = "5060";
|
||||
}
|
||||
|
||||
if (!orq->orq_tport) {
|
||||
if (sips) {
|
||||
SU_DEBUG_3(("nta outgoing create: no secure transport\n"));
|
||||
outgoing_reply(orq, SIP_416_UNSUPPORTED_URI, 1);
|
||||
}
|
||||
else {
|
||||
SU_DEBUG_3(("nta outgoing create: no transport protocol\n"));
|
||||
outgoing_reply(orq, 503, "No transport", 1);
|
||||
}
|
||||
return;
|
||||
if (tp) {
|
||||
outgoing_send_via(orq, tp);
|
||||
}
|
||||
else if (sips) {
|
||||
SU_DEBUG_3(("nta outgoing create: no secure transport\n"));
|
||||
outgoing_reply(orq, SIP_416_UNSUPPORTED_URI, 1);
|
||||
}
|
||||
else {
|
||||
SU_DEBUG_3(("nta outgoing create: no transport protocol\n"));
|
||||
outgoing_reply(orq, 503, "No transport", 1);
|
||||
}
|
||||
}
|
||||
|
||||
/** Send request using given transport */
|
||||
static void
|
||||
outgoing_send_via(nta_outgoing_t *orq, tport_t *tp)
|
||||
{
|
||||
tport_t *old_tp = orq->orq_tport;
|
||||
|
||||
orq->orq_tport = tport_ref(tp);
|
||||
|
||||
if (old_tp) tport_unref(old_tp);
|
||||
|
||||
if (outgoing_insert_via(orq, agent_tport_via(tp)) < 0) {
|
||||
SU_DEBUG_3(("nta outgoing create: cannot insert Via line\n"));
|
||||
|
@ -7198,13 +7234,14 @@ outgoing_prepare_send(nta_outgoing_t *orq)
|
|||
if (orq->orq_delayed) {
|
||||
SU_DEBUG_5(("nta: delayed sending %s (%u)\n",
|
||||
orq->orq_method_name, orq->orq_cseq->cs_seq));
|
||||
outgoing_queue(sa->sa_out.delayed, orq);
|
||||
outgoing_queue(orq->orq_agent->sa_out.delayed, orq);
|
||||
return;
|
||||
}
|
||||
|
||||
outgoing_send(orq, 0);
|
||||
}
|
||||
|
||||
|
||||
/** Send a request */
|
||||
static void
|
||||
outgoing_send(nta_outgoing_t *orq, int retransmit)
|
||||
|
@ -7226,6 +7263,11 @@ outgoing_send(nta_outgoing_t *orq, int retransmit)
|
|||
return;
|
||||
}
|
||||
|
||||
if (orq->orq_user_tport && !tport_is_clear_to_send(orq->orq_tport)) {
|
||||
outgoing_tport_error(agent, orq, NULL, orq->orq_request, EPIPE);
|
||||
return;
|
||||
}
|
||||
|
||||
if (!retransmit)
|
||||
orq->orq_sent = now;
|
||||
|
||||
|
|
|
@ -170,7 +170,8 @@ SOFIAPUBFUN int nta_msg_request_complete(msg_t *msg,
|
|||
char const *method_name,
|
||||
url_string_t const *req_url);
|
||||
|
||||
SOFIAPUBFUN int nta_is_internal_msg(msg_t const *msg);
|
||||
SOFIAPUBFUN int nta_msg_is_internal(msg_t const *msg);
|
||||
SOFIAPUBFUN int nta_sip_is_internal(sip_t const *sip);
|
||||
|
||||
/* ----------------------------------------------------------------------
|
||||
* 5) Leg-level prototypes
|
||||
|
@ -479,6 +480,8 @@ SOFIAPUBFUN void nta_reliable_destroy(nta_reliable_t *);
|
|||
|
||||
SOFIAPUBFUN void nta_msg_discard(nta_agent_t *agent, msg_t *msg);
|
||||
|
||||
SOFIAPUBFUN int nta_is_internal_msg(msg_t const *msg);
|
||||
|
||||
SOFIA_END_DECLS
|
||||
|
||||
#endif
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -8,26 +8,10 @@
|
|||
# ----------------------------------------------------------------------
|
||||
# Header paths
|
||||
|
||||
INCLUDES = -I$(srcdir)/../bnf -I../bnf \
|
||||
-I$(srcdir)/../ipt -I../ipt \
|
||||
-I$(srcdir)/../iptsec -I../iptsec \
|
||||
-I$(srcdir)/../http -I../http \
|
||||
-I$(srcdir)/../msg -I../msg \
|
||||
-I$(srcdir)/../nea -I../nea \
|
||||
-I$(srcdir)/../nta -I../nta \
|
||||
-I$(srcdir)/../nth -I../nth \
|
||||
-I$(srcdir)/../sdp -I../sdp \
|
||||
-I$(srcdir)/../sip -I../sip \
|
||||
-I$(srcdir)/../soa -I../soa \
|
||||
-I$(srcdir)/../tport -I../tport \
|
||||
-I$(srcdir)/../stun -I../stun \
|
||||
-I$(srcdir)/../url -I../url \
|
||||
-I$(srcdir)/../su -I../su
|
||||
|
||||
# ----------------------------------------------------------------------
|
||||
# Build targets
|
||||
|
||||
noinst_LTLIBRARIES = libnua.la
|
||||
noinst_LTLIBRARIES = libnua.la libtestnua.la libtestproxy.la libtestnat.la
|
||||
|
||||
check_PROGRAMS = test_nua
|
||||
|
||||
|
@ -57,7 +41,26 @@ libnua_la_SOURCES = nua.c nua_stack.h nua_common.c nua_stack.c \
|
|||
|
||||
COVERAGE_INPUT = $(libnua_la_SOURCES) $(include_sofia_HEADERS)
|
||||
|
||||
LDADD = libnua.la \
|
||||
test_nua_LDFLAGS = -static
|
||||
|
||||
libtestnua_la_SOURCES = test_nua.h test_ops.c \
|
||||
test_init.c \
|
||||
test_nua_api.c test_nua_params.c \
|
||||
test_register.c test_basic_call.c \
|
||||
test_offer_answer.c \
|
||||
test_call_reject.c test_cancel_bye.c \
|
||||
test_call_hold.c test_session_timer.c \
|
||||
test_refer.c test_100rel.c \
|
||||
test_simple.c test_sip_events.c \
|
||||
test_extension.c
|
||||
|
||||
libtestproxy_la_SOURCES = test_proxy.h test_proxy.c
|
||||
|
||||
libtestnat_la_SOURCES = test_nat.h test_nat.c test_nat_tags.c
|
||||
|
||||
test_nua_SOURCES = test_nua.c
|
||||
|
||||
test_nua_LDADD = libnua.la libtestnua.la libtestproxy.la libtestnat.la \
|
||||
../iptsec/libiptsec.la \
|
||||
../ipt/libipt.la \
|
||||
../nea/libnea.la \
|
||||
|
@ -74,21 +77,6 @@ LDADD = libnua.la \
|
|||
../bnf/libbnf.la \
|
||||
../su/libsu.la
|
||||
|
||||
test_nua_LDFLAGS = -static
|
||||
|
||||
test_nua_SOURCES = test_nua.c test_nua.h test_ops.c \
|
||||
test_init.c \
|
||||
test_nua_api.c test_nua_params.c \
|
||||
test_register.c test_basic_call.c \
|
||||
test_offer_answer.c \
|
||||
test_call_reject.c test_cancel_bye.c \
|
||||
test_call_hold.c test_session_timer.c \
|
||||
test_refer.c test_100rel.c \
|
||||
test_simple.c test_sip_events.c \
|
||||
test_extension.c \
|
||||
test_proxy.h test_proxy.c \
|
||||
test_nat.h test_nat.c test_nat_tags.c
|
||||
|
||||
# ----------------------------------------------------------------------
|
||||
# Install and distribution rules
|
||||
|
||||
|
@ -99,4 +87,6 @@ EXTRA_DIST = nua.docs $(BUILT_SOURCES)
|
|||
|
||||
include $(top_srcdir)/rules/sofia.am
|
||||
|
||||
INCLUDES = ${INTERNAL_INCLUDES}
|
||||
|
||||
TAG_DLL_FLAGS = LIST=nua_tag_list
|
||||
|
|
|
@ -43,8 +43,6 @@
|
|||
#include <sofia-sip/su_debug.h>
|
||||
|
||||
#define SU_ROOT_MAGIC_T struct nua_s
|
||||
#define SU_MSG_ARG_T struct event_s
|
||||
#define NUA_SAVED_EVENT_T su_msg_t *
|
||||
|
||||
#include <sofia-sip/sip_status.h>
|
||||
#include <sofia-sip/sip_header.h>
|
||||
|
@ -192,7 +190,7 @@ void nua_shutdown(nua_t *nua)
|
|||
|
||||
if (nua)
|
||||
nua->nua_shutdown_started = 1;
|
||||
nua_signal(nua, NULL, NULL, 1, nua_r_shutdown, 0, NULL, TAG_END());
|
||||
nua_signal(nua, NULL, NULL, nua_r_shutdown, 0, NULL, TAG_END());
|
||||
}
|
||||
|
||||
/** Destroy the @nua stack.
|
||||
|
@ -227,6 +225,8 @@ void nua_destroy(nua_t *nua)
|
|||
return;
|
||||
}
|
||||
|
||||
nua->nua_callback = NULL;
|
||||
|
||||
su_task_deinit(nua->nua_server);
|
||||
su_task_deinit(nua->nua_client);
|
||||
|
||||
|
@ -574,7 +574,7 @@ void nua_set_params(nua_t *nua, tag_type_t tag, tag_value_t value, ...)
|
|||
|
||||
enter;
|
||||
|
||||
nua_signal(nua, NULL, NULL, 0, nua_r_set_params, 0, NULL, ta_tags(ta));
|
||||
nua_signal(nua, NULL, NULL, nua_r_set_params, 0, NULL, ta_tags(ta));
|
||||
|
||||
ta_end(ta);
|
||||
}
|
||||
|
@ -587,7 +587,7 @@ void nua_get_params(nua_t *nua, tag_type_t tag, tag_value_t value, ...)
|
|||
|
||||
enter;
|
||||
|
||||
nua_signal(nua, NULL, NULL, 0, nua_r_get_params, 0, NULL, ta_tags(ta));
|
||||
nua_signal(nua, NULL, NULL, nua_r_get_params, 0, NULL, ta_tags(ta));
|
||||
|
||||
ta_end(ta);
|
||||
}
|
||||
|
@ -597,7 +597,7 @@ void nua_get_params(nua_t *nua, tag_type_t tag, tag_value_t value, ...)
|
|||
if (NH_IS_VALID((nh))) { \
|
||||
ta_list ta; \
|
||||
ta_start(ta, tag, value); \
|
||||
nua_signal((nh)->nh_nua, nh, NULL, 0, event, 0, NULL, ta_tags(ta)); \
|
||||
nua_signal((nh)->nh_nua, nh, NULL, event, 0, NULL, ta_tags(ta)); \
|
||||
ta_end(ta); \
|
||||
} \
|
||||
else { \
|
||||
|
@ -881,7 +881,7 @@ void nua_respond(nua_handle_t *nh,
|
|||
if (NH_IS_VALID(nh)) {
|
||||
ta_list ta;
|
||||
ta_start(ta, tag, value);
|
||||
nua_signal(nh->nh_nua, nh, NULL, 0, nua_r_respond,
|
||||
nua_signal(nh->nh_nua, nh, NULL, nua_r_respond,
|
||||
status, phrase, ta_tags(ta));
|
||||
ta_end(ta);
|
||||
}
|
||||
|
@ -922,197 +922,7 @@ void nua_handle_destroy(nua_handle_t *nh)
|
|||
|
||||
if (NH_IS_VALID(nh) && !NH_IS_DEFAULT(nh)) {
|
||||
nh->nh_valid = NULL; /* Events are no more delivered to appl. */
|
||||
nua_signal(nh->nh_nua, nh, NULL, 1, nua_r_destroy, 0, NULL, TAG_END());
|
||||
}
|
||||
}
|
||||
|
||||
/*# Send a request to the protocol thread */
|
||||
void nua_signal(nua_t *nua, nua_handle_t *nh, msg_t *msg, int always,
|
||||
nua_event_t event,
|
||||
int status, char const *phrase,
|
||||
tag_type_t tag, tag_value_t value, ...)
|
||||
{
|
||||
su_msg_r sumsg = SU_MSG_R_INIT;
|
||||
size_t len, xtra, e_len, l_len = 0, l_xtra = 0;
|
||||
ta_list ta;
|
||||
|
||||
if (nua == NULL)
|
||||
return;
|
||||
|
||||
ta_start(ta, tag, value);
|
||||
|
||||
e_len = offsetof(event_t, e_tags);
|
||||
len = tl_len(ta_args(ta));
|
||||
xtra = tl_xtra(ta_args(ta), len);
|
||||
|
||||
if (su_msg_create(sumsg, nua->nua_server, su_task_null,
|
||||
nua_stack_signal,
|
||||
e_len + len + l_len + xtra + l_xtra) == 0) {
|
||||
event_t *e = su_msg_data(sumsg);
|
||||
tagi_t *t = e->e_tags;
|
||||
void *b = (char *)t + len + l_len;
|
||||
|
||||
tagi_t *tend = (tagi_t *)b;
|
||||
char *bend = (char *)b + xtra + l_xtra;
|
||||
|
||||
t = tl_dup(t, ta_args(ta), &b);
|
||||
|
||||
assert(tend == t); (void)tend; assert(b == bend); (void)bend;
|
||||
|
||||
e->e_always = always;
|
||||
e->e_event = event;
|
||||
e->e_nh = event == nua_r_destroy ? nh : nua_handle_ref(nh);
|
||||
e->e_status = status;
|
||||
e->e_phrase = phrase;
|
||||
|
||||
SU_DEBUG_7(("nua(%p): signal %s\n", (void *)nh,
|
||||
nua_event_name(event) + 4));
|
||||
|
||||
if (su_msg_send(sumsg) != 0 && event != nua_r_destroy)
|
||||
nua_handle_unref(nh);
|
||||
}
|
||||
else {
|
||||
/* XXX - we should return error code to application but we just abort() */
|
||||
assert(ENOMEM == 0);
|
||||
}
|
||||
|
||||
ta_end(ta);
|
||||
}
|
||||
|
||||
/*# Receive event from protocol machine and hand it over to application */
|
||||
void nua_event(nua_t *root_magic, su_msg_r sumsg, event_t *e)
|
||||
{
|
||||
nua_t *nua;
|
||||
nua_handle_t *nh = e->e_nh;
|
||||
|
||||
enter;
|
||||
|
||||
if (nh) {
|
||||
if (!nh->nh_ref_by_user && nh->nh_valid) {
|
||||
nh->nh_ref_by_user = 1;
|
||||
nua_handle_ref(nh);
|
||||
}
|
||||
}
|
||||
|
||||
if (!nh || !nh->nh_valid) { /* Handle has been destroyed */
|
||||
if (nua_log->log_level >= 7) {
|
||||
char const *name = nua_event_name(e->e_event) + 4;
|
||||
SU_DEBUG_7(("nua(%p): event %s dropped\n", (void *)nh, name));
|
||||
}
|
||||
if (nh && !NH_IS_DEFAULT(nh) && nua_handle_unref(nh)) {
|
||||
#if HAVE_NUA_HANDLE_DEBUG
|
||||
SU_DEBUG_0(("nua(%p): freed by application\n", (void *)nh));
|
||||
#else
|
||||
SU_DEBUG_9(("nua(%p): freed by application\n", (void *)nh));
|
||||
#endif
|
||||
}
|
||||
if (e->e_msg)
|
||||
msg_destroy(e->e_msg), e->e_msg = NULL;
|
||||
return;
|
||||
}
|
||||
|
||||
nua = nh->nh_nua; assert(nua);
|
||||
|
||||
if (e->e_event == nua_r_shutdown && e->e_status >= 200)
|
||||
nua->nua_shutdown_final = 1;
|
||||
|
||||
if (!nua->nua_callback)
|
||||
return;
|
||||
|
||||
if (NH_IS_DEFAULT(nh))
|
||||
nh = NULL;
|
||||
|
||||
su_msg_save(nua->nua_current, sumsg);
|
||||
|
||||
e->e_nh = NULL;
|
||||
|
||||
nua->nua_callback(e->e_event, e->e_status, e->e_phrase,
|
||||
nua, nua->nua_magic,
|
||||
nh, nh ? nh->nh_magic : NULL,
|
||||
e->e_msg ? sip_object(e->e_msg) : NULL,
|
||||
e->e_tags);
|
||||
|
||||
if (nh && !NH_IS_DEFAULT(nh) && nua_handle_unref(nh)) {
|
||||
#if HAVE_NUA_HANDLE_DEBUG
|
||||
SU_DEBUG_0(("nua(%p): freed by application\n", (void *)nh));
|
||||
#else
|
||||
SU_DEBUG_9(("nua(%p): freed by application\n", (void *)nh));
|
||||
#endif
|
||||
}
|
||||
|
||||
if (!su_msg_is_non_null(nua->nua_current))
|
||||
return;
|
||||
|
||||
if (e->e_msg)
|
||||
msg_destroy(e->e_msg), e->e_msg = NULL;
|
||||
|
||||
su_msg_destroy(nua->nua_current);
|
||||
}
|
||||
|
||||
/** Get current request message. @NEW_1_12_4.
|
||||
*
|
||||
* @note A response message is returned when processing response message.
|
||||
*
|
||||
* @sa #nua_event_e, nua_respond(), NUTAG_WITH_CURRENT()
|
||||
*/
|
||||
msg_t *nua_current_request(nua_t const *nua)
|
||||
{
|
||||
return nua && nua->nua_current ? su_msg_data(nua->nua_current)->e_msg : NULL;
|
||||
}
|
||||
|
||||
/** Get request message from saved nua event. @NEW_1_12_4.
|
||||
*
|
||||
* @sa nua_save_event(), nua_respond(), NUTAG_WITH_SAVED(),
|
||||
*/
|
||||
msg_t *nua_saved_event_request(nua_saved_event_t const *saved)
|
||||
{
|
||||
return saved && saved[0] ? su_msg_data(saved)->e_msg : NULL;
|
||||
}
|
||||
|
||||
/** Save nua event and its arguments.
|
||||
*
|
||||
* @sa #nua_event_e, nua_event_data() nua_saved_event_request(), nua_destroy_event()
|
||||
*/
|
||||
int nua_save_event(nua_t *nua, nua_saved_event_t return_saved[1])
|
||||
{
|
||||
if (nua && return_saved) {
|
||||
su_msg_save(return_saved, nua->nua_current);
|
||||
if (su_msg_is_non_null(return_saved)) {
|
||||
/* Remove references to tasks */
|
||||
su_msg_remove_refs(return_saved);
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/** Get event data.
|
||||
*
|
||||
* @sa #nua_event_e, nua_event_save(), nua_saved_event_request(), nua_destroy_event().
|
||||
*/
|
||||
nua_event_data_t const *nua_event_data(nua_saved_event_t const saved[1])
|
||||
{
|
||||
return saved ? su_msg_data(saved) : NULL;
|
||||
}
|
||||
|
||||
/** Destroy saved event.
|
||||
*
|
||||
* @sa #nua_event_e, nua_event_save(), nua_event_data(), nua_saved_event_request().
|
||||
*/
|
||||
void nua_destroy_event(nua_saved_event_t saved[1])
|
||||
{
|
||||
if (su_msg_is_non_null(saved)) {
|
||||
event_t *e = su_msg_data(saved);
|
||||
nua_handle_t *nh = e->e_nh;
|
||||
|
||||
if (e->e_msg)
|
||||
msg_destroy(e->e_msg), e->e_msg = NULL;
|
||||
|
||||
if (nh && !NH_IS_DEFAULT(nh) && nua_handle_unref(nh)) {
|
||||
SU_DEBUG_9(("nua(%p): freed by application\n", (void *)nh));
|
||||
}
|
||||
|
||||
su_msg_destroy(saved);
|
||||
nua_signal(nh->nh_nua, nh, NULL, nua_r_destroy, 0, NULL, TAG_END());
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -52,7 +52,6 @@
|
|||
#include <sofia-sip/su_debug.h>
|
||||
|
||||
#define SU_ROOT_MAGIC_T struct nua_s
|
||||
#define SU_MSG_ARG_T struct event_s
|
||||
|
||||
#include <sofia-sip/su_wait.h>
|
||||
|
||||
|
|
|
@ -50,7 +50,11 @@ typedef struct nua_server_request nua_server_request_t;
|
|||
typedef struct nua_client_request nua_client_request_t;
|
||||
typedef struct nua_dialog_peer_info nua_dialog_peer_info_t;
|
||||
|
||||
typedef su_msg_r nua_saved_signal_t;
|
||||
#ifndef NUA_SAVED_SIGNAL_T
|
||||
#define NUA_SAVED_SIGNAL_T struct nua_saved_signal *
|
||||
#endif
|
||||
|
||||
typedef NUA_SAVED_SIGNAL_T nua_saved_signal_t;
|
||||
|
||||
typedef struct {
|
||||
sip_method_t sm_method;
|
||||
|
@ -80,6 +84,7 @@ typedef struct {
|
|||
|
||||
} nua_server_methods_t;
|
||||
|
||||
|
||||
/* Server side transaction */
|
||||
struct nua_server_request {
|
||||
struct nua_server_request *sr_next, **sr_prev;
|
||||
|
@ -132,7 +137,7 @@ struct nua_server_request {
|
|||
size_t sr_sdp_len; /**< SDP length */
|
||||
|
||||
/**< Save 200 OK nua_respond() signal until PRACK has been received */
|
||||
nua_saved_signal_t sr_signal;
|
||||
nua_saved_signal_t sr_signal[1];
|
||||
};
|
||||
|
||||
#define SR_STATUS(sr, status, phrase) \
|
||||
|
@ -141,6 +146,8 @@ struct nua_server_request {
|
|||
#define SR_STATUS1(sr, statusphrase) \
|
||||
sr_status(sr, statusphrase)
|
||||
|
||||
#define SR_HAS_SAVED_SIGNAL(sr) ((sr)->sr_signal[0] != NULL)
|
||||
|
||||
su_inline
|
||||
int sr_status(nua_server_request_t *sr, int status, char const *phrase)
|
||||
{
|
||||
|
@ -261,7 +268,7 @@ struct nua_client_request
|
|||
nua_owner_t *cr_owner;
|
||||
nua_dialog_usage_t *cr_usage;
|
||||
|
||||
nua_saved_signal_t cr_signal;
|
||||
nua_saved_signal_t cr_signal[1];
|
||||
tagi_t const *cr_tags;
|
||||
|
||||
nua_client_methods_t const *cr_methods;
|
||||
|
|
|
@ -890,7 +890,18 @@ int nua_refer_server_respond(nua_server_request_t *sr, tagi_t const *tags)
|
|||
|
||||
/** @NUA_EVENT nua_i_refer
|
||||
*
|
||||
* Incoming @b REFER request used to transfer calls.
|
||||
* Incoming @b REFER request used to transfer calls. The tag list will
|
||||
* contain tag NUTAG_REFER_EVENT() with the @Event header constructed from
|
||||
* the REFER request. It will also contain the SIPTAG_REFERRED_BY() tag with
|
||||
* the @ReferredBy header containing the identity of the party sending the
|
||||
* REFER. The @ReferredBy structure contained in the tag is constructed from
|
||||
* the @From header if the @ReferredBy header was not present in the REFER
|
||||
* request.
|
||||
*
|
||||
* The application can let the nua to send NOTIFYs from the call it
|
||||
* initiates with nua_invite() if it includes in the nua_invite() arguments
|
||||
* both the NUTAG_NOTIFY_REFER() with the handle with which nua_i_refer was
|
||||
* received and the NUTAG_REFER_EVENT() from #nua_i_refer event tags.
|
||||
*
|
||||
* @param status status code of response sent automatically by stack
|
||||
* @param phrase a short textual description of @a status code
|
||||
|
|
|
@ -1941,7 +1941,9 @@ sip_contact_t *nua_handle_contact_by_via(nua_handle_t *nh,
|
|||
char _transport[16];
|
||||
va_list va;
|
||||
sip_contact_t *m;
|
||||
url_t url = URL_INIT_AS(sip);
|
||||
url_t url;
|
||||
|
||||
url_init(&url, url_sip);
|
||||
|
||||
if (!v) return NULL;
|
||||
|
||||
|
|
|
@ -2611,20 +2611,16 @@ int nua_prack_server_report(nua_server_request_t *sr, tagi_t const *tags)
|
|||
if (sri == NULL) {
|
||||
|
||||
}
|
||||
else if (su_msg_is_non_null(sri->sr_signal)) {
|
||||
su_msg_r signal;
|
||||
event_t *e;
|
||||
else if (SR_HAS_SAVED_SIGNAL(sri)) {
|
||||
nua_signal_data_t const *e;
|
||||
|
||||
su_msg_save(signal, sri->sr_signal);
|
||||
|
||||
e = su_msg_data(signal);
|
||||
e = nua_signal_data(sri->sr_signal);
|
||||
|
||||
sri->sr_application = SR_STATUS(sri, e->e_status, e->e_phrase);
|
||||
|
||||
nua_server_params(sri, e->e_tags);
|
||||
nua_server_respond(sri, e->e_tags);
|
||||
nua_server_report(sri);
|
||||
|
||||
su_msg_destroy(signal);
|
||||
}
|
||||
else if (ss->ss_state < nua_callstate_ready
|
||||
&& !ss->ss_alerting
|
||||
|
@ -3106,7 +3102,6 @@ static int nua_update_client_report(nua_client_request_t *cr,
|
|||
nua_handle_t *nh = cr->cr_owner;
|
||||
nua_dialog_usage_t *du = cr->cr_usage;
|
||||
nua_session_usage_t *ss = nua_dialog_usage_private(du);
|
||||
unsigned next_state = ss->ss_state;
|
||||
|
||||
nua_stack_event(nh->nh_nua, nh,
|
||||
nta_outgoing_getresponse(orq),
|
||||
|
@ -3122,6 +3117,8 @@ static int nua_update_client_report(nua_client_request_t *cr,
|
|||
return 1;
|
||||
|
||||
if (cr->cr_offer_sent) {
|
||||
unsigned next_state = ss->ss_state;
|
||||
|
||||
if (status < 200)
|
||||
;
|
||||
else if (du->du_cr && du->du_cr->cr_orq && du->du_cr->cr_status >= 200) {
|
||||
|
|
|
@ -45,10 +45,11 @@
|
|||
#include <sofia-sip/su_tag_io.h>
|
||||
|
||||
#define SU_ROOT_MAGIC_T struct nua_s
|
||||
#define SU_MSG_ARG_T struct event_s
|
||||
#define SU_MSG_ARG_T struct nua_ee_data
|
||||
#define SU_TIMER_ARG_T struct nua_client_request
|
||||
|
||||
#define NUA_SAVED_EVENT_T su_msg_t *
|
||||
#define NUA_SAVED_SIGNAL_T su_msg_t *
|
||||
|
||||
#define NTA_AGENT_MAGIC_T struct nua_s
|
||||
#define NTA_LEG_MAGIC_T struct nua_handle_s
|
||||
|
@ -84,6 +85,26 @@
|
|||
*
|
||||
* ======================================================================== */
|
||||
|
||||
/* ---------------------------------------------------------------------- */
|
||||
/* Internal types */
|
||||
|
||||
/** Extended event data. */
|
||||
typedef struct nua_ee_data {
|
||||
nua_t *ee_nua;
|
||||
nua_event_data_t ee_data[1];
|
||||
} nua_ee_data_t;
|
||||
|
||||
/** @internal Linked stack frames from nua event callback */
|
||||
struct nua_event_frame_s {
|
||||
nua_event_frame_t *nf_next;
|
||||
nua_saved_event_t nf_saved[1];
|
||||
};
|
||||
|
||||
|
||||
static void nua_event_deinit(nua_ee_data_t *ee);
|
||||
static void nua_application_event(nua_t *, su_msg_r, nua_ee_data_t *ee);
|
||||
static void nua_stack_signal(nua_t *nua, su_msg_r, nua_ee_data_t *ee);
|
||||
|
||||
nua_handle_t *nh_create(nua_t *nua, tag_type_t t, tag_value_t v, ...);
|
||||
static void nh_append(nua_t *nua, nua_handle_t *nh);
|
||||
static void nh_remove(nua_t *nua, nua_handle_t *nh);
|
||||
|
@ -279,18 +300,18 @@ int nua_stack_event(nua_t *nua, nua_handle_t *nh, msg_t *msg,
|
|||
}
|
||||
|
||||
if (tags) {
|
||||
e_len = offsetof(event_t, e_tags);
|
||||
e_len = offsetof(nua_ee_data_t, ee_data[0].e_tags);
|
||||
len = tl_len(tags);
|
||||
xtra = tl_xtra(tags, len);
|
||||
}
|
||||
else {
|
||||
e_len = sizeof(event_t), len = 0, xtra = 0;
|
||||
e_len = sizeof(nua_ee_data_t), len = 0, xtra = 0;
|
||||
}
|
||||
p_len = phrase ? strlen(phrase) + 1 : 1;
|
||||
|
||||
if (su_msg_create(sumsg, nua->nua_client, su_task_null,
|
||||
nua_event, e_len + len + xtra + p_len) == 0) {
|
||||
event_t *e = su_msg_data(sumsg);
|
||||
if (su_msg_new(sumsg, e_len + len + xtra + p_len) == 0) {
|
||||
nua_ee_data_t *ee = su_msg_data(sumsg);
|
||||
nua_event_data_t *e = ee->ee_data;
|
||||
void *p;
|
||||
|
||||
if (tags) {
|
||||
|
@ -303,21 +324,138 @@ int nua_stack_event(nua_t *nua, nua_handle_t *nh, msg_t *msg,
|
|||
else
|
||||
p = e + 1;
|
||||
|
||||
ee->ee_nua = nua_stack_ref(nua);
|
||||
e->e_event = event;
|
||||
e->e_nh = nh ? nua_handle_ref(nh) : nua->nua_dhandle;
|
||||
e->e_nh = nh ? nua_handle_ref(nh) : NULL;
|
||||
e->e_status = status;
|
||||
e->e_phrase = strcpy(p, phrase ? phrase : "");
|
||||
if (msg)
|
||||
e->e_msg = msg, su_home_threadsafe(msg_home(msg));
|
||||
|
||||
if (su_msg_send(sumsg) != 0 && nh)
|
||||
nua_handle_unref(nh);
|
||||
su_msg_deinitializer(sumsg, nua_event_deinit);
|
||||
|
||||
su_msg_send_to(sumsg, nua->nua_client, nua_application_event);
|
||||
}
|
||||
|
||||
return event;
|
||||
}
|
||||
|
||||
/* ----------------------------------------------------------------------
|
||||
static
|
||||
void nua_event_deinit(nua_ee_data_t *ee)
|
||||
{
|
||||
nua_t *nua = ee->ee_nua;
|
||||
nua_event_data_t *e = ee->ee_data;
|
||||
nua_handle_t *nh = e->e_nh;
|
||||
|
||||
if (e->e_msg)
|
||||
msg_destroy(e->e_msg), e->e_msg = NULL;
|
||||
|
||||
if (nh)
|
||||
nua_handle_unref(nh), e->e_nh = NULL;
|
||||
|
||||
if (nua)
|
||||
nua_stack_unref(nua), ee->ee_nua = NULL;
|
||||
}
|
||||
|
||||
/*# Receive event from protocol machine and hand it over to application */
|
||||
static
|
||||
void nua_application_event(nua_t *dummy, su_msg_r sumsg, nua_ee_data_t *ee)
|
||||
{
|
||||
nua_t *nua = ee->ee_nua;
|
||||
nua_event_data_t *e = ee->ee_data;
|
||||
nua_handle_t *nh = e->e_nh;
|
||||
|
||||
enter;
|
||||
|
||||
ee->ee_nua = NULL;
|
||||
e->e_nh = NULL;
|
||||
|
||||
if (nh == NULL) {
|
||||
/* Xyzzy */
|
||||
}
|
||||
else if (nh->nh_valid) {
|
||||
if (!nh->nh_ref_by_user) {
|
||||
/* Application must now call nua_handle_destroy() */
|
||||
nh->nh_ref_by_user = 1;
|
||||
nua_handle_ref(nh);
|
||||
}
|
||||
}
|
||||
else if (!nh->nh_valid) { /* Handle has been destroyed */
|
||||
if (nua_log->log_level >= 7) {
|
||||
char const *name = nua_event_name(e->e_event) + 4;
|
||||
SU_DEBUG_7(("nua(%p): event %s dropped\n", (void *)nh, name));
|
||||
}
|
||||
nua_handle_unref(nh);
|
||||
nua_stack_unref(nua);
|
||||
return;
|
||||
}
|
||||
|
||||
if (e->e_event == nua_r_shutdown && e->e_status >= 200)
|
||||
nua->nua_shutdown_final = 1;
|
||||
|
||||
if (nua->nua_callback) {
|
||||
nua_event_frame_t frame[1];
|
||||
|
||||
su_msg_save(frame->nf_saved, sumsg);
|
||||
frame->nf_next = nua->nua_current, nua->nua_current = frame;
|
||||
|
||||
nua->nua_callback(e->e_event, e->e_status, e->e_phrase,
|
||||
nua, nua->nua_magic,
|
||||
nh, nh ? nh->nh_magic : NULL,
|
||||
e->e_msg ? sip_object(e->e_msg) : NULL,
|
||||
e->e_tags);
|
||||
|
||||
su_msg_destroy(frame->nf_saved);
|
||||
nua->nua_current = frame->nf_next;
|
||||
}
|
||||
|
||||
nua_handle_unref(nh);
|
||||
nua_stack_unref(nua);
|
||||
}
|
||||
|
||||
/** Get current request message. @NEW_1_12_4.
|
||||
*
|
||||
* @note A response message is returned when processing response message.
|
||||
*
|
||||
* @sa #nua_event_e, nua_respond(), NUTAG_WITH_CURRENT()
|
||||
*/
|
||||
msg_t *nua_current_request(nua_t const *nua)
|
||||
{
|
||||
if (nua && nua->nua_current && su_msg_is_non_null(nua->nua_current->nf_saved))
|
||||
return su_msg_data(nua->nua_current->nf_saved)->ee_data->e_msg;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/** Get request message from saved nua event. @NEW_1_12_4.
|
||||
*
|
||||
* @sa nua_save_event(), nua_respond(), NUTAG_WITH_SAVED(),
|
||||
*/
|
||||
msg_t *nua_saved_event_request(nua_saved_event_t const *saved)
|
||||
{
|
||||
return saved && saved[0] ? su_msg_data(saved)->ee_data->e_msg : NULL;
|
||||
}
|
||||
|
||||
/** Save nua event and its arguments.
|
||||
*
|
||||
* @sa #nua_event_e, nua_event_data() nua_saved_event_request(), nua_destroy_event()
|
||||
*/
|
||||
int nua_save_event(nua_t *nua, nua_saved_event_t return_saved[1])
|
||||
{
|
||||
if (return_saved) {
|
||||
if (nua && nua->nua_current) {
|
||||
su_msg_save(return_saved, nua->nua_current->nf_saved);
|
||||
return su_msg_is_non_null(return_saved);
|
||||
}
|
||||
else
|
||||
*return_saved = NULL;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* ---------------------------------------------------------------------- */
|
||||
|
||||
/** @internal
|
||||
* Post signal to stack itself
|
||||
*/
|
||||
void nua_stack_post_signal(nua_handle_t *nh, nua_event_t event,
|
||||
|
@ -325,16 +463,73 @@ void nua_stack_post_signal(nua_handle_t *nh, nua_event_t event,
|
|||
{
|
||||
ta_list ta;
|
||||
ta_start(ta, tag, value);
|
||||
nua_signal((nh)->nh_nua, nh, NULL, 1, event, 0, NULL, ta_tags(ta));
|
||||
nua_signal((nh)->nh_nua, nh, NULL, event, 0, NULL, ta_tags(ta));
|
||||
ta_end(ta);
|
||||
}
|
||||
|
||||
|
||||
/*# Send a request to the protocol thread */
|
||||
int nua_signal(nua_t *nua, nua_handle_t *nh, msg_t *msg,
|
||||
nua_event_t event,
|
||||
int status, char const *phrase,
|
||||
tag_type_t tag, tag_value_t value, ...)
|
||||
{
|
||||
su_msg_r sumsg = SU_MSG_R_INIT;
|
||||
size_t len, xtra, ee_len, l_len = 0, l_xtra = 0;
|
||||
ta_list ta;
|
||||
int retval = -1;
|
||||
|
||||
if (nua == NULL)
|
||||
return -1;
|
||||
|
||||
if (nua->nua_shutdown_started && event != nua_r_shutdown)
|
||||
return -1;
|
||||
|
||||
ta_start(ta, tag, value);
|
||||
|
||||
ee_len = offsetof(nua_ee_data_t, ee_data[0].e_tags);
|
||||
len = tl_len(ta_args(ta));
|
||||
xtra = tl_xtra(ta_args(ta), len);
|
||||
|
||||
if (su_msg_new(sumsg, ee_len + len + l_len + xtra + l_xtra) == 0) {
|
||||
nua_ee_data_t *ee = su_msg_data(sumsg);
|
||||
nua_event_data_t *e = ee->ee_data;
|
||||
tagi_t *t = e->e_tags;
|
||||
void *b = (char *)t + len + l_len;
|
||||
|
||||
tagi_t *tend = (tagi_t *)b;
|
||||
char *bend = (char *)b + xtra + l_xtra;
|
||||
|
||||
t = tl_dup(t, ta_args(ta), &b);
|
||||
|
||||
assert(tend == t); (void)tend; assert(b == bend); (void)bend;
|
||||
|
||||
e->e_always = event == nua_r_destroy || event == nua_r_shutdown;
|
||||
e->e_event = event;
|
||||
e->e_nh = nh ? nua_handle_ref(nh) : NULL;
|
||||
e->e_status = status;
|
||||
e->e_phrase = phrase;
|
||||
|
||||
SU_DEBUG_7(("nua(%p): signal %s\n", (void *)nh,
|
||||
nua_event_name(event) + 4));
|
||||
|
||||
su_msg_deinitializer(sumsg, nua_event_deinit);
|
||||
|
||||
retval = su_msg_send_to(sumsg, nua->nua_server, nua_stack_signal);
|
||||
}
|
||||
|
||||
ta_end(ta);
|
||||
|
||||
return retval;
|
||||
}
|
||||
|
||||
/* ----------------------------------------------------------------------
|
||||
* Receiving events from client
|
||||
*/
|
||||
void nua_stack_signal(nua_t *nua, su_msg_r msg, nua_event_data_t *e)
|
||||
static
|
||||
void nua_stack_signal(nua_t *nua, su_msg_r msg, nua_ee_data_t *ee)
|
||||
{
|
||||
nua_event_data_t *e = ee->ee_data;
|
||||
nua_handle_t *nh = e->e_nh;
|
||||
tagi_t *tags = e->e_tags;
|
||||
nua_event_t event;
|
||||
|
@ -342,11 +537,6 @@ void nua_stack_signal(nua_t *nua, su_msg_r msg, nua_event_data_t *e)
|
|||
|
||||
assert(tags);
|
||||
|
||||
if (nua_log->log_level >= 7) {
|
||||
char const *name = nua_event_name(e->e_event) + 4;
|
||||
SU_DEBUG_7(("nua(%p): recv %s\n", (void *)nh, name));
|
||||
}
|
||||
|
||||
if (nh) {
|
||||
if (!nh->nh_prev)
|
||||
nh_append(nua, nh);
|
||||
|
@ -359,6 +549,7 @@ void nua_stack_signal(nua_t *nua, su_msg_r msg, nua_event_data_t *e)
|
|||
|
||||
if (nua_log->log_level >= 5) {
|
||||
char const *name = nua_event_name(e->e_event);
|
||||
|
||||
if (e->e_status == 0)
|
||||
SU_DEBUG_5(("nua(%p): signal %s\n", (void *)nh, name + 4));
|
||||
else
|
||||
|
@ -377,8 +568,7 @@ void nua_stack_signal(nua_t *nua, su_msg_r msg, nua_event_data_t *e)
|
|||
901, "Stack is going down",
|
||||
NULL);
|
||||
}
|
||||
|
||||
switch (event) {
|
||||
else switch (event) {
|
||||
case nua_r_get_params:
|
||||
nua_stack_get_params(nua, nh ? nh : nua->nua_dhandle, event, tags);
|
||||
break;
|
||||
|
@ -463,11 +653,44 @@ void nua_stack_signal(nua_t *nua, su_msg_r msg, nua_event_data_t *e)
|
|||
nua_stack_event(nh->nh_nua, nh, NULL, event, NUA_INTERNAL_ERROR, NULL);
|
||||
}
|
||||
|
||||
if (su_msg_is_non_null(nua->nua_signal))
|
||||
su_msg_destroy(nua->nua_signal);
|
||||
su_msg_destroy(nua->nua_signal);
|
||||
}
|
||||
|
||||
if (nh != nua->nua_dhandle)
|
||||
nua_handle_unref(nh);
|
||||
/* ====================================================================== */
|
||||
/* Signal and event handling */
|
||||
|
||||
/** Get event data.
|
||||
*
|
||||
* @sa #nua_event_e, nua_event_save(), nua_saved_event_request(), nua_destroy_event().
|
||||
*/
|
||||
nua_event_data_t const *nua_event_data(nua_saved_event_t const saved[1])
|
||||
{
|
||||
return saved && saved[0] ? su_msg_data(saved)->ee_data : NULL;
|
||||
}
|
||||
|
||||
/** Destroy saved event.
|
||||
*
|
||||
* @sa #nua_event_e, nua_event_save(), nua_event_data(), nua_saved_event_request().
|
||||
*/
|
||||
void nua_destroy_event(nua_saved_event_t saved[1])
|
||||
{
|
||||
if (saved) su_msg_destroy(saved);
|
||||
}
|
||||
|
||||
/** @internal Move signal. */
|
||||
void nua_move_signal(nua_saved_signal_t a[1], nua_saved_signal_t b[1])
|
||||
{
|
||||
su_msg_save(a, b);
|
||||
}
|
||||
|
||||
void nua_destroy_signal(nua_saved_signal_t saved[1])
|
||||
{
|
||||
if (saved) su_msg_destroy(saved);
|
||||
}
|
||||
|
||||
nua_signal_data_t const *nua_signal_data(nua_saved_signal_t const saved[1])
|
||||
{
|
||||
return nua_event_data(saved);
|
||||
}
|
||||
|
||||
/* ====================================================================== */
|
||||
|
@ -1114,6 +1337,8 @@ int nua_stack_process_request(nua_handle_t *nh,
|
|||
(Call/Transaction Does Not Exist) status code and pass that to the
|
||||
server transaction.
|
||||
*/
|
||||
if (method == sip_method_info)
|
||||
/* accept out-of-dialog info */; else
|
||||
if (method != sip_method_message || !NH_PGET(nh, win_messenger_enable))
|
||||
sm = NULL;
|
||||
}
|
||||
|
@ -1242,11 +1467,12 @@ void nua_server_request_destroy(nua_server_request_t *sr)
|
|||
if (sr == NULL)
|
||||
return;
|
||||
|
||||
if (SR_HAS_SAVED_SIGNAL(sr))
|
||||
nua_destroy_signal(sr->sr_signal);
|
||||
|
||||
if (sr->sr_irq)
|
||||
nta_incoming_destroy(sr->sr_irq), sr->sr_irq = NULL;
|
||||
|
||||
su_msg_destroy(sr->sr_signal);
|
||||
|
||||
if (sr->sr_request.msg)
|
||||
msg_destroy(sr->sr_request.msg), sr->sr_request.msg = NULL;
|
||||
|
||||
|
@ -1379,8 +1605,9 @@ nua_stack_respond(nua_t *nua, nua_handle_t *nh,
|
|||
sr->sr_application = status;
|
||||
if (tags && nua_stack_set_params(nua, nh, nua_i_none, tags) < 0)
|
||||
SR_STATUS1(sr, SIP_500_INTERNAL_SERVER_ERROR);
|
||||
else
|
||||
else {
|
||||
sr->sr_status = status, sr->sr_phrase = phrase;
|
||||
}
|
||||
}
|
||||
|
||||
nua_server_params(sr, tags);
|
||||
|
@ -1771,12 +1998,12 @@ int nua_client_create(nua_handle_t *nh,
|
|||
cr->cr_auto = 1;
|
||||
|
||||
if (su_msg_is_non_null(nh->nh_nua->nua_signal)) {
|
||||
nua_event_data_t const *e = su_msg_data(nh->nh_nua->nua_signal);
|
||||
nua_event_data_t const *e = su_msg_data(nh->nh_nua->nua_signal)->ee_data;
|
||||
|
||||
if (tags == e->e_tags && event == e->e_event) {
|
||||
cr->cr_auto = 0;
|
||||
if (tags) {
|
||||
su_msg_save(cr->cr_signal, nh->nh_nua->nua_signal);
|
||||
nua_move_signal(cr->cr_signal, nh->nh_nua->nua_signal);
|
||||
cr->cr_tags = tags;
|
||||
}
|
||||
}
|
||||
|
@ -1860,7 +2087,7 @@ void nua_client_request_destroy(nua_client_request_t *cr)
|
|||
|
||||
nh = cr->cr_owner;
|
||||
|
||||
su_msg_destroy(cr->cr_signal);
|
||||
nua_destroy_signal(cr->cr_signal);
|
||||
|
||||
nua_client_request_remove(cr);
|
||||
nua_client_bind(cr, NULL);
|
||||
|
@ -2575,9 +2802,11 @@ int nua_base_client_check_restart(nua_client_request_t *cr,
|
|||
|
||||
cr->cr_challenged = 1;
|
||||
|
||||
if (invalid)
|
||||
if (invalid) {
|
||||
/* Bad username/password */
|
||||
SU_DEBUG_7(("nua(%p): bad credentials, clearing them\n", (void *)nh));
|
||||
auc_clear_credentials(&nh->nh_auth, NULL, NULL);
|
||||
}
|
||||
else if (auc_has_authorization(&nh->nh_auth))
|
||||
return nua_client_restart(cr, 100, "Request Authorized by Cache");
|
||||
|
||||
|
@ -2594,7 +2823,7 @@ int nua_base_client_check_restart(nua_client_request_t *cr,
|
|||
if (500 <= status && status < 600 &&
|
||||
sip->sip_retry_after &&
|
||||
sip->sip_retry_after->af_delta < 32) {
|
||||
char phrase[18]; /* Retry-After: XXXX\0 */
|
||||
char phrase[18]; /* Retry After XXXX\0 */
|
||||
|
||||
if (cr->cr_timer == NULL)
|
||||
cr->cr_timer = su_timer_create(su_root_task(nh->nh_nua->nua_root), 0);
|
||||
|
|
|
@ -75,7 +75,7 @@ SOFIA_BEGIN_DECLS
|
|||
#include "nua_params.h"
|
||||
#endif
|
||||
|
||||
typedef struct event_s event_t;
|
||||
typedef struct event_s event_t, nua_signal_data_t;
|
||||
|
||||
#define NONE ((void *)-1)
|
||||
|
||||
|
@ -109,7 +109,7 @@ typedef struct register_usage nua_registration_t;
|
|||
#define nua_handle_unref(nh) nua_handle_unref_by((nh), __func__)
|
||||
|
||||
su_inline nua_handle_t *nua_handle_ref_by(nua_handle_t *nh,
|
||||
char const *by)
|
||||
char const *by)
|
||||
{
|
||||
if (nh)
|
||||
SU_DEBUG_0(("nua_handle_ref(%p) => "MOD_ZU" by %s\n", nh,
|
||||
|
@ -120,11 +120,16 @@ su_inline nua_handle_t *nua_handle_ref_by(nua_handle_t *nh,
|
|||
|
||||
su_inline int nua_handle_unref_by(nua_handle_t *nh, char const *by)
|
||||
{
|
||||
if (nh)
|
||||
SU_DEBUG_0(("nua_handle_unref(%p) => "MOD_ZU" by %s\n", nh,
|
||||
su_home_refcount((su_home_t *)nh) - 1,
|
||||
by));
|
||||
return su_home_unref((su_home_t *)nh);
|
||||
if (nh) {
|
||||
size_t refcount = su_home_refcount((su_home_t *)nh) - 1;
|
||||
int freed = su_home_unref((su_home_t *)nh);
|
||||
if (freed) refcount = 0;
|
||||
SU_DEBUG_0(("nua_handle_unref(%p) => "MOD_ZU" by %s\n",
|
||||
nh, refcount, by));
|
||||
return freed;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
@ -197,6 +202,8 @@ int nh_is_special(nua_handle_t *nh)
|
|||
return nh == NULL || nh->nh_special;
|
||||
}
|
||||
|
||||
typedef struct nua_event_frame_s nua_event_frame_t;
|
||||
|
||||
extern char const nua_internal_error[];
|
||||
|
||||
#define NUA_INTERNAL_ERROR 900, nua_internal_error
|
||||
|
@ -214,7 +221,7 @@ struct nua_s {
|
|||
nua_callback_f nua_callback;
|
||||
nua_magic_t *nua_magic;
|
||||
|
||||
nua_saved_event_t nua_current[1];
|
||||
nua_event_frame_t *nua_current;
|
||||
nua_saved_event_t nua_signal[1];
|
||||
|
||||
/* Engine state flags */
|
||||
|
@ -277,10 +284,19 @@ struct nua_s {
|
|||
#define __func__ "nua"
|
||||
#endif
|
||||
|
||||
su_inline nua_t *nua_stack_ref(nua_t *nua)
|
||||
{
|
||||
return (nua_t *)su_home_ref(nua->nua_home);
|
||||
}
|
||||
|
||||
su_inline void nua_stack_unref(nua_t *nua)
|
||||
{
|
||||
su_home_unref(nua->nua_home);
|
||||
}
|
||||
|
||||
/* Internal prototypes */
|
||||
int nua_stack_init(su_root_t *root, nua_t *nua);
|
||||
void nua_stack_deinit(su_root_t *root, nua_t *nua);
|
||||
void nua_stack_signal(nua_t *nua, su_msg_r msg, event_t *e);
|
||||
|
||||
int nua_stack_init_transport(nua_t *nua, tagi_t const *tags);
|
||||
|
||||
|
@ -305,6 +321,10 @@ typedef int nua_stack_signal_handler(nua_t *,
|
|||
nua_event_t,
|
||||
tagi_t const *);
|
||||
|
||||
void nua_move_signal(nua_saved_signal_t a[1], nua_saved_signal_t b[1]);
|
||||
nua_signal_data_t const *nua_signal_data(nua_saved_signal_t const saved[1]);
|
||||
void nua_destroy_signal(nua_saved_signal_t saved[1]);
|
||||
|
||||
nua_stack_signal_handler
|
||||
nua_stack_set_params, nua_stack_get_params,
|
||||
nua_stack_register,
|
||||
|
@ -332,6 +352,8 @@ int nua_stack_event(nua_t *nua, nua_handle_t *nh, msg_t *msg,
|
|||
nua_event_t event, int status, char const *phrase,
|
||||
tagi_t const *tags);
|
||||
|
||||
void nua_move_event(nua_saved_event_t a[1], nua_saved_event_t b[1]);
|
||||
|
||||
nua_handle_t *nh_create_handle(nua_t *nua, nua_hmagic_t *hmagic, tagi_t *tags);
|
||||
|
||||
nua_handle_t *nua_stack_incoming_handle(nua_t *nua,
|
||||
|
@ -431,11 +453,9 @@ typedef unsigned longlong ull;
|
|||
/* ---------------------------------------------------------------------- */
|
||||
/* Application side prototypes */
|
||||
|
||||
void nua_signal(nua_t *nua, nua_handle_t *nh, msg_t *msg, int always,
|
||||
nua_event_t event, int status, char const *phrase,
|
||||
tag_type_t tag, tag_value_t value, ...);
|
||||
|
||||
void nua_event(nua_t *root_magic, su_msg_r sumsg, event_t *e);
|
||||
int nua_signal(nua_t *nua, nua_handle_t *nh, msg_t *msg,
|
||||
nua_event_t event, int status, char const *phrase,
|
||||
tag_type_t tag, tag_value_t value, ...);
|
||||
|
||||
SOFIA_END_DECLS
|
||||
|
||||
|
|
|
@ -463,7 +463,8 @@ int test_basic_call_2(struct context *ctx)
|
|||
#else
|
||||
/* sf.net bug #1816647: Outbound contact does not make it to dialogs */
|
||||
/* Now we use first registered contact if aor does not match */
|
||||
TEST_S(sip->sip_contact->m_url->url_user, "b");
|
||||
if (ctx->proxy_tests)
|
||||
TEST_S(sip->sip_contact->m_url->url_user, "b");
|
||||
#endif
|
||||
TEST_1(e = e->next); TEST_E(e->data->e_event, nua_i_state);
|
||||
TEST(callstate(e->data->e_tags), nua_callstate_ready); /* READY */
|
||||
|
@ -1043,7 +1044,8 @@ int test_basic_call_5(struct context *ctx)
|
|||
TEST(e->data->e_status, 200);
|
||||
TEST_1(sip = sip_object(e->data->e_msg));
|
||||
TEST_1(sip->sip_contact);
|
||||
TEST_S(sip->sip_contact->m_url->url_user, "b");
|
||||
if (ctx->proxy_tests) /* Use Contact from registration? */
|
||||
TEST_S(sip->sip_contact->m_url->url_user, "b");
|
||||
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(e = e->next); TEST_E(e->data->e_event, nua_i_state);
|
||||
|
|
|
@ -408,6 +408,7 @@ int test_deinit(struct context *ctx)
|
|||
|
||||
nua_shutdown(ctx->a.nua);
|
||||
run_a_until(ctx, nua_r_shutdown, until_final_response);
|
||||
free_events_in_list(ctx, ctx->a.events);
|
||||
free_events_in_list(ctx, ctx->a.specials);
|
||||
nua_destroy(ctx->a.nua), ctx->a.nua = NULL;
|
||||
}
|
||||
|
@ -418,6 +419,7 @@ int test_deinit(struct context *ctx)
|
|||
|
||||
nua_shutdown(ctx->b.nua);
|
||||
run_b_until(ctx, nua_r_shutdown, until_final_response);
|
||||
free_events_in_list(ctx, ctx->b.events);
|
||||
free_events_in_list(ctx, ctx->b.specials);
|
||||
nua_destroy(ctx->b.nua), ctx->b.nua = NULL;
|
||||
}
|
||||
|
@ -428,6 +430,7 @@ int test_deinit(struct context *ctx)
|
|||
|
||||
nua_shutdown(ctx->c.nua);
|
||||
run_c_until(ctx, nua_r_shutdown, until_final_response);
|
||||
free_events_in_list(ctx, ctx->c.events);
|
||||
free_events_in_list(ctx, ctx->c.specials);
|
||||
nua_destroy(ctx->c.nua), ctx->c.nua = NULL;
|
||||
}
|
||||
|
@ -436,7 +439,7 @@ int test_deinit(struct context *ctx)
|
|||
|
||||
test_nat_destroy(ctx->nat), ctx->nat = NULL;
|
||||
|
||||
su_root_destroy(ctx->root);
|
||||
su_root_destroy(ctx->root), ctx->root = NULL;
|
||||
|
||||
END();
|
||||
}
|
||||
|
|
|
@ -22,7 +22,8 @@
|
|||
*
|
||||
*/
|
||||
|
||||
/**@CFILE test_nua.h
|
||||
/**@@internal
|
||||
* @file test_nua.h
|
||||
* @brief High-level tester framework for Sofia SIP User Agent Engine
|
||||
*
|
||||
* @author Pekka Pessi <Pekka.Pessi@nokia.com>
|
||||
|
|
|
@ -206,6 +206,7 @@ struct proxy_tr
|
|||
sip_t *sip; /* request headers */
|
||||
|
||||
sip_method_t method; /* request method */
|
||||
char const *method_name;
|
||||
int status; /* best status */
|
||||
url_t *target; /* request-URI */
|
||||
|
||||
|
@ -343,6 +344,9 @@ test_proxy_deinit(su_root_t *root, struct proxy *proxy)
|
|||
{
|
||||
struct proxy_tr *t;
|
||||
|
||||
while (proxy->transactions)
|
||||
proxy_tr_destroy(proxy->transactions);
|
||||
|
||||
if ((t = proxy->stateless)) {
|
||||
proxy->stateless = NULL;
|
||||
proxy_tr_destroy(t);
|
||||
|
@ -698,7 +702,7 @@ static int domain_request(union proxy_or_domain *pod,
|
|||
{
|
||||
int (*process)(struct proxy_tr *) = NULL;
|
||||
sip_method_t method = sip->sip_request->rq_method;
|
||||
|
||||
|
||||
assert(pod->domain->magic = domain_init);
|
||||
|
||||
if (leg == pod->domain->uleg)
|
||||
|
@ -732,6 +736,7 @@ static int proxy_tr_with(struct proxy *proxy,
|
|||
t->sip = sip_object(t->msg);
|
||||
|
||||
t->method = sip->sip_request->rq_method;
|
||||
t->method_name = sip->sip_request->rq_method_name;
|
||||
t->target = sip->sip_request->rq_url;
|
||||
t->now = nta_incoming_received(irq, NULL);
|
||||
|
||||
|
@ -767,7 +772,7 @@ static int proxy_transaction(struct proxy_tr *t)
|
|||
|
||||
return target_transaction(t, t->target, NULL);
|
||||
}
|
||||
|
||||
|
||||
static int respond_transaction(struct proxy_tr *t,
|
||||
int status, char const *phrase,
|
||||
tag_type_t tag, tag_value_t value,
|
||||
|
@ -925,6 +930,7 @@ static int target_transaction(struct proxy_tr *t,
|
|||
tport_t *tport)
|
||||
{
|
||||
struct client_tr *c = su_zalloc(t->proxy->home, sizeof *c);
|
||||
int stateless = t->method == sip_method_ack;
|
||||
|
||||
if (c == NULL)
|
||||
return 500;
|
||||
|
@ -935,8 +941,7 @@ static int target_transaction(struct proxy_tr *t,
|
|||
|
||||
if (c->msg)
|
||||
c->rq = sip_request_create(msg_home(c->msg),
|
||||
c->sip->sip_request->rq_method,
|
||||
c->sip->sip_request->rq_method_name,
|
||||
t->method, t->method_name,
|
||||
(url_string_t *)target,
|
||||
NULL);
|
||||
|
||||
|
@ -957,15 +962,18 @@ static int target_transaction(struct proxy_tr *t,
|
|||
NULL,
|
||||
msg_ref_create(c->msg),
|
||||
NTATAG_TPORT(tport),
|
||||
NTATAG_STATELESS(stateless),
|
||||
TAG_END());
|
||||
|
||||
if (c->client)
|
||||
return client_tr_insert(&t->clients, c), 0;
|
||||
if (!c->client) {
|
||||
msg_destroy(c->msg);
|
||||
su_free(t->proxy->home, c);
|
||||
return 500;
|
||||
}
|
||||
|
||||
msg_destroy(c->msg);
|
||||
su_free(t->proxy->home, c);
|
||||
client_tr_insert(&t->clients, c);
|
||||
|
||||
return 500;
|
||||
return stateless ? 200 : 0;
|
||||
}
|
||||
|
||||
static int challenge_transaction(struct proxy_tr *t)
|
||||
|
@ -1095,6 +1103,8 @@ void proxy_tr_destroy(struct proxy_tr *t)
|
|||
su_free(t->proxy->home, c);
|
||||
}
|
||||
|
||||
msg_destroy(t->msg);
|
||||
|
||||
nta_incoming_destroy(t->server);
|
||||
|
||||
su_free(t->proxy->home, t);
|
||||
|
|
|
@ -1018,6 +1018,15 @@ int test_unregister(struct context *ctx)
|
|||
TEST_1(e = e->next);
|
||||
TEST_E(e->data->e_event, nua_r_unregister);
|
||||
}
|
||||
if (e->data->e_status == 401) {
|
||||
TEST_1(!e->next);
|
||||
free_events_in_list(ctx, c->events);
|
||||
AUTHENTICATE(c, NULL, c->reg->nh,
|
||||
NUTAG_AUTH("Digest:\"test-proxy\":charlie:secret"), TAG_END());
|
||||
run_c_until(ctx, -1, save_until_final_response);
|
||||
TEST_1(e = c->events->head);
|
||||
TEST_E(e->data->e_event, nua_r_unregister);
|
||||
}
|
||||
TEST(e->data->e_status, 200);
|
||||
TEST_1(sip = sip_object(e->data->e_msg));
|
||||
TEST_1(sip->sip_from->a_url->url_user);
|
||||
|
|
|
@ -398,6 +398,9 @@ typedef void su_msg_function(su_root_magic_t *magic,
|
|||
su_msg_r msg,
|
||||
su_msg_arg_t *arg);
|
||||
|
||||
/** Message deinitialize. */
|
||||
typedef void su_msg_deinit_func(su_msg_arg_t *arg);
|
||||
|
||||
/** Message delivery function pointer type. */
|
||||
typedef su_msg_function *su_msg_f;
|
||||
|
||||
|
@ -526,6 +529,7 @@ SOFIAPUBFUN int su_msg_create(su_msg_r msg,
|
|||
su_task_r const to, su_task_r const from,
|
||||
su_msg_f wakeup, isize_t size);
|
||||
SOFIAPUBFUN int su_msg_report(su_msg_r msg, su_msg_f report);
|
||||
SOFIAPUBFUN int su_msg_deinitializer(su_msg_r msg, su_msg_deinit_func *);
|
||||
SOFIAPUBFUN int su_msg_reply(su_msg_r reply, su_msg_cr msg,
|
||||
su_msg_f wakeup, isize_t size);
|
||||
SOFIAPUBFUN void su_msg_destroy(su_msg_r msg);
|
||||
|
@ -537,6 +541,11 @@ SOFIAPUBFUN _su_task_r su_msg_from(su_msg_cr msg);
|
|||
SOFIAPUBFUN _su_task_r su_msg_to(su_msg_cr msg);
|
||||
SOFIAPUBFUN int su_msg_send(su_msg_r msg);
|
||||
|
||||
SOFIAPUBFUN int su_msg_new(su_msg_r msg, size_t size);
|
||||
SOFIAPUBFUN int su_msg_send_to(su_msg_r msg,
|
||||
su_task_r const to,
|
||||
su_msg_f wakeup);
|
||||
|
||||
/** Does reference contain a message? */
|
||||
#if SU_HAVE_INLINE
|
||||
static SU_INLINE
|
||||
|
|
|
@ -268,8 +268,14 @@ static int su_base_port_execute_msgs(su_msg_t *queue)
|
|||
|
||||
queue = msg->sum_next, msg->sum_next = NULL;
|
||||
|
||||
if (f)
|
||||
f(SU_ROOT_MAGIC(msg->sum_to->sut_root), &msg, msg->sum_data);
|
||||
if (f) {
|
||||
su_root_t *root = msg->sum_to->sut_root;
|
||||
|
||||
if (msg->sum_to->sut_port == NULL)
|
||||
msg->sum_to->sut_root = NULL;
|
||||
f(SU_ROOT_MAGIC(root), &msg, msg->sum_data);
|
||||
}
|
||||
|
||||
su_msg_delivery_report(&msg);
|
||||
n++;
|
||||
}
|
||||
|
|
|
@ -61,12 +61,13 @@ SOFIA_BEGIN_DECLS
|
|||
|
||||
/** @internal Message */
|
||||
struct su_msg_s {
|
||||
isize_t sum_size;
|
||||
size_t sum_size;
|
||||
su_msg_t *sum_next;
|
||||
su_task_r sum_to;
|
||||
su_task_r sum_from;
|
||||
su_msg_f sum_func;
|
||||
su_msg_f sum_report;
|
||||
su_msg_deinit_func *sum_deinit;
|
||||
su_msg_arg_t sum_data[1]; /* minimum size, may be extended */
|
||||
};
|
||||
|
||||
|
@ -101,11 +102,11 @@ typedef struct su_port_vtable {
|
|||
struct _GSource *(*su_port_gsource)(su_port_t *port);
|
||||
int (*su_port_send)(su_port_t *self, su_msg_r rmsg);
|
||||
int (*su_port_register)(su_port_t *self,
|
||||
su_root_t *root,
|
||||
su_wait_t *wait,
|
||||
su_wakeup_f callback,
|
||||
su_wakeup_arg_t *arg,
|
||||
int priority);
|
||||
su_root_t *root,
|
||||
su_wait_t *wait,
|
||||
su_wakeup_f callback,
|
||||
su_wakeup_arg_t *arg,
|
||||
int priority);
|
||||
int (*su_port_unregister)(su_port_t *port,
|
||||
su_root_t *root,
|
||||
su_wait_t *wait,
|
||||
|
|
|
@ -875,6 +875,30 @@ int su_root_has_thread(su_root_t *root)
|
|||
* Messages
|
||||
*/
|
||||
|
||||
/**
|
||||
* Allocate a su message of given size.
|
||||
*
|
||||
* Allocate a su message with given data size.
|
||||
*
|
||||
* @param rmsg handle to the new message (may be uninitialized prior calling)
|
||||
* @param size size of the message data
|
||||
*
|
||||
* @retval 0 if successful,
|
||||
* @retval -1 if message allocation fails.
|
||||
*/
|
||||
int su_msg_new(su_msg_r rmsg, size_t size)
|
||||
{
|
||||
su_msg_t *msg;
|
||||
size_t total = sizeof(*msg) + (size_t)size;
|
||||
|
||||
*rmsg = msg = su_zalloc(NULL, (isize_t)total);
|
||||
if (!*rmsg)
|
||||
return -1;
|
||||
|
||||
msg->sum_size = total;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Allocates a message of given size.
|
||||
*
|
||||
|
@ -896,20 +920,13 @@ int su_msg_create(su_msg_r rmsg,
|
|||
su_msg_f wakeup,
|
||||
isize_t size)
|
||||
{
|
||||
su_msg_t *msg;
|
||||
|
||||
msg = su_zalloc(NULL, sizeof(*msg) + size);
|
||||
|
||||
if (msg) {
|
||||
msg->sum_size = sizeof(*msg) + size;
|
||||
SU_TASK_COPY(msg->sum_to, to, su_msg_create);
|
||||
SU_TASK_COPY(msg->sum_from, from, su_msg_create);
|
||||
msg->sum_func = wakeup;
|
||||
*rmsg = msg;
|
||||
if (su_msg_new(rmsg, (size_t) size) == 0) {
|
||||
SU_TASK_COPY(rmsg[0]->sum_to, to, su_msg_create);
|
||||
SU_TASK_COPY(rmsg[0]->sum_from, from, su_msg_create);
|
||||
rmsg[0]->sum_func = wakeup;
|
||||
return 0;
|
||||
}
|
||||
|
||||
*rmsg = NULL;
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
@ -931,11 +948,31 @@ int su_msg_report(su_msg_r msg,
|
|||
return -1;
|
||||
}
|
||||
|
||||
/** Add a deinitializer function to a message.
|
||||
*
|
||||
* The deinitializer function is called when the message gets destroyed. It
|
||||
* is called even if the message was never delivered. Note that the thread
|
||||
* destroying the message and calling the deinit function is not necessarily
|
||||
* the same that sent the message nor the original recipient.
|
||||
*
|
||||
* @param rmsg message reference
|
||||
* @param deinit pointer to deinitializer function
|
||||
*/
|
||||
int su_msg_deinitializer(su_msg_r rmsg,
|
||||
su_msg_deinit_func *deinit)
|
||||
{
|
||||
if (rmsg && rmsg[0]) {
|
||||
rmsg[0]->sum_deinit = deinit;
|
||||
return 0;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
/**
|
||||
* Allocates a reply message of given size.
|
||||
*
|
||||
* @param reply handle to the new message (may be uninitialized prior calling)
|
||||
* @param msg the incoming message
|
||||
* @param rmsg the incoming message
|
||||
* @param wakeup function that is called when message is delivered
|
||||
* @param size size of the message data
|
||||
*
|
||||
|
@ -943,17 +980,17 @@ int su_msg_report(su_msg_r msg,
|
|||
* @retval -1 otherwise.
|
||||
*/
|
||||
|
||||
int su_msg_reply(su_msg_r reply, su_msg_cr msg,
|
||||
int su_msg_reply(su_msg_r reply, su_msg_cr rmsg,
|
||||
su_msg_f wakeup, isize_t size)
|
||||
{
|
||||
su_msg_r msg0;
|
||||
su_msg_r rmsg0;
|
||||
|
||||
assert(msg != reply);
|
||||
assert(rmsg != reply);
|
||||
|
||||
*msg0 = *(su_msg_t **) msg;
|
||||
*rmsg0 = *(su_msg_t **) rmsg;
|
||||
*reply = NULL;
|
||||
|
||||
return su_msg_create(reply, su_msg_from(msg0), su_msg_to(msg0), wakeup, size);
|
||||
return su_msg_create(reply, su_msg_from(rmsg0), su_msg_to(rmsg0), wakeup, size);
|
||||
}
|
||||
|
||||
|
||||
|
@ -964,38 +1001,38 @@ int su_msg_reply(su_msg_r reply, su_msg_cr msg,
|
|||
* sending task. The sending task calls the delivery report function when it
|
||||
* has received the message.
|
||||
*/
|
||||
void su_msg_delivery_report(su_msg_r msg)
|
||||
void su_msg_delivery_report(su_msg_r rmsg)
|
||||
{
|
||||
su_task_r swap;
|
||||
|
||||
if (!msg || !msg[0])
|
||||
if (!rmsg || !rmsg[0])
|
||||
return;
|
||||
|
||||
if (!msg[0]->sum_report) {
|
||||
su_msg_destroy(msg);
|
||||
if (!rmsg[0]->sum_report) {
|
||||
su_msg_destroy(rmsg);
|
||||
return;
|
||||
}
|
||||
|
||||
*swap = *msg[0]->sum_from;
|
||||
*msg[0]->sum_from = *msg[0]->sum_to;
|
||||
*msg[0]->sum_to = *swap;
|
||||
*swap = *rmsg[0]->sum_from;
|
||||
*rmsg[0]->sum_from = *rmsg[0]->sum_to;
|
||||
*rmsg[0]->sum_to = *swap;
|
||||
|
||||
msg[0]->sum_func = msg[0]->sum_report;
|
||||
msg[0]->sum_report = NULL;
|
||||
su_msg_send(msg);
|
||||
rmsg[0]->sum_func = rmsg[0]->sum_report;
|
||||
rmsg[0]->sum_report = NULL;
|
||||
su_msg_send(rmsg);
|
||||
}
|
||||
|
||||
/** Save a message. */
|
||||
void su_msg_save(su_msg_r save, su_msg_r msg)
|
||||
void su_msg_save(su_msg_r save, su_msg_r rmsg)
|
||||
{
|
||||
if (save) {
|
||||
if (msg)
|
||||
save[0] = msg[0];
|
||||
if (rmsg)
|
||||
save[0] = rmsg[0];
|
||||
else
|
||||
save[0] = NULL;
|
||||
}
|
||||
if (msg)
|
||||
msg[0] = NULL;
|
||||
if (rmsg)
|
||||
rmsg[0] = NULL;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -1011,6 +1048,9 @@ void su_msg_destroy(su_msg_r rmsg)
|
|||
SU_TASK_ZAP(rmsg[0]->sum_to, su_msg_destroy);
|
||||
SU_TASK_ZAP(rmsg[0]->sum_from, su_msg_destroy);
|
||||
|
||||
if (rmsg[0]->sum_deinit)
|
||||
rmsg[0]->sum_deinit(rmsg[0]->sum_data);
|
||||
|
||||
su_free(NULL, rmsg[0]);
|
||||
}
|
||||
|
||||
|
@ -1048,13 +1088,13 @@ isize_t su_msg_size(su_msg_cr rmsg)
|
|||
* If the message handle contains NULL the function @c su_msg_from
|
||||
* returns NULL.
|
||||
*
|
||||
* @param msg message handle
|
||||
* @param rmsg message handle
|
||||
*
|
||||
* @return The task handle of the sender is returned.
|
||||
*/
|
||||
_su_task_r su_msg_from(su_msg_cr msg)
|
||||
_su_task_r su_msg_from(su_msg_cr rmsg)
|
||||
{
|
||||
return msg[0] ? msg[0]->sum_from : NULL;
|
||||
return rmsg[0] ? rmsg[0]->sum_from : NULL;
|
||||
}
|
||||
|
||||
/** Get destination task.
|
||||
|
@ -1065,24 +1105,24 @@ _su_task_r su_msg_from(su_msg_cr msg)
|
|||
* If the message handle contains NULL the function @c su_msg_to
|
||||
* returns NULL.
|
||||
*
|
||||
* @param msg message handle
|
||||
* @param rmsg message handle
|
||||
*
|
||||
* @return The task handle of the recipient is returned.
|
||||
*/
|
||||
_su_task_r su_msg_to(su_msg_cr msg)
|
||||
_su_task_r su_msg_to(su_msg_cr rmsg)
|
||||
{
|
||||
return msg[0] ? msg[0]->sum_to : NULL;
|
||||
return rmsg[0] ? rmsg[0]->sum_to : NULL;
|
||||
}
|
||||
|
||||
/** Remove references to 'from' and 'to' tasks from a message.
|
||||
*
|
||||
* @param msg message handle
|
||||
* @param rmsg message handle
|
||||
*/
|
||||
void su_msg_remove_refs(su_msg_cr msg)
|
||||
void su_msg_remove_refs(su_msg_cr rmsg)
|
||||
{
|
||||
if (msg[0]) {
|
||||
su_task_deinit(msg[0]->sum_to);
|
||||
su_task_deinit(msg[0]->sum_from);
|
||||
if (rmsg[0]) {
|
||||
su_task_deinit(rmsg[0]->sum_to);
|
||||
su_task_deinit(rmsg[0]->sum_from);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1115,3 +1155,36 @@ int su_msg_send(su_msg_r rmsg)
|
|||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/** Send message to the @a to_task and mark @a from_task as sender */
|
||||
SOFIAPUBFUN int su_msg_send_to(su_msg_r rmsg,
|
||||
su_task_r const to_task,
|
||||
su_msg_f wakeup)
|
||||
{
|
||||
assert(rmsg); assert(to_task);
|
||||
|
||||
if (rmsg[0]) {
|
||||
su_msg_t *msg = rmsg[0];
|
||||
|
||||
if (wakeup)
|
||||
msg->sum_func = wakeup;
|
||||
|
||||
if (msg->sum_to->sut_port &&
|
||||
msg->sum_to->sut_port != to_task->sut_port) {
|
||||
SU_TASK_ZAP(msg->sum_to, "su_msg_send_to");
|
||||
}
|
||||
|
||||
if (to_task->sut_port != NULL) {
|
||||
msg->sum_to->sut_port = NULL;
|
||||
msg->sum_to->sut_root = to_task->sut_root;
|
||||
|
||||
return su_port_send(to_task->sut_port, rmsg);
|
||||
}
|
||||
|
||||
su_msg_destroy(rmsg);
|
||||
errno = EINVAL;
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -96,7 +96,7 @@ struct hentry_s
|
|||
#define HENTRY_IS_USED(e) ((e).e_n != 0)
|
||||
#define HENTRY_REMOVE(e) ((e)->e_n = 0, (e)->e_hash = 0)
|
||||
#define HENTRY_IS_EQUAL(a, b) ((a).e_n == (b).e_n)
|
||||
#define HALLOC(home, old, newsize) (su_realloc(home, old, newsize))
|
||||
#define HALLOC(home, old, newsize) (su_realloc(home, old, (isize_t)newsize))
|
||||
|
||||
HTABLE2_BODIES2(htable2_t, htable2, ht2_, entry_t, size_t,
|
||||
HENTRY_HASH, HENTRY_IS_USED, HENTRY_REMOVE, HENTRY_IS_EQUAL,
|
||||
|
|
|
@ -559,16 +559,10 @@ int main(int argc, char *argv[])
|
|||
su_perror("su_timer_create"), exit(1);
|
||||
su_timer_set(t, (su_timer_f)do_exit, NULL);
|
||||
|
||||
su_clone_pause(ping);
|
||||
su_clone_pause(pong);
|
||||
|
||||
su_msg_create(start_msg, su_clone_task(ping), su_clone_task(pong),
|
||||
init_ping, 0);
|
||||
su_msg_send(start_msg);
|
||||
|
||||
su_clone_resume(ping);
|
||||
su_clone_resume(pong);
|
||||
|
||||
su_root_run(root);
|
||||
|
||||
su_clone_wait(root, ping);
|
||||
|
|
|
@ -41,6 +41,7 @@ char const *name = "torture_su_root";
|
|||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <assert.h>
|
||||
|
||||
#define TSTFLAGS rt->rt_flags
|
||||
#include <sofia-sip/tstdef.h>
|
||||
|
@ -50,6 +51,7 @@ typedef struct test_ep_s test_ep_t;
|
|||
|
||||
#define SU_ROOT_MAGIC_T root_test_t
|
||||
#define SU_WAKEUP_ARG_T test_ep_t
|
||||
#define SU_MSG_ARG_T root_test_t *
|
||||
|
||||
#include <sofia-sip/su_wait.h>
|
||||
#include <sofia-sip/su_alloc.h>
|
||||
|
@ -83,6 +85,9 @@ struct root_test_s {
|
|||
|
||||
su_clone_r rt_clone;
|
||||
|
||||
unsigned rt_msg_received;
|
||||
unsigned rt_msg_destroyed;
|
||||
|
||||
unsigned rt_fail_init:1;
|
||||
unsigned rt_fail_deinit:1;
|
||||
unsigned rt_success_init:1;
|
||||
|
@ -591,6 +596,22 @@ static int set_execute_bit_and_return_3(void *void_rt)
|
|||
return 3;
|
||||
}
|
||||
|
||||
static void deinit_simple_msg(su_msg_arg_t *arg)
|
||||
{
|
||||
root_test_t *rt = *arg;
|
||||
rt->rt_msg_destroyed++;
|
||||
}
|
||||
|
||||
static void receive_simple_msg(root_test_t *rt,
|
||||
su_msg_r msg,
|
||||
su_msg_arg_t *arg)
|
||||
{
|
||||
assert(rt == *arg);
|
||||
rt->rt_msg_received =
|
||||
su_task_cmp(su_msg_from(msg), su_task_null) == 0 &&
|
||||
su_task_cmp(su_msg_to(msg), su_task_null) == 0;
|
||||
}
|
||||
|
||||
static int clone_test(root_test_t rt[1])
|
||||
{
|
||||
BEGIN();
|
||||
|
@ -629,7 +650,21 @@ static int clone_test(root_test_t rt[1])
|
|||
&retval), 0);
|
||||
TEST(retval, 3);
|
||||
TEST_1(rt->rt_executed);
|
||||
|
||||
|
||||
/* Deliver message with su_msg_send() */
|
||||
TEST(su_msg_new(m, sizeof &rt), 0);
|
||||
*su_msg_data(m) = rt;
|
||||
|
||||
rt->rt_msg_received = 0;
|
||||
rt->rt_msg_destroyed = 0;
|
||||
|
||||
TEST(su_msg_deinitializer(m, deinit_simple_msg), 0);
|
||||
TEST(su_msg_send_to(m, su_clone_task(rt->rt_clone), receive_simple_msg), 0);
|
||||
|
||||
while (rt->rt_msg_destroyed == 0)
|
||||
su_root_step(rt->rt_root, 1);
|
||||
|
||||
TEST(rt->rt_msg_received, 1);
|
||||
|
||||
/* Make sure 3-way handshake is done as expected */
|
||||
TEST(su_msg_create(m,
|
||||
|
|
|
@ -166,7 +166,7 @@ typedef struct {
|
|||
(n)->tpn_comp ? ";comp=" : "", (n)->tpn_comp ? (n)->tpn_comp : "", \
|
||||
(n)->tpn_ident ? "/" : "", (n)->tpn_ident ? (n)->tpn_ident : ""
|
||||
|
||||
/** Create first primary transport. */
|
||||
/**Create master transport. */
|
||||
TPORT_DLL tport_t *tport_tcreate(tp_stack_t *stack,
|
||||
tport_stack_class_t const *tpac,
|
||||
su_root_t *root,
|
||||
|
|
|
@ -798,7 +798,7 @@ static int udp_test(tp_test_t *tt)
|
|||
int pending_server_close, pending_client_close;
|
||||
|
||||
void server_closed_callback(tp_stack_t *tt, tp_client_t *client,
|
||||
tport_t *tp, msg_t *msg, int error)
|
||||
tport_t *tp, msg_t *msg, int error)
|
||||
{
|
||||
assert(msg == NULL);
|
||||
assert(client == NULL);
|
||||
|
@ -809,7 +809,7 @@ void server_closed_callback(tp_stack_t *tt, tp_client_t *client,
|
|||
}
|
||||
|
||||
void client_closed_callback(tp_stack_t *tt, tp_client_t *client,
|
||||
tport_t *tp, msg_t *msg, int error)
|
||||
tport_t *tp, msg_t *msg, int error)
|
||||
{
|
||||
assert(msg == NULL);
|
||||
assert(client == NULL);
|
||||
|
@ -1232,6 +1232,26 @@ static int sctp_test(tp_test_t *tt)
|
|||
END();
|
||||
}
|
||||
|
||||
struct called {
|
||||
int n, error, pending, released;
|
||||
};
|
||||
|
||||
static
|
||||
void tls_error_callback(tp_stack_t *tt, tp_client_t *client,
|
||||
tport_t *tp, msg_t *msg, int error)
|
||||
{
|
||||
struct called *called = (struct called *)client;
|
||||
|
||||
tt->tt_status = -1;
|
||||
|
||||
called->n++, called->error = error;
|
||||
|
||||
if (called->pending) {
|
||||
called->released = tport_release(tp, called->pending, msg, NULL, client, 0);
|
||||
called->pending = 0;
|
||||
}
|
||||
}
|
||||
|
||||
static int tls_test(tp_test_t *tt)
|
||||
{
|
||||
BEGIN();
|
||||
|
@ -1242,6 +1262,7 @@ static int tls_test(tp_test_t *tt)
|
|||
int i;
|
||||
char ident[16];
|
||||
tport_t *tp, *tp0;
|
||||
struct called called[1] = {{ 0, 0, 0, 0 }};
|
||||
|
||||
TEST_S(dst->tpn_proto, "tls");
|
||||
|
||||
|
@ -1249,9 +1270,21 @@ static int tls_test(tp_test_t *tt)
|
|||
TEST_1(!new_test_msg(tt, &msg, "tls-first", 1, 1024));
|
||||
TEST_1(tp = tport_tsend(tt->tt_tports, msg, dst, TAG_END()));
|
||||
TEST_1(tp0 = tport_ref(tp));
|
||||
TEST_1(called->pending = tport_pend(tp, msg, tls_error_callback, (tp_client_t *)called));
|
||||
|
||||
i = tport_test_run(tt, 5);
|
||||
msg_destroy(msg);
|
||||
|
||||
TEST(tport_test_run(tt, 5), 1);
|
||||
if (i < 0) {
|
||||
if (called->n) {
|
||||
TEST(called->released, 0);
|
||||
puts("test_tport: skipping TLS tests");
|
||||
tport_unref(tp0);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
TEST(i, 1);
|
||||
|
||||
TEST_1(!check_msg(tt, tt->tt_rmsg, "tls-first"));
|
||||
msg_destroy(tt->tt_rmsg), tt->tt_rmsg = NULL;
|
||||
|
|
|
@ -405,7 +405,8 @@ static int
|
|||
tport_base_wakeup(tport_t *self, int events),
|
||||
tport_connected(su_root_magic_t *m, su_wait_t *w, tport_t *self),
|
||||
tport_resolve(tport_t *self, msg_t *msg, tp_name_t const *tpn),
|
||||
tport_send_error(tport_t *, msg_t *, tp_name_t const *),
|
||||
tport_send_error(tport_t *, msg_t *, tp_name_t const *, char const *who),
|
||||
tport_send_fatal(tport_t *, msg_t *, tp_name_t const *, char const *who),
|
||||
tport_queue(tport_t *self, msg_t *msg),
|
||||
tport_queue_rest(tport_t *self, msg_t *msg, msg_iovec_t iov[], size_t iovused),
|
||||
tport_pending_error(tport_t *self, su_sockaddr_t const *dst, int error),
|
||||
|
@ -469,7 +470,12 @@ msg_t *tport_destroy_alloc(tp_stack_t *stack, int flags,
|
|||
/** Name for "any" transport. @internal */
|
||||
static char const tpn_any[] = "*";
|
||||
|
||||
/** Create the master transport.
|
||||
/** Create the master transport.
|
||||
*
|
||||
* Master transport object is used to bind the protocol using transport with
|
||||
* actual transport objects corresponding to TCP, UDP, etc.
|
||||
*
|
||||
* @sa tport_tbind()
|
||||
*
|
||||
* @TAGS
|
||||
* TPTAG_LOG(), TPTAG_DUMP(), tags used with tport_set_params(), especially
|
||||
|
@ -2985,6 +2991,7 @@ void tport_deliver(tport_t *self,
|
|||
|
||||
ref = tport_incref(self);
|
||||
|
||||
|
||||
if (self->tp_pri->pri_vtable->vtp_deliver) {
|
||||
self->tp_pri->pri_vtable->vtp_deliver(self, msg, now);
|
||||
}
|
||||
|
@ -3405,28 +3412,28 @@ int tport_send_msg(tport_t *self, msg_t *msg,
|
|||
if (tport_is_connection_oriented(self)) {
|
||||
iov[i].mv_len -= (su_ioveclen_t)(n - total);
|
||||
iov[i].mv_base = (char *)iov[i].mv_base + (n - total);
|
||||
if (tport_queue_rest(self, msg, &iov[i], iovused - i) >= 0)
|
||||
if (tport_queue_rest(self, msg, &iov[i], iovused - i) < 0)
|
||||
return tport_send_fatal(self, msg, tpn, "tport_queue_rest");
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
else {
|
||||
char const *comp = tpn->tpn_comp;
|
||||
|
||||
SU_DEBUG_1(("tport(%p): send truncated for %s/%s:%s%s%s\n",
|
||||
(void *)self, tpn->tpn_proto, tpn->tpn_host, tpn->tpn_port,
|
||||
SU_DEBUG_1(("%s(%p): send truncated for %s/%s:%s%s%s\n",
|
||||
"tport_vsend", (void *)self, tpn->tpn_proto, tpn->tpn_host, tpn->tpn_port,
|
||||
comp ? ";comp=" : "", comp ? comp : ""));
|
||||
|
||||
su_seterrno(EIO);
|
||||
msg_set_errno(msg, EIO);
|
||||
return /* tport_send_fatal(self, msg, tpn, "tport_send") */ -1;
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
total += iov[i].mv_len;
|
||||
}
|
||||
|
||||
/* We have sent a complete message */
|
||||
|
||||
self->tp_slogged = NULL;
|
||||
self->tp_stats.sent_msgs ++;
|
||||
tport_sent_message(self, msg, 0);
|
||||
|
||||
if (!tport_is_secondary(self))
|
||||
return 0;
|
||||
|
@ -3465,9 +3472,9 @@ ssize_t tport_vsend(tport_t *self,
|
|||
return 0;
|
||||
|
||||
if (n == -1)
|
||||
return tport_send_error(self, msg, tpn);
|
||||
return tport_send_error(self, msg, tpn, "tport_vsend");
|
||||
|
||||
self->tp_stats.sent_bytes += n;
|
||||
tport_sent_bytes(self, n, n); /* Sigcomp will decrease on_line accodingly */
|
||||
|
||||
if (n > 0 && self->tp_master->mr_dump_file)
|
||||
tport_dump_iovec(self, msg, n, iov, iovused, "sent", "to");
|
||||
|
@ -3481,8 +3488,8 @@ ssize_t tport_vsend(tport_t *self,
|
|||
if (tpn == NULL || tport_is_connection_oriented(self))
|
||||
tpn = self->tp_name;
|
||||
|
||||
SU_DEBUG_7(("tport_vsend(%p): "MOD_ZU" bytes of "MOD_ZU" to %s/%s:%s%s\n",
|
||||
(void *)self, n, m, tpn->tpn_proto, tpn->tpn_host,
|
||||
SU_DEBUG_7(("%s(%p): "MOD_ZU" bytes of "MOD_ZU" to %s/%s:%s%s\n",
|
||||
"tport_vsend", (void *)self, n, m, tpn->tpn_proto, tpn->tpn_host,
|
||||
tpn->tpn_port,
|
||||
(ai->ai_flags & TP_AI_COMPRESSED) ? ";comp=sigcomp" : ""));
|
||||
}
|
||||
|
@ -3491,45 +3498,56 @@ ssize_t tport_vsend(tport_t *self,
|
|||
}
|
||||
|
||||
static
|
||||
int tport_send_error(tport_t *self, msg_t *msg,
|
||||
tp_name_t const *tpn)
|
||||
int tport_send_error(tport_t *self, msg_t *msg, tp_name_t const *tpn,
|
||||
char const *who)
|
||||
{
|
||||
int error = su_errno();
|
||||
su_addrinfo_t *ai = msg_addrinfo(msg);
|
||||
char const *comp = (ai->ai_flags & TP_AI_COMPRESSED) ? ";comp=sigcomp" : "";
|
||||
|
||||
if (error == EPIPE) {
|
||||
/*Xyzzy*/
|
||||
}
|
||||
|
||||
if (su_is_blocking(error)) {
|
||||
SU_DEBUG_5(("tport_vsend(%p): %s with (s=%d %s/%s:%s%s)\n",
|
||||
(void *)self, "EAGAIN", (int)self->tp_socket,
|
||||
su_addrinfo_t *ai = msg_addrinfo(msg);
|
||||
char const *comp = (ai->ai_flags & TP_AI_COMPRESSED) ? ";comp=sigcomp" : "";
|
||||
SU_DEBUG_5(("%s(%p): %s with (s=%d %s/%s:%s%s)\n",
|
||||
who, (void *)self, "EAGAIN", (int)self->tp_socket,
|
||||
tpn->tpn_proto, tpn->tpn_host, tpn->tpn_port, comp));
|
||||
return 0;
|
||||
}
|
||||
|
||||
msg_set_errno(msg, error);
|
||||
|
||||
return tport_send_fatal(self, msg, tpn, who);
|
||||
}
|
||||
|
||||
static
|
||||
int tport_send_fatal(tport_t *self, msg_t *msg, tp_name_t const *tpn,
|
||||
char const *who)
|
||||
{
|
||||
su_addrinfo_t *ai = msg_addrinfo(msg);
|
||||
char const *comp = (ai->ai_flags & TP_AI_COMPRESSED) ? ";comp=sigcomp" : "";
|
||||
|
||||
int error = msg_errno(msg);
|
||||
|
||||
if (self->tp_addrinfo->ai_family == AF_INET) {
|
||||
SU_DEBUG_3(("tport_vsend(%p): %s with (s=%d %s/%s:%s%s)\n",
|
||||
(void *)self, su_strerror(error), (int)self->tp_socket,
|
||||
SU_DEBUG_3(("%s(%p): %s with (s=%d %s/%s:%s%s)\n",
|
||||
who, (void *)self, su_strerror(error), (int)self->tp_socket,
|
||||
tpn->tpn_proto, tpn->tpn_host, tpn->tpn_port, comp));
|
||||
}
|
||||
#if SU_HAVE_IN6
|
||||
else if (self->tp_addrinfo->ai_family == AF_INET6) {
|
||||
su_sockaddr_t const *su = (su_sockaddr_t const *)ai->ai_addr;
|
||||
SU_DEBUG_3(("tport_vsend(%p): %s with "
|
||||
"(s=%d, IP6=%s/%s:%s%s (scope=%i) addrlen=%u)\n",
|
||||
(void *)self, su_strerror(error), (int)self->tp_socket,
|
||||
SU_DEBUG_3(("%s(%p): %s with (s=%d, IP6=%s/%s:%s%s"
|
||||
" (scope=%i) addrlen=%u)\n",
|
||||
who, (void *)self, su_strerror(error), (int)self->tp_socket,
|
||||
tpn->tpn_proto, tpn->tpn_host, tpn->tpn_port, comp,
|
||||
su->su_scope_id, (unsigned)ai->ai_addrlen));
|
||||
}
|
||||
#endif
|
||||
else {
|
||||
SU_DEBUG_3(("\ttport_vsend(%p): %s with "
|
||||
"(s=%d, AF=%u addrlen=%u)%s\n",
|
||||
(void *)self, su_strerror(error),
|
||||
SU_DEBUG_3(("%s(%p): %s with (s=%d, AF=%u addrlen=%u)%s\n",
|
||||
who, (void *)self, su_strerror(error),
|
||||
(int)self->tp_socket, ai->ai_family, (unsigned)ai->ai_addrlen, comp));
|
||||
}
|
||||
|
||||
|
@ -3856,9 +3874,8 @@ void tport_send_queue(tport_t *self)
|
|||
/* We have sent a complete message */
|
||||
|
||||
self->tp_queue[qhead] = NULL;
|
||||
tport_sent_message(self, msg, 0);
|
||||
msg_destroy(msg);
|
||||
self->tp_stats.sent_msgs++;
|
||||
self->tp_slogged = NULL;
|
||||
|
||||
qhead = (qhead + 1) % N;
|
||||
}
|
||||
|
@ -4403,7 +4420,7 @@ tport_t *tport_by_name(tport_t const *self, tp_name_t const *tpn)
|
|||
su->su_len = sulen = (socklen_t) sizeof (struct sockaddr_in6);
|
||||
su->su_family = AF_INET6;
|
||||
}
|
||||
else if (host_is_ip_address(host)) {
|
||||
else if (host_is_ip6_address(host)) {
|
||||
su->su_len = sulen = (socklen_t) sizeof (struct sockaddr_in6);
|
||||
su->su_family = AF_INET6;
|
||||
}
|
||||
|
@ -4613,27 +4630,10 @@ int tport_name_by_url(su_home_t *home,
|
|||
/** Check if transport named is already resolved */
|
||||
int tport_name_is_resolved(tp_name_t const *tpn)
|
||||
{
|
||||
size_t n;
|
||||
|
||||
if (!tpn->tpn_host)
|
||||
return 0;
|
||||
|
||||
if (tpn->tpn_host[0] == '[')
|
||||
return 1;
|
||||
|
||||
n = strspn(tpn->tpn_host, ".0123456789");
|
||||
|
||||
if (tpn->tpn_host[n] == '\0')
|
||||
return 1;
|
||||
|
||||
if (strchr(tpn->tpn_host, ':')) {
|
||||
n = strspn(tpn->tpn_host, ":0123456789abcdefABCDEF");
|
||||
|
||||
if (tpn->tpn_host[n] == '\0')
|
||||
return 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
return host_is_ip_address(tpn->tpn_host);
|
||||
}
|
||||
|
||||
/** Duplicate name.
|
||||
|
@ -4742,3 +4742,79 @@ char *tport_hostport(char buf[], isize_t bufsize,
|
|||
|
||||
return buf;
|
||||
}
|
||||
|
||||
/** @internal Update receive statistics. */
|
||||
void tport_recv_bytes(tport_t *self, ssize_t bytes, ssize_t on_line)
|
||||
{
|
||||
self->tp_stats.recv_bytes += bytes;
|
||||
self->tp_stats.recv_on_line += on_line;
|
||||
|
||||
if (self != self->tp_pri->pri_primary) {
|
||||
self = self->tp_pri->pri_primary;
|
||||
self->tp_stats.recv_bytes += bytes;
|
||||
self->tp_stats.recv_on_line += on_line;
|
||||
}
|
||||
self = self->tp_master->mr_master;
|
||||
self->tp_stats.recv_bytes += bytes;
|
||||
self->tp_stats.recv_on_line += on_line;
|
||||
}
|
||||
|
||||
/** @internal Update message-based receive statistics. */
|
||||
void tport_recv_message(tport_t *self, msg_t *msg, int error)
|
||||
{
|
||||
error = error != 0;
|
||||
|
||||
self->tp_stats.recv_msgs++;
|
||||
self->tp_stats.recv_errors += error;
|
||||
|
||||
if (self != self->tp_pri->pri_primary) {
|
||||
self = self->tp_pri->pri_primary;
|
||||
self->tp_stats.recv_msgs++;
|
||||
self->tp_stats.recv_errors += error;
|
||||
}
|
||||
|
||||
self = self->tp_master->mr_master;
|
||||
|
||||
self->tp_stats.recv_msgs++;
|
||||
self->tp_stats.recv_errors += error;
|
||||
}
|
||||
|
||||
/** @internal Update send statistics. */
|
||||
void tport_sent_bytes(tport_t *self, ssize_t bytes, ssize_t on_line)
|
||||
{
|
||||
self->tp_stats.sent_bytes += bytes;
|
||||
self->tp_stats.sent_on_line += on_line;
|
||||
|
||||
if (self != self->tp_pri->pri_primary) {
|
||||
self = self->tp_pri->pri_primary;
|
||||
self->tp_stats.sent_bytes += bytes;
|
||||
self->tp_stats.sent_on_line += on_line;
|
||||
}
|
||||
|
||||
self = self->tp_master->mr_master;
|
||||
self->tp_stats.sent_bytes += bytes;
|
||||
self->tp_stats.sent_on_line += on_line;
|
||||
}
|
||||
|
||||
/** @internal Update message-based send statistics. */
|
||||
void tport_sent_message(tport_t *self, msg_t *msg, int error)
|
||||
{
|
||||
self->tp_slogged = NULL;
|
||||
|
||||
error = error != 0;
|
||||
|
||||
self->tp_stats.sent_msgs++;
|
||||
self->tp_stats.sent_errors += error;
|
||||
|
||||
if (self != self->tp_pri->pri_primary) {
|
||||
self = self->tp_pri->pri_primary;
|
||||
self->tp_stats.sent_msgs++;
|
||||
self->tp_stats.sent_errors += error;
|
||||
}
|
||||
|
||||
self = self->tp_master->mr_master;
|
||||
|
||||
self->tp_stats.sent_msgs++;
|
||||
self->tp_stats.sent_errors += error;
|
||||
|
||||
}
|
||||
|
|
|
@ -221,8 +221,8 @@ struct tport_s {
|
|||
/* ==== Statistics ===================================================== */
|
||||
|
||||
struct {
|
||||
uint64_t sent_bytes, sent_on_line, recv_bytes, recv_on_line;
|
||||
uint64_t sent_msgs, recv_msgs;
|
||||
uint64_t sent_msgs, sent_errors, sent_bytes, sent_on_line;
|
||||
uint64_t recv_msgs, recv_errors, recv_bytes, recv_on_line;
|
||||
} tp_stats;
|
||||
};
|
||||
|
||||
|
@ -528,6 +528,12 @@ int tport_recv_stun_dgram(tport_t const *self, msg_t **in_out_msg,
|
|||
int tport_stun_server_add_socket(tport_t *tp);
|
||||
int tport_stun_server_remove_socket(tport_t *tp);
|
||||
|
||||
void tport_recv_bytes(tport_t *self, ssize_t bytes, ssize_t on_line);
|
||||
void tport_recv_message(tport_t *self, msg_t *msg, int error);
|
||||
|
||||
void tport_sent_bytes(tport_t *self, ssize_t bytes, ssize_t on_line);
|
||||
void tport_sent_message(tport_t *self, msg_t *msg, int error);
|
||||
|
||||
/* ---------------------------------------------------------------------- */
|
||||
/* Compressor plugin */
|
||||
extern tport_comp_vtable_t const *tport_comp_vtable;
|
||||
|
|
|
@ -34,6 +34,7 @@
|
|||
#include "tport_internal.h"
|
||||
|
||||
#include <string.h>
|
||||
#include <sofia-sip/string0.h>
|
||||
|
||||
tport_comp_vtable_t const *tport_comp_vtable = NULL;
|
||||
|
||||
|
|
|
@ -242,6 +242,8 @@ int tport_recv_sctp(tport_t *self)
|
|||
return 0; /* End of stream */
|
||||
}
|
||||
|
||||
tport_recv_bytes(self, n, n);
|
||||
|
||||
veclen = tport_recv_iovec(self, &self->tp_msg, iovec, N, 0);
|
||||
if (veclen < 0)
|
||||
return -1;
|
||||
|
|
|
@ -281,6 +281,8 @@ int tport_recv_stream(tport_t *self)
|
|||
|
||||
N -= n, self->tp_ping += n;
|
||||
|
||||
tport_recv_bytes(self, n, n);
|
||||
|
||||
if (N == 0) {
|
||||
/* outbound-10 section 3.5.1 - send pong */
|
||||
if (self->tp_ping >= 4)
|
||||
|
@ -305,6 +307,8 @@ int tport_recv_stream(tport_t *self)
|
|||
|
||||
assert(n <= N);
|
||||
|
||||
tport_recv_bytes(self, n, n);
|
||||
|
||||
/* Check if message contains only whitespace */
|
||||
/* This can happen if multiple PINGs are received at once */
|
||||
if (initial) {
|
||||
|
|
|
@ -46,6 +46,7 @@
|
|||
#include <errno.h>
|
||||
#include <limits.h>
|
||||
#include <string.h>
|
||||
#include <sofia-sip/string0.h>
|
||||
|
||||
/* ---------------------------------------------------------------------- */
|
||||
/* TLS */
|
||||
|
|
|
@ -293,6 +293,8 @@ int tport_recv_dgram(tport_t *self)
|
|||
return 0;
|
||||
}
|
||||
|
||||
tport_recv_bytes(self, n, n);
|
||||
|
||||
SU_CANONIZE_SOCKADDR(from);
|
||||
|
||||
if (self->tp_master->mr_dump_file)
|
||||
|
|
|
@ -204,7 +204,7 @@ SOFIAPUBFUN char *url_unescape(char *d, char const *s);
|
|||
* @endcode
|
||||
*/
|
||||
#define URL_INIT_AS(type) \
|
||||
{ { 0 }, url_##type, 0, url_##type != url_any ? #type : "*" }
|
||||
{ "\0", url_##type, 0, url_##type != url_any ? #type : "*" }
|
||||
|
||||
/** Init a url structure as given type */
|
||||
SOFIAPUBFUN void url_init(url_t *url, enum url_type_e type);
|
||||
|
|
|
@ -802,8 +802,8 @@ int url_d(url_t *url, char *s)
|
|||
if (s && !url_canonize(s, s, SIZE_MAX,
|
||||
/* Allow all URI characters but ? */
|
||||
/* Allow unescaped /;?@, - but do not convert */
|
||||
(unsigned)(SYN33('/') | SYN33(';') | SYN33('=') | SYN33('@') |
|
||||
SYN33(',')),
|
||||
SYN33('/') | SYN33(';') | SYN33('=') | SYN33('@') |
|
||||
SYN33(','),
|
||||
/* Convert escaped :&+$ to unescaped */
|
||||
":&+$"))
|
||||
return -1;
|
||||
|
@ -812,7 +812,7 @@ int url_d(url_t *url, char *s)
|
|||
if (s && !url_canonize(s, s, SIZE_MAX,
|
||||
/* Allow all URI characters but ? */
|
||||
/* Allow unescaped ;=@, - but do not convert */
|
||||
(unsigned)(SYN33(';') | SYN33('=') | SYN33('@') | SYN33(',')),
|
||||
SYN33(';') | SYN33('=') | SYN33('@') | SYN33(','),
|
||||
/* Convert escaped /:&+$ to unescaped */
|
||||
"/:&+$"))
|
||||
return -1;
|
||||
|
|
|
@ -1,6 +1,9 @@
|
|||
# common Makefile targets for libsofia-sip-ua(-glib) modules
|
||||
# ----------------------------------------------------------
|
||||
|
||||
sofiasrcdir = ${top_srcdir}/libsofia-sip-ua
|
||||
sofiabuilddir = ${top_builddir}/libsofia-sip-ua
|
||||
|
||||
AM_CFLAGS = $(CWFLAG) $(SOFIA_COVERAGE) $(SOFIA_CFLAGS) $(openssl_CFLAGS)
|
||||
|
||||
SOFIA_COVERAGE = $(COVERAGE_FLAGS)
|
||||
|
@ -19,7 +22,7 @@ clean-built-sources:
|
|||
|
||||
# rules for building tag files
|
||||
|
||||
TAG_AWK=$(top_srcdir)/libsofia-sip-ua/su/tag_dll.awk
|
||||
TAG_AWK=${sofiasrcdir}/su/tag_dll.awk
|
||||
|
||||
*_tag_ref.c: $(TAG_AWK)
|
||||
|
||||
|
@ -36,25 +39,25 @@ _tag.c_tag_ref.c:
|
|||
cd $(@D) && $(MAKE) $(@F)
|
||||
|
||||
INTERNAL_INCLUDES = \
|
||||
-I$(srcdir)/../features -I../features \
|
||||
-I$(srcdir)/../ipt -I../ipt \
|
||||
-I$(srcdir)/../iptsec -I../iptsec \
|
||||
-I$(srcdir)/../bnf -I../bnf \
|
||||
-I$(srcdir)/../http -I../http \
|
||||
-I$(srcdir)/../msg -I../msg \
|
||||
-I$(srcdir)/../nth -I../nth \
|
||||
-I$(srcdir)/../nta -I../nta \
|
||||
-I$(srcdir)/../nea -I../nea \
|
||||
-I$(srcdir)/../nua -I../nua \
|
||||
-I$(srcdir)/../soa -I../soa \
|
||||
-I$(srcdir)/../sdp -I../sdp \
|
||||
-I$(srcdir)/../sip -I../sip \
|
||||
-I$(srcdir)/../soa -I../soa \
|
||||
-I$(srcdir)/../sresolv -I../sresolv \
|
||||
-I$(srcdir)/../tport -I../tport \
|
||||
-I$(srcdir)/../stun -I../stun \
|
||||
-I$(srcdir)/../url -I../url \
|
||||
-I$(srcdir)/../su -I../su
|
||||
-I${sofiasrcdir}/features -I${sofiabuilddir}/features \
|
||||
-I${sofiasrcdir}/ipt -I${sofiabuilddir}/ipt \
|
||||
-I${sofiasrcdir}/iptsec -I${sofiabuilddir}/iptsec \
|
||||
-I${sofiasrcdir}/bnf -I${sofiabuilddir}/bnf \
|
||||
-I${sofiasrcdir}/http -I${sofiabuilddir}/http \
|
||||
-I${sofiasrcdir}/msg -I${sofiabuilddir}/msg \
|
||||
-I${sofiasrcdir}/nth -I${sofiabuilddir}/nth \
|
||||
-I${sofiasrcdir}/nta -I${sofiabuilddir}/nta \
|
||||
-I${sofiasrcdir}/nea -I${sofiabuilddir}/nea \
|
||||
-I${sofiasrcdir}/nua -I${sofiabuilddir}/nua \
|
||||
-I${sofiasrcdir}/soa -I${sofiabuilddir}/soa \
|
||||
-I${sofiasrcdir}/sdp -I${sofiabuilddir}/sdp \
|
||||
-I${sofiasrcdir}/sip -I${sofiabuilddir}/sip \
|
||||
-I${sofiasrcdir}/soa -I${sofiabuilddir}/soa \
|
||||
-I${sofiasrcdir}/sresolv -I${sofiabuilddir}/sresolv \
|
||||
-I${sofiasrcdir}/tport -I${sofiabuilddir}/tport \
|
||||
-I${sofiasrcdir}/stun -I${sofiabuilddir}/stun \
|
||||
-I${sofiasrcdir}/url -I${sofiabuilddir}/url \
|
||||
-I${sofiasrcdir}/su -I${sofiabuilddir}/su
|
||||
|
||||
PHONY = built-sources clean-built-sources
|
||||
|
||||
|
@ -63,4 +66,3 @@ include $(top_srcdir)/rules/valcheck.am
|
|||
if HAVE_LCOV
|
||||
include $(top_srcdir)/rules/lcov.am
|
||||
endif
|
||||
|
||||
|
|
|
@ -0,0 +1,28 @@
|
|||
#
|
||||
# Tests using check
|
||||
#
|
||||
|
||||
EXTRA_DIST = check_nua.c
|
||||
|
||||
TESTS =
|
||||
check_PROGRAMS =
|
||||
|
||||
include $(top_srcdir)/rules/sofia.am
|
||||
|
||||
INCLUDES = ${INTERNAL_INCLUDES}
|
||||
|
||||
AM_CFLAGS += @CHECK_CFLAGS@
|
||||
|
||||
if HAVE_CHECK
|
||||
TESTS += check_sofia
|
||||
check_PROGRAMS += check_sofia
|
||||
|
||||
check_sofia_SOURCES = check_sofia.c check_sofia.h \
|
||||
suite_for_nua.c
|
||||
|
||||
check_sofia_LDADD = \
|
||||
${sofiabuilddir}/nua/libtestnua.la \
|
||||
${sofiabuilddir}/nua/libtestproxy.la \
|
||||
${sofiabuilddir}/nua/libtestnat.la \
|
||||
${sofiabuilddir}/libsofia-sip-ua.la @CHECK_LIBS@
|
||||
endif
|
|
@ -0,0 +1,62 @@
|
|||
/*
|
||||
* This file is part of the Sofia-SIP package
|
||||
*
|
||||
* Copyright (C) 2007 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_sofia.c
|
||||
*
|
||||
* @brief Check-driven tester for Sofia SIP User Agent library
|
||||
*
|
||||
* @author Pekka Pessi <Pekka.Pessi@nokia.com>
|
||||
*
|
||||
* @copyright (C) 2007 Nokia Corporation.
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include "check_sofia.h"
|
||||
|
||||
#include <stdlib.h>
|
||||
|
||||
/* Globals used by <sofia-sip/tstdef.h> */
|
||||
int tstflags;
|
||||
char const name[] = "check_sofia";
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
int failed = 0;
|
||||
|
||||
Suite *suite;
|
||||
SRunner *runner;
|
||||
|
||||
suite = suite_for_nua();
|
||||
runner = srunner_create(suite);
|
||||
|
||||
srunner_set_xml(runner, "/tmp/result.xml");
|
||||
srunner_run_all(runner, CK_NORMAL);
|
||||
|
||||
failed = srunner_ntests_failed(runner);
|
||||
srunner_free(runner);
|
||||
|
||||
exit(failed ? EXIT_FAILURE : EXIT_SUCCESS);
|
||||
}
|
||||
|
|
@ -0,0 +1,7 @@
|
|||
#ifndef CHECK_SOFIA_H
|
||||
|
||||
#include <check.h>
|
||||
Suite *suite_for_nua(void);
|
||||
|
||||
#endif
|
||||
|
|
@ -0,0 +1,188 @@
|
|||
/*
|
||||
* This file is part of the Sofia-SIP package
|
||||
*
|
||||
* Copyright (C) 2007 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_sofia.c
|
||||
*
|
||||
* @brief Check-driven tester for Sofia SIP User Agent library
|
||||
*
|
||||
* @author Pekka Pessi <Pekka.Pessi@nokia.com>
|
||||
*
|
||||
* @copyright (C) 2007 Nokia Corporation.
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include "test_nua.h"
|
||||
#include "check_sofia.h"
|
||||
|
||||
int print_headings = 0;
|
||||
struct context ctx[1] = {{{ SU_HOME_INIT(ctx) }}};
|
||||
|
||||
SOFIAPUBVAR su_log_t nua_log[];
|
||||
SOFIAPUBVAR su_log_t soa_log[];
|
||||
SOFIAPUBVAR su_log_t nea_log[];
|
||||
SOFIAPUBVAR su_log_t nta_log[];
|
||||
SOFIAPUBVAR su_log_t tport_log[];
|
||||
SOFIAPUBVAR su_log_t su_log_default[];
|
||||
|
||||
static void init_context(void)
|
||||
{
|
||||
int level = 1;
|
||||
|
||||
su_init();
|
||||
memset(ctx, 0, sizeof ctx);
|
||||
su_home_init(ctx->home);
|
||||
endpoint_init(ctx, &ctx->a, 'a');
|
||||
endpoint_init(ctx, &ctx->b, 'b');
|
||||
endpoint_init(ctx, &ctx->c, 'c');
|
||||
|
||||
su_log_soft_set_level(nua_log, level);
|
||||
su_log_soft_set_level(soa_log, level);
|
||||
su_log_soft_set_level(su_log_default, level);
|
||||
su_log_soft_set_level(nea_log, level);
|
||||
su_log_soft_set_level(nta_log, level);
|
||||
su_log_soft_set_level(tport_log, level);
|
||||
}
|
||||
|
||||
static void clean_context(void)
|
||||
{
|
||||
test_deinit(ctx);
|
||||
su_home_deinit(ctx->home);
|
||||
memset(ctx, 0, sizeof ctx);
|
||||
su_deinit();
|
||||
}
|
||||
|
||||
/* Each testcase is run in different process */
|
||||
|
||||
START_TEST(check_api) { fail_if(test_nua_api_errors(ctx)); } END_TEST
|
||||
START_TEST(check_tag_filter) { fail_if(test_tag_filter()); } END_TEST
|
||||
START_TEST(check_params) { fail_if(test_nua_params(ctx)); } END_TEST
|
||||
START_TEST(check_destroy) { fail_if(test_nua_destroy(ctx)); } END_TEST
|
||||
START_TEST(check_stack_errors) { fail_if(test_stack_errors(ctx)); } END_TEST
|
||||
|
||||
START_TEST(without_proxy)
|
||||
{
|
||||
fail_if(test_nua_init(ctx, 0, NULL, 0, TAG_END()));
|
||||
fail_if(test_register(ctx));
|
||||
fail_if(test_connectivity(ctx));
|
||||
fail_if(test_basic_call(ctx));
|
||||
fail_if(test_rejects(ctx));
|
||||
fail_if(test_call_cancel(ctx));
|
||||
fail_if(test_call_destroy(ctx));
|
||||
fail_if(test_early_bye(ctx));
|
||||
fail_if(test_offer_answer(ctx));
|
||||
fail_if(test_reinvites(ctx));
|
||||
fail_if(test_session_timer(ctx));
|
||||
fail_if(test_refer(ctx));
|
||||
fail_if(test_100rel(ctx));
|
||||
fail_if(test_simple(ctx));
|
||||
fail_if(test_events(ctx));
|
||||
fail_if(test_extension(ctx));
|
||||
fail_if(test_unregister(ctx));
|
||||
fail_if(test_deinit(ctx));
|
||||
}
|
||||
END_TEST
|
||||
|
||||
START_TEST(with_proxy)
|
||||
{
|
||||
fail_if(test_nua_init(ctx, 1, NULL, 0, TAG_END()));
|
||||
fail_if(test_register(ctx));
|
||||
fail_if(test_connectivity(ctx));
|
||||
fail_if(test_basic_call(ctx));
|
||||
fail_if(test_rejects(ctx));
|
||||
fail_if(test_call_cancel(ctx));
|
||||
fail_if(test_call_destroy(ctx));
|
||||
fail_if(test_early_bye(ctx));
|
||||
fail_if(test_offer_answer(ctx));
|
||||
fail_if(test_reinvites(ctx));
|
||||
fail_if(test_session_timer(ctx));
|
||||
fail_if(test_refer(ctx));
|
||||
fail_if(test_100rel(ctx));
|
||||
fail_if(test_simple(ctx));
|
||||
fail_if(test_events(ctx));
|
||||
fail_if(test_extension(ctx));
|
||||
fail_if(test_unregister(ctx));
|
||||
fail_if(test_deinit(ctx));
|
||||
}
|
||||
END_TEST
|
||||
|
||||
START_TEST(with_proxy_and_nat)
|
||||
{
|
||||
fail_if(test_nua_init(ctx, 1, NULL, 1, TAG_END()));
|
||||
fail_if(test_register(ctx));
|
||||
fail_if(test_connectivity(ctx));
|
||||
fail_if(test_nat_timeout(ctx));
|
||||
fail_if(test_basic_call(ctx));
|
||||
fail_if(test_rejects(ctx));
|
||||
fail_if(test_call_cancel(ctx));
|
||||
fail_if(test_call_destroy(ctx));
|
||||
fail_if(test_early_bye(ctx));
|
||||
fail_if(test_offer_answer(ctx));
|
||||
fail_if(test_reinvites(ctx));
|
||||
fail_if(test_session_timer(ctx));
|
||||
fail_if(test_refer(ctx));
|
||||
fail_if(test_100rel(ctx));
|
||||
fail_if(test_simple(ctx));
|
||||
fail_if(test_events(ctx));
|
||||
fail_if(test_extension(ctx));
|
||||
fail_if(test_unregister(ctx));
|
||||
fail_if(test_deinit(ctx));
|
||||
}
|
||||
END_TEST
|
||||
|
||||
Suite *suite_for_nua(void)
|
||||
{
|
||||
Suite *suite = suite_create("nua");
|
||||
TCase *tc;
|
||||
|
||||
tc = tcase_create("api");
|
||||
tcase_add_unchecked_fixture(tc, init_context, clean_context);
|
||||
tcase_add_test(tc, check_api);
|
||||
tcase_add_test(tc, check_tag_filter);
|
||||
tcase_add_test(tc, check_params);
|
||||
tcase_add_test(tc, check_destroy);
|
||||
tcase_add_test(tc, check_stack_errors);
|
||||
tcase_set_timeout(tc, 5);
|
||||
suite_add_tcase(suite, tc);
|
||||
|
||||
tc = tcase_create("without-proxy");
|
||||
tcase_add_unchecked_fixture(tc, init_context, clean_context);
|
||||
tcase_add_test(tc, without_proxy);
|
||||
tcase_set_timeout(tc, 60);
|
||||
suite_add_tcase(suite, tc);
|
||||
|
||||
tc = tcase_create("with-proxy");
|
||||
tcase_add_unchecked_fixture(tc, init_context, clean_context);
|
||||
tcase_add_test(tc, with_proxy);
|
||||
tcase_set_timeout(tc, 120);
|
||||
suite_add_tcase(suite, tc);
|
||||
|
||||
tc = tcase_create("with-proxy-and-nat");
|
||||
tcase_add_unchecked_fixture(tc, init_context, clean_context);
|
||||
tcase_add_test(tc, with_proxy_and_nat);
|
||||
tcase_set_timeout(tc, 120);
|
||||
suite_add_tcase(suite, tc);
|
||||
|
||||
return suite;
|
||||
}
|
|
@ -10,31 +10,9 @@
|
|||
# ----------------------------------------------------------------------
|
||||
# Header paths
|
||||
|
||||
sofiasrc=$(top_srcdir)/libsofia-sip-ua
|
||||
sofiabld=$(top_builddir)/libsofia-sip-ua
|
||||
include $(top_srcdir)/rules/sofia.am
|
||||
|
||||
INCLUDES = -I$(sofiasrc)/features -I$(sofiabld)/features \
|
||||
-I$(sofiasrc)/ipt -I$(sofiabld)/ipt \
|
||||
-I$(sofiasrc)/iptsec -I$(sofiabld)/iptsec \
|
||||
-I$(sofiasrc)/bnf -I$(sofiabld)/bnf \
|
||||
-I$(sofiasrc)/http -I$(sofiabld)/http \
|
||||
-I$(sofiasrc)/msg -I$(sofiabld)/msg \
|
||||
-I$(sofiasrc)/nth -I$(sofiabld)/nth \
|
||||
-I$(sofiasrc)/nta -I$(sofiabld)/nta \
|
||||
-I$(sofiasrc)/nea -I$(sofiabld)/nea \
|
||||
-I$(sofiasrc)/nua -I$(sofiabld)/nua \
|
||||
-I$(sofiasrc)/soa -I$(sofiabld)/soa \
|
||||
-I$(sofiasrc)/sdp -I$(sofiabld)/sdp \
|
||||
-I$(sofiasrc)/sip -I$(sofiabld)/sip \
|
||||
-I$(sofiasrc)/soa -I$(sofiabld)/soa \
|
||||
-I$(sofiasrc)/sresolv -I$(sofiabld)/sresolv \
|
||||
-I$(sofiasrc)/tport -I$(sofiabld)/tport \
|
||||
-I$(sofiasrc)/stun -I$(sofiabld)/stun \
|
||||
-I$(sofiasrc)/url -I$(sofiabld)/url \
|
||||
-I$(sofiasrc)/su -I$(sofiabld)/su
|
||||
|
||||
|
||||
AM_CFLAGS = $(SOFIA_CFLAGS)
|
||||
INCLUDES = ${INTERNAL_INCLUDES}
|
||||
|
||||
# ----------------------------------------------------------------------
|
||||
# Build targets
|
||||
|
|
Loading…
Reference in New Issue