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
liblinphone
Commits
885d4a07
Commit
885d4a07
authored
May 11, 2012
by
jehan
Browse files
start incomming call implemention
parent
c8b19166
Changes
12
Hide whitespace changes
Inline
Side-by-side
Showing
12 changed files
with
573 additions
and
337 deletions
+573
-337
coreapi/Makefile.am
coreapi/Makefile.am
+2
-0
coreapi/bellesip_sal/sal_impl.c
coreapi/bellesip_sal/sal_impl.c
+67
-2
coreapi/bellesip_sal/sal_impl.h
coreapi/bellesip_sal/sal_impl.h
+5
-3
coreapi/bellesip_sal/sal_op_call.c
coreapi/bellesip_sal/sal_op_call.c
+170
-0
coreapi/bellesip_sal/sal_op_impl.c
coreapi/bellesip_sal/sal_op_impl.c
+24
-313
coreapi/bellesip_sal/sal_op_registration.c
coreapi/bellesip_sal/sal_op_registration.c
+159
-0
coreapi/bellesip_sal/sal_sdp.c
coreapi/bellesip_sal/sal_sdp.c
+1
-1
coreapi/sal.c
coreapi/sal.c
+19
-3
coreapi/sal.h
coreapi/sal.h
+6
-0
tester/liblinphone_tester.c
tester/liblinphone_tester.c
+101
-6
tester/multi_account_lrc
tester/multi_account_lrc
+16
-9
tester/userdb.conf
tester/userdb.conf
+3
-0
No files found.
coreapi/Makefile.am
View file @
885d4a07
...
...
@@ -43,6 +43,8 @@ if USE_BELLESIP
liblinphone_la_SOURCES
+=
bellesip_sal/sal_address_impl.c
\
bellesip_sal/sal_impl.c
\
bellesip_sal/sal_op_impl.c
\
bellesip_sal/sal_op_call.c
\
bellesip_sal/sal_op_registration.c
\
bellesip_sal/sal_sdp.c
else
liblinphone_la_SOURCES
+=
sal_eXosip2.c sal_eXosip2.h
\
...
...
coreapi/bellesip_sal/sal_impl.c
View file @
885d4a07
...
...
@@ -24,6 +24,41 @@ void sal_enable_logs(){
void
sal_disable_logs
()
{
belle_sip_set_log_level
(
BELLE_SIP_LOG_ERROR
);
}
static
void
sal_add_pending_auth
(
Sal
*
sal
,
SalOp
*
op
){
sal
->
pending_auths
=
ms_list_append
(
sal
->
pending_auths
,
op
);
}
void
sal_remove_pending_auth
(
Sal
*
sal
,
SalOp
*
op
){
sal
->
pending_auths
=
ms_list_remove
(
sal
->
pending_auths
,
op
);
}
static
void
process_authentication
(
SalOp
*
op
,
belle_sip_message_t
*
response
)
{
/*only process a single header for now*/
belle_sip_header_www_authenticate_t
*
authenticate
;
belle_sip_header_address_t
*
from
=
BELLE_SIP_HEADER_ADDRESS
(
belle_sip_message_get_header
(
response
,
BELLE_SIP_FROM
));
belle_sip_uri_t
*
uri
=
belle_sip_header_address_get_uri
(
from
);
authenticate
=
BELLE_SIP_HEADER_WWW_AUTHENTICATE
(
belle_sip_message_get_header
(
response
,
BELLE_SIP_WWW_AUTHENTICATE
));
if
(
!
authenticate
)
{
/*search for proxy authenticate*/
authenticate
=
BELLE_SIP_HEADER_WWW_AUTHENTICATE
(
belle_sip_message_get_header
(
response
,
BELLE_SIP_PROXY_AUTHENTICATE
));
}
op
->
auth_info
.
realm
=
(
char
*
)
belle_sip_header_www_authenticate_get_realm
(
authenticate
);
op
->
auth_info
.
username
=
(
char
*
)
belle_sip_uri_get_user
(
uri
);
if
(
authenticate
)
{
if
(
op
->
base
.
root
->
callbacks
.
auth_requested
(
op
,
&
op
->
auth_info
))
{
sal_op_authenticate
(
op
,
&
op
->
auth_info
);
}
else
{
ms_message
(
"No auth info found for [%s] at [%s]"
,
op
->
auth_info
.
username
,
op
->
auth_info
.
realm
);
sal_add_pending_auth
(
op
->
base
.
root
,
op
);
}
}
else
{
ms_error
(
" missing authenticate header"
);
}
}
static
void
process_dialog_terminated
(
void
*
user_ctx
,
const
belle_sip_dialog_terminated_event_t
*
event
){
ms_error
(
"process_dialog_terminated not implemented yet"
);
}
...
...
@@ -31,7 +66,9 @@ static void process_io_error(void *user_ctx, const belle_sip_io_error_event_t *e
ms_error
(
"process_io_error not implemented yet"
);
}
static
void
process_request_event
(
void
*
user_ctx
,
const
belle_sip_request_event_t
*
event
)
{
ms_error
(
"process_request_event not implemented yet"
);
belle_sip_server_transaction_t
*
server_transaction
=
belle_sip_request_event_get_server_transaction
(
event
);
SalOp
*
op
=
(
SalOp
*
)
belle_sip_transaction_get_application_data
(
BELLE_SIP_TRANSACTION
(
server_transaction
));
ms_error
(
"sal process_request_event not implemented yet"
);
}
static
void
process_response_event
(
void
*
user_ctx
,
const
belle_sip_response_event_t
*
event
){
...
...
@@ -46,6 +83,9 @@ static void process_response_event(void *user_ctx, const belle_sip_response_even
int
rport
;
bool_t
contact_updated
=
FALSE
;
char
*
new_contact
;
belle_sip_request_t
*
old_request
=
NULL
;;
belle_sip_response_t
*
old_response
=
NULL
;;
int
response_code
=
belle_sip_response_get_status_code
(
response
);
if
(
op
->
callbacks
.
process_response_event
)
{
/*Fix contact if needed*/
...
...
@@ -76,6 +116,31 @@ static void process_response_event(void *user_ctx, const belle_sip_response_even
belle_sip_object_unref
(
contact_address
);
}
}
/*update request/response
* maybe only the transaction should be kept*/
old_request
=
op
->
request
;
op
->
request
=
belle_sip_transaction_get_request
(
BELLE_SIP_TRANSACTION
(
client_transaction
));
belle_sip_object_ref
(
op
->
request
);
if
(
old_request
)
belle_sip_object_unref
(
old_request
);
old_response
=
op
->
response
;
op
->
response
=
response
;
/*kept for use at authorization time*/
belle_sip_object_ref
(
op
->
response
);
if
(
old_response
)
belle_sip_object_unref
(
old_response
);
/*handle authozation*/
switch
(
response_code
)
{
case
200
:
{
sal_remove_pending_auth
(
op
->
base
.
root
,
op
);
/*just in case*/
break
;
}
case
401
:
case
407
:{
process_authentication
(
op
,
BELLE_SIP_MESSAGE
(
response
));
return
;
}
}
op
->
callbacks
.
process_response_event
(
op
,
event
);
}
else
{
...
...
@@ -221,7 +286,7 @@ unsigned int sal_get_keepalive_period(Sal *ctx){
return
-
1
;
}
void
sal_use_session_timers
(
Sal
*
ctx
,
int
expires
){
ms_error
(
"sal_use_session_timers not implemented yet"
)
;
ctx
->
session_expires
=
expires
;
return
;
}
void
sal_use_double_registrations
(
Sal
*
ctx
,
bool_t
enabled
){
...
...
coreapi/bellesip_sal/sal_impl.h
View file @
885d4a07
...
...
@@ -30,20 +30,22 @@ struct Sal{
belle_sip_stack_t
*
stack
;
belle_sip_provider_t
*
prov
;
void
*
up
;
/*user pointer*/
int
session_expires
;
};
struct
SalOp
{
SalOpBase
base
;
belle_sip_listener_callbacks_t
callbacks
;
belle_sip_request_t
*
register_
request
;
belle_sip_response_t
*
register_
response
;
belle_sip_request_t
*
request
;
belle_sip_response_t
*
response
;
SalAuthInfo
auth_info
;
unsigned
long
int
registration_refresh_timer
;
bool_t
sdp_offering
;
};
belle_sdp_session_description_t
*
media_description_to_sdp
(
const
SalMediaDescription
*
sal
);
int
sdp_to_media_description
(
belle_sdp_session_description_t
*
sdp
,
SalMediaDescription
*
desc
);
belle_sip_request_t
*
sal_op_build_request
(
SalOp
*
op
,
const
char
*
method
);
#endif
/* SAL_IMPL_H_ */
coreapi/bellesip_sal/sal_op_call.c
0 → 100644
View file @
885d4a07
/*
linphone
Copyright (C) 2012 Belledonne Communications, Grenoble, France
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; either version 2
of the License, or (at your option) any later version.
This program 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 General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
#include "sal_impl.h"
static
void
call_process_io_error
(
void
*
user_ctx
,
const
belle_sip_io_error_event_t
*
event
){
ms_error
(
"process_io_error not implemented yet"
);
}
static
void
call_response_event
(
void
*
user_ctx
,
const
belle_sip_response_event_t
*
event
){
ms_error
(
"response_event not implemented yet"
);
}
static
void
call_process_timeout
(
void
*
user_ctx
,
const
belle_sip_timeout_event_t
*
event
)
{
ms_error
(
"process_timeout not implemented yet"
);
}
static
void
call_process_transaction_terminated
(
void
*
user_ctx
,
const
belle_sip_transaction_terminated_event_t
*
event
)
{
ms_error
(
"process_transaction_terminated not implemented yet"
);
}
static
int
set_sdp_from_desc
(
belle_sip_message_t
*
msg
,
const
SalMediaDescription
*
desc
){
belle_sdp_session_description_t
*
session_desc
=
media_description_to_sdp
(
desc
);
belle_sip_header_content_type_t
*
content_type
;
belle_sip_header_content_length_t
*
content_length
;
int
length
;
char
buff
[
1024
];
if
(
session_desc
)
{
content_type
=
belle_sip_header_content_type_create
(
"application"
,
"sdp"
);
length
=
belle_sip_object_marshal
(
BELLE_SIP_OBJECT
(
session_desc
),
buff
,
0
,
sizeof
(
buff
));
if
(
length
==
sizeof
(
buff
))
{
ms_error
(
"Buffer too small or sdp too big"
);
}
content_length
=
belle_sip_header_content_length_create
(
length
);
belle_sip_message_add_header
(
msg
,
BELLE_SIP_HEADER
(
content_type
));
belle_sip_message_add_header
(
msg
,
BELLE_SIP_HEADER
(
content_length
));
belle_sip_message_set_body
(
msg
,
buff
,
length
);
return
0
;
}
else
{
return
-
1
;
}
}
/*Call API*/
int
sal_call_set_local_media_description
(
SalOp
*
op
,
SalMediaDescription
*
desc
){
if
(
desc
)
sal_media_description_ref
(
desc
);
if
(
op
->
base
.
local_media
)
sal_media_description_unref
(
op
->
base
.
local_media
);
op
->
base
.
local_media
=
desc
;
return
0
;
}
int
sal_call
(
SalOp
*
op
,
const
char
*
from
,
const
char
*
to
){
belle_sip_request_t
*
req
;
belle_sip_header_allow_t
*
header_allow
;
belle_sip_client_transaction_t
*
client_transaction
;
belle_sip_provider_t
*
prov
=
op
->
base
.
root
->
prov
;
belle_sip_header_route_t
*
route_header
;
sal_op_set_from
(
op
,
from
);
sal_op_set_to
(
op
,
to
);
req
=
sal_op_build_request
(
op
,
"INVITE"
);
header_allow
=
belle_sip_header_allow_create
(
"INVITE, ACK, CANCEL, OPTIONS, BYE, REFER, NOTIFY, MESSAGE, SUBSCRIBE, INFO"
);
belle_sip_message_add_header
(
BELLE_SIP_MESSAGE
(
req
),
BELLE_SIP_HEADER
(
header_allow
));
if
(
op
->
base
.
root
->
session_expires
!=
0
){
belle_sip_message_add_header
(
BELLE_SIP_MESSAGE
(
req
),
belle_sip_header_create
(
"Session-expires"
,
"200"
));
belle_sip_message_add_header
(
BELLE_SIP_MESSAGE
(
req
),
belle_sip_header_create
(
"Supported"
,
"timer"
));
}
if
(
op
->
base
.
local_media
){
op
->
sdp_offering
=
TRUE
;
set_sdp_from_desc
(
BELLE_SIP_MESSAGE
(
req
),
op
->
base
.
local_media
);
}
else
op
->
sdp_offering
=
FALSE
;
if
(
sal_op_get_route_address
(
op
))
{
route_header
=
belle_sip_header_route_create
(
BELLE_SIP_HEADER_ADDRESS
(
sal_op_get_route_address
(
op
)));
belle_sip_message_add_header
(
BELLE_SIP_MESSAGE
(
req
),
BELLE_SIP_HEADER
(
route_header
));
}
op
->
callbacks
.
process_io_error
=
call_process_io_error
;
op
->
callbacks
.
process_response_event
=
call_response_event
;
op
->
callbacks
.
process_timeout
=
call_process_timeout
;
op
->
callbacks
.
process_transaction_terminated
=
call_process_transaction_terminated
;
client_transaction
=
belle_sip_provider_create_client_transaction
(
prov
,
req
);
belle_sip_transaction_set_application_data
(
BELLE_SIP_TRANSACTION
(
client_transaction
),
op
);
belle_sip_client_transaction_send_request
(
client_transaction
);
return
0
;
}
int
sal_call_notify_ringing
(
SalOp
*
h
,
bool_t
early_media
){
ms_fatal
(
"sal_call_notify_ringing not implemented yet"
);
return
-
1
;
}
/*accept an incoming call or, during a call accept a reINVITE*/
int
sal_call_accept
(
SalOp
*
h
){
ms_fatal
(
"sal_call_accept not implemented yet"
);
return
-
1
;
}
int
sal_call_decline
(
SalOp
*
h
,
SalReason
reason
,
const
char
*
redirection
/*optional*/
){
ms_fatal
(
"sal_call_decline not implemented yet"
);
return
-
1
;
}
int
sal_call_update
(
SalOp
*
h
,
const
char
*
subject
){
ms_fatal
(
"sal_call_update not implemented yet"
);
return
-
1
;
}
SalMediaDescription
*
sal_call_get_remote_media_description
(
SalOp
*
h
){
ms_fatal
(
"sal_call_get_remote_media_description not implemented yet"
);
return
NULL
;
}
SalMediaDescription
*
sal_call_get_final_media_description
(
SalOp
*
h
){
ms_fatal
(
"sal_call_get_final_media_description not implemented yet"
);
return
NULL
;
}
int
sal_call_refer
(
SalOp
*
h
,
const
char
*
refer_to
){
ms_fatal
(
"sal_call_refer not implemented yet"
);
return
-
1
;
}
int
sal_call_refer_with_replaces
(
SalOp
*
h
,
SalOp
*
other_call_h
){
ms_fatal
(
"sal_call_refer_with_replaces not implemented yet"
);
return
-
1
;
}
int
sal_call_accept_refer
(
SalOp
*
h
){
ms_fatal
(
"sal_call_accept_refer not implemented yet"
);
return
-
1
;
}
/*informs this call is consecutive to an incoming refer */
int
sal_call_set_referer
(
SalOp
*
h
,
SalOp
*
refered_call
){
ms_fatal
(
"sal_call_set_referer not implemented yet"
);
return
-
1
;
}
/* returns the SalOp of a call that should be replaced by h, if any */
SalOp
*
sal_call_get_replaces
(
SalOp
*
h
){
ms_fatal
(
"sal_call_get_replaces not implemented yet"
);
return
NULL
;
}
int
sal_call_send_dtmf
(
SalOp
*
h
,
char
dtmf
){
ms_fatal
(
"sal_call_send_dtmf not implemented yet"
);
return
-
1
;
}
int
sal_call_terminate
(
SalOp
*
h
){
ms_fatal
(
"sal_call_terminate not implemented yet"
);
return
-
1
;
}
bool_t
sal_call_autoanswer_asked
(
SalOp
*
op
){
ms_fatal
(
"sal_call_autoanswer_asked not implemented yet"
);
return
-
1
;
}
void
sal_call_send_vfu_request
(
SalOp
*
h
){
ms_fatal
(
"sal_call_send_vfu_request not implemented yet"
);
return
;
}
int
sal_call_is_offerer
(
const
SalOp
*
h
){
return
h
->
sdp_offering
;
}
coreapi/bellesip_sal/sal_op_impl.c
View file @
885d4a07
...
...
@@ -18,13 +18,6 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
#include "sal_impl.h"
static
void
sal_add_pending_auth
(
Sal
*
sal
,
SalOp
*
op
){
sal
->
pending_auths
=
ms_list_append
(
sal
->
pending_auths
,
op
);
}
static
void
sal_remove_pending_auth
(
Sal
*
sal
,
SalOp
*
op
){
sal
->
pending_auths
=
ms_list_remove
(
sal
->
pending_auths
,
op
);
}
/*create an operation */
SalOp
*
sal_op_new
(
Sal
*
sal
){
...
...
@@ -35,7 +28,7 @@ SalOp * sal_op_new(Sal *sal){
void
sal_op_release
(
SalOp
*
op
){
__sal_op_free
(
op
);
if
(
op
->
register_
request
)
belle_sip_object_unref
(
op
->
register_
request
);
if
(
op
->
request
)
belle_sip_object_unref
(
op
->
request
);
if
(
op
->
registration_refresh_timer
>
0
)
{
belle_sip_main_loop_cancel_source
(
belle_sip_stack_get_main_loop
(
op
->
base
.
root
->
stack
),
op
->
registration_refresh_timer
);
}
...
...
@@ -55,28 +48,28 @@ void sal_op_authenticate(SalOp *op, const SalAuthInfo *info){
}
else
ha1
=
computed_ha1
;
}
if
(
!
op
->
register_
response
)
{
if
(
!
op
->
response
)
{
ms_error
(
"try to authenticate an unchallenged op [%p]"
,
op
);
goto
error
;
}
authenticate
=
BELLE_SIP_HEADER_WWW_AUTHENTICATE
(
belle_sip_message_get_header
(
BELLE_SIP_MESSAGE
(
op
->
register_
response
),
BELLE_SIP_WWW_AUTHENTICATE
));
authenticate
=
BELLE_SIP_HEADER_WWW_AUTHENTICATE
(
belle_sip_message_get_header
(
BELLE_SIP_MESSAGE
(
op
->
response
),
BELLE_SIP_WWW_AUTHENTICATE
));
if
(
authenticate
)
{
authorization
=
belle_sip_auth_helper_create_authorization
(
authenticate
);
}
else
{
/*proxy inerite from www*/
authenticate
=
BELLE_SIP_HEADER_WWW_AUTHENTICATE
(
belle_sip_message_get_header
(
BELLE_SIP_MESSAGE
(
op
->
register_
response
),
BELLE_SIP_PROXY_AUTHENTICATE
));
authenticate
=
BELLE_SIP_HEADER_WWW_AUTHENTICATE
(
belle_sip_message_get_header
(
BELLE_SIP_MESSAGE
(
op
->
response
),
BELLE_SIP_PROXY_AUTHENTICATE
));
authorization
=
BELLE_SIP_HEADER_AUTHORIZATION
(
belle_sip_auth_helper_create_proxy_authorization
(
BELLE_SIP_HEADER_PROXY_AUTHENTICATE
(
authenticate
)));
}
belle_sip_header_authorization_set_uri
(
authorization
,
belle_sip_request_get_uri
(
op
->
register_
request
));
belle_sip_header_authorization_set_uri
(
authorization
,
belle_sip_request_get_uri
(
op
->
request
));
belle_sip_header_authorization_set_username
(
authorization
,
info
->
userid
);
if
(
belle_sip_auth_helper_fill_authorization
(
authorization
,
belle_sip_request_get_method
(
op
->
register_
request
)
,
belle_sip_request_get_method
(
op
->
request
)
,
ha1
))
{
belle_sip_object_unref
(
authorization
);
goto
error
;
}
belle_sip_message_set_header
(
BELLE_SIP_MESSAGE
(
op
->
register_
request
),
BELLE_SIP_HEADER
(
authorization
));
belle_sip_message_set_header
(
BELLE_SIP_MESSAGE
(
op
->
request
),
BELLE_SIP_HEADER
(
authorization
));
sal_register_refresh
(
op
,
-
1
);
return
;
...
...
@@ -95,323 +88,41 @@ int sal_op_get_auth_requested(SalOp *op, const char **realm, const char **userna
*
username
=
op
->
auth_info
.
username
;
return
0
;
}
/*Call API*/
int
sal_call_set_local_media_description
(
SalOp
*
h
,
SalMediaDescription
*
desc
){
ms_fatal
(
"sal_call_set_local_media_description not implemented yet"
);
return
-
1
;
}
int
sal_call
(
SalOp
*
h
,
const
char
*
from
,
const
char
*
to
){
ms_fatal
(
"sal_call not implemented yet"
);
return
-
1
;
}
int
sal_call_notify_ringing
(
SalOp
*
h
,
bool_t
early_media
){
ms_fatal
(
"sal_call_notify_ringing not implemented yet"
);
return
-
1
;
}
/*accept an incoming call or, during a call accept a reINVITE*/
int
sal_call_accept
(
SalOp
*
h
){
ms_fatal
(
"sal_call_accept not implemented yet"
);
return
-
1
;
}
int
sal_call_decline
(
SalOp
*
h
,
SalReason
reason
,
const
char
*
redirection
/*optional*/
){
ms_fatal
(
"sal_call_decline not implemented yet"
);
return
-
1
;
}
int
sal_call_update
(
SalOp
*
h
,
const
char
*
subject
){
ms_fatal
(
"sal_call_update not implemented yet"
);
return
-
1
;
}
SalMediaDescription
*
sal_call_get_remote_media_description
(
SalOp
*
h
){
ms_fatal
(
"sal_call_get_remote_media_description not implemented yet"
);
return
NULL
;
}
SalMediaDescription
*
sal_call_get_final_media_description
(
SalOp
*
h
){
ms_fatal
(
"sal_call_get_final_media_description not implemented yet"
);
return
NULL
;
}
int
sal_call_refer
(
SalOp
*
h
,
const
char
*
refer_to
){
ms_fatal
(
"sal_call_refer not implemented yet"
);
return
-
1
;
}
int
sal_call_refer_with_replaces
(
SalOp
*
h
,
SalOp
*
other_call_h
){
ms_fatal
(
"sal_call_refer_with_replaces not implemented yet"
);
return
-
1
;
}
int
sal_call_accept_refer
(
SalOp
*
h
){
ms_fatal
(
"sal_call_accept_refer not implemented yet"
);
return
-
1
;
}
/*informs this call is consecutive to an incoming refer */
int
sal_call_set_referer
(
SalOp
*
h
,
SalOp
*
refered_call
){
ms_fatal
(
"sal_call_set_referer not implemented yet"
);
return
-
1
;
}
/* returns the SalOp of a call that should be replaced by h, if any */
SalOp
*
sal_call_get_replaces
(
SalOp
*
h
){
ms_fatal
(
"sal_call_get_replaces not implemented yet"
);
return
NULL
;
}
int
sal_call_send_dtmf
(
SalOp
*
h
,
char
dtmf
){
ms_fatal
(
"sal_call_send_dtmf not implemented yet"
);
return
-
1
;
}
int
sal_call_terminate
(
SalOp
*
h
){
ms_fatal
(
"sal_call_terminate not implemented yet"
);
return
-
1
;
}
bool_t
sal_call_autoanswer_asked
(
SalOp
*
op
){
ms_fatal
(
"sal_call_autoanswer_asked not implemented yet"
);
return
-
1
;
}
void
sal_call_send_vfu_request
(
SalOp
*
h
){
ms_fatal
(
"sal_call_send_vfu_request not implemented yet"
);
return
;
}
int
sal_call_is_offerer
(
const
SalOp
*
h
){
ms_fatal
(
"sal_call_is_offerer not implemented yet"
);
return
-
1
;
}
static
void
process_authentication
(
SalOp
*
op
,
belle_sip_message_t
*
response
)
{
/*only process a single header for now*/
belle_sip_header_www_authenticate_t
*
authenticate
;
belle_sip_header_address_t
*
from
=
BELLE_SIP_HEADER_ADDRESS
(
belle_sip_message_get_header
(
response
,
BELLE_SIP_FROM
));
belle_sip_uri_t
*
uri
=
belle_sip_header_address_get_uri
(
from
);
authenticate
=
BELLE_SIP_HEADER_WWW_AUTHENTICATE
(
belle_sip_message_get_header
(
response
,
BELLE_SIP_WWW_AUTHENTICATE
));
if
(
!
authenticate
)
{
/*search for proxy authenticate*/
authenticate
=
BELLE_SIP_HEADER_WWW_AUTHENTICATE
(
belle_sip_message_get_header
(
response
,
BELLE_SIP_PROXY_AUTHENTICATE
));
}
op
->
auth_info
.
realm
=
(
char
*
)
belle_sip_header_www_authenticate_get_realm
(
authenticate
);
op
->
auth_info
.
username
=
(
char
*
)
belle_sip_uri_get_user
(
uri
);
if
(
authenticate
)
{
if
(
op
->
base
.
root
->
callbacks
.
auth_requested
(
op
,
&
op
->
auth_info
))
{
sal_op_authenticate
(
op
,
&
op
->
auth_info
);
}
else
{
ms_message
(
"No auth info found for [%s] at [%s]"
,
op
->
auth_info
.
username
,
op
->
auth_info
.
realm
);
sal_add_pending_auth
(
op
->
base
.
root
,
op
);
}
}
else
{
ms_error
(
" missing authenticate header"
);
}
}
/**************************REGISTRATION***************************/
//////////
static
void
send_register_request
(
SalOp
*
op
,
belle_sip_request_t
*
request
);
static
void
register_process_io_error
(
void
*
user_ctx
,
const
belle_sip_io_error_event_t
*
event
){
ms_error
(
"process_io_error not implemented yet"
);
}
static
void
register_refresh
(
SalOp
*
op
)
{
op
->
registration_refresh_timer
=
0
;
belle_sip_header_cseq_t
*
cseq
=
(
belle_sip_header_cseq_t
*
)
belle_sip_message_get_header
(
BELLE_SIP_MESSAGE
(
op
->
register_request
),
BELLE_SIP_CSEQ
);
belle_sip_header_cseq_set_seq_number
(
cseq
,
belle_sip_header_cseq_get_seq_number
(
cseq
)
+
1
);
send_register_request
(
op
,
op
->
register_request
);
}
static
bool_t
is_contact_equal
(
belle_sip_header_contact_t
*
a
,
belle_sip_header_contact_t
*
b
)
{
if
(
!
a
|
!
b
)
return
FALSE
;
return
!
belle_sip_uri_equals
(
belle_sip_header_address_get_uri
(
BELLE_SIP_HEADER_ADDRESS
(
a
))
,
belle_sip_header_address_get_uri
(
BELLE_SIP_HEADER_ADDRESS
(
b
)));
}
static
void
register_response_event
(
void
*
user_ctx
,
const
belle_sip_response_event_t
*
event
){
belle_sip_client_transaction_t
*
client_transaction
=
belle_sip_response_event_get_client_transaction
(
event
);
SalOp
*
op
=
(
SalOp
*
)
belle_sip_transaction_get_application_data
(
BELLE_SIP_TRANSACTION
(
client_transaction
));
belle_sip_response_t
*
response
=
belle_sip_response_event_get_response
(
event
);
belle_sip_header_expires_t
*
expires_header
;
belle_sip_request_t
*
old_register_request
=
NULL
;;
belle_sip_response_t
*
old_register_response
=
NULL
;;
const
belle_sip_list_t
*
contact_header_list
;
int
response_code
=
belle_sip_response_get_status_code
(
response
);
int
expires
=-
1
;
if
(
response_code
<
200
)
return
;
/*nothing to do*/
/*begin
* maybe only the transaction should be kept*/
old_register_request
=
op
->
register_request
;
op
->
register_request
=
belle_sip_transaction_get_request
(
BELLE_SIP_TRANSACTION
(
client_transaction
));
belle_sip_object_ref
(
op
->
register_request
);
if
(
old_register_request
)
belle_sip_object_unref
(
old_register_request
);
old_register_response
=
op
->
register_response
;
op
->
register_response
=
response
;
/*kept for use at authorization time*/
belle_sip_object_ref
(
op
->
register_response
);
if
(
old_register_response
)
belle_sip_object_unref
(
old_register_response
);
/*end*/
switch
(
response_code
)
{
case
200
:
{
contact_header_list
=
belle_sip_message_get_headers
(
BELLE_SIP_MESSAGE
(
response
),
BELLE_SIP_CONTACT
);
if
(
contact_header_list
)
{
contact_header_list
=
belle_sip_list_find_custom
((
belle_sip_list_t
*
)
contact_header_list
,(
belle_sip_compare_func
)
is_contact_equal
,
(
const
void
*
)
sal_op_get_contact_address
(
op
));
if
(
!
contact_header_list
)
{
ms_error
(
"no matching contact for [%s]"
,
sal_op_get_contact
(
op
));
return
;
}
expires
=
belle_sip_header_contact_get_expires
(
BELLE_SIP_HEADER_CONTACT
(
contact_header_list
->
data
));
}
if
(
expires
<
0
)
{
/*no contact with expire, looking for Expires header*/
if
((
expires_header
=
(
belle_sip_header_expires_t
*
)
belle_sip_message_get_header
(
BELLE_SIP_MESSAGE
(
response
),
BELLE_SIP_EXPIRES
)))
{
expires
=
belle_sip_header_expires_get_expires
(
expires_header
);
}
}
if
(
expires
<
0
)
{
ms_message
(
"Neither Expires header nor corresponding Contact header found"
);
expires
=
0
;
}
op
->
base
.
root
->
callbacks
.
register_success
(
op
,
expires_header
&&
expires
>=
0
);
if
(
expires
>
0
)
{
if
(
op
->
registration_refresh_timer
>
0
)
{
belle_sip_main_loop_cancel_source
(
belle_sip_stack_get_main_loop
(
op
->
base
.
root
->
stack
),
op
->
registration_refresh_timer
);
}
op
->
registration_refresh_timer
=
belle_sip_main_loop_add_timeout
(
belle_sip_stack_get_main_loop
(
op
->
base
.
root
->
stack
),(
belle_sip_source_func_t
)
register_refresh
,
op
,
expires
*
1000
);
}
sal_remove_pending_auth
(
op
->
base
.
root
,
op
);
/*just in case*/
break
;
}
case
401
:
case
407
:{
process_authentication
(
op
,
BELLE_SIP_MESSAGE
(
response
));
break
;
}
default:
{
ms_error
(
"Unexpected answer [%s] for registration request bound to [%s]"
,
belle_sip_response_get_reason_phrase
(
response
),
op
->
base
.
from
);
op
->
base
.
root
->
callbacks
.
register_failure
(
op
,
SalErrorFailure
,
SalReasonUnknown
,
belle_sip_response_get_reason_phrase
(
response
));
break
;
}
}
}
static
void
register_process_timeout
(
void
*
user_ctx
,
const
belle_sip_timeout_event_t
*
event
)
{
ms_error
(
"process_timeout not implemented yet"
);
}
static
void
register_process_transaction_terminated
(
void
*
user_ctx
,
const
belle_sip_transaction_terminated_event_t
*
event
)
{
ms_error
(
"process_transaction_terminated not implemented yet"
);
}
static
void
send_register_request
(
SalOp
*
op
,
belle_sip_request_t
*
request
)
{
belle_sip_client_transaction_t
*
client_transaction
;
belle_sip_provider_t
*
prov
=
op
->
base
.
root
->
prov
;
op
->
callbacks
.
process_io_error
=
register_process_io_error
;
op
->
callbacks
.
process_response_event
=
register_response_event
;
op
->
callbacks
.
process_timeout
=
register_process_timeout
;
op
->
callbacks
.
process_transaction_terminated
=
register_process_transaction_terminated
;
client_transaction
=
belle_sip_provider_create_client_transaction
(
prov
,
request
);
belle_sip_transaction_set_application_data
(
BELLE_SIP_TRANSACTION
(
client_transaction
),
op
);
belle_sip_client_transaction_send_request
(
client_transaction
);
}
/*if expire = -1, does not change expires*/
static
void
send_register_request_with_expires
(
SalOp
*
op
,
belle_sip_request_t
*
request
,
int
expires
)
{
belle_sip_header_expires_t
*
expires_header
=
(
belle_sip_header_expires_t
*
)
belle_sip_message_get_header
(
BELLE_SIP_MESSAGE
(
request
),
BELLE_SIP_EXPIRES
);
belle_sip_header_route_t
*
route_header
;
if
(
sal_op_get_route_address
(
op
))
{
route_header
=
belle_sip_header_route_create
(
BELLE_SIP_HEADER_ADDRESS
(
sal_op_get_route_address
(
op
)));