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
50052922
Commit
50052922
authored
Feb 18, 2011
by
Simon Morlat
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
rework sender_task, finalize client transaction
parent
5874da79
Changes
6
Hide whitespace changes
Inline
Side-by-side
Showing
6 changed files
with
111 additions
and
60 deletions
+111
-60
include/belle-sip/transaction.h
include/belle-sip/transaction.h
+1
-1
src/belle_sip_internal.h
src/belle_sip_internal.h
+22
-0
src/provider.c
src/provider.c
+14
-4
src/sender_task.c
src/sender_task.c
+18
-6
src/sender_task.h
src/sender_task.h
+2
-2
src/transaction.c
src/transaction.c
+54
-47
No files found.
include/belle-sip/transaction.h
View file @
50052922
...
...
@@ -42,7 +42,7 @@ belle_sip_transaction_state_t belle_sip_transaction_get_state(const belle_sip_tr
void
belle_sip_transaction_terminate
(
belle_sip_transaction_t
*
t
);
belle_sip_request_t
*
belle_sip_transaction_get_request
(
belle_sip_transaction_t
*
t
);
void
belle_sip_server_transaction_send_response
(
belle_sip_server_transaction_t
*
t
);
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
);
...
...
src/belle_sip_internal.h
View file @
50052922
...
...
@@ -82,6 +82,8 @@ void belle_sip_fd_source_init(belle_sip_source_t *s, belle_sip_source_func_t fun
#define belle_list_next(elem) ((elem)->next)
/* include private headers */
#include "sender_task.h"
#ifdef __cplusplus
extern
"C"
{
...
...
@@ -406,6 +408,7 @@ struct belle_sip_provider{
};
belle_sip_provider_t
*
belle_sip_provider_new
(
belle_sip_stack_t
*
s
,
belle_sip_listening_point_t
*
lp
);
void
belle_sip_provider_set_transaction_terminated
(
belle_sip_provider_t
*
p
,
belle_sip_transaction_t
*
t
);
typedef
struct
listener_ctx
{
belle_sip_listener_t
*
listener
;
...
...
@@ -425,6 +428,25 @@ typedef struct listener_ctx{
belle_sip_transaction_t
*/
struct
belle_sip_transaction
{
belle_sip_object_t
base
;
belle_sip_provider_t
*
provider
;
/*the provider that created this transaction */
belle_sip_request_t
*
request
;
belle_sip_response_t
*
prov_response
;
belle_sip_response_t
*
final_response
;
char
*
branch_id
;
belle_sip_transaction_state_t
state
;
belle_sip_sender_task_t
*
stask
;
uint64_t
start_time
;
belle_sip_source_t
*
timer
;
int
interval
;
int
is_reliable
:
1
;
int
is_server
:
1
;
int
is_invite
:
1
;
void
*
appdata
;
};
belle_sip_client_transaction_t
*
belle_sip_client_transaction_new
(
belle_sip_provider_t
*
prov
,
belle_sip_request_t
*
req
);
belle_sip_server_transaction_t
*
belle_sip_server_transaction_new
(
belle_sip_provider_t
*
prov
,
belle_sip_request_t
*
req
);
void
belle_sip_client_transaction_add_response
(
belle_sip_client_transaction_t
*
t
,
belle_sip_response_t
*
resp
);
...
...
src/provider.c
View file @
50052922
...
...
@@ -92,14 +92,24 @@ static void sender_task_cb(belle_sip_sender_task_t *t, void *data, int retcode){
void
belle_sip_provider_send_request
(
belle_sip_provider_t
*
p
,
belle_sip_request_t
*
req
){
belle_sip_sender_task_t
*
task
;
task
=
belle_sip_sender_task_new
(
p
,
BELLE_SIP_MESSAGE
(
req
),
sender_task_cb
,
NULL
);
belle_sip_sender_task_send
(
task
);
task
=
belle_sip_sender_task_new
(
p
,
sender_task_cb
,
NULL
);
belle_sip_sender_task_send
(
task
,
BELLE_SIP_MESSAGE
(
req
)
);
}
void
belle_sip_provider_send_response
(
belle_sip_provider_t
*
p
,
belle_sip_response_t
*
resp
){
belle_sip_sender_task_t
*
task
;
task
=
belle_sip_sender_task_new
(
p
,
BELLE_SIP_MESSAGE
(
resp
),
sender_task_cb
,
NULL
);
belle_sip_sender_task_send
(
task
);
task
=
belle_sip_sender_task_new
(
p
,
sender_task_cb
,
NULL
);
belle_sip_sender_task_send
(
task
,
BELLE_SIP_MESSAGE
(
resp
));
}
/*private provider API*/
void
belle_sip_provider_set_transaction_terminated
(
belle_sip_provider_t
*
p
,
belle_sip_transaction_t
*
t
){
belle_sip_transaction_terminated_event_t
ev
;
ev
.
source
=
p
;
ev
.
transaction
=
t
;
ev
.
is_server_transaction
=
t
->
is_server
;
BELLE_SIP_PROVIDER_INVOKE_LISTENERS
(
p
,
process_transaction_terminated
,
&
ev
);
}
src/sender_task.c
View file @
50052922
...
...
@@ -29,10 +29,10 @@ static void belle_sip_sender_task_uninit(belle_sip_sender_task_t *t){
if
(
t
->
resolver_id
>
0
)
belle_sip_main_loop_cancel_source
(
stack
->
ml
,
t
->
resolver_id
);
}
belle_sip_sender_task_t
*
belle_sip_sender_task_new
(
belle_sip_provider_t
*
provider
,
belle_sip_message_t
*
msg
,
belle_sip_sender_task_callback_t
cb
,
void
*
data
){
belle_sip_sender_task_t
*
belle_sip_sender_task_new
(
belle_sip_provider_t
*
provider
,
belle_sip_sender_task_callback_t
cb
,
void
*
data
){
belle_sip_sender_task_t
*
t
=
belle_sip_object_new
(
belle_sip_sender_task_t
,
belle_sip_sender_task_uninit
);
t
->
provider
=
provider
;
t
->
message
=
(
belle_sip_message_t
*
)
belle_sip_object_ref
(
msg
)
;
t
->
message
=
NULL
;
t
->
cb
=
cb
;
t
->
cb_data
=
data
;
return
t
;
...
...
@@ -60,6 +60,8 @@ static int retry_send(belle_sip_sender_task_t *t, unsigned int revents){
static
void
sender_task_send
(
belle_sip_sender_task_t
*
t
){
int
err
;
if
(
t
->
buf
==
NULL
)
t
->
buf
=
belle_sip_message_to_string
(
t
->
message
);
err
=
do_send
(
t
);
if
(
err
==-
EWOULDBLOCK
){
belle_sip_stack_t
*
stack
=
belle_sip_provider_get_sip_stack
(
t
->
provider
);
...
...
@@ -81,7 +83,7 @@ static void sender_task_find_channel_and_send(belle_sip_sender_task_t *t){
belle_sip_channel_t
*
chan
=
belle_sip_listening_point_find_output_channel
(
lp
,
t
->
dest
);
if
(
chan
==
NULL
)
goto
error
;
t
->
channel
=
(
belle_sip_channel_t
*
)
belle_sip_object_ref
(
chan
);
t
->
buf
=
belle_sip_message_to_string
(
t
->
message
);
sender_task_send
(
t
);
}
return
;
...
...
@@ -106,12 +108,22 @@ static void sender_task_res_done(void *data, const char *name, struct addrinfo *
}
}
void
belle_sip_sender_task_send
(
belle_sip_sender_task_t
*
t
){
void
belle_sip_sender_task_send
(
belle_sip_sender_task_t
*
t
,
belle_sip_message_t
*
msg
){
belle_sip_stack_t
*
stack
=
belle_sip_provider_get_sip_stack
(
t
->
provider
);
if
(
t
->
buf
!=
NULL
){
/*retransmission, everything already done*/
if
(
t
->
message
!=
NULL
&&
t
->
message
!=
msg
&&
msg
!=
NULL
){
belle_sip_object_unref
(
t
->
message
);
t
->
message
=
NULL
;
belle_sip_free
(
t
->
buf
);
t
->
buf
=
NULL
;
}
if
(
t
->
message
==
NULL
){
t
->
message
=
(
belle_sip_message_t
*
)
belle_sip_object_ref
(
msg
);
}
if
(
t
->
channel
){
/*retransmission or new response to be sent, everything already done for setting up the transport*/
sender_task_send
(
t
);
return
;
}
if
(
belle_sip_message_is_request
(
t
->
message
)){
belle_sip_stack_get_next_hop
(
stack
,
BELLE_SIP_REQUEST
(
t
->
message
),
&
t
->
hop
);
...
...
src/sender_task.h
View file @
50052922
...
...
@@ -41,9 +41,9 @@ typedef struct belle_sip_sender_task belle_sip_sender_task_t;
belle_sip_sender_task_t
*
belle_sip_sender_task_new
(
belle_sip_provider_t
*
provider
,
belle_sip_message_t
*
msg
,
belle_sip_sender_task_callback_t
cb
,
void
*
data
);
belle_sip_sender_task_t
*
belle_sip_sender_task_new
(
belle_sip_provider_t
*
provider
,
belle_sip_sender_task_callback_t
cb
,
void
*
data
);
void
belle_sip_sender_task_send
(
belle_sip_sender_task_t
*
task
);
void
belle_sip_sender_task_send
(
belle_sip_sender_task_t
*
task
,
belle_sip_message_t
*
msg
);
/*you can only call that after send has been called once */
int
belle_sip_sender_task_is_reliable
(
belle_sip_sender_task_t
*
task
);
...
...
src/transaction.c
View file @
50052922
...
...
@@ -19,21 +19,6 @@
#include "belle_sip_internal.h"
#include "sender_task.h"
struct
belle_sip_transaction
{
belle_sip_object_t
base
;
belle_sip_provider_t
*
provider
;
/*the provider that created this transaction */
belle_sip_request_t
*
request
;
belle_sip_response_t
*
prov_response
;
belle_sip_response_t
*
final_response
;
char
*
branch_id
;
belle_sip_transaction_state_t
state
;
belle_sip_sender_task_t
*
stask
;
uint64_t
start_time
;
int
is_reliable
:
1
;
int
is_server
:
1
;
int
is_invite
:
1
;
void
*
appdata
;
};
static
belle_sip_source_t
*
transaction_create_timer
(
belle_sip_transaction_t
*
t
,
belle_sip_source_func_t
func
,
unsigned
int
time_ms
){
...
...
@@ -43,12 +28,13 @@ static belle_sip_source_t * transaction_create_timer(belle_sip_transaction_t *t,
return
s
;
}
/*
static void transaction_
remov
e_time
out
(belle_sip_transaction_t *t,
unsigned long id
){
static
void
transaction_
delet
e_time
r
(
belle_sip_transaction_t
*
t
,
belle_sip_source_t
*
s
){
belle_sip_stack_t
*
stack
=
belle_sip_provider_get_sip_stack
(
t
->
provider
);
belle_sip_main_loop_cancel_source (stack->ml,id);
belle_sip_main_loop_cancel_source
(
stack
->
ml
,
s
->
id
);
belle_sip_object_unref
(
s
);
}
*/
static
void
belle_sip_transaction_init
(
belle_sip_transaction_t
*
t
,
belle_sip_provider_t
*
prov
,
belle_sip_request_t
*
req
){
belle_sip_object_init_type
(
t
,
belle_sip_transaction_t
);
...
...
@@ -81,11 +67,12 @@ belle_sip_transaction_state_t belle_sip_transaction_get_state(const belle_sip_tr
}
void
belle_sip_transaction_terminate
(
belle_sip_transaction_t
*
t
){
belle_sip_transaction_terminated_event_t
ev
;
ev
.
source
=
t
->
provider
;
ev
.
transaction
=
(
belle_sip_transaction_t
*
)
t
;
ev
.
is_server_transaction
=
t
->
is_server
;
BELLE_SIP_PROVIDER_INVOKE_LISTENERS
(
t
->
provider
,
process_transaction_terminated
,
&
ev
);
t
->
state
=
BELLE_SIP_TRANSACTION_TERMINATED
;
if
(
t
->
timer
){
transaction_delete_timer
(
t
,
t
->
timer
);
t
->
timer
=
NULL
;
}
belle_sip_provider_set_transaction_terminated
(
t
->
provider
,
t
);
}
belle_sip_request_t
*
belle_sip_transaction_get_request
(
belle_sip_transaction_t
*
t
){
...
...
@@ -93,14 +80,31 @@ belle_sip_request_t *belle_sip_transaction_get_request(belle_sip_transaction_t *
}
/*
Server transaction
*
*
* Server transaction
*
*
*/
struct
belle_sip_server_transaction
{
belle_sip_transaction_t
base
;
};
void
belle_sip_server_transaction_send_response
(
belle_sip_server_transaction_t
*
t
){
static
void
server_transaction_send_cb
(
belle_sip_sender_task_t
*
st
,
void
*
data
,
int
retcode
){
belle_sip_server_transaction_t
*
t
=
(
belle_sip_server_transaction_t
*
)
data
;
if
(
retcode
==
0
){
}
else
{
/*the provider is notified of the error by the sender_task, we just need to terminate the transaction*/
belle_sip_transaction_terminate
(
&
t
->
base
);
}
}
void
belle_sip_server_transaction_send_response
(
belle_sip_server_transaction_t
*
t
,
belle_sip_response_t
*
resp
){
if
(
t
->
base
.
stask
==
NULL
){
t
->
base
.
stask
=
belle_sip_sender_task_new
(
t
->
base
.
provider
,
server_transaction_send_cb
,
t
);
}
belle_sip_sender_task_send
(
t
->
base
.
stask
,
BELLE_SIP_MESSAGE
(
resp
));
}
static
void
server_transaction_destroy
(
belle_sip_server_transaction_t
*
t
){
...
...
@@ -114,13 +118,15 @@ belle_sip_server_transaction_t * belle_sip_server_transaction_new(belle_sip_prov
}
/*
Client transaction
*
*
* Client transaction
*
*
*/
struct
belle_sip_client_transaction
{
belle_sip_transaction_t
base
;
belle_sip_source_t
*
timer
;
int
interval
;
uint64_t
timer_F
;
uint64_t
timer_E
;
uint64_t
timer_K
;
...
...
@@ -136,20 +142,20 @@ static int on_client_transaction_timer(void *data, unsigned int revents){
switch
(
t
->
base
.
state
){
case
BELLE_SIP_TRANSACTION_TRYING
:
/*NON INVITE*/
belle_sip_sender_task_send
(
t
->
base
.
stask
);
t
->
interval
=
MIN
(
t
->
interval
*
2
,
tc
->
T2
);
belle_sip_source_set_timeout
(
t
->
timer
,
t
->
interval
);
belle_sip_sender_task_send
(
t
->
base
.
stask
,
NULL
);
t
->
base
.
interval
=
MIN
(
t
->
base
.
interval
*
2
,
tc
->
T2
);
belle_sip_source_set_timeout
(
t
->
base
.
timer
,
t
->
base
.
interval
);
break
;
case
BELLE_SIP_TRANSACTION_CALLING
:
/*INVITES*/
belle_sip_sender_task_send
(
t
->
base
.
stask
);
t
->
interval
=
t
->
interval
*
2
;
belle_sip_source_set_timeout
(
t
->
timer
,
t
->
interval
);
belle_sip_sender_task_send
(
t
->
base
.
stask
,
NULL
);
t
->
base
.
interval
=
t
->
base
.
interval
*
2
;
belle_sip_source_set_timeout
(
t
->
base
.
timer
,
t
->
base
.
interval
);
break
;
case
BELLE_SIP_TRANSACTION_PROCEEDING
:
if
(
!
t
->
base
.
is_invite
){
belle_sip_sender_task_send
(
t
->
base
.
stask
);
t
->
interval
=
tc
->
T2
;
belle_sip_source_set_timeout
(
t
->
timer
,
t
->
interval
);
belle_sip_sender_task_send
(
t
->
base
.
stask
,
NULL
);
t
->
base
.
interval
=
tc
->
T2
;
belle_sip_source_set_timeout
(
t
->
base
.
timer
,
t
->
base
.
interval
);
}
break
;
case
BELLE_SIP_TRANSACTION_COMPLETED
:
...
...
@@ -185,10 +191,10 @@ static void client_transaction_cb(belle_sip_sender_task_t *task, void *data, int
t
->
base
.
start_time
=
belle_sip_time_ms
();
t
->
timer_F
=
t
->
base
.
start_time
+
(
tc
->
T1
*
64
);
if
(
!
t
->
base
.
is_reliable
){
t
->
interval
=
tc
->
T1
;
t
->
timer
=
transaction_create_timer
(
&
t
->
base
,
on_client_transaction_timer
,
tc
->
T1
);
t
->
base
.
interval
=
tc
->
T1
;
t
->
base
.
timer
=
transaction_create_timer
(
&
t
->
base
,
on_client_transaction_timer
,
tc
->
T1
);
}
else
{
t
->
timer
=
transaction_create_timer
(
&
t
->
base
,
on_client_transaction_timer
,
tc
->
T1
*
64
);
t
->
base
.
timer
=
transaction_create_timer
(
&
t
->
base
,
on_client_transaction_timer
,
tc
->
T1
*
64
);
}
}
else
{
/* transport layer error*/
...
...
@@ -198,8 +204,8 @@ static void client_transaction_cb(belle_sip_sender_task_t *task, void *data, int
void
belle_sip_client_transaction_send_request
(
belle_sip_client_transaction_t
*
t
){
t
->
base
.
stask
=
belle_sip_sender_task_new
(
t
->
base
.
provider
,
BELLE_SIP_MESSAGE
(
t
->
base
.
request
),
client_transaction_cb
,
t
);
belle_sip_sender_task_send
(
t
->
base
.
stask
);
t
->
base
.
stask
=
belle_sip_sender_task_new
(
t
->
base
.
provider
,
client_transaction_cb
,
t
);
belle_sip_sender_task_send
(
t
->
base
.
stask
,
BELLE_SIP_MESSAGE
(
t
->
base
.
request
)
);
}
static
void
notify_response
(
belle_sip_client_transaction_t
*
t
,
belle_sip_response_t
*
resp
){
...
...
@@ -220,7 +226,7 @@ static void handle_invite_response(belle_sip_client_transaction_t *t, belle_sip_
case
BELLE_SIP_TRANSACTION_CALLING
:
if
(
!
t
->
base
.
is_reliable
){
/* we must stop retransmissions, then program the timer B/F only*/
belle_sip_source_set_timeout
(
t
->
timer
,
t
->
timer_F
-
belle_sip_time_ms
());
belle_sip_source_set_timeout
(
t
->
base
.
timer
,
t
->
timer_F
-
belle_sip_time_ms
());
}
t
->
base
.
state
=
BELLE_SIP_TRANSACTION_PROCEEDING
;
case
BELLE_SIP_TRANSACTION_PROCEEDING
:
...
...
@@ -241,7 +247,7 @@ static void handle_invite_response(belle_sip_client_transaction_t *t, belle_sip_
t
->
base
.
final_response
=
(
belle_sip_response_t
*
)
belle_sip_object_ref
(
resp
);
notify_response
(
t
,
resp
);
/*start timer D */
belle_sip_source_set_timeout
(
t
->
timer
,
32000
);
belle_sip_source_set_timeout
(
t
->
base
.
timer
,
32000
);
break
;
default:
belle_sip_warning
(
"Unexpected final response while transaction in state %i"
,
t
->
base
.
state
);
...
...
@@ -250,6 +256,7 @@ static void handle_invite_response(belle_sip_client_transaction_t *t, belle_sip_
switch
(
t
->
base
.
state
){
case
BELLE_SIP_TRANSACTION_CALLING
:
case
BELLE_SIP_TRANSACTION_PROCEEDING
:
notify_response
(
t
,
resp
);
belle_sip_transaction_terminate
(
&
t
->
base
);
break
;
default:
...
...
@@ -267,7 +274,7 @@ static void handle_non_invite_response(belle_sip_client_transaction_t *t, belle_
case
BELLE_SIP_TRANSACTION_CALLING
:
if
(
!
t
->
base
.
is_reliable
){
/* we must stop retransmissions, then program the timer B/F only*/
belle_sip_source_set_timeout
(
t
->
timer
,
t
->
timer_F
-
belle_sip_time_ms
());
belle_sip_source_set_timeout
(
t
->
base
.
timer
,
t
->
timer_F
-
belle_sip_time_ms
());
}
case
BELLE_SIP_TRANSACTION_TRYING
:
case
BELLE_SIP_TRANSACTION_PROCEEDING
:
...
...
@@ -288,7 +295,7 @@ static void handle_non_invite_response(belle_sip_client_transaction_t *t, belle_
t
->
base
.
state
=
BELLE_SIP_TRANSACTION_COMPLETED
;
t
->
base
.
final_response
=
(
belle_sip_response_t
*
)
belle_sip_object_ref
(
resp
);
notify_response
(
t
,
resp
);
belle_sip_source_set_timeout
(
t
->
timer
,
tc
->
T4
);
belle_sip_source_set_timeout
(
t
->
base
.
timer
,
tc
->
T4
);
break
;
default:
belle_sip_warning
(
"Unexpected final response while transaction in state %i"
,
t
->
base
.
state
);
...
...
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