Sync to current darcs tree:

Mon Sep 17 14:50:04 EDT 2007  Pekka.Pessi@nokia.com
  * sofia-sip/sip_util.h: updated documentation

Mon Sep 17 14:50:18 EDT 2007  Pekka.Pessi@nokia.com
  * sofia-sip/tport_tag.h: updated documentation

Mon Sep 17 14:50:28 EDT 2007  Pekka.Pessi@nokia.com
  * soa_tag.c: updated documentation

Wed Sep 19 12:50:01 EDT 2007  Pekka.Pessi@nokia.com
  * msg: updated documentation

Wed Sep 19 13:29:50 EDT 2007  Pekka.Pessi@nokia.com
  * url: updated documentation

Wed Sep 19 13:32:14 EDT 2007  Pekka.Pessi@nokia.com
  * nth: updated documentation

Wed Sep 19 13:32:27 EDT 2007  Pekka.Pessi@nokia.com
  * nea: updated documentation

Wed Sep 19 13:33:36 EDT 2007  Pekka.Pessi@nokia.com
  * http: updated documentation

Wed Sep 19 13:36:58 EDT 2007  Pekka.Pessi@nokia.com
  * bnf: updated documentation

Wed Sep 19 13:38:58 EDT 2007  Pekka.Pessi@nokia.com
  * nua: updated nua_stack_init_handle() prototype

Wed Sep 19 18:45:56 EDT 2007  Pekka.Pessi@nokia.com
  * sip: added sip_name_addr_xtra(), sip_name_addr_dup()

Wed Sep 19 19:00:19 EDT 2007  Pekka.Pessi@nokia.com
  * sip_basic.c: cleaned old crud

Thu Sep 20 13:34:04 EDT 2007  Pekka.Pessi@nokia.com
  * iptsec: updated documentation

Thu Sep 20 13:36:22 EDT 2007  Pekka.Pessi@nokia.com
  * tport: updated documentation

Thu Sep 20 13:36:56 EDT 2007  Pekka.Pessi@nokia.com
  * su: updated documentation
  Removed internal files from doxygen-generated documentation.

Thu Sep 20 13:38:29 EDT 2007  Pekka.Pessi@nokia.com
  * soa: fixed documentation

Thu Sep 20 13:39:56 EDT 2007  Pekka.Pessi@nokia.com
  * sdp: updated documentation

Thu Sep 20 13:40:16 EDT 2007  Pekka.Pessi@nokia.com
  * ipt: updated documentation

Thu Sep 20 14:24:20 EDT 2007  Pekka.Pessi@nokia.com
  * nta: updated documentation

Thu Sep 20 14:41:04 EDT 2007  Pekka.Pessi@nokia.com
  * nua: updated documentation

  Updated tag documentation.

  Moved doxygen doc entries from sofia-sip/nua_tag.h to nua_tag.c.

  Removed internal datatypes and files from the generated documents.

Wed Sep 19 13:34:20 EDT 2007  Pekka.Pessi@nokia.com
  * docs: updated the generation of documentation. Updated links to header files.

Thu Sep 20 08:45:32 EDT 2007  Pekka.Pessi@nokia.com
  * sip/Makefile.am: added tags to <sofia-sip/sip_extra.h>

  Added check for extra tags in torture_sip.c.

Thu Sep 20 14:45:22 EDT 2007  Pekka.Pessi@nokia.com
  * stun: updated documentation

Wed Jul  4 18:55:20 EDT 2007  Pekka.Pessi@nokia.com
  * torture_heap.c: added tests for ##sort() and su_smoothsort()

Wed Jul  4 18:56:59 EDT 2007  Pekka.Pessi@nokia.com
  * Makefile.am: added smoothsort.c

Fri Jul 13 12:38:44 EDT 2007  Pekka.Pessi@nokia.com
  * sofia-sip/heap.h: heap_remove() now set()s index to 0 on removed item

Mon Jul 23 11:14:22 EDT 2007  Pekka.Pessi@nokia.com
  * sofia-sip/heap.h: fixed bug in heap##remove()

  If left kid was in heap but right was not, left kid was ignored.

Wed Jul  4 18:51:08 EDT 2007  Pekka.Pessi@nokia.com
  * smoothsort.c: added

Wed Jul  4 18:51:34 EDT 2007  Pekka.Pessi@nokia.com
  * heap.h: using su_smoothsort()

Fri Jul  6 10:20:27 EDT 2007  Pekka.Pessi@nokia.com
  * smoothsort.c: added

Wed Sep 19 17:40:30 EDT 2007  Pekka.Pessi@nokia.com
  * msg_parser.awk: generate two parser tables, default and extended

Wed Sep 19 18:39:45 EDT 2007  Pekka.Pessi@nokia.com
  * msg_parser.awk: just generate list of extra headers

  Allocate extended parser dynamically.

Wed Sep 19 18:59:59 EDT 2007  Pekka.Pessi@nokia.com
  * sip: added Remote-Party-ID, P-Asserted-Identity, P-Preferred-Identity

  Added functions sip_update_default_mclass() and sip_extend_mclass()
  for handling the extended parser. Note that Reply-To and Alert-Info are only
  available with the extended parser.

Wed Sep 19 19:05:44 EDT 2007  Pekka.Pessi@nokia.com
  * RELEASE: updated

Thu Sep 20 13:38:59 EDT 2007  Pekka.Pessi@nokia.com
  * sip: updated documentation

Thu Sep 20 14:17:28 EDT 2007  Pekka.Pessi@nokia.com
  * docs/conformance.docs: updated

Mon Oct  1 10:11:14 EDT 2007  Pekka.Pessi@nokia.com
  * tport_tag.c: re-enabled tptag_trusted

Thu Oct  4 09:21:07 EDT 2007  Pekka.Pessi@nokia.com
  * su_osx_runloop.c: moved virtual function table after struct definition

  Preparing for su_port_vtable_t refactoring.

Thu Oct  4 10:22:03 EDT 2007  Pekka.Pessi@nokia.com
  * su_source.c: refactored initialization/deinitialization

Fri Oct  5 04:58:18 EDT 2007  Pekka Pessi <Pekka.Pessi@nokia.com>
  * sip_extra.c: fixed prototypes with isize_t

Fri Oct  5 04:58:45 EDT 2007  Pekka Pessi <Pekka.Pessi@nokia.com>
  * test_nta_api.c: removed warnings about signedness

Fri Oct  5 04:59:02 EDT 2007  Pekka Pessi <Pekka.Pessi@nokia.com>
  * test_nua_params.c: removed warnings about constness

Fri Oct  5 07:20:26 EDT 2007  Pekka Pessi <first.lastname@nokia.com>
  * su_port.h, su_root.c: cleaned argument checking

  The su_root_*() and su_port_*() functions now check their arguments once
  and do not assert() with NULL arguments. The sur_task->sut_port should
  always be valid while su_root_t is alive.

Fri Oct  5 07:22:09 EDT 2007  Pekka Pessi <first.lastname@nokia.com>
  * su: added su_root_obtain(), su_root_release() and su_root_has_thread()

  When root is created with su_root_create() or cloned with su_clone_start(),
  the resulting root is obtained by the calling or created thread,
  respectively.

  The root can be released with su_root_release() and another thread can
  obtain it.

  The function su_root_has_thread() can be used to check if a thread has
  obtained or released the root.

  Implementation upgraded the su_port_own_thread() method as su_port_thread().

Fri Oct  5 07:28:10 EDT 2007  Pekka Pessi <first.lastname@nokia.com>
  * su_port.h: removed su_port_threadsafe() and su_port_yield() methods

  su_port_wait_events() replaces su_port_yield().

Fri Oct  5 13:26:04 EDT 2007  Pekka Pessi <Pekka.Pessi@nokia.com>
  * msg_parser.awk: not extending header structure unless needed.

  Removed gawk-ish /* comments */.

Fri Oct  5 14:32:25 EDT 2007  Pekka Pessi <Pekka.Pessi@nokia.com>
  * run_test_su: removed GNUisms

Fri Oct  5 14:32:47 EDT 2007  Pekka Pessi <Pekka.Pessi@nokia.com>
  * Makefile.am: removed implicit check target test_urlmap

Fri Oct  5 14:22:32 EDT 2007  Pekka Pessi <first.lastname@nokia.com>
  * torture_sresolv.c: use CLOCK_REALTIME if no CLOCK_PROCESS_CPUTIME_ID available

  Casting timespec tv_sec to unsigned long.

Fri Oct * nua_s added handling nua_prack()

  Thanks to Fabio Margarido for the patch.

Mon Oct  8 10:24:35 EDT 2007  Pekka.Pessi@nokia.com
  * test_nua: added test for sf.net bug #1803686

Mon Oct  8 08:15:23 EDT 2007  Pekka.Pessi@nokia.com
  * RELEASE: updated.

Mon Oct  8 09:30:36 EDT 2007  Pekka.Pessi@nokia.com
  * nua_stack: added handling nua_prack()

  Thanks to Fabio Margarido for the patch.

Mon Oct  8 10:24:35 EDT 2007  Pekka.Pessi@nokia.com
  * test_nua: added test for sf.net bug #1803686

