mirror of
https://gitlab.linphone.org/BC/public/linphone-iphone.git
synced 2026-02-01 18:59:25 +00:00
fix cseq not incremented in case of 401/407 response
This commit is contained in:
parent
f90176b636
commit
a177101b55
9 changed files with 466 additions and 185 deletions
|
|
@ -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,500);
|
||||
resp=belle_sip_response_create_from_request(req,501);
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
/*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);
|
||||
}
|
||||
/*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);
|
||||
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 (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;
|
||||
}
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
/*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);
|
||||
}
|
||||
/*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);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -60,8 +60,8 @@ struct SalOp{
|
|||
belle_sip_refresher_t* registration_refresher;
|
||||
bool_t sdp_offering;
|
||||
belle_sip_dialog_t* dialog;
|
||||
belle_sip_header_address_t *replaces;
|
||||
belle_sip_header_address_t *referred_by;
|
||||
belle_sip_header_replaces_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_ */
|
||||
|
|
|
|||
|
|
@ -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");
|
||||
}
|
||||
}
|
||||
*/
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
||||
|
||||
linphone_core_transfer_call()
|
||||
CU_ASSERT_TRUE(wait_for(marie->lc,laure->lc,&marie->stat.number_of_LinphoneCallUpdating,initial_marie_stat.number_of_LinphoneCallUpdating+1));
|
||||
|
||||
|
||||
|
||||
linphone_core_add_to_conference(marie->lc,marie_call_pauline);
|
||||
|
||||
CU_ASSERT_TRUE(wait_for_list(lcs,&marie->stat.number_of_LinphoneCallResuming,initial_marie_stat.number_of_LinphoneCallResuming+1,2000));
|
||||
|
||||
CU_ASSERT_TRUE(wait_for_list(lcs,&pauline->stat.number_of_LinphoneCallStreamsRunning,initial_pauline_stat.number_of_LinphoneCallStreamsRunning+1,2000));
|
||||
CU_ASSERT_TRUE(wait_for_list(lcs,&marie->stat.number_of_LinphoneCallStreamsRunning,initial_marie_stat.number_of_LinphoneCallStreamsRunning+2,2000));
|
||||
CU_ASSERT_TRUE(wait_for_list(lcs,&laure->stat.number_of_LinphoneCallStreamsRunning,initial_laure_stat.number_of_LinphoneCallStreamsRunning+1,2000));
|
||||
|
||||
CU_ASSERT_TRUE(linphone_core_is_in_conference(marie->lc));
|
||||
CU_ASSERT_EQUAL(linphone_core_get_conference_size(marie->lc),3)
|
||||
|
||||
linphone_core_terminate_conference(marie->lc);
|
||||
|
||||
CU_ASSERT_TRUE(wait_for_list(lcs,&pauline->stat.number_of_LinphoneCallEnd,1,2000));
|
||||
CU_ASSERT_TRUE(wait_for_list(lcs,&marie->stat.number_of_LinphoneCallEnd,1,2000));
|
||||
CU_ASSERT_TRUE(wait_for_list(lcs,&laure->stat.number_of_LinphoneCallEnd,1,2000));
|
||||
|
||||
|
||||
*/
|
||||
linphone_core_manager_destroy(marie);
|
||||
linphone_core_manager_destroy(pauline);
|
||||
linphone_core_manager_destroy(laure);
|
||||
ms_list_free(lcs);
|
||||
}
|
||||
|
||||
int call_test_suite () {
|
||||
CU_pSuite pSuite = CU_add_suite("Call", init, uninit);
|
||||
if (NULL == CU_add_test(pSuite, "call_early_declined", call_early_declined)) {
|
||||
|
|
@ -467,6 +528,10 @@ int call_test_suite () {
|
|||
if (NULL == CU_add_test(pSuite, "simple_conference", simple_conference)) {
|
||||
return CU_get_error();
|
||||
}
|
||||
if (NULL == CU_add_test(pSuite, "simple_call_transfer", simple_call_transfer)) {
|
||||
return CU_get_error();
|
||||
}
|
||||
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -114,9 +114,11 @@ LinphoneCore* configure_lc_from(LinphoneCoreVTable* v_table, const char* file,in
|
|||
|
||||
bool_t wait_for(LinphoneCore* lc_1, LinphoneCore* lc_2,int* counter,int value) {
|
||||
MSList* lcs=NULL;
|
||||
lcs=ms_list_append(lcs,lc_1);
|
||||
if (lc_1)
|
||||
lcs=ms_list_append(lcs,lc_1);
|
||||
bool_t result;
|
||||
lcs=ms_list_append(lcs,lc_2);
|
||||
if (lc_2)
|
||||
lcs=ms_list_append(lcs,lc_2);
|
||||
result=wait_for_list(lcs,counter,value,2000);
|
||||
ms_list_free(lcs);
|
||||
return result;
|
||||
|
|
@ -153,6 +155,7 @@ LinphoneCoreManager* linphone_core_manager_new(const char* rc_file) {
|
|||
mgr->v_table.registration_state_changed=registration_state_changed;
|
||||
mgr->v_table.call_state_changed=call_state_changed;
|
||||
mgr->v_table.text_received=text_message_received;
|
||||
mgr->v_table.message_received=message_received;
|
||||
mgr->v_table.new_subscription_request=new_subscribtion_request;
|
||||
mgr->v_table.notify_presence_recv=notify_presence_received;
|
||||
mgr->lc=configure_lc_from(&mgr->v_table,rc_file,1);
|
||||
|
|
|
|||
|
|
@ -57,6 +57,13 @@ typedef struct _stats {
|
|||
int number_of_LinphoneCallReleased;
|
||||
|
||||
int number_of_LinphoneMessageReceived;
|
||||
int number_of_LinphoneMessageReceivedLegacy;
|
||||
int number_of_LinphoneMessageExtBodyReceived;
|
||||
int number_of_LinphoneMessageInProgress;
|
||||
int number_of_LinphoneMessageDelivered;
|
||||
int number_of_LinphoneMessageNotDelivered;
|
||||
|
||||
|
||||
|
||||
int number_of_NewSubscriptionRequest;
|
||||
int number_of_NotifyReceived;
|
||||
|
|
@ -80,9 +87,12 @@ void registration_state_changed(struct _LinphoneCore *lc, LinphoneProxyConfig *c
|
|||
void call_state_changed(LinphoneCore *lc, LinphoneCall *call, LinphoneCallState cstate, const char *msg);
|
||||
void notify_presence_received(LinphoneCore *lc, LinphoneFriend * lf);
|
||||
void text_message_received(LinphoneCore *lc, LinphoneChatRoom *room, const LinphoneAddress *from_address, const char *message);
|
||||
void message_received(LinphoneCore *lc, LinphoneChatRoom *room, LinphoneChatMessage* message);
|
||||
|
||||
void new_subscribtion_request(LinphoneCore *lc, LinphoneFriend *lf, const char *url);
|
||||
|
||||
void auth_info_requested(LinphoneCore *lc, const char *realm, const char *username);
|
||||
|
||||
LinphoneCore* create_lc_with_auth(unsigned int with_auth) ;
|
||||
LinphoneAddress * create_linphone_address(const char * domain);
|
||||
LinphoneCore* configure_lc_from(LinphoneCoreVTable* v_table, const char* file,int proxy_count);
|
||||
|
|
|
|||
|
|
@ -22,13 +22,40 @@
|
|||
#include "liblinphone_tester.h"
|
||||
|
||||
void text_message_received(LinphoneCore *lc, LinphoneChatRoom *room, const LinphoneAddress *from_address, const char *message) {
|
||||
char* from=linphone_address_as_string(from_address);
|
||||
ms_message("Message from [%s] is [%s]",from,message);
|
||||
stats* counters = (stats*)linphone_core_get_user_data(lc);
|
||||
counters->number_of_LinphoneMessageReceivedLegacy++;
|
||||
}
|
||||
void message_received(LinphoneCore *lc, LinphoneChatRoom *room, LinphoneChatMessage* message) {
|
||||
char* from=linphone_address_as_string(linphone_chat_message_get_from(message));
|
||||
ms_message("Message from [%s] is [%s] , external URL [%s]",from
|
||||
,linphone_chat_message_get_text(message)
|
||||
,linphone_chat_message_get_external_body_url(message));
|
||||
ms_free(from);
|
||||
stats* counters = (stats*)linphone_core_get_user_data(lc);
|
||||
counters->number_of_LinphoneMessageReceived++;
|
||||
if (linphone_chat_message_get_external_body_url(message))
|
||||
counters->number_of_LinphoneMessageExtBodyReceived++;
|
||||
}
|
||||
|
||||
void linphone_chat_message_state_change(LinphoneChatMessage* msg,LinphoneChatMessageState state,void* ud) {
|
||||
LinphoneCore* lc=(LinphoneCore*)ud;
|
||||
stats* counters = (stats*)linphone_core_get_user_data(lc);
|
||||
ms_message("Message [%s] [%s]",linphone_chat_message_get_text(msg),linphone_chat_message_state_to_string(state));
|
||||
switch (state) {
|
||||
case LinphoneChatMessageStateDelivered:
|
||||
counters->number_of_LinphoneMessageDelivered++;
|
||||
break;
|
||||
case LinphoneChatMessageStateNotDelivered:
|
||||
counters->number_of_LinphoneMessageNotDelivered++;
|
||||
break;
|
||||
case LinphoneChatMessageStateInProgress:
|
||||
counters->number_of_LinphoneMessageInProgress++;
|
||||
break;
|
||||
default:
|
||||
ms_error("Unexpected state [%s] for message [%p]",linphone_chat_message_state_to_string(state),msg);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
static void text_message() {
|
||||
LinphoneCoreManager* marie = linphone_core_manager_new("./tester/marie_rc");
|
||||
|
|
@ -37,7 +64,56 @@ static void text_message() {
|
|||
LinphoneChatRoom* chat_room = linphone_core_create_chat_room(pauline->lc,to);
|
||||
linphone_chat_room_send_message(chat_room,"Bla bla bla bla");
|
||||
CU_ASSERT_TRUE(wait_for(pauline->lc,marie->lc,&marie->stat.number_of_LinphoneMessageReceived,1));
|
||||
CU_ASSERT_EQUAL(marie->stat.number_of_LinphoneMessageReceivedLegacy,1);
|
||||
linphone_core_manager_destroy(marie);
|
||||
linphone_core_manager_destroy(pauline);
|
||||
}
|
||||
|
||||
static void text_message_with_ack() {
|
||||
LinphoneCoreManager* marie = linphone_core_manager_new("./tester/marie_rc");
|
||||
LinphoneCoreManager* pauline = linphone_core_manager_new("./tester/pauline_rc");
|
||||
char* to = linphone_address_as_string(marie->identity);
|
||||
LinphoneChatRoom* chat_room = linphone_core_create_chat_room(pauline->lc,to);
|
||||
LinphoneChatMessage* message = linphone_chat_room_create_message(chat_room,"Bli bli bli \n blu");
|
||||
linphone_chat_room_send_message2(chat_room,message,linphone_chat_message_state_change,pauline->lc);
|
||||
CU_ASSERT_TRUE(wait_for(pauline->lc,marie->lc,&marie->stat.number_of_LinphoneMessageReceived,1));
|
||||
CU_ASSERT_TRUE(wait_for(pauline->lc,marie->lc,&pauline->stat.number_of_LinphoneMessageDelivered,1));
|
||||
CU_ASSERT_EQUAL(pauline->stat.number_of_LinphoneMessageInProgress,1);
|
||||
linphone_core_manager_destroy(marie);
|
||||
linphone_core_manager_destroy(pauline);
|
||||
}
|
||||
static void text_message_with_external_body() {
|
||||
LinphoneCoreManager* marie = linphone_core_manager_new("./tester/marie_rc");
|
||||
LinphoneCoreManager* pauline = linphone_core_manager_new("./tester/pauline_rc");
|
||||
char* to = linphone_address_as_string(marie->identity);
|
||||
LinphoneChatRoom* chat_room = linphone_core_create_chat_room(pauline->lc,to);
|
||||
LinphoneChatMessage* message = linphone_chat_room_create_message(chat_room,"Bli bli bli \n blu");
|
||||
linphone_chat_message_set_external_body_url(message,"http://www.linphone.org");
|
||||
linphone_chat_room_send_message2(chat_room,message,linphone_chat_message_state_change,pauline->lc);
|
||||
CU_ASSERT_TRUE(wait_for(pauline->lc,marie->lc,&marie->stat.number_of_LinphoneMessageReceived,1));
|
||||
CU_ASSERT_TRUE(wait_for(pauline->lc,marie->lc,&pauline->stat.number_of_LinphoneMessageDelivered,1));
|
||||
CU_ASSERT_EQUAL(pauline->stat.number_of_LinphoneMessageInProgress,1);
|
||||
CU_ASSERT_EQUAL(marie->stat.number_of_LinphoneMessageExtBodyReceived,1);
|
||||
|
||||
linphone_core_manager_destroy(marie);
|
||||
linphone_core_manager_destroy(pauline);
|
||||
}
|
||||
|
||||
static void text_message_with_send_error() {
|
||||
LinphoneCoreManager* marie = linphone_core_manager_new("./tester/marie_rc");
|
||||
LinphoneCoreManager* pauline = linphone_core_manager_new("./tester/pauline_rc");
|
||||
char* to = linphone_address_as_string(pauline->identity);
|
||||
LinphoneChatRoom* chat_room = linphone_core_create_chat_room(marie->lc,to);
|
||||
LinphoneChatMessage* message = linphone_chat_room_create_message(chat_room,"Bli bli bli \n blu");
|
||||
/*simultate a network error*/
|
||||
sal_set_send_error(marie->lc->sal, -1);
|
||||
linphone_chat_room_send_message2(chat_room,message,linphone_chat_message_state_change,marie->lc);
|
||||
|
||||
CU_ASSERT_TRUE(wait_for(pauline->lc,marie->lc,&marie->stat.number_of_LinphoneMessageNotDelivered,1));
|
||||
/*CU_ASSERT_EQUAL(marie->stat.number_of_LinphoneMessageInProgress,1);*/
|
||||
CU_ASSERT_EQUAL(pauline->stat.number_of_LinphoneMessageReceived,0);
|
||||
|
||||
sal_set_send_error(marie->lc->sal, 0);
|
||||
linphone_core_manager_destroy(marie);
|
||||
linphone_core_manager_destroy(pauline);
|
||||
}
|
||||
|
|
@ -47,5 +123,15 @@ int message_test_suite () {
|
|||
if (NULL == CU_add_test(pSuite, "text_message", text_message)) {
|
||||
return CU_get_error();
|
||||
}
|
||||
if (NULL == CU_add_test(pSuite, "text_message_with_ack", text_message_with_ack)) {
|
||||
return CU_get_error();
|
||||
}
|
||||
if (NULL == CU_add_test(pSuite, "text_message_with_send_error", text_message_with_send_error)) {
|
||||
return CU_get_error();
|
||||
}
|
||||
if (NULL == CU_add_test(pSuite, "text_message_with_external_body", text_message_with_external_body)) {
|
||||
return CU_get_error();
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue