diff --git a/coreapi/Makefile.am b/coreapi/Makefile.am
index ce7dc56a0..03d42f08d 100644
--- a/coreapi/Makefile.am
+++ b/coreapi/Makefile.am
@@ -5,6 +5,13 @@ GITDESCRIBE=`cd $(top_srcdir) && git describe --always`
GIT_TAG=`cd $(top_srcdir) && git describe --abbrev=0`
GITREVISION=`cd $(top_srcdir) && git rev-parse HEAD`
+## This command is used to check if the sources are cloned in a git repo.
+## We can't only depend on the presence of the .git/ directory anymore,
+## because of gits submodule handling.
+## We now simply issue a git status and if there's an error, the $(GITSTATUS)
+## variable won't contain "GITOK"
+GITSTATUS=`cd $(top_srcdir) && git status > /dev/null && echo GITOK`
+
ECHO=/bin/echo
SUBDIRS=. help
@@ -161,7 +168,7 @@ AM_CXXFLAGS=$(AM_CFLAGS)
#the PACKAGE_VERSION given in configure.ac
make_gitversion_h:
- if test -d $(top_srcdir)/.git ; then \
+ if test "$(GITSTATUS)" == "GITOK" ; then \
if test "$(GITDESCRIBE)" != "" ; then \
if test "$(GIT_TAG)" != "$(PACKAGE_VERSION)" ; then \
echo "*** PACKAGE_VERSION and git tag differ. Please put them identical."; \
diff --git a/coreapi/authentication.c b/coreapi/authentication.c
index d763f8902..59b3ea1b5 100644
--- a/coreapi/authentication.c
+++ b/coreapi/authentication.c
@@ -21,7 +21,7 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
-
+
#include "linphonecore.h"
#include "private.h"
#include "lpconfig.h"
@@ -143,7 +143,7 @@ void linphone_auth_info_write_config(LpConfig *config, LinphoneAuthInfo *obj, in
char key[50];
sprintf(key,"auth_info_%i",pos);
lp_config_clean_section(config,key);
-
+
if (obj==NULL || lp_config_get_int(config, "sip", "store_auth_info", 1) == 0){
return;
}
@@ -176,12 +176,12 @@ LinphoneAuthInfo *linphone_auth_info_new_from_config_file(LpConfig * config, int
char key[50];
const char *username,*userid,*passwd,*ha1,*realm,*domain;
LinphoneAuthInfo *ret;
-
+
sprintf(key,"auth_info_%i",pos);
if (!lp_config_has_section(config,key)){
return NULL;
}
-
+
username=lp_config_get_string(config,key,"username",NULL);
userid=lp_config_get_string(config,key,"userid",NULL);
passwd=lp_config_get_string(config,key,"passwd",NULL);
@@ -221,7 +221,7 @@ static int realm_match(const char *realm1, const char *realm2){
static const LinphoneAuthInfo *find_auth_info(LinphoneCore *lc, const char *username, const char *realm, const char *domain){
MSList *elem;
const LinphoneAuthInfo *ret=NULL;
-
+
for (elem=lc->auth_info;elem!=NULL;elem=elem->next) {
LinphoneAuthInfo *pinfo = (LinphoneAuthInfo*)elem->data;
if (username && pinfo->username && strcmp(username,pinfo->username)==0) {
@@ -240,7 +240,7 @@ static const LinphoneAuthInfo *find_auth_info(LinphoneCore *lc, const char *user
}
} else if (domain && pinfo->domain && strcmp(domain,pinfo->domain)==0) {
return pinfo;
- } else if (!domain) {
+ } else if (!domain) {
return pinfo;
}
}
@@ -249,7 +249,7 @@ static const LinphoneAuthInfo *find_auth_info(LinphoneCore *lc, const char *user
}
/**
- * Find authentication info matching realm, username, domain criterias.
+ * Find authentication info matching realm, username, domain criteria.
* First of all, (realm,username) pair are searched. If multiple results (which should not happen because realm are supposed to be unique), then domain is added to the search.
* @param lc the LinphoneCore
* @param realm the authentication 'realm' (optional)
@@ -264,7 +264,7 @@ const LinphoneAuthInfo *linphone_core_find_auth_info(LinphoneCore *lc, const cha
if (ai==NULL && domain){
ai=find_auth_info(lc,username,realm,domain);
}
- }
+ }
if (ai == NULL && domain != NULL) {
ai=find_auth_info(lc,username,NULL,domain);
}
@@ -292,8 +292,8 @@ LinphoneAuthInfo * linphone_core_create_auth_info(LinphoneCore *lc, const char *
/**
* Adds authentication information to the LinphoneCore.
- *
- * This information will be used during all SIP transacations that require authentication.
+ *
+ * This information will be used during all SIP transactions that require authentication.
**/
void linphone_core_add_auth_info(LinphoneCore *lc, const LinphoneAuthInfo *info){
LinphoneAuthInfo *ai;
@@ -301,7 +301,7 @@ void linphone_core_add_auth_info(LinphoneCore *lc, const LinphoneAuthInfo *info)
MSList *l;
int restarted_op_count=0;
bool_t updating=FALSE;
-
+
if (info->ha1==NULL && info->passwd==NULL){
ms_error("linphone_core_add_auth_info(): info supplied with empty password or ha1.");
return;
@@ -371,7 +371,6 @@ void linphone_core_remove_auth_info(LinphoneCore *lc, const LinphoneAuthInfo *in
r=(LinphoneAuthInfo*)linphone_core_find_auth_info(lc,info->realm,info->username,info->domain);
if (r){
lc->auth_info=ms_list_remove(lc->auth_info,r);
- /*printf("len=%i newlen=%i\n",len,newlen);*/
linphone_auth_info_destroy(r);
write_auth_infos(lc);
}
diff --git a/coreapi/bellesip_sal/sal_impl.c b/coreapi/bellesip_sal/sal_impl.c
index 9693226dd..ab7714fa9 100644
--- a/coreapi/bellesip_sal/sal_impl.c
+++ b/coreapi/bellesip_sal/sal_impl.c
@@ -137,7 +137,7 @@ void sal_process_authentication(SalOp *op) {
return;
}
- if (belle_sip_provider_add_authorization(op->base.root->prov,new_request,response,from_uri,&auth_list)) {
+ if (belle_sip_provider_add_authorization(op->base.root->prov,new_request,response,from_uri,&auth_list,op->base.realm)) {
if (is_within_dialog) {
sal_op_send_request(op,new_request);
} else {
diff --git a/coreapi/bellesip_sal/sal_op_impl.c b/coreapi/bellesip_sal/sal_op_impl.c
index 649a4e240..e548cec43 100644
--- a/coreapi/bellesip_sal/sal_op_impl.c
+++ b/coreapi/bellesip_sal/sal_op_impl.c
@@ -137,7 +137,7 @@ static void add_initial_route_set(belle_sip_request_t *request, const MSList *li
continue;
}
}
-
+
route=belle_sip_header_route_create((belle_sip_header_address_t*)addr);
uri=belle_sip_header_address_get_uri((belle_sip_header_address_t*)route);
belle_sip_uri_set_lr_param(uri,1);
@@ -180,11 +180,11 @@ belle_sip_request_t* sal_op_build_request(SalOp *op,const char* method) {
belle_sip_header_p_preferred_identity_t* p_preferred_identity=belle_sip_header_p_preferred_identity_create(BELLE_SIP_HEADER_ADDRESS(sal_op_get_from_address(op)));
belle_sip_message_add_header(BELLE_SIP_MESSAGE(req),BELLE_SIP_HEADER(p_preferred_identity));
}
-
+
if (elem && strcmp(method,"REGISTER")!=0 && !op->base.root->no_initial_route){
add_initial_route_set(req,elem);
}
-
+
if (strcmp("REGISTER",method)!=0 && op->privacy!=SalPrivacyNone ){
belle_sip_header_privacy_t* privacy_header=belle_sip_header_privacy_new();
if (op->privacy&SalPrivacyCritical)
@@ -332,7 +332,7 @@ static int _sal_op_send_request_with_contact(SalOp* op, belle_sip_request_t* req
if (!belle_sip_message_get_header(BELLE_SIP_MESSAGE(request),BELLE_SIP_AUTHORIZATION)
&& !belle_sip_message_get_header(BELLE_SIP_MESSAGE(request),BELLE_SIP_PROXY_AUTHORIZATION)) {
/*hmm just in case we already have authentication param in cache*/
- belle_sip_provider_add_authorization(op->base.root->prov,request,NULL,NULL,NULL);
+ belle_sip_provider_add_authorization(op->base.root->prov,request,NULL,NULL,NULL,op->base.realm);
}
result = belle_sip_client_transaction_send_request_to(client_transaction,next_hop_uri/*might be null*/);
@@ -608,7 +608,7 @@ int sal_op_send_and_create_refresher(SalOp* op,belle_sip_request_t* req, int exp
belle_sip_object_unref(op->refresher);
}
if ((op->refresher = belle_sip_client_transaction_create_refresher(op->pending_client_trans))) {
- /*since refresher acquires the transaction, we should remove our context from the transaction, because we won't be notified
+ /*since refresher acquires the transaction, we should remove our context from the transaction, because we won't be notified
* that it is terminated anymore.*/
sal_op_unref(op);/*loose the reference that was given to the transaction when creating it*/
/* Note that the refresher will replace our data with belle_sip_transaction_set_application_data().
@@ -617,6 +617,7 @@ int sal_op_send_and_create_refresher(SalOp* op,belle_sip_request_t* req, int exp
notify the user as a normal transaction*/
belle_sip_refresher_set_listener(op->refresher,listener,op);
belle_sip_refresher_set_retry_after(op->refresher,op->base.root->refresher_retry_after);
+ belle_sip_refresher_set_realm(op->refresher,op->base.realm);
belle_sip_refresher_enable_manual_mode(op->refresher,op->manual_refresher);
return 0;
} else {
diff --git a/coreapi/bellesip_sal/sal_op_presence.c b/coreapi/bellesip_sal/sal_op_presence.c
index e1ab054aa..23db49e6f 100644
--- a/coreapi/bellesip_sal/sal_op_presence.c
+++ b/coreapi/bellesip_sal/sal_op_presence.c
@@ -35,7 +35,7 @@ void sal_add_presence_info(SalOp *op, belle_sip_message_t *notify, SalPresenceMo
belle_sip_message_remove_header(BELLE_SIP_MESSAGE(notify),BELLE_SIP_CONTENT_TYPE);
belle_sip_message_remove_header(BELLE_SIP_MESSAGE(notify),BELLE_SIP_CONTENT_LENGTH);
belle_sip_message_set_body(BELLE_SIP_MESSAGE(notify),NULL,0);
-
+
if (content){
belle_sip_message_add_header(BELLE_SIP_MESSAGE(notify)
,BELLE_SIP_HEADER(belle_sip_header_content_type_create("application","pidf+xml")));
@@ -95,7 +95,7 @@ static void presence_response_event(void *op_base, const belle_sip_response_even
belle_sip_request_t* request=belle_sip_transaction_get_request(BELLE_SIP_TRANSACTION(client_transaction));
int code = belle_sip_response_get_status_code(response);
belle_sip_header_expires_t* expires;
-
+
sal_op_set_error_info_from_response(op,response);
if (code>=300) {
@@ -127,6 +127,7 @@ static void presence_response_event(void *op_base, const belle_sip_response_even
if (expires>0){
op->refresher=belle_sip_client_transaction_create_refresher(client_transaction);
belle_sip_refresher_set_listener(op->refresher,presence_refresher_listener,op);
+ belle_sip_refresher_set_realm(op->refresher,op->base.realm);
}
}
break;
@@ -164,7 +165,7 @@ static SalPresenceModel * process_presence_notification(SalOp *op, belle_sip_req
return NULL;
if (belle_sip_header_content_length_get_content_length(content_length) == 0)
return NULL;
-
+
if (body==NULL) return NULL;
op->base.root->callbacks.parse_presence_requested(op,
@@ -181,7 +182,7 @@ static void handle_notify(SalOp *op, belle_sip_request_t *req){
belle_sip_server_transaction_t* server_transaction=op->pending_server_trans;
belle_sip_header_subscription_state_t* subscription_state_header=belle_sip_message_get_header_by_type(req,belle_sip_header_subscription_state_t);
SalSubscribeStatus sub_state;
-
+
if (strcmp("NOTIFY",belle_sip_request_get_method(req))==0) {
SalPresenceModel *presence_model = NULL;
const char* body = belle_sip_message_get_body(BELLE_SIP_MESSAGE(req));
@@ -194,7 +195,7 @@ static void handle_notify(SalOp *op, belle_sip_request_t *req){
presence_model = process_presence_notification(op, req);
if (presence_model != NULL || body==NULL) {
/* Presence notification body parsed successfully. */
-
+
resp = sal_op_create_response_from_request(op, req, 200); /*create first because the op may be destroyed by notify_presence */
op->base.root->callbacks.notify_presence(op, sub_state, presence_model, NULL);
} else if (body){
@@ -214,7 +215,7 @@ static void presence_process_request_event(void *op_base, const belle_sip_reques
belle_sip_header_expires_t* expires = belle_sip_message_get_header_by_type(req,belle_sip_header_expires_t);
belle_sip_response_t* resp;
const char *method=belle_sip_request_get_method(req);
-
+
belle_sip_object_ref(server_transaction);
if (op->pending_server_trans) belle_sip_object_unref(op->pending_server_trans);
op->pending_server_trans=server_transaction;
@@ -256,7 +257,7 @@ static void presence_process_request_event(void *op_base, const belle_sip_reques
}
}
break;
- default:
+ default:
ms_error("unexpected dialog state [%s]",belle_sip_dialog_state_to_string(dialog_state));
break;
}
diff --git a/coreapi/chat.c b/coreapi/chat.c
index e445d2bfa..165d71ac3 100644
--- a/coreapi/chat.c
+++ b/coreapi/chat.c
@@ -46,12 +46,35 @@ const char *multipart_boundary=MULTIPART_BOUNDARY;
static size_t linphone_chat_message_compute_filepart_header_size(const char *filename, const char *content_type) {
return strlen(FILEPART_HEADER_1)+strlen(filename)+strlen(FILEPART_HEADER_2)+strlen(content_type)+strlen(FILEPART_HEADER_3);
}
-static void process_io_error(void *data, const belle_sip_io_error_event_t *event){
+
+static void process_io_error_upload(void *data, const belle_sip_io_error_event_t *event){
LinphoneChatMessage* msg=(LinphoneChatMessage *)data;
- msg->cb(msg, LinphoneChatMessageStateNotDelivered, msg->chat_room->lc);
+ ms_error("I/O Error during file upload to %s - msg [%p] chat room[%p]", msg->chat_room->lc->file_transfer_server, msg, msg->chat_room);
+ if (msg->cb) {
+ msg->cb(msg, LinphoneChatMessageStateNotDelivered, msg->chat_room->lc);
+ }
}
-static void process_auth_requested(void *data, belle_sip_auth_event_t *event){
- printf("We have a auth requested!\n");
+static void process_auth_requested_upload(void *data, belle_sip_auth_event_t *event){
+ LinphoneChatMessage* msg=(LinphoneChatMessage *)data;
+ ms_error("Error during file upload : auth requested to connect %s - msg [%p] chat room[%p]", msg->chat_room->lc->file_transfer_server, msg, msg->chat_room);
+ if (msg->cb) {
+ msg->cb(msg, LinphoneChatMessageStateNotDelivered, msg->chat_room->lc);
+ }
+}
+
+static void process_io_error_download(void *data, const belle_sip_io_error_event_t *event){
+ LinphoneChatMessage* msg=(LinphoneChatMessage *)data;
+ ms_error("I/O Error during file download %s - msg [%p] chat room[%p]", msg->external_body_url, msg, msg->chat_room);
+ if (msg->cb) {
+ msg->cb(msg, LinphoneChatMessageStateFileTransferError, msg->chat_room->lc);
+ }
+}
+static void process_auth_requested_download(void *data, belle_sip_auth_event_t *event){
+ LinphoneChatMessage* msg=(LinphoneChatMessage *)data;
+ ms_error("Error during file download : auth requested to get %s - msg [%p] chat room[%p]", msg->external_body_url, msg, msg->chat_room);
+ if (msg->cb) {
+ msg->cb(msg, LinphoneChatMessageStateFileTransferError, msg->chat_room->lc);
+ }
}
/**
@@ -154,12 +177,17 @@ static void linphone_chat_message_process_response_from_post_file(void *data, co
belle_sip_free(content_type);
belle_sip_message_set_body_handler(BELLE_SIP_MESSAGE(req),BELLE_SIP_BODY_HANDLER(bh));
cbs.process_response=linphone_chat_message_process_response_from_post_file;
- cbs.process_io_error=process_io_error;
- cbs.process_auth_requested=process_auth_requested;
+ cbs.process_io_error=process_io_error_upload;
+ cbs.process_auth_requested=process_auth_requested_upload;
l=belle_http_request_listener_create_from_callbacks(&cbs,msg);
+ msg->http_request=req; /* update the reference to the http request to be able to cancel it during upload */
belle_http_provider_send_request(msg->chat_room->lc->http_provider,req,l);
}
- if (code == 200 ) { /* file has been uplaoded correctly, get server reply and send it */
+ if (code == 200 ) { /* file has been uploaded correctly, get server reply and send it */
+ /* TODO Check that the transfer has not been cancelled, note this shall be removed once the belle sip API will provide a cancel request as we shall never reach this part if the transfer is actually cancelled */
+ if (msg->http_request == NULL) {
+ return;
+ }
const char *body = belle_sip_message_get_body((belle_sip_message_t *)event->response);
msg->message = ms_strdup(body);
linphone_content_uninit(msg->file_transfer_information);
@@ -272,7 +300,8 @@ LinphoneChatRoom* linphone_core_get_or_create_chat_room(LinphoneCore* lc, const
static void linphone_chat_room_delete_composing_idle_timer(LinphoneChatRoom *cr) {
if (cr->composing_idle_timer) {
- sal_cancel_timer(cr->lc->sal, cr->composing_idle_timer);
+ if(cr->lc->sal)
+ sal_cancel_timer(cr->lc->sal, cr->composing_idle_timer);
belle_sip_object_unref(cr->composing_idle_timer);
cr->composing_idle_timer = NULL;
}
@@ -280,7 +309,8 @@ static void linphone_chat_room_delete_composing_idle_timer(LinphoneChatRoom *cr)
static void linphone_chat_room_delete_composing_refresh_timer(LinphoneChatRoom *cr) {
if (cr->composing_refresh_timer) {
- sal_cancel_timer(cr->lc->sal, cr->composing_refresh_timer);
+ if(cr->lc->sal)
+ sal_cancel_timer(cr->lc->sal, cr->composing_refresh_timer);
belle_sip_object_unref(cr->composing_refresh_timer);
cr->composing_refresh_timer = NULL;
}
@@ -288,7 +318,8 @@ static void linphone_chat_room_delete_composing_refresh_timer(LinphoneChatRoom *
static void linphone_chat_room_delete_remote_composing_refresh_timer(LinphoneChatRoom *cr) {
if (cr->remote_composing_refresh_timer) {
- sal_cancel_timer(cr->lc->sal, cr->remote_composing_refresh_timer);
+ if(cr->lc->sal)
+ sal_cancel_timer(cr->lc->sal, cr->remote_composing_refresh_timer);
belle_sip_object_unref(cr->remote_composing_refresh_timer);
cr->remote_composing_refresh_timer = NULL;
}
@@ -335,9 +366,10 @@ static void _linphone_chat_room_send_message(LinphoneChatRoom *cr, LinphoneChatM
NULL,
NULL);
cbs.process_response=linphone_chat_message_process_response_from_post_file;
- cbs.process_io_error=process_io_error;
- cbs.process_auth_requested=process_auth_requested;
+ cbs.process_io_error=process_io_error_upload;
+ cbs.process_auth_requested=process_auth_requested_upload;
l=belle_http_request_listener_create_from_callbacks(&cbs,msg); /* give msg to listener to be able to start the actual file upload when server answer a 204 No content */
+ msg->http_request = req; /* keep a reference on the request to be able to cancel it */
belle_http_provider_send_request(cr->lc->http_provider,req,l);
linphone_chat_message_unref(msg);
return;
@@ -371,8 +403,8 @@ static void _linphone_chat_room_send_message(LinphoneChatRoom *cr, LinphoneChatM
content_type=ms_strdup_printf("message/external-body; access-type=URL; URL=\"%s\"",msg->external_body_url);
sal_message_send(op,identity,cr->peer,content_type, NULL);
ms_free(content_type);
- } else {
- if (msg->content_type == NULL) {
+ } else { /* the message is either text or have a file transfer using RCS recommendation */
+ if (msg->content_type == NULL) { /* if no content type is specified, it is a text message */
sal_text_send(op, identity, cr->peer,msg->message);
} else {
sal_message_send(op, identity, cr->peer, msg->content_type, msg->message);
@@ -450,7 +482,7 @@ void linphone_core_message_received(LinphoneCore *lc, SalOp *op, const SalMessag
/* create a new chat room */
cr=linphone_core_create_chat_room(lc,cleanfrom);
}
- if (sal_msg->content_type != NULL) { /* content_type field is, for now, used only for rcs file transfer bu twe shall strcmp it with "application/vnd.gsma.rcs-ft-http+xml" */
+ if (sal_msg->content_type != NULL) { /* content_type field is, for now, used only for rcs file transfer but we shall strcmp it with "application/vnd.gsma.rcs-ft-http+xml" */
xmlChar *file_url = NULL;
xmlDocPtr xmlMessageBody;
xmlNodePtr cur;
@@ -668,6 +700,7 @@ LinphoneChatMessage* linphone_chat_room_create_message(LinphoneChatRoom *cr, con
msg->is_read=TRUE;
msg->content_type = NULL; /* this property is used only when transfering file */
msg->file_transfer_information = NULL; /* this property is used only when transfering file */
+ msg->http_request = NULL;
return msg;
}
@@ -857,6 +890,7 @@ const char* linphone_chat_message_state_to_string(const LinphoneChatMessageState
case LinphoneChatMessageStateInProgress:return "LinphoneChatMessageStateInProgress";
case LinphoneChatMessageStateDelivered:return "LinphoneChatMessageStateDelivered";
case LinphoneChatMessageStateNotDelivered:return "LinphoneChatMessageStateNotDelivered";
+ case LinphoneChatMessageStateFileTransferError:return "LinphoneChatMessageStateFileTransferError";
default: return "Unknown state";
}
@@ -953,12 +987,15 @@ const LinphoneContent *linphone_chat_message_get_file_transfer_information(const
}
static void on_recv_body(belle_sip_user_body_handler_t *bh, belle_sip_message_t *msg, void *data, size_t offset, const uint8_t *buffer, size_t size){
- //printf("Receive %ld bytes\n\n%s\n\n", size, (char *)buffer);
LinphoneChatMessage* chatMsg=(LinphoneChatMessage *)data;
LinphoneCore *lc = chatMsg->chat_room->lc;
+ /* TODO: while belle sip doesn't implement the cancel http request method, test if a request is still linked to the message before forwarding the data to callback */
+ if (chatMsg->http_request == NULL) {
+ return;
+ }
/* call back given by application level */
- if (lc->vtable.file_transfer_received != NULL) {
- lc->vtable.file_transfer_received(lc, chatMsg, chatMsg->file_transfer_information, (char *)buffer, size);
+ if (lc->vtable.file_transfer_recv != NULL) {
+ lc->vtable.file_transfer_recv(lc, chatMsg, chatMsg->file_transfer_information, (char *)buffer, size);
}
return;
}
@@ -1024,8 +1061,8 @@ static void linphone_chat_process_response_from_get_file(void *data, const belle
LinphoneChatMessage* chatMsg=(LinphoneChatMessage *)data;
LinphoneCore *lc = chatMsg->chat_room->lc;
/* file downloaded succesfully, call again the callback with size at zero */
- if (lc->vtable.file_transfer_received != NULL) {
- lc->vtable.file_transfer_received(lc, chatMsg, chatMsg->file_transfer_information, NULL, 0);
+ if (lc->vtable.file_transfer_recv != NULL) {
+ lc->vtable.file_transfer_recv(lc, chatMsg, chatMsg->file_transfer_information, NULL, 0);
}
}
}
@@ -1035,8 +1072,9 @@ static void linphone_chat_process_response_from_get_file(void *data, const belle
* Start the download of the file from remote server
*
* @param message #LinphoneChatMessage
+ * @param status_cb LinphoneChatMessageStateChangeCb status callback invoked when file is downloaded or could not be downloaded
*/
-void linphone_chat_message_start_file_download(const LinphoneChatMessage *message) {
+void linphone_chat_message_start_file_download(LinphoneChatMessage *message, LinphoneChatMessageStateChangedCb status_cb) {
belle_http_request_listener_callbacks_t cbs={0};
belle_http_request_listener_t *l;
belle_generic_uri_t *uri;
@@ -1055,12 +1093,31 @@ void linphone_chat_message_start_file_download(const LinphoneChatMessage *messag
cbs.process_response_headers=linphone_chat_process_response_headers_from_get_file;
cbs.process_response=linphone_chat_process_response_from_get_file;
- cbs.process_io_error=process_io_error;
- cbs.process_auth_requested=process_auth_requested;
+ cbs.process_io_error=process_io_error_download;
+ cbs.process_auth_requested=process_auth_requested_download;
l=belle_http_request_listener_create_from_callbacks(&cbs, (void *)message);
belle_sip_object_data_set(BELLE_SIP_OBJECT(req),"message",(void *)message,NULL);
+ message->http_request = req; /* keep a reference on the request to be able to cancel the download */
+ message->cb = status_cb;
+ message->state = LinphoneChatMessageStateInProgress; /* start the download, status is In Progress */
belle_http_provider_send_request(message->chat_room->lc->http_provider,req,l);
}
+
+/**
+ * Cancel an ongoing file transfer attached to this message.(upload or download)
+ * @param msg #LinphoneChatMessage
+ */
+void linphone_chat_room_cancel_file_transfer(LinphoneChatMessage *msg) {
+ ms_message("Cancelled file transfer %s - msg [%p] chat room[%p]", (msg->external_body_url==NULL)?msg->chat_room->lc->file_transfer_server:msg->external_body_url, msg, msg->chat_room);
+ /* TODO: here we shall call the cancel http request from bellesip API when it is available passing msg->http_request */
+ /* waiting for this API, just set to NULL the reference to the request in the message and any request */
+ msg->http_request = NULL;
+ if (msg->cb) {
+ msg->cb(msg, LinphoneChatMessageStateNotDelivered, msg->chat_room->lc);
+ }
+}
+
+
/**
* Set origin of the message
*@param message #LinphoneChatMessage obj
@@ -1288,11 +1345,11 @@ LinphoneChatMessage* linphone_chat_room_create_file_transfer_message(LinphoneCha
linphone_chat_message_set_to(msg, linphone_chat_room_get_peer_address(cr));
linphone_chat_message_set_from(msg, linphone_address_new(linphone_core_get_identity(cr->lc)));
msg->content_type=NULL; /* this will be set to application/vnd.gsma.rcs-ft-http+xml when we will transfer the xml reply from server to the peers */
+ msg->http_request=NULL; /* this will store the http request during file upload to the server */
return msg;
}
+
/**
* @}
*/
-
-
diff --git a/coreapi/help/filetransfer.c b/coreapi/help/filetransfer.c
index 819330f57..25edc2d39 100644
--- a/coreapi/help/filetransfer.c
+++ b/coreapi/help/filetransfer.c
@@ -115,16 +115,6 @@ static void file_transfer_send(LinphoneCore *lc, LinphoneChatMessage *message,
}
-/*
- * Call back called when a message is received
- */
-static void message_received(LinphoneCore *lc, LinphoneChatRoom *cr, LinphoneChatMessage *msg) {
- const LinphoneContent *file_transfer_info = linphone_chat_message_get_file_transfer_information(msg);
- printf ("Do you really want to download %s (size %ld)?[Y/n]\nOk, let's go\n", file_transfer_info->name, (long int)file_transfer_info->size);
-
- linphone_chat_message_start_file_download(msg);
-
-}
/*
* Call back to get delivery status of a message
* */
@@ -136,6 +126,16 @@ static void linphone_file_transfer_state_changed(LinphoneChatMessage* msg,Linpho
free(to);
}
+/*
+ * Call back called when a message is received
+ */
+static void message_received(LinphoneCore *lc, LinphoneChatRoom *cr, LinphoneChatMessage *msg) {
+ const LinphoneContent *file_transfer_info = linphone_chat_message_get_file_transfer_information(msg);
+ printf ("Do you really want to download %s (size %ld)?[Y/n]\nOk, let's go\n", file_transfer_info->name, (long int)file_transfer_info->size);
+
+ linphone_chat_message_start_file_download(msg, linphone_file_transfer_state_changed);
+
+}
LinphoneCore *lc;
int main(int argc, char *argv[]){
@@ -162,7 +162,7 @@ int main(int argc, char *argv[]){
in order to get notifications about incoming file receive, file_transfer_send to feed file to be transfered
and file_transfer_progress_indication to print progress.
*/
- vtable.file_transfer_received=file_transfer_received;
+ vtable.file_transfer_recv=file_transfer_received;
vtable.file_transfer_send=file_transfer_send;
vtable.file_transfer_progress_indication=file_transfer_progress_indication;
vtable.message_received=message_received;
diff --git a/coreapi/linphone_tunnel.cc b/coreapi/linphone_tunnel.cc
index 151755078..2e77bbd95 100644
--- a/coreapi/linphone_tunnel.cc
+++ b/coreapi/linphone_tunnel.cc
@@ -60,16 +60,19 @@ void linphone_tunnel_destroy(LinphoneTunnel *tunnel){
static char *linphone_tunnel_config_to_string(const LinphoneTunnelConfig *tunnel_config) {
char *str = NULL;
- if(linphone_tunnel_config_get_remote_udp_mirror_port(tunnel_config) != -1) {
- str = ms_strdup_printf("%s:%d:%d:%d",
- linphone_tunnel_config_get_host(tunnel_config),
- linphone_tunnel_config_get_port(tunnel_config),
- linphone_tunnel_config_get_remote_udp_mirror_port(tunnel_config),
- linphone_tunnel_config_get_delay(tunnel_config));
- } else {
- str = ms_strdup_printf("%s:%d",
- linphone_tunnel_config_get_host(tunnel_config),
- linphone_tunnel_config_get_port(tunnel_config));
+ const char *host = linphone_tunnel_config_get_host(tunnel_config);
+ if(host != NULL) {
+ if(linphone_tunnel_config_get_remote_udp_mirror_port(tunnel_config) != -1) {
+ str = ms_strdup_printf("%s:%d:%d:%d",
+ linphone_tunnel_config_get_host(tunnel_config),
+ linphone_tunnel_config_get_port(tunnel_config),
+ linphone_tunnel_config_get_remote_udp_mirror_port(tunnel_config),
+ linphone_tunnel_config_get_delay(tunnel_config));
+ } else {
+ str = ms_strdup_printf("%s:%d",
+ linphone_tunnel_config_get_host(tunnel_config),
+ linphone_tunnel_config_get_port(tunnel_config));
+ }
}
return str;
}
@@ -124,20 +127,21 @@ static LinphoneTunnelConfig *linphone_tunnel_config_from_string(const char *str)
static void linphone_tunnel_save_config(LinphoneTunnel *tunnel) {
- MSList *elem = tunnel->config_list;
+ MSList *elem = NULL;
char *tmp = NULL, *old_tmp = NULL, *tc_str = NULL;
- while(elem != NULL) {
+ for(elem = tunnel->config_list; elem != NULL; elem = elem->next) {
LinphoneTunnelConfig *tunnel_config = (LinphoneTunnelConfig *)elem->data;
tc_str = linphone_tunnel_config_to_string(tunnel_config);
- if(tmp != NULL) {
- old_tmp = tmp;
- tmp = ms_strdup_printf("%s %s", old_tmp, tc_str);
- ms_free(old_tmp);
- ms_free(tc_str);
- } else {
- tmp = tc_str;
+ if(tc_str != NULL) {
+ if(tmp != NULL) {
+ old_tmp = tmp;
+ tmp = ms_strdup_printf("%s %s", old_tmp, tc_str);
+ ms_free(old_tmp);
+ ms_free(tc_str);
+ } else {
+ tmp = tc_str;
+ }
}
- elem = elem->next;
}
lp_config_set_string(config(tunnel), "tunnel", "server_addresses", tmp);
if(tmp != NULL) {
diff --git a/coreapi/linphonecall.c b/coreapi/linphonecall.c
index 15df7990b..f8c6d1d72 100644
--- a/coreapi/linphonecall.c
+++ b/coreapi/linphonecall.c
@@ -701,7 +701,6 @@ void linphone_call_set_compatible_incoming_call_parameters(LinphoneCall *call, c
LinphoneCall * linphone_call_new_incoming(LinphoneCore *lc, LinphoneAddress *from, LinphoneAddress *to, SalOp *op){
LinphoneCall *call=ms_new0(LinphoneCall,1);
- char *from_str;
const SalMediaDescription *md;
LinphoneFirewallPolicy fpol;
@@ -721,11 +720,13 @@ LinphoneCall * linphone_call_new_incoming(LinphoneCore *lc, LinphoneAddress *fro
/*the following sends an option request back to the caller so that
we get a chance to discover our nat'd address before answering.*/
call->ping_op=sal_op_new(lc->sal);
- from_str=linphone_address_as_string_uri_only(from);
+
+ linphone_configure_op(lc, call->ping_op, from, NULL, FALSE);
+
sal_op_set_route(call->ping_op,sal_op_get_network_origin(op));
sal_op_set_user_pointer(call->ping_op,call);
- sal_ping(call->ping_op,linphone_core_find_best_identity(lc,from),from_str);
- ms_free(from_str);
+
+ sal_ping(call->ping_op,sal_op_get_from(call->ping_op), sal_op_get_to(call->ping_op));
}
}
@@ -1313,7 +1314,7 @@ int linphone_call_take_video_snapshot(LinphoneCall *call, const char *file){
* Note that the snapshot is asynchronous, an application shall not assume that the file is created when the function returns.
* @param call a LinphoneCall
* @param file a path where to write the jpeg content.
- * @return 0 if successfull, -1 otherwise (typically if jpeg format is not supported).
+ * @return 0 if successfull, -1 otherwise (typically if jpeg format is not supported).
**/
int linphone_call_take_preview_snapshot(LinphoneCall *call, const char *file){
#ifdef VIDEO_ENABLED
diff --git a/coreapi/linphonecore.c b/coreapi/linphonecore.c
index d12a92bdf..299bdc27f 100644
--- a/coreapi/linphonecore.c
+++ b/coreapi/linphonecore.c
@@ -999,10 +999,10 @@ static void video_config_read(LinphoneCore *lc){
linphone_core_set_preferred_video_size_by_name(lc,
lp_config_get_string(lc->config,"video","size","cif"));
-
+
linphone_core_set_preview_video_size_by_name(lc,
lp_config_get_string(lc->config,"video","preview_size",NULL));
-
+
linphone_core_set_preferred_framerate(lc,lp_config_get_float(lc->config,"video","framerate",0));
#ifdef VIDEO_ENABLED
@@ -1417,7 +1417,7 @@ static void linphone_core_init(LinphoneCore * lc, const LinphoneCoreVTable *vtab
remote_provisioning_uri = linphone_core_get_provisioning_uri(lc);
if (remote_provisioning_uri == NULL) {
linphone_configuring_terminated(lc, LinphoneConfiguringSkipped, NULL);
- } // else linphone_core_start will be called after the remote provisioining (see linphone_core_iterate)
+ } // else linphone_core_start will be called after the remote provisioning (see linphone_core_iterate)
}
/**
@@ -2351,7 +2351,7 @@ void linphone_core_iterate(LinphoneCore *lc){
#endif //BUILD_UPNP
linphone_core_start_invite(lc,call, NULL);
}
- if (call->state==LinphoneCallIncomingReceived){
+ if (call->state==LinphoneCallIncomingReceived || call->state==LinphoneCallIncomingEarlyMedia){
if (one_second_elapsed) ms_message("incoming call ringing for %i seconds",elapsed);
if (elapsed>lc->sip_conf.inc_timeout){
LinphoneReason decline_reason;
@@ -2824,6 +2824,7 @@ void linphone_configure_op(LinphoneCore *lc, SalOp *op, const LinphoneAddress *d
sal_op_set_to_address(op,dest);
sal_op_set_from(op,identity);
sal_op_set_sent_custom_header(op,headers);
+ sal_op_set_realm(op,linphone_proxy_config_get_realm(proxy));
if (with_contact && proxy && proxy->op){
const SalAddress *contact;
if ((contact=sal_op_get_contact_address(proxy->op))){
diff --git a/coreapi/linphonecore.h b/coreapi/linphonecore.h
index 6e0d88807..5e842ac59 100644
--- a/coreapi/linphonecore.h
+++ b/coreapi/linphonecore.h
@@ -917,6 +917,20 @@ LINPHONE_PUBLIC bool_t linphone_proxy_config_is_registered(const LinphoneProxyCo
**/
LINPHONE_PUBLIC const char *linphone_proxy_config_get_domain(const LinphoneProxyConfig *cfg);
+/**
+ * Get the realm of the given proxy config.
+ * @param[in] cfg #LinphoneProxyConfig object.
+ * @returns The realm of the proxy config.
+**/
+LINPHONE_PUBLIC const char *linphone_proxy_config_get_realm(const LinphoneProxyConfig *cfg);
+/**
+ * Set the realm of the given proxy config.
+ * @param[in] cfg #LinphoneProxyConfig object.
+ * @param[in] realm New realm value.
+ * @returns The realm of the proxy config.
+**/
+LINPHONE_PUBLIC void linphone_proxy_config_set_realm(LinphoneProxyConfig *cfg, const char * realm);
+
LINPHONE_PUBLIC const char *linphone_proxy_config_get_route(const LinphoneProxyConfig *obj);
LINPHONE_PUBLIC const char *linphone_proxy_config_get_identity(const LinphoneProxyConfig *obj);
LINPHONE_PUBLIC bool_t linphone_proxy_config_publish_enabled(const LinphoneProxyConfig *obj);
@@ -1244,7 +1258,8 @@ typedef enum _LinphoneChatMessageState {
LinphoneChatMessageStateIdle, /**< Initial state */
LinphoneChatMessageStateInProgress, /**< Delivery in progress */
LinphoneChatMessageStateDelivered, /**< Message succesffully delivered an acknoleged by remote end point */
- LinphoneChatMessageStateNotDelivered /**< Message was not delivered */
+ LinphoneChatMessageStateNotDelivered, /**< Message was not delivered */
+ LinphoneChatMessageStateFileTransferError /**< Message was received(and acknowledged) but cannot get file from server */
} LinphoneChatMessageState;
/**
@@ -1317,7 +1332,8 @@ LINPHONE_PUBLIC const LinphoneAddress* linphone_chat_message_get_to(const Linpho
LINPHONE_PUBLIC const char* linphone_chat_message_get_external_body_url(const LinphoneChatMessage* message);
LINPHONE_PUBLIC void linphone_chat_message_set_external_body_url(LinphoneChatMessage* message,const char* url);
LINPHONE_PUBLIC const LinphoneContent* linphone_chat_message_get_file_transfer_information(const LinphoneChatMessage* message);
-LINPHONE_PUBLIC void linphone_chat_message_start_file_download(const LinphoneChatMessage*message);
+LINPHONE_PUBLIC void linphone_chat_message_start_file_download(LinphoneChatMessage* message, LinphoneChatMessageStateChangedCb status_cb);
+LINPHONE_PUBLIC void linphone_chat_room_cancel_file_transfer(LinphoneChatMessage* msg);
LINPHONE_PUBLIC const char* linphone_chat_message_get_appdata(const LinphoneChatMessage* message);
LINPHONE_PUBLIC void linphone_chat_message_set_appdata(LinphoneChatMessage* message, const char* data);
LINPHONE_PUBLIC const char* linphone_chat_message_get_text(const LinphoneChatMessage* message);
@@ -1588,7 +1604,7 @@ typedef struct _LinphoneCoreVTable{
DisplayUrlCb display_url; /**< @deprecated */
ShowInterfaceCb show; /**< @deprecated Notifies the application that it should show up*/
LinphoneCoreTextMessageReceivedCb text_received; /** @deprecated, use #message_received instead
A text message has been received */
- LinphoneCoreFileTransferRecvCb file_transfer_received; /** Callback to store file received attached to a #LinphoneChatMessage */
+ LinphoneCoreFileTransferRecvCb file_transfer_recv; /** Callback to store file received attached to a #LinphoneChatMessage */
LinphoneCoreFileTransferSendCb file_transfer_send; /** Callback to collect file chunk to be sent for a #LinphoneChatMessage */
LinphoneCoreFileTransferProgressIndicationCb file_transfer_progress_indication; /**Callback to indicate file transfer progress*/
} LinphoneCoreVTable;
diff --git a/coreapi/linphonecore_jni.cc b/coreapi/linphonecore_jni.cc
index 609493b3e..1f01ccadf 100644
--- a/coreapi/linphonecore_jni.cc
+++ b/coreapi/linphonecore_jni.cc
@@ -3033,6 +3033,19 @@ JNIEXPORT jstring JNICALL Java_org_linphone_core_LinphoneProxyConfigImpl_getQual
return jvalue;
}
+JNIEXPORT void JNICALL Java_org_linphone_core_LinphoneProxyConfigImpl_setRealm(JNIEnv *env, jobject thiz, jlong ptr, jstring jrealm) {
+ if (jrealm){
+ const char *realm=env->GetStringUTFChars(jrealm, NULL);
+ linphone_proxy_config_set_realm((LinphoneProxyConfig *)ptr, realm);
+ env->ReleaseStringUTFChars(jrealm,realm);
+ }
+}
+
+JNIEXPORT jstring JNICALL Java_org_linphone_core_LinphoneProxyConfigImpl_getRealm(JNIEnv *env, jobject thiz, jlong ptr) {
+ jstring jvalue = env->NewStringUTF(linphone_proxy_config_get_realm((LinphoneProxyConfig *)ptr));
+ return jvalue;
+}
+
extern "C" jint Java_org_linphone_core_LinphoneCallImpl_getDuration(JNIEnv* env,jobject thiz,jlong ptr) {
return (jint)linphone_call_get_duration((LinphoneCall *) ptr);
}
diff --git a/coreapi/private.h b/coreapi/private.h
index 32e013c94..2df416fba 100644
--- a/coreapi/private.h
+++ b/coreapi/private.h
@@ -163,8 +163,9 @@ struct _LinphoneChatMessage {
bool_t is_read;
unsigned int storage_id;
SalOp *op;
- LinphoneContent *file_transfer_information;
- char *content_type;
+ LinphoneContent *file_transfer_information; /**< used to store file transfer information when the message is of file transfer type */
+ char *content_type; /**< is used to specified the type of message to be sent, used only for file transfer message */
+ belle_http_request_t *http_request; /**< keep a reference to the http_request in case of file transfer in order to be able to cancel the transfer */
};
BELLE_SIP_DECLARE_VPTR(LinphoneChatMessage);
@@ -423,6 +424,7 @@ struct _LinphoneProxyConfig
char *reg_identity;
char *reg_route;
char *quality_reporting_collector;
+ char *domain;
char *realm;
char *contact_params;
char *contact_uri_params;
diff --git a/coreapi/proxy.c b/coreapi/proxy.c
index 409ddb4a3..e6a33d556 100644
--- a/coreapi/proxy.c
+++ b/coreapi/proxy.c
@@ -94,6 +94,7 @@ static void linphone_proxy_config_init(LinphoneCore* lc, LinphoneProxyConfig *ob
const char *identity = lc ? lp_config_get_default_string(lc->config, "proxy", "reg_identity", NULL) : NULL;
const char *proxy = lc ? lp_config_get_default_string(lc->config, "proxy", "reg_proxy", NULL) : NULL;
const char *route = lc ? lp_config_get_default_string(lc->config, "proxy", "reg_route", NULL) : NULL;
+ const char *realm = lc ? lp_config_get_default_string(lc->config, "proxy", "realm", NULL) : NULL;
const char *quality_reporting_collector = lc ? lp_config_get_default_string(lc->config, "proxy", "quality_reporting_collector", NULL) : NULL;
const char *contact_params = lc ? lp_config_get_default_string(lc->config, "proxy", "contact_parameters", NULL) : NULL;
const char *contact_uri_params = lc ? lp_config_get_default_string(lc->config, "proxy", "contact_uri_parameters", NULL) : NULL;
@@ -108,6 +109,7 @@ static void linphone_proxy_config_init(LinphoneCore* lc, LinphoneProxyConfig *ob
obj->reg_identity = identity ? ms_strdup(identity) : NULL;
obj->reg_proxy = proxy ? ms_strdup(proxy) : NULL;
obj->reg_route = route ? ms_strdup(route) : NULL;
+ obj->realm = realm ? ms_strdup(realm) : NULL;
obj->quality_reporting_enabled = lc ? lp_config_get_default_int(lc->config, "proxy", "quality_reporting_enabled", 0) : 0;
obj->quality_reporting_collector = quality_reporting_collector ? ms_strdup(quality_reporting_collector) : NULL;
obj->quality_reporting_interval = lc ? lp_config_get_default_int(lc->config, "proxy", "quality_reporting_interval", 0) : 0;
@@ -150,6 +152,7 @@ void linphone_proxy_config_destroy(LinphoneProxyConfig *obj){
if (obj->reg_route!=NULL) ms_free(obj->reg_route);
if (obj->quality_reporting_collector!=NULL) ms_free(obj->quality_reporting_collector);
if (obj->ssctx!=NULL) sip_setup_context_free(obj->ssctx);
+ if (obj->domain!=NULL) ms_free(obj->domain);
if (obj->realm!=NULL) ms_free(obj->realm);
if (obj->type!=NULL) ms_free(obj->type);
if (obj->dial_prefix!=NULL) ms_free(obj->dial_prefix);
@@ -228,10 +231,10 @@ int linphone_proxy_config_set_identity(LinphoneProxyConfig *obj, const char *ide
obj->reg_identity=NULL;
}
obj->reg_identity=ms_strdup(identity);
- if (obj->realm){
- ms_free(obj->realm);
+ if (obj->domain){
+ ms_free(obj->domain);
}
- obj->realm=ms_strdup(linphone_address_get_domain(addr));
+ obj->domain=ms_strdup(linphone_address_get_domain(addr));
linphone_address_destroy(addr);
return 0;
}
@@ -240,7 +243,7 @@ int linphone_proxy_config_set_identity(LinphoneProxyConfig *obj, const char *ide
}
const char *linphone_proxy_config_get_domain(const LinphoneProxyConfig *cfg){
- return cfg->realm;
+ return cfg->domain;
}
/**
@@ -310,7 +313,7 @@ void linphone_proxy_config_enable_publish(LinphoneProxyConfig *obj, bool_t val){
/**
* Prevent a proxy config from refreshing its registration.
- * This is useful to let registrations to expire naturally (or) when the application wants to keep control on when
+ * This is useful to let registrations to expire naturally (or) when the application wants to keep control on when
* refreshes are sent.
* However, linphone_core_set_network_reachable(lc,TRUE) will always request the proxy configs to refresh their registrations.
* The refreshing operations can be resumed with linphone_proxy_config_refresh_register().
@@ -409,6 +412,7 @@ void _linphone_proxy_config_unregister(LinphoneProxyConfig *obj) {
static void linphone_proxy_config_register(LinphoneProxyConfig *obj){
if (obj->reg_sendregister){
LinphoneAddress* proxy=linphone_address_new(obj->reg_proxy);
+ LinphoneAddress* to=linphone_address_new(obj->reg_identity);
char* proxy_string;
LinphoneAddress *contact;
ms_message("LinphoneProxyConfig [%p] about to register (LinphoneCore version: %s)",obj,linphone_core_get_version());
@@ -417,11 +421,18 @@ static void linphone_proxy_config_register(LinphoneProxyConfig *obj){
if (obj->op)
sal_op_release(obj->op);
obj->op=sal_op_new(obj->lc->sal);
+
+ linphone_configure_op(obj->lc, obj->op, to, NULL, FALSE);
+ linphone_address_destroy(to);
+
if ((contact=guess_contact_for_register(obj))) {
sal_op_set_contact_address(obj->op,contact);
linphone_address_destroy(contact);
}
+
sal_op_set_user_pointer(obj->op,obj);
+
+
if (sal_register(obj->op,proxy_string,obj->reg_identity,obj->expires)==0) {
linphone_proxy_config_set_state(obj,LinphoneRegistrationProgress,"Registration in progress");
} else {
@@ -946,13 +957,16 @@ int linphone_proxy_config_done(LinphoneProxyConfig *obj)
return 0;
}
+const char* linphone_proxy_config_get_realm(const LinphoneProxyConfig *cfg)
+{
+ return cfg?cfg->realm:NULL;
+}
void linphone_proxy_config_set_realm(LinphoneProxyConfig *cfg, const char *realm)
{
if (cfg->realm!=NULL) {
ms_free(cfg->realm);
- cfg->realm=NULL;
}
- if (realm!=NULL) cfg->realm=ms_strdup(realm);
+ cfg->realm=ms_strdup(realm);
}
int linphone_proxy_config_send_publish(LinphoneProxyConfig *proxy, LinphonePresenceModel *presence){
@@ -960,10 +974,15 @@ int linphone_proxy_config_send_publish(LinphoneProxyConfig *proxy, LinphonePrese
if (proxy->state==LinphoneRegistrationOk || proxy->state==LinphoneRegistrationCleared){
if (proxy->publish_op==NULL){
+ LinphoneAddress *to=linphone_address_new(linphone_proxy_config_get_identity(proxy));
proxy->publish_op=sal_op_new(proxy->lc->sal);
- sal_op_set_route(proxy->publish_op,proxy->reg_proxy);
- sal_op_set_from(proxy->publish_op,linphone_proxy_config_get_identity(proxy));
- sal_op_set_to(proxy->publish_op,linphone_proxy_config_get_identity(proxy));
+
+ linphone_configure_op(proxy->lc, proxy->publish_op,
+ to, NULL, FALSE);
+
+ if (to!=NULL){
+ linphone_address_destroy(to);
+ }
if (lp_config_get_int(proxy->lc->config,"sip","publish_msg_with_contact",0)){
SalAddress *addr=sal_address_new(linphone_proxy_config_get_identity(proxy));
sal_op_set_contact_address(proxy->publish_op,addr);
@@ -1205,6 +1224,9 @@ void linphone_proxy_config_write_to_config_file(LpConfig *config, LinphoneProxyC
if (obj->reg_identity!=NULL){
lp_config_set_string(config,key,"reg_identity",obj->reg_identity);
}
+ if (obj->realm!=NULL){
+ lp_config_set_string(config,key,"realm",obj->realm);
+ }
if (obj->contact_params!=NULL){
lp_config_set_string(config,key,"contact_parameters",obj->contact_params);
}
@@ -1259,10 +1281,10 @@ LinphoneProxyConfig *linphone_proxy_config_new_from_config_file(LinphoneCore* lc
CONFIGURE_STRING_VALUE(cfg,config,key,server_addr,"reg_proxy")
CONFIGURE_STRING_VALUE(cfg,config,key,route,"reg_route")
+ CONFIGURE_STRING_VALUE(cfg,config,key,realm,"realm")
+
CONFIGURE_BOOL_VALUE(cfg,config,key,quality_reporting,"quality_reporting_enabled")
-
CONFIGURE_STRING_VALUE(cfg,config,key,quality_reporting_collector,"quality_reporting_collector")
-
CONFIGURE_INT_VALUE(cfg,config,key,quality_reporting_interval,"quality_reporting_interval")
CONFIGURE_STRING_VALUE(cfg,config,key,contact_parameters,"contact_parameters")
diff --git a/coreapi/remote_provisioning.c b/coreapi/remote_provisioning.c
index abf884e95..1b081a354 100644
--- a/coreapi/remote_provisioning.c
+++ b/coreapi/remote_provisioning.c
@@ -36,20 +36,28 @@ static void xml2lpc_callback(void *ctx, xml2lpc_log_level level, const char *fmt
static void linphone_remote_provisioning_apply(LinphoneCore *lc, const char *xml) {
xml2lpc_context *context = xml2lpc_context_new(xml2lpc_callback, lc);
int result = xml2lpc_set_xml_string(context, xml);
+ char * error_msg = NULL;
if (result == 0) {
- result = xml2lpc_convert(context, linphone_core_get_config(lc));
+ LpConfig * lpc = linphone_core_get_config(lc);
+ result = xml2lpc_convert(context, lpc);
if (result == 0) {
- lp_config_sync(linphone_core_get_config(lc));
- xml2lpc_context_destroy(context);
- linphone_configuring_terminated(lc, LinphoneConfiguringSuccessful, NULL);
+ // if the remote provisioning added a proxy config and none was set before, set it
+ if (lp_config_has_section(lpc, "proxy_0") && lp_config_get_int(lpc, "sip", "default_proxy", -1) == -1){
+ lp_config_set_int(lpc, "sip", "default_proxy", 0);
+ }
+ lp_config_sync(lpc);
+
} else {
- xml2lpc_context_destroy(context);
- linphone_configuring_terminated(lc, LinphoneConfiguringFailed, "xml to lpc failed");
+ error_msg = "xml to lpc failed";
}
} else {
- xml2lpc_context_destroy(context);
- linphone_configuring_terminated(lc, LinphoneConfiguringFailed, "invalid xml");
+ error_msg = "invalid xml";
}
+
+ xml2lpc_context_destroy(context);
+ linphone_configuring_terminated(lc
+ ,error_msg ? LinphoneConfiguringFailed : LinphoneConfiguringSuccessful
+ , error_msg);
}
static int linphone_remote_provisioning_load_file( LinphoneCore* lc, const char* file_path){
diff --git a/coreapi/sal.c b/coreapi/sal.c
index 24da751b6..8a48c79d0 100644
--- a/coreapi/sal.c
+++ b/coreapi/sal.c
@@ -386,6 +386,13 @@ void sal_op_add_route_address(SalOp *op, const SalAddress *address){
sal_op_set_route_address(op,address);
}
}
+void sal_op_set_realm(SalOp *op, const char *realm){
+ SalOpBase* op_base = (SalOpBase*)op;
+ if (op_base->realm != NULL){
+ ms_free(op_base->realm);
+ }
+ op_base->realm = ms_strdup(realm);
+}
void sal_op_set_from(SalOp *op, const char *from){
SET_PARAM(op,from);
}
@@ -511,6 +518,10 @@ void __sal_op_free(SalOp *op){
ms_free(b->route);
b->route=NULL;
}
+ if (b->realm) {
+ ms_free(b->realm);
+ b->realm=NULL;
+ }
if (b->contact_address) {
sal_address_destroy(b->contact_address);
}
diff --git a/include/sal/sal.h b/include/sal/sal.h
index 5533182ed..ffca87c5f 100644
--- a/include/sal/sal.h
+++ b/include/sal/sal.h
@@ -285,6 +285,7 @@ typedef struct SalOpBase{
SalMediaDescription *remote_media;
void *user_pointer;
const char* call_id;
+ char* realm;
SalAddress* service_route; /*as defined by rfc3608, might be a list*/
SalCustomHeader *sent_custom_headers;
SalCustomHeader *recv_custom_headers;
@@ -560,6 +561,7 @@ void sal_op_set_contact_address(SalOp *op, const SalAddress* address);
void sal_op_set_route(SalOp *op, const char *route);
void sal_op_set_route_address(SalOp *op, const SalAddress* address);
void sal_op_add_route_address(SalOp *op, const SalAddress* address);
+void sal_op_set_realm(SalOp *op, const char *realm);
void sal_op_set_from(SalOp *op, const char *from);
void sal_op_set_from_address(SalOp *op, const SalAddress *from);
void sal_op_set_to(SalOp *op, const char *to);
diff --git a/java/common/org/linphone/core/LinphoneCall.java b/java/common/org/linphone/core/LinphoneCall.java
index 90fe60ded..d75f1bbdb 100644
--- a/java/common/org/linphone/core/LinphoneCall.java
+++ b/java/common/org/linphone/core/LinphoneCall.java
@@ -323,4 +323,14 @@ public interface LinphoneCall {
*/
ErrorInfo getErrorInfo();
+ /**
+ * attached a user data to a call
+ **/
+ void setUserData(Object obj);
+
+ /**
+ * Returns user data from a call. return null if any
+ * @return an Object.
+ */
+ Object getUserData();
}
diff --git a/java/common/org/linphone/core/LinphoneProxyConfig.java b/java/common/org/linphone/core/LinphoneProxyConfig.java
index 0f8db591b..8b668da2e 100644
--- a/java/common/org/linphone/core/LinphoneProxyConfig.java
+++ b/java/common/org/linphone/core/LinphoneProxyConfig.java
@@ -25,9 +25,6 @@ package org.linphone.core;
*/
public interface LinphoneProxyConfig {
- public void setIsDeleted(boolean b);
- public boolean getIsDeleted();
-
/**
*Starts editing a proxy configuration.
*Because proxy configuration must be consistent, applications MUST call {@link #edit()} before doing any attempts to modify proxy configuration (such as identity, proxy address and so on).
@@ -227,6 +224,19 @@ public interface LinphoneProxyConfig {
*/
String getQualityReportingCollector();
+ /**
+ * Set the outbound proxy realm. It is used in digest authentication to avoid
+ * re-authentication if a previous token has already been provided.
+ * @param The new outbound proxy realm.
+ */
+ void setRealm(String realm);
+
+ /**
+ * Get the outbound proxy realm.
+ * @return The outbound proxy realm.
+ */
+ String getRealm();
+
/**
* Set optional contact parameters that will be added to the contact information sent in the registration.
* @param contact_params a string containing the additional parameters in text form, like "myparam=something;myparam2=something_else"
@@ -290,4 +300,15 @@ public interface LinphoneProxyConfig {
* @return the publish expiration time in second. Default value is the registration expiration value.
*/
public int getPublishExpires();
+
+ /**
+ * attached a user data to a proxy config
+ **/
+ void setUserData(Object obj);
+
+ /**
+ * Returns user data from a proxy config. return null if any
+ * @return an Object.
+ */
+ Object getUserData();
}
diff --git a/java/impl/org/linphone/core/LinphoneCallImpl.java b/java/impl/org/linphone/core/LinphoneCallImpl.java
index 66a9bf1d9..ee78e9d89 100644
--- a/java/impl/org/linphone/core/LinphoneCallImpl.java
+++ b/java/impl/org/linphone/core/LinphoneCallImpl.java
@@ -22,6 +22,7 @@ class LinphoneCallImpl implements LinphoneCall {
protected final long nativePtr;
boolean ownPtr = false;
+ Object userData;
private LinphoneCallStats audioStats;
private LinphoneCallStats videoStats;
@@ -236,4 +237,12 @@ class LinphoneCallImpl implements LinphoneCall {
public ErrorInfo getErrorInfo() {
return new ErrorInfoImpl(getErrorInfo(nativePtr));
}
+ @Override
+ public void setUserData(Object obj) {
+ userData = obj;
+ }
+ @Override
+ public Object getUserData() {
+ return userData;
+ }
}
diff --git a/java/impl/org/linphone/core/LinphoneProxyConfigImpl.java b/java/impl/org/linphone/core/LinphoneProxyConfigImpl.java
index 68d444332..5113f958c 100644
--- a/java/impl/org/linphone/core/LinphoneProxyConfigImpl.java
+++ b/java/impl/org/linphone/core/LinphoneProxyConfigImpl.java
@@ -24,8 +24,7 @@ class LinphoneProxyConfigImpl implements LinphoneProxyConfig {
protected long nativePtr;
protected LinphoneCoreImpl mCore;
- protected boolean isDeleting;
-
+ Object userData;
private native int getState(long nativePtr);
private native void setExpires(long nativePtr, int delay);
private native int getExpires(long nativePtr);
@@ -36,7 +35,6 @@ class LinphoneProxyConfigImpl implements LinphoneProxyConfig {
setIdentity(identity);
setProxy(proxy);
setRoute(route);
- setIsDeleted(false);
enableRegister(enableRegister);
ownPtr=true;
}
@@ -52,14 +50,6 @@ class LinphoneProxyConfigImpl implements LinphoneProxyConfig {
ownPtr=false;
}
- public boolean getIsDeleted() {
- return isDeleting;
- }
-
- public void setIsDeleted(boolean b) {
- isDeleting = b;
- }
-
private void isValid() {
if (nativePtr == 0) {
throw new RuntimeException("proxy config removed");
@@ -331,6 +321,7 @@ class LinphoneProxyConfigImpl implements LinphoneProxyConfig {
isValid();
return getQualityReportingInterval(nativePtr);
}
+
private native void setQualityReportingCollector(long nativePtr, String collector);
@Override
public void setQualityReportingCollector(String collector) {
@@ -344,6 +335,21 @@ class LinphoneProxyConfigImpl implements LinphoneProxyConfig {
isValid();
return getQualityReportingCollector(nativePtr);
}
+
+ private native void setRealm(long nativePtr, String realm);
+ @Override
+ public void setRealm(String realm) {
+ isValid();
+ setRealm(nativePtr, realm);
+ }
+ private native String getRealm(long nativePtr);
+ @Override
+ public String getRealm() {
+
+ isValid();
+ return getRealm(nativePtr);
+ }
+
private native void setPublishExpires(long nativePtr, int expires);
@Override
public void setPublishExpires(int expires) {
@@ -357,4 +363,13 @@ class LinphoneProxyConfigImpl implements LinphoneProxyConfig {
isValid();
return getPublishExpires(nativePtr);
}
+
+ @Override
+ public void setUserData(Object obj) {
+ userData = obj;
+ }
+ @Override
+ public Object getUserData() {
+ return userData;
+ }
}
diff --git a/mediastreamer2 b/mediastreamer2
index 003add3c5..47df383ea 160000
--- a/mediastreamer2
+++ b/mediastreamer2
@@ -1 +1 @@
-Subproject commit 003add3c50881ad8c16cdd38202376afea2f424a
+Subproject commit 47df383ea1631ef1171e10ecf4d6d8333979c3fd
diff --git a/oRTP b/oRTP
index 99f33a0f5..1fc29ba46 160000
--- a/oRTP
+++ b/oRTP
@@ -1 +1 @@
-Subproject commit 99f33a0f510310389c22bf88a39582450be38425
+Subproject commit 1fc29ba469c5bb1dbfc19c64e8dac382913d2fa7
diff --git a/tester/message_tester.c b/tester/message_tester.c
index daafac426..d71f2db53 100644
--- a/tester/message_tester.c
+++ b/tester/message_tester.c
@@ -46,11 +46,11 @@ void message_received(LinphoneCore *lc, LinphoneChatRoom *room, LinphoneChatMess
ms_free(from);
counters = get_stats(lc);
counters->number_of_LinphoneMessageReceived++;
- if (linphone_chat_message_get_file_transfer_information(message))
- counters->number_of_LinphoneMessageReceivedWithFile++;
if (counters->last_received_chat_message) linphone_chat_message_unref(counters->last_received_chat_message);
linphone_chat_message_ref(counters->last_received_chat_message=message);
- if (linphone_chat_message_get_external_body_url(message)) {
+ if (linphone_chat_message_get_file_transfer_information(message)) {
+ counters->number_of_LinphoneMessageReceivedWithFile++;
+ } else if (linphone_chat_message_get_external_body_url(message)) {
counters->number_of_LinphoneMessageExtBodyReceived++;
if (message_external_body_url) {
CU_ASSERT_STRING_EQUAL(linphone_chat_message_get_external_body_url(message),message_external_body_url);
@@ -75,7 +75,7 @@ void file_transfer_received(LinphoneCore *lc, LinphoneChatMessage *message, cons
/*next chunk*/
file = (FILE*)linphone_chat_message_get_user_data(message);
- if (size==0) { /* tranfer complerte */
+ if (size==0) { /* tranfer complete */
stats* counters = get_stats(lc);
linphone_chat_room_destroy(linphone_chat_message_get_chat_room(message));
linphone_chat_message_destroy(message);
@@ -124,7 +124,7 @@ void file_transfer_progress_indication(LinphoneCore *lc, LinphoneChatMessage *me
const LinphoneAddress* to_address = linphone_chat_message_get_to(message);
char *address = linphone_chat_message_is_outgoing(message)?linphone_address_as_string(to_address):linphone_address_as_string(from_address);
stats* counters = get_stats(lc);
- printf(" File transfer [%d%%] %s of type [%s/%s] %s [%s] \n", (int)progress
+ ms_message(" File transfer [%d%%] %s of type [%s/%s] %s [%s] \n", (int)progress
,(linphone_chat_message_is_outgoing(message)?"sent":"received")
, content->type
, content->subtype
@@ -157,6 +157,9 @@ void liblinphone_tester_chat_message_state_change(LinphoneChatMessage* msg,Linph
case LinphoneChatMessageStateInProgress:
counters->number_of_LinphoneMessageInProgress++;
break;
+ case LinphoneChatMessageStateFileTransferError:
+ counters->number_of_LinphoneMessageNotDelivered++;
+ break;
default:
ms_error("Unexpected state [%s] for message [%p]",linphone_chat_message_state_to_string(state),msg);
}
@@ -377,19 +380,20 @@ static void file_transfer_message(void) {
linphone_chat_room_send_message2(chat_room,message,liblinphone_tester_chat_message_state_change,pauline->lc);
CU_ASSERT_TRUE(wait_for(pauline->lc,marie->lc,&marie->stat.number_of_LinphoneMessageReceivedWithFile,1));
- if (marie->stat.last_received_info_message ) {
- linphone_chat_message_start_file_download((const LinphoneChatMessage*)marie->stat.last_received_info_message);
+ if (marie->stat.last_received_chat_message ) {
+ linphone_chat_message_start_file_download(marie->stat.last_received_chat_message, liblinphone_tester_chat_message_state_change);
}
- CU_ASSERT_TRUE(wait_for(pauline->lc,marie->lc,&pauline->stat.number_of_LinphoneMessageDelivered,1));
+ CU_ASSERT_TRUE(wait_for(pauline->lc,marie->lc,&marie->stat.number_of_LinphoneMessageExtBodyReceived,1));
CU_ASSERT_EQUAL(pauline->stat.number_of_LinphoneMessageInProgress,1);
+ CU_ASSERT_EQUAL(pauline->stat.number_of_LinphoneMessageDelivered,1);
CU_ASSERT_EQUAL(marie->stat.number_of_LinphoneMessageExtBodyReceived,1);
linphone_core_manager_destroy(marie);
linphone_core_manager_destroy(pauline);
}
-static void file_transfer_message_io_error(void) {
+static void file_transfer_message_io_error_upload(void) {
int i;
char* to;
LinphoneChatRoom* chat_room;
@@ -439,6 +443,173 @@ static void file_transfer_message_io_error(void) {
linphone_core_manager_destroy(pauline);
}
+
+#ifdef TEST_IS_BUGGED_NO_CALL_TO_IO_ERROR_CALLBACK
+static void file_transfer_message_io_error_download(void) {
+ int i;
+ char* to;
+ LinphoneChatRoom* chat_room;
+ LinphoneChatMessage* message;
+ LinphoneContent content;
+ const char* big_file_content="big file"; /* setting dummy file content to something */
+ LinphoneCoreManager* marie = linphone_core_manager_new( "marie_rc");
+ LinphoneCoreManager* pauline = linphone_core_manager_new( "pauline_rc");
+ reset_counters(&marie->stat);
+ reset_counters(&pauline->stat);
+
+ /* setting dummy file content to something */
+ for (i=0;ilc,"https://www.linphone.org:444/lft.php");
+
+ /* create a chatroom on pauline's side */
+ to = linphone_address_as_string(marie->identity);
+ chat_room = linphone_core_create_chat_room(pauline->lc,to);
+
+ /* create a file transfer message */
+ memset(&content,0,sizeof(content));
+ content.type="text";
+ content.subtype="plain";
+ content.size=sizeof(big_file); /*total size to be transfered*/
+ content.name = "bigfile.txt";
+ message = linphone_chat_room_create_file_transfer_message(chat_room, &content);
+
+ linphone_chat_room_send_message2(chat_room,message,liblinphone_tester_chat_message_state_change,pauline->lc);
+
+ /* wait for marie to receive pauline's message */
+ CU_ASSERT_TRUE(wait_for(pauline->lc,marie->lc,&marie->stat.number_of_LinphoneMessageReceivedWithFile,1));
+
+
+ if (marie->stat.last_received_chat_message ) { /* get last message and use it to download file */
+ linphone_chat_message_start_file_download(marie->stat.last_received_chat_message, liblinphone_tester_chat_message_state_change);
+ /* wait for file to be 50% downloaded */
+ CU_ASSERT_TRUE(wait_for(pauline->lc,marie->lc,&marie->stat.progress_of_LinphoneFileTransfer, 50));
+ /* and simulate network error */
+ sal_set_recv_error(marie->lc->sal, -1);
+ }
+
+ CU_ASSERT_EQUAL(pauline->stat.number_of_LinphoneMessageInProgress,1);
+ CU_ASSERT_EQUAL(pauline->stat.number_of_LinphoneMessageDelivered,1);
+ CU_ASSERT_EQUAL(marie->stat.number_of_LinphoneMessageNotDelivered,1);
+ CU_ASSERT_EQUAL(marie->stat.number_of_LinphoneMessageExtBodyReceived,0);
+
+ sal_set_recv_error(marie->lc->sal, 0);
+ linphone_core_manager_destroy(marie);
+ linphone_core_manager_destroy(pauline);
+}
+#endif
+
+static void file_transfer_message_upload_cancelled(void) {
+ int i;
+ char* to;
+ LinphoneChatRoom* chat_room;
+ LinphoneChatMessage* message;
+ LinphoneContent content;
+ const char* big_file_content="big file"; /* setting dummy file content to something */
+ LinphoneCoreManager* marie = linphone_core_manager_new( "marie_rc");
+ LinphoneCoreManager* pauline = linphone_core_manager_new( "pauline_rc");
+ reset_counters(&marie->stat);
+ reset_counters(&pauline->stat);
+
+ /* setting dummy file content to something */
+ for (i=0;ilc,"https://www.linphone.org:444/lft.php");
+
+ /* create a chatroom on pauline's side */
+ to = linphone_address_as_string(marie->identity);
+ chat_room = linphone_core_create_chat_room(pauline->lc,to);
+
+ /* create a file transfer message */
+ memset(&content,0,sizeof(content));
+ content.type="text";
+ content.subtype="plain";
+ content.size=sizeof(big_file); /*total size to be transfered*/
+ content.name = "bigfile.txt";
+ message = linphone_chat_room_create_file_transfer_message(chat_room, &content);
+
+ linphone_chat_room_send_message2(chat_room,message,liblinphone_tester_chat_message_state_change,pauline->lc);
+
+ /*wait for file to be 50% uploaded and cancel the transfer */
+ CU_ASSERT_TRUE(wait_for(pauline->lc,marie->lc,&pauline->stat.progress_of_LinphoneFileTransfer, 50));
+ linphone_chat_room_cancel_file_transfer(message);
+
+ CU_ASSERT_TRUE(wait_for(pauline->lc,marie->lc,&pauline->stat.number_of_LinphoneMessageNotDelivered,1));
+
+ CU_ASSERT_EQUAL(pauline->stat.number_of_LinphoneMessageNotDelivered,1);
+ CU_ASSERT_EQUAL(marie->stat.number_of_LinphoneMessageExtBodyReceived,0);
+
+ linphone_core_manager_destroy(marie);
+ linphone_core_manager_destroy(pauline);
+}
+
+static void file_transfer_message_download_cancelled(void) {
+ int i;
+ char* to;
+ LinphoneChatRoom* chat_room;
+ LinphoneChatMessage* message;
+ LinphoneContent content;
+ const char* big_file_content="big file"; /* setting dummy file content to something */
+ LinphoneCoreManager* marie = linphone_core_manager_new( "marie_rc");
+ LinphoneCoreManager* pauline = linphone_core_manager_new( "pauline_rc");
+ reset_counters(&marie->stat);
+ reset_counters(&pauline->stat);
+
+ /* setting dummy file content to something */
+ for (i=0;ilc,"https://www.linphone.org:444/lft.php");
+
+ /* create a chatroom on pauline's side */
+ to = linphone_address_as_string(marie->identity);
+ chat_room = linphone_core_create_chat_room(pauline->lc,to);
+
+ /* create a file transfer message */
+ memset(&content,0,sizeof(content));
+ content.type="text";
+ content.subtype="plain";
+ content.size=sizeof(big_file); /*total size to be transfered*/
+ content.name = "bigfile.txt";
+ message = linphone_chat_room_create_file_transfer_message(chat_room, &content);
+
+ linphone_chat_room_send_message2(chat_room,message,liblinphone_tester_chat_message_state_change,pauline->lc);
+
+ /* wait for marie to receive pauline's message */
+ CU_ASSERT_TRUE(wait_for(pauline->lc,marie->lc,&marie->stat.number_of_LinphoneMessageReceivedWithFile,1));
+
+
+ if (marie->stat.last_received_chat_message ) { /* get last message and use it to download file */
+ linphone_chat_message_start_file_download(marie->stat.last_received_chat_message, liblinphone_tester_chat_message_state_change);
+ /* wait for file to be 50% downloaded */
+ CU_ASSERT_TRUE(wait_for(pauline->lc,marie->lc,&marie->stat.progress_of_LinphoneFileTransfer, 50));
+ /* and cancel the transfer */
+ linphone_chat_room_cancel_file_transfer(marie->stat.last_received_chat_message);
+ }
+
+ CU_ASSERT_EQUAL(pauline->stat.number_of_LinphoneMessageInProgress,1);
+ CU_ASSERT_EQUAL(pauline->stat.number_of_LinphoneMessageDelivered,1);
+ CU_ASSERT_EQUAL(marie->stat.number_of_LinphoneMessageExtBodyReceived,0);
+ CU_ASSERT_EQUAL(marie->stat.number_of_LinphoneMessageNotDelivered,1);
+
+ linphone_core_manager_destroy(marie);
+ linphone_core_manager_destroy(pauline);
+}
+
static void text_message_with_send_error(void) {
LinphoneCoreManager* marie = linphone_core_manager_new("marie_rc");
LinphoneCoreManager* pauline = linphone_core_manager_new( "pauline_rc");
@@ -671,7 +842,10 @@ test_t message_tests[] = {
{ "Text message with send error", text_message_with_send_error },
{ "Text message with external body", text_message_with_external_body },
{ "File transfer message", file_transfer_message },
- { "File transfer message with io error", file_transfer_message_io_error },
+ { "File transfer message with io error at upload", file_transfer_message_io_error_upload },
+/* { "File transfer message with io error at download", file_transfer_message_io_error_download },*/
+ { "File transfer message upload cancelled", file_transfer_message_upload_cancelled },
+ { "File transfer message download cancelled", file_transfer_message_download_cancelled },
{ "Text message denied", text_message_denied },
{ "Info message", info_message },
{ "Info message with body", info_message_with_body },
diff --git a/tester/tester.c b/tester/tester.c
index 475d2c90f..d0faca038 100644
--- a/tester/tester.c
+++ b/tester/tester.c
@@ -199,7 +199,7 @@ LinphoneCoreManager* linphone_core_manager_new2(const char* rc_file, int check_f
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.file_transfer_received=file_transfer_received;
+ mgr->v_table.file_transfer_recv=file_transfer_received;
mgr->v_table.file_transfer_send=file_transfer_send;
mgr->v_table.file_transfer_progress_indication=file_transfer_progress_indication;
mgr->v_table.is_composing_received=is_composing_received;