Skip to content
GitLab
Projects
Groups
Snippets
Help
Loading...
Help
What's new
10
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
Open sidebar
BC
public
belle-sip
Commits
7ddd3dda
Commit
7ddd3dda
authored
Oct 17, 2012
by
jehan
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
implements invite transaction cancelling
parent
a6a62138
Changes
9
Hide whitespace changes
Inline
Side-by-side
Showing
9 changed files
with
53 additions
and
17 deletions
+53
-17
include/belle-sip/listener.h
include/belle-sip/listener.h
+5
-1
include/belle-sip/transaction.h
include/belle-sip/transaction.h
+1
-1
src/belle_sip_internal.h
src/belle_sip_internal.h
+2
-2
src/dialog.c
src/dialog.c
+7
-0
src/ist.c
src/ist.c
+5
-0
src/provider.c
src/provider.c
+19
-7
src/siplistener.c
src/siplistener.c
+3
-1
src/transaction.c
src/transaction.c
+10
-5
tester/belle_sip_dialog_tester.c
tester/belle_sip_dialog_tester.c
+1
-0
No files found.
include/belle-sip/listener.h
View file @
7ddd3dda
...
...
@@ -41,15 +41,19 @@ BELLE_SIP_DECLARE_INTERFACE_END
#define BELLE_SIP_LISTENER(obj) BELLE_SIP_INTERFACE_CAST(obj,belle_sip_listener_t)
/*Response event*/
belle_sip_response_t
*
belle_sip_response_event_get_response
(
const
belle_sip_response_event_t
*
event
);
belle_sip_client_transaction_t
*
belle_sip_response_event_get_client_transaction
(
const
belle_sip_response_event_t
*
event
);
belle_sip_dialog_t
*
belle_sip_response_event_get_dialog
(
const
belle_sip_response_event_t
*
event
);
/*Request event*/
belle_sip_request_t
*
belle_sip_request_event_get_request
(
const
belle_sip_request_event_t
*
event
);
belle_sip_server_transaction_t
*
belle_sip_request_event_get_server_transaction
(
const
belle_sip_request_event_t
*
event
);
belle_sip_dialog_t
*
belle_sip_request_event_get_dialog
(
const
belle_sip_request_event_t
*
event
);
/*Dialog terminated event*/
belle_sip_dialog_t
*
belle_sip_dialog_terminated_get_dialog
(
const
belle_sip_dialog_terminated_event_t
*
event
);
/*auth event*/
const
char
*
belle_sip_auth_event_get_username
(
const
belle_sip_auth_event_t
*
event
);
void
belle_sip_auth_event_set_username
(
belle_sip_auth_event_t
*
event
,
const
char
*
value
);
...
...
include/belle-sip/transaction.h
View file @
7ddd3dda
...
...
@@ -43,7 +43,7 @@ belle_sip_dialog_t* belle_sip_transaction_get_dialog(const belle_sip_transactio
void
belle_sip_server_transaction_send_response
(
belle_sip_server_transaction_t
*
t
,
belle_sip_response_t
*
resp
);
belle_sip_request_t
*
belle_sip_client_transaction_create_cancel
(
belle_sip_client_transaction_t
*
t
);
void
belle_sip_client_transaction_send_request
(
belle_sip_client_transaction_t
*
t
);
int
belle_sip_client_transaction_send_request
(
belle_sip_client_transaction_t
*
t
);
/**
* Create an authenticated request based on an existing terminated transaction
* */
...
...
src/belle_sip_internal.h
View file @
7ddd3dda
...
...
@@ -237,7 +237,7 @@ void belle_sip_fd_source_init(belle_sip_source_t *s, belle_sip_source_func_t fun
#ifdef __cplusplus
extern
"C"
{
extern
"C"
{
#endif
...
...
@@ -563,7 +563,7 @@ static inline const belle_sip_timer_config_t * belle_sip_transaction_get_timer_c
static
inline
void
belle_sip_transaction_start_timer
(
belle_sip_transaction_t
*
obj
,
belle_sip_source_t
*
timer
){
belle_sip_main_loop_add_source
(
obj
->
provider
->
stack
->
ml
,
timer
);
}
/** */
static
inline
void
belle_sip_transaction_stop_timer
(
belle_sip_transaction_t
*
obj
,
belle_sip_source_t
*
timer
){
belle_sip_main_loop_remove_source
(
obj
->
provider
->
stack
->
ml
,
timer
);
}
...
...
src/dialog.c
View file @
7ddd3dda
...
...
@@ -206,6 +206,13 @@ int belle_sip_dialog_establish(belle_sip_dialog_t *obj, belle_sip_request_t *req
obj
->
state
=
BELLE_SIP_DIALOG_CONFIRMED
;
obj
->
needs_ack
=
TRUE
;
}
else
return
-
1
;
}
else
if
(
code
>=
300
&&
obj
->
state
!=
BELLE_SIP_DIALOG_CONFIRMED
)
{
/*12.3 Termination of a Dialog
Independent of the method, if a request outside of a dialog generates
a non-2xx final response, any early dialogs created through
provisional responses to that request are terminated. The mechanism
for terminating confirmed dialogs is method specific.*/
belle_sip_dialog_delete
(
obj
);
}
return
0
;
}
...
...
src/ist.c
View file @
7ddd3dda
...
...
@@ -28,21 +28,26 @@ static void ist_destroy(belle_sip_ist_t *obj){
static
void
ist_on_terminate
(
belle_sip_ist_t
*
obj
){
belle_sip_transaction_t
*
base
=
(
belle_sip_transaction_t
*
)
obj
;
/*timer pointers are set to NULL because they can be released later*/
if
(
obj
->
timer_G
){
belle_sip_transaction_stop_timer
(
base
,
obj
->
timer_G
);
belle_sip_object_unref
(
obj
->
timer_G
);
obj
->
timer_G
=
NULL
;
}
if
(
obj
->
timer_H
){
belle_sip_transaction_stop_timer
(
base
,
obj
->
timer_H
);
belle_sip_object_unref
(
obj
->
timer_H
);
obj
->
timer_H
=
NULL
;
}
if
(
obj
->
timer_I
){
belle_sip_transaction_stop_timer
(
base
,
obj
->
timer_I
);
belle_sip_object_unref
(
obj
->
timer_I
);
obj
->
timer_I
=
NULL
;
}
if
(
obj
->
timer_L
){
belle_sip_transaction_stop_timer
(
base
,
obj
->
timer_L
);
belle_sip_object_unref
(
obj
->
timer_L
);
obj
->
timer_L
=
NULL
;
}
}
...
...
src/provider.c
View file @
7ddd3dda
...
...
@@ -94,6 +94,7 @@ static void belle_sip_provider_dispatch_request(belle_sip_provider_t* prov, bell
ev
.
request
=
req
;
BELLE_SIP_PROVIDER_INVOKE_LISTENERS
(
prov
,
process_request_event
,
&
ev
);
}
belle_sip_object_unref
(
req
);
}
static
void
belle_sip_provider_dispatch_response
(
belle_sip_provider_t
*
prov
,
belle_sip_response_t
*
msg
){
...
...
@@ -117,6 +118,7 @@ static void belle_sip_provider_dispatch_response(belle_sip_provider_t* prov, bel
event
.
response
=
msg
;
BELLE_SIP_PROVIDER_INVOKE_LISTENERS
(
prov
,
process_response_event
,
&
event
);
}
belle_sip_object_unref
(
msg
);
}
static
void
belle_sip_provider_dispatch_message
(
belle_sip_provider_t
*
prov
,
belle_sip_message_t
*
msg
){
...
...
@@ -333,7 +335,11 @@ void belle_sip_provider_add_dialog(belle_sip_provider_t *prov, belle_sip_dialog_
}
void
belle_sip_provider_remove_dialog
(
belle_sip_provider_t
*
prov
,
belle_sip_dialog_t
*
dialog
){
belle_sip_dialog_terminated_event_t
ev
;
ev
.
source
=
prov
;
ev
.
dialog
=
dialog
;
prov
->
dialogs
=
belle_sip_list_remove
(
prov
->
dialogs
,
dialog
);
BELLE_SIP_PROVIDER_INVOKE_LISTENERS
(
prov
,
process_dialog_terminated
,
&
ev
);
belle_sip_object_unref
(
dialog
);
}
...
...
@@ -493,7 +499,7 @@ struct server_transaction_matcher{
const
char
*
branchid
;
const
char
*
method
;
const
char
*
sentby
;
int
is_ack
;
int
is_ack
_or_cancel
;
};
static
int
rfc3261_server_transaction_match
(
const
void
*
p_tr
,
const
void
*
p_matcher
){
...
...
@@ -502,7 +508,7 @@ static int rfc3261_server_transaction_match(const void *p_tr, const void *p_matc
const
char
*
req_method
=
belle_sip_request_get_method
(
tr
->
base
.
request
);
if
(
strcmp
(
matcher
->
branchid
,
tr
->
base
.
branch_id
)
==
0
){
if
(
strcmp
(
matcher
->
method
,
req_method
)
==
0
)
return
0
;
if
(
matcher
->
is_ack
&&
strcmp
(
req_method
,
"INVITE"
)
==
0
)
return
0
;
if
(
matcher
->
is_ack
_or_cancel
&&
strcmp
(
req_method
,
"INVITE"
)
==
0
)
return
0
;
}
return
-
1
;
}
...
...
@@ -518,10 +524,10 @@ belle_sip_server_transaction_t * belle_sip_provider_find_matching_server_transac
}
matcher
.
branchid
=
belle_sip_header_via_get_branch
(
via
);
matcher
.
method
=
belle_sip_request_get_method
(
req
);
matcher
.
is_ack
=
(
strcmp
(
matcher
.
method
,
"ACK"
)
==
0
);
matcher
.
is_ack
_or_cancel
=
(
strcmp
(
matcher
.
method
,
"ACK"
)
==
0
||
strcmp
(
matcher
.
method
,
"CANCEL"
)
==
0
);
if
(
strncmp
(
matcher
.
branchid
,
BELLE_SIP_BRANCH_MAGIC_COOKIE
,
strlen
(
BELLE_SIP_BRANCH_MAGIC_COOKIE
))
==
0
){
/*compliant to RFC3261*/
elem
=
belle_sip_list_find_custom
(
prov
->
client
_transactions
,
rfc3261_server_transaction_match
,
&
matcher
);
elem
=
belle_sip_list_find_custom
(
prov
->
server
_transactions
,
rfc3261_server_transaction_match
,
&
matcher
);
}
else
{
//FIXME
}
...
...
@@ -598,18 +604,24 @@ int belle_sip_provider_add_authorization(belle_sip_provider_t *p, belle_sip_requ
const
char
*
ha1
;
char
computed_ha1
[
33
];
int
result
=
0
;
const
char
*
request_method
;
/*check params*/
if
(
!
p
||
!
request
)
{
belle_sip_error
(
"belle_sip_provider_add_authorization bad parameters"
);
return
-
1
;
}
request_method
=
belle_sip_request_get_method
(
request
);
if
(
strcmp
(
"CANCEL"
,
request_method
)
==
0
||
strcmp
(
"ACK"
,
request_method
)
==
0
)
{
belle_sip_debug
(
"no authorization header needed for method [%s]"
,
request_method
);
return
0
;
}
/*get authenticates value from response*/
if
(
resp
)
{
call_id
=
belle_sip_message_get_header_by_type
(
BELLE_SIP_MESSAGE
(
resp
),
belle_sip_header_call_id_t
);
/*searching for authentication headers*/
head
=
authenticate_lst
=
belle_sip_list_copy
(
belle_sip_message_get_headers
(
BELLE_SIP_MESSAGE
(
resp
),
BELLE_SIP_WWW_AUTHENTICATE
));
authenticate_lst
=
belle_sip_list_copy
(
belle_sip_message_get_headers
(
BELLE_SIP_MESSAGE
(
resp
),
BELLE_SIP_WWW_AUTHENTICATE
));
/*search for proxy authenticate*/
authenticate_lst
=
belle_sip_list_append_link
(
authenticate_lst
,
belle_sip_list_copy
(
belle_sip_message_get_headers
(
BELLE_SIP_MESSAGE
(
resp
),
BELLE_SIP_PROXY_AUTHENTICATE
)));
/*update auth contexts with authenticate headers from response*/
...
...
@@ -617,7 +629,7 @@ int belle_sip_provider_add_authorization(belle_sip_provider_t *p, belle_sip_requ
authenticate
=
BELLE_SIP_HEADER_WWW_AUTHENTICATE
(
authenticate_lst
->
data
);
belle_sip_provider_update_or_create_auth_context
(
p
,
call_id
,
authenticate
);
}
belle_sip_list_free
(
head
);
belle_sip_list_free
(
authenticate_lst
);
}
/*put authorization header if passwd found*/
...
...
src/siplistener.c
View file @
7ddd3dda
...
...
@@ -42,7 +42,9 @@ belle_sip_dialog_t *belle_sip_request_event_get_dialog(const belle_sip_request_e
return
event
->
dialog
;
}
belle_sip_dialog_t
*
belle_sip_dialog_terminated_get_dialog
(
const
belle_sip_dialog_terminated_event_t
*
event
)
{
return
event
->
dialog
;
}
typedef
struct
belle_sip_callbacks
belle_sip_callbacks_t
;
...
...
src/transaction.c
View file @
7ddd3dda
...
...
@@ -121,6 +121,8 @@ BELLE_SIP_INSTANCIATE_CUSTOM_VPTR(belle_sip_server_transaction_t)={
};
void
belle_sip_server_transaction_init
(
belle_sip_server_transaction_t
*
t
,
belle_sip_provider_t
*
prov
,
belle_sip_request_t
*
req
){
belle_sip_header_via_t
*
via
=
BELLE_SIP_HEADER_VIA
(
belle_sip_message_get_header
((
belle_sip_message_t
*
)
req
,
"via"
));
t
->
base
.
branch_id
=
belle_sip_strdup
(
belle_sip_header_via_get_branch
(
via
));
belle_sip_transaction_init
((
belle_sip_transaction_t
*
)
t
,
prov
,
req
);
belle_sip_random_token
(
t
->
to_tag
,
sizeof
(
t
->
to_tag
));
}
...
...
@@ -205,9 +207,10 @@ belle_sip_request_t * belle_sip_client_transaction_create_cancel(belle_sip_clien
belle_sip_error
(
"belle_sip_client_transaction_create_cancel() cannot be used for ACK or non-INVITE transactions."
);
return
NULL
;
}
if
(
t
->
base
.
state
=
=
BELLE_SIP_TRANSACTION_PROCEEDING
){
if
(
t
->
base
.
state
!
=
BELLE_SIP_TRANSACTION_PROCEEDING
){
belle_sip_error
(
"belle_sip_client_transaction_create_cancel() can only be used in state BELLE_SIP_TRANSACTION_PROCEEDING"
" but current transaction state is %s"
,
belle_sip_transaction_state_to_string
(
t
->
base
.
state
));
return
NULL
;
}
req
=
belle_sip_request_new
();
belle_sip_request_set_method
(
req
,
"CANCEL"
);
...
...
@@ -225,14 +228,14 @@ belle_sip_request_t * belle_sip_client_transaction_create_cancel(belle_sip_clien
}
void
belle_sip_client_transaction_send_request
(
belle_sip_client_transaction_t
*
t
){
int
belle_sip_client_transaction_send_request
(
belle_sip_client_transaction_t
*
t
){
belle_sip_hop_t
hop
=
{
0
};
belle_sip_channel_t
*
chan
;
belle_sip_provider_t
*
prov
=
t
->
base
.
provider
;
if
(
t
->
base
.
state
!=
BELLE_SIP_TRANSACTION_INIT
){
belle_sip_error
(
"belle_sip_client_transaction_send_request: bad state."
);
return
;
return
-
1
;
}
belle_sip_stack_get_next_hop
(
prov
->
stack
,
t
->
base
.
request
,
&
hop
);
chan
=
belle_sip_provider_get_channel
(
prov
,
hop
.
host
,
hop
.
port
,
hop
.
transport
);
...
...
@@ -250,19 +253,21 @@ void belle_sip_client_transaction_send_request(belle_sip_client_transaction_t *t
}
}
else
belle_sip_error
(
"belle_sip_client_transaction_send_request(): no channel available"
);
belle_sip_hop_free
(
&
hop
);
return
0
;
}
void
belle_sip_client_transaction_notify_response
(
belle_sip_client_transaction_t
*
t
,
belle_sip_response_t
*
resp
){
belle_sip_transaction_t
*
base
=
(
belle_sip_transaction_t
*
)
t
;
belle_sip_response_event_t
event
;
belle_sip_dialog_t
*
dialog
=
base
->
dialog
;
int
status_code
=
belle_sip_response_get_status_code
(
resp
);
if
(
base
->
last_response
)
belle_sip_object_unref
(
base
->
last_response
);
base
->
last_response
=
(
belle_sip_response_t
*
)
belle_sip_object_ref
(
resp
);
if
(
dialog
){
if
(
dialog
->
state
==
BELLE_SIP_DIALOG_EARLY
||
dialog
->
state
==
BELLE_SIP_DIALOG_CONFIRMED
){
if
(
status_code
>=
200
&&
status_code
<
300
&&
(
dialog
->
state
==
BELLE_SIP_DIALOG_EARLY
||
dialog
->
state
==
BELLE_SIP_DIALOG_CONFIRMED
)){
/*make sure this response matches the current dialog, or creates a new one*/
if
(
!
belle_sip_dialog_match
(
dialog
,(
belle_sip_message_t
*
)
resp
,
FALSE
)){
dialog
=
belle_sip_dialog_new
(
base
);
...
...
tester/belle_sip_dialog_tester.c
View file @
7ddd3dda
...
...
@@ -321,6 +321,7 @@ static void simple_call(void) {
unregister_user
(
stack
,
prov
,
pauline_register_req
,
1
);
unregister_user
(
stack
,
prov
,
marie_register_req
,
1
);
}
int
belle_sip_dialog_test_suite
(){
CU_pSuite
pSuite
=
CU_add_suite
(
"Dialog"
,
init
,
uninit
);
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
.
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment