Skip to content
GitLab
Menu
Projects
Groups
Snippets
Loading...
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
Menu
Open sidebar
BC
public
external
sofia-sip
Commits
92cad624
Commit
92cad624
authored
Mar 08, 2006
by
Pekka Pessi
Browse files
Split nua_stack.c into multiple files.
darcs-hash:20060308162955-65a35-a80f73008ddae5845d2dc72deef893af15e73c9f.gz
parent
ff1e0e09
Changes
14
Expand all
Hide whitespace changes
Inline
Side-by-side
Showing
14 changed files
with
6168 additions
and
5366 deletions
+6168
-5366
libsofia-sip-ua/nua/Makefile.am
libsofia-sip-ua/nua/Makefile.am
+6
-0
libsofia-sip-ua/nua/nua.c
libsofia-sip-ua/nua/nua.c
+13
-52
libsofia-sip-ua/nua/nua_dialog.c
libsofia-sip-ua/nua/nua_dialog.c
+452
-0
libsofia-sip-ua/nua/nua_dialog.h
libsofia-sip-ua/nua/nua_dialog.h
+177
-0
libsofia-sip-ua/nua/nua_event_server.c
libsofia-sip-ua/nua/nua_event_server.c
+349
-0
libsofia-sip-ua/nua/nua_message.c
libsofia-sip-ua/nua/nua_message.c
+185
-0
libsofia-sip-ua/nua/nua_options.c
libsofia-sip-ua/nua/nua_options.c
+146
-0
libsofia-sip-ua/nua/nua_publish.c
libsofia-sip-ua/nua/nua_publish.c
+236
-0
libsofia-sip-ua/nua/nua_register.c
libsofia-sip-ua/nua/nua_register.c
+392
-0
libsofia-sip-ua/nua/nua_session.c
libsofia-sip-ua/nua/nua_session.c
+2461
-0
libsofia-sip-ua/nua/nua_stack.c
libsofia-sip-ua/nua/nua_stack.c
+340
-5189
libsofia-sip-ua/nua/nua_stack.h
libsofia-sip-ua/nua/nua_stack.h
+166
-125
libsofia-sip-ua/nua/nua_subnotref.c
libsofia-sip-ua/nua/nua_subnotref.c
+975
-0
libsofia-sip-ua/nua/nua_tag_ref.c
libsofia-sip-ua/nua/nua_tag_ref.c
+270
-0
No files found.
libsofia-sip-ua/nua/Makefile.am
View file @
92cad624
...
...
@@ -29,6 +29,8 @@ noinst_PROGRAMS = test_nua
TESTS
=
test_nua
CLEANFILES
=
tmp_sippasswd.??????
# ----------------------------------------------------------------------
# Rules for building the targets
...
...
@@ -38,6 +40,10 @@ nobase_include_sofia_HEADERS = \
sofia-sip/nua.h sofia-sip/nua_tag.h
libnua_la_SOURCES
=
nua.c nua_stack.h nua_common.c nua_stack.c
\
nua_dialog.c
\
nua_register.c nua_session.c nua_options.c
\
nua_message.c nua_publish.c nua_subnotref.c
\
nua_event_server.c
\
nua_tag.c nua_tag_ref.c
COVERAGE_INPUT
=
$(libnua_la_SOURCES)
$(include_sofia_HEADERS)
...
...
libsofia-sip-ua/nua/nua.c
View file @
92cad624
...
...
@@ -25,6 +25,8 @@
/**@CFILE nua.c Nokia User Agent API.
*
* @author Pekka Pessi <Pekka.Pessi@nokia.com>
* @author Kai Vehmanen <Kai.Vehmanen@nokia.com>
* @author Pasi Rinne-Rahkola
*
* @date Created: Wed Feb 14 18:32:58 2001 ppessi
*
...
...
@@ -35,18 +37,10 @@
/* From AM_INIT/AC_INIT in our "config.h" */
char
const
nua_version
[]
=
VERSION
;
#include <stddef.h>
#include <stdlib.h>
#include <string.h>
#include <assert.h>
#include <sofia-sip/su_tag.h>
#include <sofia-sip/su_tag_class.h>
#include <sofia-sip/su_tagarg.h>
#include <stdio.h>
#include <sofia-sip/su_tag_io.h>
#define SU_LOG (nua_log)
...
...
@@ -54,54 +48,21 @@ char const nua_version[] = VERSION;
#define SU_ROOT_MAGIC_T struct nua_s
#define SU_MSG_ARG_T struct event_s
#include <sofia-sip/su_wait.h>
#include <sofia-sip/su_strlst.h>
#define NUA_SAVED_EVENT_T su_msg_t *
#include "sofia-sip/nua.h"
#include "sofia-sip/nua_tag.h"
#define NTA_AGENT_MAGIC_T struct nua_s
#define NTA_LEG_MAGIC_T struct nua_handle_s
#define NTA_OUTGOING_MAGIC_T struct nua_handle_s
#define NTA_INCOMING_MAGIC_T struct nua_handle_s
#define NTR_AGENT_MAGIC_T struct nua_s
#define NTR_SESSION_MAGIC_T struct nua_handle_s
#define NTR_OUTGOING_MAGIC_T struct nua_handle_s
#define NTR_INCOMING_MAGIC_T struct nua_handle_s
#define NEA_SMAGIC_T nua_handle_t
#define NEA_EMAGIC_T nua_handle_t
#include <sofia-sip/sip.h>
#include <sofia-sip/sip_header.h>
#include <sofia-sip/sip_status.h>
#include <sofia-sip/sip_util.h>
#include <sofia-sip/sip_header.h>
#include <sofia-sip/nta.h>
#include <sofia-sip/nea.h>
#include <sofia-sip/tport_tag.h>
#if HAVE_UICC_H
#include <uicc.h>
#endif
#include <sofia-sip/auth_client.h>
#if HAVE_SMIME
/* Start NRC Boston */
#include "smimec.h"
#endif
/* End NRC Boston */
#include <sofia-sip/sdp.h>
#include <sofia-sip/sl_utils.h>
#include "sofia-sip/nua.h"
#include "sofia-sip/nua_tag.h"
#include "nua_stack.h"
#undef nua_default
#include <stddef.h>
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#include <assert.h>
/**@var NUA_DEBUG
*
...
...
@@ -191,8 +152,8 @@ nua_t *nua_create(su_root_t *root,
if
(
su_clone_start
(
root
,
nua
->
nua_clone
,
nua
,
ua_init
,
ua_deinit
)
==
SU_SUCCESS
)
{
n
ua_
stack_
init
,
n
ua_
stack_
deinit
)
==
SU_SUCCESS
)
{
su_task_copy
(
nua
->
nua_server
,
su_clone_task
(
nua
->
nua_clone
));
nua
->
nua_callback
=
callback
;
nua
->
nua_magic
=
magic
;
...
...
@@ -1400,7 +1361,7 @@ void nua_signal(nua_t *nua, nua_handle_t *nh, msg_t *msg, int always,
xtra
=
tl_xtra
(
ta_args
(
ta
),
len
);
if
(
su_msg_create
(
sumsg
,
nua
->
nua_server
,
nua
->
nua_client
,
ua_signal
,
n
ua_
stack_
signal
,
e_len
+
len
+
l_len
+
xtra
+
l_xtra
)
==
0
)
{
event_t
*
e
=
su_msg_data
(
sumsg
);
tagi_t
*
t
=
e
->
e_tags
;
...
...
libsofia-sip-ua/nua/nua_dialog.c
0 → 100644
View file @
92cad624
/*
* This file is part of the Sofia-SIP package
*
* Copyright (C) 2006 Nokia Corporation.
*
* Contact: Pekka Pessi <pekka.pessi@nokia.com>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public License
* as published by the Free Software Foundation; either version 2.1 of
* the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
* 02110-1301 USA
*
*/
/**@CFILE nua_dialog.c
* @brief Dialog and dialog usage handling
*
* @author Pekka Pessi <Pekka.Pessi@nokia.com>
*
* @date Created: Wed Mar 8 11:48:49 EET 2006 ppessi
*/
#include "config.h"
#include <stddef.h>
#include <stdlib.h>
#include <string.h>
#include <limits.h>
#include <assert.h>
#include <sofia-sip/string0.h>
#include <sofia-sip/sip_protos.h>
#include "nua_dialog.h"
/* ======================================================================== */
/* Dialog handling */
static
void
nua_dialog_usage_remove_at
(
nua_handle_t
*
,
nua_dialog_state_t
*
,
nua_dialog_usage_t
**
);
static
void
nua_dialog_log_usage
(
nua_handle_t
*
,
nua_dialog_state_t
*
);
/** UAS tag and route */
void
nua_dialog_uas_route
(
nua_handle_t
*
nh
,
sip_t
const
*
sip
,
int
rtag
)
{
struct
nua_dialog_state
*
ds
=
nh
->
nh_ds
;
int
established
=
nua_dialog_is_established
(
ds
);
if
(
!
established
&&
sip
->
sip_from
->
a_tag
)
ds
->
ds_remote_tag
=
su_strdup
(
nh
->
nh_home
,
sip
->
sip_from
->
a_tag
);
if
(
ds
->
ds_leg
==
NULL
)
return
;
nta_leg_server_route
(
ds
->
ds_leg
,
sip
->
sip_record_route
,
sip
->
sip_contact
);
ds
->
ds_route
=
ds
->
ds_route
||
sip
->
sip_record_route
||
sip
->
sip_contact
;
if
(
rtag
&&
!
established
&&
sip
->
sip_from
->
a_tag
)
nta_leg_rtag
(
ds
->
ds_leg
,
sip
->
sip_from
->
a_tag
);
}
/** UAC tag and route.
*
* Update dialog tags and route on the UAC side.
*
* @param nh NUA handle
* @param sip SIP message containing response used to update dialog
* @param rtag if true, set remote tag within the leg
*/
void
nua_dialog_uac_route
(
nua_handle_t
*
nh
,
sip_t
const
*
sip
,
int
rtag
)
{
struct
nua_dialog_state
*
ds
=
nh
->
nh_ds
;
int
established
=
nua_dialog_is_established
(
ds
);
if
(
!
established
&&
sip
->
sip_to
->
a_tag
)
ds
->
ds_remote_tag
=
su_strdup
(
nh
->
nh_home
,
sip
->
sip_to
->
a_tag
);
if
(
ds
->
ds_leg
==
NULL
)
return
;
nta_leg_client_route
(
ds
->
ds_leg
,
sip
->
sip_record_route
,
sip
->
sip_contact
);
ds
->
ds_route
=
ds
->
ds_route
||
sip
->
sip_record_route
||
sip
->
sip_contact
;
if
(
rtag
&&
!
established
&&
sip
->
sip_to
->
a_tag
)
nta_leg_rtag
(
ds
->
ds_leg
,
sip
->
sip_to
->
a_tag
);
}
/** Store information from remote endpoint. */
void
nua_dialog_get_peer_info
(
nua_handle_t
*
nh
,
sip_t
const
*
sip
)
{
nua_remote_t
*
nr
=
nh
->
nh_ds
->
ds_remote_ua
,
old
[
1
];
*
old
=
*
nr
;
if
(
sip
->
sip_allow
)
{
nr
->
nr_allow
=
sip_allow_dup
(
nh
->
nh_home
,
sip
->
sip_allow
);
su_free
(
nh
->
nh_home
,
old
->
nr_allow
);
}
if
(
sip
->
sip_accept
)
{
nr
->
nr_accept
=
sip_accept_dup
(
nh
->
nh_home
,
sip
->
sip_accept
);
su_free
(
nh
->
nh_home
,
old
->
nr_accept
);
}
if
(
sip
->
sip_require
)
{
nr
->
nr_require
=
sip_require_dup
(
nh
->
nh_home
,
sip
->
sip_require
);
su_free
(
nh
->
nh_home
,
old
->
nr_require
);
}
if
(
sip
->
sip_supported
)
{
nr
->
nr_supported
=
sip_supported_dup
(
nh
->
nh_home
,
sip
->
sip_supported
);
su_free
(
nh
->
nh_home
,
old
->
nr_supported
);
}
if
(
sip
->
sip_user_agent
)
{
nr
->
nr_user_agent
=
sip_user_agent_dup
(
nh
->
nh_home
,
sip
->
sip_user_agent
);
su_free
(
nh
->
nh_home
,
old
->
nr_user_agent
);
}
}
/** Get dialog usage slot */
nua_dialog_usage_t
**
nua_dialog_usage_at
(
nua_dialog_state_t
const
*
ds
,
nua_usage_class
const
*
kind
,
sip_event_t
const
*
event
)
{
static
nua_dialog_usage_t
*
none
=
NULL
;
if
(
ds
)
{
nua_dialog_usage_t
*
du
,
*
const
*
prev
;
sip_event_t
const
*
o
;
for
(
prev
=
&
ds
->
ds_usage
;
(
du
=
*
prev
);
prev
=
&
du
->
du_next
)
{
if
(
du
->
du_class
!=
kind
)
continue
;
if
(
event
==
NONE
)
return
(
nua_dialog_usage_t
**
)
prev
;
o
=
du
->
du_event
;
if
(
!
event
&&
!
o
)
return
(
nua_dialog_usage_t
**
)
prev
;
if
(
event
!=
o
)
{
if
(
event
==
NULL
||
o
==
NULL
)
continue
;
if
(
strcmp
(
event
->
o_type
,
o
->
o_type
))
continue
;
if
(
str0casecmp
(
event
->
o_id
,
o
->
o_id
))
continue
;
}
return
(
nua_dialog_usage_t
**
)
prev
;
}
}
return
&
none
;
}
/** Get a dialog usage */
nua_dialog_usage_t
*
nua_dialog_usage_get
(
nua_dialog_state_t
const
*
ds
,
nua_usage_class
const
*
kind
,
sip_event_t
const
*
event
)
{
return
*
nua_dialog_usage_at
(
ds
,
kind
,
event
);
}
/** Get dialog usage name */
char
const
*
nua_dialog_usage_name
(
nua_dialog_usage_t
const
*
du
)
{
if
(
du
==
NULL
)
return
"<NULL>"
;
return
du
->
du_class
->
usage_name
(
du
);
}
/** Add dialog usage */
nua_dialog_usage_t
*
nua_dialog_usage_add
(
nua_handle_t
*
nh
,
struct
nua_dialog_state
*
ds
,
nua_usage_class
const
*
uclass
,
sip_event_t
const
*
event
)
{
if
(
ds
)
{
sip_event_t
*
o
;
nua_dialog_usage_t
*
du
,
**
prev_du
;
prev_du
=
nua_dialog_usage_at
(
ds
,
uclass
,
event
);
du
=
*
prev_du
;
if
(
du
)
{
/* Already exists */
SU_DEBUG_5
((
"nua(%p): adding already existing %s usage%s%s
\n
"
,
nh
,
nua_dialog_usage_name
(
du
),
event
?
" with event "
:
""
,
event
?
event
->
o_type
:
""
));
if
(
prev_du
!=
&
ds
->
ds_usage
)
{
/* Move as a first usage in the list */
*
prev_du
=
du
->
du_next
;
du
->
du_next
=
ds
->
ds_usage
;
ds
->
ds_usage
=
du
;
}
return
du
;
}
o
=
event
?
sip_event_dup
(
nh
->
nh_home
,
event
)
:
NULL
;
if
(
o
!=
NULL
||
event
==
NULL
)
du
=
su_zalloc
(
nh
->
nh_home
,
sizeof
*
du
+
uclass
->
usage_size
);
if
(
du
)
{
du
->
du_class
=
uclass
;
du
->
du_event
=
o
;
if
(
uclass
->
usage_add
(
nh
,
ds
,
du
)
<
0
)
{
su_free
(
nh
->
nh_home
,
o
);
su_free
(
nh
->
nh_home
,
du
);
return
NULL
;
}
SU_DEBUG_5
((
"nua(%p): adding %s usage%s%s
\n
"
,
nh
,
nua_dialog_usage_name
(
du
),
o
?
" with event "
:
""
,
o
?
o
->
o_type
:
""
));
nua_handle_ref
(
nh
);
du
->
du_next
=
ds
->
ds_usage
,
ds
->
ds_usage
=
du
;
return
du
;
}
su_free
(
nh
->
nh_home
,
o
);
}
return
NULL
;
}
/** Remove dialog usage. */
void
nua_dialog_usage_remove
(
nua_handle_t
*
nh
,
nua_dialog_state_t
*
ds
,
nua_dialog_usage_t
*
du
)
{
nua_dialog_usage_t
**
at
;
assert
(
nh
);
assert
(
ds
);
assert
(
du
);
for
(
at
=
&
ds
->
ds_usage
;
*
at
;
at
=
&
(
*
at
)
->
du_next
)
if
(
du
==
*
at
)
break
;
assert
(
*
at
);
nua_dialog_usage_remove_at
(
nh
,
ds
,
at
);
}
/** Remove dialog usage.
*
* Zap dialog state (leg, tag and route) if no usages remain.
*/
static
void
nua_dialog_usage_remove_at
(
nua_handle_t
*
nh
,
nua_dialog_state_t
*
ds
,
nua_dialog_usage_t
**
at
)
{
if
(
*
at
)
{
nua_dialog_usage_t
*
du
=
*
at
;
sip_event_t
const
*
o
=
NULL
;
*
at
=
du
->
du_next
;
o
=
du
->
du_event
;
SU_DEBUG_5
((
"nua(%p): removing %s usage%s%s
\n
"
,
nh
,
nua_dialog_usage_name
(
du
),
o
?
" with event "
:
""
,
o
?
o
->
o_type
:
""
));
du
->
du_class
->
usage_remove
(
nh
,
ds
,
du
);
msg_destroy
(
du
->
du_msg
);
nua_handle_unref
(
nh
);
su_free
(
nh
->
nh_home
,
du
);
}
/* Zap dialog if there is no more usages */
if
(
ds
->
ds_usage
==
NULL
)
{
nta_leg_destroy
(
ds
->
ds_leg
),
ds
->
ds_leg
=
NULL
;
su_free
(
nh
->
nh_home
,
(
void
*
)
ds
->
ds_remote_tag
),
ds
->
ds_remote_tag
=
NULL
;
ds
->
ds_route
=
0
;
ds
->
ds_has_events
=
0
;
ds
->
ds_terminated
=
0
;
return
;
}
else
if
(
!
ds
->
ds_terminated
)
{
nua_dialog_log_usage
(
nh
,
ds
);
}
}
static
void
nua_dialog_log_usage
(
nua_handle_t
*
nh
,
nua_dialog_state_t
*
ds
)
{
nua_dialog_usage_t
*
du
;
if
(
nua_log
->
log_level
>=
3
)
{
char
buffer
[
160
];
int
l
=
0
,
n
,
N
=
sizeof
buffer
;
buffer
[
0
]
=
'\0'
;
for
(
du
=
ds
->
ds_usage
;
du
;
du
=
du
->
du_next
)
{
msg_header_t
const
*
h
=
(
void
*
)
du
->
du_event
;
if
(
!
h
)
continue
;
n
=
sip_event_e
(
buffer
+
l
,
N
-
l
,
h
,
0
);
if
(
n
==
-
1
)
break
;
l
+=
n
;
if
(
du
->
du_next
&&
l
+
2
<
sizeof
(
buffer
))
{
strcpy
(
buffer
+
l
,
", "
);
l
+=
2
;
}
}
SU_DEBUG_3
((
"nua(%p): handle with %s%s%s
\n
"
,
nh
,
ds
->
ds_has_session
?
"session and "
:
""
,
ds
->
ds_has_events
?
"events "
:
""
,
buffer
));
}
}
/** Dialog has been terminated. */
void
nua_dialog_terminated
(
nua_handle_t
*
nh
,
struct
nua_dialog_state
*
ds
,
int
status
,
char
const
*
phrase
)
{
ds
->
ds_terminated
=
1
;
while
(
ds
->
ds_usage
)
{
#if 0
int call = 0;
if (ds->ds_usage->du_kind == nua_session_usage)
call = 1; /* Delay sending the event */
else
/* XXX */;
#endif
nua_dialog_usage_remove_at
(
nh
,
ds
,
&
ds
->
ds_usage
);
}
}
/** Set refresh value suitably.
*
* The refresh time is set either at half of the @a delta interval or if @a
* delta is less than 5 minutes, 30 seconds before end of interval. $
*
* If @a delta is 0, the refresh time is set at the end of the world
* (maximum time, for 32-bit systems sometimes during 2036).
*/
void
nua_dialog_usage_set_refresh
(
nua_dialog_usage_t
*
du
,
unsigned
delta
)
{
sip_time_t
target
=
sip_now
();
if
(
delta
>
60
&&
delta
<
5
*
60
)
/* refresh 30 seconds before deadline */
delta
-=
30
;
else
/* refresh at half time before deadline */
delta
/=
2
;
if
(
target
+
delta
>=
target
)
target
=
target
+
delta
;
else
target
=
SIP_TIME_MAX
;
du
->
du_refresh
=
target
;
}
#if 0
switch (kind) {
case nua_session_usage:
ds->ds_has_session = 0;
break;
case nua_notifier_usage:
su_free(nh->nh_home, (void *)du->du_event);
ds->ds_has_notifier = NULL != *nua_dialog_usage_at(ds, kind, NONE);
ds->ds_has_events = ds->ds_has_notifier || ds->ds_has_subscription;
break;
case nua_subscriber_usage:
su_free(nh->nh_home, (void *)du->du_event);
ds->ds_has_subscription = NULL != *nua_dialog_usage_at(ds, kind, NONE);
ds->ds_has_events = ds->ds_has_subscription || ds->ds_has_notifier;
msg_destroy(du->du_subscriber->de_msg);
break;
case nua_register_usage:
ds->ds_has_register = 0;
msg_destroy(du->du_register->ru_msg);
break;
case nua_publish_usage:
ds->ds_has_publish = 0;
su_free(nh->nh_home, du->du_publisher->pu_etag);
break;
case nua_transaction_usage:
default:
break;
}
switch (kind) {
case nua_session_usage:
ds->ds_has_session = 1;
break;
case nua_notifier_usage:
ds->ds_has_events = 1;
ds->ds_has_notifier = 1;
break;
case nua_subscriber_usage:
ds->ds_has_events = 1;
ds->ds_has_subscription = 1;
break;
case nua_register_usage:
ds->ds_has_register = 1;
break;
case nua_publish_usage:
ds->ds_has_publish = 1;
break;
case nua_transaction_usage:
default:
break;
}
typedef struct {
void (*nua_dialog_destructor)(nua_handle_t *nh,
nua_dialog_usage_t *du);
} nua_usage_class;
#endif
libsofia-sip-ua/nua/nua_dialog.h
0 → 100644
View file @
92cad624
/*
* 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
*
*/
#ifndef NUA_DIALOG_H
/** Defined when <nua_dialog.h> has been included. */
#define NUA_DIALOG_H
/**@file nua_dialog.h
* @brief Dialog and dialog usage handling
*