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
a177101b
Commit
a177101b
authored
Feb 13, 2013
by
jehan
Browse files
fix cseq not incremented in case of 401/407 response
parent
f90176b6
Changes
9
Hide whitespace changes
Inline
Side-by-side
Showing
9 changed files
with
455 additions
and
174 deletions
+455
-174
coreapi/bellesip_sal/sal_impl.c
coreapi/bellesip_sal/sal_impl.c
+126
-151
coreapi/bellesip_sal/sal_impl.h
coreapi/bellesip_sal/sal_impl.h
+4
-2
coreapi/bellesip_sal/sal_op_call.c
coreapi/bellesip_sal/sal_op_call.c
+56
-7
coreapi/bellesip_sal/sal_op_message.c
coreapi/bellesip_sal/sal_op_message.c
+94
-5
coreapi/callbacks.c
coreapi/callbacks.c
+7
-5
tester/call_tester.c
tester/call_tester.c
+65
-0
tester/liblinphone_tester.c
tester/liblinphone_tester.c
+5
-2
tester/liblinphone_tester.h
tester/liblinphone_tester.h
+10
-0
tester/message_tester.c
tester/message_tester.c
+88
-2
No files found.
coreapi/bellesip_sal/sal_impl.c
View file @
a177101b
...
...
@@ -77,9 +77,9 @@ void sal_process_authentication(SalOp *op, belle_sip_response_t *response) {
}
if
(belle_sip_provider_add_authorization(op->base.root->prov,request,response,&auth_list))
{
if
(is_within_dialog)
{
sal_op_resend_request(op,request)
;
}
else
{
sal_op_send_request(op,request)
;
}
else
{
sal_op_resend_request(op,request)
;
}
}
else
{
ms_message("No
auth
info
found
for
[%s]",sal_op_get_from(op))
;
...
...
@@ -115,7 +115,7 @@ static void process_io_error(void *user_ctx, const belle_sip_io_error_event_t *e
op->callbacks.process_io_error(op,event)
;
}
}
else
{
ms_error("process_io_error
not
implemented
yet
for
non
transaction")
;
ms_error("
sal
process_io_error
not
implemented
yet
for
non
transaction")
;
}
}
static
void
process_request_event
(
void
*
sal
,
const
belle_sip_request_event_t
*
event
)
{
...
...
@@ -126,17 +126,10 @@ static void process_request_event(void *sal, const belle_sip_request_event_t *ev
belle_sip_header_address_t*
address
;
belle_sip_header_from_t*
from_header
;
belle_sip_header_to_t*
to
;
belle_sip_header_content_type_t*
content_type
;
belle_sip_response_t*
resp
;
belle_sip_header_call_id_t*
call_id
=
belle_sip_message_get_header_by_type(req,belle_sip_header_call_id_t)
;
belle_sip_header_cseq_t*
cseq
=
belle_sip_message_get_header_by_type(req,belle_sip_header_cseq_t)
;
SalMessage
salmsg
;
char
message_id[256]=
{
0
};
from_header=belle_sip_message_get_header_by_type(BELLE_SIP_MESSAGE(req),belle_sip_header_from_t)
;
char*
from
;
if
(dialog)
{
op=(SalOp*)belle_sip_dialog_get_application_data(dialog)
;
}
else
if
(strcmp("INVITE",belle_sip_request_get_method(req))==0)
{
...
...
@@ -148,34 +141,13 @@ static void process_request_event(void *sal, const belle_sip_request_event_t *ev
op->dir=SalOpDirIncoming
;
sal_op_presence_fill_cbs(op)
;
}
else
if
(strcmp("MESSAGE",belle_sip_request_get_method(req))==0)
{
content_type=belle_sip_message_get_header_by_type(BELLE_SIP_MESSAGE(req),belle_sip_header_content_type_t)
;
if
(content_type
&&
strcmp("text",belle_sip_header_content_type_get_type(content_type))==0
&&
strcmp("plain",belle_sip_header_content_type_get_subtype(content_type))==0)
{
address=belle_sip_header_address_create(belle_sip_header_address_get_displayname(BELLE_SIP_HEADER_ADDRESS(from_header))
,belle_sip_header_address_get_uri(BELLE_SIP_HEADER_ADDRESS(from_header)))
;
from=belle_sip_object_to_string(BELLE_SIP_OBJECT(address))
;
snprintf(message_id,sizeof(message_id)-1,"%s%i"
,belle_sip_header_call_id_get_call_id(call_id)
,belle_sip_header_cseq_get_seq_number(cseq))
;
salmsg.from=from
;
salmsg.text=belle_sip_message_get_body(BELLE_SIP_MESSAGE(req))
;
salmsg.url=NULL
;
/*FIXME not implemented yet*/
salmsg.message_id=message_id
;
op=sal_op_new((Sal*)sal)
;
((Sal*)sal)->callbacks.text_received(op,&salmsg)
;
sal_op_release(op)
;
belle_sip_object_unref(address)
;
belle_sip_free(from)
;
return
;
}
else
{
ms_error("Unsupported
MESSAGE
with
content
type
[%s/%s]",belle_sip_header_content_type_get_type(content_type)
,belle_sip_header_content_type_get_subtype(content_type))
;
return
;
}
op=sal_op_new((Sal*)sal)
;
op->dir=SalOpDirIncoming
;
sal_op_message_fill_cbs(op)
;
}
else
{
ms_error("sal
process_request_event
not
implemented
yet
for
method
[%s]",belle_sip_request_get_method(req))
;
resp=belle_sip_response_create_from_request(req,50
0
)
;
resp=belle_sip_response_create_from_request(req,50
1
)
;
belle_sip_provider_send_response(((Sal*)sal)->prov,resp)
;
return
;
...
...
@@ -217,136 +189,139 @@ static void process_request_event(void *sal, const belle_sip_request_event_t *ev
static
void
process_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)
;
if
(!client_transaction)
{
ms_error("Unexpected
stateless
response,
trashing")
;
return
;
}
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_request_t*
request=belle_sip_transaction_get_request(BELLE_SIP_TRANSACTION(client_transaction))
;
belle_sip_header_contact_t*
original_contact
;
belle_sip_header_address_t*
contact_address=NULL
;
belle_sip_header_via_t*
via_header
;
belle_sip_uri_t*
contact_uri
;
unsigned
int
contact_port
;
const
char*
received
;
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->state
==
SalOpStateTerminated)
{
belle_sip_message("Op
is
terminated,
nothing
to
do
with
this
[%i]",response_code)
;
if
(!client_transaction)
{
ms_warning("Discarding
state
less
response
[%i]",response_code)
;
return
;
}
if
(!op->base.remote_ua)
{
sal_op_set_remote_ua(op,BELLE_SIP_MESSAGE(response))
;
}
if
(op->callbacks.process_response_event)
{
/*Fix contact if needed*/
via_header=
(belle_sip_header_via_t*)belle_sip_message_get_header(BELLE_SIP_MESSAGE(response),BELLE_SIP_VIA)
;
received
=
belle_sip_header_via_get_received(via_header)
;
rport
=
belle_sip_header_via_get_rport(via_header)
;
if
(!sal_op_get_contact(op))
{
/*check if contqct set in reauest*/
if
((original_contact=belle_sip_message_get_header_by_type(request,belle_sip_header_contact_t)))
{
/*no contact set yet, try to see if sip tack has an updated one*/
contact_address=belle_sip_header_address_create(NULL,belle_sip_header_address_get_uri(BELLE_SIP_HEADER_ADDRESS(original_contact)))
;
sal_op_set_contact_address(op,(const
SalAddress
*)contact_address)
;
belle_sip_object_unref(contact_address)
;
}
else
{
/*hmm update contact from via, maybe useless, some op may not need any contact at all*/
contact_address=belle_sip_header_address_new()
;
contact_uri=belle_sip_uri_create(NULL,belle_sip_header_via_get_host(via_header))
;
belle_sip_header_address_set_uri(contact_address,contact_uri)
;
if
(strcasecmp(belle_sip_header_via_get_transport(via_header),"UDP")!=0)
{
belle_sip_uri_set_transport_param(contact_uri,belle_sip_header_via_get_transport_lowercase(via_header))
;
}
if
(belle_sip_header_via_get_listening_port(via_header)
!=
belle_sip_listening_point_get_well_known_port(belle_sip_header_via_get_transport(via_header)))
{
belle_sip_uri_set_port(contact_uri,belle_sip_header_via_get_listening_port(via_header)
)
;
}
contact_updated=TRUE
;
}
}
else
{
SalOp*
op
=
(SalOp*)belle_sip_transaction_get_application_data(BELLE_SIP_TRANSACTION(client_transaction))
;
belle_sip_request_t*
request=belle_sip_transaction_get_request(BELLE_SIP_TRANSACTION(client_transaction))
;
belle_sip_header_contact_t*
original_contact
;
belle_sip_header_address_t*
contact_address=NULL
;
belle_sip_header_via_t*
via_header
;
belle_sip_uri_t*
contact_uri
;
unsigned
int
contact_port
;
const
char*
received
;
int
rport
;
bool_t
contact_updated=FALSE
;
char*
new_contact
;
belle_sip_request_t*
old_request=NULL
;;
belle_sip_response_t*
old_response=NULL
;;
if
(op->state
==
SalOpStateTerminated)
{
belle_sip_message("Op
is
terminated,
nothing
to
do
with
this
[%i]",response_code)
;
return
;
}
if
(!op->base.remote_ua)
{
sal_op_set_remote_ua(op,BELLE_SIP_MESSAGE(response))
;
}
if
(received!=NULL
||
rport>0)
{
if
(sal_op_get_contact(op))
{
contact_address
=
BELLE_SIP_HEADER_ADDRESS(sal_address_clone(sal_op_get_contact_address(op)))
;
}
contact_uri=belle_sip_header_address_get_uri(BELLE_SIP_HEADER_ADDRESS(contact_address))
;
if
(received
&&
strcmp(received,belle_sip_uri_get_host(contact_uri))!=0)
{
/*need to update host*/
belle_sip_uri_set_host(contact_uri,received)
;
contact_updated=TRUE
;
}
contact_port
=
belle_sip_uri_get_port(contact_uri)
;
if
(rport>0
&&
rport!=contact_port
&&
(contact_port+rport)!=5060)
{
/*need to update port*/
belle_sip_uri_set_port(contact_uri,rport)
;
contact_updated=TRUE
;
if
(op->callbacks.process_response_event)
{
/*Fix contact if needed*/
via_header=
(belle_sip_header_via_t*)belle_sip_message_get_header(BELLE_SIP_MESSAGE(response),BELLE_SIP_VIA)
;
received
=
belle_sip_header_via_get_received(via_header)
;
rport
=
belle_sip_header_via_get_rport(via_header)
;
if
(!sal_op_get_contact(op))
{
/*check if contqct set in reauest*/
if
((original_contact=belle_sip_message_get_header_by_type(request,belle_sip_header_contact_t)))
{
/*no contact set yet, try to see if sip tack has an updated one*/
contact_address=belle_sip_header_address_create(NULL,belle_sip_header_address_get_uri(BELLE_SIP_HEADER_ADDRESS(original_contact)))
;
sal_op_set_contact_address(op,(const
SalAddress
*)contact_address)
;
belle_sip_object_unref(contact_address)
;
}
else
{
/*hmm update contact from via, maybe useless, some op may not need any contact at all*/
contact_address=belle_sip_header_address_new()
;
contact_uri=belle_sip_uri_create(NULL,belle_sip_header_via_get_host(via_header))
;
belle_sip_header_address_set_uri(contact_address,contact_uri)
;
if
(strcasecmp(belle_sip_header_via_get_transport(via_header),"UDP")!=0)
{
belle_sip_uri_set_transport_param(contact_uri,belle_sip_header_via_get_transport_lowercase(via_header))
;
}
if
(belle_sip_header_via_get_listening_port(via_header)
!=
belle_sip_listening_point_get_well_known_port(belle_sip_header_via_get_transport(via_header)))
{
belle_sip_uri_set_port(contact_uri,belle_sip_header_via_get_listening_port(via_header)
)
;
}
contact_updated=TRUE
;
}
}
/*try to fix transport if needed (very unlikely)*/
if
(strcasecmp(belle_sip_header_via_get_transport(via_header),"UDP")!=0)
{
if
(!belle_sip_uri_get_transport_param(contact_uri)
||strcasecmp(belle_sip_uri_get_transport_param(contact_uri),belle_sip_header_via_get_transport(via_header))!=0)
{
belle_sip_uri_set_transport_param(contact_uri,belle_sip_header_via_get_transport_lowercase(via_header))
;
if
(received!=NULL
||
rport>0)
{
if
(sal_op_get_contact(op))
{
contact_address
=
BELLE_SIP_HEADER_ADDRESS(sal_address_clone(sal_op_get_contact_address(op)))
;
}
contact_uri=belle_sip_header_address_get_uri(BELLE_SIP_HEADER_ADDRESS(contact_address))
;
if
(received
&&
strcmp(received,belle_sip_uri_get_host(contact_uri))!=0)
{
/*need to update host*/
belle_sip_uri_set_host(contact_uri,received)
;
contact_updated=TRUE
;
}
}
else
{
if
(belle_sip_uri_get_transport_param(contact_uri))
{
contact_port
=
belle_sip_uri_get_port(contact_uri)
;
if
(rport>0
&&
rport!=contact_port
&&
(contact_port+rport)!=5060)
{
/*need to update port*/
belle_sip_uri_set_port(contact_uri,rport)
;
contact_updated=TRUE
;
belle_sip_uri_set_transport_param(contact_uri,NULL)
;
}
/*try to fix transport if needed (very unlikely)*/
if
(strcasecmp(belle_sip_header_via_get_transport(via_header),"UDP")!=0)
{
if
(!belle_sip_uri_get_transport_param(contact_uri)
||strcasecmp(belle_sip_uri_get_transport_param(contact_uri),belle_sip_header_via_get_transport(via_header))!=0)
{
belle_sip_uri_set_transport_param(contact_uri,belle_sip_header_via_get_transport_lowercase(via_header))
;
contact_updated=TRUE
;
}
}
else
{
if
(belle_sip_uri_get_transport_param(contact_uri))
{
contact_updated=TRUE
;
belle_sip_uri_set_transport_param(contact_uri,NULL)
;
}
}
if
(contact_updated)
{
new_contact=belle_sip_object_to_string(BELLE_SIP_OBJECT(contact_address))
;
ms_message("Updating
contact
from
[%s]
to
[%s]
for
[%p]",sal_op_get_contact(op),new_contact,op)
;
sal_op_set_contact(op,new_contact)
;
belle_sip_free(new_contact)
;
}
if
(contact_address)belle_sip_object_unref(contact_address)
;
}
if
(contact_updated)
{
new_contact=belle_sip_object_to_string(BELLE_SIP_OBJECT(contact_address))
;
ms_message("Updating
contact
from
[%s]
to
[%s]
for
[%p]",sal_op_get_contact(op),new_contact,op)
;
sal_op_set_contact(op,new_contact)
;
belle_sip_free(new_contact)
;
/*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:
{
if
(op->state
==
SalOpStateTerminating)
{
belle_sip_message("Op
is
in
state
terminating,
nothing
else
to
do")
;
return
;
}
else
{
sal_process_authentication(op,response)
;
return
;
}
}
if
(contact_address)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:
{
if
(op->state
==
SalOpStateTerminating)
{
belle_sip_message("Op
is
in
state
terminating,
nothing
else
to
do")
;
return
;
}
else
{
sal_process_authentication(op,response)
;
return
;
}
}
}
op->callbacks.process_response_event(op,event)
;
}
else
{
ms_error("Unhandled
event
response
[%p]",event)
;
op->callbacks.process_response_event(op,event)
;
}
else
{
ms_error("Unhandled
event
response
[%p]",event)
;
}
}
}
...
...
coreapi/bellesip_sal/sal_impl.h
View file @
a177101b
...
...
@@ -60,8 +60,8 @@ struct SalOp{
belle_sip_refresher_t*
registration_refresher
;
bool_t
sdp_offering
;
belle_sip_dialog_t*
dialog
;
belle_sip_header_
addres
s_t
*replaces
;
belle_sip_header_
address_
t
*referred_by
;
belle_sip_header_
replace
s_t
*replaces
;
belle_sip_header_t
*referred_by
;
bool_t
auto_answer_asked
;
SalMediaDescription
*result
;
belle_sdp_session_description_t
*sdp_answer
;
...
...
@@ -90,5 +90,7 @@ bool_t sal_compute_sal_errors(belle_sip_response_t* response,SalError* sal_err,S
void
sal_compute_sal_errors_from_code
(
int
code
,
SalError
*
sal_err
,
SalReason
*
sal_reason
)
;
/*presence*/
void
sal_op_presence_fill_cbs
(
SalOp
*
op
);
/*messaging*/
void
sal_op_message_fill_cbs
(
SalOp
*
op
);
#endif
/* SAL_IMPL_H_ */
coreapi/bellesip_sal/sal_op_call.c
View file @
a177101b
...
...
@@ -266,7 +266,6 @@ static void process_request_event(void *op_base, const belle_sip_request_event_t
op->pending_server_trans=server_transaction
;
belle_sdp_session_description_t*
sdp
;
belle_sip_request_t*
req
=
belle_sip_request_event_get_request(event)
;
belle_sip_header_t*
replace_header
;
belle_sip_dialog_state_t
dialog_state
;
belle_sip_response_t*
resp
;
belle_sip_header_t*
call_info
;
...
...
@@ -279,8 +278,7 @@ static void process_request_event(void *op_base, const belle_sip_request_event_t
switch(dialog_state)
{
case
BELLE_SIP_DIALOG_NULL:
{
if
(!op->replaces
&&
(replace_header=belle_sip_message_get_header(BELLE_SIP_MESSAGE(req),"replaces")))
{
op->replaces=belle_sip_header_address_parse(belle_sip_header_extension_get_value(BELLE_SIP_HEADER_EXTENSION(replace_header)))
;
if
(!op->replaces
&&
(op->replaces=belle_sip_message_get_header_by_type(BELLE_SIP_MESSAGE(req),belle_sip_header_replaces_t)))
{
belle_sip_object_ref(op->replaces)
;
}
else
if(op->replaces)
{
ms_warning("replace
header
already
set")
;
...
...
@@ -550,9 +548,15 @@ SalMediaDescription * sal_call_get_final_media_description(SalOp *h){
}
return
h->result
;
}
int
sal_call_refer
(
SalOp
*
h
,
const
char
*
refer_to
){
ms_fatal("sal_call_refer
not
implemented
yet")
;
return
-1
;
int
sal_call_refer
(
SalOp
*
op
,
const
char
*
refer_to
){
belle_sip_header_refer_to_t*
refer_to_header=belle_sip_header_refer_to_create(belle_sip_header_address_parse(refer_to))
;
belle_sip_request_t*
req=op->dialog?belle_sip_dialog_create_request(op->dialog,"REFER"):NULL
;
/*cannot create request if dialog not set yet*/
if
(!req)
{
ms_error("Cannot
refer
to
[%s]
for
op
[%p]",refer_to,op)
;
return
-1
;
}
belle_sip_message_add_header(BELLE_SIP_MESSAGE(req),BELLE_SIP_HEADER(refer_to_header))
;
return
sal_op_send_request(op,req)
;
}
int
sal_call_refer_with_replaces
(
SalOp
*
h
,
SalOp
*
other_call_h
){
ms_fatal("sal_call_refer_with_replaces
not
implemented
yet")
;
...
...
@@ -660,4 +664,49 @@ void sal_expire_old_registration_contacts(Sal *ctx, bool_t enabled){
void
sal_use_dates
(
Sal
*
ctx
,
bool_t
enabled
){
ms_warning("sal_use_dates
not
implemented
yet")
;
}
/*
static void process_refer(SalOp *op, belle_sip_request_event_t *event){
belle_sip_request_t* req = belle_sip_request_event_get_request(event);
belle_sip_header_refer_to_t *refer_to= belle_sip_message_get_header_by_type(BELLE_SIP_MESSAGE(req),belle_sip_header_refer_to_t);;
belle_sip_uri_t* refer_to_uri=belle_sip_header_address_get_uri(BELLE_SIP_HEADER_ADDRESS(refer_to));
ms_message("Receiving REFER request on op [%p]",op);
if (refer_to){
char *tmp;
if (refer_to_uri){
if (op ){
osip_uri_header_t *uh=NULL;
osip_header_t *referred_by=NULL;
osip_uri_header_get_byname(&from->url->url_headers,(char*)"Replaces",&uh);
if (belle_sip_uri_get_header(refer_to_uri,"Replaces"))
if (uh!=NULL && uh->gvalue && uh->gvalue[0]!='\0'){
ms_message("Found replaces in Refer-To");
if (op->replaces){
ms_free(op->replaces);
}
op->replaces=ms_strdup(uh->gvalue);
}
osip_message_header_get_byname(ev->request,"Referred-By",0,&referred_by);
if (referred_by && referred_by->hvalue && referred_by->hvalue[0]!='\0'){
if (op->referred_by)
ms_free(op->referred_by);
op->referred_by=ms_strdup(referred_by->hvalue);
}
}
osip_uri_header_freelist(&from->url->url_headers);
osip_from_to_str(from,&tmp);
sal->callbacks.refer_received(sal,op,tmp);
osip_free(tmp);
osip_from_free(from);
}
eXosip_lock();
eXosip_call_build_answer(ev->tid,202,&ans);
if (ans)
eXosip_call_send_answer(ev->tid,202,ans);
eXosip_unlock();
}
else
{
ms_warning("cannot do anything with the refer without destination\n");
}
}
*/
coreapi/bellesip_sal/sal_op_message.c
View file @
a177101b
...
...
@@ -18,21 +18,103 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
#include "sal_impl.h"
static
void
message_response_event
(
void
*
op_base
,
const
belle_sip_response_event_t
*
event
){
/*nop for futur use*/
static
void
process_error
(
SalOp
*
op
)
{
if
(op->dir
==
SalOpDirOutgoing)
{
op->base.root->callbacks.text_delivery_update(op,SalTextDeliveryFailed)
;
}
else
{
ms_warning("unexpected
io
error
for
incoming
message
on
op
[%p]",op)
;
}
op->state=SalOpStateTerminated
;
}
static
void
process_io_error
(
void
*
user_ctx
,
const
belle_sip_io_error_event_t
*
event
){
SalOp*
op
=
(SalOp*)user_ctx
;
process_error(op)
;
}
static
void
process_timeout
(
void
*
user_ctx
,
const
belle_sip_timeout_event_t
*
event
)
{
SalOp*
op=(SalOp*)user_ctx
;
process_error(op)
;
}
static
void
process_response_event
(
void
*
op_base
,
const
belle_sip_response_event_t
*
event
){
SalOp*
op
=
(SalOp*)op_base
;
int
code
=
belle_sip_response_get_status_code(belle_sip_response_event_get_response(event))
;
SalTextDeliveryStatus
status
;
if
(code>=100
&&
code
<200)
status=SalTextDeliveryInProgress
;
else
if
(code>=200
&&
code
<300)
status=SalTextDeliveryDone
;
else
status=SalTextDeliveryFailed
;
op->base.root->callbacks.text_delivery_update(op,status)
;
}
static
bool_t
is_plain_text
(
belle_sip_header_content_type_t
*
content_type
)
{
return
strcmp("text",belle_sip_header_content_type_get_type(content_type))==0
&&
strcmp("plain",belle_sip_header_content_type_get_subtype(content_type))==0
;
}
static
bool_t
is_external_body
(
belle_sip_header_content_type_t
*
content_type
)
{
return
strcmp("message",belle_sip_header_content_type_get_type(content_type))==0
&&
strcmp("external-body",belle_sip_header_content_type_get_subtype(content_type))==0
;
}
static
void
process_request_event
(
void
*
op_base
,
const
belle_sip_request_event_t
*
event
)
{
SalOp*
op
=
(SalOp*)op_base
;
belle_sip_request_t*
req
=
belle_sip_request_event_get_request(event)
;
belle_sip_server_transaction_t*
server_transaction
=
belle_sip_provider_create_server_transaction(op->base.root->prov,req)
;
belle_sip_header_address_t*
address
;
belle_sip_header_from_t*
from_header
;
belle_sip_header_content_type_t*
content_type
;
belle_sip_response_t*
resp
;
belle_sip_header_call_id_t*
call_id
=
belle_sip_message_get_header_by_type(req,belle_sip_header_call_id_t)
;
belle_sip_header_cseq_t*
cseq
=
belle_sip_message_get_header_by_type(req,belle_sip_header_cseq_t)
;
SalMessage
salmsg
;
char
message_id[256]=
{
0
};
int
response_code=501
;
char*
from
;
bool_t
plain_text=FALSE
;
bool_t
external_body=FALSE
;
from_header=belle_sip_message_get_header_by_type(BELLE_SIP_MESSAGE(req),belle_sip_header_from_t)
;
content_type=belle_sip_message_get_header_by_type(BELLE_SIP_MESSAGE(req),belle_sip_header_content_type_t)
;
if
(content_type
&&
((plain_text=is_plain_text(content_type))
||
(external_body=is_external_body(content_type))))
{
address=belle_sip_header_address_create(belle_sip_header_address_get_displayname(BELLE_SIP_HEADER_ADDRESS(from_header))
,belle_sip_header_address_get_uri(BELLE_SIP_HEADER_ADDRESS(from_header)))
;
from=belle_sip_object_to_string(BELLE_SIP_OBJECT(address))
;
snprintf(message_id,sizeof(message_id)-1,"%s%i"
,belle_sip_header_call_id_get_call_id(call_id)
,belle_sip_header_cseq_get_seq_number(cseq))
;
salmsg.from=from
;
salmsg.text=plain_text?belle_sip_message_get_body(BELLE_SIP_MESSAGE(req)):NULL
;
salmsg.url=external_body?belle_sip_parameters_get_parameter(BELLE_SIP_PARAMETERS(content_type),"URL"):NULL
;
salmsg.message_id=message_id
;
op->base.root->callbacks.text_received(op,&salmsg)
;
belle_sip_object_unref(address)
;
belle_sip_free(from)
;
response_code=200
;
}
else
{
ms_error("Unsupported
MESSAGE
with
content
type
[%s/%s]",belle_sip_header_content_type_get_type(content_type)
,belle_sip_header_content_type_get_subtype(content_type))
;
response_code=501
;
/*not implemented sound appropriate*/
}
resp
=
belle_sip_response_create_from_request(req,response_code)
;
belle_sip_server_transaction_send_response(server_transaction,resp)
;
sal_op_release(op)
;
}
int
sal_message_send
(
SalOp
*
op
,
const
char
*
from
,
const
char
*
to
,
const
char
*
content_type
,
const
char
*
msg
){
belle_sip_request_t*
req
;
char
content_type_raw[256]
;
size_t
content_length
=
strlen(msg)
;
if
(!op->callbacks.process_response_event)
op->callbacks.process_response_event=message_response_event
;
size_t
content_length
=
msg?strlen(msg):0
;
sal_op_message_fill_cbs(op)
;
if
(from)
sal_op_set_from(op,from)
;
if
(to)
sal_op_set_to(op,to)
;
op->dir=SalOpDirOutgoing
;
req=sal_op_build_request(op,"MESSAGE")
;
snprintf(content_type_raw,sizeof(content_type_raw),BELLE_SIP_CONTENT_TYPE
":
%s",content_type)
;
belle_sip_message_add_header(BELLE_SIP_MESSAGE(req),BELLE_SIP_HEADER(belle_sip_header_content_type_parse(content_type_raw)))
;
...
...
@@ -44,3 +126,10 @@ int sal_message_send(SalOp *op, const char *from, const char *to, const char* co
int
sal_text_send
(
SalOp
*
op
,
const
char
*
from
,
const
char
*
to
,
const
char
*
msg
)
{
return
sal_message_send(op,from,to,"text/plain",msg)
;
}
void
sal_op_message_fill_cbs
(
SalOp
*
op
)
{
op->callbacks.process_io_error=process_io_error
;
op->callbacks.process_response_event=process_response_event
;
op->callbacks.process_timeout=process_timeout
;
op->callbacks.process_request_event=process_request_event
;
}
coreapi/callbacks.c
View file @
a177101b
...
...
@@ -965,11 +965,13 @@ static void text_delivery_update(SalOp *op, SalTextDeliveryStatus status){
,chatStatusSal2Linphone(status)
,chat_msg->cb_ud)
;
}
linphone_chat_message_destroy(chat_msg)
;
if
(!ms_list_find_custom((MSList*)calls,
(MSCompareFunc)
op_equals,
op))
{
/*op was only create for messaging purpose, destroying*/
sal_op_release(op)
;
if
(status
!=
SalTextDeliveryInProgress)
{
/*don't release op if progress*/
linphone_chat_message_destroy(chat_msg)
;
if
(!ms_list_find_custom((MSList*)calls,
(MSCompareFunc)
op_equals,
op))
{
/*op was only create for messaging purpose, destroying*/
sal_op_release(op)
;
}
}
}
...
...
tester/call_tester.c
View file @
a177101b
...
...
@@ -432,6 +432,67 @@ static void call_early_media() {
linphone_core_manager_destroy(pauline)
;
}
static
void
simple_call_transfer
()
{
LinphoneCoreManager*
marie
=
linphone_core_manager_new("./tester/marie_rc")
;
/* stats initial_marie_stat;
stats initial_pauline_stat;
stats initial_laure_stat;*/
LinphoneCoreManager*
pauline
=
linphone_core_manager_new("./tester/pauline_rc")
;
LinphoneCoreManager*
laure
=
linphone_core_manager_new("./tester/laure_rc")
;
char*
laure_identity=linphone_address_as_string(laure->identity)
;
MSList*
lcs=ms_list_append(NULL,marie->lc)
;
lcs=ms_list_append(lcs,pauline->lc)
;
lcs=ms_list_append(lcs,laure->lc)
;
LinphoneCall*
marie_call_pauline
;
LinphoneCall*
pauline_called_by_marie
;
/* LinphoneCall* marie_call_laure;*/
CU_ASSERT_TRUE(call(marie,pauline))
;
marie_call_pauline=linphone_core_get_current_call(marie->lc)
;
pauline_called_by_marie=linphone_core_get_current_call(pauline->lc)
;
linphone_core_transfer_call(pauline->lc,pauline_called_by_marie,laure_identity)
;
/*
initial_marie_stat=marie->stat;
initial_pauline_stat=pauline->stat;
initial_laure_stat=laure->stat;
marie_call_laure=linphone_core_get_current_call(marie->lc);