Mon Oct  8 10:26:31 EDT 2007  Pekka.Pessi@nokia.com
  * nua: added test for nua_prack() (sf.net bug #1804248)

  Avoid sending nua_i_state after nua_prack() if no SDP O/A is happening, too.

Mon Oct  8 10:32:04 EDT 2007  Mikhail Zabaluev <mikhail.zabaluev@nokia.com>
  * su_source.c: don t leak the wait arrays

Mon Oct  8 10:37:11 EDT 2007  Pekka.Pessi@nokia.com
  * RELEASE: updated

Wed Oct 10 11:55:21 EDT 2007  Pekka.Pessi@nokia.com
  * sip_parser.c: silenced warning about extra const in sip_extend_mclass()

Wed Oct 10 11:57:08 EDT 2007  Pekka.Pessi@nokia.com
  * nta_tag.c: updated tag documentation

Wed Oct 10 13:16:40 EDT 2007  Pekka.Pessi@nokia.com
  * nua: fix logging crash if outbound used with application contact

  Silenced warnings.

Wed Oct 10 13:30:45 EDT 2007  Pekka.Pessi@nokia.com
  * msg_parser.awk: removed extra "const"

Wed Oct 10 13:31:45 EDT 2007  Pekka.Pessi@nokia.com
  * Makefile.am's: fixed distclean of documentation



git-svn-id: http://svn.freeswitch.org/svn/freeswitch/trunk@5840 d0543943-73ff-0310-b7d9-9358b9ac24b2
This commit is contained in:
Michael Jerris 2007-10-11 14:16:59 +00:00
parent 24ff890bbb
commit 5e81b98eba
153 changed files with 7633 additions and 4401 deletions

View File

@ -4,42 +4,73 @@ Release notes for current version of Sofia-SIP
Changes since last release
--------------------------
<changes since last written in freshmeat.net "Changes:" style;
and in less than 10 lines, written in 3rd person English, with
complete sentences />
The stack now compiles and runs on Symbian SDK with Open C support
enabled.
Bugs in blaa and foo have been fixed. The stack now supports
use of foobar...
The stacksupports specifying the outbound proxy by a set of Route
headers as recommended by RFC3261. It also supports CR-LF-based keepalives
on TCP connections.
Bugs in call state machines, URI and SDP handling has been fixed.
API/ABI changes and versioning
------------------------------
<see previous release notes at
http://sofia-sip.sourceforge.net/relnotes/ for examples ;
- should include all changes to public headers, and
other important information to developers;
- and should be updated _continuously_! />
New features in API are marked with Doxytag macro @VERSION_1_12_7.
New features in API are marked with Doxytag macro @VERSION_1_12_7 or
@NEW_1_12_7.
libsofia-sip-ua:
- Added access point selection functionality for Open C / Symbian
- Removed extra system headers from <sofia-sip/stun_common.h>
- Added global variable su_socket_blocking. If it is set to true,
sockets are created as blocking.
- Added accessor function nta_outgoing_branch()
- Added SIP headers Alert-Info and Reply-To.
- Added macros SIP_HAVE_XXXX for extra headers, e.g., SIP_HAVE_ALERT_INFO().
- **template**: Added foobar() function (sofia-sip/foobar.h).
- This release is ABI/API compatible with applications linked against
any 1.12.x release. However, applications built against this release won't
work against an older library. The ABI has been tested with the nua module
unit test (test_nua) built against original 1.12.0 release.
libsofia-sip-ua/nua:
- Added tag NUTAG_INITIAL_ROUTE(), NUTAG_INITIAL_ROUTE_STR()
libsofia-sip-ua/nta:
- Added nta_incoming_received()
- Added accessor function nta_outgoing_branch()
- Added tag NTATAG_TIMER_C()
- Deprecated nta_msg_ackbye()
libsofia-sip-ua/iptsec:
- Added tag AUTHTAG_MAX_NCOUNT()
libsofia-sip-ua/sip:
- Added SIPEXTHDRTAG_TYPEDEF() macro and tag class sipexthdrtag_class[]
- Added SIP headers Alert-Info and Reply-To. Remote-Party-ID,
P-Asserted-Identity, P-Preferred-Identity
- Added sip_update_default_mclass() and sip_extend_mclass()
- Added macros SIP_HAVE_XXXX for extra headers, e.g., SIP_HAVE_ALERT_INFO().
libsofia-sip-ua/soa:
- Added tags SOATAG_ORDERED_USER() and SOATAG_REUSE_REJECTED()
libsofia-sip-ua/tport:
- Updated transport timers
- Added TPTAG_KEEPALIVE(), TPTAG_PINGPONG(), TPTAG_PONG2PING()
- Added tport_is_clear_to_send(), tport_has_queued()
- Updated timer handling
- Added abstract type su_timer_queue_t (typedef'd to SU_TIMER_QUEUE_T)
- Updated su_task_timers() and su_timer_expire() prototypes
libsofia-sip-ua/stun:
- Removed extra system headers from <sofia-sip/stun_common.h>
libsofia-sip-ua/su:
- Added su_nanotime_t and functions su_nanotime()/su_monotime()
- Added function su_getsocktype()
- Added heap template in <sofia-sip/heap.h>
- Added configure option --disable-tag-cast and macro SU_INLINE_TAG_CAST
- Added global variable su_socket_blocking. If it is set to true,
sockets are created as blocking.
- Added access point selection functionality for Open C / Symbian
- Added functions su_root_release(), su_root_obtain() and
su_root_has_thread(). A thread can release a su_root_t and another one can
obtain it.
libsofia-sip-ua-glib:
- No ABI/API changes, compatible with 1.12.0. Note, libsofia-sip-ua-glib
interface is not considered stable and may change in a future 1.12.x
@ -48,28 +79,21 @@ libsofia-sip-ua-glib:
Contributors to this release
----------------------------
<list of people who contributed to _this_ release
- update as people's patches are added, or when you commit stuff
- current development team members (see AUTHORS) may be omitted,
or listed at the end of the contribur list (depending on the scope
of the work done since the last release)
- name of the contributor should be enough (email addresses in AUTHORS),
plus a _brief_ description of what was contributed
- roughly sorted by number of patches accepted
/>
- Mikhail Zabaluev (bug fixes)
- Fabio Margarido (bug fixes)
- Martti Mela (Open C port and extra functionality, bug fixes)
- Kai Vehmanen (fixes to win32 VC6/2005 project files)
- Pekka Pessi (everything else)
See the AUTHORS file in the distribution package.
Notes on new features
---------------------
<information about major new features
- new/changed/removed functionality
- links to further documentation
- section may be omitted for minor releases
/>
The route to the outbound proxy can now be specified as an explicit route
set.
The TCP transport can use CR-LF keepalive and CR-LF PING-PONG messages.
IPv6 support can now be disabled in VC6/VC2005 builds, by
setting SU_HAVE_IN6 to zero `win32/sofia-sip/su_configure.h'.
@ -78,14 +102,53 @@ Symbian Open C build and packaging (SIS) files for libsofia-sip-ua,
libsofia-sip-ua-glib and for several test apps have been added under
sofia-sip/open_c.
New SIP headers are not available by default. Application must enable them
with sip_update_default_mclass() and sip_extend_mclass().
Bugs fixed in this release
--------------------------
< notable bugs fixed in this release
- check the sf.net bug tracker; see closed bugs,
sorted by closing date
- other bugs as fixed in CVS/darcs
/>
- Fixed #1472682 sf.net bug: ACK does not find INVITE when
To URI has been changed.
- Fixed sf.net bug #1804248: nua_prack() now works.
Thanks to Fabio Margarido for sending the patch.
- Fixed sf.net bug 1803686: nua_destroy() can now be called from inside
nua event callback.
Thanks to Mikhail Zabaluev for reporting the problem.
- SIP Content-Length structure was casted to one with 64-bit integer instead
of 32-bit, so message body was not parsed on 64-bit big-endian platform.
Thanks to Martin Drasar for hunting down the bug.
- Authentication scheme token was compared as case-sensitive on client side.
Thanks to Russell McConnachie for reporting this problem.
- Fixed sf.net bug #1706629: in-dialog requests not routed according to the
dialog route. Problem was because the outbound proxy was not handles as
RECOMMENDED by RFC 3261. The new tag NUTAG_INITIAL_ROUTE() allows correct
handling of requests.
- Fixed problems in nua state engines (call setup failing if some messages
were re-ordered or crashing when they were lost)
Thanks to Michail Jerris, Anthony Minessale, and others in Freeswitch
project for hunting down these bugs and reporting them
- When nua generates Contact URI, the user-specified URI parameters are now
overriden by actual transport parameters (e.g., transport=tcp)
Thanks to Mikhail Zabaluev for submitting the patch.
- Fixed sf.net bug #1750691: used to send ACK&BYE when extra 200 OK is
received and the 200 OK did not match any client transaction.
Thanks to Mikhail Zabaluev for reporting the problem.
- Fixed problem of un-escaping reserved characters in URIs
Thanks to Jan van den Bosch, Fabio Margarido and Mikhail Zabaluev for
reporting the problem.
- Fixed missing links in doxygen-generated documentation
Thanks to Jerry Richards for reporting this problem.
- Fixed timing problem with CANCELed INVITE transactions.
Thanks to Fabio Margarido for reporting this problem.
- Fixed sf.net bug #1771243: tport_check_trunc() does not block anymore
Thanks to Erland Lwin for reporting the problem
- Fixed sf.net bug #1733323: extra tag arguments were used by
nta_outgoing_tcancel().
Thanks to Fabio Margarido for reporting this problem.
- Fixed sf.net bug #1747149: sdp_session_cmp() ignored some m= lines
(e.g., new SDP in re-INVITE was sometimes ignored)
Thanks to Mikhail Zabaluev for reporting the problem.
- Fixed sf.net bug #1726034: crash in msg_as_string() with too large messages
- Fixed sf.net bug #1472682: ACK did not find INVITE server transaction when
the To URI had been changed.
- Do not block when making a TCP connect()ion in tport.
Thanks to Mikhail Zabaluev for submitting the patch.

View File

@ -51,3 +51,8 @@ include $(top_srcdir)/rules/lcov.am
endif
.PHONY = $(PHONY)
CLEANFILES = docs/*.doxytags
distclean-local:
-rm -rf docs/html

View File

@ -88,6 +88,9 @@ GSourceFuncs su_source_funcs[1] = {{
NULL
}};
static int su_source_port_init(su_port_t *self, su_port_vtable_t const *vtable);
static void su_source_port_deinit(su_port_t *self);
static void su_source_lock(su_port_t *self, char const *who);
static void su_source_unlock(su_port_t *self, char const *who);
static void su_source_incref(su_port_t *self, char const *who);
@ -115,7 +118,7 @@ static int su_source_eventmask(su_port_t *self,
static void su_source_run(su_port_t *self);
static void su_source_break(su_port_t *self);
static su_duration_t su_source_step(su_port_t *self, su_duration_t tout);
static int su_source_own_thread(su_port_t const *port);
static int su_source_thread(su_port_t *self, enum su_port_thread_op op);
static int su_source_add_prepoll(su_port_t *port,
su_root_t *root,
su_prepoll_f *,
@ -147,13 +150,11 @@ su_port_vtable_t const su_source_port_vtable[1] =
su_source_run,
su_source_break,
su_source_step,
su_source_own_thread,
su_source_thread,
su_source_add_prepoll,
su_source_remove_prepoll,
su_base_port_timers,
su_source_multishot,
su_base_port_threadsafe,
/*su_source_yield*/ NULL,
/*su_source_wait_events*/ NULL,
su_base_port_getmsgs,
su_base_port_getmsgs_from,
@ -177,6 +178,8 @@ struct su_source_s {
su_base_port_t sup_base[1];
GThread *sup_tid;
GStaticMutex sup_obtained[1];
GStaticMutex sup_mutex[1];
GSource *sup_source; /**< Backpointer to source */
@ -258,37 +261,51 @@ GSource *su_glib_root_gsource(su_root_t *root)
/*=============== Private function definitions ===============*/
/** Initialize source port */
int su_source_port_init(su_port_t *self,
GSource *gs,
su_port_vtable_t const *vtable)
static int su_source_port_init(su_port_t *self,
su_port_vtable_t const *vtable)
{
if (su_base_port_init(self, vtable) < 0)
return -1;
GSource *gs = (GSource *)((char *)self - offsetof(SuSource, ss_port));
self->sup_source = gs;
self->sup_tid = g_thread_self();
g_static_mutex_init(self->sup_obtained);
g_static_mutex_init(self->sup_mutex);
return 0;
return su_base_port_init(self, vtable);
}
static void su_source_port_deinit(su_port_t *self)
{
su_base_port_deinit(self);
g_static_mutex_free(self->sup_mutex);
g_static_mutex_free(self->sup_obtained);
if (self->sup_indices)
free (self->sup_indices), self->sup_indices = NULL;
if (self->sup_waits)
free (self->sup_waits), self->sup_waits = NULL;
if (self->sup_wait_cbs)
free (self->sup_wait_cbs), self->sup_wait_cbs = NULL;
if (self->sup_wait_args)
free (self->sup_wait_args), self->sup_wait_args = NULL;
if (self->sup_wait_roots)
free (self->sup_wait_roots), self->sup_wait_roots = NULL;
su_home_deinit(self->sup_base->sup_home);
}
/** @internal Destroy a port. */
static
void su_source_finalize(GSource *gs)
{
SuSource *ss = (SuSource *)gs;
su_port_t *self = ss->ss_port;
assert(gs);
SU_DEBUG_9(("su_source_finalize() called\n"));
g_static_mutex_free(self->sup_mutex);
su_base_port_deinit(self);
su_home_deinit(self->sup_base->sup_home);
su_source_port_deinit(ss->ss_port);
}
void su_source_port_lock(su_port_t *self, char const *who)
@ -330,16 +347,46 @@ int su_source_send(su_port_t *self, su_msg_r rmsg)
}
/** @internal
* Checks if the calling thread owns the port object.
*
* Change or query ownership of the port object.
*
* @param self pointer to a port object
* @param op operation
*
* @retval true (nonzero) if the calling thread owns the port,
* @retval false (zero) otherwise.
* @ERRORS
* @ERROR EALREADY port already has an owner (or has no owner)
*/
int su_source_own_thread(su_port_t const *self)
static int su_source_thread(su_port_t *self, enum su_port_thread_op op)
{
return self == NULL || SU_SOURCE_OWN_THREAD(self);
GThread *me = g_thread_self();
switch (op) {
case su_port_thread_op_is_obtained:
if (self->sup_tid == me)
return 2;
else if (self->sup_tid)
return 1;
else
return 0;
case su_port_thread_op_release:
if (self->sup_tid != me)
return errno = EALREADY, -1;
self->sup_tid = NULL;
g_static_mutex_unlock(self->sup_obtained);
return 0;
case su_port_thread_op_obtain:
if (su_home_threadsafe(su_port_home(self)) == -1)
return -1;
g_static_mutex_lock(self->sup_obtained);
self->sup_tid = me;
return 0;
default:
return errno = ENOSYS, -1;
}
}
/* -- Registering and unregistering ------------------------------------- */
@ -1044,7 +1091,7 @@ static su_port_t *su_source_port_create(void)
if (ss) {
self = ss->ss_port;
if (su_source_port_init(self, ss->ss_source, su_source_port_vtable) < 0)
if (su_source_port_init(self, su_source_port_vtable) < 0)
g_source_unref(ss->ss_source), self = NULL;
} else {
su_perror("su_source_port_create(): g_source_new");

View File

@ -6,8 +6,10 @@
*
* The Sofia @b bnf module contains macros and functions for parsing
* text-based formats, for example, for SIP. The interface is described in
* <bnf.h>, the <bnf.c> contains a #_bnf_table table used to classify
* characters.
* <sofia-sip/bnf.h>.
*
* The interface used for validating hostnames and IP addresses is in
* <sofia-sip/hostdomain.h>.
*
* @CONTACT Pekka Pessi <Pekka.Pessi@nokia.com>
*

View File

@ -28,7 +28,7 @@ ALIASES = \
"TAG=\par \n" \
"EVENTS=\par Events:\n" \
"RESPONSES=\par Related Response Codes:\n" \
"CFILE=\file" \
"CFILE=\internal \file" \
"IFILE=\file" \
"HI=\hideinitializer " \
"HIDE=\hideinitializer " \

View File

@ -23,6 +23,7 @@ COLLABORATION_GRAPH = YES
GROUP_GRAPHS = NO
EXTRACT_ALL = NO
EXTRACT_PRIVATE = NO
VERBATIM_HEADERS = YES
HIDE_UNDOC_RELATIONS = YES
HIDE_UNDOC_MEMBERS = YES
HIDE_UNDOC_CLASSES = YES

View File

@ -7,6 +7,7 @@ INPUT = @srcdir@/mainpage.docs @srcdir@/docguide.docs @srcdir@/conformanc
@INCLUDE_PATH = . @srcdir@
@INCLUDE = ../docs/Doxyfile.conf
@INCLUDE = ../sip/sip.doxyaliases
GENERATE_TAGFILE = docs.doxytags
@ -28,4 +29,6 @@ TAGFILES += nea.doxytags=nea
TAGFILES += nua.doxytags=nua
TAGFILES += features.doxytags=features
EXAMPLE_PATH = @srcdir@/../sip

View File

@ -40,7 +40,10 @@ Doxyfile.rfc:
from=700 to=4800 \
/dev/null > $@
CLEANFILES = Doxyfile.rfc
CLEANFILES = Doxyfile.rfc *.doxytags
distclean-local:
-rm -rf html
# ----------------------------------------------------------------------
# Sofia specific rules

View File

@ -20,32 +20,37 @@ below.
<a href="#3313">RFC 3313</a> <br>
<a href="#3323">RFC 3323</a> <br>
<a href="#3326">RFC 3326</a> <br>
</td><td>
<a href="#3325">RFC 3325</a> <br>
<a href="#3327">RFC 3327</a> <br>
</td><td>
<a href="#3329">RFC 3329</a> <br>
<a href="#3361">RFC 3361</a> <br>
<a href="#3420">RFC 3420</a> <br>
<a href="#3428">RFC 3428</a> <br>
<a href="#3486">RFC 3486</a> <br>
<a href="#3515">RFC 3515</a> <br>
<a href="#3581">RFC 3581</a> <br>
<a href="#3608">RFC 3608</a> <br>
<a href="#3680">RFC 3680</a> <br>
<a href="#3824">RFC 3824</a> <br>
</td><td>
<a href="#3840">RFC 3840</a> <br>
<a href="#3841">RFC 3841</a> <br>
<a href="#3842">RFC 3842</a> <br>
</td><td>
<a href="#3856">RFC 3856</a> <br>
<a href="#3857">RFC 3857</a> <br>
<a href="#3858">RFC 3858</a> <br>
<a href="#3859">RFC 3859</a> <br>
<a href="#3860">RFC 3860</a> <br>
<a href="#3891">RFC 3891</a> <br>
<a href="#3892">RFC 3892</a> <br>
<a href="#3903">RFC 3903</a> <br>
<a href="#4028">RFC 4028</a> <br>
<a href="#4168">RFC 4168</a> <br>
<a href="#4320">RFC 4320</a> <br>
<a href="#4566">RFC 4566</a> <br>
<a href="#4488">RFC 4488</a> <br>
</td><td>
<a href="#4566">RFC 4566</a> <br>
<a href="#2327">RFC 2327</a> <br>
<a href="#3264">RFC 3264</a> <br>
<a href="#3266">RFC 3266</a> <br>
@ -53,6 +58,7 @@ below.
<a href="#3388">RFC 3388</a> <br>
<a href="#3407">RFC 3407</a> <br>
<a href="#3524">RFC 3524</a> <br>
<a href="#3551">RFC 3551</a> <br>
<a href="#3556">RFC 3556</a> <br>
<a href="#3605">RFC 3605</a> <br>
<a href="#3890">RFC 3890</a> <br>
@ -98,7 +104,7 @@ below.
</td>
<td>
The supported @RFC3261 methods are: @b REGISTER, @b OPTIONS, @b
INVITE, @b ACK, @b CANCEL, @b BYE, as well as methods
INVITE, @b ACK, @b CANCEL, @b BYE, as well as extension methods
<a href="#2976"><b>INFO</b></a>,
<a href="#3262"><b>PRACK</b></a>,
<a href="#3265"><b>SUBSCRIBE</b></a>,
@ -116,7 +122,7 @@ below.
@ref sip_accept "Accept",
@ref sip_accept_encoding "Accept-Encoding",
@ref sip_accept_language "Accept-Language",
@ref sip_alert_info "Alert-Info" (@VERSION_1_12_7),
@ref sip_alert_info "Alert-Info" (extension in @VERSION_1_12_7),
@ref sip_allow "Allow",
@ref sip_authentication_info "Authentication-Info",
@ref sip_authorization "Authorization",
@ -138,12 +144,18 @@ below.
@ref sip_min_expires "Min-Expires",
@ref sip_mime_version "MIME-Version",
@ref sip_organization "Organization",
@ref sip_p_asserted_identity "P-Asserted-Identity"
(extension in @VERSION_1_12_7),
@ref sip_p_preferred_identity "P-Preferred-Identity"
(extension in @VERSION_1_12_7),
@ref sip_priority "Priority",
@ref sip_proxy_authenticate "Proxy-Authenticate",
@ref sip_proxy_authorization "Proxy-Authorization",
@ref sip_proxy_require "Proxy-Require",
@ref sip_record_route "Record-Route",
@ref sip_reply_to "Reply-To" (@VERSION_1_12_7),
@ref sip_refer_sub "Refer-Sub" (@VERSION_1_12_5),
@ref sip_remote_party_id "Remote-Party-ID" (extension in @VERSION_1_12_7),
@ref sip_reply_to "Reply-To" (extension in @VERSION_1_12_7),
@ref sip_require "Require",
@ref sip_retry_after "Retry-After",
@ref sip_route "Route",
@ -167,7 +179,7 @@ below.
<td>
- Automatic escaping of reserved characters has not been
implemented.
- Using NUL (zero byte) in doublequoted strings has not been implemented
- Using NUL (zero byte) in double-quoted strings has not been implemented
</td>
</tr>
@ -196,7 +208,7 @@ below.
Only one SIP message is accepted per UDP message, as per @RFC3261.
</td>
<td>
There is experimental support for SCTP, too.
There is <a href="#4168">experimental support for SCTP</a>, too.
</td>
</tr>
@ -212,8 +224,12 @@ below.
User-Agent and Proxy modes.
Default values for SIP timers are those specified by @RFC3261. The
defaults for T1, T1x64, T2 and T4 can be changed via
values for T1, T1x64, T2 and T4 can be changed via
configuration tags defined in <sofia-sip/nta_tag.h>.
The SIP timer C is implemented from @VERSION_1_12_7. Also, its value
can be changed via configuration tag NTATAG_TIMER_C() defined in
<sofia-sip/nta_tag.h>.
</td>
<td>
&nbsp;
@ -462,10 +478,13 @@ below.
@RFC3325: Asserted Identity
</th>
<td>
Sofia-SIP provides <a href="#3261.19">generic support</a> for
extension headers and parameters. P-Asserted-Identity and
P-Preferred-Identity are supported as supported as @ref
sip_unknown "extension headers".
Sofia-SIP supports
@ref sip_p_asserted_identity "P-Asserted-Identity" and
@ref sip_p_preferred_identity "P-Preferred-Identity" headers
(generating, parsing and syntax checking). Also the non-standard
header @ref sip_remote_party_id "Remote-Party-ID" is supported.
@NEW_1_12_7.
</td>
<td>
Not implemented:
@ -733,10 +752,11 @@ below.
</td>
</tr>
<a name="3856"></a>
<a name="3856"></a><a name="3859"></a>
<tr valign=top>
<th align="left">
@RFC3856: Presence
@RFC3856: Presence <br />
@RFC3859: Common Profile for Presence
</th>
<td>
Sofia-SIP supports <a href="#3265">generic SIP event support</a> for
@ -778,7 +798,22 @@ below.
- Including correct @ref sip_event "Event" and
@ref sip_accept "Accept" headers in the request (if needed)
- Processing notifications for winfo events:
- Processing watcherxinfo XML documents
- Processing watcherinfo XML documents
</td>
</tr>
<a name="3860"></a>
<tr valign=top>
<th align="left">
@RFC3860: Common Profile for IM
</th>
<td>
Sofia-SIP supports handling of any URI type. Sofia-SIP parses "im:"
URIs.
</td>
<td>
Application must take care of:
- resolving the "im:" URI
</td>
</tr>
@ -834,7 +869,7 @@ below.
<td>
Application must take care of:
- Including correct @ref sip_event "Event" in the request
- Permanently storing SIP-ETag
- Permanently storing @SIPETag
</td>
</tr>
@ -864,6 +899,26 @@ below.
</td>
</tr>
<a name="4168"></a>
<tr valign=top>
<th align="left">
@RFC4168: SCTP as Transport for SIP
</th>
<td>
The transport=sctp URI parameter is supported. The SCTP transport
protocol is supported as experimental. It is enabled with
configure script argument --enable-sctp.
The framing of SIP messages over SCTP is not specified clearly in
@RFC4168. It is possible to send SIP messages smaller than 64K over
SCTP.
</td>
<td>
&nbsp;
</td>
</tr>
<a name="4320"></a>
<tr valign=top>
<th align="left">
@ -886,6 +941,28 @@ below.
</td>
</tr>
<a name="4488"></a>
<tr valign=top>
<th align="left">
@RFC4488: Suppression of REFER Implicit Subscription
</th>
<td>
Sofia-SIP supports @ref sip_refer_sub "Refer-Sub" header
(generating, parsing and syntax checking).
The implicit subscription is suppressed by @nua, if the @ReferSub:
true header is included in the REFER
request (@ref nua_refer "on server side") or
response (@ref nua_i_refer "on client side").
@NEW_1_12_5
</td>
<td>
The REFER client application must include SIPTAG_REFER_SUB_STR("true")
in the nua_refer() tags.
</td>
</tr>
</table>
<table border=1 cellpadding=4 cellspacing=0>
@ -922,7 +999,7 @@ below.
"a=inactive", @ref sdp_rtpmap_s "a=rtpmap", and "a=fmtp" are parsed.
The implementation partially implements @RFC4566. Note that
definiton of 'token' was updated in @RFC4566 and the parser has not
definition of 'token' was updated in @RFC4566 and the parser has not
been updated yet.
</td>
<td>
@ -1023,6 +1100,23 @@ below.
</td>
</tr>
<a name="3551"></a>
<tr valign=top>
<th align="left">
@RFC3551: RTP/AVP
</th>
<td>
Sofia-SIP recognizes the RTP payload types for well-known audio and
video codecs defined in @RFC3551.
</td>
<td>
Application must take care of:
- Audio or video processing
- Generating a=rtpmap or a=fmtp lines when needed
</td>
</tr>
<a name="3556"></a>
<tr valign=top>
<th align="left">

View File

@ -260,7 +260,7 @@ C 99 standard defines the following fixed length data types:
- int8_t
- uint8_t
To use these data types you must include the <su_types.h> header, which
To use these data types you must include the <sofia-sip/su_types.h> header, which
takes care of including correct file. If @b su includes are not available,
you must include the following code segment to each file where you plan to
use them:
@ -298,7 +298,7 @@ network byte order to host byte order.
The ntohs() function converts the unsigned short integer netshort
from network byte order to host byte order.
You need to include <netinet/in.h> or <su.h> to use these functions.
You need to include <netinet/in.h> or <sofia-sip/su.h> to use these functions.
@subsection port_struct Packing structures
@ -467,7 +467,7 @@ reference. This simplifies application logic because application code does
not need to keep track of the allocated memory and free every allocated block
separately.
See documentation of <su_alloc.h> and @ref su_alloc "memory managment tutorial"
See documentation of <sofia-sip/su_alloc.h> and @ref su_alloc "memory managment tutorial"
for more information of memory management services.
@subsection contextdata Memory management of context data
@ -532,7 +532,7 @@ controlled by upper level memory management.
@section testing Testing Your Code
See <tstdef.h> for example of how to write module tests with macros provided
See <sofia-sip/tstdef.h> for example of how to write module tests with macros provided
by Sofia.
Here are some ideas of what you should test:

View File

@ -15,7 +15,7 @@
*
* @section http_overview Overview
*
* Each HTTP header has a structure defined for it in <http.h>. All the
* Each HTTP header has a structure defined for it in <sofia-sip/http.h>. All the
* variables, objects and functions related to a particular HTTP header are
* documented in a <a href="modules.html">submodule</a> for the header. In
* addition to the header structure, there is defined a @em header @em class

View File

@ -30,7 +30,7 @@
*
*/
/**@file http_tag.c HTTP Tag classes
/**@internal @file http_tag.c HTTP Tag classes
*
* This file is autogenerated from <http_tag.c.in>.
*

View File

@ -1,7 +1,9 @@
PROJECT_NAME = "ipt"
OUTPUT_DIRECTORY = ../docs/html/ips
OUTPUT_DIRECTORY = ../docs/html/ipt
INPUT = @srcdir@/ipt.docs @srcdir@/sofia-sip @srcdir@ .
INPUT = @srcdir@/ipt.docs
INPUT += @srcdir@/sofia-sip/base64.h @srcdir@/base64.c
INPUT += @srcdir@/sofia-sip/token64.h @srcdir@/token64.c
@INCLUDE_PATH = . @srcdir@
@INCLUDE = ../docs/Doxyfile.conf

View File

@ -15,6 +15,6 @@
* @section ipt_overview Overview
*
* This module contain some routines useful for IPT applications, like
* - <sofia-sip/base64.h> BASE64 encoding/decoding,
* - <sofia-sip/token64.h> encoding/decoding binary as SIP/HTTP token,
* - <sofia-sip/base64.h> BASE64 encoding/decoding, and
* - <sofia-sip/token64.h> encoding/decoding binary as SIP/HTTP token.
*/

View File

@ -57,7 +57,7 @@ SOFIAPUBFUN isize_t base64_e(char buf[], isize_t bsiz, void *data, isize_t dsiz)
/** Calculate size of n bytes encoded in base64 */
#define BASE64_SIZE(n) ((((n) + 2) / 3) * 4)
/** Calculate size of n bytes encoded in base64 sans trailing =. @NEW_1_12_5 */
/** Calculate size of n bytes encoded in base64 sans trailing =. @NEW_1_12_5. */
#define BASE64_MINSIZE(n) ((n * 4 + 2) / 3)
SOFIA_END_DECLS

View File

@ -22,7 +22,7 @@
*
*/
/**@CFILE token64.c
/**@internal @file token64.c
*
* Token encoding.
*
@ -41,7 +41,7 @@
static const char code[65] =
"0123456789-abcdefghijklmnopqrstuvwxyz_ABCDEFGHIJKLMNOPQRSTUVWXYZ";
/** Encode data as an http token.
/** Encode data as a SIP/HTTP token.
*
* @note
* A token is case-independent, so this is really not a good idea.

View File

@ -20,7 +20,7 @@ TAGFILES += ../docs/nta.doxytags=../nta
GENERATE_TAGFILE = ../docs/iptsec.doxytags
ALIASES +=
ALIASES += "iptsec=@ref index \"iptsec\""
PREDEFINED += SOFIA_EXTEND_AUTH_CLIENT=1

View File

@ -205,15 +205,17 @@ int ca_challenge(auth_client_t *ca,
* processed.
*
* @bug
* The result can be quite unexpected if there are more than one
* authenticator with the given type (specified by @a crcl). In principle,
* SIP allows more than one challenge for a single request.
* In principle, SIP allows more than one challenge for a single request.
* For example, there can be multiple proxies that each challenge the
* client. The result of storing authentication info can be quite unexpected
* if there are more than one authenticator with the given type (specified
* by @a credential_class).
*
* @retval number of challenges to updated
* @retval 0 when there was no challenge to update
* @retval -1 upon an error
*
* @NEW_1_12_5
* @NEW_1_12_5.
*/
int auc_info(auth_client_t **auc_list,
msg_auth_info_t const *info,
@ -525,7 +527,7 @@ int ca_clear_credentials(auth_client_t *ca)
* @retval 1 when authorization can proceed
* @retval 0 when there is not enough credentials
*
* @NEW_1_12_5
* @NEW_1_12_5.
*/
int auc_has_authorization(auth_client_t **auc_list)
{

View File

@ -22,7 +22,7 @@
*
*/
/**
/**@internal
* @file auth_module_http.c
* @brief Authenticate HTTP request
*

View File

@ -22,7 +22,7 @@
*
*/
/**
/**@internal
* @file auth_module_sip.c
* @brief Authenticate SIP request
*

View File

@ -22,7 +22,7 @@
*
*/
/**
/**@internal
* @file auth_plugin.c
* @brief Plugin interface for authentication verification modules.
*

View File

@ -22,7 +22,7 @@
*
*/
/**@file iptsec_debug.c
/**@internal @file iptsec_debug.c
* @brief Debug log for IPTSEC module.
*
* @author Pekka Pessi <Pekka.Pessi@nokia.com>
@ -36,25 +36,34 @@
#include "iptsec_debug.h"
/**@var IPTSEC_DEBUG
#if DOXYGEN_ONLY
/** @defgroup iptsec_env Environment Variables Used by iptsec Module
*
* Environment variable determining the debug log level for @b iptsec
* @brief Environment variables used by @iptsec module are listed here.
*
* The #IPTSEC_DEBUG variable sets the debug level.
*/
/**@ingroup iptsec_env
*
* Environment variable determining the debug log level for @iptsec
* module.
*
* The IPTSEC_DEBUG environment variable is used to determine the debug
* logging level for @b iptsec module. The default level is 3.
* logging level for @iptsec module. The default level is 3.
*
* @sa <sofia-sip/su_debug.h>, iptsec_log, SOFIA_DEBUG
* @sa <sofia-sip/su_debug.h>, #iptsec_log, #SOFIA_DEBUG
*/
extern char const IPTSEC_DEBUG[];
extern IPTSEC_DEBUG;
#endif
#ifndef SU_DEBUG
#define SU_DEBUG 3
#endif
/**Debug log for @b iptsec module.
/** Common log for client and server components.
*
* The iptsec_log is the log object used by @b iptsec module. The level of
* The iptsec_log is the log object used by @iptsec module. The level of
* #iptsec_log is set using #IPTSEC_DEBUG environment variable.
*/
su_log_t iptsec_log[] = { SU_LOG_INIT("iptsec", "IPTSEC_DEBUG", SU_DEBUG) };

View File

@ -26,7 +26,8 @@
/** Defined when <iptsec_debug.h> has been included. */
#define IPTSEC_DEBUG_H
/**@file iptsec_debug.h
/**@internal
* @file iptsec_debug.h
* @brief Debug log for IPTSEC module.
*
* @author Pekka Pessi <Pekka.Pessi@nokia.com>
@ -38,7 +39,7 @@
SOFIA_BEGIN_DECLS
/** Common log for application and srvlib components. */
/** Common log for client and server components. */
SOFIAPUBVAR su_log_t iptsec_log[];
SOFIA_END_DECLS

View File

@ -91,12 +91,12 @@ struct auth_client_plugin
int (*auc_info)(auth_client_t *ca, msg_auth_info_t const *ai);
#if SOFIA_EXTEND_AUTH_CLIENT
/** Clear credentials (user/pass). @NEW_1_12_6 */
/** Clear credentials (user/pass). @NEW_1_12_6. */
int (*auc_clear)(auth_client_t *ca);
#endif
};
/** Check if authentication client has been extended. @NEW_1_12_6 */
/** Check if authentication client has been extended. @NEW_1_12_6. */
#define AUTH_CLIENT_IS_EXTENDED(ca) \
((ca)->ca_auc->auc_plugin_size > \
(int)offsetof(auth_client_plugin_t, auc_clear) \

View File

@ -7,6 +7,8 @@ INPUT = @srcdir@/msg.docs @srcdir@/sofia-sip sofia-sip @srcdir@ .
@INCLUDE = ../docs/Doxyfile.conf
@INCLUDE = ../sip/sip.doxyaliases
EXCLUDE_PATTERNS += msg_test*.h msg_test*.c
TAGFILES += ../docs/ipt.doxytags=../ipt \
../docs/su.doxytags=../su \
../docs/sip.doxytags=../sip \

View File

@ -22,7 +22,7 @@
*
*/
/**@file msg.c Message object implementation.
/**@internal @file msg.c Message object implementation.
*
* @author Pekka Pessi <Pekka.Pessi@nokia.com>
*

View File

@ -142,7 +142,7 @@ separator and the message body are all in their own fragment structure. The
fragments form a dual-linked list known as @e fragment @e chain as shown in
the above figure. The memory buffers for the message, the fragment chain,
and a whole lot of other stuff is held by the generic message type, #msg_t,
defined in <msg.h>. The internal structure of #msg_t is known only within @b
defined in <sofia-sip/msg.h>. The internal structure of #msg_t is known only within @b
msg module and it is opaque to other modules.
The @b msg parser engine also drives the reverse process, invoking the
@ -262,7 +262,7 @@ header members that are also found in the beginning of a header
structure. The @e sip_size indicates the size of the structure - the
application can extend the parser and #sip_t structure beyond the
original size. The @e sip_flags contains various flags used during the
parsing and printing process. They are documented in the <msg.h>. These
parsing and printing process. They are documented in the <sofia-sip/msg.h>. These
boilerplate members are followed by the pointers to various message
elements and headers.

View File

@ -22,7 +22,8 @@
*
*/
/**@ingroup msg_parser
/**@internal
* @ingroup msg_parser
* @file msg_generic.c
* @brief Functions for generic headers
*

View File

@ -67,36 +67,6 @@ size_t memcspn(const void *mem, size_t memlen,
/** Protocol version of MIME */
char const msg_mime_version_1_0[] = "MIME/1.0";
/* Internally used version of msg_header_t */
union msg_mime_u
{
msg_common_t sh_common[1];
struct {
msg_common_t shn_common;
msg_header_t *shn_next;
} sh_header_next[1];
msg_multipart_t sh_multipart[1];
msg_accept_t sh_accept[1];
msg_accept_any_t sh_accept_any[1];
msg_accept_charset_t sh_accept_charset[1];
msg_accept_encoding_t sh_accept_encoding[1];
msg_accept_language_t sh_accept_language[1];
msg_content_disposition_t sh_content_disposition[1];
msg_content_encoding_t sh_content_encoding[1];
msg_content_id_t sh_content_id[1];
msg_content_language_t sh_content_language[1];
msg_content_length_t sh_content_length[1];
msg_content_location_t sh_content_location[1];
msg_content_type_t sh_content_type[1];
msg_mime_version_t sh_mime_version[1];
msg_warning_t sh_warning[1];
msg_unknown_t sh_unknown[1];
msg_separator_t sh_separator[1];
msg_payload_t sh_payload[1];
};
#include <sofia-sip/msg_parser.h>
#include <sofia-sip/msg_mime_protos.h>

View File

@ -54,25 +54,26 @@ BEGIN {
split("", NAMES);
split("", Comments);
split("", COMMENTS);
split("", experimental);
# indexed by the C name of the header
split("", Since); # Non-NUL if extra
split("", Extra); # Offset in extra headers
total = 0;
ordinary = 0;
basic = 0;
extra = 0;
without_experimental = 0;
template="";
template1="";
template2="";
template3="";
prefix="";
tprefix="";
extra=0;
failed=0;
success=0;
extra_struct = "msg_pub_extra";
ERRNO="error";
}
@ -159,7 +160,6 @@ function protos (name, comment, hash, since)
symbols[name] = comment;
if (since) {
Since[name] = since;
Extra[name] = extra++;
}
expr = (without_experimental > 0 && do_hash);
@ -210,7 +210,7 @@ function replace (p, hash, name, NAME, comment, Comment, COMMENT, since)
#
# Repeat each line in the footer containing the magic replacement
# pattern with a instance of all headers
# pattern with an instance of all headers
#
function process_footer (text)
{
@ -368,9 +368,14 @@ function templates ()
}
/^#### EXTRA HEADER LIST STARTS HERE ####$/ { HLIST=1; templates(); }
HLIST && /^#### DEFAULT HEADER LIST ENDS HERE ####$/ { basic=total; }
HLIST && /^#### EXPERIMENTAL HEADER LIST STARTS HERE ####$/ {
without_experimental=total; }
HLIST && /^[a-z]/ { protos($1, $0, 0, $2); headers[total++] = $1; }
without_experimental = total; }
HLIST && /^[a-z]/ { protos($1, $0, 0, $2);
headers[total++] = $1;
Extra[$1] = extra++;
}
/^#### EXTRA HEADER LIST ENDS HERE ####$/ { HLIST=0; }
/^ *\/\* === Headers start here \*\// { in_header_list=1; templates(); }
@ -396,15 +401,117 @@ in_header_list && /^ (sip|rtsp|http|msg|mp)_[a-z_0-9]+_t/ {
if (!NO_MIDDLE)
protos(n, $0, 0);
headers[total++] = n;
headers[total] = n; total++; ordinary++;
}
function print_parser_table(struct, scope, name, N, N_EXPERIMENTAL)
{
if (PT) {
if (N > ordinary) {
printf("/* Ordinary %u, extra %u, experimental %u */\n",
ordinary, N - ordinary, N_EXPERIMENTAL - N) > PT;
printf("struct %s {\n", struct) > PT;
printf(" %s_t base;\n", module) > PT;
printf(" msg_header_t *extra[%u];\n", N - ordinary) > PT;
if (N != N_EXPERIMENTAL) {
print "#if SU_HAVE_EXPERIMENTAL" > PT;
printf(" msg_header_t *extra[%u];\n", N_EXPERIMENTAL - N) > PT;
print "#endif" > PT;
}
printf("};\n\n") > PT;
}
printf("%s\n", scope) > PT;
printf("msg_mclass_t const %s[1] = \n{{\n", name) > PT;
printf("# if defined (%s_HCLASS)\n", toupper(module)) > PT;
printf(" %s_HCLASS,\n", toupper(module)) > PT;
printf("#else\n") > PT;
printf(" {{ 0 }},\n") > PT;
printf("#endif\n") > PT;
printf(" %s_VERSION_CURRENT,\n", toupper(module)) > PT;
printf(" %s_PROTOCOL_TAG,\n", toupper(module)) > PT;
printf("#if defined (%s_PARSER_FLAGS)\n", toupper(module)) > PT;
printf(" %s_PARSER_FLAGS,\n", toupper(module)) > PT;
printf("#else\n") > PT;
printf(" 0,\n") > PT;
printf("#endif\n") > PT;
if (N > ordinary) {
printf(" sizeof (struct %s),\n", struct) > PT;
}
else {
printf(" sizeof (%s_t),\n", module) > PT;
}
printf(" %s_extract_body,\n", module) > PT;
len = split("request status separator payload unknown error", unnamed, " ");
for (i = 1; i <= len; i++) {
printf(" {{ %s_%s_class, msg_offsetof(%s_t, %s_%s) }},\n",
tprefix, unnamed[i], module, prefix, unnamed[i]) > PT;
}
if (multipart) {
printf(" {{ %s_class, msg_offsetof(%s_t, %s_multipart) }},\n",
multipart, module, prefix) > PT;
} else {
printf(" {{ NULL, 0 }},\n") > PT;
}
if (MC_SHORT_SIZE) {
printf(" %s_short_forms, \n", module) > PT;
}
else {
printf(" NULL, \n") > PT;
}
printf(" %d, \n", MC_HASH_SIZE) > PT;
if (N != N_EXPERIMENTAL) {
print "#if SU_HAVE_EXPERIMENTAL" > PT;
printf(" %d,\n", N_EXPERIMENTAL) > PT;
print "#else" > PT;
}
printf(" %d,\n", N) > PT;
if (N != N_EXPERIMENTAL) {
print "#endif" > PT;
}
printf(" {\n") > PT;
for (j = 0; j < MC_HASH_SIZE; j++) {
c = (j + 1 == MC_HASH_SIZE) ? "" : ",";
if (j in header_hash) {
n = header_hash[j];
i = index_hash[j];
flags = header_flags[n]; if (flags) flags = ",\n " flags;
if (i >= N) {
print "#if SU_HAVE_EXPERIMENTAL" > PT;
}
if (i >= ordinary) {
printf(" { %s_%s_class,\n" \
" msg_offsetof(struct %s, extra[%u])%s }%s\n",
tprefix, n, struct, Extra[n], flags, c) > PT;
}
else {
printf(" { %s_%s_class, msg_offsetof(%s_t, %s_%s)%s }%s\n",
tprefix, n, module, prefix, n, flags, c) > PT;
}
if (i >= N) {
printf("#else\n { NULL, 0 }%s\n#endif\n", c) > PT;
}
}
else {
printf(" { NULL, 0 }%s\n", c) > PT;
}
}
printf(" }\n}};\n\n") > PT;
}
}
END {
if (failed) { exit };
if (without_experimental == 0)
without_experimental = total;
if (!NO_LAST) {
protos("unknown", "/**< Unknown headers */", -3);
protos("error", "/**< Erroneous headers */", -4);
@ -429,8 +536,6 @@ END {
getline footer < TEMPLATE;
RS=RS0;
module_struct = module "_t";
sub(/.*[\/]/, "", TEMPLATE);
gsub(/#AUTO#/, auto, header);
gsub(/#DATE#/, "@date Generated: " date, header);
@ -451,9 +556,9 @@ END {
n = shorts[i];
flags = header_flags[n]; if (flags) flags = ",\n " flags;
printf(" { /* %s */ %s_%s_class, msg_offsetof(%s_t, %s_%s)%s }%s\n",
substr(lower_case, i, 1),
tprefix, n, module, prefix, n, flags, c) \
printf(" { /* %s */ %s_%s_class, msg_offsetof(%s_t, %s_%s)%s }%s\n",
substr(lower_case, i, 1),
tprefix, n, module, prefix, n, flags, c) \
> PT;
}
else {
@ -466,67 +571,13 @@ END {
# printf("extern msg_hclass_t msg_multipart_class[];\n\n") > PT;
if (extra > 0) {
printf("struct %s {\n", extra_struct) > PT;
printf(" %s base;\n", module_struct) > PT;
if (total - without_experimental < extra) {
printf(" msg_header_t *extra[%u];\n",
extra - (total - without_experimental)) > PT;
}
if (total - without_experimental > 0) {
print "#if SU_HAVE_EXPERIMENTAL" > PT;
printf(" msg_header_t *experimental[%u];\n",
total - without_experimental) > PT;
print "#endif" > PT;
}
printf("};\n\n") > PT;
module_struct = "struct " extra_struct;
}
if (basic == 0) basic = total;
if (without_experimental == 0) without_experimental = total;
printf("msg_mclass_t const %s_mclass[1] = \n{{\n", module) > PT;
printf("# if defined (%s_HCLASS)\n", toupper(module)) > PT;
printf(" %s_HCLASS,\n", toupper(module)) > PT;
printf("#else\n") > PT;
printf(" {{ 0 }},\n") > PT;
printf("#endif\n") > PT;
printf(" %s_VERSION_CURRENT,\n", toupper(module)) > PT;
printf(" %s_PROTOCOL_TAG,\n", toupper(module)) > PT;
printf("#if defined (%s_PARSER_FLAGS)\n", toupper(module)) > PT;
printf(" %s_PARSER_FLAGS,\n", toupper(module)) > PT;
printf("#else\n") > PT;
printf(" 0,\n") > PT;
printf("#endif\n") > PT;
printf(" sizeof (%s),\n", module_struct) > PT;
printf(" %s_extract_body,\n", module) > PT;
split("", header_hash);
split("", index_hash);
len = split("request status separator payload unknown error", unnamed, " ");
for (i = 1; i <= len; i++) {
printf(" {{ %s_%s_class, msg_offsetof(%s_t, %s_%s) }},\n",
tprefix, unnamed[i], module, prefix, unnamed[i]) > PT;
}
if (multipart) {
printf(" {{ %s_class, msg_offsetof(%s_t, %s_multipart) }},\n",
multipart, module, prefix) > PT;
} else {
printf(" {{ NULL, 0 }},\n") > PT;
}
if (MC_SHORT_SIZE) {
printf(" %s_short_forms, \n", module) > PT;
}
else {
printf(" NULL, \n") > PT;
}
printf(" %d, \n", MC_HASH_SIZE) > PT;
printf ("#if SU_HAVE_EXPERIMENTAL\n" \
" %d,\n" \
"#else\n" \
" %d,\n" \
"#endif\n", \
total, without_experimental) > PT;
printf(" {\n") > PT;
for (i = 0; i < total; i++) {
for (i = 0; i < basic; i++) {
n = headers[i];
h = hashed[n];
@ -542,38 +593,67 @@ END {
}
header_hash[j] = n;
experimental2[j] = (i >= without_experimental);
index_hash[j] = i;
}
for (i = 0; i < MC_HASH_SIZE; i++) {
c = (i + 1 == MC_HASH_SIZE) ? "" : ",";
if (i in header_hash) {
n = header_hash[i];
flags = header_flags[n]; if (flags) flags = ",\n " flags;
m = module "_mclass";
s = "_d_" module "_t";
if (experimental2[i]) {
# Add basic headers
if (ordinary == basic) {
print_parser_table(s, "", m, basic, basic);
}
else if (basic < without_experimental) {
print_parser_table(s, "", m, basic, basic);
}
else {
print_parser_table(s, "", m, without_experimental, basic);
}
if (0) {
# Hash extra headers
for (i = basic; i < total; i++) {
n = headers[i];
h = hashed[n];
if (h < 0)
continue;
j = h % MC_HASH_SIZE; if (j == -0) j = 0;
for (; j in header_hash;) {
if (++j == MC_HASH_SIZE) {
j = 0;
}
}
header_hash[j] = n;
index_hash[j] = i;
}
if (basic < total) {
m = module "_ext_mclass";
s = "_e_" module "_s";
print_parser_table(s, "static", m, without_experimental, total);
}
printf("msg_mclass_t const * %s_extended_mclass = %s;\n\n", module, m) > PT;
}
if (basic < total) {
printf("msg_hclass_t * const %s_extensions[] = {\n", module) > PT;
for (i = basic; i < total; i++) {
if (i == without_experimental) {
print "#if SU_HAVE_EXPERIMENTAL" > PT;
}
if (Since[n]) {
printf(" { %s_%s_class,\n" \
" msg_offsetof(struct %s, extra[%u])%s }%s\n",
tprefix, n, extra_struct, Extra[n], flags, c) > PT;
}
else {
printf(" { %s_%s_class, msg_offsetof(%s_t, %s_%s)%s }%s\n",
tprefix, n, module, prefix, n, flags, c) > PT;
}
if (experimental2[i]) {
printf("#else\n { NULL, 0 }%s\n#endif\n", c) > PT;
}
}
else {
printf(" { NULL, 0 }%s\n", c) > PT;
}
printf(" %s_%s_class,\n", module, headers[i]) > PT;
}
if (total != without_experimental)
print "#endif" > PT;
print " NULL\n};\n\n" > PT;
}
printf(" }\n}};\n\n") > PT;
}
exit success;

View File

@ -22,7 +22,7 @@
*
*/
/**
/**@internal
* @file nea_event.c
* @brief Default MIME type for certain events.
*

View File

@ -22,7 +22,7 @@
*
*/
/**@file nea_server.c
/**@internal @file nea_server.c
* @brief Nokia Event API - event notifier implementation.
*
* @author Pekka Pessi <Pekka.Pessi@nokia.com>
@ -65,7 +65,7 @@
/** Number of primary views (with different MIME type or content) */
#define NEA_VIEW_MAX (8)
/** Server object, created for every notifier.
/** @internal Server object, created for every notifier.
*/
struct nea_server_s {
su_home_t nes_home[1];
@ -112,7 +112,7 @@ struct nea_server_s {
};
/** Supported events and their subscribers */
/** @internal Supported events and their subscribers */
struct nea_event_s {
nea_event_t *ev_next;
nea_event_t **ev_prev;
@ -141,7 +141,7 @@ struct nea_event_s {
typedef struct nea_event_queue_s nea_event_queue_t;
/** Object representing particular view of event */
/** @internal Object representing particular view of event */
struct nea_event_view_s
{
nea_event_view_t *evv_next;
@ -156,7 +156,7 @@ struct nea_event_view_s
unsigned evv_reliable:1; /**< Keep all notifications */
unsigned:0;
/** Queued notification */
/** @internal Queued notification */
struct nea_event_queue_s
{
nea_event_queue_t *evq_next;
@ -173,7 +173,7 @@ struct nea_event_view_s
#define evv_payload evv_head->evq_payload
/** Subscription object
/** @internal Subscription object.
*/
struct nea_sub_s {
nea_sub_t *s_next;

View File

@ -4538,7 +4538,7 @@ nta_incoming_t *incoming_create(nta_agent_t *agent,
irq->irq_home = home = msg_home(msg_ref_create(msg));
irq->irq_agent = agent;
irq->irq_received = agent_now(agent);
irq->irq_received = agent_now(agent); /* Timestamp originally from tport */
irq->irq_method = method;
irq->irq_rq = sip_request_copy(home, sip->sip_request);
@ -5129,7 +5129,12 @@ nta_incoming_magic_t *nta_incoming_magic(nta_incoming_t *irq,
return irq && irq->irq_callback == callback ? irq->irq_magic : NULL;
}
/** When received */
/** When received.
*
* Return timestamp from the reception of the initial request.
*
* @NEW_1_12_7.
*/
sip_time_t nta_incoming_received(nta_incoming_t *irq,
su_nanotime_t *return_nano)
{
@ -6768,7 +6773,7 @@ unsigned nta_outgoing_delay(nta_outgoing_t const *orq)
return orq != NULL && orq != NONE ? orq->orq_delay : UINT_MAX;
}
/** Get the branch parameter. @NEW_1_12_7 */
/** Get the branch parameter. @NEW_1_12_7. */
char const *nta_outgoing_branch(nta_outgoing_t const *orq)
{
return orq != NULL && orq != NONE && orq->orq_branch

View File

@ -26,7 +26,8 @@
/** Defined when <nta_internal.h> has been included. */
#define NTA_INTERNAL_H
/**@IFILE nta_internal.h
/**@internal @file nta_internal.h
*
* @brief Internals of NTA objects.
*
* @author Pekka Pessi <Pekka.Pessi@nokia.com>

File diff suppressed because it is too large Load Diff

View File

@ -22,8 +22,8 @@
*
*/
/**@file portbind.c
* @brief bind a socket to an UDP/TCP port and return the port number
/**@internal @file portbind.c
* @brief Bind a socket to an UDP/TCP port and return the port number
*
* @author Pekka Pessi <Pekka.Pessi@nokia.com>
*

View File

@ -63,25 +63,25 @@ typedef struct nta_incoming_s nta_incoming_t;
#ifndef NTA_AGENT_MAGIC_T
/** Default type of application context for NTA agents.
* Application may define this to appropriate type before including
* <nta.h>. */
* <sofia-sip/nta.h>. */
#define NTA_AGENT_MAGIC_T struct nta_agent_magic_s
#endif
#ifndef NTA_LEG_MAGIC_T
/** Default type of application context for NTA call legs.
* Application may define this to appropriate type before including
* <nta.h>. */
* <sofia-sip/nta.h>. */
#define NTA_LEG_MAGIC_T struct nta_leg_magic_s
#endif
#ifndef NTA_OUTGOING_MAGIC_T
/** Default type of application context for outgoing NTA requests.
* Application may define this to appropriate type before including
* <nta.h>. */
* <sofia-sip/nta.h>. */
#define NTA_OUTGOING_MAGIC_T struct nta_outgoing_magic_s
#endif
#ifndef NTA_INCOMING_MAGIC_T
/** Default type of application context for incoming NTA requests.
* Application may define this to appropriate type before including
* <nta.h>. */
* <sofia-sip/nta.h>. */
#define NTA_INCOMING_MAGIC_T struct nta_incoming_magic_s
#endif
@ -439,13 +439,13 @@ SOFIAPUBFUN int nta_outgoing_setrseq(nta_outgoing_t *orq, uint32_t rseq);
typedef struct nta_reliable_s nta_reliable_t;
#ifndef NTA_RELIABLE_MAGIC_T
/** Default type of application context for reliable NTA responses.
/** Default type of application context for reliable preliminary responses.
* Application may define this to appropriate type before including
* <nta.h>. */
* <sofia-sip/nta.h>. */
#define NTA_RELIABLE_MAGIC_T struct nta_reliable_magic_s
#endif
/** Application context for reliable NTA requests */
/** Application context for reliable preliminary responses. */
typedef NTA_RELIABLE_MAGIC_T nta_reliable_magic_t;
typedef int nta_prack_f(nta_reliable_magic_t *rmagic,

File diff suppressed because it is too large Load Diff

View File

@ -534,11 +534,11 @@ int api_test_params(agent_t *ag)
TEST_1(default_proxy == NULL);
TEST_1(smime == NULL);
TEST_1(blacklist != -1);
TEST_1(blacklist != (unsigned)-1);
TEST(debug_drop_prob, 0);
TEST_1(max_forwards >= 20);
TEST_1(maxsize >= 65536);
TEST_1(preload != -1);
TEST_1(preload != (unsigned)-1);
TEST_1(progress <= 60 * 1000);
TEST(sip_t1, NTA_SIP_T1);
TEST(sip_t2, NTA_SIP_T2);

View File

@ -22,7 +22,7 @@
*
*/
/**@file nth_server.c
/**@internal @file nth_server.c
* @brief HTTP server.
*
* @author Pekka Pessi <Pekka.Pessi@nokia.com>

View File

@ -50,7 +50,7 @@ typedef struct nth_request_s nth_request_t;
#ifndef NTH_CLIENT_MAGIC_T
/** Default type of application context for client NTH requests.
* Application may define this to appropriate type before including
* <nth.h>. */
* <sofia-sip/nth.h>. */
#define NTH_CLIENT_MAGIC_T struct nth_client_magic_s
#endif
@ -60,7 +60,7 @@ typedef NTH_CLIENT_MAGIC_T nth_client_magic_t;
#ifndef NTH_SITE_MAGIC_T
/** Default type of application context for NTH servers.
* Application may define this to appropriate type before including
* <nth.h>. */
* <sofia-sip/nth.h>. */
#define NTH_SITE_MAGIC_T struct nth_site_magic_s
#endif

View File

@ -32,7 +32,7 @@ ALIASES += NUA_EVENT="@var nua_event_e::"
ALIASES += END_NUA_EVENT="@par &nbsp;"
ALIASES += \
NUA_HPARAM_CALLS="nua_invite(), nua_respond(), nua_ack(), nua_prack(), nua_update(), nua_info(), nua_bye(), nua_options(), nua_message(), nua_register(), nua_publish(), nua_refer(),nua_subscribe(), nua_notify(), nua_refer(), nua_notifier()"
NUA_HPARAM_CALLS="nua_method(), nua_respond(), nua_invite(), nua_ack(), nua_cancel(), nua_prack(), nua_update(), nua_info(), nua_bye(), nua_options(), nua_message(), nua_register(), nua_unregister(), nua_publish(), nua_refer(), nua_subscribe(), nua_unsubscribe(), nua_notify(), nua_notifier()"
VERBATIM_HEADERS = NO

View File

@ -22,7 +22,7 @@
*
*/
/**@file nua.c High-Level User Agent Library - "nua" Implementation.
/**@internal @file nua.c High-Level User Agent Library - "nua" Implementation.
*
* @author Pekka Pessi <Pekka.Pessi@nokia.com>
* @author Kai Vehmanen <Kai.Vehmanen@nokia.com>
@ -93,19 +93,28 @@ su_log_t nua_log[] = { SU_LOG_INIT("nua", "NUA_DEBUG", SU_DEBUG) };
* @param magic Pointer to callback context
* @param tag, value, ... List of tagged parameters
*
* @retval !=NULL a pointer to a @nua stack object \n
* @retval !=NULL a pointer to a @nua stack object
* @retval NULL upon an error
*
* @par Related tags:
* NUTAG_PROXY() \n
* NUTAG_URL() \n
* NUTAG_SIPS_URL() \n
* NUTAG_SIP_PARSER() \n
* NUTAG_CERTIFICATE_DIR() \n
* all tags listed in nua_set_params(), \n
* all NTATAG_* are passed to NTA listed in <sofia-sip/nta_tag.h> \n
* all tport tags listed in <sofia-sip/tport_tag.h> \n
* STUNTAG_DOMAIN(), STUNTAG_SERVER() \n
* - NUTAG_PROXY(), giving the URI of the outbound proxy
* (but see also NUTAG_INITIAL_ROUTE()).
* - NUTAG_URL() (and NUTAG_SIPS_URL(), listing URIs describing
* transports)
* - NUTAG_CERTIFICATE_DIR(), specifying the location of the
* root and client/server certificate files
* - NUTAG_SIP_PARSER(), providing customized parser used to
* parse received SIP messages
* - All parameter tags, listed with nua_set_params()
* - All NTATAG_* are passed to NTA documented in <sofia-sip/nta_tag.h>:
* see NTATAG_EXTRA_100(),
* - All tport tags are passed to tport.
* They are documented in <sofia-sip/tport_tag.h>
* - All SOATAG_* are passed to the default SOA (media session) object which
* is created by nua_create() unless NUTAG_MEDIA_ENABLE(0) is included in
* the tag list
* - STUN tags STUNTAG_DOMAIN(), STUNTAG_SERVER().
* STUN is deprecated, however.
*
* @note
* From the @VERSION_1_12_2 all the nua_set_params() tags are processed.
@ -186,6 +195,13 @@ void nua_shutdown(nua_t *nua)
nua_signal(nua, NULL, NULL, 1, nua_r_shutdown, 0, NULL, TAG_END());
}
/** @internal Linked stack frames from nua event callback */
struct nua_event_frame_s {
nua_event_frame_t *nf_next;
nua_t *nf_nua;
nua_saved_event_t nf_saved[1];
};
/** Destroy the @nua stack.
*
* Before calling nua_destroy() the application
@ -211,6 +227,8 @@ void nua_destroy(nua_t *nua)
enter;
if (nua) {
nua_event_frame_t *nf;
if (!nua->nua_shutdown_final) {
SU_DEBUG_0(("nua_destroy(%p): FATAL: nua_shutdown not completed\n",
(void *)nua));
@ -218,6 +236,13 @@ void nua_destroy(nua_t *nua)
return;
}
nua->nua_callback = NULL;
for (nf = nua->nua_current; nf; nf = nf->nf_next) {
nf->nf_nua = NULL;
}
nua->nua_current = NULL;
su_task_deinit(nua->nua_server);
su_task_deinit(nua->nua_client);
@ -975,9 +1000,10 @@ 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;
e->e_nh = NULL;
if (nh) {
if (!nh->nh_ref_by_user && nh->nh_valid) {
nh->nh_ref_by_user = 1;
@ -1004,40 +1030,40 @@ void nua_event(nua_t *root_magic, su_msg_r sumsg, event_t *e)
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);
if (e->e_event == nua_r_shutdown && e->e_status >= 200)
nua->nua_shutdown_final = 1;
e->e_nh = NULL;
if (nua->nua_callback) {
nua_event_frame_t frame[1];
su_msg_remove_refs(sumsg); /* Remove references to tasks */
su_msg_save(frame->nf_saved, sumsg);
frame->nf_nua = nua;
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);
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)) {
su_msg_destroy(frame->nf_saved);
if (frame->nf_nua == NULL)
return;
nua->nua_current = frame->nf_next;
}
if (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.
@ -1048,7 +1074,9 @@ void nua_event(nua_t *root_magic, su_msg_r sumsg, event_t *e)
*/
msg_t *nua_current_request(nua_t const *nua)
{
return nua && nua->nua_current ? su_msg_data(nua->nua_current)->e_msg : NULL;
if (nua && nua->nua_current && su_msg_is_non_null(nua->nua_current->nf_saved))
return su_msg_data(nua->nua_current->nf_saved)->e_msg;
return NULL;
}
/** Get request message from saved nua event. @NEW_1_12_4.
@ -1066,14 +1094,15 @@ msg_t *nua_saved_event_request(nua_saved_event_t const *saved)
*/
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;
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;
}

View File

@ -238,7 +238,7 @@ char const *nua_generate_instance_identifier(su_home_t *home)
*
* @sa nua_respond(), #nua_event_e, #nua_event_t, nua_event_name()
*
* @NEW_1_12_6
* @NEW_1_12_6.
*/
int nua_event_is_incoming_request(nua_event_t event)
{

View File

@ -80,7 +80,7 @@ typedef struct {
} nua_server_methods_t;
/** Server side transaction */
/* Server side transaction */
struct nua_server_request {
struct nua_server_request *sr_next, **sr_prev;
@ -147,7 +147,7 @@ int sr_status(nua_server_request_t *sr, int status, char const *phrase)
return (void)(sr->sr_phrase = phrase), (sr->sr_status = status);
}
/** Methods for client request */
/* Methods for client request. @internal */
typedef struct {
sip_method_t crm_method;
char const *crm_method_name;
@ -367,7 +367,7 @@ struct nua_dialog_state
} ds_remote_ua[1];
};
/** Virtual function pointer table for dialog usage. */
/* Virtual function pointer table for dialog usage. */
typedef struct {
unsigned usage_size, usage_class_size;
int (*usage_add)(nua_owner_t *,
@ -387,7 +387,7 @@ typedef struct {
} nua_usage_class;
/** Base structure for dialog usage. */
/* Base structure for dialog usage. */
struct nua_dialog_usage {
nua_dialog_usage_t *du_next;
nua_usage_class const *du_class;

View File

@ -79,7 +79,7 @@ nua_stack_notifier(nua_t *nua, nua_handle_t *nh, nua_event_t e, tagi_t const *ta
int status = 900;
char const *phrase = nua_internal_error;
nua_stack_init_handle(nua, nh, TAG_NEXT(tags));
nua_stack_init_handle(nua, nh, tags);
tl_gets(tags,
NUTAG_URL_REF(url),

View File

@ -35,7 +35,7 @@
* @date Created: Wed Mar 8 11:38:18 EET 2006 ppessi
*/
/** NUA preferences.
/**@internal @brief NUA preferences.
*
* This structure contains values for various preferences and a separate
* bitmap (nhp_set) for each preference. Preferences are set using

View File

@ -116,7 +116,7 @@ static int nua_register_usage_shutdown(nua_handle_t *,
nua_dialog_state_t *,
nua_dialog_usage_t *);
/** REGISTER usage, aka nua_registration_t */
/** @internal @brief REGISTER usage, aka nua_registration_t. */
struct register_usage {
nua_registration_t *nr_next, **nr_prev, **nr_list; /* Doubly linked list and its head */
sip_from_t *nr_aor; /**< AoR for this registration, NULL if none */
@ -293,7 +293,7 @@ outbound_owner_vtable nua_stack_outbound_callbacks = {
* @par Related tags:
* NUTAG_REGISTRAR(), NUTAG_INSTANCE(), NUTAG_OUTBOUND(),
* NUTAG_KEEPALIVE(), NUTAG_KEEPALIVE_STREAM(), NUTAG_M_USERNAME(),
* NUTAG_M_DISPLAY(), NUTAG_M_PARAMS(), NUTAG_M_FEATURES(),
* NUTAG_M_DISPLAY(), NUTAG_M_PARAMS(), NUTAG_M_FEATURES()
*
* @par Events:
* #nua_r_register, #nua_i_outbound

View File

@ -57,9 +57,15 @@
* Incoming REGISTER request.
*
* In order to receive #nua_i_register events, the application must enable
* the REGISTER method with NUTAG_ALLOW() tag.
* the REGISTER method with NUTAG_ALLOW() tag, e.g.,
* @verbatim
* nua_set_params(nua;
* NUTAG_APPL_METHOD("REGISTER"),
* NUTAG_ALLOW("REGISTER"),
* TAG_END());
* @endverbatim
*
* The nua_response() call responding to a REGISTER request must have
* The nua_response() call responding to a REGISTER request must include
* NUTAG_WITH() (or NUTAG_WITH_THIS()/NUTAG_WITH_SAVED()) tag. Note that
* a successful response to REGISTER @b MUST include the @Contact header
* bound to the the AoR URI (in @To header).

View File

@ -137,7 +137,7 @@ sip_response_terminates_dialog().
/* ---------------------------------------------------------------------- */
/* Session event usage */
/** Session-related state */
/** @internal @brief Session-related state. */
typedef struct nua_session_usage
{
enum nua_callstate ss_state; /**< Session status (enum nua_callstate) */
@ -1591,7 +1591,11 @@ static int nua_prack_client_request(nua_client_request_t *cr,
else if (answer_sent)
ss->ss_oa_sent = Answer;
if (!cr->cr_restarting) /* Restart logic calls nua_prack_client_report */
if (cr->cr_restarting)
/* Restart logic calls nua_prack_client_report */;
else if (!cr->cr_auto && (!offer_sent || !answer_sent))
/* Suppose application know it called nua_prack() */;
else
signal_call_state_change(nh, ss, status, phrase, ss->ss_state);
}

View File

@ -414,6 +414,9 @@ void nua_stack_signal(nua_t *nua, su_msg_r msg, nua_event_data_t *e)
case nua_r_info:
error = nua_stack_info(nua, nh, event, tags);
break;
case nua_r_prack:
error = nua_stack_prack(nua, nh, event, tags);
break;
case nua_r_update:
error = nua_stack_update(nua, nh, event, tags);
break;
@ -754,10 +757,8 @@ void nh_destroy(nua_t *nua, nua_handle_t *nh)
* @retval -1 upon an error
* @retval 0 when successful
*/
int nua_stack_init_handle(nua_t *nua, nua_handle_t *nh,
tag_type_t tag, tag_value_t value, ...)
int nua_stack_init_handle(nua_t *nua, nua_handle_t *nh, tagi_t const *tags)
{
ta_list ta;
int retval = 0;
if (nh == NULL)
@ -765,13 +766,9 @@ int nua_stack_init_handle(nua_t *nua, nua_handle_t *nh,
assert(nh != nua->nua_dhandle);
ta_start(ta, tag, value);
if (nua_stack_set_params(nua, nh, nua_i_error, ta_args(ta)) < 0)
if (nua_stack_set_params(nua, nh, nua_i_error, tags) < 0)
retval = -1;
ta_end(ta);
if (retval || nh->nh_init) /* Already initialized? */
return retval;
@ -814,7 +811,7 @@ nua_handle_t *nua_stack_incoming_handle(nua_t *nua,
SIPTAG_FROM(from), /* Remote AoR */
TAG_END());
if (nua_stack_init_handle(nh->nh_nua, nh, TAG_END()) < 0)
if (nua_stack_init_handle(nh->nh_nua, nh, NULL) < 0)
nh_destroy(nua, nh), nh = NULL;
if (nh && create_dialog) {
@ -1672,7 +1669,9 @@ int nua_base_server_report(nua_server_request_t *sr, tagi_t const *tags)
/* ---------------------------------------------------------------------- */
/** @class nua_client_request
/**@internal
*
* @class nua_client_request
*
* Each handle has a queue of client-side requests; if a request is pending,
* a new request from API is added to the queue. After the request is
@ -1944,7 +1943,7 @@ int nua_client_init_request(nua_client_request_t *cr)
cr->cr_offer_recv = 0, cr->cr_answer_sent = 0;
cr->cr_terminated = 0, cr->cr_graceful = 0;
nua_stack_init_handle(nua, nh, TAG_NEXT(cr->cr_tags));
nua_stack_init_handle(nua, nh, cr->cr_tags);
if (cr->cr_method == sip_method_cancel) {
if (cr->cr_methods->crm_init) {

View File

@ -129,7 +129,7 @@ su_inline int nua_handle_unref_by(nua_handle_t *nh, char const *by)
#endif
/** NUA handle.
/** @internal @brief NUA handle.
*
*/
struct nua_handle_s
@ -197,6 +197,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 +216,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 */
@ -307,7 +309,8 @@ nua_stack_signal_handler
nua_stack_set_params, nua_stack_get_params,
nua_stack_register,
nua_stack_invite, nua_stack_ack, nua_stack_cancel,
nua_stack_bye, nua_stack_info, nua_stack_update,
nua_stack_bye, nua_stack_info, nua_stack_update,
nua_stack_prack,
nua_stack_options, nua_stack_publish, nua_stack_message,
nua_stack_subscribe, nua_stack_notify, nua_stack_refer,
nua_stack_method;
@ -336,8 +339,7 @@ nua_handle_t *nua_stack_incoming_handle(nua_t *nua,
sip_t const *sip,
int create_dialog);
int nua_stack_init_handle(nua_t *nua, nua_handle_t *nh,
tag_type_t tag, tag_value_t value, ...);
int nua_stack_init_handle(nua_t *nua, nua_handle_t *nh, tagi_t const *tags);
enum nh_kind {
nh_has_nothing,

View File

@ -737,7 +737,10 @@ int nua_notify_server_report(nua_server_request_t *sr, tagi_t const *tags)
* #nua_i_notify
*
* @sa #nua_r_refer, NUTAG_SUBSTATE(), NUTAG_REFER_EVENT(),#nua_i_refer,
* @RFC3515, @ReferTo, @RFC3892, @ReferredBy
* @RFC3515, @ReferTo, SIPTAG_REFER_TO(), SIPTAG_REFER_TO_STR(),
* @RFC3892, @ReferredBy, SIPTAG_REFERRED_BY(), SIPTAG_REFERRED_BY_STR(),
* @RFC3891, @Replaces, SIPTAG_REPLACES(), SIPTAG_REPLACES_STR(),
* @RFC4488, @ReferSub, SIPTAG_REFER_SUB(), SIPTAG_REFER_SUB_STR()
*/
/**@NUA_EVENT nua_r_refer
@ -758,7 +761,7 @@ int nua_notify_server_report(nua_server_request_t *sr, tagi_t const *tags)
* NUTAG_SUBSTATE()
*
* @sa nua_refer(), NUTAG_SUBSTATE(), #nua_i_refer,
* @RFC3515, @ReferTo, @RFC3892, @ReferredBy
* @RFC3515, @RFC4488, @ReferSub
*
* @END_NUA_EVENT
*/

File diff suppressed because it is too large Load Diff

View File

@ -863,11 +863,20 @@ static int response_to_keepalive_options(outbound_t *ob,
loglevel = 1; /* XXX ... for now */
if (loglevel >= SU_LOG->log_level) {
su_llog(SU_LOG, loglevel,
"outbound(%p): %s <" URL_PRINT_FORMAT ">\n",
(void *)ob->ob_owner,
failed ? "FAILED to validate" : "validated",
URL_PRINT_ARGS(ob->ob_rcontact->m_url));
sip_contact_t const *m = ob->ob_rcontact;
if (m)
su_llog(SU_LOG, loglevel,
"outbound(%p): %s <" URL_PRINT_FORMAT ">\n",
(void *)ob->ob_owner,
failed ? "FAILED to validate" : "validated",
URL_PRINT_ARGS(m->m_url));
else
su_llog(SU_LOG, loglevel,
"outbound(%p): %s registration\n",
(void *)ob->ob_owner,
failed ? "FAILED to validate" : "validated");
if (failed)
su_llog(SU_LOG, loglevel, "outbound(%p): FAILED with %u %s\n",
(void *)ob->ob_owner, status, phrase);
@ -1101,6 +1110,8 @@ int outbound_set_contact(outbound_t *ob,
previous = ob->ob_rcontact;
}
else if (application_contact) {
rcontact = sip_contact_dup(home, application_contact);
if (!ob->ob_rcontact ||
url_cmp_all(ob->ob_rcontact->m_url, application_contact->m_url)) {
contact_uri_changed = 1;

File diff suppressed because it is too large Load Diff

View File

@ -550,6 +550,7 @@ int ringing_pracked(CONDITION_PARAMS)
}
int respond_483_to_prack(CONDITION_PARAMS);
static int prack_100rel(CONDITION_PARAMS);
int test_183rel(struct context *ctx)
{
@ -681,13 +682,14 @@ int test_183rel(struct context *ctx)
if (print_headings)
printf("TEST NUA-10.2.2: graceful termination because PRACK fails\n");
nua_set_hparams(a_call->nh, NUTAG_APPL_METHOD("PRACK"), TAG_END());
nua_set_hparams(b_call->nh, NUTAG_APPL_METHOD("PRACK"),
NUTAG_AUTOANSWER(0), TAG_END());
run_b_until(ctx, nua_r_set_params, NULL);
run_ab_until(ctx, nua_r_set_params, NULL, nua_r_set_params, NULL);
INVITE(a, a_call, a_call->nh, TAG_END());
run_ab_until(ctx, -1, until_terminated, -1, respond_483_to_prack);
run_ab_until(ctx, -1, prack_100rel, -1, respond_483_to_prack);
/* Client transitions:
INIT -(C1)-> CALLING: nua_invite(), nua_i_state
@ -790,6 +792,29 @@ int test_183rel(struct context *ctx)
END();
}
static int prack_100rel(CONDITION_PARAMS)
{
if (!check_handle(ep, call, nh, SIP_500_INTERNAL_SERVER_ERROR))
return 0;
save_event_in_list(ctx, event, ep, call);
if (event == nua_r_invite && 100 < status && status < 200 &&
sip_has_feature(sip->sip_require, "100rel")) {
sip_rack_t rack[1];
sip_rack_init(rack);
rack->ra_response = sip->sip_rseq->rs_response;
rack->ra_cseq = sip->sip_cseq->cs_seq;
rack->ra_method = sip->sip_cseq->cs_method;
rack->ra_method_name = sip->sip_cseq->cs_method_name;
nua_prack(nh, SIPTAG_RACK(rack), TAG_END());
}
return event == nua_i_state && callstate(tags) == nua_callstate_terminated;
}
int respond_483_to_prack(CONDITION_PARAMS)
{
if (!(check_handle(ep, call, nh, SIP_500_INTERNAL_SERVER_ERROR)))

View File

@ -338,6 +338,8 @@ int main(int argc, char *argv[])
retval |= test_nua_params(ctx); SINGLE_FAILURE_CHECK();
retval |= test_nua_destroy(ctx); SINGLE_FAILURE_CHECK();
retval |= test_nua_init(ctx, o_iproxy, o_proxy, o_inat,
TESTNATTAG_SYMMETRIC(o_inat_symmetric),
TESTNATTAG_LOGGING(o_inat_logging),

View File

@ -327,6 +327,7 @@ int test_nua_init(struct context *ctx,
int test_deinit(struct context *ctx);
int test_nua_api_errors(struct context *ctx);
int test_nua_destroy(struct context *ctx);
int test_stack_errors(struct context *ctx);
int test_tag_filter(void);
int test_nua_params(struct context *ctx);

View File

@ -34,6 +34,7 @@
#include "config.h"
#include "test_nua.h"
#include "sofia-sip/tport_tag.h"
#if HAVE_FUNC
#elif HAVE_FUNCTION
@ -71,9 +72,9 @@ int test_nua_api_errors(struct context *ctx)
TEST(status, 200); TEST_S(phrase, sip_200_OK);
su_log_init(nua_log);
level = nua_log->log_level;
if (!(tstflags & tst_verbatim))
su_log_set_level(nua_log, 0); /* Log at level 0 by default */
level = nua_log->log_level;
TEST_1(!nua_create(NULL, NULL, NULL, TAG_END()));
TEST_VOID(nua_shutdown(NULL));
@ -142,6 +143,61 @@ int test_nua_api_errors(struct context *ctx)
/* ======================================================================== */
void destroy_callback(nua_event_t event,
int status, char const *phrase,
nua_t *nua, struct context *ctx,
nua_handle_t *nh, struct call *call,
sip_t const *sip,
tagi_t tags[])
{
if (status >= 200) {
nua_destroy(ctx->a.nua), ctx->a.nua = NULL;
su_root_break(ctx->root);
}
}
/* Test different nua_destroy() corner cases */
int test_nua_destroy(struct context *ctx)
{
BEGIN();
struct endpoint *a = &ctx->a;
TEST_1(ctx->root = su_root_create(NULL));
#if 0
a->nua = nua_create(ctx->root, destroy_callback, ctx,
NUTAG_URL("sip:0.0.0.0:*"),
TAG_IF(ctx->a.logging, TPTAG_LOG(1)),
TAG_END());
TEST_1(a->nua);
nua_get_params(a->nua, TAG_ANY(), TAG_END());
su_root_run(ctx->root);
TEST_1(a->nua == NULL);
#endif
a->nua = nua_create(ctx->root, destroy_callback, ctx,
NUTAG_URL("sip:0.0.0.0:*"),
TAG_IF(ctx->a.logging, TPTAG_LOG(1)),
TAG_END());
TEST_1(a->nua);
nua_shutdown(a->nua);
su_root_run(ctx->root);
TEST_1(a->nua == NULL);
su_root_destroy(ctx->root), ctx->root = NULL;
END();
}
/* ======================================================================== */
int test_stack_errors(struct context *ctx)
{
BEGIN();

View File

@ -299,7 +299,7 @@ int test_nua_params(struct context *ctx)
sip_organization_t const *organization = NONE;
char const *organization_str = "NONE";
sip_route_t *initial_route = NONE;
sip_route_t const *initial_route = NONE;
char const *initial_route_str = NONE;
char const *outbound = "NONE";

View File

@ -22,7 +22,7 @@
*
*/
/**
/**@internal
* @file sdp_tag.c
* @brief SDP Tags
*

View File

@ -230,7 +230,7 @@ typedef enum
sdp_media_control, /**< Additional conference control */
sdp_media_message, /**< Messaging sessions*/
sdp_media_image, /**< Image browsing sessions for JPIP, and T.38 */
sdp_media_red /**< Redundancy. @NEW_1_12_4 */
sdp_media_red /**< Redundancy. @NEW_1_12_4. */
} sdp_media_e;
/** Media transport protocol. */
@ -241,7 +241,7 @@ typedef enum
sdp_proto_udp = 17, /**< Plain UDP */
sdp_proto_rtp = 256, /**< RTP/AVP */
sdp_proto_srtp = 257, /**< RTP/SAVP */
sdp_proto_udptl = 258, /**< UDPTL. @NEW_1_12_4 */
sdp_proto_udptl = 258, /**< UDPTL. @NEW_1_12_4. */
sdp_proto_tls = 511, /**< TLS over TCP */
sdp_proto_any = 512 /**< * wildcard */
} sdp_proto_e;

View File

@ -1,13 +1,11 @@
Description of Adding a SIP Header to Sofia SIP
===============================================
Adding a SIP Header to Sofia SIP
================================
by Pekka Pessi (2002-08-16, updated 2006-10-03)
by Pekka Pessi (2002-08-16, last updated 2007-09-19)
There are three ways to extend the Sofia SIP parser, including a standard
header in sip_t structure, including a standard header in extra headers or
putting the extension headers into a separate library.
Probalem with extending #sip_t is that it breaks binary compatibility.
There are two recommended ways to extend the Sofia SIP parser, including a
standard header in extra headers or putting the extension headers into a
separate library.
In the text below, we use "Example" header as our example with following
ABNF:
@ -18,30 +16,18 @@ ABNF:
IF YOUR HEADER IS A STANDARD ONE
--------------------------------
* In <sip.h>, add:
* In <sofia-sip/sip_extra.h>, add:
- Add typedef to the header structure.
The typedefs to ordinary headers are in more or less alphabetic
order after typedef of sip_unknown_t. You should add a typedef line
like this:
You should add a typedef line like this:
typedef struct sip_example_s sip_example_t;
Note that the typedefs are documented together with the
implementation in the .c file.
- Add field to the sip_t structure (struct sip_s)
- Remember to add a comment containing the header name
after field for benefit of the AWK script autmatically generating
boilerplate functions and macros:
sip_example_t *sip_example; /**< Example */
- The AWK script msg_parser.awk automatically creates the default
prototypes and tags for the newly created header when the entry in
sip_t structure is formatted like to the example above.
It will complain about mismatches between header name and field name.
* Add the actual header structure:
- Add the actual header structure:
The header structure would look like below. The first field MUST be a
sip_common_t structure, second field MUST be a pointer to next header
@ -61,6 +47,21 @@ IF YOUR HEADER IS A STANDARD ONE
unsigned long ex_value; /**< Value of example. */
};
* Add entry to sip_extra_headers.txt:
- In this case:
example @NEW_2_0 /* Example header */
- The first is the base C name used for functions and types related to
the type. The AWK script msg_parser.awk automatically creates the
default prototypes and tags for the newly created header. It will
complain about mismatches between header name and the base name.
- If the entry is before #### DEFAULT HEADER LIST ENDS HERE ####
the new header is added to the default parser
- If after, the new header is added only to the extended parser.
- The extended parser will be used after call to
sip_update_default_mclass(NULL)
* Write parsing tests for your new headers in torture_sip.c:
Add all relevant parsing/processing cases you can think of
@ -86,8 +87,10 @@ IF YOUR HEADER IS A STANDARD ONE
* Run "make check" after you are ready. Really.
IF YOUR HEADERS ARE NON-STANDARD
--------------------------------
IF YOUR HEADERS ARE COMPLETELY NON-STANDARD
-------------------------------------------
* Add a separate library package for them
- There is an example package sofia-sip-2543.tar.gz, available from
sofia-sip.sourceforge.net
@ -147,6 +150,3 @@ struct sip_example_dummy_structure {
#endif /** !defined(SIP_EXAMPLE_H) */
--->8---->8---->8---->8---->8---->8---->8---->8---->8---->8---->8---->8---

View File

@ -148,4 +148,5 @@ sofia-sip/sip_extra.h: ${srcdir}/sofia-sip/sip_extra.h.in ${EXTRA}
PACKAGE_VERSION="${PACKAGE_VERSION}" \
TEMPLATE1=${srcdir}/sofia-sip/sip_hclasses.h.in \
TEMPLATE2=${srcdir}/sofia-sip/sip_protos.h.in \
TEMPLATE3=${srcdir}/sofia-sip/sip_tag.h.in \
TEMPLATE=${srcdir}/sofia-sip/sip_extra.h.in ${EXTRA}

View File

@ -69,4 +69,6 @@ ALIASES += \
"ReplyTo=@ref sip_reply_to \"Reply-To\"" \
"SuppressBodyIfMatch=@ref sip_suppress_body_if_match \"Suppress-Body-If-Match\"" \
"SuppressNotifyIfMatch=@ref sip_suppress_notify_if_match \"Suppress-Notify-If-Match\"" \
"RemotePartyID=@ref sip_remote_party_id \"Remote-Party-ID\"" \
"PAssertedIdentity=@ref sip_p_asserted_identity \"P-Asserted-Identity\"" \
"PPreferredIdentity=@ref sip_p_preferred_identity \"P-Preferred-Identity\"" \

View File

@ -123,7 +123,7 @@ SIP_HEADER_CLASS(request, NULL, "", rq_common, single_critical, request);
/**Parse @ref sip_request "request line" from a a SIP message. */
issize_t sip_request_d(su_home_t *home, sip_header_t *h, char *s, isize_t slen)
{
sip_request_t *rq = h->sh_request;
sip_request_t *rq = (sip_request_t *)h;
char *uri, *version;
if (msg_firstline_d(s, &uri, &version) < 0 || !uri || !version ||
@ -138,7 +138,7 @@ issize_t sip_request_d(su_home_t *home, sip_header_t *h, char *s, isize_t slen)
/**Encode @ref sip_request "request line" of a a SIP message. */
issize_t sip_request_e(char b[], isize_t bsiz, sip_header_t const *h, int flags)
{
sip_request_t const *rq = h->sh_request;
sip_request_t const *rq = (sip_request_t *)h;
return snprintf(b, bsiz, "%s " URL_FORMAT_STRING " %s" CRLF,
rq->rq_method_name,
@ -148,7 +148,7 @@ issize_t sip_request_e(char b[], isize_t bsiz, sip_header_t const *h, int flags)
isize_t sip_request_dup_xtra(sip_header_t const *h, isize_t offset)
{
sip_request_t const *rq = h->sh_request;
sip_request_t const *rq = (sip_request_t *)h;
offset += url_xtra(rq->rq_url);
if (!rq->rq_method)
@ -162,8 +162,8 @@ isize_t sip_request_dup_xtra(sip_header_t const *h, isize_t offset)
char *sip_request_dup_one(sip_header_t *dst, sip_header_t const *src,
char *b, isize_t xtra)
{
sip_request_t *rq = dst->sh_request;
sip_request_t const *o = src->sh_request;
sip_request_t *rq = (sip_request_t *)dst;
sip_request_t const *o = (sip_request_t *)src;
char *end = b + xtra;
URL_DUP(b, end, rq->rq_url, o->rq_url);
@ -224,7 +224,7 @@ sip_request_t *sip_request_create(su_home_t *home,
xtra = url_xtra(uri->us_url) + (method ? 0 : strlen(name) + 1);
rq = sip_header_alloc(home, sip_request_class, xtra)->sh_request;
rq = (sip_request_t *)sip_header_alloc(home, sip_request_class, xtra);
if (rq) {
char *b = (char *)(rq + 1), *end = b + xtra;
@ -298,7 +298,7 @@ SIP_HEADER_CLASS(status, NULL, "", st_common, single_critical, status);
/** Parse status line */
issize_t sip_status_d(su_home_t *home, sip_header_t *h, char *s, isize_t slen)
{
sip_status_t *st = h->sh_status;
sip_status_t *st = (sip_status_t *)h;
char *status, *phrase;
unsigned long code;
@ -315,25 +315,26 @@ issize_t sip_status_d(su_home_t *home, sip_header_t *h, char *s, isize_t slen)
issize_t sip_status_e(char b[], isize_t bsiz, sip_header_t const *h, int flags)
{
sip_status_t const *st = (sip_status_t *)h;
int status;
assert(sip_is_status(h));
status = h->sh_status->st_status;
status = st->st_status;
if (status > 999 || status < 100)
status = 0;
return snprintf(b, bsiz, "%s %03u %s" CRLF,
h->sh_status->st_version,
st->st_version,
status,
h->sh_status->st_phrase);
st->st_phrase);
}
/** Extra size of a #sip_status_t object. */
isize_t sip_status_dup_xtra(sip_header_t const *h, isize_t offset)
{
sip_status_t const *st = h->sh_status;
sip_status_t const *st = (sip_status_t *)h;
offset += sip_version_xtra(st->st_version);
offset += MSG_STRING_SIZE(st->st_phrase);
return offset;
@ -343,8 +344,8 @@ isize_t sip_status_dup_xtra(sip_header_t const *h, isize_t offset)
char *sip_status_dup_one(sip_header_t *dst, sip_header_t const *src,
char *b, isize_t xtra)
{
sip_status_t *st = dst->sh_status;
sip_status_t const *o = src->sh_status;
sip_status_t *st = (sip_status_t *)dst;
sip_status_t const *o = (sip_status_t *)src;
char *end = b + xtra;
sip_version_dup(&b, &st->st_version, o->st_version);
@ -386,7 +387,7 @@ sip_status_t *sip_status_create(su_home_t *home,
if (phrase == NULL && (phrase = sip_status_phrase(status)) == NULL)
phrase = "";
if ((st = sip_header_alloc(home, sip_status_class, 0)->sh_status)) {
if ((st = (sip_status_t *)sip_header_alloc(home, sip_status_class, 0))) {
st->st_status = status;
st->st_phrase = phrase;
st->st_version = version ? version : SIP_VERSION_CURRENT;
@ -452,7 +453,7 @@ sip_payload_t *sip_payload_create(su_home_t *home, void const *data, isize_t len
{
msg_hclass_t *hc = sip_payload_class;
sip_header_t *h = sip_header_alloc(home, hc, len + 1);
sip_payload_t *pl = h->sh_payload;
sip_payload_t *pl = (sip_payload_t *)h;
if (pl) {
char *b = sip_header_data(h);
@ -512,8 +513,8 @@ SIP_HEADER_CLASS(separator, NULL, "", sep_common, single, any);
*/
sip_separator_t *sip_separator_create(su_home_t *home)
{
sip_separator_t *sep =
sip_header_alloc(home, sip_separator_class, 0)->sh_separator;
sip_separator_t *sep = (sip_separator_t *)
sip_header_alloc(home, sip_separator_class, 0);
if (sep)
strcpy(sep->sep_data, CRLF);
@ -764,7 +765,7 @@ issize_t sip_name_addr_e(char b[], isize_t bsiz,
int flags,
char const *display,
int brackets, url_t const url[],
msg_param_t const params[],
msg_param_t const params[],
char const *comment)
{
int const compact = MSG_IS_COMPACT(flags);
@ -801,6 +802,63 @@ issize_t sip_name_addr_e(char b[], isize_t bsiz,
return b - b0;
}
/** Calculate the extra size needed to duplicate a name-addr-params construct.
*
* @param display display name (may be NULL)
* @param addr pointer to URL structure
* @param params pointer to parameter list (may be NULL)
* @param offset base offset
*
* @retval Size of duplicated name-addr-params construct, including base offset.
*
* @NEW_1_12_7.
*/
isize_t sip_name_addr_xtra(char const *display, url_t const *addr,
msg_param_t const params[],
isize_t offset)
{
SIP_PARAMS_SIZE(offset, params);
offset += SIP_STRING_SIZE(display);
offset += url_xtra(addr);
return offset;
}
/**Duplicate a name-addr-params construct.
*
* @param d_display value-result parameter for copied @e name (may be NULL)
* @param display display name (may be NULL)
* @param d_addr value-result parameter for copied @e address
* @param addr pointer to URL address structure
* @param d_params value-result parameter for copied parameters (may be NULL)
* @param params pointer to parameter list (may be NULL)
* @param b pointer to memory pool
* @param xtra size of the memory pool
*
* @retval End of the memory area used.
*
* @NEW_1_12_7.
*/
char *sip_name_addr_dup(char const **d_display, char const *display,
url_t *d_addr, url_t const *addr,
msg_param_t const **d_params, msg_param_t const params[],
char *b, isize_t xtra)
{
char *end = b + xtra;
if (d_params)
b = msg_params_dup(d_params, params, b, xtra);
URL_DUP(b, end, d_addr, addr);
if (d_display)
MSG_STRING_DUP(b, *d_display, display);
assert(b <= end);
return b;
}
/** Parse @To or @From headers */
static issize_t sip_addr_d(su_home_t *home,
sip_header_t *h,
@ -851,10 +909,11 @@ isize_t sip_addr_dup_xtra(sip_header_t const *h, isize_t offset)
{
sip_addr_t const *a = (sip_addr_t const *)h;
MSG_PARAMS_SIZE(offset, a->a_params);
offset += MSG_STRING_SIZE(a->a_display);
offset += url_xtra(a->a_url);
return sip_name_addr_xtra(a->a_display,
a->a_url,
a->a_params,
offset);
return offset;
}
@ -866,15 +925,11 @@ static char *sip_addr_dup_one(sip_header_t *dst, sip_header_t const *src,
{
sip_addr_t *a = (sip_addr_t *)dst;
sip_addr_t const *o = (sip_addr_t *)src;
char *end = b + xtra;
b = msg_params_dup(&a->a_params, o->a_params, b, xtra);
MSG_STRING_DUP(b, a->a_display, o->a_display);
URL_DUP(b, end, a->a_url, o->a_url);
assert(b <= end);
return b;
return sip_name_addr_dup(&a->a_display, o->a_display,
a->a_url, o->a_url,
&a->a_params, o->a_params,
b, xtra);
}
/** Update parameters in sip_addr_t object */
@ -905,7 +960,7 @@ sip_addr_make_url(su_home_t *home, msg_hclass_t *hc, url_string_t const *us)
h = sip_header_alloc(home, hc, n);
if (h) {
sip_addr_t *a = h->sh_to;
sip_addr_t *a = (sip_to_t *)h;
char *s2 = sip_header_data(h);
if ((size_t)url_dup(s2, n, a->a_url, us->us_url) == n)
@ -997,7 +1052,7 @@ issize_t sip_call_id_d(su_home_t *home,
char *s,
isize_t slen)
{
sip_call_id_t *i = h->sh_call_id;
sip_call_id_t *i = (sip_call_id_t *)h;
i->i_id = s; /* XXX - why not sip_word_at_word_d(&s); */
i->i_hash = msg_hash_string(s);
@ -1008,10 +1063,11 @@ issize_t sip_call_id_d(su_home_t *home,
issize_t sip_call_id_e(char b[], isize_t bsiz, sip_header_t const *h, int flags)
{
size_t n = strlen(h->sh_call_id->i_id);
sip_call_id_t const *i = (sip_call_id_t *)h;
size_t n = strlen(i->i_id);
if (bsiz > n)
strcpy(b, h->sh_call_id->i_id);
strcpy(b, i->i_id);
return (issize_t)n;
}
@ -1019,7 +1075,7 @@ issize_t sip_call_id_e(char b[], isize_t bsiz, sip_header_t const *h, int flags)
/** Extra size of a #sip_call_id_t object. */
isize_t sip_call_id_dup_xtra(sip_header_t const *h, isize_t offset)
{
sip_call_id_t const *i = h->sh_call_id;
sip_call_id_t const *i = (sip_call_id_t *)h;
return offset + MSG_STRING_SIZE(i->i_id);
}
@ -1038,8 +1094,8 @@ isize_t sip_call_id_dup_xtra(sip_header_t const *h, isize_t offset)
char *sip_call_id_dup_one(sip_header_t *dst, sip_header_t const *src,
char *b, isize_t xtra)
{
sip_call_id_t *i = dst->sh_call_id;
sip_call_id_t const *o = src->sh_call_id;
sip_call_id_t *i = (sip_call_id_t *)dst;
sip_call_id_t const *o = (sip_call_id_t *)src;
char *end = b + xtra;
MSG_STRING_DUP(b, i->i_id, o->i_id);
@ -1072,7 +1128,7 @@ sip_call_id_t *sip_call_id_create(su_home_t *home, char const *domain)
sip_call_id_t *i;
size_t xtra = su_guid_strlen + 1 + (domain ? strlen(domain) + 1 : 0);
i = sip_header_alloc(home, sip_call_id_class, xtra)->sh_call_id;
i = (sip_call_id_t *)sip_header_alloc(home, sip_call_id_class, xtra);
if (i) {
char *b;
@ -1149,7 +1205,7 @@ issize_t sip_cseq_d(su_home_t *home,
char *s,
isize_t slen)
{
sip_cseq_t *cs = h->sh_cseq;
sip_cseq_t *cs = (sip_cseq_t *)h;
if (msg_uint32_d(&s, &cs->cs_seq) < 0)
return -1;
@ -1165,17 +1221,16 @@ issize_t sip_cseq_d(su_home_t *home,
issize_t sip_cseq_e(char b[], isize_t bsiz, sip_header_t const *h, int flags)
{
sip_cseq_t const *cs = (sip_cseq_t *)h;
assert(sip_is_cseq(h));
return snprintf(b, bsiz,
"%u %s",
h->sh_cseq->cs_seq,
h->sh_cseq->cs_method_name);
return snprintf(b, bsiz, "%u %s", cs->cs_seq, cs->cs_method_name);
}
isize_t sip_cseq_dup_xtra(sip_header_t const *h, isize_t offset)
{
sip_cseq_t const *cs = h->sh_cseq;
sip_cseq_t const *cs = (sip_cseq_t *)h;
if (!cs->cs_method)
return offset + MSG_STRING_SIZE(cs->cs_method_name);
else
@ -1185,8 +1240,8 @@ isize_t sip_cseq_dup_xtra(sip_header_t const *h, isize_t offset)
char *sip_cseq_dup_one(sip_header_t *dst, sip_header_t const *src,
char *b, isize_t xtra)
{
sip_cseq_t *cs = dst->sh_cseq;
sip_cseq_t const *o = src->sh_cseq;
sip_cseq_t *cs = (sip_cseq_t *)dst;
sip_cseq_t const *o = (sip_cseq_t *)src;
char *end = b + xtra;
if (!(cs->cs_method = o->cs_method))
@ -1241,7 +1296,7 @@ sip_cseq_t *sip_cseq_create(su_home_t *home,
xtra = (method ? 0 : (strlen(method_name) + 1));
cs = sip_header_alloc(home, sip_cseq_class, xtra)->sh_cseq;
cs = (sip_cseq_t *)sip_header_alloc(home, sip_cseq_class, xtra);
if (cs) {
cs->cs_seq = seq;
@ -1355,7 +1410,7 @@ issize_t sip_contact_d(su_home_t *home,
issize_t sip_contact_e(char b[], isize_t bsiz, sip_header_t const *h, int flags)
{
sip_contact_t const *m = h->sh_contact;
sip_contact_t const *m = (sip_contact_t *)h;
int always_lt_gt = MSG_IS_CANONIC(flags) && m->m_url->url_type != url_any;
assert(sip_is_contact(h));
@ -1369,30 +1424,26 @@ issize_t sip_contact_e(char b[], isize_t bsiz, sip_header_t const *h, int flags)
isize_t sip_contact_dup_xtra(sip_header_t const *h, isize_t offset)
{
sip_contact_t const *m = h->sh_contact;
sip_contact_t const *m = (sip_contact_t *)h;
MSG_PARAMS_SIZE(offset, m->m_params);
offset += MSG_STRING_SIZE(m->m_display);
offset += url_xtra(m->m_url);
offset += MSG_STRING_SIZE(m->m_comment);
return offset;
return sip_name_addr_xtra(m->m_display,
m->m_url,
m->m_params,
offset)
+ MSG_STRING_SIZE(m->m_comment);
}
char *sip_contact_dup_one(sip_header_t *dst, sip_header_t const *src,
char *b, isize_t xtra)
{
char *end = b + xtra;
sip_contact_t *m = dst->sh_contact;
sip_contact_t const *o = src->sh_contact;
sip_contact_t *m = (sip_contact_t *)dst;
sip_contact_t const *o = (sip_contact_t *)src;
b = msg_params_dup(&m->m_params, o->m_params, b, xtra);
MSG_STRING_DUP(b, m->m_display, o->m_display);
URL_DUP(b, end, m->m_url, o->m_url);
b = sip_name_addr_dup(&m->m_display, o->m_display,
m->m_url, o->m_url,
&m->m_params, o->m_params,
b, xtra);
MSG_STRING_DUP(b, m->m_comment, o->m_comment);
assert(b <= end);
return b;
}
@ -1515,8 +1566,8 @@ issize_t sip_content_length_e(char b[], isize_t bsiz, sip_header_t const *h, int
*/
sip_content_length_t *sip_content_length_create(su_home_t *home, uint32_t n)
{
sip_content_length_t *l =
sip_header_alloc(home, sip_content_length_class, 0)->sh_content_length;
sip_content_length_t *l = (sip_content_length_t *)
sip_header_alloc(home, sip_content_length_class, 0);
if (l)
l->l_length = n;
@ -1570,7 +1621,7 @@ SIP_HEADER_CLASS(date, "Date", "", d_common, single, any);
issize_t sip_date_d(su_home_t *home, sip_header_t *h, char *s, isize_t slen)
{
sip_date_t *date = h->sh_date;
sip_date_t *date = (sip_date_t *)h;
if (msg_date_d((char const **)&s, &date->d_time) < 0 || *s)
return -1;
@ -1580,7 +1631,7 @@ issize_t sip_date_d(su_home_t *home, sip_header_t *h, char *s, isize_t slen)
issize_t sip_date_e(char b[], isize_t bsiz, sip_header_t const *h, int f)
{
sip_date_t const *date = h->sh_date;
sip_date_t const *date = (sip_date_t *)h;
return msg_date_e(b, bsiz, date->d_time);
}
@ -1601,15 +1652,15 @@ issize_t sip_date_e(char b[], isize_t bsiz, sip_header_t const *h, int f)
*/
sip_date_t *sip_date_create(su_home_t *home, sip_time_t date)
{
sip_header_t *h = sip_header_alloc(home, sip_date_class, 0);
sip_date_t *d = (sip_date_t *)sip_header_alloc(home, sip_date_class, 0);
if (h) {
if (d) {
if (date == 0)
date = sip_now();
h->sh_date->d_time = date;
d->d_time = date;
}
return h->sh_date;
return d;
}
/* ====================================================================== */
@ -1651,7 +1702,7 @@ SIP_HEADER_CLASS(expires, "Expires", "", ex_common, single, any);
issize_t sip_expires_d(su_home_t *home, sip_header_t *h, char *s, isize_t slen)
{
sip_expires_t *expires = h->sh_expires;
sip_expires_t *expires = (sip_expires_t *)h;
if (msg_date_delta_d((char const **)&s,
&expires->ex_date,
@ -1663,7 +1714,7 @@ issize_t sip_expires_d(su_home_t *home, sip_header_t *h, char *s, isize_t slen)
issize_t sip_expires_e(char b[], isize_t bsiz, sip_header_t const *h, int f)
{
sip_expires_t const *expires = h->sh_expires;
sip_expires_t const *expires = (sip_expires_t *)h;
if (expires->ex_date)
return msg_date_e(b, bsiz, expires->ex_date + expires->ex_delta);
@ -1685,12 +1736,13 @@ issize_t sip_expires_e(char b[], isize_t bsiz, sip_header_t const *h, int f)
*/
sip_expires_t *sip_expires_create(su_home_t *home, sip_time_t delta)
{
sip_header_t *h = sip_header_alloc(home, sip_expires_class, 0);
sip_expires_t *ex = (sip_expires_t *)
sip_header_alloc(home, sip_expires_class, 0);
if (h)
h->sh_expires->ex_delta = delta;
if (ex)
ex->ex_delta = delta;
return h->sh_expires;
return ex;
}
/* ====================================================================== */
@ -1955,7 +2007,7 @@ SIP_HEADER_CLASS(retry_after, "Retry-After", "", af_params, single,
issize_t sip_retry_after_d(su_home_t *home, sip_header_t *h, char *s, isize_t slen)
{
sip_retry_after_t *af = h->sh_retry_after;
sip_retry_after_t *af = (sip_retry_after_t *)h;
if ((msg_delta_d((char const **)&s, &af->af_delta) < 0) ||
(*s == '(' && msg_comment_d(&s, &af->af_comment) == -1) ||
@ -1974,7 +2026,7 @@ issize_t sip_retry_after_d(su_home_t *home, sip_header_t *h, char *s, isize_t sl
issize_t sip_retry_after_e(char b[], isize_t bsiz, sip_header_t const *h, int f)
{
sip_retry_after_t const *af = h->sh_retry_after;
sip_retry_after_t const *af = (sip_retry_after_t *)h;
int const compact = MSG_IS_COMPACT(f);
char *b0 = b, *end = b + bsiz;
@ -2000,7 +2052,7 @@ issize_t sip_retry_after_e(char b[], isize_t bsiz, sip_header_t const *h, int f)
isize_t sip_retry_after_dup_xtra(sip_header_t const *h, isize_t offset)
{
sip_retry_after_t const *af = h->sh_retry_after;
sip_retry_after_t const *af = (sip_retry_after_t *)h;
MSG_PARAMS_SIZE(offset, af->af_params);
offset += MSG_STRING_SIZE(af->af_comment);
@ -2013,8 +2065,8 @@ char *sip_retry_after_dup_one(sip_header_t *dst,
char *b,
isize_t xtra)
{
sip_retry_after_t *af = dst->sh_retry_after;
sip_retry_after_t const *o = src->sh_retry_after;
sip_retry_after_t *af = (sip_retry_after_t *)dst;
sip_retry_after_t const *o = (sip_retry_after_t *)src;
char *end = b + xtra;
b = msg_params_dup(&af->af_params, o->af_params, b, xtra);
@ -2072,7 +2124,7 @@ issize_t sip_any_route_d(su_home_t *home,
issize_t sip_any_route_e(char b[], isize_t bsiz, sip_header_t const *h, int flags)
{
sip_route_t const *r = h->sh_route;
sip_route_t const *r = (sip_route_t *)h;
return sip_name_addr_e(b, bsiz, flags,
r->r_display, 1, r->r_url, r->r_params, NULL);
@ -2080,30 +2132,23 @@ issize_t sip_any_route_e(char b[], isize_t bsiz, sip_header_t const *h, int flag
isize_t sip_any_route_dup_xtra(sip_header_t const *h, isize_t offset)
{
sip_route_t const *r = h->sh_route;
MSG_PARAMS_SIZE(offset, r->r_params);
offset += MSG_STRING_SIZE(r->r_display);
offset += url_xtra(r->r_url);
return offset;
sip_route_t const *r = (sip_route_t *)h;
return sip_name_addr_xtra(r->r_display,
r->r_url,
r->r_params,
offset);
}
char *sip_any_route_dup_one(sip_header_t *dst, sip_header_t const *src,
char *b,
isize_t xtra)
{
sip_route_t *r = dst->sh_route;
sip_route_t const *o = src->sh_route;
char *end = b + xtra;
b = msg_params_dup(&r->r_params, o->r_params, b, xtra);
MSG_STRING_DUP(b, r->r_display, o->r_display);
URL_DUP(b, end, r->r_url, o->r_url);
assert(b <= end);
return b;
sip_route_t *r = (sip_route_t *)dst;
sip_route_t const *o = (sip_route_t *)src;
return sip_name_addr_dup(&r->r_display, o->r_display,
r->r_url, o->r_url,
&r->r_params, o->r_params,
b, xtra);
}
#define sip_any_route_update NULL
@ -2149,7 +2194,7 @@ sip_route_t *sip_any_route_create(su_home_t *home,
xtra = n_url + n_params + n_addr + (n_params || n_addr);
h = sip_header_alloc(home, hc, xtra);
if ((rr = h->sh_record_route)) {
if ((rr = (sip_record_route_t *)h)) {
b = sip_header_data(h);
n = url_dup(b, n_url, rr->r_url, url);
assert(n == n_url);
@ -2519,7 +2564,7 @@ issize_t sip_via_d(su_home_t *home, sip_header_t *h, char *s, isize_t slen)
issize_t sip_via_e(char b[], isize_t bsiz, sip_header_t const *h, int flags)
{
char *b0 = b, *end = b + bsiz;
sip_via_t const *v = h->sh_via;
sip_via_t const *v = (sip_via_t *)h;
assert(sip_is_via(h));
@ -2548,7 +2593,7 @@ issize_t sip_via_e(char b[], isize_t bsiz, sip_header_t const *h, int flags)
isize_t sip_via_dup_xtra(sip_header_t const *h, isize_t offset)
{
sip_via_t const *v = h->sh_via;
sip_via_t const *v = (sip_via_t *)h;
MSG_PARAMS_SIZE(offset, v->v_params);
offset += sip_transport_xtra(v->v_protocol);
@ -2563,8 +2608,8 @@ isize_t sip_via_dup_xtra(sip_header_t const *h, isize_t offset)
char *sip_via_dup_one(sip_header_t *dst, sip_header_t const *src,
char *b, isize_t xtra)
{
sip_via_t *v = dst->sh_via;
sip_via_t const *o = src->sh_via;
sip_via_t *v = (sip_via_t *)dst;
sip_via_t const *o = (sip_via_t *)src;
char *end = b + xtra;
b = msg_params_dup(&v->v_params, o->v_params, b, xtra);
@ -2679,7 +2724,7 @@ sip_via_t *sip_via_create(su_home_t *home,
via->v_host = host;
via->v_port = port;
v = msg_header_dup_as(home, sip_via_class, (sip_header_t *)via)->sh_via;
v = (sip_via_t *)msg_header_dup_as(home, sip_via_class, (sip_header_t *)via);
if (v) {
char const *param;

View File

@ -219,7 +219,9 @@ issize_t sip_error_info_e(char b[], isize_t bsiz, sip_header_t const *h, int f)
*
* The parsed Alert-Info header is stored in #sip_alert_info_t structure.
*
* @NEW_1_12_7
* @NEW_1_12_7. In order to use @b Alert-Info header,
* initialize the SIP parser with, e.g.,
* sip_update_default_mclass(sip_extend_mclass(NULL))
*/
/**@ingroup sip_alert_info
@ -239,7 +241,7 @@ issize_t sip_error_info_e(char b[], isize_t bsiz, sip_header_t const *h, int f)
* };
* @endcode
*
* @NEW_1_12_7
* @NEW_1_12_7.
*/
msg_hclass_t sip_alert_info_class[] =
@ -276,6 +278,12 @@ issize_t sip_alert_info_e(char b[], isize_t bsiz, sip_header_t const *h, int f)
* @endcode
*
* The parsed Reply-To header is stored in #sip_reply_to_t structure.
*
* @sa sip_update_default_mclass()
*
* @NEW_1_12_7. In order to use @b Reply-To header,
* initialize the SIP parser with, e.g.,
* sip_update_default_mclass(sip_extend_mclass(NULL)).
*/
/**@ingroup sip_reply_to
@ -336,11 +344,10 @@ static isize_t sip_reply_to_dup_xtra(sip_header_t const *h, isize_t offset)
{
sip_reply_to_t const *rplyto = (sip_reply_to_t const *)h;
MSG_PARAMS_SIZE(offset, rplyto->rplyto_params);
offset += MSG_STRING_SIZE(rplyto->rplyto_display);
offset += url_xtra(rplyto->rplyto_url);
return offset;
return sip_name_addr_xtra(rplyto->rplyto_display,
rplyto->rplyto_url,
rplyto->rplyto_params,
offset);
}
/**@internal Duplicate one sip_reply_to_t object. */
@ -349,15 +356,11 @@ static char *sip_reply_to_dup_one(sip_header_t *dst, sip_header_t const *src,
{
sip_reply_to_t *rplyto = (sip_reply_to_t *)dst;
sip_reply_to_t const *o = (sip_reply_to_t *)src;
char *end = b + xtra;
b = msg_params_dup(&rplyto->rplyto_params, o->rplyto_params, b, xtra);
MSG_STRING_DUP(b, rplyto->rplyto_display, o->rplyto_display);
URL_DUP(b, end, rplyto->rplyto_url, o->rplyto_url);
assert(b <= end);
return b;
return sip_name_addr_dup(&rplyto->rplyto_display, o->rplyto_display,
rplyto->rplyto_url, o->rplyto_url,
&rplyto->rplyto_params, o->rplyto_params,
b, xtra);
}
/* ====================================================================== */
@ -889,10 +892,10 @@ isize_t sip_info_dup_xtra(sip_header_t const *h, isize_t offset)
{
sip_call_info_t const *ci = h->sh_call_info;
MSG_PARAMS_SIZE(offset, ci->ci_params);
offset += url_xtra(ci->ci_url);
return offset;
return sip_name_addr_xtra(NULL,
ci->ci_url,
ci->ci_params,
offset);
}
char *sip_info_dup_one(sip_header_t *dst,
@ -902,14 +905,11 @@ char *sip_info_dup_one(sip_header_t *dst,
{
sip_call_info_t *ci = dst->sh_call_info;
sip_call_info_t const *o = src->sh_call_info;
char *end = b + xtra;
b = msg_params_dup(&ci->ci_params, o->ci_params, b, xtra);
URL_DUP(b, end, ci->ci_url, o->ci_url);
assert(b <= end);
return b;
return sip_name_addr_dup(NULL, NULL,
ci->ci_url, o->ci_url,
&ci->ci_params, o->ci_params,
b, xtra);
}
/* ====================================================================== */
@ -1047,3 +1047,319 @@ issize_t sip_suppress_notify_if_match_e(char b[], isize_t bsiz,
}
#endif
#if SIP_HAVE_REMOTE_PARTY_ID
/**@SIP_HEADER sip_remote_party_id Remote-Party-ID Header
*
* The syntax of the Remote-Party-ID header is described as follows:
* @code
* Remote-Party-ID = "Remote-Party-ID" HCOLON rpid *(COMMA rpid)
*
* rpid = [display-name] LAQUOT addr-spec RAQUOT
* *(SEMI rpi-token)
*
* rpi-token = rpi-screen / rpi-pty-type /
* rpi-id-type / rpi-privacy / other-rpi-token
*
* rpi-screen = "screen" EQUAL ("no" / "yes")
*
* rpi-pty-type = "party" EQUAL ("calling" / "called" / token)
*
* rpi-id-type = "id-type" EQUAL ("subscriber" / "user" /
* "term" / token)
*
* rpi-privacy = "privacy" EQUAL
* ( rpi-priv-element
* / (LDQUOT rpi-priv-element
* *(COMMA rpi-priv-element) RDQUOT) )
*
* rpi-priv-element = ("full" / "name" / "uri" / "off" / token)
* ["-" ( "network" / token )]
*
* other-rpi-token = ["-"] token [EQUAL (token / quoted-string)]
*
* @endcode
*
* @sa sip_update_default_mclass(), draft-ietf-sip-privacy-04.txt, @RFC3325
*
* @NEW_1_12_7. In order to use @b Remote-Party-ID header,
* initialize the SIP parser with, e.g.,
* sip_update_default_mclass(sip_extend_mclass(NULL)).
*/
/**@ingroup sip_remote_party_id
* @typedef typedef struct sip_remote_party_id_s sip_remote_party_id_t;
*
* The structure #sip_remote_party_id_t contains representation of SIP
* @RemotePartyID header.
*
* The #sip_remote_party_id_t is defined as follows:
* @code
* typedef struct sip_remote_party_id_s {
* sip_common_t rpid_common[1]; // Common fragment info
* sip_remote_party_id_t *rpid_next; // Link to next
* char const *rpid_display; // Display name
* url_t rpid_url[1]; // URL
* sip_param_t const *rpid_params; // Parameters
* // Shortcuts to screen, party, id-type and privacy parameters
* char const *rpid_screen, *rpid_party, *rpid_id_type, *rpid_privacy;
* } sip_remote_party_id_t;
* @endcode
*/
extern msg_xtra_f sip_remote_party_id_dup_xtra;
extern msg_dup_f sip_remote_party_id_dup_one;
static msg_update_f sip_remote_party_id_update;
msg_hclass_t sip_remote_party_id_class[] =
SIP_HEADER_CLASS(remote_party_id, "Remote-Party-ID", "",
rpid_params, append, remote_party_id);
issize_t sip_remote_party_id_d(su_home_t *home, sip_header_t *h,
char *s, isize_t slen)
{
sip_remote_party_id_t *rpid = (sip_remote_party_id_t *)h;
while (*s == ',') /* Ignore empty entries (comma-whitespace) */
*s = '\0', s += span_lws(s + 1) + 1;
if (sip_name_addr_d(home, &s,
&rpid->rpid_display,
rpid->rpid_url,
&rpid->rpid_params, NULL) == -1)
return -1;
return msg_parse_next_field(home, h, s, slen);
}
issize_t sip_remote_party_id_e(char b[], isize_t bsiz,
sip_header_t const *h, int f)
{
sip_remote_party_id_t const *rpid = (sip_remote_party_id_t *)h;
return sip_name_addr_e(b, bsiz, f,
rpid->rpid_display, 1,
rpid->rpid_url,
rpid->rpid_params,
NULL);
}
/** Calculate size of extra data required for duplicating one
* sip_remote_party_id_t header.
*/
isize_t sip_remote_party_id_dup_xtra(sip_header_t const *h, isize_t offset)
{
sip_remote_party_id_t const *rpid = (sip_remote_party_id_t *)h;
return sip_name_addr_xtra(rpid->rpid_display,
rpid->rpid_url,
rpid->rpid_params,
offset);
}
/** Duplicate one sip_remote_party_id_t object */
char *sip_remote_party_id_dup_one(sip_header_t *dst,
sip_header_t const *src,
char *b, isize_t xtra)
{
sip_remote_party_id_t *rpid = (sip_remote_party_id_t *)dst;
sip_remote_party_id_t const *o = (sip_remote_party_id_t const *)src;
return sip_name_addr_dup(&rpid->rpid_display, o->rpid_display,
rpid->rpid_url, o->rpid_url,
&rpid->rpid_params, o->rpid_params,
b, xtra);
}
static int sip_remote_party_id_update(msg_common_t *h,
char const *name, isize_t namelen,
char const *value)
{
sip_remote_party_id_t *rpid = (sip_remote_party_id_t *)h;
if (name == NULL) {
rpid->rpid_screen = NULL;
rpid->rpid_party = NULL;
rpid->rpid_id_type = NULL;
rpid->rpid_privacy = NULL;
}
#define MATCH(s) (namelen == strlen(#s) && !strncasecmp(name, #s, strlen(#s)))
else if (MATCH(screen))
rpid->rpid_screen = value;
else if (MATCH(party))
rpid->rpid_party = value;
else if (MATCH(id-type))
rpid->rpid_id_type = value;
else if (MATCH(privacy))
rpid->rpid_privacy = value;
#undef MATCH
return 0;
}
#endif
#if SIP_HAVE_P_ASSERTED_IDENTITY
/**@SIP_HEADER sip_p_asserted_identity P-Asserted-Identity Header
*
* The P-Asserted-Identity header is used used among trusted SIP entities
* (typically intermediaries) to carry the identity of the user sending a
* SIP message as it was verified by authentication. It is "defined" in
* @RFC3325 section 9.1 as follows:
*
* @code
* PAssertedID = "P-Asserted-Identity" HCOLON PAssertedID-value
* *(COMMA PAssertedID-value)
* PAssertedID-value = name-addr / addr-spec
* @endcode
*
* @sa @RFC3325, @PPreferredIdentity
*
* @NEW_1_12_7. In order to use @b P-Asserted-Identity header,
* initialize the SIP parser with, e.g.,
* sip_update_default_mclass(sip_extend_mclass(NULL)).
*/
/**@ingroup sip_p_asserted_identity
* @typedef typedef struct sip_p_asserted_identity_s sip_p_asserted_identity_t;
*
* The structure #sip_p_asserted_identity_t contains representation of SIP
* @PAssertedIdentity header.
*
* The #sip_p_asserted_identity_t is defined as follows:
* @code
* typedef struct sip_p_asserted_identity_s {
* sip_common_t paid_common[1]; // Common fragment info
* sip_p_asserted_identity_t *paid_next; // Link to next
* char const *paid_display; // Display name
* url_t paid_url[1]; // URL
* } sip_p_asserted_identity_t;
* @endcode
*/
static msg_xtra_f sip_p_asserted_identity_dup_xtra;
static msg_dup_f sip_p_asserted_identity_dup_one;
#define sip_p_asserted_identity_update NULL
msg_hclass_t sip_p_asserted_identity_class[] =
SIP_HEADER_CLASS(p_asserted_identity, "P-Asserted-Identity", "",
paid_common, append, p_asserted_identity);
issize_t sip_p_asserted_identity_d(su_home_t *home, sip_header_t *h,
char *s, isize_t slen)
{
sip_p_asserted_identity_t *paid = (sip_p_asserted_identity_t *)h;
while (*s == ',') /* Ignore empty entries (comma-whitespace) */
*s = '\0', s += span_lws(s + 1) + 1;
if (sip_name_addr_d(home, &s,
&paid->paid_display,
paid->paid_url,
NULL, NULL) == -1)
return -1;
return msg_parse_next_field(home, h, s, slen);
}
issize_t sip_p_asserted_identity_e(char b[], isize_t bsiz,
sip_header_t const *h, int f)
{
sip_p_asserted_identity_t const *paid = (sip_p_asserted_identity_t *)h;
return sip_name_addr_e(b, bsiz, f,
paid->paid_display, MSG_IS_CANONIC(f),
paid->paid_url,
NULL,
NULL);
}
isize_t sip_p_asserted_identity_dup_xtra(sip_header_t const *h, isize_t offset)
{
sip_p_asserted_identity_t const *paid = (sip_p_asserted_identity_t *)h;
return sip_name_addr_xtra(paid->paid_display,
paid->paid_url,
NULL,
offset);
}
/** Duplicate one sip_p_asserted_identity_t object */
char *sip_p_asserted_identity_dup_one(sip_header_t *dst,
sip_header_t const *src,
char *b, isize_t xtra)
{
sip_p_asserted_identity_t *paid = (sip_p_asserted_identity_t *)dst;
sip_p_asserted_identity_t const *o = (sip_p_asserted_identity_t *)src;
return sip_name_addr_dup(&paid->paid_display, o->paid_display,
paid->paid_url, o->paid_url,
NULL, NULL,
b, xtra);
}
#endif
#if SIP_HAVE_P_PREFERRED_IDENTITY
/**@SIP_HEADER sip_p_preferred_identity P-Preferred-Identity Header
*
* The P-Preferred-Identity header is used used among trusted SIP entities
* (typically intermediaries) to carry the identity of the user sending a
* SIP message as it was verified by authentication. It is "defined" in
* @RFC3325 section 9.1 as follows:
*
* @code
* PPreferredID = "P-Preferred-Identity" HCOLON PPreferredID-value
* *(COMMA PPreferredID-value)
* PPreferredID-value = name-addr / addr-spec
* @endcode
*
* @sa @RFC3325, @PAssertedIdentity
*
* @NEW_1_12_7. In order to use @b P-Preferred-Identity header,
* initialize the SIP parser with, e.g.,
* sip_update_default_mclass(sip_extend_mclass(NULL)).
*/
/**@ingroup sip_p_preferred_identity
* @typedef typedef struct sip_p_preferred_identity_s sip_p_preferred_identity_t;
*
* The structure #sip_p_preferred_identity_t contains representation of SIP
* @PPreferredIdentity header.
*
* The #sip_p_preferred_identity_t is defined as follows:
* @code
* typedef struct sip_p_preferred_identity_s {
* sip_common_t ppid_common[1]; // Common fragment info
* sip_p_preferred_identity_t *ppid_next; // Link to next
* char const *ppid_display; // Display name
* url_t ppid_url[1]; // URL
* } sip_p_preferred_identity_t;
* @endcode
*/
msg_hclass_t sip_p_preferred_identity_class[] =
SIP_HEADER_CLASS(p_preferred_identity, "P-Preferred-Identity", "",
ppid_common, append, p_asserted_identity);
issize_t sip_p_preferred_identity_d(su_home_t *home, sip_header_t *h,
char *s, isize_t slen)
{
return sip_p_asserted_identity_d(home, h, s, slen);
}
issize_t sip_p_preferred_identity_e(char b[], isize_t bsiz,
sip_header_t const *h, int f)
{
return sip_p_asserted_identity_e(b, bsiz, h, f);
}
#endif

View File

@ -1,6 +1,9 @@
#
# This file specifies extra SIP headers not included in sip_t structure
#
# The parsed headers are accessed with function (or macro) like sip_refer_sub()
# e.g., sip_refer_sub_t *rsub = sip_refer_sub(sip);
#
# The line format is:
# C-name @SINCE sip_t-like-comment
#
@ -9,8 +12,19 @@
#### EXTRA HEADER LIST STARTS HERE ####
refer_sub @NEW_1_12_5 /**< Refer-Sub header */
#### DEFAULT HEADER LIST ENDS HERE ####
#
# These headers are added to the extended parser, installed
# as default with sip_update_default_mclass(NULL)
#
alert_info @NEW_1_12_7 /**< Alert-Info header */
reply_to @NEW_1_12_7 /**< Reply-To header */
remote_party_id @NEW_1_12_7 /**< Remote-Party-ID header */
p_asserted_identity @NEW_1_12_7 /**<P-Asserted-Identity*/
p_preferred_identity @NEW_1_12_7 /**<P-Preferred-Identity*/
#### EXPERIMENTAL HEADER LIST STARTS HERE ####

View File

@ -60,11 +60,84 @@ char const sip_parser_version[] = VERSION;
char const sip_version_2_0[] = "SIP/2.0";
/** Default message class */
extern msg_mclass_t const sip_mclass[];
extern msg_mclass_t sip_mclass[];
static msg_mclass_t const *_default = sip_mclass;
/** Return a built-in SIP parser object. */
msg_mclass_t const *sip_default_mclass(void)
{
return sip_mclass;
return _default;
}
/** Update the default SIP parser.
*
* Use the extended SIP parser as default one.
*
* If the applications want to use headers added after @VERSION_1_12_5,
* they should call this function before doing any other initialization, e.g.,
* @code
* su_init();
* if (sip_update_default_mclass(sip_extend_mclass(NULL)) < 0) {
* su_deinit();
* exit(2);
* }
* @endcode
*
* The default parser is not extended because it may break the old
* applications looking for extension headers from sip_unknown list.
*
* @retval 0 when successful
* @retval -1 upon an error
*
* @NEW_1_12_7.
*/
int sip_update_default_mclass(msg_mclass_t const *mclass)
{
if (mclass == NULL)
return -1;
_default = mclass;
return 0;
}
/**Extend SIP parser class with extension headers.
*
* Extend given SIP parser class with extension headers. If the given parser
* class is the default one or NULL, make a clone of it before extending it.
*
* @param input pointer to a SIP message class (may be NULL)
*
* @return Pointer to extended mclass, or NULL upon an error.
*
* @NEW_1_12_7.
*/
msg_mclass_t *sip_extend_mclass(msg_mclass_t *input)
{
msg_mclass_t *mclass;
if (input == NULL || input == _default)
mclass = msg_mclass_clone(_default, 0, 0);
else
mclass = input;
if (mclass) {
extern msg_hclass_t * const sip_extensions[];
int i;
for (i = 0; sip_extensions[i]; i++) {
msg_hclass_t *hclass = sip_extensions[i];
if (mclass->mc_unknown != msg_find_hclass(mclass, hclass->hc_name, NULL))
continue;
if (msg_mclass_insert_header(mclass, hclass, 0) < 0) {
if (input != mclass)
free(mclass);
return mclass = NULL;
}
}
}
return mclass;
}
/** Extract the SIP message body, including separator line.

View File

@ -56,7 +56,7 @@
*/
#ifndef SIP_H
#include <sip.h>
#include <sofia-sip/sip.h>
#endif
/**@ingroup sip_also

View File

@ -543,12 +543,12 @@ sip_contact_t *sip_contact_immunize(su_home_t *home, sip_contact_t const *m)
*
* @retval -1 if the contact is rejected
* @retval 1000 if contact is immune to caller preferences
* @retval 0..1000 reflecting @RFC3481 score in 0.000 - 1.000.
* @retval 0..1000 reflecting @RFC3841 score in 0.000 - 1.000.
*
* @sa sip_q_value(),
* sip_contact_accept(), sip_contact_reject(), sip_contact_is_immune(),
* sip_contact_immunize(), sip_is_callerpref(), sip_prefs_matching(),
* @RFC3481, @AcceptContact, @RejectContact, @Contact
* @RFC3841, @AcceptContact, @RejectContact, @Contact
*/
int sip_contact_score(sip_contact_t const *m,
sip_accept_contact_t const *ac,

View File

@ -1421,3 +1421,4 @@ int sip_response_terminates_dialog(int response_code,
return 0;
}

View File

@ -107,7 +107,7 @@ typedef msg_time_t sip_time_t;
/** Latest time that can be expressed with #sip_time_t. @HIDE */
#define SIP_TIME_MAX ((sip_time_t)MSG_TIME_MAX)
/** SIP message object. */
/** Structure for accessing parsed SIP headers. */
typedef struct sip_s sip_t;
/** Any SIP header - union of all possible SIP headers. */
@ -409,7 +409,7 @@ struct sip_accept_s
/**@ingroup sip_allow
* @brief Structure for @Allow header field.
*
* @NEW_1_12_5 (before used struct msg_list_s with @Allow).
* @NEW_1_12_5. (Before used struct msg_list_s with @Allow).
*/
struct sip_allow_s
{
@ -417,7 +417,7 @@ struct sip_allow_s
msg_list_t *k_next; /**< Link to next */
msg_param_t *k_items; /**< List of allowed items */
uint32_t k_bitmap; /**< Bitmap of allowed methods.
@NEW_1_12_5 */
@NEW_1_12_5. */
};
/**@ingroup sip_authentication_info
@ -573,7 +573,7 @@ struct sip_min_expires_s
};
/**@ingroup sip_rack
* @brief Structure for @b Rack header.
* @brief Structure for @RAck header.
*/
struct sip_rack_s
{

View File

@ -1,4 +1,4 @@
/**@file sofia-sip/sip_extra.h.in
`/**@file sofia-sip/sip_extra.h.in
* -*- C -*-
* Template for <sofia-sip/sip_extra.h>.
*
@ -117,6 +117,55 @@ struct sip_suppress_notify_if_match_s
char const *snim_tag; /**< Entity-tag */
};
typedef struct sip_p_asserted_identity_s sip_p_asserted_identity_t;
/**@ingroup sip_p_asserted_identity
* @brief Structure for @PAssertedIdentity header.
*/
struct sip_p_asserted_identity_s
{
sip_common_t paid_common[1];/**< Common fragment info */
sip_p_asserted_identity_t
*paid_next; /**< Link to next identity */
char const *paid_display; /**< Display name */
url_t paid_url[1]; /**< SIP, SIPS or TEL URL */
};
typedef struct sip_p_preferred_identity_s sip_p_preferred_identity_t;
/**@ingroup sip_p_preferred_identity
* @brief Structure for @PPreferredIdentity header.
*/
struct sip_p_preferred_identity_s
{
sip_common_t ppid_common[1];/**< Common fragment info */
sip_p_preferred_identity_t
*ppid_next; /**< Link to next identity */
char const *ppid_display; /**< Display name */
url_t ppid_url[1]; /**< SIP, SIPS or TEL URL */
};
int sip_p_initialize_remote_party_id_headers(msg_mclass_t *mclass);
typedef struct sip_remote_party_id_s sip_remote_party_id_t;
/**@ingroup sip_remote_party_id
* @brief Structure for @RemotePartyID header.
*/
struct sip_remote_party_id_s
{
sip_common_t rpid_common[1];/**< Common fragment info */
sip_remote_party_id_t
*rpid_next; /**< Link to next identity */
char const *rpid_display; /**< Display name */
url_t rpid_url[1]; /**< URL */
sip_param_t const *rpid_params; /**< Parameters */
/** Shortcuts to screen, party, id-type and privacy parameters */
char const *rpid_screen, *rpid_party, *rpid_id_type, *rpid_privacy;
};
/** Defined as 1 if the @ref sip_#xxxxxx# "#xxxxxxx_xxxxxxx#" is supported */
#define SIP_HAVE_#XXXXXX# 1

View File

@ -57,13 +57,16 @@
SOFIA_BEGIN_DECLS
/** Return built-in SIP parser object. */
/** Return a built-in SIP parser object. */
SOFIAPUBFUN msg_mclass_t const *sip_default_mclass(void);
/** Check that sip_t is a SIP structure (not RTSP or HTTP). @HIDE */
SOFIAPUBFUN int sip_update_default_mclass(msg_mclass_t const *mclass);
SOFIAPUBFUN msg_mclass_t *sip_extend_mclass(msg_mclass_t *input);
/** Check that sip_t is a SIP header structure (not MIME or HTTP). @HIDE */
#define sip_is_sip(sip) ((sip) && (sip)->sip_ident == SIP_PROTOCOL_TAG)
/** Initializer for a SIP header object. @HIDE */
/** Initializer for a SIP header structure. @HIDE */
#define SIP_HDR_INIT(name) {{{ 0, 0, sip_##name##_class }}}
/** Initialize a SIP header structure. @HIDE */
@ -349,7 +352,7 @@ int sip_has_feature(msg_list_t const *supported, char const *feature);
SOFIAPUBFUN int sip_is_allowed(sip_allow_t const *allow,
sip_method_t method, char const *name);
/** Check if the well-known method is listed in @Allow header. @NEW_1_12_6 */
/** Check if the well-known method is listed in @Allow header. @NEW_1_12_6. */
#define SIP_IS_ALLOWED(allow, method) \
(sip_method_unknown < (method) && (method) < 32 && \
(allow) && ((allow)->k_bitmap & (1 << (method))) != 0)
@ -447,7 +450,7 @@ enum sip_bad_mask {
/** Bit marking essential headers for PUBLISH servers and clients.
*
* @SIPEtag, and @SIPIfMatch.
* @SIPETag, and @SIPIfMatch.
*
* @sa @RFC3903.
*/

View File

@ -137,6 +137,17 @@ SOFIAPUBFUN issize_t sip_name_addr_e(char b[], isize_t bsiz,
msg_param_t const params[],
char const *comment);
SOFIAPUBFUN isize_t sip_name_addr_xtra(char const *display, url_t const *addr,
msg_param_t const params[],
isize_t offset);
SOFIAPUBFUN char *sip_name_addr_dup(char const **d_display, char const *display,
url_t *d_addr, url_t const *addr,
msg_param_t const **d_params,
msg_param_t const params[],
char *b, isize_t xtra);
/* ---------------------------------------------------------------------------
* 3) Compatibility macros and functions
*/

View File

@ -153,7 +153,7 @@ siptag_header_vr(sip_header_t const **vp)
* Macro is used to include a tag item containing an unknown extension
* header in the tag list, e.g.,
* @code
* SIPTAG_HEADER_STR("Remote-Party-ID: +358718008000")
* SIPTAG_HEADER_STR("P-Alternative-URL: <+358718008000>")
* @endcode
*
* It is also possible to include multiple headers at once

View File

@ -138,7 +138,7 @@ union sip_pref
usize_t spl_length;
} sp_literal;
/** String (tag="&lt;foo&gt;"). */
/** String (tag="&lt;foo&gt;"). */ /* (tag="<foo>") */
struct sp_string {
enum sp_type sps_type;
char const *sps_value;

View File

@ -74,6 +74,135 @@ msg_mclass_t *test_mclass = NULL;
static msg_t *read_message(int flags, char const string[]);
static int test_identity(void)
{
su_home_t *home;
sip_p_asserted_identity_t *paid;
sip_p_preferred_identity_t *ppid;
msg_t *msg;
sip_t *sip;
BEGIN();
msg_href_t const *href;
msg_mclass_t const *def0, *def1, *ext;
def0 = sip_default_mclass();
/* Check that Refer-Sub has been added to our parser */
TEST_1(href = msg_find_hclass(def0, "Refer-Sub", NULL));
TEST_P(href->hr_class, sip_refer_sub_class);
/* Check that Reply-To is not there */
TEST_P(msg_find_hclass(def0, "Reply-To", NULL), def0->mc_unknown);
TEST_1(ext = sip_extend_mclass(NULL));
/* Update default parser */
TEST_1(sip_update_default_mclass(ext) == 0);
def1 = sip_default_mclass();
TEST_1(def0 != def1);
TEST_1(ext == def1);
TEST_1(href = msg_find_hclass(def1, "Reply-To", NULL));
TEST_P(href->hr_class, sip_reply_to_class);
TEST_1(test_mclass = msg_mclass_clone(def0, 0, 0));
msg = read_message(MSG_DO_EXTRACT_COPY,
"BYE sip:foo@bar SIP/2.0\r\n"
"To: <sip:foo@bar>;tag=deadbeef\r\n"
"From: <sip:bar@foo>;\r\n"
"Call-ID: 0ha0isndaksdj@10.1.2.3\r\n"
"CSeq: 8 SUBSCRIBE\r\n"
"Via: SIP/2.0/UDP 135.180.130.133\r\n"
"P-Asserted-Identity: <sip:test@test.domain.com>\r\n"
"P-Preferred-Identity: <sip:test@test.domain.com>, <tel:+358708008000>\r\n"
"Content-Length: 0\r\n"
"\r\n");
sip = sip_object(msg);
TEST_1(!sip_p_asserted_identity(sip));
TEST_1(!sip_p_preferred_identity(sip));
msg_destroy(msg);
TEST_1(msg_mclass_insert_header(test_mclass,
sip_p_asserted_identity_class, 0) > 0);
TEST_1(msg_mclass_insert_header(test_mclass,
sip_p_preferred_identity_class, 0) > 0);
msg = read_message(MSG_DO_EXTRACT_COPY,
"BYE sip:foo@bar SIP/2.0\r\n"
"To: <sip:foo@bar>;tag=deadbeef\r\n"
"From: <sip:bar@foo>;\r\n"
"Call-ID: 0ha0isndaksdj@10.1.2.3\r\n"
"CSeq: 8 SUBSCRIBE\r\n"
"Via: SIP/2.0/UDP 135.180.130.133\r\n"
"P-Asserted-Identity: <sip:test@test.domain.com>\r\n"
"P-Preferred-Identity: <sip:test@test.domain.com>, <tel:+358708008000>\r\n"
"Content-Length: 0\r\n"
"\r\n");
sip = sip_object(msg);
TEST_1(home = msg_home(msg));
TEST_1((paid = sip_p_asserted_identity_make(home, "sip:joe@example.com")));
TEST_1((paid = sip_p_asserted_identity_make
(home, "Jaska <sip:joe@example.com>, Helmi <tel:+3587808000>")));
TEST_1(paid->paid_next);
TEST_1((ppid = sip_p_preferred_identity_make(home, "sip:joe@example.com")));
TEST_1((ppid = sip_p_preferred_identity_make
(home, "Jaska <sip:joe@example.com>, Helmi <tel:+3587808000>")));
msg_destroy(msg);
/* Now with extensions */
TEST_1(test_mclass = msg_mclass_clone(def1, 0, 0));
{
su_home_t *home = su_home_clone(NULL, sizeof *home);
char *s;
char const canonic[] =
"\"Jaska Jokunen\" <sip:jaska.jokunen@example.com>;"
"screen=yes;party=called;id-type=user;privacy=\"name,uri-network\"";
char const canonic2[] =
"Jaska Jokunen <sip:jaska.jokunen@example.com>;"
"screen=yes;party=called;id-type=user;privacy=\"name,uri-network\"";
sip_remote_party_id_t *rpid, *d;
TEST_1(rpid = sip_remote_party_id_make(home, canonic));
TEST_S(rpid->rpid_display, "\"Jaska Jokunen\"");
TEST_S(rpid->rpid_url->url_user, "jaska.jokunen");
TEST_S(rpid->rpid_params[0], "screen=yes");
TEST_S(rpid->rpid_screen, "yes");
TEST_S(rpid->rpid_party, "called");
TEST_S(rpid->rpid_id_type, "user");
TEST_S(rpid->rpid_privacy, "\"name,uri-network\"");
TEST_1(s = sip_header_as_string(home, (void*)rpid));
TEST_S(s, canonic);
TEST_1(d = sip_remote_party_id_dup(home, rpid));
TEST_S(d->rpid_display, rpid->rpid_display);
TEST_S(d->rpid_params[0], rpid->rpid_params[0]);
TEST_1(rpid = sip_remote_party_id_make(home, canonic2));
TEST_S(rpid->rpid_display, "Jaska Jokunen");
TEST_1(s = sip_header_as_string(home, (void*)rpid));
TEST_S(s, canonic2);
TEST_1(d = sip_remote_party_id_dup(home, rpid));
TEST_S(d->rpid_display, rpid->rpid_display);
su_home_check(home);
su_home_zap(home);
}
END();
}
int test_url_headers(void)
{
BEGIN();
@ -84,16 +213,20 @@ int test_url_headers(void)
sip_from_t const *f;
sip_accept_t const *ac;
sip_payload_t const *body;
sip_refer_sub_t rs[1];
TEST_1(home = su_home_new(sizeof *home));
sip_refer_sub_init(rs)->rs_value = "false";
s = sip_headers_as_url_query
(home,
SIPTAG_SUBJECT_STR(";"),
SIPTAG_SUBJECT_STR("kuik"),
SIPTAG_REFER_SUB(rs),
TAG_END());
TEST_1(s);
TEST_S(s, "subject=;");
TEST_S(s, "subject=kuik&refer-sub=false");
s = sip_headers_as_url_query
(home,
@ -2189,7 +2322,7 @@ int test_refer(void)
TEST_1(home = su_home_create());
/* Check that Refer-Sub has already been added to our parser */
/* Check that Refer-Sub has now been added to our parser */
TEST_1(msg_mclass_insert_with_mask(test_mclass, sip_refer_sub_class,
0, 0) == -1);
@ -3334,9 +3467,13 @@ int main(int argc, char *argv[])
tstflags |= tst_verbatim;
#endif
if (!test_mclass)
retval |= test_identity(); fflush(stdout);
if (test_mclass == NULL)
test_mclass = msg_mclass_clone(sip_default_mclass(), 0, 0);
retval |= parser_test(); fflush(stdout);
retval |= test_url_headers(); fflush(stdout);
retval |= test_manipulation(); fflush(stdout);
retval |= test_methods(); fflush(stdout);
@ -3348,7 +3485,7 @@ int main(int argc, char *argv[])
retval |= tag_test(); fflush(stdout);
retval |= parser_tag_test(); fflush(stdout);
retval |= response_phrase_test(); fflush(stdout);
retval |= parser_test(); fflush(stdout);
retval |= sip_header_test(); fflush(stdout);
retval |= test_bad_packet(); fflush(stdout);
retval |= test_sip_list_header(); fflush(stdout);

View File

@ -22,9 +22,10 @@
*
*/
/**@IFILE validator.c
/**@internal @IFILE validator.c
*
* SIP parser tester. This uses output
* SIP parser tester. This uses output from tport dump where messages are
* separated with Control-K ('\v') from each other.
*
* @author Pekka Pessi <Pekka.Pessi@nokia.com>.
*

View File

@ -824,7 +824,7 @@ int soa_get_warning(soa_session_t *ss, char const **return_text)
* nua_options(), #nua_i_options
*/
int soa_get_capability_sdp(soa_session_t const *ss,
sdp_session_t const **return_sdp,
struct sdp_session_s const **return_sdp,
char const **return_sdp_str,
isize_t *return_len)
{
@ -874,7 +874,7 @@ int soa_get_capability_sdp(soa_session_t const *ss,
* nua_options(), #nua_i_options
*/
int soa_set_capability_sdp(soa_session_t *ss,
sdp_session_t const *sdp,
struct sdp_session_s const *sdp,
char const *str, issize_t len)
{
SU_DEBUG_9(("soa_set_capability_sdp(%s::%p, %p, %p, "MOD_ZD") called\n",
@ -956,7 +956,7 @@ soa_base_set_capability_sdp(soa_session_t *ss,
* soa_get_capability_sdp()
*/
int soa_get_user_sdp(soa_session_t const *ss,
sdp_session_t const **return_sdp,
struct sdp_session_s const **return_sdp,
char const **return_sdp_str,
isize_t *return_len)
{
@ -1032,7 +1032,7 @@ int soa_get_user_version(soa_session_t const *ss)
* soa_set_remote_sdp()
*/
int soa_set_user_sdp(soa_session_t *ss,
sdp_session_t const *sdp,
struct sdp_session_s const *sdp,
char const *str, issize_t len)
{
SU_DEBUG_9(("soa_set_user_sdp(%s::%p, %p, %p, "MOD_ZD") called\n",
@ -1073,7 +1073,7 @@ int soa_base_set_user_sdp(soa_session_t *ss,
* soa_get_local_sdp(), soa_get_user_sdp(), soa_get_capability_sdp().
*/
int soa_get_remote_sdp(soa_session_t const *ss,
sdp_session_t const **return_sdp,
struct sdp_session_s const **return_sdp,
char const **return_sdp_str,
isize_t *return_len)
{
@ -1151,7 +1151,7 @@ int soa_get_remote_version(soa_session_t const *ss)
* soa_set_user_sdp(), soa_set_capability_sdp().
*/
int soa_set_remote_sdp(soa_session_t *ss,
sdp_session_t const *sdp,
struct sdp_session_s const *sdp,
char const *str, issize_t len)
{
SU_DEBUG_9(("soa_set_remote_sdp(%s::%p, %p, %p, "MOD_ZD") called\n",
@ -1245,7 +1245,7 @@ int soa_has_received_sdp(soa_session_t const *ss)
* soa_get_user_sdp(), soa_get_remote_sdp(), soa_get_capability_sdp().
*/
int soa_get_local_sdp(soa_session_t const *ss,
sdp_session_t const **return_sdp,
struct sdp_session_s const **return_sdp,
char const **return_sdp_str,
isize_t *return_len)
{
@ -1412,7 +1412,7 @@ int soa_generate_offer(soa_session_t *ss,
if (ss == NULL)
return su_seterrno(EFAULT), -1;
/** @ERROR An operation is already in progress */
/** @ERROR EALREADY An operation is already in progress */
if (ss->ss_in_progress)
return su_seterrno(EALREADY), -1;
@ -1500,7 +1500,7 @@ int soa_generate_answer(soa_session_t *ss,
if (ss == NULL)
return su_seterrno(EFAULT), -1;
/** @ERROR An operation is already in progress. */
/** @ERROR EALREADY An operation is already in progress. */
if (ss->ss_in_progress)
return su_seterrno(EALREADY), -1;
@ -1580,7 +1580,7 @@ int soa_process_answer(soa_session_t *ss,
if (ss == NULL)
return su_seterrno(EFAULT), -1;
/** @ERROR An operation is already in progress. */
/** @ERROR EALREADY An operation is already in progress. */
if (ss->ss_in_progress)
return su_seterrno(EALREADY), -1;
@ -1661,7 +1661,7 @@ int soa_process_reject(soa_session_t *ss,
if (ss == NULL)
return su_seterrno(EFAULT), -1;
/** @ERROR An operation is already in progress. */
/** @ERROR EALREADY An operation is already in progress. */
if (ss->ss_in_progress)
return su_seterrno(EALREADY), -1;

View File

@ -3,7 +3,7 @@
@section soa_meta Module Information
The Sofia SIP @b soa module consists of an asynchronous SDP Offer/Answer engine
library. The interface to library is defined in <soa.h>.
library. The interface to library is defined in <sofia-sip/soa.h>.
@CONTACT Pekka Pessi <Pekka.Pessi@nokia.com>

View File

@ -631,6 +631,8 @@ tag_typedef_t soatag_hold = STRTAG_TYPEDEF(hold);
* Corresponding tag taking a reference parameter is SOATAG_RTP_SELECT_REF().
*
* @sa @RFC3264 section 8.3.3, T.38
*
* @NEW_1_12_7.
*/
tag_typedef_t soatag_ordered_user = BOOLTAG_TYPEDEF(ordered_user);

View File

@ -30,14 +30,14 @@
# Author(s): Pekka Pessi <Pekka.Pessi@nokia.com>.
#
s=${0%/*}
test x$s = x$0 && s=`pwd`
s=`dirname $0`
test x$s = x. && s=`pwd`
PATH=/usr/sbin:/usr/local/sbin:/sbin:$PATH
export PATH
# Test for support for IPv6 on Linux. This probably fails on everything else.
ipv6='sysctl net.ipv6.conf.default.mtu >& /dev/null'
ipv6='sysctl net.ipv6.conf.default.mtu >/dev/null 2>&1'
# Bind not working with IPv6 on RHEL 4:
# client.c:1325: unexpected error: failed to get request's destination: failure
#ipv6=false
@ -46,18 +46,18 @@ port=`expr $$ % \( 65536 - 1024 \) + 1024`
# Try to find a free port
if netstat --ip >/dev/null 2>&1 ; then
while netstat --ip -n -a | fgrep -q ":$port "
while netstat --ip -n -a | fgrep ":$port " > /dev/null
do
port=$(($port + 1))
if [$port = 65536] ; then
port=`expr $port + 1`
if test $port = 65536 ; then
port=1024
fi
done
fi
# No BIND 9, no fun
{ type -p named >/dev/null &&
named -v | grep -q BIND.*9
{ type named >/dev/null &&
named -v | grep BIND.*9 > /dev/null
} || {
echo test_sresolv: there is no BIND 9 named in you path, skipping
exit 77
@ -66,10 +66,10 @@ exit 77
if eval $ipv6
then
# Figure out nice IPv6 address for us
ns=$(ip addr ls | awk '
ns=`ip addr ls | awk '
/^[0-9]:/ { up = ($3 ~ /UP/) && ($3 !~ /LOOPBACK/); }
/inet6 fe80::/ { next; } # no link-local
up && $1 ~ /inet6/ { sub(/\/.*$/, "", $2); print $2; exit 0; }')
up && $1 ~ /inet6/ { sub(/\/.*$/, "", $2); print $2; exit 0; }'`
# Nothing found, use localnode ::1
if test -z "$ns"; then ns=::1 ; fi
@ -113,9 +113,11 @@ search example.com
port $port
EOF
absolute=`cd $s; pwd`
cat > $t/named.conf <<EOF
options {
directory "$(cd $s; pwd)";
directory "$absolute";
pid-file "$t/named.pid";
notify no;
$listen4
@ -164,16 +166,16 @@ done
test -r $t/named.pid || {
echo $0: cannot start named >&2 ;
if fgrep -q -i -e SELINUX=enforcing /etc/selinux/config 2>&/dev/null ; then
if fgrep -i -e SELINUX=enforcing /etc/selinux/config >/dev/null 2>&1 ; then
echo $0: perhaps you have to disable SELinux protection for named
fi
exit 77
}
function kill_named
kill_named ()
{
kill `cat $t/named.pid`
rm $t/named.conf $t/resolv.conf $t/error.conf $t/named.pid
rm $t/named.conf $t/resolv.conf $t/error.conf $t/named.pid 2>/dev/null
rmdir $t
}
trap kill_named EXIT

View File

@ -224,6 +224,10 @@ int test_api_errors(void)
extern void sres_cache_clean(sres_cache_t *cache, time_t now);
#ifndef CLOCK_PROCESS_CPUTIME_ID
#define CLOCK_PROCESS_CPUTIME_ID CLOCK_REALTIME
#endif
static
int test_cache(void)
{
@ -282,7 +286,7 @@ int test_cache(void)
if (t1.tv_nsec < t0.tv_nsec)
t2.tv_sec--, t2.tv_nsec += 1000000000;
printf("sres_cache: stored %u entries: %lu.%09lu sec\n",
N, t2.tv_sec, t2.tv_nsec);
N, (long unsigned)t2.tv_sec, t2.tv_nsec);
}
for (i = 0, N; i < N; i++)
@ -299,7 +303,7 @@ int test_cache(void)
if (t1.tv_nsec < t0.tv_nsec)
t2.tv_sec--, t2.tv_nsec += 1000000000;
printf("sres_cache: cleaned %u entries: %lu.%09lu sec\n",
N, t2.tv_sec, t2.tv_nsec);
N, (long unsigned)t2.tv_sec, t2.tv_nsec);
}
for (i = 0, N; i < N; i++)
@ -321,7 +325,7 @@ int test_cache(void)
if (t1.tv_nsec < t0.tv_nsec)
t2.tv_sec--, t2.tv_nsec += 1000000000;
printf("sres_cache: stored %u entries: %lu.%09lu sec\n",
N, t2.tv_sec, t2.tv_nsec);
N, (long unsigned)t2.tv_sec, t2.tv_nsec);
}
for (i = 0, N; i < N; i++)
@ -339,7 +343,7 @@ int test_cache(void)
if (t1.tv_nsec < t0.tv_nsec)
t2.tv_sec--, t2.tv_nsec += 1000000000;
printf("sres_cache: cleaned %u entries: %lu.%09lu sec\n",
N, t2.tv_sec, t2.tv_nsec);
N, (long unsigned)t2.tv_sec, t2.tv_nsec);
}
for (i = 0, N; i < N; i++) {

View File

@ -22,7 +22,7 @@
*
*/
/**
/**@internal
* @file lookup_stun_server.c
* @brief Test app for STUN DNS-SRV lookups.
*

View File

@ -22,7 +22,7 @@
*
*/
/**
/**@internal
* @file stun.c STUN client module
*
* See RFC 3489/3489bis for further information.

View File

@ -14,9 +14,9 @@ client library.
@section stun_contents Contents of stun Module
The stun module contains the public header files as follows:
- <stun.h> the public API of the module
- <stun_common.h> low-level functions for parsing and encoding STUN messages
- <stun_tag.h> defines the su tags used by stun
- <sofia-sip/stun.h> the public API of the module
- <sofia-sip/stun_common.h> low-level functions for parsing and encoding STUN messages
- <sofia-sip/stun_tag.h> defines the su tags used by stun
@section stun_usage Using Sofia STUN Library

View File

@ -22,7 +22,7 @@
*
*/
/**
/**@internal
* @file stun_common.c
* @brief
*

View File

@ -22,7 +22,7 @@
*
*/
/**
/**@internal
* @file stun_dns.c
* @brief Functins to discover STUN server address using DNS-SRV.
*

View File

@ -22,7 +22,7 @@
*
*/
/**
/**@internal
* @file stun_mini.c
* @brief Minimal stun server
*

View File

@ -22,7 +22,7 @@
*
*/
/**@CFILE stun_tag.c Tags and tag lists for Offer/Answer Engine
/**@internal @CFILE stun_tag.c Tags and tag lists for Offer/Answer Engine
*
* @author Pekka Pessi <Pekka.Pessi@nokia.com>
* @author Martti Mela <Martti.Mela@nokia.com>

View File

@ -73,7 +73,7 @@ libsu_la_SOURCES = \
su_os_nw.c \
su_taglist.c su_tag.c su_tag_io.c \
su_log.c su_global_log.c su_default_log.c su_module_debug.h \
su_md5.c su_uniqueid.c su_bm.c string0.c $(OSXSOURCES)
su_md5.c su_uniqueid.c su_bm.c smoothsort.c string0.c $(OSXSOURCES)
EXTRA_libsu_la_SOURCES = \

View File

@ -0,0 +1,265 @@
/*
* This file is part of the Sofia-SIP package
*
* Copyright (C) 2005 Nokia Corporation.
*
* Contact: Pekka Pessi <pekka.pessi@nokia.com>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public License
* as published by the Free Software Foundation; either version 2.1 of
* the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
* 02110-1301 USA
*
*/
/**@file smoothsort.c
* @brief Smoothsort implementation
*
* Smoothsort is a in-place sorting algorithm with performance of O(NlogN)
* in worst case and O(n) in best case.
*
* @sa <a href="http://www.enterag.ch/hartwig/order/smoothsort.pdf">
* "Smoothsort, an alternative for sorting in-situ", E.D. Dijkstra, EWD796a</a>,
* &lt;http://www.enterag.ch/hartwig/order/smoothsort.pdf&gt;.
*
* @author Pekka Pessi <Pekka.Pessi@nokia.com>
*/
#include "config.h"
#include <assert.h>
#include <stdio.h>
#include <sys/types.h>
/** Description of current stretch */
typedef struct {
size_t b, c; /**< Leonardo numbers */
unsigned longlong p; /**< Concatenation codification */
} stretch;
/** Description of array */
typedef struct
{
void *m;
int (*less)(void *m, size_t a, size_t b);
void (*swap)(void *m, size_t a, size_t b);
} array;
static inline size_t stretch_up(stretch s[1])
{
size_t next;
s->p >>= 1;
next = s->b + s->c + 1, s->c = s->b, s->b = next;
return next;
}
static inline size_t stretch_down(stretch s[1], unsigned bit)
{
size_t next;
s->p <<= 1, s->p |= bit;
next = s->c, s->c = s->b - s->c - 1, s->b = next;
return next;
}
#if DEBUG_SMOOTHSORT
static char const *binary(unsigned long long p)
{
static char binary[65];
int i;
if (p == 0)
return "0";
binary[64] = 0;
for (i = 64; p; p >>= 1)
binary[--i] = "01"[p & 1];
return binary + i;
}
#else
#define DEBUG(x) ((void)0)
#endif
/**
* Sift the root of the stretch.
*
* The low values are sifted up (towards index 0) from root.
*
* @param array description of array to sort
* @param r root of the stretch
* @param s description of current stretch
*/
static void sift(array const *array, size_t r, stretch s)
{
while (s.b >= 3) {
size_t r2 = r - s.b + s.c;
if (!array->less(array->m, r - 1, r2)) {
r2 = r - 1;
stretch_down(&s, 0);
}
if (array->less(array->m, r2, r))
break;
DEBUG(("\tswap(%p @%zu <=> @%zu)\n", array, r, r2));
array->swap(array->m, r, r2); r = r2;
stretch_down(&s, 0);
}
}
/** Trinkle the roots of the given stretches
*
* @param array description of array to sort
* @param r root of the stretch
* @param s description of stretches to concatenate
*/
static void trinkle(array const *array, size_t r, stretch s)
{
DEBUG(("trinkle(%p, %zu, (%u, %s))\n", array, r, s.b, binary(s.p)));
while (s.p != 0) {
size_t r2, r3;
while ((s.p & 1) == 0)
stretch_up(&s);
if (s.p == 1)
break;
r3 = r - s.b;
if (array->less(array->m, r3, r))
break;
s.p--;
if (s.b < 3) {
DEBUG(("\tswap(%p @%zu <=> @%zu b=%u)\n", array, r, r3, s.b));
array->swap(array->m, r, r3); r = r3;
continue;
}
r2 = r - s.b + s.c;
if (array->less(array->m, r2, r - 1)) {
r2 = r - 1;
stretch_down(&s, 0);
}
if (array->less(array->m, r2, r3)) {
DEBUG(("swap(%p [%zu]=[%zu])\n", array, r, r3));
array->swap(array->m, r, r3); r = r3;
continue;
}
DEBUG(("\tswap(%p @%zu <=> @%zu b=%u)\n", array, r, r2, s.b));
array->swap(array->m, r, r2); r = r2;
stretch_down(&s, 0);
break;
}
sift(array, r, s);
}
/** Trinkles the stretches when the adjacent stretches are already trusty.
*
* @param array description of array to sort
* @param r root of the stretch
* @param stretch description of stretches to trinkle
*/
static void semitrinkle(array const *array, size_t r, stretch s)
{
size_t r1 = r - s.c;
DEBUG(("semitrinkle(%p, %zu, (%u, %s))\n", array, r, s.b, binary(s.p)));
if (array->less(array->m, r, r1)) {
DEBUG(("\tswap(%p @%zu <=> @%zu b=%u)\n", array, r, r1, s.b));
array->swap(array->m, r, r1);
trinkle(array, r1, s);
}
}
/** Sort array using smoothsort.
*
* Sort @a N elements from array @a base starting with index @a r with smoothsort.
*
* @param base pointer to array
* @param r lowest index to sort
* @param N number of elements to sort
* @param less comparison function returning nonzero if m[a] < m[b]
* @param swap swapper function exchanging elements m[a] and m[b]
*/
void su_smoothsort(void *base, size_t r, size_t N,
int (*less)(void *m, size_t a, size_t b),
void (*swap)(void *m, size_t a, size_t b))
{
stretch s = { 1, 1, 1 };
size_t q;
array const array[1] = {{ base, less, swap }};
assert(less && swap);
if (base == NULL || N <= 1 || less == NULL || swap == NULL)
return;
DEBUG(("\nsmoothsort(%p, %zu)\n", array, nmemb));
for (q = 1; q != N; q++, r++, s.p++) {
DEBUG(("loop0 q=%zu, b=%u, p=%s \n", q, s.b, binary(s.p)));
if ((s.p & 7) == 3) {
sift(array, r, s), stretch_up(&s), stretch_up(&s);
}
else /* if ((s.p & 3) == 1) */ { assert((s.p & 3) == 1);
if (q + s.c < N)
sift(array, r, s);
else
trinkle(array, r, s);
while (stretch_down(&s, 0) > 1)
;
}
}
trinkle(array, r, s);
for (; q > 1; q--) {
s.p--;
DEBUG(("loop1 q=%zu: b=%u p=%s\n", q, s.b, binary(s.p)));
if (s.b <= 1) {
while ((s.p & 1) == 0)
stretch_up(&s);
--r;
}
else /* if b >= 3 */ {
if (s.p) semitrinkle(array, r - (s.b - s.c), s);
stretch_down(&s, 1);
semitrinkle(array, --r, s);
stretch_down(&s, 1);
}
}
}

View File

@ -22,7 +22,7 @@
*
*/
/**@file memccpy.c
/**@internal @file memccpy.c
* @brief The memccpy() replacement function.
*
* @author Pekka Pessi <Pekka.Pessi@nokia.com>

View File

@ -22,7 +22,7 @@
*
*/
/**@file memcspn.c
/**@internal @file memcspn.c
* @brief The memcspn() replacement function.
*
* @author Pekka Pessi <Pekka.Pessi@nokia.com>

View File

@ -22,7 +22,8 @@
*
*/
/**@file memmem.c
/**@internal @file memmem.c
*
* @brief Backup implementation of memmem()
*
* @author Pekka Pessi <Pekka.Pessi@nokia.com>

View File

@ -22,7 +22,8 @@
*
*/
/**@file memspn.c
/**@internal @file memspn.c
*
* The memspn() replacement function.
*
* @author Pekka Pessi <Pekka.Pessi@nokia.com>

View File

@ -8,7 +8,7 @@ for SU_PORT in select kqueue devpoll epoll poll ; do
export SU_PORT
egrep -q -i '^#define have_(sys_)?'$SU_PORT ../../config.h ||
egrep -i '^#define have_(sys_)?'$SU_PORT ../../config.h >/dev/null ||
continue
run=yes

Some files were not shown because too many files have changed in this diff Show More